From: lhauch Date: Thu, 5 Oct 2006 23:16:50 +0000 (+0000) Subject: More renames for Tool Packages X-Git-Tag: edk2-stable201903~24199 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=28305207ea586d0b5ceb530b0e2a436cad9fdd8f;ds=sidebyside More renames for Tool Packages git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1675 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/Tools/CodeTools/Source/Common/CommonLib.c b/Tools/CodeTools/Source/Common/CommonLib.c new file mode 100644 index 0000000000..4d1663a55a --- /dev/null +++ b/Tools/CodeTools/Source/Common/CommonLib.c @@ -0,0 +1,508 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + CommonLib.c + +Abstract: + + Common Library Functions + +--*/ + +#include +#include +#include +#include "CommonLib.h" + +VOID +PeiZeroMem ( + IN VOID *Buffer, + IN UINTN Size + ) +/*++ + +Routine Description: + + Set Buffer to zero for Size bytes. + +Arguments: + + Buffer - Memory to set. + + Size - Number of bytes to set + +Returns: + + None + +--*/ +{ + INT8 *Ptr; + + Ptr = Buffer; + while (Size--) { + *(Ptr++) = 0; + } +} + +VOID +PeiCopyMem ( + IN VOID *Destination, + IN VOID *Source, + IN UINTN Length + ) +/*++ + +Routine Description: + + Copy Length bytes from Source to Destination. + +Arguments: + + Destination - Target of copy + + Source - Place to copy from + + Length - Number of bytes to copy + +Returns: + + None + +--*/ +{ + CHAR8 *Destination8; + CHAR8 *Source8; + + Destination8 = Destination; + Source8 = Source; + while (Length--) { + *(Destination8++) = *(Source8++); + } +} + +VOID +ZeroMem ( + IN VOID *Buffer, + IN UINTN Size + ) +{ + PeiZeroMem (Buffer, Size); +} + +VOID +CopyMem ( + IN VOID *Destination, + IN VOID *Source, + IN UINTN Length + ) +{ + PeiCopyMem (Destination, Source, Length); +} + +INTN +CompareGuid ( + IN EFI_GUID *Guid1, + IN EFI_GUID *Guid2 + ) +/*++ + +Routine Description: + + Compares to GUIDs + +Arguments: + + Guid1 - guid to compare + Guid2 - guid to compare + +Returns: + = 0 if Guid1 == Guid2 + != 0 if Guid1 != Guid2 + +--*/ +{ + INT32 *g1; + INT32 *g2; + INT32 r; + + // + // Compare 32 bits at a time + // + g1 = (INT32 *) Guid1; + g2 = (INT32 *) Guid2; + + r = g1[0] - g2[0]; + r |= g1[1] - g2[1]; + r |= g1[2] - g2[2]; + r |= g1[3] - g2[3]; + + return r; +} + +EFI_STATUS +GetFileImage ( + IN CHAR8 *InputFileName, + OUT CHAR8 **InputFileImage, + OUT UINT32 *BytesRead + ) +/*++ + +Routine Description: + + This function opens a file and reads it into a memory buffer. The function + will allocate the memory buffer and returns the size of the buffer. + +Arguments: + + InputFileName The name of the file to read. + InputFileImage A pointer to the memory buffer. + BytesRead The size of the memory buffer. + +Returns: + + EFI_SUCCESS The function completed successfully. + EFI_INVALID_PARAMETER One of the input parameters was invalid. + EFI_ABORTED An error occurred. + EFI_OUT_OF_RESOURCES No resource to complete operations. + +--*/ +{ + FILE *InputFile; + UINT32 FileSize; + + // + // Verify input parameters. + // + if (InputFileName == NULL || strlen (InputFileName) == 0 || InputFileImage == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Open the file and copy contents into a memory buffer. + // + // + // Open the file + // + InputFile = fopen (InputFileName, "rb"); + if (InputFile == NULL) { + printf ("ERROR: Could not open input file \"%s\".\n", InputFileName); + return EFI_ABORTED; + } + // + // Go to the end so that we can determine the file size + // + if (fseek (InputFile, 0, SEEK_END)) { + printf ("ERROR: System error reading input file \"%s\".\n", InputFileName); + fclose (InputFile); + return EFI_ABORTED; + } + // + // Get the file size + // + FileSize = ftell (InputFile); + if (FileSize == -1) { + printf ("ERROR: System error parsing input file \"%s\".\n", InputFileName); + fclose (InputFile); + return EFI_ABORTED; + } + // + // Allocate a buffer + // + *InputFileImage = malloc (FileSize); + if (*InputFileImage == NULL) { + fclose (InputFile); + return EFI_OUT_OF_RESOURCES; + } + // + // Reset to the beginning of the file + // + if (fseek (InputFile, 0, SEEK_SET)) { + printf ("ERROR: System error reading input file \"%s\".\n", InputFileName); + fclose (InputFile); + free (*InputFileImage); + *InputFileImage = NULL; + return EFI_ABORTED; + } + // + // Read all of the file contents. + // + *BytesRead = fread (*InputFileImage, sizeof (UINT8), FileSize, InputFile); + if (*BytesRead != sizeof (UINT8) * FileSize) { + printf ("ERROR: Reading file \"%s\"%i.\n", InputFileName); + fclose (InputFile); + free (*InputFileImage); + *InputFileImage = NULL; + return EFI_ABORTED; + } + // + // Close the file + // + fclose (InputFile); + + return EFI_SUCCESS; +} + +UINT8 +CalculateChecksum8 ( + IN UINT8 *Buffer, + IN UINTN Size + ) +/*++ + +Routine Description: + + This function calculates the value needed for a valid UINT8 checksum + +Arguments: + + Buffer Pointer to buffer containing byte data of component. + Size Size of the buffer + +Returns: + + The 8 bit checksum value needed. + +--*/ +{ + return (UINT8) (0x100 - CalculateSum8 (Buffer, Size)); +} + +UINT8 +CalculateSum8 ( + IN UINT8 *Buffer, + IN UINTN Size + ) +/*++ + +Routine Description:: + + This function calculates the UINT8 sum for the requested region. + +Arguments: + + Buffer Pointer to buffer containing byte data of component. + Size Size of the buffer + +Returns: + + The 8 bit checksum value needed. + +--*/ +{ + UINTN Index; + UINT8 Sum; + + Sum = 0; + + // + // Perform the byte sum for buffer + // + for (Index = 0; Index < Size; Index++) { + Sum = (UINT8) (Sum + Buffer[Index]); + } + + return Sum; +} + +UINT16 +CalculateChecksum16 ( + IN UINT16 *Buffer, + IN UINTN Size + ) +/*++ + +Routine Description:: + + This function calculates the value needed for a valid UINT16 checksum + +Arguments: + + Buffer Pointer to buffer containing byte data of component. + Size Size of the buffer + +Returns: + + The 16 bit checksum value needed. + +--*/ +{ + return (UINT16) (0x10000 - CalculateSum16 (Buffer, Size)); +} + +UINT16 +CalculateSum16 ( + IN UINT16 *Buffer, + IN UINTN Size + ) +/*++ + +Routine Description: + + This function calculates the UINT16 sum for the requested region. + +Arguments: + + Buffer Pointer to buffer containing byte data of component. + Size Size of the buffer + +Returns: + + The 16 bit checksum + +--*/ +{ + UINTN Index; + UINT16 Sum; + + Sum = 0; + + // + // Perform the word sum for buffer + // + for (Index = 0; Index < Size; Index++) { + Sum = (UINT16) (Sum + Buffer[Index]); + } + + return (UINT16) Sum; +} + +EFI_STATUS +PrintGuid ( + IN EFI_GUID *Guid + ) +/*++ + +Routine Description: + + This function prints a GUID to STDOUT. + +Arguments: + + Guid Pointer to a GUID to print. + +Returns: + + EFI_SUCCESS The GUID was printed. + EFI_INVALID_PARAMETER The input was NULL. + +--*/ +{ + if (Guid == NULL) { + printf ("ERROR: PrintGuid called with a NULL value.\n"); + return EFI_INVALID_PARAMETER; + } + + printf ( + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", + Guid->Data1, + Guid->Data2, + Guid->Data3, + Guid->Data4[0], + Guid->Data4[1], + Guid->Data4[2], + Guid->Data4[3], + Guid->Data4[4], + Guid->Data4[5], + Guid->Data4[6], + Guid->Data4[7] + ); + return EFI_SUCCESS; +} + +EFI_STATUS +PrintGuidToBuffer ( + IN EFI_GUID *Guid, + IN OUT UINT8 *Buffer, + IN UINT32 BufferLen, + IN BOOLEAN Uppercase + ) +/*++ + +Routine Description: + + This function prints a GUID to a buffer + +Arguments: + + Guid - Pointer to a GUID to print. + Buffer - Pointer to a user-provided buffer to print to + BufferLen - Size of the Buffer + Uppercase - If use upper case. + +Returns: + + EFI_SUCCESS The GUID was printed. + EFI_INVALID_PARAMETER The input was NULL. + EFI_BUFFER_TOO_SMALL The input buffer was not big enough + +--*/ +{ + if (Guid == NULL) { + printf ("ERROR: PrintGuidToBuffer() called with a NULL value\n"); + return EFI_INVALID_PARAMETER; + } + + if (BufferLen < PRINTED_GUID_BUFFER_SIZE) { + printf ("ERORR: PrintGuidToBuffer() called with invalid buffer size\n"); + return EFI_BUFFER_TOO_SMALL; + } + + if (Uppercase) { + sprintf ( + Buffer, + "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", + Guid->Data1, + Guid->Data2, + Guid->Data3, + Guid->Data4[0], + Guid->Data4[1], + Guid->Data4[2], + Guid->Data4[3], + Guid->Data4[4], + Guid->Data4[5], + Guid->Data4[6], + Guid->Data4[7] + ); + } else { + sprintf ( + Buffer, + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + Guid->Data1, + Guid->Data2, + Guid->Data3, + Guid->Data4[0], + Guid->Data4[1], + Guid->Data4[2], + Guid->Data4[3], + Guid->Data4[4], + Guid->Data4[5], + Guid->Data4[6], + Guid->Data4[7] + ); + } + + return EFI_SUCCESS; +} + +#ifdef __GNUC__ +#ifndef __CYGWIN__ +char *strlwr(char *s) +{ + char *p = s; + for(;*s;s++) { + *s = tolower(*s); + } + return p; +} +#endif +#endif diff --git a/Tools/CodeTools/Source/Common/CommonLib.h b/Tools/CodeTools/Source/Common/CommonLib.h new file mode 100644 index 0000000000..46f0cbace5 --- /dev/null +++ b/Tools/CodeTools/Source/Common/CommonLib.h @@ -0,0 +1,135 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + CommonLib.h + +Abstract: + + Common library assistance routines. + +--*/ + +#ifndef _EFI_COMMON_LIB_H +#define _EFI_COMMON_LIB_H + +#include + +#ifndef _MAX_PATH +#define _MAX_PATH 500 +#endif + +#define PRINTED_GUID_BUFFER_SIZE 37 // including null-termination +// +// Function declarations +// +VOID +PeiZeroMem ( + IN VOID *Buffer, + IN UINTN Size + ) +; + +VOID +PeiCopyMem ( + IN VOID *Destination, + IN VOID *Source, + IN UINTN Length + ) +; + +VOID +ZeroMem ( + IN VOID *Buffer, + IN UINTN Size + ) +; + +VOID +CopyMem ( + IN VOID *Destination, + IN VOID *Source, + IN UINTN Length + ) +; + +INTN +CompareGuid ( + IN EFI_GUID *Guid1, + IN EFI_GUID *Guid2 + ) +; + +EFI_STATUS +GetFileImage ( + IN CHAR8 *InputFileName, + OUT CHAR8 **InputFileImage, + OUT UINT32 *BytesRead + ) +; + +UINT8 +CalculateChecksum8 ( + IN UINT8 *Buffer, + IN UINTN Size + ) +; + +UINT8 +CalculateSum8 ( + IN UINT8 *Buffer, + IN UINTN Size + ) +; + +UINT16 +CalculateChecksum16 ( + IN UINT16 *Buffer, + IN UINTN Size + ) +; + +UINT16 +CalculateSum16 ( + IN UINT16 *Buffer, + IN UINTN Size + ) +; + +EFI_STATUS +PrintGuid ( + IN EFI_GUID *Guid + ) +; + +#define PRINTED_GUID_BUFFER_SIZE 37 // including null-termination +EFI_STATUS +PrintGuidToBuffer ( + IN EFI_GUID *Guid, + IN OUT UINT8 *Buffer, + IN UINT32 BufferLen, + IN BOOLEAN Uppercase + ) +; + +#define ASSERT(x) assert(x) + +#ifdef __GNUC__ +#define stricmp strcasecmp +#define strnicmp strncasecmp +#define strcmpi strcasecmp +#ifndef __CYGWIN__ +char *strlwr(char *s); +#endif +#endif + +#endif diff --git a/Tools/CodeTools/Source/Common/Crc32.c b/Tools/CodeTools/Source/Common/Crc32.c new file mode 100644 index 0000000000..4ae5eb486b --- /dev/null +++ b/Tools/CodeTools/Source/Common/Crc32.c @@ -0,0 +1,326 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + crc32.c + +Abstract: + + CalcuateCrc32 routine. + +--*/ + +#include +#include "Crc32.h" + +UINT32 mCrcTable[256] = { + 0x00000000, + 0x77073096, + 0xEE0E612C, + 0x990951BA, + 0x076DC419, + 0x706AF48F, + 0xE963A535, + 0x9E6495A3, + 0x0EDB8832, + 0x79DCB8A4, + 0xE0D5E91E, + 0x97D2D988, + 0x09B64C2B, + 0x7EB17CBD, + 0xE7B82D07, + 0x90BF1D91, + 0x1DB71064, + 0x6AB020F2, + 0xF3B97148, + 0x84BE41DE, + 0x1ADAD47D, + 0x6DDDE4EB, + 0xF4D4B551, + 0x83D385C7, + 0x136C9856, + 0x646BA8C0, + 0xFD62F97A, + 0x8A65C9EC, + 0x14015C4F, + 0x63066CD9, + 0xFA0F3D63, + 0x8D080DF5, + 0x3B6E20C8, + 0x4C69105E, + 0xD56041E4, + 0xA2677172, + 0x3C03E4D1, + 0x4B04D447, + 0xD20D85FD, + 0xA50AB56B, + 0x35B5A8FA, + 0x42B2986C, + 0xDBBBC9D6, + 0xACBCF940, + 0x32D86CE3, + 0x45DF5C75, + 0xDCD60DCF, + 0xABD13D59, + 0x26D930AC, + 0x51DE003A, + 0xC8D75180, + 0xBFD06116, + 0x21B4F4B5, + 0x56B3C423, + 0xCFBA9599, + 0xB8BDA50F, + 0x2802B89E, + 0x5F058808, + 0xC60CD9B2, + 0xB10BE924, + 0x2F6F7C87, + 0x58684C11, + 0xC1611DAB, + 0xB6662D3D, + 0x76DC4190, + 0x01DB7106, + 0x98D220BC, + 0xEFD5102A, + 0x71B18589, + 0x06B6B51F, + 0x9FBFE4A5, + 0xE8B8D433, + 0x7807C9A2, + 0x0F00F934, + 0x9609A88E, + 0xE10E9818, + 0x7F6A0DBB, + 0x086D3D2D, + 0x91646C97, + 0xE6635C01, + 0x6B6B51F4, + 0x1C6C6162, + 0x856530D8, + 0xF262004E, + 0x6C0695ED, + 0x1B01A57B, + 0x8208F4C1, + 0xF50FC457, + 0x65B0D9C6, + 0x12B7E950, + 0x8BBEB8EA, + 0xFCB9887C, + 0x62DD1DDF, + 0x15DA2D49, + 0x8CD37CF3, + 0xFBD44C65, + 0x4DB26158, + 0x3AB551CE, + 0xA3BC0074, + 0xD4BB30E2, + 0x4ADFA541, + 0x3DD895D7, + 0xA4D1C46D, + 0xD3D6F4FB, + 0x4369E96A, + 0x346ED9FC, + 0xAD678846, + 0xDA60B8D0, + 0x44042D73, + 0x33031DE5, + 0xAA0A4C5F, + 0xDD0D7CC9, + 0x5005713C, + 0x270241AA, + 0xBE0B1010, + 0xC90C2086, + 0x5768B525, + 0x206F85B3, + 0xB966D409, + 0xCE61E49F, + 0x5EDEF90E, + 0x29D9C998, + 0xB0D09822, + 0xC7D7A8B4, + 0x59B33D17, + 0x2EB40D81, + 0xB7BD5C3B, + 0xC0BA6CAD, + 0xEDB88320, + 0x9ABFB3B6, + 0x03B6E20C, + 0x74B1D29A, + 0xEAD54739, + 0x9DD277AF, + 0x04DB2615, + 0x73DC1683, + 0xE3630B12, + 0x94643B84, + 0x0D6D6A3E, + 0x7A6A5AA8, + 0xE40ECF0B, + 0x9309FF9D, + 0x0A00AE27, + 0x7D079EB1, + 0xF00F9344, + 0x8708A3D2, + 0x1E01F268, + 0x6906C2FE, + 0xF762575D, + 0x806567CB, + 0x196C3671, + 0x6E6B06E7, + 0xFED41B76, + 0x89D32BE0, + 0x10DA7A5A, + 0x67DD4ACC, + 0xF9B9DF6F, + 0x8EBEEFF9, + 0x17B7BE43, + 0x60B08ED5, + 0xD6D6A3E8, + 0xA1D1937E, + 0x38D8C2C4, + 0x4FDFF252, + 0xD1BB67F1, + 0xA6BC5767, + 0x3FB506DD, + 0x48B2364B, + 0xD80D2BDA, + 0xAF0A1B4C, + 0x36034AF6, + 0x41047A60, + 0xDF60EFC3, + 0xA867DF55, + 0x316E8EEF, + 0x4669BE79, + 0xCB61B38C, + 0xBC66831A, + 0x256FD2A0, + 0x5268E236, + 0xCC0C7795, + 0xBB0B4703, + 0x220216B9, + 0x5505262F, + 0xC5BA3BBE, + 0xB2BD0B28, + 0x2BB45A92, + 0x5CB36A04, + 0xC2D7FFA7, + 0xB5D0CF31, + 0x2CD99E8B, + 0x5BDEAE1D, + 0x9B64C2B0, + 0xEC63F226, + 0x756AA39C, + 0x026D930A, + 0x9C0906A9, + 0xEB0E363F, + 0x72076785, + 0x05005713, + 0x95BF4A82, + 0xE2B87A14, + 0x7BB12BAE, + 0x0CB61B38, + 0x92D28E9B, + 0xE5D5BE0D, + 0x7CDCEFB7, + 0x0BDBDF21, + 0x86D3D2D4, + 0xF1D4E242, + 0x68DDB3F8, + 0x1FDA836E, + 0x81BE16CD, + 0xF6B9265B, + 0x6FB077E1, + 0x18B74777, + 0x88085AE6, + 0xFF0F6A70, + 0x66063BCA, + 0x11010B5C, + 0x8F659EFF, + 0xF862AE69, + 0x616BFFD3, + 0x166CCF45, + 0xA00AE278, + 0xD70DD2EE, + 0x4E048354, + 0x3903B3C2, + 0xA7672661, + 0xD06016F7, + 0x4969474D, + 0x3E6E77DB, + 0xAED16A4A, + 0xD9D65ADC, + 0x40DF0B66, + 0x37D83BF0, + 0xA9BCAE53, + 0xDEBB9EC5, + 0x47B2CF7F, + 0x30B5FFE9, + 0xBDBDF21C, + 0xCABAC28A, + 0x53B39330, + 0x24B4A3A6, + 0xBAD03605, + 0xCDD70693, + 0x54DE5729, + 0x23D967BF, + 0xB3667A2E, + 0xC4614AB8, + 0x5D681B02, + 0x2A6F2B94, + 0xB40BBE37, + 0xC30C8EA1, + 0x5A05DF1B, + 0x2D02EF8D +}; + +EFI_STATUS +CalculateCrc32 ( + IN UINT8 *Data, + IN UINTN DataSize, + IN OUT UINT32 *CrcOut + ) +/*++ + +Routine Description: + + The CalculateCrc32 routine. + +Arguments: + + Data - The buffer contaning the data to be processed + DataSize - The size of data to be processed + CrcOut - A pointer to the caller allocated UINT32 that on + contains the CRC32 checksum of Data + +Returns: + + EFI_SUCCESS - Calculation is successful. + EFI_INVALID_PARAMETER - Data / CrcOut = NULL, or DataSize = 0 + +--*/ +{ + UINT32 Crc; + UINTN Index; + UINT8 *Ptr; + + if ((DataSize == 0) || (Data == NULL) || (CrcOut == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Crc = 0xffffffff; + for (Index = 0, Ptr = Data; Index < DataSize; Index++, Ptr++) { + Crc = (Crc >> 8) ^ mCrcTable[(UINT8) Crc ^ *Ptr]; + } + + *CrcOut = Crc ^ 0xffffffff; + + return EFI_SUCCESS; +} diff --git a/Tools/CodeTools/Source/Common/Crc32.h b/Tools/CodeTools/Source/Common/Crc32.h new file mode 100644 index 0000000000..ec48cdd478 --- /dev/null +++ b/Tools/CodeTools/Source/Common/Crc32.h @@ -0,0 +1,54 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + Crc32.h + +Abstract: + + Header file for CalcuateCrc32 routine + +--*/ + +#ifndef _CRC32_H +#define _CRC32_H + +#include + +EFI_STATUS +CalculateCrc32 ( + IN UINT8 *Data, + IN UINTN DataSize, + IN OUT UINT32 *CrcOut + ) +/*++ + +Routine Description: + + The CalculateCrc32 routine. + +Arguments: + + Data - The buffer contaning the data to be processed + DataSize - The size of data to be processed + CrcOut - A pointer to the caller allocated UINT32 that on + contains the CRC32 checksum of Data + +Returns: + + EFI_SUCCESS - Calculation is successful. + EFI_INVALID_PARAMETER - Data / CrcOut = NULL, or DataSize = 0 + +--*/ +; + +#endif diff --git a/Tools/CodeTools/Source/Common/EfiCompress.c b/Tools/CodeTools/Source/Common/EfiCompress.c new file mode 100644 index 0000000000..5b91b1d216 --- /dev/null +++ b/Tools/CodeTools/Source/Common/EfiCompress.c @@ -0,0 +1,1742 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + EfiCompress.c + +Abstract: + + Compression routine. The compression algorithm is a mixture of + LZ77 and Huffman coding. LZ77 transforms the source data into a + sequence of Original Characters and Pointers to repeated strings. + This sequence is further divided into Blocks and Huffman codings + are applied to each Block. + +--*/ + +#include "EfiCompress.h" + +// +// Macro Definitions +// +typedef INT32 NODE; +#define UINT8_BIT 8 +#define THRESHOLD 3 +#define INIT_CRC 0 +#define WNDBIT 19 +#define WNDSIZ (1U << WNDBIT) +#define MAXMATCH 256 +#define BLKSIZ (1U << 14) // 16 * 1024U +#define PERC_FLAG 0x80000000U +#define CODE_BIT 16 +#define NIL 0 +#define MAX_HASH_VAL (3 * WNDSIZ + (WNDSIZ / 512 + 1) * UINT8_MAX) +#define HASH(p, c) ((p) + ((c) << (WNDBIT - 9)) + WNDSIZ * 2) +#define CRCPOLY 0xA001 +#define UPDATE_CRC(c) mCrc = mCrcTable[(mCrc ^ (c)) & 0xFF] ^ (mCrc >> UINT8_BIT) + +// +// C: the Char&Len Set; P: the Position Set; T: the exTra Set +// +#define NC (UINT8_MAX + MAXMATCH + 2 - THRESHOLD) +#define CBIT 9 +#define NP (WNDBIT + 1) +#define PBIT 5 +#define NT (CODE_BIT + 3) +#define TBIT 5 +#if NT > NP +#define NPT NT +#else +#define NPT NP +#endif +// +// Function Prototypes +// +STATIC VOID PutDword(IN UINT32 Data); + +STATIC +EFI_STATUS +AllocateMemory ( + VOID + ); + +STATIC +VOID +FreeMemory ( + VOID + ); + +STATIC +VOID +InitSlide ( + VOID + ); + +STATIC +NODE +Child ( + IN NODE NodeQ, + IN UINT8 CharC + ); + +STATIC +VOID +MakeChild ( + IN NODE NodeQ, + IN UINT8 CharC, + IN NODE NodeR + ); + +STATIC +VOID +Split ( + IN NODE Old + ); + +STATIC +VOID +InsertNode ( + VOID + ); + +STATIC +VOID +DeleteNode ( + VOID + ); + +STATIC +VOID +GetNextMatch ( + VOID + ); + +STATIC +EFI_STATUS +Encode ( + VOID + ); + +STATIC +VOID +CountTFreq ( + VOID + ); + +STATIC +VOID +WritePTLen ( + IN INT32 Number, + IN INT32 nbit, + IN INT32 Special + ); + +STATIC +VOID +WriteCLen ( + VOID + ); + +STATIC +VOID +EncodeC ( + IN INT32 Value + ); + +STATIC +VOID +EncodeP ( + IN UINT32 Value + ); + +STATIC +VOID +SendBlock ( + VOID + ); + +STATIC +VOID +Output ( + IN UINT32 c, + IN UINT32 p + ); + +STATIC +VOID +HufEncodeStart ( + VOID + ); + +STATIC +VOID +HufEncodeEnd ( + VOID + ); + +STATIC +VOID +MakeCrcTable ( + VOID + ); + +STATIC +VOID +PutBits ( + IN INT32 Number, + IN UINT32 Value + ); + +STATIC +INT32 +FreadCrc ( + OUT UINT8 *Pointer, + IN INT32 Number + ); + +STATIC +VOID +InitPutBits ( + VOID + ); + +STATIC +VOID +CountLen ( + IN INT32 Index + ); + +STATIC +VOID +MakeLen ( + IN INT32 Root + ); + +STATIC +VOID +DownHeap ( + IN INT32 Index + ); + +STATIC +VOID +MakeCode ( + IN INT32 Number, + IN UINT8 Len[ ], + OUT UINT16 Code[] + ); + +STATIC +INT32 +MakeTree ( + IN INT32 NParm, + IN UINT16 FreqParm[], + OUT UINT8 LenParm[ ], + OUT UINT16 CodeParm[] + ); + +// +// Global Variables +// +static UINT8 *mSrc, *mDst, *mSrcUpperLimit, *mDstUpperLimit; + +static UINT8 *mLevel, *mText, *mChildCount, *mBuf, mCLen[NC], mPTLen[NPT], *mLen; +static INT16 mHeap[NC + 1]; +static INT32 mRemainder, mMatchLen, mBitCount, mHeapSize, mN; +static UINT32 mBufSiz = 0, mOutputPos, mOutputMask, mSubBitBuf, mCrc; +static UINT32 mCompSize, mOrigSize; + +static UINT16 *mFreq, *mSortPtr, mLenCnt[17], mLeft[2 * NC - 1], mRight[2 * NC - 1], mCrcTable[UINT8_MAX + 1], + mCFreq[2 * NC - 1], mCTable[4096], mCCode[NC], mPFreq[2 * NP - 1], mPTCode[NPT], mTFreq[2 * NT - 1]; + +static NODE mPos, mMatchPos, mAvail, *mPosition, *mParent, *mPrev, *mNext = NULL; + +// +// functions +// +EFI_STATUS +Compress ( + IN UINT8 *SrcBuffer, + IN UINT32 SrcSize, + IN UINT8 *DstBuffer, + IN OUT UINT32 *DstSize + ) +/*++ + +Routine Description: + + The main compression routine. + +Arguments: + + SrcBuffer - The buffer storing the source data + SrcSize - The size of source data + DstBuffer - The buffer to store the compressed data + DstSize - On input, the size of DstBuffer; On output, + the size of the actual compressed data. + +Returns: + + EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. In this case, + DstSize contains the size needed. + EFI_SUCCESS - Compression is successful. + EFI_OUT_OF_RESOURCES - No resource to complete function. + +--*/ +{ + EFI_STATUS Status; + + // + // Initializations + // + mBufSiz = 0; + mBuf = NULL; + mText = NULL; + mLevel = NULL; + mChildCount = NULL; + mPosition = NULL; + mParent = NULL; + mPrev = NULL; + mNext = NULL; + + mSrc = SrcBuffer; + mSrcUpperLimit = mSrc + SrcSize; + mDst = DstBuffer; + mDstUpperLimit = mDst +*DstSize; + + PutDword (0L); + PutDword (0L); + + MakeCrcTable (); + + mOrigSize = mCompSize = 0; + mCrc = INIT_CRC; + + // + // Compress it + // + Status = Encode (); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + // + // Null terminate the compressed data + // + if (mDst < mDstUpperLimit) { + *mDst++ = 0; + } + // + // Fill in compressed size and original size + // + mDst = DstBuffer; + PutDword (mCompSize + 1); + PutDword (mOrigSize); + + // + // Return + // + if (mCompSize + 1 + 8 > *DstSize) { + *DstSize = mCompSize + 1 + 8; + return EFI_BUFFER_TOO_SMALL; + } else { + *DstSize = mCompSize + 1 + 8; + return EFI_SUCCESS; + } + +} + +STATIC +VOID +PutDword ( + IN UINT32 Data + ) +/*++ + +Routine Description: + + Put a dword to output stream + +Arguments: + + Data - the dword to put + +Returns: (VOID) + +--*/ +{ + if (mDst < mDstUpperLimit) { + *mDst++ = (UINT8) (((UINT8) (Data)) & 0xff); + } + + if (mDst < mDstUpperLimit) { + *mDst++ = (UINT8) (((UINT8) (Data >> 0x08)) & 0xff); + } + + if (mDst < mDstUpperLimit) { + *mDst++ = (UINT8) (((UINT8) (Data >> 0x10)) & 0xff); + } + + if (mDst < mDstUpperLimit) { + *mDst++ = (UINT8) (((UINT8) (Data >> 0x18)) & 0xff); + } +} + +STATIC +EFI_STATUS +AllocateMemory ( + VOID + ) +/*++ + +Routine Description: + + Allocate memory spaces for data structures used in compression process + +Argements: + VOID + +Returns: + + EFI_SUCCESS - Memory is allocated successfully + EFI_OUT_OF_RESOURCES - Allocation fails + +--*/ +{ + UINT32 Index; + + mText = malloc (WNDSIZ * 2 + MAXMATCH); + for (Index = 0; Index < WNDSIZ * 2 + MAXMATCH; Index++) { + mText[Index] = 0; + } + + mLevel = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mLevel)); + mChildCount = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mChildCount)); + mPosition = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mPosition)); + mParent = malloc (WNDSIZ * 2 * sizeof (*mParent)); + mPrev = malloc (WNDSIZ * 2 * sizeof (*mPrev)); + mNext = malloc ((MAX_HASH_VAL + 1) * sizeof (*mNext)); + + mBufSiz = BLKSIZ; + mBuf = malloc (mBufSiz); + while (mBuf == NULL) { + mBufSiz = (mBufSiz / 10U) * 9U; + if (mBufSiz < 4 * 1024U) { + return EFI_OUT_OF_RESOURCES; + } + + mBuf = malloc (mBufSiz); + } + + mBuf[0] = 0; + + return EFI_SUCCESS; +} + +VOID +FreeMemory ( + VOID + ) +/*++ + +Routine Description: + + Called when compression is completed to free memory previously allocated. + +Arguments: (VOID) + +Returns: (VOID) + +--*/ +{ + if (mText != NULL) { + free (mText); + } + + if (mLevel != NULL) { + free (mLevel); + } + + if (mChildCount != NULL) { + free (mChildCount); + } + + if (mPosition != NULL) { + free (mPosition); + } + + if (mParent != NULL) { + free (mParent); + } + + if (mPrev != NULL) { + free (mPrev); + } + + if (mNext != NULL) { + free (mNext); + } + + if (mBuf != NULL) { + free (mBuf); + } + + return ; +} + +STATIC +VOID +InitSlide ( + VOID + ) +/*++ + +Routine Description: + + Initialize String Info Log data structures + +Arguments: (VOID) + +Returns: (VOID) + +--*/ +{ + NODE Index; + + for (Index = WNDSIZ; Index <= WNDSIZ + UINT8_MAX; Index++) { + mLevel[Index] = 1; + mPosition[Index] = NIL; /* sentinel */ + } + + for (Index = WNDSIZ; Index < WNDSIZ * 2; Index++) { + mParent[Index] = NIL; + } + + mAvail = 1; + for (Index = 1; Index < WNDSIZ - 1; Index++) { + mNext[Index] = (NODE) (Index + 1); + } + + mNext[WNDSIZ - 1] = NIL; + for (Index = WNDSIZ * 2; Index <= MAX_HASH_VAL; Index++) { + mNext[Index] = NIL; + } +} + +STATIC +NODE +Child ( + IN NODE NodeQ, + IN UINT8 CharC + ) +/*++ + +Routine Description: + + Find child node given the parent node and the edge character + +Arguments: + + NodeQ - the parent node + CharC - the edge character + +Returns: + + The child node (NIL if not found) + +--*/ +{ + NODE NodeR; + + NodeR = mNext[HASH (NodeQ, CharC)]; + // + // sentinel + // + mParent[NIL] = NodeQ; + while (mParent[NodeR] != NodeQ) { + NodeR = mNext[NodeR]; + } + + return NodeR; +} + +STATIC +VOID +MakeChild ( + IN NODE Parent, + IN UINT8 CharC, + IN NODE Child + ) +/*++ + +Routine Description: + + Create a new child for a given parent node. + +Arguments: + + Parent - the parent node + CharC - the edge character + Child - the child node + +Returns: (VOID) + +--*/ +{ + NODE Node1; + NODE Node2; + + Node1 = (NODE) HASH (Parent, CharC); + Node2 = mNext[Node1]; + mNext[Node1] = Child; + mNext[Child] = Node2; + mPrev[Node2] = Child; + mPrev[Child] = Node1; + mParent[Child] = Parent; + mChildCount[Parent]++; +} + +STATIC +VOID +Split ( + NODE Old + ) +/*++ + +Routine Description: + + Split a node. + +Arguments: + + Old - the node to split + +Returns: (VOID) + +--*/ +{ + NODE New; + NODE TempNode; + + New = mAvail; + mAvail = mNext[New]; + mChildCount[New] = 0; + TempNode = mPrev[Old]; + mPrev[New] = TempNode; + mNext[TempNode] = New; + TempNode = mNext[Old]; + mNext[New] = TempNode; + mPrev[TempNode] = New; + mParent[New] = mParent[Old]; + mLevel[New] = (UINT8) mMatchLen; + mPosition[New] = mPos; + MakeChild (New, mText[mMatchPos + mMatchLen], Old); + MakeChild (New, mText[mPos + mMatchLen], mPos); +} + +STATIC +VOID +InsertNode ( + VOID + ) +/*++ + +Routine Description: + + Insert string info for current position into the String Info Log + +Arguments: (VOID) + +Returns: (VOID) + +--*/ +{ + NODE NodeQ; + NODE NodeR; + NODE Index2; + NODE NodeT; + UINT8 CharC; + UINT8 *t1; + UINT8 *t2; + + if (mMatchLen >= 4) { + // + // We have just got a long match, the target tree + // can be located by MatchPos + 1. Travese the tree + // from bottom up to get to a proper starting point. + // The usage of PERC_FLAG ensures proper node deletion + // in DeleteNode() later. + // + mMatchLen--; + NodeR = (NODE) ((mMatchPos + 1) | WNDSIZ); + NodeQ = mParent[NodeR]; + while (NodeQ == NIL) { + NodeR = mNext[NodeR]; + NodeQ = mParent[NodeR]; + } + + while (mLevel[NodeQ] >= mMatchLen) { + NodeR = NodeQ; + NodeQ = mParent[NodeQ]; + } + + NodeT = NodeQ; + while (mPosition[NodeT] < 0) { + mPosition[NodeT] = mPos; + NodeT = mParent[NodeT]; + } + + if (NodeT < WNDSIZ) { + mPosition[NodeT] = (NODE) (mPos | (UINT32) PERC_FLAG); + } + } else { + // + // Locate the target tree + // + NodeQ = (NODE) (mText[mPos] + WNDSIZ); + CharC = mText[mPos + 1]; + NodeR = Child (NodeQ, CharC); + if (NodeR == NIL) { + MakeChild (NodeQ, CharC, mPos); + mMatchLen = 1; + return ; + } + + mMatchLen = 2; + } + // + // Traverse down the tree to find a match. + // Update Position value along the route. + // Node split or creation is involved. + // + for (;;) { + if (NodeR >= WNDSIZ) { + Index2 = MAXMATCH; + mMatchPos = NodeR; + } else { + Index2 = mLevel[NodeR]; + mMatchPos = (NODE) (mPosition[NodeR] & (UINT32)~PERC_FLAG); + } + + if (mMatchPos >= mPos) { + mMatchPos -= WNDSIZ; + } + + t1 = &mText[mPos + mMatchLen]; + t2 = &mText[mMatchPos + mMatchLen]; + while (mMatchLen < Index2) { + if (*t1 != *t2) { + Split (NodeR); + return ; + } + + mMatchLen++; + t1++; + t2++; + } + + if (mMatchLen >= MAXMATCH) { + break; + } + + mPosition[NodeR] = mPos; + NodeQ = NodeR; + NodeR = Child (NodeQ, *t1); + if (NodeR == NIL) { + MakeChild (NodeQ, *t1, mPos); + return ; + } + + mMatchLen++; + } + + NodeT = mPrev[NodeR]; + mPrev[mPos] = NodeT; + mNext[NodeT] = mPos; + NodeT = mNext[NodeR]; + mNext[mPos] = NodeT; + mPrev[NodeT] = mPos; + mParent[mPos] = NodeQ; + mParent[NodeR] = NIL; + + // + // Special usage of 'next' + // + mNext[NodeR] = mPos; + +} + +STATIC +VOID +DeleteNode ( + VOID + ) +/*++ + +Routine Description: + + Delete outdated string info. (The Usage of PERC_FLAG + ensures a clean deletion) + +Arguments: (VOID) + +Returns: (VOID) + +--*/ +{ + NODE NodeQ; + NODE NodeR; + NODE NodeS; + NODE NodeT; + NODE NodeU; + + if (mParent[mPos] == NIL) { + return ; + } + + NodeR = mPrev[mPos]; + NodeS = mNext[mPos]; + mNext[NodeR] = NodeS; + mPrev[NodeS] = NodeR; + NodeR = mParent[mPos]; + mParent[mPos] = NIL; + if (NodeR >= WNDSIZ) { + return ; + } + + mChildCount[NodeR]--; + if (mChildCount[NodeR] > 1) { + return ; + } + + NodeT = (NODE) (mPosition[NodeR] & (UINT32)~PERC_FLAG); + if (NodeT >= mPos) { + NodeT -= WNDSIZ; + } + + NodeS = NodeT; + NodeQ = mParent[NodeR]; + NodeU = mPosition[NodeQ]; + while (NodeU & (UINT32) PERC_FLAG) { + NodeU &= (UINT32)~PERC_FLAG; + if (NodeU >= mPos) { + NodeU -= WNDSIZ; + } + + if (NodeU > NodeS) { + NodeS = NodeU; + } + + mPosition[NodeQ] = (NODE) (NodeS | WNDSIZ); + NodeQ = mParent[NodeQ]; + NodeU = mPosition[NodeQ]; + } + + if (NodeQ < WNDSIZ) { + if (NodeU >= mPos) { + NodeU -= WNDSIZ; + } + + if (NodeU > NodeS) { + NodeS = NodeU; + } + + mPosition[NodeQ] = (NODE) (NodeS | WNDSIZ | (UINT32) PERC_FLAG); + } + + NodeS = Child (NodeR, mText[NodeT + mLevel[NodeR]]); + NodeT = mPrev[NodeS]; + NodeU = mNext[NodeS]; + mNext[NodeT] = NodeU; + mPrev[NodeU] = NodeT; + NodeT = mPrev[NodeR]; + mNext[NodeT] = NodeS; + mPrev[NodeS] = NodeT; + NodeT = mNext[NodeR]; + mPrev[NodeT] = NodeS; + mNext[NodeS] = NodeT; + mParent[NodeS] = mParent[NodeR]; + mParent[NodeR] = NIL; + mNext[NodeR] = mAvail; + mAvail = NodeR; +} + +STATIC +VOID +GetNextMatch ( + VOID + ) +/*++ + +Routine Description: + + Advance the current position (read in new data if needed). + Delete outdated string info. Find a match string for current position. + +Arguments: (VOID) + +Returns: (VOID) + +--*/ +{ + INT32 Number; + + mRemainder--; + mPos++; + if (mPos == WNDSIZ * 2) { + memmove (&mText[0], &mText[WNDSIZ], WNDSIZ + MAXMATCH); + Number = FreadCrc (&mText[WNDSIZ + MAXMATCH], WNDSIZ); + mRemainder += Number; + mPos = WNDSIZ; + } + + DeleteNode (); + InsertNode (); +} + +STATIC +EFI_STATUS +Encode ( + VOID + ) +/*++ + +Routine Description: + + The main controlling routine for compression process. + +Arguments: (VOID) + +Returns: + + EFI_SUCCESS - The compression is successful + EFI_OUT_0F_RESOURCES - Not enough memory for compression process + +--*/ +{ + EFI_STATUS Status; + INT32 LastMatchLen; + NODE LastMatchPos; + + Status = AllocateMemory (); + if (EFI_ERROR (Status)) { + FreeMemory (); + return Status; + } + + InitSlide (); + + HufEncodeStart (); + + mRemainder = FreadCrc (&mText[WNDSIZ], WNDSIZ + MAXMATCH); + + mMatchLen = 0; + mPos = WNDSIZ; + InsertNode (); + if (mMatchLen > mRemainder) { + mMatchLen = mRemainder; + } + + while (mRemainder > 0) { + LastMatchLen = mMatchLen; + LastMatchPos = mMatchPos; + GetNextMatch (); + if (mMatchLen > mRemainder) { + mMatchLen = mRemainder; + } + + if (mMatchLen > LastMatchLen || LastMatchLen < THRESHOLD) { + // + // Not enough benefits are gained by outputting a pointer, + // so just output the original character + // + Output (mText[mPos - 1], 0); + + } else { + + if (LastMatchLen == THRESHOLD) { + if (((mPos - LastMatchPos - 2) & (WNDSIZ - 1)) > (1U << 11)) { + Output (mText[mPos - 1], 0); + continue; + } + } + // + // Outputting a pointer is beneficial enough, do it. + // + Output ( + LastMatchLen + (UINT8_MAX + 1 - THRESHOLD), + (mPos - LastMatchPos - 2) & (WNDSIZ - 1) + ); + LastMatchLen--; + while (LastMatchLen > 0) { + GetNextMatch (); + LastMatchLen--; + } + + if (mMatchLen > mRemainder) { + mMatchLen = mRemainder; + } + } + } + + HufEncodeEnd (); + FreeMemory (); + return EFI_SUCCESS; +} + +STATIC +VOID +CountTFreq ( + VOID + ) +/*++ + +Routine Description: + + Count the frequencies for the Extra Set + +Arguments: (VOID) + +Returns: (VOID) + +--*/ +{ + INT32 Index; + INT32 Index3; + INT32 Number; + INT32 Count; + + for (Index = 0; Index < NT; Index++) { + mTFreq[Index] = 0; + } + + Number = NC; + while (Number > 0 && mCLen[Number - 1] == 0) { + Number--; + } + + Index = 0; + while (Index < Number) { + Index3 = mCLen[Index++]; + if (Index3 == 0) { + Count = 1; + while (Index < Number && mCLen[Index] == 0) { + Index++; + Count++; + } + + if (Count <= 2) { + mTFreq[0] = (UINT16) (mTFreq[0] + Count); + } else if (Count <= 18) { + mTFreq[1]++; + } else if (Count == 19) { + mTFreq[0]++; + mTFreq[1]++; + } else { + mTFreq[2]++; + } + } else { + mTFreq[Index3 + 2]++; + } + } +} + +STATIC +VOID +WritePTLen ( + IN INT32 Number, + IN INT32 nbit, + IN INT32 Special + ) +/*++ + +Routine Description: + + Outputs the code length array for the Extra Set or the Position Set. + +Arguments: + + Number - the number of symbols + nbit - the number of bits needed to represent 'n' + Special - the special symbol that needs to be take care of + +Returns: (VOID) + +--*/ +{ + INT32 Index; + INT32 Index3; + + while (Number > 0 && mPTLen[Number - 1] == 0) { + Number--; + } + + PutBits (nbit, Number); + Index = 0; + while (Index < Number) { + Index3 = mPTLen[Index++]; + if (Index3 <= 6) { + PutBits (3, Index3); + } else { + PutBits (Index3 - 3, (1U << (Index3 - 3)) - 2); + } + + if (Index == Special) { + while (Index < 6 && mPTLen[Index] == 0) { + Index++; + } + + PutBits (2, (Index - 3) & 3); + } + } +} + +STATIC +VOID +WriteCLen ( + VOID + ) +/*++ + +Routine Description: + + Outputs the code length array for Char&Length Set + +Arguments: (VOID) + +Returns: (VOID) + +--*/ +{ + INT32 Index; + INT32 Index3; + INT32 Number; + INT32 Count; + + Number = NC; + while (Number > 0 && mCLen[Number - 1] == 0) { + Number--; + } + + PutBits (CBIT, Number); + Index = 0; + while (Index < Number) { + Index3 = mCLen[Index++]; + if (Index3 == 0) { + Count = 1; + while (Index < Number && mCLen[Index] == 0) { + Index++; + Count++; + } + + if (Count <= 2) { + for (Index3 = 0; Index3 < Count; Index3++) { + PutBits (mPTLen[0], mPTCode[0]); + } + } else if (Count <= 18) { + PutBits (mPTLen[1], mPTCode[1]); + PutBits (4, Count - 3); + } else if (Count == 19) { + PutBits (mPTLen[0], mPTCode[0]); + PutBits (mPTLen[1], mPTCode[1]); + PutBits (4, 15); + } else { + PutBits (mPTLen[2], mPTCode[2]); + PutBits (CBIT, Count - 20); + } + } else { + PutBits (mPTLen[Index3 + 2], mPTCode[Index3 + 2]); + } + } +} + +STATIC +VOID +EncodeC ( + IN INT32 Value + ) +{ + PutBits (mCLen[Value], mCCode[Value]); +} + +STATIC +VOID +EncodeP ( + IN UINT32 Value + ) +{ + UINT32 Index; + UINT32 NodeQ; + + Index = 0; + NodeQ = Value; + while (NodeQ) { + NodeQ >>= 1; + Index++; + } + + PutBits (mPTLen[Index], mPTCode[Index]); + if (Index > 1) { + PutBits (Index - 1, Value & (0xFFFFFFFFU >> (32 - Index + 1))); + } +} + +STATIC +VOID +SendBlock ( + VOID + ) +/*++ + +Routine Description: + + Huffman code the block and output it. + +Arguments: + (VOID) + +Returns: + (VOID) + +--*/ +{ + UINT32 Index; + UINT32 Index2; + UINT32 Index3; + UINT32 Flags; + UINT32 Root; + UINT32 Pos; + UINT32 Size; + Flags = 0; + + Root = MakeTree (NC, mCFreq, mCLen, mCCode); + Size = mCFreq[Root]; + PutBits (16, Size); + if (Root >= NC) { + CountTFreq (); + Root = MakeTree (NT, mTFreq, mPTLen, mPTCode); + if (Root >= NT) { + WritePTLen (NT, TBIT, 3); + } else { + PutBits (TBIT, 0); + PutBits (TBIT, Root); + } + + WriteCLen (); + } else { + PutBits (TBIT, 0); + PutBits (TBIT, 0); + PutBits (CBIT, 0); + PutBits (CBIT, Root); + } + + Root = MakeTree (NP, mPFreq, mPTLen, mPTCode); + if (Root >= NP) { + WritePTLen (NP, PBIT, -1); + } else { + PutBits (PBIT, 0); + PutBits (PBIT, Root); + } + + Pos = 0; + for (Index = 0; Index < Size; Index++) { + if (Index % UINT8_BIT == 0) { + Flags = mBuf[Pos++]; + } else { + Flags <<= 1; + } + + if (Flags & (1U << (UINT8_BIT - 1))) { + EncodeC (mBuf[Pos++] + (1U << UINT8_BIT)); + Index3 = mBuf[Pos++]; + for (Index2 = 0; Index2 < 3; Index2++) { + Index3 <<= UINT8_BIT; + Index3 += mBuf[Pos++]; + } + + EncodeP (Index3); + } else { + EncodeC (mBuf[Pos++]); + } + } + + for (Index = 0; Index < NC; Index++) { + mCFreq[Index] = 0; + } + + for (Index = 0; Index < NP; Index++) { + mPFreq[Index] = 0; + } +} + +STATIC +VOID +Output ( + IN UINT32 CharC, + IN UINT32 Pos + ) +/*++ + +Routine Description: + + Outputs an Original Character or a Pointer + +Arguments: + + CharC - The original character or the 'String Length' element of a Pointer + Pos - The 'Position' field of a Pointer + +Returns: (VOID) + +--*/ +{ + static UINT32 CPos; + + if ((mOutputMask >>= 1) == 0) { + mOutputMask = 1U << (UINT8_BIT - 1); + // + // Check the buffer overflow per outputing UINT8_BIT symbols + // which is an Original Character or a Pointer. The biggest + // symbol is a Pointer which occupies 5 bytes. + // + if (mOutputPos >= mBufSiz - 5 * UINT8_BIT) { + SendBlock (); + mOutputPos = 0; + } + + CPos = mOutputPos++; + mBuf[CPos] = 0; + } + + mBuf[mOutputPos++] = (UINT8) CharC; + mCFreq[CharC]++; + if (CharC >= (1U << UINT8_BIT)) { + mBuf[CPos] |= mOutputMask; + mBuf[mOutputPos++] = (UINT8) (Pos >> 24); + mBuf[mOutputPos++] = (UINT8) (Pos >> 16); + mBuf[mOutputPos++] = (UINT8) (Pos >> (UINT8_BIT)); + mBuf[mOutputPos++] = (UINT8) Pos; + CharC = 0; + while (Pos) { + Pos >>= 1; + CharC++; + } + + mPFreq[CharC]++; + } +} + +STATIC +VOID +HufEncodeStart ( + VOID + ) +{ + INT32 Index; + + for (Index = 0; Index < NC; Index++) { + mCFreq[Index] = 0; + } + + for (Index = 0; Index < NP; Index++) { + mPFreq[Index] = 0; + } + + mOutputPos = mOutputMask = 0; + InitPutBits (); + return ; +} + +STATIC +VOID +HufEncodeEnd ( + VOID + ) +{ + SendBlock (); + + // + // Flush remaining bits + // + PutBits (UINT8_BIT - 1, 0); + + return ; +} + +STATIC +VOID +MakeCrcTable ( + VOID + ) +{ + UINT32 Index; + UINT32 Index2; + UINT32 Temp; + + for (Index = 0; Index <= UINT8_MAX; Index++) { + Temp = Index; + for (Index2 = 0; Index2 < UINT8_BIT; Index2++) { + if (Temp & 1) { + Temp = (Temp >> 1) ^ CRCPOLY; + } else { + Temp >>= 1; + } + } + + mCrcTable[Index] = (UINT16) Temp; + } +} + +STATIC +VOID +PutBits ( + IN INT32 Number, + IN UINT32 Value + ) +/*++ + +Routine Description: + + Outputs rightmost n bits of x + +Arguments: + + Number - the rightmost n bits of the data is used + x - the data + +Returns: (VOID) + +--*/ +{ + UINT8 Temp; + + while (Number >= mBitCount) { + // + // Number -= mBitCount should never equal to 32 + // + Temp = (UINT8) (mSubBitBuf | (Value >> (Number -= mBitCount))); + if (mDst < mDstUpperLimit) { + *mDst++ = Temp; + } + + mCompSize++; + mSubBitBuf = 0; + mBitCount = UINT8_BIT; + } + + mSubBitBuf |= Value << (mBitCount -= Number); +} + +STATIC +INT32 +FreadCrc ( + OUT UINT8 *Pointer, + IN INT32 Number + ) +/*++ + +Routine Description: + + Read in source data + +Arguments: + + Pointer - the buffer to hold the data + Number - number of bytes to read + +Returns: + + number of bytes actually read + +--*/ +{ + INT32 Index; + + for (Index = 0; mSrc < mSrcUpperLimit && Index < Number; Index++) { + *Pointer++ = *mSrc++; + } + + Number = Index; + + Pointer -= Number; + mOrigSize += Number; + Index--; + while (Index >= 0) { + UPDATE_CRC (*Pointer++); + Index--; + } + + return Number; +} + +STATIC +VOID +InitPutBits ( + VOID + ) +{ + mBitCount = UINT8_BIT; + mSubBitBuf = 0; +} + +STATIC +VOID +CountLen ( + IN INT32 Index + ) +/*++ + +Routine Description: + + Count the number of each code length for a Huffman tree. + +Arguments: + + Index - the top node + +Returns: (VOID) + +--*/ +{ + static INT32 Depth = 0; + + if (Index < mN) { + mLenCnt[(Depth < 16) ? Depth : 16]++; + } else { + Depth++; + CountLen (mLeft[Index]); + CountLen (mRight[Index]); + Depth--; + } +} + +STATIC +VOID +MakeLen ( + IN INT32 Root + ) +/*++ + +Routine Description: + + Create code length array for a Huffman tree + +Arguments: + + Root - the root of the tree + +Returns: + + VOID + +--*/ +{ + INT32 Index; + INT32 Index3; + UINT32 Cum; + + for (Index = 0; Index <= 16; Index++) { + mLenCnt[Index] = 0; + } + + CountLen (Root); + + // + // Adjust the length count array so that + // no code will be generated longer than its designated length + // + Cum = 0; + for (Index = 16; Index > 0; Index--) { + Cum += mLenCnt[Index] << (16 - Index); + } + + while (Cum != (1U << 16)) { + mLenCnt[16]--; + for (Index = 15; Index > 0; Index--) { + if (mLenCnt[Index] != 0) { + mLenCnt[Index]--; + mLenCnt[Index + 1] += 2; + break; + } + } + + Cum--; + } + + for (Index = 16; Index > 0; Index--) { + Index3 = mLenCnt[Index]; + Index3--; + while (Index3 >= 0) { + mLen[*mSortPtr++] = (UINT8) Index; + Index3--; + } + } +} + +STATIC +VOID +DownHeap ( + IN INT32 Index + ) +{ + INT32 Index2; + INT32 Index3; + + // + // priority queue: send Index-th entry down heap + // + Index3 = mHeap[Index]; + Index2 = 2 * Index; + while (Index2 <= mHeapSize) { + if (Index2 < mHeapSize && mFreq[mHeap[Index2]] > mFreq[mHeap[Index2 + 1]]) { + Index2++; + } + + if (mFreq[Index3] <= mFreq[mHeap[Index2]]) { + break; + } + + mHeap[Index] = mHeap[Index2]; + Index = Index2; + Index2 = 2 * Index; + } + + mHeap[Index] = (INT16) Index3; +} + +STATIC +VOID +MakeCode ( + IN INT32 Number, + IN UINT8 Len[ ], + OUT UINT16 Code[] + ) +/*++ + +Routine Description: + + Assign code to each symbol based on the code length array + +Arguments: + + Number - number of symbols + Len - the code length array + Code - stores codes for each symbol + +Returns: (VOID) + +--*/ +{ + INT32 Index; + UINT16 Start[18]; + + Start[1] = 0; + for (Index = 1; Index <= 16; Index++) { + Start[Index + 1] = (UINT16) ((Start[Index] + mLenCnt[Index]) << 1); + } + + for (Index = 0; Index < Number; Index++) { + Code[Index] = Start[Len[Index]]++; + } +} + +STATIC +INT32 +MakeTree ( + IN INT32 NParm, + IN UINT16 FreqParm[], + OUT UINT8 LenParm[ ], + OUT UINT16 CodeParm[] + ) +/*++ + +Routine Description: + + Generates Huffman codes given a frequency distribution of symbols + +Arguments: + + NParm - number of symbols + FreqParm - frequency of each symbol + LenParm - code length for each symbol + CodeParm - code for each symbol + +Returns: + + Root of the Huffman tree. + +--*/ +{ + INT32 Index; + INT32 Index2; + INT32 Index3; + INT32 Avail; + + // + // make tree, calculate len[], return root + // + mN = NParm; + mFreq = FreqParm; + mLen = LenParm; + Avail = mN; + mHeapSize = 0; + mHeap[1] = 0; + for (Index = 0; Index < mN; Index++) { + mLen[Index] = 0; + if (mFreq[Index]) { + mHeapSize++; + mHeap[mHeapSize] = (INT16) Index; + } + } + + if (mHeapSize < 2) { + CodeParm[mHeap[1]] = 0; + return mHeap[1]; + } + + for (Index = mHeapSize / 2; Index >= 1; Index--) { + // + // make priority queue + // + DownHeap (Index); + } + + mSortPtr = CodeParm; + do { + Index = mHeap[1]; + if (Index < mN) { + *mSortPtr++ = (UINT16) Index; + } + + mHeap[1] = mHeap[mHeapSize--]; + DownHeap (1); + Index2 = mHeap[1]; + if (Index2 < mN) { + *mSortPtr++ = (UINT16) Index2; + } + + Index3 = Avail++; + mFreq[Index3] = (UINT16) (mFreq[Index] + mFreq[Index2]); + mHeap[1] = (INT16) Index3; + DownHeap (1); + mLeft[Index3] = (UINT16) Index; + mRight[Index3] = (UINT16) Index2; + } while (mHeapSize > 1); + + mSortPtr = CodeParm; + MakeLen (Index3); + MakeCode (NParm, LenParm, CodeParm); + + // + // return root + // + return Index3; +} diff --git a/Tools/CodeTools/Source/Common/EfiCompress.h b/Tools/CodeTools/Source/Common/EfiCompress.h new file mode 100644 index 0000000000..6ad80e4742 --- /dev/null +++ b/Tools/CodeTools/Source/Common/EfiCompress.h @@ -0,0 +1,69 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + EfiCompress.h + +Abstract: + + Header file for compression routine + +--*/ + +#ifndef _EFICOMPRESS_H +#define _EFICOMPRESS_H + +#include +#include + +#include + +EFI_STATUS +Compress ( + IN UINT8 *SrcBuffer, + IN UINT32 SrcSize, + IN UINT8 *DstBuffer, + IN OUT UINT32 *DstSize + ) +; + +/*++ + +Routine Description: + + The compression routine. + +Arguments: + + SrcBuffer - The buffer storing the source data + SrcSize - The size of source data + DstBuffer - The buffer to store the compressed data + DstSize - On input, the size of DstBuffer; On output, + the size of the actual compressed data. + +Returns: + + EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. In this case, + DstSize contains the size needed. + EFI_SUCCESS - Compression is successful. + +--*/ +typedef +EFI_STATUS +(*COMPRESS_FUNCTION) ( + IN UINT8 *SrcBuffer, + IN UINT32 SrcSize, + IN UINT8 *DstBuffer, + IN OUT UINT32 *DstSize + ); + +#endif diff --git a/Tools/CodeTools/Source/Common/EfiCustomizedCompress.h b/Tools/CodeTools/Source/Common/EfiCustomizedCompress.h new file mode 100644 index 0000000000..af26b6f12a --- /dev/null +++ b/Tools/CodeTools/Source/Common/EfiCustomizedCompress.h @@ -0,0 +1,141 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + EfiCustomizedCompress.h + +Abstract: + + Header file for Customized compression routine + +--*/ + +#ifndef _EFICUSTOMIZEDCOMPRESS_H +#define _EFICUSTOMIZEDCOMPRESS_H + +#include + +EFI_STATUS +SetCustomizedCompressionType ( + IN CHAR8 *Type + ) +; + +/*++ + +Routine Description: + +The implementation of Customized SetCompressionType(). + +Arguments: + Type - The type if compression. + +Returns: + + EFI_SUCCESS - The type has been set. + EFI_UNSUPPORTED - This type is unsupported. + + +--*/ +EFI_STATUS +CustomizedGetInfo ( + IN VOID *Source, + IN UINT32 SrcSize, + OUT UINT32 *DstSize, + OUT UINT32 *ScratchSize + ) +; + +/*++ + +Routine Description: + + The implementation of Customized GetInfo(). + +Arguments: + + Source - The source buffer containing the compressed data. + SrcSize - The size of source buffer + DstSize - The size of destination buffer. + ScratchSize - The size of scratch buffer. + +Returns: + + EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved. + EFI_INVALID_PARAMETER - The source data is corrupted + +--*/ +EFI_STATUS +CustomizedDecompress ( + IN VOID *Source, + IN UINT32 SrcSize, + IN OUT VOID *Destination, + IN UINT32 DstSize, + IN OUT VOID *Scratch, + IN UINT32 ScratchSize + ) +; + +/*++ + +Routine Description: + + The implementation of Customized Decompress(). + +Arguments: + + This - The protocol instance pointer + Source - The source buffer containing the compressed data. + SrcSize - The size of source buffer + Destination - The destination buffer to store the decompressed data + DstSize - The size of destination buffer. + Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data. + ScratchSize - The size of scratch buffer. + +Returns: + + EFI_SUCCESS - Decompression is successfull + EFI_INVALID_PARAMETER - The source data is corrupted + +--*/ +EFI_STATUS +CustomizedCompress ( + IN UINT8 *SrcBuffer, + IN UINT32 SrcSize, + IN UINT8 *DstBuffer, + IN OUT UINT32 *DstSize + ) +; + +/*++ + +Routine Description: + + The Customized compression routine. + +Arguments: + + SrcBuffer - The buffer storing the source data + SrcSize - The size of source data + DstBuffer - The buffer to store the compressed data + DstSize - On input, the size of DstBuffer; On output, + the size of the actual compressed data. + +Returns: + + EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. In this case, + DstSize contains the size needed. + EFI_SUCCESS - Compression is successful. + +--*/ + +#endif diff --git a/Tools/CodeTools/Source/Common/EfiDecompress.c b/Tools/CodeTools/Source/Common/EfiDecompress.c new file mode 100644 index 0000000000..288c42579e --- /dev/null +++ b/Tools/CodeTools/Source/Common/EfiDecompress.c @@ -0,0 +1,790 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + EfiDecompress.c + +Abstract: + + Decompressor. Algorithm Ported from OPSD code (Decomp.asm) + +--*/ + +#include "EfiDecompress.h" + +// +// Decompression algorithm begins here +// +#define BITBUFSIZ 32 +#define MAXMATCH 256 +#define THRESHOLD 3 +#define CODE_BIT 16 +#define BAD_TABLE - 1 + +// +// C: Char&Len Set; P: Position Set; T: exTra Set +// +#define NC (0xff + MAXMATCH + 2 - THRESHOLD) +#define CBIT 9 +#define PBIT 5 +#define TBIT 5 +#define MAXNP ((1U << PBIT) - 1) +#define NT (CODE_BIT + 3) +#if NT > MAXNP +#define NPT NT +#else +#define NPT MAXNP +#endif + +typedef struct { + UINT8 *mSrcBase; // Starting address of compressed data + UINT8 *mDstBase; // Starting address of decompressed data + UINT32 mOutBuf; + UINT32 mInBuf; + + UINT16 mBitCount; + UINT32 mBitBuf; + UINT32 mSubBitBuf; + UINT16 mBlockSize; + UINT32 mCompSize; + UINT32 mOrigSize; + + UINT16 mBadTableFlag; + + UINT16 mLeft[2 * NC - 1]; + UINT16 mRight[2 * NC - 1]; + UINT8 mCLen[NC]; + UINT8 mPTLen[NPT]; + UINT16 mCTable[4096]; + UINT16 mPTTable[256]; +} SCRATCH_DATA; + +STATIC +VOID +FillBuf ( + IN SCRATCH_DATA *Sd, + IN UINT16 NumOfBits + ) +/*++ + +Routine Description: + + Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source. + +Arguments: + + Sd - The global scratch data + NumOfBit - The number of bits to shift and read. + +Returns: (VOID) + +--*/ +{ + Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits); + + while (NumOfBits > Sd->mBitCount) { + + Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount))); + + if (Sd->mCompSize > 0) { + // + // Get 1 byte into SubBitBuf + // + Sd->mCompSize--; + Sd->mSubBitBuf = 0; + Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++]; + Sd->mBitCount = 8; + + } else { + // + // No more bits from the source, just pad zero bit. + // + Sd->mSubBitBuf = 0; + Sd->mBitCount = 8; + + } + } + + Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits); + Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount; +} + +STATIC +UINT32 +GetBits ( + IN SCRATCH_DATA *Sd, + IN UINT16 NumOfBits + ) +/*++ + +Routine Description: + + Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent + NumOfBits of bits from source. Returns NumOfBits of bits that are + popped out. + +Arguments: + + Sd - The global scratch data. + NumOfBits - The number of bits to pop and read. + +Returns: + + The bits that are popped out. + +--*/ +{ + UINT32 OutBits; + + OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits)); + + FillBuf (Sd, NumOfBits); + + return OutBits; +} + +STATIC +UINT16 +MakeTable ( + IN SCRATCH_DATA *Sd, + IN UINT16 NumOfChar, + IN UINT8 *BitLen, + IN UINT16 TableBits, + OUT UINT16 *Table + ) +/*++ + +Routine Description: + + Creates Huffman Code mapping table according to code length array. + +Arguments: + + Sd - The global scratch data + NumOfChar - Number of symbols in the symbol set + BitLen - Code length array + TableBits - The width of the mapping table + Table - The table + +Returns: + + 0 - OK. + BAD_TABLE - The table is corrupted. + +--*/ +{ + UINT16 Count[17]; + UINT16 Weight[17]; + UINT16 Start[18]; + UINT16 *Pointer; + UINT16 Index3; + UINT16 Index; + UINT16 Len; + UINT16 Char; + UINT16 JuBits; + UINT16 Avail; + UINT16 NextCode; + UINT16 Mask; + + for (Index = 1; Index <= 16; Index++) { + Count[Index] = 0; + } + + for (Index = 0; Index < NumOfChar; Index++) { + Count[BitLen[Index]]++; + } + + Start[1] = 0; + + for (Index = 1; Index <= 16; Index++) { + Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index))); + } + + if (Start[17] != 0) { + /*(1U << 16)*/ + return (UINT16) BAD_TABLE; + } + + JuBits = (UINT16) (16 - TableBits); + + for (Index = 1; Index <= TableBits; Index++) { + Start[Index] >>= JuBits; + Weight[Index] = (UINT16) (1U << (TableBits - Index)); + } + + while (Index <= 16) { + Weight[Index++] = (UINT16) (1U << (16 - Index)); + } + + Index = (UINT16) (Start[TableBits + 1] >> JuBits); + + if (Index != 0) { + Index3 = (UINT16) (1U << TableBits); + while (Index != Index3) { + Table[Index++] = 0; + } + } + + Avail = NumOfChar; + Mask = (UINT16) (1U << (15 - TableBits)); + + for (Char = 0; Char < NumOfChar; Char++) { + + Len = BitLen[Char]; + if (Len == 0) { + continue; + } + + NextCode = (UINT16) (Start[Len] + Weight[Len]); + + if (Len <= TableBits) { + + for (Index = Start[Len]; Index < NextCode; Index++) { + Table[Index] = Char; + } + + } else { + + Index3 = Start[Len]; + Pointer = &Table[Index3 >> JuBits]; + Index = (UINT16) (Len - TableBits); + + while (Index != 0) { + if (*Pointer == 0) { + Sd->mRight[Avail] = Sd->mLeft[Avail] = 0; + *Pointer = Avail++; + } + + if (Index3 & Mask) { + Pointer = &Sd->mRight[*Pointer]; + } else { + Pointer = &Sd->mLeft[*Pointer]; + } + + Index3 <<= 1; + Index--; + } + + *Pointer = Char; + + } + + Start[Len] = NextCode; + } + // + // Succeeds + // + return 0; +} + +STATIC +UINT32 +DecodeP ( + IN SCRATCH_DATA *Sd + ) +/*++ + +Routine Description: + + Decodes a position value. + +Arguments: + + Sd - the global scratch data + +Returns: + + The position value decoded. + +--*/ +{ + UINT16 Val; + UINT32 Mask; + UINT32 Pos; + + Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)]; + + if (Val >= MAXNP) { + Mask = 1U << (BITBUFSIZ - 1 - 8); + + do { + + if (Sd->mBitBuf & Mask) { + Val = Sd->mRight[Val]; + } else { + Val = Sd->mLeft[Val]; + } + + Mask >>= 1; + } while (Val >= MAXNP); + } + // + // Advance what we have read + // + FillBuf (Sd, Sd->mPTLen[Val]); + + Pos = Val; + if (Val > 1) { + Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1))); + } + + return Pos; +} + +STATIC +UINT16 +ReadPTLen ( + IN SCRATCH_DATA *Sd, + IN UINT16 nn, + IN UINT16 nbit, + IN UINT16 Special + ) +/*++ + +Routine Description: + + Reads code lengths for the Extra Set or the Position Set + +Arguments: + + Sd - The global scratch data + nn - Number of symbols + nbit - Number of bits needed to represent nn + Special - The special symbol that needs to be taken care of + +Returns: + + 0 - OK. + BAD_TABLE - Table is corrupted. + +--*/ +{ + UINT16 Number; + UINT16 CharC; + UINT16 Index; + UINT32 Mask; + + Number = (UINT16) GetBits (Sd, nbit); + + if (Number == 0) { + CharC = (UINT16) GetBits (Sd, nbit); + + for (Index = 0; Index < 256; Index++) { + Sd->mPTTable[Index] = CharC; + } + + for (Index = 0; Index < nn; Index++) { + Sd->mPTLen[Index] = 0; + } + + return 0; + } + + Index = 0; + + while (Index < Number) { + + CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3)); + + if (CharC == 7) { + Mask = 1U << (BITBUFSIZ - 1 - 3); + while (Mask & Sd->mBitBuf) { + Mask >>= 1; + CharC += 1; + } + } + + FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3)); + + Sd->mPTLen[Index++] = (UINT8) CharC; + + if (Index == Special) { + CharC = (UINT16) GetBits (Sd, 2); + CharC--; + while ((INT16) (CharC) >= 0) { + Sd->mPTLen[Index++] = 0; + CharC--; + } + } + } + + while (Index < nn) { + Sd->mPTLen[Index++] = 0; + } + + return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable); +} + +STATIC +VOID +ReadCLen ( + SCRATCH_DATA *Sd + ) +/*++ + +Routine Description: + + Reads code lengths for Char&Len Set. + +Arguments: + + Sd - the global scratch data + +Returns: (VOID) + +--*/ +{ + UINT16 Number; + UINT16 CharC; + UINT16 Index; + UINT32 Mask; + + Number = (UINT16) GetBits (Sd, CBIT); + + if (Number == 0) { + CharC = (UINT16) GetBits (Sd, CBIT); + + for (Index = 0; Index < NC; Index++) { + Sd->mCLen[Index] = 0; + } + + for (Index = 0; Index < 4096; Index++) { + Sd->mCTable[Index] = CharC; + } + + return ; + } + + Index = 0; + while (Index < Number) { + + CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)]; + if (CharC >= NT) { + Mask = 1U << (BITBUFSIZ - 1 - 8); + + do { + + if (Mask & Sd->mBitBuf) { + CharC = Sd->mRight[CharC]; + } else { + CharC = Sd->mLeft[CharC]; + } + + Mask >>= 1; + + } while (CharC >= NT); + } + // + // Advance what we have read + // + FillBuf (Sd, Sd->mPTLen[CharC]); + + if (CharC <= 2) { + + if (CharC == 0) { + CharC = 1; + } else if (CharC == 1) { + CharC = (UINT16) (GetBits (Sd, 4) + 3); + } else if (CharC == 2) { + CharC = (UINT16) (GetBits (Sd, CBIT) + 20); + } + + CharC--; + while ((INT16) (CharC) >= 0) { + Sd->mCLen[Index++] = 0; + CharC--; + } + + } else { + + Sd->mCLen[Index++] = (UINT8) (CharC - 2); + + } + } + + while (Index < NC) { + Sd->mCLen[Index++] = 0; + } + + MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable); + + return ; +} + +STATIC +UINT16 +DecodeC ( + SCRATCH_DATA *Sd + ) +/*++ + +Routine Description: + + Decode a character/length value. + +Arguments: + + Sd - The global scratch data. + +Returns: + + The value decoded. + +--*/ +{ + UINT16 Index2; + UINT32 Mask; + + if (Sd->mBlockSize == 0) { + // + // Starting a new block + // + Sd->mBlockSize = (UINT16) GetBits (Sd, 16); + Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3); + if (Sd->mBadTableFlag != 0) { + return 0; + } + + ReadCLen (Sd); + + Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, PBIT, (UINT16) (-1)); + if (Sd->mBadTableFlag != 0) { + return 0; + } + } + + Sd->mBlockSize--; + Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)]; + + if (Index2 >= NC) { + Mask = 1U << (BITBUFSIZ - 1 - 12); + + do { + if (Sd->mBitBuf & Mask) { + Index2 = Sd->mRight[Index2]; + } else { + Index2 = Sd->mLeft[Index2]; + } + + Mask >>= 1; + } while (Index2 >= NC); + } + // + // Advance what we have read + // + FillBuf (Sd, Sd->mCLen[Index2]); + + return Index2; +} + +STATIC +VOID +Decode ( + SCRATCH_DATA *Sd + ) +/*++ + +Routine Description: + + Decode the source data and put the resulting data into the destination buffer. + +Arguments: + + Sd - The global scratch data + +Returns: (VOID) + + --*/ +{ + UINT16 BytesRemain; + UINT32 DataIdx; + UINT16 CharC; + + BytesRemain = (UINT16) (-1); + + DataIdx = 0; + + for (;;) { + CharC = DecodeC (Sd); + if (Sd->mBadTableFlag != 0) { + return ; + } + + if (CharC < 256) { + // + // Process an Original character + // + Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC; + if (Sd->mOutBuf >= Sd->mOrigSize) { + return ; + } + + } else { + // + // Process a Pointer + // + CharC = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD)); + + BytesRemain = CharC; + + DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1; + + BytesRemain--; + while ((INT16) (BytesRemain) >= 0) { + Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++]; + if (Sd->mOutBuf >= Sd->mOrigSize) { + return ; + } + + BytesRemain--; + } + } + } + + return ; +} + +EFI_STATUS +GetInfo ( + IN VOID *Source, + IN UINT32 SrcSize, + OUT UINT32 *DstSize, + OUT UINT32 *ScratchSize + ) +/*++ + +Routine Description: + + The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo(). + +Arguments: + + Source - The source buffer containing the compressed data. + SrcSize - The size of source buffer + DstSize - The size of destination buffer. + ScratchSize - The size of scratch buffer. + +Returns: + + EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved. + EFI_INVALID_PARAMETER - The source data is corrupted + +--*/ +{ + UINT8 *Src; + + *ScratchSize = sizeof (SCRATCH_DATA); + + Src = Source; + if (SrcSize < 8) { + return EFI_INVALID_PARAMETER; + } + + *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24); + return EFI_SUCCESS; +} + +EFI_STATUS +Decompress ( + IN VOID *Source, + IN UINT32 SrcSize, + IN OUT VOID *Destination, + IN UINT32 DstSize, + IN OUT VOID *Scratch, + IN UINT32 ScratchSize + ) +/*++ + +Routine Description: + + The implementation of EFI_DECOMPRESS_PROTOCOL.Decompress(). + +Arguments: + + This - The protocol instance pointer + Source - The source buffer containing the compressed data. + SrcSize - The size of source buffer + Destination - The destination buffer to store the decompressed data + DstSize - The size of destination buffer. + Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data. + ScratchSize - The size of scratch buffer. + +Returns: + + EFI_SUCCESS - Decompression is successfull + EFI_INVALID_PARAMETER - The source data is corrupted + +--*/ +{ + UINT32 Index; + UINT32 CompSize; + UINT32 OrigSize; + EFI_STATUS Status; + SCRATCH_DATA *Sd; + UINT8 *Src; + UINT8 *Dst; + + Status = EFI_SUCCESS; + Src = Source; + Dst = Destination; + + if (ScratchSize < sizeof (SCRATCH_DATA)) { + return EFI_INVALID_PARAMETER; + } + + Sd = (SCRATCH_DATA *) Scratch; + + if (SrcSize < 8) { + return EFI_INVALID_PARAMETER; + } + + CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24); + OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24); + + if (SrcSize < CompSize + 8) { + return EFI_INVALID_PARAMETER; + } + + if (DstSize != OrigSize) { + return EFI_INVALID_PARAMETER; + } + + Src = Src + 8; + + for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) { + ((UINT8 *) Sd)[Index] = 0; + } + + Sd->mSrcBase = Src; + Sd->mDstBase = Dst; + Sd->mCompSize = CompSize; + Sd->mOrigSize = OrigSize; + + // + // Fill the first BITBUFSIZ bits + // + FillBuf (Sd, BITBUFSIZ); + + // + // Decompress it + // + Decode (Sd); + + if (Sd->mBadTableFlag != 0) { + // + // Something wrong with the source + // + Status = EFI_INVALID_PARAMETER; + } + + return Status; +} diff --git a/Tools/CodeTools/Source/Common/EfiDecompress.h b/Tools/CodeTools/Source/Common/EfiDecompress.h new file mode 100644 index 0000000000..3f82ac6872 --- /dev/null +++ b/Tools/CodeTools/Source/Common/EfiDecompress.h @@ -0,0 +1,106 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + EfiDecompress.h + +Abstract: + + Header file for compression routine + +--*/ + +#ifndef _EFI_DECOMPRESS_H +#define _EFI_DECOMPRESS_H + +#include + +EFI_STATUS +GetInfo ( + IN VOID *Source, + IN UINT32 SrcSize, + OUT UINT32 *DstSize, + OUT UINT32 *ScratchSize + ); + +/*++ + +Routine Description: + + The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo(). + +Arguments: + + Source - The source buffer containing the compressed data. + SrcSize - The size of source buffer + DstSize - The size of destination buffer. + ScratchSize - The size of scratch buffer. + +Returns: + + EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved. + EFI_INVALID_PARAMETER - The source data is corrupted + +--*/ +EFI_STATUS +Decompress ( + IN VOID *Source, + IN UINT32 SrcSize, + IN OUT VOID *Destination, + IN UINT32 DstSize, + IN OUT VOID *Scratch, + IN UINT32 ScratchSize + ) +; + +/*++ + +Routine Description: + + The implementation of EFI_DECOMPRESS_PROTOCOL.Decompress(). + +Arguments: + + This - The protocol instance pointer + Source - The source buffer containing the compressed data. + SrcSize - The size of source buffer + Destination - The destination buffer to store the decompressed data + DstSize - The size of destination buffer. + Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data. + ScratchSize - The size of scratch buffer. + +Returns: + + EFI_SUCCESS - Decompression is successfull + EFI_INVALID_PARAMETER - The source data is corrupted + +--*/ +typedef +EFI_STATUS +(*GETINFO_FUNCTION) ( + IN VOID *Source, + IN UINT32 SrcSize, + OUT UINT32 *DstSize, + OUT UINT32 *ScratchSize + ); + +typedef +EFI_STATUS +(*DECOMPRESS_FUNCTION) ( + IN VOID *Source, + IN UINT32 SrcSize, + IN OUT VOID *Destination, + IN UINT32 DstSize, + IN OUT VOID *Scratch, + IN UINT32 ScratchSize + ); +#endif diff --git a/Tools/CodeTools/Source/Common/EfiUtilityMsgs.c b/Tools/CodeTools/Source/Common/EfiUtilityMsgs.c new file mode 100644 index 0000000000..566d214cab --- /dev/null +++ b/Tools/CodeTools/Source/Common/EfiUtilityMsgs.c @@ -0,0 +1,755 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + EfiUtilityMsgs.c + +Abstract: + + EFI tools utility functions to display warning, error, and informational + messages. + +--*/ + +#include +#include +#include +#include + +#include "EfiUtilityMsgs.h" + +#define MAX_LINE_LEN 200 + +// +// Declare module globals for keeping track of the the utility's +// name and other settings. +// +static STATUS mStatus = STATUS_SUCCESS; +static CHAR8 mUtilityName[50] = { 0 }; +static UINT32 mDebugMsgMask = 0; +static CHAR8 *mSourceFileName = NULL; +static UINT32 mSourceFileLineNum = 0; +static UINT32 mErrorCount = 0; +static UINT32 mWarningCount = 0; +static UINT32 mMaxErrors = 0; +static UINT32 mMaxWarnings = 0; +static UINT32 mMaxWarningsPlusErrors = 0; +static INT8 mPrintLimitsSet = 0; + +static +void +PrintMessage ( + CHAR8 *Type, + CHAR8 *FileName, + UINT32 LineNumber, + UINT32 MessageCode, + CHAR8 *Text, + CHAR8 *MsgFmt, + va_list List + ); + +static +void +PrintLimitExceeded ( + VOID + ); + +void +Error ( + CHAR8 *FileName, + UINT32 LineNumber, + UINT32 MessageCode, + CHAR8 *Text, + CHAR8 *MsgFmt, + ... + ) +/*++ + +Routine Description: + Prints an error message. + +Arguments: + All arguments are optional, though the printed message may be useless if + at least something valid is not specified. + + FileName - name of the file or application. If not specified, then the + utilty name (as set by the utility calling SetUtilityName() + earlier) is used. Otherwise "Unknown utility" is used. + + LineNumber - the line number of error, typically used by parsers. If the + utility is not a parser, then 0 should be specified. Otherwise + the FileName and LineNumber info can be used to cause + MS Visual Studio to jump to the error. + + MessageCode - an application-specific error code that can be referenced in + other documentation. + + Text - the text in question, typically used by parsers. + + MsgFmt - the format string for the error message. Can contain formatting + controls for use with the varargs. + +Returns: + None. + +Notes: + We print the following (similar to the Warn() and Debug() + W + Typical error/warning message format: + + bin\VfrCompile.cpp(330) : error C2660: 'AddVfrDataStructField' : function does not take 2 parameters + + BUGBUG -- these three utility functions are almost identical, and + should be modified to share code. + + Visual Studio does not find error messages with: + + " error :" + " error 1:" + " error c1:" + " error 1000:" + " error c100:" + + It does find: + " error c1000:" +--*/ +{ + va_list List; + // + // If limits have been set, then check that we have not exceeded them + // + if (mPrintLimitsSet) { + // + // See if we've exceeded our total count + // + if (mMaxWarningsPlusErrors != 0) { + if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) { + PrintLimitExceeded (); + return ; + } + } + // + // See if we've exceeded our error count + // + if (mMaxErrors != 0) { + if (mErrorCount > mMaxErrors) { + PrintLimitExceeded (); + return ; + } + } + } + + mErrorCount++; + va_start (List, MsgFmt); + PrintMessage ("error", FileName, LineNumber, MessageCode, Text, MsgFmt, List); + va_end (List); + // + // Set status accordingly + // + if (mStatus < STATUS_ERROR) { + mStatus = STATUS_ERROR; + } +} + +void +ParserError ( + UINT32 MessageCode, + CHAR8 *Text, + CHAR8 *MsgFmt, + ... + ) +/*++ + +Routine Description: + Print a parser error, using the source file name and line number + set by a previous call to SetParserPosition(). + +Arguments: + MessageCode - application-specific error code + Text - text to print in the error message + MsgFmt - format string to print at the end of the error message + +Returns: + NA + +--*/ +{ + va_list List; + // + // If limits have been set, then check them + // + if (mPrintLimitsSet) { + // + // See if we've exceeded our total count + // + if (mMaxWarningsPlusErrors != 0) { + if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) { + PrintLimitExceeded (); + return ; + } + } + // + // See if we've exceeded our error count + // + if (mMaxErrors != 0) { + if (mErrorCount > mMaxErrors) { + PrintLimitExceeded (); + return ; + } + } + } + + mErrorCount++; + va_start (List, MsgFmt); + PrintMessage ("error", mSourceFileName, mSourceFileLineNum, MessageCode, Text, MsgFmt, List); + va_end (List); + // + // Set status accordingly + // + if (mStatus < STATUS_ERROR) { + mStatus = STATUS_ERROR; + } +} + +void +ParserWarning ( + UINT32 ErrorCode, + CHAR8 *OffendingText, + CHAR8 *MsgFmt, + ... + ) +/*++ + +Routine Description: + Print a parser warning, using the source file name and line number + set by a previous call to SetParserPosition(). + +Arguments: + ErrorCode - application-specific error code + OffendingText - text to print in the warning message + MsgFmt - format string to print at the end of the warning message + +Returns: + NA + +--*/ +{ + va_list List; + // + // If limits have been set, then check them + // + if (mPrintLimitsSet) { + // + // See if we've exceeded our total count + // + if (mMaxWarningsPlusErrors != 0) { + if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) { + PrintLimitExceeded (); + return ; + } + } + // + // See if we've exceeded our warning count + // + if (mMaxWarnings != 0) { + if (mWarningCount > mMaxWarnings) { + PrintLimitExceeded (); + return ; + } + } + } + + mWarningCount++; + va_start (List, MsgFmt); + PrintMessage ("warning", mSourceFileName, mSourceFileLineNum, ErrorCode, OffendingText, MsgFmt, List); + va_end (List); + // + // Set status accordingly + // + if (mStatus < STATUS_WARNING) { + mStatus = STATUS_WARNING; + } +} + +void +Warning ( + CHAR8 *FileName, + UINT32 LineNumber, + UINT32 MessageCode, + CHAR8 *Text, + CHAR8 *MsgFmt, + ... + ) +/*++ + +Routine Description: + Print a warning message. + +Arguments: + FileName - name of the file where the warning was detected, or the name + of the application that detected the warning + + LineNumber - the line number where the warning was detected (parsers). + 0 should be specified if the utility is not a parser. + + MessageCode - an application-specific warning code that can be referenced in + other documentation. + + Text - the text in question (parsers) + + MsgFmt - the format string for the warning message. Can contain formatting + controls for use with varargs. + +Returns: + None. + +--*/ +{ + va_list List; + // + // If limits have been set, then check them + // + if (mPrintLimitsSet) { + // + // See if we've exceeded our total count + // + if (mMaxWarningsPlusErrors != 0) { + if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) { + PrintLimitExceeded (); + return ; + } + } + // + // See if we've exceeded our warning count + // + if (mMaxWarnings != 0) { + if (mWarningCount > mMaxWarnings) { + PrintLimitExceeded (); + return ; + } + } + } + + mWarningCount++; + va_start (List, MsgFmt); + PrintMessage ("warning", FileName, LineNumber, MessageCode, Text, MsgFmt, List); + va_end (List); + // + // Set status accordingly + // + if (mStatus < STATUS_WARNING) { + mStatus = STATUS_WARNING; + } +} + +void +DebugMsg ( + CHAR8 *FileName, + UINT32 LineNumber, + UINT32 MsgMask, + CHAR8 *Text, + CHAR8 *MsgFmt, + ... + ) +/*++ + +Routine Description: + Print a warning message. + +Arguments: + FileName - typically the name of the utility printing the debug message, but + can be the name of a file being parsed. + + LineNumber - the line number in FileName (parsers) + + MsgMask - an application-specific bitmask that, in combination with mDebugMsgMask, + determines if the debug message gets printed. + + Text - the text in question (parsers) + + MsgFmt - the format string for the debug message. Can contain formatting + controls for use with varargs. + +Returns: + None. + +--*/ +{ + va_list List; + // + // If the debug mask is not applicable, then do nothing. + // + if ((MsgMask != 0) && ((mDebugMsgMask & MsgMask) == 0)) { + return ; + } + + va_start (List, MsgFmt); + PrintMessage ("debug", FileName, LineNumber, 0, Text, MsgFmt, List); + va_end (List); +} + +static +void +PrintMessage ( + CHAR8 *Type, + CHAR8 *FileName, + UINT32 LineNumber, + UINT32 MessageCode, + CHAR8 *Text, + CHAR8 *MsgFmt, + va_list List + ) +/*++ + +Routine Description: + Worker routine for all the utility printing services. Prints the message in + a format that Visual Studio will find when scanning build outputs for + errors or warnings. + +Arguments: + Type - "warning" or "error" string to insert into the message to be + printed. The first character of this string (converted to uppercase) + is used to preceed the MessageCode value in the output string. + + FileName - name of the file where the warning was detected, or the name + of the application that detected the warning + + LineNumber - the line number where the warning was detected (parsers). + 0 should be specified if the utility is not a parser. + + MessageCode - an application-specific warning code that can be referenced in + other documentation. + + Text - part of the message to print + + MsgFmt - the format string for the message. Can contain formatting + controls for use with varargs. + List - the variable list. + +Returns: + None. + +Notes: + If FileName == NULL then this utility will use the string passed into SetUtilityName(). + + LineNumber is only used if the caller is a parser, in which case FileName refers to the + file being parsed. + + Text and MsgFmt are both optional, though it would be of little use calling this function with + them both NULL. + + Output will typically be of the form: + () : : : + + Parser (LineNumber != 0) + VfrCompile.cpp(330) : error E2660: AddVfrDataStructField : function does not take 2 parameters + Generic utility (LineNumber == 0) + UtilityName : error E1234 : Text string : MsgFmt string and args + +--*/ +{ + CHAR8 Line[MAX_LINE_LEN]; + CHAR8 Line2[MAX_LINE_LEN]; + CHAR8 *Cptr; + // + // If given a filename, then add it (and the line number) to the string. + // If there's no filename, then use the program name if provided. + // + if (FileName != NULL) { + Cptr = FileName; + } else if (mUtilityName[0] != 0) { + Cptr = mUtilityName; + } else { + Cptr = "Unknown utility"; + } + + strcpy (Line, Cptr); + if (LineNumber != 0) { + sprintf (Line2, "(%d)", LineNumber); + strcat (Line, Line2); + } + // + // Have to print an error code or Visual Studio won't find the + // message for you. It has to be decimal digits too. + // + sprintf (Line2, " : %s %c%04d", Type, toupper (Type[0]), MessageCode); + strcat (Line, Line2); + fprintf (stdout, "%s", Line); + // + // If offending text was provided, then print it + // + if (Text != NULL) { + fprintf (stdout, ": %s ", Text); + } + // + // Print formatted message if provided + // + if (MsgFmt != NULL) { + vsprintf (Line2, MsgFmt, List); + fprintf (stdout, ": %s", Line2); + } + + fprintf (stdout, "\n"); +} + +void +ParserSetPosition ( + CHAR8 *SourceFileName, + UINT32 LineNum + ) +/*++ + +Routine Description: + Set the position in a file being parsed. This can be used to + print error messages deeper down in a parser. + +Arguments: + SourceFileName - name of the source file being parsed + LineNum - line number of the source file being parsed + +Returns: + NA + +--*/ +{ + mSourceFileName = SourceFileName; + mSourceFileLineNum = LineNum; +} + +void +SetUtilityName ( + CHAR8 *UtilityName + ) +/*++ + +Routine Description: + All printed error/warning/debug messages follow the same format, and + typically will print a filename or utility name followed by the error + text. However if a filename is not passed to the print routines, then + they'll print the utility name if you call this function early in your + app to set the utility name. + +Arguments: + UtilityName - name of the utility, which will be printed with all + error/warning/debug messags. + +Returns: + NA + +--*/ +{ + // + // Save the name of the utility in our local variable. Make sure its + // length does not exceed our buffer. + // + if (UtilityName != NULL) { + if (strlen (UtilityName) >= sizeof (mUtilityName)) { + Error (UtilityName, 0, 0, "application error", "utility name length exceeds internal buffer size"); + strncpy (mUtilityName, UtilityName, sizeof (mUtilityName) - 1); + mUtilityName[sizeof (mUtilityName) - 1] = 0; + return ; + } else { + strcpy (mUtilityName, UtilityName); + } + } else { + Error (NULL, 0, 0, "application error", "SetUtilityName() called with NULL utility name"); + } +} + +STATUS +GetUtilityStatus ( + VOID + ) +/*++ + +Routine Description: + When you call Error() or Warning(), this module keeps track of it and + sets a local mStatus to STATUS_ERROR or STATUS_WARNING. When the utility + exits, it can call this function to get the status and use it as a return + value. + +Arguments: + None. + +Returns: + Worst-case status reported, as defined by which print function was called. + +--*/ +{ + return mStatus; +} + +void +SetDebugMsgMask ( + UINT32 DebugMask + ) +/*++ + +Routine Description: + Set the debug printing mask. This is used by the DebugMsg() function + to determine when/if a debug message should be printed. + +Arguments: + DebugMask - bitmask, specific to the calling application + +Returns: + NA + +--*/ +{ + mDebugMsgMask = DebugMask; +} + +void +SetPrintLimits ( + UINT32 MaxErrors, + UINT32 MaxWarnings, + UINT32 MaxWarningsPlusErrors + ) +/*++ + +Routine Description: + Set the limits of how many errors, warnings, and errors+warnings + we will print. + +Arguments: + MaxErrors - maximum number of error messages to print + MaxWarnings - maximum number of warning messages to print + MaxWarningsPlusErrors + - maximum number of errors+warnings to print + +Returns: + NA + +--*/ +{ + mMaxErrors = MaxErrors; + mMaxWarnings = MaxWarnings; + mMaxWarningsPlusErrors = MaxWarningsPlusErrors; + mPrintLimitsSet = 1; +} + +static +void +PrintLimitExceeded ( + VOID + ) +{ + static INT8 mPrintLimitExceeded = 0; + // + // If we've already printed the message, do nothing. Otherwise + // temporarily increase our print limits so we can pass one + // more message through. + // + if (mPrintLimitExceeded == 0) { + mPrintLimitExceeded++; + mMaxErrors++; + mMaxWarnings++; + mMaxWarningsPlusErrors++; + Error (NULL, 0, 0, "error/warning print limit exceeded", NULL); + mMaxErrors--; + mMaxWarnings--; + mMaxWarningsPlusErrors--; + } +} + +#if 0 +void +TestUtilityMessages ( + VOID + ) +{ + char *ArgStr = "ArgString"; + int ArgInt; + + ArgInt = 0x12345678; + // + // Test without setting utility name + // + fprintf (stdout, "* Testing without setting utility name\n"); + fprintf (stdout, "** Test debug message not printed\n"); + DebugMsg (NULL, 0, 0x00000001, NULL, NULL); + fprintf (stdout, "** Test warning with two strings and two args\n"); + Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); + fprintf (stdout, "** Test error with two strings and two args\n"); + Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); + fprintf (stdout, "** Test parser warning with nothing\n"); + ParserWarning (0, NULL, NULL); + fprintf (stdout, "** Test parser error with nothing\n"); + ParserError (0, NULL, NULL); + // + // Test with utility name set now + // + fprintf (stdout, "** Testingin with utility name set\n"); + SetUtilityName ("MyUtilityName"); + // + // Test debug prints + // + SetDebugMsgMask (2); + fprintf (stdout, "** Test debug message with one string\n"); + DebugMsg (NULL, 0, 0x00000002, "Text1", NULL); + fprintf (stdout, "** Test debug message with one string\n"); + DebugMsg (NULL, 0, 0x00000002, NULL, "Text2"); + fprintf (stdout, "** Test debug message with two strings\n"); + DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2"); + fprintf (stdout, "** Test debug message with two strings and two args\n"); + DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); + // + // Test warning prints + // + fprintf (stdout, "** Test warning with no strings\n"); + Warning (NULL, 0, 1234, NULL, NULL); + fprintf (stdout, "** Test warning with one string\n"); + Warning (NULL, 0, 1234, "Text1", NULL); + fprintf (stdout, "** Test warning with one string\n"); + Warning (NULL, 0, 1234, NULL, "Text2"); + fprintf (stdout, "** Test warning with two strings and two args\n"); + Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); + // + // Test error prints + // + fprintf (stdout, "** Test error with no strings\n"); + Error (NULL, 0, 1234, NULL, NULL); + fprintf (stdout, "** Test error with one string\n"); + Error (NULL, 0, 1234, "Text1", NULL); + fprintf (stdout, "** Test error with one string\n"); + Error (NULL, 0, 1234, NULL, "Text2"); + fprintf (stdout, "** Test error with two strings and two args\n"); + Error (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); + // + // Test parser prints + // + fprintf (stdout, "** Test parser errors\n"); + ParserSetPosition (__FILE__, __LINE__ + 1); + ParserError (1234, NULL, NULL); + ParserSetPosition (__FILE__, __LINE__ + 1); + ParserError (1234, "Text1", NULL); + ParserSetPosition (__FILE__, __LINE__ + 1); + ParserError (1234, NULL, "Text2"); + ParserSetPosition (__FILE__, __LINE__ + 1); + ParserError (1234, "Text1", "Text2"); + ParserSetPosition (__FILE__, __LINE__ + 1); + ParserError (1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); + + fprintf (stdout, "** Test parser warnings\n"); + ParserSetPosition (__FILE__, __LINE__ + 1); + ParserWarning (4321, NULL, NULL); + ParserSetPosition (__FILE__, __LINE__ + 1); + ParserWarning (4321, "Text1", NULL); + ParserSetPosition (__FILE__, __LINE__ + 1); + ParserWarning (4321, NULL, "Text2"); + ParserSetPosition (__FILE__, __LINE__ + 1); + ParserWarning (4321, "Text1", "Text2"); + ParserSetPosition (__FILE__, __LINE__ + 1); + ParserWarning (4321, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); +} +#endif diff --git a/Tools/CodeTools/Source/Common/EfiUtilityMsgs.h b/Tools/CodeTools/Source/Common/EfiUtilityMsgs.h new file mode 100644 index 0000000000..a76b822675 --- /dev/null +++ b/Tools/CodeTools/Source/Common/EfiUtilityMsgs.h @@ -0,0 +1,137 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + EfiUtilityMsgs.h + +Abstract: + + Defines and prototypes for common EFI utility error and debug messages. + +--*/ + +#ifndef _EFI_UTILITY_MSGS_H_ +#define _EFI_UTILITY_MSGS_H_ + +#include + +// +// Status codes returned by EFI utility programs and functions +// +#define STATUS_SUCCESS 0 +#define STATUS_WARNING 1 +#define STATUS_ERROR 2 +#define VOID void + +typedef int STATUS; + +#ifdef __cplusplus +extern "C" { +#endif +// +// When we call Error() or Warning(), the module keeps track of the worst +// case reported. GetUtilityStatus() will get the worst-case results, which +// can be used as the return value from the app. +// +STATUS +GetUtilityStatus ( + void + ); + +// +// If someone prints an error message and didn't specify a source file name, +// then we print the utility name instead. However they must tell us the +// utility name early on via this function. +// +void +SetUtilityName ( + CHAR8 *ProgramName + ) +; + +void +Error ( + CHAR8 *FileName, + UINT32 LineNumber, + UINT32 ErrorCode, + CHAR8 *OffendingText, + CHAR8 *MsgFmt, + ... + ) +; + +void +Warning ( + CHAR8 *FileName, + UINT32 LineNumber, + UINT32 ErrorCode, + CHAR8 *OffendingText, + CHAR8 *MsgFmt, + ... + ) +; + +void +DebugMsg ( + CHAR8 *FileName, + UINT32 LineNumber, + UINT32 MsgLevel, + CHAR8 *OffendingText, + CHAR8 *MsgFmt, + ... + ) +; + +void +SetDebugMsgMask ( + UINT32 MsgMask + ) +; + +void +ParserSetPosition ( + CHAR8 *SourceFileName, + UINT32 LineNum + ) +; + +void +ParserError ( + UINT32 ErrorCode, + CHAR8 *OffendingText, + CHAR8 *MsgFmt, + ... + ) +; + +void +ParserWarning ( + UINT32 ErrorCode, + CHAR8 *OffendingText, + CHAR8 *MsgFmt, + ... + ) +; + +void +SetPrintLimits ( + UINT32 NumErrors, + UINT32 NumWarnings, + UINT32 NumWarningsPlusErrors + ) +; + +#ifdef __cplusplus +} +#endif + +#endif // #ifndef _EFI_UTILITY_MSGS_H_ diff --git a/Tools/CodeTools/Source/Common/FvLib.c b/Tools/CodeTools/Source/Common/FvLib.c new file mode 100644 index 0000000000..e8d62791f3 --- /dev/null +++ b/Tools/CodeTools/Source/Common/FvLib.c @@ -0,0 +1,780 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + FvLib.c + +Abstract: + + These functions assist in parsing and manipulating a Firmware Volume. + +--*/ + +// +// Include files +// +#include "FvLib.h" +#include "CommonLib.h" +#include "EfiUtilityMsgs.h" + +// +// Module global variables +// +EFI_FIRMWARE_VOLUME_HEADER *mFvHeader = NULL; +UINT32 mFvLength = 0; + +// +// External function implementations +// +EFI_STATUS +InitializeFvLib ( + IN VOID *Fv, + IN UINT32 FvLength + ) +/*++ + +Routine Description: + + This initializes the FV lib with a pointer to the FV and length. It does not + verify the FV in any way. + +Arguments: + + Fv Buffer containing the FV. + FvLength Length of the FV + +Returns: + + EFI_SUCCESS Function Completed successfully. + EFI_INVALID_PARAMETER A required parameter was NULL. + +--*/ +{ + // + // Verify input arguments + // + if (Fv == NULL) { + return EFI_INVALID_PARAMETER; + } + + mFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) Fv; + mFvLength = FvLength; + + return EFI_SUCCESS; +} + +EFI_STATUS +GetFvHeader ( + OUT EFI_FIRMWARE_VOLUME_HEADER **FvHeader, + OUT UINT32 *FvLength + ) +/*++ + +Routine Description: + + This function returns a pointer to the current FV and the size. + +Arguments: + + FvHeader Pointer to the FV buffer. + FvLength Length of the FV + +Returns: + + EFI_SUCCESS Function Completed successfully. + EFI_INVALID_PARAMETER A required parameter was NULL. + EFI_ABORTED The library needs to be initialized. + +--*/ +{ + // + // Verify library has been initialized. + // + if (mFvHeader == NULL || mFvLength == 0) { + return EFI_ABORTED; + } + // + // Verify input arguments + // + if (FvHeader == NULL) { + return EFI_INVALID_PARAMETER; + } + + *FvHeader = mFvHeader; + return EFI_SUCCESS; +} + +EFI_STATUS +GetNextFile ( + IN EFI_FFS_FILE_HEADER *CurrentFile, + OUT EFI_FFS_FILE_HEADER **NextFile + ) +/*++ + +Routine Description: + + This function returns the next file. If the current file is NULL, it returns + the first file in the FV. If the function returns EFI_SUCCESS and the file + pointer is NULL, then there are no more files in the FV. + +Arguments: + + CurrentFile Pointer to the current file, must be within the current FV. + NextFile Pointer to the next file in the FV. + +Returns: + + EFI_SUCCESS Function completed successfully. + EFI_INVALID_PARAMETER A required parameter was NULL or is out of range. + EFI_ABORTED The library needs to be initialized. + +--*/ +{ + EFI_STATUS Status; + + // + // Verify library has been initialized. + // + if (mFvHeader == NULL || mFvLength == 0) { + return EFI_ABORTED; + } + // + // Verify input arguments + // + if (NextFile == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Verify FV header + // + Status = VerifyFv (mFvHeader); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + // + // Get first file + // + if (CurrentFile == NULL) { + CurrentFile = (EFI_FFS_FILE_HEADER *) ((UINTN) mFvHeader + mFvHeader->HeaderLength); + + // + // Verify file is valid + // + Status = VerifyFfsFile (CurrentFile); + if (EFI_ERROR (Status)) { + // + // no files in this FV + // + *NextFile = NULL; + return EFI_SUCCESS; + } else { + // + // Verify file is in this FV. + // + if ((UINTN) CurrentFile >= (UINTN) mFvHeader + mFvLength - sizeof (EFI_FFS_FILE_HEADER)) { + *NextFile = NULL; + return EFI_SUCCESS; + } + + *NextFile = CurrentFile; + return EFI_SUCCESS; + } + } + // + // Verify current file is in range + // + if (((UINTN) CurrentFile < (UINTN) mFvHeader + sizeof (EFI_FIRMWARE_VOLUME_HEADER)) || + ((UINTN) CurrentFile >= (UINTN) mFvHeader + mFvLength - sizeof (EFI_FIRMWARE_VOLUME_HEADER)) + ) { + return EFI_INVALID_PARAMETER; + } + // + // Get next file, compensate for 8 byte alignment if necessary. + // + *NextFile = (EFI_FFS_FILE_HEADER *) (((UINTN) CurrentFile + GetLength (CurrentFile->Size) + 0x07) & (-1 << 3)); + + // + // Verify file is in this FV. + // + if ((UINTN) *NextFile >= (UINTN) mFvHeader + mFvLength - sizeof (EFI_FFS_FILE_HEADER)) { + *NextFile = NULL; + return EFI_SUCCESS; + } + // + // Verify file is valid + // + Status = VerifyFfsFile (*NextFile); + if (EFI_ERROR (Status)) { + // + // no more files in this FV + // + *NextFile = NULL; + return EFI_SUCCESS; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +GetFileByName ( + IN EFI_GUID *FileName, + OUT EFI_FFS_FILE_HEADER **File + ) +/*++ + +Routine Description: + + Find a file by name. The function will return NULL if the file is not found. + +Arguments: + + FileName The GUID file name of the file to search for. + File Return pointer. In the case of an error, contents are undefined. + +Returns: + + EFI_SUCCESS The function completed successfully. + EFI_ABORTED An error was encountered. + EFI_INVALID_PARAMETER One of the parameters was NULL. + +--*/ +{ + EFI_FFS_FILE_HEADER *CurrentFile; + EFI_STATUS Status; + + // + // Verify library has been initialized. + // + if (mFvHeader == NULL || mFvLength == 0) { + return EFI_ABORTED; + } + // + // Verify input parameters + // + if (FileName == NULL || File == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Verify FV header + // + Status = VerifyFv (mFvHeader); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + // + // Get the first file + // + Status = GetNextFile (NULL, &CurrentFile); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "error parsing the FV", NULL); + return EFI_ABORTED; + } + // + // Loop as long as we have a valid file + // + while (CurrentFile) { + if (!CompareGuid (&CurrentFile->Name, FileName)) { + *File = CurrentFile; + return EFI_SUCCESS; + } + + Status = GetNextFile (CurrentFile, &CurrentFile); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "error parsing the FV", NULL); + return EFI_ABORTED; + } + } + // + // File not found in this FV. + // + *File = NULL; + return EFI_SUCCESS; +} + +EFI_STATUS +GetFileByType ( + IN EFI_FV_FILETYPE FileType, + IN UINTN Instance, + OUT EFI_FFS_FILE_HEADER **File + ) +/*++ + +Routine Description: + + Find a file by type and instance. An instance of 1 is the first instance. + The function will return NULL if a matching file cannot be found. + File type EFI_FV_FILETYPE_ALL means any file type is valid. + +Arguments: + + FileType Type of file to search for. + Instance Instace of the file type to return. + File Return pointer. In the case of an error, contents are undefined. + +Returns: + + EFI_SUCCESS The function completed successfully. + EFI_ABORTED An error was encountered. + EFI_INVALID_PARAMETER One of the parameters was NULL. + +--*/ +{ + EFI_FFS_FILE_HEADER *CurrentFile; + EFI_STATUS Status; + UINTN FileCount; + + // + // Verify library has been initialized. + // + if (mFvHeader == NULL || mFvLength == 0) { + return EFI_ABORTED; + } + // + // Verify input parameters + // + if (File == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Verify FV header + // + Status = VerifyFv (mFvHeader); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + // + // Initialize the number of matching files found. + // + FileCount = 0; + + // + // Get the first file + // + Status = GetNextFile (NULL, &CurrentFile); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "error parsing FV", NULL); + return EFI_ABORTED; + } + // + // Loop as long as we have a valid file + // + while (CurrentFile) { + if (FileType == EFI_FV_FILETYPE_ALL || CurrentFile->Type == FileType) { + FileCount++; + } + + if (FileCount == Instance) { + *File = CurrentFile; + return EFI_SUCCESS; + } + + Status = GetNextFile (CurrentFile, &CurrentFile); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "error parsing the FV", NULL); + return EFI_ABORTED; + } + } + + *File = NULL; + return EFI_SUCCESS; +} + +EFI_STATUS +GetSectionByType ( + IN EFI_FFS_FILE_HEADER *File, + IN EFI_SECTION_TYPE SectionType, + IN UINTN Instance, + OUT EFI_FILE_SECTION_POINTER *Section + ) +/*++ + +Routine Description: + + Find a section in a file by type and instance. An instance of 1 is the first + instance. The function will return NULL if a matching section cannot be found. + The function will not handle encapsulating sections. + +Arguments: + + File The file to search. + SectionType Type of file to search for. + Instance Instace of the section to return. + Section Return pointer. In the case of an error, contents are undefined. + +Returns: + + EFI_SUCCESS The function completed successfully. + EFI_ABORTED An error was encountered. + EFI_INVALID_PARAMETER One of the parameters was NULL. + EFI_NOT_FOUND No found. +--*/ +{ + EFI_FILE_SECTION_POINTER CurrentSection; + EFI_STATUS Status; + UINTN SectionCount; + + // + // Verify input parameters + // + if (File == NULL || Instance == 0) { + return EFI_INVALID_PARAMETER; + } + // + // Verify FFS header + // + Status = VerifyFfsFile (File); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "invalid FFS file", NULL); + return EFI_ABORTED; + } + // + // Initialize the number of matching sections found. + // + SectionCount = 0; + + // + // Get the first section + // + CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) File + sizeof (EFI_FFS_FILE_HEADER)); + + // + // Loop as long as we have a valid file + // + while ((UINTN) CurrentSection.CommonHeader < (UINTN) File + GetLength (File->Size)) { + if (CurrentSection.CommonHeader->Type == SectionType) { + SectionCount++; + } + + if (SectionCount == Instance) { + *Section = CurrentSection; + return EFI_SUCCESS; + } + // + // Find next section (including compensating for alignment issues. + // + CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetLength (CurrentSection.CommonHeader->Size) + 0x03) & (-1 << 2)); + } + // + // Section not found + // + (*Section).Code16Section = NULL; + return EFI_NOT_FOUND; +} +// +// will not parse compressed sections +// +EFI_STATUS +VerifyFv ( + IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader + ) +/*++ + +Routine Description: + + Verify the current pointer points to a valid FV header. + +Arguments: + + FvHeader Pointer to an alleged FV file. + +Returns: + + EFI_SUCCESS The FV header is valid. + EFI_VOLUME_CORRUPTED The FV header is not valid. + EFI_INVALID_PARAMETER A required parameter was NULL. + EFI_ABORTED Operation aborted. + +--*/ +{ + UINT16 Checksum; + + // + // Verify input parameters + // + if (FvHeader == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (FvHeader->Signature != EFI_FVH_SIGNATURE) { + Error (NULL, 0, 0, "invalid FV header signature", NULL); + return EFI_VOLUME_CORRUPTED; + } + // + // Verify header checksum + // + Checksum = CalculateSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); + + if (Checksum != 0) { + Error (NULL, 0, 0, "invalid FV header checksum", NULL); + return EFI_ABORTED; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +VerifyFfsFile ( + IN EFI_FFS_FILE_HEADER *FfsHeader + ) +/*++ + +Routine Description: + + Verify the current pointer points to a FFS file header. + +Arguments: + + FfsHeader Pointer to an alleged FFS file. + +Returns: + + EFI_SUCCESS The Ffs header is valid. + EFI_NOT_FOUND This "file" is the beginning of free space. + EFI_VOLUME_CORRUPTED The Ffs header is not valid. + EFI_ABORTED The erase polarity is not known. + +--*/ +{ + BOOLEAN ErasePolarity; + EFI_STATUS Status; + EFI_FFS_FILE_HEADER BlankHeader; + UINT8 Checksum; + UINT32 FileLength; + UINT32 OccupiedFileLength; + EFI_FFS_FILE_TAIL *Tail; + UINT8 SavedChecksum; + UINT8 SavedState; + UINT8 FileGuidString[80]; + UINT32 TailSize; + // + // Verify library has been initialized. + // + if (mFvHeader == NULL || mFvLength == 0) { + return EFI_ABORTED; + } + // + // Verify FV header + // + Status = VerifyFv (mFvHeader); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + // + // Get the erase polarity. + // + Status = GetErasePolarity (&ErasePolarity); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + // + // Check if we have free space + // + if (ErasePolarity) { + memset (&BlankHeader, -1, sizeof (EFI_FFS_FILE_HEADER)); + } else { + memset (&BlankHeader, 0, sizeof (EFI_FFS_FILE_HEADER)); + } + + if (memcmp (&BlankHeader, FfsHeader, sizeof (EFI_FFS_FILE_HEADER)) == 0) { + return EFI_NOT_FOUND; + } + // + // Convert the GUID to a string so we can at least report which file + // if we find an error. + // + PrintGuidToBuffer (&FfsHeader->Name, FileGuidString, sizeof (FileGuidString), TRUE); + if (FfsHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) { + TailSize = sizeof (EFI_FFS_FILE_TAIL); + } else { + TailSize = 0; + } + // + // Verify file header checksum + // + SavedState = FfsHeader->State; + FfsHeader->State = 0; + SavedChecksum = FfsHeader->IntegrityCheck.Checksum.File; + FfsHeader->IntegrityCheck.Checksum.File = 0; + Checksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER)); + FfsHeader->State = SavedState; + FfsHeader->IntegrityCheck.Checksum.File = SavedChecksum; + if (Checksum != 0) { + Error (NULL, 0, 0, FileGuidString, "invalid FFS file header checksum"); + return EFI_ABORTED; + } + // + // Verify file checksum + // + if (FfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) { + // + // Verify file data checksum + // + FileLength = GetLength (FfsHeader->Size); + OccupiedFileLength = (FileLength + 0x07) & (-1 << 3); + Checksum = CalculateSum8 ((UINT8 *) FfsHeader, FileLength - TailSize); + Checksum = (UINT8) (Checksum - FfsHeader->State); + if (Checksum != 0) { + Error (NULL, 0, 0, FileGuidString, "invalid FFS file checksum"); + return EFI_ABORTED; + } + } else { + // + // File does not have a checksum + // Verify contents are 0x5A as spec'd + // + if (FfsHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) { + Error (NULL, 0, 0, FileGuidString, "invalid fixed FFS file header checksum"); + return EFI_ABORTED; + } + } + // + // Check if the tail is present and verify it if it is. + // + if (FfsHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) { + // + // Verify tail is complement of integrity check field in the header. + // + Tail = (EFI_FFS_FILE_TAIL *) ((UINTN) FfsHeader + GetLength (FfsHeader->Size) - sizeof (EFI_FFS_FILE_TAIL)); + if (FfsHeader->IntegrityCheck.TailReference != (EFI_FFS_FILE_TAIL)~(*Tail)) { + Error (NULL, 0, 0, FileGuidString, "invalid FFS file tail"); + return EFI_ABORTED; + } + } + + return EFI_SUCCESS; +} + +UINT32 +GetLength ( + UINT8 *ThreeByteLength + ) +/*++ + +Routine Description: + + Converts a three byte length value into a UINT32. + +Arguments: + + ThreeByteLength Pointer to the first of the 3 byte length. + +Returns: + + UINT32 Size of the section + +--*/ +{ + UINT32 Length; + + if (ThreeByteLength == NULL) { + return 0; + } + + Length = *((UINT32 *) ThreeByteLength); + Length = Length & 0x00FFFFFF; + + return Length; +} + +EFI_STATUS +GetErasePolarity ( + OUT BOOLEAN *ErasePolarity + ) +/*++ + +Routine Description: + + This function returns with the FV erase polarity. If the erase polarity + for a bit is 1, the function return TRUE. + +Arguments: + + ErasePolarity A pointer to the erase polarity. + +Returns: + + EFI_SUCCESS The function completed successfully. + EFI_INVALID_PARAMETER One of the input parameters was invalid. + EFI_ABORTED Operation aborted. + +--*/ +{ + EFI_STATUS Status; + + // + // Verify library has been initialized. + // + if (mFvHeader == NULL || mFvLength == 0) { + return EFI_ABORTED; + } + // + // Verify FV header + // + Status = VerifyFv (mFvHeader); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + // + // Verify input parameters. + // + if (ErasePolarity == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (mFvHeader->Attributes & EFI_FVB_ERASE_POLARITY) { + *ErasePolarity = TRUE; + } else { + *ErasePolarity = FALSE; + } + + return EFI_SUCCESS; +} + +UINT8 +GetFileState ( + IN BOOLEAN ErasePolarity, + IN EFI_FFS_FILE_HEADER *FfsHeader + ) +/*++ + +Routine Description: + + This function returns a the highest state bit in the FFS that is set. + It in no way validate the FFS file. + +Arguments: + + ErasePolarity The erase polarity for the file state bits. + FfsHeader Pointer to a FFS file. + +Returns: + + UINT8 The hightest set state of the file. + +--*/ +{ + UINT8 FileState; + UINT8 HighestBit; + + FileState = FfsHeader->State; + + if (ErasePolarity) { + FileState = (UINT8)~FileState; + } + + HighestBit = 0x80; + while (HighestBit != 0 && (HighestBit & FileState) == 0) { + HighestBit >>= 1; + } + + return HighestBit; +} diff --git a/Tools/CodeTools/Source/Common/FvLib.h b/Tools/CodeTools/Source/Common/FvLib.h new file mode 100644 index 0000000000..1ad1e812dd --- /dev/null +++ b/Tools/CodeTools/Source/Common/FvLib.h @@ -0,0 +1,181 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + FvLib.h + +Abstract: + + These functions assist in parsing and manipulating a Firmware Volume. + +--*/ + +#ifndef _EFI_FV_LIB_H +#define _EFI_FV_LIB_H + +// +// Include files +// +#include + +#include +#include +#include +#include +#include +#include + +EFI_STATUS +InitializeFvLib ( + IN VOID *Fv, + IN UINT32 FvLength + ) +; + +EFI_STATUS +GetFvHeader ( + OUT EFI_FIRMWARE_VOLUME_HEADER **FvHeader, + OUT UINT32 *FvLength + ) +; + +EFI_STATUS +GetNextFile ( + IN EFI_FFS_FILE_HEADER *CurrentFile, + OUT EFI_FFS_FILE_HEADER **NextFile + ) +; + +EFI_STATUS +GetFileByName ( + IN EFI_GUID *FileName, + OUT EFI_FFS_FILE_HEADER **File + ) +; + +EFI_STATUS +GetFileByType ( + IN EFI_FV_FILETYPE FileType, + IN UINTN Instance, + OUT EFI_FFS_FILE_HEADER **File + ) +; + +EFI_STATUS +GetSectionByType ( + IN EFI_FFS_FILE_HEADER *File, + IN EFI_SECTION_TYPE SectionType, + IN UINTN Instance, + OUT EFI_FILE_SECTION_POINTER *Section + ) +; +// +// will not parse compressed sections +// +EFI_STATUS +VerifyFv ( + IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader + ) +; + +EFI_STATUS +VerifyFfsFile ( + IN EFI_FFS_FILE_HEADER *FfsHeader + ) +; + +/*++ + +Routine Description: + + Verify the current pointer points to a FFS file header. + +Arguments: + + FfsHeader Pointer to an alleged FFS file. + +Returns: + + EFI_SUCCESS The Ffs header is valid. + EFI_NOT_FOUND This "file" is the beginning of free space. + EFI_VOLUME_CORRUPTED The Ffs header is not valid. + +--*/ +UINT32 +GetLength ( + UINT8 *ThreeByteLength + ) +; + +/*++ + +Routine Description: + + Converts a three byte length value into a UINT32. + +Arguments: + + ThreeByteLength Pointer to the first of the 3 byte length. + +Returns: + + UINT32 Size of the section + +--*/ +EFI_STATUS +GetErasePolarity ( + OUT BOOLEAN *ErasePolarity + ) +; + +/*++ + +Routine Description: + + This function returns with the FV erase polarity. If the erase polarity + for a bit is 1, the function return TRUE. + +Arguments: + + ErasePolarity A pointer to the erase polarity. + +Returns: + + EFI_SUCCESS The function completed successfully. + EFI_INVALID_PARAMETER One of the input parameters was invalid. + +--*/ +UINT8 +GetFileState ( + IN BOOLEAN ErasePolarity, + IN EFI_FFS_FILE_HEADER *FfsHeader + ) +; + +/*++ + +Routine Description: + + This function returns a the highest state bit in the FFS that is set. + It in no way validate the FFS file. + +Arguments: + + ErasePolarity The erase polarity for the file state bits. + FfsHeader Pointer to a FFS file. + +Returns: + + UINT8 The hightest set state of the file. + +--*/ +#endif diff --git a/Tools/CodeTools/Source/Common/MyAlloc.c b/Tools/CodeTools/Source/Common/MyAlloc.c new file mode 100644 index 0000000000..39fddf7428 --- /dev/null +++ b/Tools/CodeTools/Source/Common/MyAlloc.c @@ -0,0 +1,516 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + MyAlloc.c + +Abstract: + + File for memory allocation tracking functions. + +--*/ + +#include "MyAlloc.h" + +#if USE_MYALLOC +// +// Get back to original alloc/free calls. +// +#undef malloc +#undef calloc +#undef realloc +#undef free +// +// Start of allocation list. +// +static MY_ALLOC_STRUCT *MyAllocData = NULL; + +// +// +// +static UINT32 MyAllocHeadMagik = MYALLOC_HEAD_MAGIK; +static UINT32 MyAllocTailMagik = MYALLOC_TAIL_MAGIK; + +// +// //////////////////////////////////////////////////////////////////////////// +// +// +VOID +MyCheck ( + BOOLEAN Final, + UINT8 File[], + UINTN Line + ) +// *++ +// Description: +// +// Check for corruptions in the allocated memory chain. If a corruption +// is detection program operation stops w/ an exit(1) call. +// +// Parameters: +// +// Final := When FALSE, MyCheck() returns if the allocated memory chain +// has not been corrupted. When TRUE, MyCheck() returns if there +// are no un-freed allocations. If there are un-freed allocations, +// they are displayed and exit(1) is called. +// +// +// File := Set to __FILE__ by macro expansion. +// +// Line := Set to __LINE__ by macro expansion. +// +// Returns: +// +// n/a +// +// --*/ +// +{ + MY_ALLOC_STRUCT *Tmp; + + // + // Check parameters. + // + if (File == NULL || Line == 0) { + printf ( + "\nMyCheck(Final=%u, File=%xh, Line=%u)" + "Invalid parameter(s).\n", + Final, + File, + Line + ); + + exit (1); + } + + if (strlen (File) == 0) { + printf ( + "\nMyCheck(Final=%u, File=%s, Line=%u)" + "Invalid parameter.\n", + Final, + File, + Line + ); + + exit (1); + } + // + // Check structure contents. + // + for (Tmp = MyAllocData; Tmp != NULL; Tmp = Tmp->Next) { + if (memcmp(Tmp->Buffer, &MyAllocHeadMagik, sizeof MyAllocHeadMagik) || + memcmp(&Tmp->Buffer[Tmp->Size + sizeof(UINT32)], &MyAllocTailMagik, sizeof MyAllocTailMagik)) { + break; + } + } + // + // If Tmp is not NULL, the structure is corrupt. + // + if (Tmp != NULL) { + printf ( + "\nMyCheck(Final=%u, File=%s, Line=%u)""\nStructure corrupted!" + "\nFile=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n", + Final, + File, + Line, + Tmp->File, + Tmp->Line, + Tmp->Size, + *(UINT32 *) (Tmp->Buffer), + *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)]) + ); + + exit (1); + } + // + // If Final is TRUE, display the state of the structure chain. + // + if (Final) { + if (MyAllocData != NULL) { + printf ( + "\nMyCheck(Final=%u, File=%s, Line=%u)" + "\nSome allocated items have not been freed.\n", + Final, + File, + Line + ); + + for (Tmp = MyAllocData; Tmp != NULL; Tmp = Tmp->Next) { + printf ( + "File=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n", + Tmp->File, + Tmp->Line, + Tmp->Size, + *(UINT32 *) (Tmp->Buffer), + *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)]) + ); + } + } + } +} +// +// //////////////////////////////////////////////////////////////////////////// +// +// +VOID * +MyAlloc ( + UINTN Size, + UINT8 File[], + UINTN Line + ) +// *++ +// Description: +// +// Allocate a new link in the allocation chain along with enough storage +// for the File[] string, requested Size and alignment overhead. If +// memory cannot be allocated or the allocation chain has been corrupted, +// exit(1) will be called. +// +// Parameters: +// +// Size := Number of bytes (UINT8) requested by the called. +// Size cannot be zero. +// +// File := Set to __FILE__ by macro expansion. +// +// Line := Set to __LINE__ by macro expansion. +// +// Returns: +// +// Pointer to the caller's buffer. +// +// --*/ +// +{ + MY_ALLOC_STRUCT *Tmp; + UINTN Len; + + // + // Check for invalid parameters. + // + if (Size == 0 || File == NULL || Line == 0) { + printf ( + "\nMyAlloc(Size=%u, File=%xh, Line=%u)" + "\nInvalid parameter(s).\n", + Size, + File, + Line + ); + + exit (1); + } + + Len = strlen (File); + if (Len == 0) { + printf ( + "\nMyAlloc(Size=%u, File=%s, Line=%u)" + "\nInvalid parameter.\n", + Size, + File, + Line + ); + + exit (1); + } + // + // Check the allocation list for corruption. + // + MyCheck (0, __FILE__, __LINE__); + + // + // Allocate a new entry. + // + Tmp = calloc ( + 1, + sizeof (MY_ALLOC_STRUCT) + Len + 1 + sizeof (UINT64) + Size + (sizeof MyAllocHeadMagik) + (sizeof MyAllocTailMagik) + ); + + if (Tmp == NULL) { + printf ( + "\nMyAlloc(Size=%u, File=%s, Line=%u)" + "\nOut of memory.\n", + Size, + File, + Line + ); + + exit (1); + } + // + // Fill in the new entry. + // + Tmp->File = ((UINT8 *) Tmp) + sizeof (MY_ALLOC_STRUCT); + strcpy (Tmp->File, File); + Tmp->Line = Line; + Tmp->Size = Size; + Tmp->Buffer = (UINT8 *) (((UINTN) Tmp + Len + 9) &~7); + + memcpy (Tmp->Buffer, &MyAllocHeadMagik, sizeof MyAllocHeadMagik); + + memcpy ( + &Tmp->Buffer[Size + sizeof (UINT32)], + &MyAllocTailMagik, + sizeof MyAllocTailMagik + ); + + Tmp->Next = MyAllocData; + Tmp->Cksum = (UINTN) Tmp + (UINTN) (Tmp->Next) + Tmp->Line + Tmp->Size + (UINTN) (Tmp->File) + (UINTN) (Tmp->Buffer); + + MyAllocData = Tmp; + + return Tmp->Buffer + sizeof (UINT32); +} +// +// //////////////////////////////////////////////////////////////////////////// +// +// +VOID * +MyRealloc ( + VOID *Ptr, + UINTN Size, + UINT8 File[], + UINTN Line + ) +// *++ +// Description: +// +// This does a MyAlloc(), memcpy() and MyFree(). There is no optimization +// for shrinking or expanding buffers. An invalid parameter will cause +// MyRealloc() to fail with a call to exit(1). +// +// Parameters: +// +// Ptr := Pointer to the caller's buffer to be re-allocated. +// +// Size := Size of new buffer. Size cannot be zero. +// +// File := Set to __FILE__ by macro expansion. +// +// Line := Set to __LINE__ by macro expansion. +// +// Returns: +// +// Pointer to new caller's buffer. +// +// --*/ +// +{ + MY_ALLOC_STRUCT *Tmp; + VOID *Buffer; + + // + // Check for invalid parameter(s). + // + if (Size == 0 || File == NULL || Line == 0) { + printf ( + "\nMyRealloc(Ptr=%xh, Size=%u, File=%xh, Line=%u)" + "\nInvalid parameter(s).\n", + Ptr, + Size, + File, + Line + ); + + exit (1); + } + + if (strlen (File) == 0) { + printf ( + "\nMyRealloc(Ptr=%xh, Size=%u, File=%s, Line=%u)" + "\nInvalid parameter.\n", + Ptr, + Size, + File, + Line + ); + + exit (1); + } + // + // Find existing buffer in allocation list. + // + if (Ptr == NULL) { + Tmp = NULL; + } else if (&MyAllocData->Buffer[sizeof (UINT32)] == Ptr) { + Tmp = MyAllocData; + } else { + for (Tmp = MyAllocData;; Tmp = Tmp->Next) { + if (Tmp->Next == NULL) { + printf ( + "\nMyRealloc(Ptr=%xh, Size=%u, File=%s, Line=%u)" + "\nCould not find buffer.\n", + Ptr, + Size, + File, + Line + ); + + exit (1); + } + + Tmp = Tmp->Next; + } + } + // + // Allocate new buffer, copy old data, free old buffer. + // + Buffer = MyAlloc (Size, File, Line); + + if (Buffer != NULL && Tmp != NULL) { + memcpy ( + Buffer, + &Tmp->Buffer[sizeof (UINT32)], + ((Size <= Tmp->Size) ? Size : Tmp->Size) + ); + + MyFree (Ptr, __FILE__, __LINE__); + } + + return Buffer; +} +// +// //////////////////////////////////////////////////////////////////////////// +// +// +VOID +MyFree ( + VOID *Ptr, + UINT8 File[], + UINTN Line + ) +// *++ +// Description: +// +// Release a previously allocated buffer. Invalid parameters will cause +// MyFree() to fail with an exit(1) call. +// +// Parameters: +// +// Ptr := Pointer to the caller's buffer to be freed. +// A NULL pointer will be ignored. +// +// File := Set to __FILE__ by macro expansion. +// +// Line := Set to __LINE__ by macro expansion. +// +// Returns: +// +// n/a +// +// --*/ +// +{ + MY_ALLOC_STRUCT *Tmp; + MY_ALLOC_STRUCT *Tmp2; + + // + // Check for invalid parameter(s). + // + if (File == NULL || Line == 0) { + printf ( + "\nMyFree(Ptr=%xh, File=%xh, Line=%u)" + "\nInvalid parameter(s).\n", + Ptr, + File, + Line + ); + + exit (1); + } + + if (strlen (File) == 0) { + printf ( + "\nMyFree(Ptr=%xh, File=%s, Line=%u)" + "\nInvalid parameter.\n", + Ptr, + File, + Line + ); + + exit (1); + } + // + // Freeing NULL is always valid. + // + if (Ptr == NULL) { + return ; + } + // + // Fail if nothing is allocated. + // + if (MyAllocData == NULL) { + printf ( + "\nMyFree(Ptr=%xh, File=%s, Line=%u)" + "\nCalled before memory allocated.\n", + Ptr, + File, + Line + ); + + exit (1); + } + // + // Check for corrupted allocation list. + // + MyCheck (0, __FILE__, __LINE__); + + // + // Need special check for first item in list. + // + if (&MyAllocData->Buffer[sizeof (UINT32)] == Ptr) { + // + // Unlink first item in list. + // + Tmp = MyAllocData; + MyAllocData = MyAllocData->Next; + } else { + // + // Walk list looking for matching item. + // + for (Tmp = MyAllocData;; Tmp = Tmp->Next) { + // + // Fail if end of list is reached. + // + if (Tmp->Next == NULL) { + printf ( + "\nMyFree(Ptr=%xh, File=%s, Line=%u)\n" + "\nNot found.\n", + Ptr, + File, + Line + ); + + exit (1); + } + // + // Leave loop when match is found. + // + if (&Tmp->Next->Buffer[sizeof (UINT32)] == Ptr) { + break; + } + } + // + // Unlink item from list. + // + Tmp2 = Tmp->Next; + Tmp->Next = Tmp->Next->Next; + Tmp = Tmp2; + } + // + // Release item. + // + free (Tmp); +} + +#endif /* USE_MYALLOC */ + +/* eof - MyAlloc.c */ diff --git a/Tools/CodeTools/Source/Common/MyAlloc.h b/Tools/CodeTools/Source/Common/MyAlloc.h new file mode 100644 index 0000000000..9697012d7d --- /dev/null +++ b/Tools/CodeTools/Source/Common/MyAlloc.h @@ -0,0 +1,222 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + MyAlloc.h + +Abstract: + + Header file for memory allocation tracking functions. + +--*/ + +#ifndef _MYALLOC_H_ +#define _MYALLOC_H_ + +#include +#include +#include + +#include + +// +// Default operation is to use the memory allocation tracking functions. +// To over-ride add "#define USE_MYALLOC 0" to your program header and/or +// source files as needed. Or, just do not include this header file in +// your project. +// +#ifndef USE_MYALLOC +#define USE_MYALLOC 1 +#endif + +#if USE_MYALLOC +// +// Replace C library allocation routines with MyAlloc routines. +// +#define malloc(size) MyAlloc ((size), __FILE__, __LINE__) +#define calloc(count, size) MyAlloc ((count) * (size), __FILE__, __LINE__) +#define realloc(ptr, size) MyRealloc ((ptr), (size), __FILE__, __LINE__) +#define free(ptr) MyFree ((ptr), __FILE__, __LINE__) +#define alloc_check(final) MyCheck ((final), __FILE__, __LINE__) + +// +// Structure for checking/tracking memory allocations. +// +typedef struct MyAllocStruct { + UINTN Cksum; + struct MyAllocStruct *Next; + UINTN Line; + UINTN Size; + UINT8 *File; + UINT8 *Buffer; +} MY_ALLOC_STRUCT; +// +// Cksum := (UINTN)This + (UINTN)Next + Line + Size + (UINTN)File + +// (UINTN)Buffer; +// +// Next := Pointer to next allocation structure in the list. +// +// Line := __LINE__ +// +// Size := Size of allocation request. +// +// File := Pointer to __FILE__ string stored immediately following +// MY_ALLOC_STRUCT in memory. +// +// Buffer := Pointer to UINT32 aligned storage immediately following +// the NULL terminated __FILE__ string. This is UINT32 +// aligned because the underflow signature is 32-bits and +// this will place the first caller address on a 64-bit +// boundary. +// +// +// Signatures used to check for buffer overflow/underflow conditions. +// +#define MYALLOC_HEAD_MAGIK 0xBADFACED +#define MYALLOC_TAIL_MAGIK 0xDEADBEEF + +VOID +MyCheck ( + BOOLEAN Final, + UINT8 File[], + UINTN Line + ) +; +// +// *++ +// Description: +// +// Check for corruptions in the allocated memory chain. If a corruption +// is detection program operation stops w/ an exit(1) call. +// +// Parameters: +// +// Final := When FALSE, MyCheck() returns if the allocated memory chain +// has not been corrupted. When TRUE, MyCheck() returns if there +// are no un-freed allocations. If there are un-freed allocations, +// they are displayed and exit(1) is called. +// +// +// File := Set to __FILE__ by macro expansion. +// +// Line := Set to __LINE__ by macro expansion. +// +// Returns: +// +// n/a +// +// --*/ +// +VOID * +MyAlloc ( + UINTN Size, + UINT8 File[], + UINTN Line + ) +; +// +// *++ +// Description: +// +// Allocate a new link in the allocation chain along with enough storage +// for the File[] string, requested Size and alignment overhead. If +// memory cannot be allocated or the allocation chain has been corrupted, +// exit(1) will be called. +// +// Parameters: +// +// Size := Number of bytes (UINT8) requested by the called. +// Size cannot be zero. +// +// File := Set to __FILE__ by macro expansion. +// +// Line := Set to __LINE__ by macro expansion. +// +// Returns: +// +// Pointer to the caller's buffer. +// +// --*/ +// +VOID * +MyRealloc ( + VOID *Ptr, + UINTN Size, + UINT8 File[], + UINTN Line + ) +; +// +// *++ +// Description: +// +// This does a MyAlloc(), memcpy() and MyFree(). There is no optimization +// for shrinking or expanding buffers. An invalid parameter will cause +// MyRealloc() to fail with a call to exit(1). +// +// Parameters: +// +// Ptr := Pointer to the caller's buffer to be re-allocated. +// Ptr cannot be NULL. +// +// Size := Size of new buffer. Size cannot be zero. +// +// File := Set to __FILE__ by macro expansion. +// +// Line := Set to __LINE__ by macro expansion. +// +// Returns: +// +// Pointer to new caller's buffer. +// +// --*/ +// +VOID +MyFree ( + VOID *Ptr, + UINT8 File[], + UINTN Line + ) +; +// +// *++ +// Description: +// +// Release a previously allocated buffer. Invalid parameters will cause +// MyFree() to fail with an exit(1) call. +// +// Parameters: +// +// Ptr := Pointer to the caller's buffer to be freed. +// A NULL pointer will be ignored. +// +// File := Set to __FILE__ by macro expansion. +// +// Line := Set to __LINE__ by macro expansion. +// +// Returns: +// +// n/a +// +// --*/ +// +#else /* USE_MYALLOC */ + +// +// Nothing to do when USE_MYALLOC is zero. +// +#define alloc_check(final) + +#endif /* USE_MYALLOC */ +#endif /* _MYALLOC_H_ */ + +/* eof - MyAlloc.h */ diff --git a/Tools/CodeTools/Source/Common/ParseInf.c b/Tools/CodeTools/Source/Common/ParseInf.c new file mode 100644 index 0000000000..de0ffd85c7 --- /dev/null +++ b/Tools/CodeTools/Source/Common/ParseInf.c @@ -0,0 +1,630 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + ParseInf.c + +Abstract: + + This contains some useful functions for parsing INF files. + +--*/ + +#include +#include +#include +#include +#include "ParseInf.h" + +#ifndef _MAX_PATH +#define _MAX_PATH 500 +#endif + +CHAR8 * +ReadLine ( + IN MEMORY_FILE *InputFile, + IN OUT CHAR8 *InputBuffer, + IN UINTN MaxLength + ) +/*++ + +Routine Description: + + This function reads a line, stripping any comments. + The function reads a string from the input stream argument and stores it in + the input string. ReadLine reads characters from the current file position + to and including the first newline character, to the end of the stream, or + until the number of characters read is equal to MaxLength - 1, whichever + comes first. The newline character, if read, is replaced with a \0. + +Arguments: + + InputFile Memory file image. + InputBuffer Buffer to read into, must be _MAX_PATH size. + MaxLength The maximum size of the input buffer. + +Returns: + + NULL if error or EOF + InputBuffer otherwise + +--*/ +{ + CHAR8 *CharPtr; + CHAR8 *EndOfLine; + UINTN CharsToCopy; + + // + // Verify input parameters are not null + // + assert (InputBuffer); + assert (InputFile->FileImage); + assert (InputFile->Eof); + assert (InputFile->CurrentFilePointer); + + // + // Check for end of file condition + // + if (InputFile->CurrentFilePointer >= InputFile->Eof) { + return NULL; + } + // + // Find the next newline char + // + EndOfLine = strchr (InputFile->CurrentFilePointer, '\n'); + + // + // Determine the number of characters to copy. + // + if (EndOfLine == 0) { + // + // If no newline found, copy to the end of the file. + // + CharsToCopy = InputFile->Eof - InputFile->CurrentFilePointer; + } else if (EndOfLine >= InputFile->Eof) { + // + // If the newline found was beyond the end of file, copy to the eof. + // + CharsToCopy = InputFile->Eof - InputFile->CurrentFilePointer; + } else { + // + // Newline found in the file. + // + CharsToCopy = EndOfLine - InputFile->CurrentFilePointer; + } + // + // If the end of line is too big for the current buffer, set it to the max + // size of the buffer (leaving room for the \0. + // + if (CharsToCopy > MaxLength - 1) { + CharsToCopy = MaxLength - 1; + } + // + // Copy the line. + // + memcpy (InputBuffer, InputFile->CurrentFilePointer, CharsToCopy); + + // + // Add the null termination over the 0x0D + // + InputBuffer[CharsToCopy - 1] = '\0'; + + // + // Increment the current file pointer (include the 0x0A) + // + InputFile->CurrentFilePointer += CharsToCopy + 1; + + // + // Strip any comments + // + CharPtr = strstr (InputBuffer, "//"); + if (CharPtr != 0) { + CharPtr[0] = 0; + } + // + // Return the string + // + return InputBuffer; +} + +BOOLEAN +FindSection ( + IN MEMORY_FILE *InputFile, + IN CHAR8 *Section + ) +/*++ + +Routine Description: + + This function parses a file from the beginning to find a section. + The section string may be anywhere within a line. + +Arguments: + + InputFile Memory file image. + Section Section to search for + +Returns: + + FALSE if error or EOF + TRUE if section found + +--*/ +{ + CHAR8 InputBuffer[_MAX_PATH]; + CHAR8 *CurrentToken; + + // + // Verify input is not NULL + // + assert (InputFile->FileImage); + assert (InputFile->Eof); + assert (InputFile->CurrentFilePointer); + assert (Section); + + // + // Rewind to beginning of file + // + InputFile->CurrentFilePointer = InputFile->FileImage; + + // + // Read lines until the section is found + // + while (InputFile->CurrentFilePointer < InputFile->Eof) { + // + // Read a line + // + ReadLine (InputFile, InputBuffer, _MAX_PATH); + + // + // Check if the section is found + // + CurrentToken = strstr (InputBuffer, Section); + if (CurrentToken != NULL) { + return TRUE; + } + } + + return FALSE; +} + +EFI_STATUS +FindToken ( + IN MEMORY_FILE *InputFile, + IN CHAR8 *Section, + IN CHAR8 *Token, + IN UINTN Instance, + OUT CHAR8 *Value + ) +/*++ + +Routine Description: + + Finds a token value given the section and token to search for. + +Arguments: + + InputFile Memory file image. + Section The section to search for, a string within []. + Token The token to search for, e.g. EFI_PEIM_RECOVERY, followed by an = in the INF file. + Instance The instance of the token to search for. Zero is the first instance. + Value The string that holds the value following the =. Must be _MAX_PATH in size. + +Returns: + + EFI_SUCCESS Value found. + EFI_ABORTED Format error detected in INF file. + EFI_INVALID_PARAMETER Input argument was null. + EFI_LOAD_ERROR Error reading from the file. + EFI_NOT_FOUND Section/Token/Value not found. + +--*/ +{ + CHAR8 InputBuffer[_MAX_PATH]; + CHAR8 *CurrentToken; + BOOLEAN ParseError; + BOOLEAN ReadError; + UINTN Occurrance; + + // + // Check input parameters + // + if (InputFile->FileImage == NULL || + InputFile->Eof == NULL || + InputFile->CurrentFilePointer == NULL || + Section == NULL || + strlen (Section) == 0 || + Token == NULL || + strlen (Token) == 0 || + Value == NULL + ) { + return EFI_INVALID_PARAMETER; + } + // + // Initialize error codes + // + ParseError = FALSE; + ReadError = FALSE; + + // + // Initialize our instance counter for the search token + // + Occurrance = 0; + + if (FindSection (InputFile, Section)) { + // + // Found the desired section, find and read the desired token + // + do { + // + // Read a line from the file + // + if (ReadLine (InputFile, InputBuffer, _MAX_PATH) == NULL) { + // + // Error reading from input file + // + ReadError = TRUE; + break; + } + // + // Get the first non-whitespace string + // + CurrentToken = strtok (InputBuffer, " \t\n"); + if (CurrentToken == NULL) { + // + // Whitespace line found (or comment) so continue + // + CurrentToken = InputBuffer; + continue; + } + // + // Make sure we have not reached the end of the current section + // + if (CurrentToken[0] == '[') { + break; + } + // + // Compare the current token with the desired token + // + if (strcmp (CurrentToken, Token) == 0) { + // + // Found it + // + // + // Check if it is the correct instance + // + if (Instance == Occurrance) { + // + // Copy the contents following the = + // + CurrentToken = strtok (NULL, "= \t\n"); + if (CurrentToken == NULL) { + // + // Nothing found, parsing error + // + ParseError = TRUE; + } else { + // + // Copy the current token to the output value + // + strcpy (Value, CurrentToken); + return EFI_SUCCESS; + } + } else { + // + // Increment the occurrance found + // + Occurrance++; + } + } + } while ( + !ParseError && + !ReadError && + InputFile->CurrentFilePointer < InputFile->Eof && + CurrentToken[0] != '[' && + Occurrance <= Instance + ); + } + // + // Distinguish between read errors and INF file format errors. + // + if (ReadError) { + return EFI_LOAD_ERROR; + } + + if (ParseError) { + return EFI_ABORTED; + } + + return EFI_NOT_FOUND; +} + +EFI_STATUS +StringToGuid ( + IN CHAR8 *AsciiGuidBuffer, + OUT EFI_GUID *GuidBuffer + ) +/*++ + +Routine Description: + + Converts a string to an EFI_GUID. The string must be in the + xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format. + +Arguments: + + AsciiGuidBuffer - pointer to ascii string + GuidBuffer - pointer to destination Guid + +Returns: + + EFI_ABORTED Could not convert the string + EFI_SUCCESS The string was successfully converted + EFI_INVALID_PARAMETER Input parameter is invalid. + +--*/ +{ + INT32 Index; + UINTN Data1; + UINTN Data2; + UINTN Data3; + UINTN Data4[8]; + + if (AsciiGuidBuffer == NULL || GuidBuffer == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Scan the guid string into the buffer + // + Index = sscanf ( + AsciiGuidBuffer, + "%08x-%04x-%04x-%02x%02x-%02hx%02hx%02hx%02hx%02hx%02hx", + &Data1, + &Data2, + &Data3, + &Data4[0], + &Data4[1], + &Data4[2], + &Data4[3], + &Data4[4], + &Data4[5], + &Data4[6], + &Data4[7] + ); + + // + // Verify the correct number of items were scanned. + // + if (Index != 11) { + printf ("ERROR: Malformed GUID \"%s\".\n\n", AsciiGuidBuffer); + return EFI_ABORTED; + } + // + // Copy the data into our GUID. + // + GuidBuffer->Data1 = (UINT32) Data1; + GuidBuffer->Data2 = (UINT16) Data2; + GuidBuffer->Data3 = (UINT16) Data3; + GuidBuffer->Data4[0] = (UINT8) Data4[0]; + GuidBuffer->Data4[1] = (UINT8) Data4[1]; + GuidBuffer->Data4[2] = (UINT8) Data4[2]; + GuidBuffer->Data4[3] = (UINT8) Data4[3]; + GuidBuffer->Data4[4] = (UINT8) Data4[4]; + GuidBuffer->Data4[5] = (UINT8) Data4[5]; + GuidBuffer->Data4[6] = (UINT8) Data4[6]; + GuidBuffer->Data4[7] = (UINT8) Data4[7]; + + return EFI_SUCCESS; +} + +EFI_STATUS +AsciiStringToUint64 ( + IN CONST CHAR8 *AsciiString, + IN BOOLEAN IsHex, + OUT UINT64 *ReturnValue + ) +/*++ + +Routine Description: + + Converts a null terminated ascii string that represents a number into a + UINT64 value. A hex number may be preceeded by a 0x, but may not be + succeeded by an h. A number without 0x or 0X is considered to be base 10 + unless the IsHex input is true. + +Arguments: + + AsciiString The string to convert. + IsHex Force the string to be treated as a hex number. + ReturnValue The return value. + +Returns: + + EFI_SUCCESS Number successfully converted. + EFI_ABORTED Invalid character encountered. + +--*/ +{ + UINT8 Index; + UINT64 HexNumber; + CHAR8 CurrentChar; + + // + // Initialize the result + // + HexNumber = 0; + + // + // Add each character to the result + // + if (IsHex || (AsciiString[0] == '0' && (AsciiString[1] == 'x' || AsciiString[1] == 'X'))) { + // + // Verify string is a hex number + // + for (Index = 2; Index < strlen (AsciiString); Index++) { + if (isxdigit (AsciiString[Index]) == 0) { + return EFI_ABORTED; + } + } + // + // Convert the hex string. + // + for (Index = 2; AsciiString[Index] != '\0'; Index++) { + CurrentChar = AsciiString[Index]; + HexNumber *= 16; + if (CurrentChar >= '0' && CurrentChar <= '9') { + HexNumber += CurrentChar - '0'; + } else if (CurrentChar >= 'a' && CurrentChar <= 'f') { + HexNumber += CurrentChar - 'a' + 10; + } else if (CurrentChar >= 'A' && CurrentChar <= 'F') { + HexNumber += CurrentChar - 'A' + 10; + } else { + // + // Unrecognized character + // + return EFI_ABORTED; + } + } + + *ReturnValue = HexNumber; + } else { + // + // Verify string is a number + // + for (Index = 0; Index < strlen (AsciiString); Index++) { + if (isdigit (AsciiString[Index]) == 0) { + return EFI_ABORTED; + } + } + + *ReturnValue = atol (AsciiString); + } + + return EFI_SUCCESS; +}; + +CHAR8 * +ReadLineInStream ( + IN FILE *InputFile, + IN OUT CHAR8 *InputBuffer + ) +/*++ + +Routine Description: + + This function reads a line, stripping any comments. + // BUGBUG: This is obsolete once genmake goes away... + +Arguments: + + InputFile Stream pointer. + InputBuffer Buffer to read into, must be _MAX_PATH size. + +Returns: + + NULL if error or EOF + InputBuffer otherwise + +--*/ +{ + CHAR8 *CharPtr; + + // + // Verify input parameters are not null + // + assert (InputFile); + assert (InputBuffer); + + // + // Read a line + // + if (fgets (InputBuffer, _MAX_PATH, InputFile) == NULL) { + return NULL; + } + // + // Strip any comments + // + CharPtr = strstr (InputBuffer, "//"); + if (CharPtr != 0) { + CharPtr[0] = 0; + } + + CharPtr = strstr (InputBuffer, "#"); + if (CharPtr != 0) { + CharPtr[0] = 0; + } + // + // Return the string + // + return InputBuffer; +} + +BOOLEAN +FindSectionInStream ( + IN FILE *InputFile, + IN CHAR8 *Section + ) +/*++ + +Routine Description: + + This function parses a stream file from the beginning to find a section. + The section string may be anywhere within a line. + // BUGBUG: This is obsolete once genmake goes away... + +Arguments: + + InputFile Stream pointer. + Section Section to search for + +Returns: + + FALSE if error or EOF + TRUE if section found + +--*/ +{ + CHAR8 InputBuffer[_MAX_PATH]; + CHAR8 *CurrentToken; + + // + // Verify input is not NULL + // + assert (InputFile); + assert (Section); + + // + // Rewind to beginning of file + // + if (fseek (InputFile, 0, SEEK_SET) != 0) { + return FALSE; + } + // + // Read lines until the section is found + // + while (feof (InputFile) == 0) { + // + // Read a line + // + ReadLineInStream (InputFile, InputBuffer); + + // + // Check if the section is found + // + CurrentToken = strstr (InputBuffer, Section); + if (CurrentToken != NULL) { + return TRUE; + } + } + + return FALSE; +} diff --git a/Tools/CodeTools/Source/Common/ParseInf.h b/Tools/CodeTools/Source/Common/ParseInf.h new file mode 100644 index 0000000000..ff986352c6 --- /dev/null +++ b/Tools/CodeTools/Source/Common/ParseInf.h @@ -0,0 +1,234 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + ParseInf.h + +Abstract: + + Header file for helper functions useful for parsing INF files. + +--*/ + +#ifndef _EFI_PARSE_INF_H +#define _EFI_PARSE_INF_H + +#include +#include + +#include + +// +// Common data structures +// +typedef struct { + CHAR8 *FileImage; + CHAR8 *Eof; + CHAR8 *CurrentFilePointer; +} MEMORY_FILE; + +// +// Functions declarations +// +CHAR8 * +ReadLine ( + IN MEMORY_FILE *InputFile, + IN OUT CHAR8 *InputBuffer, + IN UINTN MaxLength + ) +; + +/*++ + +Routine Description: + + This function reads a line, stripping any comments. + The function reads a string from the input stream argument and stores it in + the input string. ReadLine reads characters from the current file position + to and including the first newline character, to the end of the stream, or + until the number of characters read is equal to MaxLength - 1, whichever + comes first. The newline character, if read, is replaced with a \0. + +Arguments: + + InputFile Memory file image. + InputBuffer Buffer to read into, must be _MAX_PATH size. + MaxLength The maximum size of the input buffer. + +Returns: + + NULL if error or EOF + InputBuffer otherwise + +--*/ +BOOLEAN +FindSection ( + IN MEMORY_FILE *InputFile, + IN CHAR8 *Section + ) +; + +/*++ + +Routine Description: + + This function parses a file from the beginning to find a section. + The section string may be anywhere within a line. + +Arguments: + + InputFile Memory file image. + Section Section to search for + +Returns: + + FALSE if error or EOF + TRUE if section found + +--*/ +EFI_STATUS +FindToken ( + IN MEMORY_FILE *InputFile, + IN CHAR8 *Section, + IN CHAR8 *Token, + IN UINTN Instance, + OUT CHAR8 *Value + ) +; + +/*++ + +Routine Description: + + Finds a token value given the section and token to search for. + +Arguments: + + InputFile Memory file image. + Section The section to search for, a string within []. + Token The token to search for, e.g. EFI_PEIM_RECOVERY, followed by an = in the INF file. + Instance The instance of the token to search for. Zero is the first instance. + Value The string that holds the value following the =. Must be _MAX_PATH in size. + +Returns: + + EFI_SUCCESS Value found. + EFI_ABORTED Format error detected in INF file. + EFI_INVALID_PARAMETER Input argument was null. + EFI_LOAD_ERROR Error reading from the file. + EFI_NOT_FOUND Section/Token/Value not found. + +--*/ +EFI_STATUS +StringToGuid ( + IN CHAR8 *AsciiGuidBuffer, + OUT EFI_GUID *GuidBuffer + ) +; + +/*++ + +Routine Description: + + Converts a string to an EFI_GUID. The string must be in the + xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format. + +Arguments: + + GuidBuffer - pointer to destination Guid + AsciiGuidBuffer - pointer to ascii string + +Returns: + + EFI_ABORTED Could not convert the string + EFI_SUCCESS The string was successfully converted + +--*/ +EFI_STATUS +AsciiStringToUint64 ( + IN CONST CHAR8 *AsciiString, + IN BOOLEAN IsHex, + OUT UINT64 *ReturnValue + ) +; + +/*++ + +Routine Description: + + Converts a null terminated ascii string that represents a number into a + UINT64 value. A hex number may be preceeded by a 0x, but may not be + succeeded by an h. A number without 0x or 0X is considered to be base 10 + unless the IsHex input is true. + +Arguments: + + AsciiString The string to convert. + IsHex Force the string to be treated as a hex number. + ReturnValue The return value. + +Returns: + + EFI_SUCCESS Number successfully converted. + EFI_ABORTED Invalid character encountered. + +--*/ +CHAR8 * +ReadLineInStream ( + IN FILE *InputFile, + IN OUT CHAR8 *InputBuffer + ) +; + +/*++ + +Routine Description: + + This function reads a line, stripping any comments. + +Arguments: + + InputFile Stream pointer. + InputBuffer Buffer to read into, must be _MAX_PATH size. + +Returns: + + NULL if error or EOF + InputBuffer otherwise + +--*/ +BOOLEAN +FindSectionInStream ( + IN FILE *InputFile, + IN CHAR8 *Section + ) +; + +/*++ + +Routine Description: + + This function parses a stream file from the beginning to find a section. + The section string may be anywhere within a line. + +Arguments: + + InputFile Stream pointer. + Section Section to search for + +Returns: + + FALSE if error or EOF + TRUE if section found + +--*/ +#endif diff --git a/Tools/CodeTools/Source/Common/SimpleFileParsing.c b/Tools/CodeTools/Source/Common/SimpleFileParsing.c new file mode 100644 index 0000000000..73b74cd0ff --- /dev/null +++ b/Tools/CodeTools/Source/Common/SimpleFileParsing.c @@ -0,0 +1,1457 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + SimpleFileParsing.c + +Abstract: + + Generic but simple file parsing routines. + +--*/ + +#include +#include +#include +#include + +#include "EfiUtilityMsgs.h" +#include "SimpleFileParsing.h" + +#ifndef MAX_PATH +#define MAX_PATH 255 +#endif +// +// just in case we get in an endless loop. +// +#define MAX_NEST_DEPTH 20 +// +// number of wchars +// +#define MAX_STRING_IDENTIFIER_NAME 100 + +#define MAX_LINE_LEN 400 + +#define T_CHAR_SPACE ' ' +#define T_CHAR_NULL 0 +#define T_CHAR_CR '\r' +#define T_CHAR_TAB '\t' +#define T_CHAR_LF '\n' +#define T_CHAR_SLASH '/' +#define T_CHAR_BACKSLASH '\\' +#define T_CHAR_DOUBLE_QUOTE '"' +#define T_CHAR_LC_X 'x' +#define T_CHAR_0 '0' +#define T_CHAR_STAR '*' + +// +// We keep a linked list of these for the source files we process +// +typedef struct _SOURCE_FILE { + FILE *Fptr; + T_CHAR *FileBuffer; + T_CHAR *FileBufferPtr; + unsigned int FileSize; + char FileName[MAX_PATH]; + unsigned int LineNum; + BOOLEAN EndOfFile; + BOOLEAN SkipToHash; + struct _SOURCE_FILE *Previous; + struct _SOURCE_FILE *Next; + T_CHAR ControlCharacter; +} SOURCE_FILE; + +typedef struct { + T_CHAR *FileBufferPtr; +} FILE_POSITION; + +// +// Keep all our module globals in this structure +// +static struct { + SOURCE_FILE SourceFile; + BOOLEAN VerboseFile; + BOOLEAN VerboseToken; +} mGlobals; + +static +unsigned int +t_strcmp ( + T_CHAR *Buffer, + T_CHAR *Str + ); + +static +unsigned int +t_strncmp ( + T_CHAR *Str1, + T_CHAR *Str2, + int Len + ); + +static +unsigned int +t_strlen ( + T_CHAR *Str + ); + +static +void +RewindFile ( + SOURCE_FILE *SourceFile + ); + +static +BOOLEAN +IsWhiteSpace ( + SOURCE_FILE *SourceFile + ); + +static +unsigned int +SkipWhiteSpace ( + SOURCE_FILE *SourceFile + ); + +static +BOOLEAN +EndOfFile ( + SOURCE_FILE *SourceFile + ); + +static +void +PreprocessFile ( + SOURCE_FILE *SourceFile + ); + +static +T_CHAR * +t_strcpy ( + T_CHAR *Dest, + T_CHAR *Src + ); + +static +STATUS +ProcessIncludeFile ( + SOURCE_FILE *SourceFile, + SOURCE_FILE *ParentSourceFile + ); + +static +STATUS +ParseFile ( + SOURCE_FILE *SourceFile + ); + +static +FILE * +FindFile ( + char *FileName, + char *FoundFileName, + unsigned int FoundFileNameLen + ); + +static +STATUS +ProcessFile ( + SOURCE_FILE *SourceFile + ); + +static +STATUS +GetFilePosition ( + FILE_POSITION *Fpos + ); + +static +STATUS +SetFilePosition ( + FILE_POSITION *Fpos + ); + +STATUS +SFPInit ( + VOID + ) +/*++ + +Routine Description: + +Arguments: + None. + +Returns: + STATUS_SUCCESS always + +--*/ +{ + memset ((void *) &mGlobals, 0, sizeof (mGlobals)); + return STATUS_SUCCESS; +} + +unsigned +int +SFPGetLineNumber ( + VOID + ) +/*++ + +Routine Description: + Return the line number of the file we're parsing. Used + for error reporting purposes. + +Arguments: + None. + +Returns: + The line number, or 0 if no file is being processed + +--*/ +{ + return mGlobals.SourceFile.LineNum; +} + +T_CHAR * +SFPGetFileName ( + VOID + ) +/*++ + +Routine Description: + Return the name of the file we're parsing. Used + for error reporting purposes. + +Arguments: + None. + +Returns: + A pointer to the file name. Null if no file is being + processed. + +--*/ +{ + if (mGlobals.SourceFile.FileName[0]) { + return mGlobals.SourceFile.FileName; + } + + return NULL; +} + +STATUS +SFPOpenFile ( + char *FileName + ) +/*++ + +Routine Description: + Open a file for parsing. + +Arguments: + FileName - name of the file to parse + +Returns: + + +--*/ +{ + STATUS Status; + t_strcpy (mGlobals.SourceFile.FileName, FileName); + Status = ProcessIncludeFile (&mGlobals.SourceFile, NULL); + return Status; +} + +BOOLEAN +SFPIsToken ( + T_CHAR *Str + ) +/*++ + +Routine Description: + Check to see if the specified token is found at + the current position in the input file. + +Arguments: + Str - the token to look for + +Returns: + TRUE - the token is next + FALSE - the token is not next + +Notes: + We do a simple string comparison on this function. It is + the responsibility of the caller to ensure that the token + is not a subset of some other token. + + The file pointer is advanced past the token in the input file. + +--*/ +{ + unsigned int Len; + SkipWhiteSpace (&mGlobals.SourceFile); + if (EndOfFile (&mGlobals.SourceFile)) { + return FALSE; + } + + if ((Len = t_strcmp (mGlobals.SourceFile.FileBufferPtr, Str)) > 0) { + mGlobals.SourceFile.FileBufferPtr += Len; + if (mGlobals.VerboseToken) { + printf ("Token: '%s'\n", Str); + } + + return TRUE; + } + + return FALSE; +} + +BOOLEAN +SFPIsKeyword ( + T_CHAR *Str + ) +/*++ + +Routine Description: + Check to see if the specified keyword is found at + the current position in the input file. + +Arguments: + Str - keyword to look for + +Returns: + TRUE - the keyword is next + FALSE - the keyword is not next + +Notes: + A keyword is defined as a "special" string that has a non-alphanumeric + character following it. + +--*/ +{ + unsigned int Len; + SkipWhiteSpace (&mGlobals.SourceFile); + if (EndOfFile (&mGlobals.SourceFile)) { + return FALSE; + } + + if ((Len = t_strcmp (mGlobals.SourceFile.FileBufferPtr, Str)) > 0) { + if (isalnum (mGlobals.SourceFile.FileBufferPtr[Len])) { + return FALSE; + } + + mGlobals.SourceFile.FileBufferPtr += Len; + if (mGlobals.VerboseToken) { + printf ("Token: '%s'\n", Str); + } + + return TRUE; + } + + return FALSE; +} + +BOOLEAN +SFPGetNextToken ( + T_CHAR *Str, + unsigned int Len + ) +/*++ + +Routine Description: + Get the next token from the input stream. + +Arguments: + Str - pointer to a copy of the next token + Len - size of buffer pointed to by Str + +Returns: + TRUE - next token successfully returned + FALSE - otherwise + +Notes: + Preceeding white space is ignored. + The parser's buffer pointer is advanced past the end of the + token. + +--*/ +{ + unsigned int Index; + T_CHAR TempChar; + + SkipWhiteSpace (&mGlobals.SourceFile); + if (EndOfFile (&mGlobals.SourceFile)) { + return FALSE; + } + // + // Have to have enough string for at least one char and a null-terminator + // + if (Len < 2) { + return FALSE; + } + // + // Look at the first character. If it's an identifier, then treat it + // as such + // + TempChar = mGlobals.SourceFile.FileBufferPtr[0]; + if (((TempChar >= 'a') && (TempChar <= 'z')) || ((TempChar >= 'A') && (TempChar <= 'Z')) || (TempChar == '_')) { + Str[0] = TempChar; + mGlobals.SourceFile.FileBufferPtr++; + Index = 1; + while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) { + TempChar = mGlobals.SourceFile.FileBufferPtr[0]; + if (((TempChar >= 'a') && (TempChar <= 'z')) || + ((TempChar >= 'A') && (TempChar <= 'Z')) || + ((TempChar >= '0') && (TempChar <= '9')) || + (TempChar == '_') + ) { + Str[Index] = mGlobals.SourceFile.FileBufferPtr[0]; + mGlobals.SourceFile.FileBufferPtr++; + Index++; + } else { + // + // Invalid character for symbol name, so break out + // + break; + } + } + // + // Null terminate and return success + // + Str[Index] = 0; + return TRUE; + } else if ((TempChar == ')') || (TempChar == '(') || (TempChar == '*')) { + Str[0] = mGlobals.SourceFile.FileBufferPtr[0]; + mGlobals.SourceFile.FileBufferPtr++; + Str[1] = 0; + return TRUE; + } else { + // + // Everything else is white-space (or EOF) separated + // + Index = 0; + while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) { + if (IsWhiteSpace (&mGlobals.SourceFile)) { + if (Index > 0) { + Str[Index] = 0; + return TRUE; + } + + return FALSE; + } else { + Str[Index] = mGlobals.SourceFile.FileBufferPtr[0]; + mGlobals.SourceFile.FileBufferPtr++; + Index++; + } + } + // + // See if we just ran out of file contents, but did find a token + // + if ((Index > 0) && EndOfFile (&mGlobals.SourceFile)) { + Str[Index] = 0; + return TRUE; + } + } + + return FALSE; +} + +BOOLEAN +SFPGetGuidToken ( + T_CHAR *Str, + UINT32 Len + ) +/*++ + +Routine Description: + Parse a GUID from the input stream. Stop when you discover white space. + +Arguments: + Str - pointer to a copy of the next token + Len - size of buffer pointed to by Str + +Returns: + TRUE - GUID string returned successfully + FALSE - otherwise + +--*/ +{ + UINT32 Index; + SkipWhiteSpace (&mGlobals.SourceFile); + if (EndOfFile (&mGlobals.SourceFile)) { + return FALSE; + } + + Index = 0; + while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) { + if (IsWhiteSpace (&mGlobals.SourceFile)) { + if (Index > 0) { + Str[Index] = 0; + return TRUE; + } + + return FALSE; + } else { + Str[Index] = mGlobals.SourceFile.FileBufferPtr[0]; + mGlobals.SourceFile.FileBufferPtr++; + Index++; + } + } + + return FALSE; +} + +BOOLEAN +SFPSkipToToken ( + T_CHAR *Str + ) +{ + unsigned int Len; + T_CHAR *SavePos; + Len = t_strlen (Str); + SavePos = mGlobals.SourceFile.FileBufferPtr; + SkipWhiteSpace (&mGlobals.SourceFile); + while (!EndOfFile (&mGlobals.SourceFile)) { + if (t_strncmp (Str, mGlobals.SourceFile.FileBufferPtr, Len) == 0) { + mGlobals.SourceFile.FileBufferPtr += Len; + return TRUE; + } + + mGlobals.SourceFile.FileBufferPtr++; + SkipWhiteSpace (&mGlobals.SourceFile); + } + + mGlobals.SourceFile.FileBufferPtr = SavePos; + return FALSE; +} + +BOOLEAN +SFPGetNumber ( + unsigned int *Value + ) +/*++ + +Routine Description: + Check the token at the current file position for a numeric value. + May be either decimal or hex. + +Arguments: + Value - pointer where to store the value + +Returns: + FALSE - current token is not a number + TRUE - current token is a number + +--*/ +{ + SkipWhiteSpace (&mGlobals.SourceFile); + if (EndOfFile (&mGlobals.SourceFile)) { + return FALSE; + } + + if (isdigit (mGlobals.SourceFile.FileBufferPtr[0])) { + // + // Check for hex value + // + if ((mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_0) && (mGlobals.SourceFile.FileBufferPtr[1] == T_CHAR_LC_X)) { + if (!isxdigit (mGlobals.SourceFile.FileBufferPtr[2])) { + return FALSE; + } + + mGlobals.SourceFile.FileBufferPtr += 2; + sscanf (mGlobals.SourceFile.FileBufferPtr, "%x", Value); + while (isxdigit (mGlobals.SourceFile.FileBufferPtr[0])) { + mGlobals.SourceFile.FileBufferPtr++; + } + + return TRUE; + } else { + *Value = atoi (mGlobals.SourceFile.FileBufferPtr); + while (isdigit (mGlobals.SourceFile.FileBufferPtr[0])) { + mGlobals.SourceFile.FileBufferPtr++; + } + + return TRUE; + } + } else { + return FALSE; + } +} + +STATUS +SFPCloseFile ( + VOID + ) +/*++ + +Routine Description: + Close the file being parsed. + +Arguments: + None. + +Returns: + STATUS_SUCCESS - the file was closed + STATUS_ERROR - no file is currently open + +--*/ +{ + if (mGlobals.SourceFile.FileBuffer != NULL) { + free (mGlobals.SourceFile.FileBuffer); + memset (&mGlobals.SourceFile, 0, sizeof (mGlobals.SourceFile)); + return STATUS_SUCCESS; + } + + return STATUS_ERROR; +} + +static +STATUS +ProcessIncludeFile ( + SOURCE_FILE *SourceFile, + SOURCE_FILE *ParentSourceFile + ) +/*++ + +Routine Description: + + Given a source file, open the file and parse it + +Arguments: + + SourceFile - name of file to parse + ParentSourceFile - for error reporting purposes, the file that #included SourceFile. + +Returns: + + Standard status. + +--*/ +{ + static unsigned int NestDepth = 0; + char FoundFileName[MAX_PATH]; + STATUS Status; + + Status = STATUS_SUCCESS; + NestDepth++; + // + // Print the file being processed. Indent so you can tell the include nesting + // depth. + // + if (mGlobals.VerboseFile) { + fprintf (stdout, "%*cProcessing file '%s'\n", NestDepth * 2, ' ', SourceFile->FileName); + fprintf (stdout, "Parent source file = '%s'\n", ParentSourceFile); + } + + // + // Make sure we didn't exceed our maximum nesting depth + // + if (NestDepth > MAX_NEST_DEPTH) { + Error (NULL, 0, 0, SourceFile->FileName, "max nesting depth (%d) exceeded", NestDepth); + Status = STATUS_ERROR; + goto Finish; + } + // + // Try to open the file locally, and if that fails try along our include paths. + // + strcpy (FoundFileName, SourceFile->FileName); + if ((SourceFile->Fptr = fopen (FoundFileName, "rb")) == NULL) { + return STATUS_ERROR; + } + // + // Process the file found + // + ProcessFile (SourceFile); +Finish: + // + // Close open files and return status + // + if (SourceFile->Fptr != NULL) { + fclose (SourceFile->Fptr); + SourceFile->Fptr = NULL; + } + + return Status; +} + +static +STATUS +ProcessFile ( + SOURCE_FILE *SourceFile + ) +/*++ + +Routine Description: + + Given a source file that's been opened, read the contents into an internal + buffer and pre-process it to remove comments. + +Arguments: + + SourceFile - structure containing info on the file to process + +Returns: + + Standard status. + +--*/ +{ + // + // Get the file size, and then read the entire thing into memory. + // Allocate extra space for a terminator character. + // + fseek (SourceFile->Fptr, 0, SEEK_END); + SourceFile->FileSize = ftell (SourceFile->Fptr); + if (mGlobals.VerboseFile) { + printf ("FileSize = %d (0x%X)\n", SourceFile->FileSize, SourceFile->FileSize); + } + + fseek (SourceFile->Fptr, 0, SEEK_SET); + SourceFile->FileBuffer = (T_CHAR *) malloc (SourceFile->FileSize + sizeof (T_CHAR)); + if (SourceFile->FileBuffer == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + fread ((void *) SourceFile->FileBuffer, SourceFile->FileSize, 1, SourceFile->Fptr); + SourceFile->FileBuffer[(SourceFile->FileSize / sizeof (T_CHAR))] = T_CHAR_NULL; + // + // Pre-process the file to replace comments with spaces + // + PreprocessFile (SourceFile); + SourceFile->LineNum = 1; + return STATUS_SUCCESS; +} + +static +void +PreprocessFile ( + SOURCE_FILE *SourceFile + ) +/*++ + +Routine Description: + Preprocess a file to replace all carriage returns with NULLs so + we can print lines (as part of error messages) from the file to the screen. + +Arguments: + SourceFile - structure that we use to keep track of an input file. + +Returns: + Nothing. + +--*/ +{ + BOOLEAN InComment; + BOOLEAN SlashSlashComment; + int LineNum; + + RewindFile (SourceFile); + InComment = FALSE; + SlashSlashComment = FALSE; + while (!EndOfFile (SourceFile)) { + // + // If a line-feed, then no longer in a comment if we're in a // comment + // + if (SourceFile->FileBufferPtr[0] == T_CHAR_LF) { + SourceFile->FileBufferPtr++; + SourceFile->LineNum++; + if (InComment && SlashSlashComment) { + InComment = FALSE; + SlashSlashComment = FALSE; + } + } else if (SourceFile->FileBufferPtr[0] == T_CHAR_CR) { + // + // Replace all carriage returns with a NULL so we can print stuff + // + SourceFile->FileBufferPtr[0] = 0; + SourceFile->FileBufferPtr++; + // + // Check for */ comment end + // + } else if (InComment && + !SlashSlashComment && + (SourceFile->FileBufferPtr[0] == T_CHAR_STAR) && + (SourceFile->FileBufferPtr[1] == T_CHAR_SLASH) + ) { + SourceFile->FileBufferPtr[0] = T_CHAR_SPACE; + SourceFile->FileBufferPtr++; + SourceFile->FileBufferPtr[0] = T_CHAR_SPACE; + SourceFile->FileBufferPtr++; + InComment = FALSE; + } else if (InComment) { + SourceFile->FileBufferPtr[0] = T_CHAR_SPACE; + SourceFile->FileBufferPtr++; + // + // Check for // comments + // + } else if ((SourceFile->FileBufferPtr[0] == T_CHAR_SLASH) && (SourceFile->FileBufferPtr[1] == T_CHAR_SLASH)) { + InComment = TRUE; + SlashSlashComment = TRUE; + // + // Check for /* comment start + // + } else if ((SourceFile->FileBufferPtr[0] == T_CHAR_SLASH) && (SourceFile->FileBufferPtr[1] == T_CHAR_STAR)) { + SourceFile->FileBufferPtr[0] = T_CHAR_SPACE; + SourceFile->FileBufferPtr++; + SourceFile->FileBufferPtr[0] = T_CHAR_SPACE; + SourceFile->FileBufferPtr++; + SlashSlashComment = FALSE; + InComment = TRUE; + } else { + SourceFile->FileBufferPtr++; + } + } + // + // Could check for end-of-file and still in a comment, but + // should not be necessary. So just restore the file pointers. + // + RewindFile (SourceFile); + // + // Dump the reformatted file if verbose mode + // + if (mGlobals.VerboseFile) { + LineNum = 1; + printf ("%04d: ", LineNum); + while (!EndOfFile (SourceFile)) { + if (SourceFile->FileBufferPtr[0] == T_CHAR_LF) { + printf ("'\n%04d: '", ++LineNum); + } else { + printf ("%c", SourceFile->FileBufferPtr[0]); + } + + SourceFile->FileBufferPtr++; + } + + printf ("'\n"); + printf ("FileSize = %d (0x%X)\n", SourceFile->FileSize, SourceFile->FileSize); + RewindFile (SourceFile); + } +} + +BOOLEAN +SFPGetQuotedString ( + T_CHAR *Str, + int Length + ) +/*++ + +Routine Description: + Retrieve a quoted-string from the input file. + +Arguments: + Str - pointer to a copy of the quoted string parsed + Length - size of buffer pointed to by Str + +Returns: + TRUE - next token in input stream was a quoted string, and + the string value was returned in Str + FALSE - otherwise + +--*/ +{ + SkipWhiteSpace (&mGlobals.SourceFile); + if (EndOfFile (&mGlobals.SourceFile)) { + return FALSE; + } + + if (mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) { + mGlobals.SourceFile.FileBufferPtr++; + while (Length > 0) { + if (EndOfFile (&mGlobals.SourceFile)) { + return FALSE; + } + // + // Check for closing quote + // + if (mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) { + mGlobals.SourceFile.FileBufferPtr++; + *Str = 0; + return TRUE; + } + + *Str = mGlobals.SourceFile.FileBufferPtr[0]; + Str++; + Length--; + mGlobals.SourceFile.FileBufferPtr++; + } + } + // + // First character was not a quote, or the input string length was + // insufficient to contain the quoted string, so return failure code. + // + return FALSE; +} + +BOOLEAN +SFPIsEOF ( + VOID + ) +/*++ + +Routine Description: + Return TRUE of FALSE to indicate whether or not we've reached the end of the + file we're parsing. + +Arguments: + NA + +Returns: + TRUE - EOF reached + FALSE - otherwise + +--*/ +{ + SkipWhiteSpace (&mGlobals.SourceFile); + return EndOfFile (&mGlobals.SourceFile); +} + +#if 0 +static +T_CHAR * +GetQuotedString ( + SOURCE_FILE *SourceFile, + BOOLEAN Optional + ) +{ + T_CHAR *String; + T_CHAR *Start; + T_CHAR *Ptr; + unsigned int Len; + BOOLEAN PreviousBackslash; + + if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) { + if (Optional == FALSE) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted string", "%S", SourceFile->FileBufferPtr); + } + + return NULL; + } + + Len = 0; + SourceFile->FileBufferPtr++; + Start = Ptr = SourceFile->FileBufferPtr; + PreviousBackslash = FALSE; + while (!EndOfFile (SourceFile)) { + if ((SourceFile->FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) && (PreviousBackslash == FALSE)) { + break; + } else if (SourceFile->FileBufferPtr[0] == T_CHAR_CR) { + Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start); + PreviousBackslash = FALSE; + } else if (SourceFile->FileBufferPtr[0] == T_CHAR_BACKSLASH) { + PreviousBackslash = TRUE; + } else { + PreviousBackslash = FALSE; + } + + SourceFile->FileBufferPtr++; + Len++; + } + + if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) { + Warning (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing quote on string", "%S", Start); + } else { + SourceFile->FileBufferPtr++; + } + // + // Now allocate memory for the string and save it off + // + String = (T_CHAR *) malloc ((Len + 1) * sizeof (T_CHAR)); + if (String == NULL) { + Error (NULL, 0, 0, "memory allocation failed", NULL); + return NULL; + } + // + // Copy the string from the file buffer to the local copy. + // We do no reformatting of it whatsoever at this point. + // + Ptr = String; + while (Len > 0) { + *Ptr = *Start; + Start++; + Ptr++; + Len--; + } + + *Ptr = 0; + return String; +} +#endif +static +BOOLEAN +EndOfFile ( + SOURCE_FILE *SourceFile + ) +{ + // + // The file buffer pointer will typically get updated before the End-of-file flag in the + // source file structure, so check it first. + // + if (SourceFile->FileBufferPtr >= SourceFile->FileBuffer + SourceFile->FileSize / sizeof (T_CHAR)) { + SourceFile->EndOfFile = TRUE; + return TRUE; + } + + if (SourceFile->EndOfFile) { + return TRUE; + } + + return FALSE; +} + +#if 0 +static +void +ProcessTokenInclude ( + SOURCE_FILE *SourceFile + ) +{ + char IncludeFileName[MAX_PATH]; + char *To; + unsigned int Len; + BOOLEAN ReportedError; + SOURCE_FILE IncludedSourceFile; + + ReportedError = FALSE; + if (SkipWhiteSpace (SourceFile) == 0) { + Warning (SourceFile->FileName, SourceFile->LineNum, 0, "expected whitespace following #include keyword", NULL); + } + // + // Should be quoted file name + // + if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted include file name", NULL); + goto FailDone; + } + + SourceFile->FileBufferPtr++; + // + // Copy the filename as ascii to our local string + // + To = IncludeFileName; + Len = 0; + while (!EndOfFile (SourceFile)) { + if ((SourceFile->FileBufferPtr[0] == T_CHAR_CR) || (SourceFile->FileBufferPtr[0] == T_CHAR_LF)) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-line found in quoted include file name", NULL); + goto FailDone; + } + + if (SourceFile->FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) { + SourceFile->FileBufferPtr++; + break; + } + // + // If too long, then report the error once and process until the closing quote + // + Len++; + if (!ReportedError && (Len >= sizeof (IncludeFileName))) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "length of include file name exceeds limit", NULL); + ReportedError = TRUE; + } + + if (!ReportedError) { + *To = (T_CHAR) SourceFile->FileBufferPtr[0]; + To++; + } + + SourceFile->FileBufferPtr++; + } + + if (!ReportedError) { + *To = 0; + memset ((char *) &IncludedSourceFile, 0, sizeof (SOURCE_FILE)); + strcpy (IncludedSourceFile.FileName, IncludeFileName); + ProcessIncludeFile (&IncludedSourceFile, SourceFile); + } + + return ; +FailDone: + // + // Error recovery -- skip to next # + // + SourceFile->SkipToHash = TRUE; +} +#endif +static +BOOLEAN +IsWhiteSpace ( + SOURCE_FILE *SourceFile + ) +{ + switch (*SourceFile->FileBufferPtr) { + case T_CHAR_NULL: + case T_CHAR_CR: + case T_CHAR_SPACE: + case T_CHAR_TAB: + case T_CHAR_LF: + return TRUE; + + default: + return FALSE; + } +} + +unsigned int +SkipWhiteSpace ( + SOURCE_FILE *SourceFile + ) +{ + unsigned int Count; + + Count = 0; + while (!EndOfFile (SourceFile)) { + Count++; + switch (*SourceFile->FileBufferPtr) { + case T_CHAR_NULL: + case T_CHAR_CR: + case T_CHAR_SPACE: + case T_CHAR_TAB: + SourceFile->FileBufferPtr++; + break; + + case T_CHAR_LF: + SourceFile->FileBufferPtr++; + SourceFile->LineNum++; + break; + + default: + return Count - 1; + } + } + // + // Some tokens require trailing whitespace. If we're at the end of the + // file, then we count that as well. + // + if ((Count == 0) && (EndOfFile (SourceFile))) { + Count++; + } + + return Count; +} + +static +unsigned int +t_strcmp ( + T_CHAR *Buffer, + T_CHAR *Str + ) +/*++ + +Routine Description: + Compare two strings for equality. The string pointed to by 'Buffer' may or may not be null-terminated, + so only compare up to the length of Str. + +Arguments: + Buffer - pointer to first (possibly not null-terminated) string + Str - pointer to null-terminated string to compare to Buffer + +Returns: + Number of bytes matched if exact match + 0 if Buffer does not start with Str + +--*/ +{ + unsigned int Len; + + Len = 0; + while (*Str && (*Str == *Buffer)) { + Buffer++; + Str++; + Len++; + } + + if (*Str) { + return 0; + } + + return Len; +} + +static +unsigned int +t_strlen ( + T_CHAR *Str + ) +{ + unsigned int Len; + Len = 0; + while (*Str) { + Len++; + Str++; + } + + return Len; +} + +static +unsigned int +t_strncmp ( + T_CHAR *Str1, + T_CHAR *Str2, + int Len + ) +{ + while (Len > 0) { + if (*Str1 != *Str2) { + return Len; + } + + Len--; + Str1++; + Str2++; + } + + return 0; +} + +static +T_CHAR * +t_strcpy ( + T_CHAR *Dest, + T_CHAR *Src + ) +{ + T_CHAR *SaveDest; + SaveDest = Dest; + while (*Src) { + *Dest = *Src; + Dest++; + Src++; + } + + *Dest = 0; + return SaveDest; +} + +static +void +RewindFile ( + SOURCE_FILE *SourceFile + ) +{ + SourceFile->LineNum = 1; + SourceFile->FileBufferPtr = SourceFile->FileBuffer; + SourceFile->EndOfFile = 0; +} + +static +UINT32 +GetHexChars ( + T_CHAR *Buffer, + UINT32 BufferLen + ) +{ + UINT32 Len; + Len = 0; + while (!EndOfFile (&mGlobals.SourceFile) && (BufferLen > 0)) { + if (isxdigit (mGlobals.SourceFile.FileBufferPtr[0])) { + *Buffer = mGlobals.SourceFile.FileBufferPtr[0]; + Buffer++; + Len++; + BufferLen--; + mGlobals.SourceFile.FileBufferPtr++; + } else { + break; + } + } + // + // Null terminate if we can + // + if ((Len > 0) && (BufferLen > 0)) { + *Buffer = 0; + } + + return Len; +} + +BOOLEAN +SFPGetGuid ( + int GuidStyle, + EFI_GUID *Value + ) +/*++ + +Routine Description: + Parse a GUID from the input stream. Stop when you discover white space. + +Arguments: + GuidStyle - Style of the following GUID token + Value - pointer to EFI_GUID struct for output + +Returns: + TRUE - GUID string parsed successfully + FALSE - otherwise + + GUID styles + Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD + +--*/ +{ + UINT32 Value32; + UINT32 Index; + FILE_POSITION FPos; + T_CHAR TempString[20]; + T_CHAR TempString2[3]; + T_CHAR *From; + T_CHAR *To; + UINT32 Len; + BOOLEAN Status; + + Status = FALSE; + // + // Skip white space, then start parsing + // + SkipWhiteSpace (&mGlobals.SourceFile); + GetFilePosition (&FPos); + if (EndOfFile (&mGlobals.SourceFile)) { + return FALSE; + } + + if (GuidStyle == PARSE_GUID_STYLE_5_FIELDS) { + // + // Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD + // + Len = GetHexChars (TempString, sizeof (TempString)); + if ((Len == 0) || (Len > 8)) { + goto Done; + } + + sscanf (TempString, "%x", &Value32); + Value->Data1 = Value32; + // + // Next two UINT16 fields + // + if (mGlobals.SourceFile.FileBufferPtr[0] != '-') { + goto Done; + } + + mGlobals.SourceFile.FileBufferPtr++; + Len = GetHexChars (TempString, sizeof (TempString)); + if ((Len == 0) || (Len > 4)) { + goto Done; + } + + sscanf (TempString, "%x", &Value32); + Value->Data2 = (UINT16) Value32; + + if (mGlobals.SourceFile.FileBufferPtr[0] != '-') { + goto Done; + } + + mGlobals.SourceFile.FileBufferPtr++; + Len = GetHexChars (TempString, sizeof (TempString)); + if ((Len == 0) || (Len > 4)) { + goto Done; + } + + sscanf (TempString, "%x", &Value32); + Value->Data3 = (UINT16) Value32; + // + // Parse the "AAAA" as two bytes + // + if (mGlobals.SourceFile.FileBufferPtr[0] != '-') { + goto Done; + } + + mGlobals.SourceFile.FileBufferPtr++; + Len = GetHexChars (TempString, sizeof (TempString)); + if ((Len == 0) || (Len > 4)) { + goto Done; + } + + sscanf (TempString, "%x", &Value32); + Value->Data4[0] = (UINT8) (Value32 >> 8); + Value->Data4[1] = (UINT8) Value32; + if (mGlobals.SourceFile.FileBufferPtr[0] != '-') { + goto Done; + } + + mGlobals.SourceFile.FileBufferPtr++; + // + // Read the last 6 bytes of the GUID + // + // + Len = GetHexChars (TempString, sizeof (TempString)); + if ((Len == 0) || (Len > 12)) { + goto Done; + } + // + // Insert leading 0's to make life easier + // + if (Len != 12) { + From = TempString + Len - 1; + To = TempString + 11; + TempString[12] = 0; + while (From >= TempString) { + *To = *From; + To--; + From--; + } + + while (To >= TempString) { + *To = '0'; + To--; + } + } + // + // Now parse each byte + // + TempString2[2] = 0; + for (Index = 0; Index < 6; Index++) { + // + // Copy the two characters from the input string to something + // we can parse. + // + TempString2[0] = TempString[Index * 2]; + TempString2[1] = TempString[Index * 2 + 1]; + sscanf (TempString2, "%x", &Value32); + Value->Data4[Index + 2] = (UINT8) Value32; + } + + Status = TRUE; + } else { + // + // Unsupported GUID style + // + return FALSE; + } + +Done: + if (Status == FALSE) { + SetFilePosition (&FPos); + } + + return Status; +} + +static +STATUS +GetFilePosition ( + FILE_POSITION *Fpos + ) +{ + Fpos->FileBufferPtr = mGlobals.SourceFile.FileBufferPtr; + return STATUS_SUCCESS; +} + +static +STATUS +SetFilePosition ( + FILE_POSITION *Fpos + ) +{ + // + // Should check range of pointer + // + mGlobals.SourceFile.FileBufferPtr = Fpos->FileBufferPtr; + return STATUS_SUCCESS; +} diff --git a/Tools/CodeTools/Source/Common/SimpleFileParsing.h b/Tools/CodeTools/Source/Common/SimpleFileParsing.h new file mode 100644 index 0000000000..7cf25a6bf8 --- /dev/null +++ b/Tools/CodeTools/Source/Common/SimpleFileParsing.h @@ -0,0 +1,120 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + SimpleFileParsing.h + +Abstract: + + Function prototypes and defines for the simple file parsing routines. + +--*/ + +#ifndef _SIMPLE_FILE_PARSING_H_ +#define _SIMPLE_FILE_PARSING_H_ + +#include + +#define T_CHAR char + +STATUS +SFPInit ( + VOID + ) +; + +STATUS +SFPOpenFile ( + char *FileName + ) +; + +BOOLEAN +SFPIsKeyword ( + T_CHAR *Str + ) +; + +BOOLEAN +SFPIsToken ( + T_CHAR *Str + ) +; + +BOOLEAN +SFPGetNextToken ( + T_CHAR *Str, + unsigned int Len + ) +; + +BOOLEAN +SFPGetGuidToken ( + T_CHAR *Str, + UINT32 Len + ) +; + +#define PARSE_GUID_STYLE_5_FIELDS 0 + +BOOLEAN +SFPGetGuid ( + int GuidStyle, + EFI_GUID *Value + ) +; + +BOOLEAN +SFPSkipToToken ( + T_CHAR *Str + ) +; + +BOOLEAN +SFPGetNumber ( + unsigned int *Value + ) +; + +BOOLEAN +SFPGetQuotedString ( + T_CHAR *Str, + int Length + ) +; + +BOOLEAN +SFPIsEOF ( + VOID + ) +; + +STATUS +SFPCloseFile ( + VOID + ) +; + +unsigned +int +SFPGetLineNumber ( + VOID + ) +; + +T_CHAR * +SFPGetFileName ( + VOID + ) +; + +#endif // #ifndef _SIMPLE_FILE_PARSING_H_ diff --git a/Tools/CodeTools/Source/Common/WinNtInclude.h b/Tools/CodeTools/Source/Common/WinNtInclude.h new file mode 100644 index 0000000000..80e45b4ad6 --- /dev/null +++ b/Tools/CodeTools/Source/Common/WinNtInclude.h @@ -0,0 +1,73 @@ +/*-- + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + WinNtInclude.h + +Abstract: + Include file for the WinNt Library + +--*/ + +#ifndef __WIN_NT_INCLUDE_H__ +#define __WIN_NT_INCLUDE_H__ + +// +// Win32 include files do not compile clean with /W4, so we use the warning +// pragma to suppress the warnings for Win32 only. This way our code can stil +// compile at /W4 (highest warning level) with /WX (warnings cause build +// errors). +// +#pragma warning(disable : 4115) +#pragma warning(disable : 4201) +#pragma warning(disable : 4214) +#pragma warning(disable : 4028) +#pragma warning(disable : 4133) + +#define GUID _WINNT_DUP_GUID_____ +#define _LIST_ENTRY _WINNT_DUP_LIST_ENTRY_FORWARD +#define LIST_ENTRY _WINNT_DUP_LIST_ENTRY +#define InterlockedIncrement _WINNT_DUP_InterlockedIncrement +#define InterlockedDecrement _WINNT_DUP_InterlockedDecrement +#define InterlockedCompareExchange64 _WINNT_DUP_InterlockedCompareExchange64 +#undef UNALIGNED +#undef CONST +#undef VOID + +#ifndef __GNUC__ +#include "windows.h" +#endif + +#undef GUID +#undef _LIST_ENTRY +#undef LIST_ENTRY +#undef InterlockedIncrement +#undef InterlockedDecrement +#undef InterlockedCompareExchange64 +#undef InterlockedCompareExchangePointer + +#define VOID void + +// +// Prevent collisions with Windows API name macros that deal with Unicode/Not issues +// +#undef LoadImage +#undef CreateEvent + +// +// Set the warnings back on as the EFI code must be /W4. +// +#pragma warning(default : 4115) +#pragma warning(default : 4201) +#pragma warning(default : 4214) + + +#endif diff --git a/Tools/CodeTools/Source/Common/build.xml b/Tools/CodeTools/Source/Common/build.xml new file mode 100644 index 0000000000..902f677d1d --- /dev/null +++ b/Tools/CodeTools/Source/Common/build.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/CompressDll/CompressDll.c b/Tools/CodeTools/Source/CompressDll/CompressDll.c new file mode 100644 index 0000000000..cc06f26c05 --- /dev/null +++ b/Tools/CodeTools/Source/CompressDll/CompressDll.c @@ -0,0 +1,105 @@ +/** @file + Compression DLL used by PCD Tools + + Copyright (c) 2006, Intel Corporation All rights reserved. + This program and the accompanying materials are licensed and made available + under the terms and conditions of the BSD License which accompanies this + distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ +#if defined(__GNUC__) +typedef long long __int64;/*For cygwin build*/ +#endif +#include "CompressDll.h" +#include "EfiCompress.h" + +extern +EFI_STATUS +Compress ( + IN UINT8 *SrcBuffer, + IN UINT32 SrcSize, + IN UINT8 *DstBuffer, + IN OUT UINT32 *DstSize + ); + +JNIEXPORT jbyteArray JNICALL Java_org_tianocore_framework_tasks_Compress_CallCompress +(JNIEnv *env, jobject obj, jbyteArray SourceBuffer, jint SourceSize, jstring path) +{ + char* DestBuffer; + int DestSize; + int Result; + char *InputBuffer; + jbyteArray OutputBuffer; + jbyte *TempByte; + + DestSize = 0; + DestBuffer = NULL; + + TempByte = (*env)->GetByteArrayElements(env, SourceBuffer, 0); + InputBuffer = (char*) TempByte; + + + // + // First call compress function and get need buffer size + // + + Result = Compress ( + (char*) InputBuffer, + SourceSize, + DestBuffer, + &DestSize + ); + + if (Result = EFI_BUFFER_TOO_SMALL) { + DestBuffer = malloc (DestSize); + } + + // + // Second call compress and get the DestBuffer value + // + Result = Compress( + (char*) InputBuffer, + SourceSize, + DestBuffer, + &DestSize + ); + + // + // new a MV array to store the return compressed buffer + // + OutputBuffer = (*env)->NewByteArray(env, DestSize); + (*env)->SetByteArrayRegion(env, OutputBuffer,0, DestSize, (jbyte*) DestBuffer); + + // + // Free Ouputbuffer. + // + free (DestBuffer); + + + if (Result != 0) { + return NULL; + } else { + return OutputBuffer; + } +} + +#ifdef _MSC_VER +BOOLEAN +__stdcall +DllMainCRTStartup( + unsigned int hDllHandle, + unsigned int nReason, + void* Reserved +) +{ + return TRUE; +} +#else +#ifdef __GNUC__ +#endif +#endif + diff --git a/Tools/CodeTools/Source/CompressDll/CompressDll.h b/Tools/CodeTools/Source/CompressDll/CompressDll.h new file mode 100644 index 0000000000..fa3b83cd10 --- /dev/null +++ b/Tools/CodeTools/Source/CompressDll/CompressDll.h @@ -0,0 +1,22 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ + +#include +/* Header for class org_tianocore_frameworktasks_Compress */ + +#ifndef _Included_org_tianocore_framework_tasks_Compress +#define _Included_org_tianocore_framework_tasks_Compress +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_tianocore_frameworktasks_Compress + * Method: CallCompress + * Signature: ([BILjava/lang/String;)[B + */ +JNIEXPORT jbyteArray JNICALL Java_org_tianocore_framework_tasks_Compress_CallCompress + (JNIEnv *, jobject, jbyteArray, jint, jstring); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Tools/CodeTools/Source/CompressDll/build.xml b/Tools/CodeTools/Source/CompressDll/build.xml new file mode 100644 index 0000000000..5043d127d5 --- /dev/null +++ b/Tools/CodeTools/Source/CompressDll/build.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/CreateMtFile/CreateMtFile.c b/Tools/CodeTools/Source/CreateMtFile/CreateMtFile.c new file mode 100644 index 0000000000..1c17b3de23 --- /dev/null +++ b/Tools/CodeTools/Source/CreateMtFile/CreateMtFile.c @@ -0,0 +1,247 @@ +/*++ + +Copyright (c) 1999-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +Module Name: + + CreateMtFile.c + +Abstract: + + Simple utility to create a pad file containing fixed data. + +--*/ + +#include +#include +#include + +#include + +#define PROGRAM_NAME "CreateMtFile" + +typedef struct { + INT8 *OutFileName; + INT8 ByteValue; + UINT32 FileSize; +} OPTIONS; + +static +EFI_STATUS +ProcessArgs ( + IN INT32 Argc, + IN INT8 *Argv[], + IN OUT OPTIONS *Options + ); + +static +void +Usage ( + VOID + ); + +int +main ( + IN INT32 Argc, + IN INT8 *Argv[] + ) +/*++ + +Routine Description: + + Main entry point for this utility. + +Arguments: + + Standard C entry point args Argc and Argv + +Returns: + + EFI_SUCCESS if good to go + +--*/ +// GC_TODO: ] - add argument and description to function comment +// GC_TODO: EFI_INVALID_PARAMETER - add return value to function comment +// GC_TODO: EFI_DEVICE_ERROR - add return value to function comment +// GC_TODO: EFI_DEVICE_ERROR - add return value to function comment +{ + FILE *OutFptr; + OPTIONS Options; + + // + // Process the command-line arguments. + // + if (ProcessArgs (Argc, Argv, &Options) != EFI_SUCCESS) { + return EFI_INVALID_PARAMETER; + } + // + // Open the output file + // + if ((OutFptr = fopen (Options.OutFileName, "wb")) == NULL) { + fprintf ( + stdout, + PROGRAM_NAME " ERROR: Could not open output file '%s' for writing\n", + Options.OutFileName + ); + return EFI_DEVICE_ERROR; + } + // + // Write the pad bytes. Do it the slow way (one at a time) for now. + // + while (Options.FileSize > 0) { + if (fwrite (&Options.ByteValue, 1, 1, OutFptr) != 1) { + fclose (OutFptr); + fprintf (stdout, PROGRAM_NAME " ERROR: Failed to write to output file\n"); + return EFI_DEVICE_ERROR; + } + + Options.FileSize--; + } + // + // Close the file + // + fclose (OutFptr); + return EFI_SUCCESS; +} + +static +EFI_STATUS +ProcessArgs ( + IN INT32 Argc, + IN INT8 *Argv[], + IN OUT OPTIONS *Options + ) +/*++ + +Routine Description: + + Process the command line arguments. + +Arguments: + + Argc - argument count as passed in to the entry point function + Argv - array of arguments as passed in to the entry point function + Options - stucture of where to put the values of the parsed arguments + +Returns: + + EFI_SUCCESS if everything looks good + EFI_INVALID_PARAMETER otherwise + +--*/ +// GC_TODO: ] - add argument and description to function comment +{ + UINT32 Multiplier; + + // + // Clear the options + // + memset ((char *) Options, 0, sizeof (OPTIONS)); + + // + // Skip program name + // + Argv++; + Argc--; + if (Argc < 2) { + Usage (); + return EFI_INVALID_PARAMETER; + } + // + // If first arg is dash-option, then print usage. + // + if (Argv[0][0] == '-') { + Usage (); + return EFI_INVALID_PARAMETER; + } + // + // First arg is file name + // + Options->OutFileName = Argv[0]; + Argc--; + Argv++; + + // + // Second arg is file size. Allow 0x1000, 0x100K, 1024, 1K + // + Multiplier = 1; + if ((Argv[0][strlen (Argv[0]) - 1] == 'k') || (Argv[0][strlen (Argv[0]) - 1] == 'K')) { + Multiplier = 1024; + } + // + // Look for 0x prefix on file size + // + if ((Argv[0][0] == '0') && ((Argv[0][1] == 'x') || (Argv[0][1] == 'X'))) { + if (sscanf (Argv[0], "%x", &Options->FileSize) != 1) { + fprintf (stdout, PROGRAM_NAME " ERROR: Invalid file size '%s'\n", Argv[0]); + Usage (); + return EFI_INVALID_PARAMETER; + } + // + // Otherwise must be a decimal number + // + } else { + if (sscanf (Argv[0], "%d", &Options->FileSize) != 1) { + fprintf (stdout, PROGRAM_NAME " ERROR: Invalid file size '%s'\n", Argv[0]); + Usage (); + return EFI_INVALID_PARAMETER; + } + } + + Options->FileSize *= Multiplier; + // + // Assume byte value of 0xff + // + Options->ByteValue = (INT8) (UINT8) 0xFF; + return EFI_SUCCESS; +} +// +// Print utility usage info +// +static +void +Usage ( + VOID + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + None + +Returns: + + GC_TODO: add return values + +--*/ +{ + UINT32 Index; + static const INT8 *Text[] = { + " ", + "Usage: "PROGRAM_NAME " OutFileName FileSize", + " where:", + " OutFileName is the name of the output file to generate", + " FileSize is the size of the file to create", + " Examples:", + " "PROGRAM_NAME " OutFile.bin 32K", + " "PROGRAM_NAME " OutFile.bin 0x1000", + " ", + NULL + }; + + for (Index = 0; Text[Index] != NULL; Index++) { + fprintf (stdout, "%s\n", Text[Index]); + } +} diff --git a/Tools/CodeTools/Source/CreateMtFile/build.xml b/Tools/CodeTools/Source/CreateMtFile/build.xml new file mode 100644 index 0000000000..b2272244cd --- /dev/null +++ b/Tools/CodeTools/Source/CreateMtFile/build.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/CustomizedCompress/CustomizedCompress.c b/Tools/CodeTools/Source/CustomizedCompress/CustomizedCompress.c new file mode 100644 index 0000000000..0dc66128c9 --- /dev/null +++ b/Tools/CodeTools/Source/CustomizedCompress/CustomizedCompress.c @@ -0,0 +1,146 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + CustomizedCompress.c + +Abstract: + + Header file for Customized compression routine + +--*/ + +#include + +EFI_STATUS +SetCustomizedCompressionType ( + IN CHAR8 *Type + ) +/*++ + +Routine Description: + +The implementation of Customized SetCompressionType(). + +Arguments: + Type - The type if compression. + +Returns: + + EFI_SUCCESS - The type has been set. + EFI_UNSUPPORTED - This type is unsupported. + + +--*/ +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +CustomizedGetInfo ( + IN VOID *Source, + IN UINT32 SrcSize, + OUT UINT32 *DstSize, + OUT UINT32 *ScratchSize + ) +/*++ + +Routine Description: + +The implementation of Customized GetInfo(). + +Arguments: + Source - The source buffer containing the compressed data. + SrcSize - The size of source buffer + DstSize - The size of destination buffer. + ScratchSize - The size of scratch buffer. + +Returns: + + EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved. + EFI_INVALID_PARAMETER - The source data is corrupted + EFI_UNSUPPORTED - The operation is unsupported. + + +--*/ +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +CustomizedDecompress ( + IN VOID *Source, + IN UINT32 SrcSize, + IN OUT VOID *Destination, + IN UINT32 DstSize, + IN OUT VOID *Scratch, + IN UINT32 ScratchSize + ) +/*++ + +Routine Description: + + The implementation of Customized Decompress(). + +Arguments: + + This - The protocol instance pointer + Source - The source buffer containing the compressed data. + SrcSize - The size of source buffer + Destination - The destination buffer to store the decompressed data + DstSize - The size of destination buffer. + Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data. + ScratchSize - The size of scratch buffer. + +Returns: + + EFI_SUCCESS - Decompression is successfull + EFI_INVALID_PARAMETER - The source data is corrupted + EFI_UNSUPPORTED - The operation is unsupported. + +--*/ +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +CustomizedCompress ( + IN UINT8 *SrcBuffer, + IN UINT32 SrcSize, + IN UINT8 *DstBuffer, + IN OUT UINT32 *DstSize + ) +/*++ + +Routine Description: + + The Customized compression routine. + +Arguments: + + SrcBuffer - The buffer storing the source data + SrcSize - The size of source data + DstBuffer - The buffer to store the compressed data + DstSize - On input, the size of DstBuffer; On output, + the size of the actual compressed data. + +Returns: + + EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. In this case, + DstSize contains the size needed. + EFI_SUCCESS - Compression is successful. + + EFI_UNSUPPORTED - The operation is unsupported. +--*/ +{ + return EFI_UNSUPPORTED; +} diff --git a/Tools/CodeTools/Source/CustomizedCompress/build.xml b/Tools/CodeTools/Source/CustomizedCompress/build.xml new file mode 100644 index 0000000000..4664a957f0 --- /dev/null +++ b/Tools/CodeTools/Source/CustomizedCompress/build.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/EfiCompress/EfiCompressMain.c b/Tools/CodeTools/Source/EfiCompress/EfiCompressMain.c new file mode 100644 index 0000000000..492210f67c --- /dev/null +++ b/Tools/CodeTools/Source/EfiCompress/EfiCompressMain.c @@ -0,0 +1,165 @@ +/*++ + +Copyright (c) 1999-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +Module Name: + + EfiCompressMain.c + +Abstract: + + The main function for the compression utility. + +--*/ + +#include +#include +#include +#include +#include + +#include + +#include "EfiCompress.h" + +int +main ( + INT32 argc, + CHAR8 *argv[] + ) +/*++ + +Routine Description: + + Compresses the input files + +Arguments: + + argc - number of arguments passed into the command line. + argv[] - files to compress and files to output compressed data to. + +Returns: + + int: 0 for successful execution of the function. + +--*/ +{ + EFI_STATUS Status; + FILE *infile; + FILE *outfile; + UINT32 SrcSize; + UINT32 DstSize; + UINT8 *SrcBuffer; + UINT8 *DstBuffer; + UINT8 Buffer[8]; + + // + // Added for makefile debug - KCE + // + INT32 arg_counter; + printf ("\n\n"); + for (arg_counter = 0; arg_counter < argc; arg_counter++) { + printf ("%s ", argv[arg_counter]); + } + + printf ("\n\n"); + + SrcBuffer = DstBuffer = NULL; + + infile = outfile = NULL; + + if (argc != 3) { + printf ("Usage: EFICOMPRESS \n"); + goto Done; + } + + if ((outfile = fopen (argv[2], "wb")) == NULL) { + printf ("Can't open output file\n"); + goto Done; + } + + if ((infile = fopen (argv[1], "rb")) == NULL) { + printf ("Can't open input file\n"); + goto Done; + } + // + // Get the size of source file + // + SrcSize = 0; + while (fread (Buffer, 1, 1, infile)) { + SrcSize++; + + } + // + // Read in the source data + // + if ((SrcBuffer = malloc (SrcSize)) == NULL) { + printf ("Can't allocate memory\n"); + goto Done; + } + + rewind (infile); + if (fread (SrcBuffer, 1, SrcSize, infile) != SrcSize) { + printf ("Can't read from source\n"); + goto Done; + } + // + // Get destination data size and do the compression + // + DstSize = 0; + Status = Compress (SrcBuffer, SrcSize, DstBuffer, &DstSize); + if (Status == EFI_BUFFER_TOO_SMALL) { + if ((DstBuffer = malloc (DstSize)) == NULL) { + printf ("Can't allocate memory\n"); + goto Done; + } + + Status = Compress (SrcBuffer, SrcSize, DstBuffer, &DstSize); + } + + if (EFI_ERROR (Status)) { + printf ("Compress Error\n"); + goto Done; + } + + printf ("\nOrig Size = %ld\n", SrcSize); + printf ("Comp Size = %ld\n", DstSize); + + if (DstBuffer == NULL) { + printf ("No destination to write to.\n"); + goto Done; + } + // + // Write out the result + // + if (fwrite (DstBuffer, 1, DstSize, outfile) != DstSize) { + printf ("Can't write to destination file\n"); + } + +Done: + if (SrcBuffer) { + free (SrcBuffer); + } + + if (DstBuffer) { + free (DstBuffer); + } + + if (infile) { + fclose (infile); + } + + if (outfile) { + fclose (outfile); + } + + return 0; +} diff --git a/Tools/CodeTools/Source/EfiCompress/build.xml b/Tools/CodeTools/Source/EfiCompress/build.xml new file mode 100644 index 0000000000..94f60558cc --- /dev/null +++ b/Tools/CodeTools/Source/EfiCompress/build.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/EfiRom/EfiRom.c b/Tools/CodeTools/Source/EfiRom/EfiRom.c new file mode 100644 index 0000000000..2cc478b119 --- /dev/null +++ b/Tools/CodeTools/Source/EfiRom/EfiRom.c @@ -0,0 +1,1536 @@ +/*++ + +Copyright (c) 1999-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + EfiRom.c + +Abstract: + + Utility program to create an EFI option ROM image from binary and + EFI PE32 files. + + +--*/ + +#include +#include +#include + +#include +#include // for PE32 structure definitions +#include + +#include // for option ROM header structures + +#include "EfiCompress.h" +#include "CommonLib.h" + +// +// Version of this utility +// +#define UTILITY_VERSION "v2.5" + +// +// Define some status return values +// +#define STATUS_SUCCESS 0 +#define STATUS_WARNING 1 +#define STATUS_ERROR 2 + +// +// Define the max length of a filename +// +#define MAX_PATH 200 + +#define DEFAULT_OUTPUT_EXTENSION ".rom" + +// +// Max size for an option ROM image +// +#define MAX_OPTION_ROM_SIZE (1024 * 1024 * 16) // 16MB +// +// Values for the indicator field in the PCI data structure +// +#define INDICATOR_LAST 0x80 // last file in series of files +// +// Masks for the FILE_LIST.FileFlags field +// +#define FILE_FLAG_BINARY 0x01 +#define FILE_FLAG_EFI 0x02 +#define FILE_FLAG_COMPRESS 0x04 + +// +// Use this linked list structure to keep track of all the filenames +// specified on the command line. +// +typedef struct _FILE_LIST { + struct _FILE_LIST *Next; + INT8 *FileName; + UINT32 FileFlags; + UINT32 ClassCode; + UINT16 CodeRevision; +} FILE_LIST; + +// +// Use this to track our command-line options +// +typedef struct { + INT8 OutFileName[MAX_PATH]; + INT8 NoLast; + INT8 Verbose; + INT8 DumpOption; + UINT8 DevIdValid; + UINT8 VendIdValid; + UINT16 VendId; + UINT16 DevId; + FILE_LIST *FileList; +} OPTIONS; + +// +// Make a global structure to keep track of command-line options +// +static OPTIONS mOptions; + +// +// Use these to convert from machine type value to a named type +// +typedef struct { + UINT16 Value; + char *Name; +} STRING_LOOKUP; + +static STRING_LOOKUP mMachineTypes[] = { + EFI_IMAGE_MACHINE_IA32, + "IA32", + EFI_IMAGE_MACHINE_IA64, + "IA64", + EFI_IMAGE_MACHINE_EBC, + "EBC", + 0, + NULL +}; + +static STRING_LOOKUP mSubsystemTypes[] = { + EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION, + "EFI application", + EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, + "EFI boot service driver", + EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER, + "EFI runtime driver", + 0, + NULL +}; +// +// Function prototypes +// +static +void +Usage ( + VOID + ); + +static +int +ParseCommandLine ( + int Argc, + char *Argv[], + OPTIONS *Options + ); + +static +int +CheckPE32File ( + FILE *Fptr, + UINT16 *MachineType, + UINT16 *SubSystem + ); + +static +int +ProcessEfiFile ( + FILE *OutFptr, + FILE_LIST *InFile, + UINT16 VendId, + UINT16 DevId, + UINT32 *Size + ); + +static +int +ProcessBinFile ( + FILE *OutFptr, + FILE_LIST *InFile, + UINT32 *Size + ); + +static +void +DumpImage ( + FILE_LIST *InFile + ); + +char * +GetMachineTypeStr ( + UINT16 MachineType + ); + +static +char * +GetSubsystemTypeStr ( + UINT16 SubsystemType + ); + +main ( + int Argc, + char *Argv[] + ) +/*++ + +Routine Description: + + Given an EFI image filename, create a ROM-able image by creating an option + ROM header and PCI data structure, filling them in, and then writing the + option ROM header + PCI data structure + EFI image out to the output file. + +Arguments: + + Argc - standard C main() argument count + + Argv - standard C main() argument list + +Returns: + + 0 success + non-zero otherwise + +--*/ +// GC_TODO: ] - add argument and description to function comment +{ + INT8 *Ext; + FILE *FptrOut; + UINT32 Status; + FILE_LIST *FList; + UINT32 TotalSize; + UINT32 Size; + + Status = STATUS_SUCCESS; + FptrOut = NULL; + + // + // Parse the command line arguments + // + if (ParseCommandLine (Argc, Argv, &mOptions)) { + return STATUS_ERROR; + } + // + // If dumping an image, then do that and quit + // + if (mOptions.DumpOption) { + DumpImage (mOptions.FileList); + goto BailOut; + } + // + // Determine the output filename. Either what they specified on + // the command line, or the first input filename with a different extension. + // + if (!mOptions.OutFileName[0]) { + strcpy (mOptions.OutFileName, mOptions.FileList->FileName); + // + // Find the last . on the line and replace the filename extension with + // the default + // + for (Ext = mOptions.OutFileName + strlen (mOptions.OutFileName) - 1; + (Ext >= mOptions.OutFileName) && (*Ext != '.') && (*Ext != '\\'); + Ext-- + ) + ; + // + // If dot here, then insert extension here, otherwise append + // + if (*Ext != '.') { + Ext = mOptions.OutFileName + strlen (mOptions.OutFileName); + } + + strcpy (Ext, DEFAULT_OUTPUT_EXTENSION); + } + // + // Make sure we don't have the same filename for input and output files + // + for (FList = mOptions.FileList; FList != NULL; FList = FList->Next) { + if (stricmp (mOptions.OutFileName, FList->FileName) == 0) { + Status = STATUS_ERROR; + fprintf ( + stdout, + "ERROR: Input and output file names must be different - %s = %s\n", + FList->FileName, + mOptions.OutFileName + ); + goto BailOut; + } + } + // + // Now open our output file + // + if ((FptrOut = fopen (mOptions.OutFileName, "w+b")) == NULL) { + fprintf (stdout, "ERROR: Failed to open output file %s\n", mOptions.OutFileName); + goto BailOut; + } + // + // Process all our files + // + TotalSize = 0; + for (FList = mOptions.FileList; FList != NULL; FList = FList->Next) { + Size = 0; + if (FList->FileFlags & FILE_FLAG_EFI) { + if (mOptions.Verbose) { + fprintf (stdout, "Processing EFI file %s\n", FList->FileName); + } + + Status = ProcessEfiFile (FptrOut, FList, mOptions.VendId, mOptions.DevId, &Size); + } else if (FList->FileFlags & FILE_FLAG_BINARY) { + if (mOptions.Verbose) { + fprintf (stdout, "Processing binary file %s\n", FList->FileName); + } + + Status = ProcessBinFile (FptrOut, FList, &Size); + } else { + fprintf (stdout, "ERROR: File not specified as EFI or binary: %s\n", FList->FileName); + Status = STATUS_ERROR; + } + + if (mOptions.Verbose) { + fprintf (stdout, " Output size = 0x%X\n", Size); + } + + if (Status != STATUS_SUCCESS) { + break; + } + + TotalSize += Size; + } + // + // Check total size + // + if (TotalSize > MAX_OPTION_ROM_SIZE) { + fprintf ( + stdout, + "ERROR: Option ROM image size exceeds limit 0x%X bytes\n", + MAX_OPTION_ROM_SIZE + ); + Status = STATUS_ERROR; + } + +BailOut: + if (FptrOut != NULL) { + fclose (FptrOut); + } + // + // Clean up our file list + // + while (mOptions.FileList != NULL) { + FList = mOptions.FileList->Next; + free (mOptions.FileList); + mOptions.FileList = FList; + } + + return Status; +} + +static +int +ProcessBinFile ( + FILE *OutFptr, + FILE_LIST *InFile, + UINT32 *Size + ) +/*++ + +Routine Description: + + Process a binary input file. + +Arguments: + + OutFptr - file pointer to output binary ROM image file we're creating + InFile - structure contains information on the binary file to process + Size - pointer to where to return the size added to the output file + +Returns: + + 0 - successful + +--*/ +{ + FILE *InFptr; + UINT32 TotalSize; + UINT32 FileSize; + UINT8 *Buffer; + UINT32 Status; + PCI_EXPANSION_ROM_HEADER *RomHdr; + PCI_DATA_STRUCTURE *PciDs; + UINT32 Index; + UINT8 ByteCheckSum; + + Status = STATUS_SUCCESS; + + // + // Try to open the input file + // + if ((InFptr = fopen (InFile->FileName, "rb")) == NULL) { + fprintf (stdout, "ERROR: Failed to open input file %s\n", InFile->FileName); + return STATUS_ERROR; + } + // + // Seek to the end of the input file and get the file size. Then allocate + // a buffer to read it in to. + // + fseek (InFptr, 0, SEEK_END); + FileSize = ftell (InFptr); + if (mOptions.Verbose) { + fprintf (stdout, " File size = 0x%X\n", FileSize); + } + + fseek (InFptr, 0, SEEK_SET); + Buffer = (INT8 *) malloc (FileSize); + if (Buffer == NULL) { + fprintf (stdout, "ERROR: Memory allocation failed\n"); + Status = STATUS_ERROR; + goto BailOut; + } + + if (fread (Buffer, FileSize, 1, InFptr) != 1) { + fprintf (stdout, "ERROR: Failed to read all bytes from input file\n"); + Status = STATUS_ERROR; + goto BailOut; + } + // + // Total size must be an even multiple of 512 bytes, and can't exceed + // the option ROM image size. + // + TotalSize = FileSize; + if (TotalSize & 0x1FF) { + TotalSize = (TotalSize + 0x200) &~0x1ff; + } + + if (TotalSize > MAX_OPTION_ROM_SIZE) { + fprintf ( + stdout, + "ERROR: Option ROM image %s size exceeds limit 0x%X bytes\n", + InFile->FileName, + MAX_OPTION_ROM_SIZE + ); + Status = STATUS_ERROR; + goto BailOut; + } + // + // Return the size to the caller so they can keep track of the running total. + // + *Size = TotalSize; + + // + // Crude check to make sure it's a legitimate ROM image + // + RomHdr = (PCI_EXPANSION_ROM_HEADER *) Buffer; + if (RomHdr->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) { + fprintf (stdout, "ERROR: ROM image file has invalid ROM signature\n"); + Status = STATUS_ERROR; + goto BailOut; + } + // + // Make sure the pointer to the PCI data structure is within the size of the image. + // Then check it for valid signature. + // + if ((RomHdr->PcirOffset > FileSize) || (RomHdr->PcirOffset == 0)) { + fprintf (stdout, "ERROR: Invalid PCI data structure offset\n"); + Status = STATUS_ERROR; + goto BailOut; + } + + PciDs = (PCI_DATA_STRUCTURE *) (Buffer + RomHdr->PcirOffset); + if (PciDs->Signature != PCI_DATA_STRUCTURE_SIGNATURE) { + fprintf (stdout, "ERROR: PCI data structure has invalid signature\n"); + Status = STATUS_ERROR; + goto BailOut; + } + // + // If this is the last image, then set the LAST bit unless requested not + // to via the command-line -l argument. Otherwise, make sure you clear it. + // + if ((InFile->Next == NULL) && (mOptions.NoLast == 0)) { + PciDs->Indicator = INDICATOR_LAST; + } else { + PciDs->Indicator = 0; + } + + ByteCheckSum = 0; + for (Index = 0; Index < FileSize - 1; Index++) { + ByteCheckSum = (UINT8) (ByteCheckSum + Buffer[Index]); + } + + Buffer[FileSize - 1] = (UINT8) ((~ByteCheckSum) + 1); + fprintf (stdout, "CheckSUm = %02x\n", (UINT32) Buffer[FileSize - 1]); + + // + // Now copy the input file contents out to the output file + // + if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) { + fprintf (stdout, "ERROR: Failed to write all file bytes to output file\n"); + Status = STATUS_ERROR; + goto BailOut; + } + + TotalSize -= FileSize; + // + // Pad the rest of the image to make it a multiple of 512 bytes + // + while (TotalSize > 0) { + putc (~0, OutFptr); + TotalSize--; + } + +BailOut: + if (InFptr != NULL) { + fclose (InFptr); + } + + if (Buffer != NULL) { + free (Buffer); + } + // + // Print the file name if errors occurred + // + if (Status != STATUS_SUCCESS) { + fprintf (stdout, "Error processing binary file %s\n", InFile->FileName); + } + + return Status; +} + +static +int +ProcessEfiFile ( + FILE *OutFptr, + FILE_LIST *InFile, + UINT16 VendId, + UINT16 DevId, + UINT32 *Size + ) +/*++ + +Routine Description: + + Process a PE32 EFI file. + +Arguments: + + OutFptr - file pointer to output binary ROM image file we're creating + InFile - structure contains information on the PE32 file to process + VendId - vendor ID as required in the option ROM header + DevId - device ID as required in the option ROM header + Size - pointer to where to return the size added to the output file + +Returns: + + 0 - successful + +--*/ +{ + UINT32 Status; + FILE *InFptr; + EFI_PCI_EXPANSION_ROM_HEADER RomHdr; + PCI_DATA_STRUCTURE PciDs; + UINT32 FileSize; + UINT32 CompressedFileSize; + UINT8 *Buffer; + UINT8 *CompressedBuffer; + UINT8 *TempBufferPtr; + UINT32 TotalSize; + UINT32 HeaderSize; + UINT16 MachineType; + UINT16 SubSystem; + UINT32 HeaderPadBytes; + + // + // Try to open the input file + // + if ((InFptr = fopen (InFile->FileName, "rb")) == NULL) { + fprintf (stdout, "ERROR: Failed to open input file %s\n", InFile->FileName); + return STATUS_ERROR; + } + // + // Initialize our buffer pointers to null. + // + Buffer = NULL; + CompressedBuffer = NULL; + + // + // Double-check the file to make sure it's what we expect it to be + // + Status = CheckPE32File (InFptr, &MachineType, &SubSystem); + if (Status != STATUS_SUCCESS) { + goto BailOut; + } + // + // Seek to the end of the input file and get the file size + // + fseek (InFptr, 0, SEEK_END); + FileSize = ftell (InFptr); + + // + // Get the size of the headers we're going to put in front of the image. The + // EFI header must be aligned on a 4-byte boundary, so pad accordingly. + // + if (sizeof (RomHdr) & 0x03) { + HeaderPadBytes = 4 - (sizeof (RomHdr) & 0x03); + } else { + HeaderPadBytes = 0; + } + + HeaderSize = sizeof (PCI_DATA_STRUCTURE) + HeaderPadBytes + sizeof (EFI_PCI_EXPANSION_ROM_HEADER); + if (mOptions.Verbose) { + fprintf (stdout, " File size = 0x%X\n", FileSize); + } + // + // Allocate memory for the entire file (in case we have to compress), then + // seek back to the beginning of the file and read it into our buffer. + // + Buffer = (INT8 *) malloc (FileSize); + if (Buffer == NULL) { + fprintf (stdout, "ERROR: Memory allocation failed\n"); + Status = STATUS_ERROR; + goto BailOut; + } + + fseek (InFptr, 0, SEEK_SET); + if (fread (Buffer, FileSize, 1, InFptr) != 1) { + fprintf (stdout, "ERROR: Failed to read all bytes from input file\n"); + Status = STATUS_ERROR; + goto BailOut; + } + // + // Now determine the size of the final output file. It's either the header size + // plus the file's size, or the header size plus the compressed file size. + // + if (InFile->FileFlags & FILE_FLAG_COMPRESS) { + // + // Allocate a buffer into which we can compress the image, compress it, + // and use that size as the new size. + // + CompressedBuffer = (INT8 *) malloc (FileSize); + if (CompressedBuffer == NULL) { + fprintf (stdout, "ERROR: Memory allocation failed\n"); + Status = STATUS_ERROR; + goto BailOut; + } + + CompressedFileSize = FileSize; + Status = Compress (Buffer, FileSize, CompressedBuffer, &CompressedFileSize); + if (Status != STATUS_SUCCESS) { + fprintf (stdout, "ERROR: Compression failed\n"); + goto BailOut; + } + // + // Now compute the size, then swap buffer pointers. + // + if (mOptions.Verbose) { + fprintf (stdout, " Comp size = 0x%X\n", CompressedFileSize); + } + + TotalSize = CompressedFileSize + HeaderSize; + FileSize = CompressedFileSize; + TempBufferPtr = Buffer; + Buffer = CompressedBuffer; + CompressedBuffer = TempBufferPtr; + } else { + TotalSize = FileSize + HeaderSize; + } + // + // Total size must be an even multiple of 512 bytes + // + if (TotalSize & 0x1FF) { + TotalSize = (TotalSize + 0x200) &~0x1ff; + } + // + // Check size + // + if (TotalSize > MAX_OPTION_ROM_SIZE) { + fprintf ( + stdout, + "ERROR: Option ROM image %s size exceeds limit 0x%X bytes\n", + InFile->FileName, + MAX_OPTION_ROM_SIZE + ); + Status = STATUS_ERROR; + goto BailOut; + } + // + // Return the size to the caller so they can keep track of the running total. + // + *Size = TotalSize; + + // + // Now fill in the ROM header. These values come from chapter 18 of the + // EFI 1.02 specification. + // + memset (&RomHdr, 0, sizeof (RomHdr)); + RomHdr.Signature = PCI_EXPANSION_ROM_HEADER_SIGNATURE; + RomHdr.InitializationSize = (UINT16) (TotalSize / 512); + RomHdr.EfiSignature = EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE; + RomHdr.EfiSubsystem = SubSystem; + RomHdr.EfiMachineType = MachineType; + RomHdr.EfiImageHeaderOffset = (UINT16) HeaderSize; + RomHdr.PcirOffset = (UINT16) (sizeof (RomHdr) + HeaderPadBytes); + // + // Set image as compressed or not + // + if (InFile->FileFlags & FILE_FLAG_COMPRESS) { + RomHdr.CompressionType = EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED; + } + // + // Fill in the PCI data structure + // + memset (&PciDs, 0, sizeof (PCI_DATA_STRUCTURE)); + + PciDs.Signature = PCI_DATA_STRUCTURE_SIGNATURE; + PciDs.VendorId = VendId; + PciDs.DeviceId = DevId; + PciDs.Length = (UINT16) sizeof (PCI_DATA_STRUCTURE); + PciDs.Revision = 0; + // + // Class code and code revision from the command line (optional) + // + PciDs.ClassCode[0] = (UINT8) InFile->ClassCode; + PciDs.ClassCode[1] = (UINT8) (InFile->ClassCode >> 8); + PciDs.ClassCode[2] = (UINT8) (InFile->ClassCode >> 16); + PciDs.ImageLength = RomHdr.InitializationSize; + PciDs.CodeRevision = InFile->CodeRevision; + PciDs.CodeType = PCI_CODE_TYPE_EFI_IMAGE; + + // + // If this is the last image, then set the LAST bit unless requested not + // to via the command-line -l argument. + // + if ((InFile->Next == NULL) && (mOptions.NoLast == 0)) { + PciDs.Indicator = INDICATOR_LAST; + } + // + // Write the ROM header to the output file + // + if (fwrite (&RomHdr, sizeof (RomHdr), 1, OutFptr) != 1) { + fprintf (stdout, "ERROR: Failed to write ROM header to output file\n"); + Status = STATUS_ERROR; + goto BailOut; + } + + // + // Write pad bytes to align the PciDs + // + while (HeaderPadBytes > 0) { + if (putc (0, OutFptr) == EOF) { + fprintf (stdout, "ERROR: Failed to write ROM header pad bytes to output file\n"); + Status = STATUS_ERROR; + goto BailOut; + } + + HeaderPadBytes--; + } + // + // Write the PCI data structure header to the output file + // + if (fwrite (&PciDs, sizeof (PciDs), 1, OutFptr) != 1) { + fprintf (stdout, "ERROR: Failed to write PCI ROM header to output file\n"); + Status = STATUS_ERROR; + goto BailOut; + } + // + // Keep track of how many bytes left to write + // + TotalSize -= HeaderSize; + + // + // Now dump the input file's contents to the output file + // + if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) { + fprintf (stdout, "ERROR: Failed to write all file bytes to output file\n"); + Status = STATUS_ERROR; + goto BailOut; + } + + TotalSize -= FileSize; + // + // Pad the rest of the image to make it a multiple of 512 bytes + // + while (TotalSize > 0) { + if (putc (~0, OutFptr) == EOF) { + fprintf (stdout, "ERROR: Failed to write trailing pad bytes output file\n"); + Status = STATUS_ERROR; + goto BailOut; + } + + TotalSize--; + } + +BailOut: + if (InFptr != NULL) { + fclose (InFptr); + } + + // + // Free up our buffers + // + if (Buffer != NULL) { + free (Buffer); + } + + if (CompressedBuffer != NULL) { + free (CompressedBuffer); + } + // + // Print the file name if errors occurred + // + if (Status != STATUS_SUCCESS) { + fprintf (stdout, "Error processing EFI file %s\n", InFile->FileName); + } + + return Status; +} + +static +int +CheckPE32File ( + FILE *Fptr, + UINT16 *MachineType, + UINT16 *SubSystem + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + Fptr - GC_TODO: add argument description + MachineType - GC_TODO: add argument description + SubSystem - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + /*++ + +Routine Description: + + Given a file pointer to a supposed PE32 image file, verify that it is indeed a + PE32 image file, and then return the machine type in the supplied pointer. + +Arguments: + + Fptr File pointer to the already-opened PE32 file + MachineType Location to stuff the machine type of the PE32 file. This is needed + because the image may be Itanium-based, IA32, or EBC. + +Returns: + + 0 success + non-zero otherwise + +--*/ + EFI_IMAGE_DOS_HEADER DosHeader; + EFI_IMAGE_FILE_HEADER FileHdr; + EFI_IMAGE_OPTIONAL_HEADER OptionalHdr; + UINT32 PESig; + + // + // Position to the start of the file + // + fseek (Fptr, 0, SEEK_SET); + + // + // Read the DOS header + // + if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) { + fprintf (stdout, "ERROR: Failed to read the DOS stub from the input file\n"); + return STATUS_ERROR; + } + // + // Check the magic number (0x5A4D) + // + if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) { + fprintf (stdout, "ERROR: Input file does not appear to be a PE32 image (magic number)\n"); + return STATUS_ERROR; + } + // + // Position into the file and check the PE signature + // + fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET); + if (fread (&PESig, sizeof (PESig), 1, Fptr) != 1) { + fprintf (stdout, "ERROR: Failed to read PE signature bytes from input file\n"); + return STATUS_ERROR; + } + // + // Check the PE signature in the header "PE\0\0" + // + if (PESig != EFI_IMAGE_NT_SIGNATURE) { + fprintf (stdout, "ERROR: Input file does not appear to be a PE32 image (signature)\n"); + return STATUS_ERROR; + } + // + // Read the file header and stuff their MachineType + // + if (fread (&FileHdr, sizeof (FileHdr), 1, Fptr) != 1) { + fprintf (stdout, "ERROR: Failed to read PE file header from input file\n"); + return STATUS_ERROR; + } + + memcpy ((char *) MachineType, &FileHdr.Machine, 2); + + // + // Read the optional header so we can get the subsystem + // + if (fread (&OptionalHdr, sizeof (OptionalHdr), 1, Fptr) != 1) { + fprintf (stdout, "ERROR: Failed to read COFF optional header from input file\n"); + return STATUS_ERROR; + } + + *SubSystem = OptionalHdr.Subsystem; + if (mOptions.Verbose) { + fprintf (stdout, " Got subsystem = 0x%X from image\n", (int) *SubSystem); + } + // + // Good to go + // + return STATUS_SUCCESS; +} + +static +int +ParseCommandLine ( + int Argc, + char *Argv[], + OPTIONS *Options + ) +/*++ + +Routine Description: + + Given the Argc/Argv program arguments, and a pointer to an options structure, + parse the command-line options and check their validity. + + +Arguments: + + Argc - standard C main() argument count + Argv[] - standard C main() argument list + Options - pointer to a structure to store the options in + +Returns: + + STATUS_SUCCESS success + non-zero otherwise + +--*/ +// +{ + FILE_LIST *FileList; + + FILE_LIST *PrevFileList; + UINT32 FileFlags; + UINT32 ClassCode; + UINT32 CodeRevision; + + FileFlags = 0; + + // + // Clear out the options + // + memset ((char *) Options, 0, sizeof (OPTIONS)); + + // + // To avoid compile warnings + // + FileList = PrevFileList = NULL; + + ClassCode = 0; + CodeRevision = 0; + // + // Skip over the program name + // + Argc--; + Argv++; + + // + // If no arguments, assume they want usage info + // + if (Argc == 0) { + Usage (); + return STATUS_ERROR; + } + // + // Process until no more arguments + // + while (Argc > 0) { + if ((Argv[0][0] == '-') || (Argv[0][0] == '/')) { + // + // To simplify string comparisons, replace slashes with dashes + // + Argv[0][0] = '-'; + + // + // Vendor ID specified with -v + // + if (stricmp (Argv[0], "-v") == 0) { + // + // Make sure there's another parameter + // + if (Argc > 1) { + Options->VendId = (UINT16) strtol (Argv[1], NULL, 16); + Options->VendIdValid = 1; + } else { + fprintf ( + stdout, + "ERROR: Missing Vendor ID with %s\n\n", + Argv[0] + ); + Usage (); + return STATUS_ERROR; + } + + Argv++; + Argc--; + } else if (stricmp (Argv[0], "-d") == 0) { + // + // Device ID specified with -d + // Make sure there's another parameter + // + if (Argc > 1) { + Options->DevId = (UINT16) strtol (Argv[1], NULL, 16); + Options->DevIdValid = 1; + } else { + fprintf ( + stdout, + "ERROR: Missing Device ID with %s\n\n", + Argv[0] + ); + Usage (); + return STATUS_ERROR; + } + + Argv++; + Argc--; + } else if (stricmp (Argv[0], "-o") == 0) { + // + // Output filename specified with -o + // Make sure there's another parameter + // + if (Argc > 1) { + strcpy (Options->OutFileName, Argv[1]); + } else { + fprintf ( + stdout, + "ERROR: Missing output file name with %s\n\n", + Argv[0] + ); + Usage (); + return STATUS_ERROR; + } + + Argv++; + Argc--; + } else if ((stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) { + // + // Help option + // + Usage (); + return STATUS_ERROR; + } else if (stricmp (Argv[0], "-b") == 0) { + // + // Specify binary files with -b + // + FileFlags = (FileFlags &~FILE_FLAG_EFI) | FILE_FLAG_BINARY; + } else if ((stricmp (Argv[0], "-e") == 0) || (stricmp (Argv[0], "-ec") == 0)) { + // + // Specify EFI files with -e. Specify EFI-compressed with -ec. + // + FileFlags = (FileFlags &~FILE_FLAG_BINARY) | FILE_FLAG_EFI; + if ((Argv[0][2] == 'c') || (Argv[0][2] == 'C')) { + FileFlags |= FILE_FLAG_COMPRESS; + } + // + // Specify not to set the LAST bit in the last file with -l + // + } else if (stricmp (Argv[0], "-l") == 0) { + Options->NoLast = 1; + } else if (stricmp (Argv[0], "-p") == 0) { + // + // -v for verbose would have been nicer, but it's already used. Let's use + // -p for prolix (wordy) output + // + Options->Verbose = 1; + } else if (stricmp (Argv[0], "-dump") == 0) { + // + // -dump for dumping a ROM image. In this case, say that the device id + // and vendor id are valid so we don't have to specify bogus ones on the + // command line. + // + Options->DumpOption = 1; + + Options->VendIdValid = 1; + Options->DevIdValid = 1; + FileFlags = FILE_FLAG_BINARY; + } else if (stricmp (Argv[0], "-cc") == 0) { + // + // Class code value for the next file in the list. + // Make sure there's another parameter + // + if (Argc > 1) { + // + // No error checking on the return value. Could check for LONG_MAX, + // LONG_MIN, or 0 class code value if desired. Check range (3 bytes) + // at least. + // + ClassCode = (UINT32) strtol (Argv[1], NULL, 16); + if (ClassCode & 0xFF000000) { + fprintf (stdout, "ERROR: Class code %s out of range\n", Argv[1]); + return STATUS_ERROR; + } + } else { + fprintf ( + stdout, + "ERROR: Missing class code value with %s\n\n", + Argv[0] + ); + Usage (); + return STATUS_ERROR; + } + + Argv++; + Argc--; + } else if (stricmp (Argv[0], "-rev") == 0) { + // + // Code revision in the PCI data structure. The value is for the next + // file in the list. + // Make sure there's another parameter + // + if (Argc > 1) { + // + // No error checking on the return value. Could check for LONG_MAX, + // LONG_MIN, or 0 value if desired. Check range (2 bytes) + // at least. + // + CodeRevision = (UINT32) strtol (Argv[1], NULL, 16); + if (CodeRevision & 0xFFFF0000) { + fprintf (stdout, "ERROR: Code revision %s out of range\n", Argv[1]); + return STATUS_ERROR; + } + } else { + fprintf ( + stdout, + "ERROR: Missing code revision value with %s\n\n", + Argv[0] + ); + Usage (); + return STATUS_ERROR; + } + + Argv++; + Argc--; + } else { + fprintf (stdout, "ERROR: Invalid option specified: %s\n\n", Argv[0]); + Usage (); + return STATUS_ERROR; + } + } else { + // + // Not a slash-option argument. Must be a file name. Make sure they've specified + // -e or -b already. + // + if ((FileFlags & (FILE_FLAG_BINARY | FILE_FLAG_EFI)) == 0) { + fprintf (stdout, "ERROR: Missing -e or -b with input file %s\n", Argv[0]); + return STATUS_ERROR; + } + // + // Create a new file structure + // + FileList = (FILE_LIST *) malloc (sizeof (FILE_LIST)); + if (FileList == NULL) { + fprintf (stdout, "ERROR: Memory allocation failure\n"); + return STATUS_ERROR; + } + + memset ((char *) FileList, 0, sizeof (FILE_LIST)); + FileList->FileName = Argv[0]; + FileList->FileFlags = FileFlags; + if (Options->FileList == NULL) { + Options->FileList = FileList; + } else { + if (PrevFileList == NULL) { + PrevFileList = FileList; + } else { + PrevFileList->Next = FileList; + } + } + + PrevFileList = FileList; + // + // Set the class code and code revision for this file, then reset the values. + // + FileList->ClassCode = ClassCode; + FileList->CodeRevision = (UINT16) CodeRevision; + ClassCode = 0; + CodeRevision = 0; + } + // + // Next argument + // + Argv++; + Argc--; + } + // + // Make sure they specified a device ID and vendor ID + // + if (!Options->VendIdValid) { + fprintf (stdout, "ERROR: Missing Vendor ID on command line\n\n"); + Usage (); + return STATUS_ERROR; + } + + if (!Options->DevIdValid) { + fprintf (stdout, "ERROR: Missing Device ID on command line\n\n"); + Usage (); + return STATUS_ERROR; + } + // + // Must have specified some files + // + if (Options->FileList == NULL) { + fprintf (stdout, "ERROR: Missing input file name\n"); + Usage (); + return STATUS_ERROR; + } + + return 0; +} + +static +void +Usage ( + VOID + ) +/*++ + +Routine Description: + + Print usage information for this utility. + +Arguments: + + None. + +Returns: + + Nothing. + +--*/ +{ + int Index; + static const char *Msg[] = { + "EfiRom "UTILITY_VERSION " - Intel EFI Make Option ROM utility", + " Copyright (C), 1999-2002 Intel Coproration\n", + " Create an option ROM image from a list of input files", + " Usage: efirom {-p} [-v VendorId] [-d DeviceId] {-o OutFileName} ", + " [-e|-b] [FileName(s)]", + " where:", + " VendorId - required hex PCI Vendor ID for the device", + " DeviceId - required hex PCI Device ID for the device", + " OutFileName - optional output file name. Default is the first input", + " file name with a "DEFAULT_OUTPUT_EXTENSION " file extension", + " FileNames - input PE32 or binary file name(s)", + " BinFileName - input binary file name(s)", + " -p - for verbose output", + " -l - to not automatically set the LAST bit on the last file", + " -b - following FileNames are binary files", + " -e - following FileNames are EFI PE32 image files", + " -ec - following FileNames are EFI PE32 image files, and should", + " be compressed by this utility", + " -cc ClassCode - to use hex ClassCode in the PCI data structure header for", + " the following FileName", + " -rev Revision - to use hex Revision in the PCI data structure header for", + " the following FileName", + " -dump - to dump the headers of an existing option ROM image", + "", + "Example usage: EfiRom -v 0xABCD -d 0x1234 -b File1.bin File2.bin -e File1.efi File2.efi ", + "", + NULL + }; + + for (Index = 0; Msg[Index] != NULL; Index++) { + fprintf (stdout, "%s\n", Msg[Index]); + } +} + +static +void +DumpImage ( + FILE_LIST *InFile + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + InFile - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + PCI_EXPANSION_ROM_HEADER PciRomHdr; + FILE *InFptr; + UINT32 ImageStart; + UINT32 ImageCount; + EFI_PCI_EXPANSION_ROM_HEADER EfiRomHdr; + PCI_DATA_STRUCTURE PciDs; + + // + // Open the input file + // + if ((InFptr = fopen (InFile->FileName, "rb")) == NULL) { + fprintf ( + stdout, + "ERROR: Could not open input file %s\n", + InFile->FileName + ); + return ; + } + // + // Go through the image and dump the header stuff for each + // + ImageCount = 0; + for (;;) { + // + // Save our postition in the file, since offsets in the headers + // are relative to the particular image. + // + ImageStart = ftell (InFptr); + ImageCount++; + + // + // Read the option ROM header. Have to assume a raw binary image for now. + // + if (fread (&PciRomHdr, sizeof (PciRomHdr), 1, InFptr) != 1) { + fprintf (stdout, "ERROR: Failed to read PCI ROM header from file\n"); + goto BailOut; + } + + // + // Dump the contents of the header + // + fprintf (stdout, "Image %d -- Offset 0x%X\n", ImageCount, ImageStart); + fprintf (stdout, " ROM header contents\n"); + fprintf (stdout, " Signature 0x%04X\n", (UINT32) PciRomHdr.Signature); + fprintf (stdout, " PCIR offset 0x%04X\n", (UINT32) PciRomHdr.PcirOffset); + // + // Find PCI data structure + // + if (fseek (InFptr, ImageStart + PciRomHdr.PcirOffset, SEEK_SET)) { + fprintf (stdout, "ERROR: Failed to seek to PCI data structure\n"); + goto BailOut; + } + // + // Read and dump the PCI data structure + // + if (fread (&PciDs, sizeof (PciDs), 1, InFptr) != 1) { + fprintf (stdout, "ERROR: Failed to read PCI data structure from file\n"); + goto BailOut; + } + + fprintf (stdout, " PCI Data Structure\n"); + fprintf ( + stdout, + " Signature %c%c%c%c\n", + (char) PciDs.Signature, + (char) (PciDs.Signature >> 8), + (char) (PciDs.Signature >> 16), + (char) (PciDs.Signature >> 24) + ); + fprintf (stdout, " Vendor ID 0x%04X\n", PciDs.VendorId); + fprintf (stdout, " Device ID 0x%04X\n", PciDs.DeviceId); + fprintf ( + stdout, + " Class Code 0x%06X\n", + (UINT32) (PciDs.ClassCode[0] | (PciDs.ClassCode[1] << 8) | (PciDs.ClassCode[2] << 16)) + ); + fprintf (stdout, " Image size 0x%X\n", PciDs.ImageLength * 512); + fprintf (stdout, " Code revision: 0x%04X\n", PciDs.CodeRevision); + fprintf (stdout, " Indicator 0x%02X", (UINT32) PciDs.Indicator); + // + // Print the indicator, used to flag the last image + // + if (PciDs.Indicator == INDICATOR_LAST) { + fprintf (stdout, " (last image)\n"); + } else { + fprintf (stdout, "\n"); + } + // + // Print the code type. If EFI code, then we can provide more info. + // + fprintf (stdout, " Code type 0x%02X", (UINT32) PciDs.CodeType); + if (PciDs.CodeType == PCI_CODE_TYPE_EFI_IMAGE) { + fprintf (stdout, " (EFI image)\n"); + // + // Re-read the header as an EFI ROM header, then dump more info + // + fprintf (stdout, " EFI ROM header contents\n"); + if (fseek (InFptr, ImageStart, SEEK_SET)) { + fprintf (stdout, "ERROR: Failed to re-seek to ROM header structure\n"); + goto BailOut; + } + + if (fread (&EfiRomHdr, sizeof (EfiRomHdr), 1, InFptr) != 1) { + fprintf (stdout, "ERROR: Failed to read EFI PCI ROM header from file\n"); + goto BailOut; + } + // + // Now dump more info + // + fprintf (stdout, " EFI Signature 0x%04X\n", EfiRomHdr.EfiSignature); + fprintf ( + stdout, + " Compression Type 0x%04X ", + (UINT32) EfiRomHdr.CompressionType + ); + if (EfiRomHdr.CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) { + fprintf (stdout, "(compressed)\n"); + } else { + fprintf (stdout, "(not compressed)\n"); + } + + fprintf ( + stdout, + " Machine type 0x%04X (%s)\n", + EfiRomHdr.EfiMachineType, + GetMachineTypeStr (EfiRomHdr.EfiMachineType) + ); + fprintf ( + stdout, + " Subsystem 0x%04X (%s)\n", + EfiRomHdr.EfiSubsystem, + GetSubsystemTypeStr (EfiRomHdr.EfiSubsystem) + ); + fprintf ( + stdout, + " EFI image offset 0x%04X (@0x%X)\n", + (UINT32) EfiRomHdr.EfiImageHeaderOffset, + (UINT32) (EfiRomHdr.EfiImageHeaderOffset + ImageStart) + ); + + } else { + // + // Not an EFI image + // + fprintf (stdout, "\n"); + } + // + // If code type is EFI image, then dump it as well? + // + // if (PciDs.CodeType == PCI_CODE_TYPE_EFI_IMAGE) { + // } + // + // If last image, then we're done + // + if (PciDs.Indicator == INDICATOR_LAST) { + goto BailOut; + } + // + // Seek to the start of the next image + // + if (fseek (InFptr, ImageStart + (PciDs.ImageLength * 512), SEEK_SET)) { + fprintf (stdout, "ERROR: Failed to seek to next image\n"); + goto BailOut; + } + } + +BailOut: + fclose (InFptr); +} + +char * +GetMachineTypeStr ( + UINT16 MachineType + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + MachineType - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + int Index; + + for (Index = 0; mMachineTypes[Index].Name != NULL; Index++) { + if (mMachineTypes[Index].Value == MachineType) { + return mMachineTypes[Index].Name; + } + } + + return "unknown"; +} + +static +char * +GetSubsystemTypeStr ( + UINT16 SubsystemType + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + SubsystemType - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + int Index; + + for (Index = 0; mSubsystemTypes[Index].Name != NULL; Index++) { + if (mSubsystemTypes[Index].Value == SubsystemType) { + return mSubsystemTypes[Index].Name; + } + } + + return "unknown"; +} diff --git a/Tools/CodeTools/Source/EfiRom/build.xml b/Tools/CodeTools/Source/EfiRom/build.xml new file mode 100644 index 0000000000..acb94a4835 --- /dev/null +++ b/Tools/CodeTools/Source/EfiRom/build.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/FlashMap/FlashDefFile.c b/Tools/CodeTools/Source/FlashMap/FlashDefFile.c new file mode 100644 index 0000000000..cdbf7886ec --- /dev/null +++ b/Tools/CodeTools/Source/FlashMap/FlashDefFile.c @@ -0,0 +1,2788 @@ +/*++ + +Copyright (c) 2004-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + FlashDefFile.c + +Abstract: + + Utility for flash management in the Intel Platform Innovation Framework + for EFI build environment. + +--*/ + +#include +#include +#include + +#include +#include +#include + +#include "EfiUtilityMsgs.h" +#include "FlashDefFile.h" +#include "SimpleFileParsing.h" +#include "Symbols.h" + +// +// #include "TrackMallocFree.h" +// +#define WCHAR_T char +#define MAX_STRING_LEN 256 +#define MAX_NAME_LEN 128 +#define BUFFER_SIZE 1024 +#define MAX_ATTR_LEN 128 +#define MAX_AREATYPE_LEN 128 +#define COLUMN2_START 60 +#define COLUMN3_START 70 +// +// Information for each subregions defined in the fdf file will be saved in these +// +typedef struct _FLASH_SUBREGION_DESCRIPTION { + struct _FLASH_SUBREGION_DESCRIPTION *Next; + int CreateHob; // to add to the auto-created HOB array + WCHAR_T Name[MAX_NAME_LEN]; // each subregion within a region must have a unique name + unsigned int Size; // size, in bytes, of this subregion + unsigned int SizeLeft; // used when creating the image + WCHAR_T Attributes[MAX_ATTR_LEN]; // subregion attributes used in the output HOB + WCHAR_T AreaType[MAX_AREATYPE_LEN]; // subregion area type used in the output HOB + EFI_GUID NameGuid; // used in the output HOB + WCHAR_T NameGuidString[MAX_NAME_LEN]; + EFI_GUID AreaTypeGuid; // used in the output HOB + WCHAR_T AreaTypeGuidString[MAX_NAME_LEN]; + EFI_GUID FileSystemGuid; // used in the output HOB + WCHAR_T FileSystemGuidString[MAX_NAME_LEN]; +} FLASH_SUBREGION_DESCRIPTION; + +// +// Information for each block in a flash device will be saved in one of these. +// We'll also use it for region definitions. +// +typedef struct _FLASH_BLOCK_DESCRIPTION { + struct _FLASH_BLOCK_DESCRIPTION *Next; // next block in the linked list + WCHAR_T Name[MAX_NAME_LEN]; // each block must have a unique name + unsigned int Size; // size, in bytes, of this block + unsigned int SizeLeft; // for use when creating image + unsigned int Flags; // user-defined flags for the block + unsigned int Alignment; // power of 2 alignment + WCHAR_T Attributes[MAX_ATTR_LEN]; // only used for Region definitions + WCHAR_T AreaType[MAX_AREATYPE_LEN]; // only used for Region definitions + FLASH_SUBREGION_DESCRIPTION *Subregions; + FLASH_SUBREGION_DESCRIPTION *LastSubregion; +} FLASH_BLOCK_DESCRIPTION; + +// +// Information for each flash device will be saved in one of these +// +typedef struct _FLASH_DEVICE_DESCRIPTION { + struct _FLASH_DEVICE_DESCRIPTION *Next; // next flash device in our linked list + int ErasePolarity; // erase polarity of the flash device + unsigned int BaseAddress; // base address of the flash device + unsigned int Size; // total size, in bytes, of the flash device + WCHAR_T Name[MAX_NAME_LEN]; // name of the flash device + FLASH_BLOCK_DESCRIPTION *PBlocks; // linked list of physical block descriptors + FLASH_BLOCK_DESCRIPTION *LastPBlock; // last block in the linked list + FLASH_BLOCK_DESCRIPTION *Regions; // linked list of flash region descriptors + FLASH_BLOCK_DESCRIPTION *LastRegion; // last region in the linked list +} FLASH_DEVICE_DESCRIPTION; + +// +// For image definitions, they can specify a file name or raw data bytes. Keep a linked list. +// +typedef struct _IMAGE_DEFINITION_ENTRY { + struct _IMAGE_DEFINITION_ENTRY *Next; + WCHAR_T RegionName[MAX_NAME_LEN]; + WCHAR_T SubregionName[MAX_NAME_LEN]; + WCHAR_T Name[MAX_NAME_LEN]; // file or data name + int IsRawData; // non-zero if raw data bytes + unsigned int RawDataSize; + char *RawData; + int Optional; // optional file (don't include if it doesn't exist) +} IMAGE_DEFINITION_ENTRY; + +// +// When we parse an image definition, save all the data for each in one of these +// +typedef struct _IMAGE_DEFINITION { + struct _IMAGE_DEFINITION *Next; + WCHAR_T Name[MAX_NAME_LEN]; + IMAGE_DEFINITION_ENTRY *Entries; + IMAGE_DEFINITION_ENTRY *LastEntry; +} IMAGE_DEFINITION; + +typedef struct { + char *BufferStart; + char *BufferEnd; + char *BufferPos; +} BUFFER_DATA; + +static const char *CIncludeHeader = "/*++\n\n" +" DO NOT EDIT -- file auto-generated by FlashMap utility\n\n""--*/\n""\n""#ifndef _FLASH_MAP_H_\n" +"#define _FLASH_MAP_H_\n\n"; +// +// "#include \"EfiFlashMap.h\"\n\n"; +// +static const char *CIncludeFooter = "#endif // #ifndef _FLASH_MAP_H_\n\n"; + +static const char *CFlashMapDataFileHeader = "/*++\n\n" +" DO NOT EDIT -- file auto-generated by FlashMap utility\n\n""--*/\n""\n"; + +static FLASH_DEVICE_DESCRIPTION *mFlashDevices = NULL; +static IMAGE_DEFINITION *mImageDefinitions = NULL; + +// +// Local function prototypes +// +static +BUFFER_DATA * +CreateBufferData ( + VOID + ); + +static +BOOLEAN +AddBufferDataByte ( + BUFFER_DATA *Buffer, + char Data + ); + +static +void +FreeBufferData ( + BUFFER_DATA *Buffer, + BOOLEAN FreeData + ); + +static +char * +GetBufferData ( + BUFFER_DATA *Buffer, + int *BufferSize + ); + +static +FLASH_SUBREGION_DESCRIPTION * +ParseSubregionDefinition ( + unsigned int SizeLeft + ); + +void +FDFConstructor ( + VOID + ) +/*++ + +Routine Description: + Initialization routine for the services that operate on a flash + definition file. + +Arguments: + None. + +Returns: + NA + +--*/ +{ + mFlashDevices = NULL; + mImageDefinitions = NULL; +} + +void +FDFDestructor ( + VOID + ) +/*++ + +Routine Description: + Finalization/cleanup routine for the services that operate on a flash + definition file. + +Arguments: + None. + +Returns: + NA + +--*/ +{ + FLASH_BLOCK_DESCRIPTION *FBNext; + FLASH_DEVICE_DESCRIPTION *FDNext; + IMAGE_DEFINITION *IDNext; + IMAGE_DEFINITION_ENTRY *IDENext; + FLASH_SUBREGION_DESCRIPTION *SubNext; + // + // Go through all our flash devices and free the memory + // + while (mFlashDevices != NULL) { + // + // Free the physical block definitions + // + while (mFlashDevices->PBlocks != NULL) { + FBNext = mFlashDevices->PBlocks->Next; + _free (mFlashDevices->PBlocks); + mFlashDevices->PBlocks = FBNext; + } + // + // Free the region definitions + // + while (mFlashDevices->Regions != NULL) { + FBNext = mFlashDevices->Regions->Next; + // + // First free the subregion definitions + // + while (mFlashDevices->Regions->Subregions != NULL) { + SubNext = mFlashDevices->Regions->Subregions->Next; + _free (mFlashDevices->Regions->Subregions); + mFlashDevices->Regions->Subregions = SubNext; + } + + _free (mFlashDevices->Regions); + mFlashDevices->Regions = FBNext; + } + + FDNext = mFlashDevices->Next; + _free (mFlashDevices); + mFlashDevices = FDNext; + } + // + // Free up the image definitions, and the data + // + while (mImageDefinitions != NULL) { + // + // Free the entries + // + while (mImageDefinitions->Entries != NULL) { + IDENext = mImageDefinitions->Entries->Next; + if (mImageDefinitions->Entries->RawData != NULL) { + _free (mImageDefinitions->Entries->RawData); + } + + _free (mImageDefinitions->Entries); + mImageDefinitions->Entries = IDENext; + } + + IDNext = mImageDefinitions->Next; + _free (mImageDefinitions); + mImageDefinitions = IDNext; + } +} + +STATUS +FDFParseFile ( + char *FileName + ) +/*++ + +Routine Description: + Parse the specified flash definition file, saving the definitions in + file-static variables for use by other functions. + +Arguments: + FileName - name of the input flash definition text file. + +Returns: + STATUS_SUCCESS - file parsed with no errors or warnings + STATUS_WARNING - warnings, but no errors, were encountered while parsing + STATUS_ERROR - errors were encountered while parsing + +--*/ +{ + FILE *Fptr; + STATUS Status; + unsigned int Num; + FLASH_DEVICE_DESCRIPTION *FDDesc; + FLASH_BLOCK_DESCRIPTION *FBlockDesc; + FLASH_BLOCK_DESCRIPTION *TempBlockDesc; + FLASH_SUBREGION_DESCRIPTION *Subregion; + FLASH_SUBREGION_DESCRIPTION *TempSubregion; + unsigned int BlockSizeLeft; + unsigned int RegionSizeLeft; + unsigned int SubregionSizeLeft; + int ErrorCount; + int WarningCount; + IMAGE_DEFINITION *ImageDef; + IMAGE_DEFINITION_ENTRY *ImageDefEntry; + IMAGE_DEFINITION_ENTRY *TempImageDefEntry; + BUFFER_DATA *BufferData; + char Str[100]; + BOOLEAN PreviousComma; + + if ((Fptr = fopen (FileName, "r")) == NULL) { + Error (NULL, 0, 0, FileName, "failed to open input flash definition file for reading"); + return STATUS_ERROR; + } + + fclose (Fptr); + Status = STATUS_SUCCESS; + ErrorCount = 0; + WarningCount = 0; + // + // Initialize the simple-file-parsing routines + // + SFPInit (); + // + // Open the file + // + if ((Status = SFPOpenFile (FileName)) != STATUS_SUCCESS) { + return Status; + } + // + // Parse the file. Should start with a series of these: + // FlashDevice { + // Name = "FLASH_1234", Size = 0x2004, BaseAddress = 0xFFF0000, ErasePolarity = 1, + // Block { Name = "BLOCK1", Size = 0x1000, Flags = 0x0001 } + // Block { Name = "BLOCK2", Size = 0x1004, Flags = 0x0002 } + // Region { Name = "REGION_NAME", Size = 0x2004, Align= 4 } + // } + // + while (SFPIsKeyword ("FlashDevice")) { + // + // Allocate memory for new flash device description block + // + FDDesc = (FLASH_DEVICE_DESCRIPTION *) _malloc (sizeof (FLASH_DEVICE_DESCRIPTION)); + if (FDDesc == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + ErrorCount++; + goto Done; + } + + memset (FDDesc, 0, sizeof (FLASH_DEVICE_DESCRIPTION)); + // + // Open brace -- warning if not there + // + if (!SFPIsToken ("{")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL); + WarningCount++; + } + // + // Parse: Name = "DeviceName", + // + if (!SFPIsKeyword ("Name")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetQuotedString (FDDesc->Name, sizeof (FDDesc->Name))) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of flash device", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following flash device name", NULL); + WarningCount++; + } + // + // Parse: Size = 0x20000, + // + if (!SFPIsKeyword ("Size")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetNumber (&FDDesc->Size)) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL); + ErrorCount++; + goto Done; + } + // + // Check for 0 size + // + if (FDDesc->Size == 0) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, FDDesc->Name, "Size field cannot be 0", NULL); + ErrorCount++; + goto Done; + } + + SFPIsToken (","); + // + // Parse: BaseAddress = 0xFFF0000, + // + if (!SFPIsKeyword ("BaseAddress")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'BaseAddress'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetNumber (&FDDesc->BaseAddress)) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for BaseAddress", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following BaseAddress value", NULL); + WarningCount++; + } + // + // Parse: ErasePolarity = 1, + // + if (!SFPIsKeyword ("ErasePolarity")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'ErasePolarity'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetNumber (&Num) || ((Num != 0) && (Num != 1))) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric erase polarity value 1 or 0", NULL); + ErrorCount++; + goto Done; + } + + FDDesc->ErasePolarity = Num; + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following erase polarity value", NULL); + WarningCount++; + } + // + // Parse array of: + // Block { Name = "BLOCK1", Size = 0x1000, Flags = 0x0001 } + // + // Keep track of size to make sure the sum of the physical blocks and region sizes do not + // exceed the size of the flash device. + // + BlockSizeLeft = FDDesc->Size; + RegionSizeLeft = FDDesc->Size; + while (SFPIsKeyword ("Block")) { + // + // Allocate memory for a new physical block descriptor + // + FBlockDesc = (FLASH_BLOCK_DESCRIPTION *) _malloc (sizeof (FLASH_BLOCK_DESCRIPTION)); + if (FBlockDesc == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + ErrorCount++; + goto Done; + } + + memset (FBlockDesc, 0, sizeof (FLASH_BLOCK_DESCRIPTION)); + // + // Open brace -- warning if not there + // + if (!SFPIsToken ("{")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL); + WarningCount++; + } + // + // Parse: Name = "BlockName", + // + if (!SFPIsKeyword ("Name")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetQuotedString (FBlockDesc->Name, sizeof (FBlockDesc->Name))) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of physical block", NULL); + ErrorCount++; + goto Done; + } + // + // Make sure there are no other physical block names with this same name + // + for (TempBlockDesc = FDDesc->PBlocks; TempBlockDesc != NULL; TempBlockDesc = TempBlockDesc->Next) { + if (strcmp (TempBlockDesc->Name, FBlockDesc->Name) == 0) { + Error ( + SFPGetFileName (), + SFPGetLineNumber (), + 0, + TempBlockDesc->Name, + "physical block with this name already defined" + ); + ErrorCount++; + } + } + + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following physical block name", NULL); + WarningCount++; + } + // + // Parse: Size = 0x2000, + // + if (!SFPIsKeyword ("Size")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetNumber (&FBlockDesc->Size)) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL); + ErrorCount++; + goto Done; + } + // + // Make sure the sum of physical blocks so far does not exceed flash device size + // + if (BlockSizeLeft < FBlockDesc->Size) { + Error ( + SFPGetFileName (), + SFPGetLineNumber (), + 0, + "sum of physical block sizes exceeds flash device size", + NULL + ); + ErrorCount++; + } + + BlockSizeLeft -= FBlockDesc->Size; + SFPIsToken (","); + // + // Optional parse: Flags = 0xFFF0000, + // + if (SFPIsKeyword ("Flags")) { + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetNumber (&FBlockDesc->Flags)) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for Flags", NULL); + ErrorCount++; + goto Done; + } + } + + if (!SFPIsToken ("}")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected PhysicalBlock closing brace '}'", NULL); + WarningCount++; + } + // + // Add the physical block descriptor to the end of the linked list + // + if (FDDesc->LastPBlock != NULL) { + FDDesc->LastPBlock->Next = FBlockDesc; + } else { + FDDesc->PBlocks = FBlockDesc; + } + + FDDesc->LastPBlock = FBlockDesc; + } + // + // Make sure sum of sizes of physical blocks added up to size of flash device + // + if (BlockSizeLeft != 0) { + Error ( + SFPGetFileName (), + SFPGetLineNumber (), + 0, + NULL, + "sum of sizes of physical blocks (0x%08X) != flash device size (0x%08X) : delta = 0x%08X", + FDDesc->Size - BlockSizeLeft, + FDDesc->Size, + BlockSizeLeft + ); + ErrorCount++; + } + // + // Parse array of: + // Region { Name = "REGION_1", Size = 0x2000, Flags = 0x1234, Alignment = 4, Attributes = "str", AreaType = "str" } + // + while (SFPIsKeyword ("Region")) { + // + // Allocate memory for a new physical block descriptor + // + FBlockDesc = (FLASH_BLOCK_DESCRIPTION *) _malloc (sizeof (FLASH_BLOCK_DESCRIPTION)); + if (FBlockDesc == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + ErrorCount++; + goto Done; + } + + memset (FBlockDesc, 0, sizeof (FLASH_BLOCK_DESCRIPTION)); + // + // Open brace -- warning if not there + // + if (!SFPIsToken ("{")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL); + WarningCount++; + } + // + // Parse: Name = "BlockName", + // + if (!SFPIsKeyword ("Name")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetQuotedString (FBlockDesc->Name, sizeof (FBlockDesc->Name))) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL); + ErrorCount++; + goto Done; + } + // + // Make sure there are no other region names with this same name + // + for (TempBlockDesc = FDDesc->Regions; TempBlockDesc != NULL; TempBlockDesc = TempBlockDesc->Next) { + if (strcmp (TempBlockDesc->Name, FBlockDesc->Name) == 0) { + Error ( + SFPGetFileName (), + SFPGetLineNumber (), + 0, + TempBlockDesc->Name, + "Region with this name already defined" + ); + ErrorCount++; + } + } + + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL); + WarningCount++; + } + // + // Parse: Size = 0x2000, + // + if (!SFPIsKeyword ("Size")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetNumber (&FBlockDesc->Size)) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL); + } + // + // Make sure the sum of regions so far does not exceed flash device size + // + if (RegionSizeLeft < FBlockDesc->Size) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "sum of Region sizes exceeds flash device size", NULL); + ErrorCount++; + } + + RegionSizeLeft -= FBlockDesc->Size; + // + // Optional parse: Flags = 0xFFF0000, + // + if (SFPIsKeyword ("Flags")) { + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetNumber (&FBlockDesc->Flags)) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for Flags", NULL); + ErrorCount++; + goto Done; + } + // + // comma + // + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL); + } + } + // + // Optional parse: Alignment = 4 + // + if (SFPIsKeyword ("Alignment")) { + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetNumber (&FBlockDesc->Alignment)) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Alignment value", NULL); + ErrorCount++; + goto Done; + } + // + // comma + // + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL); + } + } + // + // Parse: Attributes = "String", + // + if (!SFPIsKeyword ("Attributes")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Attributes'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetQuotedString (FBlockDesc->Attributes, sizeof (FBlockDesc->Attributes))) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Attributes string", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL); + } + // + // Parse: AreaType = "String", + // + if (!SFPIsKeyword ("AreaType")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'AreaType'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetQuotedString (FBlockDesc->AreaType, sizeof (FBlockDesc->AreaType))) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted AreaType string", NULL); + ErrorCount++; + goto Done; + } + + PreviousComma = SFPIsToken (","); + // + // Parse optional Subregion definitions + // + SubregionSizeLeft = FBlockDesc->Size; + while (SFPIsToken ("Subregion")) { + if (!PreviousComma) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'Subregion'", NULL); + WarningCount++; + PreviousComma = TRUE; + } + + Subregion = ParseSubregionDefinition (SubregionSizeLeft); + if (Subregion == NULL) { + ErrorCount++; + goto Done; + } + + SubregionSizeLeft -= Subregion->Size; + // + // Add it to the end of our list + // + if (FBlockDesc->Subregions == NULL) { + FBlockDesc->Subregions = Subregion; + } else { + FBlockDesc->LastSubregion->Next = Subregion; + } + + FBlockDesc->LastSubregion = Subregion; + // + // Make sure all subregion names are unique. We do this each time + // through so that we catch the error immediately after it happens, in + // which case the reported line number is at least close to where the + // problem lies. We don't exit on the error because we can continue parsing + // the script to perhaps catch other errors or warnings. + // + for (Subregion = FBlockDesc->Subregions; Subregion != NULL; Subregion = Subregion->Next) { + for (TempSubregion = Subregion->Next; TempSubregion != NULL; TempSubregion = TempSubregion->Next) { + if (strcmp (Subregion->Name, TempSubregion->Name) == 0) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, Subregion->Name, "duplicate Subregion name"); + ErrorCount++; + } + } + } + } + + if (!SFPIsToken ("}")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Region closing brace '}'", NULL); + WarningCount++; + } + // + // Add the region descriptor to the end of the linked list + // + if (FDDesc->LastRegion != NULL) { + FDDesc->LastRegion->Next = FBlockDesc; + } else { + FDDesc->Regions = FBlockDesc; + } + + FDDesc->LastRegion = FBlockDesc; + } + // + // Make sure sum of sizes of regions adds up to size of flash device + // + if (RegionSizeLeft != 0) { + Error ( + SFPGetFileName (), + SFPGetLineNumber (), + 0, + NULL, + "sum of sizes of Regions (0x%08X) != flash device size (0x%08X) : delta = 0x%08X", + FDDesc->Size - RegionSizeLeft, + FDDesc->Size, + RegionSizeLeft + ); + ErrorCount++; + } + // + // Look for closing brace + // + if (!SFPIsToken ("}")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected FlashDevice closing brace '}'", NULL); + WarningCount++; + } + // + // Add this flash description to the list + // + FDDesc->Next = mFlashDevices; + mFlashDevices = FDDesc; + } + + while (SFPIsKeyword ("FlashDeviceImage")) { + // + // Allocate memory for a new FD image definition + // + ImageDef = (IMAGE_DEFINITION *) _malloc (sizeof (IMAGE_DEFINITION)); + if (ImageDef == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + ErrorCount++; + goto Done; + } + + memset (ImageDef, 0, sizeof (IMAGE_DEFINITION)); + // + // Open brace -- warning if not there + // + if (!SFPIsToken ("{")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL); + WarningCount++; + } + // + // Parse: Name = "ImageName", + // + if (!SFPIsKeyword ("Name")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetQuotedString (ImageDef->Name, sizeof (ImageDef->Name))) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of image", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following image name", NULL); + WarningCount++; + } + + while (1) { + // + // Parse: File { Name = "FV\FvOem.fv", Region = "REGION_OEM", Optional = TRUE } + // + if (SFPIsKeyword ("File")) { + ImageDefEntry = (IMAGE_DEFINITION_ENTRY *) _malloc (sizeof (IMAGE_DEFINITION_ENTRY)); + if (ImageDefEntry == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + ErrorCount++; + goto Done; + } + + memset (ImageDefEntry, 0, sizeof (IMAGE_DEFINITION_ENTRY)); + // + // Open brace -- warning if not there + // + if (!SFPIsToken ("{")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL); + WarningCount++; + } + // + // Parse: Name = "FileName.txt" + // + if (!SFPIsKeyword ("Name")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetQuotedString (ImageDefEntry->Name, sizeof (ImageDefEntry->Name))) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of file", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following file name", NULL); + WarningCount++; + } + // + // Parse: Region = "REGION_NAME" + // + if (!SFPIsKeyword ("Region")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Region'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetQuotedString (ImageDefEntry->RegionName, sizeof (ImageDefEntry->RegionName))) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL); + WarningCount++; + } + // + // Parse optional: Subregion = "SUBREGION_NAME" + // + if (SFPIsKeyword ("Subregion")) { + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetQuotedString (ImageDefEntry->SubregionName, sizeof (ImageDefEntry->SubregionName))) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Subegion name", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Subregion name", NULL); + WarningCount++; + } + // + // For a given region, you can only place data using the region name, or the subregion names. + // In other words, you can't say File1->Region1 and File2->Region1.Subregion1. Enforce that + // here by checking that any previous entries with the same Region name had a Subregion specified + // as well. + // + for (TempImageDefEntry = ImageDef->Entries; + TempImageDefEntry != NULL; + TempImageDefEntry = TempImageDefEntry->Next + ) { + if (strcmp (TempImageDefEntry->Name, ImageDefEntry->Name) == 0) { + if (TempImageDefEntry->SubregionName[0] == 0) { + Error ( + SFPGetFileName (), + SFPGetLineNumber (), + 0, + TempImageDefEntry->RegionName, + "data already placed on a region-basis in the region, can't place data using subregions" + ); + ErrorCount++; + } + } + } + } + // + // Optional parse: Optional = TRUE | FALSE + // + if (SFPIsKeyword ("Optional")) { + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPIsKeyword ("TRUE")) { + ImageDefEntry->Optional = 1; + } else if (SFPIsKeyword ("FALSE")) { + // + // Already set to 0 + // + } else { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL); + ErrorCount++; + goto Done; + } + + SFPIsToken (","); + } + // + // Closing brace + // + if (!SFPIsToken ("}")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '}' closing brace to File entry", NULL); + ErrorCount++; + goto Done; + } + // + // Add the entry to the end of the list + // + if (ImageDef->LastEntry != NULL) { + ImageDef->LastEntry->Next = ImageDefEntry; + } else { + ImageDef->Entries = ImageDefEntry; + } + + ImageDef->LastEntry = ImageDefEntry; + } else if (SFPIsKeyword ("RawData")) { + // + // Parse: RawData { Name = "PadBytes", Region = "REGION_1", Data = { 0x78, 0x56, 0x34, 0x12 }} + // + ImageDefEntry = (IMAGE_DEFINITION_ENTRY *) _malloc (sizeof (IMAGE_DEFINITION_ENTRY)); + if (ImageDefEntry == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + ErrorCount++; + goto Done; + } + + memset (ImageDefEntry, 0, sizeof (IMAGE_DEFINITION_ENTRY)); + ImageDefEntry->IsRawData = 1; + // + // Open brace -- warning if not there + // + if (!SFPIsToken ("{")) { + Warning ( + SFPGetFileName (), + SFPGetLineNumber (), + 0, + "expected '{' opening brace for RawData definition", + NULL + ); + WarningCount++; + } + // + // Parse: Name = "PadBytes" + // + if (!SFPIsKeyword ("Name")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetQuotedString (ImageDefEntry->Name, sizeof (ImageDefEntry->Name))) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of raw data", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following raw data name", NULL); + WarningCount++; + } + // + // Parse: Region = "REGION_NAME" + // + if (!SFPIsKeyword ("Region")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Region'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetQuotedString (ImageDefEntry->RegionName, sizeof (ImageDefEntry->RegionName))) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL); + WarningCount++; + } + // + // Parse optional: Subregion = "SUBREGION_NAME" + // + if (SFPIsKeyword ("Subregion")) { + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetQuotedString (ImageDefEntry->SubregionName, sizeof (ImageDefEntry->SubregionName))) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Subegion name", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Subregion name", NULL); + WarningCount++; + } + // + // For a given region, you can only place data using the region name, or the subregion names. + // In other words, you can't say File1->Region1 and File2->Region1.Subregion1. Enforce that + // here by checking that any previous entries with the same Region name had a Subregion specified + // as well. + // + for (TempImageDefEntry = ImageDef->Entries; + TempImageDefEntry != NULL; + TempImageDefEntry = TempImageDefEntry->Next + ) { + if (strcmp (TempImageDefEntry->Name, ImageDefEntry->Name) == 0) { + if (TempImageDefEntry->SubregionName[0] == 0) { + Error ( + SFPGetFileName (), + SFPGetLineNumber (), + 0, + TempImageDefEntry->RegionName, + "data already placed on a region-basis in the region, can't place data using subregions" + ); + ErrorCount++; + } + } + } + } + // + // Parse: Data = { 0x78, 0x56, 0x34, 0x12 } + // + if (!SFPIsKeyword ("Data")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Data'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPIsToken ("{")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '{' preceeding data list", NULL); + WarningCount++; + } + + if ((BufferData = CreateBufferData ()) == NULL) { + ErrorCount++; + goto Done; + } + // + // Read bytes from input file until closing brace + // + while (!SFPIsToken ("}")) { + if (!SFPGetNumber (&Num)) { + SFPGetNextToken (Str, sizeof (Str)); + Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "expected data value", Str); + ErrorCount++; + FreeBufferData (BufferData, TRUE); + goto Done; + } else { + // + // Only allow bytes + // + if (Num > 0xFF) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "only values 0-255 (0x00-0xFF) allowed", NULL); + ErrorCount++; + FreeBufferData (BufferData, TRUE); + goto Done; + } + + AddBufferDataByte (BufferData, (char) Num); + SFPIsToken (","); + } + } + // + // Now get the data and save it in our image entry + // + ImageDefEntry->RawData = GetBufferData (BufferData, &ImageDefEntry->RawDataSize); + FreeBufferData (BufferData, 0); + // + // Closing brace for RawData {} + // + if (!SFPIsToken ("}")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '}' closing brace for RawData", NULL); + ErrorCount++; + goto Done; + } + // + // Add the entry to the end of the list + // + if (ImageDef->LastEntry != NULL) { + ImageDef->LastEntry->Next = ImageDefEntry; + } else { + ImageDef->Entries = ImageDefEntry; + } + + ImageDef->LastEntry = ImageDefEntry; + } else if (SFPIsToken ("}")) { + // + // Closing brace for FDImage {} + // + break; + } else { + SFPGetNextToken (Str, sizeof (Str)); + Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "unrecognized token", Str); + ErrorCount++; + goto Done; + } + } + // + // Add this image definition to our global list + // + ImageDef->Next = mImageDefinitions; + mImageDefinitions = ImageDef; + } + // + // Check for end-of-file + // + if (!SFPIsEOF ()) { + SFPGetNextToken (Str, sizeof (Str)); + Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "expected end-of-file", Str); + ErrorCount++; + } + +Done: + SFPCloseFile (); + if (ErrorCount != 0) { + return STATUS_ERROR; + } else if (WarningCount != 0) { + return STATUS_WARNING; + } + + return STATUS_SUCCESS; +} + +static +FLASH_SUBREGION_DESCRIPTION * +ParseSubregionDefinition ( + unsigned int SizeLeft + ) +/*++ + +Routine Description: + + Parse Subregion definitions from the input flash definition file. Format: + + Subregion { + CreateHob = TRUE, + Name = "FOO", + Size = 0xA000, + Attributes = "EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV", + AreaType = "EFI_FLASH_AREA_EFI_VARIABLES", + NameGuid = 12345678-1234-5678-AAAA-BBBBCCCCDDDD (or "EFI_SOME_GUID"), + AreaTypeGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID") (optional) + FileSystemGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID") (optional) + } + + NOTE: The caller has already parsed the "Subregion" token, so start with the opening brace. + +Arguments: + + SizeLeft - in the flash definition file, a Region can be broken up into + one or more subregions. As we parse the subregion definitions, + the caller keeps track of how much space is left in the region + that we're parsing subregions for. SizeLeft is that size, and + so the size of the subregion we're now parsing better not + exceed the size left. + Returns: + + NULL - unrecoverable errors detected while parsing the subregion definition + + pointer to a subregion definition created from the parsed subregion + +--*/ +{ + FLASH_SUBREGION_DESCRIPTION *Subregion; + int ErrorCount; + int WarningCount; + unsigned int Number; + BOOLEAN PreviousComma; + // + // Allocate memory for the new subregion descriptor + // + ErrorCount = 0; + WarningCount = 0; + Subregion = (FLASH_SUBREGION_DESCRIPTION *) _malloc (sizeof (FLASH_SUBREGION_DESCRIPTION)); + if (Subregion == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + ErrorCount++; + goto Done; + } + + memset (Subregion, 0, sizeof (FLASH_SUBREGION_DESCRIPTION)); + // + // Open brace -- warning if not there + // + if (!SFPIsToken ("{")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL); + WarningCount++; + } + // + // Parse: CreateHob = TRUE | FALSE, + // + if (!SFPIsKeyword ("CreateHob")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'CreateHob'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (SFPIsToken ("TRUE")) { + Subregion->CreateHob = 1; + } else if (SFPIsToken ("FALSE")) { + // + // Subregion->CreateHob = 0; -- not required since we did a memset earlier + // + } else { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following CreateHob value", NULL); + WarningCount++; + } + // + // Parse: Name = "Name", + // + if (!SFPIsKeyword ("Name")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetQuotedString (Subregion->Name, sizeof (Subregion->Name))) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Subregion name", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL); + WarningCount++; + } + // + // Parse: Size = 0x2000, + // + if (!SFPIsKeyword ("Size")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (!SFPGetNumber (&Subregion->Size)) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL); + ErrorCount++; + goto Done; + } + + // + // Check that the size does not exceed the size left passed in + // + if (Subregion->Size > SizeLeft) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "sum of Subregion sizes exceeds Region size", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following Size value", NULL); + } + // + // Parse: Attributes = Number | "String", + // + if (!SFPIsKeyword ("Attributes")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Attributes'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (SFPGetNumber (&Number)) { + sprintf (Subregion->Attributes, "0x%X", Number); + } else if (!SFPGetQuotedString (Subregion->Attributes, sizeof (Subregion->Attributes))) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Attributes string", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL); + } + // + // Parse: AreaType = Number | "String", + // AreaType is a UINT8, so error if it exceeds the size + // + if (!SFPIsKeyword ("AreaType")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'AreaType'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (SFPGetNumber (&Number)) { + if (Number > 0xFF) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "AreaType value exceeds 255", NULL); + ErrorCount++; + } + + sprintf (Subregion->AreaType, "0x%X", Number & 0x00FF); + } else if (!SFPGetQuotedString (Subregion->AreaType, sizeof (Subregion->AreaType))) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted AreaType string", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken (",")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following AreaType value", NULL); + } + // + // Parse the three GUIDs (last two are optional) + // + // NameGuid = 12345678-1234-5678-AAAA-BBBBCCCCDDDD, (or "EFI_SOME_GUID") + // AreaTypeGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID") + // FileSysteGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID") + // + if (!SFPIsKeyword ("NameGuid")) { + Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'NameGuid'", NULL); + ErrorCount++; + goto Done; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + // + // Allow a GUID or a quoted string identifier, which we'll just copy as a string + // + if (SFPGetQuotedString (Subregion->NameGuidString, sizeof (Subregion->NameGuidString))) { + // + // Nothing else to do + // + } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->NameGuid)) { + Error ( + SFPGetFileName (), + SFPGetLineNumber (), + 0, + "expected NameGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC", + NULL + ); + ErrorCount++; + goto Done; + } + // + // Comma following NameGuid is optional if they don't specify AreaTypeGuid or FileSystemGuid + // + PreviousComma = SFPIsToken (","); + if (SFPIsKeyword ("AreaTypeGuid")) { + // + // Check for preceeding comma now + // + if (!PreviousComma) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'AreaTypeGuid'", NULL); + WarningCount++; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + + if (SFPGetQuotedString (Subregion->AreaTypeGuidString, sizeof (Subregion->AreaTypeGuidString))) { + // + // Nothing else to do + // + } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->AreaTypeGuid)) { + Error ( + SFPGetFileName (), + SFPGetLineNumber (), + 0, + "expected AreaTypeGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC", + NULL + ); + ErrorCount++; + goto Done; + } + + PreviousComma = SFPIsToken (","); + } + + if (SFPIsKeyword ("FileSystemGuid")) { + // + // Check for preceeding comma now + // + if (!PreviousComma) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'FileSystemGuid'", NULL); + WarningCount++; + } + + if (!SFPIsToken ("=")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); + WarningCount++; + } + // + // Allow a GUID or a quoted string identifier, which we'll just copy as a string + // + if (SFPGetQuotedString (Subregion->FileSystemGuidString, sizeof (Subregion->FileSystemGuidString))) { + // + // Nothing else to do + // + } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->FileSystemGuid)) { + Error ( + SFPGetFileName (), + SFPGetLineNumber (), + 0, + "expected FileSystemGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC", + NULL + ); + ErrorCount++; + goto Done; + } + + SFPIsToken (","); + } + // + // Look for subregion closing brace + // + if (!SFPIsToken ("}")) { + Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Subregion closing brace '}'", NULL); + WarningCount++; + } + +Done: + // + // If any errors were encountered, then delete the subregion definition + // + if (ErrorCount != 0) { + _free (Subregion); + Subregion = NULL; + } + + return Subregion; +} + +STATUS +FDFCreateCIncludeFile ( + char *FlashDeviceName, + char *FileName + ) +/*++ + +Routine Description: + Create a header file with #define definitions per an already-parsed + flash definition file. + +Arguments: + FlashDeviceName - name of flash device (from the flash definition file) + to use + FileName - name of output file to create + +Returns: + STATUS_SUCCESS - no errors or warnings + STATUS_WARNING - warnings, but no errors, were encountered + STATUS_ERROR - errors were encountered + +--*/ +{ + FILE *OutFptr; + FLASH_BLOCK_DESCRIPTION *FBlock; + FLASH_DEVICE_DESCRIPTION *FDev; + FLASH_SUBREGION_DESCRIPTION *Subregion; + unsigned int Offset; + unsigned int SubregionOffset; + int CreateHobs; + // + // Find the definition we're supposed to use + // + for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) { + if (strcmp (FDev->Name, FlashDeviceName) == 0) { + break; + } + } + + if (FDev == NULL) { + Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions"); + return STATUS_ERROR; + } + + if ((OutFptr = fopen (FileName, "w")) == NULL) { + Error (NULL, 0, 0, FileName, "failed to open output file for writing"); + return STATUS_ERROR; + } + // + // Write a header + // + fprintf (OutFptr, CIncludeHeader); + // + // Write flash block base and size defines + // + fprintf (OutFptr, "#define FLASH_BASE 0x%08X\n", FDev->BaseAddress); + fprintf (OutFptr, "#define FLASH_SIZE 0x%08X\n\n", FDev->Size); + // + // Write flash regions base, size and offset defines + // + Offset = 0; + CreateHobs = 0; + for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) { + fprintf ( + OutFptr, + "#define FLASH_REGION_%s_BASE %*c0x%08X\n", + FBlock->Name, + COLUMN2_START - 40 - strlen (FBlock->Name), + ' ', + Offset + FDev->BaseAddress + ); + fprintf ( + OutFptr, + "#define FLASH_REGION_%s_SIZE %*c0x%08X\n", + FBlock->Name, + COLUMN2_START - 40 - strlen (FBlock->Name), + ' ', + FBlock->Size + ); + fprintf ( + OutFptr, + "#define FLASH_REGION_%s_OFFSET %*c0x%08X\n", + FBlock->Name, + COLUMN2_START - 40 - strlen (FBlock->Name), + ' ', + Offset + ); + // + // Create defines for any subregions + // + SubregionOffset = 0; + for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) { + fprintf ( + OutFptr, + "#define FLASH_REGION_%s_SUBREGION_%s_BASE %*c0x%08X\n", + FBlock->Name, + Subregion->Name, + COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name), + ' ', + FDev->BaseAddress + Offset + SubregionOffset + ); + fprintf ( + OutFptr, + "#define FLASH_REGION_%s_SUBREGION_%s_SIZE %*c0x%08X\n", + FBlock->Name, + Subregion->Name, + COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name), + ' ', + Subregion->Size + ); + fprintf ( + OutFptr, + "#define FLASH_REGION_%s_SUBREGION_%s_OFFSET %*c0x%08X\n", + FBlock->Name, + Subregion->Name, + COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name), + ' ', + Offset + SubregionOffset + ); + SubregionOffset += Subregion->Size; + if (Subregion->CreateHob != 0) { + CreateHobs = 1; + } + } + + Offset += FBlock->Size; + } + // + // Now create a #define for the flash map data definition + // + fprintf (OutFptr, "\n\n#define EFI_FLASH_AREA_DATA_DEFINITION \\\n"); + // + // Emit entry for each region + // + Offset = 0; + for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) { + fprintf (OutFptr, " /* %s region */\\\n", FBlock->Name); + fprintf (OutFptr, " {\\\n"); + fprintf (OutFptr, " FLASH_REGION_%s_BASE,\\\n", FBlock->Name); + fprintf (OutFptr, " FLASH_REGION_%s_SIZE,\\\n", FBlock->Name); + fprintf (OutFptr, " %s,\\\n", FBlock->Attributes); + fprintf (OutFptr, " %s,\\\n },\\\n", FBlock->AreaType); + } + + fprintf (OutFptr, "\n\n"); + // + // Now walk the list again to create the EFI_HOB_FLASH_MAP_ENTRY_TYPE definition + // + if (CreateHobs != 0) { + fprintf (OutFptr, "//\n// EFI_HOB_FLASH_MAP_ENTRY_TYPE definition\n//\n"); + fprintf (OutFptr, "#define EFI_HOB_FLASH_MAP_ENTRY_TYPE_DATA_DEFINITION"); + for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) { + // + // See if the block has subregions, and that the CreateHobs flag is set + // for any of them. + // + CreateHobs = 0; + for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) { + if (Subregion->CreateHob != 0) { + CreateHobs = 1; + break; + } + } + // + // If any of the subregions had the CreateHobs flag set, then create the entries in the + // output file + // + if (CreateHobs != 0) { + for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) { + if (Subregion->CreateHob != 0) { + fprintf (OutFptr, " \\\n"); + fprintf (OutFptr, " /* %s.%s Subregion */\\\n", FBlock->Name, Subregion->Name); + fprintf (OutFptr, " {\\\n"); + fprintf (OutFptr, " EFI_HOB_TYPE_GUID_EXTENSION,\\\n"); + fprintf (OutFptr, " sizeof (EFI_HOB_FLASH_MAP_ENTRY_TYPE ),\\\n"); + fprintf (OutFptr, " 0,\\\n"); + // + // The NameGuid may have been specified in the input flash definition file as a GUID, or + // as a quoted string. Do the right one. + // + if (Subregion->NameGuidString[0] != 0) { + fprintf (OutFptr, " %s, \\\n", Subregion->NameGuidString); + } else { + fprintf ( + OutFptr, + " { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n", + Subregion->NameGuid.Data1, + (unsigned int) Subregion->NameGuid.Data2, + (unsigned int) Subregion->NameGuid.Data3, + (unsigned int) Subregion->NameGuid.Data4[0], + (unsigned int) Subregion->NameGuid.Data4[1], + (unsigned int) Subregion->NameGuid.Data4[2], + (unsigned int) Subregion->NameGuid.Data4[3], + (unsigned int) Subregion->NameGuid.Data4[4], + (unsigned int) Subregion->NameGuid.Data4[5], + (unsigned int) Subregion->NameGuid.Data4[6], + (unsigned int) Subregion->NameGuid.Data4[7] + ); + } + + fprintf (OutFptr, " 0, 0, 0,\\\n"); + fprintf (OutFptr, " %s,\\\n", Subregion->AreaType); + // + // The AreaTypeGuid may have been specified in the input flash definition file as a GUID, or + // as a quoted string. Do the right one. + // + if (Subregion->AreaTypeGuidString[0] != 0) { + fprintf (OutFptr, " %s, \\\n", Subregion->AreaTypeGuidString); + } else { + fprintf ( + OutFptr, + " { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n", + Subregion->AreaTypeGuid.Data1, + (unsigned int) Subregion->AreaTypeGuid.Data2, + (unsigned int) Subregion->AreaTypeGuid.Data3, + (unsigned int) Subregion->AreaTypeGuid.Data4[0], + (unsigned int) Subregion->AreaTypeGuid.Data4[1], + (unsigned int) Subregion->AreaTypeGuid.Data4[2], + (unsigned int) Subregion->AreaTypeGuid.Data4[3], + (unsigned int) Subregion->AreaTypeGuid.Data4[4], + (unsigned int) Subregion->AreaTypeGuid.Data4[5], + (unsigned int) Subregion->AreaTypeGuid.Data4[6], + (unsigned int) Subregion->AreaTypeGuid.Data4[7] + ); + } + + fprintf (OutFptr, " 1,\\\n"); + fprintf (OutFptr, " {\\\n"); + fprintf (OutFptr, " %s,\\\n", Subregion->Attributes); + fprintf (OutFptr, " 0,\\\n"); + fprintf (OutFptr, " FLASH_REGION_%s_SUBREGION_%s_BASE,\\\n", FBlock->Name, Subregion->Name); + fprintf (OutFptr, " FLASH_REGION_%s_SUBREGION_%s_SIZE,\\\n", FBlock->Name, Subregion->Name); + // + // The FileSystemGuid may have been specified in the input flash definition file as a GUID, or + // as a quoted string. Do the right one. + // + if (Subregion->FileSystemGuidString[0] != 0) { + fprintf (OutFptr, " %s, \\\n", Subregion->FileSystemGuidString); + } else { + fprintf ( + OutFptr, + " { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n", + Subregion->FileSystemGuid.Data1, + (unsigned int) Subregion->FileSystemGuid.Data2, + (unsigned int) Subregion->FileSystemGuid.Data3, + (unsigned int) Subregion->FileSystemGuid.Data4[0], + (unsigned int) Subregion->FileSystemGuid.Data4[1], + (unsigned int) Subregion->FileSystemGuid.Data4[2], + (unsigned int) Subregion->FileSystemGuid.Data4[3], + (unsigned int) Subregion->FileSystemGuid.Data4[4], + (unsigned int) Subregion->FileSystemGuid.Data4[5], + (unsigned int) Subregion->FileSystemGuid.Data4[6], + (unsigned int) Subregion->FileSystemGuid.Data4[7] + ); + } + + fprintf (OutFptr, " },\\\n"); + fprintf (OutFptr, " },"); + } + } + } + } + + fprintf (OutFptr, "\n\n"); + } + + // + // Write the file's closing #endif + // + fprintf (OutFptr, CIncludeFooter); + fclose (OutFptr); + return STATUS_SUCCESS; +} + +STATUS +FDFCreateAsmIncludeFile ( + char *FlashDeviceName, + char *FileName + ) +/*++ + +Routine Description: + Create an assembly header file with equate definitions per an already-parsed + flash definition file. + +Arguments: + FlashDeviceName - name of flash device (from the flash definition file) + to use + FileName - name of output file to create + +Returns: + STATUS_SUCCESS - no errors or warnings + STATUS_WARNING - warnings, but no errors, were encountered + STATUS_ERROR - errors were encountered + +--*/ +{ + FILE *OutFptr; + FLASH_BLOCK_DESCRIPTION *FBlock; + FLASH_DEVICE_DESCRIPTION *FDev; + unsigned int Offset; + FLASH_SUBREGION_DESCRIPTION *Subregion; + unsigned int SubregionOffset; + // + // Find the definition we're supposed to use + // + for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) { + if (strcmp (FDev->Name, FlashDeviceName) == 0) { + break; + } + } + + if (FDev == NULL) { + Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions"); + return STATUS_ERROR; + } + + if ((OutFptr = fopen (FileName, "w")) == NULL) { + Error (NULL, 0, 0, FileName, "failed to open output file for writing"); + return STATUS_ERROR; + } + // + // Write a header + // + fprintf (OutFptr, "\n\n"); + // + // Write flash block size and offset defines + // + fprintf ( + OutFptr, + "FLASH_BASE %*cequ 0%08Xh\n", + COLUMN2_START - 40, + ' ', + FDev->BaseAddress + ); + fprintf (OutFptr, "FLASH_SIZE %*cequ 0%08Xh\n", COLUMN2_START - 40, ' ', FDev->Size); + // + // Write flash region size and offset defines + // + fprintf (OutFptr, "\n"); + Offset = 0; + for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) { + fprintf ( + OutFptr, + "FLASH_REGION_%s_BASE %*cequ 0%08Xh\n", + FBlock->Name, + COLUMN2_START - 20 - strlen (FBlock->Name), + ' ', + FDev->BaseAddress + Offset + ); + fprintf ( + OutFptr, + "FLASH_REGION_%s_SIZE %*cequ 0%08Xh\n", + FBlock->Name, + COLUMN2_START - 20 - strlen (FBlock->Name), + ' ', + FBlock->Size + ); + fprintf ( + OutFptr, + "FLASH_REGION_%s_OFFSET %*cequ 0%08Xh\n", + FBlock->Name, + COLUMN2_START - 20 - strlen (FBlock->Name), + ' ', + Offset + ); + // + // Create defines for any subregions + // + SubregionOffset = 0; + for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) { + fprintf ( + OutFptr, + "FLASH_REGION_%s_SUBREGION_%s_BASE %*cequ 0%08Xh\n", + FBlock->Name, + Subregion->Name, + COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name), + ' ', + FDev->BaseAddress + Offset + SubregionOffset + ); + fprintf ( + OutFptr, + "FLASH_REGION_%s_SUBREGION_%s_SIZE %*cequ 0%08Xh\n", + FBlock->Name, + Subregion->Name, + COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name), + ' ', + Subregion->Size + ); + fprintf ( + OutFptr, + "FLASH_REGION_%s_SUBREGION_%s_OFFSET %*cequ 0%08Xh\n", + FBlock->Name, + Subregion->Name, + COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name), + ' ', + Offset + SubregionOffset + ); + SubregionOffset += Subregion->Size; + } + + Offset += FBlock->Size; + } + + // + // Write closing \n + // + fprintf (OutFptr, "\n\n"); + fclose (OutFptr); + return STATUS_SUCCESS; +} + +STATUS +FDFCreateSymbols ( + char *FlashDeviceName + ) +/*++ + +Routine Description: + Using the given flash device name, add symbols to the global symbol table. This + allows other functions to use the symbol definitions for other purposes. + +Arguments: + FlashDeviceName - name of flash device (from the flash definition file) + to use + +Returns: + STATUS_SUCCESS - no errors or warnings + STATUS_WARNING - warnings, but no errors, were encountered + STATUS_ERROR - errors were encountered + +--*/ +{ + FLASH_BLOCK_DESCRIPTION *FBlock; + FLASH_DEVICE_DESCRIPTION *FDev; + unsigned int Offset; + char SymName[120]; + char SymValue[120]; + FLASH_SUBREGION_DESCRIPTION *Subregion; + unsigned int SubregionOffset; + // + // Find the definition we're supposed to use + // + for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) { + if (strcmp (FDev->Name, FlashDeviceName) == 0) { + break; + } + } + + if (FDev == NULL) { + Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions"); + return STATUS_ERROR; + } + + sprintf (SymValue, "0x%08X", FDev->BaseAddress); + SymbolAdd ("FLASH_BASE", SymValue, 0); + sprintf (SymValue, "0x%08X", FDev->Size); + SymbolAdd ("FLASH_SIZE", SymValue, 0); + // + // Add flash block size and offset defines + // + // Offset = 0; + // for (FBlock = FDev->PBlocks; FBlock != NULL; FBlock = FBlock->Next) { + // sprintf (SymName, "FLASH_BLOCK_%s_BASE", FBlock->Name); + // sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset); + // SymbolAdd (SymName, SymValue, 0); + // sprintf (SymName, "FLASH_BLOCK_%s_SIZE", FBlock->Name); + // sprintf (SymValue, "0x%08X", FBlock->Size); + // SymbolAdd (SymName, SymValue, 0); + // sprintf (SymName, "FLASH_BLOCK_%s_OFFSET", FBlock->Name); + // sprintf (SymValue, "0x%08X", Offset); + // SymbolAdd (SymName, SymValue, 0); + // Offset += FBlock->Size; + // } + // + // Add flash region block base, size, and offset defines + // + Offset = 0; + for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) { + sprintf (SymName, "FLASH_REGION_%s_BASE", FBlock->Name); + sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset); + SymbolAdd (SymName, SymValue, 0); + sprintf (SymName, "FLASH_REGION_%s_SIZE", FBlock->Name); + sprintf (SymValue, "0x%08X", FBlock->Size); + SymbolAdd (SymName, SymValue, 0); + sprintf (SymName, "FLASH_REGION_%s_OFFSET", FBlock->Name); + sprintf (SymValue, "0x%08X", Offset); + SymbolAdd (SymName, SymValue, 0); + // + // Add subregion symbols + // + if (FBlock->Subregions != NULL) { + SubregionOffset = 0; + for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) { + sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_BASE", FBlock->Name, Subregion->Name); + sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset + SubregionOffset); + SymbolAdd (SymName, SymValue, 0); + sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_SIZE", FBlock->Name, Subregion->Name); + sprintf (SymValue, "0x%08X", Subregion->Size); + SymbolAdd (SymName, SymValue, 0); + sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_OFFSET", FBlock->Name, Subregion->Name); + sprintf (SymValue, "0x%08X", Offset + SubregionOffset); + SymbolAdd (SymName, SymValue, 0); + SubregionOffset += Subregion->Size; + } + } + + Offset += FBlock->Size; + } + + return STATUS_SUCCESS; +} + +STATUS +FDFCreateImage ( + char *FlashDeviceName, + char *ImageName, + char *FileName + ) +/*++ + +Routine Description: + Create a flash image using the given device and image names. + +Arguments: + FlashDeviceName - name of flash device (from the flash definition file) + to use + ImageName - name of image (from the flash definition file) to create + FileName - name of output file to create + +Returns: + STATUS_SUCCESS - no errors or warnings + STATUS_WARNING - warnings, but no errors, were encountered + STATUS_ERROR - errors were encountered + +--*/ +{ + STATUS Status; + FILE *OutFptr; + FLASH_BLOCK_DESCRIPTION *RegionDef; + FLASH_DEVICE_DESCRIPTION *FDev; + IMAGE_DEFINITION *ImageDef; + unsigned int Offset; + char *Buffer; + FILE *InFptr; + long FileSize; + IMAGE_DEFINITION_ENTRY *IDefEntry; + FLASH_SUBREGION_DESCRIPTION *SubregionDef; + // + // Find the flash definition we're supposed to use + // + InFptr = NULL; + Status = STATUS_ERROR; + for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) { + if (strcmp (FDev->Name, FlashDeviceName) == 0) { + break; + } + } + + if (FDev == NULL) { + Error (NULL, 0, 0, FlashDeviceName, "flash device not found in flash definitions"); + return STATUS_ERROR; + } + // + // Find the image name we're supposed to create + // + for (ImageDef = mImageDefinitions; ImageDef != NULL; ImageDef = ImageDef->Next) { + if (strcmp (ImageDef->Name, ImageName) == 0) { + break; + } + } + + if (ImageDef == NULL) { + Error (NULL, 0, 0, ImageName, "image definition not found in image definitions"); + return STATUS_ERROR; + } + // + // Open the output file + // + if ((OutFptr = fopen (FileName, "wb")) == NULL) { + Error (NULL, 0, 0, FileName, "failed to open output file for writing"); + return STATUS_ERROR; + } + // + // Allocate a buffer to copy the input data to + // + Buffer = (char *) _malloc (FDev->Size); + if (Buffer == NULL) { + Error (NULL, 0, 0, (INT8 *) "failed to allocate memory", NULL); + goto Done; + } + // + // Set contents of buffer to the erased value + // + if (FDev->ErasePolarity) { + memset (Buffer, 0xFF, FDev->Size); + } else { + memset (Buffer, 0, FDev->Size); + } + // + // Set all region and subregion size-left fields to the size of the region/subregion + // + for (RegionDef = FDev->Regions; RegionDef != NULL; RegionDef = RegionDef->Next) { + RegionDef->SizeLeft = RegionDef->Size; + for (SubregionDef = RegionDef->Subregions; SubregionDef != NULL; SubregionDef = SubregionDef->Next) { + SubregionDef->SizeLeft = SubregionDef->Size; + } + } + // + // Now go through the image list, read files into the buffer. + // + for (IDefEntry = ImageDef->Entries; IDefEntry != NULL; IDefEntry = IDefEntry->Next) { + // + // If it's a file name, open the file, get the size, find the corresponding + // flash region it's in, and copy the data. + // + if (IDefEntry->IsRawData == 0) { + if ((InFptr = fopen (IDefEntry->Name, "rb")) == NULL) { + Error (NULL, 0, 0, IDefEntry->Name, "failed to open input file for reading"); + goto Done; + } + + fseek (InFptr, 0, SEEK_END); + FileSize = ftell (InFptr); + fseek (InFptr, 0, SEEK_SET); + } else { + FileSize = IDefEntry->RawDataSize; + } + // + // Find the region/subregion it's in, see if we have space left + // + Offset = 0; + for (RegionDef = FDev->Regions; RegionDef != NULL; RegionDef = RegionDef->Next) { + if (strcmp (RegionDef->Name, IDefEntry->RegionName) == 0) { + break; + } + + Offset += RegionDef->Size; + } + + if (RegionDef == NULL) { + Error (NULL, 0, 0, IDefEntry->RegionName, "Region name not found in FlashDevice %s definition", FDev->Name); + goto Done; + } + + // + // Check for subregion + // + if (IDefEntry->SubregionName[0] != 0) { + for (SubregionDef = RegionDef->Subregions; SubregionDef != NULL; SubregionDef = SubregionDef->Next) { + if (strcmp (SubregionDef->Name, IDefEntry->SubregionName) == 0) { + break; + } + + Offset += SubregionDef->Size; + } + + if (SubregionDef == NULL) { + Error ( + NULL, + 0, + 0, + IDefEntry->SubregionName, + "Subregion name not found in FlashDevice %s.%s Region definition", + FDev->Name, + RegionDef->Name + ); + goto Done; + } + // + // Enough space in the subregion? + // + if (SubregionDef->SizeLeft < (unsigned int) FileSize) { + Error ( + NULL, + 0, + 0, + IDefEntry->Name, + "insufficient space in Subregion (at least 0x%X additional bytes required)", + FileSize - SubregionDef->SizeLeft + ); + goto Done; + } + + // + // Read the file into the buffer if it's a file. Otherwise copy the raw data + // + if (IDefEntry->IsRawData == 0) { + if (fread (Buffer + Offset + (SubregionDef->Size - SubregionDef->SizeLeft), FileSize, 1, InFptr) != 1) { + Error (NULL, 0, 0, IDefEntry->Name, "failed to read file contents"); + goto Done; + } + + fclose (InFptr); + InFptr = NULL; + } else { + memcpy ( + Buffer + Offset + (SubregionDef->Size - SubregionDef->SizeLeft), + IDefEntry->RawData, + IDefEntry->RawDataSize + ); + } + + SubregionDef->SizeLeft -= FileSize; + // + // Align based on the Region alignment requirements. + // + if (RegionDef->Alignment != 0) { + while (((unsigned int) (SubregionDef->Size - SubregionDef->SizeLeft) &~RegionDef->Alignment) != 0) { + if (SubregionDef->SizeLeft == 0) { + break; + } + + SubregionDef->SizeLeft--; + } + } + } else { + // + // Placing data in a region. Check for enough space in the region left. + // + if (RegionDef->SizeLeft < (unsigned int) FileSize) { + Error ( + NULL, + 0, + 0, + IDefEntry->Name, + "insufficient space in Region (at least 0x%X additional bytes required)", + FileSize - RegionDef->SizeLeft + ); + goto Done; + } + + // + // Read the file into the buffer if it's a file. Otherwise copy the raw data + // + if (IDefEntry->IsRawData == 0) { + if (fread (Buffer + Offset + (RegionDef->Size - RegionDef->SizeLeft), FileSize, 1, InFptr) != 1) { + Error (NULL, 0, 0, IDefEntry->Name, "failed to read file contents"); + goto Done; + } + + fclose (InFptr); + InFptr = NULL; + } else { + memcpy (Buffer + Offset + (RegionDef->Size - RegionDef->SizeLeft), IDefEntry->RawData, IDefEntry->RawDataSize); + } + + RegionDef->SizeLeft -= FileSize; + // + // Align + // + if (RegionDef->Alignment != 0) { + while (((unsigned int) (RegionDef->Size - RegionDef->SizeLeft) &~RegionDef->Alignment) != 0) { + if (RegionDef->SizeLeft == 0) { + break; + } + + RegionDef->SizeLeft--; + } + } + } + } + + if (fwrite (Buffer, FDev->Size, 1, OutFptr) != 1) { + Error (NULL, 0, 0, "failed to write buffer contents to output file", NULL); + goto Done; + } + + Status = STATUS_SUCCESS; +Done: + if (InFptr != NULL) { + fclose (InFptr); + } + + if (Buffer != NULL) { + _free (Buffer); + } + + if (OutFptr != NULL) { + fclose (OutFptr); + if (Status == STATUS_ERROR) { + remove (FileName); + } + } + + return Status; +} + +STATUS +FDFCreateDscFile ( + char *FlashDeviceName, + char *FileName + ) +/*++ + +Routine Description: + Create a DSC-style output file with equates for flash management. + +Arguments: + FlashDeviceName - name of flash device (from the flash definition file) + to use + FileName - name of output file to create + +Returns: + STATUS_SUCCESS - no errors or warnings + STATUS_WARNING - warnings, but no errors, were encountered + STATUS_ERROR - errors were encountered + +--*/ +{ + FILE *OutFptr; + FLASH_BLOCK_DESCRIPTION *FBlock; + FLASH_DEVICE_DESCRIPTION *FDev; + unsigned int Offset; + FLASH_SUBREGION_DESCRIPTION *Subregion; + unsigned int SubregionOffset; + // + // Find the definition we're supposed to use + // + for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) { + if (strcmp (FDev->Name, FlashDeviceName) == 0) { + break; + } + } + + if (FDev == NULL) { + Error (NULL, 0, 0, FlashDeviceName, "flash device not found in flash definitions"); + return STATUS_ERROR; + } + + if ((OutFptr = fopen (FileName, "w")) == NULL) { + Error (NULL, 0, 0, FileName, "failed to open output file for writing"); + return STATUS_ERROR; + } + // + // Write the flash base address and size + // + fprintf (OutFptr, "\n"); + fprintf (OutFptr, "FLASH_BASE = 0x%08X\n", FDev->BaseAddress); + fprintf (OutFptr, "FLASH_SIZE = 0x%08X\n\n", FDev->Size); + // + // Write flash block size and offset defines + // + Offset = 0; + for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) { + fprintf ( + OutFptr, + "FLASH_REGION_%s_BASE %*c= 0x%08X\n", + FBlock->Name, + COLUMN2_START - 40 - strlen (FBlock->Name), + ' ', + Offset + FDev->BaseAddress + ); + fprintf ( + OutFptr, + "FLASH_REGION_%s_SIZE %*c= 0x%08X\n", + FBlock->Name, + COLUMN2_START - 40 - strlen (FBlock->Name), + ' ', + FBlock->Size + ); + fprintf ( + OutFptr, + "FLASH_REGION_%s_SIZE_BLOCKS %*c= 0x%x\n", + FBlock->Name, + COLUMN2_START - 40 - strlen (FBlock->Name), + ' ', + (FBlock->Size)/(FDev->PBlocks->Size) + ); + // + // Create defines for any subregions + // + SubregionOffset = 0; + for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) { + fprintf ( + OutFptr, + "FLASH_REGION_%s_SUBREGION_%s_BASE %*c= 0x%08X\n", + FBlock->Name, + Subregion->Name, + COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name), + ' ', + FDev->BaseAddress + Offset + SubregionOffset + ); + fprintf ( + OutFptr, + "FLASH_REGION_%s_SUBREGION_%s_SIZE %*c= 0x%08X\n", + FBlock->Name, + Subregion->Name, + COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name), + ' ', + Subregion->Size + ); + fprintf ( + OutFptr, + "FLASH_REGION_%s_SUBREGION_%s_OFFSET %*c= 0x%08X\n", + FBlock->Name, + Subregion->Name, + COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name), + ' ', + Offset + SubregionOffset + ); + + SubregionOffset += Subregion->Size; + } + + Offset += FBlock->Size; + } + // + // Close file + // + fprintf (OutFptr, "\n"); + fclose (OutFptr); + return STATUS_SUCCESS; +} + + +/*++ + +Routine Description: + The following buffer management routines are used to encapsulate functionality + for managing a growable data buffer. + +Arguments: + BUFFER_DATA - structure that is used to maintain a data buffer + +Returns: + NA + +--*/ +static +BUFFER_DATA * +CreateBufferData ( + VOID + ) +/*++ + +Routine Description: + + Create a growable data buffer with default buffer length. + +Arguments: + + None + +Returns: + + NULL - error occured during data buffer creation + Not NULL - the pointer to the newly created data buffer + +--*/ +{ + BUFFER_DATA *BD; + BD = (BUFFER_DATA *) _malloc (sizeof (BUFFER_DATA)); + if (BD == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return NULL; + } + + memset (BD, 0, sizeof (BUFFER_DATA)); + BD->BufferStart = (char *) _malloc (BUFFER_SIZE); + if (BD->BufferStart == NULL) { + _free (BD); + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return NULL; + } + + BD->BufferEnd = BD->BufferStart + BUFFER_SIZE; + BD->BufferPos = BD->BufferStart; + return BD; +} + +static +BOOLEAN +AddBufferDataByte ( + BUFFER_DATA *Buffer, + char Data + ) +/*++ + +Routine Description: + + Add a single byte to a growable data buffer, growing the buffer if required. + +Arguments: + + Buffer - pointer to the growable data buffer to add a single byte to + Data - value of the single byte data to be added + +Returns: + + TRUE - the single byte data was successfully added + FALSE - error occurred, the single byte data was not added + +--*/ +{ + int Size; + char *NewBuffer; + // + // See if we have to grow the buffer + // + if (Buffer->BufferPos >= Buffer->BufferEnd) { + Size = (int) Buffer->BufferEnd - (int) Buffer->BufferStart; + NewBuffer = (char *) _malloc (Size + BUFFER_SIZE); + if (NewBuffer == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return FALSE; + } + + memcpy (NewBuffer, Buffer->BufferStart, Size); + _free (Buffer->BufferStart); + Buffer->BufferStart = NewBuffer; + Buffer->BufferPos = Buffer->BufferStart + Size; + Buffer->BufferEnd = Buffer->BufferStart + Size + BUFFER_SIZE; + } + + *Buffer->BufferPos = Data; + Buffer->BufferPos++; + return TRUE; +} + +static +void +FreeBufferData ( + BUFFER_DATA *Buffer, + BOOLEAN FreeData + ) +/*++ + +Routine Description: + + Free memory used to manage a growable data buffer. + +Arguments: + + Buffer - pointer to the growable data buffer to be destructed + FreeData - TRUE, free memory containing the buffered data + FALSE, do not free the buffered data memory + +Returns: + + None + +--*/ +{ + if (Buffer != NULL) { + if (FreeData && (Buffer->BufferStart != NULL)) { + _free (Buffer->BufferStart); + } + + _free (Buffer); + } +} + +static +char * +GetBufferData ( + BUFFER_DATA *Buffer, + int *BufferSize + ) +/*++ + +Routine Description: + + Return a pointer and size of the data in a growable data buffer. + +Arguments: + + Buffer - pointer to the growable data buffer + BufferSize - size of the data in the growable data buffer + +Returns: + + pointer of the data in the growable data buffer + +--*/ +{ + *BufferSize = (int) Buffer->BufferPos - (int) Buffer->BufferStart; + return Buffer->BufferStart; +} + +STATUS +FDDiscover ( + char *FDFileName, + unsigned int BaseAddr + ) +/*++ + +Routine Description: + Walk a binary image and see if you find anything that looks like a + firmware volume. + +Arguments: + FDFileName - name of input FD image to parse + BaseAddr - base address of input FD image + +Returns: + STATUS_SUCCESS - no errors or warnings + STATUS_WARNING - warnings, but no errors, were encountered + STATUS_ERROR - errors were encountered + +NOTE: + This routine is used for debug purposes only. + +--*/ +{ + FILE *InFptr; + long FileSize; + long Offset; + EFI_FIRMWARE_VOLUME_HEADER FVHeader; + EFI_GUID + FileSystemGuid = { 0x7A9354D9, 0x0468, 0x444a, 0x81, 0xCE, 0x0B, 0xF6, 0x17, 0xD8, 0x90, 0xDF }; + + if ((InFptr = fopen (FDFileName, "rb")) == NULL) { + Error (NULL, 0, 0, FDFileName, "failed to open file for reading"); + return STATUS_ERROR; + } + + fseek (InFptr, 0, SEEK_END); + FileSize = ftell (InFptr); + fseek (InFptr, 0, SEEK_SET); + Offset = 0; + while (Offset < FileSize) { + fseek (InFptr, Offset, SEEK_SET); + // + // Read the contents of the file, see if it's an FV header + // + if (fread (&FVHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER), 1, InFptr) == 1) { + // + // Check version and GUID + // + if ((FVHeader.Revision == EFI_FVH_REVISION) && (FVHeader.Signature == EFI_FVH_SIGNATURE)) { + fprintf (stdout, "FV header at 0x%08X FVSize=0x%08X ", Offset + BaseAddr, (UINT32) FVHeader.FvLength); + if (memcmp (&FVHeader.FileSystemGuid, &FileSystemGuid, sizeof (EFI_GUID)) == 0) { + fprintf (stdout, "standard FFS file system\n"); + } else { + fprintf (stdout, "non-standard FFS file system\n"); + } + } + } + + Offset += 16 * 1024; + } + + fclose (InFptr); + return STATUS_SUCCESS; +} diff --git a/Tools/CodeTools/Source/FlashMap/FlashDefFile.h b/Tools/CodeTools/Source/FlashMap/FlashDefFile.h new file mode 100644 index 0000000000..0e2ea2c920 --- /dev/null +++ b/Tools/CodeTools/Source/FlashMap/FlashDefFile.h @@ -0,0 +1,281 @@ +/*++ + +Copyright (c) 2004-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +Module Name: + + FlashDefFile.h + +Abstract: + + Header file for flash management utility in the Intel Platform + Innovation Framework for EFI build environment. + +--*/ + +#ifndef _FLASH_DEF_FILE_H_ +#define _FLASH_DEF_FILE_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +void +FDFConstructor ( + VOID + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + None + +Returns: + + GC_TODO: add return values + +--*/ +; + +void +FDFDestructor ( + VOID + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + None + +Returns: + + GC_TODO: add return values + +--*/ +; + +STATUS +FDFParseFile ( + char *FileName + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FileName - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +STATUS +FDFCreateCIncludeFile ( + char *FlashDeviceName, + char *FileName + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FlashDeviceName - GC_TODO: add argument description + FileName - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +STATUS +FDFCreateCFlashMapDataFile ( + char *FlashDeviceName, + char *FileName + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FlashDeviceName - GC_TODO: add argument description + FileName - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +STATUS +FDFCreateAsmIncludeFile ( + char *FlashDeviceName, + char *FileName + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FlashDeviceName - GC_TODO: add argument description + FileName - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +STATUS +FDFParseFile ( + char *FileName + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FileName - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +STATUS +FDFCreateImage ( + char *FlashDeviceName, + char *ImageName, + char *FileName + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FlashDeviceName - GC_TODO: add argument description + ImageName - GC_TODO: add argument description + FileName - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +STATUS +FDFCreateDscFile ( + char *FlashDeviceName, + char *FileName + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FlashDeviceName - GC_TODO: add argument description + FileName - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +STATUS +FDFCreateSymbols ( + char *FlashDeviceName + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FlashDeviceName - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +STATUS +FDDiscover ( + char *FDFileName, + unsigned int BaseAddr + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FDFileName - GC_TODO: add argument description + BaseAddr - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +#ifdef __cplusplus +} +#endif + +#endif // #ifndef _FLASH_DEF_FILE_H_ diff --git a/Tools/CodeTools/Source/FlashMap/FlashMap.c b/Tools/CodeTools/Source/FlashMap/FlashMap.c new file mode 100644 index 0000000000..88f5003d2d --- /dev/null +++ b/Tools/CodeTools/Source/FlashMap/FlashMap.c @@ -0,0 +1,769 @@ +/*++ + +Copyright (c) 2004-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + FlashMap.c + +Abstract: + + Utility for flash management in the Intel Platform Innovation Framework + for EFI build environment. + +--*/ + +#include +#include +#include +#include + +#include + +#include "EfiUtilityMsgs.h" +#include "Microcode.h" +#include "FlashDefFile.h" +#include "Symbols.h" + +#define UTILITY_NAME "FlashMap" + +typedef struct _STRING_LIST { + struct _STRING_LIST *Next; + char *Str; +} STRING_LIST; + +// +// Keep our globals in one of these structures +// +static struct { + char *CIncludeFileName; + char *FlashDevice; + char *FlashDeviceImage; + char *MCIFileName; + char *MCOFileName; + char *ImageOutFileName; + char *DscFileName; + char *AsmIncludeFileName; + char *FlashDefinitionFileName; + char *StringReplaceInFileName; + char *StringReplaceOutFileName; + char *DiscoverFDImageName; + char MicrocodePadByteValue; + unsigned int MicrocodeAlignment; + STRING_LIST *MCIFileNames; + STRING_LIST *LastMCIFileNames; + unsigned int BaseAddress; +} mGlobals; + +#define DEFAULT_MC_PAD_BYTE_VALUE 0xFF +#define DEFAULT_MC_ALIGNMENT 16 + +static +STATUS +ProcessCommandLine ( + int argc, + char *argv[] + ); + +static +STATUS +MergeMicrocodeFiles ( + char *OutFileName, + STRING_LIST *FileNames, + unsigned int Alignment, + char PadByteValue + ); + +static +void +Usage ( + VOID + ); + +char* +NormalizePath ( + char* OldPathName + ); + +int +main ( + int argc, + char *argv[] + ) +/*++ + +Routine Description: + Parse the command line arguments and then call worker functions to do the work + +Arguments: + argc - number of elements in argv + argv - array of command-line arguments + +Returns: + STATUS_SUCCESS - no problems encountered while processing + STATUS_WARNING - warnings, but no errors, were encountered while processing + STATUS_ERROR - errors were encountered while processing + +--*/ +{ + STATUS Status; + + SetUtilityName (UTILITY_NAME); + Status = ProcessCommandLine (argc, argv); + if (Status != STATUS_SUCCESS) { + return Status; + } + // + // Check for discovery of an FD (command line option) + // + if (mGlobals.DiscoverFDImageName != NULL) { + Status = FDDiscover (mGlobals.DiscoverFDImageName, mGlobals.BaseAddress); + goto Done; + } + // + // If they're doing microcode file parsing, then do that + // + if (mGlobals.MCIFileName != NULL) { + MicrocodeConstructor (); + MicrocodeParseFile (mGlobals.MCIFileName, mGlobals.MCOFileName); + MicrocodeDestructor (); + } + // + // If they're doing microcode file merging, then do that now + // + if (mGlobals.MCIFileNames != NULL) { + MergeMicrocodeFiles ( + mGlobals.MCOFileName, + mGlobals.MCIFileNames, + mGlobals.MicrocodeAlignment, + mGlobals.MicrocodePadByteValue + ); + } + // + // If using a flash definition file, then process that and return + // + if (mGlobals.FlashDefinitionFileName != NULL) { + FDFConstructor (); + SymbolsConstructor (); + Status = FDFParseFile (mGlobals.FlashDefinitionFileName); + if (GetUtilityStatus () != STATUS_ERROR) { + // + // If they want us to do a string-replace on a file, then add the symbol definitions to + // the symbol table, and then do the string replace. + // + if (mGlobals.StringReplaceInFileName != NULL) { + Status = FDFCreateSymbols (mGlobals.FlashDevice); + Status = SymbolsFileStringsReplace (mGlobals.StringReplaceInFileName, mGlobals.StringReplaceOutFileName); + } + // + // If they want us to create a .h defines file or .c flashmap data file, then do so now + // + if (mGlobals.CIncludeFileName != NULL) { + Status = FDFCreateCIncludeFile (mGlobals.FlashDevice, mGlobals.CIncludeFileName); + } + if (mGlobals.AsmIncludeFileName != NULL) { + Status = FDFCreateAsmIncludeFile (mGlobals.FlashDevice, mGlobals.AsmIncludeFileName); + } + // + // If they want us to create an image, do that now + // + if (mGlobals.ImageOutFileName != NULL) { + Status = FDFCreateImage (mGlobals.FlashDevice, mGlobals.FlashDeviceImage, mGlobals.ImageOutFileName); + } + // + // If they want to create an output DSC file, do that now + // + if (mGlobals.DscFileName != NULL) { + Status = FDFCreateDscFile (mGlobals.FlashDevice, mGlobals.DscFileName); + } + } + SymbolsDestructor (); + FDFDestructor (); + } +Done: + // + // Free up memory + // + while (mGlobals.MCIFileNames != NULL) { + mGlobals.LastMCIFileNames = mGlobals.MCIFileNames->Next; + _free (mGlobals.MCIFileNames); + mGlobals.MCIFileNames = mGlobals.LastMCIFileNames; + } + return GetUtilityStatus (); +} + +static +STATUS +MergeMicrocodeFiles ( + char *OutFileName, + STRING_LIST *FileNames, + unsigned int Alignment, + char PadByteValue + ) +/*++ + +Routine Description: + + Merge binary microcode files into a single file, taking into consideration + the alignment and pad value. + +Arguments: + + OutFileName - name of the output file to create + FileNames - linked list of input microcode files to merge + Alignment - alignment for each microcode file in the output image + PadByteValue - value to use when padding to meet alignment requirements + +Returns: + + STATUS_SUCCESS - merge completed successfully or with acceptable warnings + STATUS_ERROR - merge failed, output file not created + +--*/ +{ + long FileSize; + long TotalFileSize; + FILE *InFptr; + FILE *OutFptr; + char *Buffer; + STATUS Status; + + // + // Open the output file + // + if ((OutFptr = fopen (OutFileName, "wb")) == NULL) { + Error (NULL, 0, 0, OutFileName, "failed to open output file for writing"); + return STATUS_ERROR; + } + // + // Walk the list of files + // + Status = STATUS_ERROR; + Buffer = NULL; + InFptr = NULL; + TotalFileSize = 0; + while (FileNames != NULL) { + // + // Open the file, determine the size, then read it in and write + // it back out. + // + if ((InFptr = fopen (NormalizePath(FileNames->Str), "rb")) == NULL) { + Error (NULL, 0, 0, NormalizePath(FileNames->Str), "failed to open input file for reading"); + goto Done; + } + fseek (InFptr, 0, SEEK_END); + FileSize = ftell (InFptr); + fseek (InFptr, 0, SEEK_SET); + if (FileSize != 0) { + Buffer = (char *) _malloc (FileSize); + if (Buffer == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + goto Done; + } + if (fread (Buffer, FileSize, 1, InFptr) != 1) { + Error (NULL, 0, 0, FileNames->Str, "failed to read file contents"); + goto Done; + } + // + // Align + // + if (Alignment != 0) { + while ((TotalFileSize % Alignment) != 0) { + if (fwrite (&PadByteValue, 1, 1, OutFptr) != 1) { + Error (NULL, 0, 0, OutFileName, "failed to write pad bytes to output file"); + goto Done; + } + TotalFileSize++; + } + } + TotalFileSize += FileSize; + if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) { + Error (NULL, 0, 0, OutFileName, "failed to write to output file"); + goto Done; + } + _free (Buffer); + Buffer = NULL; + } else { + Warning (NULL, 0, 0, FileNames->Str, "0-size file encountered"); + } + fclose (InFptr); + InFptr = NULL; + FileNames = FileNames->Next; + } + Status = STATUS_SUCCESS; +Done: + fclose (OutFptr); + if (InFptr != NULL) { + fclose (InFptr); + } + if (Buffer != NULL) { + _free (Buffer); + } + if (Status == STATUS_ERROR) { + remove (OutFileName); + } + return Status; +} + +static +STATUS +ProcessCommandLine ( + int argc, + char *argv[] + ) +/*++ + +Routine Description: + Process the command line arguments + +Arguments: + argc - Standard C entry point arguments + argv[] - Standard C entry point arguments + +Returns: + STATUS_SUCCESS - no problems encountered while processing + STATUS_WARNING - warnings, but no errors, were encountered while processing + STATUS_ERROR - errors were encountered while processing + +--*/ +{ + int ThingsToDo; + unsigned int Temp; + STRING_LIST *Str; + // + // Skip program name arg, process others + // + argc--; + argv++; + if (argc == 0) { + Usage (); + return STATUS_ERROR; + } + // + // Clear out our globals, then start walking the arguments + // + memset ((void *) &mGlobals, 0, sizeof (mGlobals)); + mGlobals.MicrocodePadByteValue = DEFAULT_MC_PAD_BYTE_VALUE; + mGlobals.MicrocodeAlignment = DEFAULT_MC_ALIGNMENT; + ThingsToDo = 0; + while (argc > 0) { + if (strcmp (argv[0], "-?") == 0) { + Usage (); + return STATUS_ERROR; + } else if (strcmp (argv[0], "-hfile") == 0) { + // + // -hfile FileName + // + // Used to specify an output C #include file to create that contains + // #define statements for all the flashmap region offsets and sizes. + // Check for additional argument. + // + if (argc < 2) { + Error (NULL, 0, 0, argv[0], "option requires an output file name"); + return STATUS_ERROR; + } + argc--; + argv++; + mGlobals.CIncludeFileName = argv[0]; + ThingsToDo++; + } else if (strcmp (argv[0], "-flashdevice") == 0) { + // + // -flashdevice FLASH_DEVICE_NAME + // + // Used to select which flash device definition to operate on. + // Check for additional argument + // + if (argc < 2) { + Error (NULL, 0, 0, argv[0], "option requires a flash device name to use"); + return STATUS_ERROR; + } + argc--; + argv++; + mGlobals.FlashDevice = argv[0]; + } else if (strcmp (argv[0], "-mco") == 0) { + // + // -mco OutFileName + // + // Used to specify a microcode output binary file to create. + // Check for additional argument. + // + if (argc < 2) { + Error (NULL, 0, 0, (INT8 *) argv[0], (INT8 *) "option requires an output microcode file name to create"); + return STATUS_ERROR; + } + argc--; + argv++; + mGlobals.MCOFileName = argv[0]; + ThingsToDo++; + } else if (strcmp (argv[0], "-asmincfile") == 0) { + // + // -asmincfile FileName + // + // Used to specify the name of the output assembly include file that contains + // equates for the flash region addresses and sizes. + // Check for additional argument. + // + if (argc < 2) { + Error (NULL, 0, 0, argv[0], "option requires an output ASM include file name to create"); + return STATUS_ERROR; + } + argc--; + argv++; + mGlobals.AsmIncludeFileName = argv[0]; + ThingsToDo++; + } else if (strcmp (argv[0], "-mci") == 0) { + // + // -mci FileName + // + // Used to specify an input microcode text file to parse. + // Check for additional argument + // + if (argc < 2) { + Error (NULL, 0, 0, (INT8 *) argv[0], (INT8 *) "option requires an input microcode text file name to parse"); + return STATUS_ERROR; + } + argc--; + argv++; + mGlobals.MCIFileName = argv[0]; + } else if (strcmp (argv[0], "-flashdeviceimage") == 0) { + // + // -flashdeviceimage FlashDeviceImage + // + // Used to specify which flash device image definition from the input flash definition file + // to create. + // Check for additional argument. + // + if (argc < 2) { + Error (NULL, 0, 0, argv[0], "option requires the name of a flash definition image to use"); + return STATUS_ERROR; + } + argc--; + argv++; + mGlobals.FlashDeviceImage = argv[0]; + } else if (strcmp (argv[0], "-imageout") == 0) { + // + // -imageout FileName + // + // Used to specify the name of the output FD image file to create. + // Check for additional argument. + // + if (argc < 2) { + Error (NULL, 0, 0, argv[0], "option requires an output image filename to create"); + return STATUS_ERROR; + } + argc--; + argv++; + mGlobals.ImageOutFileName = argv[0]; + ThingsToDo++; + } else if (strcmp (argv[0], "-dsc") == 0) { + // + // -dsc FileName + // + // Used to specify the name of the output DSC file to create. + // Check for additional argument. + // + if (argc < 2) { + Error (NULL, 0, 0, argv[0], "option requires an output DSC filename to create"); + return STATUS_ERROR; + } + argc--; + argv++; + mGlobals.DscFileName = argv[0]; + ThingsToDo++; + } else if (strcmp (argv[0], "-fdf") == 0) { + // + // -fdf FileName + // + // Used to specify the name of the input flash definition file. + // Check for additional argument. + // + if (argc < 2) { + Error (NULL, 0, 0, argv[0], "option requires an input flash definition file name"); + return STATUS_ERROR; + } + argc--; + argv++; + mGlobals.FlashDefinitionFileName = argv[0]; + } else if (strcmp (argv[0], "-discover") == 0) { + // + // -discover FDFileName + // + // Debug functionality used to scan an existing FD image, trying to find + // firmware volumes at 64K boundaries. + // Check for additional argument. + // + if (argc < 2) { + Error (NULL, 0, 0, argv[0], "option requires an input FD image file name"); + return STATUS_ERROR; + } + argc--; + argv++; + mGlobals.DiscoverFDImageName = argv[0]; + ThingsToDo++; + } else if (strcmp (argv[0], "-baseaddr") == 0) { + // + // -baseaddr Addr + // + // Used to specify a base address when doing a discover of an FD image. + // Check for additional argument. + // + if (argc < 2) { + Error (NULL, 0, 0, argv[0], "option requires a base address"); + return STATUS_ERROR; + } + argc--; + argv++; + if (tolower (argv[0][1]) == 'x') { + sscanf (argv[0] + 2, "%x", &mGlobals.BaseAddress); + } else { + sscanf (argv[0], "%d", &mGlobals.BaseAddress); + } + } else if (strcmp (argv[0], "-padvalue") == 0) { + // + // -padvalue Value + // + // Used to specify the value to pad with when aligning data while + // creating an FD image. Check for additional argument. + // + if (argc < 2) { + Error (NULL, 0, 0, argv[0], "option requires a byte value"); + return STATUS_ERROR; + } + argc--; + argv++; + if (tolower (argv[0][1]) == 'x') { + sscanf (argv[0] + 2, "%x", &Temp); + mGlobals.MicrocodePadByteValue = (char) Temp; + } else { + sscanf (argv[0], "%d", &Temp); + mGlobals.MicrocodePadByteValue = (char) Temp; + } + } else if (strcmp (argv[0], "-align") == 0) { + // + // -align Alignment + // + // Used to specify how each data file is aligned in the region + // when creating an FD image. Check for additional argument. + // + if (argc < 2) { + Error (NULL, 0, 0, argv[0], "option requires an alignment"); + return STATUS_ERROR; + } + argc--; + argv++; + if (tolower (argv[0][1]) == 'x') { + sscanf (argv[0] + 2, "%x", &mGlobals.MicrocodeAlignment); + } else { + sscanf (argv[0], "%d", &mGlobals.MicrocodeAlignment); + } + } else if (strcmp (argv[0], "-mcmerge") == 0) { + // + // -mcmerge FileName(s) + // + // Used to concatenate multiple microde binary files. Can specify + // multiple file names with the one -mcmerge flag. Check for additional argument. + // + if ((argc < 2) || (argv[1][0] == '-')) { + Error (NULL, 0, 0, argv[0], "option requires one or more input file names"); + return STATUS_ERROR; + } + // + // Take input files until another option or end of list + // + ThingsToDo++; + while ((argc > 1) && (argv[1][0] != '-')) { + Str = (STRING_LIST *) _malloc (sizeof (STRING_LIST)); + if (Str == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + memset (Str, 0, sizeof (STRING_LIST)); + Str->Str = argv[1]; + if (mGlobals.MCIFileNames == NULL) { + mGlobals.MCIFileNames = Str; + } else { + mGlobals.LastMCIFileNames->Next = Str; + } + mGlobals.LastMCIFileNames = Str; + argc--; + argv++; + } + } else if (strcmp (argv[0], "-strsub") == 0) { + // + // -strsub SrcFile DestFile + // + // Used to perform string substitutions on a file, writing the result to a new + // file. Check for two additional arguments. + // + if (argc < 3) { + Error (NULL, 0, 0, argv[0], "option requires input and output file names for string substitution"); + return STATUS_ERROR; + } + argc--; + argv++; + mGlobals.StringReplaceInFileName = argv[0]; + argc--; + argv++; + mGlobals.StringReplaceOutFileName = argv[0]; + ThingsToDo++; + } else { + Error (NULL, 0, 0, argv[0], "invalid option"); + return STATUS_ERROR; + } + argc--; + argv++; + } + // + // If no outputs requested, then report an error + // + if (ThingsToDo == 0) { + Error (NULL, 0, 0, "nothing to do", NULL); + return STATUS_ERROR; + } + // + // If they want an asm file, #include file, or C file to be created, then they have to specify a + // flash device name and flash definition file name. + // + if ((mGlobals.CIncludeFileName != NULL) && + ((mGlobals.FlashDevice == NULL) || (mGlobals.FlashDefinitionFileName == NULL))) { + Error (NULL, 0, 0, "must specify -flashdevice and -fdf with -hfile", NULL); + return STATUS_ERROR; + } + if ((mGlobals.AsmIncludeFileName != NULL) && + ((mGlobals.FlashDevice == NULL) || (mGlobals.FlashDefinitionFileName == NULL))) { + Error (NULL, 0, 0, "must specify -flashdevice and -fdf with -asmincfile", NULL); + return STATUS_ERROR; + } + // + // If they want a dsc file to be created, then they have to specify a + // flash device name and a flash definition file name + // + if (mGlobals.DscFileName != NULL) { + if (mGlobals.FlashDevice == NULL) { + Error (NULL, 0, 0, "must specify -flashdevice with -dsc", NULL); + return STATUS_ERROR; + } + if (mGlobals.FlashDefinitionFileName == NULL) { + Error (NULL, 0, 0, "must specify -fdf with -dsc", NULL); + return STATUS_ERROR; + } + } + // + // If they specified an output microcode file name, then they have to specify an input + // file name, and vice versa. + // + if ((mGlobals.MCIFileName != NULL) && (mGlobals.MCOFileName == NULL)) { + Error (NULL, 0, 0, "must specify output microcode file name", NULL); + return STATUS_ERROR; + } + if ((mGlobals.MCOFileName != NULL) && (mGlobals.MCIFileName == NULL) && (mGlobals.MCIFileNames == NULL)) { + Error (NULL, 0, 0, "must specify input microcode file name", NULL); + return STATUS_ERROR; + } + // + // If doing merge, then have to specify output file name + // + if ((mGlobals.MCIFileNames != NULL) && (mGlobals.MCOFileName == NULL)) { + Error (NULL, 0, 0, "must specify output microcode file name", NULL); + return STATUS_ERROR; + } + // + // If they want an output image to be created, then they have to specify + // the flash device and the flash device image to use. + // + if (mGlobals.ImageOutFileName != NULL) { + if (mGlobals.FlashDevice == NULL) { + Error (NULL, 0, 0, "must specify -flashdevice with -imageout", NULL); + return STATUS_ERROR; + } + if (mGlobals.FlashDeviceImage == NULL) { + Error (NULL, 0, 0, "must specify -flashdeviceimage with -imageout", NULL); + return STATUS_ERROR; + } + if (mGlobals.FlashDefinitionFileName == NULL) { + Error (NULL, 0, 0, "must specify -c or -fdf with -imageout", NULL); + return STATUS_ERROR; + } + } + return STATUS_SUCCESS; +} + +static +void +Usage ( + VOID + ) +/*++ + +Routine Description: + Print utility command line help + +Arguments: + None + +Returns: + NA + +--*/ +{ + int i; + char *Msg[] = { + "Usage: FlashTool -fdf FlashDefFile -flashdevice FlashDevice", + " -flashdeviceimage FlashDeviceImage -mci MCIFile -mco MCOFile", + " -discover FDImage -dsc DscFile -asmincfile AsmIncFile", + " -imageOut ImageOutFile -hfile HFile -strsub InStrFile OutStrFile", + " -baseaddr BaseAddr -align Alignment -padvalue PadValue", + " -mcmerge MCIFile(s)", + " where", + " FlashDefFile - input Flash Definition File", + " FlashDevice - flash device to use (from flash definition file)", + " FlashDeviceImage - flash device image to use (from flash definition file)", + " MCIFile - input microcode file to parse", + " MCOFile - output binary microcode image to create from MCIFile", + " HFile - output #include file to create", + " FDImage - name of input FDImage file to scan", + " ImageOutFile - output image file to create", + " DscFile - output DSC file to create", + " AsmIncFile - output ASM include file to create", + " InStrFile - input file to replace symbol names, writing result to OutStrFile", + " BaseAddr - base address of FDImage (used with -discover)", + " Alignment - alignment to use when merging microcode binaries", + " PadValue - byte value to use as pad value when aligning microcode binaries", + " MCIFile(s) - one or more microcode binary files to merge/concatenate", + "", + NULL + }; + for (i = 0; Msg[i] != NULL; i++) { + fprintf (stdout, "%s\n", Msg[i]); + } +} + +char* +NormalizePath ( + char* OldPathName + ) +{ + char* Visitor; + + if (OldPathName == NULL) { + return NULL; + } + + Visitor = OldPathName; + while (*Visitor != '\0') { + if (*Visitor == '\\') { + *Visitor = '/'; + } + Visitor++; + } + + return OldPathName; +} + diff --git a/Tools/CodeTools/Source/FlashMap/Microcode.c b/Tools/CodeTools/Source/FlashMap/Microcode.c new file mode 100644 index 0000000000..23353254a4 --- /dev/null +++ b/Tools/CodeTools/Source/FlashMap/Microcode.c @@ -0,0 +1,304 @@ +/*++ + +Copyright (c) 2004-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + Microcode.c + +Abstract: + + Utility for working with microcode patch files in the Intel + Platform Innovation Framework for EFI build environment. + +--*/ + +#include +#include // for memset() +#include +#include // for malloc() + +#include "EfiUtilityMsgs.h" +#include "Microcode.h" + +#define MAX_LINE_LEN 256 + +// +// Structure definition for a microcode header +// +typedef struct { + unsigned int HeaderVersion; + unsigned int PatchId; + unsigned int Date; + unsigned int CpuId; + unsigned int Checksum; + unsigned int LoaderVersion; + unsigned int PlatformId; + unsigned int DataSize; // if 0, then TotalSize = 2048, and TotalSize field is invalid + unsigned int TotalSize; // number of bytes + unsigned int Reserved[3]; +} MICROCODE_IMAGE_HEADER; + +static +STATUS +MicrocodeReadData ( + FILE *InFptr, + unsigned int *Data + ); + +void +MicrocodeConstructor ( + void + ) +/*++ + +Routine Description: + + Constructor of module Microcode + +Arguments: + + None + +Returns: + + None + +--*/ +{ +} + +void +MicrocodeDestructor ( + void + ) +/*++ + +Routine Description: + + Destructor of module Microcode + +Arguments: + + None + +Returns: + + None + +--*/ +{ +} + +static +STATUS +MicrocodeReadData ( + FILE *InFptr, + unsigned int *Data + ) +/*++ + +Routine Description: + Read a 32-bit microcode data value from a text file and convert to raw binary form. + +Arguments: + InFptr - file pointer to input text file + Data - pointer to where to return the data parsed + +Returns: + STATUS_SUCCESS - no errors or warnings, Data contains valid information + STATUS_ERROR - errors were encountered + +--*/ +{ + char Line[MAX_LINE_LEN]; + char *cptr; + + Line[MAX_LINE_LEN - 1] = 0; + *Data = 0; + if (fgets (Line, MAX_LINE_LEN, InFptr) == NULL) { + return STATUS_ERROR; + } + // + // If it was a binary file, then it may have overwritten our null terminator + // + if (Line[MAX_LINE_LEN - 1] != 0) { + return STATUS_ERROR; + } + // + // Look for + // dd 000000001h ; comment + // dd XXXXXXXX + // DD XXXXXXXXX + // DD XXXXXXXXX + // + for (cptr = Line; *cptr && isspace(*cptr); cptr++) { + } + if ((tolower(cptr[0]) == 'd') && (tolower(cptr[1]) == 'd') && isspace (cptr[2])) { + // + // Skip blanks and look for a hex digit + // + cptr += 3; + for (; *cptr && isspace(*cptr); cptr++) { + } + if (isxdigit (*cptr)) { + if (sscanf (cptr, "%X", Data) != 1) { + return STATUS_ERROR; + } + } + return STATUS_SUCCESS; + } + return STATUS_ERROR; +} + +STATUS +MicrocodeParseFile ( + char *InFileName, + char *OutFileName + ) +/*++ + +Routine Description: + Parse a microcode text file, and write the binary results to an output file. + +Arguments: + InFileName - input text file to parse + OutFileName - output file to write raw binary data from parsed input file + +Returns: + STATUS_SUCCESS - no errors or warnings + STATUS_ERROR - errors were encountered + +--*/ +{ + FILE *InFptr; + FILE *OutFptr; + STATUS Status; + MICROCODE_IMAGE_HEADER *Header; + unsigned int Size; + unsigned int Size2; + unsigned int Data; + unsigned int Checksum; + char *Buffer; + char *Ptr; + unsigned int TotalSize; + + Status = STATUS_ERROR; + InFptr = NULL; + OutFptr = NULL; + Buffer = NULL; + // + // Open the input text file + // + if ((InFptr = fopen (InFileName, "r")) == NULL) { + Error (NULL, 0, 0, InFileName, "failed to open input microcode file for reading"); + return STATUS_ERROR; + } + // + // Make two passes on the input file. The first pass is to determine how + // much data is in the file so we can allocate a working buffer. Then + // we'll allocate a buffer and re-read the file into the buffer for processing. + // + Size = 0; + do { + Status = MicrocodeReadData (InFptr, &Data); + if (Status == STATUS_SUCCESS) { + Size += sizeof (Data); + } + } while (Status == STATUS_SUCCESS); + // + // Error if no data. + // + if (Size == 0) { + Error (NULL, 0, 0, InFileName, "no parse-able data found in file"); + goto Done; + } + if (Size < sizeof (MICROCODE_IMAGE_HEADER)) { + Error (NULL, 0, 0, InFileName, "amount of parse-able data is insufficient to contain a microcode header"); + goto Done; + } + // + // Allocate a buffer for the data + // + Buffer = (char *) _malloc (Size); + if (Buffer == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + goto Done; + } + // + // Re-read the file, storing the data into our buffer + // + fseek (InFptr, 0, SEEK_SET); + Ptr = Buffer; + do { + Status = MicrocodeReadData (InFptr, &Data); + if (Status == STATUS_SUCCESS) { + *(unsigned int *) Ptr = Data; + Ptr += sizeof (Data); + } + } while (Status == STATUS_SUCCESS); + // + // Can't do much checking on the header because, per the spec, the + // DataSize field may be 0, which means DataSize = 2000 and TotalSize = 2K, + // and the TotalSize field is invalid (actually missing). Thus we can't + // even verify the Reserved fields are 0. + // + Header = (MICROCODE_IMAGE_HEADER *) Buffer; + if (Header->DataSize == 0) { + TotalSize = 2048; + } else { + TotalSize = Header->TotalSize; + } + if (TotalSize != Size) { + Error (NULL, 0, 0, InFileName, "file contents do not contain expected TotalSize 0x%04X", TotalSize); + goto Done; + } + // + // Checksum the contents + // + Ptr = Buffer; + Checksum = 0; + Size2 = 0; + while (Size2 < Size) { + Checksum += *(unsigned int *) Ptr; + Ptr += 4; + Size2 += 4; + } + if (Checksum != 0) { + Error (NULL, 0, 0, InFileName, "checksum failed on file contents"); + goto Done; + } + // + // Open the output file and write the buffer contents + // + if ((OutFptr = fopen (OutFileName, "wb")) == NULL) { + Error (NULL, 0, 0, OutFileName, "failed to open output microcode file for writing"); + goto Done; + } + if (fwrite (Buffer, Size, 1, OutFptr) != 1) { + Error (NULL, 0, 0, OutFileName, "failed to write microcode data to output file"); + goto Done; + } + Status = STATUS_SUCCESS; +Done: + if (Buffer != NULL) { + free (Buffer); + } + if (InFptr != NULL) { + fclose (InFptr); + } + if (OutFptr != NULL) { + fclose (OutFptr); + if (Status == STATUS_ERROR) { + remove (OutFileName); + } + } + return Status; +} diff --git a/Tools/CodeTools/Source/FlashMap/Microcode.h b/Tools/CodeTools/Source/FlashMap/Microcode.h new file mode 100644 index 0000000000..f85313e978 --- /dev/null +++ b/Tools/CodeTools/Source/FlashMap/Microcode.h @@ -0,0 +1,87 @@ +/*++ + +Copyright (c) 2004-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + Microcode.h + +Abstract: + + Header file for flash management utility in the Intel Platform + Innovation Framework for EFI build environment. + +--*/ + +#ifndef _MICROCODE_H_ +#define _MICROCODE_H_ + +void +MicrocodeConstructor ( + void + ); +/*++ + +Routine Description: + + Constructor of module Microcode + +Arguments: + + None + +Returns: + + None + +--*/ + +void +MicrocodeDestructor ( + void + ); +/*++ + +Routine Description: + + Destructor of module Microcode + +Arguments: + + None + +Returns: + + None + +--*/ + +STATUS +MicrocodeParseFile ( + char *InFileName, + char *OutFileName + ); +/*++ + +Routine Description: + Parse a microcode text file, and write the binary results to an output file. + +Arguments: + InFileName - input text file to parse + OutFileName - output file to write raw binary data from parsed input file + +Returns: + STATUS_SUCCESS - no errors or warnings + STATUS_ERROR - errors were encountered + +--*/ + + +#endif // #ifndef _MICROCODE_H_ diff --git a/Tools/CodeTools/Source/FlashMap/Symbols.c b/Tools/CodeTools/Source/FlashMap/Symbols.c new file mode 100644 index 0000000000..8e408144db --- /dev/null +++ b/Tools/CodeTools/Source/FlashMap/Symbols.c @@ -0,0 +1,648 @@ +/*++ + +Copyright (c) 2004-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + Symbol.c + +Abstract: + + Class-like implementation for a symbol table. + +--*/ + +// GC_TODO: fix comment to set correct module name: Symbols.c +#include +#include +#include +// +// for isspace() +// +#include + +#include + +#include "CommonLib.h" +#include "EfiUtilityMsgs.h" +#include "Symbols.h" + +#define MAX_LINE_LEN 512 + +// +// Linked list to keep track of all symbols +// +typedef struct _SYMBOL { + struct _SYMBOL *Next; + int Type; + char *Name; + char *Value; +} SYMBOL; + +static +SYMBOL * +FreeSymbols ( + SYMBOL *Syms + ); + +static +int +ExpandMacros ( + char *SourceLine, + char *DestLine, + int LineLen + ); + +static SYMBOL *mSymbolTable = NULL; + +void +SymbolsConstructor ( + VOID + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + None + +Returns: + + GC_TODO: add return values + +--*/ +{ + SymbolsDestructor (); +} + +void +SymbolsDestructor ( + VOID + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + None + +Returns: + + GC_TODO: add return values + +--*/ +{ + mSymbolTable = FreeSymbols (mSymbolTable); +} + +char * +GetSymbolValue ( + char *SymbolName + ) +/*++ + +Routine Description: + + Look up a symbol in our symbol table. + +Arguments: + + SymbolName + +Returns: + + Pointer to the value of the symbol if found + NULL if the symbol is not found + +--*/ +// GC_TODO: SymbolName - add argument and description to function comment +{ + SYMBOL *Symbol; + // + // Walk the symbol table + // + Symbol = mSymbolTable; + while (Symbol) { + if (stricmp (SymbolName, Symbol->Name) == 0) { + return Symbol->Value; + } + + Symbol = Symbol->Next; + } + + return NULL; +} + +int +SymbolAdd ( + char *Name, + char *Value, + int Mode + ) +/*++ + +Routine Description: + + Add a symbol name/value to the symbol table + +Arguments: + + Name - name of symbol to add + Value - value of symbol to add + Mode - currrently unused + +Returns: + + Length of symbol added. + +Notes: + If Value == NULL, then this routine will assume that the Name field + looks something like "MySymName = MySymValue", and will try to parse + it that way and add the symbol name/pair from the string. + +--*/ +{ + SYMBOL *Symbol; + + SYMBOL *NewSymbol; + int Len; + char *Start; + char *Cptr; + char CSave; + char *SaveCptr; + + Len = 0; + SaveCptr = NULL; + CSave = 0; + // + // If value pointer is null, then they passed us a line something like: + // varname = value, or simply var = + // + if (Value == NULL) { + Start = Name; + while (*Name && isspace (*Name)) { + Name++; + } + + if (Name == NULL) { + return -1; + } + // + // Find the end of the name. Either space or a '='. + // + for (Value = Name; *Value && !isspace (*Value) && (*Value != '='); Value++) + ; + if (Value == NULL) { + return -1; + } + // + // Look for the '=' + // + Cptr = Value; + while (*Value && (*Value != '=')) { + Value++; + } + + if (Value == NULL) { + return -1; + } + // + // Now truncate the name + // + *Cptr = 0; + // + // Skip over the = and then any spaces + // + Value++; + while (*Value && isspace (*Value)) { + Value++; + + } + // + // Find end of string, checking for quoted string + // + if (*Value == '\"') { + Value++; + for (Cptr = Value; *Cptr && *Cptr != '\"'; Cptr++) + ; + } else { + for (Cptr = Value; *Cptr && !isspace (*Cptr); Cptr++) + ; + } + // + // Null terminate the value string + // + CSave = *Cptr; + SaveCptr = Cptr; + *Cptr = 0; + Len = (int) (Cptr - Start); + } + // + // We now have a symbol name and a value. Look for an existing variable + // and overwrite it. + // + Symbol = mSymbolTable; + while (Symbol) { + // + // Check for symbol name match + // + if (stricmp (Name, Symbol->Name) == 0) { + _free (Symbol->Value); + Symbol->Value = (char *) _malloc (strlen (Value) + 1); + if (Symbol->Value == NULL) { + Error (NULL, 0, 0, NULL, "failed to allocate memory"); + return -1; + } + + strcpy (Symbol->Value, Value); + // + // If value == "NULL", then make it a 0-length string + // + if (stricmp (Symbol->Value, "NULL") == 0) { + Symbol->Value[0] = 0; + } + + return Len; + } + + Symbol = Symbol->Next; + } + // + // Does not exist, create a new one + // + NewSymbol = (SYMBOL *) _malloc (sizeof (SYMBOL)); + if (NewSymbol == NULL) { + Error (NULL, 0, 0, NULL, "memory allocation failure"); + return -1; + } + + memset ((char *) NewSymbol, 0, sizeof (SYMBOL)); + NewSymbol->Name = (char *) _malloc (strlen (Name) + 1); + if (NewSymbol->Name == NULL) { + Error (NULL, 0, 0, NULL, "memory allocation failure"); + _free (NewSymbol); + return -1; + } + + NewSymbol->Value = (char *) _malloc (strlen (Value) + 1); + if (NewSymbol->Value == NULL) { + Error (NULL, 0, 0, NULL, "memory allocation failure"); + _free (NewSymbol->Name); + _free (NewSymbol); + return -1; + } + + strcpy (NewSymbol->Name, Name); + strcpy (NewSymbol->Value, Value); + // + // Remove trailing spaces + // + Cptr = NewSymbol->Value + strlen (NewSymbol->Value) - 1; + while (Cptr > NewSymbol->Value) { + if (isspace (*Cptr)) { + *Cptr = 0; + Cptr--; + } else { + break; + } + } + // + // Add it to the head of the list. + // + NewSymbol->Next = mSymbolTable; + mSymbolTable = NewSymbol; + // + // If value == "NULL", then make it a 0-length string + // + if (stricmp (NewSymbol->Value, "NULL") == 0) { + NewSymbol->Value[0] = 0; + } + // + // Restore the terminator we inserted if they passed in var=value + // + if (SaveCptr != NULL) { + *SaveCptr = CSave; + } + _free (NewSymbol->Value); + _free (NewSymbol->Name); + _free (NewSymbol); + return Len; +} + +static +STATUS +RemoveSymbol ( + char *Name, + char SymbolType + ) +/*++ + +Routine Description: + + Remove a symbol name/value from the symbol table + +Arguments: + + Name - name of symbol to remove + SymbolType - type of symbol to remove + +Returns: + + STATUS_SUCCESS - matching symbol found and removed + STATUS_ERROR - matching symbol not found in symbol table + +--*/ +{ + SYMBOL *Symbol; + + SYMBOL *PrevSymbol; + + PrevSymbol = NULL; + Symbol = mSymbolTable; + // + // Walk the linked list of symbols in the symbol table looking + // for a match of both symbol name and type. + // + while (Symbol) { + if ((stricmp (Name, Symbol->Name) == 0) && (Symbol->Type & SymbolType)) { + // + // If the symbol has a value associated with it, free the memory + // allocated for the value. + // Then free the memory allocated for the symbols string name. + // + if (Symbol->Value) { + _free (Symbol->Value); + } + + _free (Symbol->Name); + // + // Link the previous symbol to the next symbol to effectively + // remove this symbol from the linked list. + // + if (PrevSymbol) { + PrevSymbol->Next = Symbol->Next; + } else { + mSymbolTable = Symbol->Next; + } + + _free (Symbol); + return STATUS_SUCCESS; + } + + PrevSymbol = Symbol; + Symbol = Symbol->Next; + } + + return STATUS_WARNING; +} + +static +SYMBOL * +FreeSymbols ( + SYMBOL *Syms + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + Syms - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + SYMBOL *Next; + while (Syms) { + if (Syms->Name != NULL) { + _free (Syms->Name); + } + + if (Syms->Value != NULL) { + _free (Syms->Value); + } + + Next = Syms->Next; + _free (Syms); + Syms = Next; + } + + return Syms; +} + +static +int +ExpandMacros ( + char *SourceLine, + char *DestLine, + int LineLen + ) +/*++ + +Routine Description: + + Given a line of text, replace all variables of format $(NAME) with values + from our symbol table. + +Arguments: + + SourceLine - input line of text to do symbol replacements on + DestLine - on output, SourceLine with symbols replaced + LineLen - length of DestLine, so we don't exceed its allocated length + +Returns: + + STATUS_SUCCESS - no problems encountered + STATUS_WARNING - missing closing parenthesis on a symbol reference in SourceLine + STATUS_ERROR - memory allocation failure + +--*/ +{ + static int NestDepth = 0; + char *FromPtr; + char *ToPtr; + char *SaveStart; + char *Cptr; + char *value; + int Expanded; + int ExpandedCount; + INT8 *LocalDestLine; + STATUS Status; + int LocalLineLen; + + NestDepth++; + Status = STATUS_SUCCESS; + LocalDestLine = (char *) _malloc (LineLen); + if (LocalDestLine == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failed", NULL); + return STATUS_ERROR; + } + + FromPtr = SourceLine; + ToPtr = LocalDestLine; + // + // Walk the entire line, replacing $(MACRO_NAME). + // + LocalLineLen = LineLen; + ExpandedCount = 0; + while (*FromPtr && (LocalLineLen > 0)) { + if ((*FromPtr == '$') && (*(FromPtr + 1) == '(')) { + // + // Save the start in case it's undefined, in which case we copy it as-is. + // + SaveStart = FromPtr; + Expanded = 0; + // + // Macro expansion time. Find the end (no spaces allowed) + // + FromPtr += 2; + for (Cptr = FromPtr; *Cptr && (*Cptr != ')'); Cptr++) + ; + if (*Cptr) { + // + // Truncate the string at the closing parenthesis for ease-of-use. + // Then copy the string directly to the destination line in case we don't find + // a definition for it. + // + *Cptr = 0; + strcpy (ToPtr, SaveStart); + if ((value = GetSymbolValue (FromPtr)) != NULL) { + strcpy (ToPtr, value); + LocalLineLen -= strlen (value); + ToPtr += strlen (value); + Expanded = 1; + ExpandedCount++; + } + + if (!Expanded) { + // + // Restore closing parenthesis, and advance to next character + // + *Cptr = ')'; + FromPtr = SaveStart + 1; + ToPtr++; + } else { + FromPtr = Cptr + 1; + } + } else { + Error (NULL, 0, 0, SourceLine, "missing closing parenthesis on macro"); + strcpy (ToPtr, FromPtr); + Status = STATUS_WARNING; + goto Done; + } + } else { + *ToPtr = *FromPtr; + FromPtr++; + ToPtr++; + LocalLineLen--; + } + } + + if (*FromPtr == 0) { + *ToPtr = 0; + } + + // + // If we expanded at least one string successfully, then make a recursive call to try again. + // + if ((ExpandedCount != 0) && (Status == STATUS_SUCCESS) && (NestDepth < 10)) { + Status = ExpandMacros (LocalDestLine, DestLine, LineLen); + _free (LocalDestLine); + NestDepth = 0; + return Status; + } + +Done: + if (Status != STATUS_ERROR) { + strcpy (DestLine, LocalDestLine); + } + + NestDepth = 0; + _free (LocalDestLine); + return Status; +} + +STATUS +SymbolsFileStringsReplace ( + char *InFileName, + char *OutFileName + ) +/*++ + +Routine Description: + + Given input and output file names, read in the input file, replace variable + references of format $(NAME) with appropriate values from our symbol table, + and write the result out to the output file. + +Arguments: + + InFileName - name of input text file to replace variable references + OutFileName - name of output text file to write results to + +Returns: + + STATUS_SUCCESS - no problems encountered + STATUS_ERROR - failed to open input or output file + +--*/ +{ + STATUS Status; + FILE *InFptr; + FILE *OutFptr; + char Line[MAX_LINE_LEN]; + char OutLine[MAX_LINE_LEN]; + + Status = STATUS_ERROR; + // + // Open input and output files + // + InFptr = NULL; + OutFptr = NULL; + if ((InFptr = fopen (InFileName, "r")) == NULL) { + Error (NULL, 0, 0, InFileName, "failed to open input file for reading"); + goto Done; + } + + if ((OutFptr = fopen (OutFileName, "w")) == NULL) { + Error (NULL, 0, 0, OutFileName, "failed to open output file for writing"); + goto Done; + } + // + // Read lines from input file until done + // + while (fgets (Line, sizeof (Line), InFptr) != NULL) { + ExpandMacros (Line, OutLine, sizeof (OutLine)); + fprintf (OutFptr, OutLine); + } + + Status = STATUS_SUCCESS; +Done: + if (InFptr != NULL) { + fclose (InFptr); + } + + if (OutFptr != NULL) { + fclose (OutFptr); + } + + return Status; +} diff --git a/Tools/CodeTools/Source/FlashMap/Symbols.h b/Tools/CodeTools/Source/FlashMap/Symbols.h new file mode 100644 index 0000000000..a3cadff268 --- /dev/null +++ b/Tools/CodeTools/Source/FlashMap/Symbols.h @@ -0,0 +1,124 @@ +/*++ + +Copyright (c) 2004-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + Symbols.h + +Abstract: + + Defines and prototypes for a class-like symbol table service. + +--*/ + +#ifndef _SYMBOLS_H_ +#define _SYMBOLS_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +int +SymbolAdd ( + char *Name, + char *Value, + int Mode + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + Name - GC_TODO: add argument description + Value - GC_TODO: add argument description + Mode - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +STATUS +SymbolsFileStringsReplace ( + char *InFileName, + char *OutFileName + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + InFileName - GC_TODO: add argument description + OutFileName - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +void +SymbolsConstructor ( + VOID + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + None + +Returns: + + GC_TODO: add return values + +--*/ +; + +void +SymbolsDestructor ( + VOID + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + None + +Returns: + + GC_TODO: add return values + +--*/ +; + +#ifdef __cplusplus +} +#endif + +#endif // #ifndef _SYMBOLS_H_ diff --git a/Tools/CodeTools/Source/FlashMap/build.xml b/Tools/CodeTools/Source/FlashMap/build.xml new file mode 100644 index 0000000000..680c1820b0 --- /dev/null +++ b/Tools/CodeTools/Source/FlashMap/build.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/FwImage/build.xml b/Tools/CodeTools/Source/FwImage/build.xml new file mode 100644 index 0000000000..b52c576c34 --- /dev/null +++ b/Tools/CodeTools/Source/FwImage/build.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/FwImage/fwimage.c b/Tools/CodeTools/Source/FwImage/fwimage.c new file mode 100644 index 0000000000..5dd1634b99 --- /dev/null +++ b/Tools/CodeTools/Source/FwImage/fwimage.c @@ -0,0 +1,510 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + fwimage.c + +Abstract: + + Converts a pe32+ image to an FW image type + +--*/ + +#include "WinNtInclude.h" + +#ifndef __GNUC__ +#include +#endif +#include +#include +#include +#include + +#include +#include + +#include "CommonLib.h" +#include "EfiUtilityMsgs.c" + +#define UTILITY_NAME "FwImage" + +#ifdef __GNUC__ +typedef unsigned long ULONG; +typedef unsigned char UCHAR; +typedef unsigned char *PUCHAR; +typedef unsigned short USHORT; +#endif + +VOID +Usage ( + VOID + ) +{ + printf ("Usage: " UTILITY_NAME " {-t time-date} [BASE|SEC|PEI_CORE|PEIM|DXE_CORE|DXE_DRIVER|DXE_RUNTIME_DRIVER|DXE_SAL_DRIVER|DXE_SMM_DRIVER|TOOL|UEFI_DRIVER|UEFI_APPLICATION|USER_DEFINED] peimage [outimage]"); +} + +static +STATUS +FCopyFile ( + FILE *in, + FILE *out + ) +{ + ULONG filesize; + ULONG offset; + ULONG length; + UCHAR Buffer[8 * 1024]; + + fseek (in, 0, SEEK_END); + filesize = ftell (in); + + fseek (in, 0, SEEK_SET); + fseek (out, 0, SEEK_SET); + + offset = 0; + while (offset < filesize) { + length = sizeof (Buffer); + if (filesize - offset < length) { + length = filesize - offset; + } + + fread (Buffer, length, 1, in); + fwrite (Buffer, length, 1, out); + offset += length; + } + + if ((ULONG) ftell (out) != filesize) { + Error (NULL, 0, 0, "write error", NULL); + return STATUS_ERROR; + } + + return STATUS_SUCCESS; +} + +static +STATUS +FReadFile ( + FILE *in, + VOID **Buffer, + UINTN *Length + ) +{ + fseek (in, 0, SEEK_END); + *Length = ftell (in); + *Buffer = malloc (*Length); + fseek (in, 0, SEEK_SET); + fread (*Buffer, *Length, 1, in); + return STATUS_SUCCESS; +} + +static +STATUS +FWriteFile ( + FILE *out, + VOID *Buffer, + UINTN Length + ) +{ + fseek (out, 0, SEEK_SET); + fwrite (Buffer, Length, 1, out); + if ((ULONG) ftell (out) != Length) { + Error (NULL, 0, 0, "write error", NULL); + return STATUS_ERROR; + } + free (Buffer); + return STATUS_SUCCESS; +} + +int +main ( + int argc, + char *argv[] + ) +/*++ + +Routine Description: + + Main function. + +Arguments: + + argc - Number of command line parameters. + argv - Array of pointers to command line parameter strings. + +Returns: + STATUS_SUCCESS - Utility exits successfully. + STATUS_ERROR - Some error occurred during execution. + +--*/ +{ + ULONG Type; + PUCHAR Ext; + PUCHAR p; + PUCHAR pe; + PUCHAR OutImageName; + UCHAR outname[500]; + FILE *fpIn; + FILE *fpOut; + VOID *ZeroBuffer; + EFI_IMAGE_DOS_HEADER *DosHdr; + EFI_IMAGE_NT_HEADERS *PeHdr; + EFI_IMAGE_OPTIONAL_HEADER32 *Optional32; + EFI_IMAGE_OPTIONAL_HEADER64 *Optional64; + time_t TimeStamp; + struct tm TimeStruct; + EFI_IMAGE_DOS_HEADER BackupDosHdr; + ULONG Index; + ULONG Index1; + ULONG Index2; + ULONG Index3; + BOOLEAN TimeStampPresent; + UINTN AllignedRelocSize; + UINTN Delta; + EFI_IMAGE_SECTION_HEADER *SectionHeader; + UINT8 *FileBuffer; + UINTN FileLength; + RUNTIME_FUNCTION *RuntimeFunction; + UNWIND_INFO *UnwindInfo; + + SetUtilityName (UTILITY_NAME); + // + // Assign to fix compile warning + // + OutImageName = NULL; + Type = 0; + Ext = 0; + TimeStamp = 0; + TimeStampPresent = FALSE; + + // + // Look for -t time-date option first. If the time is "0", then + // skip it. + // + if ((argc > 2) && !strcmp (argv[1], "-t")) { + TimeStampPresent = TRUE; + if (strcmp (argv[2], "0") != 0) { + // + // Convert the string to a value + // + memset ((char *) &TimeStruct, 0, sizeof (TimeStruct)); + if (sscanf( + argv[2], "%d/%d/%d,%d:%d:%d", + &TimeStruct.tm_mon, /* months since January - [0,11] */ + &TimeStruct.tm_mday, /* day of the month - [1,31] */ + &TimeStruct.tm_year, /* years since 1900 */ + &TimeStruct.tm_hour, /* hours since midnight - [0,23] */ + &TimeStruct.tm_min, /* minutes after the hour - [0,59] */ + &TimeStruct.tm_sec /* seconds after the minute - [0,59] */ + ) != 6) { + Error (NULL, 0, 0, argv[2], "failed to convert to mm/dd/yyyy,hh:mm:ss format"); + return STATUS_ERROR; + } + // + // Now fixup some of the fields + // + TimeStruct.tm_mon--; + TimeStruct.tm_year -= 1900; + // + // Sanity-check values? + // Convert + // + TimeStamp = mktime (&TimeStruct); + if (TimeStamp == (time_t) - 1) { + Error (NULL, 0, 0, argv[2], "failed to convert time"); + return STATUS_ERROR; + } + } + // + // Skip over the args + // + argc -= 2; + argv += 2; + } + // + // Check for enough args + // + if (argc < 3) { + Usage (); + return STATUS_ERROR; + } + + if (argc == 4) { + OutImageName = argv[3]; + } + // + // Get new image type + // + p = argv[1]; + if (*p == '/' || *p == '\\') { + p += 1; + } + + if (stricmp (p, "app") == 0 || stricmp (p, "UEFI_APPLICATION") == 0) { + Type = EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION; + Ext = ".efi"; + + } else if (stricmp (p, "bsdrv") == 0 || stricmp (p, "DXE_DRIVER") == 0) { + Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER; + Ext = ".efi"; + + } else if (stricmp (p, "rtdrv") == 0 || stricmp (p, "DXE_RUNTIME_DRIVER") == 0) { + Type = EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER; + Ext = ".efi"; + + } else if (stricmp (p, "rtdrv") == 0 || stricmp (p, "DXE_SAL_DRIVER") == 0) { + Type = EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER; + Ext = ".efi"; + } else if (stricmp (p, "SEC") == 0) { + Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER; + Ext = ".sec"; + } else if (stricmp (p, "peim") == 0 || + stricmp (p, "BASE") == 0 || + stricmp (p, "PEI_CORE") == 0 || + stricmp (p, "PEIM") == 0 || + stricmp (p, "DXE_SMM_DRIVER") == 0 || + stricmp (p, "TOOL") == 0 || + stricmp (p, "UEFI_APPLICATION") == 0 || + stricmp (p, "USER_DEFINED") == 0 || + stricmp (p, "UEFI_DRIVER") == 0 || + stricmp (p, "DXE_CORE") == 0 + ) { + Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER; + Ext = ".pei"; + } else { + printf ("%s", p); + Usage (); + return STATUS_ERROR; + } + // + // open source file + // + fpIn = fopen (argv[2], "rb"); + if (!fpIn) { + Error (NULL, 0, 0, argv[2], "failed to open input file for reading"); + return STATUS_ERROR; + } + + FReadFile (fpIn, (VOID **)&FileBuffer, &FileLength); + + // + // Read the dos & pe hdrs of the image + // + DosHdr = (EFI_IMAGE_DOS_HEADER *)FileBuffer; + if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) { + Error (NULL, 0, 0, argv[2], "DOS header signature not found in source image"); + fclose (fpIn); + return STATUS_ERROR; + } + + PeHdr = (EFI_IMAGE_NT_HEADERS *)(FileBuffer + DosHdr->e_lfanew); + if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) { + Error (NULL, 0, 0, argv[2], "PE header signature not found in source image"); + fclose (fpIn); + return STATUS_ERROR; + } + + // + // open output file + // + strcpy (outname, argv[2]); + pe = NULL; + for (p = outname; *p; p++) { + if (*p == '.') { + pe = p; + } + } + + if (!pe) { + pe = p; + } + + strcpy (pe, Ext); + + if (!OutImageName) { + OutImageName = outname; + } + + fpOut = fopen (OutImageName, "w+b"); + if (!fpOut) { + Error (NULL, 0, 0, OutImageName, "could not open output file for writing"); + fclose (fpIn); + return STATUS_ERROR; + } + + // + // Zero all unused fields of the DOS header + // + memcpy (&BackupDosHdr, DosHdr, sizeof (EFI_IMAGE_DOS_HEADER)); + memset (DosHdr, 0, sizeof (EFI_IMAGE_DOS_HEADER)); + DosHdr->e_magic = BackupDosHdr.e_magic; + DosHdr->e_lfanew = BackupDosHdr.e_lfanew; + + for (Index = sizeof (EFI_IMAGE_DOS_HEADER); Index < (ULONG) DosHdr->e_lfanew; Index++) { + FileBuffer[Index] = DosHdr->e_cp; + } + + // + // Path the PE header + // + PeHdr->OptionalHeader.Subsystem = (USHORT) Type; + if (TimeStampPresent) { + PeHdr->FileHeader.TimeDateStamp = (UINT32) TimeStamp; + } + + if (PeHdr->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->OptionalHeader; + Optional32->MajorLinkerVersion = 0; + Optional32->MinorLinkerVersion = 0; + Optional32->MajorOperatingSystemVersion = 0; + Optional32->MinorOperatingSystemVersion = 0; + Optional32->MajorImageVersion = 0; + Optional32->MinorImageVersion = 0; + Optional32->MajorSubsystemVersion = 0; + Optional32->MinorSubsystemVersion = 0; + Optional32->Win32VersionValue = 0; + Optional32->CheckSum = 0; + Optional32->SizeOfStackReserve = 0; + Optional32->SizeOfStackCommit = 0; + Optional32->SizeOfHeapReserve = 0; + Optional32->SizeOfHeapCommit = 0; + + // + // Strip zero padding at the end of the .reloc section + // + if (Optional32->NumberOfRvaAndSizes >= 6) { + if (Optional32->DataDirectory[5].Size != 0) { + SectionHeader = (EFI_IMAGE_SECTION_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof(UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + PeHdr->FileHeader.SizeOfOptionalHeader); + for (Index = 0; Index < PeHdr->FileHeader.NumberOfSections; Index++, SectionHeader++) { + // + // Look for the Section Header that starts as the same virtual address as the Base Relocation Data Directory + // + if (SectionHeader->VirtualAddress == Optional32->DataDirectory[5].VirtualAddress) { + SectionHeader->Misc.VirtualSize = Optional32->DataDirectory[5].Size; + AllignedRelocSize = (Optional32->DataDirectory[5].Size + Optional32->FileAlignment - 1) & (~(Optional32->FileAlignment - 1)); + // + // Check to see if there is zero padding at the end of the base relocations + // + if (AllignedRelocSize < SectionHeader->SizeOfRawData) { + // + // Check to see if the base relocations are at the end of the file + // + if (SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData == Optional32->SizeOfImage) { + // + // All the required conditions are met to strip the zero padding of the end of the base relocations section + // + Optional32->SizeOfImage -= (SectionHeader->SizeOfRawData - AllignedRelocSize); + Optional32->SizeOfInitializedData -= (SectionHeader->SizeOfRawData - AllignedRelocSize); + SectionHeader->SizeOfRawData = AllignedRelocSize; + FileLength = Optional32->SizeOfImage; + } + } + } + } + } + } + } + if (PeHdr->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->OptionalHeader; + Optional64->MajorLinkerVersion = 0; + Optional64->MinorLinkerVersion = 0; + Optional64->MajorOperatingSystemVersion = 0; + Optional64->MinorOperatingSystemVersion = 0; + Optional64->MajorImageVersion = 0; + Optional64->MinorImageVersion = 0; + Optional64->MajorSubsystemVersion = 0; + Optional64->MinorSubsystemVersion = 0; + Optional64->Win32VersionValue = 0; + Optional64->CheckSum = 0; + Optional64->SizeOfStackReserve = 0; + Optional64->SizeOfStackCommit = 0; + Optional64->SizeOfHeapReserve = 0; + Optional64->SizeOfHeapCommit = 0; + + // + // Zero the .pdata section if the machine type is X64 and the Debug Directory is empty + // + if (PeHdr->FileHeader.Machine == 0x8664) { // X64 + if (Optional64->NumberOfRvaAndSizes >= 4) { + if (Optional64->NumberOfRvaAndSizes < 7 || (Optional64->NumberOfRvaAndSizes >= 7 && Optional64->DataDirectory[6].Size == 0)) { + SectionHeader = (EFI_IMAGE_SECTION_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof(UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + PeHdr->FileHeader.SizeOfOptionalHeader); + for (Index = 0; Index < PeHdr->FileHeader.NumberOfSections; Index++, SectionHeader++) { + if (SectionHeader->VirtualAddress == Optional64->DataDirectory[3].VirtualAddress) { + RuntimeFunction = (RUNTIME_FUNCTION *)(FileBuffer + SectionHeader->PointerToRawData); + for (Index1 = 0; Index1 < Optional64->DataDirectory[3].Size / sizeof (RUNTIME_FUNCTION); Index1++, RuntimeFunction++) { + SectionHeader = (EFI_IMAGE_SECTION_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof(UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + PeHdr->FileHeader.SizeOfOptionalHeader); + for (Index2 = 0; Index2 < PeHdr->FileHeader.NumberOfSections; Index2++, SectionHeader++) { + if (RuntimeFunction->UnwindInfoAddress > SectionHeader->VirtualAddress && RuntimeFunction->UnwindInfoAddress < (SectionHeader->VirtualAddress + SectionHeader->SizeOfRawData)) { + UnwindInfo = (UNWIND_INFO *)(FileBuffer + SectionHeader->PointerToRawData + (RuntimeFunction->UnwindInfoAddress - SectionHeader->VirtualAddress)); + if (UnwindInfo->Version == 1) { + memset (UnwindInfo + 1, 0, UnwindInfo->CountOfUnwindCodes * sizeof (UINT16)); + memset (UnwindInfo, 0, sizeof (UNWIND_INFO)); + } + } + } + memset (RuntimeFunction, 0, sizeof (RUNTIME_FUNCTION)); + } + } + } + Optional64->DataDirectory[3].Size = 0; + Optional64->DataDirectory[3].VirtualAddress = 0; + } + } + } + + // + // Strip zero padding at the end of the .reloc section + // + if (Optional64->NumberOfRvaAndSizes >= 6) { + if (Optional64->DataDirectory[5].Size != 0) { + SectionHeader = (EFI_IMAGE_SECTION_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof(UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + PeHdr->FileHeader.SizeOfOptionalHeader); + for (Index = 0; Index < PeHdr->FileHeader.NumberOfSections; Index++, SectionHeader++) { + // + // Look for the Section Header that starts as the same virtual address as the Base Relocation Data Directory + // + if (SectionHeader->VirtualAddress == Optional64->DataDirectory[5].VirtualAddress) { + SectionHeader->Misc.VirtualSize = Optional64->DataDirectory[5].Size; + AllignedRelocSize = (Optional64->DataDirectory[5].Size + Optional64->FileAlignment - 1) & (~(Optional64->FileAlignment - 1)); + // + // Check to see if there is zero padding at the end of the base relocations + // + if (AllignedRelocSize < SectionHeader->SizeOfRawData) { + // + // Check to see if the base relocations are at the end of the file + // + if (SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData == Optional64->SizeOfImage) { + // + // All the required conditions are met to strip the zero padding of the end of the base relocations section + // + Optional64->SizeOfImage -= (SectionHeader->SizeOfRawData - AllignedRelocSize); + Optional64->SizeOfInitializedData -= (SectionHeader->SizeOfRawData - AllignedRelocSize); + SectionHeader->SizeOfRawData = AllignedRelocSize; + FileLength = Optional64->SizeOfImage; + } + } + } + } + } + } + } + + FWriteFile (fpOut, FileBuffer, FileLength); + + // + // Done + // + fclose (fpIn); + fclose (fpOut); + // + // printf ("Created %s\n", OutImageName); + // + return STATUS_SUCCESS; +} diff --git a/Tools/CodeTools/Source/GenAcpiTable/GenAcpiTable.c b/Tools/CodeTools/Source/GenAcpiTable/GenAcpiTable.c new file mode 100644 index 0000000000..7a413eacb0 --- /dev/null +++ b/Tools/CodeTools/Source/GenAcpiTable/GenAcpiTable.c @@ -0,0 +1,544 @@ +/*++ + +Copyright (c) 2004-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + GenAcpiTable.c + +Abstract: + + A utility that extracts the .DATA section from a PE/COFF image. + +--*/ + +#include +#include +#include + +#include +#include // for PE32 structure definitions + +#include "CommonLib.h" +#include "EfiUtilityMsgs.h" + +// +// Version of this utility +// +#define UTILITY_NAME "GenAcpiTable" +#define UTILITY_VERSION "v0.11" + +// +// Define the max length of a filename +// +#define MAX_PATH 256 +#define DEFAULT_OUTPUT_EXTENSION ".acpi" + +// +// Use this to track our command-line options and globals +// +struct { + INT8 OutFileName[MAX_PATH]; + INT8 InFileName[MAX_PATH]; +} mOptions; + +// +// Use these to convert from machine type value to a named type +// +typedef struct { + UINT16 Value; + INT8 *Name; +} STRING_LOOKUP; + +static STRING_LOOKUP mMachineTypes[] = { + EFI_IMAGE_MACHINE_IA32, + "IA32", + EFI_IMAGE_MACHINE_IA64, + "IA64", + EFI_IMAGE_MACHINE_EBC, + "EBC", + 0, + NULL +}; + +static STRING_LOOKUP mSubsystemTypes[] = { + EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION, + "EFI application", + EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, + "EFI boot service driver", + EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER, + "EFI runtime driver", + 0, + NULL +}; +// +// Function prototypes +// +static +void +Usage ( + VOID + ); + +static +STATUS +ParseCommandLine ( + int Argc, + char *Argv[] + ); + +static +STATUS +CheckPE32File ( + INT8 *FileName, + FILE *Fptr, + UINT16 *MachineType, + UINT16 *SubSystem + ); + +static +STATUS +ProcessFile ( + INT8 *InFileName, + INT8 *OutFileName + ); + +static +void +DumpImage ( + INT8 *FileName + ); + +main ( + int Argc, + char *Argv[] + ) +/*++ + +Routine Description: + + +Arguments: + + Argc - standard C main() argument count + + Argv - standard C main() argument list + +Returns: + + 0 success + non-zero otherwise + +--*/ +// GC_TODO: ] - add argument and description to function comment +{ + UINT32 Status; + + SetUtilityName (UTILITY_NAME); + // + // Parse the command line arguments + // + if (ParseCommandLine (Argc, Argv)) { + return STATUS_ERROR; + } + // + // Make sure we don't have the same filename for input and output files + // + if (stricmp (mOptions.OutFileName, mOptions.InFileName) == 0) { + Error (NULL, 0, 0, mOptions.OutFileName, "input and output file names must be different"); + goto Finish; + } + // + // Process the file + // + ProcessFile (mOptions.InFileName, mOptions.OutFileName); +Finish: + Status = GetUtilityStatus (); + return Status; +} + +static +STATUS +ProcessFile ( + INT8 *InFileName, + INT8 *OutFileName + ) +/*++ + +Routine Description: + + Process a PE32 EFI file. + +Arguments: + + InFileName - Name of the PE32 EFI file to process. + OutFileName - Name of the output file for the processed data. + +Returns: + + 0 - successful + +--*/ +{ + STATUS Status; + UINTN Index; + FILE *InFptr; + FILE *OutFptr; + UINT16 MachineType; + UINT16 SubSystem; + UINT32 PESigOffset; + EFI_IMAGE_FILE_HEADER FileHeader; + EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader32; + EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader64; + EFI_IMAGE_SECTION_HEADER SectionHeader; + UINT8 *Buffer; + long SaveFilePosition; + + InFptr = NULL; + OutFptr = NULL; + Buffer = NULL; + Status = STATUS_ERROR; + // + // Try to open the input file + // + if ((InFptr = fopen (InFileName, "rb")) == NULL) { + Error (NULL, 0, 0, InFileName, "failed to open input file for reading"); + return STATUS_ERROR; + } + // + // Double-check the file to make sure it's what we expect it to be + // + if (CheckPE32File (InFileName, InFptr, &MachineType, &SubSystem) != STATUS_SUCCESS) { + goto Finish; + } + // + // Per the PE/COFF specification, at offset 0x3C in the file is a 32-bit + // offset (from the start of the file) to the PE signature, which always + // follows the MSDOS stub. The PE signature is immediately followed by the + // COFF file header. + // + // + if (fseek (InFptr, 0x3C, SEEK_SET) != 0) { + Error (NULL, 0, 0, InFileName, "failed to seek to PE signature in file", NULL); + goto Finish; + } + + if (fread (&PESigOffset, sizeof (PESigOffset), 1, InFptr) != 1) { + Error (NULL, 0, 0, InFileName, "failed to read PE signature offset from file"); + goto Finish; + } + + if (fseek (InFptr, PESigOffset + 4, SEEK_SET) != 0) { + Error (NULL, 0, 0, InFileName, "failed to seek to PE signature"); + goto Finish; + } + // + // We should now be at the COFF file header. Read it in and verify it's + // of an image type we support. + // + if (fread (&FileHeader, sizeof (EFI_IMAGE_FILE_HEADER), 1, InFptr) != 1) { + Error (NULL, 0, 0, InFileName, "failed to read file header from image"); + goto Finish; + } + + if ((FileHeader.Machine != EFI_IMAGE_MACHINE_IA32) && (FileHeader.Machine != EFI_IMAGE_MACHINE_IA64) && (FileHeader.Machine != EFI_IMAGE_MACHINE_X64)) { + Error (NULL, 0, 0, InFileName, "image is of an unsupported machine type 0x%X", (UINT32) FileHeader.Machine); + goto Finish; + } + // + // Read in the optional header. Assume PE32, and if not, then re-read as PE32+ + // + SaveFilePosition = ftell (InFptr); + if (fread (&OptionalHeader32, sizeof (EFI_IMAGE_OPTIONAL_HEADER32), 1, InFptr) != 1) { + Error (NULL, 0, 0, InFileName, "failed to read optional header from input file"); + goto Finish; + } + + if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + if (fseek (InFptr, SaveFilePosition, SEEK_SET) != 0) { + Error (NULL, 0, 0, InFileName, "failed to seek to .data section"); + goto Finish; + } + + if (fread (&OptionalHeader64, sizeof (EFI_IMAGE_OPTIONAL_HEADER64), 1, InFptr) != 1) { + Error (NULL, 0, 0, InFileName, "failed to read optional header from input file"); + goto Finish; + } + } + // + // Search for the ".data" section + // + for (Index = 0; Index < FileHeader.NumberOfSections; Index++) { + if (fread (&SectionHeader, sizeof (EFI_IMAGE_SECTION_HEADER), 1, InFptr) != 1) { + Error (NULL, 0, 0, InFileName, "failed to read optional header from input file"); + goto Finish; + } + + if (strcmp (SectionHeader.Name, ".data") == 0) { + if (fseek (InFptr, SectionHeader.PointerToRawData, SEEK_SET) != 0) { + Error (NULL, 0, 0, InFileName, "failed to seek to .data section"); + goto Finish; + } + + Buffer = (UINT8 *) malloc (SectionHeader.Misc.VirtualSize); + if (Buffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Finish; + } + if (fread (Buffer, SectionHeader.Misc.VirtualSize, 1, InFptr) != 1) { + Error (NULL, 0, 0, InFileName, "failed to .data section"); + goto Finish; + } + // + // Now open our output file + // + if ((OutFptr = fopen (OutFileName, "wb")) == NULL) { + Error (NULL, 0, 0, OutFileName, "failed to open output file for writing"); + goto Finish; + } + + if (fwrite (Buffer, SectionHeader.Misc.VirtualSize, 1, OutFptr) != 1) { + Error (NULL, 0, 0, OutFileName, "failed to write .data section"); + goto Finish; + } + + Status = STATUS_SUCCESS; + goto Finish; + } + } + + Status = STATUS_ERROR; + +Finish: + if (InFptr != NULL) { + fclose (InFptr); + } + // + // Close the output file. If there was an error, delete the output file so + // that a subsequent build will rebuild it. + // + if (OutFptr != NULL) { + fclose (OutFptr); + if (GetUtilityStatus () == STATUS_ERROR) { + remove (OutFileName); + } + } + + // + // Free up our buffer + // + if (Buffer != NULL) { + free (Buffer); + } + + return Status; +} + +static +STATUS +CheckPE32File ( + INT8 *FileName, + FILE *Fptr, + UINT16 *MachineType, + UINT16 *SubSystem + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FileName - GC_TODO: add argument description + Fptr - GC_TODO: add argument description + MachineType - GC_TODO: add argument description + SubSystem - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + /*++ + +Routine Description: + + Given a file pointer to a supposed PE32 image file, verify that it is indeed a + PE32 image file, and then return the machine type in the supplied pointer. + +Arguments: + + Fptr File pointer to the already-opened PE32 file + MachineType Location to stuff the machine type of the PE32 file. This is needed + because the image may be Itanium-based, IA32, or EBC. + +Returns: + + 0 success + non-zero otherwise + +--*/ + EFI_IMAGE_DOS_HEADER DosHeader; + EFI_IMAGE_FILE_HEADER FileHdr; + EFI_IMAGE_OPTIONAL_HEADER OptionalHdr; + UINT32 PESig; + STATUS Status; + + Status = STATUS_ERROR; + // + // Position to the start of the file + // + fseek (Fptr, 0, SEEK_SET); + // + // Read the DOS header + // + if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) { + Error (NULL, 0, 0, FileName, "failed to read the DOS stub from the input file"); + goto Finish; + } + // + // Check the magic number (0x5A4D) + // + if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) { + Error (NULL, 0, 0, FileName, "input file does not appear to be a PE32 image (magic number)"); + goto Finish; + } + // + // Position into the file and check the PE signature + // + fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET); + if (fread (&PESig, sizeof (PESig), 1, Fptr) != 1) { + Error (NULL, 0, 0, FileName, "failed to read PE signature bytes"); + goto Finish; + } + // + // Check the PE signature in the header "PE\0\0" + // + if (PESig != EFI_IMAGE_NT_SIGNATURE) { + Error (NULL, 0, 0, FileName, "file does not appear to be a PE32 image (signature)"); + goto Finish; + } + // + // Read the file header + // + if (fread (&FileHdr, sizeof (FileHdr), 1, Fptr) != 1) { + Error (NULL, 0, 0, FileName, "failed to read PE file header from input file"); + goto Finish; + } + // + // Read the optional header so we can get the subsystem + // + if (fread (&OptionalHdr, sizeof (OptionalHdr), 1, Fptr) != 1) { + Error (NULL, 0, 0, FileName, "failed to read COFF optional header from input file"); + goto Finish; + } + + *SubSystem = OptionalHdr.Subsystem; + // + // Good to go + // + Status = STATUS_SUCCESS; +Finish: + fseek (Fptr, 0, SEEK_SET); + return Status; +} + +static +int +ParseCommandLine ( + int Argc, + char *Argv[] + ) +/*++ + +Routine Description: + + Given the Argc/Argv program arguments, and a pointer to an options structure, + parse the command-line options and check their validity. + + +Arguments: + + Argc - standard C main() argument count + Argv - standard C main() argument list + +Returns: + + STATUS_SUCCESS success + non-zero otherwise + +--*/ +// GC_TODO: ] - add argument and description to function comment +{ + // + // Clear out the options + // + memset ((char *) &mOptions, 0, sizeof (mOptions)); + // + // Skip over the program name + // + Argc--; + Argv++; + + if (Argc != 2) { + Usage (); + return STATUS_ERROR; + } + + strcpy (mOptions.InFileName, Argv[0]); + // + // Next argument + // + Argv++; + Argc--; + + strcpy (mOptions.OutFileName, Argv[0]); + + return STATUS_SUCCESS; +} + +static +void +Usage ( + VOID + ) +/*++ + +Routine Description: + + Print usage information for this utility. + +Arguments: + + None. + +Returns: + + Nothing. + +--*/ +{ + int Index; + static const char *Msg[] = { + UTILITY_NAME " version "UTILITY_VERSION " - Generate ACPI Table image utility", + " Generate an ACPI Table image from an EFI PE32 image", + " Usage: "UTILITY_NAME " InFileName OutFileName", + " where:", + " InFileName - name of the input PE32 file", + " OutFileName - to write output to OutFileName rather than InFileName"DEFAULT_OUTPUT_EXTENSION, + "", + NULL + }; + for (Index = 0; Msg[Index] != NULL; Index++) { + fprintf (stdout, "%s\n", Msg[Index]); + } +} diff --git a/Tools/CodeTools/Source/GenAcpiTable/build.xml b/Tools/CodeTools/Source/GenAcpiTable/build.xml new file mode 100644 index 0000000000..8c8c5eb81f --- /dev/null +++ b/Tools/CodeTools/Source/GenAcpiTable/build.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/GenCRC32Section/GenCRC32Section.c b/Tools/CodeTools/Source/GenCRC32Section/GenCRC32Section.c new file mode 100644 index 0000000000..b99cf2f816 --- /dev/null +++ b/Tools/CodeTools/Source/GenCRC32Section/GenCRC32Section.c @@ -0,0 +1,286 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + GenCRC32Section.c + +Abstract: + + This file contains functions required to generate a Firmware File System + file. The code is compliant with the Tiano C Coding standards. + +--*/ + +#include "GenCRC32Section.h" + +#define TOOLVERSION "0.2" + +#define UTILITY_NAME "GenCrc32Section" + +EFI_GUID gEfiCrc32SectionGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID; + +EFI_STATUS +SignSectionWithCrc32 ( + IN OUT UINT8 *FileBuffer, + IN OUT UINT32 *BufferSize, + IN UINT32 DataSize + ) +/*++ + +Routine Description: + + Signs the section with CRC32 and add GUIDed section header for the + signed data. data stays in same location (overwrites source data). + +Arguments: + + FileBuffer - Buffer containing data to sign + + BufferSize - On input, the size of FileBuffer. On output, the size of + actual section data (including added section header). + + DataSize - Length of data to Sign + + Key - Key to use when signing. Currently only CRC32 is supported. + +Returns: + + EFI_SUCCESS - Successful + EFI_OUT_OF_RESOURCES - Not enough resource to complete the operation. + +--*/ +{ + + UINT32 Crc32Checksum; + EFI_STATUS Status; + UINT32 TotalSize; + CRC32_SECTION_HEADER Crc32Header; + UINT8 *SwapBuffer; + + Crc32Checksum = 0; + SwapBuffer = NULL; + + if (DataSize == 0) { + *BufferSize = 0; + + return EFI_SUCCESS; + } + + Status = CalculateCrc32 (FileBuffer, DataSize, &Crc32Checksum); + if (EFI_ERROR (Status)) { + return Status; + } + + TotalSize = DataSize + CRC32_SECTION_HEADER_SIZE; + Crc32Header.GuidSectionHeader.CommonHeader.Type = EFI_SECTION_GUID_DEFINED; + Crc32Header.GuidSectionHeader.CommonHeader.Size[0] = (UINT8) (TotalSize & 0xff); + Crc32Header.GuidSectionHeader.CommonHeader.Size[1] = (UINT8) ((TotalSize & 0xff00) >> 8); + Crc32Header.GuidSectionHeader.CommonHeader.Size[2] = (UINT8) ((TotalSize & 0xff0000) >> 16); + memcpy (&(Crc32Header.GuidSectionHeader.SectionDefinitionGuid), &gEfiCrc32SectionGuid, sizeof (EFI_GUID)); + Crc32Header.GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID; + Crc32Header.GuidSectionHeader.DataOffset = CRC32_SECTION_HEADER_SIZE; + Crc32Header.CRC32Checksum = Crc32Checksum; + + SwapBuffer = (UINT8 *) malloc (DataSize); + if (SwapBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + memcpy (SwapBuffer, FileBuffer, DataSize); + memcpy (FileBuffer, &Crc32Header, CRC32_SECTION_HEADER_SIZE); + memcpy (FileBuffer + CRC32_SECTION_HEADER_SIZE, SwapBuffer, DataSize); + + // + // Make sure section ends on a DWORD boundary + // + while ((TotalSize & 0x03) != 0) { + FileBuffer[TotalSize] = 0; + TotalSize++; + } + + *BufferSize = TotalSize; + + if (SwapBuffer != NULL) { + free (SwapBuffer); + } + + return EFI_SUCCESS; +} + +VOID +PrintUsage ( + VOID + ) +{ + printf ("Usage:\n"); + printf (UTILITY_NAME " -i \"inputfile1\" \"inputfile2\" -o \"outputfile\" \n"); + printf (" -i \"inputfile\":\n "); + printf (" specifies the input files that would be signed to CRC32 Guided section.\n"); + printf (" -o \"outputfile\":\n"); + printf (" specifies the output file that is a CRC32 Guided section.\n"); +} + +INT32 +ReadFilesContentsIntoBuffer ( + IN CHAR8 *argv[], + IN INT32 Start, + IN OUT UINT8 **FileBuffer, + IN OUT UINT32 *BufferSize, + OUT UINT32 *ContentSize, + IN INT32 MaximumArguments + ) +{ + INT32 Index; + CHAR8 *FileName; + FILE *InputFile; + UINT8 Temp; + UINT32 Size; + + FileName = NULL; + InputFile = NULL; + Size = 0; + Index = 0; + + // + // read all input files into one file buffer + // + while (argv[Start + Index][0] != '-') { + + FileName = argv[Start + Index]; + InputFile = fopen (FileName, "rb"); + if (InputFile == NULL) { + Error (NULL, 0, 0, FileName, "failed to open input binary file"); + return -1; + } + + fread (&Temp, sizeof (UINT8), 1, InputFile); + while (!feof (InputFile)) { + (*FileBuffer)[Size++] = Temp; + fread (&Temp, sizeof (UINT8), 1, InputFile); + } + + fclose (InputFile); + InputFile = NULL; + + // + // Make sure section ends on a DWORD boundary + // + while ((Size & 0x03) != 0) { + (*FileBuffer)[Size] = 0; + Size++; + } + + Index++; + if (Index == MaximumArguments) { + break; + } + } + + *ContentSize = Size; + return Index; +} + +int +main ( + INT32 argc, + CHAR8 *argv[] + ) +{ + FILE *OutputFile; + UINT8 *FileBuffer; + UINT32 BufferSize; + EFI_STATUS Status; + UINT32 ContentSize; + CHAR8 *OutputFileName; + INT32 ReturnValue; + INT32 Index; + + OutputFile = NULL; + FileBuffer = NULL; + ContentSize = 0; + OutputFileName = NULL; + + SetUtilityName (UTILITY_NAME); + + if (argc == 1) { + PrintUsage (); + return -1; + } + + BufferSize = 1024 * 1024 * 16; + FileBuffer = (UINT8 *) malloc (BufferSize * sizeof (UINT8)); + if (FileBuffer == NULL) { + Error (NULL, 0, 0, "memory allocation failed", NULL); + return -1; + } + + ZeroMem (FileBuffer, BufferSize); + + for (Index = 0; Index < argc; Index++) { + if (strcmpi (argv[Index], "-i") == 0) { + ReturnValue = ReadFilesContentsIntoBuffer ( + argv, + (Index + 1), + &FileBuffer, + &BufferSize, + &ContentSize, + (argc - (Index + 1)) + ); + if (ReturnValue == -1) { + Error (NULL, 0, 0, "failed to read file contents", NULL); + return -1; + } + + Index += ReturnValue; + } + + if (strcmpi (argv[Index], "-o") == 0) { + OutputFileName = argv[Index + 1]; + } + } + + OutputFile = fopen (OutputFileName, "wb"); + if (OutputFile == NULL) { + Error (NULL, 0, 0, OutputFileName, "failed to open output binary file"); + free (FileBuffer); + return -1; + } + + /* + // + // make sure section ends on a DWORD boundary ?? + // + while ( (Size & 0x03) != 0 ) { + FileBuffer[Size] = 0; + Size ++; + } +*/ + Status = SignSectionWithCrc32 (FileBuffer, &BufferSize, ContentSize); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "failed to sign section", NULL); + free (FileBuffer); + fclose (OutputFile); + return -1; + } + + ContentSize = fwrite (FileBuffer, sizeof (UINT8), BufferSize, OutputFile); + if (ContentSize != BufferSize) { + Error (NULL, 0, 0, "failed to write output buffer", NULL); + ReturnValue = -1; + } else { + ReturnValue = 0; + } + + free (FileBuffer); + fclose (OutputFile); + return ReturnValue; +} diff --git a/Tools/CodeTools/Source/GenCRC32Section/GenCRC32Section.h b/Tools/CodeTools/Source/GenCRC32Section/GenCRC32Section.h new file mode 100644 index 0000000000..1cf976b065 --- /dev/null +++ b/Tools/CodeTools/Source/GenCRC32Section/GenCRC32Section.h @@ -0,0 +1,63 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + GenCRC32Section.h + +Abstract: + + Header file for GenFfsFile. Mainly defines the header of section + header for CRC32 GUID defined sections. Share with GenSection.c + +--*/ + +// +// External Files Referenced +// + +/* Standard Headers */ +#include +#include +#include +#include + +/* MDE Headers */ +#include +#include +#include +#include +#include +#include + +/* Tool Headers */ +#include "CommonLib.h" +#include "Crc32.h" +#include "EfiCompress.h" +#include "EfiUtilityMsgs.h" +#include "ParseInf.h" + +// +// Module Coded to Tiano Coding Conventions +// +#ifndef _EFI_GEN_CRC32_SECTION_H +#define _EFI_GEN_CRC32_SECTION_H + + +typedef struct { + EFI_GUID_DEFINED_SECTION GuidSectionHeader; + UINT32 CRC32Checksum; +} CRC32_SECTION_HEADER; + +#define EFI_SECTION_CRC32_GUID_DEFINED 0 +#define CRC32_SECTION_HEADER_SIZE (sizeof (CRC32_SECTION_HEADER)) + +#endif diff --git a/Tools/CodeTools/Source/GenCRC32Section/build.xml b/Tools/CodeTools/Source/GenCRC32Section/build.xml new file mode 100644 index 0000000000..bbb0f71f5d --- /dev/null +++ b/Tools/CodeTools/Source/GenCRC32Section/build.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/GenCapsuleHdr/CreateGuid.c b/Tools/CodeTools/Source/GenCapsuleHdr/CreateGuid.c new file mode 100644 index 0000000000..2a984fa70e --- /dev/null +++ b/Tools/CodeTools/Source/GenCapsuleHdr/CreateGuid.c @@ -0,0 +1,50 @@ +/*++ + +Copyright (c) 2004-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +Module Name: + + CreateGuid.c + +Abstract: + + Library routine to create a GUID + +--*/ + +#include +#include +#include +#include +#include + +void +CreateGuid ( + GUID *Guid + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + Guid - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + CoCreateGuid (Guid); +} diff --git a/Tools/CodeTools/Source/GenCapsuleHdr/GenCapsuleHdr.c b/Tools/CodeTools/Source/GenCapsuleHdr/GenCapsuleHdr.c new file mode 100644 index 0000000000..d1f55b9abd --- /dev/null +++ b/Tools/CodeTools/Source/GenCapsuleHdr/GenCapsuleHdr.c @@ -0,0 +1,2674 @@ +/*++ + +Copyright (c) 2002-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +Module Name: + + GenCapsuleHdr.c + +Abstract: + + Generate a capsule header for a file, and optionally prepend the + header to a file or list of files. + +--*/ + +#define _UNICODE + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include // for FV header GUID +#include +#include // for FV header GUID + +#include "CommonLib.h" +#include "EfiUtilityMsgs.h" + +#define MAX_PATH 256 +#define PROGRAM_NAME "GenCapsuleHdr" + +#define UNICODE_BACKSLASH L'\\' +#define UNICODE_FILE_START 0xFEFF +#define UNICODE_CR 0x000D +#define UNICODE_LF 0x000A +#define UNICODE_NULL 0x0000 +#define UNICODE_SPACE L' ' +#define UNICODE_SLASH L'/' +#define UNICODE_DOUBLE_QUOTE L'"' +#define UNICODE_A L'A' +#define UNICODE_F L'F' +#define UNICODE_Z L'Z' +#define UNICODE_a L'a' +#define UNICODE_f L'f' +#define UNICODE_z L'z' +#define UNICODE_0 L'0' +#define UNICODE_9 L'9' +#define UNICODE_TAB L'\t' + +#define OEM_HEADER_STRING L"OemHeader" +#define AUTHOR_INFO_STRING L"AuthorInfo" +#define REVISION_INFO_STRING L"RevisionInfo" +#define SHORT_DESCRIPTION_STRING L"ShortDescription" +#define LONG_DESCRIPTION_STRING L"LongDescription" +#define EQUAL_STRING L"=" +#define OPEN_BRACE_STRING L"{" +#define CLOSE_BRACE_STRING L"}" +#define GUID_STRING L"GUID" +#define DATA_STRING L"DATA" + +#if (EFI_SPECIFICATION_VERSION >= 0x00020000) +#define UEFI_CAPSULE_HEADER_NO_FALAGS 0 +#define UEFI_CAPSULE_HEADER_RESET_FALAGS CAPSULE_FLAGS_PERSIST_ACROSS_RESET +#define UEFI_CAPSULE_HEADER_ALL_FALAGS (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) +#endif + +typedef wchar_t WCHAR; + +typedef struct _FILE_LIST { + struct _FILE_LIST *Next; + INT8 FileName[MAX_PATH]; +} FILE_LIST; + +typedef struct _SIZE_LIST { + struct _SIZE_LIST *Next; + UINT32 Size; +} SIZE_LIST; + +typedef struct { + INT8 FileName[MAX_PATH]; + WCHAR *FileBuffer; + WCHAR *FileBufferPtr; + UINT32 FileSize; + FILE *FilePtr; + BOOLEAN EndOfFile; + UINT32 LineNum; +} SOURCE_FILE; + +// +// Here's all our globals. +// +static struct { + BOOLEAN Dump; + BOOLEAN Verbose; + BOOLEAN JoinMode; + INT8 ScriptFileName[MAX_PATH]; + INT8 OutputFileName[MAX_PATH]; + FILE_LIST *FileList; + FILE *OutFptr; + SIZE_LIST *SizeList; + SIZE_LIST *LastSize; + SIZE_LIST *CurrentSize; +} mOptions; + +static EFI_GUID mEfiCapsuleHeaderGuid = EFI_CAPSULE_GUID; + +void +CreateGuid ( + EFI_GUID *Guid + ); + +static +STATUS +ProcessArgs ( + int Argc, + char *Argv[] + ); + +static +void +SkipWhiteSpace ( + SOURCE_FILE *SourceFile + ); + +static +STATUS +GetHexValue ( + SOURCE_FILE *SourceFile, + UINT32 *Value, + UINT32 NumDigits + ); + +static +BOOLEAN +GetSplitFileName ( + INT8 *BaseFileName, + INT8 *NewFileName, + UINT32 SequenceNumber + ); + +static +STATUS +SplitCapsule ( + INT8 *CapsuleFileName + ); + +static +void +Usage ( + VOID + ); + +static +void +DumpCapsule ( + VOID + ); + +static +STATUS +JoinCapsule ( + VOID + ); + +static +STATUS +DumpCapsuleHeaderStrings ( + UINT8 *SectionName, + WCHAR *Buffer + ); + +static +STATUS +CheckFirmwareVolumeHeader ( + INT8 *FileName, + INT8 *Buffer, + UINT32 BufferSize + ); + +static +BOOLEAN +IsToken ( + SOURCE_FILE *File, + WCHAR *Token + ); + +static +BOOLEAN +GetNumber ( + INT8 *Str, + UINT32 *Value + ); + +static +STATUS +ProcessScriptFile ( + INT8 *ScriptFileName, + FILE *OutFptr, + EFI_CAPSULE_HEADER *CapsuleHeader + ); + +static +STATUS +ParseCapsuleInfo ( + SOURCE_FILE *SourceFile, + FILE *OutFptr, + WCHAR *SectionName + ); + +static +STATUS +CreateCapsule ( + VOID + ); + +static +STATUS +ParseOemInfo ( + SOURCE_FILE *SourceFile, + FILE *OutFptr + ); + +static +BOOLEAN +IsWhiteSpace ( + WCHAR Char + ); + +static +BOOLEAN +EndOfFile ( + SOURCE_FILE *File + ); + +int +main ( + int Argc, + char *Argv[] + ) +/*++ + +Routine Description: + Call the routine to process the command-line arguments, then + dispatch to the appropriate function. + +Arguments: + Standard C main() argc and argv. + +Returns: + 0 if successful + nonzero otherwise + +--*/ +// GC_TODO: Argc - add argument and description to function comment +// GC_TODO: ] - add argument and description to function comment +{ + STATUS Status; + FILE_LIST *NextFile; + // + // Specify our program name to the error printing routines. + // + SetUtilityName (PROGRAM_NAME); + // + // Process the command-line arguments + // + Status = ProcessArgs (Argc, Argv); + if (Status == STATUS_SUCCESS) { + if (mOptions.Dump) { + DumpCapsule (); + } else if (mOptions.JoinMode) { + JoinCapsule (); + } else { + CreateCapsule (); + } + } + // + // Cleanup + // + while (mOptions.FileList != NULL) { + NextFile = mOptions.FileList->Next; + free (mOptions.FileList); + mOptions.FileList = NextFile; + } + + while (mOptions.SizeList != NULL) { + mOptions.CurrentSize = mOptions.SizeList->Next; + free (mOptions.SizeList); + mOptions.SizeList = mOptions.CurrentSize; + } + + return GetUtilityStatus (); +} + +static +STATUS +CreateCapsule ( + VOID + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + None + +Returns: + + GC_TODO: add return values + +--*/ +{ + FILE *InFptr; + FILE_LIST *FileList; + INT8 *Buffer; + UINT32 Size; + EFI_CAPSULE_HEADER CapsuleHeader; + UINT8 Zero; + UINT8 FirstFile; + UINT32 CapsuleHeaderSize; + long InsertedBlockMapEntryOffset; + EFI_FV_BLOCK_MAP_ENTRY InsertedBlockMapEntry; + UINT64 FirmwareVolumeSize; + long FileSize; + EFI_FIRMWARE_VOLUME_HEADER FVHeader; + + Buffer = NULL; + InFptr = NULL; + FirmwareVolumeSize = 0; + CapsuleHeaderSize = 0; + InsertedBlockMapEntryOffset = 0; + memset (&InsertedBlockMapEntry, 0, sizeof (EFI_FV_BLOCK_MAP_ENTRY)); + memset (&FVHeader, 0, sizeof (EFI_FIRMWARE_VOLUME_HEADER)); + + if ((mOptions.OutFptr = fopen (mOptions.OutputFileName, "wb")) == NULL) { + Error (NULL, 0, 0, mOptions.OutputFileName, "failed to open output file for writing"); + return STATUS_ERROR; + } + + memset ((char *) &CapsuleHeader, 0, sizeof (CapsuleHeader)); + memcpy ((void *) &CapsuleHeader.CapsuleGuid, (void *) &mEfiCapsuleHeaderGuid, sizeof (EFI_GUID)); + CapsuleHeader.HeaderSize = sizeof (EFI_CAPSULE_HEADER); + CapsuleHeader.CapsuleImageSize = sizeof (EFI_CAPSULE_HEADER); + if (mOptions.ScriptFileName[0] != 0) { + if (ProcessScriptFile (mOptions.ScriptFileName, mOptions.OutFptr, &CapsuleHeader) != STATUS_SUCCESS) { + goto Done; + } + } else { + // + // Insert a default capsule header +#if (EFI_SPECIFICATION_VERSION >= 0x00020000) + CapsuleHeader.HeaderSize = sizeof (EFI_CAPSULE_HEADER); + CapsuleHeader.Flags = UEFI_CAPSULE_HEADER_ALL_FALAGS; +#endif + CapsuleHeader.OffsetToCapsuleBody = sizeof (EFI_CAPSULE_HEADER); + + if (fwrite ((void *) &CapsuleHeader, sizeof (CapsuleHeader), 1, mOptions.OutFptr) != 1) { + Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file"); + goto Done; + } + } + + CapsuleHeaderSize = CapsuleHeader.OffsetToCapsuleBody; + // + // Now copy the contents of any other files specified on the command + // line to the output file. Files must be FFS files, which are aligned + // on 8-byte boundaries. Don't align the first file, since it's the start + // of the image once the capsule header has been removed. + // + FileList = mOptions.FileList; + FirstFile = 1; + Zero = 0; + while (FileList != NULL) { + if ((InFptr = fopen (FileList->FileName, "rb")) == NULL) { + Error (NULL, 0, 0, FileList->FileName, "failed to open file for reading"); + goto Done; + } + // + // Allocate a buffer into which we can read the file. + // + fseek (InFptr, 0, SEEK_END); + Size = ftell (InFptr); + rewind (InFptr); + Buffer = (char *) malloc (Size); + if (Buffer == NULL) { + Error (__FILE__, __LINE__, 0, FileList->FileName, "failed to allocate buffer to read file into"); + goto Done; + } + + if (fread ((void *) Buffer, Size, 1, InFptr) != 1) { + Error (NULL, 0, 0, FileList->FileName, "failed to read file contents"); + goto Done; + } + + if (Size > 0) { + // + // Align the write of the first bytes from the file if not the first file + // + if (FirstFile) { + // + // First file must be a firmware volume. Double-check, and then insert + // an additional block map entry so we can add more files from the command line + // + if (CheckFirmwareVolumeHeader (FileList->FileName, Buffer, Size) != STATUS_SUCCESS) { + goto Done; + } + // + // Save a copy of the firmware volume header for later + // + memcpy (&FVHeader, Buffer, sizeof (EFI_FIRMWARE_VOLUME_HEADER)); + FirmwareVolumeSize = FVHeader.FvLength; + if (FileList->Next != NULL) { + // + // Copy the firmware volume header + // + InsertedBlockMapEntryOffset = CapsuleHeaderSize + FVHeader.HeaderLength; + if (fwrite (Buffer, FVHeader.HeaderLength, 1, mOptions.OutFptr) != 1) { + Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file"); + goto Done; + } + + if (fwrite (&InsertedBlockMapEntry, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, mOptions.OutFptr) != 1) { + Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file"); + goto Done; + } + + if (fwrite ( + Buffer + FVHeader.HeaderLength, + Size - FVHeader.HeaderLength, + 1, + mOptions.OutFptr + ) != 1) { + Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file"); + goto Done; + } + } else { + // + // Copy the file contents as-is + // + if (fwrite ((void *) Buffer, Size, 1, mOptions.OutFptr) != 1) { + Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file"); + goto Done; + } + } + } else { + while ((ftell (mOptions.OutFptr) - CapsuleHeaderSize) & 0x07) { + if (fwrite ((void *) &Zero, 1, 1, mOptions.OutFptr) != 1) { + Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file"); + goto Done; + } + } + + if (fwrite ((void *) Buffer, Size, 1, mOptions.OutFptr) != 1) { + Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file"); + goto Done; + } + } + + FirstFile = 0; + } + + free (Buffer); + Buffer = NULL; + fclose (InFptr); + InFptr = NULL; + FileList = FileList->Next; + } + +Done: + if (Buffer != NULL) { + free (Buffer); + } + + if (InFptr != NULL) { + fclose (InFptr); + } + // + // If we inserted an additional block map entry, then fix it up. Fix up the + // FV header as well to reflect our new size. + // + if (InsertedBlockMapEntryOffset != 0) { + FileSize = ftell (mOptions.OutFptr); + InsertedBlockMapEntry.NumBlocks = 1; + InsertedBlockMapEntry.BlockLength = (UINT32) ((UINT64) FileSize - (UINT64) CapsuleHeaderSize - FirmwareVolumeSize - sizeof (EFI_FV_BLOCK_MAP_ENTRY)); + fseek (mOptions.OutFptr, InsertedBlockMapEntryOffset, SEEK_SET); + fwrite (&InsertedBlockMapEntry, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, mOptions.OutFptr); + // + // Fix up the firmware volume header and write it out + // + fseek (mOptions.OutFptr, CapsuleHeaderSize, SEEK_SET); + FVHeader.FvLength = FileSize - CapsuleHeaderSize; + FVHeader.HeaderLength += sizeof (EFI_FV_BLOCK_MAP_ENTRY); + fwrite (&FVHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, mOptions.OutFptr); + // + // Reposition to the end of the file + // + } + // + // Close files and free the global string lists we allocated memory for + // + if (mOptions.OutFptr != NULL) { + // + // We should now know the full capsule image size. Update the header and write it again. + // + fseek (mOptions.OutFptr, 0, SEEK_END); + Size = ftell (mOptions.OutFptr); + CapsuleHeader.CapsuleImageSize = Size; + fseek (mOptions.OutFptr, 0, SEEK_SET); + if (fwrite ((void *) &CapsuleHeader, sizeof (CapsuleHeader), 1, mOptions.OutFptr) != 1) { + Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file"); + } + + fseek (mOptions.OutFptr, 0, SEEK_END); + fclose (mOptions.OutFptr); + mOptions.OutFptr = NULL; + } + // + // If they are doing split capsule output, then split it up now. + // + if ((mOptions.Dump == 0) && (GetUtilityStatus () == STATUS_SUCCESS) && (mOptions.SizeList != NULL)) { + SplitCapsule (mOptions.OutputFileName); + } + + return STATUS_SUCCESS; +} + +static +STATUS +ProcessScriptFile ( + INT8 *ScriptFileName, + FILE *OutFptr, + EFI_CAPSULE_HEADER *CapsuleHeader + ) +/*++ + +Routine Description: + Parse a capsule header script file. + +Arguments: + ScriptFileName - name of script file to parse + OutFptr - output to dump binary data + CapsuleHeader - capsule header to update with size info + of parsed fields in the script file + +Returns: + STATUS_SUCCESS - if all went well + +--*/ +{ +#if 0 + STATUS Status; + SOURCE_FILE SourceFile; + WCHAR *WScriptFileName; + BOOLEAN InComment; + + if (fwrite (CapsuleHeader, sizeof (EFI_CAPSULE_HEADER), 1, OutFptr) != 1) { + Error (NULL, 0, 0, "failed to write capsule header to output file", NULL); + return STATUS_ERROR; + } + + memset (&SourceFile, 0, sizeof (SOURCE_FILE)); + strcpy (SourceFile.FileName, ScriptFileName); + + Status = STATUS_ERROR; + // + // Open the input unicode script file and read it into a buffer + // + WScriptFileName = (WCHAR *) malloc ((strlen (ScriptFileName) + 1) * sizeof (WCHAR)); + if (WScriptFileName == NULL) { + Error (__FILE__, __LINE__, 0, "failed to allocate memory", NULL); + return STATUS_ERROR; + } + + swprintf (WScriptFileName, L"%S", ScriptFileName); + if ((SourceFile.FilePtr = _wfopen (WScriptFileName, L"r")) == NULL) { + free (WScriptFileName); + Error (NULL, 0, 0, ScriptFileName, "failed to open script file for reading"); + goto Done; + } + + free (WScriptFileName); + fseek (SourceFile.FilePtr, 0, SEEK_END); + SourceFile.FileSize = ftell (SourceFile.FilePtr); + rewind (SourceFile.FilePtr); + SourceFile.FileBuffer = (WCHAR *) malloc (SourceFile.FileSize + sizeof (WCHAR)); + if (SourceFile.FileBuffer == NULL) { + Error (__FILE__, __LINE__, 0, ScriptFileName, "failed to allocate memory to read in file contents"); + goto Done; + } + + if (fread (SourceFile.FileBuffer, SourceFile.FileSize, 1, SourceFile.FilePtr) != 1) { + Error (NULL, 0, 0, ScriptFileName, "failed to read file contents"); + goto Done; + } + + SourceFile.FileBufferPtr = SourceFile.FileBuffer; + SourceFile.LineNum = 1; + if (SourceFile.FileBuffer[0] != UNICODE_FILE_START) { + Error (ScriptFileName, 1, 0, "file does not appear to be a unicode file", NULL); + goto Done; + } + + SourceFile.FileBufferPtr++; + SourceFile.FileBuffer[SourceFile.FileSize / sizeof (WCHAR)] = 0; + // + // Walk the source file buffer and replace all carriage returns with 0 so + // we can print from the file contents on parse errors. + // + InComment = 0; + while (!EndOfFile (&SourceFile)) { + if (SourceFile.FileBufferPtr[0] == UNICODE_CR) { + SourceFile.FileBufferPtr[0] = 0; + InComment = 0; + } else if (SourceFile.FileBufferPtr[0] == UNICODE_LF) { + InComment = 0; + } else if (InComment) { + SourceFile.FileBufferPtr[0] = UNICODE_SPACE; + } else if ((SourceFile.FileBufferPtr[0] == UNICODE_SLASH) && (SourceFile.FileBufferPtr[1] == UNICODE_SLASH)) { + InComment = 1; + SourceFile.FileBufferPtr[0] = UNICODE_SPACE; + } + + SourceFile.FileBufferPtr++; + } + // + // Reposition to the start of the file, but skip over the unicode file start + // + SourceFile.FileBufferPtr = SourceFile.FileBuffer; + SourceFile.FileBufferPtr++; + SourceFile.EndOfFile = 0; + CapsuleHeader->OffsetToOemDefinedHeader = ftell (OutFptr); + // + // Parse the OEM bytes + // + if (ParseOemInfo (&SourceFile, OutFptr) != STATUS_SUCCESS) { + goto Done; + } + // + // Parse the author information + // + CapsuleHeader->OffsetToAuthorInformation = ftell (OutFptr); + if (ParseCapsuleInfo (&SourceFile, OutFptr, AUTHOR_INFO_STRING) != STATUS_SUCCESS) { + goto Done; + } + // + // Parse the revision information + // + CapsuleHeader->OffsetToRevisionInformation = ftell (OutFptr); + if (ParseCapsuleInfo (&SourceFile, OutFptr, REVISION_INFO_STRING) != STATUS_SUCCESS) { + goto Done; + } + // + // Parse the short description + // + CapsuleHeader->OffsetToShortDescription = ftell (OutFptr); + if (ParseCapsuleInfo (&SourceFile, OutFptr, SHORT_DESCRIPTION_STRING) != STATUS_SUCCESS) { + goto Done; + } + // + // Parse the long description + // + CapsuleHeader->OffsetToLongDescription = ftell (OutFptr); + if (ParseCapsuleInfo (&SourceFile, OutFptr, LONG_DESCRIPTION_STRING) != STATUS_SUCCESS) { + goto Done; + } + // + // Better be end of contents + // + SkipWhiteSpace (&SourceFile); + if (!EndOfFile (&SourceFile)) { + Error (ScriptFileName, SourceFile.LineNum, 0, NULL, "expected end-of-file, not %.20S", SourceFile.FileBufferPtr); + goto Done; + } + + CapsuleHeader->OffsetToCapsuleBody = ftell (OutFptr); + rewind (OutFptr); + fwrite (CapsuleHeader, sizeof (EFI_CAPSULE_HEADER), 1, OutFptr); + fseek (OutFptr, 0, SEEK_END); + Status = STATUS_SUCCESS; +Done: + if (SourceFile.FilePtr != NULL) { + fclose (SourceFile.FilePtr); + } + + if (SourceFile.FileBuffer != NULL) { + free (SourceFile.FileBuffer); + } + + return Status; + +#endif + return STATUS_SUCCESS; +} +// +// Parse the OEM data of format: +// OemInfo { +// GUID = 12345676-1234-1234-123456789ABC +// DATA = 0x01, 0x02, 0x03... +// } +// +static +STATUS +ParseOemInfo ( + SOURCE_FILE *SourceFile, + FILE *OutFptr + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + SourceFile - GC_TODO: add argument description + OutFptr - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + long OemHeaderOffset; + UINT32 Data; + EFI_CAPSULE_OEM_HEADER OemHeader; + STATUS Status; + UINT32 DigitCount; + WCHAR *SaveFilePos; + UINT8 ByteData; + + Status = STATUS_ERROR; + memset (&OemHeader, 0, sizeof (EFI_CAPSULE_OEM_HEADER)); + OemHeaderOffset = ftell (OutFptr); + OemHeader.HeaderSize = sizeof (EFI_CAPSULE_OEM_HEADER); + if (fwrite (&OemHeader, sizeof (EFI_CAPSULE_OEM_HEADER), 1, OutFptr) != 1) { + Error (NULL, 0, 0, "failed to write OEM header to output file", NULL); + goto Done; + } + + if (!IsToken (SourceFile, OEM_HEADER_STRING)) { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + NULL, + "expected %S, not %.20S", + OEM_HEADER_STRING, + SourceFile->FileBufferPtr + ); + goto Done; + } + + if (!IsToken (SourceFile, EQUAL_STRING)) { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + NULL, + "expected %S, not %.20S", + EQUAL_STRING, + SourceFile->FileBufferPtr + ); + goto Done; + } + + if (!IsToken (SourceFile, OPEN_BRACE_STRING)) { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + NULL, + "expected %S, not %.20S", + OPEN_BRACE_STRING, + SourceFile->FileBufferPtr + ); + goto Done; + } + // + // Look for: GUID = xxxxxxx-xxxx-xxxx-xxxxxxxxxxxxx + // + if (!IsToken (SourceFile, GUID_STRING)) { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + NULL, + "expected %S, not %.20S", + GUID_STRING, + SourceFile->FileBufferPtr + ); + goto Done; + } + + if (!IsToken (SourceFile, EQUAL_STRING)) { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + NULL, + "expected %S, not %.20S", + EQUAL_STRING, + SourceFile->FileBufferPtr + ); + goto Done; + } + // + // Parse the xxxxxxxx-xxxx-xxxx-xxxx portion of the GUID + // + SkipWhiteSpace (SourceFile); + if (GetHexValue (SourceFile, &Data, 8) != STATUS_SUCCESS) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid GUID", NULL); + goto Done; + } + + OemHeader.OemGuid.Data1 = Data; + if (!IsToken (SourceFile, L"-")) { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + NULL, + "expected dash in GUID, not %S", + SourceFile->FileBufferPtr + ); + goto Done; + } + // + // Get 3 word values + // + for (DigitCount = 0; DigitCount < 3; DigitCount++) { + if (GetHexValue (SourceFile, &Data, 4) != STATUS_SUCCESS) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid GUID", NULL); + goto Done; + } + + switch (DigitCount) { + case 0: + OemHeader.OemGuid.Data2 = (UINT16) Data; + break; + + case 1: + OemHeader.OemGuid.Data3 = (UINT16) Data; + break; + + case 2: + OemHeader.OemGuid.Data4[1] = (UINT8) Data; + OemHeader.OemGuid.Data4[0] = (UINT8) (Data >> 8); + break; + } + + if (!IsToken (SourceFile, L"-")) { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + NULL, + "expected dash in GUID, not %S", + SourceFile->FileBufferPtr + ); + goto Done; + } + } + // + // Pick up the last 6 bytes of the GUID + // + SaveFilePos = SourceFile->FileBufferPtr; + for (DigitCount = 0; DigitCount < 6; DigitCount++) { + if (GetHexValue (SourceFile, &Data, 2) != STATUS_SUCCESS) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid GUID", NULL); + goto Done; + } + + OemHeader.OemGuid.Data4[DigitCount + 2] = (UINT8) Data; + } + // + // Now read raw OEM data bytes. May or may not be present. + // DATA = 0x01, 0x02, 0x02... + // + if (IsToken (SourceFile, CLOSE_BRACE_STRING)) { + Status = STATUS_SUCCESS; + goto Done; + } + + if (!IsToken (SourceFile, DATA_STRING)) { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + NULL, + "expected %S, not %.20S", + DATA_STRING, + SourceFile->FileBufferPtr + ); + goto Done; + } + + if (!IsToken (SourceFile, EQUAL_STRING)) { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + NULL, + "expected %S, not %.20S", + EQUAL_STRING, + SourceFile->FileBufferPtr + ); + goto Done; + } + + while (!EndOfFile (SourceFile)) { + if (IsToken (SourceFile, CLOSE_BRACE_STRING)) { + Status = STATUS_SUCCESS; + goto Done; + } + + if (IsToken (SourceFile, L"0x")) { + if (swscanf (SourceFile->FileBufferPtr, L"%x", &Data) != 1) { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + NULL, + "expected hex byte value, not %.20S", + SourceFile->FileBufferPtr + ); + goto Done; + } + + if (Data &~0xFF) { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + NULL, + "expected byte hex byte value at %.20S", + SourceFile->FileBufferPtr + ); + goto Done; + } + // + // Skip over the hex digits, then write the data + // + while (iswxdigit (SourceFile->FileBufferPtr[0])) { + SourceFile->FileBufferPtr++; + } + + ByteData = (UINT8) Data; + if (fwrite (&ByteData, 1, 1, OutFptr) != 1) { + Error (NULL, 0, 0, "failed to write OEM data to output file", NULL); + goto Done; + } + + OemHeader.HeaderSize++; + // + // Optional comma + // + IsToken (SourceFile, L","); + } else { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + NULL, + "expected hex OEM data, not %.20S", + SourceFile->FileBufferPtr + ); + goto Done; + } + } + + if (EndOfFile (SourceFile)) { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + NULL, + "expected %S close to OEM header data", + CLOSE_BRACE_STRING + ); + goto Done; + } + + Status = STATUS_SUCCESS; +Done: + // + // re-write the oem header if no errors + // + if (Status == STATUS_SUCCESS) { + fseek (OutFptr, OemHeaderOffset, SEEK_SET); + if (fwrite (&OemHeader, sizeof (EFI_CAPSULE_OEM_HEADER), 1, OutFptr) != 1) { + Error (NULL, 0, 0, "failed to write OEM header to output file", NULL); + goto Done; + } + + fseek (OutFptr, 0, SEEK_END); + } + + return Status; +} + +static +STATUS +ParseCapsuleInfo ( + SOURCE_FILE *SourceFile, + FILE *OutFptr, + WCHAR *SectionName + ) +// GC_TODO: function comment should start with '/*++' +// +// GC_TODO: function comment is missing 'Routine Description:' +// GC_TODO: function comment is missing 'Arguments:' +// GC_TODO: function comment is missing 'Returns:' +// GC_TODO: SourceFile - add argument and description to function comment +// GC_TODO: OutFptr - add argument and description to function comment +// GC_TODO: SectionName - add argument and description to function comment +// Parse: eng "string " "parts" +// spa "string " "parts" +// Write out: "eng string parts\0spa string parts\0\0 +// +{ + STATUS Status; + int StringCount; + WCHAR Zero; + WCHAR Spacebar; + + Status = STATUS_ERROR; + Zero = 0; + Spacebar = UNICODE_SPACE; + + if (!IsToken (SourceFile, SectionName)) { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + NULL, + "expected %S, not %.20S", + SectionName, + SourceFile->FileBufferPtr + ); + goto Done; + } + + if (!IsToken (SourceFile, EQUAL_STRING)) { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + NULL, + "expected %S, not %.20S", + EQUAL_STRING, + SourceFile->FileBufferPtr + ); + goto Done; + } + + if (!IsToken (SourceFile, OPEN_BRACE_STRING)) { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + NULL, + "expected %S, not %.20S", + OPEN_BRACE_STRING, + SourceFile->FileBufferPtr + ); + goto Done; + } + + while (!EndOfFile (SourceFile)) { + if (IsToken (SourceFile, CLOSE_BRACE_STRING)) { + break; + } + // + // Look for language identifier (3 lowercase chars) + // + if ((SourceFile->FileBufferPtr[0] >= UNICODE_a) && + (SourceFile->FileBufferPtr[0] <= UNICODE_z) && + (SourceFile->FileBufferPtr[1] >= UNICODE_a) && + (SourceFile->FileBufferPtr[1] <= UNICODE_z) && + (SourceFile->FileBufferPtr[2] >= UNICODE_a) && + (SourceFile->FileBufferPtr[2] <= UNICODE_z) && + IsWhiteSpace (SourceFile->FileBufferPtr[3]) + ) { + // + // Write the 3 chars followed by a spacebar, and then look for opening quote + // + fwrite (SourceFile->FileBufferPtr, sizeof (WCHAR), 1, OutFptr); + SourceFile->FileBufferPtr++; + fwrite (SourceFile->FileBufferPtr, sizeof (WCHAR), 1, OutFptr); + SourceFile->FileBufferPtr++; + fwrite (SourceFile->FileBufferPtr, sizeof (WCHAR), 1, OutFptr); + SourceFile->FileBufferPtr++; + fwrite (&Spacebar, sizeof (WCHAR), 1, OutFptr); + StringCount = 0; + while (IsToken (SourceFile, L"\"")) { + StringCount++; + while (!EndOfFile (SourceFile)) { + if (SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) { + SourceFile->FileBufferPtr++; + break; + } else if ((SourceFile->FileBufferPtr[0] == UNICODE_LF) || (SourceFile->FileBufferPtr[0] == 0)) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing quote on string", NULL); + goto Done; + } else { + fwrite (SourceFile->FileBufferPtr, sizeof (WCHAR), 1, OutFptr); + SourceFile->FileBufferPtr++; + } + } + } + + if (StringCount == 0) { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + NULL, + "expected quoted string, not %.20S", + SourceFile->FileBufferPtr + ); + goto Done; + } + // + // This string's null terminator + // + fwrite (&Zero, sizeof (WCHAR), 1, OutFptr); + } else { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + NULL, + "expected valid language identifer, not %.20S", + SourceFile->FileBufferPtr + ); + goto Done; + } + } + // + // Double null terminator + // + fwrite (&Zero, sizeof (WCHAR), 1, OutFptr); + Status = STATUS_SUCCESS; +Done: + return Status; +} + +static +STATUS +SplitCapsule ( + INT8 *CapsuleFileName + ) +/*++ + +Routine Description: + We've created an entire capsule image. Now split it up into the + size pieces they requested. + +Arguments: + CapsuleFileName - name of an existing capsule file on disk + +Returns: + STATUS_SUCCESS - if no problems + +Notes: + This implementation reads in the entire capsule image from + disk, then overwrites the original file with the first + in the series. + +--*/ +{ +#if 0 + EFI_CAPSULE_HEADER *CapHdr; + + EFI_CAPSULE_HEADER Hdr; + FILE *CapFptr; + FILE *OutFptr; + UINT32 SizeLeft; + UINT32 CurrentSize; + UINT32 DataSize; + UINT32 SequenceNumber; + INT8 *Buffer; + INT8 FileName[MAX_PATH]; + STATUS Status; + UINT32 FileSize; + // + // Figure out the total size, then rewind the input file and + // read the entire thing in + // + if ((CapFptr = fopen (CapsuleFileName, "rb")) == NULL) { + Error (NULL, 0, 0, CapsuleFileName, "failed to open capsule image for reading"); + return STATUS_ERROR; + } + + OutFptr = NULL; + Status = STATUS_SUCCESS; + fseek (CapFptr, 0, SEEK_END); + SizeLeft = ftell (CapFptr); + fseek (CapFptr, 0, SEEK_SET); + CapHdr = (EFI_CAPSULE_HEADER *) malloc (SizeLeft); + if (CapHdr == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + goto FailDone; + } + + if (fread (CapHdr, SizeLeft, 1, CapFptr) != 1) { + Error (NULL, 0, 0, "failed to read capsule contents", "split failed"); + goto FailDone; + } + + fclose (CapFptr); + CapFptr = NULL; + // + // Get a GUID to fill in the InstanceId GUID in the header + // + CreateGuid (&CapHdr->InstanceId); + SequenceNumber = 0; + // + // If the split size is larger than the original capsule image, then + // we're done. + // + if (mOptions.SizeList->Size >= SizeLeft) { + mOptions.SizeList->Size = SizeLeft; + goto Done; + } + // + // First size has to be big enough for the original header + // + if (mOptions.SizeList->Size < CapHdr->OffsetToCapsuleBody) { + Error (NULL, 0, 0, "first split size is insufficient for the original capsule header", NULL); + goto FailDone; + } + // + // Initialize the header we'll use on all but the first part + // + memset (&Hdr, 0, sizeof (Hdr)); + Hdr.CapsuleGuid = CapHdr->CapsuleGuid; + Hdr.HeaderSize = sizeof (Hdr); + Hdr.Flags = CapHdr->Flags; + Hdr.InstanceId = CapHdr->InstanceId; + Hdr.CapsuleImageSize = CapHdr->CapsuleImageSize; + Hdr.OffsetToCapsuleBody = Hdr.HeaderSize; + Hdr.SequenceNumber = 1; + // + // printf ("Created %s - 0x%X bytes\n", CapsuleFileName, mOptions.SizeList->Size); + // + Buffer = (UINT8 *) CapHdr; + // + // Walk the list of sizes and write out a capsule header, and + // then the raw capsule data. + // + // SizeLeft -= mOptions.SizeList->Size; + // + mOptions.CurrentSize = mOptions.SizeList; + while (SizeLeft) { + CurrentSize = mOptions.CurrentSize->Size; + GetSplitFileName (mOptions.OutputFileName, FileName, SequenceNumber); + if ((OutFptr = fopen (FileName, "wb")) == NULL) { + Error (NULL, 0, 0, FileName, "failed to open split file for writing"); + goto FailDone; + } + + if (Buffer == (UINT8 *) CapHdr) { + // + // First part -- write out original header and data + // + if (fwrite (Buffer, CurrentSize, 1, OutFptr) != 1) { + Error (NULL, 0, 0, FileName, "failed to write to split image file"); + goto FailDone; + } + + SizeLeft -= CurrentSize; + Buffer += CurrentSize; + DataSize = CurrentSize; + FileSize = CurrentSize; + } else { + // + // Not the first part. Write the default header, and then the raw bytes from the + // original image. + // + if (CurrentSize <= sizeof (Hdr)) { + Error (NULL, 0, 0, "split size too small for capsule header + data", "0x%X", CurrentSize); + goto FailDone; + } + + DataSize = CurrentSize - sizeof (Hdr); + if (DataSize > SizeLeft) { + DataSize = SizeLeft; + } + + if (fwrite (&Hdr, sizeof (Hdr), 1, OutFptr) != 1) { + Error (NULL, 0, 0, FileName, "failed to write capsule header to output file"); + fclose (OutFptr); + goto FailDone; + } + + if (fwrite (Buffer, DataSize, 1, OutFptr) != 1) { + Error (NULL, 0, 0, FileName, "failed to write capsule data to output file"); + fclose (OutFptr); + goto FailDone; + } + + Hdr.SequenceNumber++; + Buffer += DataSize; + SizeLeft -= DataSize; + FileSize = DataSize + sizeof (Hdr); + } + // + // Next size in list if there is one + // + if (mOptions.CurrentSize->Next != NULL) { + mOptions.CurrentSize = mOptions.CurrentSize->Next; + } + + SequenceNumber++; + fclose (OutFptr); + OutFptr = NULL; + printf ("Created %s - 0x%X bytes (0x%X bytes of data)\n", FileName, FileSize, DataSize); + } + + goto Done; +FailDone: + Status = STATUS_ERROR; +Done: + if (CapHdr != NULL) { + free (CapHdr); + } + + if (CapFptr != NULL) { + fclose (CapFptr); + } + + if (OutFptr != NULL) { + fclose (OutFptr); + } + + return Status; + +#endif + return STATUS_SUCCESS; +} + +static +BOOLEAN +GetSplitFileName ( + INT8 *BaseFileName, + INT8 *NewFileName, + UINT32 SequenceNumber + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + BaseFileName - GC_TODO: add argument description + NewFileName - GC_TODO: add argument description + SequenceNumber - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + /*++ + +Routine Description: + Given an initial split capsule file name and a sequence number, + create an appropriate file name for this split of a capsule image. + +Arguments: + BaseFileName - name of of the first split file in the series + NewFileName - output name of the split file + SequenceNumber - 0-based sequence number of split images + +Returns: + TRUE - name created successfully + FALSE - otherwise + +--*/ + INT8 *Ptr; + INT8 *Part2Start; + UINT32 Digits; + UINT32 Len; + UINT32 BaseOffset; + // + // Work back from the end of the file name and see if there is a number somewhere + // + for (Ptr = BaseFileName + strlen (BaseFileName) - 1; (Ptr > BaseFileName) && !isdigit (*Ptr); Ptr--) + ; + if ((Ptr == BaseFileName) && (!isdigit (*Ptr))) { + // + // Found no number, so just add it to the end + // + sprintf (NewFileName, "%s%d", BaseFileName, SequenceNumber); + return TRUE; + } else { + // + // Found a number. Look back to find the first digit. + // + Part2Start = Ptr + 1; + for (Digits = 1; isdigit (*Ptr) && (Ptr > BaseFileName); Ptr--, Digits++) + ; + if (!isdigit (*Ptr)) { + Ptr++; + Digits--; + } + + BaseOffset = atoi (Ptr); + SequenceNumber = SequenceNumber + BaseOffset; + if (Digits > 1) { + // + // Copy the first part of the original file name to the new filename + // This is the path for filenames with format path\name001.cap + // + Len = (UINT32) Ptr - (UINT32) BaseFileName; + strncpy (NewFileName, BaseFileName, Len); + sprintf (NewFileName + Len, "%0*d", Digits, SequenceNumber); + strcat (NewFileName, Part2Start); + return TRUE; + } else { + // + // Only one digit found. This is the path for filenames with + // format path\name1.cap + // + Len = (UINT32) Ptr - (UINT32) BaseFileName + 1; + strncpy (NewFileName, BaseFileName, Len); + sprintf (NewFileName + Len - 1, "%d", SequenceNumber); + strcat (NewFileName, Part2Start); + return TRUE; + } + } +} + +static +BOOLEAN +IsWhiteSpace ( + WCHAR Char + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + Char - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + switch (Char) { + case UNICODE_SPACE: + case UNICODE_TAB: + case UNICODE_NULL: + case UNICODE_CR: + case UNICODE_LF: + return TRUE; + + default: + return FALSE; + } +} + +static +BOOLEAN +IsToken ( + SOURCE_FILE *File, + WCHAR *Token + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + File - GC_TODO: add argument description + Token - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + SkipWhiteSpace (File); + if (EndOfFile (File)) { + return FALSE; + } + + if (wcsncmp (Token, File->FileBufferPtr, wcslen (Token)) == 0) { + File->FileBufferPtr += wcslen (Token); + return TRUE; + } + + return FALSE; +} + +static +STATUS +CheckFirmwareVolumeHeader ( + INT8 *FileName, + INT8 *Buffer, + UINT32 BufferSize + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FileName - GC_TODO: add argument description + Buffer - GC_TODO: add argument description + BufferSize - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + EFI_FIRMWARE_VOLUME_HEADER *Hdr; + EFI_GUID FVHeaderGuid = EFI_FIRMWARE_FILE_SYSTEM_GUID; + + Hdr = (EFI_FIRMWARE_VOLUME_HEADER *) Buffer; + if (Hdr->Signature != EFI_FVH_SIGNATURE) { + Error (NULL, 0, 0, FileName, "file does not appear to be a firmware volume (bad signature)"); + return STATUS_ERROR; + } + + if (Hdr->Revision != EFI_FVH_REVISION) { + Error (NULL, 0, 0, FileName, "unsupported firmware volume header version"); + return STATUS_ERROR; + } + + if (Hdr->FvLength > BufferSize) { + Error (NULL, 0, 0, FileName, "malformed firmware volume -- FvLength > file size"); + return STATUS_ERROR; + } + + if (memcmp (&Hdr->FileSystemGuid, &FVHeaderGuid, sizeof (EFI_GUID)) != 0) { + Error (NULL, 0, 0, FileName, "invalid FFS GUID in firmware volume header"); + return STATUS_ERROR; + } + + return STATUS_SUCCESS; +} + +static +void +DumpCapsule ( + VOID + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + None + +Returns: + + GC_TODO: add return values + +--*/ +{ +#if 0 + FILE *InFptr; + FILE_LIST *FileList; + EFI_CAPSULE_HEADER CapsuleHeader; + EFI_FIRMWARE_VOLUME_HEADER FVHeader; + EFI_CAPSULE_OEM_HEADER *OemHeader; + UINT8 *BPtr; + UINT32 FileSize; + UINT32 CapsuleHeaderDataSize; + UINT8 ByteCount; + UINT8 *CapsuleHeaderData; + BOOLEAN SplitImage; + + InFptr = NULL; + CapsuleHeaderData = NULL; + FileList = mOptions.FileList; + while (FileList != NULL) { + if ((InFptr = fopen (FileList->FileName, "rb")) == NULL) { + Error (NULL, 0, 0, FileList->FileName, "failed to open file for reading"); + goto Done; + } + + if (fread (&CapsuleHeader, sizeof (EFI_CAPSULE_HEADER), 1, InFptr) != 1) { + Error (NULL, 0, 0, FileList->FileName, "failed to read capsule header"); + goto Done; + } + + fseek (InFptr, 0, SEEK_END); + FileSize = ftell (InFptr); + if (CapsuleHeader.CapsuleImageSize > FileSize) { + SplitImage = TRUE; + } else { + SplitImage = FALSE; + } + + printf ( + "Capsule %s Size=0x%X CargoSize=0x%X\n", + FileList->FileName, + FileSize, + FileSize - CapsuleHeader.OffsetToCapsuleBody + ); + printf ( + " GUID %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", + CapsuleHeader.CapsuleGuid.Data1, + (UINT32) CapsuleHeader.CapsuleGuid.Data2, + (UINT32) CapsuleHeader.CapsuleGuid.Data3, + (UINT32) CapsuleHeader.CapsuleGuid.Data4[0], + (UINT32) CapsuleHeader.CapsuleGuid.Data4[1], + (UINT32) CapsuleHeader.CapsuleGuid.Data4[2], + (UINT32) CapsuleHeader.CapsuleGuid.Data4[3], + (UINT32) CapsuleHeader.CapsuleGuid.Data4[4], + (UINT32) CapsuleHeader.CapsuleGuid.Data4[5], + (UINT32) CapsuleHeader.CapsuleGuid.Data4[6], + (UINT32) CapsuleHeader.CapsuleGuid.Data4[7] + ); + if (memcmp (&CapsuleHeader.CapsuleGuid, &mEfiCapsuleHeaderGuid, sizeof (EFI_GUID)) != 0) { + printf (" INVALID GUID"); + } + + printf ("\n"); + printf (" Header size 0x%08X\n", CapsuleHeader.HeaderSize); + printf (" Flags 0x%08X\n", CapsuleHeader.Flags); + if (!SplitImage) { + printf (" Capsule image size 0x%08X\n", CapsuleHeader.CapsuleImageSize); + } else { + printf (" Capsule image size 0x%08X (split)\n", CapsuleHeader.CapsuleImageSize); + } + + printf (" Sequence number %d\n", CapsuleHeader.SequenceNumber); + printf ( + " InstanceId %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n", + CapsuleHeader.InstanceId.Data1, + (UINT32) CapsuleHeader.InstanceId.Data2, + (UINT32) CapsuleHeader.InstanceId.Data3, + (UINT32) CapsuleHeader.InstanceId.Data4[0], + (UINT32) CapsuleHeader.InstanceId.Data4[1], + (UINT32) CapsuleHeader.InstanceId.Data4[2], + (UINT32) CapsuleHeader.InstanceId.Data4[3], + (UINT32) CapsuleHeader.InstanceId.Data4[4], + (UINT32) CapsuleHeader.InstanceId.Data4[5], + (UINT32) CapsuleHeader.InstanceId.Data4[6], + (UINT32) CapsuleHeader.InstanceId.Data4[7] + ); + printf (" Offset to capsule 0x%X\n", CapsuleHeader.OffsetToCapsuleBody); + // + // Dump header data if there + // + CapsuleHeaderDataSize = CapsuleHeader.OffsetToCapsuleBody - CapsuleHeader.HeaderSize; + if (CapsuleHeaderDataSize != 0) { + CapsuleHeaderData = (UINT8 *) malloc (CapsuleHeaderDataSize); + if (CapsuleHeaderData == NULL) { + Error ( + NULL, + 0, + 0, + "failed to allocate memory to read in capsule header data", + "0x%X bytes", + CapsuleHeaderDataSize + ); + goto Done; + } + + fseek (InFptr, CapsuleHeader.HeaderSize, SEEK_SET); + if (fread (CapsuleHeaderData, CapsuleHeaderDataSize, 1, InFptr) != 1) { + Error ( + NULL, + 0, + 0, + "failed to read capsule header data contents from file", + "0x%X bytes", + CapsuleHeaderDataSize + ); + goto Done; + } + // + // ************************************************************************ + // + // OEM HEADER + // + // ************************************************************************ + // + if (CapsuleHeader.OffsetToOemDefinedHeader != 0) { + OemHeader = (EFI_CAPSULE_OEM_HEADER *) (CapsuleHeaderData + CapsuleHeader.OffsetToOemDefinedHeader - CapsuleHeader.HeaderSize); + printf (" OEM Header\n"); + printf ( + " GUID %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n", + OemHeader->OemGuid.Data1, + (UINT32) OemHeader->OemGuid.Data2, + (UINT32) OemHeader->OemGuid.Data3, + (UINT32) OemHeader->OemGuid.Data4[0], + (UINT32) OemHeader->OemGuid.Data4[1], + (UINT32) OemHeader->OemGuid.Data4[2], + (UINT32) OemHeader->OemGuid.Data4[3], + (UINT32) OemHeader->OemGuid.Data4[4], + (UINT32) OemHeader->OemGuid.Data4[5], + (UINT32) OemHeader->OemGuid.Data4[6], + (UINT32) OemHeader->OemGuid.Data4[7] + ); + printf (" Header size: 0x%X\n", OemHeader->HeaderSize); + printf (" OEM data"); + BPtr = (UINT8 *) (OemHeader + 1); + for (ByteCount = 0; ByteCount < OemHeader->HeaderSize - sizeof (EFI_CAPSULE_OEM_HEADER); ByteCount++) { + if ((ByteCount & 0x7) == 0) { + printf ("\n "); + } + + printf ("%02X ", (UINT32) *BPtr); + BPtr++; + } + + printf ("\n"); + } + // + // ************************************************************************ + // + // Author, revision, short description, and long description information + // + // ************************************************************************ + // + if (CapsuleHeader.OffsetToAuthorInformation != 0) { + if (DumpCapsuleHeaderStrings ( + "Author information", + (WCHAR *) (CapsuleHeaderData + CapsuleHeader.OffsetToAuthorInformation - CapsuleHeader.HeaderSize) + ) != STATUS_SUCCESS) { + goto Done; + } + } + + if (CapsuleHeader.OffsetToRevisionInformation != 0) { + if (DumpCapsuleHeaderStrings ( + "Revision information", + (WCHAR *) (CapsuleHeaderData + CapsuleHeader.OffsetToRevisionInformation - CapsuleHeader.HeaderSize) + ) != STATUS_SUCCESS) { + goto Done; + } + } + + if (CapsuleHeader.OffsetToShortDescription != 0) { + if (DumpCapsuleHeaderStrings ( + "Short description", + (WCHAR *) (CapsuleHeaderData + CapsuleHeader.OffsetToShortDescription - CapsuleHeader.HeaderSize) + ) != STATUS_SUCCESS) { + goto Done; + } + } + + if (CapsuleHeader.OffsetToLongDescription != 0) { + if (DumpCapsuleHeaderStrings ( + "Long description", + (WCHAR *) (CapsuleHeaderData + CapsuleHeader.OffsetToLongDescription - CapsuleHeader.HeaderSize) + ) != STATUS_SUCCESS) { + goto Done; + } + } + } + // + // If it's not a split image, or it is a split image and this is the first in the series, then + // dump the cargo volume. + // + if ((!SplitImage) || (CapsuleHeader.SequenceNumber == 0)) { + printf (" Cargo FV dump\n"); + fseek (InFptr, CapsuleHeader.OffsetToCapsuleBody, SEEK_SET); + if (fread (&FVHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER), 1, InFptr) != 1) { + Error (NULL, 0, 0, FileList->FileName, "failed to read cargo FV header"); + goto Done; + } + + printf (" FV length 0x%X", FVHeader.FvLength); + if (FileSize - CapsuleHeader.OffsetToCapsuleBody != FVHeader.FvLength) { + if (!SplitImage) { + printf (" ERROR: expected 0x%X to jive with file size on disk", FileSize - CapsuleHeader.OffsetToCapsuleBody); + } + } + + printf ("\n"); + printf (" Signature 0x%X ", FVHeader.Signature); + if (FVHeader.Signature == EFI_FVH_SIGNATURE) { + printf ("_FVH\n"); + } else { + printf ("INVALID\n"); + } + + printf (" FV header length 0x%X\n", (UINT32) FVHeader.HeaderLength); + printf (" Revision 0x%X\n", (UINT32) FVHeader.Revision); + printf ("\n"); + } + + FileList = FileList->Next; + } + +Done: + if (InFptr != NULL) { + fclose (InFptr); + } + + if (CapsuleHeaderData != NULL) { + free (CapsuleHeaderData); + } +#endif +} + +static +STATUS +JoinCapsule ( + VOID + ) +/*++ + +Routine Description: + Join split capsule images into a single image. This is the + support function for the -j command-line option. + +Arguments: + None. + +Returns: + STATUS_SUCCESS - no problems encountered + +--*/ +{ +#if 0 + UINT32 Size; + FILE *InFptr; + FILE *OutFptr; + INT8 *Buffer; + FILE_LIST *FileList; + STATUS Status; + EFI_CAPSULE_HEADER CapHdr; + EFI_CAPSULE_HEADER *CapHdrPtr; + UINT32 SizeLeft; + UINT32 SequenceNumber; + // + // Must have at least two files for join mode + // + if ((mOptions.FileList == NULL) || (mOptions.FileList->Next == NULL)) { + Error (NULL, 0, 0, "must specify at least two file names to join", NULL); + return STATUS_ERROR; + } + // + // Open the output file + // + if ((OutFptr = fopen (mOptions.OutputFileName, "wb")) == NULL) { + Error (NULL, 0, 0, mOptions.OutputFileName, "failed to open output file for writing"); + return STATUS_ERROR; + } + + FileList = mOptions.FileList; + Buffer = NULL; + SequenceNumber = 0; + InFptr = NULL; + SizeLeft = 0; + while (FileList != NULL) { + if ((InFptr = fopen (FileList->FileName, "rb")) == NULL) { + Error (NULL, 0, 0, FileList->FileName, "failed to open file for reading"); + goto FailDone; + } + // + // Allocate a buffer into which we can read the file. + // + fseek (InFptr, 0, SEEK_END); + Size = ftell (InFptr); + rewind (InFptr); + Buffer = (char *) malloc (Size); + if (Buffer == NULL) { + Error (__FILE__, __LINE__, 0, FileList->FileName, "failed to allocate buffer to read file into"); + goto FailDone; + } + + CapHdrPtr = (EFI_CAPSULE_HEADER *) Buffer; + if (fread ((void *) Buffer, Size, 1, InFptr) != 1) { + Error (NULL, 0, 0, FileList->FileName, "failed to read file contents"); + goto FailDone; + } + // + // Check the header for validity. Check size first. + // + if (Size < sizeof (EFI_CAPSULE_HEADER)) { + Error (NULL, 0, 0, FileList->FileName, "file size is insufficient for a capsule header"); + goto FailDone; + } + // + // Check GUID + // + if (memcmp (&CapHdrPtr->CapsuleGuid, &mEfiCapsuleHeaderGuid, sizeof (EFI_GUID)) != 0) { + Error (NULL, 0, 0, FileList->FileName, "invalid capsule GUID"); + goto FailDone; + } + // + // Check sequence number + // + if (CapHdrPtr->SequenceNumber != SequenceNumber) { + Error ( + NULL, + 0, + 0, + FileList->FileName, + "invalid sequence number %d (expected %d)", + CapHdrPtr->SequenceNumber, + SequenceNumber + ); + goto FailDone; + } + // + // If the first file, read save the capsule header + // + if (SequenceNumber == 0) { + memcpy (&CapHdr, CapHdrPtr, sizeof (EFI_CAPSULE_HEADER)); + // + // Erase the InstanceId GUID + // + memset (&CapHdrPtr->InstanceId, 0, sizeof (EFI_GUID)); + if (fwrite (Buffer, Size, 1, OutFptr) != 1) { + Error (NULL, 0, 0, FileList->FileName, "failed to write contents to output file"); + goto FailDone; + } + + if (CapHdr.CapsuleImageSize < Size) { + Error (NULL, 0, 0, FileList->FileName, "capsule image size in capsule header < image size"); + goto FailDone; + } + + SizeLeft = CapHdr.CapsuleImageSize - Size; + } else { + // + // Check the GUID against the first file's GUID + // + if (memcmp (&CapHdr.CapsuleGuid, &CapHdrPtr->CapsuleGuid, sizeof (EFI_GUID)) != 0) { + Error (NULL, 0, 0, FileList->FileName, "GUID does not match first file's GUID"); + goto FailDone; + } + // + // Make sure we're not throwing out any header info + // + if (CapHdrPtr->OffsetToCapsuleBody > sizeof (EFI_CAPSULE_HEADER)) { + // + // Could be the split information, so just emit a warning + // + Warning ( + NULL, + 0, + 0, + FileList->FileName, + "image appears to have additional capsule header information -- ignoring" + ); + } else if (CapHdrPtr->OffsetToCapsuleBody < sizeof (EFI_CAPSULE_HEADER)) { + Error (NULL, 0, 0, FileList->FileName, "offset to capsule body in capsule header is insufficient"); + goto FailDone; + } + + if (fwrite (Buffer + CapHdrPtr->OffsetToCapsuleBody, Size - CapHdrPtr->OffsetToCapsuleBody, 1, OutFptr) != 1) { + Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file"); + goto FailDone; + } + + if (SizeLeft < (Size - CapHdrPtr->OffsetToCapsuleBody)) { + Error (NULL, 0, 0, "sum of image sizes exceeds size specified in initial capsule header", NULL); + goto FailDone; + } + // + // printf ("FILE: %s OffsetToCapsuleBody=0x%X\n", FileList->FileName, CapHdrPtr->OffsetToCapsuleBody); + // + SizeLeft = SizeLeft - (Size - CapHdrPtr->OffsetToCapsuleBody); + } + // + // printf ("FILE: %s sizeleft=0x%X\n", FileList->FileName, SizeLeft); + // + fclose (InFptr); + InFptr = NULL; + free (Buffer); + Buffer = NULL; + FileList = FileList->Next; + SequenceNumber++; + } + + if (SizeLeft) { + Error (NULL, 0, 0, "sum of capsule images is insufficient", "0x%X bytes missing", SizeLeft); + goto FailDone; + } + + Status = STATUS_SUCCESS; + goto Done; +FailDone: + Status = STATUS_ERROR; +Done: + if (InFptr != NULL) { + fclose (InFptr); + } + + if (OutFptr != NULL) { + fclose (OutFptr); + } + + if (Buffer != NULL) { + free (Buffer); + } + + return Status; + +#endif +return STATUS_SUCCESS; +} + +static +STATUS +DumpCapsuleHeaderStrings ( + UINT8 *SectionName, + WCHAR *Buffer + ) +/*++ + +Routine Description: + Given a pointer to string data from a capsule header, dump + the strings. + +Arguments: + SectionName - name of the capsule header section to which + the string data pertains + Buffer - pointer to string data from a capsule header + +Returns: + STATUS_SUCCESS - all went well + +--*/ +{ + printf (" %s\n", SectionName); + while (*Buffer) { + printf (" Language: %S\n", Buffer); + while (*Buffer) { + Buffer++; + } + + Buffer++; + while (*Buffer) { + if (wcslen (Buffer) > 60) { + printf (" %.60S\n", Buffer); + Buffer += 60; + } else { + printf (" %S\n", Buffer); + Buffer += wcslen (Buffer); + } + } + + Buffer++; + } + + return STATUS_SUCCESS; +} + +static +STATUS +GetHexValue ( + SOURCE_FILE *SourceFile, + UINT32 *Value, + UINT32 NumDigits + ) +/*++ + +Routine Description: + Scan a hex value from the input stream. + +Arguments: + SourceFile - input file contents + Value - returned value + NumDigits - number of digits to read + +Returns: + STATUS_SUCCESS - if NumDigits were read from the file + STATUS_ERROR - otherwise + + +--*/ +{ + WCHAR *SaveFilePos; + UINT32 Digits; + WCHAR Nibble; + + SaveFilePos = SourceFile->FileBufferPtr; + *Value = 0; + Digits = NumDigits; + while (Digits > 0) { + Nibble = SourceFile->FileBufferPtr[0]; + if ((Nibble >= UNICODE_0) && (Nibble <= UNICODE_9)) { + *Value = (*Value << 4) | (Nibble - UNICODE_0); + } else if ((Nibble >= UNICODE_A) && (Nibble <= UNICODE_F)) { + *Value = (*Value << 4) | (Nibble - UNICODE_A + 0x10); + } else if ((Nibble >= UNICODE_a) && (Nibble <= UNICODE_f)) { + *Value = (*Value << 4) | (Nibble - UNICODE_a + 0x10); + } else { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + NULL, + "expected %d valid hex nibbles at %.20S", + NumDigits, + SaveFilePos + ); + return STATUS_ERROR; + } + + SourceFile->FileBufferPtr++; + Digits--; + } + + return STATUS_SUCCESS; +} + +static +BOOLEAN +EndOfFile ( + SOURCE_FILE *File + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + File - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + if ((UINT32) File->FileBufferPtr - (UINT32) File->FileBuffer >= File->FileSize) { + File->EndOfFile = TRUE; + } + // + // Reposition to the end of the file if we went beyond + // + if (File->EndOfFile) { + File->FileBufferPtr = File->FileBuffer + File->FileSize / sizeof (WCHAR); + } + + return File->EndOfFile; +} + +static +void +SkipWhiteSpace ( + SOURCE_FILE *SourceFile + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + SourceFile - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + while (!EndOfFile (SourceFile)) { + switch (*SourceFile->FileBufferPtr) { + case UNICODE_NULL: + case UNICODE_CR: + case UNICODE_SPACE: + case UNICODE_TAB: + SourceFile->FileBufferPtr++; + break; + + case UNICODE_LF: + SourceFile->FileBufferPtr++; + SourceFile->LineNum++; + break; + + default: + return ; + } + } +} +// +// Parse a number. Possible format: +// 1234 +// 1234k +// 1234K +// 1M +// 1m +// 0x100 +// +static +BOOLEAN +GetNumber ( + INT8 *Str, + UINT32 *Value + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + Str - GC_TODO: add argument description + Value - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + UINT32 LValue; + + *Value = 0; + LValue = 0; + if (!isdigit (Str[0])) { + return FALSE; + } + // + // Look for hex number + // + if ((Str[0] == '0') && (tolower (Str[1]) == 'x')) { + Str += 2; + if (Str[0] == 0) { + return FALSE; + } + + while (Str[0]) { + if ((Str[0] >= '0') && (Str[0] <= '9')) { + LValue = (LValue << 4) | (Str[0] - '0'); + } else if ((Str[0] >= 'A') && (Str[0] <= 'F')) { + LValue = (LValue << 4) | (Str[0] - 'A' + 0x10); + } else if ((Str[0] >= 'a') && (Str[0] <= 'f')) { + LValue = (LValue << 4) | (Str[0] - 'a' + 0x10); + } else { + break; + } + + Str++; + } + } else { + LValue = atoi (Str); + while (isdigit (*Str)) { + Str++; + } + } + // + // If string left over, better be one character we recognize + // + if (Str[0]) { + if (Str[1]) { + return FALSE; + } + + switch (Str[0]) { + case 'k': + case 'K': + LValue *= 1024; + break; + + case 'm': + case 'M': + LValue *= 1024 * 1024; + break; + + default: + return FALSE; + } + } + + *Value = LValue; + return TRUE; +} +// +// Process the command-line arguments +// +static +STATUS +ProcessArgs ( + int Argc, + char *Argv[] + ) +/*++ + +Routine Description: + + Processes command line arguments. + +Arguments: + + Argc - Number of command line arguments + Argv[] - Array of files input on command line + +Returns: + + STATUS_ERROR - Function exited with an error + STATUS_SUCCESS - Function executed successfully + +--*/ +{ + FILE_LIST *NewFile; + + FILE_LIST *LastFile; + SIZE_LIST *NewSize; + + NewFile = NULL; + NewSize = NULL; + + // + // Clear our globals + // + memset ((char *) &mOptions, 0, sizeof (mOptions)); + + // + // Skip program name + // + Argc--; + Argv++; + + if (Argc == 0) { + Usage (); + return STATUS_ERROR; + } + // + // Process until no more options + // + while ((Argc > 0) && (Argv[0][0] == '-')) { + if (stricmp (Argv[0], "-script") == 0) { + // + // Check for one more arg + // + if (Argc > 1) { + // + // Save the file name + // + if (strlen (Argv[1]) >= sizeof (mOptions.ScriptFileName)) { + Error (NULL, 0, 0, NULL, "input script file name length exceeds internal buffer size"); + + if (NewFile != NULL) { + free (NewFile); + } + if (NewSize != NULL) { + free (NewSize); + } + + return STATUS_ERROR; + } + + strcpy (mOptions.ScriptFileName, Argv[1]); + } else { + Error (NULL, 0, 0, Argv[0], "missing script file name with option"); + Usage (); + + if (NewFile != NULL) { + free (NewFile); + } + if (NewSize != NULL) { + free (NewSize); + } + + return STATUS_ERROR; + } + + Argc--; + Argv++; + // + // -o outfilename -- specify output file name (required) + // + } else if (stricmp (Argv[0], "-o") == 0) { + // + // check for one more arg + // + if (Argc > 1) { + // + // Try to open the file + // + // if ((mOptions.OutFptr = fopen (Argv[1], "wb")) == NULL) { + // Error (NULL, 0, 0, Argv[1], "failed to open output file for writing"); + // return STATUS_ERROR; + // } + // + strcpy (mOptions.OutputFileName, Argv[1]); + } else { + Error (NULL, 0, 0, Argv[0], "missing output filename with option"); + Usage (); + + if (NewFile != NULL) { + free (NewFile); + } + if (NewSize != NULL) { + free (NewSize); + } + + return STATUS_ERROR; + } + + Argc--; + Argv++; + } else if (stricmp (Argv[0], "-j") == 0) { + mOptions.JoinMode = TRUE; + // + // -split option (multiple allowed) + // + } else if (stricmp (Argv[0], "-split") == 0) { + if (Argc > 1) { + NewSize = (SIZE_LIST *) malloc (sizeof (SIZE_LIST)); + if (NewSize == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + + if (NewFile != NULL) { + free (NewFile); + } + if (NewSize != NULL) { + free (NewSize); + } + + return STATUS_ERROR; + } + + memset (NewSize, 0, sizeof (SIZE_LIST)); + // + // Get the size from the next arg, and then add this size + // to our size list + // + if (!GetNumber (Argv[1], &NewSize->Size)) { + Error (NULL, 0, 0, Argv[1], "invalid split size argument"); + + if (NewFile != NULL) { + free (NewFile); + } + if (NewSize != NULL) { + free (NewSize); + } + + return STATUS_ERROR; + } + + if (mOptions.SizeList == NULL) { + mOptions.SizeList = NewSize; + mOptions.CurrentSize = NewSize; + } else { + mOptions.LastSize->Next = NewSize; + } + + mOptions.LastSize = NewSize; + free (NewSize); + } else { + Error (NULL, 0, 0, Argv[0], "missing size parameter with option"); + Usage (); + + if (NewFile != NULL) { + free (NewFile); + } + if (NewSize != NULL) { + free (NewSize); + } + + return STATUS_ERROR; + } + + Argc--; + Argv++; + } else if ((stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) { + Usage (); + + if (NewFile != NULL) { + free (NewFile); + } + if (NewSize != NULL) { + free (NewSize); + } + + return STATUS_ERROR; + // + // Default minimum header + // + } else if (stricmp (Argv[0], "-dump") == 0) { + mOptions.Dump = TRUE; + } else if (stricmp (Argv[0], "-v") == 0) { + mOptions.Verbose = TRUE; + } else { + Error (NULL, 0, 0, Argv[0], "unrecognized option"); + Usage (); + + if (NewFile != NULL) { + free (NewFile); + } + if (NewSize != NULL) { + free (NewSize); + } + + return STATUS_ERROR; + } + + Argc--; + Argv++; + } + // + // Can't -j join files and -s split output capsule + // + if ((mOptions.SizeList != NULL) && (mOptions.JoinMode)) { + Error (NULL, 0, 0, "cannot specify both -j and -size", NULL); + + if (NewFile != NULL) { + free (NewFile); + } + if (NewSize != NULL) { + free (NewSize); + } + + return STATUS_ERROR; + } + // + // Must have specified an output file name if not -dump + // + if ((mOptions.Dump == 0) && (mOptions.OutputFileName[0] == 0)) { + Error (NULL, 0, 0, NULL, "-o OutputFileName must be specified"); + Usage (); + + if (NewFile != NULL) { + free (NewFile); + } + if (NewSize != NULL) { + free (NewSize); + } + + return STATUS_ERROR; + } + // + // Rest of arguments are input files. The first one is a firmware + // volume image, and the rest are FFS files that are to be inserted + // into the firmware volume. + // + LastFile = NULL; + while (Argc > 0) { + NewFile = (FILE_LIST *) malloc (sizeof (FILE_LIST)); + if (NewFile == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + + if (NewFile != NULL) { + free (NewFile); + } + if (NewSize != NULL) { + free (NewSize); + } + + return STATUS_ERROR; + } + + memset ((char *) NewFile, 0, sizeof (FILE_LIST)); + strcpy (NewFile->FileName, Argv[0]); + if (mOptions.FileList == NULL) { + mOptions.FileList = NewFile; + } else { + if (LastFile == NULL) { + LastFile = NewFile; + } else { + LastFile->Next = NewFile; + } + } + + LastFile = NewFile; + Argc--; + Argv++; + } + + // + // Must have provided at least one file name + // + if (mOptions.FileList == NULL) { + Error (NULL, 0, 0, "must specify at least one file name", NULL); + Usage (); + + if (NewFile != NULL) { + free (NewFile); + } + if (NewSize != NULL) { + free (NewSize); + } + + return STATUS_ERROR; + } + + return STATUS_SUCCESS; +} + +static +void +Usage ( + VOID + ) +/*++ + +Routine Description: + + Print usage information for this utility. + +Arguments: + + None. + +Returns: + + Nothing. + +--*/ +{ + int Index; + static const char *Str[] = { + PROGRAM_NAME " -- create a capsule header", + " Usage: "PROGRAM_NAME " {options} [CapsuleFV]", + // + // {FfsFileNames}", + // + " Options include:", + " -h or -? for this help information", + " -script fname to take capsule header info from unicode script", + " file fname", + " -o fname write output to file fname (required)", + " -split size split capsule image into multiple output files", + " -dump to dump a capsule header", + " -v for verbose output\n", + " -j to join split capsule images into a single image", + "", + " CapsuleFV is the name of an existing well-formed Tiano firmware", + " volume file.", + // + // FfsFileNames are the names of one or more Tiano FFS files to", + // " insert into the output capsule image.", + // + NULL + }; + for (Index = 0; Str[Index] != NULL; Index++) { + fprintf (stdout, "%s\n", Str[Index]); + } +} diff --git a/Tools/CodeTools/Source/GenCapsuleHdr/build.xml b/Tools/CodeTools/Source/GenCapsuleHdr/build.xml new file mode 100644 index 0000000000..7c43d0a347 --- /dev/null +++ b/Tools/CodeTools/Source/GenCapsuleHdr/build.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/GenDepex/DepexParser.c b/Tools/CodeTools/Source/GenDepex/DepexParser.c new file mode 100644 index 0000000000..9f0a0cbbab --- /dev/null +++ b/Tools/CodeTools/Source/GenDepex/DepexParser.c @@ -0,0 +1,903 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + DepexParser.c + +Abstract: + + Validate Dependency Expression syntax + recursive descent Algorithm + + The original BNF grammar(taken from "Pre EFI Initialization Core Interface Specification + draft review 0.9") is thus: + ::= BEFORE END + | AFTER END + | SOR END + | END + ::= AND + | OR + | + ::= NOT + | + ::= + | TRUE + | FALSE + | GUID + + ::= '{' ',' ',' ',' + ',' ',' ',' ',' + ',' ',' ',' '}' + ::= + ::= + ::= + ::= '0' 'x' + | '0' 'X' + ::= + | + ::= [0-9] + | [a-f] + | [A-F] + + After cleaning left recursive and parentheses supported, the BNF grammar used in this module is thus: + ::= BEFORE + | AFTER + | SOR + | + ::= + ::= AND + | OR + | '' + ::= NOT + | + ::= '('')' + | NOT + | TRUE + | FALSE + | END + | + ::=AND + | OR + | '' + ::= '{' ',' ',' ',' + ',' ',' ',' ',' + ',' ',' ',' '}' + ::= + ::= + ::= + ::= '0' 'x' + | '0' 'X' + ::= + | + ::= [0-9] + | [a-f] + | [A-F] + + Note: 1. There's no precedence in operators except parentheses; + 2. For hex32, less and equal than 8 bits is valid, more than 8 bits is invalid. + Same constraint for hex16 is 4, hex8 is 2. All hex should contains at least 1 bit. + 3. " ::= '('')'" is added to support parentheses; + 4. " ::= GUID" is changed to " ::= "; + 5. "DEPENDENCY_END" is the terminal of the expression. But it has been filtered by caller. + During parsing, "DEPENDENCY_END" will be treated as illegal factor; + + This code should build in any environment that supports a standard C-library w/ string + operations and File I/O services. + + As an example of usage, consider the following: + + The input string could be something like: + + NOT ({ 0xce345171, 0xba0b, 0x11d2, 0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72, + 0x3b } AND { 0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, + 0x72, 0x3b }) OR { 0x03c4e603, 0xac28, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27, + 0x3f, 0xc1, 0x4d } AND + + It's invalid for an extra "AND" in the end. + + Complies with Tiano C Coding Standards Document, version 0.33, 16 Aug 2001. + +--*/ + +#include "DepexParser.h" + +BOOLEAN +ParseBool ( + IN INT8 *Pbegin, + IN UINT32 length, + IN OUT INT8 **Pindex + ); + +BOOLEAN +ParseTerm ( + IN INT8 *Pbegin, + IN UINT32 length, + IN OUT INT8 **Pindex + ); + +BOOLEAN +ParseRightBool ( + IN INT8 *Pbegin, + IN UINT32 length, + IN OUT INT8 **Pindex + ); + +BOOLEAN +ParseFactor ( + IN INT8 *Pbegin, + IN UINT32 length, + IN OUT INT8 **Pindex + ); + +VOID +LeftTrim ( + IN INT8 *Pbegin, + IN UINT32 length, + IN OUT INT8 **Pindex + ) +/*++ + +Routine Description: + + Left trim the space, '\n' and '\r' character in string. + The space at the end does not need trim. + + +Arguments: + + Pbegin The pointer to the string + length length of the string + Pindex The pointer of pointer to the next parse character in the string + +Returns: + + None + + +--*/ +{ + while + ( + ((*Pindex) < (Pbegin + length)) && + ((strncmp (*Pindex, " ", 1) == 0) || (strncmp (*Pindex, "\n", 1) == 0) || (strncmp (*Pindex, "\r", 1) == 0)) + ) { + (*Pindex)++; + } +} + +BOOLEAN +ParseHexdigit ( + IN INT8 *Pbegin, + IN UINT32 length, + IN OUT INT8 **Pindex + ) +/*++ + +Routine Description: + + Parse Hex bit in dependency expression. + +Arguments: + + Pbegin The pointer to the string + length Length of the string + Pindex The pointer of pointer to the next parse character in the string + +Returns: + + BOOLEAN If parses a valid hex bit, return TRUE, otherwise FALSE + + +--*/ +{ + // + // ::= [0-9] | [a-f] | [A-F] + // + if (((**Pindex) >= '0' && (**Pindex) <= '9') || + ((**Pindex) >= 'a' && (**Pindex) <= 'f') || + ((**Pindex) >= 'A' && (**Pindex) <= 'F') + ) { + (*Pindex)++; + return TRUE; + } else { + return FALSE; + } +} + +BOOLEAN +ParseHex32 ( + IN INT8 *Pbegin, + IN UINT32 length, + IN OUT INT8 **Pindex + ) +/*++ + +Routine Description: + + Parse Hex32 in dependency expression. + +Arguments: + + Pbegin The pointer to the string + length Length of the string + Pindex The pointer of point to the next parse character in the string + +Returns: + + BOOLEAN If parses a valid hex32, return TRUE, otherwise FALSE + + +--*/ +{ + INT32 Index; + INT8 *Pin; + + Index = 0; + Pin = *Pindex; + LeftTrim (Pbegin, length, Pindex); + + if ((strncmp (*Pindex, "0x", 2) != 0) && (strncmp (*Pindex, "0X", 2) != 0)) { + return FALSE; + } + (*Pindex) += 2; + + while (ParseHexdigit (Pbegin, length, Pindex)) { + Index++; + } + + if (Index > 0 && Index <= 8) { + return TRUE; + } else { + *Pindex = Pin; + return FALSE; + } +} + +BOOLEAN +ParseHex16 ( + IN INT8 *Pbegin, + IN UINT32 length, + IN OUT INT8 **Pindex + ) +/*++ + +Routine Description: + + Parse Hex16 in dependency expression. + +Arguments: + + Pbegin The pointer to the string + length Length of the string + Pindex The pointer of pointer to the next parse character in the string + +Returns: + + BOOLEAN If parses a valid hex16, return TRUE, otherwise FALSE + + +--*/ +{ + int Index; + INT8 *Pin; + + Index = 0; + Pin = *Pindex; + LeftTrim (Pbegin, length, Pindex); + + if ((strncmp (*Pindex, "0x", 2) != 0) && (strncmp (*Pindex, "0X", 2) != 0)) { + return FALSE; + } + (*Pindex) += 2; + + while (ParseHexdigit (Pbegin, length, Pindex)) { + Index++; + } + + if (Index > 0 && Index <= 4) { + return TRUE; + } else { + *Pindex = Pin; + return FALSE; + } +} + +BOOLEAN +ParseHex8 ( + IN INT8 *Pbegin, + IN UINT32 length, + IN OUT INT8 **Pindex + ) +/*++ + +Routine Description: + + Parse Hex8 in dependency expression. + +Arguments: + + Pbegin The pointer to the string + length Length of the string + Pindex The pointer of pointer to the next parse character in the string + +Returns: + + BOOLEAN If parses a valid hex8, return TRUE, otherwise FALSE + + +--*/ +{ + int Index; + INT8 *Pin; + + Index = 0; + Pin = *Pindex; + LeftTrim (Pbegin, length, Pindex); + + if ((strncmp (*Pindex, "0x", 2) != 0) && (strncmp (*Pindex, "0X", 2) != 0)) { + return FALSE; + } + (*Pindex) += 2; + + while (ParseHexdigit (Pbegin, length, Pindex)) { + Index++; + } + + if (Index > 0 && Index <= 2) { + return TRUE; + } else { + *Pindex = Pin; + return FALSE; + } +} + +BOOLEAN +ParseGuid ( + IN INT8 *Pbegin, + IN UINT32 length, + IN OUT INT8 **Pindex + ) +/*++ + +Routine Description: + + Parse guid in dependency expression. + There can be any number of spaces between '{' and hexword, ',' and hexword, + hexword and ',', hexword and '}'. The hexword include hex32, hex16 and hex8. + +Arguments: + + Pbegin The pointer to the string + length length of the string + Pindex The pointer of pointer to the next parse character in the string + +Returns: + + BOOLEAN If parses a valid guid, return TRUE, otherwise FALSE + + +--*/ +{ + INT32 Index; + INT8 *Pin; + Pin = *Pindex; + LeftTrim (Pbegin, length, Pindex); + if (strncmp (*Pindex, "{", 1) != 0) { + return FALSE; + } + (*Pindex)++; + + LeftTrim (Pbegin, length, Pindex); + if (!ParseHex32 (Pbegin, length, Pindex)) { + *Pindex = Pin; + return FALSE; + } + + LeftTrim (Pbegin, length, Pindex); + if (strncmp (*Pindex, ",", 1) != 0) { + return FALSE; + } else { + (*Pindex)++; + } + + for (Index = 0; Index < 2; Index++) { + LeftTrim (Pbegin, length, Pindex); + if (!ParseHex16 (Pbegin, length, Pindex)) { + *Pindex = Pin; + return FALSE; + } + + LeftTrim (Pbegin, length, Pindex); + if (strncmp (*Pindex, ",", 1) != 0) { + return FALSE; + } else { + (*Pindex)++; + } + } + + LeftTrim (Pbegin, length, Pindex); + if (strncmp (*Pindex, "{", 1) != 0) { + return FALSE; + } + (*Pindex)++; + + for (Index = 0; Index < 7; Index++) { + LeftTrim (Pbegin, length, Pindex); + if (!ParseHex8 (Pbegin, length, Pindex)) { + *Pindex = Pin; + return FALSE; + } + + LeftTrim (Pbegin, length, Pindex); + if (strncmp (*Pindex, ",", 1) != 0) { + return FALSE; + } else { + (*Pindex)++; + } + } + + LeftTrim (Pbegin, length, Pindex); + if (!ParseHex8 (Pbegin, length, Pindex)) { + *Pindex = Pin; + return FALSE; + } + + LeftTrim (Pbegin, length, Pindex); + if (strncmp (*Pindex, "}", 1) != 0) { + return FALSE; + } else { + (*Pindex)++; + } + + LeftTrim (Pbegin, length, Pindex); + if (strncmp (*Pindex, "}", 1) != 0) { + return FALSE; + } else { + (*Pindex)++; + } + + return TRUE; +} + +BOOLEAN +ParseRightFactor ( + IN INT8 *Pbegin, + IN UINT32 length, + IN OUT INT8 **Pindex + ) +/*++ + +Routine Description: + + Parse rightfactor in bool expression. + +Arguments: + + Pbegin The pointer to the string + length length of the string + Pindex The pointer of pointer to the next parse character in the string + +Returns: + + BOOLEAN If string is a valid rightfactor expression, return TRUE, otherwise FALSE + + +--*/ +{ + INT8 *Pin; + + Pin = *Pindex; + LeftTrim (Pbegin, length, Pindex); + + // + // ::=AND + // + if (strncmp (*Pindex, OPERATOR_AND, strlen (OPERATOR_AND)) == 0) { + *Pindex += strlen (OPERATOR_AND); + LeftTrim (Pbegin, length, Pindex); + + if (ParseTerm (Pbegin, length, Pindex)) { + LeftTrim (Pbegin, length, Pindex); + + if (ParseRightBool (Pbegin, length, Pindex)) { + LeftTrim (Pbegin, length, Pindex); + if (ParseRightFactor (Pbegin, length, Pindex)) { + return TRUE; + } else { + *Pindex = Pin; + } + } else { + *Pindex = Pin; + } + } else { + *Pindex = Pin; + } + } + // + // ::=OR + // + if (strncmp (*Pindex, OPERATOR_OR, strlen (OPERATOR_OR)) == 0) { + *Pindex += strlen (OPERATOR_OR); + LeftTrim (Pbegin, length, Pindex); + + if (ParseTerm (Pbegin, length, Pindex)) { + LeftTrim (Pbegin, length, Pindex); + + if (ParseRightBool (Pbegin, length, Pindex)) { + LeftTrim (Pbegin, length, Pindex); + if (ParseRightFactor (Pbegin, length, Pindex)) { + return TRUE; + } else { + *Pindex = Pin; + } + } else { + *Pindex = Pin; + } + } else { + *Pindex = Pin; + } + } + // + // ::= '' + // + *Pindex = Pin; + return TRUE; +} + +BOOLEAN +ParseRightBool ( + IN INT8 *Pbegin, + IN UINT32 length, + IN OUT INT8 **Pindex + ) +/*++ + +Routine Description: + + Parse rightbool in bool expression. + +Arguments: + + Pbegin The pointer to the string + length length of the string + Pindex The pointer of pointer to the next parse character in the string + +Returns: + + BOOLEAN If string is a valid rightbool expression, return TRUE, otherwise FALSE + + +--*/ +{ + INT8 *Pin; + + Pin = *Pindex; + LeftTrim (Pbegin, length, Pindex); + + // + // ::= AND + // + if (strncmp (*Pindex, OPERATOR_AND, strlen (OPERATOR_AND)) == 0) { + *Pindex += strlen (OPERATOR_AND); + LeftTrim (Pbegin, length, Pindex); + + if (ParseTerm (Pbegin, length, Pindex)) { + LeftTrim (Pbegin, length, Pindex); + + if (ParseRightBool (Pbegin, length, Pindex)) { + return TRUE; + } else { + *Pindex = Pin; + } + } else { + *Pindex = Pin; + } + } + // + // ::= OR + // + if (strncmp (*Pindex, OPERATOR_OR, strlen (OPERATOR_OR)) == 0) { + *Pindex += strlen (OPERATOR_OR); + LeftTrim (Pbegin, length, Pindex); + + if (ParseTerm (Pbegin, length, Pindex)) { + LeftTrim (Pbegin, length, Pindex); + + if (ParseRightBool (Pbegin, length, Pindex)) { + return TRUE; + } else { + *Pindex = Pin; + } + } else { + *Pindex = Pin; + } + } + // + // ::= '' + // + *Pindex = Pin; + return TRUE; +} + +BOOLEAN +ParseFactor ( + IN INT8 *Pbegin, + IN UINT32 length, + IN OUT INT8 **Pindex + ) +/*++ + +Routine Description: + + Parse factor in bool expression. + +Arguments: + + Pbegin The pointer to the string + length length of the string + Pindex The pointer of pointer to the next parse character in the string + +Returns: + + BOOLEAN If string is a valid factor, return TRUE, otherwise FALSE + + +--*/ +{ + INT8 *Pin; + + Pin = *Pindex; + LeftTrim (Pbegin, length, Pindex); + + // + // ::= '('')' + // + if (strncmp (*Pindex, OPERATOR_LEFT_PARENTHESIS, strlen (OPERATOR_LEFT_PARENTHESIS)) == 0) { + *Pindex += strlen (OPERATOR_LEFT_PARENTHESIS); + LeftTrim (Pbegin, length, Pindex); + + if (!ParseBool (Pbegin, length, Pindex)) { + *Pindex = Pin; + } else { + LeftTrim (Pbegin, length, Pindex); + + if (strncmp (*Pindex, OPERATOR_RIGHT_PARENTHESIS, strlen (OPERATOR_RIGHT_PARENTHESIS)) == 0) { + *Pindex += strlen (OPERATOR_RIGHT_PARENTHESIS); + LeftTrim (Pbegin, length, Pindex); + + if (ParseRightFactor (Pbegin, length, Pindex)) { + return TRUE; + } else { + *Pindex = Pin; + } + } + } + } + // + // ::= NOT + // + if (strncmp (*Pindex, OPERATOR_NOT, strlen (OPERATOR_NOT)) == 0) { + *Pindex += strlen (OPERATOR_NOT); + LeftTrim (Pbegin, length, Pindex); + + if (ParseFactor (Pbegin, length, Pindex)) { + LeftTrim (Pbegin, length, Pindex); + + if (ParseRightBool (Pbegin, length, Pindex)) { + LeftTrim (Pbegin, length, Pindex); + + if (ParseRightFactor (Pbegin, length, Pindex)) { + return TRUE; + } else { + *Pindex = Pin; + } + } else { + *Pindex = Pin; + } + } else { + *Pindex = Pin; + } + } + // + // ::= TRUE + // + if (strncmp (*Pindex, OPERATOR_TRUE, strlen (OPERATOR_TRUE)) == 0) { + *Pindex += strlen (OPERATOR_TRUE); + LeftTrim (Pbegin, length, Pindex); + + if (ParseRightFactor (Pbegin, length, Pindex)) { + return TRUE; + } else { + *Pindex = Pin; + } + } + // + // ::= FALSE + // + if (strncmp (*Pindex, OPERATOR_FALSE, strlen (OPERATOR_FALSE)) == 0) { + *Pindex += strlen (OPERATOR_FALSE); + LeftTrim (Pbegin, length, Pindex); + + if (ParseRightFactor (Pbegin, length, Pindex)) { + return TRUE; + } else { + *Pindex = Pin; + } + } + // + // ::= + // + if (ParseGuid (Pbegin, length, Pindex)) { + LeftTrim (Pbegin, length, Pindex); + + if (ParseRightFactor (Pbegin, length, Pindex)) { + return TRUE; + } else { + *Pindex = Pin; + return FALSE; + } + } else { + *Pindex = Pin; + return FALSE; + } +} + +BOOLEAN +ParseTerm ( + IN INT8 *Pbegin, + IN UINT32 length, + IN OUT INT8 **Pindex + ) +/*++ + +Routine Description: + + Parse term in bool expression. + +Arguments: + + Pbegin The pointer to the string + length length of the string + Pindex The pointer of pointer to the next parse character in the string + +Returns: + + BOOLEAN If string is a valid term, return TRUE, otherwise FALSE + + +--*/ +{ + INT8 *Pin; + + Pin = *Pindex; + LeftTrim (Pbegin, length, Pindex); + + // + // ::= NOT + // + if (strncmp (*Pindex, OPERATOR_NOT, strlen (OPERATOR_NOT)) == 0) { + *Pindex += strlen (OPERATOR_NOT); + LeftTrim (Pbegin, length, Pindex); + + if (!ParseFactor (Pbegin, length, Pindex)) { + *Pindex = Pin; + } else { + return TRUE; + } + } + // + // ::= + // + if (ParseFactor (Pbegin, length, Pindex)) { + return TRUE; + } else { + *Pindex = Pin; + return FALSE; + } +} + +BOOLEAN +ParseBool ( + IN INT8 *Pbegin, + IN UINT32 length, + IN OUT INT8 **Pindex + ) +/*++ + +Routine Description: + + Parse bool expression. + +Arguments: + + Pbegin The pointer to the string + length length of the string + Pindex The pointer of pointer to the next parse character in the string + +Returns: + + BOOLEAN If string is a valid bool expression, return TRUE, otherwise FALSE + + +--*/ +{ + INT8 *Pin; + Pin = *Pindex; + LeftTrim (Pbegin, length, Pindex); + + if (ParseTerm (Pbegin, length, Pindex)) { + LeftTrim (Pbegin, length, Pindex); + + if (!ParseRightBool (Pbegin, length, Pindex)) { + *Pindex = Pin; + return FALSE; + } else { + return TRUE; + } + } else { + *Pindex = Pin; + return FALSE; + } +} + +BOOLEAN +ParseDepex ( + IN INT8 *Pbegin, + IN UINT32 length + ) +/*++ + +Routine Description: + + Parse whole dependency expression. + +Arguments: + + Pbegin The pointer to the string + length length of the string + +Returns: + + BOOLEAN If string is a valid dependency expression, return TRUE, otherwise FALSE + + +--*/ +{ + BOOLEAN Result; + INT8 **Pindex; + INT8 *temp; + + Result = FALSE; + temp = Pbegin; + Pindex = &temp; + + LeftTrim (Pbegin, length, Pindex); + if (strncmp (*Pindex, OPERATOR_BEFORE, strlen (OPERATOR_BEFORE)) == 0) { + (*Pindex) += strlen (OPERATOR_BEFORE); + Result = ParseGuid (Pbegin, length, Pindex); + + } else if (strncmp (*Pindex, OPERATOR_AFTER, strlen (OPERATOR_AFTER)) == 0) { + (*Pindex) += strlen (OPERATOR_AFTER); + Result = ParseGuid (Pbegin, length, Pindex); + + } else if (strncmp (*Pindex, OPERATOR_SOR, strlen (OPERATOR_SOR)) == 0) { + (*Pindex) += strlen (OPERATOR_SOR); + Result = ParseBool (Pbegin, length, Pindex); + + } else { + Result = ParseBool (Pbegin, length, Pindex); + + } + + LeftTrim (Pbegin, length, Pindex); + return (BOOLEAN) (Result && (*Pindex) >= (Pbegin + length)); +} diff --git a/Tools/CodeTools/Source/GenDepex/DepexParser.h b/Tools/CodeTools/Source/GenDepex/DepexParser.h new file mode 100644 index 0000000000..29e0884a3e --- /dev/null +++ b/Tools/CodeTools/Source/GenDepex/DepexParser.h @@ -0,0 +1,26 @@ +/*++ +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: + GenDepex.h + + Abstract: + This file contains the relevant declarations required + to generate a binary Dependency File + + Complies with Tiano C Coding Standards Document, version 0.31, 12 Dec 2000. + +--*/ + +// TODO: fix comment to set correct module name: DepexParser.h +#ifndef _EFI_DEPEX_PARSER_H_ +#define _EFI_DEPEX_PARSER_H_ +#include "GenDepex.h" +#endif diff --git a/Tools/CodeTools/Source/GenDepex/GenDepex.c b/Tools/CodeTools/Source/GenDepex/GenDepex.c new file mode 100644 index 0000000000..3818649330 --- /dev/null +++ b/Tools/CodeTools/Source/GenDepex/GenDepex.c @@ -0,0 +1,919 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + GenDepex.c + +Abstract: + + Generate Dependency Expression ("GenDepex") + + Infix to Postfix Algorithm + + This code has been scrubbed to be free of having any EFI core tree dependencies. + It should build in any environment that supports a standard C-library w/ string + operations and File I/O services. + + As an example of usage, consider the following: + + The input user file could be something like "Sample.DXS" whose contents are + + #include "Tiano.h" + + DEPENDENCY_START + NOT (DISK_IO_PROTOCOL AND SIMPLE_FILE_SYSTEM_PROTOCOL) + OR EFI_PXE_BASE_CODE_PROTOCOL + DEPENDENCY_END + + This file is then washed through the C-preprocessor, viz., + + cl /EP Sample.DXS > Sample.TMP1 + + This yields the following file "Sample.TMP1" whose contents are + + DEPENDENCY_START + NOT ({ 0xce345171, 0xba0b, 0x11d2, 0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72, + 0x3b } AND { 0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, + 0x72, 0x3b }) OR { 0x03c4e603, 0xac28, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27, + 0x3f, 0xc1, 0x4d } + DEPENDENCY_END + + This file, in turn, will be fed into the utility, viz., + + GenDepex Sample.TMP1 Sample.TMP2 + + With a file that is 55 bytes long: + + 55 bytes for the grammar binary + PUSH opcode - 1 byte + GUID Instance - 16 bytes + PUSH opcode - 1 byte + GUID Instance - 16 bytes + AND opcode - 1 byte + NOT opcode - 1 byte + PUSH opcode - 1 byte + GUID Instance - 16 bytes + OR opcode - 1 byte + END opcode - 1 byte + + The file "Sample.TMP2" could be fed via a Section-builder utility + (GenSection) that would be used for the creation of a dependency + section file (.DPX) which in turn would be used by a generate FFS + utility (GenFfsFile) to produce a DXE driver/core (.DXE) or + a DXE application (.APP) file. + + Complies with Tiano C Coding Standards Document, version 0.31, 12 Dec 2000. + +--*/ + +#include "GenDepex.h" + +#define TOOL_NAME "GenDepex" + +extern +ParseDepex ( + IN INT8 *Pbegin, + IN UINT32 length + ); + +VOID +PrintGenDepexUtilityInfo ( + VOID + ) +/*++ + +Routine Description: + + Displays the standard utility information to SDTOUT. + +Arguments: + + None + +Returns: + + None + +--*/ +{ + printf ( + "%s, Tiano Dependency Expression Generation Utility. Version %d.%d.\n", + UTILITY_NAME, + UTILITY_MAJOR_VERSION, + UTILITY_MINOR_VERSION + ); + printf ("Copyright (C) 1996-2002 Intel Corporation. All rights reserved.\n\n"); +} + +VOID +PrintGenDepexUsageInfo ( + VOID + ) +/*++ + +Routine Description: + + Displays the utility usage syntax to STDOUT. + +Arguments: + + None + +Returns: + + None + +--*/ +{ + printf ( + "Usage: %s -I -O [-P ] \n", + UTILITY_NAME + ); + printf (" Where:\n"); + printf (" is the input pre-processed dependency text files name.\n"); + printf (" is the output binary dependency files name.\n"); + printf (" is the padding integer value.\n"); + printf (" This is the boundary to align the output file size to.\n"); +} + +DEPENDENCY_OPCODE +PopOpCode ( + IN OUT VOID **Stack + ) +/*++ + +Routine Description: + + Pop an element from the Opcode stack. + +Arguments: + + Stack Current top of the OpCode stack location + +Returns: + + DEPENDENCY_OPCODE OpCode at the top of the OpCode stack. + Stack New top of the OpCode stack location + + +--*/ +{ + DEPENDENCY_OPCODE *OpCodePtr; + + OpCodePtr = *Stack; + OpCodePtr--; + *Stack = OpCodePtr; + return *OpCodePtr; +} + +VOID +PushOpCode ( + IN OUT VOID **Stack, + IN DEPENDENCY_OPCODE OpCode + ) +/*++ + +Routine Description: + + Push an element onto the Opcode Stack + +Arguments: + + Stack Current top of the OpCode stack location + OpCode OpCode to push onto the stack + +Returns: + + Stack New top of the OpCode stack location + +--*/ +{ + DEPENDENCY_OPCODE *OpCodePtr; + + OpCodePtr = *Stack; + *OpCodePtr = OpCode; + OpCodePtr++; + *Stack = OpCodePtr; +} + +EFI_STATUS +GenerateDependencyExpression ( + IN FILE *InFile, + IN OUT FILE *OutFile, + IN INT8 Padding OPTIONAL + ) +/*++ + +Routine Description: + + This takes the pre-compiled dependency text file and + converts it into a binary dependency file. + + The BNF for the dependency expression is as follows + (from the DXE 1.0 Draft specification). + + The inputted BNF grammar is thus: + ::= sor | + before GUID | + after GUID | + + + ::= | + + ::= and | + or | + + + ::= not | + + + ::= ( ) | + | + GUID | + + + ::= true | + false + + The outputed binary grammer is thus: + ::= sor | + before | + after | + + + ::= | + + ::= and | + or | + + ::= not | + + + ::= ( ) | + | + | + | + + + ::= true | + false + + ::= push GUID + + ::= end + + BugBug: A correct grammer is parsed correctly. A file that violates the + grammer may parse when it should generate an error. There is some + error checking and it covers most of the case when it's an include + of definition issue. An ill formed expresion may not be detected. + +Arguments: + + InFile - Input pre-compiled text file of the dependency expression. + This needs to be in ASCII. + The file pointer can not be NULL. + + OutFile - Binary dependency file. + The file pointer can not be NULL. + + Padding - OPTIONAL integer value to pad the output file to. + + +Returns: + + EFI_SUCCESS The function completed successfully. + EFI_INVALID_PARAMETER One of the parameters in the text file was invalid. + EFI_OUT_OF_RESOURCES Unable to allocate memory. + EFI_ABORTED An misc error occurred. + +--*/ +{ + INT8 *Ptrx; + INT8 *Pend; + INT8 *EvaluationStack; + INT8 *StackPtr; + INT8 *Buffer; + INT8 Line[LINESIZE]; + UINTN Index; + UINTN OutFileSize; + UINTN FileSize; + UINTN Results; + BOOLEAN NotDone; + BOOLEAN Before_Flag; + BOOLEAN After_Flag; + BOOLEAN Dep_Flag; + BOOLEAN SOR_Flag; + EFI_GUID Guid; + UINTN ArgCountParsed; + DEPENDENCY_OPCODE Opcode; + + Before_Flag = FALSE; + After_Flag = FALSE; + Dep_Flag = FALSE; + SOR_Flag = FALSE; + + memset (Line, 0, LINESIZE); + + OutFileSize = 0; + + EvaluationStack = (INT8 *) malloc (EVAL_STACK_SIZE); + + if (EvaluationStack != NULL) { + StackPtr = EvaluationStack; + } else { + printf ("Unable to allocate memory to EvaluationStack - Out of resources\n"); + return EFI_OUT_OF_RESOURCES; + } + + Results = (UINTN) fseek (InFile, 0, SEEK_END); + + if (Results != 0) { + printf ("FSEEK failed - Aborted\n"); + return EFI_ABORTED; + } + + FileSize = ftell (InFile); + + if (FileSize == -1L) { + printf ("FTELL failed - Aborted\n"); + return EFI_ABORTED; + } + + Buffer = (INT8 *) malloc (FileSize + BUFFER_SIZE); + + if (Buffer == NULL) { + printf ("Unable to allocate memory to Buffer - Out of resources\n"); + free (EvaluationStack); + + Results = (UINTN) fclose (InFile); + if (Results != 0) { + printf ("FCLOSE failed\n"); + } + + Results = (UINTN) fclose (OutFile); + if (Results != 0) { + printf ("FCLOSE failed\n"); + } + + return EFI_OUT_OF_RESOURCES; + } + + Results = (UINTN) fseek (InFile, 0, SEEK_SET); + + if (Results != 0) { + printf ("FSEEK failed - Aborted\n"); + return EFI_ABORTED; + } + + memset (Buffer, 0, FileSize + BUFFER_SIZE); + fread (Buffer, FileSize, 1, InFile); + + Ptrx = Buffer; + Pend = Ptrx + FileSize - strlen (DEPENDENCY_END); + Index = FileSize; + + NotDone = TRUE; + while ((Index--) && NotDone) { + + if (strncmp (Pend, DEPENDENCY_END, strlen (DEPENDENCY_END)) == 0) { + NotDone = FALSE; + } else { + Pend--; + } + } + + if (NotDone) { + printf ("Couldn't find end string %s\n", DEPENDENCY_END); + + Results = (UINTN) fclose (InFile); + if (Results != 0) { + printf ("FCLOSE failed\n"); + } + + Results = (UINTN) fclose (OutFile); + if (Results != 0) { + printf ("FCLOSE failed\n"); + } + + free (Buffer); + free (EvaluationStack); + + return EFI_INVALID_PARAMETER; + } + + Index = FileSize; + + NotDone = TRUE; + while ((Index--) && NotDone) { + + if (strncmp (Ptrx, DEPENDENCY_START, strlen (DEPENDENCY_START)) == 0) { + Ptrx += sizeof (DEPENDENCY_START); + NotDone = FALSE; + // + // BUGBUG -- should Index be decremented by sizeof(DEPENDENCY_START)? + // + } else { + Ptrx++; + } + } + + if (NotDone) { + printf ("Couldn't find start string %s\n", DEPENDENCY_START); + + Results = (UINTN) fclose (InFile); + if (Results != 0) { + printf ("FCLOSE failed\n"); + } + + Results = (UINTN) fclose (OutFile); + if (Results != 0) { + printf ("FCLOSE failed\n"); + } + + free (Buffer); + free (EvaluationStack); + + return EFI_INVALID_PARAMETER; + } + // + // validate the syntax of expression + // + if (!ParseDepex (Ptrx, Pend - Ptrx - 1)) { + printf ("The syntax of expression is wrong\n"); + + Results = (UINTN) fclose (InFile); + if (Results != 0) { + printf ("FCLOSE failed\n"); + } + + Results = (UINTN) fclose (OutFile); + if (Results != 0) { + printf ("FCLOSE failed\n"); + } + + free (Buffer); + free (EvaluationStack); + + return EFI_INVALID_PARAMETER; + } + + NotDone = TRUE; + + while ((Index--) && NotDone) { + + if (*Ptrx == ' ') { + Ptrx++; + } else if (*Ptrx == '\n' || *Ptrx == '\r') { + Ptrx++; + } else if (strncmp (Ptrx, OPERATOR_SOR, strlen (OPERATOR_SOR)) == 0) { + // + // Checks for some invalid dependencies + // + if (Before_Flag) { + + printf ("A BEFORE operator was detected.\n"); + printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); + return EFI_INVALID_PARAMETER; + + } else if (After_Flag) { + + printf ("An AFTER operator was detected.\n"); + printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); + return EFI_INVALID_PARAMETER; + + } else if (SOR_Flag) { + + printf ("Another SOR operator was detected.\n"); + printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); + return EFI_INVALID_PARAMETER; + + } else if (Dep_Flag) { + + printf ("The Schedule On Request - SOR operator must be the first operator following DEPENDENCY_START\n"); + return EFI_INVALID_PARAMETER; + + } else { + // + // BUGBUG - This was not in the spec but is in the CORE code + // An OPERATOR_SOR has to be first - following the DEPENDENCY_START + // + fputc (EFI_DEP_SOR, OutFile); + OutFileSize++; + Ptrx += sizeof (OPERATOR_SOR); + SOR_Flag = TRUE; + + } + } else if (strncmp (Ptrx, OPERATOR_BEFORE, strlen (OPERATOR_BEFORE)) == 0) { + // + // Checks for some invalid dependencies + // + if (Before_Flag) { + + printf ("Another BEFORE operator was detected.\n"); + printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); + return EFI_INVALID_PARAMETER; + + } else if (After_Flag) { + + printf ("An AFTER operator was detected.\n"); + printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); + return EFI_INVALID_PARAMETER; + + } else if (SOR_Flag) { + + printf ("A SOR operator was detected.\n"); + printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); + return EFI_INVALID_PARAMETER; + + } else if (Dep_Flag) { + + printf ("The BEFORE operator must be the first operator following DEPENDENCY_START\n"); + return EFI_INVALID_PARAMETER; + + } else { + fputc (EFI_DEP_BEFORE, OutFile); + OutFileSize++; + Ptrx += sizeof (OPERATOR_BEFORE); + Before_Flag = TRUE; + } + } else if (strncmp (Ptrx, OPERATOR_AFTER, strlen (OPERATOR_AFTER)) == 0) { + // + // Checks for some invalid dependencies + // + if (Before_Flag) { + + printf ("A BEFORE operator was detected.\n"); + printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); + return EFI_INVALID_PARAMETER; + + } else if (After_Flag) { + + printf ("Another AFTER operator was detected.\n"); + printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); + return EFI_INVALID_PARAMETER; + + } else if (SOR_Flag) { + + printf ("A SOR operator was detected.\n"); + printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); + return EFI_INVALID_PARAMETER; + + } else if (Dep_Flag) { + + printf ("The AFTER operator must be the first operator following DEPENDENCY_START\n"); + return EFI_INVALID_PARAMETER; + + } else { + fputc (EFI_DEP_AFTER, OutFile); + OutFileSize++; + Ptrx += sizeof (OPERATOR_AFTER); + Dep_Flag = TRUE; + After_Flag = TRUE; + } + } else if (strncmp (Ptrx, OPERATOR_AND, strlen (OPERATOR_AND)) == 0) { + while (StackPtr != EvaluationStack) { + Opcode = PopOpCode ((VOID **) &StackPtr); + if (Opcode != DXE_DEP_LEFT_PARENTHESIS) { + fputc (Opcode, OutFile); + OutFileSize++; + } else { + PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS); + break; + } + } + + PushOpCode ((VOID **) &StackPtr, EFI_DEP_AND); + Ptrx += sizeof (OPERATOR_AND); + Dep_Flag = TRUE; + + } else if (strncmp (Ptrx, OPERATOR_OR, strlen (OPERATOR_OR)) == 0) { + while (StackPtr != EvaluationStack) { + Opcode = PopOpCode ((VOID **) &StackPtr); + if (Opcode != DXE_DEP_LEFT_PARENTHESIS) { + fputc (Opcode, OutFile); + OutFileSize++; + } else { + PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS); + break; + } + } + + PushOpCode ((VOID **) &StackPtr, EFI_DEP_OR); + Ptrx += sizeof (OPERATOR_OR); + Dep_Flag = TRUE; + + } else if (strncmp (Ptrx, OPERATOR_NOT, strlen (OPERATOR_NOT)) == 0) { + while (StackPtr != EvaluationStack) { + Opcode = PopOpCode ((VOID **) &StackPtr); + if (Opcode != DXE_DEP_LEFT_PARENTHESIS) { + fputc (Opcode, OutFile); + OutFileSize++; + } else { + PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS); + break; + } + } + + PushOpCode ((VOID **) &StackPtr, EFI_DEP_NOT); + Ptrx += sizeof (OPERATOR_NOT); + Dep_Flag = TRUE; + + } else if (*Ptrx == '\t') { + + printf ("File contains tabs. This violates the coding standard\n"); + return EFI_INVALID_PARAMETER; + + } else if (*Ptrx == '\n') { + // + // Skip the newline character in the file + // + Ptrx++; + + } else if (strncmp (Ptrx, OPERATOR_LEFT_PARENTHESIS, strlen (OPERATOR_LEFT_PARENTHESIS)) == 0) { + PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS); + + Ptrx += strlen (OPERATOR_LEFT_PARENTHESIS); + Dep_Flag = TRUE; + + } else if (strncmp (Ptrx, OPERATOR_RIGHT_PARENTHESIS, strlen (OPERATOR_RIGHT_PARENTHESIS)) == 0) { + while (StackPtr != EvaluationStack) { + Opcode = PopOpCode ((VOID **) &StackPtr); + if (Opcode != DXE_DEP_LEFT_PARENTHESIS) { + fputc (Opcode, OutFile); + OutFileSize++; + } else { + break; + } + } + + Ptrx += strlen (OPERATOR_RIGHT_PARENTHESIS); + Dep_Flag = TRUE; + + } else if (strncmp (Ptrx, OPERATOR_TRUE, strlen (OPERATOR_TRUE)) == 0) { + + fputc (EFI_DEP_TRUE, OutFile); + + OutFileSize++; + + // + // OutFileSize += sizeof (EFI_DEP_TRUE); + // + Dep_Flag = TRUE; + + Ptrx += strlen (OPERATOR_TRUE); + + } else if (strncmp (Ptrx, OPERATOR_FALSE, strlen (OPERATOR_FALSE)) == 0) { + + fputc (EFI_DEP_FALSE, OutFile); + + OutFileSize++; + + // + // OutFileSize += sizeof (EFI_DEP_FALSE); + // + Dep_Flag = TRUE; + + Ptrx += strlen (OPERATOR_FALSE); + + } else if (*Ptrx == '{') { + Ptrx++; + + if (*Ptrx == ' ') { + Ptrx++; + } + + { + int byte_index; + // This is an array of UINT32s. sscanf will trash memory + // if you try to read into a UINT8 with a %x formatter. + UINT32 Guid_Data4[8]; + + ArgCountParsed = sscanf ( + Ptrx, + "%x, %x, %x, { %x, %x, %x, %x, %x, %x, %x, %x }", + &Guid.Data1, + &Guid.Data2, + &Guid.Data3, + &Guid_Data4[0], + &Guid_Data4[1], + &Guid_Data4[2], + &Guid_Data4[3], + &Guid_Data4[4], + &Guid_Data4[5], + &Guid_Data4[6], + &Guid_Data4[7] + ); + + // Now we can copy the 32 bit ints into the GUID. + for (byte_index=0; byte_index<8; byte_index++) { + Guid.Data4[byte_index] = (UINT8) Guid_Data4[byte_index]; + } + } + + if (ArgCountParsed != 11) { + printf ("We have found an illegal GUID\n"); + printf ("Fix your depex\n"); + exit (-1); + } + + while (*Ptrx != '}') { + Ptrx++; + } + + Ptrx++; + while (*Ptrx != '}') { + Ptrx++; + } + // + // Absorb the closing } + // + Ptrx++; + + // + // Don't provide a PUSH Opcode for the Before and After case + // + if ((!Before_Flag) && (!After_Flag)) { + fputc (EFI_DEP_PUSH, OutFile); + OutFileSize++; + } + + fwrite (&Guid, sizeof (EFI_GUID), 1, OutFile); + + OutFileSize += sizeof (EFI_GUID); + Dep_Flag = TRUE; + + } else if (strncmp (Ptrx, DEPENDENCY_END, strlen (DEPENDENCY_END)) == 0) { + NotDone = FALSE; + } else { + // + // Not a valid construct. Null terminate somewhere out there and + // print an error message. + // + *(Ptrx + 20) = 0; + printf (TOOL_NAME " ERROR: Unrecognized input at: \"%s\"...\n", Ptrx); + return EFI_INVALID_PARAMETER; + } + } + // + // DRAIN(); + // + while (StackPtr != EvaluationStack) { + fputc (PopOpCode ((VOID **) &StackPtr), OutFile); + OutFileSize++; + } + + if (OutFileSize == 0) { + printf ("Grammer contains no operators or constants\n"); + return EFI_INVALID_PARAMETER; + } + + fputc (EFI_DEP_END, OutFile); + + OutFileSize++; + + // + // Checks for invalid padding values + // + if (Padding < 0) { + + printf ("The inputted padding value was %d\n", Padding); + printf ("The optional padding value can not be less than ZERO\n"); + return EFI_INVALID_PARAMETER; + + } else if (Padding > 0) { + + while ((OutFileSize % Padding) != 0) { + + fputc (' ', OutFile); + OutFileSize++; + } + } + + Results = (UINTN) fclose (InFile); + if (Results != 0) { + printf ("FCLOSE failed\n"); + } + + Results = (UINTN) fclose (OutFile); + if (Results != 0) { + printf ("FCLOSE failed\n"); + } + + free (Buffer); + free (EvaluationStack); + + return EFI_SUCCESS; +} // End GenerateDependencyExpression function + +int +main ( + IN UINTN argc, + IN CHAR8 *argv[] + ) +/*++ + +Routine Description: + + Parse user entries. Print some rudimentary help + +Arguments: + + argc The count of input arguments + argv The input arguments string array + +Returns: + + EFI_SUCCESS The function completed successfully. + EFI_INVALID_PARAMETER One of the input parameters was invalid or one of the parameters in the text file was invalid. + EFI_OUT_OF_RESOURCES Unable to allocate memory. + EFI_ABORTED Unable to open/create a file or a misc error. + +--*/ +// TODO: ] - add argument and description to function comment +{ + FILE *OutFile; + FILE *InFile; + UINT8 Padding; + UINTN Index; + BOOLEAN Input_Flag; + BOOLEAN Output_Flag; + BOOLEAN Pad_Flag; + + InFile = NULL; + OutFile = NULL; + Padding = 0; + Input_Flag = FALSE; + Output_Flag = FALSE; + Pad_Flag = FALSE; + + if (argc < 5) { + printf ("Not enough arguments\n"); + PrintGenDepexUsageInfo (); + return EFI_INVALID_PARAMETER; + } + + for (Index = 1; Index < argc - 1; Index++) { + + if ((strcmp (argv[Index], "-I") == 0) || (strcmp (argv[Index], "-i") == 0)) { + + if (!Input_Flag) { + + InFile = fopen (argv[Index + 1], "rb"); + Input_Flag = TRUE; + + } else { + printf ("GenDepex only allows one INPUT (-I) argument\n"); + return EFI_INVALID_PARAMETER; + } + + } else if ((strcmp (argv[Index], "-O") == 0) || (strcmp (argv[Index], "-o") == 0)) { + + if (!Output_Flag) { + + OutFile = fopen (argv[Index + 1], "wb"); + Output_Flag = TRUE; + + } else { + printf ("GenDepex only allows one OUTPUT (-O) argument\n"); + return EFI_INVALID_PARAMETER; + } + + } else if ((strcmp (argv[Index], "-P") == 0) || (strcmp (argv[Index], "-p") == 0)) { + + if (!Pad_Flag) { + + Padding = (UINT8) atoi (argv[Index + 1]); + Pad_Flag = TRUE; + + } else { + printf ("GenDepex only allows one PADDING (-P) argument\n"); + return EFI_INVALID_PARAMETER; + } + } + } + + PrintGenDepexUtilityInfo (); + + if (InFile == NULL) { + printf ("Can not open for reading.\n"); + PrintGenDepexUsageInfo (); + return EFI_ABORTED; + } + + if (OutFile == NULL) { + printf ("Can not open for writting.\n"); + PrintGenDepexUsageInfo (); + return EFI_ABORTED; + } + + return GenerateDependencyExpression (InFile, OutFile, Padding); +} diff --git a/Tools/CodeTools/Source/GenDepex/GenDepex.h b/Tools/CodeTools/Source/GenDepex/GenDepex.h new file mode 100644 index 0000000000..b198156baa --- /dev/null +++ b/Tools/CodeTools/Source/GenDepex/GenDepex.h @@ -0,0 +1,71 @@ +/*++ +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: + GenDepex.h + + Abstract: + This file contains the relevant declarations required + to generate a binary Dependency File + + Complies with Tiano C Coding Standards Document, version 0.31, 12 Dec 2000. + +--*/ + +#ifndef _EFI_GEN_DEPEX_H +#define _EFI_GEN_DEPEX_H + + +#include +#include +#include +#include +#ifndef __GNUC__ +#include +#endif + +#include +#include + +#define DEPENDENCY_START "DEPENDENCY_START" +#define OPERATOR_BEFORE "BEFORE" +#define OPERATOR_AFTER "AFTER" +#define OPERATOR_AND "AND" +#define OPERATOR_OR "OR" +#define OPERATOR_NOT "NOT" +#define OPERATOR_TRUE "TRUE" +#define OPERATOR_FALSE "FALSE" +#define OPERATOR_SOR "SOR" +#define OPERATOR_END "END" +#define OPERATOR_LEFT_PARENTHESIS "(" +#define OPERATOR_RIGHT_PARENTHESIS ")" +#define DEPENDENCY_END "DEPENDENCY_END" + +#define DXE_DEP_LEFT_PARENTHESIS 0x0a +#define DXE_DEP_RIGHT_PARENTHESIS 0x0b + +#define LINESIZE 320 +#define SIZE_A_SYMBOL 60 +#define DEPENDENCY_OPCODE UINT8 +#define EVAL_STACK_SIZE 0x1024 +#define BUFFER_SIZE 0x100 + +// +// Utility Name +// +#define UTILITY_NAME "GenDepex" + +// +// Utility version information +// +#define UTILITY_MAJOR_VERSION 0 +#define UTILITY_MINOR_VERSION 5 + +#endif diff --git a/Tools/CodeTools/Source/GenDepex/build.xml b/Tools/CodeTools/Source/GenDepex/build.xml new file mode 100644 index 0000000000..568177aa03 --- /dev/null +++ b/Tools/CodeTools/Source/GenDepex/build.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/GenFfsFile/GenFfsFile.c b/Tools/CodeTools/Source/GenFfsFile/GenFfsFile.c new file mode 100644 index 0000000000..1eea09f5fb --- /dev/null +++ b/Tools/CodeTools/Source/GenFfsFile/GenFfsFile.c @@ -0,0 +1,2646 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + GenFfsFile.c + +Abstract: + + This file contains functions required to generate a Firmware File System + file. + +--*/ + +#include +#include // for isalpha() +// +// include file for _spawnv +// +#ifndef __GNUC__ +#include +#endif +#include +#include + +#include +#include +#include +#include +#include + +#include "ParseInf.h" +#include "EfiCompress.h" +#include "EfiCustomizedCompress.h" +#include "Crc32.h" +#include "GenFfsFile.h" +#include "CommonLib.h" +#include "EfiUtilityMsgs.h" +#include "SimpleFileParsing.h" + +#define UTILITY_NAME "GenFfsFile" +#define TOOLVERSION "0.32" +#define MAX_ARRAY_SIZE 100 + +static +INT32 +GetNextLine ( + OUT CHAR8 *Destination, + IN FILE *Package, + IN OUT UINT32 *LineNumber + ); + +static +void +CheckSlash ( + IN OUT CHAR8 *String, + IN FILE *In, + IN OUT UINT32 *LineNumber + ); + +static +INT32 +FindSectionInPackage ( + IN CHAR8 *BuildDirectory, + IN FILE *OverridePackage, + IN OUT UINT32 *LineNumber + ); + +static +STATUS +ProcessCommandLineArgs ( + int Argc, + char *Argv[] + ); + +static +void +PrintUsage ( + void + ); + +// +// Keep globals in this structure +// +static struct { + UINT8 BuildDirectory[_MAX_PATH]; + UINT8 PrimaryPackagePath[_MAX_PATH]; + UINT8 OverridePackagePath[_MAX_PATH]; + BOOLEAN Verbose; +} mGlobals; + +static EFI_GUID mZeroGuid = { 0 }; + +static +void +StripQuotes ( + IN OUT CHAR8 *String + ) +/*++ + +Routine Description: + + Removes quotes and/or whitespace from around a string + +Arguments: + + String - String to remove quotes from + +Returns: + + None + +--*/ +{ + UINTN Index; + UINTN Index2; + UINTN StrLen; + + Index2 = strspn (String, "\" \t\n"); + StrLen = strlen (String); + + for (Index = Index2; String[Index] != '\"', Index < StrLen; Index++) { + String[Index - Index2] = String[Index]; + } + + String[Index - Index2] = 0; +} + +static +void +PrintUsage ( + void + ) +/*++ + +Routine Description: + + Print Error / Help message. + +Arguments: + + void + +Returns: + + None + +--*/ +{ + printf ("Usage:\n"); + printf (UTILITY_NAME " -b \"build directory\" -p1 \"package1.inf\" -p2 \"package2.inf\" -v\n"); + printf (" -b \"build directory\":\n "); + printf (" specifies the full path to the component build directory.\n"); + printf (" -p1 \"P1_path\":\n"); + printf (" specifies fully qualified file name to the primary package file.\n"); + printf (" This file will normally exist in the same directory as the makefile\n"); + printf (" for the component. Required.\n"); + printf (" -p2 \"P2_path\":\n"); + printf (" specifies fully qualified file name to the override package file.\n"); + printf (" This file will normally exist in the build tip. Optional.\n"); +} + +static +INT32 +TestComment ( + IN CHAR8 *String, + IN FILE *In + ) +/*++ + +Routine Description: + + Tests input string to see if it is a comment, and if so goes to the next line in the file that is not a comment + +Arguments: + + String - String to test + + In - Open file to move pointer within + +Returns: + + -1 - End of file reached + 0 - Not a comment + 1 - Comment bypassed + +--*/ +{ + CHAR8 CharBuffer; + + CharBuffer = 0; + if ((String[0] == '/') && (String[1] == '/')) { + while (CharBuffer != '\n') { + fscanf (In, "%c", &CharBuffer); + if (feof (In)) { + return -1; + } + } + } else { + return 0; + } + + return 1; +} + +static +void +BreakString ( + IN CONST CHAR8 *Source, + OUT CHAR8 *Destination, + IN INTN Direction + ) +/*++ + +Routine Description: + + Takes an input string and returns either the part before the =, or the part after the =, depending on direction + +Arguments: + + Source - String to break + + Destination - Buffer to place new string in + + Direction - 0 to return all of source string before = + 1 to return all of source string after = + +Returns: + + None + +--*/ +{ + UINTN Index; + UINTN Index2; + + Index = 0; + Index2 = 0; + + if (strchr (Source, '=') == NULL) { + strcpy (Destination, Source); + + return ; + } + + if (Direction == 0) { + // + // return part of string before = + // + while (Source[Index] != '=') { + Destination[Index] = Source[Index++]; + } + + Destination[Index] = 0; + } else { + // + // return part of string after = + // + strcpy (Destination, strchr (Source, '=') + 1); + } +} + +static +INT32 +GetNextLine ( + OUT CHAR8 *Destination, + IN FILE *Package, + IN OUT UINT32 *LineNumber + ) +/*++ + +Routine Description: + + Gets the next non-commented line from the file + +Arguments: + + Destination - Where to put string + + Package - Package to get string from + + LineNumber - The actual line number. + +Returns: + + -1 - End of file reached + 0 - Success + +--*/ +{ + CHAR8 String[_MAX_PATH]; + fscanf (Package, "%s", &String); + if (feof (Package)) { + return -1; + } + + while (TestComment (String, Package) == 1) { + fscanf (Package, "%s", &String); + if (feof (Package)) { + return -1; + } + } + + strcpy (Destination, String); + return 0; +} + +static +VOID +CheckSlash ( + IN OUT CHAR8 *String, + IN FILE *In, + IN OUT UINT32 *LineNumber + ) +/*++ + +Routine Description: + + Checks to see if string is line continuation character, if so goes to next valid line + +Arguments: + + String - String to test + + In - Open file to move pointer within + + LineNumber - The line number. + +Returns: + + None + +--*/ +{ + CHAR8 ByteBuffer; + ByteBuffer = 0; + + switch (String[0]) { + + case '\\': + while (String[0] == '\\') { + while (ByteBuffer != '\n') { + fscanf (In, "%c", &ByteBuffer); + } + (*LineNumber)++; + if (GetNextLine (String, In, LineNumber) == -1) { + return ; + } + } + break; + + case '\n': + (*LineNumber)++; + while (String[0] == '\n') { + if (GetNextLine (String, In, LineNumber) == -1) { + return ; + } + } + break; + + default: + break; + + } + +} + +static +INT32 +FindSectionInPackage ( + IN CHAR8 *BuildDirectory, + IN FILE *OverridePackage, + IN OUT UINT32 *LineNumber + ) +/*++ + +Routine Description: + + Finds the matching section within the package + +Arguments: + + BuildDirectory - name of section to find + + OverridePackage - Package file to search within + + LineNumber - The line number. + +Returns: + + -1 - End of file reached + 0 - Success + +--*/ +{ + CHAR8 String[_MAX_PATH]; + CHAR8 NewString[_MAX_PATH]; + String[0] = 0; + + while (strcmp (BuildDirectory, String) != 0) { + if (GetNextLine (NewString, OverridePackage, LineNumber) != 0) { + return -1; + } + + if (NewString[0] == '[') { + if (NewString[strlen (NewString) - 1] != ']') { + // + // have to construct string. + // + strcpy (String, NewString + 1); + + while (1) { + fscanf (OverridePackage, "%s", &NewString); + if (feof (OverridePackage)) { + return -1; + } + + if (NewString[0] != ']') { + if (strlen (String) != 0) { + strcat (String, " "); + } + + strcat (String, NewString); + if (String[strlen (String) - 1] == ']') { + String[strlen (String) - 1] = 0; + break; + } + } else { + break; + } + } + } else { + NewString[strlen (NewString) - 1] = 0; + strcpy (String, NewString + 1); + } + } + } + + return 0; +} + +static +EFI_STATUS +GenSimpleGuidSection ( + IN OUT UINT8 *FileBuffer, + IN OUT UINT32 *BufferSize, + IN UINT32 DataSize, + IN EFI_GUID SignGuid, + IN UINT16 GuidedSectionAttributes + ) +/*++ + +Routine Description: + + add GUIDed section header for the data buffer. + data stays in same location (overwrites source data). + +Arguments: + + FileBuffer - Buffer containing data to sign + + BufferSize - On input, the size of FileBuffer. On output, the size of + actual section data (including added section header). + + DataSize - Length of data to Sign + + SignGuid - Guid to be add. + + GuidedSectionAttributes - The section attribute. + +Returns: + + EFI_SUCCESS - Successful + EFI_OUT_OF_RESOURCES - Not enough resource. + +--*/ +{ + UINT32 TotalSize; + + EFI_GUID_DEFINED_SECTION GuidSectionHeader; + UINT8 *SwapBuffer; + + SwapBuffer = NULL; + + if (DataSize == 0) { + *BufferSize = 0; + + return EFI_SUCCESS; + } + + TotalSize = DataSize + sizeof (EFI_GUID_DEFINED_SECTION); + GuidSectionHeader.CommonHeader.Type = EFI_SECTION_GUID_DEFINED; + GuidSectionHeader.CommonHeader.Size[0] = (UINT8) (TotalSize & 0xff); + GuidSectionHeader.CommonHeader.Size[1] = (UINT8) ((TotalSize & 0xff00) >> 8); + GuidSectionHeader.CommonHeader.Size[2] = (UINT8) ((TotalSize & 0xff0000) >> 16); + memcpy (&(GuidSectionHeader.SectionDefinitionGuid), &SignGuid, sizeof (EFI_GUID)); + GuidSectionHeader.Attributes = GuidedSectionAttributes; + GuidSectionHeader.DataOffset = sizeof (EFI_GUID_DEFINED_SECTION); + + SwapBuffer = (UINT8 *) malloc (DataSize); + if (SwapBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + memcpy (SwapBuffer, FileBuffer, DataSize); + memcpy (FileBuffer, &GuidSectionHeader, sizeof (EFI_GUID_DEFINED_SECTION)); + memcpy (FileBuffer + sizeof (EFI_GUID_DEFINED_SECTION), SwapBuffer, DataSize); + + // + // Make sure section ends on a DWORD boundary + // + while ((TotalSize & 0x03) != 0) { + FileBuffer[TotalSize] = 0; + TotalSize++; + } + + *BufferSize = TotalSize; + + if (SwapBuffer != NULL) { + free (SwapBuffer); + } + + return EFI_SUCCESS; +} + +static +EFI_STATUS +CompressSection ( + UINT8 *FileBuffer, + UINT32 *BufferSize, + UINT32 DataSize, + CHAR8 *Type + ) +/*++ + +Routine Description: + + Compress the data and add section header for the compressed data. + Compressed data (with section header) stays in same location as the source + (overwrites source data). + +Arguments: + + FileBuffer - Buffer containing data to Compress + + BufferSize - On input, the size of FileBuffer. On output, the size of + actual compressed data (including added section header). + When buffer is too small, this value indicates the size needed. + + DataSize - The size of data to compress + + Type - The compression type (not used currently). + Assume EFI_HEAVY_COMPRESSION. + +Returns: + + EFI_BUFFER_TOO_SMALL - Buffer size is too small. + EFI_UNSUPPORTED - Compress type can not be supported. + EFI_SUCCESS - Successful + EFI_OUT_OF_RESOURCES - Not enough resource. + +--*/ +{ + EFI_STATUS Status; + UINT8 *CompData; + UINT32 CompSize; + UINT32 TotalSize; + EFI_COMPRESSION_SECTION CompressionSet; + UINT8 CompressionType; + COMPRESS_FUNCTION CompressFunction; + + Status = EFI_SUCCESS; + CompData = NULL; + CompSize = 0; + TotalSize = 0; + CompressFunction = NULL; + + // + // Get the compress type + // + if (strcmpi (Type, "Dummy") == 0) { + // + // Added "Dummy" to keep backward compatibility. + // + CompressionType = EFI_STANDARD_COMPRESSION; + CompressFunction = (COMPRESS_FUNCTION) Compress; + + } else if (strcmpi (Type, "LZH") == 0) { + // + // EFI stardard compression (LZH) + // + CompressionType = EFI_STANDARD_COMPRESSION; + CompressFunction = (COMPRESS_FUNCTION) Compress; + + } else { + // + // Customized compression + // + Status = SetCustomizedCompressionType (Type); + if (EFI_ERROR (Status)) { + return Status; + } + + CompressionType = EFI_CUSTOMIZED_COMPRESSION; + CompressFunction = (COMPRESS_FUNCTION) CustomizedCompress; + } + // + // Compress the raw data + // + Status = CompressFunction (FileBuffer, DataSize, CompData, &CompSize); + if (Status == EFI_BUFFER_TOO_SMALL) { + CompData = malloc (CompSize); + if (!CompData) { + return EFI_OUT_OF_RESOURCES; + } + + Status = CompressFunction (FileBuffer, DataSize, CompData, &CompSize); + } + + if (EFI_ERROR (Status)) { + if (CompData != NULL) { + free (CompData); + } + + return Status; + } + + TotalSize = CompSize + sizeof (EFI_COMPRESSION_SECTION); + + // + // Buffer too small? + // + if (TotalSize > *BufferSize) { + *BufferSize = TotalSize; + if (CompData != NULL) { + free (CompData); + } + + return EFI_BUFFER_TOO_SMALL; + } + // + // Add the section header for the compressed data + // + CompressionSet.CommonHeader.Type = EFI_SECTION_COMPRESSION; + CompressionSet.CommonHeader.Size[0] = (UINT8) (TotalSize & 0xff); + CompressionSet.CommonHeader.Size[1] = (UINT8) ((TotalSize & 0xff00) >> 8); + CompressionSet.CommonHeader.Size[2] = (UINT8) ((TotalSize & 0xff0000) >> 16); + CompressionSet.CompressionType = CompressionType; + CompressionSet.UncompressedLength = DataSize; + + // + // Copy header and data to the buffer + // + memcpy (FileBuffer, &CompressionSet, sizeof (EFI_COMPRESSION_SECTION)); + memcpy (FileBuffer + sizeof (CompressionSet), CompData, CompSize); + + // + // Make sure section ends on a DWORD boundary + // + while ((TotalSize & 0x03) != 0) { + FileBuffer[TotalSize] = 0; + TotalSize++; + } + + *BufferSize = TotalSize; + + if (CompData != NULL) { + free (CompData); + } + + return EFI_SUCCESS; +} + +static +void +StripParens ( + IN OUT CHAR8 *String + ) +/*++ + +Routine Description: + + Removes Parenthesis from around a string + +Arguments: + + String - String to remove parens from + +Returns: + + None + +--*/ +{ + INT32 Index; + + if (String[0] != '(') { + return ; + } + + for (Index = 1; String[Index] != ')'; Index++) { + String[Index - 1] = String[Index]; + if (String[Index] == 0) { + return ; + } + } + + String[Index - 1] = 0; + + return ; +} + +static +void +StripEqualMark ( + IN OUT CHAR8 *String + ) +/*++ + +Routine Description: + + Removes Equal Mark from around a string + +Arguments: + + String - String to remove equal mark from + +Returns: + + None + +--*/ +{ + INT32 Index; + + if (String[0] != '=' && String[strlen (String) - 1] != '=') { + return ; + } + + if (String[0] == '=') { + + for (Index = 1; String[Index] != 0; Index++) { + String[Index - 1] = String[Index]; + } + + String[Index - 1] = 0; + } + + if (String[strlen (String) - 1] == '=') { + String[strlen (String) - 1] = 0; + } + + return ; +} + +static +INT32 +ProcessEnvironmentVariable ( + IN CHAR8 *Buffer, + OUT CHAR8 *NewBuffer + ) +/*++ + +Routine Description: + + Converts environment variables to values + +Arguments: + + Buffer - Buffer containing Environment Variable String + + NewBuffer - Buffer containing value of environment variable + + +Returns: + + Number of characters from Buffer used + +--*/ +{ + INT32 Index; + INT32 Index2; + CHAR8 VariableBuffer[_MAX_PATH]; + + Index = 2; + Index2 = 0; + + while (Buffer[Index] != ')') { + VariableBuffer[Index - 2] = Buffer[Index++]; + } + + VariableBuffer[Index - 2] = 0; + Index++; + + if (getenv (VariableBuffer) != NULL) { + strcpy (NewBuffer, getenv (VariableBuffer)); + } else { + printf ("Environment variable %s not found!\n", VariableBuffer); + } + + return Index; +} + +static +void +SplitAttributesField ( + IN CHAR8 *Buffer, + IN CHAR8 *AttributesArray[], + IN OUT UINT32 *NumberOfAttributes + ) +/* + NumberOfAttributes: on input, it specifies the current number of attributes + stored in AttributeArray. + on output, it is updated to the latest number of attributes + stored in AttributesArray. +*/ +{ + UINT32 Index; + UINT32 Index2; + UINT32 z; + CHAR8 *CharBuffer; + + CharBuffer = NULL; + CharBuffer = (CHAR8 *) malloc (_MAX_PATH); + ZeroMem (CharBuffer, _MAX_PATH); + + for (Index = 0, z = 0, Index2 = 0; Index < strlen (Buffer); Index++) { + + if (Buffer[Index] != '|') { + CharBuffer[z] = Buffer[Index]; + z++; + } else { + + CharBuffer[z] = 0; + AttributesArray[*NumberOfAttributes + Index2] = CharBuffer; + Index2++; + + // + // allocate new char buffer for the next attributes string + // + CharBuffer = (CHAR8 *) malloc (_MAX_PATH); + ZeroMem (CharBuffer, _MAX_PATH); + z = 0; + } + } + + CharBuffer[z] = 0; + // + // record the last attributes string in the Buffer + // + AttributesArray[*NumberOfAttributes + Index2] = CharBuffer; + Index2++; + + *NumberOfAttributes += Index2; + + return ; +} + +static +INT32 +GetToolArguments ( + CHAR8 *ToolArgumentsArray[], + FILE *Package, + CHAR8 **PtrInputFileName, + CHAR8 **PtrOutputFileName, + EFI_GUID *Guid, + UINT16 *GuidedSectionAttributes + ) +{ + CHAR8 Buffer[_MAX_PATH]; + BOOLEAN ArgumentsFlag; + BOOLEAN InputFlag; + BOOLEAN OutputFlag; + BOOLEAN GuidFlag; + BOOLEAN AttributesFlag; + UINT32 argc; + UINT32 Index2; + UINT32 z; + CHAR8 *CharBuffer; + INT32 Index; + INT32 ReturnValue; + EFI_STATUS Status; + + CHAR8 *AttributesArray[MAX_ARRAY_SIZE]; + UINT32 NumberOfAttributes; + CHAR8 *InputFileName; + CHAR8 *OutputFileName; + UINT32 LineNumber; + Buffer[_MAX_PATH]; + + ArgumentsFlag = FALSE; + InputFlag = FALSE; + OutputFlag = FALSE; + GuidFlag = FALSE; + AttributesFlag = FALSE; + // + // Start at 1, since ToolArgumentsArray[0] + // is the program name. + // + argc = 1; + Index2 = 0; + + z = 0; + ReturnValue = 0; + NumberOfAttributes = 0; + InputFileName = NULL; + OutputFileName = NULL; + + ZeroMem (Buffer, _MAX_PATH); + ZeroMem (AttributesArray, sizeof (CHAR8 *) * MAX_ARRAY_SIZE); + LineNumber = 0; + while (Buffer[0] != ')') { + + if (GetNextLine (Buffer, Package, &LineNumber) != -1) { + CheckSlash (Buffer, Package, &LineNumber); + StripEqualMark (Buffer); + } else { + Error (NULL, 0, 0, "failed to get next line from package file", NULL); + return -1; + } + + if (Buffer[0] == ')') { + break; + } else if (strcmpi (Buffer, "ARGS") == 0) { + + ArgumentsFlag = TRUE; + AttributesFlag = FALSE; + continue; + + } else if (strcmpi (Buffer, "INPUT") == 0) { + + InputFlag = TRUE; + ArgumentsFlag = FALSE; + AttributesFlag = FALSE; + continue; + + } else if (strcmpi (Buffer, "OUTPUT") == 0) { + + OutputFlag = TRUE; + ArgumentsFlag = FALSE; + AttributesFlag = FALSE; + continue; + + } else if (strcmpi (Buffer, "GUID") == 0) { + + GuidFlag = TRUE; + ArgumentsFlag = FALSE; + AttributesFlag = FALSE; + // + // fetch the GUID for the section + // + continue; + + } else if (strcmpi (Buffer, "ATTRIBUTES") == 0) { + + AttributesFlag = TRUE; + ArgumentsFlag = FALSE; + // + // fetch the GUIDed Section's Attributes + // + continue; + + } else if (strcmpi (Buffer, "") == 0) { + continue; + } + // + // get all command arguments into ToolArgumentsArray + // + if (ArgumentsFlag) { + + StripEqualMark (Buffer); + + CharBuffer = (CHAR8 *) malloc (_MAX_PATH); + if (CharBuffer == NULL) { + goto ErrorExit; + } + + ZeroMem (CharBuffer, sizeof (_MAX_PATH)); + + ToolArgumentsArray[argc] = CharBuffer; + + if (Buffer[0] == '$') { + Index = ProcessEnvironmentVariable (&Buffer[0], ToolArgumentsArray[argc]); + // + // if there is string after the environment variable, cat it. + // + if ((UINT32) Index < strlen (Buffer)) { + strcat (ToolArgumentsArray[argc], &Buffer[Index]); + } + } else { + strcpy (ToolArgumentsArray[argc], Buffer); + } + + argc += 1; + ToolArgumentsArray[argc] = NULL; + continue; + } + + if (InputFlag) { + + StripEqualMark (Buffer); + + InputFileName = (CHAR8 *) malloc (_MAX_PATH); + if (InputFileName == NULL) { + goto ErrorExit; + } + + ZeroMem (InputFileName, sizeof (_MAX_PATH)); + + if (Buffer[0] == '$') { + Index = ProcessEnvironmentVariable (&Buffer[0], InputFileName); + // + // if there is string after the environment variable, cat it. + // + if ((UINT32) Index < strlen (Buffer)) { + strcat (InputFileName, &Buffer[Index]); + } + } else { + strcpy (InputFileName, Buffer); + } + + InputFlag = FALSE; + continue; + } + + if (OutputFlag) { + + StripEqualMark (Buffer); + + OutputFileName = (CHAR8 *) malloc (_MAX_PATH); + if (OutputFileName == NULL) { + goto ErrorExit; + } + + ZeroMem (OutputFileName, sizeof (_MAX_PATH)); + + if (Buffer[0] == '$') { + Index = ProcessEnvironmentVariable (&Buffer[0], OutputFileName); + // + // if there is string after the environment variable, cat it. + // + if ((UINT32) Index < strlen (Buffer)) { + strcat (OutputFileName, &Buffer[Index]); + } + } else { + strcpy (OutputFileName, Buffer); + } + + OutputFlag = FALSE; + continue; + } + + if (GuidFlag) { + + StripEqualMark (Buffer); + + Status = StringToGuid (Buffer, Guid); + if (EFI_ERROR (Status)) { + ReturnValue = -1; + goto ErrorExit; + } + + GuidFlag = FALSE; + } + + if (AttributesFlag) { + + StripEqualMark (Buffer); + + // + // there might be no space between each attribute in the statement, + // split them aside and return each attribute string + // in the AttributesArray + // + SplitAttributesField (Buffer, AttributesArray, &NumberOfAttributes); + } + } + // + // ReplaceVariableInBuffer (ToolArgumentsArray,&i,"INPUT",InputVariable,j); + // ReplaceVariableInBuffer (ToolArgumentsArray,&i,"OUTPUT",&TargetFileName,1); + // + for (z = 0; z < NumberOfAttributes; z++) { + if (strcmpi (AttributesArray[z], "PROCESSING_REQUIRED") == 0) { + *GuidedSectionAttributes |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED; + } else if (strcmpi (AttributesArray[z], "AUTH_STATUS_VALID") == 0) { + *GuidedSectionAttributes |= EFI_GUIDED_SECTION_AUTH_STATUS_VALID; + } + } + +ErrorExit: + + for (Index2 = 0; Index2 < MAX_ARRAY_SIZE; Index2++) { + if (AttributesArray[Index2] == NULL) { + break; + } + + free (AttributesArray[Index2]); + } + + *PtrInputFileName = InputFileName; + *PtrOutputFileName = OutputFileName; + + return ReturnValue; +} + +static +INT32 +ProcessScript ( + IN OUT UINT8 *FileBuffer, + IN FILE *Package, + IN CHAR8 *BuildDirectory, + IN BOOLEAN ForceUncompress + ) +/*++ + +Routine Description: + + Signs the section, data stays in same location + +Arguments: + + FileBuffer - Data Buffer + + Package - Points to curly brace in Image Script + + BuildDirectory - Name of the source directory parameter + + ForceUncompress - Whether to force uncompress. + +Returns: + + Number of bytes added to file buffer + -1 on error + +--*/ +{ + EFI_STATUS Status; + UINT32 Size; + CHAR8 Buffer[_MAX_PATH]; + CHAR8 Type[_MAX_PATH]; + CHAR8 FileName[_MAX_PATH]; + CHAR8 NewBuffer[_MAX_PATH]; + INT32 Index3; + INT32 Index2; + UINT32 ReturnValue; + UINT8 ByteBuffer; + FILE *InFile; + UINT32 SourceDataSize; + CHAR8 *ToolArgumentsArray[MAX_ARRAY_SIZE]; + CHAR8 *OutputFileName; + CHAR8 *InputFileName; + CHAR8 ToolName[_MAX_PATH]; + FILE *OutputFile; + FILE *InputFile; + UINT8 Temp; + int returnint; + INT32 Index; + UINT32 LineNumber; + BOOLEAN IsError; + EFI_GUID SignGuid; + UINT16 GuidedSectionAttributes; + UINT8 *TargetFileBuffer; + + OutputFileName = NULL; + InputFileName = NULL; + OutputFile = NULL; + InputFile = NULL; + IsError = FALSE; + GuidedSectionAttributes = 0; + TargetFileBuffer = NULL; + + Size = 0; + LineNumber = 0; + Buffer[0] = 0; + for (Index3 = 0; Index3 < MAX_ARRAY_SIZE; ++Index3) { + ToolArgumentsArray[Index3] = NULL; + } + + while (Buffer[0] != '}') { + if (GetNextLine (Buffer, Package, &LineNumber) != -1) { + CheckSlash (Buffer, Package, &LineNumber); + } else { + printf ("ERROR in IMAGE SCRIPT!\n"); + IsError = TRUE; + goto Done; + } + + if (strcmpi (Buffer, "Compress") == 0) { + // + // Handle compress + // + // + // read compression type + // + if (GetNextLine (Buffer, Package, &LineNumber) != -1) { + CheckSlash (Buffer, Package, &LineNumber); + } + + StripParens (Buffer); + if (Buffer[0] == '$') { + ProcessEnvironmentVariable (&Buffer[0], Type); + } else { + strcpy (Type, Buffer); + } + // + // build buffer + // + while (Buffer[0] != '{') { + if (GetNextLine (Buffer, Package, &LineNumber) != -1) { + CheckSlash (Buffer, Package, &LineNumber); + } + } + + ReturnValue = ProcessScript (&FileBuffer[Size], Package, BuildDirectory, ForceUncompress); + if (ReturnValue == -1) { + IsError = TRUE; + goto Done; + } + // + // Call compress routine on buffer. + // Occasionally, compressed data + section header would + // be largere than the source and EFI_BUFFER_TOO_SMALL is + // returned from CompressSection() + // + SourceDataSize = ReturnValue; + + if (!ForceUncompress) { + + Status = CompressSection ( + &FileBuffer[Size], + &ReturnValue, + SourceDataSize, + Type + ); + + if (Status == EFI_BUFFER_TOO_SMALL) { + Status = CompressSection ( + &FileBuffer[Size], + &ReturnValue, + SourceDataSize, + Type + ); + } + + if (EFI_ERROR (Status)) { + IsError = TRUE; + goto Done; + } + } + + Size += ReturnValue; + + } else if (strcmpi (Buffer, "Tool") == 0) { + + ZeroMem (ToolName, _MAX_PATH); + ZeroMem (ToolArgumentsArray, sizeof (CHAR8 *) * MAX_ARRAY_SIZE); + ZeroMem (&SignGuid, sizeof (EFI_GUID)); + + // + // handle signing Tool + // + while (Buffer[0] != '(') { + if (GetNextLine (Buffer, Package, &LineNumber) != -1) { + CheckSlash (Buffer, Package, &LineNumber); + } + } + + if (strcmpi (Buffer, "(") == 0) { + if (GetNextLine (Buffer, Package, &LineNumber) != -1) { + CheckSlash (Buffer, Package, &LineNumber); + } + } + + StripParens (Buffer); + + if (Buffer[0] == '$') { + Index = ProcessEnvironmentVariable (&Buffer[0], ToolName); + // + // if there is string after the environment variable, cat it. + // + if ((UINT32) Index < strlen (Buffer)) { + strcat (ToolName, &Buffer[Index]); + } + } else { + strcpy (ToolName, Buffer); + } + + ToolArgumentsArray[0] = ToolName; + + // + // read ARGS + // + if (GetToolArguments ( + ToolArgumentsArray, + Package, + &InputFileName, + &OutputFileName, + &SignGuid, + &GuidedSectionAttributes + ) == -1) { + IsError = TRUE; + goto Done; + } + // + // if the tool need input file, + // dump the file buffer to the specified input file. + // + if (InputFileName != NULL) { + InputFile = fopen (InputFileName, "wb"); + if (InputFile == NULL) { + Error (NULL, 0, 0, InputFileName, "failed to open output file for writing"); + IsError = TRUE; + goto Done; + } + + fwrite (FileBuffer, sizeof (UINT8), Size, InputFile); + fclose (InputFile); + InputFile = NULL; + free (InputFileName); + InputFileName = NULL; + } + // + // dispatch signing tool + // +#ifdef __GNUC__ + { + char CommandLine[1000]; + sprintf(CommandLine, "%s %s", ToolName, ToolArgumentsArray); + returnint = system(CommandLine); + } +#else + returnint = _spawnv (_P_WAIT, ToolName, ToolArgumentsArray); +#endif + if (returnint != 0) { + Error (NULL, 0, 0, ToolName, "external tool failed"); + IsError = TRUE; + goto Done; + } + // + // if the tool has output file, + // dump the output file to the file buffer + // + if (OutputFileName != NULL) { + + OutputFile = fopen (OutputFileName, "rb"); + if (OutputFile == NULL) { + Error (NULL, 0, 0, OutputFileName, "failed to open output file for writing"); + IsError = TRUE; + goto Done; + } + + TargetFileBuffer = &FileBuffer[Size]; + SourceDataSize = Size; + + fread (&Temp, sizeof (UINT8), 1, OutputFile); + while (!feof (OutputFile)) { + FileBuffer[Size++] = Temp; + fread (&Temp, sizeof (UINT8), 1, OutputFile); + } + + while ((Size & 0x03) != 0) { + FileBuffer[Size] = 0; + Size++; + } + + SourceDataSize = Size - SourceDataSize; + + fclose (OutputFile); + OutputFile = NULL; + free (OutputFileName); + OutputFileName = NULL; + + if (CompareGuid (&SignGuid, &mZeroGuid) != 0) { + ReturnValue = SourceDataSize; + Status = GenSimpleGuidSection ( + TargetFileBuffer, + &ReturnValue, + SourceDataSize, + SignGuid, + GuidedSectionAttributes + ); + if (EFI_ERROR (Status)) { + IsError = TRUE; + goto Done; + } + + Size = ReturnValue; + } + } + + } else if (Buffer[0] != '}') { + // + // if we are here, we should see either a file name, + // or a }. + // + Index3 = 0; + FileName[0] = 0; + // + // Prepend the build directory to the file name if the + // file name does not already contain a full path. + // + if (!isalpha (Buffer[0]) || (Buffer[1] != ':')) { + sprintf (FileName, "%s\\", BuildDirectory); + } + + while (Buffer[Index3] != '\n') { + if (Buffer[Index3] == '$') { + Index3 += ProcessEnvironmentVariable (&Buffer[Index3], NewBuffer); + strcat (FileName, NewBuffer); + } + + if (Buffer[Index3] == 0) { + break; + } else { + Index2 = strlen (FileName); + FileName[Index2++] = Buffer[Index3++]; + FileName[Index2] = 0; + } + } + + InFile = fopen (FileName, "rb"); + if (InFile == NULL) { + Error (NULL, 0, 0, FileName, "failed to open file for reading"); + IsError = TRUE; + goto Done; + } + + fread (&ByteBuffer, sizeof (UINT8), 1, InFile); + while (!feof (InFile)) { + FileBuffer[Size++] = ByteBuffer; + fread (&ByteBuffer, sizeof (UINT8), 1, InFile); + } + + fclose (InFile); + InFile = NULL; + + // + // Make sure section ends on a DWORD boundary + // + while ((Size & 0x03) != 0) { + FileBuffer[Size] = 0; + Size++; + } + + } + } + +Done: + for (Index3 = 1; Index3 < MAX_ARRAY_SIZE; Index3++) { + if (ToolArgumentsArray[Index3] == NULL) { + break; + } + + free (ToolArgumentsArray[Index3]); + } + + if (IsError) { + return -1; + } + + return Size; + +} + +static +UINT8 +StringToType ( + IN CHAR8 *String + ) +/*++ + +Routine Description: + + Converts File Type String to value. EFI_FV_FILETYPE_ALL indicates that an + unrecognized file type was specified. + +Arguments: + + String - File type string + +Returns: + + File Type Value + +--*/ +{ + if (strcmpi (String, "EFI_FV_FILETYPE_RAW") == 0) { + return EFI_FV_FILETYPE_RAW; + } + + if (strcmpi (String, "EFI_FV_FILETYPE_FREEFORM") == 0) { + return EFI_FV_FILETYPE_FREEFORM; + } + + if (strcmpi (String, "EFI_FV_FILETYPE_SECURITY_CORE") == 0) { + return EFI_FV_FILETYPE_SECURITY_CORE; + } + + if (strcmpi (String, "EFI_FV_FILETYPE_PEI_CORE") == 0) { + return EFI_FV_FILETYPE_PEI_CORE; + } + + if (strcmpi (String, "EFI_FV_FILETYPE_DXE_CORE") == 0) { + return EFI_FV_FILETYPE_DXE_CORE; + } + + if (strcmpi (String, "EFI_FV_FILETYPE_PEIM") == 0) { + return EFI_FV_FILETYPE_PEIM; + } + + if (strcmpi (String, "EFI_FV_FILETYPE_DRIVER") == 0) { + return EFI_FV_FILETYPE_DRIVER; + } + + if (strcmpi (String, "EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER") == 0) { + return EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER; + } + + if (strcmpi (String, "EFI_FV_FILETYPE_APPLICATION") == 0) { + return EFI_FV_FILETYPE_APPLICATION; + } + + if (strcmpi (String, "EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE") == 0) { + return EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE; + } + + return EFI_FV_FILETYPE_ALL; +} + +static +UINT32 +AdjustFileSize ( + IN UINT8 *FileBuffer, + IN UINT32 FileSize + ) +/*++ + +Routine Description: + Adjusts file size to insure sectioned file is exactly the right length such + that it ends on exactly the last byte of the last section. ProcessScript() + may have padded beyond the end of the last section out to a 4 byte boundary. + This padding is stripped. + +Arguments: + FileBuffer - Data Buffer - contains a section stream + FileSize - Size of FileBuffer as returned from ProcessScript() + +Returns: + Corrected size of file. + +--*/ +{ + UINT32 TotalLength; + UINT32 CurrentLength; + UINT32 SectionLength; + UINT32 SectionStreamLength; + EFI_COMMON_SECTION_HEADER *SectionHeader; + EFI_COMMON_SECTION_HEADER *NextSectionHeader; + + TotalLength = 0; + CurrentLength = 0; + SectionStreamLength = FileSize; + + SectionHeader = (EFI_COMMON_SECTION_HEADER *) FileBuffer; + + while (TotalLength < SectionStreamLength) { + SectionLength = *((UINT32 *) SectionHeader->Size) & 0x00ffffff; + TotalLength += SectionLength; + + if (TotalLength == SectionStreamLength) { + return TotalLength; + } + // + // Move to the next byte following the section... + // + SectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) SectionHeader + SectionLength); + CurrentLength = (UINTN) SectionHeader - (UINTN) FileBuffer; + + // + // Figure out where the next section begins + // + NextSectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) SectionHeader + 3); + NextSectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) NextSectionHeader &~ (UINTN) 3); + TotalLength += (UINTN) NextSectionHeader - (UINTN) SectionHeader; + SectionHeader = NextSectionHeader; + } + + return CurrentLength; +} + +static +INT32 +MainEntry ( + INT32 argc, + CHAR8 *argv[], + BOOLEAN ForceUncompress + ) +/*++ + +Routine Description: + + MainEntry function. + +Arguments: + + argc - Number of command line parameters. + argv - Array of pointers to command line parameter strings. + ForceUncompress - If TRUE, force to do not compress the sections even if compression + is specified in the script. Otherwise, FALSE. + +Returns: + STATUS_SUCCESS - Function exits successfully. + STATUS_ERROR - Some error occurred during execution. + +--*/ +{ + FILE *PrimaryPackage; + FILE *OverridePackage; + FILE *Out; + CHAR8 BaseName[_MAX_PATH]; + EFI_GUID FfsGuid; + CHAR8 GuidString[_MAX_PATH]; + EFI_FFS_FILE_HEADER FileHeader; + CHAR8 FileType[_MAX_PATH]; + EFI_FFS_FILE_ATTRIBUTES FfsAttrib; + EFI_FFS_FILE_ATTRIBUTES FfsAttribDefined; + UINT64 FfsAlignment; + UINT32 FfsAlignment32; + CHAR8 InputString[_MAX_PATH]; + BOOLEAN ImageScriptInOveride; + UINT32 FileSize; + UINT8 *FileBuffer; + EFI_STATUS Status; + UINT32 LineNumber; + EFI_FFS_FILE_TAIL TailValue; + + BaseName[0] = 0; + FileType[0] = 0; + FfsAttrib = 0; + FfsAttribDefined = 0; + FfsAlignment = 0; + FfsAlignment32 = 0; + PrimaryPackage = NULL; + Out = NULL; + OverridePackage = NULL; + FileBuffer = NULL; + + strcpy (GuidString, "00000000-0000-0000-0000-000000000000"); + Status = StringToGuid (GuidString, &FfsGuid); + if (Status != 0) { + Error (NULL, 0, 0, GuidString, "error parsing GUID string"); + return STATUS_ERROR; + } + + GuidString[0] = 0; + ImageScriptInOveride = FALSE; + // + // Initialize the simple file parsing routines. Then open + // the primary package file for parsing. + // + SFPInit (); + if (SFPOpenFile (mGlobals.PrimaryPackagePath) != STATUS_SUCCESS) { + Error (NULL, 0, 0, mGlobals.PrimaryPackagePath, "unable to open primary package file"); + goto Done; + } + // + // First token in the file must be "PACKAGE.INF" + // + if (!SFPIsToken ("PACKAGE.INF")) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'PACKAGE.INF'", NULL); + goto Done; + } + // + // Find the [.] section + // + if (!SFPSkipToToken ("[.]")) { + Error (mGlobals.PrimaryPackagePath, 1, 0, "could not locate [.] section in package file", NULL); + goto Done; + } + // + // Start parsing the data. The algorithm is essentially the same for each keyword: + // 1. Identify the keyword + // 2. Verify that the keyword/value pair has not already been defined + // 3. Set some flag indicating that the keyword/value pair has been defined + // 4. Skip over the "=" + // 5. Get the value, which may be a number, TRUE, FALSE, or a string. + // + while (1) { + if (SFPIsToken ("BASE_NAME")) { + // + // Found BASE_NAME, format: + // BASE_NAME = MyBaseName + // + if (BaseName[0] != 0) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "BASE_NAME already defined", NULL); + goto Done; + } + + if (!SFPIsToken ("=")) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL); + goto Done; + } + + if (!SFPGetNextToken (BaseName, sizeof (BaseName))) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected valid base name", NULL); + goto Done; + } + } else if (SFPIsToken ("IMAGE_SCRIPT")) { + // + // Found IMAGE_SCRIPT. Break out and process below. + // + break; + } else if (SFPIsToken ("FFS_FILEGUID")) { + // + // found FILEGUID, format: + // FFS_FILEGUID = F7845C4F-EDF5-42C5-BD8F-A02AF63DD93A + // + if (GuidString[0] != 0) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_FILEGUID already defined", NULL); + goto Done; + } + + if (!SFPIsToken ("=")) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL); + goto Done; + } + + if (SFPGetGuidToken (GuidString, sizeof (GuidString)) != TRUE) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected file GUID", NULL); + goto Done; + } + + Status = StringToGuid (GuidString, &FfsGuid); + if (Status != 0) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected valid file GUID", NULL); + goto Done; + } + } else if (SFPIsToken ("FFS_FILETYPE")) { + // + // *********************************************************************** + // + // Found FFS_FILETYPE, format: + // FFS_FILETYPE = EFI_FV_FILETYPE_APPLICATION + // + if (FileType[0] != 0) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_FILETYPE previously defined", NULL); + goto Done; + } + + if (!SFPIsToken ("=")) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL); + goto Done; + } + + if (!SFPGetNextToken (FileType, sizeof (FileType))) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected valid FFS_FILETYPE", NULL); + goto Done; + } + } else if (SFPIsToken ("FFS_ATTRIB_HEADER_EXTENSION")) { + // + // *********************************************************************** + // + // Found: FFS_ATTRIB_HEADER_EXTENSION = FALSE + // Spec says the bit is for future expansion, and must be false. + // + if (FfsAttribDefined & FFS_ATTRIB_HEADER_EXTENSION) { + Error ( + mGlobals.PrimaryPackagePath, + SFPGetLineNumber (), + 0, + "FFS_ATTRIB_HEADER_EXTENSION previously defined", + NULL + ); + goto Done; + } + + FfsAttribDefined |= FFS_ATTRIB_HEADER_EXTENSION; + if (!SFPIsToken ("=")) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL); + goto Done; + } + + if (SFPIsToken ("TRUE")) { + Error ( + mGlobals.PrimaryPackagePath, + SFPGetLineNumber (), + 0, + "only FFS_ATTRIB_HEADER_EXTENSION = FALSE is supported", + NULL + ); + goto Done; + } else if (SFPIsToken ("FALSE")) { + // + // Default is FALSE + // + } else { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'FALSE'", NULL); + goto Done; + } + } else if (SFPIsToken ("FFS_ATTRIB_TAIL_PRESENT")) { + // + // *********************************************************************** + // + // Found: FFS_ATTRIB_TAIL_PRESENT = TRUE | FALSE + // + if (FfsAttribDefined & FFS_ATTRIB_TAIL_PRESENT) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_ATTRIB_TAIL_PRESENT previously defined", NULL); + goto Done; + } + + FfsAttribDefined |= FFS_ATTRIB_TAIL_PRESENT; + if (!SFPIsToken ("=")) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL); + goto Done; + } + + if (SFPIsToken ("TRUE")) { + FfsAttrib |= FFS_ATTRIB_TAIL_PRESENT; + } else if (SFPIsToken ("FALSE")) { + // + // Default is FALSE + // + } else { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL); + goto Done; + } + } else if (SFPIsToken ("FFS_ATTRIB_RECOVERY")) { + // + // *********************************************************************** + // + // Found: FFS_ATTRIB_RECOVERY = TRUE | FALSE + // + if (FfsAttribDefined & FFS_ATTRIB_RECOVERY) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_ATTRIB_RECOVERY previously defined", NULL); + goto Done; + } + + FfsAttribDefined |= FFS_ATTRIB_RECOVERY; + if (!SFPIsToken ("=")) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL); + goto Done; + } + + if (SFPIsToken ("TRUE")) { + FfsAttrib |= FFS_ATTRIB_RECOVERY; + } else if (SFPIsToken ("FALSE")) { + // + // Default is FALSE + // + } else { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL); + goto Done; + } + } else if (SFPIsToken ("FFS_ATTRIB_CHECKSUM")) { + // + // *********************************************************************** + // + // Found: FFS_ATTRIB_CHECKSUM = TRUE | FALSE + // + if (FfsAttribDefined & FFS_ATTRIB_CHECKSUM) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_ATTRIB_CHECKSUM previously defined", NULL); + goto Done; + } + + FfsAttribDefined |= FFS_ATTRIB_CHECKSUM; + if (!SFPIsToken ("=")) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL); + goto Done; + } + + if (SFPIsToken ("TRUE")) { + FfsAttrib |= FFS_ATTRIB_CHECKSUM; + } else if (SFPIsToken ("FALSE")) { + // + // Default is FALSE + // + } else { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL); + goto Done; + } + } else if (SFPIsToken ("FFS_ALIGNMENT") || SFPIsToken ("FFS_ATTRIB_DATA_ALIGNMENT")) { + // + // *********************************************************************** + // + // Found FFS_ALIGNMENT, formats: + // FFS_ALIGNMENT = 0-7 + // FFS_ATTRIB_DATA_ALIGNMENT = 0-7 + // + if (FfsAttribDefined & FFS_ATTRIB_DATA_ALIGNMENT) { + Error ( + mGlobals.PrimaryPackagePath, + SFPGetLineNumber (), + 0, + "FFS_ALIGNMENT/FFS_ATTRIB_DATA_ALIGNMENT previously defined", + NULL + ); + goto Done; + } + + FfsAttribDefined |= FFS_ATTRIB_DATA_ALIGNMENT; + if (!SFPIsToken ("=")) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL); + goto Done; + } + + if (!SFPGetNumber (&FfsAlignment32)) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected numeric value for alignment", NULL); + goto Done; + } + + if (FfsAlignment32 > 7) { + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 0 <= alignment <= 7", NULL); + goto Done; + } + + FfsAttrib |= (((EFI_FFS_FILE_ATTRIBUTES) FfsAlignment32) << 3); + } else { + SFPGetNextToken (InputString, sizeof (InputString)); + Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, InputString, "unrecognized/unexpected token"); + goto Done; + } + } + // + // Close the primary package file + // + SFPCloseFile (); + // + // TODO: replace code below with basically a copy of the code above. Don't + // forget to reset the FfsAttribDefined variable first. Also, you'll need + // to somehow keep track of whether or not the basename is defined multiple + // times in the override package. Ditto on the file GUID. + // + if (mGlobals.OverridePackagePath[0] != 0) { + OverridePackage = fopen (mGlobals.OverridePackagePath, "r"); + // + // NOTE: For package override to work correctly, the code below must be modified to + // SET or CLEAR bits properly. For example, if the primary package set + // FFS_ATTRIB_CHECKSUM = TRUE, and the override set FFS_ATTRIB_CHECKSUM = FALSE, then + // we'd need to clear the bit below. Since this is not happening, I'm guessing that + // the override functionality is not being used, so should be made obsolete. If I'm + // wrong, and it is being used, then it needs to be fixed. Thus emit an error if it is + // used, and we'll address it then. 4/10/2003 + // + Error (__FILE__, __LINE__, 0, "package override functionality is not implemented correctly", NULL); + goto Done; + } else { + OverridePackage = NULL; + } + +#ifdef OVERRIDE_SUPPORTED + if (OverridePackage != NULL) { + // + // Parse override package file + // + fscanf (OverridePackage, "%s", &InputString); + if (strcmpi (InputString, "PACKAGE.INF") != 0) { + Error (mGlobals.OverridePackagePath, 1, 0, "invalid package file", "expected 'PACKAGE.INF'"); + goto Done; + } + // + // Match [dir] to Build Directory + // + if (FindSectionInPackage (mGlobals.BuildDirectory, OverridePackage, &LineNumber) != 0) { + Error (mGlobals.OverridePackagePath, 1, 0, mGlobals.BuildDirectory, "section not found in package file"); + goto Done; + } + + InputString[0] = 0; + while ((InputString[0] != '[') && (!feof (OverridePackage))) { + if (GetNextLine (InputString, OverridePackage, &LineNumber) != -1) { + if (InputString[0] != '[') { +here: + if (strcmpi (InputString, "BASE_NAME") == 0) { + // + // found BASE_NAME, next is = and string. + // + fscanf (OverridePackage, "%s", &InputString); + CheckSlash (InputString, OverridePackage, &LineNumber); + if (strlen (InputString) == 1) { + // + // string is just = + // + fscanf (OverridePackage, "%s", &InputString); + CheckSlash (InputString, OverridePackage, &LineNumber); + strcpy (BaseName, InputString); + } else { + BreakString (InputString, InputString, 1); + strcpy (BaseName, InputString); + } + } else if (strcmpi (InputString, "IMAGE_SCRIPT") == 0) { + // + // found IMAGE_SCRIPT, come back later to process it + // + ImageScriptInOveride = TRUE; + fscanf (OverridePackage, "%s", &InputString); + } else if (strcmpi (InputString, "FFS_FILEGUID") == 0) { + // + // found FILEGUID, next is = and string. + // + fscanf (OverridePackage, "%s", &InputString); + CheckSlash (InputString, OverridePackage, &LineNumber); + if (strlen (InputString) == 1) { + // + // string is just = + // + fscanf (OverridePackage, "%s", &InputString); + CheckSlash (InputString, OverridePackage, &LineNumber); + Status = StringToGuid (InputString, &FfsGuid); + if (Status != 0) { + Error (mGlobals.OverridePackagePath, 1, 0, InputString, "bad FFS_FILEGUID format"); + goto Done; + } + } else { + BreakString (InputString, InputString, 1); + Status = StringToGuid (InputString, &FfsGuid); + if (Status != 0) { + Error (mGlobals.OverridePackagePath, 1, 0, InputString, "bad FFS_FILEGUID format"); + goto Done; + } + } + } else if (strcmpi (InputString, "FFS_FILETYPE") == 0) { + // + // found FILETYPE, next is = and string. + // + fscanf (OverridePackage, "%s", &InputString); + CheckSlash (InputString, OverridePackage, &LineNumber); + if (strlen (InputString) == 1) { + // + // string is just = + // + fscanf (OverridePackage, "%s", &InputString); + CheckSlash (InputString, OverridePackage, &LineNumber); + strcpy (FileType, InputString); + } else { + BreakString (InputString, InputString, 1); + strcpy (FileType, InputString); + } + + } else if (strcmpi (InputString, "FFS_ATTRIB_RECOVERY") == 0) { + // + // found FFS_ATTRIB_RECOVERY, next is = and string. + // + fscanf (OverridePackage, "%s", &InputString); + CheckSlash (InputString, OverridePackage, &LineNumber); + if (strlen (InputString) == 1) { + // + // string is just = + // + fscanf (OverridePackage, "%s", &InputString); + CheckSlash (InputString, OverridePackage, &LineNumber); + if (strcmpi (InputString, "TRUE") == 0) { + FfsAttrib |= FFS_ATTRIB_RECOVERY; + } + } else { + BreakString (InputString, InputString, 1); + if (strcmpi (InputString, "TRUE") == 0) { + FfsAttrib |= FFS_ATTRIB_RECOVERY; + } + } + } else if (strcmpi (InputString, "FFS_ATTRIB_CHECKSUM") == 0) { + // + // found FFS_ATTRIB_CHECKSUM, next is = and string. + // + fscanf (OverridePackage, "%s", &InputString); + CheckSlash (InputString, OverridePackage, &LineNumber); + if (strlen (InputString) == 1) { + // + // string is just = + // + fscanf (OverridePackage, "%s", &InputString); + CheckSlash (InputString, OverridePackage, &LineNumber); + if (strcmpi (InputString, "TRUE") == 0) { + FfsAttrib |= FFS_ATTRIB_CHECKSUM; + } + } else { + BreakString (InputString, InputString, 1); + if (strcmpi (InputString, "TRUE") == 0) { + FfsAttrib |= FFS_ATTRIB_CHECKSUM; + } + } + } else if (strcmpi (InputString, "FFS_ALIGNMENT") == 0) { + // + // found FFS_ALIGNMENT, next is = and string. + // + fscanf (OverridePackage, "%s", &InputString); + CheckSlash (InputString, OverridePackage, &LineNumber); + if (strlen (InputString) == 1) { + // + // string is just = + // + fscanf (OverridePackage, "%s", &InputString); + CheckSlash (InputString, OverridePackage, &LineNumber); + } else { + BreakString (InputString, InputString, 1); + } + + AsciiStringToUint64 (InputString, FALSE, &FfsAlignment); + if (FfsAlignment > 7) { + Error (mGlobals.OverridePackagePath, 1, 0, InputString, "invalid FFS_ALIGNMENT value"); + goto Done; + } + + FfsAttrib |= (((EFI_FFS_FILE_ATTRIBUTES) FfsAlignment) << 3); + } else if (strchr (InputString, '=') != NULL) { + BreakString (InputString, String, 1); + fseek (OverridePackage, (-1 * (strlen (String) + 1)), SEEK_CUR); + BreakString (InputString, InputString, 0); + goto here; + } + } + } + } + } +#endif // #ifdef OVERRIDE_SUPPORTED + // + // Require that they specified a file GUID at least, since that's how we're + // naming the file. + // + if (GuidString[0] == 0) { + Error (mGlobals.PrimaryPackagePath, 1, 0, "FFS_FILEGUID must be specified", NULL); + return STATUS_ERROR; + } + // + // Build Header and process image script + // + FileBuffer = (UINT8 *) malloc ((1024 * 1024 * 16) * sizeof (UINT8)); + if (FileBuffer == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failed", NULL); + goto Done; + } + + FileSize = 0; + if (ImageScriptInOveride) { +#ifdef OVERRIDE_SUPORTED + rewind (OverridePackage); + LineNumber = 0; + FindSectionInPackage (mGlobals.BuildDirectory, OverridePackage, &LineNumber); + while (strcmpi (InputString, "IMAGE_SCRIPT") != 0) { + GetNextLine (InputString, OverridePackage, &LineNumber); + CheckSlash (InputString, OverridePackage, &LineNumber); + if (strchr (InputString, '=') != NULL) { + BreakString (InputString, InputString, 0); + } + } + + while (InputString[0] != '{') { + GetNextLine (InputString, OverridePackage, &LineNumber); + CheckSlash (InputString, OverridePackage, &LineNumber); + } + // + // Found start of image script, process it + // + FileSize += ProcessScript (FileBuffer, OverridePackage, mGlobals.BuildDirectory, ForceUncompress); + if (FileSize == -1) { + return -1; + } + + if (StringToType (FileType) != EFI_FV_FILETYPE_RAW) { + FileSize = AdjustFileSize (FileBuffer, FileSize); + } + + if (BaseName[0] == '\"') { + StripQuotes (BaseName); + } + + if (BaseName[0] != 0) { + sprintf (InputString, "%s-%s", GuidString, BaseName); + } else { + strcpy (InputString, GuidString); + } + + switch (StringToType (FileType)) { + + case EFI_FV_FILETYPE_SECURITY_CORE: + strcat (InputString, ".SEC"); + break; + + case EFI_FV_FILETYPE_PEIM: + case EFI_FV_FILETYPE_PEI_CORE: + case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER: + strcat (InputString, ".PEI"); + break; + + case EFI_FV_FILETYPE_DRIVER: + case EFI_FV_FILETYPE_DXE_CORE: + strcat (InputString, ".DXE"); + break; + + case EFI_FV_FILETYPE_APPLICATION: + strcat (InputString, ".APP"); + break; + + case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE: + strcat (InputString, ".FVI"); + break; + + case EFI_FV_FILETYPE_ALL: + Error (mGlobals.OverridePackagePath, 1, 0, "invalid FFS file type for this utility", NULL); + goto Done; + + default: + strcat (InputString, ".FFS"); + break; + } + + if (ForceUncompress) { + strcat (InputString, ".ORG"); + } + + Out = fopen (InputString, "wb"); + if (Out == NULL) { + Error (NULL, 0, 0, InputString, "could not open output file for writing"); + goto Done; + } + // + // create ffs header + // + memset (&FileHeader, 0, sizeof (EFI_FFS_FILE_HEADER)); + memcpy (&FileHeader.Name, &FfsGuid, sizeof (EFI_GUID)); + FileHeader.Type = StringToType (FileType); + FileHeader.Attributes = FfsAttrib; + // + // Now FileSize includes the EFI_FFS_FILE_HEADER + // + FileSize += sizeof (EFI_FFS_FILE_HEADER); + FileHeader.Size[0] = (UINT8) (FileSize & 0xFF); + FileHeader.Size[1] = (UINT8) ((FileSize & 0xFF00) >> 8); + FileHeader.Size[2] = (UINT8) ((FileSize & 0xFF0000) >> 16); + // + // Fill in checksums and state, these must be zero for checksumming + // + // FileHeader.IntegrityCheck.Checksum.Header = 0; + // FileHeader.IntegrityCheck.Checksum.File = 0; + // FileHeader.State = 0; + // + FileHeader.IntegrityCheck.Checksum.Header = CalculateChecksum8 ( + (UINT8 *) &FileHeader, + sizeof (EFI_FFS_FILE_HEADER) + ); + if (FileHeader.Attributes & FFS_ATTRIB_CHECKSUM) { + FileHeader.IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) &FileHeader, FileSize); + } else { + FileHeader.IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; + } + + FileHeader.State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID; + // + // write header + // + if (fwrite (&FileHeader, sizeof (FileHeader), 1, Out) != 1) { + Error (NULL, 0, 0, "failed to write file header to output file", NULL); + goto Done; + } + // + // write data + // + if (fwrite (FileBuffer, FileSize - sizeof (EFI_FFS_FILE_HEADER), 1, Out) != 1) { + Error (NULL, 0, 0, "failed to write all bytes to output file", NULL); + goto Done; + } + + fclose (Out); + Out = NULL; +#endif // #ifdef OVERRIDE_SUPPORTED + } else { + // + // Open primary package file and process the IMAGE_SCRIPT section + // + PrimaryPackage = fopen (mGlobals.PrimaryPackagePath, "r"); + if (PrimaryPackage == NULL) { + Error (NULL, 0, 0, mGlobals.PrimaryPackagePath, "unable to open primary package file"); + goto Done; + } + + LineNumber = 1; + FindSectionInPackage (".", PrimaryPackage, &LineNumber); + while (strcmpi (InputString, "IMAGE_SCRIPT") != 0) { + GetNextLine (InputString, PrimaryPackage, &LineNumber); + CheckSlash (InputString, PrimaryPackage, &LineNumber); + if (strchr (InputString, '=') != NULL) { + BreakString (InputString, InputString, 0); + } + } + + while (InputString[0] != '{') { + GetNextLine (InputString, PrimaryPackage, &LineNumber); + CheckSlash (InputString, PrimaryPackage, &LineNumber); + } + // + // Found start of image script, process it + // + FileSize += ProcessScript (FileBuffer, PrimaryPackage, mGlobals.BuildDirectory, ForceUncompress); + if (FileSize == -1) { + goto Done; + } + + if (StringToType (FileType) != EFI_FV_FILETYPE_RAW) { + FileSize = AdjustFileSize (FileBuffer, FileSize); + } + + if (BaseName[0] == '\"') { + StripQuotes (BaseName); + } + + if (BaseName[0] != 0) { + sprintf (InputString, "%s-%s", GuidString, BaseName); + } else { + strcpy (InputString, GuidString); + } + + switch (StringToType (FileType)) { + + case EFI_FV_FILETYPE_SECURITY_CORE: + strcat (InputString, ".SEC"); + break; + + case EFI_FV_FILETYPE_PEIM: + case EFI_FV_FILETYPE_PEI_CORE: + case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER: + strcat (InputString, ".PEI"); + break; + + case EFI_FV_FILETYPE_DRIVER: + case EFI_FV_FILETYPE_DXE_CORE: + strcat (InputString, ".DXE"); + break; + + case EFI_FV_FILETYPE_APPLICATION: + strcat (InputString, ".APP"); + break; + + case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE: + strcat (InputString, ".FVI"); + break; + + case EFI_FV_FILETYPE_ALL: + Error (mGlobals.PrimaryPackagePath, 1, 0, "invalid FFS file type for this utility", NULL); + goto Done; + + default: + strcat (InputString, ".FFS"); + break; + } + + if (ForceUncompress) { + strcat (InputString, ".ORG"); + } + + Out = fopen (InputString, "wb"); + if (Out == NULL) { + Error (NULL, 0, 0, InputString, "failed to open output file for writing"); + goto Done; + } + // + // Initialize the FFS file header + // + memset (&FileHeader, 0, sizeof (EFI_FFS_FILE_HEADER)); + memcpy (&FileHeader.Name, &FfsGuid, sizeof (EFI_GUID)); + FileHeader.Type = StringToType (FileType); + FileHeader.Attributes = FfsAttrib; + // + // From this point on FileSize includes the size of the EFI_FFS_FILE_HEADER + // + FileSize += sizeof (EFI_FFS_FILE_HEADER); + // + // If using a tail, then it adds two bytes + // + if (FileHeader.Attributes & FFS_ATTRIB_TAIL_PRESENT) { + // + // Tail is not allowed for pad and 0-length files + // + if ((FileHeader.Type == EFI_FV_FILETYPE_FFS_PAD) || (FileSize == sizeof (EFI_FFS_FILE_HEADER))) { + Error ( + mGlobals.PrimaryPackagePath, + 1, + 0, + "FFS_ATTRIB_TAIL_PRESENT=TRUE is invalid for PAD or 0-length files", + NULL + ); + goto Done; + } + + FileSize += sizeof (EFI_FFS_FILE_TAIL); + } + + FileHeader.Size[0] = (UINT8) (FileSize & 0xFF); + FileHeader.Size[1] = (UINT8) ((FileSize & 0xFF00) >> 8); + FileHeader.Size[2] = (UINT8) ((FileSize & 0xFF0000) >> 16); + // + // Fill in checksums and state, they must be 0 for checksumming. + // + // FileHeader.IntegrityCheck.Checksum.Header = 0; + // FileHeader.IntegrityCheck.Checksum.File = 0; + // FileHeader.State = 0; + // + FileHeader.IntegrityCheck.Checksum.Header = CalculateChecksum8 ( + (UINT8 *) &FileHeader, + sizeof (EFI_FFS_FILE_HEADER) + ); + if (FileHeader.Attributes & FFS_ATTRIB_CHECKSUM) { + // + // Cheating here. Since the header checksums, just calculate the checksum of the body. + // Checksum does not include the tail + // + if (FileHeader.Attributes & FFS_ATTRIB_TAIL_PRESENT) { + FileHeader.IntegrityCheck.Checksum.File = CalculateChecksum8 ( + FileBuffer, + FileSize - sizeof (EFI_FFS_FILE_HEADER) - sizeof (EFI_FFS_FILE_TAIL) + ); + } else { + FileHeader.IntegrityCheck.Checksum.File = CalculateChecksum8 ( + FileBuffer, + FileSize - sizeof (EFI_FFS_FILE_HEADER) + ); + } + } else { + FileHeader.IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; + } + // + // Set the state now. Spec says the checksum assumes the state is 0 + // + FileHeader.State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID; + // + // If there is a tail, then set it + // + if (FileHeader.Attributes & FFS_ATTRIB_TAIL_PRESENT) { + TailValue = FileHeader.IntegrityCheck.TailReference; + TailValue = (UINT16) (~TailValue); + memcpy ( + (UINT8 *) FileBuffer + FileSize - sizeof (EFI_FFS_FILE_HEADER) - sizeof (EFI_FFS_FILE_TAIL), + &TailValue, + sizeof (TailValue) + ); + } + // + // Write the FFS file header + // + if (fwrite (&FileHeader, sizeof (FileHeader), 1, Out) != 1) { + Error (NULL, 0, 0, "failed to write file header contents", NULL); + goto Done; + } + // + // Write data + // + if (fwrite (FileBuffer, FileSize - sizeof (EFI_FFS_FILE_HEADER), 1, Out) != 1) { + Error (NULL, 0, 0, "failed to write file contents", NULL); + goto Done; + } + } + +Done: + SFPCloseFile (); + if (Out != NULL) { + fclose (Out); + } + + if (PrimaryPackage != NULL) { + fclose (PrimaryPackage); + } + + if (FileBuffer != NULL) { + free (FileBuffer); + } + + if (OverridePackage != NULL) { + fclose (OverridePackage); + } + + return GetUtilityStatus (); +} + +int +main ( + INT32 argc, + CHAR8 *argv[] + ) +/*++ + +Routine Description: + + Main function. + +Arguments: + + argc - Number of command line parameters. + argv - Array of pointers to parameter strings. + +Returns: + STATUS_SUCCESS - Utility exits successfully. + STATUS_ERROR - Some error occurred during execution. + +--*/ +{ + STATUS Status; + // + // Set the name of our utility for error reporting purposes. + // + SetUtilityName (UTILITY_NAME); + Status = ProcessCommandLineArgs (argc, argv); + if (Status != STATUS_SUCCESS) { + return Status; + } + + Status = MainEntry (argc, argv, TRUE); + if (Status == STATUS_SUCCESS) { + MainEntry (argc, argv, FALSE); + } + // + // If any errors were reported via the standard error reporting + // routines, then the status has been saved. Get the value and + // return it to the caller. + // + return GetUtilityStatus (); +} + +static +STATUS +ProcessCommandLineArgs ( + int Argc, + char *Argv[] + ) +/*++ + +Routine Description: + Process the command line arguments. + +Arguments: + Argc - as passed in to main() + Argv - as passed in to main() + +Returns: + STATUS_SUCCESS - arguments all ok + STATUS_ERROR - problem with args, so caller should exit + +--*/ +{ + // + // If no args, then print usage instructions and return an error + // + if (Argc == 1) { + PrintUsage (); + return STATUS_ERROR; + } + + memset (&mGlobals, 0, sizeof (mGlobals)); + Argc--; + Argv++; + while (Argc > 0) { + if (strcmpi (Argv[0], "-b") == 0) { + // + // OPTION: -b BuildDirectory + // Make sure there is another argument, then save it to our globals. + // + if (Argc < 2) { + Error (NULL, 0, 0, "-b option requires the build directory name", NULL); + return STATUS_ERROR; + } + + if (mGlobals.BuildDirectory[0]) { + Error (NULL, 0, 0, Argv[0], "option can only be specified once"); + return STATUS_ERROR; + } + + strcpy (mGlobals.BuildDirectory, Argv[1]); + Argc--; + Argv++; + } else if (strcmpi (Argv[0], "-p1") == 0) { + // + // OPTION: -p1 PrimaryPackageFile + // Make sure there is another argument, then save it to our globals. + // + if (Argc < 2) { + Error (NULL, 0, 0, Argv[0], "option requires the primary package file name"); + return STATUS_ERROR; + } + + if (mGlobals.PrimaryPackagePath[0]) { + Error (NULL, 0, 0, Argv[0], "option can only be specified once"); + return STATUS_ERROR; + } + + strcpy (mGlobals.PrimaryPackagePath, Argv[1]); + Argc--; + Argv++; + } else if (strcmpi (Argv[0], "-p2") == 0) { + // + // OPTION: -p2 OverridePackageFile + // Make sure there is another argument, then save it to our globals. + // + if (Argc < 2) { + Error (NULL, 0, 0, Argv[0], "option requires the override package file name"); + return STATUS_ERROR; + } + + if (mGlobals.OverridePackagePath[0]) { + Error (NULL, 0, 0, Argv[0], "option can only be specified once"); + return STATUS_ERROR; + } + + strcpy (mGlobals.OverridePackagePath, Argv[1]); + Argc--; + Argv++; + } else if (strcmpi (Argv[0], "-v") == 0) { + // + // OPTION: -v verbose + // + mGlobals.Verbose = TRUE; + } else if (strcmpi (Argv[0], "-h") == 0) { + // + // OPTION: -h help + // + PrintUsage (); + return STATUS_ERROR; + } else if (strcmpi (Argv[0], "-?") == 0) { + // + // OPTION: -? help + // + PrintUsage (); + return STATUS_ERROR; + } else { + Error (NULL, 0, 0, Argv[0], "unrecognized option"); + PrintUsage (); + return STATUS_ERROR; + } + + Argv++; + Argc--; + } + // + // Must have at least specified the package file name + // + if (mGlobals.PrimaryPackagePath[0] == 0) { + Error (NULL, 0, 0, "must specify primary package file", NULL); + return STATUS_ERROR; + } + + return STATUS_SUCCESS; +} diff --git a/Tools/CodeTools/Source/GenFfsFile/GenFfsFile.h b/Tools/CodeTools/Source/GenFfsFile/GenFfsFile.h new file mode 100644 index 0000000000..f5bc718716 --- /dev/null +++ b/Tools/CodeTools/Source/GenFfsFile/GenFfsFile.h @@ -0,0 +1,36 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + GenFfsFile.h + +Abstract: + + Header file for GenFfsFile. + +--*/ + +// +// Module Coded to Tiano Coding Conventions +// +#ifndef _EFI_GEN_FFSFILE_H +#define _EFI_GEN_FFSFILE_H + +// +// External Files Referenced +// +#include +#include + +#include "MyAlloc.h" + +#endif diff --git a/Tools/CodeTools/Source/GenFfsFile/SimpleFileParsing.c b/Tools/CodeTools/Source/GenFfsFile/SimpleFileParsing.c new file mode 100644 index 0000000000..5fa5a22096 --- /dev/null +++ b/Tools/CodeTools/Source/GenFfsFile/SimpleFileParsing.c @@ -0,0 +1,969 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + SimpleFileParsing.c + +Abstract: + + Generic but simple file parsing routines. + +--*/ + +#include +#include +#include +#include + +#include + +#include "EfiUtilityMsgs.h" +#include "SimpleFileParsing.h" + +#define MAX_PATH 255 +#define MAX_NEST_DEPTH 20 // just in case we get in an endless loop. +#define MAX_STRING_IDENTIFIER_NAME 100 // number of wchars +#define MAX_LINE_LEN 400 + +#define T_CHAR_SPACE ' ' +#define T_CHAR_NULL 0 +#define T_CHAR_CR '\r' +#define T_CHAR_TAB '\t' +#define T_CHAR_LF '\n' +#define T_CHAR_SLASH '/' +#define T_CHAR_BACKSLASH '\\' +#define T_CHAR_DOUBLE_QUOTE '"' +#define T_CHAR_LC_X 'x' +#define T_CHAR_0 '0' + +// +// We keep a linked list of these for the source files we process +// +typedef struct _SOURCE_FILE { + FILE *Fptr; + T_CHAR *FileBuffer; + T_CHAR *FileBufferPtr; + UINT32 FileSize; + INT8 FileName[MAX_PATH]; + UINT32 LineNum; + BOOLEAN EndOfFile; + BOOLEAN SkipToHash; + struct _SOURCE_FILE *Previous; + struct _SOURCE_FILE *Next; + T_CHAR ControlCharacter; +} SOURCE_FILE; + +// +// Here's all our module globals. +// +static struct { + SOURCE_FILE SourceFile; + BOOLEAN Verbose; +} mGlobals; + +static +UINT32 +t_strcmp ( + T_CHAR *Buffer, + T_CHAR *Str + ); + +static +UINT32 +t_strncmp ( + T_CHAR *Str1, + T_CHAR *Str2, + UINT32 Len + ); + +static +UINT32 +t_strlen ( + T_CHAR *Str + ); + +static +void +RewindFile ( + SOURCE_FILE *SourceFile + ); + +static +BOOLEAN +SkipTo ( + SOURCE_FILE *SourceFile, + T_CHAR TChar, + BOOLEAN StopAfterNewline + ); + +static +BOOLEAN +IsWhiteSpace ( + SOURCE_FILE *SourceFile + ); + +static +UINT32 +SkipWhiteSpace ( + SOURCE_FILE *SourceFile + ); + +static +BOOLEAN +EndOfFile ( + SOURCE_FILE *SourceFile + ); + +static +void +PreprocessFile ( + SOURCE_FILE *SourceFile + ); + +// +// static +// T_CHAR * +// GetQuotedString ( +// SOURCE_FILE *SourceFile, +// BOOLEAN Optional +// ); +// +static +T_CHAR * +t_strcpy ( + T_CHAR *Dest, + T_CHAR *Src + ); + +static +STATUS +ProcessIncludeFile ( + SOURCE_FILE *SourceFile, + SOURCE_FILE *ParentSourceFile + ); + +static +STATUS +ParseFile ( + SOURCE_FILE *SourceFile + ); + +static +FILE * +FindFile ( + IN INT8 *FileName, + OUT INT8 *FoundFileName, + IN UINT32 FoundFileNameLen + ); + +static +STATUS +ProcessFile ( + SOURCE_FILE *SourceFile + ); + +STATUS +SFPInit ( + VOID + ) +{ + memset ((void *) &mGlobals, 0, sizeof (mGlobals)); + return STATUS_SUCCESS; +} + +UINT32 +SFPGetLineNumber ( + VOID + ) +{ + return mGlobals.SourceFile.LineNum; +} + +/*++ + +Routine Description: + Return the line number of the file we're parsing. Used + for error reporting purposes. + +Arguments: + None. + +Returns: + The line number, or 0 if no file is being processed + +--*/ +T_CHAR * +SFPGetFileName ( + VOID + ) +/*++ + +Routine Description: + Return the name of the file we're parsing. Used + for error reporting purposes. + +Arguments: + None. + +Returns: + A pointer to the file name. Null if no file is being + processed. + +--*/ +{ + if (mGlobals.SourceFile.FileName[0]) { + return mGlobals.SourceFile.FileName; + } + + return NULL; +} + +STATUS +SFPOpenFile ( + IN INT8 *FileName + ) +/*++ + +Routine Description: + Open a file for parsing. + +Arguments: + FileName - name of the file to parse + +Returns: + + +--*/ +{ + STATUS Status; + t_strcpy (mGlobals.SourceFile.FileName, FileName); + Status = ProcessIncludeFile (&mGlobals.SourceFile, NULL); + return Status; +} + +BOOLEAN +SFPIsToken ( + T_CHAR *Str + ) +/*++ + +Routine Description: + Check to see if the specified token is found at + the current position in the input file. + +Arguments: + Str - the token to look for + +Returns: + TRUE - the token is next + FALSE - the token is not next + +Notes: + We do a simple string comparison on this function. It is + the responsibility of the caller to ensure that the token + is not a subset of some other token. + + The file pointer is advanced past the token in the input file. + +--*/ +{ + UINT32 Len; + SkipWhiteSpace (&mGlobals.SourceFile); + + if ((Len = t_strcmp (mGlobals.SourceFile.FileBufferPtr, Str)) > 0) { + mGlobals.SourceFile.FileBufferPtr += Len; + return TRUE; + } + + return FALSE; + +} + +BOOLEAN +SFPGetNextToken ( + T_CHAR *Str, + UINT32 Len + ) +{ + UINT32 Index; + SkipWhiteSpace (&mGlobals.SourceFile); + Index = 0; + while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) { + if (IsWhiteSpace (&mGlobals.SourceFile)) { + if (Index > 0) { + Str[Index] = 0; + return TRUE; + } + + return FALSE; + } else { + Str[Index] = mGlobals.SourceFile.FileBufferPtr[0]; + mGlobals.SourceFile.FileBufferPtr++; + Index++; + } + } + + return FALSE; +} + +BOOLEAN +SFPSkipToToken ( + T_CHAR *Str + ) +{ + UINT32 Len; + T_CHAR *SavePos; + Len = t_strlen (Str); + SavePos = mGlobals.SourceFile.FileBufferPtr; + SkipWhiteSpace (&mGlobals.SourceFile); + while (!EndOfFile (&mGlobals.SourceFile)) { + if (t_strncmp (Str, mGlobals.SourceFile.FileBufferPtr, Len) == 0) { + mGlobals.SourceFile.FileBufferPtr += Len; + return TRUE; + } + + mGlobals.SourceFile.FileBufferPtr++; + SkipWhiteSpace (&mGlobals.SourceFile); + } + + mGlobals.SourceFile.FileBufferPtr = SavePos; + return FALSE; +} + +BOOLEAN +SFPGetNumber ( + UINT32 *Value + ) +/*++ + +Routine Description: + Check the token at the current file position for a numeric value. + May be either decimal or hex. + +Arguments: + Value - pointer where to store the value + +Returns: + FALSE - current token is not a number + TRUE - current token is a number + +--*/ +{ + // + // UINT32 Len; + // + SkipWhiteSpace (&mGlobals.SourceFile); + if (EndOfFile (&mGlobals.SourceFile)) { + return FALSE; + } + + if (isdigit (mGlobals.SourceFile.FileBufferPtr[0])) { + // + // Check for hex value + // + if ((mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_0) && (mGlobals.SourceFile.FileBufferPtr[1] == T_CHAR_LC_X)) { + if (!isxdigit (mGlobals.SourceFile.FileBufferPtr[2])) { + return FALSE; + } + + mGlobals.SourceFile.FileBufferPtr += 2; + sscanf (mGlobals.SourceFile.FileBufferPtr, "%x", Value); + while (isxdigit (mGlobals.SourceFile.FileBufferPtr[0])) { + mGlobals.SourceFile.FileBufferPtr++; + } + + return TRUE; + } else { + *Value = atoi (mGlobals.SourceFile.FileBufferPtr); + while (isdigit (mGlobals.SourceFile.FileBufferPtr[0])) { + mGlobals.SourceFile.FileBufferPtr++; + } + + return TRUE; + } + } else { + return FALSE; + } +} + +STATUS +SFPCloseFile ( + VOID + ) +/*++ + +Routine Description: + Close the file being parsed. + +Arguments: + None. + +Returns: + STATUS_SUCCESS - the file was closed + STATUS_ERROR - no file is currently open + +--*/ +{ + if (mGlobals.SourceFile.FileBuffer != NULL) { + free (mGlobals.SourceFile.FileBuffer); + memset (&mGlobals.SourceFile, 0, sizeof (mGlobals.SourceFile)); + return STATUS_SUCCESS; + } + + return STATUS_ERROR; +} + +static +STATUS +ProcessIncludeFile ( + SOURCE_FILE *SourceFile, + SOURCE_FILE *ParentSourceFile + ) +/*++ + +Routine Description: + + Given a source file, open the file and parse it + +Arguments: + + SourceFile - name of file to parse + ParentSourceFile - for error reporting purposes, the file that #included SourceFile. + +Returns: + + Standard status. + +--*/ +{ + static UINT32 NestDepth = 0; + INT8 FoundFileName[MAX_PATH]; + STATUS Status; + + Status = STATUS_SUCCESS; + NestDepth++; + // + // Print the file being processed. Indent so you can tell the include nesting + // depth. + // + if (mGlobals.Verbose) { + fprintf (stdout, "%*cProcessing file '%s'\n", NestDepth * 2, ' ', SourceFile->FileName); + } + + // + // Make sure we didn't exceed our maximum nesting depth + // + if (NestDepth > MAX_NEST_DEPTH) { + Error (NULL, 0, 0, SourceFile->FileName, "max nesting depth (%d) exceeded", NestDepth); + Status = STATUS_ERROR; + goto Finish; + } + // + // Try to open the file locally, and if that fails try along our include paths. + // + strcpy (FoundFileName, SourceFile->FileName); + if ((SourceFile->Fptr = fopen (FoundFileName, "r")) == NULL) { + // + // Try to find it among the paths if it has a parent (that is, it is included + // by someone else). + // + Error (NULL, 0, 0, SourceFile->FileName, "file not found"); + return STATUS_ERROR; + } + // + // Process the file found + // + ProcessFile (SourceFile); +Finish: + // + // Close open files and return status + // + if (SourceFile->Fptr != NULL) { + fclose (SourceFile->Fptr); + SourceFile->Fptr = NULL; + } + + return Status; +} + +static +STATUS +ProcessFile ( + SOURCE_FILE *SourceFile + ) +{ + // + // Get the file size, and then read the entire thing into memory. + // Allocate space for a terminator character. + // + fseek (SourceFile->Fptr, 0, SEEK_END); + SourceFile->FileSize = ftell (SourceFile->Fptr); + fseek (SourceFile->Fptr, 0, SEEK_SET); + SourceFile->FileBuffer = (T_CHAR *) malloc (SourceFile->FileSize + sizeof (T_CHAR)); + if (SourceFile->FileBuffer == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + fread ((VOID *) SourceFile->FileBuffer, SourceFile->FileSize, 1, SourceFile->Fptr); + SourceFile->FileBuffer[(SourceFile->FileSize / sizeof (T_CHAR))] = T_CHAR_NULL; + // + // Pre-process the file to replace comments with spaces + // + PreprocessFile (SourceFile); + SourceFile->LineNum = 1; + return STATUS_SUCCESS; +} + +static +void +PreprocessFile ( + SOURCE_FILE *SourceFile + ) +/*++ + +Routine Description: + Preprocess a file to replace all carriage returns with NULLs so + we can print lines from the file to the screen. + +Arguments: + SourceFile - structure that we use to keep track of an input file. + +Returns: + Nothing. + +--*/ +{ + BOOLEAN InComment; + + RewindFile (SourceFile); + InComment = FALSE; + while (!EndOfFile (SourceFile)) { + // + // If a line-feed, then no longer in a comment + // + if (SourceFile->FileBufferPtr[0] == T_CHAR_LF) { + SourceFile->FileBufferPtr++; + SourceFile->LineNum++; + InComment = 0; + } else if (SourceFile->FileBufferPtr[0] == T_CHAR_CR) { + // + // Replace all carriage returns with a NULL so we can print stuff + // + SourceFile->FileBufferPtr[0] = 0; + SourceFile->FileBufferPtr++; + } else if (InComment) { + SourceFile->FileBufferPtr[0] = T_CHAR_SPACE; + SourceFile->FileBufferPtr++; + } else if ((SourceFile->FileBufferPtr[0] == T_CHAR_SLASH) && (SourceFile->FileBufferPtr[1] == T_CHAR_SLASH)) { + SourceFile->FileBufferPtr += 2; + InComment = TRUE; + } else { + SourceFile->FileBufferPtr++; + } + } + // + // Could check for end-of-file and still in a comment, but + // should not be necessary. So just restore the file pointers. + // + RewindFile (SourceFile); +} + +#if 0 +static +T_CHAR * +GetQuotedString ( + SOURCE_FILE *SourceFile, + BOOLEAN Optional + ) +{ + T_CHAR *String; + T_CHAR *Start; + T_CHAR *Ptr; + UINT32 Len; + BOOLEAN PreviousBackslash; + + if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) { + if (!Optional) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted string", "%S", SourceFile->FileBufferPtr); + } + + return NULL; + } + + Len = 0; + SourceFile->FileBufferPtr++; + Start = Ptr = SourceFile->FileBufferPtr; + PreviousBackslash = FALSE; + while (!EndOfFile (SourceFile)) { + if ((SourceFile->FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) && (!PreviousBackslash)) { + break; + } else if (SourceFile->FileBufferPtr[0] == T_CHAR_CR) { + Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start); + PreviousBackslash = FALSE; + } else if (SourceFile->FileBufferPtr[0] == T_CHAR_BACKSLASH) { + PreviousBackslash = TRUE; + } else { + PreviousBackslash = FALSE; + } + + SourceFile->FileBufferPtr++; + Len++; + } + + if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) { + Warning (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing quote on string", "%S", Start); + } else { + SourceFile->FileBufferPtr++; + } + // + // Now allocate memory for the string and save it off + // + String = (T_CHAR *) malloc ((Len + 1) * sizeof (T_CHAR)); + if (String == NULL) { + Error (NULL, 0, 0, "memory allocation failed", NULL); + return NULL; + } + // + // Copy the string from the file buffer to the local copy. + // We do no reformatting of it whatsoever at this point. + // + Ptr = String; + while (Len > 0) { + *Ptr = *Start; + Start++; + Ptr++; + Len--; + } + + *Ptr = 0; + return String; +} +#endif +static +BOOLEAN +EndOfFile ( + SOURCE_FILE *SourceFile + ) +{ + // + // The file buffer pointer will typically get updated before the End-of-file flag in the + // source file structure, so check it first. + // + if (SourceFile->FileBufferPtr >= SourceFile->FileBuffer + SourceFile->FileSize / sizeof (T_CHAR)) { + SourceFile->EndOfFile = TRUE; + return TRUE; + } + + if (SourceFile->EndOfFile) { + return TRUE; + } + + return FALSE; +} + +#if 0 +static +void +ProcessTokenInclude ( + SOURCE_FILE *SourceFile + ) +{ + INT8 IncludeFileName[MAX_PATH]; + INT8 *To; + UINT32 Len; + BOOLEAN ReportedError; + SOURCE_FILE IncludedSourceFile; + + ReportedError = FALSE; + if (SkipWhiteSpace (SourceFile) == 0) { + Warning (SourceFile->FileName, SourceFile->LineNum, 0, "expected whitespace following #include keyword", NULL); + } + // + // Should be quoted file name + // + if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted include file name", NULL); + goto FailDone; + } + + SourceFile->FileBufferPtr++; + // + // Copy the filename as ascii to our local string + // + To = IncludeFileName; + Len = 0; + while (!EndOfFile (SourceFile)) { + if ((SourceFile->FileBufferPtr[0] == T_CHAR_CR) || (SourceFile->FileBufferPtr[0] == T_CHAR_LF)) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-line found in quoted include file name", NULL); + goto FailDone; + } + + if (SourceFile->FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) { + SourceFile->FileBufferPtr++; + break; + } + // + // If too long, then report the error once and process until the closing quote + // + Len++; + if (!ReportedError && (Len >= sizeof (IncludeFileName))) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "length of include file name exceeds limit", NULL); + ReportedError = TRUE; + } + + if (!ReportedError) { + // + // *To = UNICODE_TO_ASCII(SourceFile->FileBufferPtr[0]); + // + *To = (T_CHAR) SourceFile->FileBufferPtr[0]; + To++; + } + + SourceFile->FileBufferPtr++; + } + + if (!ReportedError) { + *To = 0; + memset ((char *) &IncludedSourceFile, 0, sizeof (SOURCE_FILE)); + strcpy (IncludedSourceFile.FileName, IncludeFileName); + // + // IncludedSourceFile.ControlCharacter = DEFAULT_CONTROL_CHARACTER; + // + ProcessIncludeFile (&IncludedSourceFile, SourceFile); + // + // printf ("including file '%s'\n", IncludeFileName); + // + } + + return ; +FailDone: + // + // Error recovery -- skip to next # + // + SourceFile->SkipToHash = TRUE; +} +#endif +static +BOOLEAN +IsWhiteSpace ( + SOURCE_FILE *SourceFile + ) +{ + switch (*SourceFile->FileBufferPtr) { + case T_CHAR_NULL: + case T_CHAR_CR: + case T_CHAR_SPACE: + case T_CHAR_TAB: + case T_CHAR_LF: + return TRUE; + + default: + return FALSE; + } +} + +UINT32 +SkipWhiteSpace ( + SOURCE_FILE *SourceFile + ) +{ + UINT32 Count; + + Count = 0; + while (!EndOfFile (SourceFile)) { + Count++; + switch (*SourceFile->FileBufferPtr) { + case T_CHAR_NULL: + case T_CHAR_CR: + case T_CHAR_SPACE: + case T_CHAR_TAB: + SourceFile->FileBufferPtr++; + break; + + case T_CHAR_LF: + SourceFile->FileBufferPtr++; + SourceFile->LineNum++; + if (mGlobals.Verbose) { + printf ("%d: %S\n", SourceFile->LineNum, SourceFile->FileBufferPtr); + } + break; + + default: + return Count - 1; + } + } + // + // Some tokens require trailing whitespace. If we're at the end of the + // file, then we count that as well. + // + if ((Count == 0) && (EndOfFile (SourceFile))) { + Count++; + } + + return Count; +} + +static +UINT32 +t_strcmp ( + T_CHAR *Buffer, + T_CHAR *Str + ) +{ + UINT32 Len; + + Len = 0; + while (*Str == *Buffer) { + Buffer++; + Str++; + Len++; + } + + if (*Str) { + return 0; + } + + return Len; +} + +static +UINT32 +t_strlen ( + T_CHAR *Str + ) +{ + UINT32 Len; + Len = 0; + while (*Str) { + Len++; + Str++; + } + + return Len; +} + +static +UINT32 +t_strncmp ( + T_CHAR *Str1, + T_CHAR *Str2, + UINT32 Len + ) +{ + while (Len > 0) { + if (*Str1 != *Str2) { + return Len; + } + + Len--; + Str1++; + Str2++; + } + + return 0; +} + +static +T_CHAR * +t_strcpy ( + T_CHAR *Dest, + T_CHAR *Src + ) +{ + T_CHAR *SaveDest; + SaveDest = Dest; + while (*Src) { + *Dest = *Src; + Dest++; + Src++; + } + + *Dest = 0; + return SaveDest; +} + +#if 0 +static +BOOLEAN +IsValidIdentifierChar ( + INT8 Char, + BOOLEAN FirstChar + ) +{ + // + // If it's the first character of an identifier, then + // it must be one of [A-Za-z_]. + // + if (FirstChar) { + if (isalpha (Char) || (Char == '_')) { + return TRUE; + } + } else { + // + // If it's not the first character, then it can + // be one of [A-Za-z_0-9] + // + if (isalnum (Char) || (Char == '_')) { + return TRUE; + } + } + + return FALSE; +} +#endif +static +void +RewindFile ( + SOURCE_FILE *SourceFile + ) +{ + SourceFile->LineNum = 1; + SourceFile->FileBufferPtr = SourceFile->FileBuffer; + SourceFile->EndOfFile = 0; +} + +#if 0 +static +BOOLEAN +SkipTo ( + SOURCE_FILE *SourceFile, + T_CHAR TChar, + BOOLEAN StopAfterNewline + ) +{ + while (!EndOfFile (SourceFile)) { + // + // Check for the character of interest + // + if (SourceFile->FileBufferPtr[0] == TChar) { + return TRUE; + } else { + if (SourceFile->FileBufferPtr[0] == T_CHAR_LF) { + SourceFile->LineNum++; + if (StopAfterNewline) { + SourceFile->FileBufferPtr++; + if (SourceFile->FileBufferPtr[0] == 0) { + SourceFile->FileBufferPtr++; + } + + return FALSE; + } + } + + SourceFile->FileBufferPtr++; + } + } + + return FALSE; +} +#endif diff --git a/Tools/CodeTools/Source/GenFfsFile/build.xml b/Tools/CodeTools/Source/GenFfsFile/build.xml new file mode 100644 index 0000000000..b7f8681436 --- /dev/null +++ b/Tools/CodeTools/Source/GenFfsFile/build.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/GenFvImage/Ebc/PeCoffLoaderEx.c b/Tools/CodeTools/Source/GenFvImage/Ebc/PeCoffLoaderEx.c new file mode 100644 index 0000000000..e8cf8b6457 --- /dev/null +++ b/Tools/CodeTools/Source/GenFvImage/Ebc/PeCoffLoaderEx.c @@ -0,0 +1,57 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PeCoffLoaderEx.c + +Abstract: + + EBC Specific relocation fixups + +Revision History + +--*/ + + + + +RETURN_STATUS +PeCoffLoaderRelocateImageEx ( + IN UINT16 *Reloc, + IN OUT CHAR8 *Fixup, + IN OUT CHAR8 **FixupData, + IN UINT64 Adjust + ) +/*++ + +Routine Description: + + Performs an IA-32 specific relocation fixup + +Arguments: + + Reloc - Pointer to the relocation record + + Fixup - Pointer to the address to fix up + + FixupData - Pointer to a buffer to log the fixups + + Adjust - The offset to adjust the fixup + +Returns: + + EFI_UNSUPPORTED - Unsupported now + +--*/ +{ + return RETURN_UNSUPPORTED; +} diff --git a/Tools/CodeTools/Source/GenFvImage/GenFvImageExe.c b/Tools/CodeTools/Source/GenFvImage/GenFvImageExe.c new file mode 100644 index 0000000000..d0117b8ae9 --- /dev/null +++ b/Tools/CodeTools/Source/GenFvImage/GenFvImageExe.c @@ -0,0 +1,299 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + GenFvImageExe.c + +Abstract: + + This contains all code necessary to build the GenFvImage.exe utility. + This utility relies heavily on the GenFvImage Lib. Definitions for both + can be found in the Tiano Firmware Volume Generation Utility + Specification, review draft. + +--*/ + +// +// File included in build +// +#include "GenFvImageExe.h" +#include "CommonLib.h" +#include "EfiUtilityMsgs.h" + +VOID +PrintUtilityInfo ( + VOID + ) +/*++ + +Routine Description: + + Displays the standard utility information to SDTOUT + +Arguments: + + None + +Returns: + + None + +--*/ +{ + printf ( + "%s - Tiano Firmware Volume Generation Utility."" Version %i.%i\n\n", + UTILITY_NAME, + UTILITY_MAJOR_VERSION, + UTILITY_MINOR_VERSION + ); +} + +VOID +PrintUsage ( + VOID + ) +/*++ + +Routine Description: + + Displays the utility usage syntax to STDOUT + +Arguments: + + None + +Returns: + + None + +--*/ +{ + printf ("Usage: %s -I FvInfFileName\n", UTILITY_NAME); + printf (" Where:\n"); + printf ("\tFvInfFileName is the name of the image description file.\n\n"); +} + +int +main ( + IN INTN argc, + IN CHAR8 **argv + ) +/*++ + +Routine Description: + + This utility uses GenFvImage.Lib to build a firmware volume image. + +Arguments: + + FvInfFileName The name of an FV image description file. + + Arguments come in pair in any order. + -I FvInfFileName + +Returns: + + EFI_SUCCESS No error conditions detected. + EFI_INVALID_PARAMETER One or more of the input parameters is invalid. + EFI_OUT_OF_RESOURCES A resource required by the utility was unavailable. + Most commonly this will be memory allocation + or file creation. + EFI_LOAD_ERROR GenFvImage.lib could not be loaded. + EFI_ABORTED Error executing the GenFvImage lib. + +--*/ +{ + EFI_STATUS Status; + CHAR8 InfFileName[_MAX_PATH]; + CHAR8 *InfFileImage; + UINTN InfFileSize; + UINT8 *FvImage; + UINTN FvImageSize; + UINT8 Index; + CHAR8 FvFileNameBuffer[_MAX_PATH]; + CHAR8 *FvFileName; + FILE *FvFile; + FILE *SymFile; + CHAR8 SymFileNameBuffer[_MAX_PATH]; + CHAR8 *SymFileName; + UINT8 *SymImage; + UINTN SymImageSize; + CHAR8 *CurrentSymString; + + FvFileName = FvFileNameBuffer; + SymFileName = SymFileNameBuffer; + + SetUtilityName (UTILITY_NAME); + // + // Display utility information + // + PrintUtilityInfo (); + + // + // Verify the correct number of arguments + // + if (argc != MAX_ARGS) { + Error (NULL, 0, 0, "invalid number of input parameters specified", NULL); + PrintUsage (); + return GetUtilityStatus (); + } + // + // Initialize variables + // + strcpy (InfFileName, ""); + + // + // Parse the command line arguments + // + for (Index = 1; Index < MAX_ARGS; Index += 2) { + // + // Make sure argument pair begin with - or / + // + if (argv[Index][0] != '-' && argv[Index][0] != '/') { + Error (NULL, 0, 0, argv[Index], "argument pair must begin with \"-\" or \"/\""); + PrintUsage (); + return GetUtilityStatus (); + } + // + // Make sure argument specifier is only one letter + // + if (argv[Index][2] != 0) { + Error (NULL, 0, 0, argv[Index], "unrecognized argument"); + PrintUsage (); + return GetUtilityStatus (); + } + // + // Determine argument to read + // + switch (argv[Index][1]) { + + case 'I': + case 'i': + if (strlen (InfFileName) == 0) { + strcpy (InfFileName, argv[Index + 1]); + } else { + Error (NULL, 0, 0, argv[Index + 1], "FvInfFileName may only be specified once"); + PrintUsage (); + return GetUtilityStatus (); + } + break; + + default: + Error (NULL, 0, 0, argv[Index], "unrecognized argument"); + PrintUsage (); + return GetUtilityStatus (); + break; + } + } + // + // Read the INF file image + // + Status = GetFileImage (InfFileName, &InfFileImage, &InfFileSize); + if (EFI_ERROR (Status)) { + return STATUS_ERROR; + } + // + // Call the GenFvImage lib + // + Status = GenerateFvImage ( + InfFileImage, + InfFileSize, + &FvImage, + &FvImageSize, + &FvFileName, + &SymImage, + &SymImageSize, + &SymFileName + ); + + if (EFI_ERROR (Status)) { + switch (Status) { + + case EFI_INVALID_PARAMETER: + Error (NULL, 0, 0, "invalid parameter passed to GenFvImage Lib", NULL); + return GetUtilityStatus (); + break; + + case EFI_ABORTED: + Error (NULL, 0, 0, "error detected while creating the file image", NULL); + return GetUtilityStatus (); + break; + + case EFI_OUT_OF_RESOURCES: + Error (NULL, 0, 0, "GenFvImage Lib could not allocate required resources", NULL); + return GetUtilityStatus (); + break; + + case EFI_VOLUME_CORRUPTED: + Error (NULL, 0, 0, "no base address was specified, but the FV.INF included a PEI or BSF file", NULL); + return GetUtilityStatus (); + break; + + case EFI_LOAD_ERROR: + Error (NULL, 0, 0, "could not load FV image generation library", NULL); + return GetUtilityStatus (); + break; + + default: + Error (NULL, 0, 0, "GenFvImage Lib returned unknown status", "status returned = 0x%X", Status); + return GetUtilityStatus (); + break; + } + } + // + // Write file + // + FvFile = fopen (FvFileName, "wb"); + if (FvFile == NULL) { + Error (NULL, 0, 0, FvFileName, "could not open output file"); + free (FvImage); + free (SymImage); + return GetUtilityStatus (); + } + + if (fwrite (FvImage, 1, FvImageSize, FvFile) != FvImageSize) { + Error (NULL, 0, 0, FvFileName, "failed to write to output file"); + free (FvImage); + free (SymImage); + fclose (FvFile); + return GetUtilityStatus (); + } + + fclose (FvFile); + free (FvImage); + + // + // Write symbol file + // + if (strcmp (SymFileName, "")) { + SymFile = fopen (SymFileName, "wt"); + if (SymFile == NULL) { + Error (NULL, 0, 0, SymFileName, "could not open output symbol file"); + free (SymImage); + return GetUtilityStatus (); + } + + fprintf (SymFile, "TEXTSYM format | V1.0\n"); + + CurrentSymString = SymImage; + while (((UINTN) CurrentSymString - (UINTN) SymImage) < SymImageSize) { + fprintf (SymFile, "%s", CurrentSymString); + CurrentSymString = (CHAR8 *) (((UINTN) CurrentSymString) + strlen (CurrentSymString) + 1); + } + + fclose (SymFile); + } + + free (SymImage); + + return GetUtilityStatus (); +} diff --git a/Tools/CodeTools/Source/GenFvImage/GenFvImageExe.h b/Tools/CodeTools/Source/GenFvImage/GenFvImageExe.h new file mode 100644 index 0000000000..9b97935656 --- /dev/null +++ b/Tools/CodeTools/Source/GenFvImage/GenFvImageExe.h @@ -0,0 +1,98 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + GenFvImageExe.h + +Abstract: + + Definitions for the PeimFixup exe utility. + +--*/ + +// +// Coded to Tiano Coding Standards +// +#ifndef _EFI_GEN_FV_IMAGE_EXE_H +#define _EFI_GEN_FV_IMAGE_EXE_H + +#include +#include +#include +#include "GenFvImageLib.h" + +// +// Utility Name +// +#define UTILITY_NAME "GenFvImage" + +// +// Utility version information +// +#define UTILITY_MAJOR_VERSION 0 +#define UTILITY_MINOR_VERSION 1 +#define UTILITY_DATE __DATE__ + +// +// The maximum number of arguments accepted from the command line. +// +#define MAX_ARGS 3 + +// +// The function that displays general utility information +// +VOID +PrintUtilityInfo ( + VOID + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + None + +Returns: + + TODO: add return values + +--*/ +; + +// +// The function that displays the utility usage message. +// +VOID +PrintUsage ( + VOID + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + None + +Returns: + + TODO: add return values + +--*/ +; + +#endif diff --git a/Tools/CodeTools/Source/GenFvImage/GenFvImageLib.c b/Tools/CodeTools/Source/GenFvImage/GenFvImageLib.c new file mode 100644 index 0000000000..888656ad5c --- /dev/null +++ b/Tools/CodeTools/Source/GenFvImage/GenFvImageLib.c @@ -0,0 +1,2727 @@ +/*++ +i + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + GenFvImageLib.c + +Abstract: + + This file contains functions required to generate a Firmware Volume. + +--*/ + +// +// Include files +// +#ifdef __GNUC__ +#include +#include +#endif +#include +#ifndef __GNUC__ +#include +#endif +#include + +#include +#include +#include +#include +#include + +#include "GenFvImageLib.h" +#include "GenFvImageLibInternal.h" +#include "CommonLib.h" +#include "Crc32.h" +#include "EfiUtilityMsgs.h" +#include "FvLib.h" +#include "EfiCompress.h" +#include "WinNtInclude.h" + + +// +// Local function prototypes +// +EFI_STATUS +GetPe32Info ( + IN UINT8 *Pe32, + OUT UINT32 *EntryPoint, + OUT UINT32 *BaseOfCode, + OUT UINT16 *MachineType + ); + +// +// Local function implementations. +// +EFI_GUID FfsGuid = EFI_FIRMWARE_FILE_SYSTEM_GUID; +EFI_GUID DefaultFvPadFileNameGuid = { 0x78f54d4, 0xcc22, 0x4048, 0x9e, 0x94, 0x87, 0x9c, 0x21, 0x4d, 0x56, 0x2f }; + +// +// This data array will be located at the base of the Firmware Volume Header (FVH) +// in the boot block. It must not exceed 14 bytes of code. The last 2 bytes +// will be used to keep the FVH checksum consistent. +// This code will be run in response to a starutp IPI for HT-enabled systems. +// +#define SIZEOF_STARTUP_DATA_ARRAY 0x10 + +UINT8 m128kRecoveryStartupApDataArray[SIZEOF_STARTUP_DATA_ARRAY] = { + // + // EA D0 FF 00 F0 ; far jmp F000:FFD0 + // 0, 0, 0, 0, 0, 0, 0, 0, 0, ; Reserved bytes + // 0, 0 ; Checksum Padding + // + 0xEA, + 0xD0, + 0xFF, + 0x0, + 0xF0, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00 +}; + +UINT8 m64kRecoveryStartupApDataArray[SIZEOF_STARTUP_DATA_ARRAY] = { + // + // EB CE ; jmp short ($-0x30) + // ; (from offset 0x0 to offset 0xFFD0) + // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ; Reserved bytes + // 0, 0 ; Checksum Padding + // + 0xEB, + 0xCE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00 +}; + +EFI_STATUS +ParseFvInf ( + IN MEMORY_FILE *InfFile, + IN FV_INFO *FvInfo + ) +/*++ + +Routine Description: + + This function parses a FV.INF file and copies info into a FV_INFO structure. + +Arguments: + + InfFile Memory file image. + FvInfo Information read from INF file. + +Returns: + + EFI_SUCCESS INF file information successfully retrieved. + EFI_ABORTED INF file has an invalid format. + EFI_NOT_FOUND A required string was not found in the INF file. +--*/ +{ + CHAR8 Value[_MAX_PATH]; + UINT64 Value64; + UINTN Index; + EFI_STATUS Status; + + // + // Initialize FV info + // + memset (FvInfo, 0, sizeof (FV_INFO)); + + // + // Read the FV base address + // + Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_BASE_ADDRESS_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Get the base address + // + Status = AsciiStringToUint64 (Value, FALSE, &Value64); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, EFI_FV_BASE_ADDRESS_STRING, "invalid value"); + return EFI_ABORTED; + } + + FvInfo->BaseAddress = Value64; + } else { + Error (NULL, 0, 0, EFI_FV_BASE_ADDRESS_STRING, "could not find value"); + return EFI_ABORTED; + } + // + // Read the FV Guid + // + Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_GUID_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Get the guid value + // + Status = StringToGuid (Value, &FvInfo->FvGuid); + if (EFI_ERROR (Status)) { + memcpy (&FvInfo->FvGuid, &FfsGuid, sizeof (EFI_GUID)); + } + } else { + memcpy (&FvInfo->FvGuid, &FfsGuid, sizeof (EFI_GUID)); + } + // + // Read the FV file name + // + Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_FILE_NAME_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // copy the file name + // + strcpy (FvInfo->FvName, Value); + } else { + Error (NULL, 0, 0, EFI_FV_FILE_NAME_STRING, "value not specified"); + return EFI_ABORTED; + } + // + // Read the Sym file name + // + Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_SYM_FILE_NAME_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // copy the file name + // + strcpy (FvInfo->SymName, Value); + } else { + // + // Symbols not required, so init to NULL. + // + strcpy (FvInfo->SymName, ""); + } + // + // Read the read disabled capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_READ_DISABLED_CAP_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update the read disabled flag + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_READ_DISABLED_CAP; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_READ_DISABLED_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_READ_DISABLED_CAP_STRING, "value not specified"); + return Status; + } + // + // Read the read enabled capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_READ_ENABLED_CAP_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update the read disabled flag + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_READ_ENABLED_CAP; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_READ_ENABLED_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_READ_ENABLED_CAP_STRING, "value not specified"); + return Status; + } + // + // Read the read status attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_READ_STATUS_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update the read disabled flag + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_READ_STATUS; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_READ_STATUS_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_READ_STATUS_STRING, "value not specified"); + return Status; + } + // + // Read the write disabled capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_WRITE_DISABLED_CAP_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update the write disabled flag + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_WRITE_DISABLED_CAP; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_WRITE_DISABLED_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_WRITE_DISABLED_CAP_STRING, "value not specified"); + return Status; + } + // + // Read the write enabled capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_WRITE_ENABLED_CAP_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update the write disabled flag + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_WRITE_ENABLED_CAP; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_WRITE_ENABLED_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_WRITE_ENABLED_CAP_STRING, "value not specified"); + return Status; + } + // + // Read the write status attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_WRITE_STATUS_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update the write disabled flag + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_WRITE_STATUS; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_WRITE_STATUS_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_WRITE_STATUS_STRING, "value not specified"); + return Status; + } + // + // Read the lock capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_LOCK_CAP_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update the attribute flag + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_LOCK_CAP; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_LOCK_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_LOCK_CAP_STRING, "value not specified"); + return Status; + } + // + // Read the lock status attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_LOCK_STATUS_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update the attribute flag + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_LOCK_STATUS; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_LOCK_STATUS_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_LOCK_STATUS_STRING, "value not specified"); + return Status; + } + // + // Read the sticky write attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_STICKY_WRITE_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update the attribute flag + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_STICKY_WRITE; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_STICKY_WRITE_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_STICKY_WRITE_STRING, "value not specified"); + return Status; + } + // + // Read the memory mapped attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_MEMORY_MAPPED_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update the attribute flag + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_MEMORY_MAPPED; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_MEMORY_MAPPED_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_MEMORY_MAPPED_STRING, "value not specified"); + return Status; + } + // + // Read the erase polarity attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ERASE_POLARITY_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update the attribute flag + // + if (strcmp (Value, ONE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_ERASE_POLARITY; + } else if (strcmp (Value, ZERO_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_ERASE_POLARITY_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_ERASE_POLARITY_STRING, "value not specified"); + return Status; + } + // + // Read the alignment capabilities attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_CAP_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update attribute + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_CAP; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_CAP_STRING, "value not specified"); + return Status; + } + // + // Read the word alignment capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_2_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update attribute + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_2; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_2_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_2_STRING, "value not specified"); + return Status; + } + // + // Read the dword alignment capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_4_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update attribute + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_4; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_4_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_4_STRING, "value not specified"); + return Status; + } + // + // Read the word alignment capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_8_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update attribute + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_8; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_8_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_8_STRING, "value not specified"); + return Status; + } + // + // Read the qword alignment capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_16_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update attribute + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_16; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_16_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_16_STRING, "value not specified"); + return Status; + } + // + // Read the 32 byte alignment capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_32_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update attribute + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_32; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_32_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_32_STRING, "value not specified"); + return Status; + } + // + // Read the 64 byte alignment capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_64_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update attribute + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_64; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_64_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_64_STRING, "value not specified"); + return Status; + } + // + // Read the 128 byte alignment capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_128_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update attribute + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_128; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_128_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_128_STRING, "value not specified"); + return Status; + } + // + // Read the 256 byte alignment capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_256_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update attribute + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_256; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_256_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_256_STRING, "value not specified"); + return Status; + } + // + // Read the 512 byte alignment capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_512_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update attribute + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_512; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_512_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_512_STRING, "value not specified"); + return Status; + } + // + // Read the 1K byte alignment capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_1K_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update attribute + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_1K; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_1K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_1K_STRING, "value not specified"); + return Status; + } + // + // Read the 2K byte alignment capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_2K_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update attribute + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_2K; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_2K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_2K_STRING, "value not specified"); + return Status; + } + // + // Read the 4K byte alignment capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_4K_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update attribute + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_4K; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_4K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_4K_STRING, "value not specified"); + return Status; + } + // + // Read the 8K byte alignment capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_8K_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update attribute + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_8K; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_8K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_8K_STRING, "value not specified"); + return Status; + } + // + // Read the 16K byte alignment capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_16K_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update attribute + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_16K; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_16K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_16K_STRING, "value not specified"); + return Status; + } + // + // Read the 32K byte alignment capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_32K_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update attribute + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_32K; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_32K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_32K_STRING, "value not specified"); + return Status; + } + // + // Read the 64K byte alignment capability attribute + // + Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_64K_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Update attribute + // + if (strcmp (Value, TRUE_STRING) == 0) { + FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_64K; + } else if (strcmp (Value, FALSE_STRING) != 0) { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_64K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); + return EFI_ABORTED; + } + } else { + Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_64K_STRING, "value not specified"); + return Status; + } + + if (!(FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_CAP) && + ( + (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_2) || + (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_4) || + (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_8) || + (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_16) || + (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_32) || + (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_64) || + (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_128) || + (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_256) || + (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_512) || + (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_1K) || + (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_2K) || + (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_4K) || + (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_8K) || + (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_16K) || + (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_32K) || + (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_64K) + ) + ) { + Error ( + NULL, + 0, + 0, + "illegal combination of alignment attributes", + "if %s is not %s, no individual alignments can be %s", + EFI_FVB_ALIGNMENT_CAP_STRING, + TRUE_STRING, + TRUE_STRING + ); + return EFI_ABORTED; + } + // + // Read block maps + // + for (Index = 0; Index < MAX_NUMBER_OF_FV_BLOCKS; Index++) { + // + // Read the number of blocks + // + Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_NUM_BLOCKS_STRING, Index, Value); + + if (Status == EFI_SUCCESS) { + // + // Update the number of blocks + // + Status = AsciiStringToUint64 (Value, FALSE, &Value64); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, Value, "invalid value for %s", EFI_NUM_BLOCKS_STRING); + return EFI_ABORTED; + } + + FvInfo->FvBlocks[Index].NumBlocks = (UINT32) Value64; + } else { + // + // If there is no number of blocks, but there is a size, then we have a mismatched pair + // and should return an error. + // + Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_BLOCK_SIZE_STRING, Index, Value); + if (!EFI_ERROR (Status)) { + Error (NULL, 0, 0, "must specify both", "%s and %s", EFI_NUM_BLOCKS_STRING, EFI_BLOCK_SIZE_STRING); + return EFI_ABORTED; + } else { + // + // We are done + // + break; + } + } + // + // Read the size of blocks + // + Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_BLOCK_SIZE_STRING, Index, Value); + + if (Status == EFI_SUCCESS) { + // + // Update the number of blocks + // + Status = AsciiStringToUint64 (Value, FALSE, &Value64); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, Value, "invalid value specified for %s", EFI_BLOCK_SIZE_STRING); + return EFI_ABORTED; + } + + FvInfo->FvBlocks[Index].BlockLength = (UINT32) Value64; + } else { + // + // There is a number of blocks, but there is no size, so we have a mismatched pair + // and should return an error. + // + Error (NULL, 0, 0, "must specify both", "%s and %s", EFI_NUM_BLOCKS_STRING, EFI_BLOCK_SIZE_STRING); + return EFI_ABORTED; + } + } + // + // Read files + // + for (Index = 0; Index < MAX_NUMBER_OF_FILES_IN_FV; Index++) { + // + // Read the number of blocks + // + Status = FindToken (InfFile, FILES_SECTION_STRING, EFI_FILE_NAME_STRING, Index, Value); + + if (Status == EFI_SUCCESS) { + // + // Add the file + // + strcpy (FvInfo->FvFiles[Index], Value); + } else { + break; + } + } + + if (FindSection (InfFile, COMPONENT_SECTION_STRING)) { + Index = 0; + // + // Read component FV_VARIABLE + // + Status = FindToken (InfFile, COMPONENT_SECTION_STRING, EFI_NV_VARIABLE_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Add the component + // + strcpy (FvInfo->FvComponents[Index].ComponentName, EFI_NV_VARIABLE_STRING); + Status = AsciiStringToUint64 (Value, FALSE, &Value64); + if (EFI_ERROR (Status)) { + printf ("ERROR: %s is not a valid integer.\n", EFI_NV_VARIABLE_STRING); + return EFI_ABORTED; + } + + FvInfo->FvComponents[Index].Size = (UINTN) Value64; + } else { + printf ("WARNING: Could not read %s.\n", EFI_NV_VARIABLE_STRING); + } + + Index++; + // + // Read component FV_EVENT_LOG + // + Status = FindToken (InfFile, COMPONENT_SECTION_STRING, EFI_NV_EVENT_LOG_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Add the component + // + strcpy (FvInfo->FvComponents[Index].ComponentName, EFI_NV_EVENT_LOG_STRING); + Status = AsciiStringToUint64 (Value, FALSE, &Value64); + if (EFI_ERROR (Status)) { + printf ("ERROR: %s is not a valid integer.\n", EFI_NV_EVENT_LOG_STRING); + return EFI_ABORTED; + } + + FvInfo->FvComponents[Index].Size = (UINTN) Value64; + } else { + printf ("WARNING: Could not read %s.\n", EFI_NV_EVENT_LOG_STRING); + } + + Index++; + // + // Read component FV_FTW_WORKING + // + Status = FindToken (InfFile, COMPONENT_SECTION_STRING, EFI_NV_FTW_WORKING_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Add the component + // + strcpy (FvInfo->FvComponents[Index].ComponentName, EFI_NV_FTW_WORKING_STRING); + Status = AsciiStringToUint64 (Value, FALSE, &Value64); + if (EFI_ERROR (Status)) { + printf ("ERROR: %s is not a valid integer.\n", EFI_NV_FTW_WORKING_STRING); + return EFI_ABORTED; + } + + FvInfo->FvComponents[Index].Size = (UINTN) Value64; + } else { + printf ("WARNING: Could not read %s.\n", EFI_NV_FTW_WORKING_STRING); + } + + Index++; + // + // Read component FV_FTW_SPARE + // + Status = FindToken (InfFile, COMPONENT_SECTION_STRING, EFI_NV_FTW_SPARE_STRING, 0, Value); + + if (Status == EFI_SUCCESS) { + // + // Add the component + // + strcpy (FvInfo->FvComponents[Index].ComponentName, EFI_NV_FTW_SPARE_STRING); + Status = AsciiStringToUint64 (Value, FALSE, &Value64); + if (EFI_ERROR (Status)) { + printf ("ERROR: %s is not a valid integer.\n", EFI_NV_FTW_SPARE_STRING); + return EFI_ABORTED; + } + + FvInfo->FvComponents[Index].Size = (UINTN) Value64; + } else { + printf ("WARNING: Could not read %s.\n", EFI_NV_FTW_SPARE_STRING); + } + } + // + // Compute size for easy access later + // + FvInfo->Size = 0; + for (Index = 0; FvInfo->FvBlocks[Index].NumBlocks; Index++) { + FvInfo->Size += FvInfo->FvBlocks[Index].NumBlocks * FvInfo->FvBlocks[Index].BlockLength; + } + + return EFI_SUCCESS; +} + +VOID +UpdateFfsFileState ( + IN EFI_FFS_FILE_HEADER *FfsFile, + IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader + ) +/*++ + +Routine Description: + + This function changes the FFS file attributes based on the erase polarity + of the FV. + +Arguments: + + FfsFile File header. + FvHeader FV header. + +Returns: + + None + +--*/ +{ + if (FvHeader->Attributes & EFI_FVB_ERASE_POLARITY) { + FfsFile->State = (UINT8)~(FfsFile->State); + } +} + +EFI_STATUS +ReadFfsAlignment ( + IN EFI_FFS_FILE_HEADER *FfsFile, + IN OUT UINT32 *Alignment + ) +/*++ + +Routine Description: + + This function determines the alignment of the FFS input file from the file + attributes. + +Arguments: + + FfsFile FFS file to parse + Alignment The minimum required alignment of the FFS file, in bytes + +Returns: + + EFI_SUCCESS The function completed successfully. + EFI_INVALID_PARAMETER One of the input parameters was invalid. + EFI_ABORTED An error occurred. + +--*/ +{ + // + // Verify input parameters. + // + if (FfsFile == NULL || Alignment == NULL) { + return EFI_INVALID_PARAMETER; + } + + switch ((FfsFile->Attributes >> 3) & 0x07) { + + case 0: + // + // 1 byte alignment + // + *Alignment = (1 << 0); + break; + + case 1: + // + // 16 byte alignment + // + *Alignment = (1 << 4); + break; + + case 2: + // + // 128 byte alignment + // + *Alignment = (1 << 7); + break; + + case 3: + // + // 512 byte alignment + // + *Alignment = (1 << 9); + break; + + case 4: + // + // 1K byte alignment + // + *Alignment = (1 << 10); + break; + + case 5: + // + // 4K byte alignment + // + *Alignment = (1 << 12); + break; + + case 6: + // + // 32K byte alignment + // + *Alignment = (1 << 15); + break; + + case 7: + // + // 64K byte alignment + // + *Alignment = (1 << 16); + break; + + default: + Error (NULL, 0, 0, "nvalid file attribute calculated, this is most likely a utility error", NULL); + return EFI_ABORTED; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +AddPadFile ( + IN OUT MEMORY_FILE *FvImage, + IN UINT32 DataAlignment + ) +/*++ + +Routine Description: + + This function adds a pad file to the FV image if it required to align the + data of the next file. + +Arguments: + + FvImage The memory image of the FV to add it to. The current offset + must be valid. + DataAlignment The data alignment of the next FFS file. + +Returns: + + EFI_SUCCESS The function completed successfully. + EFI_INVALID_PARAMETER One of the input parameters was invalid. + EFI_OUT_OF_RESOURCES Insufficient resources exist in the FV to complete + the pad file add. + +--*/ +{ + EFI_FFS_FILE_HEADER *PadFile; + EFI_GUID PadFileGuid; + UINTN PadFileSize; + + // + // Verify input parameters. + // + if (FvImage == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Basic assumption is we start from an 8 byte aligned address + // and our file header is a multiple of 8 bytes + // + assert ((UINTN) FvImage->CurrentFilePointer % 8 == 0); + assert (sizeof (EFI_FFS_FILE_HEADER) % 8 == 0); + + // + // Check if a pad file is necessary + // + if (((UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + sizeof (EFI_FFS_FILE_HEADER)) % DataAlignment == 0) { + return EFI_SUCCESS; + } + // + // Write pad file header + // + PadFile = (EFI_FFS_FILE_HEADER *) FvImage->CurrentFilePointer; + + // + // Verify that we have enough space for the file header + // + if ((UINTN) (PadFile + sizeof (EFI_FFS_FILE_HEADER)) >= (UINTN) FvImage->Eof) { + return EFI_OUT_OF_RESOURCES; + } + +#ifdef __GNUC__ + { + uuid_t tmp_id; + uuid_generate (tmp_id); + memcpy (&PadFileGuid, tmp_id, sizeof (EFI_GUID)); + } +#else + UuidCreate (&PadFileGuid); +#endif + memset (PadFile, 0, sizeof (EFI_FFS_FILE_HEADER)); + memcpy (&PadFile->Name, &PadFileGuid, sizeof (EFI_GUID)); + PadFile->Type = EFI_FV_FILETYPE_FFS_PAD; + PadFile->Attributes = 0; + + // + // Calculate the pad file size + // + // + // This is the earliest possible valid offset (current plus pad file header + // plus the next file header) + // + PadFileSize = (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + (sizeof (EFI_FFS_FILE_HEADER) * 2); + + // + // Add whatever it takes to get to the next aligned address + // + while ((PadFileSize % DataAlignment) != 0) { + PadFileSize++; + } + // + // Subtract the next file header size + // + PadFileSize -= sizeof (EFI_FFS_FILE_HEADER); + + // + // Subtract the starting offset to get size + // + PadFileSize -= (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage; + + // + // Write pad file size (calculated size minus next file header size) + // + PadFile->Size[0] = (UINT8) (PadFileSize & 0xFF); + PadFile->Size[1] = (UINT8) ((PadFileSize >> 8) & 0xFF); + PadFile->Size[2] = (UINT8) ((PadFileSize >> 16) & 0xFF); + + // + // Fill in checksums and state, they must be 0 for checksumming. + // + PadFile->IntegrityCheck.Checksum.Header = 0; + PadFile->IntegrityCheck.Checksum.File = 0; + PadFile->State = 0; + PadFile->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) PadFile, sizeof (EFI_FFS_FILE_HEADER)); + if (PadFile->Attributes & FFS_ATTRIB_CHECKSUM) { + PadFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) PadFile, PadFileSize); + } else { + PadFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; + } + + PadFile->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID; + UpdateFfsFileState ( + (EFI_FFS_FILE_HEADER *) PadFile, + (EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage + ); + + // + // Verify that we have enough space (including the padding + // + if ((UINTN) (PadFile + sizeof (EFI_FFS_FILE_HEADER)) >= (UINTN) FvImage->Eof) { + return EFI_OUT_OF_RESOURCES; + } + // + // Update the current FV pointer + // + FvImage->CurrentFilePointer += PadFileSize; + + return EFI_SUCCESS; +} + +BOOLEAN +IsVtfFile ( + IN EFI_FFS_FILE_HEADER *FileBuffer + ) +/*++ + +Routine Description: + + This function checks the header to validate if it is a VTF file + +Arguments: + + FileBuffer Buffer in which content of a file has been read. + +Returns: + + TRUE If this is a VTF file + FALSE If this is not a VTF file + +--*/ +{ + EFI_GUID VtfGuid = EFI_FFS_VOLUME_TOP_FILE_GUID; + if (!memcmp (&FileBuffer->Name, &VtfGuid, sizeof (EFI_GUID))) { + return TRUE; + } else { + return FALSE; + } +} + +EFI_STATUS +FfsRebaseImageRead ( + IN VOID *FileHandle, + IN UINTN FileOffset, + IN OUT UINT32 *ReadSize, + OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file + +Arguments: + + FileHandle - The handle to the PE/COFF file + + FileOffset - The offset, in bytes, into the file to read + + ReadSize - The number of bytes to read from the file starting at FileOffset + + Buffer - A pointer to the buffer to read the data into. + +Returns: + + EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset + +--*/ +{ + CHAR8 *Destination8; + CHAR8 *Source8; + UINT32 Length; + + Destination8 = Buffer; + Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset); + Length = *ReadSize; + while (Length--) { + *(Destination8++) = *(Source8++); + } + + return EFI_SUCCESS; +} + + +EFI_STATUS +AddSymFile ( + IN UINT64 BaseAddress, + IN EFI_FFS_FILE_HEADER *FfsFile, + IN OUT MEMORY_FILE *SymImage, + IN CHAR8 *SourceFileName + ) +/*++ + +Routine Description: + + This function adds the SYM tokens in the source file to the destination file. + The SYM tokens are updated to reflect the base address. + +Arguments: + + BaseAddress The base address for the new SYM tokens. + FfsFile Pointer to the beginning of the FFS file in question. + SymImage The memory file to update with symbol information. + SourceFileName The source file. + +Returns: + + EFI_SUCCESS The function completed successfully. + EFI_INVALID_PARAMETER One of the input parameters was invalid. + EFI_ABORTED An error occurred. + +--*/ +{ + FILE *SourceFile; + + CHAR8 Buffer[_MAX_PATH]; + CHAR8 Type[_MAX_PATH]; + CHAR8 Address[_MAX_PATH]; + CHAR8 Section[_MAX_PATH]; + CHAR8 Token[_MAX_PATH]; + CHAR8 SymFileName[_MAX_PATH]; + CHAR8 CodeModuleName[_MAX_PATH]; + CHAR8 *Ptr; + + UINT64 TokenAddress; + + EFI_STATUS Status; + EFI_FILE_SECTION_POINTER Pe32Section; + UINT32 EntryPoint; + UINT32 BaseOfCode; + UINT16 MachineType; + + // + // Verify input parameters. + // + if (BaseAddress == 0 || FfsFile == NULL || SymImage == NULL || SourceFileName == NULL) { + Error (NULL, 0, 0, "invalid parameter passed to AddSymFile()", NULL); + return EFI_INVALID_PARAMETER; + } + // + // Check if we want to add this file + // + // + // Get the file name + // + strcpy (Buffer, SourceFileName); + + // + // Copy the file name for the path of the sym file and truncate the name portion. + // + strcpy (SymFileName, Buffer); + Ptr = strrchr (SymFileName, '\\'); + assert (Ptr); + Ptr[0] = 0; + + // + // Find the file extension and make it lower case + // + Ptr = strrchr (SymFileName, '.'); + if (Ptr != NULL) { + strlwr (Ptr); + } + // + // Check if it is PEI file + // + if (strstr (Buffer, ".pei") != NULL) { + // + // Find the human readable portion + // + if (!strtok (Buffer, "-") || + !strtok (NULL, "-") || + !strtok (NULL, "-") || + !strtok (NULL, "-") || + !strtok (NULL, "-") || + !strcpy (Buffer, strtok (NULL, ".")) + ) { + Error (NULL, 0, 0, "failed to find human readable portion of the file name in AddSymFile()", NULL); + return EFI_ABORTED; + } + // + // Save code module name + // + strcpy (CodeModuleName, Buffer); + + // + // Add the symbol file name and extension to the file path. + // + strcat (Buffer, ".sym"); + strcat (SymFileName, "\\"); + strcat (SymFileName, Buffer); + } else { + // + // Only handle PEIM files. + // + return EFI_SUCCESS; + } + // + // Find PE32 section + // + Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, 1, &Pe32Section); + + // + // BUGBUG: Assume if no PE32 section it is PIC and hardcode base address + // + if (Status == EFI_NOT_FOUND) { + Status = GetSectionByType (FfsFile, EFI_SECTION_TE, 1, &Pe32Section); + } + + if (Status == EFI_SUCCESS) { + Status = GetPe32Info ( + (VOID *) ((UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32)), + &EntryPoint, + &BaseOfCode, + &MachineType + ); + } else if (Status == EFI_NOT_FOUND) { + // + // For PIC, hardcode. + // + BaseOfCode = 0x60; + Status = EFI_SUCCESS; + } else { + Error (NULL, 0, 0, "could not parse a PE32 section from the PEI file", NULL); + return Status; + } + + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "GetPe32Info() could not get PE32 entry point for PEI file", NULL); + return Status; + } + + // + // Open the source file + // + SourceFile = fopen (SymFileName, "r"); + if (SourceFile == NULL) { + // + // SYM files are not required. + // + return EFI_SUCCESS; + } + // + // Read the first line + // + if (fgets (Buffer, _MAX_PATH, SourceFile) == NULL) { + Buffer[0] = 0; + } + // + // Make sure it matches the expected sym format + // + if (strcmp (Buffer, "TEXTSYM format | V1.0\n")) { + fclose (SourceFile); + Error (NULL, 0, 0, "AddSymFile() found unexpected sym format in input file", NULL); + return EFI_ABORTED; + } + // + // Read in the file + // + while (feof (SourceFile) == 0) { + // + // Read a line + // + if (fscanf ( + SourceFile, + "%s | %s | %s | %s\n", + Type, + Address, + Section, + Token + ) == 4) { + // + // If the token starts with "??" ignore it + // + if (Token[0] == '?' && Token[1] == '?') { + continue; + } + // + // Get the token address + // + AsciiStringToUint64 (Address, TRUE, &TokenAddress); + + // + // Add the base address + // + TokenAddress += BaseAddress; + + // + // If PE32 or TE section then find the start of code. For PIC it is hardcoded. + // + if (Pe32Section.Pe32Section) { + // + // Add the offset of the PE32 section + // + TokenAddress += (UINTN) Pe32Section.Pe32Section - (UINTN) FfsFile; + + // + // Add the size of the PE32 section header + // + TokenAddress += sizeof (EFI_PE32_SECTION); + } else { + // + // For PIC hardcoded. + // + TokenAddress += 0x28; + } + + // + // Add the beginning of the code + // + TokenAddress += BaseOfCode; + + sprintf ( + Buffer, + "%s | %016I64X | %s | _%s%s\n", + Type, + TokenAddress, + Section, + CodeModuleName, + Token + ); + memcpy (SymImage->CurrentFilePointer, Buffer, strlen (Buffer) + 1); + SymImage->CurrentFilePointer = (UINT8 *) (((UINTN) SymImage->CurrentFilePointer) + strlen (Buffer) + 1); + } + } + + fclose (SourceFile); + return EFI_SUCCESS; +} + +EFI_STATUS +AddFile ( + IN OUT MEMORY_FILE *FvImage, + IN FV_INFO *FvInfo, + IN UINTN Index, + IN OUT EFI_FFS_FILE_HEADER **VtfFileImage, + IN OUT MEMORY_FILE *SymImage + ) +/*++ + +Routine Description: + + This function adds a file to the FV image. The file will pad to the + appropriate alignment if required. + +Arguments: + + FvImage The memory image of the FV to add it to. The current offset + must be valid. + FvInfo Pointer to information about the FV. + Index The file in the FvInfo file list to add. + VtfFileImage A pointer to the VTF file within the FvImage. If this is equal + to the end of the FvImage then no VTF previously found. + SymImage The memory image of the Sym file to update if symbols are present. + The current offset must be valid. + +Returns: + + EFI_SUCCESS The function completed successfully. + EFI_INVALID_PARAMETER One of the input parameters was invalid. + EFI_ABORTED An error occurred. + EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the add. + +--*/ +{ + FILE *NewFile; + UINTN FileSize; + UINT8 *FileBuffer; + UINTN NumBytesRead; + UINT32 CurrentFileAlignment; + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS CurrentFileBaseAddress; + UINT8 VtfHeaderChecksum; + UINT8 VtfFileChecksum; + UINT8 FileState; + EFI_FFS_FILE_TAIL TailValue; + UINT32 TailSize; + // + // Verify input parameters. + // + if (FvImage == NULL || FvInfo == NULL || FvInfo->FvFiles[Index][0] == 0 || VtfFileImage == NULL || SymImage == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Read the file to add + // + NewFile = fopen (FvInfo->FvFiles[Index], "rb"); + + if (NewFile == NULL) { + Error (NULL, 0, 0, FvInfo->FvFiles[Index], "failed to open file for reading"); + return EFI_ABORTED; + } + // + // Get the file size + // +#ifdef __GNUC__ + { + struct stat stat_buf; + fstat(fileno(NewFile), &stat_buf); + FileSize = stat_buf.st_size; + } +#else + FileSize = _filelength (fileno (NewFile)); +#endif + + // + // Read the file into a buffer + // + FileBuffer = malloc (FileSize); + if (FileBuffer == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + return EFI_OUT_OF_RESOURCES; + } + + NumBytesRead = fread (FileBuffer, sizeof (UINT8), FileSize, NewFile); + + // + // Done with the file, from this point on we will just use the buffer read. + // + fclose (NewFile); + + // + // Verify read successful + // + if (NumBytesRead != sizeof (UINT8) * FileSize) { + free (FileBuffer); + Error (NULL, 0, 0, FvInfo->FvFiles[Index], "failed to read input file contents"); + return EFI_ABORTED; + } + // + // Verify space exists to add the file + // + if (FileSize > (UINTN) ((UINTN) *VtfFileImage - (UINTN) FvImage->CurrentFilePointer)) { + Error (NULL, 0, 0, FvInfo->FvFiles[Index], "insufficient space remains to add the file"); + return EFI_OUT_OF_RESOURCES; + } + // + // Update the file state based on polarity of the FV. + // + UpdateFfsFileState ( + (EFI_FFS_FILE_HEADER *) FileBuffer, + (EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage + ); + + // + // If we have a VTF file, add it at the top. + // + if (IsVtfFile ((EFI_FFS_FILE_HEADER *) FileBuffer)) { + if ((UINTN) *VtfFileImage == (UINTN) FvImage->Eof) { + // + // No previous VTF, add this one. + // + *VtfFileImage = (EFI_FFS_FILE_HEADER *) (UINTN) ((UINTN) FvImage->FileImage + FvInfo->Size - FileSize); + // + // Sanity check. The file MUST align appropriately + // + if ((((UINTN) *VtfFileImage) & 0x07) != 0) { + Error (NULL, 0, 0, "VTF file does not align on 8-byte boundary", NULL); + } + // + // copy VTF File Header + // + memcpy (*VtfFileImage, FileBuffer, sizeof (EFI_FFS_FILE_HEADER)); + + // + // Copy VTF body + // + memcpy ( + (UINT8 *) *VtfFileImage + sizeof (EFI_FFS_FILE_HEADER), + FileBuffer + sizeof (EFI_FFS_FILE_HEADER), + FileSize - sizeof (EFI_FFS_FILE_HEADER) + ); + + // + // re-calculate the VTF File Header + // + FileState = (*VtfFileImage)->State; + (*VtfFileImage)->State = 0; + *(UINT32 *) ((*VtfFileImage)->Size) = FileSize; + (*VtfFileImage)->IntegrityCheck.Checksum.Header = 0; + (*VtfFileImage)->IntegrityCheck.Checksum.File = 0; + + VtfHeaderChecksum = CalculateChecksum8 ((UINT8 *) *VtfFileImage, sizeof (EFI_FFS_FILE_HEADER)); + (*VtfFileImage)->IntegrityCheck.Checksum.Header = VtfHeaderChecksum; + // + // Determine if it has a tail + // + if ((*VtfFileImage)->Attributes & FFS_ATTRIB_TAIL_PRESENT) { + TailSize = sizeof (EFI_FFS_FILE_TAIL); + } else { + TailSize = 0; + } + + if ((*VtfFileImage)->Attributes & FFS_ATTRIB_CHECKSUM) { + VtfFileChecksum = CalculateChecksum8 ((UINT8 *) *VtfFileImage, FileSize - TailSize); + (*VtfFileImage)->IntegrityCheck.Checksum.File = VtfFileChecksum; + } else { + (*VtfFileImage)->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; + } + // + // If it has a file tail, update it + // + if ((*VtfFileImage)->Attributes & FFS_ATTRIB_TAIL_PRESENT) { + TailValue = (EFI_FFS_FILE_TAIL) (~((*VtfFileImage)->IntegrityCheck.TailReference)); + *(EFI_FFS_FILE_TAIL *) (((UINTN) (*VtfFileImage) + GetLength ((*VtfFileImage)->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue; + } + (*VtfFileImage)->State = FileState; + free (FileBuffer); + return EFI_SUCCESS; + } else { + // + // Already found a VTF file. + // + Error (NULL, 0, 0, "multiple VTF files are illegal in a single FV", NULL); + free (FileBuffer); + return EFI_ABORTED; + } + } + // + // Check if alignment is required + // + Status = ReadFfsAlignment ((EFI_FFS_FILE_HEADER *) FileBuffer, &CurrentFileAlignment); + if (EFI_ERROR (Status)) { + printf ("ERROR: Could not determine alignment of file %s.\n", FvInfo->FvFiles[Index]); + free (FileBuffer); + return EFI_ABORTED; + } + // + // Add pad file if necessary + // + Status = AddPadFile (FvImage, CurrentFileAlignment); + if (EFI_ERROR (Status)) { + printf ("ERROR: Could not align the file data properly.\n"); + free (FileBuffer); + return EFI_ABORTED; + } + // + // Add file + // + if ((FvImage->CurrentFilePointer + FileSize) < FvImage->Eof) { + // + // Copy the file + // + memcpy (FvImage->CurrentFilePointer, FileBuffer, FileSize); + + // + // If the file is XIP, rebase + // + CurrentFileBaseAddress = FvInfo->BaseAddress + ((UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage); + // + // Status = RebaseFfsFile ((EFI_FFS_FILE_HEADER*) FvImage->CurrentFilePointer, CurrentFileBaseAddress); + // if (EFI_ERROR(Status)) { + // printf ("ERROR: Could not rebase the file %s.\n", FvInfo->FvFiles[Index]); + // return EFI_ABORTED; + // } + // + // Update Symbol file + // + Status = AddSymFile ( + CurrentFileBaseAddress, + (EFI_FFS_FILE_HEADER *) FvImage->CurrentFilePointer, + SymImage, + FvInfo->FvFiles[Index] + ); + assert (!EFI_ERROR (Status)); + + // + // Update the current pointer in the FV image + // + FvImage->CurrentFilePointer += FileSize; + } else { + printf ("ERROR: The firmware volume is out of space, could not add file %s.\n", FvInfo->FvFiles[Index]); + return EFI_ABORTED; + } + // + // Make next file start at QWord Boundry + // + while (((UINTN) FvImage->CurrentFilePointer & 0x07) != 0) { + FvImage->CurrentFilePointer++; + } + // + // Free allocated memory. + // + free (FileBuffer); + + return EFI_SUCCESS; +} + +EFI_STATUS +AddVariableBlock ( + IN UINT8 *FvImage, + IN UINTN Size, + IN FV_INFO *FvInfo + ) +{ + EFI_FIRMWARE_VOLUME_HEADER *FvHeader; + VARIABLE_STORE_HEADER *VarStoreHeader; + // + // Variable block should exclude FvHeader. Since the length of + // FvHeader depends on the block map, which is variable length, + // we could only decide the actual variable block length here. + // + FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FvImage; + FvImage = FvImage + FvHeader->HeaderLength; + + VarStoreHeader = (VARIABLE_STORE_HEADER *) FvImage; + + VarStoreHeader->Signature = VARIABLE_STORE_SIGNATURE; + VarStoreHeader->Size = Size - FvHeader->HeaderLength; + VarStoreHeader->Format = VARIABLE_STORE_FORMATTED; + VarStoreHeader->State = VARIABLE_STORE_HEALTHY; + VarStoreHeader->Reserved = 0; + VarStoreHeader->Reserved1 = 0; + + return EFI_SUCCESS; +} + +EFI_STATUS +AddEventLogBlock ( + IN UINT8 *FvImage, + IN UINTN Size, + IN FV_INFO *FvInfo + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +AddFTWWorkingBlock ( + IN UINT8 *FvImage, + IN UINTN Size, + IN FV_INFO *FvInfo + ) +{ + EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *FTWHeader; + UINT32 Crc32; + + Crc32 = 0; + FTWHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) FvImage; + memcpy (&FTWHeader->Signature, &(FvInfo->FvGuid), sizeof (EFI_GUID)); + FTWHeader->WriteQueueSize = Size - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER); + CalculateCrc32 (FvImage, sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER), &Crc32); + FTWHeader->Crc = Crc32; + if (FvInfo->FvAttributes & EFI_FVB_ERASE_POLARITY) { + FTWHeader->WorkingBlockValid = 0; + FTWHeader->WorkingBlockInvalid = 1; + } else { + FTWHeader->WorkingBlockValid = 1; + FTWHeader->WorkingBlockInvalid = 0; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +AddFTWSpareBlock ( + IN UINT8 *FvImage, + IN UINTN Size, + IN FV_INFO *FvInfo + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +GenNonFFSFv ( + IN UINT8 *FvImage, + IN FV_INFO *FvInfo + ) +/*++ + +Routine Description: + + This function generate the non FFS FV image, such as the working block + and spare block. How each component of the FV is built is component + specific. + +Arguments: + + FvImage The memory image of the FV to add it to. The current offset + must be valid. + FvInfo Pointer to information about the FV. + +Returns: + + EFI_SUCCESS The function completed successfully. + EFI_INVALID_PARAMETER One of the input parameters was invalid. + EFI_ABORTED An error occurred. + EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the add. + +--*/ +{ + UINTN Index; + EFI_FIRMWARE_VOLUME_HEADER *FvHeader; + UINT64 TotalSize; + + FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FvImage; + TotalSize = 0; + + for (Index = 0; FvInfo->FvComponents[Index].Size != 0; Index++) { + if (stricmp (FvInfo->FvComponents[Index].ComponentName, EFI_NV_VARIABLE_STRING) == 0) { + AddVariableBlock (FvImage, FvInfo->FvComponents[Index].Size, FvInfo); + } else if (stricmp (FvInfo->FvComponents[Index].ComponentName, EFI_NV_EVENT_LOG_STRING) == 0) { + AddEventLogBlock (FvImage, FvInfo->FvComponents[Index].Size, FvInfo); + } else if (stricmp (FvInfo->FvComponents[Index].ComponentName, EFI_NV_FTW_WORKING_STRING) == 0) { + AddFTWWorkingBlock (FvImage, FvInfo->FvComponents[Index].Size, FvInfo); + } else if (stricmp (FvInfo->FvComponents[Index].ComponentName, EFI_NV_FTW_SPARE_STRING) == 0) { + AddFTWSpareBlock (FvImage, FvInfo->FvComponents[Index].Size, FvInfo); + } else { + printf ("Error. Unknown Non-FFS block %s \n", FvInfo->FvComponents[Index].ComponentName); + return EFI_ABORTED; + } + + FvImage = FvImage + FvInfo->FvComponents[Index].Size; + TotalSize = TotalSize + FvInfo->FvComponents[Index].Size; + } + // + // Index and TotalSize is zero mean there's no component, so this is an empty fv + // + if ((Index != 0 || TotalSize != 0) && TotalSize != FvInfo->Size) { + printf ("Error. Component size does not sum up to FV size.\n"); + return EFI_ABORTED; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +PadFvImage ( + IN MEMORY_FILE *FvImage, + IN EFI_FFS_FILE_HEADER *VtfFileImage + ) +/*++ + +Routine Description: + + This function places a pad file between the last file in the FV and the VTF + file if the VTF file exists. + +Arguments: + + FvImage Memory file for the FV memory image + VtfFileImage The address of the VTF file. If this is the end of the FV + image, no VTF exists and no pad file is needed. + +Returns: + + EFI_SUCCESS Completed successfully. + EFI_INVALID_PARAMETER One of the input parameters was NULL. + +--*/ +{ + EFI_FFS_FILE_HEADER *PadFile; + UINTN FileSize; + + // + // If there is no VTF or the VTF naturally follows the previous file without a + // pad file, then there's nothing to do + // + if ((UINTN) VtfFileImage == (UINTN) FvImage->Eof || (void *) FvImage->CurrentFilePointer == (void *) VtfFileImage) { + return EFI_SUCCESS; + } + // + // Pad file starts at beginning of free space + // + PadFile = (EFI_FFS_FILE_HEADER *) FvImage->CurrentFilePointer; + + // + // write header + // + memset (PadFile, 0, sizeof (EFI_FFS_FILE_HEADER)); + memcpy (&PadFile->Name, &DefaultFvPadFileNameGuid, sizeof (EFI_GUID)); + PadFile->Type = EFI_FV_FILETYPE_FFS_PAD; + PadFile->Attributes = 0; + + // + // FileSize includes the EFI_FFS_FILE_HEADER + // + FileSize = (UINTN) VtfFileImage - (UINTN) FvImage->CurrentFilePointer; + PadFile->Size[0] = (UINT8) (FileSize & 0x000000FF); + PadFile->Size[1] = (UINT8) ((FileSize & 0x0000FF00) >> 8); + PadFile->Size[2] = (UINT8) ((FileSize & 0x00FF0000) >> 16); + + // + // Fill in checksums and state, must be zero during checksum calculation. + // + PadFile->IntegrityCheck.Checksum.Header = 0; + PadFile->IntegrityCheck.Checksum.File = 0; + PadFile->State = 0; + PadFile->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) PadFile, sizeof (EFI_FFS_FILE_HEADER)); + if (PadFile->Attributes & FFS_ATTRIB_CHECKSUM) { + PadFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) PadFile, FileSize); + } else { + PadFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; + } + + PadFile->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID; + + UpdateFfsFileState ( + (EFI_FFS_FILE_HEADER *) PadFile, + (EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage + ); + // + // Update the current FV pointer + // + FvImage->CurrentFilePointer = FvImage->Eof; + + return EFI_SUCCESS; +} + +EFI_STATUS +UpdateResetVector ( + IN MEMORY_FILE *FvImage, + IN FV_INFO *FvInfo, + IN EFI_FFS_FILE_HEADER *VtfFile + ) +/*++ + +Routine Description: + + This parses the FV looking for the PEI core and then plugs the address into + the SALE_ENTRY point of the BSF/VTF for IPF and does BUGBUG TBD action to + complete an IA32 Bootstrap FV. + +Arguments: + + FvImage Memory file for the FV memory image + FvInfo Information read from INF file. + VtfFile Pointer to the VTF file in the FV image. + +Returns: + + EFI_SUCCESS Function Completed successfully. + EFI_ABORTED Error encountered. + EFI_INVALID_PARAMETER A required parameter was NULL. + EFI_NOT_FOUND PEI Core file not found. + +--*/ +{ + EFI_FFS_FILE_HEADER *PeiCoreFile; + EFI_FFS_FILE_HEADER *SecCoreFile; + EFI_STATUS Status; + EFI_FILE_SECTION_POINTER Pe32Section; + UINT32 EntryPoint; + UINT32 BaseOfCode; + UINT16 MachineType; + EFI_PHYSICAL_ADDRESS PeiCorePhysicalAddress; + EFI_PHYSICAL_ADDRESS SecCorePhysicalAddress; + EFI_PHYSICAL_ADDRESS *SecCoreEntryAddressPtr; + UINT32 *Ia32ResetAddressPtr; + UINT8 *BytePointer; + UINT8 *BytePointer2; + UINT16 *WordPointer; + UINT16 CheckSum; + UINTN Index; + EFI_FFS_FILE_STATE SavedState; + EFI_FFS_FILE_TAIL TailValue; + UINT32 TailSize; + UINT64 FitAddress; + FIT_TABLE *FitTablePtr; + + // + // Verify input parameters + // + if (FvImage == NULL || FvInfo == NULL || VtfFile == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Initialize FV library + // + InitializeFvLib (FvImage->FileImage, (UINTN) FvImage->Eof - (UINTN) FvImage->FileImage); + + // + // Verify VTF file + // + Status = VerifyFfsFile (VtfFile); + if (EFI_ERROR (Status)) { + return EFI_INVALID_PARAMETER; + } + // + // Find the PEI Core + // + Status = GetFileByType (EFI_FV_FILETYPE_PEI_CORE, 1, &PeiCoreFile); + if (EFI_ERROR (Status) || PeiCoreFile == NULL) { + Error (NULL, 0, 0, "could not find the PEI core in the FV", NULL); + return EFI_ABORTED; + } + + // + // PEI Core found, now find PE32 or TE section + // + Status = GetSectionByType (PeiCoreFile, EFI_SECTION_PE32, 1, &Pe32Section); + if (Status == EFI_NOT_FOUND) { + Status = GetSectionByType (PeiCoreFile, EFI_SECTION_TE, 1, &Pe32Section); + } + + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "could not find PE32 or TE section in PEI core file", NULL); + return EFI_ABORTED; + } + + Status = GetPe32Info ( + (VOID *) ((UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32)), + &EntryPoint, + &BaseOfCode, + &MachineType + ); + + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "could not get PE32 entry point for PEI core", NULL); + return EFI_ABORTED; + } + // + // Physical address is FV base + offset of PE32 + offset of the entry point + // + PeiCorePhysicalAddress = FvInfo->BaseAddress; + PeiCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32) - (UINTN) FvImage->FileImage; + PeiCorePhysicalAddress += EntryPoint; + + if (MachineType == EFI_IMAGE_MACHINE_IA64) { + // + // Update PEI_CORE address + // + // + // Set the uncached attribute bit in the physical address + // + PeiCorePhysicalAddress |= 0x8000000000000000ULL; + + // + // Check if address is aligned on a 16 byte boundary + // + if (PeiCorePhysicalAddress & 0xF) { + printf ( + "ERROR: PEI_CORE entry point is not aligned on a 16 byte boundary, address specified is %Xh.\n", + PeiCorePhysicalAddress + ); + return EFI_ABORTED; + } + // + // First Get the FIT table address + // + FitAddress = (*(UINT64 *) (FvImage->Eof - IPF_FIT_ADDRESS_OFFSET)) & 0xFFFFFFFF; + + FitTablePtr = (FIT_TABLE *) (FvImage->FileImage + (FitAddress - FvInfo->BaseAddress)); + + Status = UpdatePeiCoreEntryInFit (FitTablePtr, PeiCorePhysicalAddress); + + if (!EFI_ERROR (Status)) { + UpdateFitCheckSum (FitTablePtr); + } + // + // Find the Sec Core + // + Status = GetFileByType (EFI_FV_FILETYPE_SECURITY_CORE, 1, &SecCoreFile); + if (EFI_ERROR (Status) || SecCoreFile == NULL) { + Error (NULL, 0, 0, "could not find the Sec core in the FV", NULL); + return EFI_ABORTED; + } + // + // Sec Core found, now find PE32 section + // + Status = GetSectionByType (SecCoreFile, EFI_SECTION_PE32, 1, &Pe32Section); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "could not find PE32 section in SEC core file", NULL); + return EFI_ABORTED; + } + + Status = GetPe32Info ( + (VOID *) ((UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32)), + &EntryPoint, + &BaseOfCode, + &MachineType + ); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "could not get PE32 entry point for SEC core", NULL); + return EFI_ABORTED; + } + // + // Physical address is FV base + offset of PE32 + offset of the entry point + // + SecCorePhysicalAddress = FvInfo->BaseAddress; + SecCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32) - (UINTN) FvImage->FileImage; + SecCorePhysicalAddress += EntryPoint; + + // + // Update SEC_CORE address + // + // + // Set the uncached attribute bit in the physical address + // + SecCorePhysicalAddress |= 0x8000000000000000ULL; + + // + // Update the address + // + SecCoreEntryAddressPtr = (EFI_PHYSICAL_ADDRESS *) ((UINTN) FvImage->Eof - IPF_SALE_ENTRY_ADDRESS_OFFSET); + *SecCoreEntryAddressPtr = SecCorePhysicalAddress; + + // + // Check if address is aligned on a 16 byte boundary + // + if (SecCorePhysicalAddress & 0xF) { + printf ( + "ERROR: SALE_ENTRY entry point is not aligned on a 16 byte boundary, address specified is %Xh.\n", + SecCorePhysicalAddress + ); + return EFI_ABORTED; + } + } else if (MachineType == EFI_IMAGE_MACHINE_IA32) { + // + // Get the location to update + // + Ia32ResetAddressPtr = (UINT32 *) ((UINTN) FvImage->Eof - IA32_PEI_CORE_ENTRY_OFFSET); + + // + // Write lower 32 bits of physical address + // + *Ia32ResetAddressPtr = (UINT32) PeiCorePhysicalAddress; + + // + // Update the BFV base address + // + Ia32ResetAddressPtr = (UINT32 *) ((UINTN) FvImage->Eof - 4); + *Ia32ResetAddressPtr = (UINT32) (FvInfo->BaseAddress); + + CheckSum = 0x0000; + + // + // Update the Startup AP in the FVH header block ZeroVector region. + // + BytePointer = (UINT8 *) ((UINTN) FvImage->FileImage); + BytePointer2 = (FvInfo->Size == 0x10000) ? m64kRecoveryStartupApDataArray : m128kRecoveryStartupApDataArray; + for (Index = 0; Index < SIZEOF_STARTUP_DATA_ARRAY; Index++) { + *BytePointer++ = *BytePointer2++; + } + // + // Calculate the checksum + // + WordPointer = (UINT16 *) ((UINTN) FvImage->FileImage); + for (Index = 0; Index < SIZEOF_STARTUP_DATA_ARRAY / 2; Index++) { + CheckSum = (UINT16) (CheckSum + ((UINT16) *WordPointer)); + WordPointer++; + } + // + // Update the checksum field + // + BytePointer = (UINT8 *) ((UINTN) FvImage->FileImage); + BytePointer += (SIZEOF_STARTUP_DATA_ARRAY - 2); + WordPointer = (UINT16 *) BytePointer; + *WordPointer = (UINT16) (0x10000 - (UINT32) CheckSum); + } else { + Error (NULL, 0, 0, "invalid machine type in PEI core", "machine type=0x%X", (UINT32) MachineType); + return EFI_ABORTED; + } + // + // Determine if it has an FFS file tail. + // + if (VtfFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) { + TailSize = sizeof (EFI_FFS_FILE_TAIL); + } else { + TailSize = 0; + } + // + // Now update file checksum + // + SavedState = VtfFile->State; + VtfFile->IntegrityCheck.Checksum.File = 0; + VtfFile->State = 0; + if (VtfFile->Attributes & FFS_ATTRIB_CHECKSUM) { + VtfFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ( + (UINT8 *) VtfFile, + GetLength (VtfFile->Size) - TailSize + ); + } else { + VtfFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; + } + + VtfFile->State = SavedState; + + // + // Update tail if present + // + if (VtfFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) { + TailValue = (EFI_FFS_FILE_TAIL) (~(VtfFile->IntegrityCheck.TailReference)); + *(EFI_FFS_FILE_TAIL *) (((UINTN) (VtfFile) + GetLength (VtfFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +GetPe32Info ( + IN UINT8 *Pe32, + OUT UINT32 *EntryPoint, + OUT UINT32 *BaseOfCode, + OUT UINT16 *MachineType + ) +/*++ + +Routine Description: + + Retrieves the PE32 entry point offset and machine type from PE image or TeImage. + See EfiImage.h for machine types. The entry point offset is from the beginning + of the PE32 buffer passed in. + +Arguments: + + Pe32 Beginning of the PE32. + EntryPoint Offset from the beginning of the PE32 to the image entry point. + BaseOfCode Base address of code. + MachineType Magic number for the machine type. + +Returns: + + EFI_SUCCESS Function completed successfully. + EFI_ABORTED Error encountered. + EFI_INVALID_PARAMETER A required parameter was NULL. + EFI_UNSUPPORTED The operation is unsupported. + +--*/ +{ + EFI_IMAGE_DOS_HEADER *DosHeader; + EFI_IMAGE_NT_HEADERS *NtHeader; + EFI_TE_IMAGE_HEADER *TeHeader; + + // + // Verify input parameters + // + if (Pe32 == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // First check whether it is one TE Image. + // + TeHeader = (EFI_TE_IMAGE_HEADER *) Pe32; + if (TeHeader->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { + // + // By TeImage Header to get output + // + *EntryPoint = TeHeader->AddressOfEntryPoint + sizeof (EFI_TE_IMAGE_HEADER) - TeHeader->StrippedSize; + *BaseOfCode = TeHeader->BaseOfCode + sizeof (EFI_TE_IMAGE_HEADER) - TeHeader->StrippedSize; + *MachineType = TeHeader->Machine; + } else { + + // + // Then check whether + // First is the DOS header + // + DosHeader = (EFI_IMAGE_DOS_HEADER *) Pe32; + + // + // Verify DOS header is expected + // + if (DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) { + printf ("ERROR: Unknown magic number in the DOS header, 0x%04X.\n", DosHeader->e_magic); + return EFI_UNSUPPORTED; + } + // + // Immediately following is the NT header. + // + NtHeader = (EFI_IMAGE_NT_HEADERS *) ((UINTN) Pe32 + DosHeader->e_lfanew); + + // + // Verify NT header is expected + // + if (NtHeader->Signature != EFI_IMAGE_NT_SIGNATURE) { + printf ("ERROR: Unrecognized image signature 0x%08X.\n", NtHeader->Signature); + return EFI_UNSUPPORTED; + } + // + // Get output + // + *EntryPoint = NtHeader->OptionalHeader.AddressOfEntryPoint; + *BaseOfCode = NtHeader->OptionalHeader.BaseOfCode; + *MachineType = NtHeader->FileHeader.Machine; + } + + // + // Verify machine type is supported + // + if (*MachineType != EFI_IMAGE_MACHINE_IA32 && *MachineType != EFI_IMAGE_MACHINE_IA64 && *MachineType != EFI_IMAGE_MACHINE_X64 && *MachineType != EFI_IMAGE_MACHINE_EBC) { + printf ("ERROR: Unrecognized machine type in the PE32 file.\n"); + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} +// +// Exposed function implementations (prototypes are defined in GenFvImageLib.h) +// +EFI_STATUS +GenerateFvImage ( + IN CHAR8 *InfFileImage, + IN UINTN InfFileSize, + OUT UINT8 **FvImage, + OUT UINTN *FvImageSize, + OUT CHAR8 **FvFileName, + OUT UINT8 **SymImage, + OUT UINTN *SymImageSize, + OUT CHAR8 **SymFileName + ) +/*++ + +Routine Description: + + This is the main function which will be called from application. + +Arguments: + + InfFileImage Buffer containing the INF file contents. + InfFileSize Size of the contents of the InfFileImage buffer. + FvImage Pointer to the FV image created. + FvImageSize Size of the FV image created and pointed to by FvImage. + FvFileName Requested name for the FV file. + SymImage Pointer to the Sym image created. + SymImageSize Size of the Sym image created and pointed to by SymImage. + SymFileName Requested name for the Sym file. + +Returns: + + EFI_SUCCESS Function completed successfully. + EFI_OUT_OF_RESOURCES Could not allocate required resources. + EFI_ABORTED Error encountered. + EFI_INVALID_PARAMETER A required parameter was NULL. + +--*/ +{ + EFI_STATUS Status; + MEMORY_FILE InfMemoryFile; + MEMORY_FILE FvImageMemoryFile; + MEMORY_FILE SymImageMemoryFile; + FV_INFO FvInfo; + UINTN Index; + EFI_FIRMWARE_VOLUME_HEADER *FvHeader; + EFI_FFS_FILE_HEADER *VtfFileImage; + + // + // Check for invalid parameter + // + if (InfFileImage == NULL || FvImage == NULL || FvImageSize == NULL || FvFileName == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Initialize file structures + // + InfMemoryFile.FileImage = InfFileImage; + InfMemoryFile.CurrentFilePointer = InfFileImage; + InfMemoryFile.Eof = InfFileImage + InfFileSize; + + // + // Parse the FV inf file for header information + // + Status = ParseFvInf (&InfMemoryFile, &FvInfo); + if (EFI_ERROR (Status)) { + printf ("ERROR: Could not parse the input INF file.\n"); + return EFI_ABORTED; + } + // + // Update the file name return values + // + strcpy (*FvFileName, FvInfo.FvName); + strcpy (*SymFileName, FvInfo.SymName); + + // + // Calculate the FV size + // + *FvImageSize = FvInfo.Size; + + // + // Allocate the FV + // + *FvImage = malloc (*FvImageSize); + if (*FvImage == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // Allocate space for symbol file storage + // + *SymImage = malloc (SYMBOL_FILE_SIZE); + if (*SymImage == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // Initialize the FV to the erase polarity + // + if (FvInfo.FvAttributes & EFI_FVB_ERASE_POLARITY) { + memset (*FvImage, -1, *FvImageSize); + } else { + memset (*FvImage, 0, *FvImageSize); + } + // + // Initialize FV header + // + FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) *FvImage; + + // + // Initialize the zero vector to all zeros. + // + memset (FvHeader->ZeroVector, 0, 16); + + // + // Copy the FFS GUID + // + memcpy (&FvHeader->FileSystemGuid, &FvInfo.FvGuid, sizeof (EFI_GUID)); + + FvHeader->FvLength = *FvImageSize; + FvHeader->Signature = EFI_FVH_SIGNATURE; + FvHeader->Attributes = FvInfo.FvAttributes; + FvHeader->Revision = EFI_FVH_REVISION; + FvHeader->Reserved[0] = 0; + FvHeader->Reserved[1] = 0; + FvHeader->Reserved[2] = 0; + + // + // Copy firmware block map + // + for (Index = 0; FvInfo.FvBlocks[Index].NumBlocks != 0; Index++) { + FvHeader->FvBlockMap[Index].NumBlocks = FvInfo.FvBlocks[Index].NumBlocks; + FvHeader->FvBlockMap[Index].BlockLength = FvInfo.FvBlocks[Index].BlockLength; + } + // + // Add block map terminator + // + FvHeader->FvBlockMap[Index].NumBlocks = 0; + FvHeader->FvBlockMap[Index].BlockLength = 0; + + // + // Complete the header + // + FvHeader->HeaderLength = (UINT16) (((UINTN) &(FvHeader->FvBlockMap[Index + 1])) - (UINTN) *FvImage); + FvHeader->Checksum = 0; + FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); + + // + // If there is no FFS file, find and generate each components of the FV + // + if (FvInfo.FvFiles[0][0] == 0) { + Status = GenNonFFSFv (*FvImage, &FvInfo); + if (EFI_ERROR (Status)) { + printf ("ERROR: Could not generate NonFFS FV.\n"); + free (*FvImage); + return EFI_ABORTED; + } + + return EFI_SUCCESS; + } + // + // Initialize our "file" view of the buffer + // + FvImageMemoryFile.FileImage = *FvImage; + FvImageMemoryFile.CurrentFilePointer = *FvImage + FvHeader->HeaderLength; + FvImageMemoryFile.Eof = *FvImage +*FvImageSize; + + // + // Initialize our "file" view of the symbol file. + // + SymImageMemoryFile.FileImage = *SymImage; + SymImageMemoryFile.CurrentFilePointer = *SymImage; + SymImageMemoryFile.Eof = *FvImage + SYMBOL_FILE_SIZE; + + // + // Initialize the FV library. + // + InitializeFvLib (FvImageMemoryFile.FileImage, FvInfo.Size); + + // + // Files start on 8 byte alignments, so move to the next 8 byte aligned + // address. For now, just assert if it isn't. Currently FV header is + // always a multiple of 8 bytes. + // BUGBUG: Handle this better + // + assert ((((UINTN) FvImageMemoryFile.CurrentFilePointer) % 8) == 0); + + // + // Initialize the VTF file address. + // + VtfFileImage = (EFI_FFS_FILE_HEADER *) FvImageMemoryFile.Eof; + + // + // Add files to FV + // + for (Index = 0; FvInfo.FvFiles[Index][0] != 0; Index++) { + // + // Add the file + // + Status = AddFile (&FvImageMemoryFile, &FvInfo, Index, &VtfFileImage, &SymImageMemoryFile); + + // + // Exit if error detected while adding the file + // + if (EFI_ERROR (Status)) { + printf ("ERROR: Could not add file %s.\n", FvInfo.FvFiles[Index]); + free (*FvImage); + return EFI_ABORTED; + } + } + // + // If there is a VTF file, some special actions need to occur. + // + if ((UINTN) VtfFileImage != (UINTN) FvImageMemoryFile.Eof) { + // + // Pad from the end of the last file to the beginning of the VTF file. + // + Status = PadFvImage (&FvImageMemoryFile, VtfFileImage); + if (EFI_ERROR (Status)) { + printf ("ERROR: Could not create the pad file between the last file and the VTF file.\n"); + free (*FvImage); + return EFI_ABORTED; + } + // + // Update reset vector (SALE_ENTRY for IPF) + // Now for IA32 and IA64 platform, the fv which has bsf file must have the + // EndAddress of 0xFFFFFFFF. Thus, only this type fv needs to update the + // reset vector. If the PEI Core is found, the VTF file will probably get + // corrupted by updating the entry point. + // + if ((FvInfo.BaseAddress + FvInfo.Size) == FV_IMAGES_TOP_ADDRESS) { + Status = UpdateResetVector (&FvImageMemoryFile, &FvInfo, VtfFileImage); + if (EFI_ERROR(Status)) { + printf ("ERROR: Could not update the reset vector.\n"); + free (*FvImage); + return EFI_ABORTED; + } + } + } + // + // Determine final Sym file size + // + *SymImageSize = SymImageMemoryFile.CurrentFilePointer - SymImageMemoryFile.FileImage; + + return EFI_SUCCESS; +} + +EFI_STATUS +UpdatePeiCoreEntryInFit ( + IN FIT_TABLE *FitTablePtr, + IN UINT64 PeiCorePhysicalAddress + ) +/*++ + +Routine Description: + + This function is used to update the Pei Core address in FIT, this can be used by Sec core to pass control from + Sec to Pei Core + +Arguments: + + FitTablePtr - The pointer of FIT_TABLE. + PeiCorePhysicalAddress - The address of Pei Core entry. + +Returns: + + EFI_SUCCESS - The PEI_CORE FIT entry was updated successfully. + EFI_NOT_FOUND - Not found the PEI_CORE FIT entry. + +--*/ +{ + FIT_TABLE *TmpFitPtr; + UINTN Index; + UINTN NumFitComponents; + + TmpFitPtr = FitTablePtr; + NumFitComponents = TmpFitPtr->CompSize; + + for (Index = 0; Index < NumFitComponents; Index++) { + if ((TmpFitPtr->CvAndType & FIT_TYPE_MASK) == COMP_TYPE_FIT_PEICORE) { + TmpFitPtr->CompAddress = PeiCorePhysicalAddress; + return EFI_SUCCESS; + } + + TmpFitPtr++; + } + + return EFI_NOT_FOUND; +} + +VOID +UpdateFitCheckSum ( + IN FIT_TABLE *FitTablePtr + ) +/*++ + +Routine Description: + + This function is used to update the checksum for FIT. + + +Arguments: + + FitTablePtr - The pointer of FIT_TABLE. + +Returns: + + None. + +--*/ +{ + if ((FitTablePtr->CvAndType & CHECKSUM_BIT_MASK) >> 7) { + FitTablePtr->CheckSum = 0; + FitTablePtr->CheckSum = CalculateChecksum8 ((UINT8 *) FitTablePtr, FitTablePtr->CompSize * 16); + } +} diff --git a/Tools/CodeTools/Source/GenFvImage/GenFvImageLib.h b/Tools/CodeTools/Source/GenFvImage/GenFvImageLib.h new file mode 100644 index 0000000000..47a5a3b1b2 --- /dev/null +++ b/Tools/CodeTools/Source/GenFvImage/GenFvImageLib.h @@ -0,0 +1,142 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + GenFvImageLib.h + +Abstract: + + This file contains describes the public interfaces to the GenFvImage Library. + The basic purpose of the library is to create Firmware Volume images. + +--*/ + +#ifndef _EFI_GEN_FV_IMAGE_LIB_H +#define _EFI_GEN_FV_IMAGE_LIB_H + +// +// Include files +// +#include +#include + +#include "ParseInf.h" + +// +// Following definition is used for FIT in IPF +// +#define COMP_TYPE_FIT_PEICORE 0x10 +#define COMP_TYPE_FIT_UNUSED 0x7F + +#define FIT_TYPE_MASK 0x7F +#define CHECKSUM_BIT_MASK 0x80 + +#pragma pack(1) + +typedef struct { + UINT64 CompAddress; + UINT32 CompSize; + UINT16 CompVersion; + UINT8 CvAndType; + UINT8 CheckSum; +} FIT_TABLE; + +#pragma pack() +// +// Exported function prototypes +// +EFI_STATUS +GenerateFvImage ( + IN CHAR8 *InfFileImage, + IN UINTN InfFileSize, + OUT UINT8 **FvImage, + OUT UINTN *FvImageSize, + OUT CHAR8 **FvFileName, + OUT UINT8 **SymImage, + OUT UINTN *SymImageSize, + OUT CHAR8 **SymFileName + ) +; + +/*++ + +Routine Description: + + This is the main function which will be called from application. + +Arguments: + + InfFileImage Buffer containing the INF file contents. + InfFileSize Size of the contents of the InfFileImage buffer. + FvImage Pointer to the FV image created. + FvImageSize Size of the FV image created and pointed to by FvImage. + FvFileName Requested name for the FV file. + SymImage Pointer to the Sym image created. + SymImageSize Size of the Sym image created and pointed to by SymImage. + SymFileName Requested name for the Sym file. + +Returns: + + EFI_SUCCESS Function completed successfully. + EFI_OUT_OF_RESOURCES Could not allocate required resources. + EFI_ABORTED Error encountered. + EFI_INVALID_PARAMETER A required parameter was NULL. + +--*/ +EFI_STATUS +UpdatePeiCoreEntryInFit ( + IN FIT_TABLE *FitTablePtr, + IN UINT64 PeiCorePhysicalAddress + ) +; + +/*++ + +Routine Description: + + This function is used to update the Pei Core address in FIT, this can be used by Sec core to pass control from + Sec to Pei Core + +Arguments: + + FitTablePtr - The pointer of FIT_TABLE. + PeiCorePhysicalAddress - The address of Pei Core entry. + +Returns: + + EFI_SUCCESS - The PEI_CORE FIT entry was updated successfully. + EFI_NOT_FOUND - Not found the PEI_CORE FIT entry. + +--*/ +VOID +UpdateFitCheckSum ( + IN FIT_TABLE *FitTablePtr + ) +; + +/*++ + +Routine Description: + + This function is used to update the checksum for FIT. + + +Arguments: + + FitTablePtr - The pointer of FIT_TABLE. + +Returns: + + None. + +--*/ +#endif diff --git a/Tools/CodeTools/Source/GenFvImage/GenFvImageLibInternal.h b/Tools/CodeTools/Source/GenFvImage/GenFvImageLibInternal.h new file mode 100644 index 0000000000..cff3b1aea4 --- /dev/null +++ b/Tools/CodeTools/Source/GenFvImage/GenFvImageLibInternal.h @@ -0,0 +1,172 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + GenFvImageLibInternal.h + +Abstract: + + This file contains describes the private declarations for the GenFvImage Library. + The basic purpose of the library is to create Firmware Volume images. + +--*/ + +#ifndef _EFI_GEN_FV_IMAGE_LIB_INTERNAL_H +#define _EFI_GEN_FV_IMAGE_LIB_INTERNAL_H + +// +// Include files +// +#include + +#include + +#include "CommonLib.h" +#include "GenFvImageLib.h" + +// +// Private data declarations +// +// +// The maximum number of block map entries supported by the library +// +#define MAX_NUMBER_OF_FV_BLOCKS 100 + +// +// The maximum number of files in the FV supported by the library +// +#define MAX_NUMBER_OF_FILES_IN_FV 1000 +#define MAX_NUMBER_OF_COMPONENTS_IN_FV 10 + +// +// INF file strings +// +#define OPTIONS_SECTION_STRING "[options]" +#define ATTRIBUTES_SECTION_STRING "[attributes]" +#define FILES_SECTION_STRING "[files]" +#define COMPONENT_SECTION_STRING "[components]" + +#define EFI_FV_BASE_ADDRESS_STRING "EFI_BASE_ADDRESS" +#define EFI_FV_FILE_NAME_STRING "EFI_FILE_NAME" +#define EFI_SYM_FILE_NAME_STRING "EFI_SYM_FILE_NAME" +#define EFI_NUM_BLOCKS_STRING "EFI_NUM_BLOCKS" +#define EFI_BLOCK_SIZE_STRING "EFI_BLOCK_SIZE" +#define EFI_FV_GUID_STRING "EFI_FV_GUID" + +#define EFI_FVB_READ_DISABLED_CAP_STRING "EFI_READ_DISABLED_CAP" +#define EFI_FVB_READ_ENABLED_CAP_STRING "EFI_READ_ENABLED_CAP" +#define EFI_FVB_READ_STATUS_STRING "EFI_READ_STATUS" + +#define EFI_FVB_WRITE_DISABLED_CAP_STRING "EFI_WRITE_DISABLED_CAP" +#define EFI_FVB_WRITE_ENABLED_CAP_STRING "EFI_WRITE_ENABLED_CAP" +#define EFI_FVB_WRITE_STATUS_STRING "EFI_WRITE_STATUS" + +#define EFI_FVB_LOCK_CAP_STRING "EFI_LOCK_CAP" +#define EFI_FVB_LOCK_STATUS_STRING "EFI_LOCK_STATUS" + +#define EFI_FVB_STICKY_WRITE_STRING "EFI_STICKY_WRITE" +#define EFI_FVB_MEMORY_MAPPED_STRING "EFI_MEMORY_MAPPED" +#define EFI_FVB_ERASE_POLARITY_STRING "EFI_ERASE_POLARITY" + +#define EFI_FVB_ALIGNMENT_CAP_STRING "EFI_ALIGNMENT_CAP" +#define EFI_FVB_ALIGNMENT_2_STRING "EFI_ALIGNMENT_2" +#define EFI_FVB_ALIGNMENT_4_STRING "EFI_ALIGNMENT_4" +#define EFI_FVB_ALIGNMENT_8_STRING "EFI_ALIGNMENT_8" +#define EFI_FVB_ALIGNMENT_16_STRING "EFI_ALIGNMENT_16" +#define EFI_FVB_ALIGNMENT_32_STRING "EFI_ALIGNMENT_32" +#define EFI_FVB_ALIGNMENT_64_STRING "EFI_ALIGNMENT_64" +#define EFI_FVB_ALIGNMENT_128_STRING "EFI_ALIGNMENT_128" +#define EFI_FVB_ALIGNMENT_256_STRING "EFI_ALIGNMENT_256" +#define EFI_FVB_ALIGNMENT_512_STRING "EFI_ALIGNMENT_512" +#define EFI_FVB_ALIGNMENT_1K_STRING "EFI_ALIGNMENT_1K" +#define EFI_FVB_ALIGNMENT_2K_STRING "EFI_ALIGNMENT_2K" +#define EFI_FVB_ALIGNMENT_4K_STRING "EFI_ALIGNMENT_4K" +#define EFI_FVB_ALIGNMENT_8K_STRING "EFI_ALIGNMENT_8K" +#define EFI_FVB_ALIGNMENT_16K_STRING "EFI_ALIGNMENT_16K" +#define EFI_FVB_ALIGNMENT_32K_STRING "EFI_ALIGNMENT_32K" +#define EFI_FVB_ALIGNMENT_64K_STRING "EFI_ALIGNMENT_64K" + +// +// Component sections +// +#define EFI_NV_VARIABLE_STRING "EFI_NV_VARIABLE" +#define EFI_NV_EVENT_LOG_STRING "EFI_NV_EVENT_LOG" +#define EFI_NV_FTW_WORKING_STRING "EFI_NV_FTW_WORKING" +#define EFI_NV_FTW_SPARE_STRING "EFI_NV_FTW_SPARE" + +#define EFI_FILE_NAME_STRING "EFI_FILE_NAME" + +#define ONE_STRING "1" +#define ZERO_STRING "0" +#define TRUE_STRING "TRUE" +#define FALSE_STRING "FALSE" +#define NULL_STRING "NULL" + +// +// Defines to calculate the offset for PEI CORE entry points +// +#define IA32_PEI_CORE_ENTRY_OFFSET 0x20 + +// +// Defines to calculate the FIT table +// +#define IPF_FIT_ADDRESS_OFFSET 0x20 + +// +// Defines to calculate the offset for SALE_ENTRY +// +#define IPF_SALE_ENTRY_ADDRESS_OFFSET 0x18 + +// +// Symbol file definitions, current max size if 512K +// +#define SYMBOL_FILE_SIZE 0x80000 + +#define FV_IMAGES_TOP_ADDRESS 0x100000000ULL + +// +// Private data types +// +// +// Component information +// +typedef struct { + UINTN Size; + CHAR8 ComponentName[_MAX_PATH]; +} COMPONENT_INFO; + +// +// FV information holder +// +typedef struct { + EFI_PHYSICAL_ADDRESS BaseAddress; + EFI_GUID FvGuid; + UINTN Size; + CHAR8 FvName[_MAX_PATH]; + CHAR8 SymName[_MAX_PATH]; + EFI_FV_BLOCK_MAP_ENTRY FvBlocks[MAX_NUMBER_OF_FV_BLOCKS]; + EFI_FVB_ATTRIBUTES FvAttributes; + CHAR8 FvFiles[MAX_NUMBER_OF_FILES_IN_FV][_MAX_PATH]; + COMPONENT_INFO FvComponents[MAX_NUMBER_OF_COMPONENTS_IN_FV]; +} FV_INFO; + +// +// Private function prototypes +// +EFI_STATUS +ParseFvInf ( + IN MEMORY_FILE *InfFile, + IN FV_INFO *FvInfo + ) +; + +#endif diff --git a/Tools/CodeTools/Source/GenFvImage/build.xml b/Tools/CodeTools/Source/GenFvImage/build.xml new file mode 100644 index 0000000000..ae930b053b --- /dev/null +++ b/Tools/CodeTools/Source/GenFvImage/build.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/GenSection/GenSection.c b/Tools/CodeTools/Source/GenSection/GenSection.c new file mode 100644 index 0000000000..353b1a3985 --- /dev/null +++ b/Tools/CodeTools/Source/GenSection/GenSection.c @@ -0,0 +1,938 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + GenSection.c + +Abstract: + + Creates output file that is a properly formed section per the FV spec. + +--*/ + +#include +#include +#include + +#include +#include +#include + +#include "CommonLib.h" +#include "EfiCompress.h" +#include "EfiCustomizedCompress.h" +#include "Crc32.h" +#include "EfiUtilityMsgs.h" +#include "GenSection.h" + + +#define UTILITY_NAME "GenSection" + +#define PARAMETER_NOT_SPECIFIED "Parameter not specified" +#define MAXIMUM_INPUT_FILE_NUM 10 + +char *SectionTypeName[] = { + NULL, // 0x00 - reserved + "EFI_SECTION_COMPRESSION", // 0x01 + "EFI_SECTION_GUID_DEFINED", // 0x02 + NULL, // 0x03 - reserved + NULL, // 0x04 - reserved + NULL, // 0x05 - reserved + NULL, // 0x06 - reserved + NULL, // 0x07 - reserved + NULL, // 0x08 - reserved + NULL, // 0x09 - reserved + NULL, // 0x0A - reserved + NULL, // 0x0B - reserved + NULL, // 0x0C - reserved + NULL, // 0x0D - reserved + NULL, // 0x0E - reserved + NULL, // 0x0F - reserved + "EFI_SECTION_PE32", // 0x10 + "EFI_SECTION_PIC", // 0x11 + "EFI_SECTION_TE", // 0x12 + "EFI_SECTION_DXE_DEPEX", // 0x13 + "EFI_SECTION_VERSION", // 0x14 + "EFI_SECTION_USER_INTERFACE", // 0x15 + "EFI_SECTION_COMPATIBILITY16", // 0x16 + "EFI_SECTION_FIRMWARE_VOLUME_IMAGE", // 0x17 + "EFI_SECTION_FREEFORM_SUBTYPE_GUID", // 0x18 + "EFI_SECTION_RAW", // 0x19 + NULL, // 0x1A + "EFI_SECTION_PEI_DEPEX" // 0x1B +}; + +char *CompressionTypeName[] = { "NONE", "STANDARD" }; +char *GUIDedSectionTypeName[] = { "CRC32" }; +EFI_GUID gEfiCrc32SectionGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID; + +static +VOID +PrintUsageMessage ( + VOID + ) +{ + UINTN SectionType; + UINTN DisplayCount; + + printf ("Usage: "UTILITY_NAME " -i InputFile -o OutputFile -s SectionType [SectionType params]\n\n"); + printf (" Where SectionType is one of the following section types:\n\n"); + + DisplayCount = 0; + for (SectionType = 0; SectionType <= EFI_SECTION_LAST_SECTION_TYPE; SectionType++) { + if (SectionTypeName[SectionType] != NULL) { + printf (" %s\n", SectionTypeName[SectionType]); + } + } + + printf ("\n and SectionType dependent parameters are as follows:\n\n"); + printf ( + " %s: -t < %s | %s >\n", + SectionTypeName[EFI_SECTION_COMPRESSION], + CompressionTypeName[EFI_NOT_COMPRESSED], + CompressionTypeName[EFI_STANDARD_COMPRESSION] + ); + printf ( + " %s: -t < %s >\n"" // Currently only CRC32 is supported\n\n", + SectionTypeName[EFI_SECTION_GUID_DEFINED], + GUIDedSectionTypeName[EFI_SECTION_CRC32_GUID_DEFINED] + ); + printf ( + " %s: -v VersionNumber\n"" [-a \"Version string\"]\n\n", + SectionTypeName[EFI_SECTION_VERSION] + ); + printf ( + " %s: -a \"Human readable name\"\n\n", + SectionTypeName[EFI_SECTION_USER_INTERFACE] + ); +} + +VOID +Ascii2UnicodeWriteString ( + char *String, + FILE *OutFile, + BOOLEAN WriteLangCode + ) +{ + UINTN Index; + UINT8 AsciiNull; + // + // BUGBUG need to get correct language code... + // + char *EnglishLangCode = "eng"; + AsciiNull = 0; + // + // first write the language code (english only) + // + if (WriteLangCode) { + fwrite (EnglishLangCode, 1, 4, OutFile); + } + // + // Next, write out the string... Convert ASCII to Unicode in the process. + // + Index = 0; + do { + fwrite (&String[Index], 1, 1, OutFile); + fwrite (&AsciiNull, 1, 1, OutFile); + } while (String[Index++] != 0); +} + +STATUS +GenSectionCommonLeafSection ( + char **InputFileName, + int InputFileNum, + UINTN SectionType, + FILE *OutFile + ) +/*++ + +Routine Description: + + Generate a leaf section of type other than EFI_SECTION_VERSION + and EFI_SECTION_USER_INTERFACE. Input file must be well formed. + The function won't validate the input file's contents. For + common leaf sections, the input file may be a binary file. + The utility will add section header to the file. + +Arguments: + + InputFileName - Name of the input file. + + InputFileNum - Number of input files. Should be 1 for leaf section. + + SectionType - A valid section type string + + OutFile - Output file handle + +Returns: + + STATUS_ERROR - can't continue + STATUS_SUCCESS - successful return + +--*/ +{ + UINT64 InputFileLength; + FILE *InFile; + UINT8 *Buffer; + INTN TotalLength; + EFI_COMMON_SECTION_HEADER CommonSect; + STATUS Status; + + if (InputFileNum > 1) { + Error (NULL, 0, 0, "invalid parameter", "more than one input file specified"); + return STATUS_ERROR; + } else if (InputFileNum < 1) { + Error (NULL, 0, 0, "no input file specified", NULL); + return STATUS_ERROR; + } + // + // Open the input file + // + InFile = fopen (InputFileName[0], "rb"); + if (InFile == NULL) { + Error (NULL, 0, 0, InputFileName[0], "failed to open input file"); + return STATUS_ERROR; + } + + Status = STATUS_ERROR; + Buffer = NULL; + // + // Seek to the end of the input file so we can determine its size + // + fseek (InFile, 0, SEEK_END); + fgetpos (InFile, &InputFileLength); + fseek (InFile, 0, SEEK_SET); + // + // Fill in the fields in the local section header structure + // + CommonSect.Type = (EFI_SECTION_TYPE) SectionType; + TotalLength = sizeof (CommonSect) + (INTN) InputFileLength; + // + // Size must fit in 3 bytes + // + if (TotalLength >= 0x1000000) { + Error (NULL, 0, 0, InputFileName[0], "file size (0x%X) exceeds section size limit", TotalLength); + goto Done; + } + // + // Now copy the size into the section header and write out the section header + // + memcpy (&CommonSect.Size, &TotalLength, 3); + fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile); + // + // Allocate a buffer to read in the contents of the input file. Then + // read it in as one block and write it to the output file. + // + if (InputFileLength != 0) { + Buffer = (UINT8 *) malloc ((size_t) InputFileLength); + if (Buffer == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + goto Done; + } + + if (fread (Buffer, (size_t) InputFileLength, 1, InFile) != 1) { + Error (NULL, 0, 0, InputFileName[0], "failed to read contents of file"); + goto Done; + } + + if (fwrite (Buffer, (size_t) InputFileLength, 1, OutFile) != 1) { + Error (NULL, 0, 0, "failed to write to output file", NULL); + goto Done; + } + } + + Status = STATUS_SUCCESS; +Done: + fclose (InFile); + if (Buffer != NULL) { + free (Buffer); + } + + return Status; +} + +EFI_STATUS +GetSectionContents ( + char **InputFileName, + int InputFileNum, + UINT8 *FileBuffer, + UINTN *BufferLength + ) +/*++ + +Routine Description: + + Get the contents of all section files specified in InputFileName + into FileBuffer. + +Arguments: + + InputFileName - Name of the input file. + + InputFileNum - Number of input files. Should be at least 1. + + FileBuffer - Output buffer to contain data + + BufferLength - Actual length of the data + +Returns: + + EFI_SUCCESS on successful return + EFI_INVALID_PARAMETER if InputFileNum is less than 1 + EFI_ABORTED if unable to open input file. + +--*/ +{ + UINTN Size; + UINTN FileSize; + INTN Index; + FILE *InFile; + + if (InputFileNum < 1) { + Error (NULL, 0, 0, "must specify at least one input file", NULL); + return EFI_INVALID_PARAMETER; + } + + Size = 0; + // + // Go through our array of file names and copy their contents + // to the output buffer. + // + for (Index = 0; Index < InputFileNum; Index++) { + InFile = fopen (InputFileName[Index], "rb"); + if (InFile == NULL) { + Error (NULL, 0, 0, InputFileName[Index], "failed to open input file"); + return EFI_ABORTED; + } + + fseek (InFile, 0, SEEK_END); + FileSize = ftell (InFile); + fseek (InFile, 0, SEEK_SET); + // + // Now read the contents of the file into the buffer + // + if (FileSize > 0) { + if (fread (FileBuffer + Size, (size_t) FileSize, 1, InFile) != 1) { + Error (NULL, 0, 0, InputFileName[Index], "failed to read contents of input file"); + fclose (InFile); + return EFI_ABORTED; + } + } + + fclose (InFile); + Size += (UINTN) FileSize; + // + // make sure section ends on a DWORD boundary + // + while ((Size & 0x03) != 0) { + FileBuffer[Size] = 0; + Size++; + } + } + + *BufferLength = Size; + return EFI_SUCCESS; +} + +EFI_STATUS +GenSectionCompressionSection ( + char **InputFileName, + int InputFileNum, + UINTN SectionType, + UINTN SectionSubType, + FILE *OutFile + ) +/*++ + +Routine Description: + + Generate an encapsulating section of type EFI_SECTION_COMPRESSION + Input file must be already sectioned. The function won't validate + the input files' contents. Caller should hand in files already + with section header. + +Arguments: + + InputFileName - Name of the input file. + + InputFileNum - Number of input files. Should be at least 1. + + SectionType - Section type to generate. Should be + EFI_SECTION_COMPRESSION + + SectionSubType - Specify the compression algorithm requested. + + OutFile - Output file handle + +Returns: + + EFI_SUCCESS on successful return + EFI_INVALID_PARAMETER if InputFileNum is less than 1 + EFI_ABORTED if unable to open input file. + EFI_OUT_OF_RESOURCES No resource to complete the operation. +--*/ +{ + UINTN TotalLength; + UINTN InputLength; + UINTN CompressedLength; + UINT8 *FileBuffer; + UINT8 *OutputBuffer; + EFI_STATUS Status; + EFI_COMPRESSION_SECTION CompressionSect; + COMPRESS_FUNCTION CompressFunction; + + if (SectionType != EFI_SECTION_COMPRESSION) { + Error (NULL, 0, 0, "parameter must be EFI_SECTION_COMPRESSION", NULL); + return EFI_INVALID_PARAMETER; + } + + InputLength = 0; + FileBuffer = NULL; + OutputBuffer = NULL; + CompressedLength = 0; + FileBuffer = (UINT8 *) malloc ((1024 * 1024 * 4) * sizeof (UINT8)); + if (FileBuffer == NULL) { + Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory"); + return EFI_OUT_OF_RESOURCES; + } + // + // read all input file contents into a buffer + // + Status = GetSectionContents ( + InputFileName, + InputFileNum, + FileBuffer, + &InputLength + ); + if (EFI_ERROR (Status)) { + free (FileBuffer); + return Status; + } + + CompressFunction = NULL; + + // + // Now data is in FileBuffer, compress the data + // + switch (SectionSubType) { + case EFI_NOT_COMPRESSED: + CompressedLength = InputLength; + break; + + case EFI_STANDARD_COMPRESSION: + CompressFunction = (COMPRESS_FUNCTION) Compress; + break; + + case EFI_CUSTOMIZED_COMPRESSION: + CompressFunction = (COMPRESS_FUNCTION) CustomizedCompress; + break; + + default: + Error (NULL, 0, 0, "unknown compression type", NULL); + free (FileBuffer); + return EFI_ABORTED; + } + + if (CompressFunction != NULL) { + + Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength); + if (Status == EFI_BUFFER_TOO_SMALL) { + OutputBuffer = malloc (CompressedLength); + if (!OutputBuffer) { + free (FileBuffer); + return EFI_OUT_OF_RESOURCES; + } + + Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength); + } + + free (FileBuffer); + FileBuffer = OutputBuffer; + + if (EFI_ERROR (Status)) { + if (FileBuffer != NULL) { + free (FileBuffer); + } + + return Status; + } + } + + TotalLength = CompressedLength + sizeof (EFI_COMPRESSION_SECTION); + // + // Add the section header for the compressed data + // + CompressionSect.CommonHeader.Type = (EFI_SECTION_TYPE) SectionType; + CompressionSect.CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff); + CompressionSect.CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8); + CompressionSect.CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16); + CompressionSect.CompressionType = (UINT8) SectionSubType; + CompressionSect.UncompressedLength = InputLength; + + fwrite (&CompressionSect, sizeof (CompressionSect), 1, OutFile); + fwrite (FileBuffer, CompressedLength, 1, OutFile); + free (FileBuffer); + return EFI_SUCCESS; +} + +EFI_STATUS +GenSectionGuidDefinedSection ( + char **InputFileName, + int InputFileNum, + UINTN SectionType, + UINTN SectionSubType, + FILE *OutFile + ) +/*++ + +Routine Description: + + Generate an encapsulating section of type EFI_SECTION_GUID_DEFINED + Input file must be already sectioned. The function won't validate + the input files' contents. Caller should hand in files already + with section header. + +Arguments: + + InputFileName - Name of the input file. + + InputFileNum - Number of input files. Should be at least 1. + + SectionType - Section type to generate. Should be + EFI_SECTION_GUID_DEFINED + + SectionSubType - Specify the authentication algorithm requested. + + OutFile - Output file handle + +Returns: + + EFI_SUCCESS on successful return + EFI_INVALID_PARAMETER if InputFileNum is less than 1 + EFI_ABORTED if unable to open input file. + EFI_OUT_OF_RESOURCES No resource to complete the operation. + +--*/ +{ + INTN TotalLength; + INTN InputLength; + UINT8 *FileBuffer; + UINT32 Crc32Checksum; + EFI_STATUS Status; + CRC32_SECTION_HEADER Crc32GuidSect; + + if (SectionType != EFI_SECTION_GUID_DEFINED) { + Error (NULL, 0, 0, "parameter must be EFI_SECTION_GUID_DEFINED", NULL); + return EFI_INVALID_PARAMETER; + } + + InputLength = 0; + FileBuffer = NULL; + FileBuffer = (UINT8 *) malloc ((1024 * 1024 * 4) * sizeof (UINT8)); + if (FileBuffer == NULL) { + Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory"); + return EFI_OUT_OF_RESOURCES; + } + // + // read all input file contents into a buffer + // + Status = GetSectionContents ( + InputFileName, + InputFileNum, + FileBuffer, + &InputLength + ); + if (EFI_ERROR (Status)) { + free (FileBuffer); + return Status; + } + // + // Now data is in FileBuffer, compress the data + // + switch (SectionSubType) { + case EFI_SECTION_CRC32_GUID_DEFINED: + Crc32Checksum = 0; + CalculateCrc32 (FileBuffer, InputLength, &Crc32Checksum); + if (EFI_ERROR (Status)) { + free (FileBuffer); + return Status; + } + + TotalLength = InputLength + CRC32_SECTION_HEADER_SIZE; + Crc32GuidSect.GuidSectionHeader.CommonHeader.Type = (EFI_SECTION_TYPE) SectionType; + Crc32GuidSect.GuidSectionHeader.CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff); + Crc32GuidSect.GuidSectionHeader.CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8); + Crc32GuidSect.GuidSectionHeader.CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16); + memcpy (&(Crc32GuidSect.GuidSectionHeader.SectionDefinitionGuid), &gEfiCrc32SectionGuid, sizeof (EFI_GUID)); + Crc32GuidSect.GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID; + Crc32GuidSect.GuidSectionHeader.DataOffset = CRC32_SECTION_HEADER_SIZE; + Crc32GuidSect.CRC32Checksum = Crc32Checksum; + + break; + + default: + Error (NULL, 0, 0, "invalid parameter", "unknown GUID defined type"); + free (FileBuffer); + return EFI_ABORTED; + } + + fwrite (&Crc32GuidSect, sizeof (Crc32GuidSect), 1, OutFile); + fwrite (FileBuffer, InputLength, 1, OutFile); + + free (FileBuffer); + + return EFI_SUCCESS; +} + +int +main ( + int argc, + char *argv[] + ) +/*++ + +Routine Description: + + Main + +Arguments: + + command line parameters + +Returns: + + EFI_SUCCESS Section header successfully generated and section concatenated. + EFI_ABORTED Could not generate the section + EFI_OUT_OF_RESOURCES No resource to complete the operation. + +--*/ +{ + INTN Index; + INTN VersionNumber; + UINTN SectionType; + UINTN SectionSubType; + BOOLEAN InputFileRequired; + BOOLEAN SubTypeRequired; + FILE *InFile; + FILE *OutFile; + INTN InputFileNum; + + char **InputFileName; + char *OutputFileName; + char AuxString[500] = { 0 }; + + char *ParamSectionType; + char *ParamSectionSubType; + char *ParamLength; + char *ParamVersion; + char *ParamDigitalSignature; + + EFI_STATUS Status; + EFI_COMMON_SECTION_HEADER CommonSect; + + InputFileName = NULL; + OutputFileName = PARAMETER_NOT_SPECIFIED; + ParamSectionType = PARAMETER_NOT_SPECIFIED; + ParamSectionSubType = PARAMETER_NOT_SPECIFIED; + ParamLength = PARAMETER_NOT_SPECIFIED; + ParamVersion = PARAMETER_NOT_SPECIFIED; + ParamDigitalSignature = PARAMETER_NOT_SPECIFIED; + Status = EFI_SUCCESS; + + VersionNumber = 0; + SectionType = 0; + SectionSubType = 0; + InputFileRequired = TRUE; + SubTypeRequired = FALSE; + InFile = NULL; + OutFile = NULL; + InputFileNum = 0; + Status = EFI_SUCCESS; + + SetUtilityName (UTILITY_NAME); + if (argc == 1) { + PrintUsageMessage (); + return STATUS_ERROR; + } + // + // Parse command line + // + Index = 1; + while (Index < argc) { + if (strcmpi (argv[Index], "-i") == 0) { + // + // Input File found + // + Index++; + InputFileName = (char **) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (char *)); + if (InputFileName == NULL) { + Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory"); + return EFI_OUT_OF_RESOURCES; + } + + memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (char *))); + InputFileName[InputFileNum] = argv[Index]; + InputFileNum++; + Index++; + // + // Parse subsequent parameters until another switch is encountered + // + while ((Index < argc) && (argv[Index][0] != '-')) { + if ((InputFileNum % MAXIMUM_INPUT_FILE_NUM) == 0) { + // + // InputFileName buffer too small, need to realloc + // + InputFileName = (char **) realloc ( + InputFileName, + (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (char *) + ); + if (InputFileName == NULL) { + Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory"); + return EFI_OUT_OF_RESOURCES; + } + + memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (char *))); + } + + InputFileName[InputFileNum] = argv[Index]; + InputFileNum++; + Index++; + } + + } + + if (strcmpi (argv[Index], "-o") == 0) { + // + // Output file found + // + Index++; + OutputFileName = argv[Index]; + } else if (strcmpi (argv[Index], "-s") == 0) { + // + // Section Type found + // + Index++; + ParamSectionType = argv[Index]; + } else if (strcmpi (argv[Index], "-t") == 0) { + // + // Compression or Authentication type + // + Index++; + ParamSectionSubType = argv[Index]; + } else if (strcmpi (argv[Index], "-l") == 0) { + // + // Length + // + Index++; + ParamLength = argv[Index]; + } else if (strcmpi (argv[Index], "-v") == 0) { + // + // VersionNumber + // + Index++; + ParamVersion = argv[Index]; + } else if (strcmpi (argv[Index], "-a") == 0) { + // + // Aux string + // + Index++; + // + // Note, the MSVC C-Start parses out and consolidates quoted strings from the command + // line. Quote characters are stripped. If this tool is ported to other environments + // this will need to be taken into account + // + strncpy (AuxString, argv[Index], 499); + } else if (strcmpi (argv[Index], "-d") == 0) { + // + // Digital signature for EFI_TEST_AUTHENTICAION (must be 0 or 1) + // + Index++; + ParamDigitalSignature = argv[Index]; + } else if (strcmpi (argv[Index], "-?") == 0) { + PrintUsageMessage (); + return STATUS_ERROR; + } else { + Error (NULL, 0, 0, argv[Index], "unknown option"); + return GetUtilityStatus (); + } + + Index++; + } + // + // At this point, all command line parameters are verified as not being totally + // bogus. Next verify the command line parameters are complete and make + // sense... + // + if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_COMPRESSION]) == 0) { + SectionType = EFI_SECTION_COMPRESSION; + SubTypeRequired = TRUE; + if (stricmp (ParamSectionSubType, CompressionTypeName[EFI_NOT_COMPRESSED]) == 0) { + SectionSubType = EFI_NOT_COMPRESSED; + } else if (stricmp (ParamSectionSubType, CompressionTypeName[EFI_STANDARD_COMPRESSION]) == 0) { + SectionSubType = EFI_STANDARD_COMPRESSION; + } else { + Error (NULL, 0, 0, ParamSectionSubType, "unknown compression type"); + PrintUsageMessage (); + return GetUtilityStatus (); + } + } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_GUID_DEFINED]) == 0) { + SectionType = EFI_SECTION_GUID_DEFINED; + SubTypeRequired = TRUE; + if (stricmp (ParamSectionSubType, GUIDedSectionTypeName[EFI_SECTION_CRC32_GUID_DEFINED]) == 0) { + SectionSubType = EFI_SECTION_CRC32_GUID_DEFINED; + } else { + Error (NULL, 0, 0, ParamSectionSubType, "unknown GUID defined section type", ParamSectionSubType); + PrintUsageMessage (); + return GetUtilityStatus (); + } + } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_PE32]) == 0) { + SectionType = EFI_SECTION_PE32; + } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_PIC]) == 0) { + SectionType = EFI_SECTION_PIC; + } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_TE]) == 0) { + SectionType = EFI_SECTION_TE; + } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_DXE_DEPEX]) == 0) { + SectionType = EFI_SECTION_DXE_DEPEX; + } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_VERSION]) == 0) { + SectionType = EFI_SECTION_VERSION; + InputFileRequired = FALSE; + Index = sscanf (ParamVersion, "%d", &VersionNumber); + if (Index != 1 || VersionNumber < 0 || VersionNumber > 65565) { + Error (NULL, 0, 0, ParamVersion, "illegal version number"); + PrintUsageMessage (); + return GetUtilityStatus (); + } + + if (strcmp (AuxString, PARAMETER_NOT_SPECIFIED) == 0) { + AuxString[0] = 0; + } + } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_USER_INTERFACE]) == 0) { + SectionType = EFI_SECTION_USER_INTERFACE; + InputFileRequired = FALSE; + if (strcmp (AuxString, PARAMETER_NOT_SPECIFIED) == 0) { + Error (NULL, 0, 0, "user interface string not specified", NULL); + PrintUsageMessage (); + return GetUtilityStatus (); + } + } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_COMPATIBILITY16]) == 0) { + SectionType = EFI_SECTION_COMPATIBILITY16; + } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_FIRMWARE_VOLUME_IMAGE]) == 0) { + SectionType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE; + } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_FREEFORM_SUBTYPE_GUID]) == 0) { + SectionType = EFI_SECTION_FREEFORM_SUBTYPE_GUID; + } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_RAW]) == 0) { + SectionType = EFI_SECTION_RAW; + } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_PEI_DEPEX]) == 0) { + SectionType = EFI_SECTION_PEI_DEPEX; + } else { + Error (NULL, 0, 0, ParamSectionType, "unknown section type"); + PrintUsageMessage (); + return GetUtilityStatus (); + } + // + // Open output file + // + OutFile = fopen (OutputFileName, "wb"); + if (OutFile == NULL) { + Error (NULL, 0, 0, OutputFileName, "failed to open output file for writing"); + if (InFile != NULL) { + fclose (InFile); + } + + return GetUtilityStatus (); + } + // + // At this point, we've fully validated the command line, and opened appropriate + // files, so let's go and do what we've been asked to do... + // + // + // Within this switch, build and write out the section header including any + // section type specific pieces. If there's an input file, it's tacked on later + // + switch (SectionType) { + case EFI_SECTION_COMPRESSION: + Status = GenSectionCompressionSection ( + InputFileName, + InputFileNum, + SectionType, + SectionSubType, + OutFile + ); + break; + + case EFI_SECTION_GUID_DEFINED: + Status = GenSectionGuidDefinedSection ( + InputFileName, + InputFileNum, + SectionType, + SectionSubType, + OutFile + ); + break; + + case EFI_SECTION_VERSION: + CommonSect.Type = (EFI_SECTION_TYPE) SectionType; + + Index = sizeof (CommonSect); + // + // 2 characters for the build number + // + Index += 2; + // + // Aux string is ascii.. unicode is 2X + 2 bytes for terminating unicode null. + // + Index += (strlen (AuxString) * 2) + 2; + memcpy (&CommonSect.Size, &Index, 3); + fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile); + fwrite (&VersionNumber, 2, 1, OutFile); + Ascii2UnicodeWriteString (AuxString, OutFile, FALSE); + break; + + case EFI_SECTION_USER_INTERFACE: + CommonSect.Type = (EFI_SECTION_TYPE) SectionType; + Index = sizeof (CommonSect); + // + // Aux string is ascii.. unicode is 2X + 2 bytes for terminating unicode null. + // + Index += (strlen (AuxString) * 2) + 2; + memcpy (&CommonSect.Size, &Index, 3); + fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile); + Ascii2UnicodeWriteString (AuxString, OutFile, FALSE); + break; + + default: + // + // All other section types are caught by default (they're all the same) + // + Status = GenSectionCommonLeafSection ( + InputFileName, + InputFileNum, + SectionType, + OutFile + ); + break; + } + + if (InputFileName != NULL) { + free (InputFileName); + } + + fclose (OutFile); + // + // If we had errors, then delete the output file + // + if (GetUtilityStatus () == STATUS_ERROR) { + remove (OutputFileName); + } + + return GetUtilityStatus (); +} diff --git a/Tools/CodeTools/Source/GenSection/GenSection.h b/Tools/CodeTools/Source/GenSection/GenSection.h new file mode 100644 index 0000000000..36064632db --- /dev/null +++ b/Tools/CodeTools/Source/GenSection/GenSection.h @@ -0,0 +1,42 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + GenSection.h + +Abstract: + + Header file for GenSection. + +--*/ + +// +// Module Coded to Tiano Coding Conventions +// +#ifndef _EFI_GEN_SECTION_H +#define _EFI_GEN_SECTION_H + +// +// External Files Referenced +// +#include +#include + +typedef struct { + EFI_GUID_DEFINED_SECTION GuidSectionHeader; + UINT32 CRC32Checksum; +} CRC32_SECTION_HEADER; + +#define EFI_SECTION_CRC32_GUID_DEFINED 0 +#define CRC32_SECTION_HEADER_SIZE (sizeof (CRC32_SECTION_HEADER)) + +#endif diff --git a/Tools/CodeTools/Source/GenSection/build.xml b/Tools/CodeTools/Source/GenSection/build.xml new file mode 100644 index 0000000000..63ffccdf74 --- /dev/null +++ b/Tools/CodeTools/Source/GenSection/build.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/GenTEImage/GenTEImage.c b/Tools/CodeTools/Source/GenTEImage/GenTEImage.c new file mode 100644 index 0000000000..90f3b3919a --- /dev/null +++ b/Tools/CodeTools/Source/GenTEImage/GenTEImage.c @@ -0,0 +1,916 @@ +/*++ + +Copyright (c) 1999-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + GenTEImage.c + +Abstract: + + Utility program to shrink a PE32 image down by replacing + the DOS, PE, and optional headers with a minimal header. + +--*/ + +#include +#include +#include + +#include +#include // for PE32 structure definitions + +#include "CommonLib.h" +#include "EfiUtilityMsgs.h" + +// +// Version of this utility +// +#define UTILITY_NAME "GenTEImage" +#define UTILITY_VERSION "v0.11" + +// +// Define the max length of a filename +// +#define MAX_PATH 256 +#define DEFAULT_OUTPUT_EXTENSION ".te" + +// +// Use this to track our command-line options and globals +// +struct { + INT8 OutFileName[MAX_PATH]; + INT8 InFileName[MAX_PATH]; + INT8 Verbose; + INT8 Dump; +} mOptions; + +// +// Use these to convert from machine type value to a named type +// +typedef struct { + UINT16 Value; + INT8 *Name; +} STRING_LOOKUP; + +static STRING_LOOKUP mMachineTypes[] = { + EFI_IMAGE_MACHINE_IA32, + "IA32", + EFI_IMAGE_MACHINE_IA64, + "IA64", + EFI_IMAGE_MACHINE_EBC, + "EBC", + 0, + NULL +}; + +static STRING_LOOKUP mSubsystemTypes[] = { + EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION, + "EFI application", + EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, + "EFI boot service driver", + EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER, + "EFI runtime driver", + 0, + NULL +}; +// +// Function prototypes +// +static +void +Usage ( + VOID + ); + +static +STATUS +ParseCommandLine ( + int Argc, + char *Argv[] + ); + +static +STATUS +CheckPE32File ( + INT8 *FileName, + FILE *Fptr, + UINT16 *MachineType, + UINT16 *SubSystem + ); + +static +STATUS +ProcessFile ( + INT8 *InFileName, + INT8 *OutFileName + ); + +static +void +DumpImage ( + INT8 *FileName + ); + +static +INT8 * +GetMachineTypeStr ( + UINT16 MachineType + ); + +static +INT8 * +GetSubsystemTypeStr ( + UINT16 SubsystemType + ); + +main ( + int Argc, + char *Argv[] + ) +/*++ + +Routine Description: + + +Arguments: + + Argc - standard C main() argument count + + Argv - standard C main() argument list + +Returns: + + 0 success + non-zero otherwise + +--*/ +// GC_TODO: ] - add argument and description to function comment +{ + INT8 *Ext; + UINT32 Status; + + SetUtilityName (UTILITY_NAME); + // + // Parse the command line arguments + // + if (ParseCommandLine (Argc, Argv)) { + return STATUS_ERROR; + } + // + // If dumping an image, then do that and quit + // + if (mOptions.Dump) { + DumpImage (mOptions.InFileName); + goto Finish; + } + // + // Determine the output filename. Either what they specified on + // the command line, or the first input filename with a different extension. + // + if (!mOptions.OutFileName[0]) { + strcpy (mOptions.OutFileName, mOptions.InFileName); + // + // Find the last . on the line and replace the filename extension with + // the default + // + for (Ext = mOptions.OutFileName + strlen (mOptions.OutFileName) - 1; + (Ext >= mOptions.OutFileName) && (*Ext != '.') && (*Ext != '\\'); + Ext-- + ) + ; + // + // If dot here, then insert extension here, otherwise append + // + if (*Ext != '.') { + Ext = mOptions.OutFileName + strlen (mOptions.OutFileName); + } + + strcpy (Ext, DEFAULT_OUTPUT_EXTENSION); + } + // + // Make sure we don't have the same filename for input and output files + // + if (stricmp (mOptions.OutFileName, mOptions.InFileName) == 0) { + Error (NULL, 0, 0, mOptions.OutFileName, "input and output file names must be different"); + goto Finish; + } + // + // Process the file + // + ProcessFile (mOptions.InFileName, mOptions.OutFileName); +Finish: + Status = GetUtilityStatus (); + return Status; +} + +static +STATUS +ProcessFile ( + INT8 *InFileName, + INT8 *OutFileName + ) +/*++ + +Routine Description: + + Process a PE32 EFI file. + +Arguments: + + InFileName - the file name pointer to the input file + OutFileName - the file name pointer to the output file + +Returns: + + STATUS_SUCCESS - the process has been finished successfully + STATUS_ERROR - error occured during the processing + +--*/ +{ + STATUS Status; + FILE *InFptr; + FILE *OutFptr; + UINT16 MachineType; + UINT16 SubSystem; + EFI_TE_IMAGE_HEADER TEImageHeader; + UINT32 PESigOffset; + EFI_IMAGE_FILE_HEADER FileHeader; + EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader32; + EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader64; + UINT32 BytesStripped; + UINT32 FileSize; + UINT8 *Buffer; + long SaveFilePosition; + + InFptr = NULL; + OutFptr = NULL; + Buffer = NULL; + Status = STATUS_ERROR; + + // + // Try to open the input file + // + if ((InFptr = fopen (InFileName, "rb")) == NULL) { + Error (NULL, 0, 0, InFileName, "failed to open input file for reading"); + return STATUS_ERROR; + } + // + // Double-check the file to make sure it's what we expect it to be + // + if (CheckPE32File (InFileName, InFptr, &MachineType, &SubSystem) != STATUS_SUCCESS) { + goto Finish; + } + // + // Initialize our new header + // + memset (&TEImageHeader, 0, sizeof (EFI_TE_IMAGE_HEADER)); + + // + // Seek to the end to get the file size + // + fseek (InFptr, 0, SEEK_END); + FileSize = ftell (InFptr); + fseek (InFptr, 0, SEEK_SET); + + // + // Per the PE/COFF specification, at offset 0x3C in the file is a 32-bit + // offset (from the start of the file) to the PE signature, which always + // follows the MSDOS stub. The PE signature is immediately followed by the + // COFF file header. + // + // + if (fseek (InFptr, 0x3C, SEEK_SET) != 0) { + Error (NULL, 0, 0, InFileName, "failed to seek to PE signature in file", NULL); + goto Finish; + } + + if (fread (&PESigOffset, sizeof (PESigOffset), 1, InFptr) != 1) { + Error (NULL, 0, 0, InFileName, "failed to read PE signature offset from file"); + goto Finish; + } + + if (fseek (InFptr, PESigOffset + 4, SEEK_SET) != 0) { + Error (NULL, 0, 0, InFileName, "failed to seek to PE signature"); + goto Finish; + } + // + // We should now be at the COFF file header. Read it in and verify it's + // of an image type we support. + // + if (fread (&FileHeader, sizeof (EFI_IMAGE_FILE_HEADER), 1, InFptr) != 1) { + Error (NULL, 0, 0, InFileName, "failed to read file header from image"); + goto Finish; + } + + if ((FileHeader.Machine != EFI_IMAGE_MACHINE_IA32) && (FileHeader.Machine != EFI_IMAGE_MACHINE_IA64)) { + Error (NULL, 0, 0, InFileName, "image is of an unsupported machine type 0x%X", (UINT32) FileHeader.Machine); + goto Finish; + } + // + // Calculate the total number of bytes we're going to strip off. The '4' is for the + // PE signature PE\0\0. Then sanity check the size. + // + BytesStripped = PESigOffset + 4 + sizeof (EFI_IMAGE_FILE_HEADER) + FileHeader.SizeOfOptionalHeader; + if (BytesStripped >= FileSize) { + Error (NULL, 0, 0, InFileName, "attempt to strip more bytes than the total file size"); + goto Finish; + } + + if (BytesStripped &~0xFFFF) { + Error (NULL, 0, 0, InFileName, "attempt to strip more than 64K bytes", NULL); + goto Finish; + } + + TEImageHeader.StrippedSize = (UINT16) BytesStripped; + + // + // Read in the optional header. Assume PE32, and if not, then re-read as PE32+ + // + SaveFilePosition = ftell (InFptr); + if (fread (&OptionalHeader32, sizeof (EFI_IMAGE_OPTIONAL_HEADER32), 1, InFptr) != 1) { + Error (NULL, 0, 0, InFileName, "failed to read optional header from input file"); + goto Finish; + } + + if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + // + // Fill in our new header with required data directory entries + // + TEImageHeader.AddressOfEntryPoint = OptionalHeader32.AddressOfEntryPoint; + // + // - BytesStripped + sizeof (EFI_TE_IMAGE_HEADER); + // + // We're going to pack the subsystem into 1 byte. Make sure it fits + // + if (OptionalHeader32.Subsystem &~0xFF) { + Error ( + NULL, + 0, + 0, + InFileName, + NULL, + "image subsystem 0x%X cannot be packed into 1 byte", + (UINT32) OptionalHeader32.Subsystem + ); + goto Finish; + } + + TEImageHeader.Subsystem = (UINT8) OptionalHeader32.Subsystem; + TEImageHeader.BaseOfCode = OptionalHeader32.BaseOfCode; + TEImageHeader.ImageBase = (UINT64) (OptionalHeader32.ImageBase + TEImageHeader.StrippedSize - sizeof (EFI_TE_IMAGE_HEADER)); + if (OptionalHeader32.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; + } + + if (OptionalHeader32.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size; + } + } else if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + // + // Rewind and re-read the optional header + // + fseek (InFptr, SaveFilePosition, SEEK_SET); + if (fread (&OptionalHeader64, sizeof (EFI_IMAGE_OPTIONAL_HEADER64), 1, InFptr) != 1) { + Error (NULL, 0, 0, InFileName, "failed to re-read optional header from input file"); + goto Finish; + } + + TEImageHeader.AddressOfEntryPoint = OptionalHeader64.AddressOfEntryPoint; + // + // - BytesStripped + sizeof (EFI_TE_IMAGE_HEADER); + // + // We're going to pack the subsystem into 1 byte. Make sure it fits + // + if (OptionalHeader64.Subsystem &~0xFF) { + Error ( + NULL, + 0, + 0, + InFileName, + NULL, + "image subsystem 0x%X cannot be packed into 1 byte", + (UINT32) OptionalHeader64.Subsystem + ); + goto Finish; + } + + TEImageHeader.Subsystem = (UINT8) OptionalHeader64.Subsystem; + TEImageHeader.BaseOfCode = OptionalHeader32.BaseOfCode; + TEImageHeader.ImageBase = (UINT64) (OptionalHeader64.ImageBase + TEImageHeader.StrippedSize - sizeof (EFI_TE_IMAGE_HEADER)); + if (OptionalHeader64.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; + } + + if (OptionalHeader64.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size; + } + } else { + Error ( + NULL, + 0, + 0, + InFileName, + "unsupported magic number 0x%X found in optional header", + (UINT32) OptionalHeader32.Magic + ); + goto Finish; + } + // + // Fill in the remainder of our new image header + // + TEImageHeader.Signature = EFI_TE_IMAGE_HEADER_SIGNATURE; + TEImageHeader.Machine = FileHeader.Machine; + // + // We're going to pack the number of sections into a single byte. Make sure it fits. + // + if (FileHeader.NumberOfSections &~0xFF) { + Error ( + NULL, + 0, + 0, + InFileName, + NULL, + "image's number of sections 0x%X cannot be packed into 1 byte", + (UINT32) FileHeader.NumberOfSections + ); + goto Finish; + } + + TEImageHeader.NumberOfSections = (UINT8) FileHeader.NumberOfSections; + + // + // Now open our output file + // + if ((OutFptr = fopen (OutFileName, "wb")) == NULL) { + Error (NULL, 0, 0, OutFileName, "failed to open output file for writing"); + goto Finish; + } + // + // Write the TE header + // + if (fwrite (&TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER), 1, OutFptr) != 1) { + Error (NULL, 0, 0, "failed to write image header to output file", NULL); + goto Finish; + } + // + // Position into the input file, read the part we're not stripping, and + // write it out. + // + fseek (InFptr, BytesStripped, SEEK_SET); + Buffer = (UINT8 *) malloc (FileSize - BytesStripped); + if (Buffer == NULL) { + Error (NULL, 0, 0, "application error", "failed to allocate memory"); + goto Finish; + } + + if (fread (Buffer, FileSize - BytesStripped, 1, InFptr) != 1) { + Error (NULL, 0, 0, InFileName, "failed to read remaining contents of input file"); + goto Finish; + } + + if (fwrite (Buffer, FileSize - BytesStripped, 1, OutFptr) != 1) { + Error (NULL, 0, 0, OutFileName, "failed to write all bytes to output file"); + goto Finish; + } + + Status = STATUS_SUCCESS; + +Finish: + if (InFptr != NULL) { + fclose (InFptr); + } + // + // Close the output file. If there was an error, delete the output file so + // that a subsequent build will rebuild it. + // + if (OutFptr != NULL) { + fclose (OutFptr); + if (GetUtilityStatus () == STATUS_ERROR) { + remove (OutFileName); + } + } + + // + // Free up our buffer + // + if (Buffer != NULL) { + free (Buffer); + } + + return Status; +} + +static +STATUS +CheckPE32File ( + INT8 *FileName, + FILE *Fptr, + UINT16 *MachineType, + UINT16 *SubSystem + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FileName - GC_TODO: add argument description + Fptr - GC_TODO: add argument description + MachineType - GC_TODO: add argument description + SubSystem - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + /*++ + +Routine Description: + + Given a file pointer to a supposed PE32 image file, verify that it is indeed a + PE32 image file, and then return the machine type in the supplied pointer. + +Arguments: + + Fptr File pointer to the already-opened PE32 file + MachineType Location to stuff the machine type of the PE32 file. This is needed + because the image may be Itanium-based, IA32, or EBC. + +Returns: + + 0 success + non-zero otherwise + +--*/ + EFI_IMAGE_DOS_HEADER DosHeader; + EFI_IMAGE_FILE_HEADER FileHdr; + EFI_IMAGE_OPTIONAL_HEADER OptionalHdr; + UINT32 PESig; + STATUS Status; + + Status = STATUS_ERROR; + // + // Position to the start of the file + // + fseek (Fptr, 0, SEEK_SET); + // + // Read the DOS header + // + if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) { + Error (NULL, 0, 0, FileName, "failed to read the DOS stub from the input file"); + goto Finish; + } + // + // Check the magic number (0x5A4D) + // + if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) { + Error (NULL, 0, 0, FileName, "input file does not appear to be a PE32 image (magic number)"); + goto Finish; + } + // + // Position into the file and check the PE signature + // + fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET); + if (fread (&PESig, sizeof (PESig), 1, Fptr) != 1) { + Error (NULL, 0, 0, FileName, "failed to read PE signature bytes"); + goto Finish; + } + // + // Check the PE signature in the header "PE\0\0" + // + if (PESig != EFI_IMAGE_NT_SIGNATURE) { + Error (NULL, 0, 0, FileName, "file does not appear to be a PE32 image (signature)"); + goto Finish; + } + // + // Read the file header + // + if (fread (&FileHdr, sizeof (FileHdr), 1, Fptr) != 1) { + Error (NULL, 0, 0, FileName, "failed to read PE file header from input file"); + goto Finish; + } + // + // Read the optional header so we can get the subsystem + // + if (fread (&OptionalHdr, sizeof (OptionalHdr), 1, Fptr) != 1) { + Error (NULL, 0, 0, FileName, "failed to read COFF optional header from input file"); + goto Finish; + } + + *SubSystem = OptionalHdr.Subsystem; + if (mOptions.Verbose) { + fprintf (stdout, " Got subsystem = 0x%X from image\n", (int) *SubSystem); + } + // + // Good to go + // + Status = STATUS_SUCCESS; +Finish: + fseek (Fptr, 0, SEEK_SET); + return Status; +} + +static +int +ParseCommandLine ( + int Argc, + char *Argv[] + ) +/*++ + +Routine Description: + + Given the Argc/Argv program arguments, and a pointer to an options structure, + parse the command-line options and check their validity. + + +Arguments: + + Argc - standard C main() argument count + Argv - standard C main() argument list + +Returns: + + STATUS_SUCCESS success + non-zero otherwise + +--*/ +// GC_TODO: ] - add argument and description to function comment +{ + // + // Clear out the options + // + memset ((char *) &mOptions, 0, sizeof (mOptions)); + // + // Skip over the program name + // + Argc--; + Argv++; + // + // If no arguments, assume they want usage info + // + if (Argc == 0) { + Usage (); + return STATUS_ERROR; + } + // + // Process until no more arguments + // + while ((Argc > 0) && (Argv[0][0] == '-')) { + if (stricmp (Argv[0], "-o") == 0) { + // + // Output filename specified with -o + // Make sure there's another parameter + // + if (Argc > 1) { + strcpy (mOptions.OutFileName, Argv[1]); + } else { + Error (NULL, 0, 0, Argv[0], "missing output file name with option"); + Usage (); + return STATUS_ERROR; + } + + Argv++; + Argc--; + } else if ((stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) { + // + // Help option + // + Usage (); + return STATUS_ERROR; + } else if (stricmp (Argv[0], "-v") == 0) { + // + // -v for verbose + // + mOptions.Verbose = 1; + } else if (stricmp (Argv[0], "-dump") == 0) { + // + // -dump for dumping an image + // + mOptions.Dump = 1; + } else { + Error (NULL, 0, 0, Argv[0], "unrecognized option"); + Usage (); + return STATUS_ERROR; + } + // + // Next argument + // + Argv++; + Argc--; + } + // + // Better be one more arg for input file name + // + if (Argc == 0) { + Error (NULL, 0, 0, "input file name required", NULL); + Usage (); + return STATUS_ERROR; + } + + if (Argc != 1) { + Error (NULL, 0, 0, Argv[1], "extra arguments on command line"); + return STATUS_ERROR; + } + + strcpy (mOptions.InFileName, Argv[0]); + return STATUS_SUCCESS; +} + +static +void +Usage ( + VOID + ) +/*++ + +Routine Description: + + Print usage information for this utility. + +Arguments: + + None. + +Returns: + + Nothing. + +--*/ +{ + int Index; + static const char *Msg[] = { + UTILITY_NAME " version "UTILITY_VERSION " - TE image utility", + " Generate a TE image from an EFI PE32 image", + " Usage: "UTILITY_NAME " {-v} {-dump} {-h|-?} {-o OutFileName} InFileName", + " [-e|-b] [FileName(s)]", + " where:", + " -v - for verbose output", + " -dump - to dump the input file to a text file", + " -h -? - for this help information", + " -o OutFileName - to write output to OutFileName rather than InFileName"DEFAULT_OUTPUT_EXTENSION, + " InFileName - name of the input PE32 file", + "", + NULL + }; + for (Index = 0; Msg[Index] != NULL; Index++) { + fprintf (stdout, "%s\n", Msg[Index]); + } +} + +static +VOID +DumpImage ( + INT8 *FileName + ) +/*++ + +Routine Description: + + Dump a specified image information + +Arguments: + + FileName - File name pointer to the image to dump + +Returns: + + Nothing. + +--*/ +{ + FILE *InFptr; + EFI_TE_IMAGE_HEADER TEImageHeader; + INT8 *NamePtr; + + // + // Open the input file + // + InFptr = NULL; + + if ((InFptr = fopen (FileName, "rb")) == NULL) { + Error (NULL, 0, 0, FileName, "failed to open input file for reading"); + return ; + } + + if (fread (&TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER), 1, InFptr) != 1) { + Error (NULL, 0, 0, FileName, "failed to read image header from input file"); + goto Finish; + } + + if (TEImageHeader.Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) { + Error (NULL, 0, 0, FileName, "Image does not appear to be a TE image (bad signature)"); + goto Finish; + } + // + // Dump the header + // + fprintf (stdout, "Header (%d bytes):\n", sizeof (EFI_TE_IMAGE_HEADER)); + fprintf (stdout, " Signature: 0x%04X (TE)\n", (UINT32) TEImageHeader.Signature); + NamePtr = GetMachineTypeStr (TEImageHeader.Machine); + fprintf (stdout, " Machine: 0x%04X (%s)\n", (UINT32) TEImageHeader.Machine, NamePtr); + NamePtr = GetSubsystemTypeStr (TEImageHeader.Subsystem); + fprintf (stdout, " Subsystem: 0x%02X (%s)\n", (UINT32) TEImageHeader.Subsystem, NamePtr); + fprintf (stdout, " Number of sections 0x%02X\n", (UINT32) TEImageHeader.NumberOfSections); + fprintf (stdout, " Stripped size: 0x%04X\n", (UINT32) TEImageHeader.StrippedSize); + fprintf (stdout, " Entry point: 0x%08X\n", TEImageHeader.AddressOfEntryPoint); + fprintf (stdout, " Base of code: 0x%08X\n", TEImageHeader.BaseOfCode); + fprintf (stdout, " Data directories:\n"); + fprintf ( + stdout, + " %8X [%8X] RVA [size] of Base Relocation Directory\n", + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress, + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size + ); + fprintf ( + stdout, + " %8X [%8X] RVA [size] of Debug Directory\n", + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress, + TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size + ); + +Finish: + if (InFptr != NULL) { + fclose (InFptr); + } +} + +static +INT8 * +GetMachineTypeStr ( + UINT16 MachineType + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + MachineType - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + int Index; + + for (Index = 0; mMachineTypes[Index].Name != NULL; Index++) { + if (mMachineTypes[Index].Value == MachineType) { + return mMachineTypes[Index].Name; + } + } + + return "unknown"; +} + +static +INT8 * +GetSubsystemTypeStr ( + UINT16 SubsystemType + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + SubsystemType - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + int Index; + + for (Index = 0; mSubsystemTypes[Index].Name != NULL; Index++) { + if (mSubsystemTypes[Index].Value == SubsystemType) { + return mSubsystemTypes[Index].Name; + } + } + + return "unknown"; +} diff --git a/Tools/CodeTools/Source/GenTEImage/build.xml b/Tools/CodeTools/Source/GenTEImage/build.xml new file mode 100644 index 0000000000..e79f9574a9 --- /dev/null +++ b/Tools/CodeTools/Source/GenTEImage/build.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/GuidChk/CommonUtils.h b/Tools/CodeTools/Source/GuidChk/CommonUtils.h new file mode 100644 index 0000000000..f7a331e5d7 --- /dev/null +++ b/Tools/CodeTools/Source/GuidChk/CommonUtils.h @@ -0,0 +1,57 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + CommonUtils.h + +Abstract: + + Common utility defines and structure definitions. + +--*/ + +#ifndef _COMMON_UTILS_H_ +#define _COMMON_UTILS_H_ + +// +// Basic types +// +typedef unsigned char UINT8; +typedef char INT8; +typedef unsigned short UINT16; +typedef unsigned int UINT32; + +typedef UINT8 BOOLEAN; +typedef UINT32 STATUS; + +#define TRUE 1 +#define FALSE 0 + +#define STATUS_SUCCESS 0 +#define STATUS_WARNING 1 +#define STATUS_ERROR 2 + +// +// Linked list of strings +// +typedef struct _STRING_LIST { + struct _STRING_LIST *Next; + char *Str; +} STRING_LIST; + +int +CreateGuidList ( + INT8 *OutFileName + ) +; + +#endif // #ifndef _COMMON_UTILS_H_ diff --git a/Tools/CodeTools/Source/GuidChk/FileSearch.c b/Tools/CodeTools/Source/GuidChk/FileSearch.c new file mode 100644 index 0000000000..8b5b58fddf --- /dev/null +++ b/Tools/CodeTools/Source/GuidChk/FileSearch.c @@ -0,0 +1,285 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + FileSearch.c + +Abstract: + + Module used to support file searches on the system. + +--*/ + +#include + +#include "CommonUtils.h" +#include "FileSearch.h" +#include "UtilsMsgs.h" + +// +// Internal file search flag for sanity checks +// +#define FILE_SEARCH_STARTED 0x8000 +#define FILE_SEARCH_INITED 0x4000 + +static +BOOLEAN +FileSearchMeetsCriteria ( + FILE_SEARCH_DATA *FSData + ); + +/*****************************************************************************/ +STATUS +FileSearchInit ( + FILE_SEARCH_DATA *FSData + ) +{ + memset ((char *) FSData, 0, sizeof (FILE_SEARCH_DATA)); + FSData->Handle = INVALID_HANDLE_VALUE; + FSData->FileSearchFlags = FILE_SEARCH_INITED; + FSData->FileName[0] = 0; + return STATUS_SUCCESS; +} + +STATUS +FileSearchStart ( + FILE_SEARCH_DATA *FSData, + char *FileMask, + UINT32 SearchFlags + ) +{ + BOOLEAN Done; + + // + // Save their flags, and set a flag to indicate that they called this + // start function so we can perform extended checking in the other + // routines we have in this module. + // + FSData->FileSearchFlags |= (SearchFlags | FILE_SEARCH_STARTED); + FSData->FileName[0] = 0; + + // + // Begin the search + // + FSData->Handle = FindFirstFile (FileMask, &(FSData->FindData)); + if (FSData->Handle == INVALID_HANDLE_VALUE) { + return STATUS_ERROR; + } + // + // Keep looping through until we find a file meeting the caller's + // criteria per the search flags + // + Done = FALSE; + while (!Done) { + // + // If we're done (we found a match) copy the file name found and return + // + Done = FileSearchMeetsCriteria (FSData); + if (Done) { + return STATUS_SUCCESS; + } + // + // Go on to next file + // + if (!FindNextFile (FSData->Handle, &(FSData->FindData))) { + return STATUS_NOT_FOUND; + } + } + // + // Not reached + // + return STATUS_NOT_FOUND; +} + +// +// Find the next file meeting their criteria and return it. +// +STATUS +FileSearchFindNext ( + FILE_SEARCH_DATA *FSData + ) +{ + BOOLEAN Done; + + Done = FALSE; + while (!Done) { + if (!FindNextFile (FSData->Handle, &(FSData->FindData))) { + return STATUS_NOT_FOUND; + } + // + // See if it matches their criteria + // + Done = FileSearchMeetsCriteria (FSData); + if (Done) { + return STATUS_SUCCESS; + } + } + // + // Not reached + // + return STATUS_NOT_FOUND; +} +// +// Perform any cleanup necessary to close down a search +// +STATUS +FileSearchDestroy ( + FILE_SEARCH_DATA *FSData + ) +{ + if (FSData->Handle != INVALID_HANDLE_VALUE) { + FindClose (FSData->Handle); + FSData->Handle = INVALID_HANDLE_VALUE; + } + + FSData->FileName[0] = 0; + FSData->FileSearchFlags = 0; + return STATUS_SUCCESS; +} + +static +BOOLEAN +FileSearchMeetsCriteria ( + FILE_SEARCH_DATA *FSData + ) +{ + BOOLEAN Status; + STRING_LIST *StrList; + UINT32 ExtLen; + UINT32 FileNameLen; + + Status = FALSE; + + // + // First clear the flag indicating this is neither a file or a + // directory. + // + FSData->FileFlags &= ~(FILE_SEARCH_DIR | FILE_SEARCH_FILE); + + // + // We found a file. See if it matches the user's search criteria. First + // check for this being a directory, and they want directories, and + // it's not "." and it's not ".." + // + if ((FSData->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && + (FSData->FileSearchFlags & FILE_SEARCH_DIR) && + (strcmp (FSData->FindData.cFileName, ".")) && + (strcmp (FSData->FindData.cFileName, "..")) + ) { + // + // Assume we'll make it past this check + // + Status = TRUE; + // + // If they have a list of exclude directories, then check for those + // + StrList = FSData->ExcludeDirs; + while (StrList != NULL) { + if (stricmp (FSData->FindData.cFileName, StrList->Str) == 0) { + Status = FALSE; + break; + } + + StrList = StrList->Next; + } + // + // If we didn't fail due to excluded directories, then set the dir flag + // + if (Status) { + FSData->FileFlags |= FILE_SEARCH_DIR; + } + // + // Else check for a file, and they want files.... + // + } else if (((FSData->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) && + (FSData->FileSearchFlags & FILE_SEARCH_FILE) + ) { + // + // See if it's in our list of excluded files + // + Status = TRUE; + StrList = FSData->ExcludeFiles; + while (StrList != NULL) { + if (stricmp (FSData->FindData.cFileName, StrList->Str) == 0) { + Status = FALSE; + break; + } + + StrList = StrList->Next; + } + + if (Status) { + // + // See if it's in our list of excluded file extensions + // + FileNameLen = strlen (FSData->FindData.cFileName); + StrList = FSData->ExcludeExtensions; + while (StrList != NULL) { + ExtLen = strlen (StrList->Str); + if (stricmp ( + FSData->FindData.cFileName + FileNameLen - ExtLen, + StrList->Str + ) == 0) { + Status = FALSE; + break; + } + + StrList = StrList->Next; + } + } + + if (Status) { + FSData->FileFlags |= FILE_SEARCH_FILE; + } + } + // + // If it's a match, copy the filename into another field of the structure + // for portability. + // + if (Status) { + strcpy (FSData->FileName, FSData->FindData.cFileName); + } + + return Status; +} +// +// Exclude a list of subdirectories. +// +STATUS +FileSearchExcludeDirs ( + FILE_SEARCH_DATA *FSData, + STRING_LIST *StrList + ) +{ + FSData->ExcludeDirs = StrList; + return STATUS_SUCCESS; +} + +STATUS +FileSearchExcludeFiles ( + FILE_SEARCH_DATA *FSData, + STRING_LIST *StrList + ) +{ + FSData->ExcludeFiles = StrList; + return STATUS_SUCCESS; +} + +STATUS +FileSearchExcludeExtensions ( + FILE_SEARCH_DATA *FSData, + STRING_LIST *StrList + ) +{ + FSData->ExcludeExtensions = StrList; + return STATUS_SUCCESS; +} diff --git a/Tools/CodeTools/Source/GuidChk/FileSearch.h b/Tools/CodeTools/Source/GuidChk/FileSearch.h new file mode 100644 index 0000000000..bc40265366 --- /dev/null +++ b/Tools/CodeTools/Source/GuidChk/FileSearch.h @@ -0,0 +1,108 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + FileSearch.h + +Abstract: + + Header file to support file searching. + +--*/ + +#ifndef _FILE_SEARCH_H_ +#define _FILE_SEARCH_H_ + +// +// Since the file searching routines are OS dependent, put the +// necessary include paths in this header file so that the non-OS-dependent +// files don't need to include these windows-specific header files. +// +#include +#include +#include +#include +#include + +// +// Return codes of some of the file search routines +// +#define STATUS_NOT_FOUND 0x1000 + +// +// Flags for what to search for. Also used in the FileFlags return field. +// +#define FILE_SEARCH_DIR 0x0001 +#define FILE_SEARCH_FILE 0x0002 + +// +// Here's our class definition +// +typedef struct { + HANDLE Handle; + WIN32_FIND_DATA FindData; + UINT32 FileSearchFlags; // DIRS, FILES, etc + UINT32 FileFlags; + INT8 FileName[MAX_PATH]; // for portability + STRING_LIST *ExcludeDirs; + STRING_LIST *ExcludeFiles; + STRING_LIST *ExcludeExtensions; +} FILE_SEARCH_DATA; + +// +// Here's our member functions +// +STATUS +FileSearchInit ( + FILE_SEARCH_DATA *FSData + ) +; + +STATUS +FileSearchDestroy ( + FILE_SEARCH_DATA *FSData + ) +; + +STATUS +FileSearchStart ( + FILE_SEARCH_DATA *FSData, + char *FileMask, + UINT32 SearchFlags + ) +; + +STATUS +FileSearchFindNext ( + FILE_SEARCH_DATA *FSData + ) +; + +STATUS +FileSearchExcludeDirs ( + FILE_SEARCH_DATA *FSData, + STRING_LIST *StrList + ) +; +STATUS +FileSearchExcludeExtensions ( + FILE_SEARCH_DATA *FSData, + STRING_LIST *StrList + ) +; +STATUS +FileSearchExcludeFiles ( + FILE_SEARCH_DATA *FSData, + STRING_LIST *StrList + ) +; +#endif diff --git a/Tools/CodeTools/Source/GuidChk/GuidChk.c b/Tools/CodeTools/Source/GuidChk/GuidChk.c new file mode 100644 index 0000000000..de88405872 --- /dev/null +++ b/Tools/CodeTools/Source/GuidChk/GuidChk.c @@ -0,0 +1,2348 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + GuidChk.c + +Abstract: + + Parse files in a directory and subdirectories to find all guid definitions. + Then check them against each other to make sure there are no duplicates. + +--*/ + +#include +#include +#include +#include + +#include "CommonUtils.h" +#include "FileSearch.h" +#include "UtilsMsgs.h" + +#define MAX_LINE_LEN 180 // we concatenate two lines sometimes +// Define a structure that correlates filename extensions to an enumerated +// type. +// +typedef struct { + INT8 *Extension; + INT8 ExtensionCode; +} FILE_TYPE_TABLE_ENTRY; + +#define FILE_EXTENSION_UNKNOWN 0 +#define FILE_EXTENSION_C 1 +#define FILE_EXTENSION_H 2 +#define FILE_EXTENSION_IA32_ASM 3 +#define FILE_EXTENSION_IA32_INC 4 +#define FILE_EXTENSION_IA64_ASM 5 +#define FILE_EXTENSION_IA64_INC 6 +#define FILE_EXTENSION_PKG 7 +#define FILE_EXTENSION_INF 8 + +FILE_TYPE_TABLE_ENTRY FileTypeTable[] = { + ".c", + FILE_EXTENSION_C, + ".h", + FILE_EXTENSION_H, + ".inc", + FILE_EXTENSION_IA32_INC, + ".asm", + FILE_EXTENSION_IA32_ASM, + ".s", + FILE_EXTENSION_IA64_ASM, + ".pkg", + FILE_EXTENSION_PKG, + ".inf", + FILE_EXTENSION_INF, + ".i", + FILE_EXTENSION_IA64_INC, + NULL, + 0 +}; + +typedef struct EFI_GUID { + UINT32 Data1; + UINT16 Data2; + UINT16 Data3; + UINT8 Data4[8]; +} EFI_GUID; + +typedef struct { + INT8 Data[4]; + INT8 DataLen; +} EFI_SIGNATURE; + +typedef struct _GUID_RECORD { + struct _GUID_RECORD *Next; + BOOLEAN Reported; + INT8 *FileName; + INT8 *SymName; + EFI_GUID Guid; +} GUID_RECORD; + +typedef struct _SIGNATURE_RECORD { + struct _SIGNATURE_RECORD *Next; + BOOLEAN Reported; + INT8 *FileName; + EFI_SIGNATURE Signature; +} SIGNATURE_RECORD; + +// +// Utility options +// +typedef struct { + INT8 DatabaseOutputFileName[MAX_PATH]; // with -b option + STRING_LIST *ExcludeDirs; // list of directory names not to process + STRING_LIST *ExcludeSubDirs; // list of directory names to not process subdirectories (build) + STRING_LIST *ExcludeFiles; // list of files to exclude (make.inf) + STRING_LIST *ExcludeExtensions; // list of filename extensions to exclude (.inf, .pkg) + BOOLEAN Verbose; + BOOLEAN PrintFound; + BOOLEAN CheckGuids; + BOOLEAN CheckSignatures; + BOOLEAN GuidXReference; +} OPTIONS; + +static +STATUS +ProcessArgs ( + int Argc, + char *Argv[] + ); + +static +VOID +Usage ( + VOID + ); + +static +STATUS +ProcessDirectory ( + INT8 *Path, + INT8 *DirectoryName + ); + +static +STATUS +ProcessFile ( + INT8 *DirectoryName, + INT8 *FileName + ); + +static +UINT32 +GetFileExtension ( + INT8 *FileName + ); + +static +UINT32 +SkipWhiteSpace ( + INT8 *Str + ); + +static +UINT32 +ValidSymbolName ( + INT8 *Name + ); + +static +STATUS +ProcessCFileGuids ( + INT8 *FileName + ); + +static +STATUS +AddSignature ( + INT8 *FileName, + INT8 *StrDef, + UINT32 SigSize + ); + +static +STATUS +ProcessCFileSigs ( + INT8 *FileName + ); + +static +STATUS +ProcessINFFileGuids ( + INT8 *FileName + ); + +static +STATUS +ProcessPkgFileGuids ( + INT8 *FileName + ); + +static +STATUS +ProcessIA32FileGuids ( + INT8 *FileName + ); + +static +STATUS +ProcessIA64FileGuids ( + INT8 *FileName + ); + +static +BOOLEAN +IsIA64GuidLine ( + INT8 *Line, + UINT32 *GuidHigh, + UINT32 *GuidLow, + BOOLEAN *Low, + INT8 *SymName + ); + +static +STATUS +AddGuid11 ( + INT8 *FileName, + UINT32 *Data, + INT8 *SymName + ); + +static +STATUS +AddPkgGuid ( + INT8 *FileName, + UINT32 *Data, + UINT64 *Data64 + ); + +static +STATUS +AddGuid16 ( + INT8 *FileName, + UINT32 *Data + ); + +static +STATUS +AddGuid64x2 ( + INT8 *FileName, + UINT32 DataHH, // Upper 32-bits of upper 64 bits of guid + UINT32 DataHL, // Lower 32-bits of upper 64 bits + UINT32 DataLH, + UINT32 DataLL + ); + +static +VOID +FreeGuids ( + VOID + ); + +static +VOID +FreeSigs ( + VOID + ); + +static +STATUS +CheckDuplicates ( + VOID + ); + +// +// static +// VOID +// ReportGuid ( +// INT8 *FileName, +// GUID_RECORD *FileRecord +// ); +// +static +VOID +FreeOptions ( + VOID + ); + +static +BOOLEAN +CheckGuidData ( + UINT32 *GuidData, + UINT32 DataCount + ); + +/**************************** GLOBALS ****************************************/ +static GUID_RECORD *gGuidList = NULL; +static SIGNATURE_RECORD *gSignatureList = NULL; +static OPTIONS gOptions; + +/*****************************************************************************/ +int +main ( + int Argc, + char *Argv[] + ) +{ + INT8 *Cwd; + STATUS Status; + + SetUtilityName ("GuidChk"); + // + // Get the current working directory and then process the command line + // arguments. + // + Cwd = _getcwd (NULL, 0); + Status = ProcessArgs (Argc, Argv); + if (Status != STATUS_SUCCESS) { + return Status; + } + + if (gOptions.CheckGuids || gOptions.CheckSignatures) { + Status = ProcessDirectory (Cwd, NULL); + if (Status == STATUS_SUCCESS) { + // + // Check for duplicates + // + Status = CheckDuplicates (); + } + } + + if (gOptions.DatabaseOutputFileName[0] != 0) { + CreateGuidList (gOptions.DatabaseOutputFileName); + } + // + // Free up the memory + // + free (Cwd); + FreeGuids (); + FreeSigs (); + FreeOptions (); + return GetUtilityStatus (); +} + +static +STATUS +ProcessArgs ( + int Argc, + char *Argv[] + ) +{ + STRING_LIST *StrList; + + memset ((char *) &gOptions, 0, sizeof (gOptions)); + // + // skip over program name + // + Argc--; + Argv++; + + if (Argc == 0) { + Usage (); + return STATUS_ERROR; + } + + while (Argc > 0) { + // + // Look for options + // + if ((Argv[0][0] == '-') || (Argv[0][0] == '/')) { + switch (Argv[0][1]) { + // + // Help option + // + case 'h': + case 'H': + case '?': + Usage (); + return STATUS_ERROR; + break; + + // + // Check guids option + // + case 'g': + case 'G': + gOptions.CheckGuids = TRUE; + break; + + // + // Check signatures option + // + case 's': + case 'S': + gOptions.CheckSignatures = TRUE; + break; + + // + // Print guids found option + // + case 'p': + case 'P': + gOptions.PrintFound = TRUE; + break; + + // + // Exclude files option + // + case 'f': + case 'F': + // + // Check for another arg + // + if (Argc < 2) { + Error (NULL, 0, 0, Argv[0], "missing argument with option"); + Usage (); + return STATUS_ERROR; + } + + StrList = malloc (sizeof (STRING_LIST)); + if (StrList == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + memset ((char *) StrList, 0, sizeof (STRING_LIST)); + StrList->Str = Argv[1]; + StrList->Next = gOptions.ExcludeFiles; + gOptions.ExcludeFiles = StrList; + Argc--; + Argv++; + break; + + // + // Exclude directories option + // + case 'd': + case 'D': + // + // Check for another arg + // + if (Argc < 2) { + Error (NULL, 0, 0, Argv[0], "missing argument with option"); + Usage (); + return STATUS_ERROR; + } + + StrList = malloc (sizeof (STRING_LIST)); + if (StrList == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + memset ((char *) StrList, 0, sizeof (STRING_LIST)); + StrList->Str = Argv[1]; + StrList->Next = gOptions.ExcludeDirs; + gOptions.ExcludeDirs = StrList; + Argc--; + Argv++; + break; + + // + // -u exclude all subdirectories of a given directory option + // + case 'u': + case 'U': + // + // Check for another arg + // + if (Argc < 2) { + Error (NULL, 0, 0, Argv[0], "missing argument with option"); + Usage (); + return STATUS_ERROR; + } + + StrList = malloc (sizeof (STRING_LIST)); + if (StrList == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + memset ((char *) StrList, 0, sizeof (STRING_LIST)); + StrList->Str = Argv[1]; + StrList->Next = gOptions.ExcludeSubDirs; + gOptions.ExcludeSubDirs = StrList; + Argc--; + Argv++; + break; + + // + // -e exclude by filename extension option + // + case 'e': + case 'E': + // + // Check for another arg + // + if (Argc < 2) { + Error (NULL, 0, 0, Argv[0], "missing argument with option"); + Usage (); + return STATUS_ERROR; + } + + StrList = malloc (sizeof (STRING_LIST)); + if (StrList == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + memset ((char *) StrList, 0, sizeof (STRING_LIST)); + // + // Let them put a * in front of the filename extension + // + StrList->Str = Argv[1]; + if (StrList->Str[0] == '*') { + StrList->Str++; + } + + StrList->Next = gOptions.ExcludeExtensions; + gOptions.ExcludeExtensions = StrList; + Argc--; + Argv++; + break; + + // + // Print guid with matching symbol name for guid definitions found + // + case 'x': + case 'X': + gOptions.GuidXReference = 1; + break; + + // + // -b Print the internal database list to a file + // + case 'b': + case 'B': + // + // Check for one more arg + // + if (Argc < 2) { + Error (NULL, 0, 0, Argv[0], "must specify file name with option"); + Usage (); + return STATUS_ERROR; + } + + strcpy (gOptions.DatabaseOutputFileName, Argv[1]); + Argc--; + Argv++; + break; + + default: + Error (NULL, 0, 0, Argv[0], "invalid option"); + Usage (); + return STATUS_ERROR; + } + } else { + break; + } + // + // Next arg + // + Argc--; + Argv++; + } + + if (Argc > 0) { + Error (NULL, 0, 0, Argv[0], "invalid argument"); + Usage (); + return STATUS_ERROR; + } + // + // Have to check signatures, GUIDs, or dump the GUID database. + // + if ((!gOptions.CheckGuids) && (!gOptions.CheckSignatures) && (gOptions.DatabaseOutputFileName[0] == 0)) { + Error (NULL, 0, 0, "nothing to do", "must specify -g, -s, and/or -b"); + Usage (); + return STATUS_ERROR; + } + + return STATUS_SUCCESS; +} +// +// Print usage instructions +// +static +VOID +Usage ( + VOID + ) +{ + int Index; + char *Str[] = { + "GuidChk - scan files for duplicate GUID or signature definitions", + "", + "Usage: GuidChk {options}\n", + " Options: ", + " -d dirname exclude searching of a directory", + " -f filename exclude searching of a file", + " -e extension exclude searching of files by extension", + " -p print all GUIDS found", + " -g check for duplicate guids", + " -s check for duplicate signatures", + " -x print guid+defined symbol name", + " -b outfile write internal GUID+basename list to outfile", + " -u dirname exclude searching all subdirectories of a directory", + " -h -? print this help text", + " ", + " Example: GuidChk -g -u build -d fv -f make.inf -e .pkg", + "", + NULL + }; + for (Index = 0; Str[Index] != NULL; Index++) { + fprintf (stdout, "%s\n", Str[Index]); + } +} +// +// Process an entire directory by name +// +static +STATUS +ProcessDirectory ( + INT8 *Path, + INT8 *DirectoryName + ) +{ + FILE_SEARCH_DATA FSData; + char *FileMask; + BOOLEAN Done; + UINT32 Len; + BOOLEAN NoSubdirs; + STRING_LIST *SLPtr; + + // + // Root directory may be null + // + if (DirectoryName != NULL) { + // + // printf ("Processing directory: %s\n", DirectoryName); + // + } + // + // Initialize our file searching + // + FileSearchInit (&FSData); + + // + // Exclude some directories, files, and extensions + // + FileSearchExcludeDirs (&FSData, gOptions.ExcludeDirs); + FileSearchExcludeExtensions (&FSData, gOptions.ExcludeExtensions); + FileSearchExcludeFiles (&FSData, gOptions.ExcludeFiles); + // + // See if this directory is in the list of directories that they + // don't want to process subdirectories of + // + NoSubdirs = FALSE; + if (DirectoryName != NULL) { + for (SLPtr = gOptions.ExcludeSubDirs; SLPtr != NULL; SLPtr = SLPtr->Next) { + if (stricmp (SLPtr->Str, DirectoryName) == 0) { + // + // printf ("not processing subdirectories of %s\n", DirectoryName); + // + NoSubdirs = TRUE; + break; + } + } + } + // + // Create a filemask of files to search for. We'll append "\*.*" on the + // end, so allocate some extra bytes. + // + Len = strlen (Path) + 10; + if (DirectoryName != NULL) { + Len += strlen (DirectoryName); + } + + FileMask = malloc (Len); + if (FileMask == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + // + // Now put it all together + // + strcpy (FileMask, Path); + if ((DirectoryName != NULL) && (strlen (DirectoryName) > 0)) { + strcat (FileMask, "\\"); + strcat (FileMask, DirectoryName); + } + + strcat (FileMask, "\\*.*"); + + // + // Start file searching for files and directories + // + FileSearchStart (&FSData, FileMask, FILE_SEARCH_FILE | FILE_SEARCH_DIR); + + // + // Now hack the "\*.*" off the end of the filemask so we can use it to pass + // the full directory path on recursive calls to process directories. + // + FileMask[strlen (FileMask) - 4] = 0; + + // + // Loop until no more files + // + Done = FALSE; + while (!Done) { + // + // printf ("Found %s...", FSData.FileName); + // + if (FSData.FileFlags & FILE_SEARCH_DIR) { + // + // printf ("directory\n"); + // + if (!NoSubdirs) { + ProcessDirectory (FileMask, FSData.FileName); + } + } else if (FSData.FileFlags & FILE_SEARCH_FILE) { + // + // printf ("file\n"); + // + ProcessFile (FileMask, FSData.FileName); + } else { + // + // printf ("unknown\n"); + // + } + + if (FileSearchFindNext (&FSData) != STATUS_SUCCESS) { + Done = TRUE; + } + } + // + // Free up allocated memory + // + free (FileMask); + + // + // Free up our file searching + // + FileSearchDestroy (&FSData); + + return STATUS_SUCCESS; +} +// +// Process a single file. +// +static +STATUS +ProcessFile ( + INT8 *DirectoryName, + INT8 *FileName + ) +{ + STATUS Status; + UINT32 FileExtension; + INT8 FullFileName[MAX_PATH]; + + Status = STATUS_SUCCESS; + + sprintf (FullFileName, "%s\\%s", DirectoryName, FileName); + // + // printf ("Found file: %s\n", FullFileName); + // + FileExtension = GetFileExtension (FileName); + + // + // Process these for GUID checks + // + if (gOptions.CheckGuids) { + switch (FileExtension) { + case FILE_EXTENSION_C: + case FILE_EXTENSION_H: + Status = ProcessCFileGuids (FullFileName); + break; + + case FILE_EXTENSION_PKG: + Status = ProcessPkgFileGuids (FullFileName); + break; + + case FILE_EXTENSION_IA32_INC: + case FILE_EXTENSION_IA32_ASM: + Status = ProcessIA32FileGuids (FullFileName); + break; + + case FILE_EXTENSION_INF: + Status = ProcessINFFileGuids (FullFileName); + break; + + case FILE_EXTENSION_IA64_INC: + case FILE_EXTENSION_IA64_ASM: + Status = ProcessIA64FileGuids (FullFileName); + break; + + default: + // + // No errors anyway + // + Status = STATUS_SUCCESS; + break; + } + } + + if (gOptions.CheckSignatures) { + switch (FileExtension) { + case FILE_EXTENSION_C: + case FILE_EXTENSION_H: + Status = ProcessCFileSigs (FullFileName); + break; + + default: + // + // No errors anyway + // + Status = STATUS_SUCCESS; + break; + } + } + + return Status; +} +// +// Return a code indicating the file name extension. +// +static +UINT32 +GetFileExtension ( + INT8 *FileName + ) +{ + INT8 *Extension; + int Index; + + // + // Look back for a filename extension + // + for (Extension = FileName + strlen (FileName) - 1; Extension >= FileName; Extension--) { + if (*Extension == '.') { + for (Index = 0; FileTypeTable[Index].Extension != NULL; Index++) { + if (stricmp (FileTypeTable[Index].Extension, Extension) == 0) { + return FileTypeTable[Index].ExtensionCode; + } + } + } + } + + return FILE_TYPE_UNKNOWN; +} +// +// Process a .pkg file. +// +// Look for FFS_FILEGUID=35b898ca-b6a9-49ce-8c72-904735cc49b7 +// +static +STATUS +ProcessPkgFileGuids ( + INT8 *FileName + ) +{ + FILE *Fptr; + INT8 Line[MAX_LINE_LEN * 2]; + INT8 *Cptr; + INT8 *Cptr2; + UINT32 GuidScan[11]; + UINT64 Guid64; + + if ((Fptr = fopen (FileName, "r")) == NULL) { + Error (NULL, 0, 0, FileName, "could not open input file for reading"); + return STATUS_ERROR; + } + // + // Read lines from the file until done + // + while (fgets (Line, sizeof (Line), Fptr) != NULL) { + Cptr = Line; + Cptr += SkipWhiteSpace (Line); + if (strncmp (Cptr, "FFS_FILEGUID", 12) == 0) { + Cptr += 12; + Cptr += SkipWhiteSpace (Cptr); + if (*Cptr == '=') { + Cptr++; + Cptr += SkipWhiteSpace (Cptr + 1); + // + // Blank out dashes on the line. + // + for (Cptr2 = Cptr; *Cptr2; Cptr2++) { + if (*Cptr2 == '-') { + *Cptr2 = ' '; + } + } + + if (sscanf ( + Cptr, + "%X %X %X %X %I64X", + &GuidScan[0], + &GuidScan[1], + &GuidScan[2], + &GuidScan[3], + &Guid64 + ) == 5) { + AddPkgGuid (FileName, GuidScan, &Guid64); + } else { + DebugMsg (NULL, 0, 0, FileName, "GUID scan failed"); + } + } + } + } + + fclose (Fptr); + return STATUS_SUCCESS; +} +// +// Process an IA32 assembly file. +// +// Look for: +// FIND_FD_GUID_VAL equ 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h +// PEI_GUID_FileNameGuid_Gmch815 equ 081818181h, 08181h, 08181h, 081h, 081h, 081h, 081h, 081h, 081h, 081h, 081h +// +static +STATUS +ProcessIA32FileGuids ( + INT8 *FileName + ) +{ + FILE *Fptr; + INT8 Line[MAX_LINE_LEN]; + INT8 *Cptr; + INT8 CSave; + INT8 *CSavePtr; + UINT32 Len; + UINT32 GuidData[16]; + UINT32 Index; + + if ((Fptr = fopen (FileName, "r")) == NULL) { + Error (NULL, 0, 0, FileName, "could not open input file for reading"); + return STATUS_ERROR; + } + // + // Read lines from the file until done + // + while (fgets (Line, sizeof (Line), Fptr) != NULL) { + Cptr = Line; + Cptr += SkipWhiteSpace (Line); + // + // Look for xxxGUIDyyy equ 01h, 02h, 03h, ... + // + Len = ValidSymbolName (Cptr); + if (Len) { + // + // Terminate the line after the symbol name, then look for "guid" in + // the name. + // + CSavePtr = Cptr + Len; + CSave = *CSavePtr; + *CSavePtr = 0; + while (*Cptr) { + if (strnicmp (Cptr, "guid", 4) == 0) { + break; + } + + Cptr++; + } + // + // If we found the string "guid", continue + // + if (*Cptr) { + // + // Restore the character on the line where we null-terminated the symbol + // + *CSavePtr = CSave; + Cptr = CSavePtr; + Len = SkipWhiteSpace (Cptr); + // + // Had to be some white space + // + if (Len) { + Cptr += Len; + // + // now look for "equ" + // + if (strnicmp (Cptr, "equ", 3) == 0) { + Cptr += 3; + Cptr += SkipWhiteSpace (Cptr); + // + // Now scan all the data + // + for (Index = 0; Index < 16; Index++) { + if (sscanf (Cptr, "%X", &GuidData[Index]) != 1) { + break; + } + // + // Skip to next + // + while (isxdigit (*Cptr)) { + Cptr++; + } + + if ((*Cptr != 'h') && (*Cptr != 'H')) { + break; + } else { + Cptr++; + while (*Cptr && (isspace (*Cptr) || (*Cptr == ','))) { + Cptr++; + } + } + } + // + // Now see which form we had + // + if (Index == 16) { + AddGuid16 (FileName, GuidData); + } else if (Index == 11) { + AddGuid11 (FileName, GuidData, NULL); + } + } + } + } + } + } + + fclose (Fptr); + return STATUS_SUCCESS; +} +// +// Found and parsed an IA32 assembly code guid. Save the 16 bytes off in the list +// of guids. +// +static +STATUS +AddGuid16 ( + INT8 *FileName, + UINT32 *Data + ) +{ + GUID_RECORD *NewRec; + int Index; + + // + // Sanity check the data + // + if (!CheckGuidData (Data, 16)) { + return STATUS_ERROR; + } + // + // Allocate memory for a new guid structure + // + NewRec = malloc (sizeof (GUID_RECORD)); + if (NewRec == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + memset ((char *) NewRec, 0, sizeof (GUID_RECORD)); + NewRec->FileName = malloc (strlen (FileName) + 1); + if (NewRec->FileName == NULL) { + free (NewRec); + Error (NULL, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + strcpy (NewRec->FileName, FileName); + NewRec->Guid.Data1 = (UINT32) (Data[0] | (Data[1] << 8) | (Data[2] << 16) | (Data[3] << 24)); + NewRec->Guid.Data2 = (UINT16) (Data[4] | (Data[5] << 8)); + NewRec->Guid.Data3 = (UINT16) (Data[6] | (Data[7] << 8)); + for (Index = 0; Index < 8; Index++) { + NewRec->Guid.Data4[Index] = (UINT8) Data[Index + 8]; + } + // + // Add it to the list + // + NewRec->Next = gGuidList; + gGuidList = NewRec; + + // + // Report it + // ReportGuid (FileName, NewRec); + // + return STATUS_SUCCESS; +} +// +// Add a GUID defined as GuidLow: 0x1122334455667788 +// GuidHi: 0x99AABBCCDDEEFF00 +// +// These are equivalent: +// { 0x11223344, 0x5566, 0x7788, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00 } +// and: +// Low: 00FFEEDDCCBBAA99 +// Hi: 7788556611223344 +// +static +STATUS +AddGuid64x2 ( + INT8 *FileName, + UINT32 DataHH, // Upper 32-bits of upper 64 bits of guid + UINT32 DataHL, // Lower 32-bits of upper 64 bits + UINT32 DataLH, + UINT32 DataLL + ) +{ + GUID_RECORD *NewRec; + int Index; + + // + // Allocate memory for a new guid structure + // + NewRec = malloc (sizeof (GUID_RECORD)); + if (NewRec == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + memset ((char *) NewRec, 0, sizeof (GUID_RECORD)); + NewRec->FileName = malloc (strlen (FileName) + 1); + if (NewRec->FileName == NULL) { + free (NewRec); + Error (NULL, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + strcpy (NewRec->FileName, FileName); + NewRec->Guid.Data1 = DataHL; + NewRec->Guid.Data2 = (UINT16) DataHH; + NewRec->Guid.Data3 = (UINT16) (DataHH >> 16); + for (Index = 0; Index < 4; Index++) { + NewRec->Guid.Data4[Index] = (UINT8) DataLL; + DataLL >>= 8; + } + + for (Index = 0; Index < 4; Index++) { + NewRec->Guid.Data4[Index + 4] = (UINT8) DataLH; + DataLH >>= 8; + } + // + // Add it to the list + // + NewRec->Next = gGuidList; + gGuidList = NewRec; + + // + // Report it + // ReportGuid (FileName, NewRec); + // + return STATUS_SUCCESS; +} +// +// Process INF files. Look for: +// FILE_GUID = 240612B6-A063-11d4-9A3A-0090273FC14D +// +static +STATUS +ProcessINFFileGuids ( + INT8 *FileName + ) +{ + FILE *Fptr; + INT8 Line[MAX_LINE_LEN * 2]; + INT8 *Cptr; + INT8 *Cptr2; + UINT32 GuidScan[11]; + UINT64 Guid64; + + if ((Fptr = fopen (FileName, "r")) == NULL) { + Error (NULL, 0, 0, FileName, "could not open input file for reading"); + return STATUS_ERROR; + } + // + // Read lines from the file until done + // + while (fgets (Line, sizeof (Line), Fptr) != NULL) { + Cptr = Line; + Cptr += SkipWhiteSpace (Line); + if (strncmp (Cptr, "FILE_GUID", 9) == 0) { + Cptr += 9; + Cptr += SkipWhiteSpace (Cptr); + if (*Cptr == '=') { + Cptr++; + Cptr += SkipWhiteSpace (Cptr + 1); + // + // Blank out dashes on the line. + // + for (Cptr2 = Cptr; *Cptr2; Cptr2++) { + if (*Cptr2 == '-') { + *Cptr2 = ' '; + } + } + + if (sscanf ( + Cptr, + "%X %X %X %X %I64X", + &GuidScan[0], + &GuidScan[1], + &GuidScan[2], + &GuidScan[3], + &Guid64 + ) == 5) { + AddPkgGuid (FileName, GuidScan, &Guid64); + } else { + DebugMsg (NULL, 0, 0, FileName, "GUID scan failed"); + } + } + } + } + + fclose (Fptr); + return STATUS_SUCCESS; +} +// +// Parse ('g','m','a','p','a','b','c','d') +// +static +STATUS +AddSignature ( + INT8 *FileName, + INT8 *StrDef, + UINT32 SigSize + ) +{ + SIGNATURE_RECORD *NewRec; + INT8 *Cptr; + UINT32 Index; + BOOLEAN Fail; + + // + // Allocate memory for the new record + // + Fail = FALSE; + NewRec = malloc (sizeof (SIGNATURE_RECORD)); + if (NewRec == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + // + // Allocate memory to save the file name + // + NewRec->FileName = malloc (strlen (FileName) + 1); + if (NewRec->FileName == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + free (NewRec); + return STATUS_ERROR; + } + // + // Fill in the fields + // + strcpy (NewRec->FileName, FileName); + NewRec->Signature.DataLen = (UINT8) SigSize; + // + // Skip to open parenthesis + // + Cptr = StrDef; + Cptr += SkipWhiteSpace (Cptr); + if (*Cptr != '(') { + Fail = TRUE; + goto Done; + } + + Cptr++; + // + // Skip to first ' and start processing + // + while (*Cptr && (*Cptr != '\'')) { + Cptr++; + } + + for (Index = 0; Index < SigSize; Index++) { + if (*Cptr == '\'') { + Cptr++; + NewRec->Signature.Data[Index] = (INT8) *Cptr; + // + // Skip to closing quote + // + Cptr++; + if (*Cptr != '\'') { + Fail = TRUE; + break; + } + // + // Skip over closing quote, go to next one + // + Cptr++; + while (*Cptr && (*Cptr != '\'')) { + Cptr++; + } + } else { + Fail = TRUE; + DebugMsg (NULL, 0, 0, StrDef, "failed to parse signature"); + break; + } + } + +Done: + if (Fail) { + free (NewRec->FileName); + free (NewRec); + return STATUS_ERROR; + } + + NewRec->Next = gSignatureList; + gSignatureList = NewRec; + return STATUS_SUCCESS; +} +// +// Look for: +// #define POOL_HEAD_SIGNATURE EFI_SIGNATURE_16('p','h') +// #define GCD_MEMORY_MAP_SIGNATURE EFI_SIGNATURE_32('g','m','a','p') +// #define GCD_MEMORY_MAP_SIGNATURE EFI_SIGNATURE_64('g','m','a','p','a','b','c','d') +// +static +STATUS +ProcessCFileSigs ( + INT8 *FileName + ) +{ + FILE *Fptr; + INT8 Line[MAX_LINE_LEN * 2]; + INT8 *Cptr; + UINT32 Len; + UINT32 LineLen; + + if ((Fptr = fopen (FileName, "r")) == NULL) { + Error (NULL, 0, 0, FileName, "could not open input file for reading"); + return STATUS_ERROR; + } + // + // Read lines from the file until done + // + while (fgets (Line, sizeof (Line), Fptr) != NULL) { + Cptr = Line; + Cptr += SkipWhiteSpace (Line); + // + // look for #define xxxGUIDxxx value + // + if (*Cptr == '#') { + Cptr++; + Cptr += SkipWhiteSpace (Cptr); + // + // Look for "define" + // + if (!strncmp (Cptr, "define", 6)) { + Cptr += 6; + // + // Better be whitespace + // + Len = SkipWhiteSpace (Cptr); + if (Len) { + Cptr += Len; + // + // See if it's a valid symbol name + // + Len = ValidSymbolName (Cptr); + if (Len) { + // + // It is a valid symbol name. See if there's a line continuation, + // and if so, read one more line. + // Skip over the symbol name and look for the string "EFI_SIGNATURE_xx" + // + LineLen = strlen (Line); + if ((Line[LineLen - 1] == '\n') && (Line[LineLen - 2] == '\\')) { + fgets (Line + LineLen - 2, sizeof (Line) - LineLen, Fptr); + } else if (Line[LineLen - 1] == '\\') { + fgets (Line + LineLen - 1, sizeof (Line) - LineLen, Fptr); + } + + Cptr += Len; + Cptr += SkipWhiteSpace (Cptr); + if (strncmp (Cptr, "EFI_SIGNATURE_16", 16) == 0) { + AddSignature (FileName, Cptr + 16, 2); + } else if (strncmp (Cptr, "EFI_SIGNATURE_32", 16) == 0) { + AddSignature (FileName, Cptr + 16, 4); + } else if (strncmp (Cptr, "EFI_SIGNATURE_64", 16) == 0) { + AddSignature (FileName, Cptr + 16, 8); + } + } + } + } + } + } + + fclose (Fptr); + return STATUS_SUCCESS; +} +// +// look for #define xxxGUIDyyy { 0x...} +// xxx EFI_GUID GuidName = { 0x... }; +// +static +STATUS +ProcessCFileGuids ( + INT8 *FileName + ) +{ + FILE *Fptr; + INT8 Line[MAX_LINE_LEN * 2]; + INT8 *Cptr; + INT8 CSave; + INT8 *CSavePtr; + INT8 *TempCptr; + INT8 *SymName; + UINT32 Len; + UINT32 LineLen; + UINT32 GuidScan[11]; + + if ((Fptr = fopen (FileName, "r")) == NULL) { + Error (NULL, 0, 0, FileName, "could not open input file for reading"); + return STATUS_ERROR; + } + // + // Read lines from the file until done + // + while (fgets (Line, sizeof (Line), Fptr) != NULL) { + Cptr = Line; + Cptr += SkipWhiteSpace (Line); + // + // look for #define xxxGUIDxxx value + // + if (*Cptr == '#') { + Cptr++; + Cptr += SkipWhiteSpace (Cptr); + // + // Look for "define" + // + if (!strncmp (Cptr, "define", 6)) { + Cptr += 6; + // + // Better be whitespace + // + Len = SkipWhiteSpace (Cptr); + if (Len) { + Cptr += Len; + // + // See if it's a valid symbol name + // + Len = ValidSymbolName (Cptr); + if (Len) { + // + // It is a valid symbol name. See if there's a line continuation, + // and if so, read one more line. + // Then truncate after the symbol name, look for the string "GUID", + // and continue. + // + SymName = Cptr; + LineLen = strlen (Line); + if ((Line[LineLen - 1] == '\n') && (Line[LineLen - 2] == '\\')) { + fgets (Line + LineLen - 2, sizeof (Line) - LineLen, Fptr); + } else if (Line[LineLen - 1] == '\\') { + fgets (Line + LineLen - 1, sizeof (Line) - LineLen, Fptr); + } + + CSavePtr = Cptr + Len; + CSave = *CSavePtr; + *CSavePtr = 0; + while (*Cptr) { + if (strncmp (Cptr, "GUID", 4) == 0) { + break; + } + + Cptr++; + } + // + // If we didn't run out of string, then we found the GUID string. + // Now look for { 0x....... } + // + if (*Cptr) { + Cptr = CSavePtr; + *CSavePtr = CSave; + Cptr += SkipWhiteSpace (Cptr); + if (*Cptr == '{') { + *Cptr = 0; + Cptr++; + // + // 0x665E3FF6, 0x46CC, 0x11d4, 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } + // If you have one suffixed with "L", then it doesn't work. So hack off 'L' characters + // in the string. + // + for (TempCptr = Cptr; *TempCptr; TempCptr++) { + if (*TempCptr == 'L') { + if (*(TempCptr + 1) == ',') { + *TempCptr = ','; + *(TempCptr + 1) = ' '; + } + } + } + + if (sscanf ( + Cptr, + "%X, %X, %X, %X, %X, %X, %X, %X, %X, %X, %X", + &GuidScan[0], + &GuidScan[1], + &GuidScan[2], + &GuidScan[3], + &GuidScan[4], + &GuidScan[5], + &GuidScan[6], + &GuidScan[7], + &GuidScan[8], + &GuidScan[9], + &GuidScan[10] + ) == 11) { + AddGuid11 (FileName, GuidScan, SymName); + } + } + } + } + } + } + // + // Else look for "static EFI_GUID xxxGUIDxxx = { 0x.... }; + // + } else if ((CSavePtr = strstr (Line, "EFI_GUID")) != NULL) { + // + // Read the next line if line continuation + // + LineLen = strlen (Line); + if ((Line[LineLen - 1] == '\n') && (Line[LineLen - 2] == '\\')) { + fgets (Line + LineLen - 2, sizeof (Line) - LineLen, Fptr); + } else if (Line[LineLen - 1] == '\\') { + fgets (Line + LineLen - 1, sizeof (Line) - LineLen, Fptr); + } + + Cptr = CSavePtr + 8; + Cptr += SkipWhiteSpace (Cptr); + // + // Should be variable name next + // + Len = ValidSymbolName (Cptr); + SymName = Cptr; + Cptr += Len; + Cptr += SkipWhiteSpace (Cptr); + if (*Cptr == '=') { + Cptr++; + Cptr += SkipWhiteSpace (Cptr); + // + // Should be open-brace next to define guid + // + if (*Cptr == '{') { + Cptr++; + // + // 0x665E3FF6, 0x46CC, 0x11d4, 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } + // + if (sscanf ( + Cptr, + "%X, %X, %X, %X, %X, %X, %X, %X, %X, %X, %X", + &GuidScan[0], + &GuidScan[1], + &GuidScan[2], + &GuidScan[3], + &GuidScan[4], + &GuidScan[5], + &GuidScan[6], + &GuidScan[7], + &GuidScan[8], + &GuidScan[9], + &GuidScan[10] + ) == 11) { + AddGuid11 (FileName, GuidScan, Cptr); + // + // printf ("Found guid: %s", Cptr); + // + } + } + } + } + } + + fclose (Fptr); + return STATUS_SUCCESS; +} +// +// Process Intel Itanium(TM) GUID definitions. Look for: +// #define Cs870MemoryTestPEIMGuidL 0x9C2403386E1C8FAA +// #define Cs870MemoryTestPEIMGuidH 0xE89E95C6180342f0 +// in either order. +// This function assumes no blank lines between definitions. +// +static +STATUS +ProcessIA64FileGuids ( + INT8 *FileName + ) +{ + FILE *Fptr; + INT8 Line[MAX_LINE_LEN]; + UINT32 Guid1H; + UINT32 Guid1L; + UINT32 Guid2H; + UINT32 Guid2L; + INT8 SymName1[MAX_LINE_LEN]; + INT8 SymName2[MAX_LINE_LEN]; + BOOLEAN Done; + BOOLEAN LowFirst; + BOOLEAN FoundLow; + + if ((Fptr = fopen (FileName, "r")) == NULL) { + Error (NULL, 0, 0, FileName, "could not open input file for reading"); + return STATUS_ERROR; + } + + Done = FALSE; + if (fgets (Line, sizeof (Line), Fptr) == NULL) { + Done = 1; + } + // + // Read lines from the file until done. Since the guid definition takes + // two lines, we read lines in different places to recover gracefully + // from mismatches. For example, if you thought you found the first half, + // but the next line had a symbol mismatch, then you have to process the + // line again in case it's the start of a new definition. + // + while (!Done) { + // + // Check current line for GUID definition. Assume low define first. + // + if (IsIA64GuidLine (Line, &Guid1H, &Guid1L, &FoundLow, SymName1)) { + // + // Might have to swap guids later. Save off if we found the LOW first + // + if (FoundLow) { + LowFirst = TRUE; + } else { + LowFirst = FALSE; + } + // + // Read the next line and try for the rest of the guid definition + // + if (fgets (Line, sizeof (Line), Fptr) == NULL) { + Done = 1; + } else { + if (IsIA64GuidLine (Line, &Guid2H, &Guid2L, &FoundLow, SymName2)) { + // + // Found another. If the symbol names match, then save it off. + // + if (strcmp (SymName1, SymName2) == 0) { + // + // Yea, found one. Save it off. + // + if (LowFirst) { + AddGuid64x2 (FileName, Guid2H, Guid2L, Guid1H, Guid1L); + } else { + AddGuid64x2 (FileName, Guid1H, Guid1L, Guid2H, Guid2L); + } + // + // Read the next line for processing + // + if (fgets (Line, sizeof (Line), Fptr) == NULL) { + Done = 1; + } + } else { + // + // Don't get another line so that we reprocess this line in case it + // contains the start of a new definition. + // fprintf (stdout, "Symbol name mismatch: %s: %s != %s\n", + // FileName, SymName1, SymName2); + // + } + } else { + // + // Second line was not a guid definition. Get the next line from the + // file. + // + if (fgets (Line, sizeof (Line), Fptr) == NULL) { + Done = 1; + } + } + } + } else { + // + // Not a guid define line. Next. + // + if (fgets (Line, sizeof (Line), Fptr) == NULL) { + Done = 1; + } + } + } + + fclose (Fptr); + return STATUS_SUCCESS; +} +// +// Given a line from an Itanium-based assembly file, check the line for a guid +// defininition. One of either: +// #define Cs870MemoryTestPEIMGuidL 0x9C2403386E1C8FAA +// #define Cs870MemoryTestPEIMGuidH 0xE89E95C6180342f0 +// Return the defined value as two 32-bit values, and whether it's a high +// or low guid. +// +static +BOOLEAN +IsIA64GuidLine ( + INT8 *Line, + UINT32 *GuidHigh, + UINT32 *GuidLow, + BOOLEAN *FoundLow, + INT8 *SymName + ) +{ + INT8 *Cptr; + INT8 CSave; + INT8 *CSavePtr; + INT8 *SymStart; + UINT32 Len; + + Cptr = Line; + Cptr += SkipWhiteSpace (Cptr); + // + // look for #define xxxGUID[L|H] 0xHexValue + // + if (*Cptr == '#') { + Cptr++; + Cptr += SkipWhiteSpace (Cptr); + // + // Look for "define" + // + if (!strncmp (Cptr, "define", 6)) { + Cptr += 6; + // + // Better be whitespace + // + Len = SkipWhiteSpace (Cptr); + if (Len) { + Cptr += Len; + // + // See if it's a valid symbol name + // + Len = ValidSymbolName (Cptr); + if (Len) { + // + // Save the start so we can copy it to their string if later checks are ok + // + SymStart = Cptr; + // + // It is a valid symbol name, look for the string GuidL or GuidH + // + CSavePtr = Cptr + Len; + CSave = *CSavePtr; + *CSavePtr = 0; + while (*Cptr) { + if (strncmp (Cptr, "GuidL", 5) == 0) { + *FoundLow = 1; + break; + } else if (strncmp (Cptr, "GuidH", 5) == 0) { + *FoundLow = 0; + break; + } + + Cptr++; + } + // + // If we didn't run out of string, then we found the GUID string. + // Restore the null character we inserted above and continue. + // Now look for 0x....... + // + if (*Cptr) { + // + // Return symbol name less the "L" or "H" + // + strcpy (SymName, SymStart); + SymName[strlen (SymName) - 1] = 0; + Cptr = CSavePtr; + *CSavePtr = CSave; + Cptr += SkipWhiteSpace (Cptr); + if ((*Cptr == '0') && (*(Cptr + 1) == 'x')) { + // + // skip over "0x" + // + Cptr += 2; + // + // 0x0123456789ABCDEF -- null terminate after 8 characters, + // scan, replace the character and scan at that point. + // + CSave = *(Cptr + 8); + *(Cptr + 8) = 0; + if (sscanf (Cptr, "%X", GuidHigh) == 1) { + *(Cptr + 8) = CSave; + if (sscanf (Cptr + 8, "%X", GuidLow) == 1) { + return TRUE; + } + } + } + } + } + } + } + } + + return FALSE; +} +// +// Look at the characters in the string and determine if it's a valid +// symbol name. Basically [a-zA-Z_][a-zA-Z_0-9]* +// +static +UINT32 +ValidSymbolName ( + INT8 *Name + ) +{ + int Len; + + Len = 0; + + // + // Test first character + // + if (((*Name >= 'a') && (*Name <= 'z')) || ((*Name >= 'A') && (*Name <= 'Z')) || (*Name == '_')) { + Name++; + Len = 1; + while (*Name) { + if (((*Name >= 'a') && (*Name <= 'z')) || + ((*Name >= 'A') && (*Name <= 'Z')) || + ((*Name >= '0') && (*Name <= '9')) || + (*Name == '_') + ) { + Name++; + Len++; + } else { + break; + } + } + } + + return Len; +} + +static +UINT32 +SkipWhiteSpace ( + INT8 *Str + ) +{ + UINT32 Len; + Len = 0; + while (isspace (*Str) && *Str) { + Len++; + Str++; + } + + return Len; +} +// +// found FFS_FILEGUID=35b898ca-b6a9-49ce-8c72-904735cc49b7 +// +static +STATUS +AddPkgGuid ( + INT8 *FileName, + UINT32 *Data, + UINT64 *Data64 + ) +{ + GUID_RECORD *NewRec; + int Index; + + // + // Sanity check the data + // + if ((Data[1] | Data[2] | Data[3]) & 0xFFFF0000) { + Error (NULL, 0, 0, "out of range value for GUID data word(s) [1] - [3]", NULL); + return STATUS_ERROR; + } + // + // More checks for Data64? + // Allocate memory for a new one guid structure + // + NewRec = malloc (sizeof (GUID_RECORD)); + if (NewRec == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + memset ((char *) NewRec, 0, sizeof (GUID_RECORD)); + NewRec->FileName = malloc (strlen (FileName) + 1); + if (NewRec->FileName == NULL) { + free (NewRec); + Error (NULL, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + strcpy (NewRec->FileName, FileName); + NewRec->Guid.Data1 = Data[0]; + NewRec->Guid.Data2 = (UINT16) Data[1]; + NewRec->Guid.Data3 = (UINT16) Data[2]; + NewRec->Guid.Data4[0] = (UINT8) Data[3]; + NewRec->Guid.Data4[1] = (UINT8) (Data[3] >> 8); + for (Index = 2; Index < 8; Index++) { + NewRec->Guid.Data4[Index] = (UINT8) *Data64; + *Data64 >>= 8; + } + // + // Add it to the list + // + NewRec->Next = gGuidList; + gGuidList = NewRec; + + // + // Report it + // ReportGuid (FileName, NewRec); + // + return STATUS_SUCCESS; +} +// +// Add a guid consisting of 11 fields to our list of guids +// +static +STATUS +AddGuid11 ( + INT8 *FileName, + UINT32 *Data, + INT8 *SymName + ) +{ + GUID_RECORD *NewRec; + int Index; + + // + // Sanity check the data + // + if (!CheckGuidData (Data, 11)) { + return STATUS_ERROR; + } + // + // Allocate memory for a new one guid structure + // + NewRec = malloc (sizeof (GUID_RECORD)); + if (NewRec == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + memset ((char *) NewRec, 0, sizeof (GUID_RECORD)); + NewRec->FileName = malloc (strlen (FileName) + 1); + if (NewRec->FileName == NULL) { + free (NewRec); + Error (NULL, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + strcpy (NewRec->FileName, FileName); + if (SymName != NULL) { + NewRec->SymName = malloc (strlen (SymName) + 1); + if (NewRec->SymName == NULL) { + free (NewRec); + Error (NULL, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + } + + strcpy (NewRec->SymName, SymName); + + NewRec->Guid.Data1 = Data[0]; + NewRec->Guid.Data2 = (UINT16) Data[1]; + NewRec->Guid.Data3 = (UINT16) Data[2]; + for (Index = 0; Index < 8; Index++) { + NewRec->Guid.Data4[Index] = (UINT8) Data[3 + Index]; + } + // + // Add it to the list + // + NewRec->Next = gGuidList; + gGuidList = NewRec; + + // + // Report it + // ReportGuid (FileName, NewRec); + // + return STATUS_SUCCESS; +} +// +// For debug purposes, print each guid found +// +// static +// VOID +// ReportGuid ( +// INT8 *FileName, +// GUID_RECORD *NewGuid +// ) +// { +// //fprintf (stdout, "%s: 0x%08X\n", FileName, NewGuid->Guid.Data1); +// } +// +// Free up memory we allocated to keep track of guids defined. +// +static +VOID +FreeGuids ( + VOID + ) +{ + GUID_RECORD *NextRec; + while (gGuidList != NULL) { + NextRec = gGuidList->Next; + if (gGuidList->FileName != NULL) { + free (gGuidList->FileName); + } + + if (gGuidList->SymName != NULL) { + free (gGuidList->SymName); + } + + free (gGuidList); + gGuidList = NextRec; + } +} + +static +VOID +FreeSigs ( + VOID + ) +{ + SIGNATURE_RECORD *NextRec; + while (gSignatureList != NULL) { + NextRec = gSignatureList->Next; + if (gSignatureList->FileName != NULL) { + free (gSignatureList->FileName); + } + + free (gSignatureList); + gSignatureList = NextRec; + } +} +// +// Scan through all guids defined and compare each for duplicates. +// +static +STATUS +CheckDuplicates ( + VOID + ) +{ + GUID_RECORD *CurrentFile; + + GUID_RECORD *TempFile; + SIGNATURE_RECORD *CurrentSig; + SIGNATURE_RECORD *TempSig; + STATUS Status; + int Index; + int DupCount; + int Len; + BOOLEAN Same; + UINT32 GuidSum; + INT8 *SymName; + + Status = STATUS_SUCCESS; + + // + // If we're checking guids..... + // + if (gOptions.CheckGuids) { + // + // If -p option, print all guids found + // + if (gOptions.PrintFound) { + CurrentFile = gGuidList; + while (CurrentFile != NULL) { + fprintf ( + stdout, + "GUID: 0x%08X 0x%04X 0x%04X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X %s\n", + (UINT32) CurrentFile->Guid.Data1, + (UINT32) CurrentFile->Guid.Data2, + (UINT32) CurrentFile->Guid.Data3, + (UINT32) CurrentFile->Guid.Data4[0], + (UINT32) CurrentFile->Guid.Data4[1], + (UINT32) CurrentFile->Guid.Data4[2], + (UINT32) CurrentFile->Guid.Data4[3], + (UINT32) CurrentFile->Guid.Data4[4], + (UINT32) CurrentFile->Guid.Data4[5], + (UINT32) CurrentFile->Guid.Data4[6], + (UINT32) CurrentFile->Guid.Data4[7], + CurrentFile->FileName + ); + CurrentFile = CurrentFile->Next; + } + } + + if (gOptions.GuidXReference) { + CurrentFile = gGuidList; + while (CurrentFile != NULL) { + // + // If no symbol name, print "unknown" + // + SymName = CurrentFile->SymName; + if (SymName == NULL) { + SymName = "unknown"; + } + + fprintf ( + stdout, + "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X %s\n", + (UINT32) CurrentFile->Guid.Data1, + (UINT32) CurrentFile->Guid.Data2, + (UINT32) CurrentFile->Guid.Data3, + (UINT32) CurrentFile->Guid.Data4[0], + (UINT32) CurrentFile->Guid.Data4[1], + (UINT32) CurrentFile->Guid.Data4[2], + (UINT32) CurrentFile->Guid.Data4[3], + (UINT32) CurrentFile->Guid.Data4[4], + (UINT32) CurrentFile->Guid.Data4[5], + (UINT32) CurrentFile->Guid.Data4[6], + (UINT32) CurrentFile->Guid.Data4[7], + SymName + ); + CurrentFile = CurrentFile->Next; + } + } + // + // Now go through all guids and report duplicates. + // + CurrentFile = gGuidList; + while (CurrentFile != NULL) { + DupCount = 0; + TempFile = CurrentFile->Next; + while (TempFile) { + // + // Compare the guids + // + if ((CurrentFile->Guid.Data1 == TempFile->Guid.Data1) && + (CurrentFile->Guid.Data2 == TempFile->Guid.Data2) && + (CurrentFile->Guid.Data3 == TempFile->Guid.Data3) + ) { + // + // OR in all the guid bytes so we can ignore NULL-guid definitions. + // + GuidSum = CurrentFile->Guid.Data1 | CurrentFile->Guid.Data2 | CurrentFile->Guid.Data3; + Same = TRUE; + for (Index = 0; Index < 8; Index++) { + GuidSum |= CurrentFile->Guid.Data4[Index]; + if (CurrentFile->Guid.Data4[Index] != TempFile->Guid.Data4[Index]) { + Same = FALSE; + break; + } + } + // + // If they're the same, and the guid was non-zero, print a message. + // + if (Same && GuidSum) { + if (DupCount == 0) { + Error (NULL, 0, 0, "duplicate GUIDS found", NULL); + fprintf (stdout, " FILE1: %s\n", CurrentFile->FileName); + } + + DupCount++; + fprintf (stdout, " FILE%d: %s\n", DupCount + 1, TempFile->FileName); + // + // Flag it as reported so we don't report it again if there's three or more + // + TempFile->Reported = TRUE; + } + } + // + // Next one + // + TempFile = TempFile->Next; + } + // + // Print the guid if we found duplicates + // + if (DupCount) { + fprintf ( + stdout, + " GUID: 0x%08X 0x%04X 0x%04X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", + (UINT32) CurrentFile->Guid.Data1, + (UINT32) CurrentFile->Guid.Data2, + (UINT32) CurrentFile->Guid.Data3, + (UINT32) CurrentFile->Guid.Data4[0], + (UINT32) CurrentFile->Guid.Data4[1], + (UINT32) CurrentFile->Guid.Data4[2], + (UINT32) CurrentFile->Guid.Data4[3], + (UINT32) CurrentFile->Guid.Data4[4], + (UINT32) CurrentFile->Guid.Data4[5], + (UINT32) CurrentFile->Guid.Data4[6], + (UINT32) CurrentFile->Guid.Data4[7] + ); + // + // return STATUS_ERROR; + // + } + // + // Find the next one that hasn't been reported + // + do { + CurrentFile = CurrentFile->Next; + } while ((CurrentFile != NULL) && (CurrentFile->Reported)); + } + } + + if (gOptions.CheckSignatures) { + // + // Print ones found if specified + // + if (gOptions.PrintFound) { + CurrentSig = gSignatureList; + while (CurrentSig != NULL) { + Len = CurrentSig->Signature.DataLen; + for (Index = 0; Index < Len; Index++) { + fprintf (stdout, "%c", CurrentSig->Signature.Data[Index]); + } + + fprintf (stdout, " %s\n", CurrentSig->FileName); + CurrentSig = CurrentSig->Next; + } + } + + CurrentSig = gSignatureList; + while (CurrentSig != NULL) { + DupCount = 0; + TempSig = CurrentSig->Next; + Len = CurrentSig->Signature.DataLen; + while (TempSig) { + // + // Check for same length, then do string compare + // + if (Len == TempSig->Signature.DataLen) { + if (strncmp (CurrentSig->Signature.Data, TempSig->Signature.Data, Len) == 0) { + // + // Print header message if first failure for this sig + // + if (DupCount == 0) { + Error (NULL, 0, 0, "duplicate signatures found", NULL); + fprintf (stdout, " FILE1: %s\n", CurrentSig->FileName); + } + + DupCount++; + fprintf (stdout, " FILE%d: %s\n", DupCount + 1, TempSig->FileName); + TempSig->Reported = TRUE; + } + } + + TempSig = TempSig->Next; + } + + if (DupCount) { + fprintf (stdout, " SIG: "); + for (Index = 0; Index < Len; Index++) { + fprintf (stdout, "%c", CurrentSig->Signature.Data[Index]); + } + + fprintf (stdout, "\n"); + } + // + // On to the next one that hasn't been reported + // + do { + CurrentSig = CurrentSig->Next; + } while ((CurrentSig != NULL) && (CurrentSig->Reported)); + } + } + + return Status; +} + +static +VOID +FreeOptions ( + VOID + ) +/*++ + +Routine Description: + Free up any memory we allocated when processing command-line options. + +Arguments: + None. + +Returns: + NA + +Notes: + We don't free up the ->Str fields because we did not allocate them. + Instead, we just set the pointer to point to the actual parameter + from the command line. + +--*/ +{ + STRING_LIST *Ptr; + while (gOptions.ExcludeDirs != NULL) { + Ptr = gOptions.ExcludeDirs->Next; + // + // free (gOptions.ExcludeDirs->Str); + // + free (gOptions.ExcludeDirs); + gOptions.ExcludeDirs = Ptr; + } + + while (gOptions.ExcludeSubDirs != NULL) { + Ptr = gOptions.ExcludeSubDirs->Next; + // + // free (gOptions.ExcludeSubDirs->Str); + // + free (gOptions.ExcludeSubDirs); + gOptions.ExcludeSubDirs = Ptr; + } + + while (gOptions.ExcludeExtensions != NULL) { + Ptr = gOptions.ExcludeExtensions->Next; + // + // free (gOptions.ExcludeExtensions->Str); + // + free (gOptions.ExcludeExtensions); + gOptions.ExcludeExtensions = Ptr; + } + + while (gOptions.ExcludeFiles != NULL) { + Ptr = gOptions.ExcludeFiles->Next; + // + // free (gOptions.ExcludeFiles->Str); + // + free (gOptions.ExcludeFiles); + gOptions.ExcludeFiles = Ptr; + } +} +// +// Given an array of 32-bit data, validate the data for the given number of +// guid data. For example, it might have been scanned as 16 bytes of data, or +// 11 fields of data. +// +static +BOOLEAN +CheckGuidData ( + UINT32 *Data, + UINT32 DataCount + ) +{ + UINT32 Index; + + if (DataCount == 16) { + for (Index = 0; Index < 16; Index++) { + if (Data[Index] &~0xFF) { + return FALSE; + } + } + + return TRUE; + } else if (DataCount == 11) { + // + // Data[0] never out of range (32-bit) + // + if ((Data[1] | Data[2]) &~0xFFFF) { + // + // Error ("Out of range value for GUID data word(s) [1] and/or [2]"); + // + return FALSE; + } + + for (Index = 0; Index < 8; Index++) { + if (Data[Index + 3] &~0xFF) { + // + // Error ("Out of range value for GUID data byte(s) [4] - [11]"); + // + return FALSE; + } + } + + return TRUE; + } + + return FALSE; +} diff --git a/Tools/CodeTools/Source/GuidChk/GuidList.c b/Tools/CodeTools/Source/GuidChk/GuidList.c new file mode 100644 index 0000000000..bb6a44d85e --- /dev/null +++ b/Tools/CodeTools/Source/GuidChk/GuidList.c @@ -0,0 +1,186 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + GuidList.c + +Abstract: + + Utility to create a GUID-to-name listing file that can + be used by other utilities. Basic operation is to take the + table of name+GUIDs that we have compiled into this utility, + and create a text file that can be parsed by other utilities + to do replacement of "name" with "GUID". + +Notes: + To add a new GUID to this database: + 1. Add a "#include EFI_GUID_DEFINITION(name)" statement below + 2. Modify the mGuidList[] array below to add the new GUID name + + The only issue that may come up is that, if the source GUID file + is not in the standard GUID directory, then this utility won't + compile because the #include fails. In this case you'd need + to define a new macro (if it's in a standard place) or modify + this utility's makefile to add the path to your new .h file. + +--*/ + +#include +#include +#include +#include + +#include +#include +#include + +#include "EfiUtilityMsgs.h" + + +#define GUID_XREF(varname, guid) { \ + #varname, #guid, guid \ + } + +#define NULL_GUID \ + { \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 \ + } + +typedef struct { + INT8 *VariableName; + INT8 *DefineName; + EFI_GUID Guid; +} GUID_LIST; + +// +// This is our table of all GUIDs we want to print out to create +// a GUID-to-name cross reference. +// Use the #defined name from the GUID definition's source .h file. +// +static GUID_LIST mGuidList[] = { + GUID_XREF(gAprioriGuid, EFI_APRIORI_GUID), + GUID_XREF(gEfiAcpiTableStorageGuid, EFI_ACPI_TABLE_STORAGE_GUID), + // FIXME The next line was removed in the port to R9. + // GUID_XREF(gEfiDefaultBmpLogoGuid, EFI_DEFAULT_BMP_LOGO_GUID), + GUID_XREF(gEfiAcpiTableStorageGuid, EFI_ACPI_TABLE_STORAGE_GUID), + // + // Terminator + // + { + NULL, + NULL, + NULL_GUID + } +}; + +void +PrintGuidText ( + FILE *OutFptr, + INT8 *VariableName, + INT8 *DefineName, + EFI_GUID *Guid + ); + +int +CreateGuidList ( + INT8 *OutFileName + ) +/*++ + +Routine Description: + Print our GUID/name list to the specified output file. + +Arguments: + OutFileName - name of the output file to write our results to. + +Returns: + 0 if successful + nonzero otherwise + +--*/ +{ + FILE *OutFptr; + int Index; + + // + // Open output file for writing. If the name is NULL, then write to stdout + // + if (OutFileName != NULL) { + OutFptr = fopen (OutFileName, "w"); + if (OutFptr == NULL) { + Error (NULL, 0, 0, OutFileName, "failed to open output file for writing"); + return STATUS_ERROR; + } + } else { + OutFptr = stdout; + } + + for (Index = 0; mGuidList[Index].VariableName != NULL; Index++) { + PrintGuidText (OutFptr, mGuidList[Index].VariableName, mGuidList[Index].DefineName, &mGuidList[Index].Guid); + } + // + // Close the output file if they specified one. + // + if (OutFileName != NULL) { + fclose (OutFptr); + } + + return STATUS_SUCCESS; +} + +void +PrintGuidText ( + FILE *OutFptr, + INT8 *VariableName, + INT8 *DefineName, + EFI_GUID *Guid + ) +/*++ + +Routine Description: + Print a GUID/name combo in INF-style format + + guid-guid-guid-guid DEFINE_NAME gName + +Arguments: + OutFptr - file pointer to which to write the output + VariableName - the GUID variable's name + DefineName - the name used in the #define + Guid - pointer to the GUID value + +Returns: + NA + +--*/ +{ + if (OutFptr == NULL) { + OutFptr = stdout; + } + + fprintf ( + OutFptr, + "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X %s %s\n", + Guid->Data1, + Guid->Data2, + Guid->Data3, + Guid->Data4[0], + Guid->Data4[1], + Guid->Data4[2], + Guid->Data4[3], + Guid->Data4[4], + Guid->Data4[5], + Guid->Data4[6], + Guid->Data4[7], + DefineName, + VariableName + ); +} diff --git a/Tools/CodeTools/Source/GuidChk/UtilsMsgs.c b/Tools/CodeTools/Source/GuidChk/UtilsMsgs.c new file mode 100644 index 0000000000..8aa343fc19 --- /dev/null +++ b/Tools/CodeTools/Source/GuidChk/UtilsMsgs.c @@ -0,0 +1,490 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + UtilsMsgs.c + +Abstract: + + EFI tools utility functions to display warning, error, and informational + messages. + +--*/ + +#include +#include +#include +#include + +#include + +#include "EfiUtilityMsgs.h" + +#define MAX_LINE_LEN 200 + +// +// Declare module globals for keeping track of the the utility's +// name and other settings. +// +static STATUS mStatus = STATUS_SUCCESS; +static INT8 mUtilityName[50] = { 0 }; +static INT8 *mSourceFileName = NULL; +static UINT32 mSourceFileLineNum = 0; +static UINT32 mErrorCount = 0; +static UINT32 mWarningCount = 0; +static UINT32 mDebugMsgMask = 0; + +static +void +PrintMessage ( + INT8 *Type, + INT8 *FileName, + UINT32 LineNumber, + UINT32 MessageCode, + INT8 *Text, + INT8 *MsgFmt, + va_list List + ); + +void +Error ( + INT8 *FileName, + UINT32 LineNumber, + UINT32 MessageCode, + INT8 *Text, + INT8 *MsgFmt, + ... + ) +/*++ + +Routine Description: + Prints an error message. + +Arguments: + All arguments are optional, though the printed message may be useless if + at least something valid is not specified. + + FileName - name of the file or application. If not specified, then the + utilty name (as set by the utility calling SetUtilityName() + earlier) is used. Otherwise "Unknown utility" is used. + + LineNumber - the line number of error, typically used by parsers. If the + utility is not a parser, then 0 should be specified. Otherwise + the FileName and LineNumber info can be used to cause + MS Visual Studio to jump to the error. + + MessageCode - an application-specific error code that can be referenced in + other documentation. + + Text - the text in question, typically used by parsers. + + MsgFmt - the format string for the error message. Can contain formatting + controls for use with the varargs. + +Returns: + None. + +Notes: + We print the following (similar to the Warn() and Debug() + W + Typical error/warning message format: + + bin\VfrCompile.cpp(330) : error C2660: 'AddVfrDataStructField' : function does not take 2 parameters + + BUGBUG -- these three utility functions are almost identical, and + should be modified to share code. + + Visual Studio does not find error messages with: + + " error :" + " error 1:" + " error c1:" + " error 1000:" + " error c100:" + + It does find: + " error c1000:" +--*/ +{ + va_list List; + mErrorCount++; + va_start (List, MsgFmt); + PrintMessage ("error", FileName, LineNumber, MessageCode, Text, MsgFmt, List); + va_end (List); + // + // Set status accordingly + // + if (mStatus < STATUS_ERROR) { + mStatus = STATUS_ERROR; + } +} + +void +ParserError ( + UINT32 MessageCode, + INT8 *Text, + INT8 *MsgFmt, + ... + ) +/*++ + +Routine Description: + Print a parser error, using the source file name and line number + set by a previous call to SetParserPosition(). + +Arguments: + MessageCode - application-specific error code + Text - text to print in the error message + MsgFmt - format string to print at the end of the error message + ... + +Returns: + NA + +--*/ +{ + va_list List; + mErrorCount++; + va_start (List, MsgFmt); + PrintMessage ("error", mSourceFileName, mSourceFileLineNum, MessageCode, Text, MsgFmt, List); + va_end (List); + // + // Set status accordingly + // + if (mStatus < STATUS_ERROR) { + mStatus = STATUS_ERROR; + } +} + +void +ParserWarning ( + UINT32 ErrorCode, + INT8 *OffendingText, + INT8 *MsgFmt, + ... + ) +/*++ + +Routine Description: + Print a parser warning, using the source file name and line number + set by a previous call to SetParserPosition(). + +Arguments: + ErrorCode - application-specific error code + OffendingText - text to print in the warning message + MsgFmt - format string to print at the end of the warning message + ... + +Returns: + NA + +--*/ +{ + va_list List; + mWarningCount++; + va_start (List, MsgFmt); + PrintMessage ("warning", mSourceFileName, mSourceFileLineNum, ErrorCode, OffendingText, MsgFmt, List); + va_end (List); + // + // Set status accordingly + // + if (mStatus < STATUS_WARNING) { + mStatus = STATUS_WARNING; + } +} + +void +Warning ( + INT8 *FileName, + UINT32 LineNumber, + UINT32 MessageCode, + INT8 *Text, + INT8 *MsgFmt, + ... + ) +/*++ + +Routine Description: + Print a warning message. + +Arguments: + FileName - name of the file where the warning was detected, or the name + of the application that detected the warning + + LineNumber - the line number where the warning was detected (parsers). + 0 should be specified if the utility is not a parser. + + MessageCode - an application-specific warning code that can be referenced in + other documentation. + + Text - the text in question (parsers) + + MsgFmt - the format string for the warning message. Can contain formatting + controls for use with varargs. + + ... + +Returns: + None. + +--*/ +{ + va_list List; + mWarningCount++; + va_start (List, MsgFmt); + PrintMessage ("warning", FileName, LineNumber, MessageCode, Text, MsgFmt, List); + va_end (List); + // + // Set status accordingly + // + if (mStatus < STATUS_WARNING) { + mStatus = STATUS_WARNING; + } +} + +void +DebugMsg ( + INT8 *FileName, + UINT32 LineNumber, + UINT32 MsgMask, + INT8 *Text, + INT8 *MsgFmt, + ... + ) +/*++ + +Routine Description: + Print a warning message. + +Arguments: + FileName - typically the name of the utility printing the debug message, but + can be the name of a file being parsed. + + LineNumber - the line number in FileName (parsers) + + MsgMask - an application-specific bitmask that, in combination with mDebugMsgMask, + determines if the debug message gets printed. + + Text - the text in question (parsers) + + MsgFmt - the format string for the debug message. Can contain formatting + controls for use with varargs. + + ... +Returns: + None. + +--*/ +{ + va_list List; + // + // If the debug mask is not applicable, then do nothing. + // + if ((MsgMask != 0) && ((mDebugMsgMask & MsgMask) == 0)) { + return ; + } + + va_start (List, MsgFmt); + PrintMessage ("debug", FileName, LineNumber, 0, Text, MsgFmt, List); + va_end (List); +} + +static +void +PrintMessage ( + INT8 *Type, + INT8 *FileName, + UINT32 LineNumber, + UINT32 MessageCode, + INT8 *Text, + INT8 *MsgFmt, + va_list List + ) +/*++ + +Routine Description: + Worker routine for all the utility printing services. Prints the message in + a format that Visual Studio will find when scanning build outputs for + errors or warnings. + +Arguments: + Type - "warning" or "error" string to insert into the message to be + printed. The first character of this string (converted to uppercase) + is used to preceed the MessageCode value in the output string. + + FileName - name of the file where the warning was detected, or the name + of the application that detected the warning + + LineNumber - the line number where the warning was detected (parsers). + 0 should be specified if the utility is not a parser. + + MessageCode - an application-specific warning code that can be referenced in + other documentation. + + Text - part of the message to print + + MsgFmt - the format string for the message. Can contain formatting + controls for use with varargs. + + List - Variable function parameter list. +Returns: + None. + +Notes: + If FileName == NULL then this utility will use the string passed into SetUtilityName(). + + LineNumber is only used if the caller is a parser, in which case FileName refers to the + file being parsed. + + Text and MsgFmt are both optional, though it would be of little use calling this function with + them both NULL. + + Output will typically be of the form: + () : : : + + Parser (LineNumber != 0) + VfrCompile.cpp(330) : error E2660: AddVfrDataStructField : function does not take 2 parameters + Generic utility (LineNumber == 0) + UtilityName : error E1234 : Text string : MsgFmt string and args + +--*/ +{ + INT8 Line[MAX_LINE_LEN]; + INT8 Line2[MAX_LINE_LEN]; + INT8 *Cptr; + // + // If given a filename, then add it (and the line number) to the string. + // If there's no filename, then use the program name if provided. + // + if (FileName != NULL) { + Cptr = FileName; + } else if (mUtilityName[0] != 0) { + Cptr = mUtilityName; + } else { + Cptr = "Unknown utility"; + } + + strcpy (Line, Cptr); + if (LineNumber != 0) { + sprintf (Line2, "(%d)", LineNumber); + strcat (Line, Line2); + } + // + // Have to print an error code or Visual Studio won't find the + // message for you. It has to be decimal digits too. + // + sprintf (Line2, " : %s %c%04d", Type, toupper (Type[0]), MessageCode); + strcat (Line, Line2); + fprintf (stdout, "%s", Line); + // + // If offending text was provided, then print it + // + if (Text != NULL) { + fprintf (stdout, ": %s ", Text); + } + // + // Print formatted message if provided + // + if (MsgFmt != NULL) { + vsprintf (Line2, MsgFmt, List); + fprintf (stdout, ": %s", Line2); + } + + fprintf (stdout, "\n"); +} + +void +ParserSetPosition ( + INT8 *SourceFileName, + UINT32 LineNum + ) +/*++ + +Routine Description: + Set the position in a file being parsed. This can be used to + print error messages deeper down in a parser. + +Arguments: + SourceFileName - name of the source file being parsed + LineNum - line number of the source file being parsed + +Returns: + NA + +--*/ +{ + mSourceFileName = SourceFileName; + mSourceFileLineNum = LineNum; +} + +void +SetUtilityName ( + INT8 *UtilityName + ) +/*++ + +Routine Description: + All printed error/warning/debug messages follow the same format, and + typically will print a filename or utility name followed by the error + text. However if a filename is not passed to the print routines, then + they'll print the utility name if you call this function early in your + app to set the utility name. + +Arguments: + UtilityName - name of the utility, which will be printed with all + error/warning/debug messags. + +Returns: + NA + +--*/ +{ + // + // Save the name of the utility in our local variable. Make sure its + // length does not exceed our buffer. + // + if (UtilityName != NULL) { + if (strlen (UtilityName) >= sizeof (mUtilityName)) { + Error (UtilityName, 0, 0, "application error", "utility name length exceeds internal buffer size"); + strncpy (mUtilityName, UtilityName, sizeof (mUtilityName) - 1); + mUtilityName[sizeof (mUtilityName) - 1] = 0; + return ; + } else { + strcpy (mUtilityName, UtilityName); + } + } else { + Error (NULL, 0, 0, "application error", "SetUtilityName() called with NULL utility name"); + } +} + +STATUS +GetUtilityStatus ( + VOID + ) +/*++ + +Routine Description: + When you call Error() or Warning(), this module keeps track of it and + sets a local mStatus to STATUS_ERROR or STATUS_WARNING. When the utility + exits, it can call this function to get the status and use it as a return + value. + +Arguments: + None. + +Returns: + Worst-case status reported, as defined by which print function was called. + +--*/ +{ + return mStatus; +} diff --git a/Tools/CodeTools/Source/GuidChk/UtilsMsgs.h b/Tools/CodeTools/Source/GuidChk/UtilsMsgs.h new file mode 100644 index 0000000000..5f6c7010b4 --- /dev/null +++ b/Tools/CodeTools/Source/GuidChk/UtilsMsgs.h @@ -0,0 +1,106 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + UtilsMsgs.h + +Abstract: + + Prototypes for the EFI tools utility functions. + +--*/ + +#ifndef _UTILS_MESSAGES_H_ +#define _UTILS_MESSAGES_H_ + +STATUS +GetUtilityStatus ( + VOID + ) +; + +// +// If someone prints an error message and didn't specify a source file name, +// then we print the utility name instead. However they must tell us the +// utility name early on via this function. +// +VOID +SetUtilityName ( + INT8 *ProgramName + ) +; + +void +Error ( + INT8 *FileName, + UINT32 LineNumber, + UINT32 ErrorCode, + INT8 *OffendingText, + INT8 *MsgFmt, + ... + ) +; + +void +Warning ( + INT8 *FileName, + UINT32 LineNumber, + UINT32 ErrorCode, + INT8 *OffendingText, + INT8 *MsgFmt, + ... + ) +; + +void +DebugMsg ( + INT8 *FileName, + UINT32 LineNumber, + UINT32 MsgLevel, + INT8 *OffendingText, + INT8 *MsgFmt, + ... + ) +; + +void +SetDebugMsgMask ( + UINT32 MsgMask + ) +; + +void +ParserSetPosition ( + INT8 *SourceFileName, + UINT32 LineNum + ) +; + +void +ParserError ( + UINT32 ErrorCode, + INT8 *OffendingText, + INT8 *MsgFmt, + ... + ) +; + +void +ParserWarning ( + UINT32 ErrorCode, + INT8 *OffendingText, + INT8 *MsgFmt, + ... + ) +; + +#endif diff --git a/Tools/CodeTools/Source/GuidChk/build.xml b/Tools/CodeTools/Source/GuidChk/build.xml new file mode 100644 index 0000000000..aec3ad1e9c --- /dev/null +++ b/Tools/CodeTools/Source/GuidChk/build.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/Include/Common/BaseTypes.h b/Tools/CodeTools/Source/Include/Common/BaseTypes.h new file mode 100644 index 0000000000..b87e7141e6 --- /dev/null +++ b/Tools/CodeTools/Source/Include/Common/BaseTypes.h @@ -0,0 +1,212 @@ +/** @file + Processor or Compiler specific defines for all supported processors. + + This file is stand alone self consistent set of definitions. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: BaseTypes.h + +**/ + +#ifndef __BASE_TYPES_H__ +#define __BASE_TYPES_H__ + +// +// Include processor specific binding +// +#include +#include + +#define MEMORY_FENCE() MemoryFence () +#define BREAKPOINT() CpuBreakpoint () +#define DEADLOOP() CpuDeadLoop () + +typedef struct { + UINT32 Data1; + UINT16 Data2; + UINT16 Data3; + UINT8 Data4[8]; +} GUID; + + +// +// Modifiers to absract standard types to aid in debug of problems +// +#define CONST const +#define STATIC static +#define VOID void + +// +// Modifiers for Data Types used to self document code. +// This concept is borrowed for UEFI specification. +// +#ifndef IN +// +// Some other envirnments use this construct, so #ifndef to prevent +// mulitple definition. +// +#define IN +#define OUT +#define OPTIONAL +#endif + +// +// Constants. They may exist in other build structures, so #ifndef them. +// +#ifndef TRUE +// +// BugBug: UEFI specification claims 1 and 0. We are concerned about the +// complier portability so we did it this way. +// +#define TRUE ((BOOLEAN)(1==1)) +#endif + +#ifndef FALSE +#define FALSE ((BOOLEAN)(0==1)) +#endif + +#ifndef NULL +#define NULL ((VOID *) 0) +#endif + +// +// Support for variable length argument lists using the ANSI standard. +// +// Since we are using the ANSI standard we used the standard nameing and +// did not folow the coding convention +// +// VA_LIST - typedef for argument list. +// VA_START (VA_LIST Marker, argument before the ...) - Init Marker for use. +// VA_END (VA_LIST Marker) - Clear Marker +// VA_ARG (VA_LIST Marker, var arg size) - Use Marker to get an argumnet from +// the ... list. You must know the size and pass it in this macro. +// +// example: +// +// UINTN +// ExampleVarArg ( +// IN UINTN NumberOfArgs, +// ... +// ) +// { +// VA_LIST Marker; +// UINTN Index; +// UINTN Result; +// +// // +// // Initialize the Marker +// // +// VA_START (Marker, NumberOfArgs); +// for (Index = 0, Result = 0; Index < NumberOfArgs; Index++) { +// // +// // The ... list is a series of UINTN values, so average them up. +// // +// Result += VA_ARG (Marker, UINTN); +// } +// +// VA_END (Marker); +// return Result +// } +// + +#define _INT_SIZE_OF(n) ((sizeof (n) + sizeof (UINTN) - 1) &~(sizeof (UINTN) - 1)) + +// +// Also support coding convention rules for var arg macros +// +#ifndef VA_START + +// typedef CHAR8 *VA_LIST; +// #define VA_START(ap, v) (ap = (VA_LIST) & (v) + _INT_SIZE_OF (v)) +// #define VA_ARG(ap, t) (*(t *) ((ap += _INT_SIZE_OF (t)) - _INT_SIZE_OF (t))) +// #define VA_END(ap) (ap = (VA_LIST) 0) +// Use the native arguments for tools. +#define VA_START va_start +#define VA_ARG va_arg +#define VA_END va_end +#define VA_LIST va_list + +#endif + +/// +/// CONTAINING_RECORD - returns a pointer to the structure +/// from one of it's elements. +/// +#define _CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field))) + +/// +/// ALIGN_POINTER - aligns a pointer to the lowest boundry +/// +#define ALIGN_POINTER(p, s) ((VOID *) ((p) + (((s) - ((UINTN) (p))) & ((s) - 1)))) + +/// +/// ALIGN_VARIABLE - aligns a variable up to the next natural boundry for int size of a processor +/// +#define ALIGN_VARIABLE(Value, Adjustment) \ + Adjustment = 0U; \ + if ((UINTN) (Value) % sizeof (UINTN)) { \ + (Adjustment) = (UINTN)(sizeof (UINTN) - ((UINTN) (Value) % sizeof (UINTN))); \ + } \ + (Value) = (UINTN)((UINTN) (Value) + (UINTN) (Adjustment)) + +// +// EFI Error Codes common to all execution phases +// + +typedef INTN RETURN_STATUS; + +/// +/// Set the upper bit to indicate EFI Error. +/// +#define ENCODE_ERROR(a) (MAX_BIT | (a)) + +#define ENCODE_WARNING(a) (a) +#define RETURN_ERROR(a) ((a) < 0) + +#define RETURN_SUCCESS 0 +#define RETURN_LOAD_ERROR ENCODE_ERROR (1) +#define RETURN_INVALID_PARAMETER ENCODE_ERROR (2) +#define RETURN_UNSUPPORTED ENCODE_ERROR (3) +#define RETURN_BAD_BUFFER_SIZE ENCODE_ERROR (4) +#define RETURN_BUFFER_TOO_SMALL ENCODE_ERROR (5) +#define RETURN_NOT_READY ENCODE_ERROR (6) +#define RETURN_DEVICE_ERROR ENCODE_ERROR (7) +#define RETURN_WRITE_PROTECTED ENCODE_ERROR (8) +#define RETURN_OUT_OF_RESOURCES ENCODE_ERROR (9) +#define RETURN_VOLUME_CORRUPTED ENCODE_ERROR (10) +#define RETURN_VOLUME_FULL ENCODE_ERROR (11) +#define RETURN_NO_MEDIA ENCODE_ERROR (12) +#define RETURN_MEDIA_CHANGED ENCODE_ERROR (13) +#define RETURN_NOT_FOUND ENCODE_ERROR (14) +#define RETURN_ACCESS_DENIED ENCODE_ERROR (15) +#define RETURN_NO_RESPONSE ENCODE_ERROR (16) +#define RETURN_NO_MAPPING ENCODE_ERROR (17) +#define RETURN_TIMEOUT ENCODE_ERROR (18) +#define RETURN_NOT_STARTED ENCODE_ERROR (19) +#define RETURN_ALREADY_STARTED ENCODE_ERROR (20) +#define RETURN_ABORTED ENCODE_ERROR (21) +#define RETURN_ICMP_ERROR ENCODE_ERROR (22) +#define RETURN_TFTP_ERROR ENCODE_ERROR (23) +#define RETURN_PROTOCOL_ERROR ENCODE_ERROR (24) +#define RETURN_INCOMPATIBLE_VERSION ENCODE_ERROR (25) +#define RETURN_SECURITY_VIOLATION ENCODE_ERROR (26) +#define RETURN_CRC_ERROR ENCODE_ERROR (27) +#define RETURN_END_OF_MEDIA ENCODE_ERROR (28) +#define RETURN_END_OF_FILE ENCODE_ERROR (31) + +#define RETURN_WARN_UNKNOWN_GLYPH ENCODE_WARNING (1) +#define RETURN_WARN_DELETE_FAILURE ENCODE_WARNING (2) +#define RETURN_WARN_WRITE_FAILURE ENCODE_WARNING (3) +#define RETURN_WARN_BUFFER_TOO_SMALL ENCODE_WARNING (4) + +typedef UINT64 PHYSICAL_ADDRESS; + +#endif diff --git a/Tools/CodeTools/Source/Include/Common/Capsule.h b/Tools/CodeTools/Source/Include/Common/Capsule.h new file mode 100644 index 0000000000..0434fdf7f2 --- /dev/null +++ b/Tools/CodeTools/Source/Include/Common/Capsule.h @@ -0,0 +1,67 @@ +/** @file + Defines for the EFI Capsule functionality. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: Capsule.h + + @par Revision Reference: + These definitions are from Capsule Spec Version 0.9. + +**/ + +#ifndef _EFI_CAPSULE_H_ +#define _EFI_CAPSULE_H_ + +// +// Bits in the flags field of the capsule header +// +#define EFI_CAPSULE_HEADER_FLAG_SETUP 0x00000001 // supports setup changes + + +#define CAPSULE_BLOCK_DESCRIPTOR_SIGNATURE EFI_SIGNATURE_32 ('C', 'B', 'D', 'S') + +// +// An array of these describe the blocks that make up a capsule for +// a capsule update. +// +typedef struct { + UINT64 Length; // length of the data block + EFI_PHYSICAL_ADDRESS Data; // physical address of the data block + UINT32 Signature; // CBDS + UINT32 CheckSum; // to sum this structure to 0 +} EFI_CAPSULE_BLOCK_DESCRIPTOR; + +typedef struct { + EFI_GUID OemGuid; + UINT32 HeaderSize; + // + // UINT8 OemHdrData[]; + // +} EFI_CAPSULE_OEM_HEADER; + +typedef struct { + EFI_GUID CapsuleGuid; + UINT32 HeaderSize; + UINT32 Flags; + UINT32 CapsuleImageSize; + UINT32 SequenceNumber; + EFI_GUID InstanceId; + UINT32 OffsetToSplitInformation; + UINT32 OffsetToCapsuleBody; + UINT32 OffsetToOemDefinedHeader; + UINT32 OffsetToAuthorInformation; + UINT32 OffsetToRevisionInformation; + UINT32 OffsetToShortDescription; + UINT32 OffsetToLongDescription; + UINT32 OffsetToApplicableDevices; +} EFI_CAPSULE_HEADER; + +#endif // #ifndef _EFI_CAPSULE_H_ diff --git a/Tools/CodeTools/Source/Include/Common/Dependency.h b/Tools/CodeTools/Source/Include/Common/Dependency.h new file mode 100644 index 0000000000..744027d2f3 --- /dev/null +++ b/Tools/CodeTools/Source/Include/Common/Dependency.h @@ -0,0 +1,50 @@ +/** @file + This module contains data specific to dependency expressions + and local function prototypes. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: Dependency.h + +**/ + +#ifndef __DEPENDENCY_H__ +#define __DEPENDENCY_H__ + +/// EFI_DEP_BEFORE - If present, this must be the first and only opcode +#define EFI_DEP_BEFORE 0x00 + +/// EFI_DEP_AFTER - If present, this must be the first and only opcode +#define EFI_DEP_AFTER 0x01 + +#define EFI_DEP_PUSH 0x02 +#define EFI_DEP_AND 0x03 +#define EFI_DEP_OR 0x04 +#define EFI_DEP_NOT 0x05 +#define EFI_DEP_TRUE 0x06 +#define EFI_DEP_FALSE 0x07 +#define EFI_DEP_END 0x08 + +/// EFI_DEP_SOR - If present, this must be the first opcode +#define EFI_DEP_SOR 0x09 + +/// +/// EFI_DEP_REPLACE_TRUE - Used to dynamically patch the dependecy expression +/// to save time. A EFI_DEP_PUSH is evauated one an +/// replaced with EFI_DEP_REPLACE_TRUE +/// +#define EFI_DEP_REPLACE_TRUE 0xff + +/// +/// Define the initial size of the dependency expression evaluation stack +/// +#define DEPEX_STACK_SIZE_INCREMENT 0x1000 + +#endif diff --git a/Tools/CodeTools/Source/Include/Common/EfiImage.h b/Tools/CodeTools/Source/Include/Common/EfiImage.h new file mode 100644 index 0000000000..2f5c580e98 --- /dev/null +++ b/Tools/CodeTools/Source/Include/Common/EfiImage.h @@ -0,0 +1,716 @@ +/** @file + EFI image format for PE32+. Please note some data structures are different + for IA-32 and Itanium-based images, look for UINTN and the #ifdef EFI_IA64 + + @bug Fix text - doc as defined in MSFT EFI specification. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: EfiImage.h + +**/ + +#ifndef __EFI_IMAGE_H__ +#define __EFI_IMAGE_H__ + +// +// PE32+ Subsystem type for EFI images +// +#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION 10 +#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 +#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 +#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13 + +// +// BugBug: Need to get a real answer for this problem. This is not in the +// PE specification. +// +// A SAL runtime driver does not get fixed up when a transition to +// virtual mode is made. In all other cases it should be treated +// like a EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER image +// +#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13 + +// +// PE32+ Machine type for EFI images +// +#define IMAGE_FILE_MACHINE_I386 0x014c +#define IMAGE_FILE_MACHINE_IA64 0x0200 +#define IMAGE_FILE_MACHINE_EBC 0x0EBC +#define IMAGE_FILE_MACHINE_X64 0x8664 +// +// Support old names for backward compatible +// +#define EFI_IMAGE_MACHINE_IA32 IMAGE_FILE_MACHINE_I386 +#define EFI_IMAGE_MACHINE_IA64 IMAGE_FILE_MACHINE_IA64 +#define EFI_IMAGE_MACHINE_IPF IMAGE_FILE_MACHINE_IA64 +#define EFI_IMAGE_MACHINE_EBC IMAGE_FILE_MACHINE_EBC +#define EFI_IMAGE_MACHINE_X64 IMAGE_FILE_MACHINE_X64 + +#define EFI_IMAGE_DOS_SIGNATURE 0x5A4D // MZ +#define EFI_IMAGE_OS2_SIGNATURE 0x454E // NE +#define EFI_IMAGE_OS2_SIGNATURE_LE 0x454C // LE +#define EFI_IMAGE_NT_SIGNATURE 0x00004550 // PE00 +#define EFI_IMAGE_EDOS_SIGNATURE 0x44454550 // PEED + +/// +/// PE images can start with an optional DOS header, so if an image is run +/// under DOS it can print an error message. +/// +typedef struct { + UINT16 e_magic; // Magic number + UINT16 e_cblp; // Bytes on last page of file + UINT16 e_cp; // Pages in file + UINT16 e_crlc; // Relocations + UINT16 e_cparhdr; // Size of header in paragraphs + UINT16 e_minalloc; // Minimum extra paragraphs needed + UINT16 e_maxalloc; // Maximum extra paragraphs needed + UINT16 e_ss; // Initial (relative) SS value + UINT16 e_sp; // Initial SP value + UINT16 e_csum; // Checksum + UINT16 e_ip; // Initial IP value + UINT16 e_cs; // Initial (relative) CS value + UINT16 e_lfarlc; // File address of relocation table + UINT16 e_ovno; // Overlay number + UINT16 e_res[4]; // Reserved words + UINT16 e_oemid; // OEM identifier (for e_oeminfo) + UINT16 e_oeminfo; // OEM information; e_oemid specific + UINT16 e_res2[10]; // Reserved words + UINT32 e_lfanew; // File address of new exe header +} EFI_IMAGE_DOS_HEADER; + +/// +/// File header format. +/// +typedef struct { + UINT16 Machine; + UINT16 NumberOfSections; + UINT32 TimeDateStamp; + UINT32 PointerToSymbolTable; + UINT32 NumberOfSymbols; + UINT16 SizeOfOptionalHeader; + UINT16 Characteristics; +} EFI_IMAGE_FILE_HEADER; + +#define EFI_IMAGE_SIZEOF_FILE_HEADER 20 + +#define EFI_IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file. +#define EFI_IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references). +#define EFI_IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file. +#define EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file. +#define EFI_IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed. +#define EFI_IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine. +#define EFI_IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file +#define EFI_IMAGE_FILE_SYSTEM 0x1000 // System File. +#define EFI_IMAGE_FILE_DLL 0x2000 // File is a DLL. +#define EFI_IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed. +#define EFI_IMAGE_FILE_MACHINE_UNKNOWN 0 +#define EFI_IMAGE_FILE_MACHINE_I386 0x14c // Intel 386. +#define EFI_IMAGE_FILE_MACHINE_R3000 0x162 // MIPS* little-endian, 0540 big-endian +#define EFI_IMAGE_FILE_MACHINE_R4000 0x166 // MIPS* little-endian +#define EFI_IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP* +#define EFI_IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM* PowerPC Little-Endian +#define EFI_IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine +// +// * Other names and brands may be claimed as the property of others. +// + +/// +/// Directory format. +/// +typedef struct { + UINT32 VirtualAddress; + UINT32 Size; +} EFI_IMAGE_DATA_DIRECTORY; + +#define EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16 + +typedef struct { + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + UINT32 BaseOfData; + UINT32 BaseOfBss; + UINT32 GprMask; + UINT32 CprMask[4]; + UINT32 GpValue; +} EFI_IMAGE_ROM_OPTIONAL_HEADER; + +#define EFI_IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 +#define EFI_IMAGE_SIZEOF_ROM_OPTIONAL_HEADER sizeof (EFI_IMAGE_ROM_OPTIONAL_HEADER) + +typedef struct { + EFI_IMAGE_FILE_HEADER FileHeader; + EFI_IMAGE_ROM_OPTIONAL_HEADER OptionalHeader; +} EFI_IMAGE_ROM_HEADERS; + +/// +/// @attention +/// EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64 +/// are for use ONLY by tools. All proper EFI code MUST use +/// EFI_IMAGE_OPTIONAL_HEADER ONLY!!! +/// +#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b + +typedef struct { + // + // Standard fields. + // + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + UINT32 BaseOfData; + // + // NT additional fields. + // + UINT32 ImageBase; + UINT32 SectionAlignment; + UINT32 FileAlignment; + UINT16 MajorOperatingSystemVersion; + UINT16 MinorOperatingSystemVersion; + UINT16 MajorImageVersion; + UINT16 MinorImageVersion; + UINT16 MajorSubsystemVersion; + UINT16 MinorSubsystemVersion; + UINT32 Win32VersionValue; + UINT32 SizeOfImage; + UINT32 SizeOfHeaders; + UINT32 CheckSum; + UINT16 Subsystem; + UINT16 DllCharacteristics; + UINT32 SizeOfStackReserve; + UINT32 SizeOfStackCommit; + UINT32 SizeOfHeapReserve; + UINT32 SizeOfHeapCommit; + UINT32 LoaderFlags; + UINT32 NumberOfRvaAndSizes; + EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES]; +} EFI_IMAGE_OPTIONAL_HEADER32; + +/// +/// @attention +/// EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64 +/// are for use ONLY by tools. All proper EFI code MUST use +/// EFI_IMAGE_OPTIONAL_HEADER ONLY!!! +/// +#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b + +typedef struct { + // + // Standard fields. + // + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + // + // NT additional fields. + // + UINT64 ImageBase; + UINT32 SectionAlignment; + UINT32 FileAlignment; + UINT16 MajorOperatingSystemVersion; + UINT16 MinorOperatingSystemVersion; + UINT16 MajorImageVersion; + UINT16 MinorImageVersion; + UINT16 MajorSubsystemVersion; + UINT16 MinorSubsystemVersion; + UINT32 Win32VersionValue; + UINT32 SizeOfImage; + UINT32 SizeOfHeaders; + UINT32 CheckSum; + UINT16 Subsystem; + UINT16 DllCharacteristics; + UINT64 SizeOfStackReserve; + UINT64 SizeOfStackCommit; + UINT64 SizeOfHeapReserve; + UINT64 SizeOfHeapCommit; + UINT32 LoaderFlags; + UINT32 NumberOfRvaAndSizes; + EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES]; +} EFI_IMAGE_OPTIONAL_HEADER64; + +/// +/// @attention +/// EFI_IMAGE_NT_HEADERS32 and EFI_IMAGE_HEADERS64 are for use ONLY +/// by tools. All proper EFI code MUST use EFI_IMAGE_NT_HEADERS ONLY!!! +/// +typedef struct { + UINT32 Signature; + EFI_IMAGE_FILE_HEADER FileHeader; + EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader; +} EFI_IMAGE_NT_HEADERS32; + +#define EFI_IMAGE_SIZEOF_NT_OPTIONAL32_HEADER sizeof (EFI_IMAGE_NT_HEADERS32) + +typedef struct { + UINT32 Signature; + EFI_IMAGE_FILE_HEADER FileHeader; + EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader; +} EFI_IMAGE_NT_HEADERS64; + +#define EFI_IMAGE_SIZEOF_NT_OPTIONAL64_HEADER sizeof (EFI_IMAGE_NT_HEADERS64) + +// +// Processor specific definition of EFI_IMAGE_OPTIONAL_HEADER so the +// type name EFI_IMAGE_OPTIONAL_HEADER is appropriate to the build. Same for +// EFI_IMAGE_NT_HEADERS. These definitions MUST be used by ALL EFI code. +// +#if defined (MDE_CPU_IA32) + +typedef EFI_IMAGE_OPTIONAL_HEADER32 EFI_IMAGE_OPTIONAL_HEADER; +typedef EFI_IMAGE_NT_HEADERS32 EFI_IMAGE_NT_HEADERS; + +#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC +#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \ + (((Machine) == EFI_IMAGE_MACHINE_IA32) || ((Machine) == EFI_IMAGE_MACHINE_EBC)) + +#elif defined (MDE_CPU_IPF) + +typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER; +typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS; + +#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC +#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \ + (((Machine) == EFI_IMAGE_MACHINE_IPF) || ((Machine) == EFI_IMAGE_MACHINE_EBC)) + +#elif defined (MDE_CPU_X64) + +typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER; +typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS; + +#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC +#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \ + (((Machine) == EFI_IMAGE_MACHINE_X64) || ((Machine) == EFI_IMAGE_MACHINE_EBC)) + +#elif defined (MDE_CPU_EBC) + +// +// This is just to make sure you can cross compile with the EBC compiiler. +// It does not make sense to have a PE loader coded in EBC. You need to +// understand the basic +// +typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER; +typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS; + +#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC +#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_EBC) + +#else +#error Unknown Processor Type +#endif + + +#define EFI_IMAGE_FIRST_SECTION(ntheader) \ + ( \ + (EFI_IMAGE_SECTION_HEADER *) \ + ( \ + (UINT32) ntheader + \ + FIELD_OFFSET (EFI_IMAGE_NT_HEADERS, OptionalHeader) + \ + ((EFI_IMAGE_NT_HEADERS *) (ntheader))->FileHeader.SizeOfOptionalHeader \ + ) \ + ) + +// +// Subsystem Values +// +#define EFI_IMAGE_SUBSYSTEM_UNKNOWN 0 +#define EFI_IMAGE_SUBSYSTEM_NATIVE 1 +#define EFI_IMAGE_SUBSYSTEM_WINDOWS_GUI 2 +#define EFI_IMAGE_SUBSYSTEM_WINDOWS_CUI 3. +#define EFI_IMAGE_SUBSYSTEM_OS2_CUI 5 +#define EFI_IMAGE_SUBSYSTEM_POSIX_CUI 7 + +// +// Directory Entries +// +#define EFI_IMAGE_DIRECTORY_ENTRY_EXPORT 0 +#define EFI_IMAGE_DIRECTORY_ENTRY_IMPORT 1 +#define EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE 2 +#define EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 +#define EFI_IMAGE_DIRECTORY_ENTRY_SECURITY 4 +#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC 5 +#define EFI_IMAGE_DIRECTORY_ENTRY_DEBUG 6 +#define EFI_IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 +#define EFI_IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 +#define EFI_IMAGE_DIRECTORY_ENTRY_TLS 9 +#define EFI_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 + +// +// Section header format. +// +#define EFI_IMAGE_SIZEOF_SHORT_NAME 8 + +typedef struct { + UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME]; + union { + UINT32 PhysicalAddress; + UINT32 VirtualSize; + } Misc; + UINT32 VirtualAddress; + UINT32 SizeOfRawData; + UINT32 PointerToRawData; + UINT32 PointerToRelocations; + UINT32 PointerToLinenumbers; + UINT16 NumberOfRelocations; + UINT16 NumberOfLinenumbers; + UINT32 Characteristics; +} EFI_IMAGE_SECTION_HEADER; + +#define EFI_IMAGE_SIZEOF_SECTION_HEADER 40 + +#define EFI_IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved. +#define EFI_IMAGE_SCN_CNT_CODE 0x00000020 +#define EFI_IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 +#define EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 + +#define EFI_IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved. +#define EFI_IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information. +#define EFI_IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image. +#define EFI_IMAGE_SCN_LNK_COMDAT 0x00001000 + +#define EFI_IMAGE_SCN_ALIGN_1BYTES 0x00100000 +#define EFI_IMAGE_SCN_ALIGN_2BYTES 0x00200000 +#define EFI_IMAGE_SCN_ALIGN_4BYTES 0x00300000 +#define EFI_IMAGE_SCN_ALIGN_8BYTES 0x00400000 +#define EFI_IMAGE_SCN_ALIGN_16BYTES 0x00500000 +#define EFI_IMAGE_SCN_ALIGN_32BYTES 0x00600000 +#define EFI_IMAGE_SCN_ALIGN_64BYTES 0x00700000 + +#define EFI_IMAGE_SCN_MEM_DISCARDABLE 0x02000000 +#define EFI_IMAGE_SCN_MEM_NOT_CACHED 0x04000000 +#define EFI_IMAGE_SCN_MEM_NOT_PAGED 0x08000000 +#define EFI_IMAGE_SCN_MEM_SHARED 0x10000000 +#define EFI_IMAGE_SCN_MEM_EXECUTE 0x20000000 +#define EFI_IMAGE_SCN_MEM_READ 0x40000000 +#define EFI_IMAGE_SCN_MEM_WRITE 0x80000000 + +/// +/// Symbol format. +/// +#define EFI_IMAGE_SIZEOF_SYMBOL 18 + +// +// Section values. +// +// Symbols have a section number of the section in which they are +// defined. Otherwise, section numbers have the following meanings: +// +#define EFI_IMAGE_SYM_UNDEFINED (UINT16) 0 // Symbol is undefined or is common. +#define EFI_IMAGE_SYM_ABSOLUTE (UINT16) -1 // Symbol is an absolute value. +#define EFI_IMAGE_SYM_DEBUG (UINT16) -2 // Symbol is a special debug item. +// +// Type (fundamental) values. +// +#define EFI_IMAGE_SYM_TYPE_NULL 0 // no type. +#define EFI_IMAGE_SYM_TYPE_VOID 1 // +#define EFI_IMAGE_SYM_TYPE_CHAR 2 // type character. +#define EFI_IMAGE_SYM_TYPE_SHORT 3 // type short integer. +#define EFI_IMAGE_SYM_TYPE_INT 4 +#define EFI_IMAGE_SYM_TYPE_LONG 5 +#define EFI_IMAGE_SYM_TYPE_FLOAT 6 +#define EFI_IMAGE_SYM_TYPE_DOUBLE 7 +#define EFI_IMAGE_SYM_TYPE_STRUCT 8 +#define EFI_IMAGE_SYM_TYPE_UNION 9 +#define EFI_IMAGE_SYM_TYPE_ENUM 10 // enumeration. +#define EFI_IMAGE_SYM_TYPE_MOE 11 // member of enumeration. +#define EFI_IMAGE_SYM_TYPE_BYTE 12 +#define EFI_IMAGE_SYM_TYPE_WORD 13 +#define EFI_IMAGE_SYM_TYPE_UINT 14 +#define EFI_IMAGE_SYM_TYPE_DWORD 15 + +// +// Type (derived) values. +// +#define EFI_IMAGE_SYM_DTYPE_NULL 0 // no derived type. +#define EFI_IMAGE_SYM_DTYPE_POINTER 1 +#define EFI_IMAGE_SYM_DTYPE_FUNCTION 2 +#define EFI_IMAGE_SYM_DTYPE_ARRAY 3 + +// +// Storage classes. +// +#define EFI_IMAGE_SYM_CLASS_END_OF_FUNCTION (UINT8) -1 +#define EFI_IMAGE_SYM_CLASS_NULL 0 +#define EFI_IMAGE_SYM_CLASS_AUTOMATIC 1 +#define EFI_IMAGE_SYM_CLASS_EXTERNAL 2 +#define EFI_IMAGE_SYM_CLASS_STATIC 3 +#define EFI_IMAGE_SYM_CLASS_REGISTER 4 +#define EFI_IMAGE_SYM_CLASS_EXTERNAL_DEF 5 +#define EFI_IMAGE_SYM_CLASS_LABEL 6 +#define EFI_IMAGE_SYM_CLASS_UNDEFINED_LABEL 7 +#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8 +#define EFI_IMAGE_SYM_CLASS_ARGUMENT 9 +#define EFI_IMAGE_SYM_CLASS_STRUCT_TAG 10 +#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_UNION 11 +#define EFI_IMAGE_SYM_CLASS_UNION_TAG 12 +#define EFI_IMAGE_SYM_CLASS_TYPE_DEFINITION 13 +#define EFI_IMAGE_SYM_CLASS_UNDEFINED_STATIC 14 +#define EFI_IMAGE_SYM_CLASS_ENUM_TAG 15 +#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16 +#define EFI_IMAGE_SYM_CLASS_REGISTER_PARAM 17 +#define EFI_IMAGE_SYM_CLASS_BIT_FIELD 18 +#define EFI_IMAGE_SYM_CLASS_BLOCK 100 +#define EFI_IMAGE_SYM_CLASS_FUNCTION 101 +#define EFI_IMAGE_SYM_CLASS_END_OF_STRUCT 102 +#define EFI_IMAGE_SYM_CLASS_FILE 103 +#define EFI_IMAGE_SYM_CLASS_SECTION 104 +#define EFI_IMAGE_SYM_CLASS_WEAK_EXTERNAL 105 + +// +// type packing constants +// +#define EFI_IMAGE_N_BTMASK 017 +#define EFI_IMAGE_N_TMASK 060 +#define EFI_IMAGE_N_TMASK1 0300 +#define EFI_IMAGE_N_TMASK2 0360 +#define EFI_IMAGE_N_BTSHFT 4 +#define EFI_IMAGE_N_TSHIFT 2 + +// +// Communal selection types. +// +#define EFI_IMAGE_COMDAT_SELECT_NODUPLICATES 1 +#define EFI_IMAGE_COMDAT_SELECT_ANY 2 +#define EFI_IMAGE_COMDAT_SELECT_SAME_SIZE 3 +#define EFI_IMAGE_COMDAT_SELECT_EXACT_MATCH 4 +#define EFI_IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 + +#define EFI_IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 +#define EFI_IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 +#define EFI_IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 + +/// +/// Relocation format. +/// +typedef struct { + UINT32 VirtualAddress; + UINT32 SymbolTableIndex; + UINT16 Type; +} EFI_IMAGE_RELOCATION; + +#define EFI_IMAGE_SIZEOF_RELOCATION 10 + +// +// I386 relocation types. +// +#define EFI_IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary +#define EFI_IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address +#define EFI_IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address +#define EFI_IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address +#define EFI_IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included +#define EFI_IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address +#define EFI_IMAGE_REL_I386_SECTION 012 +#define EFI_IMAGE_REL_I386_SECREL 013 +#define EFI_IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address + +/// +/// Based relocation format. +/// +typedef struct { + UINT32 VirtualAddress; + UINT32 SizeOfBlock; +} EFI_IMAGE_BASE_RELOCATION; + +#define EFI_IMAGE_SIZEOF_BASE_RELOCATION 8 + +// +// Based relocation types. +// +#define EFI_IMAGE_REL_BASED_ABSOLUTE 0 +#define EFI_IMAGE_REL_BASED_HIGH 1 +#define EFI_IMAGE_REL_BASED_LOW 2 +#define EFI_IMAGE_REL_BASED_HIGHLOW 3 +#define EFI_IMAGE_REL_BASED_HIGHADJ 4 +#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5 +#define EFI_IMAGE_REL_BASED_IA64_IMM64 9 +#define EFI_IMAGE_REL_BASED_DIR64 10 + +/// +/// Line number format. +/// +typedef struct { + union { + UINT32 SymbolTableIndex; // Symbol table index of function name if Linenumber is 0. + UINT32 VirtualAddress; // Virtual address of line number. + } Type; + UINT16 Linenumber; // Line number. +} EFI_IMAGE_LINENUMBER; + +#define EFI_IMAGE_SIZEOF_LINENUMBER 6 + +// +// Archive format. +// +#define EFI_IMAGE_ARCHIVE_START_SIZE 8 +#define EFI_IMAGE_ARCHIVE_START "!\n" +#define EFI_IMAGE_ARCHIVE_END "`\n" +#define EFI_IMAGE_ARCHIVE_PAD "\n" +#define EFI_IMAGE_ARCHIVE_LINKER_MEMBER "/ " +#define EFI_IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " + +typedef struct { + UINT8 Name[16]; // File member name - `/' terminated. + UINT8 Date[12]; // File member date - decimal. + UINT8 UserID[6]; // File member user id - decimal. + UINT8 GroupID[6]; // File member group id - decimal. + UINT8 Mode[8]; // File member mode - octal. + UINT8 Size[10]; // File member size - decimal. + UINT8 EndHeader[2]; // String to end header. +} EFI_IMAGE_ARCHIVE_MEMBER_HEADER; + +#define EFI_IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 + +// +// DLL support. +// + +/// +/// DLL Export Format +/// +typedef struct { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT16 MajorVersion; + UINT16 MinorVersion; + UINT32 Name; + UINT32 Base; + UINT32 NumberOfFunctions; + UINT32 NumberOfNames; + UINT32 AddressOfFunctions; + UINT32 AddressOfNames; + UINT32 AddressOfNameOrdinals; +} EFI_IMAGE_EXPORT_DIRECTORY; + +/// +/// DLL support. +/// Import Format +/// +typedef struct { + UINT16 Hint; + UINT8 Name[1]; +} EFI_IMAGE_IMPORT_BY_NAME; + +typedef struct { + union { + UINT32 Function; + UINT32 Ordinal; + EFI_IMAGE_IMPORT_BY_NAME *AddressOfData; + } u1; +} EFI_IMAGE_THUNK_DATA; + +#define EFI_IMAGE_ORDINAL_FLAG 0x80000000 +#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0) +#define EFI_IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) + +typedef struct { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT32 ForwarderChain; + UINT32 Name; + EFI_IMAGE_THUNK_DATA *FirstThunk; +} EFI_IMAGE_IMPORT_DESCRIPTOR; + +/// +/// Debug Format +/// +#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2 + +typedef struct { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT16 MajorVersion; + UINT16 MinorVersion; + UINT32 Type; + UINT32 SizeOfData; + UINT32 RVA; + UINT32 FileOffset; +} EFI_IMAGE_DEBUG_DIRECTORY_ENTRY; + +#define CODEVIEW_SIGNATURE_NB10 0x3031424E // "NB10" +typedef struct { + UINT32 Signature; // "NB10" + UINT32 Unknown; + UINT32 Unknown2; + UINT32 Unknown3; + // + // Filename of .PDB goes here + // +} EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY; + +#define CODEVIEW_SIGNATURE_RSDS 0x53445352 // "RSDS" +typedef struct { + UINT32 Signature; // "RSDS" + UINT32 Unknown; + UINT32 Unknown2; + UINT32 Unknown3; + UINT32 Unknown4; + UINT32 Unknown5; + // + // Filename of .PDB goes here + // +} EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY; + +// +// .pdata entries for X64 +// +typedef struct { + UINT32 FunctionStartAddress; + UINT32 FunctionEndAddress; + UINT32 UnwindInfoAddress; +} RUNTIME_FUNCTION; + +typedef struct { + UINT8 Version:3; + UINT8 Flags:5; + UINT8 SizeOfProlog; + UINT8 CountOfUnwindCodes; + UINT8 FrameRegister:4; + UINT8 FrameRegisterOffset:4; +} UNWIND_INFO; + +/// +/// Header format for TE images +/// +typedef struct { + UINT16 Signature; // signature for TE format = "VZ" + UINT16 Machine; // from the original file header + UINT8 NumberOfSections; // from the original file header + UINT8 Subsystem; // from original optional header + UINT16 StrippedSize; // how many bytes we removed from the header + UINT32 AddressOfEntryPoint; // offset to entry point -- from original optional header + UINT32 BaseOfCode; // from original image -- required for ITP debug + UINT64 ImageBase; // from original file header + EFI_IMAGE_DATA_DIRECTORY DataDirectory[2]; // only base relocation and debug directory +} EFI_TE_IMAGE_HEADER; + +#define EFI_TE_IMAGE_HEADER_SIGNATURE 0x5A56 // "VZ" + +// +// Data directory indexes in our TE image header +// +#define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC 0 +#define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG 1 + +#endif diff --git a/Tools/CodeTools/Source/Include/Common/FirmwareFileSystem.h b/Tools/CodeTools/Source/Include/Common/FirmwareFileSystem.h new file mode 100644 index 0000000000..5678a95524 --- /dev/null +++ b/Tools/CodeTools/Source/Include/Common/FirmwareFileSystem.h @@ -0,0 +1,98 @@ +/** @file + This file defines the data structures that comprise the FFS file system. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: FirmwareFileSystem.h + + @par Revision Reference: + These definitions are from Firmware File System Spec 0.9. + +**/ + +#ifndef __EFI_FFS_FILE_SYSTEM_H__ +#define __EFI_FFS_FILE_SYSTEM_H__ + +/// +/// FFS specific file types +/// +#define EFI_FV_FILETYPE_FFS_PAD 0xF0 + +// +// FFS File Attributes +// +#define FFS_ATTRIB_TAIL_PRESENT 0x01 +#define FFS_ATTRIB_RECOVERY 0x02 +#define FFS_ATTRIB_HEADER_EXTENSION 0x04 +#define FFS_ATTRIB_DATA_ALIGNMENT 0x38 +#define FFS_ATTRIB_CHECKSUM 0x40 + +/// +/// FFS_FIXED_CHECKSUM is the default checksum value used when the +/// FFS_ATTRIB_CHECKSUM attribute bit is clear +/// note this is NOT an architecturally defined value, but is in this file for +/// implementation convenience +/// +#define FFS_FIXED_CHECKSUM 0x5A + +// +// File state definitions +// +#define EFI_FILE_HEADER_CONSTRUCTION 0x01 +#define EFI_FILE_HEADER_VALID 0x02 +#define EFI_FILE_DATA_VALID 0x04 +#define EFI_FILE_MARKED_FOR_UPDATE 0x08 +#define EFI_FILE_DELETED 0x10 +#define EFI_FILE_HEADER_INVALID 0x20 + +#define EFI_FILE_ALL_STATE_BITS (EFI_FILE_HEADER_CONSTRUCTION | \ + EFI_FILE_HEADER_VALID | \ + EFI_FILE_DATA_VALID | \ + EFI_FILE_MARKED_FOR_UPDATE | \ + EFI_FILE_DELETED | \ + EFI_FILE_HEADER_INVALID \ + ) + +#define EFI_TEST_FFS_ATTRIBUTES_BIT(FvbAttributes, TestAttributes, Bit) \ + ( \ + (BOOLEAN) ( \ + (FvbAttributes & EFI_FVB_ERASE_POLARITY) ? (((~TestAttributes) & Bit) == Bit) : ((TestAttributes & Bit) == Bit) \ + ) \ + ) + +typedef UINT16 EFI_FFS_FILE_TAIL; + +/// +/// FFS file integrity check structure +/// +typedef union { + struct { + UINT8 Header; + UINT8 File; + } Checksum; + UINT16 TailReference; +} EFI_FFS_INTEGRITY_CHECK; + +// +// FFS file header definition +// +typedef UINT8 EFI_FFS_FILE_ATTRIBUTES; +typedef UINT8 EFI_FFS_FILE_STATE; + +typedef struct { + EFI_GUID Name; + EFI_FFS_INTEGRITY_CHECK IntegrityCheck; + EFI_FV_FILETYPE Type; + EFI_FFS_FILE_ATTRIBUTES Attributes; + UINT8 Size[3]; + EFI_FFS_FILE_STATE State; +} EFI_FFS_FILE_HEADER; + +#endif diff --git a/Tools/CodeTools/Source/Include/Common/FirmwareVolumeHeader.h b/Tools/CodeTools/Source/Include/Common/FirmwareVolumeHeader.h new file mode 100644 index 0000000000..038dce6f7f --- /dev/null +++ b/Tools/CodeTools/Source/Include/Common/FirmwareVolumeHeader.h @@ -0,0 +1,109 @@ +/** @file + Defines data structure that is the volume header found at the beginning of + all firmware volumes that are either memory mapped, or have an + associated FirmwareVolumeBlock protocol. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: FirmwareVolumeHeader.h + + @par Revision Reference: + These definitions are from Firmware Volume Block Spec 0.9. + +**/ + +#ifndef __EFI_FIRMWARE_VOLUME_HEADER_H__ +#define __EFI_FIRMWARE_VOLUME_HEADER_H__ + +// +// Firmware Volume Block Attributes definition +// +typedef UINT32 EFI_FVB_ATTRIBUTES; + +// +// Firmware Volume Block Attributes bit definitions +// +#define EFI_FVB_READ_DISABLED_CAP 0x00000001 +#define EFI_FVB_READ_ENABLED_CAP 0x00000002 +#define EFI_FVB_READ_STATUS 0x00000004 + +#define EFI_FVB_WRITE_DISABLED_CAP 0x00000008 +#define EFI_FVB_WRITE_ENABLED_CAP 0x00000010 +#define EFI_FVB_WRITE_STATUS 0x00000020 + +#define EFI_FVB_LOCK_CAP 0x00000040 +#define EFI_FVB_LOCK_STATUS 0x00000080 + +#define EFI_FVB_STICKY_WRITE 0x00000200 +#define EFI_FVB_MEMORY_MAPPED 0x00000400 +#define EFI_FVB_ERASE_POLARITY 0x00000800 + +#define EFI_FVB_ALIGNMENT_CAP 0x00008000 +#define EFI_FVB_ALIGNMENT_2 0x00010000 +#define EFI_FVB_ALIGNMENT_4 0x00020000 +#define EFI_FVB_ALIGNMENT_8 0x00040000 +#define EFI_FVB_ALIGNMENT_16 0x00080000 +#define EFI_FVB_ALIGNMENT_32 0x00100000 +#define EFI_FVB_ALIGNMENT_64 0x00200000 +#define EFI_FVB_ALIGNMENT_128 0x00400000 +#define EFI_FVB_ALIGNMENT_256 0x00800000 +#define EFI_FVB_ALIGNMENT_512 0x01000000 +#define EFI_FVB_ALIGNMENT_1K 0x02000000 +#define EFI_FVB_ALIGNMENT_2K 0x04000000 +#define EFI_FVB_ALIGNMENT_4K 0x08000000 +#define EFI_FVB_ALIGNMENT_8K 0x10000000 +#define EFI_FVB_ALIGNMENT_16K 0x20000000 +#define EFI_FVB_ALIGNMENT_32K 0x40000000 +#define EFI_FVB_ALIGNMENT_64K 0x80000000 + +#define EFI_FVB_CAPABILITIES (EFI_FVB_READ_DISABLED_CAP | \ + EFI_FVB_READ_ENABLED_CAP | \ + EFI_FVB_WRITE_DISABLED_CAP | \ + EFI_FVB_WRITE_ENABLED_CAP | \ + EFI_FVB_LOCK_CAP \ + ) + +#define EFI_FVB_STATUS (EFI_FVB_READ_STATUS | EFI_FVB_WRITE_STATUS | EFI_FVB_LOCK_STATUS) + +/// +/// Firmware Volume Header Revision definition +/// +#define EFI_FVH_REVISION 0x01 + +/// +/// Firmware Volume Header Signature definition +/// +#define EFI_FVH_SIGNATURE EFI_SIGNATURE_32 ('_', 'F', 'V', 'H') + +/// +/// Firmware Volume Header Block Map Entry definition +/// +typedef struct { + UINT32 NumBlocks; + UINT32 BlockLength; +} EFI_FV_BLOCK_MAP_ENTRY; + +/// +/// Firmware Volume Header definition +/// +typedef struct { + UINT8 ZeroVector[16]; + EFI_GUID FileSystemGuid; + UINT64 FvLength; + UINT32 Signature; + EFI_FVB_ATTRIBUTES Attributes; + UINT16 HeaderLength; + UINT16 Checksum; + UINT8 Reserved[3]; + UINT8 Revision; + EFI_FV_BLOCK_MAP_ENTRY FvBlockMap[1]; +} EFI_FIRMWARE_VOLUME_HEADER; + +#endif diff --git a/Tools/CodeTools/Source/Include/Common/FirmwareVolumeImageFormat.h b/Tools/CodeTools/Source/Include/Common/FirmwareVolumeImageFormat.h new file mode 100644 index 0000000000..14fa41bf26 --- /dev/null +++ b/Tools/CodeTools/Source/Include/Common/FirmwareVolumeImageFormat.h @@ -0,0 +1,277 @@ +/** @file + This file defines the data structures that are architecturally defined for file + images loaded via the FirmwareVolume protocol. The Firmware Volume specification + is the basis for these definitions. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: FimrwareVolumeImageFormat.h + + @par Revision Reference: + These definitions are from Firmware Volume Spec 0.9. + +**/ + +#ifndef __FIRMWARE_VOLUME_IMAGE_FORMAT_H__ +#define __FIRMWARE_VOLUME_IMAGE_FORMAT_H__ + +// +// pack all data structures since this is actually a binary format and we cannot +// allow internal padding in the data structures because of some compilerism.. +// +#pragma pack(1) +// +// //////////////////////////////////////////////////////////////////////////// +// +// Architectural file types +// +typedef UINT8 EFI_FV_FILETYPE; + +#define EFI_FV_FILETYPE_ALL 0x00 +#define EFI_FV_FILETYPE_RAW 0x01 +#define EFI_FV_FILETYPE_FREEFORM 0x02 +#define EFI_FV_FILETYPE_SECURITY_CORE 0x03 +#define EFI_FV_FILETYPE_PEI_CORE 0x04 +#define EFI_FV_FILETYPE_DXE_CORE 0x05 +#define EFI_FV_FILETYPE_PEIM 0x06 +#define EFI_FV_FILETYPE_DRIVER 0x07 +#define EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER 0x08 +#define EFI_FV_FILETYPE_APPLICATION 0x09 +// +// File type 0x0A is reserved and should not be used +// +#define EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE 0x0B + +// +// //////////////////////////////////////////////////////////////////////////// +// +// Section types +// +typedef UINT8 EFI_SECTION_TYPE; + +// +// ************************************************************ +// The section type EFI_SECTION_ALL is a psuedo type. It is +// used as a wildcard when retrieving sections. The section +// type EFI_SECTION_ALL matches all section types. +// ************************************************************ +// +#define EFI_SECTION_ALL 0x00 + +// +// ************************************************************ +// Encapsulation section Type values +// ************************************************************ +// +#define EFI_SECTION_COMPRESSION 0x01 +#define EFI_SECTION_GUID_DEFINED 0x02 + +// +// ************************************************************ +// Leaf section Type values +// ************************************************************ +// +#define EFI_SECTION_FIRST_LEAF_SECTION_TYPE 0x10 + +#define EFI_SECTION_PE32 0x10 +#define EFI_SECTION_PIC 0x11 +#define EFI_SECTION_TE 0x12 +#define EFI_SECTION_DXE_DEPEX 0x13 +#define EFI_SECTION_VERSION 0x14 +#define EFI_SECTION_USER_INTERFACE 0x15 +#define EFI_SECTION_COMPATIBILITY16 0x16 +#define EFI_SECTION_FIRMWARE_VOLUME_IMAGE 0x17 +#define EFI_SECTION_FREEFORM_SUBTYPE_GUID 0x18 +#define EFI_SECTION_RAW 0x19 +#define EFI_SECTION_PEI_DEPEX 0x1B + +#define EFI_SECTION_LAST_LEAF_SECTION_TYPE 0x1B +#define EFI_SECTION_LAST_SECTION_TYPE 0x1B + +// +// //////////////////////////////////////////////////////////////////////////// +// +// Common section header +// +typedef struct { + UINT8 Size[3]; + UINT8 Type; +} EFI_COMMON_SECTION_HEADER; + +#define SECTION_SIZE(SectionHeaderPtr) \ + ((UINT32) (*((UINT32 *) ((EFI_COMMON_SECTION_HEADER *) SectionHeaderPtr)->Size) & 0x00ffffff)) + +// +// //////////////////////////////////////////////////////////////////////////// +// +// Compression section +// +// +// CompressionType values +// +#define EFI_NOT_COMPRESSED 0x00 +#define EFI_STANDARD_COMPRESSION 0x01 +#define EFI_CUSTOMIZED_COMPRESSION 0x02 + +typedef struct { + EFI_COMMON_SECTION_HEADER CommonHeader; + UINT32 UncompressedLength; + UINT8 CompressionType; +} EFI_COMPRESSION_SECTION; + +// +// //////////////////////////////////////////////////////////////////////////// +// +// GUID defined section +// +typedef struct { + EFI_COMMON_SECTION_HEADER CommonHeader; + EFI_GUID SectionDefinitionGuid; + UINT16 DataOffset; + UINT16 Attributes; +} EFI_GUID_DEFINED_SECTION; + +// +// Bit values for Attributes +// +#define EFI_GUIDED_SECTION_PROCESSING_REQUIRED 0x01 +#define EFI_GUIDED_SECTION_AUTH_STATUS_VALID 0x02 + +// +// Bit values for AuthenticationStatus +// +#define EFI_AGGREGATE_AUTH_STATUS_PLATFORM_OVERRIDE 0x000001 +#define EFI_AGGREGATE_AUTH_STATUS_IMAGE_SIGNED 0x000002 +#define EFI_AGGREGATE_AUTH_STATUS_NOT_TESTED 0x000004 +#define EFI_AGGREGATE_AUTH_STATUS_TEST_FAILED 0x000008 +#define EFI_AGGREGATE_AUTH_STATUS_ALL 0x00000f + +#define EFI_LOCAL_AUTH_STATUS_PLATFORM_OVERRIDE 0x010000 +#define EFI_LOCAL_AUTH_STATUS_IMAGE_SIGNED 0x020000 +#define EFI_LOCAL_AUTH_STATUS_NOT_TESTED 0x040000 +#define EFI_LOCAL_AUTH_STATUS_TEST_FAILED 0x080000 +#define EFI_LOCAL_AUTH_STATUS_ALL 0x0f0000 + +// +// //////////////////////////////////////////////////////////////////////////// +// +// PE32+ section +// +typedef struct { + EFI_COMMON_SECTION_HEADER CommonHeader; +} EFI_PE32_SECTION; + +// +// //////////////////////////////////////////////////////////////////////////// +// +// PIC section +// +typedef struct { + EFI_COMMON_SECTION_HEADER CommonHeader; +} EFI_PIC_SECTION; + +// +// //////////////////////////////////////////////////////////////////////////// +// +// PEIM header section +// +typedef struct { + EFI_COMMON_SECTION_HEADER CommonHeader; +} EFI_PEIM_HEADER_SECTION; + +// +// //////////////////////////////////////////////////////////////////////////// +// +// DEPEX section +// +typedef struct { + EFI_COMMON_SECTION_HEADER CommonHeader; +} EFI_DEPEX_SECTION; + +// +// //////////////////////////////////////////////////////////////////////////// +// +// Version section +// +typedef struct { + EFI_COMMON_SECTION_HEADER CommonHeader; + UINT16 BuildNumber; + INT16 VersionString[1]; +} EFI_VERSION_SECTION; + +// +// //////////////////////////////////////////////////////////////////////////// +// +// User interface section +// +typedef struct { + EFI_COMMON_SECTION_HEADER CommonHeader; + INT16 FileNameString[1]; +} EFI_USER_INTERFACE_SECTION; + +// +// //////////////////////////////////////////////////////////////////////////// +// +// Code16 section +// +typedef struct { + EFI_COMMON_SECTION_HEADER CommonHeader; +} EFI_CODE16_SECTION; + +// +// //////////////////////////////////////////////////////////////////////////// +// +// Firmware Volume Image section +// +typedef struct { + EFI_COMMON_SECTION_HEADER CommonHeader; +} EFI_FIRMWARE_VOLUME_IMAGE_SECTION; + +// +// //////////////////////////////////////////////////////////////////////////// +// +// Freeform subtype GUID section +// +typedef struct { + EFI_COMMON_SECTION_HEADER CommonHeader; + EFI_GUID SubTypeGuid; +} EFI_FREEFORM_SUBTYPE_GUID_SECTION; + +// +// //////////////////////////////////////////////////////////////////////////// +// +// Raw section +// +typedef struct { + EFI_COMMON_SECTION_HEADER CommonHeader; +} EFI_RAW_SECTION; + +// +// undo the pragma from the beginning... +// +#pragma pack() + +typedef union { + EFI_COMMON_SECTION_HEADER *CommonHeader; + EFI_COMPRESSION_SECTION *CompressionSection; + EFI_GUID_DEFINED_SECTION *GuidDefinedSection; + EFI_PE32_SECTION *Pe32Section; + EFI_PIC_SECTION *PicSection; + EFI_PEIM_HEADER_SECTION *PeimHeaderSection; + EFI_DEPEX_SECTION *DependencySection; + EFI_VERSION_SECTION *VersionSection; + EFI_USER_INTERFACE_SECTION *UISection; + EFI_CODE16_SECTION *Code16Section; + EFI_FIRMWARE_VOLUME_IMAGE_SECTION *FVImageSection; + EFI_FREEFORM_SUBTYPE_GUID_SECTION *FreeformSubtypeSection; + EFI_RAW_SECTION *RawSection; +} EFI_FILE_SECTION_POINTER; + +#endif diff --git a/Tools/CodeTools/Source/Include/Common/InternalFormRepresentation.h b/Tools/CodeTools/Source/Include/Common/InternalFormRepresentation.h new file mode 100644 index 0000000000..bf3d824fbd --- /dev/null +++ b/Tools/CodeTools/Source/Include/Common/InternalFormRepresentation.h @@ -0,0 +1,422 @@ +/** @file + This file defines the encoding for the VFR (Visual Form Representation) language. + IFR is primarily consumed by the EFI presentation engine, and produced by EFI + internal application and drivers as well as all add-in card option-ROM drivers + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: InternalFormRepresentation.h + + @par Revision Reference: + These definitions are from Human Interface Infrastructure Spec Version 0.92. + +**/ + +#ifndef __EFI_INTERNAL_FORM_REPRESENTATION_H__ +#define __EFI_INTERNAL_FORM_REPRESENTATION_H__ + +// +// The following types are currently defined: +// +typedef UINT32 RELOFST; +typedef CHAR16 *EFI_STRING; + +// +// IFR Op codes +// +#define EFI_IFR_FORM_OP 0x01 +#define EFI_IFR_SUBTITLE_OP 0x02 +#define EFI_IFR_TEXT_OP 0x03 +#define EFI_IFR_GRAPHIC_OP 0x04 +#define EFI_IFR_ONE_OF_OP 0x05 +#define EFI_IFR_CHECKBOX_OP 0x06 +#define EFI_IFR_NUMERIC_OP 0x07 +#define EFI_IFR_PASSWORD_OP 0x08 +#define EFI_IFR_ONE_OF_OPTION_OP 0x09 // ONEOF OPTION field +#define EFI_IFR_SUPPRESS_IF_OP 0x0A +#define EFI_IFR_END_FORM_OP 0x0B +#define EFI_IFR_HIDDEN_OP 0x0C +#define EFI_IFR_END_FORM_SET_OP 0x0D +#define EFI_IFR_FORM_SET_OP 0x0E +#define EFI_IFR_REF_OP 0x0F +#define EFI_IFR_END_ONE_OF_OP 0x10 +#define EFI_IFR_END_OP EFI_IFR_END_ONE_OF_OP +#define EFI_IFR_INCONSISTENT_IF_OP 0x11 +#define EFI_IFR_EQ_ID_VAL_OP 0x12 +#define EFI_IFR_EQ_ID_ID_OP 0x13 +#define EFI_IFR_EQ_ID_LIST_OP 0x14 +#define EFI_IFR_AND_OP 0x15 +#define EFI_IFR_OR_OP 0x16 +#define EFI_IFR_NOT_OP 0x17 +#define EFI_IFR_END_IF_OP 0x18 // for endif of inconsistentif, suppressif, grayoutif +#define EFI_IFR_GRAYOUT_IF_OP 0x19 +#define EFI_IFR_DATE_OP 0x1A +#define EFI_IFR_TIME_OP 0x1B +#define EFI_IFR_STRING_OP 0x1C +#define EFI_IFR_LABEL_OP 0x1D +#define EFI_IFR_SAVE_DEFAULTS_OP 0x1E +#define EFI_IFR_RESTORE_DEFAULTS_OP 0x1F +#define EFI_IFR_BANNER_OP 0x20 +#define EFI_IFR_INVENTORY_OP 0x21 +#define EFI_IFR_EQ_VAR_VAL_OP 0x22 +#define EFI_IFR_ORDERED_LIST_OP 0x23 +#define EFI_IFR_VARSTORE_OP 0x24 +#define EFI_IFR_VARSTORE_SELECT_OP 0x25 +#define EFI_IFR_VARSTORE_SELECT_PAIR_OP 0x26 +#define EFI_IFR_TRUE_OP 0x27 +#define EFI_IFR_FALSE_OP 0x28 +#define EFI_IFR_GT_OP 0x29 +#define EFI_IFR_GE_OP 0x2A +#define EFI_IFR_OEM_DEFINED_OP 0x2B +#define EFI_IFR_LAST_OPCODE EFI_IFR_OEM_DEFINED_OP +#define EFI_IFR_OEM_OP 0xFE +#define EFI_IFR_NV_ACCESS_COMMAND 0xFF + +// +// Define values for the flags fields in some VFR opcodes. These are +// bitmasks. +// +#define EFI_IFR_FLAG_DEFAULT 0x01 +#define EFI_IFR_FLAG_MANUFACTURING 0x02 +#define EFI_IFR_FLAG_INTERACTIVE 0x04 +#define EFI_IFR_FLAG_NV_ACCESS 0x08 +#define EFI_IFR_FLAG_RESET_REQUIRED 0x10 +#define EFI_IFR_FLAG_LATE_CHECK 0x20 + +#define EFI_NON_DEVICE_CLASS 0x00 // Useful when you do not want something in the Device Manager +#define EFI_DISK_DEVICE_CLASS 0x01 +#define EFI_VIDEO_DEVICE_CLASS 0x02 +#define EFI_NETWORK_DEVICE_CLASS 0x04 +#define EFI_INPUT_DEVICE_CLASS 0x08 +#define EFI_ON_BOARD_DEVICE_CLASS 0x10 +#define EFI_OTHER_DEVICE_CLASS 0x20 + +#define EFI_SETUP_APPLICATION_SUBCLASS 0x00 +#define EFI_GENERAL_APPLICATION_SUBCLASS 0x01 +#define EFI_FRONT_PAGE_SUBCLASS 0x02 +#define EFI_SINGLE_USE_SUBCLASS 0x03 // Used to display a single entity and then exit + +// +// Used to flag dynamically created op-codes. This is meaningful to the IFR Library set +// and the browser since we need to distinguish between compiled NV map data and created data. +// We do not allow new entries to be created in the NV map dynamically however we still need +// to display this information correctly. To dynamically create op-codes and assume that their +// data will be saved, ensure that the NV starting location they refer to is pre-defined in the +// NV map. +// +#define EFI_IFR_FLAG_CREATED 128 + +#pragma pack(1) +// +// IFR Structure definitions +// +typedef struct { + UINT8 OpCode; + UINT8 Length; +} EFI_IFR_OP_HEADER; + +typedef struct { + EFI_IFR_OP_HEADER Header; + EFI_GUID Guid; + STRING_REF FormSetTitle; + STRING_REF Help; + EFI_PHYSICAL_ADDRESS CallbackHandle; + UINT16 Class; + UINT16 SubClass; + UINT16 NvDataSize; // set once, size of the NV data as defined in the script +} EFI_IFR_FORM_SET; + +typedef struct { + EFI_IFR_OP_HEADER Header; + UINT16 FormId; + STRING_REF FormTitle; +} EFI_IFR_FORM; + +typedef struct { + EFI_IFR_OP_HEADER Header; + UINT16 LabelId; +} EFI_IFR_LABEL; + +typedef struct { + EFI_IFR_OP_HEADER Header; + STRING_REF SubTitle; +} EFI_IFR_SUBTITLE; + +typedef struct { + EFI_IFR_OP_HEADER Header; + STRING_REF Help; + STRING_REF Text; + STRING_REF TextTwo; + UINT8 Flags; // This is included solely for purposes of interactive/dynamic support. + UINT16 Key; // Value to be passed to caller to identify this particular op-code +} EFI_IFR_TEXT; + +// +// goto +// +typedef struct { + EFI_IFR_OP_HEADER Header; + UINT16 FormId; + STRING_REF Prompt; + STRING_REF Help; // The string Token for the context-help + UINT8 Flags; // This is included solely for purposes of interactive/dynamic support. + UINT16 Key; // Value to be passed to caller to identify this particular op-code +} EFI_IFR_REF; + +typedef struct { + EFI_IFR_OP_HEADER Header; +} EFI_IFR_END_FORM; + +typedef struct { + EFI_IFR_OP_HEADER Header; +} EFI_IFR_END_FORM_SET; + +// +// Also notice that the IFR_ONE_OF and IFR_CHECK_BOX are identical in structure......code assumes this to be true, if this ever +// changes we need to revisit the InitializeTagStructures code +// +typedef struct { + EFI_IFR_OP_HEADER Header; + UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name + UINT8 Width; // The Size of the Data being saved + STRING_REF Prompt; // The String Token for the Prompt + STRING_REF Help; // The string Token for the context-help +} EFI_IFR_ONE_OF; + +typedef struct { + EFI_IFR_OP_HEADER Header; + UINT16 QuestionId; // The offset in NV for storage of the data + UINT8 MaxEntries; // The maximum number of options in the ordered list (=size of NVStore) + STRING_REF Prompt; // The string token for the prompt + STRING_REF Help; // The string token for the context-help +} EFI_IFR_ORDERED_LIST; + +typedef struct { + EFI_IFR_OP_HEADER Header; + UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name + UINT8 Width; // The Size of the Data being saved + STRING_REF Prompt; // The String Token for the Prompt + STRING_REF Help; // The string Token for the context-help + UINT8 Flags; // For now, if non-zero, means that it is the default option, - further definition likely + UINT16 Key; // Value to be passed to caller to identify this particular op-code +} EFI_IFR_CHECKBOX, EFI_IFR_CHECK_BOX; + +typedef struct { + EFI_IFR_OP_HEADER Header; + STRING_REF Option; // The string token describing the option + UINT16 Value; // The value associated with this option that is stored in the NVRAM if chosen + UINT8 Flags; // For now, if non-zero, means that it is the default option, - further definition likely above + UINT16 Key; // Value to be passed to caller to identify this particular op-code +} EFI_IFR_ONE_OF_OPTION; + +typedef struct { + EFI_IFR_OP_HEADER Header; + UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name + UINT8 Width; // The Size of the Data being saved + STRING_REF Prompt; // The String Token for the Prompt + STRING_REF Help; // The string Token for the context-help + UINT8 Flags; // This is included solely for purposes of interactive/dynamic support. + UINT16 Key; // Value to be passed to caller to identify this particular op-code + UINT16 Minimum; + UINT16 Maximum; + UINT16 Step; // If step is 0, then manual input is specified, otherwise, left/right arrow selection is called for + UINT16 Default; +} EFI_IFR_NUMERIC; + +// +// There is an interesting twist with regards to Time and Date. This is one of the few items which can accept input from +// a user, however may or may not need to use storage in the NVRAM space. The decided method for determining if NVRAM space +// will be used (only for a TimeOp or DateOp) is: If .QuestionId == 0 && .Width == 0 (normally an impossibility) then use system +// resources to store the data away and not NV resources. In other words, the setup engine will call gRT->SetTime, and gRT->SetDate +// for the saving of data, and the values displayed will be from the gRT->GetXXXX series of calls. +// +typedef struct { + EFI_IFR_NUMERIC Hour; + EFI_IFR_NUMERIC Minute; + EFI_IFR_NUMERIC Second; +} EFI_IFR_TIME; + +typedef struct { + EFI_IFR_NUMERIC Year; + EFI_IFR_NUMERIC Month; + EFI_IFR_NUMERIC Day; +} EFI_IFR_DATE; + +typedef struct { + EFI_IFR_OP_HEADER Header; + UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name + UINT8 Width; // The Size of the Data being saved -- BUGBUG -- remove someday + STRING_REF Prompt; // The String Token for the Prompt + STRING_REF Help; // The string Token for the context-help + UINT8 Flags; // This is included solely for purposes of interactive/dynamic support. + UINT16 Key; // Value to be passed to caller to identify this particular op-code + UINT8 MinSize; // Minimum allowable sized password + UINT8 MaxSize; // Maximum allowable sized password + UINT16 Encoding; +} EFI_IFR_PASSWORD; + +typedef struct { + EFI_IFR_OP_HEADER Header; + UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name + UINT8 Width; // The Size of the Data being saved -- BUGBUG -- remove someday + STRING_REF Prompt; // The String Token for the Prompt + STRING_REF Help; // The string Token for the context-help + UINT8 Flags; // This is included solely for purposes of interactive/dynamic support. + UINT16 Key; // Value to be passed to caller to identify this particular op-code + UINT8 MinSize; // Minimum allowable sized password + UINT8 MaxSize; // Maximum allowable sized password +} EFI_IFR_STRING; + +typedef struct { + EFI_IFR_OP_HEADER Header; +} EFI_IFR_END_ONE_OF; + +typedef struct { + EFI_IFR_OP_HEADER Header; + UINT16 Value; + UINT16 Key; +} EFI_IFR_HIDDEN; + +typedef struct { + EFI_IFR_OP_HEADER Header; + UINT8 Flags; +} EFI_IFR_SUPPRESS; + +typedef struct { + EFI_IFR_OP_HEADER Header; + UINT8 Flags; +} EFI_IFR_GRAY_OUT; + +typedef struct { + EFI_IFR_OP_HEADER Header; + STRING_REF Popup; + UINT8 Flags; +} EFI_IFR_INCONSISTENT; + +typedef struct { + EFI_IFR_OP_HEADER Header; + UINT16 QuestionId; // offset into variable storage + UINT8 Width; // size of variable storage + UINT16 Value; // value to compare against +} EFI_IFR_EQ_ID_VAL; + +typedef struct { + EFI_IFR_OP_HEADER Header; + UINT16 QuestionId; // offset into variable storage + UINT8 Width; // size of variable storage + UINT16 ListLength; + UINT16 ValueList[1]; +} EFI_IFR_EQ_ID_LIST; + +typedef struct { + EFI_IFR_OP_HEADER Header; + UINT16 QuestionId1; // offset into variable storage for first value to compare + UINT8 Width; // size of variable storage (must be same for both) + UINT16 QuestionId2; // offset into variable storage for second value to compare +} EFI_IFR_EQ_ID_ID; + +typedef struct { + EFI_IFR_OP_HEADER Header; + UINT16 VariableId; // offset into variable storage + UINT16 Value; // value to compare against +} EFI_IFR_EQ_VAR_VAL; + +typedef struct { + EFI_IFR_OP_HEADER Header; +} EFI_IFR_AND; + +typedef struct { + EFI_IFR_OP_HEADER Header; +} EFI_IFR_OR; + +typedef struct { + EFI_IFR_OP_HEADER Header; +} EFI_IFR_NOT; + +typedef struct { + EFI_IFR_OP_HEADER Header; +} EFI_IFR_END_EXPR, EFI_IFR_END_IF; + +typedef struct { + EFI_IFR_OP_HEADER Header; + UINT16 FormId; + STRING_REF Prompt; + STRING_REF Help; + UINT8 Flags; + UINT16 Key; +} EFI_IFR_SAVE_DEFAULTS; + +typedef struct { + EFI_IFR_OP_HEADER Header; + STRING_REF Help; + STRING_REF Text; + STRING_REF TextTwo; // optional text +} EFI_IFR_INVENTORY; + +typedef struct { + EFI_IFR_OP_HEADER Header; + EFI_GUID Guid; // GUID for the variable + UINT16 VarId; // variable store ID, as referenced elsewhere in the form + UINT16 Size; // size of the variable storage +} EFI_IFR_VARSTORE; + +typedef struct { + EFI_IFR_OP_HEADER Header; + UINT16 VarId; // variable store ID, as referenced elsewhere in the form +} EFI_IFR_VARSTORE_SELECT; + +// +// Used for the ideqid VFR statement where two variable stores may be referenced in the +// same VFR statement. +// A browser should treat this as an EFI_IFR_VARSTORE_SELECT statement and assume that all following +// IFR opcodes use the VarId as defined here. +// +typedef struct { + EFI_IFR_OP_HEADER Header; + UINT16 VarId; // variable store ID, as referenced elsewhere in the form + UINT16 SecondaryVarId; // variable store ID, as referenced elsewhere in the form +} EFI_IFR_VARSTORE_SELECT_PAIR; + +typedef struct { + EFI_IFR_OP_HEADER Header; +} EFI_IFR_TRUE; + +typedef struct { + EFI_IFR_OP_HEADER Header; +} EFI_IFR_FALSE; + +typedef struct { + EFI_IFR_OP_HEADER Header; +} EFI_IFR_GT; + +typedef struct { + EFI_IFR_OP_HEADER Header; +} EFI_IFR_GE; + +// +// Save defaults and restore defaults have same structure +// +#define EFI_IFR_RESTORE_DEFAULTS EFI_IFR_SAVE_DEFAULTS + +typedef struct { + EFI_IFR_OP_HEADER Header; + STRING_REF Title; // The string token for the banner title + UINT16 LineNumber; // 1-based line number + UINT8 Alignment; // left, center, or right-aligned +} EFI_IFR_BANNER; + +#define EFI_IFR_BANNER_ALIGN_LEFT 0 +#define EFI_IFR_BANNER_ALIGN_CENTER 1 +#define EFI_IFR_BANNER_ALIGN_RIGHT 2 +#define EFI_IFR_BANNER_TIMEOUT 0xFF + +#pragma pack() + +#endif diff --git a/Tools/CodeTools/Source/Include/Common/MultiPhase.h b/Tools/CodeTools/Source/Include/Common/MultiPhase.h new file mode 100644 index 0000000000..93867a5e8a --- /dev/null +++ b/Tools/CodeTools/Source/Include/Common/MultiPhase.h @@ -0,0 +1,84 @@ +/** @file + This includes some definitions that will be used in both PEI and DXE phases. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: MultiPhase.h + +**/ + +#ifndef __MULTI_PHASE_H__ +#define __MULTI_PHASE_H__ + +// +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// +// Needed EFI defines for PEI +// +typedef UINT64 EFI_PHYSICAL_ADDRESS; + +typedef enum { + EfiReservedMemoryType, + EfiLoaderCode, + EfiLoaderData, + EfiBootServicesCode, + EfiBootServicesData, + EfiRuntimeServicesCode, + EfiRuntimeServicesData, + EfiConventionalMemory, + EfiUnusableMemory, + EfiACPIReclaimMemory, + EfiACPIMemoryNVS, + EfiMemoryMappedIO, + EfiMemoryMappedIOPortSpace, + EfiPalCode, + EfiMaxMemoryType +} EFI_MEMORY_TYPE; + +typedef UINT32 EFI_STATUS_CODE_TYPE; +typedef UINT32 EFI_STATUS_CODE_VALUE; + +typedef struct { + UINT16 HeaderSize; + UINT16 Size; + EFI_GUID Type; +} EFI_STATUS_CODE_DATA; + +typedef struct { + UINT64 Signature; + UINT32 Revision; + UINT32 HeaderSize; + UINT32 CRC32; + UINT32 Reserved; +} EFI_TABLE_HEADER; + +#define EFI_PAGE_SIZE 4096 + + +typedef VOID *EFI_HANDLE; +typedef UINT16 EFI_HII_HANDLE; +typedef UINT16 STRING_REF; +typedef struct { + INT16 Value; + INT16 Exponent; +} EFI_EXP_BASE10_DATA; + +// +// Define macros to build data structure signatures from characters. +// +#define EFI_SIGNATURE_16(A, B) ((A) | (B << 8)) +#define EFI_SIGNATURE_32(A, B, C, D) (EFI_SIGNATURE_16 (A, B) | (EFI_SIGNATURE_16 (C, D) << 16)) +#define EFI_SIGNATURE_64(A, B, C, D, E, F, G, H) \ + (EFI_SIGNATURE_32 (A, B, C, D) | ((UINT64) (EFI_SIGNATURE_32 (E, F, G, H)) << 32)) + + +#include + +#endif diff --git a/Tools/CodeTools/Source/Include/Common/UefiBaseTypes.h b/Tools/CodeTools/Source/Include/Common/UefiBaseTypes.h new file mode 100644 index 0000000000..4954c10bf2 --- /dev/null +++ b/Tools/CodeTools/Source/Include/Common/UefiBaseTypes.h @@ -0,0 +1,85 @@ +/** @file + This file makes the BaseTypes.h backward compatible with the ones used in the + past for EFI and Tiano development. It's mostly just prepending an EFI_ on the + definitions. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: UefiBaseTypes.h + +**/ + +#ifndef __UEFI_BASE_TYPES_H__ +#define __UEFI_BASE_TYPES_H__ + +#include + +typedef UINT64 EFI_LBA; + +#define EFIERR(_a) ENCODE_ERROR(_a) + +#define EFI_MAX_BIT MAX_BIT +#define EFI_MAX_ADDRESS MAX_ADDRESS +#define EFI_BREAKPOINT() CpuBreakpoint () +#define EFI_DEADLOOP() CpuDeadLoop () +#define EFI_ERROR(A) RETURN_ERROR(A) + +typedef GUID EFI_GUID; +typedef RETURN_STATUS EFI_STATUS; + +#define EFI_SUCCESS RETURN_SUCCESS +#define EFI_LOAD_ERROR RETURN_LOAD_ERROR +#define EFI_INVALID_PARAMETER RETURN_INVALID_PARAMETER +#define EFI_UNSUPPORTED RETURN_UNSUPPORTED +#define EFI_BAD_BUFFER_SIZE RETURN_BAD_BUFFER_SIZE +#define EFI_BUFFER_TOO_SMALL RETURN_BUFFER_TOO_SMALL +#define EFI_NOT_READY RETURN_NOT_READY +#define EFI_DEVICE_ERROR RETURN_DEVICE_ERROR +#define EFI_WRITE_PROTECTED RETURN_WRITE_PROTECTED +#define EFI_OUT_OF_RESOURCES RETURN_OUT_OF_RESOURCES +#define EFI_VOLUME_CORRUPTED RETURN_VOLUME_CORRUPTED +#define EFI_VOLUME_FULL RETURN_VOLUME_FULL +#define EFI_NO_MEDIA RETURN_NO_MEDIA +#define EFI_MEDIA_CHANGED RETURN_MEDIA_CHANGED +#define EFI_NOT_FOUND RETURN_NOT_FOUND +#define EFI_ACCESS_DENIED RETURN_ACCESS_DENIED +#define EFI_NO_RESPONSE RETURN_NO_RESPONSE +#define EFI_NO_MAPPING RETURN_NO_MAPPING +#define EFI_TIMEOUT RETURN_TIMEOUT +#define EFI_NOT_STARTED RETURN_NOT_STARTED +#define EFI_ALREADY_STARTED RETURN_ALREADY_STARTED +#define EFI_ABORTED RETURN_ABORTED +#define EFI_ICMP_ERROR RETURN_ICMP_ERROR +#define EFI_TFTP_ERROR RETURN_TFTP_ERROR +#define EFI_PROTOCOL_ERROR RETURN_PROTOCOL_ERROR +#define EFI_INCOMPATIBLE_VERSION RETURN_INCOMPATIBLE_VERSION +#define EFI_SECURITY_VIOLATION RETURN_SECURITY_VIOLATION +#define EFI_CRC_ERROR RETURN_CRC_ERROR +#define EFI_END_OF_MEDIA RETURN_END_OF_MEDIA +#define EFI_END_OF_FILE RETURN_END_OF_FILE + +#define EFI_WARN_UNKNOWN_GLYPH RETURN_WARN_UNKNOWN_GLYPH +#define EFI_WARN_DELETE_FAILURE RETURN_WARN_DELETE_FAILURE +#define EFI_WARN_WRITE_FAILURE RETURN_WARN_WRITE_FAILURE +#define EFI_WARN_BUFFER_TOO_SMALL RETURN_WARN_BUFFER_TOO_SMALL + +// +// The EFI memory allocation functions work in units of EFI_PAGEs that are +// 4K. This should in no way be confused with the page size of the processor. +// An EFI_PAGE is just the quanta of memory in EFI. +// +#define EFI_PAGE_MASK 0xFFF +#define EFI_PAGE_SHIFT 12 + +#define EFI_SIZE_TO_PAGES(a) (((a) >> EFI_PAGE_SHIFT) + (((a) & EFI_PAGE_MASK) ? 1 : 0)) + +#define EFI_PAGES_TO_SIZE(a) ( (a) << EFI_PAGE_SHIFT) + +#endif diff --git a/Tools/CodeTools/Source/Include/Common/Variable.h b/Tools/CodeTools/Source/Include/Common/Variable.h new file mode 100644 index 0000000000..bc0d6408d7 --- /dev/null +++ b/Tools/CodeTools/Source/Include/Common/Variable.h @@ -0,0 +1,78 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + EfiVariable.h + +Abstract: + + Header file for EFI Variable Services + +--*/ + +#ifndef _EFI_VARIABLE_H_ +#define _EFI_VARIABLE_H_ + +#define VARIABLE_STORE_SIGNATURE EFI_SIGNATURE_32 ('$', 'V', 'S', 'S') + +#define MAX_VARIABLE_SIZE 1024 + +#define VARIABLE_DATA 0x55AA + +// +// Variable Store Header flags +// +#define VARIABLE_STORE_FORMATTED 0x5a +#define VARIABLE_STORE_HEALTHY 0xfe + +// +// Variable Store Status +// +typedef enum { + EfiRaw, + EfiValid, + EfiInvalid, + EfiUnknown +} VARIABLE_STORE_STATUS; + +// +// Variable State flags +// +#define VAR_IN_DELETED_TRANSITION 0xfe // Variable is in obsolete transistion +#define VAR_DELETED 0xfd // Variable is obsolete +#define VAR_ADDED 0x7f // Variable has been completely added +#define IS_VARIABLE_STATE(_c, _Mask) (BOOLEAN) (((~_c) & (~_Mask)) != 0) + +#pragma pack(1) + +typedef struct { + UINT32 Signature; + UINT32 Size; + UINT8 Format; + UINT8 State; + UINT16 Reserved; + UINT32 Reserved1; +} VARIABLE_STORE_HEADER; + +typedef struct { + UINT16 StartId; + UINT8 State; + UINT8 Reserved; + UINT32 Attributes; + UINTN NameSize; + UINTN DataSize; + EFI_GUID VendorGuid; +} VARIABLE_HEADER; + +#pragma pack() + +#endif // _EFI_VARIABLE_H_ diff --git a/Tools/CodeTools/Source/Include/Common/WorkingBlockHeader.h b/Tools/CodeTools/Source/Include/Common/WorkingBlockHeader.h new file mode 100644 index 0000000000..235b740e83 --- /dev/null +++ b/Tools/CodeTools/Source/Include/Common/WorkingBlockHeader.h @@ -0,0 +1,47 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + EfiWorkingBlockHeader.h + +Abstract: + + Defines data structure that is the headers found at the runtime + updatable firmware volumes, such as the FileSystemGuid of the + working block, the header structure of the variable block, FTW + working block, or event log block. + +--*/ + +#ifndef _EFI_WORKING_BLOCK_HEADER_H_ +#define _EFI_WORKING_BLOCK_HEADER_H_ + +// +// EFI Fault tolerant working block header +// The header is immediately followed by the write queue. +// +typedef struct { + EFI_GUID Signature; + UINT32 Crc; + UINT32 WorkingBlockValid : 1; + UINT32 WorkingBlockInvalid : 1; +#define WORKING_BLOCK_VALID 0x1 +#define WORKING_BLOCK_INVALID 0x2 + UINT32 Reserved : 6; + UINT8 Reserved3[3]; + UINTN WriteQueueSize; + // + // UINT8 WriteQueue[WriteQueueSize]; + // +} EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER; + +#endif diff --git a/Tools/CodeTools/Source/Include/Guid/AcpiTableStorage.h b/Tools/CodeTools/Source/Include/Guid/AcpiTableStorage.h new file mode 100644 index 0000000000..80b1154828 --- /dev/null +++ b/Tools/CodeTools/Source/Include/Guid/AcpiTableStorage.h @@ -0,0 +1,30 @@ +/** @file + The ACPI table storage file is fully FFS compliant. + The file is a number of sections of type EFI_SECTION_RAW. + This GUID is used to identify the file as an ACPI table storage file. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: AcpiTableStorage.h + + @par Revision Reference: + GUID defined in ACPI Table Storage Spec Version 0.9. + +**/ + +#ifndef _ACPI_TABLE_STORAGE_H_ +#define _ACPI_TABLE_STORAGE_H_ + +#define EFI_ACPI_TABLE_STORAGE_GUID \ + { 0x7e374e25, 0x8e01, 0x4fee, {0x87, 0xf2, 0x39, 0xc, 0x23, 0xc6, 0x6, 0xcd } } + +extern EFI_GUID gEfiAcpiTableStorageGuid; + +#endif diff --git a/Tools/CodeTools/Source/Include/Guid/Apriori.h b/Tools/CodeTools/Source/Include/Guid/Apriori.h new file mode 100644 index 0000000000..ba92560d7e --- /dev/null +++ b/Tools/CodeTools/Source/Include/Guid/Apriori.h @@ -0,0 +1,32 @@ +/** @file + GUID used as an FV filename for A Priori file. The A Priori file contains a + list of FV filenames that the DXE dispatcher will schedule reguardless of + the dependency grammer. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: Apriori.h + + @par Revision Reference: + GUID defined in DXE CIS spec version 0.91B + +**/ + +#ifndef __APRIORI_GUID_H__ +#define __APRIORI_GUID_H__ + +#define EFI_APRIORI_GUID \ + { \ + 0xfc510ee7, 0xffdc, 0x11d4, {0xbd, 0x41, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \ + } + +extern EFI_GUID gAprioriGuid; + +#endif diff --git a/Tools/CodeTools/Source/Include/Guid/Capsule.h b/Tools/CodeTools/Source/Include/Guid/Capsule.h new file mode 100644 index 0000000000..7864b924de --- /dev/null +++ b/Tools/CodeTools/Source/Include/Guid/Capsule.h @@ -0,0 +1,43 @@ +/** @file + GUIDs used for EFI Capsule + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: Capsule.h + + @par Revision Reference: + GUIDs defined in Capsule Spec Version 0.9 + +**/ + +#ifndef __CAPSULE_GUID_H__ +#define __CAPSULE_GUID_H__ + +// +// This is the GUID of the capsule header of the image on disk. +// +#define EFI_CAPSULE_GUID \ + { \ + 0x3B6686BD, 0x0D76, 0x4030, {0xB7, 0x0E, 0xB5, 0x51, 0x9E, 0x2F, 0xC5, 0xA0 } \ + } + +// +// This is the GUID of the configuration results file created by the capsule +// application. +// +#define EFI_CONFIG_FILE_NAME_GUID \ + { \ + 0x98B8D59B, 0xE8BA, 0x48EE, {0x98, 0xDD, 0xC2, 0x95, 0x39, 0x2F, 0x1E, 0xDB } \ + } + +extern EFI_GUID gEfiCapsuleGuid; +extern EFI_GUID gEfiConfigFileNameGuid; + +#endif diff --git a/Tools/CodeTools/Source/Include/Guid/FirmwareFileSystem.h b/Tools/CodeTools/Source/Include/Guid/FirmwareFileSystem.h new file mode 100644 index 0000000000..06bfa7d583 --- /dev/null +++ b/Tools/CodeTools/Source/Include/Guid/FirmwareFileSystem.h @@ -0,0 +1,40 @@ +/** @file + Guid used to define the Firmware File System. See the Framework Firmware + File System Specification for more details. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: FirmwareFileSystem.h + + @par Revision Reference: + Guids defined in Firmware File System Spec 0.9 + +**/ + +#ifndef __FIRMWARE_FILE_SYSTEM_GUID_H__ +#define __FIRMWARE_FILE_SYSTEM_GUID_H__ + +// +// GUIDs defined by the FFS specification. +// +#define EFI_FIRMWARE_FILE_SYSTEM_GUID \ + { \ + 0x7A9354D9, 0x0468, 0x444a, {0x81, 0xCE, 0x0B, 0xF6, 0x17, 0xD8, 0x90, 0xDF } \ + } + +#define EFI_FFS_VOLUME_TOP_FILE_GUID \ + { \ + 0x1BA0062E, 0xC779, 0x4582, {0x85, 0x66, 0x33, 0x6A, 0xE8, 0xF7, 0x8F, 0x9 } \ + } + +extern EFI_GUID gEfiFirmwareFileSystemGuid; +extern EFI_GUID gEfiFirmwareVolumeTopFileGuid; + +#endif diff --git a/Tools/CodeTools/Source/Include/Ia32/ProcessorBind.h b/Tools/CodeTools/Source/Include/Ia32/ProcessorBind.h new file mode 100644 index 0000000000..587d8a69ab --- /dev/null +++ b/Tools/CodeTools/Source/Include/Ia32/ProcessorBind.h @@ -0,0 +1,167 @@ +/** @file + Processor or Compiler specific defines and types for x64. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: ProcessorBind.h + +**/ + +#ifndef __PROCESSOR_BIND_H__ +#define __PROCESSOR_BIND_H__ + +// +// Define the processor type so other code can make processor based choices +// +#define MDE_CPU_IA32 + +// +// Make sure we are useing the correct packing rules per EFI specification +// +#ifndef __GNUC__ +#pragma pack() +#endif + +#if _MSC_EXTENSIONS + +// +// Disable warning that make it impossible to compile at /W4 +// This only works for Microsoft* tools +// + +// +// Disabling bitfield type checking warnings. +// +#pragma warning ( disable : 4214 ) + +// +// Disabling the unreferenced formal parameter warnings. +// +#pragma warning ( disable : 4100 ) + +// +// Disable slightly different base types warning as CHAR8 * can not be set +// to a constant string. +// +#pragma warning ( disable : 4057 ) + +// +// ASSERT(FALSE) or while (TRUE) are legal constructes so supress this warning +// +#pragma warning ( disable : 4127 ) + + +#endif + + +#if !defined(__GNUC__) && (__STDC_VERSION__ < 199901L) + // + // No ANSI C 2000 stdint.h integer width declarations, so define equivalents + // + + #if _MSC_EXTENSIONS + + // + // use Microsoft* C complier dependent interger width types + // + typedef unsigned __int64 UINT64; + typedef __int64 INT64; + typedef unsigned __int32 UINT32; + typedef __int32 INT32; + typedef unsigned short UINT16; + typedef unsigned short CHAR16; + typedef short INT16; + typedef unsigned char BOOLEAN; + typedef unsigned char UINT8; + typedef char CHAR8; + typedef char INT8; + #else + + // + // Assume standard IA-32 alignment. + // BugBug: Need to check portability of long long + // + typedef unsigned long long UINT64; + typedef long long INT64; + typedef unsigned int UINT32; + typedef int INT32; + typedef unsigned short UINT16; + typedef unsigned short CHAR16; + typedef short INT16; + typedef unsigned char BOOLEAN; + typedef unsigned char UINT8; + typedef char CHAR8; + typedef char INT8; + #endif + + #define UINT8_MAX 0xff + +#else + // + // Use ANSI C 2000 stdint.h integer width declarations + // + #include "stdint.h" + typedef uint8_t BOOLEAN; + typedef int8_t INT8; + typedef uint8_t UINT8; + typedef int16_t INT16; + typedef uint16_t UINT16; + typedef int32_t INT32; + typedef uint32_t UINT32; + typedef int64_t INT64; + typedef uint64_t UINT64; + typedef char CHAR8; + typedef uint16_t CHAR16; + +#endif + +typedef UINT32 UINTN; +typedef INT32 INTN; + + +// +// Processor specific defines +// +#define MAX_BIT 0x80000000 +#define MAX_2_BITS 0xC0000000 + +// +// Maximum legal IA-32 address +// +#define MAX_ADDRESS 0xFFFFFFFF + +// +// Modifier to ensure that all protocol member functions and EFI intrinsics +// use the correct C calling convention. All protocol member functions and +// EFI intrinsics are required to modify thier member functions with EFIAPI. +// +#if _MSC_EXTENSIONS + // + // Microsoft* compiler requires _EFIAPI useage, __cdecl is Microsoft* specific C. + // + #define EFIAPI __cdecl +#endif + +#if __GNUC__ + #define EFIAPI __attribute__((cdecl)) +#endif + +// +// The Microsoft* C compiler can removed references to unreferenced data items +// if the /OPT:REF linker option is used. We defined a macro as this is a +// a non standard extension +// +#if _MSC_EXTENSIONS + #define GLOBAL_REMOVE_IF_UNREFERENCED __declspec(selectany) +#else + #define GLOBAL_REMOVE_IF_UNREFERENCED +#endif + +#endif diff --git a/Tools/CodeTools/Source/Include/IndustryStandard/pci22.h b/Tools/CodeTools/Source/Include/IndustryStandard/pci22.h new file mode 100644 index 0000000000..7fee279e80 --- /dev/null +++ b/Tools/CodeTools/Source/Include/IndustryStandard/pci22.h @@ -0,0 +1,481 @@ +/** @file + Support for PCI 2.2 standard. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: pci22.h + +**/ + +#ifndef _PCI22_H +#define _PCI22_H + +#define PCI_MAX_SEGMENT 0 + +#define PCI_MAX_BUS 255 + +#define PCI_MAX_DEVICE 31 +#define PCI_MAX_FUNC 7 + +// +// Command +// +#define PCI_VGA_PALETTE_SNOOP_DISABLED 0x20 + +#pragma pack(push, 1) +typedef struct { + UINT16 VendorId; + UINT16 DeviceId; + UINT16 Command; + UINT16 Status; + UINT8 RevisionID; + UINT8 ClassCode[3]; + UINT8 CacheLineSize; + UINT8 LatencyTimer; + UINT8 HeaderType; + UINT8 BIST; +} PCI_DEVICE_INDEPENDENT_REGION; + +typedef struct { + UINT32 Bar[6]; + UINT32 CISPtr; + UINT16 SubsystemVendorID; + UINT16 SubsystemID; + UINT32 ExpansionRomBar; + UINT8 CapabilityPtr; + UINT8 Reserved1[3]; + UINT32 Reserved2; + UINT8 InterruptLine; + UINT8 InterruptPin; + UINT8 MinGnt; + UINT8 MaxLat; +} PCI_DEVICE_HEADER_TYPE_REGION; + +typedef struct { + PCI_DEVICE_INDEPENDENT_REGION Hdr; + PCI_DEVICE_HEADER_TYPE_REGION Device; +} PCI_TYPE00; + +typedef struct { + UINT32 Bar[2]; + UINT8 PrimaryBus; + UINT8 SecondaryBus; + UINT8 SubordinateBus; + UINT8 SecondaryLatencyTimer; + UINT8 IoBase; + UINT8 IoLimit; + UINT16 SecondaryStatus; + UINT16 MemoryBase; + UINT16 MemoryLimit; + UINT16 PrefetchableMemoryBase; + UINT16 PrefetchableMemoryLimit; + UINT32 PrefetchableBaseUpper32; + UINT32 PrefetchableLimitUpper32; + UINT16 IoBaseUpper16; + UINT16 IoLimitUpper16; + UINT8 CapabilityPtr; + UINT8 Reserved[3]; + UINT32 ExpansionRomBAR; + UINT8 InterruptLine; + UINT8 InterruptPin; + UINT16 BridgeControl; +} PCI_BRIDGE_CONTROL_REGISTER; + +typedef struct { + PCI_DEVICE_INDEPENDENT_REGION Hdr; + PCI_BRIDGE_CONTROL_REGISTER Bridge; +} PCI_TYPE01; + +typedef union { + PCI_TYPE00 Device; + PCI_TYPE01 Bridge; +} PCI_TYPE_GENERIC; + +typedef struct { + UINT32 CardBusSocketReg; // Cardus Socket/ExCA Base + // Address Register + // + UINT16 Reserved; + UINT16 SecondaryStatus; // Secondary Status + UINT8 PciBusNumber; // PCI Bus Number + UINT8 CardBusBusNumber; // CardBus Bus Number + UINT8 SubordinateBusNumber; // Subordinate Bus Number + UINT8 CardBusLatencyTimer; // CardBus Latency Timer + UINT32 MemoryBase0; // Memory Base Register 0 + UINT32 MemoryLimit0; // Memory Limit Register 0 + UINT32 MemoryBase1; + UINT32 MemoryLimit1; + UINT32 IoBase0; + UINT32 IoLimit0; // I/O Base Register 0 + UINT32 IoBase1; // I/O Limit Register 0 + UINT32 IoLimit1; + UINT8 InterruptLine; // Interrupt Line + UINT8 InterruptPin; // Interrupt Pin + UINT16 BridgeControl; // Bridge Control +} PCI_CARDBUS_CONTROL_REGISTER; + +// +// Definitions of PCI class bytes and manipulation macros. +// +#define PCI_CLASS_OLD 0x00 +#define PCI_CLASS_OLD_OTHER 0x00 +#define PCI_CLASS_OLD_VGA 0x01 + +#define PCI_CLASS_MASS_STORAGE 0x01 +#define PCI_CLASS_MASS_STORAGE_SCSI 0x00 +#define PCI_CLASS_MASS_STORAGE_IDE 0x01 // obsolete +#define PCI_CLASS_IDE 0x01 +#define PCI_CLASS_MASS_STORAGE_FLOPPY 0x02 +#define PCI_CLASS_MASS_STORAGE_IPI 0x03 +#define PCI_CLASS_MASS_STORAGE_RAID 0x04 +#define PCI_CLASS_MASS_STORAGE_OTHER 0x80 + +#define PCI_CLASS_NETWORK 0x02 +#define PCI_CLASS_NETWORK_ETHERNET 0x00 +#define PCI_CLASS_ETHERNET 0x00 // obsolete +#define PCI_CLASS_NETWORK_TOKENRING 0x01 +#define PCI_CLASS_NETWORK_FDDI 0x02 +#define PCI_CLASS_NETWORK_ATM 0x03 +#define PCI_CLASS_NETWORK_ISDN 0x04 +#define PCI_CLASS_NETWORK_OTHER 0x80 + +#define PCI_CLASS_DISPLAY 0x03 +#define PCI_CLASS_DISPLAY_CTRL 0x03 // obsolete +#define PCI_CLASS_DISPLAY_VGA 0x00 +#define PCI_CLASS_VGA 0x00 // obsolete +#define PCI_CLASS_DISPLAY_XGA 0x01 +#define PCI_CLASS_DISPLAY_3D 0x02 +#define PCI_CLASS_DISPLAY_OTHER 0x80 +#define PCI_CLASS_DISPLAY_GFX 0x80 +#define PCI_CLASS_GFX 0x80 // obsolete +#define PCI_CLASS_BRIDGE 0x06 +#define PCI_CLASS_BRIDGE_HOST 0x00 +#define PCI_CLASS_BRIDGE_ISA 0x01 +#define PCI_CLASS_ISA 0x01 // obsolete +#define PCI_CLASS_BRIDGE_EISA 0x02 +#define PCI_CLASS_BRIDGE_MCA 0x03 +#define PCI_CLASS_BRIDGE_P2P 0x04 +#define PCI_CLASS_BRIDGE_PCMCIA 0x05 +#define PCI_CLASS_BRIDGE_NUBUS 0x06 +#define PCI_CLASS_BRIDGE_CARDBUS 0x07 +#define PCI_CLASS_BRIDGE_RACEWAY 0x08 +#define PCI_CLASS_BRIDGE_ISA_PDECODE 0x80 +#define PCI_CLASS_ISA_POSITIVE_DECODE 0x80 // obsolete +#define PCI_CLASS_SERIAL 0x0C +#define PCI_CLASS_SERIAL_FIREWIRE 0x00 +#define PCI_CLASS_SERIAL_ACCESS_BUS 0x01 +#define PCI_CLASS_SERIAL_SSA 0x02 +#define PCI_CLASS_SERIAL_USB 0x03 +#define PCI_CLASS_SERIAL_FIBRECHANNEL 0x04 +#define PCI_CLASS_SERIAL_SMB 0x05 + +#define IS_CLASS1(_p, c) ((_p)->Hdr.ClassCode[2] == (c)) +#define IS_CLASS2(_p, c, s) (IS_CLASS1 (_p, c) && ((_p)->Hdr.ClassCode[1] == (s))) +#define IS_CLASS3(_p, c, s, p) (IS_CLASS2 (_p, c, s) && ((_p)->Hdr.ClassCode[0] == (p))) + +#define IS_PCI_DISPLAY(_p) IS_CLASS1 (_p, PCI_CLASS_DISPLAY) +#define IS_PCI_VGA(_p) IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA, 0) +#define IS_PCI_8514(_p) IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA, 1) +#define IS_PCI_GFX(_p) IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_GFX, 0) +#define IS_PCI_OLD(_p) IS_CLASS1 (_p, PCI_CLASS_OLD) +#define IS_PCI_OLD_VGA(_p) IS_CLASS2 (_p, PCI_CLASS_OLD, PCI_CLASS_OLD_VGA) +#define IS_PCI_IDE(_p) IS_CLASS2 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_IDE) +#define IS_PCI_SCSI(_p) IS_CLASS3 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_SCSI, 0) +#define IS_PCI_RAID(_p) IS_CLASS3 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_RAID, 0) +#define IS_PCI_LPC(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA, 0) +#define IS_PCI_P2P(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_P2P, 0) +#define IS_PCI_P2P_SUB(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_P2P, 1) +#define IS_PCI_USB(_p) IS_CLASS2 (_p, PCI_CLASS_SERIAL, PCI_CLASS_SERIAL_USB) + +#define HEADER_TYPE_DEVICE 0x00 +#define HEADER_TYPE_PCI_TO_PCI_BRIDGE 0x01 +#define HEADER_TYPE_CARDBUS_BRIDGE 0x02 + +#define HEADER_TYPE_MULTI_FUNCTION 0x80 +#define HEADER_LAYOUT_CODE 0x7f + +#define IS_PCI_BRIDGE(_p) (((_p)->Hdr.HeaderType & HEADER_LAYOUT_CODE) == (HEADER_TYPE_PCI_TO_PCI_BRIDGE)) +#define IS_CARDBUS_BRIDGE(_p) (((_p)->Hdr.HeaderType & HEADER_LAYOUT_CODE) == (HEADER_TYPE_CARDBUS_BRIDGE)) +#define IS_PCI_MULTI_FUNC(_p) ((_p)->Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION) + +#define PCI_DEVICE_ROMBAR 0x30 +#define PCI_BRIDGE_ROMBAR 0x38 + +#define PCI_MAX_BAR 6 +#define PCI_MAX_CONFIG_OFFSET 0x100 +// +// bugbug: this is supported in PCI spec v2.3 +// +#define PCI_EXP_MAX_CONFIG_OFFSET 0x1000 + +#define PCI_VENDOR_ID_OFFSET 0x00 +#define PCI_DEVICE_ID_OFFSET 0x02 +#define PCI_COMMAND_OFFSET 0x04 +#define PCI_PRIMARY_STATUS_OFFSET 0x06 +#define PCI_REVISION_ID_OFFSET 0x08 +#define PCI_CLASSCODE_OFFSET 0x09 +#define PCI_CACHELINE_SIZE_OFFSET 0x0C +#define PCI_LATENCY_TIMER_OFFSET 0x0D +#define PCI_HEADER_TYPE_OFFSET 0x0E +#define PCI_BIST_OFFSET 0x0F + +#define PCI_BRIDGE_CONTROL_REGISTER_OFFSET 0x3E +#define PCI_BRIDGE_STATUS_REGISTER_OFFSET 0x1E + +#define PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET 0x18 +#define PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET 0x19 +#define PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET 0x1a + +typedef struct { + UINT8 Register; + UINT8 Function; + UINT8 Device; + UINT8 Bus; + UINT8 Reserved[4]; +} DEFIO_PCI_ADDR; + +typedef union { + struct { + UINT32 Reg : 8; + UINT32 Func : 3; + UINT32 Dev : 5; + UINT32 Bus : 8; + UINT32 Reserved : 7; + UINT32 Enable : 1; + } Bits; + UINT32 Uint32; +} PCI_CONFIG_ACCESS_CF8; + +#pragma pack() + +#define EFI_ROOT_BRIDGE_LIST 'eprb' +#define PCI_EXPANSION_ROM_HEADER_SIGNATURE 0xaa55 +#define EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE 0x0EF1 +#define PCI_DATA_STRUCTURE_SIGNATURE EFI_SIGNATURE_32 ('P', 'C', 'I', 'R') +#define PCI_CODE_TYPE_PCAT_IMAGE 0x00 +#define PCI_CODE_TYPE_EFI_IMAGE 0x03 +#define EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED 0x0001 + +#define EFI_PCI_COMMAND_IO_SPACE 0x0001 +#define EFI_PCI_COMMAND_MEMORY_SPACE 0x0002 +#define EFI_PCI_COMMAND_BUS_MASTER 0x0004 +#define EFI_PCI_COMMAND_SPECIAL_CYCLE 0x0008 +#define EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE 0x0010 +#define EFI_PCI_COMMAND_VGA_PALETTE_SNOOP 0x0020 +#define EFI_PCI_COMMAND_PARITY_ERROR_RESPOND 0x0040 +#define EFI_PCI_COMMAND_STEPPING_CONTROL 0x0080 +#define EFI_PCI_COMMAND_SERR 0x0100 +#define EFI_PCI_COMMAND_FAST_BACK_TO_BACK 0x0200 + +#define EFI_PCI_BRIDGE_CONTROL_PARITY_ERROR_RESPONSE 0x0001 +#define EFI_PCI_BRIDGE_CONTROL_SERR 0x0002 +#define EFI_PCI_BRIDGE_CONTROL_ISA 0x0004 +#define EFI_PCI_BRIDGE_CONTROL_VGA 0x0008 +#define EFI_PCI_BRIDGE_CONTROL_VGA_16 0x0010 +#define EFI_PCI_BRIDGE_CONTROL_MASTER_ABORT 0x0020 +#define EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS 0x0040 +#define EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK 0x0080 +#define EFI_PCI_BRIDGE_CONTROL_PRIMARY_DISCARD_TIMER 0x0100 +#define EFI_PCI_BRIDGE_CONTROL_SECONDARY_DISCARD_TIMER 0x0200 +#define EFI_PCI_BRIDGE_CONTROL_TIMER_STATUS 0x0400 +#define EFI_PCI_BRIDGE_CONTROL_DISCARD_TIMER_SERR 0x0800 + +// +// Following are the PCI-CARDBUS bridge control bit +// +#define EFI_PCI_BRIDGE_CONTROL_IREQINT_ENABLE 0x0080 +#define EFI_PCI_BRIDGE_CONTROL_RANGE0_MEMORY_TYPE 0x0100 +#define EFI_PCI_BRIDGE_CONTROL_RANGE1_MEMORY_TYPE 0x0200 +#define EFI_PCI_BRIDGE_CONTROL_WRITE_POSTING_ENABLE 0x0400 + +// +// Following are the PCI status control bit +// +#define EFI_PCI_STATUS_CAPABILITY 0x0010 +#define EFI_PCI_STATUS_66MZ_CAPABLE 0x0020 +#define EFI_PCI_FAST_BACK_TO_BACK_CAPABLE 0x0080 +#define EFI_PCI_MASTER_DATA_PARITY_ERROR 0x0100 + +#define EFI_PCI_CAPABILITY_PTR 0x34 +#define EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR 0x14 + +#pragma pack(1) +typedef struct { + UINT16 Signature; // 0xaa55 + UINT8 Reserved[0x16]; + UINT16 PcirOffset; +} PCI_EXPANSION_ROM_HEADER; + +typedef struct { + UINT16 Signature; // 0xaa55 + UINT16 InitializationSize; + UINT32 EfiSignature; // 0x0EF1 + UINT16 EfiSubsystem; + UINT16 EfiMachineType; + UINT16 CompressionType; + UINT8 Reserved[8]; + UINT16 EfiImageHeaderOffset; + UINT16 PcirOffset; +} EFI_PCI_EXPANSION_ROM_HEADER; + +typedef struct { + UINT16 Signature; // 0xaa55 + UINT8 Size512; + UINT8 Reserved[15]; + UINT16 PcirOffset; +} EFI_LEGACY_EXPANSION_ROM_HEADER; + +typedef union { + UINT8 *Raw; + PCI_EXPANSION_ROM_HEADER *Generic; + EFI_PCI_EXPANSION_ROM_HEADER *Efi; + EFI_LEGACY_EXPANSION_ROM_HEADER *PcAt; +} EFI_PCI_ROM_HEADER; + +typedef struct { + UINT32 Signature; // "PCIR" + UINT16 VendorId; + UINT16 DeviceId; + UINT16 Reserved0; + UINT16 Length; + UINT8 Revision; + UINT8 ClassCode[3]; + UINT16 ImageLength; + UINT16 CodeRevision; + UINT8 CodeType; + UINT8 Indicator; + UINT16 Reserved1; +} PCI_DATA_STRUCTURE; + +// +// PCI Capability List IDs and records +// +#define EFI_PCI_CAPABILITY_ID_PMI 0x01 +#define EFI_PCI_CAPABILITY_ID_AGP 0x02 +#define EFI_PCI_CAPABILITY_ID_VPD 0x03 +#define EFI_PCI_CAPABILITY_ID_SLOTID 0x04 +#define EFI_PCI_CAPABILITY_ID_MSI 0x05 +#define EFI_PCI_CAPABILITY_ID_HOTPLUG 0x06 +#define EFI_PCI_CAPABILITY_ID_PCIX 0x07 +// +// bugbug: this ID is defined in PCI spec v2.3 +// +#define EFI_PCI_CAPABILITY_ID_PCIEXP 0x10 + +typedef struct { + UINT8 CapabilityID; + UINT8 NextItemPtr; +} EFI_PCI_CAPABILITY_HDR; + +// +// Capability EFI_PCI_CAPABILITY_ID_PMI +// +typedef struct { + EFI_PCI_CAPABILITY_HDR Hdr; + UINT16 PMC; + UINT16 PMCSR; + UINT8 BridgeExtention; + UINT8 Data; +} EFI_PCI_CAPABILITY_PMI; + +// +// Capability EFI_PCI_CAPABILITY_ID_AGP +// +typedef struct { + EFI_PCI_CAPABILITY_HDR Hdr; + UINT8 Rev; + UINT8 Reserved; + UINT32 Status; + UINT32 Command; +} EFI_PCI_CAPABILITY_AGP; + +// +// Capability EFI_PCI_CAPABILITY_ID_VPD +// +typedef struct { + EFI_PCI_CAPABILITY_HDR Hdr; + UINT16 AddrReg; + UINT32 DataReg; +} EFI_PCI_CAPABILITY_VPD; + +// +// Capability EFI_PCI_CAPABILITY_ID_SLOTID +// +typedef struct { + EFI_PCI_CAPABILITY_HDR Hdr; + UINT8 ExpnsSlotReg; + UINT8 ChassisNo; +} EFI_PCI_CAPABILITY_SLOTID; + +// +// Capability EFI_PCI_CAPABILITY_ID_MSI +// +typedef struct { + EFI_PCI_CAPABILITY_HDR Hdr; + UINT16 MsgCtrlReg; + UINT32 MsgAddrReg; + UINT16 MsgDataReg; +} EFI_PCI_CAPABILITY_MSI32; + +typedef struct { + EFI_PCI_CAPABILITY_HDR Hdr; + UINT16 MsgCtrlReg; + UINT32 MsgAddrRegLsdw; + UINT32 MsgAddrRegMsdw; + UINT16 MsgDataReg; +} EFI_PCI_CAPABILITY_MSI64; + +// +// Capability EFI_PCI_CAPABILITY_ID_HOTPLUG +// +typedef struct { + EFI_PCI_CAPABILITY_HDR Hdr; + // + // not finished - fields need to go here + // +} EFI_PCI_CAPABILITY_HOTPLUG; + +// +// Capability EFI_PCI_CAPABILITY_ID_PCIX +// +typedef struct { + EFI_PCI_CAPABILITY_HDR Hdr; + UINT16 CommandReg; + UINT32 StatusReg; +} EFI_PCI_CAPABILITY_PCIX; + +typedef struct { + EFI_PCI_CAPABILITY_HDR Hdr; + UINT16 SecStatusReg; + UINT32 StatusReg; + UINT32 SplitTransCtrlRegUp; + UINT32 SplitTransCtrlRegDn; +} EFI_PCI_CAPABILITY_PCIX_BRDG; + +#define DEVICE_ID_NOCARE 0xFFFF + +#define PCI_ACPI_UNUSED 0 +#define PCI_BAR_NOCHANGE 0 +#define PCI_BAR_OLD_ALIGN 0xFFFFFFFFFFFFFFFFULL +#define PCI_BAR_EVEN_ALIGN 0xFFFFFFFFFFFFFFFEULL +#define PCI_BAR_SQUAD_ALIGN 0xFFFFFFFFFFFFFFFDULL +#define PCI_BAR_DQUAD_ALIGN 0xFFFFFFFFFFFFFFFCULL + +#define PCI_BAR_IDX0 0x00 +#define PCI_BAR_IDX1 0x01 +#define PCI_BAR_IDX2 0x02 +#define PCI_BAR_IDX3 0x03 +#define PCI_BAR_IDX4 0x04 +#define PCI_BAR_IDX5 0x05 +#define PCI_BAR_ALL 0xFF + +#pragma pack(pop) + +#endif diff --git a/Tools/CodeTools/Source/Include/Library/PeCoffLib.h b/Tools/CodeTools/Source/Include/Library/PeCoffLib.h new file mode 100644 index 0000000000..08e8195a8a --- /dev/null +++ b/Tools/CodeTools/Source/Include/Library/PeCoffLib.h @@ -0,0 +1,131 @@ +/** @file + Memory Only PE COFF loader + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: PeCoffLib.h + +**/ + +#ifndef __BASE_PE_COFF_LIB_H__ +#define __BASE_PE_COFF_LIB_H__ + +// +// Return status codes from the PE/COFF Loader services +// BUGBUG: Find where used and see if can be replaced by RETURN_STATUS codes +// +#define IMAGE_ERROR_SUCCESS 0 +#define IMAGE_ERROR_IMAGE_READ 1 +#define IMAGE_ERROR_INVALID_PE_HEADER_SIGNATURE 2 +#define IMAGE_ERROR_INVALID_MACHINE_TYPE 3 +#define IMAGE_ERROR_INVALID_SUBSYSTEM 4 +#define IMAGE_ERROR_INVALID_IMAGE_ADDRESS 5 +#define IMAGE_ERROR_INVALID_IMAGE_SIZE 6 +#define IMAGE_ERROR_INVALID_SECTION_ALIGNMENT 7 +#define IMAGE_ERROR_SECTION_NOT_LOADED 8 +#define IMAGE_ERROR_FAILED_RELOCATION 9 +#define IMAGE_ERROR_FAILED_ICACHE_FLUSH 10 + + +// +// PE/COFF Loader Read Function passed in by caller +// +typedef +RETURN_STATUS +(EFIAPI *PE_COFF_LOADER_READ_FILE) ( + IN VOID *FileHandle, + IN UINTN FileOffset, + IN OUT UINTN *ReadSize, + OUT VOID *Buffer + ); + +// +// Context structure used while PE/COFF image is being loaded and relocated +// +typedef struct { + PHYSICAL_ADDRESS ImageAddress; + UINT64 ImageSize; + PHYSICAL_ADDRESS DestinationAddress; + PHYSICAL_ADDRESS EntryPoint; + PE_COFF_LOADER_READ_FILE ImageRead; + VOID *Handle; + VOID *FixupData; + UINT32 SectionAlignment; + UINT32 PeCoffHeaderOffset; + UINT32 DebugDirectoryEntryRva; + VOID *CodeView; + CHAR8 *PdbPointer; + UINTN SizeOfHeaders; + UINT32 ImageCodeMemoryType; + UINT32 ImageDataMemoryType; + UINT32 ImageError; + UINTN FixupDataSize; + UINT16 Machine; + UINT16 ImageType; + BOOLEAN RelocationsStripped; + BOOLEAN IsTeImage; +} PE_COFF_LOADER_IMAGE_CONTEXT; + + +/** + Retrieves information on a PE/COFF image + + @param ImageContext The context of the image being loaded + + @retval EFI_SUCCESS The information on the PE/COFF image was collected. + @retval EFI_INVALID_PARAMETER ImageContext is NULL. + @retval EFI_UNSUPPORTED The PE/COFF image is not supported. + @retval Otherwise The error status from reading the PE/COFF image using the + ImageContext->ImageRead() function + +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderGetImageInfo ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +; + +/** + Relocates a PE/COFF image in memory + + @param ImageContext Contains information on the loaded image to relocate + + @retval EFI_SUCCESS if the PE/COFF image was relocated + @retval EFI_LOAD_ERROR if the image is not a valid PE/COFF image + @retval EFI_UNSUPPORTED not support + +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderRelocateImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +; + +/** + Loads a PE/COFF image into memory + + @param ImageContext Contains information on image to load into memory + + @retval EFI_SUCCESS if the PE/COFF image was loaded + @retval EFI_BUFFER_TOO_SMALL if the caller did not provide a large enough buffer + @retval EFI_LOAD_ERROR if the image is a runtime driver with no relocations + @retval EFI_INVALID_PARAMETER if the image address is invalid + +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderLoadImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +; + +#endif diff --git a/Tools/CodeTools/Source/Include/Library/PrintLib.h b/Tools/CodeTools/Source/Include/Library/PrintLib.h new file mode 100644 index 0000000000..9c65459a59 --- /dev/null +++ b/Tools/CodeTools/Source/Include/Library/PrintLib.h @@ -0,0 +1,406 @@ +/** @file + Library that provides print services + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: PrintLib.h + +**/ + +#ifndef __PRINT_LIB_H__ +#define __PRINT_LIB_H__ + +// +// Print primitives +// +#define LEFT_JUSTIFY 0x01 +#define COMMA_TYPE 0x08 +#define PREFIX_ZERO 0x20 + +/** + Produces a Null-terminated Unicode string in an output buffer based on + a Null-terminated Unicode format string and a VA_LIST argument list + + Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer + and BufferSize. + The Unicode string is produced by parsing the format string specified by FormatString. + Arguments are pulled from the variable argument list specified by Marker based on the + contents of the format string. + The length of the produced output buffer is returned. + If BufferSize is 0, then no output buffer is produced and 0 is returned. + + If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT(). + If BufferSize is not 0 and FormatString is NULL, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than + PcdMaximumUnicodeStringLength Unicode characters, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string + contains more than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT(). + + @param StartOfBuffer APointer to the output buffer for the produced Null-terminated + Unicode string. + @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. + @param FormatString Null-terminated Unicode format string. + @param Marker VA_LIST marker for the variable argument list. + + @return return Length of the produced output buffer. + +**/ +UINTN +EFIAPI +UnicodeVSPrint ( + OUT CHAR16 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR16 *FormatString, + IN VA_LIST Marker + ); + +/** + Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated + Unicode format string and variable argument list. + + Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer + and BufferSize. + The Unicode string is produced by parsing the format string specified by FormatString. + Arguments are pulled from the variable argument list based on the contents of the format string. + The length of the produced output buffer is returned. + If BufferSize is 0, then no output buffer is produced and 0 is returned. + + If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT(). + If BufferSize is not 0 and FormatString is NULL, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than + PcdMaximumUnicodeStringLength Unicode characters, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string + contains more than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT(). + + @param StartOfBuffer APointer to the output buffer for the produced Null-terminated + Unicode string. + @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. + @param FormatString Null-terminated Unicode format string. + + @return Length of the produced output buffer. + +**/ +UINTN +EFIAPI +UnicodeSPrint ( + OUT CHAR16 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR16 *FormatString, + ... + ); + +/** + Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated + ASCII format string and a VA_LIST argument list + + Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer + and BufferSize. + The Unicode string is produced by parsing the format string specified by FormatString. + Arguments are pulled from the variable argument list specified by Marker based on the + contents of the format string. + The length of the produced output buffer is returned. + If BufferSize is 0, then no output buffer is produced and 0 is returned. + + If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT(). + If BufferSize is not 0 and FormatString is NULL, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than + PcdMaximumUnicodeStringLength Unicode characters, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string + contains more than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT(). + + @param StartOfBuffer APointer to the output buffer for the produced Null-terminated + Unicode string. + @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. + @param FormatString Null-terminated Unicode format string. + @param Marker VA_LIST marker for the variable argument list. + + @return Length of the produced output buffer. + +**/ +UINTN +EFIAPI +UnicodeVSPrintAsciiFormat ( + OUT CHAR16 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR8 *FormatString, + IN VA_LIST Marker + ); + +/** + Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated + ASCII format string and variable argument list. + + Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer + and BufferSize. + The Unicode string is produced by parsing the format string specified by FormatString. + Arguments are pulled from the variable argument list based on the contents of the + format string. + The length of the produced output buffer is returned. + If BufferSize is 0, then no output buffer is produced and 0 is returned. + + If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT(). + If BufferSize is not 0 and FormatString is NULL, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than + PcdMaximumUnicodeStringLength Unicode characters, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string + contains more than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT(). + + @param StartOfBuffer APointer to the output buffer for the produced Null-terminated + Unicode string. + @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. + @param FormatString Null-terminated Unicode format string. + + @return Length of the produced output buffer. + +**/ +UINTN +EFIAPI +UnicodeSPrintAsciiFormat ( + OUT CHAR16 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR8 *FormatString, + ... + ); + +/** + Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated + ASCII format string and a VA_LIST argument list. + + Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer + and BufferSize. + The ASCII string is produced by parsing the format string specified by FormatString. + Arguments are pulled from the variable argument list specified by Marker based on + the contents of the format string. + The length of the produced output buffer is returned. + If BufferSize is 0, then no output buffer is produced and 0 is returned. + + If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT(). + If BufferSize is not 0 and FormatString is NULL, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than + PcdMaximumUnicodeStringLength ASCII characters, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string + contains more than PcdMaximumUnicodeStringLength ASCII characters, then ASSERT(). + + @param StartOfBuffer APointer to the output buffer for the produced Null-terminated + ASCII string. + @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. + @param FormatString Null-terminated Unicode format string. + @param Marker VA_LIST marker for the variable argument list. + + @return Length of the produced output buffer. + +**/ +UINTN +EFIAPI +AsciiVSPrint ( + OUT CHAR8 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR8 *FormatString, + IN VA_LIST Marker + ); + +/** + Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated + ASCII format string and variable argument list. + + Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer + and BufferSize. + The ASCII string is produced by parsing the format string specified by FormatString. + Arguments are pulled from the variable argument list based on the contents of the + format string. + The length of the produced output buffer is returned. + If BufferSize is 0, then no output buffer is produced and 0 is returned. + + If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT(). + If BufferSize is not 0 and FormatString is NULL, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than + PcdMaximumUnicodeStringLength ASCII characters, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string + contains more than PcdMaximumUnicodeStringLength ASCII characters, then ASSERT(). + + @param StartOfBuffer APointer to the output buffer for the produced Null-terminated + ASCII string. + @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. + @param FormatString Null-terminated Unicode format string. + + @return Length of the produced output buffer. + +**/ +UINTN +EFIAPI +AsciiSPrint ( + OUT CHAR8 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR8 *FormatString, + ... + ); + +/** + Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated + ASCII format string and a VA_LIST argument list. + + Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer + and BufferSize. + The ASCII string is produced by parsing the format string specified by FormatString. + Arguments are pulled from the variable argument list specified by Marker based on + the contents of the format string. + The length of the produced output buffer is returned. + If BufferSize is 0, then no output buffer is produced and 0 is returned. + + If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT(). + If BufferSize is not 0 and FormatString is NULL, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than + PcdMaximumUnicodeStringLength ASCII characters, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string + contains more than PcdMaximumUnicodeStringLength ASCII characters, then ASSERT(). + + @param StartOfBuffer APointer to the output buffer for the produced Null-terminated + ASCII string. + @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. + @param FormatString Null-terminated Unicode format string. + @param Marker VA_LIST marker for the variable argument list. + + @return Length of the produced output buffer. + +**/ +UINTN +EFIAPI +AsciiVSPrintUnicodeFormat ( + OUT CHAR8 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR16 *FormatString, + IN VA_LIST Marker + ); + +/** + Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated + ASCII format string and variable argument list. + + Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer + and BufferSize. + The ASCII string is produced by parsing the format string specified by FormatString. + Arguments are pulled from the variable argument list based on the contents of the + format string. + The length of the produced output buffer is returned. + If BufferSize is 0, then no output buffer is produced and 0 is returned. + + If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT(). + If BufferSize is not 0 and FormatString is NULL, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than + PcdMaximumUnicodeStringLength ASCII characters, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string + contains more than PcdMaximumUnicodeStringLength ASCII characters, then ASSERT(). + + @param StartOfBuffer APointer to the output buffer for the produced Null-terminated + ASCII string. + @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. + @param FormatString Null-terminated Unicode format string. + + @return Length of the produced output buffer. + +**/ +UINTN +EFIAPI +AsciiSPrintUnicodeFormat ( + OUT CHAR8 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR16 *FormatString, + ... + ); + +/** + Converts a decimal value to a Null-terminated Unicode string. + + Converts the decimal number specified by Value to a Null-terminated Unicode + string specified by Buffer containing at most Width characters. + If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed. + The total number of characters placed in Buffer is returned. + If the conversion contains more than Width characters, then only the first + Width characters are returned, and the total number of characters + required to perform the conversion is returned. + Additional conversion parameters are specified in Flags. + The Flags bit LEFT_JUSTIFY is always ignored. + All conversions are left justified in Buffer. + If Width is 0, PREFIX_ZERO is ignored in Flags. + If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas + are inserted every 3rd digit starting from the right. + If Value is < 0, then the fist character in Buffer is a '-'. + If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, + then Buffer is padded with '0' characters so the combination of the optional '-' + sign character, '0' characters, digit characters for Value, and the Null-terminator + add up to Width characters. + + If Buffer is NULL, then ASSERT(). + If unsupported bits are set in Flags, then ASSERT(). + If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT() + + @param Buffer Pointer to the output buffer for the produced Null-terminated + Unicode string. + @param Flags The bitmask of flags that specify left justification, zero pad, and commas. + @param Value The 64-bit signed value to convert to a string. + @param Width The maximum number of Unicode characters to place in Buffer. + + @return Total number of characters required to perform the conversion. + +**/ +UINTN +EFIAPI +UnicodeValueToString ( + IN OUT CHAR16 *Buffer, + IN UINTN Flags, + IN INT64 Value, + IN UINTN Width + ); + +/** + Converts a decimal value to a Null-terminated ASCII string. + + Converts the decimal number specified by Value to a Null-terminated ASCII string + specified by Buffer containing at most Width characters. + If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed. + The total number of characters placed in Buffer is returned. + If the conversion contains more than Width characters, then only the first Width + characters are returned, and the total number of characters required to perform + the conversion is returned. + Additional conversion parameters are specified in Flags. + The Flags bit LEFT_JUSTIFY is always ignored. + All conversions are left justified in Buffer. + If Width is 0, PREFIX_ZERO is ignored in Flags. + If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas + are inserted every 3rd digit starting from the right. + If Value is < 0, then the fist character in Buffer is a '-'. + If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then Buffer + is padded with '0' characters so the combination of the optional '-' + sign character, '0' characters, digit characters for Value, and the + Null-terminator add up to Width characters. + + If Buffer is NULL, then ASSERT(). + If unsupported bits are set in Flags, then ASSERT(). + If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT() + + @param Buffer Pointer to the output buffer for the produced Null-terminated + ASCII string. + @param Flags The bitmask of flags that specify left justification, zero pad, and commas. + @param Value The 64-bit signed value to convert to a string. + @param Width The maximum number of ASCII characters to place in Buffer. + + @return Total number of characters required to perform the conversion. + +**/ +UINTN +EFIAPI +AsciiValueToString ( + IN OUT CHAR8 *Buffer, + IN UINTN Flags, + IN INT64 Value, + IN UINTN Width + ); + +#endif diff --git a/Tools/CodeTools/Source/Include/Protocol/DevicePath.h b/Tools/CodeTools/Source/Include/Protocol/DevicePath.h new file mode 100644 index 0000000000..d01999904f --- /dev/null +++ b/Tools/CodeTools/Source/Include/Protocol/DevicePath.h @@ -0,0 +1,94 @@ +/** @file + The device path protocol as defined in EFI 1.0. + + The device path represents a programatic path to a device. It's the view + from a software point of view. It also must persist from boot to boot, so + it can not contain things like PCI bus numbers that change from boot to boot. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: DevicePath.h + +**/ + +#ifndef __EFI_DEVICE_PATH_PROTOCOL_H__ +#define __EFI_DEVICE_PATH_PROTOCOL_H__ + +// +// Device Path protocol +// +#define EFI_DEVICE_PATH_PROTOCOL_GUID \ + { \ + 0x9576e91, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +#pragma pack(1) + +typedef struct { + UINT8 Type; + UINT8 SubType; + UINT8 Length[2]; +} EFI_DEVICE_PATH_PROTOCOL; + +#pragma pack() + +#define EFI_DP_TYPE_MASK 0x7F +#define EFI_DP_TYPE_UNPACKED 0x80 +#define END_DEVICE_PATH_TYPE 0x7f + +#define EFI_END_ENTIRE_DEVICE_PATH 0xff +#define EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff +#define EFI_END_INSTANCE_DEVICE_PATH 0x01 +#define END_ENTIRE_DEVICE_PATH_SUBTYPE EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE +#define END_INSTANCE_DEVICE_PATH_SUBTYPE EFI_END_INSTANCE_DEVICE_PATH + +#define EFI_END_DEVICE_PATH_LENGTH (sizeof (EFI_DEVICE_PATH_PROTOCOL)) +#define END_DEVICE_PATH_LENGTH EFI_END_DEVICE_PATH_LENGTH + +#define DP_IS_END_TYPE(a) +#define DP_IS_END_SUBTYPE(a) (((a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE) +#define DevicePathSubType(a) ((a)->SubType) +#define IsDevicePathUnpacked(a) ((a)->Type & EFI_DP_TYPE_UNPACKED) + +#define EfiDevicePathNodeLength(a) (((a)->Length[0]) | ((a)->Length[1] << 8)) +#define DevicePathNodeLength(a) (EfiDevicePathNodeLength(a)) +#define EfiNextDevicePathNode(a) ((EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) (a)) + EfiDevicePathNodeLength (a))) +#define NextDevicePathNode(a) (EfiNextDevicePathNode(a)) + +#define EfiDevicePathType(a) (((a)->Type) & EFI_DP_TYPE_MASK) +#define DevicePathType(a) (EfiDevicePathType(a)) +#define EfiIsDevicePathEndType(a) (EfiDevicePathType (a) == END_DEVICE_PATH_TYPE) +#define IsDevicePathEndType(a) (EfiIsDevicePathEndType(a)) + + +#define EfiIsDevicePathEndSubType(a) ((a)->SubType == EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE) +#define IsDevicePathEndSubType(a) (EfiIsDevicePathEndSubType(a)) +#define EfiIsDevicePathEndInstanceSubType(a) ((a)->SubType == EFI_END_INSTANCE_DEVICE_PATH) + +#define EfiIsDevicePathEnd(a) (EfiIsDevicePathEndType (a) && EfiIsDevicePathEndSubType (a)) +#define IsDevicePathEnd(a) (EfiIsDevicePathEnd(a)) +#define EfiIsDevicePathEndInstance(a) (EfiIsDevicePathEndType (a) && EfiIsDevicePathEndInstanceSubType (a)) + + +#define SetDevicePathNodeLength(a,l) { \ + (a)->Length[0] = (UINT8) (l); \ + (a)->Length[1] = (UINT8) ((l) >> 8); \ + } + +#define SetDevicePathEndNode(a) { \ + (a)->Type = END_DEVICE_PATH_TYPE; \ + (a)->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; \ + (a)->Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL); \ + (a)->Length[1] = 0; \ + } + +extern EFI_GUID gEfiDevicePathProtocolGuid; + +#endif diff --git a/Tools/CodeTools/Source/Include/Protocol/GuidedSectionExtraction.h b/Tools/CodeTools/Source/Include/Protocol/GuidedSectionExtraction.h new file mode 100644 index 0000000000..d98c56a7bc --- /dev/null +++ b/Tools/CodeTools/Source/Include/Protocol/GuidedSectionExtraction.h @@ -0,0 +1,102 @@ +/** @file + This file declares GUIDed section extraction protocol. + + This interface provides a means of decoding a GUID defined encapsulation + section. There may be multiple different GUIDs associated with the GUIDed + section extraction protocol. That is, all instances of the GUIDed section + extraction protocol must have the same interface structure. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: GuidedSectionExtraction.h + + @par Revision Reference: + This protocol is defined in Firmware Volume Specification. + Version 0.9 + +**/ + +#ifndef __GUIDED_SECTION_EXTRACTION_PROTOCOL_H__ +#define __GUIDED_SECTION_EXTRACTION_PROTOCOL_H__ + + +// +// Protocol GUID definition. Each GUIDed section extraction protocol has the +// same interface but with different GUID. All the GUIDs is defined here. +// May add multiple GUIDs here. +// +#define EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID \ + { \ + 0xFC1BCDB0, 0x7D31, 0x49aa, {0x93, 0x6A, 0xA4, 0x60, 0x0D, 0x9D, 0xD0, 0x83 } \ + } + +// +// Forward reference for pure ANSI compatability +// +typedef struct _EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL; + +// +// Protocol member functions +// +/** + Processes the input section and returns the data contained therein along + with the authentication status. + + @param This Indicates the EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL instance. + @param InputSection Buffer containing the input GUIDed section to be processed. + @param OutputBuffer *OutputBuffer is allocated from boot services pool memory + and contains the new section stream. + @param OutputSize A pointer to a caller-allocated UINTN in which the size + of *OutputBuffer allocation is stored. + @param AuthenticationStatus A pointer to a caller-allocated UINT32 that + indicates the authentication status of the output buffer. + + @retval EFI_SUCCESS The InputSection was successfully processed and the + section contents were returned. + @retval EFI_OUT_OF_RESOURCES The system has insufficient resources to + process the request. + @retval EFI_INVALID_PARAMETER The GUID in InputSection does not match + this instance of the GUIDed Section Extraction Protocol. + +**/ + +typedef +EFI_STATUS +(EFIAPI *EFI_EXTRACT_GUIDED_SECTION) ( + IN EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *This, + IN VOID *InputSection, + OUT VOID **OutputBuffer, + OUT UINTN *OutputSize, + OUT UINT32 *AuthenticationStatus + ); + +// +// Protocol definition +// +/** + @par Protocol Description: + If a GUID-defined section is encountered when doing section extraction, + the section extraction driver calls the appropriate instance of the GUIDed + Section Extraction Protocol to extract the section stream contained therein. + + @param ExtractSection + Takes the GUIDed section as input and produces the section stream data. + +**/ +struct _EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL { + EFI_EXTRACT_GUIDED_SECTION ExtractSection; +}; + +// +// may add other GUID here +// +extern EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid; + +#endif diff --git a/Tools/CodeTools/Source/Include/Protocol/Hii.h b/Tools/CodeTools/Source/Include/Protocol/Hii.h new file mode 100644 index 0000000000..ceeba1c7fb --- /dev/null +++ b/Tools/CodeTools/Source/Include/Protocol/Hii.h @@ -0,0 +1,1024 @@ +/** @file + This file defines the Human Interface Infrastructure protocol which will + be used by resources which want to publish IFR/Font/String data and have it + collected by the Configuration engine. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: Hii.h + + @par Revision Reference: + This protocol is defined in HII spec 0.92. + +**/ + +#ifndef __HII_H__ +#define __HII_H__ + + +#define EFI_HII_PROTOCOL_GUID \ + { \ + 0xea816d2c, 0xcee5, 0x4f02, {0x99, 0xb5, 0xd3, 0x90, 0x5c, 0xbb, 0xd0, 0x77 } \ + } + +// BugBug: +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// If UGA goes away we need to put this some place. I'm not sure where? +// +//typedef struct { +// UINT8 Blue; +// UINT8 Green; +// UINT8 Red; +// UINT8 Reserved; +//} EFI_UGA_PIXEL; + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// + +typedef struct _EFI_HII_PROTOCOL EFI_HII_PROTOCOL; + +// +// Global definition +// +#define NARROW_CHAR 0xFFF0 +#define WIDE_CHAR 0xFFF1 +#define NON_BREAKING_CHAR 0xFFF2 +#define GLYPH_WIDTH 8 +#define GLYPH_HEIGHT 19 + +#define EFI_HII_FONT 1 +#define EFI_HII_STRING 2 +#define EFI_HII_IFR 3 +#define EFI_HII_KEYBOARD 4 +#define EFI_HII_HANDLES 5 +#define EFI_HII_VARIABLE 6 +#define EFI_HII_DEVICE_PATH 7 + + +// References to string tokens must use this macro to enable scanning for +// token usages. +// +#define STRING_TOKEN(t) t + +// +// The following types are currently defined: +// +typedef UINT16 EFI_FORM_ID; +typedef UINT16 EFI_FORM_LABEL; + +#pragma pack(1) + +typedef struct { + UINT32 Length; + UINT16 Type; +} EFI_HII_PACK_HEADER; + +// +// A form list consists of a large variety of structure +// possibilities so to represent the binary blob of data +// associated with a package of forms, we will assume a +// pointer to a self-describing data buffer. +// +typedef struct { + EFI_HII_PACK_HEADER Header; +} EFI_HII_IFR_PACK; + +typedef struct { + EFI_HII_PACK_HEADER Header; // Must be filled in + EFI_HANDLE ImageHandle; // Must be filled in + EFI_HANDLE DeviceHandle; // Optional + EFI_HANDLE ControllerHandle; // Optional + EFI_HANDLE CallbackHandle; // Optional + EFI_HANDLE COBExportHandle; // Optional +} EFI_HII_HANDLE_PACK; + +// +// ******************************************************** +// EFI_VARIABLE_CONTENTS +// ******************************************************** +// +typedef struct { + EFI_HII_PACK_HEADER Header; + EFI_GUID VariableGuid; + UINT32 VariableNameLength; + UINT16 VariableId; + // + // CHAR16 VariableName[]; //Null-terminated + // +} EFI_HII_VARIABLE_PACK; + +// +// ******************************************************** +// EFI_DEVICE_PATH_PACK +// ******************************************************** +// +typedef struct { + EFI_HII_PACK_HEADER Header; + // + // EFI_DEVICE_PATH DevicePath[]; + // +} EFI_HII_DEVICE_PATH_PACK; + +// +// ******************************************************** +// EFI_HII_DATA_TABLE +// ******************************************************** +// +typedef struct { + EFI_HII_HANDLE HiiHandle; + EFI_GUID PackageGuid; + UINT32 DataTableSize; + UINT32 IfrDataOffset; + UINT32 StringDataOffset; + UINT32 VariableDataOffset; + UINT32 DevicePathOffset; + UINT32 NumberOfVariableData; + UINT32 NumberOfLanguages; + // + // EFI_HII_DEVICE_PATH_PACK DevicePath[]; + // EFI_HII_VARIABLE_PACK VariableData[]; + // EFI_HII_IFR_PACK IfrData; + // EFI_HII_STRING_PACK StringData[]; + // +} EFI_HII_DATA_TABLE; + +// +// ******************************************************** +// EFI_HII_EXPORT_TABLE +// ******************************************************** +// +typedef struct { + UINT32 NumberOfHiiDataTables; + EFI_GUID Revision; + // + // EFI_HII_DATA_TABLE HiiDataTable[]; + // +} EFI_HII_EXPORT_TABLE; + +typedef struct { + BOOLEAN FormSetUpdate; // If TRUE, next variable is significant + EFI_PHYSICAL_ADDRESS FormCallbackHandle; // If not 0, will update Formset with this info + BOOLEAN FormUpdate; // If TRUE, next variable is significant + UINT16 FormValue; // specify which form is to be updated if FormUpdate value is TRUE. + STRING_REF FormTitle; // If not 0, will update Form with this info + UINT16 DataCount; // The number of Data entries in this structure + UINT8 *Data; // An array of 1+ op-codes, specified by DataCount +} EFI_HII_UPDATE_DATA; + +// +// String attributes +// +#define LANG_RIGHT_TO_LEFT 0x00000001 + +// +// A string package is used to localize strings to a particular +// language. The package is associated with a particular driver +// or set of drivers. Tools are used to associate tokens with +// string references in forms and in programs. These tokens are +// language agnostic. When paired with a language pack (directly +// or indirectly), the string token resolves into an actual +// UNICODE string. The NumStringPointers determines how many +// StringPointers (offset values) there are as well as the total +// number of Strings that are defined. +// +typedef struct { + EFI_HII_PACK_HEADER Header; + RELOFST LanguageNameString; + RELOFST PrintableLanguageName; + UINT32 NumStringPointers; + UINT32 Attributes; + // + // RELOFST StringPointers[]; + // EFI_STRING Strings[]; + // +} EFI_HII_STRING_PACK; + +// +// Glyph Attributes +// +#define EFI_GLYPH_NON_SPACING 1 +#define EFI_GLYPH_WIDE 2 + +typedef struct { + CHAR16 UnicodeWeight; + UINT8 Attributes; + UINT8 GlyphCol1[GLYPH_HEIGHT]; +} EFI_NARROW_GLYPH; + +typedef struct { + CHAR16 UnicodeWeight; + UINT8 Attributes; + UINT8 GlyphCol1[GLYPH_HEIGHT]; + UINT8 GlyphCol2[GLYPH_HEIGHT]; + UINT8 Pad[3]; +} EFI_WIDE_GLYPH; + +// +// A font list consists of a font header followed by a series +// of glyph structures. Note that fonts are not language specific. +// +typedef struct { + EFI_HII_PACK_HEADER Header; + UINT16 NumberOfNarrowGlyphs; + UINT16 NumberOfWideGlyphs; +} EFI_HII_FONT_PACK; + +// +// The IfrData in the EFI_HII_IFR_PACK structure definition +// is variable length, and not really part of the header. To +// simplify from code the size of the header, define an +// identical structure that does not include the IfrData field. +// Then use sizeof() this new structure to determine the +// actual size of the header. +// +typedef struct { + EFI_HII_PACK_HEADER Header; +} EFI_HII_IFR_PACK_HEADER; + +// +// pedef EFI_HII_PACK_HEADER EFI_HII_IFR_PACK_HEADER; +// +typedef enum { + EfiKeyLCtrl, + EfiKeyA0, + EfiKeyLAlt, + EfiKeySpaceBar, + EfiKeyA2, + EfiKeyA3, + EfiKeyA4, + EfiKeyRCtrl, + EfiKeyLeftArrow, + EfiKeyDownArrow, + EfiKeyRightArrow, + EfiKeyZero, + EfiKeyPeriod, + EfiKeyEnter, + EfiKeyLShift, + EfiKeyB0, + EfiKeyB1, + EfiKeyB2, + EfiKeyB3, + EfiKeyB4, + EfiKeyB5, + EfiKeyB6, + EfiKeyB7, + EfiKeyB8, + EfiKeyB9, + EfiKeyB10, + EfiKeyRshift, + EfiKeyUpArrow, + EfiKeyOne, + EfiKeyTwo, + EfiKeyThree, + EfiKeyCapsLock, + EfiKeyC1, + EfiKeyC2, + EfiKeyC3, + EfiKeyC4, + EfiKeyC5, + EfiKeyC6, + EfiKeyC7, + EfiKeyC8, + EfiKeyC9, + EfiKeyC10, + EfiKeyC11, + EfiKeyC12, + EfiKeyFour, + EfiKeyFive, + EfiKeySix, + EfiKeyPlus, + EfiKeyTab, + EfiKeyD1, + EfiKeyD2, + EfiKeyD3, + EfiKeyD4, + EfiKeyD5, + EfiKeyD6, + EfiKeyD7, + EfiKeyD8, + EfiKeyD9, + EfiKeyD10, + EfiKeyD11, + EfiKeyD12, + EfiKeyD13, + EfiKeyDel, + EfiKeyEnd, + EfiKeyPgDn, + EfiKeySeven, + EfiKeyEight, + EfiKeyNine, + EfiKeyE0, + EfiKeyE1, + EfiKeyE2, + EfiKeyE3, + EfiKeyE4, + EfiKeyE5, + EfiKeyE6, + EfiKeyE7, + EfiKeyE8, + EfiKeyE9, + EfiKeyE10, + EfiKeyE11, + EfiKeyE12, + EfiKeyBackSpace, + EfiKeyIns, + EfiKeyHome, + EfiKeyPgUp, + EfiKeyNLck, + EfiKeySlash, + EfiKeyAsterisk, + EfiKeyMinus, + EfiKeyEsc, + EfiKeyF1, + EfiKeyF2, + EfiKeyF3, + EfiKeyF4, + EfiKeyF5, + EfiKeyF6, + EfiKeyF7, + EfiKeyF8, + EfiKeyF9, + EfiKeyF10, + EfiKeyF11, + EfiKeyF12, + EfiKeyPrint, + EfiKeySLck, + EfiKeyPause +} EFI_KEY; + +typedef struct { + EFI_KEY Key; + CHAR16 Unicode; + CHAR16 ShiftedUnicode; + CHAR16 AltGrUnicode; + CHAR16 ShiftedAltGrUnicode; + UINT16 Modifier; +} EFI_KEY_DESCRIPTOR; + +// +// This structure allows a sparse set of keys to be redefined +// or a complete redefinition of the keyboard layout. Most +// keyboards have a lot of commonality in their layouts, therefore +// only defining those keys that need to change from the default +// minimizes the passed in information. +// +// Additionally, when an update occurs, the active keyboard layout +// will be switched to the newly updated keyboard layout. This +// allows for situations that when a keyboard layout driver is +// loaded as part of system initialization, the system will default +// the keyboard behavior to the new layout. +// +// Each call to update the keyboard mapping should contain the +// complete set of key descriptors to be updated, since every +// call to the HII which contains an EFI_HII_KEYBOARD_PACK will +// wipe the previous set of overrides. A call to +// +typedef struct { + EFI_HII_PACK_HEADER Header; + EFI_KEY_DESCRIPTOR *Descriptor; + UINT8 DescriptorCount; +} EFI_HII_KEYBOARD_PACK; + +// +// The EFI_HII_PACKAGES can contain different types of packages just +// after the structure as inline data. +// +typedef struct { + UINTN NumberOfPackages; + EFI_GUID *GuidId; + // + // EFI_HII_HANDLE_PACK *HandlePack; // Only one pack. + // EFI_HII_IFR_PACK *IfrPack; // Only one pack. + // EFI_HII_FONT_PACK *FontPack[]; // Multiple packs ok + // EFI_HII_STRING_PACK *StringPack[]; // Multiple packs ok + // EFI_HII_KEYBOARD_PACK *KeyboardPack[]; // Multiple packs ok + // +} EFI_HII_PACKAGES; + +typedef struct _EFI_HII_VARIABLE_PACK_LIST { + struct _EFI_HII_VARIABLE_PACK_LIST *NextVariablePack; + EFI_HII_VARIABLE_PACK *VariablePack; +} EFI_HII_VARIABLE_PACK_LIST; + +#pragma pack() + +/** + Registers the various packs that are passed in via the Packages parameter. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param Packages A pointer to an EFI_HII_PACKAGES package instance. + + @param Handle A pointer to the EFI_HII_HANDLE instance. + + @retval EFI_SUCCESS Data was extracted from Packages, the database + was updated with the data, and Handle returned successfully. + + @retval EFI_INVALID_PARAMETER The content of Packages was invalid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_NEW_PACK) ( + IN EFI_HII_PROTOCOL *This, + IN EFI_HII_PACKAGES *Packages, + OUT EFI_HII_HANDLE *Handle + ); + +/** + Removes a package from the HII database. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param Handle The handle that was registered to the data that is requested + for removal. + + @retval EFI_SUCCESS The data associated with the Handle was removed + from the HII database. + + @retval EFI_INVALID_PARAMETER The Handle was not valid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_REMOVE_PACK) ( + IN EFI_HII_PROTOCOL *This, + IN EFI_HII_HANDLE Handle + ); + +/** + Determines the handles that are currently active in the database. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param HandleBufferLength On input, a pointer to the length of the handle + buffer. On output, the length of the handle buffer that is required + for the handles found. + + @param Handle An array of EFI_HII_HANDLE instances returned. + + @retval EFI_SUCCESS Handle was updated successfully. + + @retval EFI_BUFFER_TOO_SMALL The HandleBufferLength parameter indicates + that Handle is too small to support the number of handles. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_FIND_HANDLES) ( + IN EFI_HII_PROTOCOL *This, + IN OUT UINT16 *HandleBufferLength, + OUT EFI_HII_HANDLE *Handle + ); + +/** + Exports the contents of the database into a buffer. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param Handle An EFI_HII_HANDLE that corresponds to the desired + handle to export. If the value is 0, the entire database will be exported. + In either case, the data will be exported in a format described by the + structure definition of EFI_HII_EXPORT_TABLE. + + @param BufferSize + On input, a pointer to the length of the buffer. On output, the length + of the buffer that is required for the export data. + + @param Buffer A pointer to a buffer that will contain the results of the export function. + + @retval EFI_SUCCESS The buffer was successfully filled with BufferSize amount of data. + + @retval EFI_BUFFER_TOO_SMALL The value in BufferSize was too small to contain the export data. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_EXPORT) ( + IN EFI_HII_PROTOCOL *This, + IN EFI_HII_HANDLE Handle, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +/** + Remove any new strings that were added after the initial string export + for this handle. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param Handle The handle on which the string resides. + + @retval EFI_SUCCESS Remove strings from the handle successfully. + + @retval EFI_INVALID_PARAMETER The Handle was unknown. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_RESET_STRINGS) ( + IN EFI_HII_PROTOCOL *This, + IN EFI_HII_HANDLE Handle + ); + +/** + Tests if all of the characters in a string have corresponding font characters. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param StringToTest A pointer to a Unicode string. + + @param FirstMissing A pointer to an index into the string. On input, + the index of the first character in the StringToTest to examine. On exit, + the index of the first character encountered for which a glyph is unavailable. + If all glyphs in the string are available, the index is the index of the + terminator of the string. + + @param GlyphBufferSize A pointer to a value. On output, if the function + returns EFI_SUCCESS, it contains the amount of memory that is required to + store the string¡¯s glyph equivalent. + + @retval EFI_SUCCESS All glyphs are available. Note that an empty string + always returns this value. + + @retval EFI_NOT_FOUND A glyph was not found for a character. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_TEST_STRING) ( + IN EFI_HII_PROTOCOL *This, + IN CHAR16 *StringToTest, + IN OUT UINT32 *FirstMissing, + OUT UINT32 *GlyphBufferSize + ); + +/** + Translates a Unicode character into the corresponding font glyph. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param Source A pointer to a Unicode string. + + @param Index On input, the offset into the string from which to fetch + the character.On successful completion, the index is updated to the first + character past the character(s) making up the just extracted glyph. + + @param GlyphBuffer Pointer to an array where the glyphs corresponding + to the characters in the source may be stored. GlyphBuffer is assumed + to be wide enough to accept a wide glyph character. + + @param BitWidth If EFI_SUCCESS was returned, the UINT16 pointed to by + this value is filled with the length of the glyph in pixels. It is unchanged + if the call was unsuccessful. + + @param InternalStatus The cell pointed to by this parameter must be + initialized to zero prior to invoking the call the first time for any string. + + @retval EFI_SUCCESS It worked. + + @retval EFI_NOT_FOUND A glyph for a character was not found. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_GET_GLYPH) ( + IN EFI_HII_PROTOCOL *This, + IN CHAR16 *Source, + IN OUT UINT16 *Index, + OUT UINT8 **GlyphBuffer, + OUT UINT16 *BitWidth, + IN OUT UINT32 *InternalStatus + ); + +/** + Translates a glyph into the format required for input to the Universal + Graphics Adapter (UGA) Block Transfer (BLT) routines. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param GlyphBuffer A pointer to the buffer that contains glyph data. + + @param Foreground The foreground setting requested to be used for the + generated BltBuffer data. + + @param Background The background setting requested to be used for the + generated BltBuffer data. + + @param Count The entry in the BltBuffer upon which to act. + + @param Width The width in bits of the glyph being converted. + + @param Height The height in bits of the glyph being converted + + @param BltBuffer A pointer to the buffer that contains the data that is + ready to be used by the UGA BLT routines. + + @retval EFI_SUCCESS It worked. + + @retval EFI_NOT_FOUND A glyph for a character was not found. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_GLYPH_TO_BLT) ( + IN EFI_HII_PROTOCOL *This, + IN UINT8 *GlyphBuffer, + IN EFI_UGA_PIXEL Foreground, + IN EFI_UGA_PIXEL Background, + IN UINTN Count, + IN UINTN Width, + IN UINTN Height, + IN OUT EFI_UGA_PIXEL *BltBuffer + ); + +/** + Allows a new string to be added to an already existing string package. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param Pointer to a NULL-terminated string containing a single ISO 639-2 + language identifier, indicating the language in which the string is translated. + + @param Handle The handle of the language pack to which the string is to be added. + + @param Reference The identifier of the string to be added. If the reference + value is zero, then the string will be assigned a new identifier on that + handle for the language specified. Otherwise, the string will be updated + with the NewString Value. + + @param NewString The string to be added. + + @retval EFI_SUCCESS The string was effectively registered. + + @retval EFI_INVALID_PARAMETER The Handle was unknown. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_NEW_STRING) ( + IN EFI_HII_PROTOCOL *This, + IN CHAR16 *Language, + IN EFI_HII_HANDLE Handle, + IN OUT STRING_REF *Reference, + IN CHAR16 *NewString + ); + +/** + Allows a program to determine the primary languages that are supported + on a given handle. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param Handle The handle on which the strings reside. + + @param LanguageString A string allocated by GetPrimaryLanguages() that + contains a list of all primary languages registered on the handle. + + @retval EFI_SUCCESS LanguageString was correctly returned. + + @retval EFI_INVALID_PARAMETER The Handle was unknown. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_GET_PRI_LANGUAGES) ( + IN EFI_HII_PROTOCOL *This, + IN EFI_HII_HANDLE Handle, + OUT EFI_STRING *LanguageString + ); + +/** + Allows a program to determine which secondary languages are supported + on a given handle for a given primary language. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param Handle The handle on which the strings reside. + + @param PrimaryLanguage Pointer to a NULL-terminated string containing a single + ISO 639-2 language identifier, indicating the primary language. + + @param LanguageString A string allocated by GetSecondaryLanguages() + containing a list of all secondary languages registered on the handle. + + @retval EFI_SUCCESS LanguageString was correctly returned. + + @retval EFI_INVALID_PARAMETER The Handle was unknown. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_GET_SEC_LANGUAGES) ( + IN EFI_HII_PROTOCOL *This, + IN EFI_HII_HANDLE Handle, + IN CHAR16 *PrimaryLanguage, + OUT EFI_STRING *LanguageString + ); + +/** + Extracts a string from a package already registered with the EFI HII database. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param Handle The handle on which the string resides. + + @param Token The string token assigned to the string. + + @param Raw If TRUE, the string is returned unedited in the internal + storage format described above. If false, the string returned is edited + by replacing with and by removing special characters such + as the prefix. + + @param LanguageString Pointer to a NULL-terminated string containing a + single ISO 639-2 language identifier, indicating the language to print. + If the LanguageString is empty (starts with a NULL), the default system + language will be used to determine the language. + + @param BufferLength Length of the StringBuffer. + + @param StringBuffer The buffer designed to receive the characters in the string. + + @retval EFI_SUCCESS StringBuffer is filled with a NULL-terminated string. + + @retval EFI_INVALID_PARAMETER The handle or string token is unknown. + + @retval EFI_BUFFER_TOO_SMALL The buffer provided was not large enough to + allow the entire string to be stored. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_GET_STRING) ( + IN EFI_HII_PROTOCOL *This, + IN EFI_HII_HANDLE Handle, + IN STRING_REF Token, + IN BOOLEAN Raw, + IN CHAR16 *LanguageString, + IN OUT UINTN *BufferLength, + OUT EFI_STRING StringBuffer + ); + +/** + Allows a program to extract a part of a string of not more than a given width. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param Handle The handle on which the string resides. + + @param Token The string token assigned to the string. + + @param Index On input, the offset into the string where the line is to start. + On output, the index is updated to point to beyond the last character returned + in the call. + + @param LineWidth The maximum width of the line in units of narrow glyphs. + + @param LanguageString Pointer to a NULL-terminated string containing a + single ISO 639-2 language identifier, indicating the language to print. + + @param BufferLength Pointer to the length of the StringBuffer. + + @param StringBuffer The buffer designed to receive the characters in the string. + + @retval EFI_SUCCESS StringBuffer filled with characters that will fit on the line. + + @retval EFI_NOT_FOUND The font glyph for at least one of the characters in + the string is not in the font database. + + @retval EFI_BUFFER_TOO_SMALL The buffer provided was not large enough + to allow the entire string to be stored. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_GET_LINE) ( + IN EFI_HII_PROTOCOL *This, + IN EFI_HII_HANDLE Handle, + IN STRING_REF Token, + IN OUT UINT16 *Index, + IN UINT16 LineWidth, + IN CHAR16 *LanguageString, + IN OUT UINT16 *BufferLength, + OUT EFI_STRING StringBuffer + ); + +/** + Allows a program to extract a form or form package that has previously + been registered with the HII database. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param Handle Handle on which the form resides. + + @param FormId The ID of the form to return. If the ID is zero, + the entire form package is returned. + + @param BufferLength On input, the length of the Buffer. On output, + the length of the returned buffer, + + @param Buffer The buffer designed to receive the form(s). + + @retval EFI_SUCCESS Buffer filled with the requested forms. BufferLength + was updated. + + @retval EFI_INVALID_PARAMETER The handle is unknown. + + @retval EFI_NOT_FOUND A form on the requested handle cannot be found with + the requested FormId. + + @retval EFI_BUFFER_TOO_SMALL The buffer provided was not large enough + to allow the form to be stored. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_GET_FORMS) ( + IN EFI_HII_PROTOCOL *This, + IN EFI_HII_HANDLE Handle, + IN EFI_FORM_ID FormId, + IN OUT UINTN *BufferLength, + OUT UINT8 *Buffer + ); + +/** + Extracts the defaults that are associated with a given handle in the HII database. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param Handle The HII handle from which will have default data retrieved. + + @param DefaultMask The mask used to specify some type of default override when extracting + the default image data. + + @param VariablePackList A indirect pointer to the first entry of a link list with + type EFI_HII_VARIABLE_PACK_LIST. + + @retval EFI_SUCCESS The VariablePackList was populated with the appropriate + default setting data. + + @retval EFI_NOT_FOUND The IFR does not have any explicit or default map(s). + + @retval EFI_INVALID_PARAMETER The HII database entry associated with Handle + contain invalid data. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_GET_DEFAULT_IMAGE) ( + IN EFI_HII_PROTOCOL *This, + IN EFI_HII_HANDLE Handle, + IN UINTN DefaultMask, + OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList + ); + +/** + Allows the caller to update a form or form package that has previously been + registered with the EFI HII database. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param Handle Handle of the package where the form to be updated resides. + + @param Label The label inside the form package where the update is to take place. + + @param AddData If TRUE, adding data at a given Label; otherwise, + if FALSE, removing data at a given Label. + + @param Data The buffer containing the new tags to insert after the Label + + @retval EFI_SUCCESS The form was updated with the new tags. + + @retval EFI_INVALID_PARAMETER The buffer for the buffer length does not + contain an integral number of tags. + + @retval EFI_NOT_FOUND The Handle, Label, or FormId was not found. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_UPDATE_FORM) ( + IN EFI_HII_PROTOCOL *This, + IN EFI_HII_HANDLE Handle, + IN EFI_FORM_LABEL Label, + IN BOOLEAN AddData, + IN EFI_HII_UPDATE_DATA *Data + ); + +/** + Retrieves the current keyboard layout. + + @param This A pointer to the EFI_HII_PROTOCOL instance. + + @param DescriptorCount A pointer to the number of Descriptor entries being + described in the keyboard layout being retrieved. + + @param Descriptor A pointer to a buffer containing an array of EFI_KEY_DESCRIPTOR + entries. Each entry will reflect the definition of a specific physical key. + + @retval EFI_SUCCESS The keyboard layout was retrieved successfully. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_HII_GET_KEYBOARD_LAYOUT) ( + IN EFI_HII_PROTOCOL *This, + OUT UINT16 *DescriptorCount, + OUT EFI_KEY_DESCRIPTOR *Descriptor + ); + +/** + @par Protocol Description: + The HII Protocol manages the HII database, which is a repository for data + having to do with fonts, strings, forms, keyboards, and other future human + interface items. + + @param NewPack + Extracts the various packs from a package list. + + @param RemovePack + Removes a package from the HII database. + + @param FindHandles + Determines the handles that are currently active in the database. + + @param ExportDatabase + Export the entire contents of the database to a buffer. + + @param TestString + Tests if all of the characters in a string have corresponding font characters. + + @param GetGlyph + Translates a Unicode character into the corresponding font glyph. + + @param GlyphToBlt + Converts a glyph value into a format that is ready for a UGA BLT command. + + @param NewString + Allows a new string to be added to an already existing string package. + + @param GetPrimaryLanguages + Allows a program to determine the primary languages that are supported + on a given handle. + + @param GetSecondaryLanguages + Allows a program to determine which secondary languages are supported + on a given handle for a given primary language. + + @param GetString + Extracts a string from a package that is already registered with the + EFI HII database. + + @param ResetString + Remove any new strings that were added after the initial string export + for this handle. + + @param GetLine + Allows a program to extract a part of a string of not more than a given width. + + @param GetForms + Allows a program to extract a form or form package that has been previously registered. + + @param GetDefaultImage + Allows a program to extract the nonvolatile image that represents the default storage image. + + @param UpdateForm + Allows a program to update a previously registered form. + + @param GetKeyboardLayout + Allows a program to extract the current keyboard layout. + +**/ +struct _EFI_HII_PROTOCOL { + EFI_HII_NEW_PACK NewPack; + EFI_HII_REMOVE_PACK RemovePack; + EFI_HII_FIND_HANDLES FindHandles; + EFI_HII_EXPORT ExportDatabase; + + EFI_HII_TEST_STRING TestString; + EFI_HII_GET_GLYPH GetGlyph; + EFI_HII_GLYPH_TO_BLT GlyphToBlt; + + EFI_HII_NEW_STRING NewString; + EFI_HII_GET_PRI_LANGUAGES GetPrimaryLanguages; + EFI_HII_GET_SEC_LANGUAGES GetSecondaryLanguages; + EFI_HII_GET_STRING GetString; + EFI_HII_RESET_STRINGS ResetStrings; + EFI_HII_GET_LINE GetLine; + EFI_HII_GET_FORMS GetForms; + EFI_HII_GET_DEFAULT_IMAGE GetDefaultImage; + EFI_HII_UPDATE_FORM UpdateForm; + + EFI_HII_GET_KEYBOARD_LAYOUT GetKeyboardLayout; +}; + +extern EFI_GUID gEfiHiiProtocolGuid; + +#endif diff --git a/Tools/CodeTools/Source/Include/Protocol/UgaDraw.h b/Tools/CodeTools/Source/Include/Protocol/UgaDraw.h new file mode 100644 index 0000000000..5586bdfffb --- /dev/null +++ b/Tools/CodeTools/Source/Include/Protocol/UgaDraw.h @@ -0,0 +1,168 @@ +/** @file + UGA Draw protocol from the EFI 1.1 specification. + + Abstraction of a very simple graphics device. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: UgaDraw.h + +**/ + +#ifndef __UGA_DRAW_H__ +#define __UGA_DRAW_H__ + +#define EFI_UGA_DRAW_PROTOCOL_GUID \ + { \ + 0x982c298b, 0xf4fa, 0x41cb, {0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39 } \ + } + +typedef struct _EFI_UGA_DRAW_PROTOCOL EFI_UGA_DRAW_PROTOCOL; + +/** + Return the current video mode information. + + @param This Protocol instance pointer. + @param HorizontalResolution Current video horizontal resolution in pixels + @param VerticalResolution Current video vertical resolution in pixels + @param ColorDepth Current video color depth in bits per pixel + @param RefreshRate Current video refresh rate in Hz. + + @retval EFI_SUCCESS Mode information returned. + @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode () + @retval EFI_INVALID_PARAMETER One of the input args was NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_UGA_DRAW_PROTOCOL_GET_MODE) ( + IN EFI_UGA_DRAW_PROTOCOL *This, + OUT UINT32 *HorizontalResolution, + OUT UINT32 *VerticalResolution, + OUT UINT32 *ColorDepth, + OUT UINT32 *RefreshRate + ) +; + +/** + Return the current video mode information. + + @param This Protocol instance pointer. + @param HorizontalResolution Current video horizontal resolution in pixels + @param VerticalResolution Current video vertical resolution in pixels + @param ColorDepth Current video color depth in bits per pixel + @param RefreshRate Current video refresh rate in Hz. + + @retval EFI_SUCCESS Mode information returned. + @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode () + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_UGA_DRAW_PROTOCOL_SET_MODE) ( + IN EFI_UGA_DRAW_PROTOCOL *This, + IN UINT32 HorizontalResolution, + IN UINT32 VerticalResolution, + IN UINT32 ColorDepth, + IN UINT32 RefreshRate + ) +; + +typedef struct { + UINT8 Blue; + UINT8 Green; + UINT8 Red; + UINT8 Reserved; +} EFI_UGA_PIXEL; + +typedef union { + EFI_UGA_PIXEL Pixel; + UINT32 Raw; +} EFI_UGA_PIXEL_UNION; + +typedef enum { + EfiUgaVideoFill, + EfiUgaVideoToBltBuffer, + EfiUgaBltBufferToVideo, + EfiUgaVideoToVideo, + EfiUgaBltMax +} EFI_UGA_BLT_OPERATION; + +/** + Type specifying a pointer to a function to perform an UGA Blt operation. + + The following table defines actions for BltOperations: + + EfiUgaVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY) + directly to every pixel of the video display rectangle + (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). + Only one pixel will be used from the BltBuffer. Delta is NOT used. + + EfiUgaVideoToBltBuffer - Read data from the video display rectangle + (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in + the BltBuffer rectangle (DestinationX, DestinationY ) + (DestinationX + Width, DestinationY + Height). If DestinationX or + DestinationY is not zero then Delta must be set to the length in bytes + of a row in the BltBuffer. + + EfiUgaBltBufferToVideo - Write data from the BltBuffer rectangle + (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the + video display rectangle (DestinationX, DestinationY) + (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is + not zero then Delta must be set to the length in bytes of a row in the + BltBuffer. + + EfiUgaVideoToVideo - Copy from the video display rectangle (SourceX, SourceY) + (SourceX + Width, SourceY + Height) .to the video display rectangle + (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). + The BltBuffer and Delta are not used in this mode. + + + @param[in] This - Protocol instance pointer. + @param[in] BltBuffer - Buffer containing data to blit into video buffer. This + buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL) + @param[in] BltOperation - Operation to perform on BlitBuffer and video memory + @param[in] SourceX - X coordinate of source for the BltBuffer. + @param[in] SourceY - Y coordinate of source for the BltBuffer. + @param[in] DestinationX - X coordinate of destination for the BltBuffer. + @param[in] DestinationY - Y coordinate of destination for the BltBuffer. + @param[in] Width - Width of rectangle in BltBuffer in pixels. + @param[in] Height - Hight of rectangle in BltBuffer in pixels. + @param[in] Delta - OPTIONAL + + @retval EFI_SUCCESS - The Blt operation completed. + @retval EFI_INVALID_PARAMETER - BltOperation is not valid. + @retval EFI_DEVICE_ERROR - A hardware error occured writting to the video buffer. + +--*/ +typedef +EFI_STATUS +(EFIAPI *EFI_UGA_DRAW_PROTOCOL_BLT) ( + IN EFI_UGA_DRAW_PROTOCOL * This, + IN EFI_UGA_PIXEL * BltBuffer, OPTIONAL + IN EFI_UGA_BLT_OPERATION BltOperation, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta OPTIONAL + ); + +struct _EFI_UGA_DRAW_PROTOCOL { + EFI_UGA_DRAW_PROTOCOL_GET_MODE GetMode; + EFI_UGA_DRAW_PROTOCOL_SET_MODE SetMode; + EFI_UGA_DRAW_PROTOCOL_BLT Blt; +}; + +extern EFI_GUID gEfiUgaDrawProtocolGuid; + +#endif diff --git a/Tools/CodeTools/Source/Include/X64/ProcessorBind.h b/Tools/CodeTools/Source/Include/X64/ProcessorBind.h new file mode 100644 index 0000000000..f865ce8790 --- /dev/null +++ b/Tools/CodeTools/Source/Include/X64/ProcessorBind.h @@ -0,0 +1,193 @@ +/** @file + Processor or Compiler specific defines and types x64 (Intel(r) EM64T, AMD64). + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: ProcessorBind.h + +**/ + +#ifndef __PROCESSOR_BIND_H__ +#define __PROCESSOR_BIND_H__ + +// +// Define the processor type so other code can make processor based choices +// +#define MDE_CPU_X64 + + +// +// Make sure we are useing the correct packing rules per EFI specification +// +#pragma pack() + + +#if _MSC_EXTENSIONS + +// +// Disable warning that make it impossible to compile at /W4 +// This only works for Microsoft* tools +// + +// +// Disabling bitfield type checking warnings. +// +#pragma warning ( disable : 4214 ) + +// +// Disabling the unreferenced formal parameter warnings. +// +#pragma warning ( disable : 4100 ) + +// +// Disable slightly different base types warning as CHAR8 * can not be set +// to a constant string. +// +#pragma warning ( disable : 4057 ) + +// +// ASSERT(FALSE) or while (TRUE) are legal constructes so supress this warning +// +#pragma warning ( disable : 4127 ) + + +#endif + + +#if (__STDC_VERSION__ < 199901L) + // + // No ANSI C 2000 stdint.h integer width declarations, so define equivalents + // + + #if _MSC_EXTENSIONS + + + // + // use Microsoft C complier dependent interger width types + // + typedef unsigned __int64 UINT64; + typedef __int64 INT64; + typedef unsigned __int32 UINT32; + typedef __int32 INT32; + typedef unsigned short UINT16; + typedef unsigned short CHAR16; + typedef short INT16; + typedef unsigned char BOOLEAN; + typedef unsigned char UINT8; + typedef char CHAR8; + typedef char INT8; + #else + #ifdef _EFI_P64 + // + // P64 - is Intel Itanium(TM) speak for pointers being 64-bit and longs and ints + // are 32-bits + // + typedef unsigned long long UINT64; + typedef long long INT64; + typedef unsigned int UINT32; + typedef int INT32; + typedef unsigned short CHAR16; + typedef unsigned short UINT16; + typedef short INT16; + typedef unsigned char BOOLEAN; + typedef unsigned char UINT8; + typedef char CHAR8; + typedef char INT8; + #else + // + // Assume LP64 - longs and pointers are 64-bit. Ints are 32-bit. + // + typedef unsigned long UINT64; + typedef long INT64; + typedef unsigned int UINT32; + typedef int INT32; + typedef unsigned short UINT16; + typedef unsigned short CHAR16; + typedef short INT16; + typedef unsigned char BOOLEAN; + typedef unsigned char UINT8; + typedef char CHAR8; + typedef char INT8; + #endif + #endif + + #define UINT8_MAX 0xff + +#else + // + // Use ANSI C 2000 stdint.h integer width declarations + // + #include + typedef uint8_t BOOLEAN; + typedef int8_t INT8; + typedef uint8_t UINT8; + typedef int16_t INT16; + typedef uint16_t UINT16; + typedef int32_t INT32; + typedef uint32_t UINT32; + typedef int64_t INT64; + typedef uint64_t UINT64; + typedef char CHAR8; + typedef uint16_t CHAR16; + +#endif + +typedef UINT64 UINTN; +typedef INT64 INTN; + + +// +// Processor specific defines +// +#define MAX_BIT 0x8000000000000000 +#define MAX_2_BITS 0xC000000000000000 + +// +// Maximum legal Itanium-based address +// +#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF + +// +// Modifier to ensure that all protocol member functions and EFI intrinsics +// use the correct C calling convention. All protocol member functions and +// EFI intrinsics are required to modify thier member functions with EFIAPI. +// +#if _MSC_EXTENSIONS + /// + /// Define the standard calling convention reguardless of optimization level. + /// __cdecl is Microsoft* specific C extension. + /// + #define EFIAPI __cdecl +#elif __GNUC__ + /// + /// Define the standard calling convention reguardless of optimization level. + /// efidecl is an extension to GCC that supports the differnece between x64 + /// GCC ABI and x64 Microsoft* ABI. EFI is closer to the Microsoft* ABI and + /// EFIAPI makes sure the right ABI is used for public interfaces. + /// eficecl is a work in progress and we do not yet have the compiler + /// + #define EFIAPI +#else + #define EFIAPI +#endif + +// +// The Microsoft* C compiler can removed references to unreferenced data items +// if the /OPT:REF linker option is used. We defined a macro as this is a +// a non standard extension +// +#if _MSC_EXTENSIONS + #define GLOBAL_REMOVE_IF_UNREFERENCED __declspec(selectany) +#else + #define GLOBAL_REMOVE_IF_UNREFERENCED +#endif + +#endif + diff --git a/Tools/CodeTools/Source/MakeDeps/MakeDeps.c b/Tools/CodeTools/Source/MakeDeps/MakeDeps.c new file mode 100755 index 0000000000..3943df0654 --- /dev/null +++ b/Tools/CodeTools/Source/MakeDeps/MakeDeps.c @@ -0,0 +1,1284 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + MakeDeps.c + +Abstract: + + Recursively scan source files to find include files and emit them to + create dependency lists. + +--*/ + +#include +#include +#include +#include + +#include + +#include "EfiUtilityMsgs.h" +#include "CommonLib.h" + +// +// Structure to maintain a linked list of strings +// +typedef struct _STRING_LIST { + struct _STRING_LIST *Next; + char *Str; +} STRING_LIST; + +#define UTILITY_NAME "MakeDeps" + +#define MAX_LINE_LEN 2048 +#define MAX_PATH 2048 +#define START_NEST_DEPTH 1 +#define MAX_NEST_DEPTH 1000 // just in case we get in an endless loop. +// +// Define the relative paths used by the special #include macros +// +#define PROTOCOL_DIR_PATH "Protocol/" +#define GUID_DIR_PATH "Guid/" +#define ARCH_PROTOCOL_DIR_PATH "ArchProtocol/" +#define PPI_PROTOCOL_DIR_PATH "Ppi/" + +// +// Use this structure to keep track of all the special #include forms +// +typedef struct { + INT8 *IncludeMacroName; + INT8 *PathName; +} INCLUDE_MACRO_CONVERSION; + +// +// This data is used to convert #include macros like: +// #include EFI_PROTOCOL_DEFINITION(xxx) +// into +// #include Protocol/xxx/xxx.h +// +static const INCLUDE_MACRO_CONVERSION mMacroConversion[] = { + "EFI_PROTOCOL_DEFINITION", + PROTOCOL_DIR_PATH, + "EFI_GUID_DEFINITION", + GUID_DIR_PATH, + "EFI_ARCH_PROTOCOL_DEFINITION", + ARCH_PROTOCOL_DIR_PATH, + "EFI_PROTOCOL_PRODUCER", + PROTOCOL_DIR_PATH, + "EFI_PROTOCOL_CONSUMER", + PROTOCOL_DIR_PATH, + "EFI_PROTOCOL_DEPENDENCY", + PROTOCOL_DIR_PATH, + "EFI_ARCH_PROTOCOL_PRODUCER", + ARCH_PROTOCOL_DIR_PATH, + "EFI_ARCH_PROTOCOL_CONSUMER", + ARCH_PROTOCOL_DIR_PATH, + "EFI_ARCH_PROTOCOL_DEPENDENCY", + ARCH_PROTOCOL_DIR_PATH, + "EFI_PPI_DEFINITION", + PPI_PROTOCOL_DIR_PATH, + "EFI_PPI_PRODUCER", + PPI_PROTOCOL_DIR_PATH, + "EFI_PPI_CONSUMER", + PPI_PROTOCOL_DIR_PATH, + "EFI_PPI_DEPENDENCY", + PPI_PROTOCOL_DIR_PATH, + NULL, + NULL +}; + +typedef struct _SYMBOL { + struct _SYMBOL *Next; + INT8 *Name; + INT8 *Value; +} SYMBOL; + +// +// Here's all our globals. We need a linked list of include paths, a linked +// list of source files, a linked list of subdirectories (appended to each +// include path when searching), and flags to keep track of command-line options. +// +static struct { + STRING_LIST *IncludePaths; // all include paths to search + STRING_LIST *SourceFiles; // all source files to parse + STRING_LIST *SubDirs; // appended to each include path when searching + SYMBOL *SymbolTable; // for replacement strings + FILE *OutFptr; // output dependencies to this file + BOOLEAN Verbose; // for more detailed output + BOOLEAN IgnoreNotFound; // no warnings if files not found + BOOLEAN QuietMode; // -q - don't print missing file warnings + BOOLEAN NoSystem; // don't process #include files + BOOLEAN NeverFail; // always return success + BOOLEAN NoDupes; // to not list duplicate dependency files (for timing purposes) + BOOLEAN UseSumDeps; // use summary dependency files if found + INT8 TargetFileName[MAX_PATH]; // target object filename + INT8 SumDepsPath[MAX_PATH]; // path to summary files + INT8 *OutFileName; // -o option +} mGlobals; + +static +STATUS +ProcessFile ( + INT8 *TargetFileName, + INT8 *FileName, + UINT32 NestDepth, + STRING_LIST *ProcessedFiles + ); + +static +FILE * +FindFile ( + INT8 *FileName, + UINT32 FileNameLen + ); + +static +void +PrintDependency ( + INT8 *Target, + INT8 *DependentFile + ); + +static +void +ReplaceSymbols ( + INT8 *Str, + UINT32 StrSize + ); + +static +STATUS +ProcessArgs ( + int Argc, + char *Argv[] + ); + +static +void +Usage ( + VOID + ); + +static +void +FreeLists ( + VOID + ); + +int +main ( + int Argc, + char *Argv[] + ) +/*++ + +Routine Description: + + Call the routine to parse the command-line options, then process each file + to build dependencies. + +Arguments: + + Argc - Standard C main() argc. + Argv - Standard C main() argv. + +Returns: + + 0 if successful + nonzero otherwise + +--*/ +{ + STRING_LIST *File; + STRING_LIST ProcessedFiles; + STRING_LIST *TempList; + STATUS Status; + INT8 *Cptr; + INT8 TargetFileName[MAX_PATH]; + + SetUtilityName (UTILITY_NAME); + // + // Process the command-line arguments + // + Status = ProcessArgs (Argc, Argv); + if (Status != STATUS_SUCCESS) { + return STATUS_ERROR; + } + // + // Go through the list of source files and process each. + // + memset (&ProcessedFiles, 0, sizeof (STRING_LIST)); + File = mGlobals.SourceFiles; + while (File != NULL) { + // + // Clear out our list of processed files + // + TempList = ProcessedFiles.Next; + while (ProcessedFiles.Next != NULL) { + TempList = ProcessedFiles.Next->Next; + free (ProcessedFiles.Next->Str); + free (ProcessedFiles.Next); + ProcessedFiles.Next = TempList; + } + // + // Replace filename extension with ".obj" if they did not + // specifically specify the target file + // + if (mGlobals.TargetFileName[0] == 0) { + strcpy (TargetFileName, File->Str); + // + // Find the .extension + // + for (Cptr = TargetFileName + strlen (TargetFileName) - 1; + (*Cptr != '\\' && *Cptr != '/') && (Cptr > TargetFileName) && (*Cptr != '.'); + Cptr-- + ) + ; + if (Cptr == TargetFileName) { + Error (NULL, 0, 0, File->Str, "could not locate extension in filename"); + goto Finish; + } + // + // Tack on the ".obj" + // + strcpy (Cptr, ".obj"); + } else { + // + // Copy the target filename they specified + // + strcpy (TargetFileName, mGlobals.TargetFileName); + } + + Status = ProcessFile (TargetFileName, File->Str, START_NEST_DEPTH, &ProcessedFiles); + if (Status != STATUS_SUCCESS) { + goto Finish; + } + + File = File->Next; + } + +Finish: + // + // Free up memory + // + FreeLists (); + // + // Free up our processed files list + // + TempList = ProcessedFiles.Next; + while (ProcessedFiles.Next != NULL) { + TempList = ProcessedFiles.Next->Next; + free (ProcessedFiles.Next->Str); + free (ProcessedFiles.Next); + ProcessedFiles.Next = TempList; + } + // + // Close our output file + // + if ((mGlobals.OutFptr != stdout) && (mGlobals.OutFptr != NULL)) { + fprintf(mGlobals.OutFptr, "\t\n"); // file ending flag + fclose (mGlobals.OutFptr); + } + + if (mGlobals.NeverFail) { + return STATUS_SUCCESS; + } + // + // If any errors, then delete our output so that it will get created + // again on a rebuild. + // + if ((GetUtilityStatus () == STATUS_ERROR) && (mGlobals.OutFileName != NULL)) { + remove (mGlobals.OutFileName); + } + + return GetUtilityStatus (); +} + +static +STATUS +ProcessFile ( + INT8 *TargetFileName, + INT8 *FileName, + UINT32 NestDepth, + STRING_LIST *ProcessedFiles + ) +/*++ + +Routine Description: + + Given a source file name, open the file and parse all #include lines. + +Arguments: + + TargetFileName - name of the usually .obj target + FileName - name of the file to process + NestDepth - how deep we're nested in includes + ProcessedFiles - list of processed files. + +Returns: + + standard status. + +--*/ +{ + FILE *Fptr; + INT8 Line[MAX_LINE_LEN]; + INT8 *Cptr; + INT8 *EndPtr; + INT8 *SaveCptr; + INT8 EndChar; + INT8 FileNameCopy[MAX_PATH]; + INT8 MacroIncludeFileName[MAX_LINE_LEN]; + INT8 SumDepsFile[MAX_PATH]; + STATUS Status; + UINT32 Index; + UINT32 LineNum; + STRING_LIST *ListPtr; + + Status = STATUS_SUCCESS; + Fptr = NULL; + // + // Print the file being processed. Indent so you can tell the include nesting + // depth. + // + if (mGlobals.Verbose) { + fprintf (stdout, "%*cProcessing file '%s'\n", NestDepth * 2, ' ', FileName); + } + // + // If we're using summary dependency files, and a matching .dep file is + // found for this file, then just emit the summary dependency file as + // a dependency and return. + // + if (mGlobals.UseSumDeps) { + strcpy (SumDepsFile, mGlobals.SumDepsPath); + strcat (SumDepsFile, FileName); + for (Cptr = SumDepsFile + strlen (SumDepsFile) - 1; + (*Cptr != '\\' && *Cptr != '/') && (Cptr > SumDepsFile) && (*Cptr != '.'); + Cptr-- + ) + ; + if (*Cptr == '.') { + strcpy (Cptr, ".dep"); + } else { + strcat (SumDepsFile, ".dep"); + } + // + // See if the summary dep file exists. Could use _stat() function, but + // it's less portable. + // + if ((Fptr = fopen (SumDepsFile, "r")) != NULL) { + PrintDependency (TargetFileName, SumDepsFile); + return STATUS_SUCCESS; + } + } + // + // If we're not doing duplicates, and we've already seen this filename, + // then return + // + if (mGlobals.NoDupes) { + for (ListPtr = ProcessedFiles->Next; ListPtr != NULL; ListPtr = ListPtr->Next) { + if (stricmp (FileName, ListPtr->Str) == 0) { + break; + } + } + // + // If we found a match, we're done. If we didn't, create a new element + // and add it to the list. + // + if (ListPtr != NULL) { + // + // Print a message if verbose mode + // + if (mGlobals.Verbose) { + DebugMsg (NULL, 0, 0, FileName, "duplicate include -- not processed again"); + } + + return STATUS_SUCCESS; + } + + ListPtr = malloc (sizeof (STRING_LIST)); + ListPtr->Str = malloc (strlen (FileName) + 1); + strcpy (ListPtr->Str, FileName); + ListPtr->Next = ProcessedFiles->Next; + ProcessedFiles->Next = ListPtr; + } + + // + // Make sure we didn't exceed our maximum nesting depth + // + if (NestDepth > MAX_NEST_DEPTH) { + Error (NULL, 0, 0, FileName, "max nesting depth exceeded on file"); + goto Finish; + } + // + // Make a local copy of the filename. Then we can manipulate it + // if we have to. + // + strcpy (FileNameCopy, FileName); + // + // Try to open the file locally + // + if ((Fptr = fopen (FileNameCopy, "r")) == NULL) { + // + // Try to find it among the paths. + // + Fptr = FindFile (FileNameCopy, sizeof (FileNameCopy)); + if (Fptr == NULL) { + // + // If this is not the top-level file, and the command-line argument + // said to ignore missing files, then return ok + // + if (NestDepth != START_NEST_DEPTH) { + if (mGlobals.IgnoreNotFound) { + if (!mGlobals.QuietMode) { + DebugMsg (NULL, 0, 0, FileNameCopy, "could not find file"); + } + + return STATUS_SUCCESS; + } else { + Error (NULL, 0, 0, FileNameCopy, "could not find file"); + return STATUS_ERROR; + } + } else { + // + // Top-level (first) file. Emit an error. + // + Error (NULL, 0, 0, FileNameCopy, "could not find file"); + return STATUS_ERROR; + } + } + } + // + // Print the dependency, with string substitution + // + PrintDependency (TargetFileName, FileNameCopy); + + // + // Now read in lines and find all #include lines. Allow them to indent, and + // to put spaces between the # and include. + // + LineNum = 0; + while ((fgets (Line, sizeof (Line), Fptr) != NULL) && (Status == STATUS_SUCCESS)) { + LineNum++; + Cptr = Line; + // + // Skip preceeding spaces on the line + // + while (*Cptr && (isspace (*Cptr))) { + Cptr++; + } + // + // Check for # character + // + if (*Cptr == '#') { + Cptr++; + // + // Check for "include" + // + while (*Cptr && (isspace (*Cptr))) { + Cptr++; + } + + if (strncmp (Cptr, "include", 7) == 0) { + // + // Skip over "include" and move on to filename as "file" or + // + Cptr += 7; + while (*Cptr && (isspace (*Cptr))) { + Cptr++; + } + + if (*Cptr == '<') { + EndChar = '>'; + } else if (*Cptr == '"') { + EndChar = '"'; + } else { + // + // Handle special #include MACRO_NAME(file) + // Set EndChar to null so we fall through on processing below. + // + EndChar = 0; + // + // Look for all the special include macros and convert accordingly. + // + for (Index = 0; mMacroConversion[Index].IncludeMacroName != NULL; Index++) { + // + // Save the start of the string in case some macros are substrings + // of others. + // + SaveCptr = Cptr; + if (strncmp ( + Cptr, + mMacroConversion[Index].IncludeMacroName, + strlen (mMacroConversion[Index].IncludeMacroName) + ) == 0) { + // + // Skip over the macro name + // + Cptr += strlen (mMacroConversion[Index].IncludeMacroName); + // + // Skip over open parenthesis, blank spaces, then find closing + // parenthesis or blank space + // + while (*Cptr && (isspace (*Cptr))) { + Cptr++; + } + + if (*Cptr == '(') { + Cptr++; + while (*Cptr && (isspace (*Cptr))) { + Cptr++; + } + + EndPtr = Cptr; + while (*EndPtr && !isspace (*EndPtr) && (*EndPtr != ')')) { + EndPtr++; + } + + *EndPtr = 0; + // + // Create the path + // + strcpy (MacroIncludeFileName, mMacroConversion[Index].PathName); + strcat (MacroIncludeFileName, Cptr); + strcat (MacroIncludeFileName, "/"); + strcat (MacroIncludeFileName, Cptr); + strcat (MacroIncludeFileName, ".h"); + // + // Process immediately, then break out of the outside FOR loop. + // + Status = ProcessFile (TargetFileName, MacroIncludeFileName, NestDepth + 1, ProcessedFiles); + break; + } + } + // + // Restore the start + // + Cptr = SaveCptr; + } + // + // Don't recognize the include line? Ignore it. We assume that the + // file compiles anyway. + // + if (mMacroConversion[Index].IncludeMacroName == NULL) { + // + // Warning (FileNameCopy, LineNum, 0, "could not parse line", NULL); + // Status = STATUS_WARNING; + // + } + } + // + // Process "normal" includes. If the endchar is 0, then the + // file has already been processed. Otherwise look for the + // endchar > or ", and process the include file. + // + if (EndChar != 0) { + Cptr++; + EndPtr = Cptr; + while (*EndPtr && (*EndPtr != EndChar)) { + EndPtr++; + } + + if (*EndPtr == EndChar) { + // + // If we're processing it, do it + // + if ((EndChar != '>') || (!mGlobals.NoSystem)) { + // + // Null terminate the filename and try to process it. + // + *EndPtr = 0; + Status = ProcessFile (TargetFileName, Cptr, NestDepth + 1, ProcessedFiles); + } + } else { + Warning (FileNameCopy, LineNum, 0, "malformed include", "missing closing %c", EndChar); + Status = STATUS_WARNING; + goto Finish; + } + } + } + } + } + +Finish: + // + // Close open files and return status + // + if (Fptr != NULL) { + fclose (Fptr); + } + + return Status; +} + +static +void +PrintDependency ( + INT8 *TargetFileName, + INT8 *DependentFile + ) +/*++ + +Routine Description: + + Given a target (.obj) file name, and a dependent file name, do any string + substitutions (per the command line options) on the file names, then + print the dependency line of form: + + TargetFileName : DependentFile + +Arguments: + + TargetFileName - build target file name + DependentFile - file on which TargetFileName depends + +Returns: + + None + +--*/ +{ + INT8 Str[MAX_PATH]; + + // + // Go through the symbols and do replacements + // + strcpy (Str, DependentFile); + ReplaceSymbols (Str, sizeof (Str)); + fprintf (mGlobals.OutFptr, "%s\n", Str); +} + +static +void +ReplaceSymbols ( + INT8 *Str, + UINT32 StrSize + ) +{ + SYMBOL *Sym; + INT8 StrCopy[MAX_LINE_LEN]; + INT8 *From; + INT8 *To; + BOOLEAN Replaced; + + // + // Go through the entire string to look for replacement strings at + // every position. + // + From = Str; + To = StrCopy; + while (*From) { + // + // Copy the character + // + *To = *From; + Replaced = FALSE; + // + // Go through each symbol and try to find a string substitution + // + Sym = mGlobals.SymbolTable; + while (Sym != NULL) { + if (strnicmp (From, Sym->Value, strlen (Sym->Value)) == 0) { + // + // Replace the string, then advance the pointers past the + // replaced strings + // + strcpy (To, Sym->Name); + To += strlen (Sym->Name); + From += strlen (Sym->Value); + Replaced = TRUE; + // + // Break from the while() + // + break; + } else { + Sym = Sym->Next; + } + } + + if (!Replaced) { + From++; + To++; + } + } + // + // Null terminate, and return it + // + *To = 0; + if (strlen (StrCopy) < StrSize) { + strcpy (Str, StrCopy); + } +} +// +// Given a filename, try to find it along the include paths. +// +static +FILE * +FindFile ( + INT8 *FileName, + UINT32 FileNameLen + ) +{ + FILE *Fptr; + STRING_LIST *List; + STRING_LIST *SubDir; + INT8 FullFileName[MAX_PATH * 2]; + + // + // Traverse the list of paths and try to find the file + // + List = mGlobals.IncludePaths; + while (List != NULL) { + // + // Put the path and filename together + // + if (strlen (List->Str) + strlen (FileName) + 1 > sizeof (FullFileName)) { + Error ( + __FILE__, + __LINE__, + 0, + "application error", + "cannot concatenate '%s' + '%s'", + List->Str, + FileName + ); + return NULL; + } + // + // Append the filename to this include path and try to open the file. + // + strcpy (FullFileName, List->Str); + strcat (FullFileName, FileName); + if ((Fptr = fopen (FullFileName, "r")) != NULL) { + // + // Return the file name + // + if (FileNameLen <= strlen (FullFileName)) { + Error (__FILE__, __LINE__, 0, "application error", "internal path name of insufficient length"); + // + // fprintf (stdout, "File length > %d: %s\n", FileNameLen, FullFileName); + // + return NULL; + } + + strcpy (FileName, FullFileName); + return Fptr; + } + // + // Didn't find it there. Now try this directory with every subdirectory + // the user specified on the command line + // + for (SubDir = mGlobals.SubDirs; SubDir != NULL; SubDir = SubDir->Next) { + strcpy (FullFileName, List->Str); + strcat (FullFileName, SubDir->Str); + strcat (FullFileName, FileName); + if ((Fptr = fopen (FullFileName, "r")) != NULL) { + // + // Return the file name + // + if (FileNameLen <= strlen (FullFileName)) { + Error (__FILE__, __LINE__, 0, "application error", "internal path name of insufficient length"); + return NULL; + } + + strcpy (FileName, FullFileName); + return Fptr; + } + } + + List = List->Next; + } + // + // Not found + // + return NULL; +} +// +// Process the command-line arguments +// +static +STATUS +ProcessArgs ( + int Argc, + char *Argv[] + ) +{ + STRING_LIST *NewList; + STRING_LIST *LastIncludePath; + STRING_LIST *LastSourceFile; + SYMBOL *Symbol; + int Index; + // + // Clear our globals + // + memset ((char *) &mGlobals, 0, sizeof (mGlobals)); + mGlobals.NoDupes = TRUE; + // + // Skip program name + // + Argc--; + Argv++; + // + // Initialize locals + // + LastIncludePath = NULL; + LastSourceFile = NULL; + // + // Process until no more args + // + while (Argc) { + // + // -i path add include search path + // + if (stricmp (Argv[0], "-i") == 0) { + // + // check for one more arg + // + if (Argc > 1) { + // + // Allocate memory for a new list element, fill it in, and + // add it to our list of include paths. Always make sure it + // has a "\" on the end of it. + // + NewList = malloc (sizeof (STRING_LIST)); + if (NewList == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + NewList->Next = NULL; + NewList->Str = malloc (strlen (Argv[1]) + 2); + if (NewList->Str == NULL) { + free (NewList); + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + strcpy (NewList->Str, Argv[1]); + if (NewList->Str[strlen (NewList->Str) - 1] != '\\' && NewList->Str[strlen (NewList->Str) - 1] != '/') { + strcat (NewList->Str, "/"); + } + // + // Add it to the end of the our list of include paths + // + if (mGlobals.IncludePaths == NULL) { + mGlobals.IncludePaths = NewList; + } else { + LastIncludePath->Next = NewList; + } + + LastIncludePath = NewList; + // + // fprintf (stdout, "Added path: %s\n", NewList->Str); + // + } else { + Error (NULL, 0, 0, Argv[0], "option requires an include path"); + Usage (); + return STATUS_ERROR; + } + + Argc--; + Argv++; + } else if (stricmp (Argv[0], "-f") == 0) { + // + // Check for one more arg + // + if (Argc > 1) { + // + // Allocate memory for a new list element, fill it in, and + // add it to our list of source files. + // + NewList = malloc (sizeof (STRING_LIST)); + if (NewList == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + NewList->Next = NULL; + // + // Allocate space to replace ".c" with ".obj", plus null termination + // + NewList->Str = malloc (strlen (Argv[1]) + 5); + if (NewList->Str == NULL) { + free (NewList); + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + strcpy (NewList->Str, Argv[1]); + if (mGlobals.SourceFiles == NULL) { + mGlobals.SourceFiles = NewList; + } else { + LastSourceFile->Next = NewList; + } + + LastSourceFile = NewList; + } else { + Error (NULL, 0, 0, Argv[0], "option requires a file name"); + Usage (); + return STATUS_ERROR; + } + // + // The C compiler first looks for #include files in the directory where + // the source file came from. Add the file's source directory to the + // list of include paths. + // + NewList = malloc (sizeof (STRING_LIST)); + if (NewList == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + NewList->Next = NULL; + NewList->Str = malloc (strlen (Argv[1]) + 3); + if (NewList->Str == NULL) { + free (NewList); + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + strcpy (NewList->Str, Argv[1]); + // + // Back up in the source file name to the last backslash and terminate after it. + // + for (Index = strlen (NewList->Str) - 1; (Index > 0) && (NewList->Str[Index] != '\\' && NewList->Str[Index] != '/'); Index--) + ; + if (Index < 0) { + strcpy (NewList->Str, "./"); + } else { + NewList->Str[Index + 1] = 0; + } + // + // Add it to the end of the our list of include paths + // + if (mGlobals.IncludePaths == NULL) { + mGlobals.IncludePaths = NewList; + } else { + LastIncludePath->Next = NewList; + } + + if (mGlobals.Verbose) { + fprintf (stdout, "Adding include path: %s\n", NewList->Str); + } + + LastIncludePath = NewList; + Argc--; + Argv++; + } else if (stricmp (Argv[0], "-s") == 0) { + // + // -s subdir add subdirectory subdir to list of subdirecties to scan. + // Check for one more arg first. + // + if (Argc > 1) { + // + // Allocate memory for a new list element, fill it in, and + // add it to our list of subdirectory include paths. Always + // make sure it has a "\" on the end of it. + // + NewList = malloc (sizeof (STRING_LIST)); + if (NewList == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + NewList->Str = malloc (strlen (Argv[1]) + 2); + if (NewList->Str == NULL) { + free (NewList); + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + strcpy (NewList->Str, Argv[1]); + if (NewList->Str[strlen (NewList->Str) - 1] != '\\' && NewList->Str[strlen (NewList->Str) - 1] != '/') { + strcat (NewList->Str, "/"); + } + + NewList->Next = mGlobals.SubDirs; + mGlobals.SubDirs = NewList; + } else { + Error (NULL, 0, 0, Argv[0], "option requires a subdirectory name"); + Usage (); + return STATUS_ERROR; + } + + Argc--; + Argv++; + } else if (stricmp (Argv[0], "-sub") == 0) { + // + // -sub symname symvalue to do string substitution in the output + // + if (Argc > 2) { + // + // Allocate memory for the symbol object + // + Symbol = malloc (sizeof (SYMBOL)); + if (Symbol == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + // + // Allocate memory for the symbol name and value, then save copies + // + Symbol->Name = malloc (strlen (Argv[1]) + 1); + if (Symbol->Name == NULL) { + free (Symbol); + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + strcpy (Symbol->Name, Argv[1]); + Symbol->Value = malloc (strlen (Argv[2]) + 1); + if (Symbol->Value == NULL) { + free (Symbol->Name); + free (Symbol); + Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + strcpy (Symbol->Value, Argv[2]); + // + // Add it to the list + // + Symbol->Next = mGlobals.SymbolTable; + mGlobals.SymbolTable = Symbol; + } else { + Error (NULL, 0, 0, Argv[0], "option requires a symbol name and value"); + Usage (); + return STATUS_ERROR; + } + // + // Skip over args + // + Argc -= 2; + Argv += 2; + } else if (stricmp (Argv[0], "-nosystem") == 0) { + mGlobals.NoSystem = TRUE; + } else if (stricmp (Argv[0], "-nodupes") == 0) { + mGlobals.NoDupes = TRUE; + } else if (stricmp (Argv[0], "-nodups") == 0) { + mGlobals.NoDupes = TRUE; + } else if (stricmp (Argv[0], "-target") == 0) { + // + // -target TargetFileName - Target object file (only one allowed right + // now) is TargetFileName rather than SourceFile.obj + // + if (Argc > 1) { + strcpy (mGlobals.TargetFileName, Argv[1]); + } else { + Error (NULL, 0, 0, Argv[0], "option requires a target file name"); + Usage (); + return STATUS_ERROR; + } + + Argc--; + Argv++; + } else if (stricmp (Argv[0], "-usesumdeps") == 0) { + // + // -usesumdeps Path - if we find an included file xxx.h, and file + // Path/xxx.dep exists, list Path/xxx.dep as a dependency rather than + // xxx.h and don't parse xxx.h. This allows you to create a dependency + // file for a commonly included file, and have its dependency file updated + // only if its included files are updated. Then anyone else including this + // common include file can simply have a dependency on that file's .dep file + // rather than on all the files included by it. Confusing enough? + // + mGlobals.UseSumDeps = 1; + if (Argc > 1) { + strcpy (mGlobals.SumDepsPath, Argv[1]); + // + // Add slash on end if not there + // + if (mGlobals.SumDepsPath[strlen (mGlobals.SumDepsPath) - 1] != '\\' && mGlobals.SumDepsPath[strlen (mGlobals.SumDepsPath) - 1] != '/') { + strcat (mGlobals.SumDepsPath, "/"); + } + } else { + Error (NULL, 0, 0, Argv[0], "option requires path to summary dependency files"); + Usage (); + return STATUS_ERROR; + } + + Argc--; + Argv++; + + } else if (stricmp (Argv[0], "-o") == 0) { + // + // -o OutputFileName - specify an output filename for dependency list + // check for one more arg + // + if (Argc > 1) { + // + // Try to open the file + // + if ((mGlobals.OutFptr = fopen (Argv[1], "w")) == NULL) { + Error (NULL, 0, 0, Argv[1], "could not open file for writing"); + return STATUS_ERROR; + } + + mGlobals.OutFileName = Argv[1]; + } else { + Error (NULL, 0, 0, Argv[0], "option requires output file name"); + Usage (); + return STATUS_ERROR; + } + + Argc--; + Argv++; + } else if (stricmp (Argv[0], "-v") == 0) { + mGlobals.Verbose = TRUE; + } else if (stricmp (Argv[0], "-neverfail") == 0) { + mGlobals.NeverFail = TRUE; + } else if (stricmp (Argv[0], "-q") == 0) { + mGlobals.QuietMode = TRUE; + } else if (stricmp (Argv[0], "-ignorenotfound") == 0) { + mGlobals.IgnoreNotFound = TRUE; + } else if ((stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) { + Usage (); + return STATUS_ERROR; + } else { + Error (NULL, 0, 0, Argv[0], "unrecognized option"); + Usage (); + return STATUS_ERROR; + } + + Argc--; + Argv++; + } + // + // Had to specify at least one source file + // + if (mGlobals.SourceFiles == NULL) { + Error (NULL, 0, 0, "must specify one source file name", NULL); + Usage (); + return STATUS_ERROR; + } + // + // Assume output to stdout if not specified + // + if (mGlobals.OutFptr == NULL) { + mGlobals.OutFptr = stdout; + } + + return STATUS_SUCCESS; +} +// +// Free the global string lists we allocated memory for +// +static +void +FreeLists ( + VOID + ) +{ + STRING_LIST *Temp; + SYMBOL *NextSym; + + // + // printf ("Free lists....."); + // + // Traverse the include paths, freeing each + // printf ("freeing include paths\n"); + // + while (mGlobals.IncludePaths != NULL) { + Temp = mGlobals.IncludePaths->Next; + // + // printf ("Freeing include path string '%s' at 0x%X\n", + // mGlobals.IncludePaths->Str, (int)(mGlobals.IncludePaths->Str)); + // + free (mGlobals.IncludePaths->Str); + // + // printf ("Freeing include path object at 0x%X\n", (int)(mGlobals.IncludePaths)); + // + free (mGlobals.IncludePaths); + mGlobals.IncludePaths = Temp; + } + // + // Traverse the source files, freeing each + // + while (mGlobals.SourceFiles != NULL) { + Temp = mGlobals.SourceFiles->Next; + free (mGlobals.SourceFiles->Str); + free (mGlobals.SourceFiles); + mGlobals.SourceFiles = Temp; + } + // + // Traverse the subdirectory list, freeing each + // + while (mGlobals.SubDirs != NULL) { + Temp = mGlobals.SubDirs->Next; + free (mGlobals.SubDirs->Str); + free (mGlobals.SubDirs); + mGlobals.SubDirs = Temp; + } + // + // Free the symbol table + // + while (mGlobals.SymbolTable != NULL) { + NextSym = mGlobals.SymbolTable->Next; + free (mGlobals.SymbolTable->Name); + free (mGlobals.SymbolTable->Value); + mGlobals.SymbolTable = NextSym; + } + // + // printf ("done\n"); + // +} + +static +void +Usage ( + VOID + ) +/*++ + +Routine Description: + + Print usage information for this utility. + +Arguments: + + None. + +Returns: + + Nothing. + +--*/ +{ + int Index; + static const char *Str[] = { + UTILITY_NAME " -- make dependencies", + " Usage: MakeDeps [options]", + " Options include:", + " -h or -? for this help information", + " -f SourceFile add SourceFile to list of files to scan", + " -i IncludePath add IncludePath to list of search paths", + " -o OutputFile write output dependencies to OutputFile", + " -s SubDir for each IncludePath, also search IncludePath\\SubDir", + " -v for verbose output", + " -ignorenotfound don't warn for files not found", + " -target Target for single SourceFile, target is Target, not SourceFile.obj", + " -q quiet mode to not report files not found if ignored", + " -sub sym str replace all occurrances of 'str' with 'sym' in the output", + " -nosystem not process system files", + " -neverfail always return a success return code", + // + // " -nodupes keep track of include files, don't rescan duplicates", + // + " -usesumdeps path use summary dependency files in 'path' directory.", + "", + NULL + }; + for (Index = 0; Str[Index] != NULL; Index++) { + fprintf (stdout, "%s\n", Str[Index]); + } +} diff --git a/Tools/CodeTools/Source/MakeDeps/build.xml b/Tools/CodeTools/Source/MakeDeps/build.xml new file mode 100755 index 0000000000..60c34c2dfa --- /dev/null +++ b/Tools/CodeTools/Source/MakeDeps/build.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/ModifyInf/ModifyInf.c b/Tools/CodeTools/Source/ModifyInf/ModifyInf.c new file mode 100755 index 0000000000..6008feb981 --- /dev/null +++ b/Tools/CodeTools/Source/ModifyInf/ModifyInf.c @@ -0,0 +1,321 @@ +/*++ + +Copyright (c) 1999-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +Module Name: + + ModifyInf.c + +Abstract: + + It is a simple tool to modify some fields in a FV inf file + and output a new FV inf file. + +--*/ + +#include "stdio.h" +#include "string.h" + +// +// Read a line into buffer including '\r\n' +// +int +ReadLine ( + char *LineBuffer, + FILE *fp + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + LineBuffer - GC_TODO: add argument description + fp - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + int CharC; + char *Line; + + Line = LineBuffer; + + while ((CharC = fgetc (fp)) != EOF) { + *Line++ = (char) CharC; + if (CharC == 0x0a) { + break; + } + } + + *Line = 0; + + if (CharC == EOF) { + return 0; + } else { + return 1; + } + +} +// +// Write a line into output file +// +int +WriteLine ( + char *Line, + FILE *fp + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + Line - GC_TODO: add argument description + fp - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + fwrite (Line, strlen (Line), 1, fp); + return 0; +} +// +// Apply patterns to a line +// Currently there are 2 patterns to support +// '==' replace a field value with a new value +// '+=' append a string at the end of original line +// '-' prevent the line from applying any patterns +// it has the highest priority +// +int +ApplyPattern ( + char *Line, + char *argv[], + int argc + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + Line - GC_TODO: add argument description + ] - GC_TODO: add argument description + argc - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + static char Section[256]; + char PatternBuffer[256]; + char *Pattern; + char *Pattern1; + char *Pattern2; + int PatternNum; + char *Ptr; + + Pattern = PatternBuffer; + + PatternNum = argc; + + // + // For section field + // record current scope section into static buffer + // + Ptr = Line; + if (*Ptr == '[') { + while (*Ptr != ']') { + if (!(*Ptr++)) { + return -1; + } + } + + strcpy (Section, Line); + Section[Ptr - Line + 1] = 0; + } + // + // Apply each pattern on the line + // + while (PatternNum-- > 3) { + + strcpy (Pattern, argv[PatternNum]); + + // + // For pattern '-' + // keep it unmodified by other patterns + // + if (*Pattern == '-') { + if (strstr (Line, Pattern + 1)) { + return 0; + } else { + continue; + } + } + // + // For other patterns + // get its section at first if it has + // + if (*Pattern == '[') { + if (strncmp (Section, Pattern, strlen (Section))) { + // + // This pattern can't be appied for current section + // + continue; + } + // + // Strip the section field + // + while (*Pattern != ']') { + if (!(*Pattern++)) { + return -1; + } + } + + Pattern++; + } + // + // Apply patterns + // + Pattern1 = strstr (Pattern, "=="); + Pattern2 = strstr (Pattern, "+="); + if (Pattern1) { + // + // For pattern '==' + // replace the field value with a new string + // + if (!strncmp (Line, Pattern, Pattern1 - Pattern)) { + Pattern1 += 2; + Ptr = strstr (Line, "="); + if (!Ptr) { + return -1; + } + + while (*(++Ptr) == ' ') + ; + *Ptr = 0; + strcat (Line, Pattern1); + strcat (Line, "\r\n"); + } + } else if (Pattern2) { + // + // For pattern '+=' + // append a string at end of the original string + // + if (!strncmp (Line, Pattern, Pattern2 - Pattern)) { + Pattern2 += 2; + Ptr = Line; + while (*Ptr != 0x0D && *Ptr != 0x0A) { + Ptr++; + } + + *Ptr = 0; + strcat (Line, Pattern2); + strcat (Line, "\r\n"); + } + } + } + + return 0; +} + +void +Usage ( + void + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + None + +Returns: + + GC_TODO: add return values + +--*/ +{ + printf ("ModifyInf InputFVInfFileName OutputFVInfFileName [Pattern strings]\r\n"); +} + +int +main ( + int argc, + char*argv[] + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + argc - GC_TODO: add argument description + ] - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + char LineBuffer[256]; + FILE *fpin; + FILE *fpout; + + if (argc < 3) { + Usage (); + return -1; + } + + fpin = fopen (argv[1], "rb"); + if (!fpin) { + printf ("Can't open input file!\r\n"); + return -1; + } + + fpout = fopen (argv[2], "wb"); + if (!fpout) { + fclose (fpin); + printf ("Can't create output file!\r\n"); + return -1; + } + + while (ReadLine (LineBuffer, fpin)) { + ApplyPattern (LineBuffer, argv, argc); + WriteLine (LineBuffer, fpout); + } + + fclose (fpin); + fclose (fpout); + + return 0; +} diff --git a/Tools/CodeTools/Source/ModifyInf/build.xml b/Tools/CodeTools/Source/ModifyInf/build.xml new file mode 100644 index 0000000000..a695ae0e80 --- /dev/null +++ b/Tools/CodeTools/Source/ModifyInf/build.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/Pccts/CHANGES_FROM_131.txt b/Tools/CodeTools/Source/Pccts/CHANGES_FROM_131.txt new file mode 100644 index 0000000000..500d84f2e8 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/CHANGES_FROM_131.txt @@ -0,0 +1,522 @@ +CHANGES FROM 1.31 + +This file contains the migration of PCCTS from 1.31 in the order that +changes were made. 1.32b7 is the last beta before full 1.32. +Terence Parr, Parr Research Corporation 1995. + + +====================================================================== +1.32b1 +Added Russell Quong to banner, changed banner for output slightly +Fixed it so that you have before / after actions for C++ in class def +Fixed bug in optimizer that made it sometimes forget to set internal + token pointers. Only showed up when a {...} was in the "wrong spot". + +====================================================================== +1.32b2 +Added fixes by Dave Seidel for PC compilers in 32 bit mode (config.h +and set.h). + +====================================================================== +1.32b3 +Fixed hideous bug in code generator for wildcard and for ~token op. + +from Dave Seidel + + Added pcnames.bat + 1. in antlr/main.c: change strcasecmp() to stricmp() + + 2. in dlg/output.c: use DLEXER_C instead on "DLexer.C" + + 3. in h/PBlackBox.h: use instead of + +====================================================================== +1.32b4 +When the -ft option was used, any path prefix screwed up +the gate on the .h files + +Fixed yet another bug due to the optimizer. + +The exception handling thing was a bit wacko: + +a : ( A B )? A B + | A C + ; + exception ... + +caused an exception if "A C" was the input. In other words, +it found that A C didn't match the (A B)? pred and caused +an exception rather than trying the next alt. All I did +was to change the zzmatch_wsig() macros. + +Fixed some problems in gen.c relating to the name of token +class bit sets in the output. + +Added the tremendously cool generalized predicate. For the +moment, I'll give this bried description. + +a : <>? blah + | foo + ; + +This implies that (assuming blah and foo are syntactically +ambiguous) "predicate" indicates the semantic validity of +applying "blah". If "predicate" is false, "foo" is attempted. + +Previously, you had to say: + +a : <>? ID + | ID + ; + +Now, you can simply use "predicate" without the ?: operator +if you turn on ANTLR command line option: "-prc on". This +tells ANTLR to compute that all by itself. It computes n +tokens of lookahead where LT(n) or LATEXT(n) is the farthest +ahead you look. + +If you give a predicate using "-prc on" that is followed +by a construct that can recognize more than one n-sequence, +you will get a warning from ANTLR. For example, + +a : <getText())>>? (ID|INT) + ; + +This is wrong because the predicate will be applied to INTs +as well as ID's. You should use this syntax to make +the predicate more specific: + +a : (ID)? => <getText())>>? (ID|INT) + ; + +which says "don't apply the predicate unless ID is the +current lookahead context". + +You cannot currently have anything in the "(context)? =>" +except sequences such as: + +( LPAREN ID | LPAREN SCOPE )? => <>? + +I haven't tested this THAT much, but it does work for the +C++ grammar. + +====================================================================== +1.32b5 + +Added getLine() to the ANTLRTokenBase and DLGBasedToken classes +left line() for backward compatibility. +---- +Removed SORCERER_TRANSFORM from the ast.h stuff. +------- +Fixed bug in code gen of ANTLR such that nested syn preds work more +efficiently now. The ANTLRTokenBuffer was getting very large +with nested predicates. +------ +Memory leak is now gone from ANTLRTokenBuf; all tokens are deleted. +For backward compatibility reasons, you have to say parser->deleteTokens() +or mytokenbuffer->deleteTokens() but later it will be the default mode. +Say this after the parser is constructed. E.g., + + ParserBlackBox p(stdin); + p.parser()->deleteTokens(); + p.parser()->start_symbol(); + + +============================== +1.32b6 + +Changed so that deleteTokens() will do a delete ((ANTLRTokenBase *)) +on the ptr. This gets the virtual destructor. + +Fixed some weird things in the C++ header files (a few return types). + +Made the AST routines correspond to the book and SORCERER stuff. + +New token stuff: See testcpp/14/test.g + +ANTLR accepts a #pragma gc_tokens which says +[1] Generate label = copy(LT(1)) instead of label=LT(1) for + all labeled token references. +[2] User now has to define ANTLRTokenPtr (as a class or a typedef + to just a pointer) as well as the ANTLRToken class itself. + See the example. + +To delete tokens in token buffer, use deleteTokens() message on parser. + + All tokens that fall off the ANTLRTokenBuffer get deleted + which is what currently happens when deleteTokens() message + has been sent to token buffer. + +We always generate ANTLRTokenPtr instead of 'ANTLRToken *' now. +Then if no pragma set, ANTLR generates a + + class ANTLRToken; + typedef ANTLRToken *ANTLRTokenPtr; + +in each file. + +Made a warning for x:rule_ref <<$x>>; still no warning for $i's, however. +class BB { + +a : x:b y:A <<$x +$y>> + ; + +b : B; + +} +generates +Antlr parser generator Version 1.32b6 1989-1995 +test.g, line 3: error: There are no token ptrs for rule references: '$x' + +=================== +1.32b7: + +[With respect to token object garbage collection (GC), 1.32b7 + backtracks from 1.32b6, but results in better and less intrusive GC. + This is the last beta version before full 1.32.] + +BIGGEST CHANGES: + +o The "#pragma gc_tokens" is no longer used. + +o .C files are now .cpp files (hence, makefiles will have to + be changed; or you can rerun genmk). This is a good move, + but causes some backward incompatibility problems. You can + avoid this by changing CPP_FILE_SUFFIX to ".C" in pccts/h/config.h. + +o The token object class hierarchy has been flattened to include + only three classes: ANTLRAbstractToken, ANTLRCommonToken, and + ANTLRCommonNoRefCountToken. The common token now does garbage + collection via ref counting. + +o "Smart" pointers are now used for garbage collection. That is, + ANTLRTokenPtr is used instead of "ANTLRToken *". + +o The antlr.1 man page has been cleaned up slightly. + +o The SUN C++ compiler now complains less about C++ support code. + +o Grammars which subclass ANTLRCommonToken must wrap all token + pointer references in mytoken(token_ptr). This is the only + serious backward incompatibility. See below. + + +MINOR CHANGES: + +-------------------------------------------------------- +1 deleteTokens() + +The deleteTokens() message to the parser or token buffer has been changed +to one of: + + void noGarbageCollectTokens() { inputTokens->noGarbageCollectTokens(); } + void garbageCollectTokens() { inputTokens->garbageCollectTokens(); } + +The token buffer deletes all non-referenced tokens by default now. + +-------------------------------------------------------- +2 makeToken() + +The makeToken() message returns a new type. The function should look +like: + + virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt, + ANTLRChar *txt, + int line) + { + ANTLRAbstractToken *t = new ANTLRCommonToken(tt,txt); + t->setLine(line); + return t; + } + +-------------------------------------------------------- +3 TokenType + +Changed TokenType-> ANTLRTokenType (often forces changes in AST defs due +to #[] constructor called to AST(tokentype, string)). + +-------------------------------------------------------- +4 AST() + +You must define AST(ANTLRTokenPtr t) now in your AST class definition. +You might also have to include ATokPtr.h above the definition; e.g., +if AST is defined in a separate file, such as AST.h, it's a good idea +to include ATOKPTR_H (ATokPtr.h). For example, + + #include ATOKPTR_H + class AST : public ASTBase { + protected: + ANTLRTokenPtr token; + public: + AST(ANTLRTokenPtr t) { token = t; } + void preorder_action() { + char *s = token->getText(); + printf(" %s", s); + } + }; + +Note the use of smart pointers rather than "ANTLRToken *". + +-------------------------------------------------------- +5 SUN C++ + +From robertb oakhill.sps.mot.com Bob Bailey. Changed ANTLR C++ output +to avoid an error in Sun C++ 3.0.1. Made "public" return value +structs created to hold multiple return values public. + +-------------------------------------------------------- +6 genmk + +Fixed genmk so that target List.* is not included anymore. It's +called SList.* anyway. + +-------------------------------------------------------- +7 \r vs \n + +Scott Vorthmann fixed antlr.g in ANTLR so that \r +is allowed as the return character as well as \n. + +-------------------------------------------------------- +8 Exceptions + +Bug in exceptions attached to labeled token/tokclass references. Didn't gen +code for exceptions. This didn't work: + +a : "help" x:ID + ; + exception[x] + catch MismatchedToken : <> + +Now ANTLR generates (which is kinda big, but necessary): + + if ( !_match_wsig(ID) ) { + if ( guessing ) goto fail; + _signal=MismatchedToken; + switch ( _signal ) { + case MismatchedToken : + printf("eh?\n"); + _signal = NoSignal; + break; + default : + goto _handler; + } + } + +which implies that you can recover and continue parsing after a missing/bad +token reference. + +-------------------------------------------------------- +9 genmk + +genmk now correctly uses config file for CPP_FILE_SUFFIX stuff. + +-------------------------------------------------------- +10 general cleanup / PURIFY + +Anthony Green suggested a bunch of good general +clean up things for the code; he also suggested a few things to +help out the "PURIFY" memory allocation checker. + +-------------------------------------------------------- +11 $-variable references. + +Manuel ORNATO indicated that a $-variable outside of a rule caused +ANTLR to crash. I fixed this. + +12 Tom Moog suggestion + +Fail action of semantic predicate needs "{}" envelope. FIXED. + +13 references to LT(1). + +I have enclosed all assignments such as: + + _t22 = (ANTLRTokenPtr)LT(1); + +in "if ( !guessing )" so that during backtracking the reference count +for token objects is not increased. + + +TOKEN OBJECT GARBAGE COLLECTION + +1 INTRODUCTION + +The class ANTLRCommonToken is now garbaged collected through a "smart" +pointer called ANTLRTokenPtr using reference counting. Any token +object not referenced by your grammar actions is destroyed by the +ANTLRTokenBuffer when it must make room for more token objects. +Referenced tokens are then destroyed in your parser when local +ANTLRTokenPtr objects are deleted. For example, + +a : label:ID ; + +would be converted to something like: + +void yourclass::a(void) +{ + zzRULE; + ANTLRTokenPtr label=NULL; // used to be ANTLRToken *label; + zzmatch(ID); + label = (ANTLRTokenPtr)LT(1); + consume(); + ... +} + +When the "label" object is destroyed (it's just a pointer to your +input token object LT(1)), it decrements the reference count on the +object created for the ID. If the count goes to zero, the object +pointed by label is deleted. + +To correctly manage the garbage collection, you should use +ANTLRTokenPtr instead of "ANTLRToken *". Most ANTLR support code +(visible to the user) has been modified to use the smart pointers. + +*************************************************************** +Remember that any local objects that you create are not deleted when a +lonjmp() is executed. Unfortunately, the syntactic predicates (...)? +use setjmp()/longjmp(). There are some situations when a few tokens +will "leak". +*************************************************************** + +2 DETAILS + +o The default is to perform token object garbage collection. + You may use parser->noGarbageCollectTokens() to turn off + garbage collection. + + +o The type ANTLRTokenPtr is always defined now (automatically). + If you do not wish to use smart pointers, you will have to + redefined ANTLRTokenPtr by subclassing, changing the header + file or changing ANTLR's code generation (easy enough to + do in gen.c). + +o If you don't use ParserBlackBox, the new initialization sequence is: + + ANTLRTokenPtr aToken = new ANTLRToken; + scan.setToken(mytoken(aToken)); + + where mytoken(aToken) gets an ANTLRToken * from the smart pointer. + +o Define C++ preprocessor symbol DBG_REFCOUNTTOKEN to see a bunch of + debugging stuff for reference counting if you suspect something. + + +3 WHY DO I HAVE TO TYPECAST ALL MY TOKEN POINTERS NOW?????? + +If you subclass ANTLRCommonToken and then attempt to refer to one of +your token members via a token pointer in your grammar actions, the +C++ compiler will complain that your token object does not have that +member. For example, if you used to do this + +<< +class ANTLRToken : public ANTLRCommonToken { + int muck; + ... +}; +>> + +class Foo { +a : t:ID << t->muck = ...; >> ; +} + +Now, you must do change the t->muck reference to: + +a : t:ID << mytoken(t)->muck = ...; >> ; + +in order to downcast 't' to be an "ANTLRToken *" not the +"ANTLRAbstractToken *" resulting from ANTLRTokenPtr::operator->(). +The macro is defined as: + +/* + * Since you cannot redefine operator->() to return one of the user's + * token object types, we must down cast. This is a drag. Here's + * a macro that helps. template: "mytoken(a-smart-ptr)->myfield". + */ +#define mytoken(tp) ((ANTLRToken *)(tp.operator->())) + +You have to use macro mytoken(grammar-label) now because smart +pointers are not specific to a parser's token objects. In other +words, the ANTLRTokenPtr class has a pointer to a generic +ANTLRAbstractToken not your ANTLRToken; the ANTLR support code must +use smart pointers too, but be able to work with any kind of +ANTLRToken. Sorry about this, but it's C++'s fault not mine. Some +nebulous future version of the C++ compilers should obviate the need +to downcast smart pointers with runtime type checking (and by allowing +different return type of overridden functions). + +A way to have backward compatible code is to shut off the token object +garbage collection; i.e., use parser->noGarbageCollectTokens() and +change the definition of ANTLRTokenPtr (that's why you get source code +). + + +PARSER EXCEPTION HANDLING + +I've noticed some weird stuff with the exception handling. I intend +to give this top priority for the "book release" of ANTLR. + +========== +1.32 Full Release + +o Changed Token class hierarchy to be (Thanks to Tom Moog): + + ANTLRAbstractToken + ANTLRRefCountToken + ANTLRCommonToken + ANTLRNoRefCountCommonToken + +o Added virtual panic() to ANTLRAbstractToken. Made ANTLRParser::panic() + virtual also. + +o Cleaned up the dup() stuff in AST hierarchy to use shallowCopy() to + make node copies. John Farr at Medtronic suggested this. I.e., + if you want to use dup() with either ANTLR or SORCERER or -transform + mode with SORCERER, you must defined shallowCopy() as: + + virtual PCCTS_AST *shallowCopy() + { + return new AST; + p->setDown(NULL); + p->setRight(NULL); + return p; + } + + or + + virtual PCCTS_AST *shallowCopy() + { + return new AST(*this); + } + + if you have defined a copy constructor such as + + AST(const AST &t) // shallow copy constructor + { + token = t.token; + iconst = t.iconst; + setDown(NULL); + setRight(NULL); + } + +o Added a warning with -CC and -gk are used together. This is broken, + hence a warning is appropriate. + +o Added warning when #-stuff is used w/o -gt option. + +o Updated MPW installation. + +o "Miller, Philip W." suggested + that genmk be use RENAME_OBJ_FLAG RENAME_EXE_FLAG instead of + hardcoding "-o" in genmk.c. + +o made all exit() calls use EXIT_SUCCESS or EXIT_FAILURE. + +=========================================================================== +1.33 + +EXIT_FAILURE and EXIT_SUCCESS were not always defined. I had to modify +a bunch of files to use PCCTS_EXIT_XXX, which forces a new version. Sorry +about that. + diff --git a/Tools/CodeTools/Source/Pccts/CHANGES_FROM_133.txt b/Tools/CodeTools/Source/Pccts/CHANGES_FROM_133.txt new file mode 100644 index 0000000000..2128c4ff25 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/CHANGES_FROM_133.txt @@ -0,0 +1,2448 @@ +======================================================================= +List of Implemented Fixes and Changes for Maintenance Releases of PCCTS +======================================================================= + + DISCLAIMER + + The software and these notes are provided "as is". They may include + typographical or technical errors and their authors disclaims all + liability of any kind or nature for damages due to error, fault, + defect, or deficiency regardless of cause. All warranties of any + kind, either express or implied, including, but not limited to, the + implied warranties of merchantability and fitness for a particular + purpose are disclaimed. + + + ------------------------------------------------------- + Note: Items #153 to #1 are now in a separate file named + CHANGES_FROM_133_BEFORE_MR13.txt + ------------------------------------------------------- + +#312. (Changed in MR33) Bug caused by change #299. + + In change #299 a warning message was suppressed when there was + no LT(1) in a semantic predicate and max(k,ck) was 1. The + changed caused the code which set a default predicate depth for + the semantic predicate to be left as 0 rather than set to 1. + + This manifested as an error at line #1559 of mrhost.c + + Reported by Peter Dulimov. + +#311. (Changed in MR33) Added sorcer/lib to Makefile. + + Reported by Dale Martin. + +#310. (Changed in MR32) In C mode zzastPush was spelled zzastpush in one case. + + Reported by Jean-Claude Durand + +#309. (Changed in MR32) Renamed baseName because of VMS name conflict + + Renamed baseName to pcctsBaseName to avoid library name conflict with + VMS library routine. Reported by Jean-François PIÉRONNE. + +#308. (Changed in MR32) Used "template" as name of formal in C routine + + In astlib.h routine ast_scan a formal was named "template". This caused + problems when the C code was compiled with a C++ compiler. Reported by + Sabyasachi Dey. + +#307. (Changed in MR31) Compiler dependent bug in function prototype generation + + The code which generated function prototypes contained a bug which + was compiler/optimization dependent. Under some circumstance an + extra character would be included in portions of a function prototype. + + Reported by David Cook. + +#306. (Changed in MR30) Validating predicate following a token + + A validating predicate which immediately followed a token match + consumed the token after the predicate rather than before. Prior + to this fix (in the following example) isValidTimeScaleValue() in + the predicate would test the text for TIMESCALE rather than for + NUMBER: + + time_scale : + TIMESCALE + <getText())>>? + ts:NUMBER + ( us:MICROSECOND << tVal = ...>> + | ns:NANOSECOND << tVal = ... >> + ) + + Reported by Adalbert Perbandt. + +#305. (Changed in MR30) Alternatives with guess blocks inside (...)* blocks. + + In MR14 change #175 fixed a bug in the prediction expressions for guess + blocks which were of the form (alpha)? beta. Unfortunately, this + resulted in a new bug as exemplified by the example below, which computed + the first set for r as {B} rather than {B C}: + + r : ( (A)? B + | C + )* + + This example doesn't make any sense as A is not a prefix of B, but it + illustrates the problem. This bug did not appear for: + + r : ( (A)? + | C + )* + + because it does not use the (alpha)? beta form. + + Item #175 fixed an asymmetry in ambiguity messages for the following + constructs which appear to have identical ambiguities (between repeating + the loop vs. exiting the loop). MR30 retains this fix, but the implementation + is slightly different. + + r_star : ( (A B)? )* A ; + r_plus : ( (A B)? )+ A ; + + Reported by Arpad Beszedes (beszedes inf.u-szeged.hu). + +#304. (Changed in MR30) Crash when mismatch between output value counts. + + For a rule such as: + + r1 : r2>[i,j]; + r2 >[int i, int j] : A; + + If there were extra actuals for the reference to rule r2 from rule r1 + there antlr would crash. This bug was introduced by change #276. + + Reported by Sinan Karasu. + +#303. (Changed in MR30) DLGLexerBase::replchar + + DLGLexerBase::replchar and the C mode routine zzreplchar did not work + properly when the new character was 0. + + Reported with fix by Philippe Laporte + +#302. (Changed in MR28) Fix significant problems in initial release of MR27. + +#301. (Changed in MR27) Default tab stops set to 2 spaces. + + To have antlr generate true tabs rather than spaces, use "antlr -tab 0". + To generate 4 spaces per tab stop use "antlr -tab 4" + +#300. (Changed in MR27) + + Consider the following methods of constructing an AST from ID: + + rule1! + : id:ID << #0 = #[id]; >> ; + + rule2! + : id:ID << #0 = #id; >> ; + + rule3 + : ID ; + + rule4 + : id:ID << #0 = #id; >> ; + + For rule_2, the AST corresponding to id would always be NULL. This + is because the user explicitly suppressed AST construction using the + "!" operator on the rule. In MR27 the use of an AST expression + such as #id overrides the "!" operator and forces construction of + the AST. + + This fix does not apply to C mode ASTs when the ASTs are referenced + using numbers rather than symbols. + + For C mode, this requires that the (optional) function/macro zzmk_ast + be defined. This functions copies information from an attribute into + a previously allocated AST. + + Reported by Jan Langer (jan langernetz.de) + +#299. (Changed in MR27) Don't warn if k=1 and semantic predicate missing LT(i) + + If a semantic does not have a reference to LT(i) or (C mode LATEXT(i)) + then pccts doesn't know how many lookahead tokens to use for context. + However, if max(k,ck) is 1 then there is really only one choice and + the warning is unnecessary. + +#298. (Changed in MR27) Removed "register" for lastpos in dlgauto.c zzgettok + +#297. (Changed in MR27) Incorrect prototypes when used with classic C + + There were a number of errors in function headers when antlr was + built with compilers that do not have __STDC__ or __cplusplus set. + + The functions which have variable length argument lists now use + PCCTS_USE_STDARG rather than __USE_PROTOTYPES__ to determine + whether to use stdargs or varargs. + +#296. (Changed in MR27) Complex return types in rules. + + The following return type was not properly handled when + unpacking a struct with containing multiple return values: + + rule > [int i, IIR_Bool (IIR_Decl::*constraint)()] : ... + + Instead of using "constraint", the program got lost and used + an empty string. + + Reported by P.A. Wilsey. + +#295. (Changed in MR27) Extra ";" following zzGUESS_DONE sometimes. + + Certain constructs with guess blocks in MR23 led to extra ";" + preceding the "else" clause of an "if". + + Reported by P.A. Wilsey. + +#294. (Changed in MR27) Infinite loop in antlr for nested blocks + + An oversight in detecting an empty alternative sometimes led + to an infinite loop in antlr when it encountered a rule with + nested blocks and guess blocks. + + Reported by P.A. Wilsey. + +#293. (Changed in MR27) Sorcerer optimization of _t->type() + + Sorcerer generated code may contain many calls to _t->type() in a + single statement. This change introduces a temporary variable + to eliminate unnnecesary function calls. + + Change implemented by Tom Molteno (tim videoscript.com). + +#292. (Changed in MR27) + + WARNING: Item #267 changes the signature of methods in the AST class. + + **** Be sure to revise your AST functions of the same name *** + +#291. (Changed in MR24) + + Fix to serious code generation error in MR23 for (...)+ block. + +#290. (Changed in MR23) + + Item #247 describes a change in the way {...} blocks handled + an error. Consider: + + r1 : {A} b ; + b : B; + + with input "C". + + Prior to change #247, the error would resemble "expected B - + found C". This is correct but incomplete, and therefore + misleading. In #247 it was changed to "expected A, B - found + C". This was fine, except for users of parser exception + handling because the exception was generated in the epilogue + for {...} block rather than in rule b. This made it difficult + for users of parser exception handling because B was not + expected in that context. Those not using parser exception + handling didn't notice the difference. + + The current change restores the behavior prior to #247 when + parser exceptions are present, but retains the revised behavior + otherwise. This change should be visible only when exceptions + are in use and only for {...} blocks and sub-blocks of the form + (something|something | something | epsilon) where epsilon represents + an empty production and it is the last alternative of a sub-block. + In contrast, (something | epsilon | something) should generate the + same code as before, even when exceptions are used. + + Reported by Philippe Laporte (philippe at transvirtual.com). + +#289. (Changed in MR23) Bug in matching complement of a #tokclass + + Prior to MR23 when a #tokclass was matched in both its complemented form + and uncomplemented form, the bit set generated for its first use was used + for both cases. However, the prediction expression was correctly computed + in both cases. This meant that the second case would never be matched + because, for the second appearance, the prediction expression and the + set to be matched would be complements of each other. + + Consider: + + #token A "a" + #token B "b" + #token C "c" + #tokclass AB {A B} + + r1 : AB /* alt 1x */ + | ~AB /* alt 1y */ + ; + + Prior to MR23, this resulted in alternative 1y being unreachable. Had it + been written: + + r2 : ~AB /* alt 2x */ + : AB /* alt 2y */ + + then alternative 2y would have become unreachable. + + This bug was only for the case of complemented #tokclass. For complemented + #token the proper code was generated. + +#288. (Changed in MR23) #errclass not restricted to choice points + + The #errclass directive is supposed to allow a programmer to define + print strings which should appear in syntax error messages as a replacement + for some combinations of tokens. For instance: + + #errclass Operator {PLUS MINUS TIMES DIVIDE} + + If a syntax message includes all four of these tokens, and there is no + "better" choice of error class, the word "Operator" will be used rather + than a list of the four token names. + + Prior to MR23 the #errclass definitions were used only at choice points + (which call the FAIL macro). In other cases where there was no choice + (e.g. where a single token or token class were matched) the #errclass + information was not used. + + With MR23 the #errclass declarations are used for syntax error messages + when matching a #tokclass, a wildcard (i.e. "*"), or the complement of a + #token or #tokclass (e.g. ~Operator). + + Please note that #errclass may now be defined using #tokclass names + (see Item #284). + + Reported by Philip A. Wilsey. + +#287. (Changed in MR23) Print name for #tokclass + + Item #148 describes how to give a print name to a #token so that,for + example, #token ID could have the expression "identifier" in syntax + error messages. This has been extended to #tokclass: + + #token ID("identifier") "[a-zA-Z]+" + #tokclass Primitive("primitive type") + {INT, FLOAT, CHAR, FLOAT, DOUBLE, BOOL} + + This is really a cosmetic change, since #tokclass names do not appear + in any error messages. + +#286. (Changed in MR23) Makefile change to use of cd + + In cases where a pccts subdirectory name matched a directory identified + in a $CDPATH environment variable the build would fail. All makefile + cd commands have been changed from "cd xyz" to "cd ./xyz" in order + to avoid this problem. + +#285. (Changed in MR23) Check for null pointers in some dlg structures + + An invalid regular expression can cause dlg to build an invalid + structure to represent the regular expression even while it issues + error messages. Additional pointer checks were added. + + Reported by Robert Sherry. + +#284. (Changed in MR23) Allow #tokclass in #errclass definitions + + Previously, a #tokclass reference in the definition of an + #errclass was not handled properly. Instead of being expanded + into the set of tokens represented by the #tokclass it was + treated somewhat like an #errclass. However, in a later phase + when all #errclass were expanded into the corresponding tokens + the #tokclass reference was not expanded (because it wasn't an + #errclass). In effect the reference was ignored. + + This has been fixed. + + Problem reported by Mike Dimmick (mike dimmick.demon.co.uk). + +#283. (Changed in MR23) Option -tmake invoke's parser's tmake + + When the string #(...) appears in an action antlr replaces it with + a call to ASTBase::tmake(...) to construct an AST. It is sometimes + useful to change the tmake routine so that it has access to information + in the parser - something which is not possible with a static method + in an application where they may be multiple parsers active. + + The antlr option -tmake replaces the call to ASTBase::tmake with a call + to a user supplied tmake routine. + +#282. (Changed in MR23) Initialization error for DBG_REFCOUNTTOKEN + + When the pre-processor symbol DBG_REFCOUNTTOKEN is defined + incorrect code is generated to initialize ANTLRRefCountToken::ctor and + dtor. + + Fix reported by Sven Kuehn (sven sevenkuehn.de). + +#281. (Changed in MR23) Addition of -noctor option for Sorcerer + + Added a -noctor option to suppress generation of the blank ctor + for users who wish to define their own ctor. + + Contributed by Jan Langer (jan langernetz.de). + +#280. (Changed in MR23) Syntax error message for EOF token + + The EOF token now receives special treatment in syntax error messages + because there is no text matched by the eof token. The token name + of the eof token is used unless it is "@" - in which case the string + "" is used. + + Problem reported by Erwin Achermann (erwin.achermann switzerland.org). + +#279. (Changed in MR23) Exception groups + + There was a bug in the way that exception groups were attached to + alternatives which caused problems when there was a block contained + in an alternative. For instance, in the following rule; + + statement : IF S { ELSE S } + exception .... + ; + + the exception would be attached to the {...} block instead of the + entire alternative because it was attached, in error, to the last + alternative instead of the last OPEN alternative. + + Reported by Ty Mordane (tymordane hotmail.com). + +#278. (Changed in MR23) makefile changes + + Contributed by Tomasz Babczynski (faster lab05-7.ict.pwr.wroc.pl). + + The -cfile option is not absolutely needed: when extension of + source file is one of the well-known C/C++ extensions it is + treated as C/C++ source + + The gnu make defines the CXX variable as the default C++ compiler + name, so I added a line to copy this (if defined) to the CCC var. + + Added a -sor option: after it any -class command defines the class + name for sorcerer, not for ANTLR. A file extended with .sor is + treated as sorcerer input. Because sorcerer can be called multiple + times, -sor option can be repeated. Any files and classes (one class + per group) after each -sor makes one tree parser. + + Not implemented: + + 1. Generate dependences for user c/c++ files. + 2. Support for -sor in c mode not. + + I have left the old genmk program in the directory as genmk_old.c. + +#277. (Changed in MR23) Change in macro for failed semantic predicates + + In the past, a semantic predicate that failed generated a call to + the macro zzfailed_pred: + + #ifndef zzfailed_pred + #define zzfailed_pred(_p) \ + if (guessing) { \ + zzGUESS_FAIL; \ + } else { \ + something(_p) + } + #endif + + If a user wished to use the failed action option for semantic predicates: + + rule : <>? [my_fail_action] A + | ... + + + the code for my_fail_action would have to contain logic for handling + the guess part of the zzfailed_pred macro. The user should not have + to be aware of the guess logic in writing the fail action. + + The zzfailed_pred has been rewritten to have three arguments: + + arg 1: the stringized predicate of the semantic predicate + arg 2: 0 => there is no user-defined fail action + 1 => there is a user-defined fail action + arg 3: the user-defined fail action (if defined) + otherwise a no-operation + + The zzfailed_pred macro is now defined as: + + #ifndef zzfailed_pred + #define zzfailed_pred(_p,_hasuseraction,_useraction) \ + if (guessing) { \ + zzGUESS_FAIL; \ + } else { \ + zzfailed_pred_action(_p,_hasuseraction,_useraction) \ + } + #endif + + + With zzfailed_pred_action defined as: + + #ifndef zzfailed_pred_action + #define zzfailed_pred_action(_p,_hasuseraction,_useraction) \ + if (_hasUserAction) { _useraction } else { failedSemanticPredicate(_p); } + #endif + + In C++ mode failedSemanticPredicate() is a virtual function. + In C mode the default action is a fprintf statement. + + Suggested by Erwin Achermann (erwin.achermann switzerland.org). + +#276. (Changed in MR23) Addition of return value initialization syntax + + In an attempt to reduce the problems caused by the PURIFY macro I have + added new syntax for initializing the return value of rules and the + antlr option "-nopurify". + + A rule with a single return argument: + + r1 > [Foo f = expr] : + + now generates code that resembles: + + Foo r1(void) { + Foo _retv = expr; + ... + } + + A rule with more than one return argument: + + r2 > [Foo f = expr1, Bar b = expr2 ] : + + generates code that resembles: + + struct _rv1 { + Foo f; + Bar b; + } + + _rv1 r2(void) { + struct _rv1 _retv; + _retv.f = expr1; + _retv.b = expr2; + ... + } + + C++ style comments appearing in the initialization list may cause problems. + +#275. (Changed in MR23) Addition of -nopurify option to antlr + + A long time ago the PURIFY macro was introduced to initialize + return value arguments and get rid of annying messages from program + that checked for unitialized variables. + + This has caused significant annoyance for C++ users that had + classes with virtual functions or non-trivial contructors because + it would zero the object, including the pointer to the virtual + function table. This could be defeated by redefining + the PURIFY macro to be empty, but it was a constant surprise to + new C++ users of pccts. + + I would like to remove it, but I fear that some existing programs + depend on it and would break. My temporary solution is to add + an antlr option -nopurify which disables generation of the PURIFY + macro call. + + The PURIFY macro should be avoided in favor of the new syntax + for initializing return arguments described in item #275. + + To avoid name clash, the PURIFY macro has been renamed PCCTS_PURIFY. + +#274. (Changed in MR23) DLexer.cpp renamed to DLexer.h + (Changed in MR23) ATokPtr.cpp renamed to ATokPtrImpl.h + + These two files had .cpp extensions but acted like .h files because + there were included in other files. This caused problems for many IDE. + I have renamed them. The ATokPtrImpl.h was necessary because there was + already an ATokPtr.h. + +#273. (Changed in MR23) Default win32 library changed to multi-threaded DLL + + The model used for building the Win32 debug and release libraries has changed + to multi-threaded DLL. + + To make this change in your MSVC 6 project: + + Project -> Settings + Select the C++ tab in the right pane of the dialog box + Select "Category: Code Generation" + Under "Use run-time library" select one of the following: + + Multi-threaded DLL + Debug Multi-threaded DLL + + Suggested by Bill Menees (bill.menees gogallagher.com) + +#272. (Changed in MR23) Failed semantic predicate reported via virtual function + + In the past, a failed semantic predicated reported the problem via a + macro which used fprintf(). The macro now expands into a call on + the virtual function ANTLRParser::failedSemanticPredicate(). + +#271. (Changed in MR23) Warning for LT(i), LATEXT(i) in token match actions + + An bug (or at least an oddity) is that a reference to LT(1), LA(1), + or LATEXT(1) in an action which immediately follows a token match + in a rule refers to the token matched, not the token which is in + the lookahead buffer. Consider: + + r : abc <> D <> E; + + In this case LT(1) in action alpha will refer to the next token in + the lookahead buffer ("D"), but LT(1) in action beta will refer to + the token matched by D - the preceding token. + + A warning has been added for users about this when an action + following a token match contains a reference to LT(1), LA(1), or LATEXT(1). + + This behavior should be changed, but it appears in too many programs + now. Another problem, perhaps more significant, is that the obvious + fix (moving the consume() call to before the action) could change the + order in which input is requested and output appears in existing programs. + + This problem was reported, along with a fix by Benjamin Mandel + (beny sd.co.il). However, I felt that changing the behavior was too + dangerous for existing code. + +#270. (Changed in MR23) Removed static objects from PCCTSAST.cpp + + There were some statically allocated objects in PCCTSAST.cpp + These were changed to non-static. + +#269. (Changed in MR23) dlg output for initializing static array + + The output from dlg contains a construct similar to the + following: + + struct XXX { + static const int size; + static int array1[5]; + }; + + const int XXX::size = 4; + int XXX::array1[size+1]; + + + The problem is that although the expression "size+1" used in + the definition of array1 is equal to 5 (the expression used to + declare array), it is not considered equivalent by some compilers. + + Reported with fix by Volker H. Simonis (simonis informatik.uni-tuebingen.de) + +#268. (Changed in MR23) syn() routine output when k > 1 + + The syn() routine is supposed to print out the text of the + token causing the syntax error. It appears that it always + used the text from the first lookahead token rather than the + appropriate one. The appropriate one is computed by comparing + the token codes of lookahead token i (for i = 1 to k) with + the FIRST(i) set. + + This has been corrected in ANTLRParser::syn(). + + Reported by Bill Menees (bill.menees gogallagher.com) + +#267. (Changed in MR23) AST traversal functions client data argument + + The AST traversal functions now take an extra (optional) parameter + which can point to client data: + + preorder_action(void* pData = NULL) + preorder_before_action(void* pData = NULL) + preorder_after_action(void* pData = NULL) + + **** Warning: this changes the AST signature. *** + **** Be sure to revise your AST functions of the same name *** + + Bill Menees (bill.menees gogallagher.com) + +#266. (Changed in MR23) virtual function printMessage() + + Bill Menees (bill.menees gogallagher.com) has completed the + tedious taks of replacing all calls to fprintf() with calls + to the virtual function printMessage(). For classes which + have a pointer to the parser it forwards the printMessage() + call to the parser's printMessage() routine. + + This should make it significanly easier to redirect pccts + error and warning messages. + +#265. (Changed in MR23) Remove "labase++" in C++ mode + + In C++ mode labase++ is called when a token is matched. + It appears that labase is not used in C++ mode at all, so + this code has been commented out. + +#264. (Changed in MR23) Complete rewrite of ParserBlackBox.h + + The parser black box (PBlackBox.h) was completely rewritten + by Chris Uzdavinis (chris atdesk.com) to improve its robustness. + +#263. (Changed in MR23) -preamble and -preamble_first rescinded + + Changes for item #253 have been rescinded. + +#262. (Changed in MR23) Crash with -alpha option during traceback + + Under some circumstances a -alpha traceback was started at the + "wrong" time. As a result, internal data structures were not + initialized. + + Reported by Arpad Beszedes (beszedes inf.u-szeged.hu). + +#261. (Changed in MR23) Defer token fetch for C++ mode + + Item #216 has been revised to indicate that use of the defer fetch + option (ZZDEFER_FETCH) requires dlg option -i. + +#260. (MR22) Raise default lex buffer size from 8,000 to 32,000 bytes. + + ZZLEXBUFSIZE is the size (in bytes) of the buffer used by dlg + generated lexers. The default value has been raised to 32,000 and + the value used by antlr, dlg, and sorcerer has also been raised to + 32,000. + +#259. (MR22) Default function arguments in C++ mode. + + If a rule is declared: + + rr [int i = 0] : .... + + then the declaration generated by pccts resembles: + + void rr(int i = 0); + + however, the definition must omit the default argument: + + void rr(int i) {...} + + In the past the default value was not omitted. In MR22 + the generated code resembles: + + void rr(int i /* = 0 */ ) {...} + + Implemented by Volker H. Simonis (simonis informatik.uni-tuebingen.de) + + + Note: In MR23 this was changed so that nested C style comments + ("/* ... */") would not cause problems. + +#258. (MR22) Using a base class for your parser + + In item #102 (MR10) the class statement was extended to allow one + to specify a base class other than ANTLRParser for the generated + parser. It turned out that this was less than useful because + the constructor still specified ANTLRParser as the base class. + + The class statement now uses the first identifier appearing after + the ":" as the name of the base class. For example: + + class MyParser : public FooParser { + + Generates in MyParser.h: + + class MyParser : public FooParser { + + Generates in MyParser.cpp something that resembles: + + MyParser::MyParser(ANTLRTokenBuffer *input) : + FooParser(input,1,0,0,4) + { + token_tbl = _token_tbl; + traceOptionValueDefault=1; // MR10 turn trace ON + } + + The base class constructor must have a signature similar to + that of ANTLRParser. + +#257. (MR21a) Removed dlg statement that -i has no effect in C++ mode. + + This was incorrect. + +#256. (MR21a) Malformed syntax graph causes crash after error message. + + In the past, certain kinds of errors in the very first grammar + element could cause the construction of a malformed graph + representing the grammar. This would eventually result in a + fatal internal error. The code has been changed to be more + resistant to this particular error. + +#255. (MR21a) ParserBlackBox(FILE* f) + + This constructor set openByBlackBox to the wrong value. + + Reported by Kees Bakker (kees_bakker tasking.nl). + +#254. (MR21a) Reporting syntax error at end-of-file + + When there was a syntax error at the end-of-file the syntax + error routine would substitute "" for the programmer's + end-of-file symbol. This substitution is now done only when + the programmer does not define his own end-of-file symbol + or the symbol begins with the character "@". + + Reported by Kees Bakker (kees_bakker tasking.nl). + +#253. (MR21) Generation of block preamble (-preamble and -preamble_first) + + *** This change was rescinded by item #263 *** + + The antlr option -preamble causes antlr to insert the code + BLOCK_PREAMBLE at the start of each rule and block. It does + not insert code before rules references, token references, or + actions. By properly defining the macro BLOCK_PREAMBLE the + user can generate code which is specific to the start of blocks. + + The antlr option -preamble_first is similar, but inserts the + code BLOCK_PREAMBLE_FIRST(PreambleFirst_123) where the symbol + PreambleFirst_123 is equivalent to the first set defined by + the #FirstSetSymbol described in Item #248. + + I have not investigated how these options interact with guess + mode (syntactic predicates). + +#252. (MR21) Check for null pointer in trace routine + + When some trace options are used when the parser is generated + without the trace enabled, the current rule name may be a + NULL pointer. A guard was added to check for this in + restoreState. + + Reported by Douglas E. Forester (dougf projtech.com). + +#251. (MR21) Changes to #define zzTRACE_RULES + + The macro zzTRACE_RULES was being use to pass information to + AParser.h. If this preprocessor symbol was not properly + set the first time AParser.h was #included, the declaration + of zzTRACEdata would be omitted (it is used by the -gd option). + Subsequent #includes of AParser.h would be skipped because of + the #ifdef guard, so the declaration of zzTracePrevRuleName would + never be made. The result was that proper compilation was very + order dependent. + + The declaration of zzTRACEdata was made unconditional and the + problem of removing unused declarations will be left to optimizers. + + Diagnosed by Douglas E. Forester (dougf projtech.com). + +#250. (MR21) Option for EXPERIMENTAL change to error sets for blocks + + The antlr option -mrblkerr turns on an experimental feature + which is supposed to provide more accurate syntax error messages + for k=1, ck=1 grammars. When used with k>1 or ck>1 grammars the + behavior should be no worse than the current behavior. + + There is no problem with the matching of elements or the computation + of prediction expressions in pccts. The task is only one of listing + the most appropriate tokens in the error message. The error sets used + in pccts error messages are approximations of the exact error set when + optional elements in (...)* or (...)+ are involved. While entirely + correct, the error messages are sometimes not 100% accurate. + + There is also a minor philosophical issue. For example, suppose the + grammar expects the token to be an optional A followed by Z, and it + is X. X, of course, is neither A nor Z, so an error message is appropriate. + Is it appropriate to say "Expected Z" ? It is correct, it is accurate, + but it is not complete. + + When k>1 or ck>1 the problem of providing the exactly correct + list of tokens for the syntax error messages ends up becoming + equivalent to evaluating the prediction expression for the + alternatives twice. However, for k=1 ck=1 grammars the prediction + expression can be computed easily and evaluated cheaply, so I + decided to try implementing it to satisfy a particular application. + This application uses the error set in an interactive command language + to provide prompts which list the alternatives available at that + point in the parser. The user can then enter additional tokens to + complete the command line. To do this required more accurate error + sets then previously provided by pccts. + + In some cases the default pccts behavior may lead to more robust error + recovery or clearer error messages then having the exact set of tokens. + This is because (a) features like -ge allow the use of symbolic names for + certain sets of tokens, so having extra tokens may simply obscure things + and (b) the error set is use to resynchronize the parser, so a good + choice is sometimes more important than having the exact set. + + Consider the following example: + + Note: All examples code has been abbreviated + to the absolute minimum in order to make the + examples concise. + + star1 : (A)* Z; + + The generated code resembles: + + old new (with -mrblkerr) + --//----------- -------------------- + for (;;) { for (;;) { + match(A); match(A); + } } + match(Z); if (! A and ! Z) then + FAIL(...{A,Z}...); + } + match(Z); + + + With input X + old message: Found X, expected Z + new message: Found X, expected A, Z + + For the example: + + star2 : (A|B)* Z; + + old new (with -mrblkerr) + ------------- -------------------- + for (;;) { for (;;) { + if (!A and !B) break; if (!A and !B) break; + if (...) { if (...) { + + } } + else { else { + FAIL(...{A,B,Z}...) FAIL(...{A,B}...); + } } + } } + match(B); if (! A and ! B and !Z) then + FAIL(...{A,B,Z}...); + } + match(B); + + With input X + old message: Found X, expected Z + new message: Found X, expected A, B, Z + With input A X + old message: Found X, expected Z + new message: Found X, expected A, B, Z + + This includes the choice of looping back to the + star block. + + The code for plus blocks: + + plus1 : (A)+ Z; + + The generated code resembles: + + old new (with -mrblkerr) + ------------- -------------------- + do { do { + match(A); match(A); + } while (A) } while (A) + match(Z); if (! A and ! Z) then + FAIL(...{A,Z}...); + } + match(Z); + + With input A X + old message: Found X, expected Z + new message: Found X, expected A, Z + + This includes the choice of looping back to the + plus block. + + For the example: + + plus2 : (A|B)+ Z; + + old new (with -mrblkerr) + ------------- -------------------- + do { do { + if (A) { + match(A); + } else if (B) { + match(B); + } else { + if (cnt > 1) break; + FAIL(...{A,B,Z}...) FAIL(...{A,B}...); + } } + cnt++; + } } + + match(Z); if (! A and ! B and !Z) then + FAIL(...{A,B,Z}...); + } + match(B); + + With input X + old message: Found X, expected A, B, Z + new message: Found X, expected A, B + With input A X + old message: Found X, expected Z + new message: Found X, expected A, B, Z + + This includes the choice of looping back to the + star block. + +#249. (MR21) Changes for DEC/VMS systems + + Jean-François Piéronne (jfp altavista.net) has updated some + VMS related command files and fixed some minor problems related + to building pccts under the DEC/VMS operating system. For DEC/VMS + users the most important differences are: + + a. Revised makefile.vms + b. Revised genMMS for genrating VMS style makefiles. + +#248. (MR21) Generate symbol for first set of an alternative + + pccts can generate a symbol which represents the tokens which may + appear at the start of a block: + + rr : #FirstSetSymbol(rr_FirstSet) ( Foo | Bar ) ; + + This will generate the symbol rr_FirstSet of type SetWordType with + elements Foo and Bar set. The bits can be tested using code similar + to the following: + + if (set_el(Foo, &rr_FirstSet)) { ... + + This can be combined with the C array zztokens[] or the C++ routine + tokenName() to get the print name of the token in the first set. + + The size of the set is given by the newly added enum SET_SIZE, a + protected member of the generated parser's class. The number of + elements in the generated set will not be exactly equal to the + value of SET_SIZE because of synthetic tokens created by #tokclass, + #errclass, the -ge option, and meta-tokens such as epsilon, and + end-of-file. + + The #FirstSetSymbol must appear immediately before a block + such as (...)+, (...)*, and {...}, and (...). It may not appear + immediately before a token, a rule reference, or action. However + a token or rule reference can be enclosed in a (...) in order to + make the use of #pragma FirstSetSymbol legal. + + rr_bad : #FirstSetSymbol(rr_bad_FirstSet) Foo; // Illegal + + rr_ok : #FirstSetSymbol(rr_ok_FirstSet) (Foo); // Legal + + Do not confuse FirstSetSymbol sets with the sets used for testing + lookahead. The sets used for FirstSetSymbol have one element per bit, + so the number of bytes is approximately the largest token number + divided by 8. The sets used for testing lookahead store 8 lookahead + sets per byte, so the length of the array is approximately the largest + token number. + + If there is demand, a similar routine for follow sets can be added. + +#247. (MR21) Misleading error message on syntax error for optional elements. + + =================================================== + The behavior has been revised when parser exception + handling is used. See Item #290 + =================================================== + + Prior to MR21, tokens which were optional did not appear in syntax + error messages if the block which immediately followed detected a + syntax error. + + Consider the following grammar which accepts Number, Word, and Other: + + rr : {Number} Word; + + For this rule the code resembles: + + if (LA(1) == Number) { + match(Number); + consume(); + } + match(Word); + + Prior to MR21, the error message for input "$ a" would be: + + line 1: syntax error at "$" missing Word + + With MR21 the message will be: + + line 1: syntax error at "$" expecting Word, Number. + + The generate code resembles: + + if ( (LA(1)==Number) ) { + zzmatch(Number); + consume(); + } + else { + if ( (LA(1)==Word) ) { + /* nothing */ + } + else { + FAIL(... message for both Number and Word ...); + } + } + match(Word); + + The code generated for optional blocks in MR21 is slightly longer + than the previous versions, but it should give better error messages. + + The code generated for: + + { a | b | c } + + should now be *identical* to: + + ( a | b | c | ) + + which was not the case prior to MR21. + + Reported by Sue Marvin (sue siara.com). + +#246. (Changed in MR21) Use of $(MAKE) for calls to make + + Calls to make from the makefiles were replaced with $(MAKE) + because of problems when using gmake. + + Reported with fix by Sunil K.Vallamkonda (sunil siara.com). + +#245. (Changed in MR21) Changes to genmk + + The following command line options have been added to genmk: + + -cfiles ... + + To add a user's C or C++ files into makefile automatically. + The list of files must be enclosed in apostrophes. This + option may be specified multiple times. + + -compiler ... + + The name of the compiler to use for $(CCC) or $(CC). The + default in C++ mode is "CC". The default in C mode is "cc". + + -pccts_path ... + + The value for $(PCCTS), the pccts directory. The default + is /usr/local/pccts. + + Contributed by Tomasz Babczynski (t.babczynski ict.pwr.wroc.pl). + +#244. (Changed in MR21) Rename variable "not" in antlr.g + + When antlr.g is compiled with a C++ compiler, a variable named + "not" causes problems. Reported by Sinan Karasu + (sinan.karasu boeing.com). + +#243 (Changed in MR21) Replace recursion with iteration in zzfree_ast + + Another refinement to zzfree_ast in ast.c to limit recursion. + + NAKAJIMA Mutsuki (muc isr.co.jp). + + +#242. (Changed in MR21) LineInfoFormatStr + + Added an #ifndef/#endif around LineInfoFormatStr in pcctscfg.h. + +#241. (Changed in MR21) Changed macro PURIFY to a no-op + + *********************** + *** NOT IMPLEMENTED *** + *********************** + + The PURIFY macro was changed to a no-op because it was causing + problems when passing C++ objects. + + The old definition: + + #define PURIFY(r,s) memset((char *) &(r),'\\0',(s)); + + The new definition: + + #define PURIFY(r,s) /* nothing */ +#endif + +#240. (Changed in MR21) sorcerer/h/sorcerer.h _MATCH and _MATCHRANGE + + Added test for NULL token pointer. + + Suggested by Peter Keller (keller ebi.ac.uk) + +#239. (Changed in MR21) C++ mode AParser::traceGuessFail + + If tracing is turned on when the code has been generated + without trace code, a failed guess generates a trace report + even though there are no other trace reports. This + make the behavior consistent with other parts of the + trace system. + + Reported by David Wigg (wiggjd sbu.ac.uk). + +#238. (Changed in MR21) Namespace version #include files + + Changed reference from CStdio to cstdio (and other + #include file names) in the namespace version of pccts. + Should have known better. + +#237. (Changed in MR21) ParserBlackBox(FILE*) + + In the past, ParserBlackBox would close the FILE in the dtor + even though it was not opened by ParserBlackBox. The problem + is that there were two constructors, one which accepted a file + name and did an fopen, the other which accepted a FILE and did + not do an fopen. There is now an extra member variable which + remembers whether ParserBlackBox did the open or not. + + Suggested by Mike Percy (mpercy scires.com). + +#236. (Changed in MR21) tmake now reports down pointer problem + + When ASTBase::tmake attempts to update the down pointer of + an AST it checks to see if the down pointer is NULL. If it + is not NULL it does not do the update and returns NULL. + An attempt to update the down pointer is almost always a + result of a user error. This can lead to difficult to find + problems during tree construction. + + With this change, the routine calls a virtual function + reportOverwriteOfDownPointer() which calls panic to + report the problem. Users who want the old behavior can + redefined the virtual function in their AST class. + + Suggested by Sinan Karasu (sinan.karasu boeing.com) + +#235. (Changed in MR21) Made ANTLRParser::resynch() virtual + + Suggested by Jerry Evans (jerry swsl.co.uk). + +#234. (Changed in MR21) Implicit int for function return value + + ATokenBuffer:bufferSize() did not specify a type for the + return value. + + Reported by Hai Vo-Ba (hai fc.hp.com). + +#233. (Changed in MR20) Converted to MSVC 6.0 + + Due to external circumstances I have had to convert to MSVC 6.0 + The MSVC 5.0 project files (.dsw and .dsp) have been retained as + xxx50.dsp and xxx50.dsw. The MSVC 6.0 files are named xxx60.dsp + and xxx60.dsw (where xxx is the related to the directory/project). + +#232. (Changed in MR20) Make setwd bit vectors protected in parser.h + + The access for the setwd array in the parser header was not + specified. As a result, it would depend on the code which + preceded it. In MR20 it will always have access "protected". + + Reported by Piotr Eljasiak (eljasiak zt.gdansk.tpsa.pl). + +#231. (Changed in MR20) Error in token buffer debug code. + + When token buffer debugging is selected via the pre-processor + symbol DEBUG_TOKENBUFFER there is an erroneous check in + AParser.cpp: + + #ifdef DEBUG_TOKENBUFFER + if (i >= inputTokens->bufferSize() || + inputTokens->minTokens() < LLk ) /* MR20 Was "<=" */ + ... + #endif + + Reported by David Wigg (wiggjd sbu.ac.uk). + +#230. (Changed in MR20) Fixed problem with #define for -gd option + + There was an error in setting zzTRACE_RULES for the -gd (trace) option. + + Reported by Gary Funck (gary intrepid.com). + +#229. (Changed in MR20) Additional "const" for literals + + "const" was added to the token name literal table. + "const" was added to some panic() and similar routine + +#228. (Changed in MR20) dlg crashes on "()" + + The following token defintion will cause DLG to crash. + + #token "()" + + When there is a syntax error in a regular expression + many of the dlg routines return a structure which has + null pointers. When this is accessed by callers it + generates the crash. + + I have attempted to fix the more common cases. + + Reported by Mengue Olivier (dolmen bigfoot.com). + +#227. (Changed in MR20) Array overwrite + + Steveh Hand (sassth unx.sas.com) reported a problem which + was traced to a temporary array which was not properly + resized for deeply nested blocks. This has been fixed. + +#226. (Changed in MR20) -pedantic conformance + + G. Hobbelt (i_a mbh.org) and THM made many, many minor + changes to create prototypes for all the functions and + bring antlr, dlg, and sorcerer into conformance with + the gcc -pedantic option. + + This may require uses to add pccts/h/pcctscfg.h to some + files or makefiles in order to have __USE_PROTOS defined. + +#225 (Changed in MR20) AST stack adjustment in C mode + + The fix in #214 for AST stack adjustment in C mode missed + some cases. + + Reported with fix by Ger Hobbelt (i_a mbh.org). + +#224 (Changed in MR20) LL(1) and LL(2) with #pragma approx + + This may take a record for the oldest, most trival, lexical + error in pccts. The regular expressions for LL(1) and LL(2) + lacked an escape for the left and right parenthesis. + + Reported by Ger Hobbelt (i_a mbh.org). + +#223 (Changed in MR20) Addition of IBM_VISUAL_AGE directory + + Build files for antlr, dlg, and sorcerer under IBM Visual Age + have been contributed by Anton Sergeev (ags mlc.ru). They have + been placed in the pccts/IBM_VISUAL_AGE directory. + +#222 (Changed in MR20) Replace __STDC__ with __USE_PROTOS + + Most occurrences of __STDC__ replaced with __USE_PROTOS due to + complaints from several users. + +#221 (Changed in MR20) Added #include for DLexerBase.h to PBlackBox. + + Added #include for DLexerBase.h to PBlackBox. + +#220 (Changed in MR19) strcat arguments reversed in #pred parse + + The arguments to strcat are reversed when creating a print + name for a hash table entry for use with #pred feature. + + Problem diagnosed and fix reported by Scott Harrington + (seh4 ix.netcom.com). + +#219. (Changed in MR19) C Mode routine zzfree_ast + + Changes to reduce use of recursion for AST trees with only right + links or only left links in the C mode routine zzfree_ast. + + Implemented by SAKAI Kiyotaka (ksakai isr.co.jp). + +#218. (Changed in MR19) Changes to support unsigned char in C mode + + Changes to antlr.h and err.h to fix omissions in use of zzchar_t + + Implemented by SAKAI Kiyotaka (ksakai isr.co.jp). + +#217. (Changed in MR19) Error message when dlg -i and -CC options selected + + *** This change was rescinded by item #257 *** + + The parsers generated by pccts in C++ mode are not able to support the + interactive lexer option (except, perhaps, when using the deferred fetch + parser option.(Item #216). + + DLG now warns when both -i and -CC are selected. + + This warning was suggested by David Venditti (07751870267-0001 t-online.de). + +#216. (Changed in MR19) Defer token fetch for C++ mode + + Implemented by Volker H. Simonis (simonis informatik.uni-tuebingen.de) + + Normally, pccts keeps the lookahead token buffer completely filled. + This requires max(k,ck) tokens of lookahead. For some applications + this can cause deadlock problems. For example, there may be cases + when the parser can't tell when the input has been completely consumed + until the parse is complete, but the parse can't be completed because + the input routines are waiting for additional tokens to fill the + lookahead buffer. + + When the ANTLRParser class is built with the pre-processor option + ZZDEFER_FETCH defined, the fetch of new tokens by consume() is deferred + until LA(i) or LT(i) is called. + + To test whether this option has been built into the ANTLRParser class + use "isDeferFetchEnabled()". + + Using the -gd trace option with the default tracein() and traceout() + routines will defeat the effort to defer the fetch because the + trace routines print out information about the lookahead token at + the start of the rule. + + Because the tracein and traceout routines are virtual it is + easy to redefine them in your parser: + + class MyParser { + << + virtual void tracein(ANTLRChar * ruleName) + { fprintf(stderr,"Entering: %s\n", ruleName); } + virtual void traceout(ANTLRChar * ruleName) + { fprintf(stderr,"Leaving: %s\n", ruleName); } + >> + + The originals for those routines are pccts/h/AParser.cpp + + This requires use of the dlg option -i (interactive lexer). + + This is implemented only for C++ mode. + + This is experimental. The interaction with guess mode (syntactic + predicates)is not known. + +#215. (Changed in MR19) Addition of reset() to DLGLexerBase + + There was no obvious way to reset the lexer for reuse. The + reset() method now does this. + + Suggested by David Venditti (07751870267-0001 t-online.de). + +#214. (Changed in MR19) C mode: Adjust AST stack pointer at exit + + In C mode the AST stack pointer needs to be reset if there will + be multiple calls to the ANTLRx macros. + + Reported with fix by Paul D. Smith (psmith baynetworks.com). + +#213. (Changed in MR18) Fatal error with -mrhoistk (k>1 hoisting) + + When rearranging code I forgot to un-comment a critical line of + code that handles hoisting of predicates with k>1 lookahead. This + is now fixed. + + Reported by Reinier van den Born (reinier vnet.ibm.com). + +#212. (Changed in MR17) Mac related changes by Kenji Tanaka + + Kenji Tanaka (kentar osa.att.ne.jp) has made a number of changes for + Macintosh users. + + a. The following Macintosh MPW files aid in installing pccts on Mac: + + pccts/MPW_Read_Me + + pccts/install68K.mpw + pccts/installPPC.mpw + + pccts/antlr/antlr.r + pccts/antlr/antlr68K.make + pccts/antlr/antlrPPC.make + + pccts/dlg/dlg.r + pccts/dlg/dlg68K.make + pccts/dlg/dlgPPC.make + + pccts/sorcerer/sor.r + pccts/sorcerer/sor68K.make + pccts/sorcerer/sorPPC.make + + They completely replace the previous Mac installation files. + + b. The most significant is a change in the MAC_FILE_CREATOR symbol + in pcctscfg.h: + + old: #define MAC_FILE_CREATOR 'MMCC' /* Metrowerks C/C++ Text files */ + new: #define MAC_FILE_CREATOR 'CWIE' /* Metrowerks C/C++ Text files */ + + c. Added calls to special_fopen_actions() where necessary. + +#211. (Changed in MR16a) C++ style comment in dlg + + This has been fixed. + +#210. (Changed in MR16a) Sor accepts \r\n, \r, or \n for end-of-line + + A user requested that Sorcerer be changed to accept other forms + of end-of-line. + +#209. (Changed in MR16) Name of files changed. + + Old: CHANGES_FROM_1.33 + New: CHANGES_FROM_133.txt + + Old: KNOWN_PROBLEMS + New: KNOWN_PROBLEMS.txt + +#208. (Changed in MR16) Change in use of pccts #include files + + There were problems with MS DevStudio when mixing Sorcerer and + PCCTS in the same source file. The problem is caused by the + redefinition of setjmp in the MS header file setjmp.h. In + setjmp.h the pre-processor symbol setjmp was redefined to be + _setjmp. A later effort to execute #include resulted + in an effort to #include <_setjmp.h>. I'm not sure whether this + is a bug or a feature. In any case, I decided to fix it by + avoiding the use of pre-processor symbols in #include statements + altogether. This has the added benefit of making pre-compiled + headers work again. + + I've replaced statements: + + old: #include PCCTS_SETJMP_H + new: #include "pccts_setjmp.h" + + Where pccts_setjmp.h contains: + + #ifndef __PCCTS_SETJMP_H__ + #define __PCCTS_SETJMP_H__ + + #ifdef PCCTS_USE_NAMESPACE_STD + #include + #else + #include + #endif + + #endif + + A similar change has been made for other standard header files + required by pccts and sorcerer: stdlib.h, stdarg.h, stdio.h, etc. + + Reported by Jeff Vincent (JVincent novell.com) and Dale Davis + (DalDavis spectrace.com). + +#207. (Changed in MR16) dlg reports an invalid range for: [\0x00-\0xff] + + ----------------------------------------------------------------- + Note from MR23: This fix does not work. I am investigating why. + ----------------------------------------------------------------- + + dlg will report that this is an invalid range. + + Diagnosed by Piotr Eljasiak (eljasiak no-spam.zt.gdansk.tpsa.pl): + + I think this problem is not specific to unsigned chars + because dlg reports no error for the range [\0x00-\0xfe]. + + I've found that information on range is kept in field + letter (unsigned char) of Attrib struct. Unfortunately + the letter value internally is for some reasons increased + by 1, so \0xff is represented here as 0. + + That's why dlg complains about the range [\0x00-\0xff] in + dlg_p.g: + + if ($$.letter > $2.letter) { + error("invalid range ", zzline); + } + + The fix is: + + if ($$.letter > $2.letter && 255 != $$2.letter) { + error("invalid range ", zzline); + } + +#206. (Changed in MR16) Free zzFAILtext in ANTLRParser destructor + + The ANTLRParser destructor now frees zzFAILtext. + + Problem and fix reported by Manfred Kogler (km cast.uni-linz.ac.at). + +#205. (Changed in MR16) DLGStringReset argument now const + + Changed: void DLGStringReset(DLGChar *s) {...} + To: void DLGStringReset(const DLGChar *s) {...} + + Suggested by Dale Davis (daldavis spectrace.com) + +#204. (Changed in MR15a) Change __WATCOM__ to __WATCOMC__ in pcctscfg.h + + Reported by Oleg Dashevskii (olegdash my-dejanews.com). + +#203. (Changed in MR15) Addition of sorcerer to distribution kit + + I have finally caved in to popular demand. The pccts 1.33mr15 + kit will include sorcerer. The separate sorcerer kit will be + discontinued. + +#202. (Changed) in MR15) Organization of MS Dev Studio Projects in Kit + + Previously there was one workspace that contained projects for + all three parts of pccts: antlr, dlg, and sorcerer. Now each + part (and directory) has its own workspace/project and there + is an additional workspace/project to build a library from the + .cpp files in the pccts/h directory. + + The library build will create pccts_debug.lib or pccts_release.lib + according to the configuration selected. + + If you don't want to build pccts 1.33MR15 you can download a + ready-to-run kit for win32 from http://www.polhode.com/win32.zip. + The ready-to-run for win32 includes executables, a pre-built static + library for the .cpp files in the pccts/h directory, and a sample + application + + You will need to define the environment variable PCCTS to point to + the root of the pccts directory hierarchy. + +#201. (Changed in MR15) Several fixes by K.J. Cummings (cummings peritus.com) + + Generation of SETJMP rather than SETJMP_H in gen.c. + + (Sor B19) Declaration of ref_vars_inits for ref_var_inits in + pccts/sorcerer/sorcerer.h. + +#200. (Changed in MR15) Remove operator=() in AToken.h + + User reported that WatCom couldn't handle use of + explicit operator =(). Replace with equivalent + using cast operator. + +#199. (Changed in MR15) Don't allow use of empty #tokclass + + Change antlr.g to disallow empty #tokclass sets. + + Reported by Manfred Kogler (km cast.uni-linz.ac.at). + +#198. Revised ANSI C grammar due to efforts by Manuel Kessler + + Manuel Kessler (mlkessler cip.physik.uni-wuerzburg.de) + + Allow trailing ... in function parameter lists. + Add bit fields. + Allow old-style function declarations. + Support cv-qualified pointers. + Better checking of combinations of type specifiers. + Release of memory for local symbols on scope exit. + Allow input file name on command line as well as by redirection. + + and other miscellaneous tweaks. + + This is not part of the pccts distribution kit. It must be + downloaded separately from: + + http://www.polhode.com/ansi_mr15.zip + +#197. (Changed in MR14) Resetting the lookahead buffer of the parser + + Explanation and fix by Sinan Karasu (sinan.karasu boeing.com) + + Consider the code used to prime the lookahead buffer LA(i) + of the parser when init() is called: + + void + ANTLRParser:: + prime_lookahead() + { + int i; + for(i=1;i<=LLk; i++) consume(); + dirty=0; + //lap = 0; // MR14 - Sinan Karasu (sinan.karusu boeing.com) + //labase = 0; // MR14 + labase=lap; // MR14 + } + + When the parser is instantiated, lap=0,labase=0 is set. + + The "for" loop runs LLk times. In consume(), lap = lap +1 (mod LLk) is + computed. Therefore, lap(before the loop) == lap (after the loop). + + Now the only problem comes in when one does an init() of the parser + after an Eof has been seen. At that time, lap could be non zero. + Assume it was lap==1. Now we do a prime_lookahead(). If LLk is 2, + then + + consume() + { + NLA = inputTokens->getToken()->getType(); + dirty--; + lap = (lap+1)&(LLk-1); + } + + or expanding NLA, + + token_type[lap&(LLk-1)]) = inputTokens->getToken()->getType(); + dirty--; + lap = (lap+1)&(LLk-1); + + so now we prime locations 1 and 2. In prime_lookahead it used to set + lap=0 and labase=0. Now, the next token will be read from location 0, + NOT 1 as it should have been. + + This was never caught before, because if a parser is just instantiated, + then lap and labase are 0, the offending assignment lines are + basically no-ops, since the for loop wraps around back to 0. + +#196. (Changed in MR14) Problems with "(alpha)? beta" guess + + Consider the following syntactic predicate in a grammar + with 2 tokens of lookahead (k=2 or ck=2): + + rule : ( alpha )? beta ; + alpha : S t ; + t : T U + | T + ; + beta : S t Z ; + + When antlr computes the prediction expression with one token + of lookahead for alts 1 and 2 of rule t it finds an ambiguity. + + Because the grammar has a lookahead of 2 it tries to compute + two tokens of lookahead for alts 1 and 2 of t. Alt 1 clearly + has a lookahead of (T U). Alt 2 is one token long so antlr + tries to compute the follow set of alt 2, which means finding + the things which can follow rule t in the context of (alpha)?. + This cannot be computed, because alpha is only part of a rule, + and antlr can't tell what part of beta is matched by alpha and + what part remains to be matched. Thus it impossible for antlr + to properly determine the follow set of rule t. + + Prior to 1.33MR14, the follow of (alpha)? was computed as + FIRST(beta) as a result of the internal representation of + guess blocks. + + With MR14 the follow set will be the empty set for that context. + + Normally, one expects a rule appearing in a guess block to also + appear elsewhere. When the follow context for this other use + is "ored" with the empty set, the context from the other use + results, and a reasonable follow context results. However if + there is *no* other use of the rule, or it is used in a different + manner then the follow context will be inaccurate - it was + inaccurate even before MR14, but it will be inaccurate in a + different way. + + For the example given earlier, a reasonable way to rewrite the + grammar: + + rule : ( alpha )? beta + alpha : S t ; + t : T U + | T + ; + beta : alpha Z ; + + If there are no other uses of the rule appearing in the guess + block it will generate a test for EOF - a workaround for + representing a null set in the lookahead tests. + + If you encounter such a problem you can use the -alpha option + to get additional information: + + line 2: error: not possible to compute follow set for alpha + in an "(alpha)? beta" block. + + With the antlr -alpha command line option the following information + is inserted into the generated file: + + #if 0 + + Trace of references leading to attempt to compute the follow set of + alpha in an "(alpha)? beta" block. It is not possible for antlr to + compute this follow set because it is not known what part of beta has + already been matched by alpha and what part remains to be matched. + + Rules which make use of the incorrect follow set will also be incorrect + + 1 #token T alpha/2 line 7 brief.g + 2 end alpha alpha/3 line 8 brief.g + 2 end (...)? block at start/1 line 2 brief.g + + #endif + + At the moment, with the -alpha option selected the program marks + any rules which appear in the trace back chain (above) as rules with + possible problems computing follow set. + + Reported by Greg Knapen (gregory.knapen bell.ca). + +#195. (Changed in MR14) #line directive not at column 1 + + Under certain circunstances a predicate test could generate + a #line directive which was not at column 1. + + Reported with fix by David Kågedal (davidk lysator.liu.se) + (http://www.lysator.liu.se/~davidk/). + +#194. (Changed in MR14) (C Mode only) Demand lookahead with #tokclass + + In C mode with the demand lookahead option there is a bug in the + code which handles matches for #tokclass (zzsetmatch and + zzsetmatch_wsig). + + The bug causes the lookahead pointer to get out of synchronization + with the current token pointer. + + The problem was reported with a fix by Ger Hobbelt (hobbelt axa.nl). + +#193. (Changed in MR14) Use of PCCTS_USE_NAMESPACE_STD + + The pcctscfg.h now contains the following definitions: + + #ifdef PCCTS_USE_NAMESPACE_STD + #define PCCTS_STDIO_H + #define PCCTS_STDLIB_H + #define PCCTS_STDARG_H + #define PCCTS_SETJMP_H + #define PCCTS_STRING_H + #define PCCTS_ASSERT_H + #define PCCTS_ISTREAM_H + #define PCCTS_IOSTREAM_H + #define PCCTS_NAMESPACE_STD namespace std {}; using namespace std; + #else + #define PCCTS_STDIO_H + #define PCCTS_STDLIB_H + #define PCCTS_STDARG_H + #define PCCTS_SETJMP_H + #define PCCTS_STRING_H + #define PCCTS_ASSERT_H + #define PCCTS_ISTREAM_H + #define PCCTS_IOSTREAM_H + #define PCCTS_NAMESPACE_STD + #endif + + The runtime support in pccts/h uses these pre-processor symbols + consistently. + + Also, antlr and dlg have been changed to generate code which uses + these pre-processor symbols rather than having the names of the + #include files hard-coded in the generated code. + + This required the addition of "#include pcctscfg.h" to a number of + files in pccts/h. + + It appears that this sometimes causes problems for MSVC 5 in + combination with the "automatic" option for pre-compiled headers. + In such cases disable the "automatic" pre-compiled headers option. + + Suggested by Hubert Holin (Hubert.Holin Bigfoot.com). + +#192. (Changed in MR14) Change setText() to accept "const ANTLRChar *" + + Changed ANTLRToken::setText(ANTLRChar *) to setText(const ANTLRChar *). + This allows literal strings to be used to initialize tokens. Since + the usual token implementation (ANTLRCommonToken) makes a copy of the + input string, this was an unnecessary limitation. + + Suggested by Bob McWhirter (bob netwrench.com). + +#191. (Changed in MR14) HP/UX aCC compiler compatibility problem + + Needed to explicitly declare zzINF_DEF_TOKEN_BUFFER_SIZE and + zzINF_BUFFER_TOKEN_CHUNK_SIZE as ints in pccts/h/AParser.cpp. + + Reported by David Cook (dcook bmc.com). + +#190. (Changed in MR14) IBM OS/2 CSet compiler compatibility problem + + Name conflict with "_cs" in pccts/h/ATokenBuffer.cpp + + Reported by David Cook (dcook bmc.com). + +#189. (Changed in MR14) -gxt switch in C mode + + The -gxt switch in C mode didn't work because of incorrect + initialization. + + Reported by Sinan Karasu (sinan boeing.com). + +#188. (Changed in MR14) Added pccts/h/DLG_stream_input.h + + This is a DLG stream class based on C++ istreams. + + Contributed by Hubert Holin (Hubert.Holin Bigfoot.com). + +#187. (Changed in MR14) Rename config.h to pcctscfg.h + + The PCCTS configuration file has been renamed from config.h to + pcctscfg.h. The problem with the original name is that it led + to name collisions when pccts parsers were combined with other + software. + + All of the runtime support routines in pccts/h/* have been + changed to use the new name. Existing software can continue + to use pccts/h/config.h. The contents of pccts/h/config.h is + now just "#include "pcctscfg.h". + + I don't have a record of the user who suggested this. + +#186. (Changed in MR14) Pre-processor symbol DllExportPCCTS class modifier + + Classes in the C++ runtime support routines are now declared: + + class DllExportPCCTS className .... + + By default, the pre-processor symbol is defined as the empty + string. This if for use by MSVC++ users to create DLL classes. + + Suggested by Manfred Kogler (km cast.uni-linz.ac.at). + +#185. (Changed in MR14) Option to not use PCCTS_AST base class for ASTBase + + Normally, the ASTBase class is derived from PCCTS_AST which contains + functions useful to Sorcerer. If these are not necessary then the + user can define the pre-processor symbol "PCCTS_NOT_USING_SOR" which + will cause the ASTBase class to replace references to PCCTS_AST with + references to ASTBase where necessary. + + The class ASTDoublyLinkedBase will contain a pure virtual function + shallowCopy() that was formerly defined in class PCCTS_AST. + + Suggested by Bob McWhirter (bob netwrench.com). + +#184. (Changed in MR14) Grammars with no tokens generate invalid tokens.h + + Reported by Hubert Holin (Hubert.Holin bigfoot.com). + +#183. (Changed in MR14) -f to specify file with names of grammar files + + In DEC/VMS it is difficult to specify very long command lines. + The -f option allows one to place the names of the grammar files + in a data file in order to bypass limitations of the DEC/VMS + command language interpreter. + + Addition supplied by Bernard Giroud (b_giroud decus.ch). + +#182. (Changed in MR14) Output directory option for DEC/VMS + + Fix some problems with the -o option under DEC/VMS. + + Fix supplied by Bernard Giroud (b_giroud decus.ch). + +#181. (Changed in MR14) Allow chars > 127 in DLGStringInput::nextChar() + + Changed DLGStringInput to cast the character using (unsigned char) + so that languages with character codes greater than 127 work + without changes. + + Suggested by Manfred Kogler (km cast.uni-linz.ac.at). + +#180. (Added in MR14) ANTLRParser::getEofToken() + + Added "ANTLRToken ANTLRParser::getEofToken() const" to match the + setEofToken routine. + + Requested by Manfred Kogler (km cast.uni-linz.ac.at). + +#179. (Fixed in MR14) Memory leak for BufFileInput subclass of DLGInputStream + + The BufFileInput class described in Item #142 neglected to release + the allocated buffer when an instance was destroyed. + + Reported by Manfred Kogler (km cast.uni-linz.ac.at). + +#178. (Fixed in MR14) Bug in "(alpha)? beta" guess blocks first sets + + In 1.33 vanilla, and all maintenance releases prior to MR14 + there is a bug in the handling of guess blocks which use the + "long" form: + + (alpha)? beta + + inside a (...)*, (...)+, or {...} block. + + This problem does *not* apply to the case where beta is omitted + or when the syntactic predicate is on the leading edge of an + alternative. + + The problem is that both alpha and beta are stored in the + syntax diagram, and that some analysis routines would fail + to skip the alpha portion when it was not on the leading edge. + Consider the following grammar with -ck 2: + + r : ( (A)? B )* C D + + | A B /* forces -ck 2 computation for old antlr */ + /* reports ambig for alts 1 & 2 */ + + | B C /* forces -ck 2 computation for new antlr */ + /* reports ambig for alts 1 & 3 */ + ; + + The prediction expression for the first alternative should be + LA(1)={B C} LA(2)={B C D}, but previous versions of antlr + would compute the prediction expression as LA(1)={A C} LA(2)={B D} + + Reported by Arpad Beszedes (beszedes inf.u-szeged.hu) who provided + a very clear example of the problem and identified the probable cause. + +#177. (Changed in MR14) #tokdefs and #token with regular expression + + In MR13 the change described by Item #162 caused an existing + feature of antlr to fail. Prior to the change it was possible + to give regular expression definitions and actions to tokens + which were defined via the #tokdefs directive. + + This now works again. + + Reported by Manfred Kogler (km cast.uni-linz.ac.at). + +#176. (Changed in MR14) Support for #line in antlr source code + + Note: this was implemented by Arpad Beszedes (beszedes inf.u-szeged.hu). + + In 1.33MR14 it is possible for a pre-processor to generate #line + directives in the antlr source and have those line numbers and file + names used in antlr error messages and in the #line directives + generated by antlr. + + The #line directive may appear in the following forms: + + #line ll "sss" xx xx ... + + where ll represents a line number, "sss" represents the name of a file + enclosed in quotation marks, and xxx are arbitrary integers. + + The following form (without "line") is not supported at the moment: + + # ll "sss" xx xx ... + + The result: + + zzline + + is replaced with ll from the # or #line directive + + FileStr[CurFile] + + is updated with the contents of the string (if any) + following the line number + + Note + ---- + The file-name string following the line number can be a complete + name with a directory-path. Antlr generates the output files from + the input file name (by replacing the extension from the file-name + with .c or .cpp). + + If the input file (or the file-name from the line-info) contains + a path: + + "../grammar.g" + + the generated source code will be placed in "../grammar.cpp" (i.e. + in the parent directory). This is inconvenient in some cases + (even the -o switch can not be used) so the path information is + removed from the #line directive. Thus, if the line-info was + + #line 2 "../grammar.g" + + then the current file-name will become "grammar.g" + + In this way, the generated source code according to the grammar file + will always be in the current directory, except when the -o switch + is used. + +#175. (Changed in MR14) Bug when guess block appears at start of (...)* + + In 1.33 vanilla and all maintenance releases prior to 1.33MR14 + there is a bug when a guess block appears at the start of a (...)+. + Consider the following k=1 (ck=1) grammar: + + rule : + ( (STAR)? ZIP )* ID ; + + Prior to 1.33MR14, the generated code resembled: + + ... + zzGUESS_BLOCK + while ( 1 ) { + if ( ! LA(1)==STAR) break; + zzGUESS + if ( !zzrv ) { + zzmatch(STAR); + zzCONSUME; + zzGUESS_DONE + zzmatch(ZIP); + zzCONSUME; + ... + + Note that the routine uses STAR for the prediction expression + rather than ZIP. With 1.33MR14 the generated code resembles: + + ... + while ( 1 ) { + if ( ! LA(1)==ZIP) break; + ... + + This problem existed only with (...)* blocks and was caused + by the slightly more complicated graph which represents (...)* + blocks. This caused the analysis routine to compute the first + set for the alpha part of the "(alpha)? beta" rather than the + beta part. + + Both (...)+ and {...} blocks handled the guess block correctly. + + Reported by Arpad Beszedes (beszedes inf.u-szeged.hu) who provided + a very clear example of the problem and identified the probable cause. + +#174. (Changed in MR14) Bug when action precedes syntactic predicate + + In 1.33 vanilla, and all maintenance releases prior to MR14, + there was a bug when a syntactic predicate was immediately + preceded by an action. Consider the following -ck 2 grammar: + + rule : + <> + (alpha)? beta C + | A B + ; + + alpha : A ; + beta : A B; + + Prior to MR14, the code generated for the first alternative + resembled: + + ... + zzGUESS + if ( !zzrv && LA(1)==A && LA(2)==A) { + alpha(); + zzGUESS_DONE + beta(); + zzmatch(C); + zzCONSUME; + } else { + ... + + The prediction expression (i.e. LA(1)==A && LA(2)==A) is clearly + wrong because LA(2) should be matched to B (first[2] of beta is {B}). + + With 1.33MR14 the prediction expression is: + + ... + if ( !zzrv && LA(1)==A && LA(2)==B) { + alpha(); + zzGUESS_DONE + beta(); + zzmatch(C); + zzCONSUME; + } else { + ... + + This will only affect users in which alpha is shorter than + than max(k,ck) and there is an action immediately preceding + the syntactic predicate. + + This problem was reported by reported by Arpad Beszedes + (beszedes inf.u-szeged.hu) who provided a very clear example + of the problem and identified the presence of the init-action + as the likely culprit. + +#173. (Changed in MR13a) -glms for Microsoft style filenames with -gl + + With the -gl option antlr generates #line directives using the + exact name of the input files specified on the command line. + An oddity of the Microsoft C and C++ compilers is that they + don't accept file names in #line directives containing "\" + even though these are names from the native file system. + + With -glms option, the "\" in file names appearing in #line + directives is replaced with a "/" in order to conform to + Microsoft compiler requirements. + + Reported by Erwin Achermann (erwin.achermann switzerland.org). + +#172. (Changed in MR13) \r\n in antlr source counted as one line + + Some MS software uses \r\n to indicate a new line. Antlr + now recognizes this in counting lines. + + Reported by Edward L. Hepler (elh ece.vill.edu). + +#171. (Changed in MR13) #tokclass L..U now allowed + + The following is now allowed: + + #tokclass ABC { A..B C } + + Reported by Dave Watola (dwatola amtsun.jpl.nasa.gov) + +#170. (Changed in MR13) Suppression for predicates with lookahead depth >1 + + In MR12 the capability for suppression of predicates with lookahead + depth=1 was introduced. With MR13 this had been extended to + predicates with lookahead depth > 1 and released for use by users + on an experimental basis. + + Consider the following grammar with -ck 2 and the predicate in rule + "a" with depth 2: + + r1 : (ab)* "@" + ; + + ab : a + | b + ; + + a : (A B)? => <>? A B C + ; + + b : A B C + ; + + Normally, the predicate would be hoisted into rule r1 in order to + determine whether to call rule "ab". However it should *not* be + hoisted because, even if p is false, there is a valid alternative + in rule b. With "-mrhoistk on" the predicate will be suppressed. + + If "-info p" command line option is present the following information + will appear in the generated code: + + while ( (LA(1)==A) + #if 0 + + Part (or all) of predicate with depth > 1 suppressed by alternative + without predicate + + pred << p(LATEXT(2))>>? + depth=k=2 ("=>" guard) rule a line 8 t1.g + tree context: + (root = A + B + ) + + The token sequence which is suppressed: ( A B ) + The sequence of references which generate that sequence of tokens: + + 1 to ab r1/1 line 1 t1.g + 2 ab ab/1 line 4 t1.g + 3 to b ab/2 line 5 t1.g + 4 b b/1 line 11 t1.g + 5 #token A b/1 line 11 t1.g + 6 #token B b/1 line 11 t1.g + + #endif + + A slightly more complicated example: + + r1 : (ab)* "@" + ; + + ab : a + | b + ; + + a : (A B)? => <>? (A B | D E) + ; + + b : <>? D E + ; + + + In this case, the sequence (D E) in rule "a" which lies behind + the guard is used to suppress the predicate with context (D E) + in rule b. + + while ( (LA(1)==A || LA(1)==D) + #if 0 + + Part (or all) of predicate with depth > 1 suppressed by alternative + without predicate + + pred << q(LATEXT(2))>>? + depth=k=2 rule b line 11 t2.g + tree context: + (root = D + E + ) + + The token sequence which is suppressed: ( D E ) + The sequence of references which generate that sequence of tokens: + + 1 to ab r1/1 line 1 t2.g + 2 ab ab/1 line 4 t2.g + 3 to a ab/1 line 4 t2.g + 4 a a/1 line 8 t2.g + 5 #token D a/1 line 8 t2.g + 6 #token E a/1 line 8 t2.g + + #endif + && + #if 0 + + pred << p(LATEXT(2))>>? + depth=k=2 ("=>" guard) rule a line 8 t2.g + tree context: + (root = A + B + ) + + #endif + + (! ( LA(1)==A && LA(2)==B ) || p(LATEXT(2)) ) { + ab(); + ... + +#169. (Changed in MR13) Predicate test optimization for depth=1 predicates + + When the MR12 generated a test of a predicate which had depth 1 + it would use the depth >1 routines, resulting in correct but + inefficient behavior. In MR13, a bit test is used. + +#168. (Changed in MR13) Token expressions in context guards + + The token expressions appearing in context guards such as: + + (A B)? => <>? someRule + + are computed during an early phase of antlr processing. As + a result, prior to MR13, complex expressions such as: + + ~B + L..U + ~L..U + TokClassName + ~TokClassName + + were not computed properly. This resulted in incorrect + context being computed for such expressions. + + In MR13 these context guards are verified for proper semantics + in the initial phase and then re-evaluated after complex token + expressions have been computed in order to produce the correct + behavior. + + Reported by Arpad Beszedes (beszedes inf.u-szeged.hu). + +#167. (Changed in MR13) ~L..U + + Prior to MR13, the complement of a token range was + not properly computed. + +#166. (Changed in MR13) token expression L..U + + The token U was represented as an unsigned char, restricting + the use of L..U to cases where U was assigned a token number + less than 256. This is corrected in MR13. + +#165. (Changed in MR13) option -newAST + + To create ASTs from an ANTLRTokenPtr antlr usually calls + "new AST(ANTLRTokenPtr)". This option generates a call + to "newAST(ANTLRTokenPtr)" instead. This allows a user + to define a parser member function to create an AST object. + + Similar changes for ASTBase::tmake and ASTBase::link were not + thought necessary since they do not create AST objects, only + use existing ones. + +#164. (Changed in MR13) Unused variable _astp + + For many compilations, we have lived with warnings about + the unused variable _astp. It turns out that this varible + can *never* be used because the code which references it was + commented out. + + This investigation was sparked by a note from Erwin Achermann + (erwin.achermann switzerland.org). + +#163. (Changed in MR13) Incorrect makefiles for testcpp examples + + All the examples in pccts/testcpp/* had incorrect definitions + in the makefiles for the symbol "CCC". Instead of CCC=CC they + had CC=$(CCC). + + There was an additional problem in testcpp/1/test.g due to the + change in ANTLRToken::getText() to a const member function + (Item #137). + + Reported by Maurice Mass (maas cuci.nl). + +#162. (Changed in MR13) Combining #token with #tokdefs + + When it became possible to change the print-name of a + #token (Item #148) it became useful to give a #token + statement whose only purpose was to giving a print name + to the #token. Prior to this change this could not be + combined with the #tokdefs feature. + +#161. (Changed in MR13) Switch -gxt inhibits generation of tokens.h + +#160. (Changed in MR13) Omissions in list of names for remap.h + + When a user selects the -gp option antlr creates a list + of macros in remap.h to rename some of the standard + antlr routines from zzXXX to userprefixXXX. + + There were number of omissions from the remap.h name + list related to the new trace facility. This was reported, + along with a fix, by Bernie Solomon (bernard ug.eds.com). + +#159. (Changed in MR13) Violations of classic C rules + + There were a number of violations of classic C style in + the distribution kit. This was reported, along with fixes, + by Bernie Solomon (bernard ug.eds.com). + +#158. (Changed in MR13) #header causes problem for pre-processors + + A user who runs the C pre-processor on antlr source suggested + that another syntax be allowed. With MR13 such directives + such as #header, #pragma, etc. may be written as "\#header", + "\#pragma", etc. For escaping pre-processor directives inside + a #header use something like the following: + + \#header + << + \#include + >> + +#157. (Fixed in MR13) empty error sets for rules with infinite recursion + + When the first set for a rule cannot be computed due to infinite + left recursion and it is the only alternative for a block then + the error set for the block would be empty. This would result + in a fatal error. + + Reported by Darin Creason (creason genedax.com) + +#156. (Changed in MR13) DLGLexerBase::getToken() now public + +#155. (Changed in MR13) Context behind predicates can suppress + + With -mrhoist enabled the context behind a guarded predicate can + be used to suppress other predicates. Consider the following grammar: + + r0 : (r1)+; + + r1 : rp + | rq + ; + rp : <

>? B ; + rq : (A)? => <>? (A|B); + + In earlier versions both predicates "p" and "q" would be hoisted into + rule r0. With MR12c predicate p is suppressed because the context which + follows predicate q includes "B" which can "cover" predicate "p". In + other words, in trying to decide in r0 whether to call r1, it doesn't + really matter whether p is false or true because, either way, there is + a valid choice within r1. + +#154. (Changed in MR13) Making hoist suppression explicit using <> + + A common error, even among experienced pccts users, is to code + an init-action to inhibit hoisting rather than a leading action. + An init-action does not inhibit hoisting. + + This was coded: + + rule1 : <<;>> rule2 + + This is what was meant: + + rule1 : <<;>> <<;>> rule2 + + With MR13, the user can code: + + rule1 : <<;>> <> rule2 + + The following will give an error message: + + rule1 : <> rule2 + + If the <> appears as an init-action rather than a leading + action an error message is issued. The meaning of an init-action + containing "nohoist" is unclear: does it apply to just one + alternative or to all alternatives ? + + + + + + + + + ------------------------------------------------------- + Note: Items #153 to #1 are now in a separate file named + CHANGES_FROM_133_BEFORE_MR13.txt + ------------------------------------------------------- diff --git a/Tools/CodeTools/Source/Pccts/CHANGES_FROM_133_BEFORE_MR13.txt b/Tools/CodeTools/Source/Pccts/CHANGES_FROM_133_BEFORE_MR13.txt new file mode 100644 index 0000000000..bba5ecdd64 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/CHANGES_FROM_133_BEFORE_MR13.txt @@ -0,0 +1,3666 @@ + + ------------------------------------------------------------ + This is the second part of a two part file. + This is a list of changes to pccts 1.33 prior to MR13 + For more recent information see CHANGES_FROM_133.txt + ------------------------------------------------------------ + + DISCLAIMER + + The software and these notes are provided "as is". They may include + typographical or technical errors and their authors disclaims all + liability of any kind or nature for damages due to error, fault, + defect, or deficiency regardless of cause. All warranties of any + kind, either express or implied, including, but not limited to, the + implied warranties of merchantability and fitness for a particular + purpose are disclaimed. + + +#153. (Changed in MR12b) Bug in computation of -mrhoist suppression set + + Consider the following grammar with k=1 and "-mrhoist on": + + r1 : (A)? => ((p>>? x /* l1 */ + | r2 /* l2 */ + ; + r2 : A /* l4 */ + | (B)? => <>? y /* l5 */ + ; + + In earlier versions the mrhoist routine would see that both l1 and + l2 contained predicates and would assume that this prevented either + from acting to suppress the other predicate. In the example above + it didn't realize the A at line l4 is capable of suppressing the + predicate at l1 even though alt l2 contains (indirectly) a predicate. + + This is fixed in MR12b. + + Reported by Reinier van den Born (reinier@vnet.ibm.com) + +#153. (Changed in MR12a) Bug in computation of -mrhoist suppression set + + An oversight similar to that described in Item #152 appeared in + the computation of the set that "covered" a predicate. If a + predicate expression included a term such as p=AND(q,r) the context + of p was taken to be context(q) & context(r), when it should have + been context(q) | context(r). This is fixed in MR12a. + +#152. (Changed in MR12) Bug in generation of predicate expressions + + The primary purpose for MR12 is to make quite clear that MR11 is + obsolete and to fix the bug related to predicate expressions. + + In MR10 code was added to optimize the code generated for + predicate expression tests. Unfortunately, there was a + significant oversight in the code which resulted in a bug in + the generation of code for predicate expression tests which + contained predicates combined using AND: + + r0 : (r1)* "@" ; + r1 : (AAA)? => <

>? r2 ; + r2 : (BBB)? => <>? Q + | (BBB)? => <>? Q + ; + + In MR11 (and MR10 when using "-mrhoist on") the code generated + for r0 to predict r1 would be equivalent to: + + if ( LA(1)==Q && + (LA(1)==AAA && LA(1)==BBB) && + ( p && ( q || r )) ) { + + This is incorrect because it expresses the idea that LA(1) + *must* be AAA in order to attempt r1, and *must* be BBB to + attempt r2. The result was that r1 became unreachable since + both condition can not be simultaneously true. + + The general philosophy of code generation for predicates + can be summarized as follows: + + a. If the context is true don't enter an alt + for which the corresponding predicate is false. + + If the context is false then it is okay to enter + the alt without evaluating the predicate at all. + + b. A predicate created by ORing of predicates has + context which is the OR of their individual contexts. + + c. A predicate created by ANDing of predicates has + (surprise) context which is the OR of their individual + contexts. + + d. Apply these rules recursively. + + e. Remember rule (a) + + The correct code should express the idea that *if* LA(1) is + AAA then p must be true to attempt r1, but if LA(1) is *not* + AAA then it is okay to attempt r1, provided that *if* LA(1) is + BBB then one of q or r must be true. + + if ( LA(1)==Q && + ( !(LA(1)==AAA || LA(1)==BBB) || + ( ! LA(1) == AAA || p) && + ( ! LA(1) == BBB || q || r ) ) ) { + + I believe this is fixed in MR12. + + Reported by Reinier van den Born (reinier@vnet.ibm.com) + +#151a. (Changed in MR12) ANTLRParser::getLexer() + + As a result of several requests, I have added public methods to + get a pointer to the lexer belonging to a parser. + + ANTLRTokenStream *ANTLRParser::getLexer() const + + Returns a pointer to the lexer being used by the + parser. ANTLRTokenStream is the base class of + DLGLexer + + ANTLRTokenStream *ANTLRTokenBuffer::getLexer() const + + Returns a pointer to the lexer being used by the + ANTLRTokenBuffer. ANTLRTokenStream is the base + class of DLGLexer + + You must manually cast the ANTLRTokenStream to your program's + lexer class. Because the name of the lexer's class is not fixed. + Thus it is impossible to incorporate it into the DLGLexerBase + class. + +#151b.(Changed in MR12) ParserBlackBox member getLexer() + + The template class ParserBlackBox now has a member getLexer() + which returns a pointer to the lexer. + +#150. (Changed in MR12) syntaxErrCount and lexErrCount now public + + See Item #127 for more information. + +#149. (Changed in MR12) antlr option -info o (letter o for orphan) + + If there is more than one rule which is not referenced by any + other rule then all such rules are listed. This is useful for + alerting one to rules which are not used, but which can still + contribute to ambiguity. For example: + + start : a Z ; + unused: a A ; + a : (A)+ ; + + will cause an ambiguity report for rule "a" which will be + difficult to understand if the user forgets about rule "unused" + simply because it is not used in the grammar. + +#148. (Changed in MR11) #token names appearing in zztokens,token_tbl + + In a #token statement like the following: + + #token Plus "\+" + + the string "Plus" appears in the zztokens array (C mode) and + token_tbl (C++ mode). This string is used in most error + messages. In MR11 one has the option of using some other string, + (e.g. "+") in those tables. + + In MR11 one can write: + + #token Plus ("+") "\+" + #token RP ("(") "\(" + #token COM ("comment begin") "/\*" + + A #token statement is allowed to appear in more than one #lexclass + with different regular expressions. However, the token name appears + only once in the zztokens/token_tbl array. This means that only + one substitute can be specified for a given #token name. The second + attempt to define a substitute name (different from the first) will + result in an error message. + +#147. (Changed in MR11) Bug in follow set computation + + There is a bug in 1.33 vanilla and all maintenance releases + prior to MR11 in the computation of the follow set. The bug is + different than that described in Item #82 and probably more + common. It was discovered in the ansi.g grammar while testing + the "ambiguity aid" (Item #119). The search for a bug started + when the ambiguity aid was unable to discover the actual source + of an ambiguity reported by antlr. + + The problem appears when an optimization of the follow set + computation is used inappropriately. The result is that the + follow set used is the "worst case". In other words, the error + can lead to false reports of ambiguity. The good news is that + if you have a grammar in which you have addressed all reported + ambiguities you are ok. The bad news is that you may have spent + time fixing ambiguities that were not real, or used k=2 when + ck=2 might have been sufficient, and so on. + + The following grammar demonstrates the problem: + + ------------------------------------------------------------ + expr : ID ; + + start : stmt SEMI ; + + stmt : CASE expr COLON + | expr SEMI + | plain_stmt + ; + + plain_stmt : ID COLON ; + ------------------------------------------------------------ + + When compiled with k=1 and ck=2 it will report: + + warning: alts 2 and 3 of the rule itself ambiguous upon + { IDENTIFIER }, { COLON } + + When antlr analyzes "stmt" it computes the first[1] set of all + alternatives. It finds an ambiguity between alts 2 and 3 for ID. + It then computes the first[2] set for alternatives 2 and 3 to resolve + the ambiguity. In computing the first[2] set of "expr" (which is + only one token long) it needs to determine what could follow "expr". + Under a certain combination of circumstances antlr forgets that it + is trying to analyze "stmt" which can only be followed by SEMI and + adds to the first[2] set of "expr" the "global" follow set (including + "COLON") which could follow "expr" (under other conditions) in the + phrase "CASE expr COLON". + +#146. (Changed in MR11) Option -treport for locating "difficult" alts + + It can be difficult to determine which alternatives are causing + pccts to work hard to resolve an ambiguity. In some cases the + ambiguity is successfully resolved after much CPU time so there + is no message at all. + + A rough measure of the amount of work being peformed which is + independent of the CPU speed and system load is the number of + tnodes created. Using "-info t" gives information about the + total number of tnodes created and the peak number of tnodes. + + Tree Nodes: peak 1300k created 1416k lost 0 + + It also puts in the generated C or C++ file the number of tnodes + created for a rule (at the end of the rule). However this + information is not sufficient to locate the alternatives within + a rule which are causing the creation of tnodes. + + Using: + + antlr -treport 100000 .... + + causes antlr to list on stdout any alternatives which require the + creation of more than 100,000 tnodes, along with the lookahead sets + for those alternatives. + + The following is a trivial case from the ansi.g grammar which shows + the format of the report. This report might be of more interest + in cases where 1,000,000 tuples were created to resolve the ambiguity. + + ------------------------------------------------------------------------- + There were 0 tuples whose ambiguity could not be resolved + by full lookahead + There were 157 tnodes created to resolve ambiguity between: + + Choice 1: statement/2 line 475 file ansi.g + Choice 2: statement/3 line 476 file ansi.g + + Intersection of lookahead[1] sets: + + IDENTIFIER + + Intersection of lookahead[2] sets: + + LPARENTHESIS COLON AMPERSAND MINUS + STAR PLUSPLUS MINUSMINUS ONESCOMPLEMENT + NOT SIZEOF OCTALINT DECIMALINT + HEXADECIMALINT FLOATONE FLOATTWO IDENTIFIER + STRING CHARACTER + ------------------------------------------------------------------------- + +#145. (Documentation) Generation of Expression Trees + + Item #99 was misleading because it implied that the optimization + for tree expressions was available only for trees created by + predicate expressions and neglected to mention that it required + the use of "-mrhoist on". The optimization applies to tree + expressions created for grammars with k>1 and for predicates with + lookahead depth >1. + + In MR11 the optimized version is always used so the -mrhoist on + option need not be specified. + +#144. (Changed in MR11) Incorrect test for exception group + + In testing for a rule's exception group the label a pointer + is compared against '\0'. The intention is "*pointer". + + Reported by Jeffrey C. Fried (Jeff@Fried.net). + +#143. (Changed in MR11) Optional ";" at end of #token statement + + Fixes problem of: + + #token X "x" + + << + parser action + >> + + Being confused with: + + #token X "x" <> + +#142. (Changed in MR11) class BufFileInput subclass of DLGInputStream + + Alexey Demakov (demakov@kazbek.ispras.ru) has supplied class + BufFileInput derived from DLGInputStream which provides a + function lookahead(char *string) to test characters in the + input stream more than one character ahead. + + The default amount of lookahead is specified by the constructor + and defaults to 8 characters. This does *not* include the one + character of lookahead maintained internally by DLG in member "ch" + and which is not available for testing via BufFileInput::lookahead(). + + This is a useful class for overcoming the one-character-lookahead + limitation of DLG without resorting to a lexer capable of + backtracking (like flex) which is not integrated with antlr as is + DLG. + + There are no restrictions on copying or using BufFileInput.* except + that the authorship and related information must be retained in the + source code. + + The class is located in pccts/h/BufFileInput.* of the kit. + +#141. (Changed in MR11) ZZDEBUG_CONSUME for ANTLRParser::consume() + + A debug aid has been added to file ANTLRParser::consume() in + file AParser.cpp: + + #ifdef ZZDEBUG_CONSUME_ACTION + zzdebug_consume_action(); + #endif + + Suggested by Sramji Ramanathan (ps@kumaran.com). + +#140. (Changed in MR11) #pred to define predicates + + +---------------------------------------------------+ + | Note: Assume "-prc on" for this entire discussion | + +---------------------------------------------------+ + + A problem with predicates is that each one is regarded as + unique and capable of disambiguating cases where two + alternatives have identical lookahead. For example: + + rule : <>? A + | <>? A + ; + + will not cause any error messages or warnings to be issued + by earlier versions of pccts. To compare the text of the + predicates is an incomplete solution. + + In 1.33MR11 I am introducing the #pred statement in order to + solve some problems with predicates. The #pred statement allows + one to give a symbolic name to a "predicate literal" or a + "predicate expression" in order to refer to it in other predicate + expressions or in the rules of the grammar. + + The predicate literal associated with a predicate symbol is C + or C++ code which can be used to test the condition. A + predicate expression defines a predicate symbol in terms of other + predicate symbols using "!", "&&", and "||". A predicate symbol + can be defined in terms of a predicate literal, a predicate + expression, or *both*. + + When a predicate symbol is defined with both a predicate literal + and a predicate expression, the predicate literal is used to generate + code, but the predicate expression is used to check for two + alternatives with identical predicates in both alternatives. + + Here are some examples of #pred statements: + + #pred IsLabel <>? + #pred IsLocalVar <>? + #pred IsGlobalVar <>? + #pred IsVar <>? IsLocalVar || IsGlobalVar + #pred IsScoped <>? IsLabel || IsLocalVar + + I hope that the use of EBNF notation to describe the syntax of the + #pred statement will not cause problems for my readers (joke). + + predStatement : "#pred" + CapitalizedName + ( + "<>?" + | "<>?" predOrExpr + | predOrExpr + ) + ; + + predOrExpr : predAndExpr ( "||" predAndExpr ) * ; + + predAndExpr : predPrimary ( "&&" predPrimary ) * ; + + predPrimary : CapitalizedName + | "!" predPrimary + | "(" predOrExpr ")" + ; + + What is the purpose of this nonsense ? + + To understand how predicate symbols help, you need to realize that + predicate symbols are used in two different ways with two different + goals. + + a. Allow simplification of predicates which have been combined + during predicate hoisting. + + b. Allow recognition of identical predicates which can't disambiguate + alternatives with common lookahead. + + First we will discuss goal (a). Consider the following rule: + + rule0: rule1 + | ID + | ... + ; + + rule1: rule2 + | rule3 + ; + + rule2: <>? ID ; + rule3: <>? ID ; + + When the predicates in rule2 and rule3 are combined by hoisting + to create a prediction expression for rule1 the result is: + + if ( LA(1)==ID + && ( isX(LATEXT(1) || !isX(LATEXT(1) ) ) { rule1(); ... + + This is inefficient, but more importantly, can lead to false + assumptions that the predicate expression distinguishes the rule1 + alternative with some other alternative with lookahead ID. In + MR11 one can write: + + #pred IsX <>? + + ... + + rule2: <>? ID ; + rule3: <>? ID ; + + During hoisting MR11 recognizes this as a special case and + eliminates the predicates. The result is a prediction + expression like the following: + + if ( LA(1)==ID ) { rule1(); ... + + Please note that the following cases which appear to be equivalent + *cannot* be simplified by MR11 during hoisting because the hoisting + logic only checks for a "!" in the predicate action, not in the + predicate expression for a predicate symbol. + + *Not* equivalent and is not simplified during hoisting: + + #pred IsX <>? + #pred NotX <>? + ... + rule2: <>? ID ; + rule3: <>? ID ; + + *Not* equivalent and is not simplified during hoisting: + + #pred IsX <>? + #pred NotX !IsX + ... + rule2: <>? ID ; + rule3: <>? ID ; + + Now we will discuss goal (b). + + When antlr discovers that there is a lookahead ambiguity between + two alternatives it attempts to resolve the ambiguity by searching + for predicates in both alternatives. In the past any predicate + would do, even if the same one appeared in both alternatives: + + rule: <>? X + | <>? X + ; + + The #pred statement is a start towards solving this problem. + During ambiguity resolution (*not* predicate hoisting) the + predicates for the two alternatives are expanded and compared. + Consider the following example: + + #pred Upper <>? + #pred Lower <>? + #pred Alpha <>? Upper || Lower + + rule0: rule1 + | <>? ID + ; + + rule1: + | rule2 + | rule3 + ... + ; + + rule2: <>? ID; + rule3: <>? ID; + + The definition of #pred Alpha expresses: + + a. to test the predicate use the C code "isAlpha(LATEXT(1))" + + b. to analyze the predicate use the information that + Alpha is equivalent to the union of Upper and Lower, + + During ambiguity resolution the definition of Alpha is expanded + into "Upper || Lower" and compared with the predicate in the other + alternative, which is also "Upper || Lower". Because they are + identical MR11 will report a problem. + + ------------------------------------------------------------------------- + t10.g, line 5: warning: the predicates used to disambiguate rule rule0 + (file t10.g alt 1 line 5 and alt 2 line 6) + are identical when compared without context and may have no + resolving power for some lookahead sequences. + ------------------------------------------------------------------------- + + If you use the "-info p" option the output file will contain: + + +----------------------------------------------------------------------+ + |#if 0 | + | | + |The following predicates are identical when compared without | + | lookahead context information. For some ambiguous lookahead | + | sequences they may not have any power to resolve the ambiguity. | + | | + |Choice 1: rule0/1 alt 1 line 5 file t10.g | + | | + | The original predicate for choice 1 with available context | + | information: | + | | + | OR expr | + | | + | pred << Upper>>? | + | depth=k=1 rule rule2 line 14 t10.g | + | set context: | + | ID | + | | + | pred << Lower>>? | + | depth=k=1 rule rule3 line 15 t10.g | + | set context: | + | ID | + | | + | The predicate for choice 1 after expansion (but without context | + | information): | + | | + | OR expr | + | | + | pred << isUpper(LATEXT(1))>>? | + | depth=k=1 rule line 1 t10.g | + | | + | pred << isLower(LATEXT(1))>>? | + | depth=k=1 rule line 2 t10.g | + | | + | | + |Choice 2: rule0/2 alt 2 line 6 file t10.g | + | | + | The original predicate for choice 2 with available context | + | information: | + | | + | pred << Alpha>>? | + | depth=k=1 rule rule0 line 6 t10.g | + | set context: | + | ID | + | | + | The predicate for choice 2 after expansion (but without context | + | information): | + | | + | OR expr | + | | + | pred << isUpper(LATEXT(1))>>? | + | depth=k=1 rule line 1 t10.g | + | | + | pred << isLower(LATEXT(1))>>? | + | depth=k=1 rule line 2 t10.g | + | | + | | + |#endif | + +----------------------------------------------------------------------+ + + The comparison of the predicates for the two alternatives takes + place without context information, which means that in some cases + the predicates will be considered identical even though they operate + on disjoint lookahead sets. Consider: + + #pred Alpha + + rule1: <>? ID + | <>? Label + ; + + Because the comparison of predicates takes place without context + these will be considered identical. The reason for comparing + without context is that otherwise it would be necessary to re-evaluate + the entire predicate expression for each possible lookahead sequence. + This would require more code to be written and more CPU time during + grammar analysis, and it is not yet clear whether anyone will even make + use of the new #pred facility. + + A temporary workaround might be to use different #pred statements + for predicates you know have different context. This would avoid + extraneous warnings. + + The above example might be termed a "false positive". Comparison + without context will also lead to "false negatives". Consider the + following example: + + #pred Alpha + #pred Beta + + rule1: <>? A + | rule2 + ; + + rule2: <>? A + | <>? B + ; + + The predicate used for alt 2 of rule1 is (Alpha || Beta). This + appears to be different than the predicate Alpha used for alt1. + However, the context of Beta is B. Thus when the lookahead is A + Beta will have no resolving power and Alpha will be used for both + alternatives. Using the same predicate for both alternatives isn't + very helpful, but this will not be detected with 1.33MR11. + + To properly handle this the predicate expression would have to be + evaluated for each distinct lookahead context. + + To determine whether two predicate expressions are identical is + difficult. The routine may fail to identify identical predicates. + + The #pred feature also compares predicates to see if a choice between + alternatives which is resolved by a predicate which makes the second + choice unreachable. Consider the following example: + + #pred A <>? + #pred B <>? + #pred A_or_B A || B + + r : s + | t + ; + s : <>? ID + ; + t : <>? ID + ; + + ---------------------------------------------------------------------------- + t11.g, line 5: warning: the predicate used to disambiguate the + first choice of rule r + (file t11.g alt 1 line 5 and alt 2 line 6) + appears to "cover" the second predicate when compared without context. + The second predicate may have no resolving power for some lookahead + sequences. + ---------------------------------------------------------------------------- + +#139. (Changed in MR11) Problem with -gp in C++ mode + + The -gp option to add a prefix to rule names did not work in + C++ mode. This has been fixed. + + Reported by Alexey Demakov (demakov@kazbek.ispras.ru). + +#138. (Changed in MR11) Additional makefiles for non-MSVC++ MS systems + + Sramji Ramanathan (ps@kumaran.com) has supplied makefiles for + building antlr and dlg with Win95/NT development tools that + are not based on MSVC5. They are pccts/antlr/AntlrMS.mak and + pccts/dlg/DlgMS.mak. + + The first line of the makefiles require a definition of PCCTS_HOME. + + These are in additiion to the AntlrMSVC50.* and DlgMSVC50.* + supplied by Jeff Vincent (JVincent@novell.com). + +#137. (Changed in MR11) Token getType(), getText(), getLine() const members + + -------------------------------------------------------------------- + If you use ANTLRCommonToken this change probably does not affect you. + -------------------------------------------------------------------- + + For a long time it has bothered me that these accessor functions + in ANTLRAbstractToken were not const member functions. I have + refrained from changing them because it require users to modify + existing token class definitions which are derived directly + from ANTLRAbstractToken. I think it is now time. + + For those who are not used to C++, a "const member function" is a + member function which does not modify its own object - the thing + to which "this" points. This is quite different from a function + which does not modify its arguments + + Most token definitions based on ANTLRAbstractToken have something like + the following in order to create concrete definitions of the pure + virtual methods in ANTLRAbstractToken: + + class MyToken : public ANTLRAbstractToken { + ... + ANTLRTokenType getType() {return _type; } + int getLine() {return _line; } + ANTLRChar * getText() {return _text; } + ... + } + + The required change is simply to put "const" following the function + prototype in the header (.h file) and the definition file (.cpp if + it is not inline): + + class MyToken : public ANTLRAbstractToken { + ... + ANTLRTokenType getType() const {return _type; } + int getLine() const {return _line; } + ANTLRChar * getText() const {return _text; } + ... + } + + This was originally proposed a long time ago by Bruce + Guenter (bruceg@qcc.sk.ca). + +#136. (Changed in MR11) Added getLength() to ANTLRCommonToken + + Classes ANTLRCommonToken and ANTLRCommonTokenNoRefCountToken + now have a member function: + + int getLength() const { return strlen(getText()) } + + Suggested by Sramji Ramanathan (ps@kumaran.com). + +#135. (Changed in MR11) Raised antlr's own default ZZLEXBUFSIZE to 8k + +#134a. (ansi_mr10.zip) T.J. Parr's ANSI C grammar made 1.33MR11 compatible + + There is a typographical error in the definition of BITWISEOREQ: + + #token BITWISEOREQ "!=" should be "\|=" + + When this change is combined with the bugfix to the follow set cache + problem (Item #147) and a minor rearrangement of the grammar + (Item #134b) it becomes a k=1 ck=2 grammar. + +#134b. (ansi_mr10.zip) T.J. Parr's ANSI C grammar made 1.33MR11 compatible + + The following changes were made in the ansi.g grammar (along with + using -mrhoist on): + + ansi.g + ====== + void tracein(char *) ====> void tracein(const char *) + void traceout(char *) ====> void traceout(const char *) + + getType()==IDENTIFIER ? isTypeName(LT(1)->getText()) : 1>>? + ====> <getText())>>? + + <<(LT(1)->getType()==LPARENTHESIS && LT(2)->getType()==IDENTIFIER) ? \ + isTypeName(LT(2)->getText()) : 1>>? + ====> (LPARENTHESIS IDENTIFIER)? => <getText())>>? + + <<(LT(1)->getType()==LPARENTHESIS && LT(2)->getType()==IDENTIFIER) ? \ + isTypeName(LT(2)->getText()) : 1>>? + ====> (LPARENTHESIS IDENTIFIER)? => <getText())>>? + + added to init(): traceOptionValueDefault=0; + added to init(): traceOption(-1); + + change rule "statement": + + statement + : plain_label_statement + | case_label_statement + | <<;>> expression SEMICOLON + | compound_statement + | selection_statement + | iteration_statement + | jump_statement + | SEMICOLON + ; + + plain_label_statement + : IDENTIFIER COLON statement + ; + + case_label_statement + : CASE constant_expression COLON statement + | DEFAULT COLON statement + ; + + support.cpp + =========== + void tracein(char *) ====> void tracein(const char *) + void traceout(char *) ====> void traceout(const char *) + + added to tracein(): ANTLRParser::tracein(r); // call superclass method + added to traceout(): ANTLRParser::traceout(r); // call superclass method + + Makefile + ======== + added to AFLAGS: -mrhoist on -prc on + +#133. (Changed in 1.33MR11) Make trace options public in ANTLRParser + + In checking T.J. Parr's ANSI C grammar for compatibility with + 1.33MR11 discovered that it was inconvenient to have the + trace facilities with protected access. + +#132. (Changed in 1.33MR11) Recognition of identical predicates in alts + + Prior to 1.33MR11, there would be no ambiguity warning when the + very same predicate was used to disambiguate both alternatives: + + test: ref B + | ref C + ; + + ref : <>? A + + In 1.33MR11 this will cause the warning: + + warning: the predicates used to disambiguate rule test + (file v98.g alt 1 line 1 and alt 2 line 2) + are identical and have no resolving power + + ----------------- Note ----------------- + + This is different than the following case + + test: <>? A B + | <>? A C + ; + + In this case there are two distinct predicates + which have exactly the same text. In the first + example there are two references to the same + predicate. The problem represented by this + grammar will be addressed later. + +#131. (Changed in 1.33MR11) Case insensitive command line options + + Command line switches like "-CC" and keywords like "on", "off", + and "stdin" are no longer case sensitive in antlr, dlg, and sorcerer. + +#130. (Changed in 1.33MR11) Changed ANTLR_VERSION to int from string + + The ANTLR_VERSION was not an integer, making it difficult to + perform conditional compilation based on the antlr version. + + Henceforth, ANTLR_VERSION will be: + + (base_version * 10000) + release number + + thus 1.33MR11 will be: 133*100+11 = 13311 + + Suggested by Rainer Janssen (Rainer.Janssen@Informatik.Uni-Oldenburg.DE). + +#129. (Changed in 1.33MR11) Addition of ANTLR_VERSION to .h + + The following code is now inserted into .h amd + stdpccts.h: + + #ifndef ANTLR_VERSION + #define ANTLR_VERSION 13311 + #endif + + Suggested by Rainer Janssen (Rainer.Janssen@Informatik.Uni-Oldenburg.DE) + +#128. (Changed in 1.33MR11) Redundant predicate code in (<>? ...)+ + + Prior to 1.33MR11, the following grammar would generate + redundant tests for the "while" condition. + + rule2 : (<>? X)+ X + | B + ; + + The code would resemble: + + if (LA(1)==X) { + if (pred) { + do { + if (!pred) {zzfailed_pred(" pred");} + zzmatch(X); zzCONSUME; + } while (LA(1)==X && pred && pred); + } else {... + + With 1.33MR11 the redundant predicate test is omitted. + +#127. (Changed in 1.33MR11) + + Count Syntax Errors Count DLG Errors + ------------------- ---------------- + + C++ mode ANTLRParser:: DLGLexerBase:: + syntaxErrCount lexErrCount + C mode zzSyntaxErrCount zzLexErrCount + + The C mode variables are global and initialized to 0. + They are *not* reset to 0 automatically when antlr is + restarted. + + The C++ mode variables are public. They are initialized + to 0 by the constructors. They are *not* reset to 0 by the + ANTLRParser::init() method. + + Suggested by Reinier van den Born (reinier@vnet.ibm.com). + +#126. (Changed in 1.33MR11) Addition of #first <<...>> + + The #first <<...>> inserts the specified text in the output + files before any other #include statements required by pccts. + The only things before the #first text are comments and + a #define ANTLR_VERSION. + + Requested by and Esa Pulkkinen (esap@cs.tut.fi) and Alexin + Zoltan (alexin@inf.u-szeged.hu). + +#125. (Changed in 1.33MR11) Lookahead for (guard)? && <

>? predicates + + When implementing the new style of guard predicate (Item #113) + in 1.33MR10 I decided to temporarily ignore the problem of + computing the "narrowest" lookahead context. + + Consider the following k=1 grammar: + + start : a + | b + ; + + a : (A)? && <>? ab ; + b : (B)? && <>? ab ; + + ab : A | B ; + + In MR10 the context for both "a" and "b" was {A B} because this is + the first set of rule "ab". Normally, this is not a problem because + the predicate which follows the guard inhibits any ambiguity report + by antlr. + + In MR11 the first set for rule "a" is {A} and for rule "b" it is {B}. + +#124. A Note on the New "&&" Style Guarded Predicates + + I've been asked several times, "What is the difference between + the old "=>" style guard predicates and the new style "&&" guard + predicates, and how do you choose one over the other" ? + + The main difference is that the "=>" does not apply the + predicate if the context guard doesn't match, whereas + the && form always does. What is the significance ? + + If you have a predicate which is not on the "leading edge" + it cannot be hoisted. Suppose you need a predicate that + looks at LA(2). You must introduce it manually. The + classic example is: + + castExpr : + LP typeName RP + | .... + ; + + typeName : <>? ID + | STRUCT ID + ; + + The problem is that typeName isn't on the leading edge + of castExpr, so the predicate isTypeName won't be hoisted into + castExpr to help make a decision on which production to choose. + + The *first* attempt to fix it is this: + + castExpr : + <>? + LP typeName RP + | .... + ; + + Unfortunately, this won't work because it ignores + the problem of STRUCT. The solution is to apply + isTypeName() in castExpr if LA(2) is an ID and + don't apply it when LA(2) is STRUCT: + + castExpr : + (LP ID)? => <>? + LP typeName RP + | .... + ; + + In conclusion, the "=>" style guarded predicate is + useful when: + + a. the tokens required for the predicate + are not on the leading edge + b. there are alternatives in the expression + selected by the predicate for which the + predicate is inappropriate + + If (b) were false, then one could use a simple + predicate (assuming "-prc on"): + + castExpr : + <>? + LP typeName RP + | .... + ; + + typeName : <>? ID + ; + + So, when do you use the "&&" style guarded predicate ? + + The new-style "&&" predicate should always be used with + predicate context. The context guard is in ADDITION to + the automatically computed context. Thus it useful for + predicates which depend on the token type for reasons + other than context. + + The following example is contributed by Reinier van den Born + (reinier@vnet.ibm.com). + + +-------------------------------------------------------------------------+ + | This grammar has two ways to call functions: | + | | + | - a "standard" call syntax with parens and comma separated args | + | - a shell command like syntax (no parens and spacing separated args) | + | | + | The former also allows a variable to hold the name of the function, | + | the latter can also be used to call external commands. | + | | + | The grammar (simplified) looks like this: | + | | + | fun_call : ID "(" { expr ("," expr)* } ")" | + | /* ID is function name */ | + | | "@" ID "(" { expr ("," expr)* } ")" | + | /* ID is var containing fun name */ | + | ; | + | | + | command : ID expr* /* ID is function name */ | + | | path expr* /* path is external command name */ | + | ; | + | | + | path : ID /* left out slashes and such */ | + | | "@" ID /* ID is environment var */ | + | ; | + | | + | expr : .... | + | | "(" expr ")"; | + | | + | call : fun_call | + | | command | + | ; | + | | + | Obviously the call is wildly ambiguous. This is more or less how this | + | is to be resolved: | + | | + | A call begins with an ID or an @ followed by an ID. | + | | + | If it is an ID and if it is an ext. command name -> command | + | if followed by a paren -> fun_call | + | otherwise -> command | + | | + | If it is an @ and if the ID is a var name -> fun_call | + | otherwise -> command | + | | + | One can implement these rules quite neatly using && predicates: | + | | + | call : ("@" ID)? && <>? fun_call | + | | (ID)? && <>? command | + | | (ID "(")? fun_call | + | | command | + | ; | + | | + | This can be done better, so it is not an ideal example, but it | + | conveys the principle. | + +-------------------------------------------------------------------------+ + +#123. (Changed in 1.33MR11) Correct definition of operators in ATokPtr.h + + The return value of operators in ANTLRTokenPtr: + + changed: unsigned ... operator !=(...) + to: int ... operator != (...) + changed: unsigned ... operator ==(...) + to: int ... operator == (...) + + Suggested by R.A. Nelson (cowboy@VNET.IBM.COM) + +#122. (Changed in 1.33MR11) Member functions to reset DLG in C++ mode + + void DLGFileReset(FILE *f) { input = f; found_eof = 0; } + void DLGStringReset(DLGChar *s) { input = s; p = &input[0]; } + + Supplied by R.A. Nelson (cowboy@VNET.IBM.COM) + +#121. (Changed in 1.33MR11) Another attempt to fix -o (output dir) option + + Another attempt is made to improve the -o option of antlr, dlg, + and sorcerer. This one by JVincent (JVincent@novell.com). + + The current rule: + + a. If -o is not specified than any explicit directory + names are retained. + + b. If -o is specified than the -o directory name overrides any + explicit directory names. + + c. The directory name of the grammar file is *not* stripped + to create the main output file. However it is stil subject + to override by the -o directory name. + +#120. (Changed in 1.33MR11) "-info f" output to stdout rather than stderr + + Added option 0 (e.g. "-info 0") which is a noop. + +#119. (Changed in 1.33MR11) Ambiguity aid for grammars + + The user can ask for additional information on ambiguities reported + by antlr to stdout. At the moment, only one ambiguity report can + be created in an antlr run. + + This feature is enabled using the "-aa" (Ambiguity Aid) option. + + The following options control the reporting of ambiguities: + + -aa ruleName Selects reporting by name of rule + -aa lineNumber Selects reporting by line number + (file name not compared) + + -aam Selects "multiple" reporting for a token + in the intersection set of the + alternatives. + + For instance, the token ID may appear dozens + of times in various paths as the program + explores the rules which are reachable from + the point of an ambiguity. With option -aam + every possible path the search program + encounters is reported. + + Without -aam only the first encounter is + reported. This may result in incomplete + information, but the information may be + sufficient and much shorter. + + -aad depth Selects the depth of the search. + The default value is 1. + + The number of paths to be searched, and the + size of the report can grow geometrically + with the -ck value if a full search for all + contributions to the source of the ambiguity + is explored. + + The depth represents the number of tokens + in the lookahead set which are matched against + the set of ambiguous tokens. A depth of 1 + means that the search stops when a lookahead + sequence of just one token is matched. + + A k=1 ck=6 grammar might generate 5,000 items + in a report if a full depth 6 search is made + with the Ambiguity Aid. The source of the + problem may be in the first token and obscured + by the volume of data - I hesitate to call + it information. + + When the user selects a depth > 1, the search + is first performed at depth=1 for both + alternatives, then depth=2 for both alternatives, + etc. + + Sample output for rule grammar in antlr.g itself: + + +---------------------------------------------------------------------+ + | Ambiguity Aid | + | | + | Choice 1: grammar/70 line 632 file a.g | + | Choice 2: grammar/82 line 644 file a.g | + | | + | Intersection of lookahead[1] sets: | + | | + | "\}" "class" "#errclass" "#tokclass" | + | | + | Choice:1 Depth:1 Group:1 ("#errclass") | + | 1 in (...)* block grammar/70 line 632 a.g | + | 2 to error grammar/73 line 635 a.g | + | 3 error error/1 line 894 a.g | + | 4 #token "#errclass" error/2 line 895 a.g | + | | + | Choice:1 Depth:1 Group:2 ("#tokclass") | + | 2 to tclass grammar/74 line 636 a.g | + | 3 tclass tclass/1 line 937 a.g | + | 4 #token "#tokclass" tclass/2 line 938 a.g | + | | + | Choice:1 Depth:1 Group:3 ("class") | + | 2 to class_def grammar/75 line 637 a.g | + | 3 class_def class_def/1 line 669 a.g | + | 4 #token "class" class_def/3 line 671 a.g | + | | + | Choice:1 Depth:1 Group:4 ("\}") | + | 2 #token "\}" grammar/76 line 638 a.g | + | | + | Choice:2 Depth:1 Group:5 ("#errclass") | + | 1 in (...)* block grammar/83 line 645 a.g | + | 2 to error grammar/93 line 655 a.g | + | 3 error error/1 line 894 a.g | + | 4 #token "#errclass" error/2 line 895 a.g | + | | + | Choice:2 Depth:1 Group:6 ("#tokclass") | + | 2 to tclass grammar/94 line 656 a.g | + | 3 tclass tclass/1 line 937 a.g | + | 4 #token "#tokclass" tclass/2 line 938 a.g | + | | + | Choice:2 Depth:1 Group:7 ("class") | + | 2 to class_def grammar/95 line 657 a.g | + | 3 class_def class_def/1 line 669 a.g | + | 4 #token "class" class_def/3 line 671 a.g | + | | + | Choice:2 Depth:1 Group:8 ("\}") | + | 2 #token "\}" grammar/96 line 658 a.g | + +---------------------------------------------------------------------+ + + For a linear lookahead set ambiguity (where k=1 or for k>1 but + when all lookahead sets [i] with i>? A ; + c : A ; + + Prior to 1.33MR10 the code generated for "start" would resemble: + + while { + if (LA(1)==A && + (!LA(1)==A || isUpper())) { + a(); + } + }; + + This code is wrong because it makes rule "c" unreachable from + "start". The essence of the problem is that antlr fails to + recognize that there can be a valid alternative within "a" even + when the predicate <>? is false. + + In 1.33MR10 with -mrhoist the hoisting of the predicate into + "start" is suppressed because it recognizes that "c" can + cover all the cases where the predicate is false: + + while { + if (LA(1)==A) { + a(); + } + }; + + With the antlr "-info p" switch the user will receive information + about the predicate suppression in the generated file: + + -------------------------------------------------------------- + #if 0 + + Hoisting of predicate suppressed by alternative without predicate. + The alt without the predicate includes all cases where + the predicate is false. + + WITH predicate: line 7 v1.g + WITHOUT predicate: line 7 v1.g + + The context set for the predicate: + + A + + The lookahead set for the alt WITHOUT the semantic predicate: + + A + + The predicate: + + pred << isUpper(LATEXT(1))>>? + depth=k=1 rule b line 9 v1.g + set context: + A + tree context: null + + Chain of referenced rules: + + #0 in rule start (line 5 v1.g) to rule a + #1 in rule a (line 7 v1.g) + + #endif + -------------------------------------------------------------- + + A predicate can be suppressed by a combination of alternatives + which, taken together, cover a predicate: + + start : (a)* "@" ; + + a : b | ca | cb | cc ; + + b : <>? ( A | B | C ) ; + + ca : A ; + cb : B ; + cc : C ; + + Consider a more complex example in which "c" covers only part of + a predicate: + + start : (a)* "@" ; + + a : b + | c + ; + + b : <>? + ( A + | X + ); + + c : A + ; + + Prior to 1.33MR10 the code generated for "start" would resemble: + + while { + if ( (LA(1)==A || LA(1)==X) && + (! (LA(1)==A || LA(1)==X) || isUpper()) { + a(); + } + }; + + With 1.33MR10 and -mrhoist the predicate context is restricted to + the non-covered lookahead. The code resembles: + + while { + if ( (LA(1)==A || LA(1)==X) && + (! (LA(1)==X) || isUpper()) { + a(); + } + }; + + With the antlr "-info p" switch the user will receive information + about the predicate restriction in the generated file: + + -------------------------------------------------------------- + #if 0 + + Restricting the context of a predicate because of overlap + in the lookahead set between the alternative with the + semantic predicate and one without + Without this restriction the alternative without the predicate + could not be reached when input matched the context of the + predicate and the predicate was false. + + WITH predicate: line 11 v4.g + WITHOUT predicate: line 12 v4.g + + The original context set for the predicate: + + A X + + The lookahead set for the alt WITHOUT the semantic predicate: + + A + + The intersection of the two sets + + A + + The original predicate: + + pred << isUpper(LATEXT(1))>>? + depth=k=1 rule b line 15 v4.g + set context: + A X + tree context: null + + The new (modified) form of the predicate: + + pred << isUpper(LATEXT(1))>>? + depth=k=1 rule b line 15 v4.g + set context: + X + tree context: null + + #endif + -------------------------------------------------------------- + + The bad news about -mrhoist: + + (a) -mrhoist does not analyze predicates with lookahead + depth > 1. + + (b) -mrhoist does not look past a guarded predicate to + find context which might cover other predicates. + + For these cases you might want to use syntactic predicates. + When a semantic predicate fails during guess mode the guess + fails and the next alternative is tried. + + Limitation (a) is illustrated by the following example: + + start : (stmt)* EOF ; + + stmt : cast + | expr + ; + cast : <>? LP ID RP ; + + expr : LP ID RP ; + + This is not much different from the first example, except that + it requires two tokens of lookahead context to determine what + to do. This predicate is NOT suppressed because the current version + is unable to handle predicates with depth > 1. + + A predicate can be combined with other predicates during hoisting. + In those cases the depth=1 predicates are still handled. Thus, + in the following example the isUpper() predicate will be suppressed + by line #4 when hoisted from "bizarre" into "start", but will still + be present in "bizarre" in order to predict "stmt". + + start : (bizarre)* EOF ; // #1 + // #2 + bizarre : stmt // #3 + | A // #4 + ; + + stmt : cast + | expr + ; + + cast : <>? LP ID RP ; + + expr : LP ID RP ; + | <>? A + + Limitation (b) is illustrated by the following example of a + context guarded predicate: + + rule : (A)? <

>? // #1 + (A // #2 + |B // #3 + ) // #4 + | <> B // #5 + ; + + Recall that this means that when the lookahead is NOT A then + the predicate "p" is ignored and it attempts to match "A|B". + Ideally, the "B" at line #3 should suppress predicate "q". + However, the current version does not attempt to look past + the guard predicate to find context which might suppress other + predicates. + + In some cases -mrhoist will lead to the reporting of ambiguities + which were not visible before: + + start : (a)* "@"; + a : bc | d; + bc : b | c ; + + b : <>? A; + c : A ; + + d : A ; + + In this case there is a true ambiguity in "a" between "bc" and "d" + which can both match "A". Without -mrhoist the predicate in "b" + is hoisted into "a" and there is no ambiguity reported. However, + with -mrhoist, the predicate in "b" is suppressed by "c" (as it + should be) making the ambiguity in "a" apparent. + + The motivations for these changes were hoisting problems reported + by Reinier van den Born (reinier@vnet.ibm.com) and several others. + +#116. (Changed in 1.33MR10) C++ mode: tracein/traceout rule name is (const char *) + + The prototype for C++ mode routine tracein (and traceout) has changed from + "char *" to "const char *". + +#115. (Changed in 1.33MR10) Using guess mode with exception handlers in C mode + + The definition of the C mode macros zzmatch_wsig and zzsetmatch_wsig + neglected to consider guess mode. When control passed to the rule's + parse exception handler the routine would exit without ever closing the + guess block. This would lead to unpredictable behavior. + + In 1.33MR10 the behavior of exceptions in C mode and C++ mode should be + identical. + +#114. (Changed in 1.33MR10) difference in [zz]resynch() between C and C++ modes + + There was a slight difference in the way C and C++ mode resynchronized + following a parsing error. The C routine would sometimes skip an extra + token before attempting to resynchronize. + + The C routine was changed to match the C++ routine. + +#113. (Changed in 1.33MR10) new context guarded pred: (g)? && <

>? expr + + The existing context guarded predicate: + + rule : (guard)? => <

>? expr + | next_alternative + ; + + generates code which resembles: + + if (lookahead(expr) && (!guard || pred)) { + expr() + } else .... + + This is not suitable for some applications because it allows + expr() to be invoked when the predicate is false. This is + intentional because it is meant to mimic automatically computed + predicate context. + + The new context guarded predicate uses the guard information + differently because it has a different goal. Consider: + + rule : (guard)? && <

>? expr + | next_alternative + ; + + The new style of context guarded predicate is equivalent to: + + rule : <>? expr + | next_alternative + ; + + It generates code which resembles: + + if (lookahead(expr) && guard && pred) { + expr(); + } else ... + + Both forms of guarded predicates severely restrict the form of + the context guard: it can contain no rule references, no + (...)*, no (...)+, and no {...}. It may contain token and + token class references, and alternation ("|"). + + Addition for 1.33MR11: in the token expression all tokens must + be at the same height of the token tree: + + (A ( B | C))? && ... is ok (all height 2) + (A ( B | ))? && ... is not ok (some 1, some 2) + (A B C D | E F G H)? && ... is ok (all height 4) + (A B C D | E )? && ... is not ok (some 4, some 1) + + This restriction is required in order to properly compute the lookahead + set for expressions like: + + rule1 : (A B C)? && <>? rule2 ; + rule2 : (A|X) (B|Y) (C|Z); + + This addition was suggested by Rienier van den Born (reinier@vnet.ibm.com) + +#112. (Changed in 1.33MR10) failed validation predicate in C guess mode + + John Lilley (jlilley@empathy.com) suggested that failed validation + predicates abort a guess rather than reporting a failed error. + This was installed in C++ mode (Item #4). Only now was it noticed + that the fix was never installed for C mode. + +#111. (Changed in 1.33MR10) moved zzTRACEIN to before init action + + When the antlr -gd switch is present antlr generates calls to + zzTRACEIN at the start of a rule and zzTRACEOUT at the exit + from a rule. Prior to 1.33MR10 Tthe call to zzTRACEIN was + after the init-action, which could cause confusion because the + init-actions were reported with the name of the enclosing rule, + rather than the active rule. + +#110. (Changed in 1.33MR10) antlr command line copied to generated file + + The antlr command line is now copied to the generated file near + the start. + +#109. (Changed in 1.33MR10) improved trace information + + The quality of the trace information provided by the "-gd" + switch has been improved significantly. Here is an example + of the output from a test program. It shows the rule name, + the first token of lookahead, the call depth, and the guess + status: + + exit rule gusxx {"?"} depth 2 + enter rule gusxx {"?"} depth 2 + enter rule gus1 {"o"} depth 3 guessing + guess done - returning to rule gus1 {"o"} at depth 3 + (guess mode continues - an enclosing guess is still active) + guess done - returning to rule gus1 {"Z"} at depth 3 + (guess mode continues - an enclosing guess is still active) + exit rule gus1 {"Z"} depth 3 guessing + guess done - returning to rule gusxx {"o"} at depth 2 (guess mode ends) + enter rule gus1 {"o"} depth 3 + guess done - returning to rule gus1 {"o"} at depth 3 (guess mode ends) + guess done - returning to rule gus1 {"Z"} at depth 3 (guess mode ends) + exit rule gus1 {"Z"} depth 3 + line 1: syntax error at "Z" missing SC + ... + + Rule trace reporting is controlled by the value of the integer + [zz]traceOptionValue: when it is positive tracing is enabled, + otherwise it is disabled. Tracing during guess mode is controlled + by the value of the integer [zz]traceGuessOptionValue. When + it is positive AND [zz]traceOptionValue is positive rule trace + is reported in guess mode. + + The values of [zz]traceOptionValue and [zz]traceGuessOptionValue + can be adjusted by subroutine calls listed below. + + Depending on the presence or absence of the antlr -gd switch + the variable [zz]traceOptionValueDefault is set to 0 or 1. When + the parser is initialized or [zz]traceReset() is called the + value of [zz]traceOptionValueDefault is copied to [zz]traceOptionValue. + The value of [zz]traceGuessOptionValue is always initialzed to 1, + but, as noted earlier, nothing will be reported unless + [zz]traceOptionValue is also positive. + + When the parser state is saved/restored the value of the trace + variables are also saved/restored. If a restore causes a change in + reporting behavior from on to off or vice versa this will be reported. + + When the -gd option is selected, the macro "#define zzTRACE_RULES" + is added to appropriate output files. + + C++ mode + -------- + int traceOption(int delta) + int traceGuessOption(int delta) + void traceReset() + int traceOptionValueDefault + + C mode + -------- + int zzTraceOption(int delta) + int zzTraceGuessOption(int delta) + void zzTraceReset() + int zzTraceOptionValueDefault + + The argument "delta" is added to the traceOptionValue. To + turn on trace when inside a particular rule one: + + rule : <> + ( + rest-of-rule + ) + <> + ; /* fail clause */ <> + + One can use the same idea to turn *off* tracing within a + rule by using a delta of (-1). + + An improvement in the rule trace was suggested by Sramji + Ramanathan (ps@kumaran.com). + +#108. A Note on Deallocation of Variables Allocated in Guess Mode + + NOTE + ------------------------------------------------------ + This mechanism only works for heap allocated variables + ------------------------------------------------------ + + The rewrite of the trace provides the machinery necessary + to properly free variables or undo actions following a + failed guess. + + The macro zzUSER_GUESS_HOOK(guessSeq,zzrv) is expanded + as part of the zzGUESS macro. When a guess is opened + the value of zzrv is 0. When a longjmp() is executed to + undo the guess, the value of zzrv will be 1. + + The macro zzUSER_GUESS_DONE_HOOK(guessSeq) is expanded + as part of the zzGUESS_DONE macro. This is executed + whether the guess succeeds or fails as part of closing + the guess. + + The guessSeq is a sequence number which is assigned to each + guess and is incremented by 1 for each guess which becomes + active. It is needed by the user to associate the start of + a guess with the failure and/or completion (closing) of a + guess. + + Guesses are nested. They must be closed in the reverse + of the order that they are opened. + + In order to free memory used by a variable during a guess + a user must write a routine which can be called to + register the variable along with the current guess sequence + number provided by the zzUSER_GUESS_HOOK macro. If the guess + fails, all variables tagged with the corresponding guess + sequence number should be released. This is ugly, but + it would require a major rewrite of antlr 1.33 to use + some mechanism other than setjmp()/longjmp(). + + The order of calls for a *successful* guess would be: + + zzUSER_GUESS_HOOK(guessSeq,0); + zzUSER_GUESS_DONE_HOOK(guessSeq); + + The order of calls for a *failed* guess would be: + + zzUSER_GUESS_HOOK(guessSeq,0); + zzUSER_GUESS_HOOK(guessSeq,1); + zzUSER_GUESS_DONE_HOOK(guessSeq); + + The default definitions of these macros are empty strings. + + Here is an example in C++ mode. The zzUSER_GUESS_HOOK and + zzUSER_GUESS_DONE_HOOK macros and myGuessHook() routine + can be used without change in both C and C++ versions. + + ---------------------------------------------------------------------- + << + + #include "AToken.h" + + typedef ANTLRCommonToken ANTLRToken; + + #include "DLGLexer.h" + + int main() { + + { + DLGFileInput in(stdin); + DLGLexer lexer(&in,2000); + ANTLRTokenBuffer pipe(&lexer,1); + ANTLRCommonToken aToken; + P parser(&pipe); + + lexer.setToken(&aToken); + parser.init(); + parser.start(); + }; + + fclose(stdin); + fclose(stdout); + return 0; + } + + >> + + << + char *s=NULL; + + #undef zzUSER_GUESS_HOOK + #define zzUSER_GUESS_HOOK(guessSeq,zzrv) myGuessHook(guessSeq,zzrv); + #undef zzUSER_GUESS_DONE_HOOK + #define zzUSER_GUESS_DONE_HOOK(guessSeq) myGuessHook(guessSeq,2); + + void myGuessHook(int guessSeq,int zzrv) { + if (zzrv == 0) { + fprintf(stderr,"User hook: starting guess #%d\n",guessSeq); + } else if (zzrv == 1) { + free (s); + s=NULL; + fprintf(stderr,"User hook: failed guess #%d\n",guessSeq); + } else if (zzrv == 2) { + free (s); + s=NULL; + fprintf(stderr,"User hook: ending guess #%d\n",guessSeq); + }; + } + + >> + + #token A "a" + #token "[\t \ \n]" <> + + class P { + + start : (top)+ + ; + + top : (which) ? <> + | other <> + ; <> + + which : which2 + ; + + which2 : which3 + ; + which3 + : (label)? <> + | (global)? <> + | (exclamation)? <> + ; + + label : <getText());>> A ":" ; + + global : <getText());>> A "::" ; + + exclamation : <getText());>> A "!" ; + + other : <getText());>> "other" ; + + } + ---------------------------------------------------------------------- + + This is a silly example, but illustrates the idea. For the input + "a ::" with tracing enabled the output begins: + + ---------------------------------------------------------------------- + enter rule "start" depth 1 + enter rule "top" depth 2 + User hook: starting guess #1 + enter rule "which" depth 3 guessing + enter rule "which2" depth 4 guessing + enter rule "which3" depth 5 guessing + User hook: starting guess #2 + enter rule "label" depth 6 guessing + guess failed + User hook: failed guess #2 + guess done - returning to rule "which3" at depth 5 (guess mode continues + - an enclosing guess is still active) + User hook: ending guess #2 + User hook: starting guess #3 + enter rule "global" depth 6 guessing + exit rule "global" depth 6 guessing + guess done - returning to rule "which3" at depth 5 (guess mode continues + - an enclosing guess is still active) + User hook: ending guess #3 + enter rule "global" depth 6 guessing + exit rule "global" depth 6 guessing + exit rule "which3" depth 5 guessing + exit rule "which2" depth 4 guessing + exit rule "which" depth 3 guessing + guess done - returning to rule "top" at depth 2 (guess mode ends) + User hook: ending guess #1 + enter rule "which" depth 3 + ..... + ---------------------------------------------------------------------- + + Remember: + + (a) Only init-actions are executed during guess mode. + (b) A rule can be invoked multiple times during guess mode. + (c) If the guess succeeds the rule will be called once more + without guess mode so that normal actions will be executed. + This means that the init-action might need to distinguish + between guess mode and non-guess mode using the variable + [zz]guessing. + +#107. (Changed in 1.33MR10) construction of ASTs in guess mode + + Prior to 1.33MR10, when using automatic AST construction in C++ + mode for a rule, an AST would be constructed for elements of the + rule even while in guess mode. In MR10 this no longer occurs. + +#106. (Changed in 1.33MR10) guess variable confusion + + In C++ mode a guess which failed always restored the parser state + using zzGUESS_DONE as part of zzGUESS_FAIL. Prior to 1.33MR10, + C mode required an explicit call to zzGUESS_DONE after the + call to zzGUESS_FAIL. + + Consider: + + rule : (alpha)? beta + | ... + ; + + The generated code resembles: + + zzGUESS + if (!zzrv && LA(1)==ID) { <==== line #1 + alpha + zzGUESS_DONE + beta + } else { + if (! zzrv) zzGUESS_DONE <==== line #2a + .... + + However, in some cases line #2 was rendered: + + if (guessing) zzGUESS_DONE <==== line #2b + + This would work for simple test cases, but would fail in + some cases where there was a guess while another guess was active. + One kind of failure would be to match up the zzGUESS_DONE at line + #2b with the "outer" guess which was still active. The outer + guess would "succeed" when only the inner guess should have + succeeded. + + In 1.33MR10 the behavior of zzGUESS and zzGUESS_FAIL in C and + and C++ mode should be identical. + + The same problem appears in 1.33 vanilla in some places. For + example: + + start : { (sub)? } ; + + or: + + start : ( + B + | ( sub )? + | C + )+ + ; + + generates incorrect code. + + The general principle is: + + (a) use [zz]guessing only when deciding between a call to zzFAIL + or zzGUESS_FAIL + + (b) use zzrv in all other cases + + This problem was discovered while testing changes to item #105. + I believe this is now fixed. My apologies. + +#105. (Changed in 1.33MR10) guess block as single alt of (...)+ + + Prior to 1.33MR10 the following constructs: + + rule_plus : ( + (sub)? + )+ + ; + + rule_star : ( + (sub)? + )* + ; + + generated incorrect code for the guess block (which could result + in runtime errors) because of an incorrect optimization of a + block with only a single alternative. + + The fix caused some changes to the fix described in Item #49 + because there are now three code generation sequences for (...)+ + blocks containing a guess block: + + a. single alternative which is a guess block + b. multiple alternatives in which the last is a guess block + c. all other cases + + Forms like "rule_star" can have unexpected behavior when there + is a syntax error: if the subrule "sub" is not matched *exactly* + then "rule_star" will consume no tokens. + + Reported by Esa Pulkkinen (esap@cs.tut.fi). + +#104. (Changed in 1.33MR10) -o option for dlg + + There was problem with the code added by item #74 to handle the + -o option of dlg. This should fix it. + +#103. (Changed in 1.33MR10) ANDed semantic predicates + + Rescinded. + + The optimization was a mistake. + The resulting problem is described in Item #150. + +#102. (Changed in 1.33MR10) allow "class parser : .... {" + + The syntax of the class statement ("class parser-name {") + has been extended to allow for the specification of base + classes. An arbirtrary number of tokens may now appear + between the class name and the "{". They are output + again when the class declaration is generated. For + example: + + class Parser : public MyBaseClassANTLRparser { + + This was suggested by a user, but I don't have a record + of who it was. + +#101. (Changed in 1.33MR10) antlr -info command line switch + + -info + + p - extra predicate information in generated file + + t - information about tnode use: + at the end of each rule in generated file + summary on stderr at end of program + + m - monitor progress + prints name of each rule as it is started + flushes output at start of each rule + + f - first/follow set information to stdout + + 0 - no operation (added in 1.33MR11) + + The options may be combined and may appear in any order. + For example: + + antlr -info ptm -CC -gt -mrhoist on mygrammar.g + +#100a. (Changed in 1.33MR10) Predicate tree simplification + + When the same predicates can be referenced in more than one + alternative of a block large predicate trees can be formed. + + The difference that these optimizations make is so dramatic + that I have decided to use it even when -mrhoist is not selected. + + Consider the following grammar: + + start : ( all )* ; + + all : a + | d + | e + | f + ; + + a : c A B + | c A C + ; + + c : <>? + ; + + d : <>? B C + ; + + e : <>? B C + ; + + f : e X Y + ; + + In rule "a" there is a reference to rule "c" in both alternatives. + The length of the predicate AAA is k=2 and it can be followed in + alternative 1 only by (A B) while in alternative 2 it can be + followed only by (A C). Thus they do not have identical context. + + In rule "all" the alternatives which refer to rules "e" and "f" allow + elimination of the duplicate reference to predicate CCC. + + The table below summarized the kind of simplification performed by + 1.33MR10. In the table, X and Y stand for single predicates + (not trees). + + (OR X (OR Y (OR Z))) => (OR X Y Z) + (AND X (AND Y (AND Z))) => (AND X Y Z) + + (OR X (... (OR X Y) ... )) => (OR X (... Y ... )) + (AND X (... (AND X Y) ... )) => (AND X (... Y ... )) + (OR X (... (AND X Y) ... )) => (OR X (... ... )) + (AND X (... (OR X Y) ... )) => (AND X (... ... )) + + (AND X) => X + (OR X) => X + + In a test with a complex grammar for a real application, a predicate + tree with six OR nodes and 12 leaves was reduced to "(OR X Y Z)". + + In 1.33MR10 there is a greater effort to release memory used + by predicates once they are no longer in use. + +#100b. (Changed in 1.33MR10) Suppression of extra predicate tests + + The following optimizations require that -mrhoist be selected. + + It is relatively easy to optimize the code generated for predicate + gates when they are of the form: + + (AND X Y Z ...) + or (OR X Y Z ...) + + where X, Y, Z, and "..." represent individual predicates (leaves) not + predicate trees. + + If the predicate is an AND the contexts of the X, Y, Z, etc. are + ANDed together to create a single Tree context for the group and + context tests for the individual predicates are suppressed: + + -------------------------------------------------- + Note: This was incorrect. The contexts should be + ORed together. This has been fixed. A more + complete description is available in item #152. + --------------------------------------------------- + + Optimization 1: (AND X Y Z ...) + + Suppose the context for Xtest is LA(1)==LP and the context for + Ytest is LA(1)==LP && LA(2)==ID. + + Without the optimization the code would resemble: + + if (lookaheadContext && + !(LA(1)==LP && LA(1)==LP && LA(2)==ID) || + ( (! LA(1)==LP || Xtest) && + (! (LA(1)==LP || LA(2)==ID) || Xtest) + )) {... + + With the -mrhoist optimization the code would resemble: + + if (lookaheadContext && + ! (LA(1)==LP && LA(2)==ID) || (Xtest && Ytest) {... + + Optimization 2: (OR X Y Z ...) with identical contexts + + Suppose the context for Xtest is LA(1)==ID and for Ytest + the context is also LA(1)==ID. + + Without the optimization the code would resemble: + + if (lookaheadContext && + ! (LA(1)==ID || LA(1)==ID) || + (LA(1)==ID && Xtest) || + (LA(1)==ID && Ytest) {... + + With the -mrhoist optimization the code would resemble: + + if (lookaheadContext && + (! LA(1)==ID) || (Xtest || Ytest) {... + + Optimization 3: (OR X Y Z ...) with distinct contexts + + Suppose the context for Xtest is LA(1)==ID and for Ytest + the context is LA(1)==LP. + + Without the optimization the code would resemble: + + if (lookaheadContext && + ! (LA(1)==ID || LA(1)==LP) || + (LA(1)==ID && Xtest) || + (LA(1)==LP && Ytest) {... + + With the -mrhoist optimization the code would resemble: + + if (lookaheadContext && + (zzpf=0, + (LA(1)==ID && (zzpf=1) && Xtest) || + (LA(1)==LP && (zzpf=1) && Ytest) || + !zzpf) { + + These may appear to be of similar complexity at first, + but the non-optimized version contains two tests of each + context while the optimized version contains only one + such test, as well as eliminating some of the inverted + logic (" !(...) || "). + + Optimization 4: Computation of predicate gate trees + + When generating code for the gates of predicate expressions + antlr 1.33 vanilla uses a recursive procedure to generate + "&&" and "||" expressions for testing the lookahead. As each + layer of the predicate tree is exposed a new set of "&&" and + "||" expressions on the lookahead are generated. In many + cases the lookahead being tested has already been tested. + + With -mrhoist a lookahead tree is computed for the entire + lookahead expression. This means that predicates with identical + context or context which is a subset of another predicate's + context disappear. + + This is especially important for predicates formed by rules + like the following: + + uppperCaseVowel : <>? vowel; + vowel: : <>? LETTERS; + + These predicates are combined using AND since both must be + satisfied for rule upperCaseVowel. They have identical + context which makes this optimization very effective. + + The affect of Items #100a and #100b together can be dramatic. In + a very large (but real world) grammar one particular predicate + expression was reduced from an (unreadable) 50 predicate leaves, + 195 LA(1) terms, and 5500 characters to an (easily comprehensible) + 3 predicate leaves (all different) and a *single* LA(1) term. + +#99. (Changed in 1.33MR10) Code generation for expression trees + + Expression trees are used for k>1 grammars and predicates with + lookahead depth >1. This optimization must be enabled using + "-mrhoist on". (Clarification added for 1.33MR11). + + In the processing of expression trees, antlr can generate long chains + of token comparisons. Prior to 1.33MR10 there were many redundant + parenthesis which caused problems for compilers which could handle + expressions of only limited complexity. For example, to test an + expression tree (root R A B C D), antlr would generate something + resembling: + + (LA(1)==R && (LA(2)==A || (LA(2)==B || (LA(2)==C || LA(2)==D))))) + + If there were twenty tokens to test then there would be twenty + parenthesis at the end of the expression. + + In 1.33MR10 the generated code for tree expressions resembles: + + (LA(1)==R && (LA(2)==A || LA(2)==B || LA(2)==C || LA(2)==D)) + + For "complex" expressions the output is indented to reflect the LA + number being tested: + + (LA(1)==R + && (LA(2)==A || LA(2)==B || LA(2)==C || LA(2)==D + || LA(2)==E || LA(2)==F) + || LA(1)==S + && (LA(2)==G || LA(2)==H)) + + + Suggested by S. Bochnak (S.Bochnak@@microTool.com.pl), + +#98. (Changed in 1.33MR10) Option "-info p" + + When the user selects option "-info p" the program will generate + detailed information about predicates. If the user selects + "-mrhoist on" additional detail will be provided explaining + the promotion and suppression of predicates. The output is part + of the generated file and sandwiched between #if 0/#endif statements. + + Consider the following k=1 grammar: + + start : ( all ) * ; + + all : ( a + | b + ) + ; + + a : c B + ; + + c : <>? + | B + ; + + b : <>? X + ; + + Below is an excerpt of the output for rule "start" for the three + predicate options (off, on, and maintenance release style hoisting). + + For those who do not wish to use the "-mrhoist on" option for code + generation the option can be used in a "diagnostic" mode to provide + valuable information: + + a. where one should insert null actions to inhibit hoisting + b. a chain of rule references which shows where predicates are + being hoisted + + ====================================================================== + Example of "-info p" with "-mrhoist on" + ====================================================================== + #if 0 + + Hoisting of predicate suppressed by alternative without predicate. + The alt without the predicate includes all cases where the + predicate is false. + + WITH predicate: line 11 v36.g + WITHOUT predicate: line 12 v36.g + + The context set for the predicate: + + B + + The lookahead set for alt WITHOUT the semantic predicate: + + B + + The predicate: + + pred << LATEXT(1)>>? depth=k=1 rule c line 11 v36.g + + set context: + B + tree context: null + + Chain of referenced rules: + + #0 in rule start (line 1 v36.g) to rule all + #1 in rule all (line 3 v36.g) to rule a + #2 in rule a (line 8 v36.g) to rule c + #3 in rule c (line 11 v36.g) + + #endif + && + #if 0 + + pred << LATEXT(1)>>? depth=k=1 rule b line 15 v36.g + + set context: + X + tree context: null + + #endif + ====================================================================== + Example of "-info p" with the default -prc setting ( "-prc off") + ====================================================================== + #if 0 + + OR + pred << LATEXT(1)>>? depth=k=1 rule c line 11 v36.g + + set context: + nil + tree context: null + + pred << LATEXT(1)>>? depth=k=1 rule b line 15 v36.g + + set context: + nil + tree context: null + + #endif + ====================================================================== + Example of "-info p" with "-prc on" and "-mrhoist off" + ====================================================================== + #if 0 + + OR + pred << LATEXT(1)>>? depth=k=1 rule c line 11 v36.g + + set context: + B + tree context: null + + pred << LATEXT(1)>>? depth=k=1 rule b line 15 v36.g + + set context: + X + tree context: null + + #endif + ====================================================================== + +#97. (Fixed in 1.33MR10) "Predicate applied for more than one ... " + + In 1.33 vanilla, the grammar listed below produced this message for + the first alternative (only) of rule "b": + + warning: predicate applied for >1 lookahead 1-sequences + [you may only want one lookahead 1-sequence to apply. + Try using a context guard '(...)? =>' + + In 1.33MR10 the message is issued for both alternatives. + + top : (a)*; + a : b | c ; + + b : <>? ( AAA | BBB ) + | <>? ( XXX | YYY ) + ; + + c : AAA | XXX; + +#96. (Fixed in 1.33MR10) Guard predicates ignored when -prc off + + Prior to 1.33MR10, guard predicate code was not generated unless + "-prc on" was selected. + + This was incorrect, since "-prc off" (the default) is supposed to + disable only AUTOMATIC computation of predicate context, not the + programmer specified context supplied by guard predicates. + +#95. (Fixed in 1.33MR10) Predicate guard context length was k, not max(k,ck) + + Prior to 1.33MR10, predicate guards were computed to k tokens rather + than max(k,ck). Consider the following grammar: + + a : ( A B C)? => <>? (A|X) (B|Y) (C|Z) ; + + The code generated by 1.33 vanilla with "-k 1 -ck 3 -prc on" + for the predicate in "a" resembles: + + if ( (! LA(1)==A) || AAA(LATEXT(1))) {... + + With 1.33MR10 and the same options the code resembles: + + if ( (! (LA(1)==A && LA(2)==B && LA(3)==C) || AAA(LATEXT(1))) {... + +#94. (Fixed in 1.33MR10) Predicates followed by rule references + + Prior to 1.33MR10, a semantic predicate which referenced a token + which was off the end of the rule caused an incomplete context + to be computed (with "-prc on") for the predicate under some circum- + stances. In some cases this manifested itself as illegal C code + (e.g. "LA(2)==[Ep](1)" in the k=2 examples below: + + all : ( a ) *; + + a : <>? ID X + | <>? Y + | Z + ; + + This might also occur when the semantic predicate was followed + by a rule reference which was shorter than the length of the + semantic predicate: + + all : ( a ) *; + + a : <>? ID X + | <>? y + | Z + ; + + y : Y ; + + Depending on circumstance, the resulting context might be too + generous because it was too short, or too restrictive because + of missing alternatives. + +#93. (Changed in 1.33MR10) Definition of Purify macro + + Ofer Ben-Ami (gremlin@cs.huji.ac.il) has supplied a definition + for the Purify macro: + + #define PURIFY(r, s) memset((char *) &(r), '\0', (s)); + + Note: This may not be the right thing to do for C++ objects that + have constructors. Reported by Bonny Rais (bonny@werple.net.au). + + For those cases one should #define PURIFY to an empty macro in the + #header or #first actions. + +#92. (Fixed in 1.33MR10) Guarded predicates and hoisting + + When a guarded predicate participates in hoisting it is linked into + a predicate expression tree. Prior to 1.33MR10 this link was never + cleared and the next time the guard was used to construct a new + tree the link could contain a spurious reference to another element + which had previosly been joined to it in the semantic predicate tree. + + For example: + + start : ( all ) *; + all : ( a | b ) ; + + start2 : ( all2 ) *; + all2 : ( a ) ; + + a : (A)? => <>? A ; + b : (B)? => <>? B ; + + Prior to 1.33MR10 the code for "start2" would include a spurious + reference to the BBB predicate which was left from constructing + the predicate tree for rule "start" (i.e. or(AAA,BBB) ). + + In 1.33MR10 this problem is avoided by cloning the original guard + each time it is linked into a predicate tree. + +#91. (Changed in 1.33MR10) Extensive changes to semantic pred hoisting + + ============================================ + This has been rendered obsolete by Item #117 + ============================================ + +#90. (Fixed in 1.33MR10) Semantic pred with LT(i) and i>max(k,ck) + + There is a bug in antlr 1.33 vanilla and all maintenance releases + prior to 1.33MR10 which allows semantic predicates to reference + an LT(i) or LATEXT(i) where i is larger than max(k,ck). When + this occurs antlr will attempt to mark the ith element of an array + in which there are only max(k,ck) elements. The result cannot + be predicted. + + Using LT(i) or LATEXT(i) for i>max(k,ck) is reported as an error + in 1.33MR10. + +#89. Rescinded + +#88. (Fixed in 1.33MR10) Tokens used in semantic predicates in guess mode + + Consider the behavior of a semantic predicate during guess mode: + + rule : a:A ( + <>? b:B + | c:C + ); + + Prior to MR10 the assignment of the token or attribute to + $a did not occur during guess mode, which would cause the + semantic predicate to misbehave because $a would be null. + + In 1.33MR10 a semantic predicate with a reference to an + element label (such as $a) forces the assignment to take + place even in guess mode. + + In order to work, this fix REQUIRES use of the $label format + for token pointers and attributes referenced in semantic + predicates. + + The fix does not apply to semantic predicates using the + numeric form to refer to attributes (e.g. <>?). + The user will receive a warning for this case. + + Reported by Rob Trout (trout@mcs.cs.kent.edu). + +#87. (Fixed in 1.33MR10) Malformed guard predicates + + Context guard predicates may contain only references to + tokens. They may not contain references to (...)+ and + (...)* blocks. This is now checked. This replaces the + fatal error message in item #78 with an appropriate + (non-fatal) error messge. + + In theory, context guards should be allowed to reference + rules. However, I have not had time to fix this. + Evaluation of the guard takes place before all rules have + been read, making it difficult to resolve a forward reference + to rule "zzz" - it hasn't been read yet ! To postpone evaluation + of the guard until all rules have been read is too much + for the moment. + +#86. (Fixed in 1.33MR10) Unequal set size in set_sub + + Routine set_sub() in pccts/support/set/set.h did not work + correctly when the sets were of unequal sizes. Rewrote + set_equ to make it simpler and remove unnecessary and + expensive calls to set_deg(). This routine was not used + in 1.33 vanila. + +#85. (Changed in 1.33MR10) Allow redefinition of MaxNumFiles + + Raised the maximum number of input files to 99 from 20. + Put a #ifndef/#endif around the "#define MaxNumFiles 99". + +#84. (Fixed in 1.33MR10) Initialize zzBadTok in macro zzRULE + + Initialize zzBadTok to NULL in zzRULE macro of AParser.h. + in order to get rid of warning messages. + +#83. (Fixed in 1.33MR10) False warnings with -w2 for #tokclass + + When -w2 is selected antlr gives inappropriate warnings about + #tokclass names not having any associated regular expressions. + Since a #tokclass is not a "real" token it will never have an + associated regular expression and there should be no warning. + + Reported by Derek Pappas (derek.pappas@eng.sun.com) + +#82. (Fixed in 1.33MR10) Computation of follow sets with multiple cycles + + Reinier van den Born (reinier@vnet.ibm.com) reported a problem + in the computation of follow sets by antlr. The problem (bug) + exists in 1.33 vanilla and all maintenance releases prior to 1.33MR10. + + The problem involves the computation of follow sets when there are + cycles - rules which have mutual references. I believe the problem + is restricted to cases where there is more than one cycle AND + elements of those cycles have rules in common. Even when this + occurs it may not affect the code generated - but it might. It + might also lead to undetected ambiguities. + + There were no changes in antlr or dlg output from the revised version. + + The following fragment demonstates the problem by giving different + follow sets (option -pa) for var_access when built with k=1 and ck=2 on + 1.33 vanilla and 1.33MR10: + + echo_statement : ECHO ( echo_expr )* + ; + + echo_expr : ( command )? + | expression + ; + + command : IDENTIFIER + { concat } + ; + + expression : operand ( OPERATOR operand )* + ; + + operand : value + | START command END + ; + + value : concat + | TYPE operand + ; + + concat : var_access { CONCAT value } + ; + + var_access : IDENTIFIER { INDEX } + + ; +#81. (Changed in 1.33MR10) C mode use of attributes and ASTs + + Reported by Isaac Clark (irclark@mindspring.com). + + C mode code ignores attributes returned by rules which are + referenced using element labels when ASTs are enabled (-gt option). + + 1. start : r:rule t:Token <<$start=$r;>> + + The $r refrence will not work when combined with + the -gt option. + + 2. start : t:Token <<$start=$t;>> + + The $t reference works in all cases. + + 3. start : rule <<$0=$1;>> + + Numeric labels work in all cases. + + With MR10 the user will receive an error message for case 1 when + the -gt option is used. + +#80. (Fixed in 1.33MR10) (...)? as last alternative of block + + A construct like the following: + + rule : a + | (b)? + ; + + does not make sense because there is no alternative when + the guess block fails. This is now reported as a warning + to the user. + + Previously, there was a code generation error for this case: + the guess block was not "closed" when the guess failed. + This could cause an infinite loop or other problems. This + is now fixed. + + Example problem: + + #header<< + #include + #include "charptr.h" + >> + + << + #include "charptr.c" + main () + { + ANTLR(start(),stdin); + } + >> + + #token "[\ \t]+" << zzskip(); >> + #token "[\n]" << zzline++; zzskip(); >> + + #token Word "[a-z]+" + #token Number "[0-9]+" + + + start : (test1)? + | (test2)? + ; + test1 : (Word Word Word Word)? + | (Word Word Word Number)? + ; + test2 : (Word Word Number Word)? + | (Word Word Number Number)? + ; + + Test data which caused infinite loop: + + a 1 a a + +#79. (Changed in 1.33MR10) Use of -fh with multiple parsers + + Previously, antlr always used the pre-processor symbol + STDPCCTS_H as a gate for the file stdpccts.h. This + caused problems when there were multiple parsers defined + because they used the same gate symbol. + + In 1.33MR10, the -fh filename is used to generate the + gate file for stdpccts.h. For instance: + + antlr -fh std_parser1.h + + generates the pre-processor symbol "STDPCCTS_std_parser1_H". + + Reported by Ramanathan Santhanam (ps@kumaran.com). + +#78. (Changed in 1.33MR9) Guard predicates that refer to rules + + ------------------------ + Please refer to Item #87 + ------------------------ + + Guard predicates are processed during an early phase + of antlr (during parsing) before all data structures + are completed. + + There is an apparent bug in earlier versions of 1.33 + which caused guard predicates which contained references + to rules (rather than tokens) to reference a structure + which hadn't yet been initialized. + + In some cases (perhaps all cases) references to rules + in guard predicates resulted in the use of "garbage". + +#79. (Changed in 1.33MR9) Jeff Vincent (JVincent@novell.com) + + Previously, the maximum length file name was set + arbitrarily to 300 characters in antlr, dlg, and sorcerer. + + The config.h file now attempts to define the maximum length + filename using _MAX_PATH from stdlib.h before falling back + to using the value 300. + +#78. (Changed in 1.33MR9) Jeff Vincent (JVincent@novell.com) + + Put #ifndef/#endif around definition of ZZLEXBUFSIZE in + antlr. + +#77. (Changed in 1.33MR9) Arithmetic overflow for very large grammars + + In routine HandleAmbiguities() antlr attempts to compute the + number of possible elements in a set that is order of + number-of-tokens raised to the number-of-lookahead-tokens power. + For large grammars or large lookahead (e.g. -ck 7) this can + cause arithmetic overflow. + + With 1.33MR9, arithmetic overflow in this computation is reported + the first time it happens. The program continues to run and + the program branches based on the assumption that the computed + value is larger than any number computed by counting actual cases + because 2**31 is larger than the number of bits in most computers. + + Before 1.33MR9 overflow was not reported. The behavior following + overflow is not predictable by anyone but the original author. + + NOTE + + In 1.33MR10 the warning message is suppressed. + The code which detects the overflow allows the + computation to continue without an error. The + error message itself made made users worry. + +#76. (Changed in 1.33MR9) Jeff Vincent (JVincent@novell.com) + + Jeff Vincent has convinced me to make ANTLRCommonToken and + ANTLRCommonNoRefCountToken use variable length strings + allocated from the heap rather than fixed length strings. + By suitable definition of setText(), the copy constructor, + and operator =() it is possible to maintain "copy" semantics. + By "copy" semantics I mean that when a token is copied from + an existing token it receives its own, distinct, copy of the + text allocated from the heap rather than simply a pointer + to the original token's text. + + ============================================================ + W * A * R * N * I * N * G + ============================================================ + + It is possible that this may cause problems for some users. + For those users I have included the old version of AToken.h as + pccts/h/AToken_traditional.h. + +#75. (Changed in 1.33MR9) Bruce Guenter (bruceg@qcc.sk.ca) + + Make DLGStringInput const correct. Since this is infrequently + subclassed, it should affect few users, I hope. + +#74. (Changed in 1.33MR9) -o (output directory) option + + Antlr does not properly handle the -o output directory option + when the filename of the grammar contains a directory part. For + example: + + antlr -o outdir pccts_src/myfile.g + + causes antlr create a file called "outdir/pccts_src/myfile.cpp. + It SHOULD create outdir/myfile.cpp + + The suggested code fix has been installed in antlr, dlg, and + Sorcerer. + +#73. (Changed in 1.33MR9) Hoisting of semantic predicates and -mrhoist + + ============================================ + This has been rendered obsolete by Item #117 + ============================================ + +#72. (Changed in 1.33MR9) virtual saveState()/restoreState()/guess_XXX + + The following methods in ANTLRParser were made virtual at + the request of S. Bochnak (S.Bochnak@microTool.com.pl): + + saveState() and restoreState() + guess(), guess_fail(), and guess_done() + +#71. (Changed in 1.33MR9) Access to omitted command line argument + + If a switch requiring arguments is the last thing on the + command line, and the argument is omitted, antlr would core. + + antlr test.g -prc + + instead of + + antlr test.g -prc off + +#70. (Changed in 1.33MR9) Addition of MSVC .dsp and .mak build files + + The following MSVC .dsp and .mak files for pccts and sorcerer + were contributed by Stanislaw Bochnak (S.Bochnak@microTool.com.pl) + and Jeff Vincent (JVincent@novell.com) + + PCCTS Distribution Kit + ---------------------- + pccts/PCCTSMSVC50.dsw + + pccts/antlr/AntlrMSVC50.dsp + pccts/antlr/AntlrMSVC50.mak + + pccts/dlg/DlgMSVC50.dsp + pccts/dlg/DlgMSVC50.mak + + pccts/support/msvc.dsp + + Sorcerer Distribution Kit + ------------------------- + pccts/sorcerer/SorcererMSVC50.dsp + pccts/sorcerer/SorcererMSVC50.mak + + pccts/sorcerer/lib/msvc.dsp + +#69. (Changed in 1.33MR9) Change "unsigned int" to plain "int" + + Declaration of max_token_num in misc.c as "unsigned int" + caused comparison between signed and unsigned ints giving + warning message without any special benefit. + +#68. (Changed in 1.33MR9) Add void return for dlg internal_error() + + Get rid of "no return value" message in internal_error() + in file dlg/support.c and dlg/dlg.h. + +#67. (Changed in Sor) sor.g: lisp() has no return value + + Added a "void" for the return type. + +#66. (Added to Sor) sor.g: ZZLEXBUFSIZE enclosed in #ifndef/#endif + + A user needed to be able to change the ZZLEXBUFSIZE for + sor. Put the definition of ZZLEXBUFSIZE inside #ifndef/#endif + +#65. (Changed in 1.33MR9) PCCTSAST::deepCopy() and ast_dup() bug + + Jeff Vincent (JVincent@novell.com) found that deepCopy() + made new copies of only the direct descendents. No new + copies were made of sibling nodes, Sibling pointers are + set to zero by shallowCopy(). + + PCCTS_AST::deepCopy() has been changed to make a + deep copy in the traditional sense. + + The deepCopy() routine depends on the behavior of + shallowCopy(). In all sor examples I've found, + shallowCopy() zeroes the right and down pointers. + + Original Tree Original deepCopy() Revised deepCopy + ------------- ------------------- ---------------- + a->b->c A A + | | | + d->e->f D D->E->F + | | | + g->h->i G G->H->I + | | + j->k J->K + + While comparing deepCopy() for C++ mode with ast_dup for + C mode I found a problem with ast_dup(). + + Routine ast_dup() has been changed to make a deep copy + in the traditional sense. + + Original Tree Original ast_dup() Revised ast_dup() + ------------- ------------------- ---------------- + a->b->c A->B->C A + | | | + d->e->f D->E->F D->E->F + | | | + g->h->i G->H->I G->H->I + | | | + j->k J->K J->K + + + I believe this affects transform mode sorcerer programs only. + +#64. (Changed in 1.33MR9) anltr/hash.h prototype for killHashTable() + +#63. (Changed in 1.33MR8) h/charptr.h does not zero pointer after free + + The charptr.h routine now zeroes the pointer after free(). + + Reported by Jens Tingleff (jensting@imaginet.fr) + +#62. (Changed in 1.33MR8) ANTLRParser::resynch had static variable + + The static variable "consumed" in ANTLRParser::resynch was + changed into an instance variable of the class with the + name "resynchConsumed". + + Reported by S.Bochnak@microTool.com.pl + +#61. (Changed in 1.33MR8) Using rule>[i,j] when rule has no return values + + Previously, the following code would cause antlr to core when + it tried to generate code for rule1 because rule2 had no return + values ("upward inheritance"): + + rule1 : <> + rule2 > [i,j] + ; + + rule2 : Anything ; + + Reported by S.Bochnak@microTool.com.pl + + Verified correct operation of antlr MR8 when missing or extra + inheritance arguments for all combinations. When there are + missing or extra arguments code will still be generated even + though this might cause the invocation of a subroutine with + the wrong number of arguments. + +#60. (Changed in 1.33MR7) Major changes to exception handling + + There were significant problems in the handling of exceptions + in 1.33 vanilla. The general problem is that it can only + process one level of exception handler. For example, a named + exception handler, an exception handler for an alternative, or + an exception for a subrule always went to the rule's exception + handler if there was no "catch" which matched the exception. + + In 1.33MR7 the exception handlers properly "nest". If an + exception handler does not have a matching "catch" then the + nextmost outer exception handler is checked for an appropriate + "catch" clause, and so on until an exception handler with an + appropriate "catch" is found. + + There are still undesirable features in the way exception + handlers are implemented, but I do not have time to fix them + at the moment: + + The exception handlers for alternatives are outside the + block containing the alternative. This makes it impossible + to access variables declared in a block or to resume the + parse by "falling through". The parse can still be easily + resumed in other ways, but not in the most natural fashion. + + This results in an inconsistentcy between named exception + handlers and exception handlers for alternatives. When + an exception handler for an alternative "falls through" + it goes to the nextmost outer handler - not the "normal + action". + + A major difference between 1.33MR7 and 1.33 vanilla is + the default action after an exception is caught: + + 1.33 Vanilla + ------------ + In 1.33 vanilla the signal value is set to zero ("NoSignal") + and the code drops through to the code following the exception. + For named exception handlers this is the "normal action". + For alternative exception handlers this is the rule's handler. + + 1.33MR7 + ------- + In 1.33MR7 the signal value is NOT automatically set to zero. + + There are two cases: + + For named exception handlers: if the signal value has been + set to zero the code drops through to the "normal action". + + For all other cases the code branches to the nextmost outer + exception handler until it reaches the handler for the rule. + + The following macros have been defined for convenience: + + C/C++ Mode Name + -------------------- + (zz)suppressSignal + set signal & return signal arg to 0 ("NoSignal") + (zz)setSignal(intValue) + set signal & return signal arg to some value + (zz)exportSignal + copy the signal value to the return signal arg + + I'm not sure why PCCTS make a distinction between the local + signal value and the return signal argument, but I'm loathe + to change the code. The burden of copying the local signal + value to the return signal argument can be given to the + default signal handler, I suppose. + +#59. (Changed in 1.33MR7) Prototypes for some functions + + Added prototypes for the following functions to antlr.h + + zzconsumeUntil() + zzconsumeUntilToken() + +#58. (Changed in 1.33MR7) Added defintion of zzbufsize to dlgauto.h + +#57. (Changed in 1.33MR7) Format of #line directive + + Previously, the -gl directive for line 1234 would + resemble: "# 1234 filename.g". This caused problems + for some compilers/pre-processors. In MR7 it generates + "#line 1234 filename.g". + +#56. (Added in 1.33MR7) Jan Mikkelsen + + Move PURIFY macro invocaton to after rule's init action. + +#55. (Fixed in 1.33MR7) Unitialized variables in ANTLRParser + + Member variables inf_labase and inf_last were not initialized. + (See item #50.) + +#54. (Fixed in 1.33MR6) Brad Schick (schick@interacess.com) + + Previously, the following constructs generated the same + code: + + rule1 : (A B C)? + | something-else + ; + + rule2 : (A B C)? () + | something-else + ; + + In all versions of pccts rule1 guesses (A B C) and then + consume all three tokens if the guess succeeds. In MR6 + rule2 guesses (A B C) but consumes NONE of the tokens + when the guess succeeds because "()" matches epsilon. + +#53. (Explanation for 1.33MR6) What happens after an exception is caught ? + + The Book is silent about what happens after an exception + is caught. + + The following code fragment prints "Error Action" followed + by "Normal Action". + + test : Word ex:Number <> + exception[ex] + catch NoViableAlt: + <> + ; + + The reason for "Normal Action" is that the normal flow of the + program after a user-written exception handler is to "drop through". + In the case of an exception handler for a rule this results in + the exection of a "return" statement. In the case of an + exception handler attached to an alternative, rule, or token + this is the code that would have executed had there been no + exception. + + The user can achieve the desired result by using a "return" + statement. + + test : Word ex:Number <> + exception[ex] + catch NoViableAlt: + <> + ; + + The most powerful mechanism for recovery from parse errors + in pccts is syntactic predicates because they provide + backtracking. Exceptions allow "return", "break", + "consumeUntil(...)", "goto _handler", "goto _fail", and + changing the _signal value. + +#52. (Fixed in 1.33MR6) Exceptions without syntactic predicates + + The following generates bad code in 1.33 if no syntactic + predicates are present in the grammar. + + test : Word ex:Number <> + exception[ex] + catch NoViableAlt: + <> + + There is a reference to a guess variable. In C mode + this causes a compiler error. In C++ mode it generates + an extraneous check on member "guessing". + + In MR6 correct code is generated for both C and C++ mode. + +#51. (Added to 1.33MR6) Exception operator "@" used without exceptions + + In MR6 added a warning when the exception operator "@" is + used and no exception group is defined. This is probably + a case where "\@" or "@" is meant. + +#50. (Fixed in 1.33MR6) Gunnar Rxnning (gunnar@candleweb.no) + http://www.candleweb.no/~gunnar/ + + Routines zzsave_antlr_state and zzrestore_antlr_state don't + save and restore all the data needed when switching states. + + Suggested patch applied to antlr.h and err.h for MR6. + +#49. (Fixed in 1.33MR6) Sinan Karasu (sinan@boeing.com) + + Generated code failed to turn off guess mode when leaving a + (...)+ block which contained a guess block. The result was + an infinite loop. For example: + + rule : ( + (x)? + | y + )+ + + Suggested code fix implemented in MR6. Replaced + + ... else if (zzcnt>1) break; + + with: + + C++ mode: + ... else if (zzcnt>1) {if (!zzrv) zzGUESS_DONE; break;}; + C mode: + ... else if (zzcnt>1) {if (zzguessing) zzGUESS_DONE; break;}; + +#48. (Fixed in 1.33MR6) Invalid exception element causes core + + A label attached to an invalid construct can cause + pccts to crash while processing the exception associated + with the label. For example: + + rule : t:(B C) + exception[t] catch MismatchedToken: <> + + Version MR6 generates the message: + + reference in exception handler to undefined label 't' + +#47. (Fixed in 1.33MR6) Manuel Ornato + + Under some circumstances involving a k >1 or ck >1 + grammar and a loop block (i.e. (...)* ) pccts will + fail to detect a syntax error and loop indefinitely. + The problem did not exist in 1.20, but has existed + from 1.23 to the present. + + Fixed in MR6. + + --------------------------------------------------- + Complete test program + --------------------------------------------------- + #header<< + #include + #include "charptr.h" + >> + + << + #include "charptr.c" + main () + { + ANTLR(global(),stdin); + } + >> + + #token "[\ \t]+" << zzskip(); >> + #token "[\n]" << zzline++; zzskip(); >> + + #token B "b" + #token C "c" + #token D "d" + #token E "e" + #token LP "\(" + #token RP "\)" + + #token ANTLREOF "@" + + global : ( + (E liste) + | liste + | listed + ) ANTLREOF + ; + + listeb : LP ( B ( B | C )* ) RP ; + listec : LP ( C ( B | C )* ) RP ; + listed : LP ( D ( B | C )* ) RP ; + liste : ( listeb | listec )* ; + + --------------------------------------------------- + Sample data causing infinite loop + --------------------------------------------------- + e (d c) + --------------------------------------------------- + +#46. (Fixed in 1.33MR6) Robert Richter + (Robert.Richter@infotech.tu-chemnitz.de) + + This item from the list of known problems was + fixed by item #18 (below). + +#45. (Fixed in 1.33MR6) Brad Schick (schick@interaccess.com) + + The dependency scanner in VC++ mistakenly sees a + reference to an MPW #include file even though properly + #ifdef/#endif in config.h. The suggested workaround + has been implemented: + + #ifdef MPW + ..... + #define MPW_CursorCtl_Header + #include MPW_CursorCtl_Header + ..... + #endif + +#44. (Fixed in 1.33MR6) cast malloc() to (char *) in charptr.c + + Added (char *) cast for systems where malloc returns "void *". + +#43. (Added to 1.33MR6) Bruce Guenter (bruceg@qcc.sk.ca) + + Add setLeft() and setUp methods to ASTDoublyLinkedBase + for symmetry with setRight() and setDown() methods. + +#42. (Fixed in 1.33MR6) Jeff Katcher (jkatcher@nortel.ca) + + C++ style comment in antlr.c corrected. + +#41. (Added in 1.33MR6) antlr -stdout + + Using "antlr -stdout ..." forces the text that would + normally go to the grammar.c or grammar.cpp file to + stdout. + +#40. (Added in 1.33MR6) antlr -tab to change tab stops + + Using "antlr -tab number ..." changes the tab stops + for the grammar.c or grammar.cpp file. The number + must be between 0 and 8. Using 0 gives tab characters, + values between 1 and 8 give the appropriate number of + space characters. + +#39. (Fixed in 1.33MR5) Jan Mikkelsen + + Commas in function prototype still not correct under + some circumstances. Suggested code fix installed. + +#38. (Fixed in 1.33MR5) ANTLRTokenBuffer constructor + + Have ANTLRTokenBuffer ctor initialize member "parser" to null. + +#37. (Fixed in 1.33MR4) Bruce Guenter (bruceg@qcc.sk.ca) + + In ANTLRParser::FAIL(int k,...) released memory pointed to by + f[i] (as well as f itself. Should only free f itself. + +#36. (Fixed in 1.33MR3) Cortland D. Starrett (cort@shay.ecn.purdue.edu) + + Neglected to properly declare isDLGmaxToken() when fixing problem + reported by Andreas Magnusson. + + Undo "_retv=NULL;" change which caused problems for return values + from rules whose return values weren't pointers. + + Failed to create bin directory if it didn't exist. + +#35. (Fixed in 1.33MR2) Andreas Magnusson +(Andreas.Magnusson@mailbox.swipnet.se) + + Repair bug introduced by 1.33MR1 for #tokdefs. The original fix + placed "DLGmaxToken=9999" and "DLGminToken=0" in the TokenType enum + in order to fix a problem with an aggresive compiler assigning an 8 + bit enum which might be too narrow. This caused #tokdefs to assume + that there were 9999 real tokens. The repair to the fix causes antlr to + ignore TokenTypes "DLGmaxToken" and "DLGminToken" in a #tokdefs file. + +#34. (Added to 1.33MR1) Add public DLGLexerBase::set_line(int newValue) + + Previously there was no public function for changing the line + number maintained by the lexer. + +#33. (Fixed in 1.33MR1) Franklin Chen (chen@adi.com) + + Accidental use of EXIT_FAILURE rather than PCCTS_EXIT_FAILURE + in pccts/h/AParser.cpp. + +#32. (Fixed in 1.33MR1) Franklin Chen (chen@adi.com) + + In PCCTSAST.cpp lines 405 and 466: Change + + free (t) + to + free ( (char *)t ); + + to match prototype. + +#31. (Added to 1.33MR1) Pointer to parser in ANTLRTokenBuffer + Pointer to parser in DLGLexerBase + + The ANTLRTokenBuffer class now contains a pointer to the + parser which is using it. This is established by the + ANTLRParser constructor calling ANTLRTokenBuffer:: + setParser(ANTLRParser *p). + + When ANTLRTokenBuffer::setParser(ANTLRParser *p) is + called it saves the pointer to the parser and then + calls ANTLRTokenStream::setParser(ANTLRParser *p) + so that the lexer can also save a pointer to the + parser. + + There is also a function getParser() in each class + with the obvious purpose. + + It is possible that these functions will return NULL + under some circumstances (e.g. a non-DLG lexer is used). + +#30. (Added to 1.33MR1) function tokenName(int token) standard + + The generated parser class now includes the + function: + + static const ANTLRChar * tokenName(int token) + + which returns a pointer to the "name" corresponding + to the token. + + The base class (ANTLRParser) always includes the + member function: + + const ANTLRChar * parserTokenName(int token) + + which can be accessed by objects which have a pointer + to an ANTLRParser, but do not know the name of the + parser class (e.g. ANTLRTokenBuffer and DLGLexerBase). + +#29. (Added to 1.33MR1) Debugging DLG lexers + + If the pre-processor symbol DEBUG_LEXER is defined + then DLexerBase will include code for printing out + key information about tokens which are recognized. + + The debug feature of the lexer is controlled by: + + int previousDebugValue=lexer.debugLexer(newValue); + + a value of 0 disables output + a value of 1 enables output + + Even if the lexer debug code is compiled into DLexerBase + it must be enabled before any output is generated. For + example: + + DLGFileInput in(stdin); + MyDLG lexer(&in,2000); + + lexer.setToken(&aToken); + + #if DEBUG_LEXER + lexer.debugLexer(1); // enable debug information + #endif + +#28. (Added to 1.33MR1) More control over DLG header + + Version 1.33MR1 adds the following directives to PCCTS + for C++ mode: + + #lexprefix <> + + Adds source code to the DLGLexer.h file + after the #include "DLexerBase.h" but + before the start of the class definition. + + #lexmember <> + + Adds source code to the DLGLexer.h file + as part of the DLGLexer class body. It + appears immediately after the start of + the class and a "public: statement. + +#27. (Fixed in 1.33MR1) Comments in DLG actions + + Previously, DLG would not recognize comments as a special case. + Thus, ">>" in the comments would cause errors. This is fixed. + +#26. (Fixed in 1.33MR1) Removed static variables from error routines + + Previously, the existence of statically allocated variables + in some of the parser's member functions posed a danger when + there was more than one parser active. + + Replaced with dynamically allocated/freed variables in 1.33MR1. + +#25. (Fixed in 1.33MR1) Use of string literals in semantic predicates + + Previously, it was not possible to place a string literal in + a semantic predicate because it was not properly "stringized" + for the report of a failed predicate. + +#24. (Fixed in 1.33MR1) Continuation lines for semantic predicates + + Previously, it was not possible to continue semantic + predicates across a line because it was not properly + "stringized" for the report of a failed predicate. + + rule : <>?[ a very + long statement ] + +#23. (Fixed in 1.33MR1) {...} envelope for failed semantic predicates + + Previously, there was a code generation error for failed + semantic predicates: + + rule : <>?[ stmt1; stmt2; ] + + which generated code which resembled: + + if (! xyz()) stmt1; stmt2; + + It now puts the statements in a {...} envelope: + + if (! xyz()) { stmt1; stmt2; }; + +#22. (Fixed in 1.33MR1) Continuation of #token across lines using "\" + + Previously, it was not possible to continue a #token regular + expression across a line. The trailing "\" and newline caused + a newline to be inserted into the regular expression by DLG. + + Fixed in 1.33MR1. + +#21. (Fixed in 1.33MR1) Use of ">>" (right shift operator in DLG actions + + It is now possible to use the C++ right shift operator ">>" + in DLG actions by using the normal escapes: + + #token "shift-right" << value=value \>\> 1;>> + +#20. (Version 1.33/19-Jan-97 Karl Eccleson + P.A. Keller (P.A.Keller@bath.ac.uk) + + There is a problem due to using exceptions with the -gh option. + + Suggested fix now in 1.33MR1. + +#19. (Fixed in 1.33MR1) Tom Piscotti and John Lilley + + There were problems suppressing messages to stdin and stdout + when running in a window environment because some functions + which uses fprint were not virtual. + + Suggested change now in 1.33MR1. + + I believe all functions containing error messages (excluding those + indicating internal inconsistency) have been placed in functions + which are virtual. + +#18. (Version 1.33/ 22-Nov-96) John Bair (jbair@iftime.com) + + Under some combination of options a required "return _retv" is + not generated. + + Suggested fix now in 1.33MR1. + +#17. (Version 1.33/3-Sep-96) Ron House (house@helios.usq.edu.au) + + The routine ASTBase::predorder_action omits two "tree->" + prefixes, which results in the preorder_action belonging + to the wrong node to be invoked. + + Suggested fix now in 1.33MR1. + +#16. (Version 1.33/7-Jun-96) Eli Sternheim + + Routine consumeUntilToken() does not check for end-of-file + condition. + + Suggested fix now in 1.33MR1. + +#15. (Version 1.33/8 Apr 96) Asgeir Olafsson + + Problem with tree duplication of doubly linked ASTs in ASTBase.cpp. + + Suggested fix now in 1.33MR1. + +#14. (Version 1.33/28-Feb-96) Andreas.Magnusson@mailbox.swipnet.se + + Problem with definition of operator = (const ANTLRTokenPtr rhs). + + Suggested fix now in 1.33MR1. + +#13. (Version 1.33/13-Feb-96) Franklin Chen (chen@adi.com) + + Sun C++ Compiler 3.0.1 can't compile testcpp/1 due to goto in + block with destructors. + + Apparently fixed. Can't locate "goto". + +#12. (Version 1.33/10-Nov-95) Minor problems with 1.33 code + + The following items have been fixed in 1.33MR1: + + 1. pccts/antlr/main.c line 142 + + "void" appears in classic C code + + 2. no makefile in support/genmk + + 3. EXIT_FAILURE/_SUCCESS instead of PCCTS_EXIT_FAILURE/_SUCCESS + + pccts/h/PCCTSAST.cpp + pccts/h/DLexerBase.cpp + pccts/testcpp/6/test.g + + 4. use of "signed int" isn't accepted by AT&T cfront + + pccts/h/PCCTSAST.h line 42 + + 5. in call to ANTLRParser::FAIL the var arg err_k is passed as + "int" but is declared "unsigned int". + + 6. I believe that a failed validation predicate still does not + get put in a "{...}" envelope, despite the release notes. + + 7. The #token ">>" appearing in the DLG grammar description + causes DLG to generate the string literal "\>\>" which + is non-conforming and will cause some compilers to + complain (scan.c function act10 line 143 of source code). + +#11. (Version 1.32b6) Dave Kuhlman (dkuhlman@netcom.com) + + Problem with file close in gen.c. Already fixed in 1.33. + +#10. (Version 1.32b6/29-Aug-95) + + pccts/antlr/main.c contains a C++ style comments on lines 149 + and 176 which causes problems for most C compilers. + + Already fixed in 1.33. + +#9. (Version 1.32b4/14-Mar-95) dlgauto.h #include "config.h" + + The file pccts/h/dlgauto.h should probably contain a #include + "config.h" as it uses the #define symbol __USE_PROTOS. + + Added to 1.33MR1. + +#8. (Version 1.32b4/6-Mar-95) Michael T. Richter (mtr@igs.net) + + In C++ output mode anonymous tokens from in-line regular expressions + can create enum values which are too wide for the datatype of the enum + assigned by the C++ compiler. + + Fixed in 1.33MR1. + +#7. (Version 1.32b4/6-Mar-95) C++ does not imply __STDC__ + + In err.h the combination of # directives assumes that a C++ + compiler has __STDC__ defined. This is not necessarily true. + + This problem also appears in the use of __USE_PROTOS which + is appropriate for both Standard C and C++ in antlr/gen.c + and antlr/lex.c + + Fixed in 1.33MR1. + +#6. (Version 1.32 ?/15-Feb-95) Name conflict for "TokenType" + + Already fixed in 1.33. + +#5. (23-Jan-95) Douglas_Cuthbertson.JTIDS@jtids_qmail.hanscom.af.mil + + The fail action following a semantic predicate is not enclosed in + "{...}". This can lead to problems when the fail action contains + more than one statement. + + Fixed in 1.33MR1. + +#4 . (Version 1.33/31-Mar-96) jlilley@empathy.com (John Lilley) + + Put briefly, a semantic predicate ought to abort a guess if it fails. + + Correction suggested by J. Lilley has been added to 1.33MR1. + +#3 . (Version 1.33) P.A.Keller@bath.ac.uk + + Extra commas are placed in the K&R style argument list for rules + when using both exceptions and ASTs. + + Fixed in 1.33MR1. + +#2. (Version 1.32b6/2-Oct-95) Brad Schick + + Construct #[] generates zzastnew() in C++ mode. + + Already fixed in 1.33. + +#1. (Version 1.33) Bob Bailey (robert@oakhill.sps.mot.com) + + Previously, config.h assumed that all PC systems required + "short" file names. The user can now override that + assumption with "#define LONGFILENAMES". + + Added to 1.33MR1. diff --git a/Tools/CodeTools/Source/Pccts/CHANGES_SUMMARY.txt b/Tools/CodeTools/Source/Pccts/CHANGES_SUMMARY.txt new file mode 100644 index 0000000000..91defae169 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/CHANGES_SUMMARY.txt @@ -0,0 +1,2049 @@ +====================================================================== + + CHANGES_SUMMARY.TXT + + A QUICK overview of changes from 1.33 in reverse order + + A summary of additions rather than bug fixes and minor code changes. + + Numbers refer to items in CHANGES_FROM_133*.TXT + which may contain additional information. + + DISCLAIMER + + The software and these notes are provided "as is". They may include + typographical or technical errors and their authors disclaims all + liability of any kind or nature for damages due to error, fault, + defect, or deficiency regardless of cause. All warranties of any + kind, either express or implied, including, but not limited to, the + implied warranties of merchantability and fitness for a particular + purpose are disclaimed. + +====================================================================== + +#258. You can specify a user-defined base class for your parser + + The base class must constructor must have a signature similar to + that of ANTLRParser. + +#253. Generation of block preamble (-preamble and -preamble_first) + + The antlr option -preamble causes antlr to insert the code + BLOCK_PREAMBLE at the start of each rule and block. + + The antlr option -preamble_first is similar, but inserts the + code BLOCK_PREAMBLE_FIRST(PreambleFirst_123) where the symbol + PreambleFirst_123 is equivalent to the first set defined by + the #FirstSetSymbol described in Item #248. + +#248. Generate symbol for first set of an alternative + + rr : #FirstSetSymbol(rr_FirstSet) ( Foo | Bar ) ; + +#216. Defer token fetch for C++ mode + + When the ANTLRParser class is built with the pre-processor option + ZZDEFER_FETCH defined, the fetch of new tokens by consume() is deferred + until LA(i) or LT(i) is called. + +#215. Use reset() to reset DLGLexerBase +#188. Added pccts/h/DLG_stream_input.h +#180. Added ANTLRParser::getEofToken() +#173. -glms for Microsoft style filenames with -gl +#170. Suppression for predicates with lookahead depth >1 + + Consider the following grammar with -ck 2 and the predicate in rule + "a" with depth 2: + + r1 : (ab)* "@" + ; + + ab : a + | b + ; + + a : (A B)? => <>? A B C + ; + + b : A B C + ; + + Normally, the predicate would be hoisted into rule r1 in order to + determine whether to call rule "ab". However it should *not* be + hoisted because, even if p is false, there is a valid alternative + in rule b. With "-mrhoistk on" the predicate will be suppressed. + + If "-info p" command line option is present the following information + will appear in the generated code: + + while ( (LA(1)==A) + #if 0 + + Part (or all) of predicate with depth > 1 suppressed by alternative + without predicate + + pred << p(LATEXT(2))>>? + depth=k=2 ("=>" guard) rule a line 8 t1.g + tree context: + (root = A + B + ) + + The token sequence which is suppressed: ( A B ) + The sequence of references which generate that sequence of tokens: + + 1 to ab r1/1 line 1 t1.g + 2 ab ab/1 line 4 t1.g + 3 to b ab/2 line 5 t1.g + 4 b b/1 line 11 t1.g + 5 #token A b/1 line 11 t1.g + 6 #token B b/1 line 11 t1.g + + #endif + + A slightly more complicated example: + + r1 : (ab)* "@" + ; + + ab : a + | b + ; + + a : (A B)? => <>? (A B | D E) + ; + + b : <>? D E + ; + + + In this case, the sequence (D E) in rule "a" which lies behind + the guard is used to suppress the predicate with context (D E) + in rule b. + + while ( (LA(1)==A || LA(1)==D) + #if 0 + + Part (or all) of predicate with depth > 1 suppressed by alternative + without predicate + + pred << q(LATEXT(2))>>? + depth=k=2 rule b line 11 t2.g + tree context: + (root = D + E + ) + + The token sequence which is suppressed: ( D E ) + The sequence of references which generate that sequence of tokens: + + 1 to ab r1/1 line 1 t2.g + 2 ab ab/1 line 4 t2.g + 3 to a ab/1 line 4 t2.g + 4 a a/1 line 8 t2.g + 5 #token D a/1 line 8 t2.g + 6 #token E a/1 line 8 t2.g + + #endif + && + #if 0 + + pred << p(LATEXT(2))>>? + depth=k=2 ("=>" guard) rule a line 8 t2.g + tree context: + (root = A + B + ) + + #endif + + (! ( LA(1)==A && LA(2)==B ) || p(LATEXT(2)) ) { + ab(); + ... + +#165. (Changed in MR13) option -newAST + + To create ASTs from an ANTLRTokenPtr antlr usually calls + "new AST(ANTLRTokenPtr)". This option generates a call + to "newAST(ANTLRTokenPtr)" instead. This allows a user + to define a parser member function to create an AST object. + +#161. (Changed in MR13) Switch -gxt inhibits generation of tokens.h + +#158. (Changed in MR13) #header causes problem for pre-processors + + A user who runs the C pre-processor on antlr source suggested + that another syntax be allowed. With MR13 such directives + such as #header, #pragma, etc. may be written as "\#header", + "\#pragma", etc. For escaping pre-processor directives inside + a #header use something like the following: + + \#header + << + \#include + >> + +#155. (Changed in MR13) Context behind predicates can suppress + + With -mrhoist enabled the context behind a guarded predicate can + be used to suppress other predicates. Consider the following grammar: + + r0 : (r1)+; + + r1 : rp + | rq + ; + rp : <

>? B ; + rq : (A)? => <>? (A|B); + + In earlier versions both predicates "p" and "q" would be hoisted into + rule r0. With MR12c predicate p is suppressed because the context which + follows predicate q includes "B" which can "cover" predicate "p". In + other words, in trying to decide in r0 whether to call r1, it doesn't + really matter whether p is false or true because, either way, there is + a valid choice within r1. + +#154. (Changed in MR13) Making hoist suppression explicit using <> + + A common error, even among experienced pccts users, is to code + an init-action to inhibit hoisting rather than a leading action. + An init-action does not inhibit hoisting. + + This was coded: + + rule1 : <<;>> rule2 + + This is what was meant: + + rule1 : <<;>> <<;>> rule2 + + With MR13, the user can code: + + rule1 : <<;>> <> rule2 + + The following will give an error message: + + rule1 : <> rule2 + + If the <> appears as an init-action rather than a leading + action an error message is issued. The meaning of an init-action + containing "nohoist" is unclear: does it apply to just one + alternative or to all alternatives ? + +#151a. Addition of ANTLRParser::getLexer(), ANTLRTokenStream::getLexer() + + You must manually cast the ANTLRTokenStream to your program's + lexer class. Because the name of the lexer's class is not fixed. + Thus it is impossible to incorporate it into the DLGLexerBase + class. + +#151b.(Changed in MR12) ParserBlackBox member getLexer() + +#150. (Changed in MR12) syntaxErrCount and lexErrCount now public + +#149. (Changed in MR12) antlr option -info o (letter o for orphan) + + If there is more than one rule which is not referenced by any + other rule then all such rules are listed. This is useful for + alerting one to rules which are not used, but which can still + contribute to ambiguity. + +#148. (Changed in MR11) #token names appearing in zztokens,token_tbl + + One can write: + + #token Plus ("+") "\+" + #token RP ("(") "\(" + #token COM ("comment begin") "/\*" + + The string in parenthesis will be used in syntax error messages. + +#146. (Changed in MR11) Option -treport for locating "difficult" alts + + It can be difficult to determine which alternatives are causing + pccts to work hard to resolve an ambiguity. In some cases the + ambiguity is successfully resolved after much CPU time so there + is no message at all. + + A rough measure of the amount of work being peformed which is + independent of the CPU speed and system load is the number of + tnodes created. Using "-info t" gives information about the + total number of tnodes created and the peak number of tnodes. + + Tree Nodes: peak 1300k created 1416k lost 0 + + It also puts in the generated C or C++ file the number of tnodes + created for a rule (at the end of the rule). However this + information is not sufficient to locate the alternatives within + a rule which are causing the creation of tnodes. + + Using: + + antlr -treport 100000 .... + + causes antlr to list on stdout any alternatives which require the + creation of more than 100,000 tnodes, along with the lookahead sets + for those alternatives. + + The following is a trivial case from the ansi.g grammar which shows + the format of the report. This report might be of more interest + in cases where 1,000,000 tuples were created to resolve the ambiguity. + + ------------------------------------------------------------------------- + There were 0 tuples whose ambiguity could not be resolved + by full lookahead + There were 157 tnodes created to resolve ambiguity between: + + Choice 1: statement/2 line 475 file ansi.g + Choice 2: statement/3 line 476 file ansi.g + + Intersection of lookahead[1] sets: + + IDENTIFIER + + Intersection of lookahead[2] sets: + + LPARENTHESIS COLON AMPERSAND MINUS + STAR PLUSPLUS MINUSMINUS ONESCOMPLEMENT + NOT SIZEOF OCTALINT DECIMALINT + HEXADECIMALINT FLOATONE FLOATTWO IDENTIFIER + STRING CHARACTER + ------------------------------------------------------------------------- + +#143. (Changed in MR11) Optional ";" at end of #token statement + + Fixes problem of: + + #token X "x" + + << + parser action + >> + + Being confused with: + + #token X "x" <> + +#142. (Changed in MR11) class BufFileInput subclass of DLGInputStream + + Alexey Demakov (demakov@kazbek.ispras.ru) has supplied class + BufFileInput derived from DLGInputStream which provides a + function lookahead(char *string) to test characters in the + input stream more than one character ahead. + The class is located in pccts/h/BufFileInput.* of the kit. + +#140. #pred to define predicates + + +---------------------------------------------------+ + | Note: Assume "-prc on" for this entire discussion | + +---------------------------------------------------+ + + A problem with predicates is that each one is regarded as + unique and capable of disambiguating cases where two + alternatives have identical lookahead. For example: + + rule : <>? A + | <>? A + ; + + will not cause any error messages or warnings to be issued + by earlier versions of pccts. To compare the text of the + predicates is an incomplete solution. + + In 1.33MR11 I am introducing the #pred statement in order to + solve some problems with predicates. The #pred statement allows + one to give a symbolic name to a "predicate literal" or a + "predicate expression" in order to refer to it in other predicate + expressions or in the rules of the grammar. + + The predicate literal associated with a predicate symbol is C + or C++ code which can be used to test the condition. A + predicate expression defines a predicate symbol in terms of other + predicate symbols using "!", "&&", and "||". A predicate symbol + can be defined in terms of a predicate literal, a predicate + expression, or *both*. + + When a predicate symbol is defined with both a predicate literal + and a predicate expression, the predicate literal is used to generate + code, but the predicate expression is used to check for two + alternatives with identical predicates in both alternatives. + + Here are some examples of #pred statements: + + #pred IsLabel <>? + #pred IsLocalVar <>? + #pred IsGlobalVar <>? + #pred IsVar <>? IsLocalVar || IsGlobalVar + #pred IsScoped <>? IsLabel || IsLocalVar + + I hope that the use of EBNF notation to describe the syntax of the + #pred statement will not cause problems for my readers (joke). + + predStatement : "#pred" + CapitalizedName + ( + "<>?" + | "<>?" predOrExpr + | predOrExpr + ) + ; + + predOrExpr : predAndExpr ( "||" predAndExpr ) * ; + + predAndExpr : predPrimary ( "&&" predPrimary ) * ; + + predPrimary : CapitalizedName + | "!" predPrimary + | "(" predOrExpr ")" + ; + + What is the purpose of this nonsense ? + + To understand how predicate symbols help, you need to realize that + predicate symbols are used in two different ways with two different + goals. + + a. Allow simplification of predicates which have been combined + during predicate hoisting. + + b. Allow recognition of identical predicates which can't disambiguate + alternatives with common lookahead. + + First we will discuss goal (a). Consider the following rule: + + rule0: rule1 + | ID + | ... + ; + + rule1: rule2 + | rule3 + ; + + rule2: <>? ID ; + rule3: <>? ID ; + + When the predicates in rule2 and rule3 are combined by hoisting + to create a prediction expression for rule1 the result is: + + if ( LA(1)==ID + && ( isX(LATEXT(1) || !isX(LATEXT(1) ) ) { rule1(); ... + + This is inefficient, but more importantly, can lead to false + assumptions that the predicate expression distinguishes the rule1 + alternative with some other alternative with lookahead ID. In + MR11 one can write: + + #pred IsX <>? + + ... + + rule2: <>? ID ; + rule3: <>? ID ; + + During hoisting MR11 recognizes this as a special case and + eliminates the predicates. The result is a prediction + expression like the following: + + if ( LA(1)==ID ) { rule1(); ... + + Please note that the following cases which appear to be equivalent + *cannot* be simplified by MR11 during hoisting because the hoisting + logic only checks for a "!" in the predicate action, not in the + predicate expression for a predicate symbol. + + *Not* equivalent and is not simplified during hoisting: + + #pred IsX <>? + #pred NotX <>? + ... + rule2: <>? ID ; + rule3: <>? ID ; + + *Not* equivalent and is not simplified during hoisting: + + #pred IsX <>? + #pred NotX !IsX + ... + rule2: <>? ID ; + rule3: <>? ID ; + + Now we will discuss goal (b). + + When antlr discovers that there is a lookahead ambiguity between + two alternatives it attempts to resolve the ambiguity by searching + for predicates in both alternatives. In the past any predicate + would do, even if the same one appeared in both alternatives: + + rule: <>? X + | <>? X + ; + + The #pred statement is a start towards solving this problem. + During ambiguity resolution (*not* predicate hoisting) the + predicates for the two alternatives are expanded and compared. + Consider the following example: + + #pred Upper <>? + #pred Lower <>? + #pred Alpha <>? Upper || Lower + + rule0: rule1 + | <>? ID + ; + + rule1: + | rule2 + | rule3 + ... + ; + + rule2: <>? ID; + rule3: <>? ID; + + The definition of #pred Alpha expresses: + + a. to test the predicate use the C code "isAlpha(LATEXT(1))" + + b. to analyze the predicate use the information that + Alpha is equivalent to the union of Upper and Lower, + + During ambiguity resolution the definition of Alpha is expanded + into "Upper || Lower" and compared with the predicate in the other + alternative, which is also "Upper || Lower". Because they are + identical MR11 will report a problem. + + ------------------------------------------------------------------------- + t10.g, line 5: warning: the predicates used to disambiguate rule rule0 + (file t10.g alt 1 line 5 and alt 2 line 6) + are identical when compared without context and may have no + resolving power for some lookahead sequences. + ------------------------------------------------------------------------- + + If you use the "-info p" option the output file will contain: + + +----------------------------------------------------------------------+ + |#if 0 | + | | + |The following predicates are identical when compared without | + | lookahead context information. For some ambiguous lookahead | + | sequences they may not have any power to resolve the ambiguity. | + | | + |Choice 1: rule0/1 alt 1 line 5 file t10.g | + | | + | The original predicate for choice 1 with available context | + | information: | + | | + | OR expr | + | | + | pred << Upper>>? | + | depth=k=1 rule rule2 line 14 t10.g | + | set context: | + | ID | + | | + | pred << Lower>>? | + | depth=k=1 rule rule3 line 15 t10.g | + | set context: | + | ID | + | | + | The predicate for choice 1 after expansion (but without context | + | information): | + | | + | OR expr | + | | + | pred << isUpper(LATEXT(1))>>? | + | depth=k=1 rule line 1 t10.g | + | | + | pred << isLower(LATEXT(1))>>? | + | depth=k=1 rule line 2 t10.g | + | | + | | + |Choice 2: rule0/2 alt 2 line 6 file t10.g | + | | + | The original predicate for choice 2 with available context | + | information: | + | | + | pred << Alpha>>? | + | depth=k=1 rule rule0 line 6 t10.g | + | set context: | + | ID | + | | + | The predicate for choice 2 after expansion (but without context | + | information): | + | | + | OR expr | + | | + | pred << isUpper(LATEXT(1))>>? | + | depth=k=1 rule line 1 t10.g | + | | + | pred << isLower(LATEXT(1))>>? | + | depth=k=1 rule line 2 t10.g | + | | + | | + |#endif | + +----------------------------------------------------------------------+ + + The comparison of the predicates for the two alternatives takes + place without context information, which means that in some cases + the predicates will be considered identical even though they operate + on disjoint lookahead sets. Consider: + + #pred Alpha + + rule1: <>? ID + | <>? Label + ; + + Because the comparison of predicates takes place without context + these will be considered identical. The reason for comparing + without context is that otherwise it would be necessary to re-evaluate + the entire predicate expression for each possible lookahead sequence. + This would require more code to be written and more CPU time during + grammar analysis, and it is not yet clear whether anyone will even make + use of the new #pred facility. + + A temporary workaround might be to use different #pred statements + for predicates you know have different context. This would avoid + extraneous warnings. + + The above example might be termed a "false positive". Comparison + without context will also lead to "false negatives". Consider the + following example: + + #pred Alpha + #pred Beta + + rule1: <>? A + | rule2 + ; + + rule2: <>? A + | <>? B + ; + + The predicate used for alt 2 of rule1 is (Alpha || Beta). This + appears to be different than the predicate Alpha used for alt1. + However, the context of Beta is B. Thus when the lookahead is A + Beta will have no resolving power and Alpha will be used for both + alternatives. Using the same predicate for both alternatives isn't + very helpful, but this will not be detected with 1.33MR11. + + To properly handle this the predicate expression would have to be + evaluated for each distinct lookahead context. + + To determine whether two predicate expressions are identical is + difficult. The routine may fail to identify identical predicates. + + The #pred feature also compares predicates to see if a choice between + alternatives which is resolved by a predicate which makes the second + choice unreachable. Consider the following example: + + #pred A <>? + #pred B <>? + #pred A_or_B A || B + + r : s + | t + ; + s : <>? ID + ; + t : <>? ID + ; + + ---------------------------------------------------------------------------- + t11.g, line 5: warning: the predicate used to disambiguate the + first choice of rule r + (file t11.g alt 1 line 5 and alt 2 line 6) + appears to "cover" the second predicate when compared without context. + The second predicate may have no resolving power for some lookahead + sequences. + ---------------------------------------------------------------------------- + +#132. (Changed in 1.33MR11) Recognition of identical predicates in alts + + Prior to 1.33MR11, there would be no ambiguity warning when the + very same predicate was used to disambiguate both alternatives: + + test: ref B + | ref C + ; + + ref : <>? A + + In 1.33MR11 this will cause the warning: + + warning: the predicates used to disambiguate rule test + (file v98.g alt 1 line 1 and alt 2 line 2) + are identical and have no resolving power + + ----------------- Note ----------------- + + This is different than the following case + + test: <>? A B + | <>? A C + ; + + In this case there are two distinct predicates + which have exactly the same text. In the first + example there are two references to the same + predicate. The problem represented by this + grammar will be addressed later. + + +#127. (Changed in 1.33MR11) + + Count Syntax Errors Count DLG Errors + ------------------- ---------------- + + C++ mode ANTLRParser:: DLGLexerBase:: + syntaxErrCount lexErrCount + C mode zzSyntaxErrCount zzLexErrCount + + The C mode variables are global and initialized to 0. + They are *not* reset to 0 automatically when antlr is + restarted. + + The C++ mode variables are public. They are initialized + to 0 by the constructors. They are *not* reset to 0 by the + ANTLRParser::init() method. + + Suggested by Reinier van den Born (reinier@vnet.ibm.com). + +#126. (Changed in 1.33MR11) Addition of #first <<...>> + + The #first <<...>> inserts the specified text in the output + files before any other #include statements required by pccts. + The only things before the #first text are comments and + a #define ANTLR_VERSION. + + Requested by and Esa Pulkkinen (esap@cs.tut.fi) and Alexin + Zoltan (alexin@inf.u-szeged.hu). + +#124. A Note on the New "&&" Style Guarded Predicates + + I've been asked several times, "What is the difference between + the old "=>" style guard predicates and the new style "&&" guard + predicates, and how do you choose one over the other" ? + + The main difference is that the "=>" does not apply the + predicate if the context guard doesn't match, whereas + the && form always does. What is the significance ? + + If you have a predicate which is not on the "leading edge" + it is cannot be hoisted. Suppose you need a predicate that + looks at LA(2). You must introduce it manually. The + classic example is: + + castExpr : + LP typeName RP + | .... + ; + + typeName : <>? ID + | STRUCT ID + ; + + The problem is that isTypeName() isn't on the leading edge + of typeName, so it won't be hoisted into castExpr to help + make a decision on which production to choose. + + The *first* attempt to fix it is this: + + castExpr : + <>? + LP typeName RP + | .... + ; + + Unfortunately, this won't work because it ignores + the problem of STRUCT. The solution is to apply + isTypeName() in castExpr if LA(2) is an ID and + don't apply it when LA(2) is STRUCT: + + castExpr : + (LP ID)? => <>? + LP typeName RP + | .... + ; + + In conclusion, the "=>" style guarded predicate is + useful when: + + a. the tokens required for the predicate + are not on the leading edge + b. there are alternatives in the expression + selected by the predicate for which the + predicate is inappropriate + + If (b) were false, then one could use a simple + predicate (assuming "-prc on"): + + castExpr : + <>? + LP typeName RP + | .... + ; + + typeName : <>? ID + ; + + So, when do you use the "&&" style guarded predicate ? + + The new-style "&&" predicate should always be used with + predicate context. The context guard is in ADDITION to + the automatically computed context. Thus it useful for + predicates which depend on the token type for reasons + other than context. + + The following example is contributed by Reinier van den Born + (reinier@vnet.ibm.com). + + +-------------------------------------------------------------------------+ + | This grammar has two ways to call functions: | + | | + | - a "standard" call syntax with parens and comma separated args | + | - a shell command like syntax (no parens and spacing separated args) | + | | + | The former also allows a variable to hold the name of the function, | + | the latter can also be used to call external commands. | + | | + | The grammar (simplified) looks like this: | + | | + | fun_call : ID "(" { expr ("," expr)* } ")" | + | /* ID is function name */ | + | | "@" ID "(" { expr ("," expr)* } ")" | + | /* ID is var containing fun name */ | + | ; | + | | + | command : ID expr* /* ID is function name */ | + | | path expr* /* path is external command name */ | + | ; | + | | + | path : ID /* left out slashes and such */ | + | | "@" ID /* ID is environment var */ | + | ; | + | | + | expr : .... | + | | "(" expr ")"; | + | | + | call : fun_call | + | | command | + | ; | + | | + | Obviously the call is wildly ambiguous. This is more or less how this | + | is to be resolved: | + | | + | A call begins with an ID or an @ followed by an ID. | + | | + | If it is an ID and if it is an ext. command name -> command | + | if followed by a paren -> fun_call | + | otherwise -> command | + | | + | If it is an @ and if the ID is a var name -> fun_call | + | otherwise -> command | + | | + | One can implement these rules quite neatly using && predicates: | + | | + | call : ("@" ID)? && <>? fun_call | + | | (ID)? && <>? command | + | | (ID "(")? fun_call | + | | command | + | ; | + | | + | This can be done better, so it is not an ideal example, but it | + | conveys the principle. | + +-------------------------------------------------------------------------+ + +#122. (Changed in 1.33MR11) Member functions to reset DLG in C++ mode + + void DLGFileReset(FILE *f) { input = f; found_eof = 0; } + void DLGStringReset(DLGChar *s) { input = s; p = &input[0]; } + + Supplied by R.A. Nelson (cowboy@VNET.IBM.COM) + +#119. (Changed in 1.33MR11) Ambiguity aid for grammars + + The user can ask for additional information on ambiguities reported + by antlr to stdout. At the moment, only one ambiguity report can + be created in an antlr run. + + This feature is enabled using the "-aa" (Ambiguity Aid) option. + + The following options control the reporting of ambiguities: + + -aa ruleName Selects reporting by name of rule + -aa lineNumber Selects reporting by line number + (file name not compared) + + -aam Selects "multiple" reporting for a token + in the intersection set of the + alternatives. + + For instance, the token ID may appear dozens + of times in various paths as the program + explores the rules which are reachable from + the point of an ambiguity. With option -aam + every possible path the search program + encounters is reported. + + Without -aam only the first encounter is + reported. This may result in incomplete + information, but the information may be + sufficient and much shorter. + + -aad depth Selects the depth of the search. + The default value is 1. + + The number of paths to be searched, and the + size of the report can grow geometrically + with the -ck value if a full search for all + contributions to the source of the ambiguity + is explored. + + The depth represents the number of tokens + in the lookahead set which are matched against + the set of ambiguous tokens. A depth of 1 + means that the search stops when a lookahead + sequence of just one token is matched. + + A k=1 ck=6 grammar might generate 5,000 items + in a report if a full depth 6 search is made + with the Ambiguity Aid. The source of the + problem may be in the first token and obscured + by the volume of data - I hesitate to call + it information. + + When the user selects a depth > 1, the search + is first performed at depth=1 for both + alternatives, then depth=2 for both alternatives, + etc. + + Sample output for rule grammar in antlr.g itself: + + +---------------------------------------------------------------------+ + | Ambiguity Aid | + | | + | Choice 1: grammar/70 line 632 file a.g | + | Choice 2: grammar/82 line 644 file a.g | + | | + | Intersection of lookahead[1] sets: | + | | + | "\}" "class" "#errclass" "#tokclass" | + | | + | Choice:1 Depth:1 Group:1 ("#errclass") | + | 1 in (...)* block grammar/70 line 632 a.g | + | 2 to error grammar/73 line 635 a.g | + | 3 error error/1 line 894 a.g | + | 4 #token "#errclass" error/2 line 895 a.g | + | | + | Choice:1 Depth:1 Group:2 ("#tokclass") | + | 2 to tclass grammar/74 line 636 a.g | + | 3 tclass tclass/1 line 937 a.g | + | 4 #token "#tokclass" tclass/2 line 938 a.g | + | | + | Choice:1 Depth:1 Group:3 ("class") | + | 2 to class_def grammar/75 line 637 a.g | + | 3 class_def class_def/1 line 669 a.g | + | 4 #token "class" class_def/3 line 671 a.g | + | | + | Choice:1 Depth:1 Group:4 ("\}") | + | 2 #token "\}" grammar/76 line 638 a.g | + | | + | Choice:2 Depth:1 Group:5 ("#errclass") | + | 1 in (...)* block grammar/83 line 645 a.g | + | 2 to error grammar/93 line 655 a.g | + | 3 error error/1 line 894 a.g | + | 4 #token "#errclass" error/2 line 895 a.g | + | | + | Choice:2 Depth:1 Group:6 ("#tokclass") | + | 2 to tclass grammar/94 line 656 a.g | + | 3 tclass tclass/1 line 937 a.g | + | 4 #token "#tokclass" tclass/2 line 938 a.g | + | | + | Choice:2 Depth:1 Group:7 ("class") | + | 2 to class_def grammar/95 line 657 a.g | + | 3 class_def class_def/1 line 669 a.g | + | 4 #token "class" class_def/3 line 671 a.g | + | | + | Choice:2 Depth:1 Group:8 ("\}") | + | 2 #token "\}" grammar/96 line 658 a.g | + +---------------------------------------------------------------------+ + + For a linear lookahead set ambiguity (where k=1 or for k>1 but + when all lookahead sets [i] with i>? A ; + c : A ; + + Prior to 1.33MR10 the code generated for "start" would resemble: + + while { + if (LA(1)==A && + (!LA(1)==A || isUpper())) { + a(); + } + }; + + This code is wrong because it makes rule "c" unreachable from + "start". The essence of the problem is that antlr fails to + recognize that there can be a valid alternative within "a" even + when the predicate <>? is false. + + In 1.33MR10 with -mrhoist the hoisting of the predicate into + "start" is suppressed because it recognizes that "c" can + cover all the cases where the predicate is false: + + while { + if (LA(1)==A) { + a(); + } + }; + + With the antlr "-info p" switch the user will receive information + about the predicate suppression in the generated file: + + -------------------------------------------------------------- + #if 0 + + Hoisting of predicate suppressed by alternative without predicate. + The alt without the predicate includes all cases where + the predicate is false. + + WITH predicate: line 7 v1.g + WITHOUT predicate: line 7 v1.g + + The context set for the predicate: + + A + + The lookahead set for the alt WITHOUT the semantic predicate: + + A + + The predicate: + + pred << isUpper(LATEXT(1))>>? + depth=k=1 rule b line 9 v1.g + set context: + A + tree context: null + + Chain of referenced rules: + + #0 in rule start (line 5 v1.g) to rule a + #1 in rule a (line 7 v1.g) + + #endif + -------------------------------------------------------------- + + A predicate can be suppressed by a combination of alternatives + which, taken together, cover a predicate: + + start : (a)* "@" ; + + a : b | ca | cb | cc ; + + b : <>? ( A | B | C ) ; + + ca : A ; + cb : B ; + cc : C ; + + Consider a more complex example in which "c" covers only part of + a predicate: + + start : (a)* "@" ; + + a : b + | c + ; + + b : <>? + ( A + | X + ); + + c : A + ; + + Prior to 1.33MR10 the code generated for "start" would resemble: + + while { + if ( (LA(1)==A || LA(1)==X) && + (! (LA(1)==A || LA(1)==X) || isUpper()) { + a(); + } + }; + + With 1.33MR10 and -mrhoist the predicate context is restricted to + the non-covered lookahead. The code resembles: + + while { + if ( (LA(1)==A || LA(1)==X) && + (! (LA(1)==X) || isUpper()) { + a(); + } + }; + + With the antlr "-info p" switch the user will receive information + about the predicate restriction in the generated file: + + -------------------------------------------------------------- + #if 0 + + Restricting the context of a predicate because of overlap + in the lookahead set between the alternative with the + semantic predicate and one without + Without this restriction the alternative without the predicate + could not be reached when input matched the context of the + predicate and the predicate was false. + + WITH predicate: line 11 v4.g + WITHOUT predicate: line 12 v4.g + + The original context set for the predicate: + + A X + + The lookahead set for the alt WITHOUT the semantic predicate: + + A + + The intersection of the two sets + + A + + The original predicate: + + pred << isUpper(LATEXT(1))>>? + depth=k=1 rule b line 15 v4.g + set context: + A X + tree context: null + + The new (modified) form of the predicate: + + pred << isUpper(LATEXT(1))>>? + depth=k=1 rule b line 15 v4.g + set context: + X + tree context: null + + #endif + -------------------------------------------------------------- + + The bad news about -mrhoist: + + (a) -mrhoist does not analyze predicates with lookahead + depth > 1. + + (b) -mrhoist does not look past a guarded predicate to + find context which might cover other predicates. + + For these cases you might want to use syntactic predicates. + When a semantic predicate fails during guess mode the guess + fails and the next alternative is tried. + + Limitation (a) is illustrated by the following example: + + start : (stmt)* EOF ; + + stmt : cast + | expr + ; + cast : <>? LP ID RP ; + + expr : LP ID RP ; + + This is not much different from the first example, except that + it requires two tokens of lookahead context to determine what + to do. This predicate is NOT suppressed because the current version + is unable to handle predicates with depth > 1. + + A predicate can be combined with other predicates during hoisting. + In those cases the depth=1 predicates are still handled. Thus, + in the following example the isUpper() predicate will be suppressed + by line #4 when hoisted from "bizarre" into "start", but will still + be present in "bizarre" in order to predict "stmt". + + start : (bizarre)* EOF ; // #1 + // #2 + bizarre : stmt // #3 + | A // #4 + ; + + stmt : cast + | expr + ; + + cast : <>? LP ID RP ; + + expr : LP ID RP ; + | <>? A + + Limitation (b) is illustrated by the following example of a + context guarded predicate: + + rule : (A)? <

>? // #1 + (A // #2 + |B // #3 + ) // #4 + | <> B // #5 + ; + + Recall that this means that when the lookahead is NOT A then + the predicate "p" is ignored and it attempts to match "A|B". + Ideally, the "B" at line #3 should suppress predicate "q". + However, the current version does not attempt to look past + the guard predicate to find context which might suppress other + predicates. + + In some cases -mrhoist will lead to the reporting of ambiguities + which were not visible before: + + start : (a)* "@"; + a : bc | d; + bc : b | c ; + + b : <>? A; + c : A ; + + d : A ; + + In this case there is a true ambiguity in "a" between "bc" and "d" + which can both match "A". Without -mrhoist the predicate in "b" + is hoisted into "a" and there is no ambiguity reported. However, + with -mrhoist, the predicate in "b" is suppressed by "c" (as it + should be) making the ambiguity in "a" apparent. + + The motivations for these changes were hoisting problems reported + by Reinier van den Born (reinier@vnet.ibm.com) and several others. + +#113. (Changed in 1.33MR10) new context guarded pred: (g)? && <

>? expr + + The existing context guarded predicate: + + rule : (guard)? => <

>? expr + | next_alternative + ; + + generates code which resembles: + + if (lookahead(expr) && (!guard || pred)) { + expr() + } else .... + + This is not suitable for some applications because it allows + expr() to be invoked when the predicate is false. This is + intentional because it is meant to mimic automatically computed + predicate context. + + The new context guarded predicate uses the guard information + differently because it has a different goal. Consider: + + rule : (guard)? && <

>? expr + | next_alternative + ; + + The new style of context guarded predicate is equivalent to: + + rule : <>? expr + | next_alternative + ; + + It generates code which resembles: + + if (lookahead(expr) && guard && pred) { + expr(); + } else ... + + Both forms of guarded predicates severely restrict the form of + the context guard: it can contain no rule references, no + (...)*, no (...)+, and no {...}. It may contain token and + token class references, and alternation ("|"). + + Addition for 1.33MR11: in the token expression all tokens must + be at the same height of the token tree: + + (A ( B | C))? && ... is ok (all height 2) + (A ( B | ))? && ... is not ok (some 1, some 2) + (A B C D | E F G H)? && ... is ok (all height 4) + (A B C D | E )? && ... is not ok (some 4, some 1) + + This restriction is required in order to properly compute the lookahead + set for expressions like: + + rule1 : (A B C)? && <>? rule2 ; + rule2 : (A|X) (B|Y) (C|Z); + + This addition was suggested by Rienier van den Born (reinier@vnet.ibm.com) + +#109. (Changed in 1.33MR10) improved trace information + + The quality of the trace information provided by the "-gd" + switch has been improved significantly. Here is an example + of the output from a test program. It shows the rule name, + the first token of lookahead, the call depth, and the guess + status: + + exit rule gusxx {"?"} depth 2 + enter rule gusxx {"?"} depth 2 + enter rule gus1 {"o"} depth 3 guessing + guess done - returning to rule gus1 {"o"} at depth 3 + (guess mode continues - an enclosing guess is still active) + guess done - returning to rule gus1 {"Z"} at depth 3 + (guess mode continues - an enclosing guess is still active) + exit rule gus1 {"Z"} depth 3 guessing + guess done - returning to rule gusxx {"o"} at depth 2 (guess mode ends) + enter rule gus1 {"o"} depth 3 + guess done - returning to rule gus1 {"o"} at depth 3 (guess mode ends) + guess done - returning to rule gus1 {"Z"} at depth 3 (guess mode ends) + exit rule gus1 {"Z"} depth 3 + line 1: syntax error at "Z" missing SC + ... + + Rule trace reporting is controlled by the value of the integer + [zz]traceOptionValue: when it is positive tracing is enabled, + otherwise it is disabled. Tracing during guess mode is controlled + by the value of the integer [zz]traceGuessOptionValue. When + it is positive AND [zz]traceOptionValue is positive rule trace + is reported in guess mode. + + The values of [zz]traceOptionValue and [zz]traceGuessOptionValue + can be adjusted by subroutine calls listed below. + + Depending on the presence or absence of the antlr -gd switch + the variable [zz]traceOptionValueDefault is set to 0 or 1. When + the parser is initialized or [zz]traceReset() is called the + value of [zz]traceOptionValueDefault is copied to [zz]traceOptionValue. + The value of [zz]traceGuessOptionValue is always initialzed to 1, + but, as noted earlier, nothing will be reported unless + [zz]traceOptionValue is also positive. + + When the parser state is saved/restored the value of the trace + variables are also saved/restored. If a restore causes a change in + reporting behavior from on to off or vice versa this will be reported. + + When the -gd option is selected, the macro "#define zzTRACE_RULES" + is added to appropriate output files. + + C++ mode + -------- + int traceOption(int delta) + int traceGuessOption(int delta) + void traceReset() + int traceOptionValueDefault + + C mode + -------- + int zzTraceOption(int delta) + int zzTraceGuessOption(int delta) + void zzTraceReset() + int zzTraceOptionValueDefault + + The argument "delta" is added to the traceOptionValue. To + turn on trace when inside a particular rule one: + + rule : <> + ( + rest-of-rule + ) + <> + ; /* fail clause */ <> + + One can use the same idea to turn *off* tracing within a + rule by using a delta of (-1). + + An improvement in the rule trace was suggested by Sramji + Ramanathan (ps@kumaran.com). + +#108. A Note on Deallocation of Variables Allocated in Guess Mode + + NOTE + ------------------------------------------------------ + This mechanism only works for heap allocated variables + ------------------------------------------------------ + + The rewrite of the trace provides the machinery necessary + to properly free variables or undo actions following a + failed guess. + + The macro zzUSER_GUESS_HOOK(guessSeq,zzrv) is expanded + as part of the zzGUESS macro. When a guess is opened + the value of zzrv is 0. When a longjmp() is executed to + undo the guess, the value of zzrv will be 1. + + The macro zzUSER_GUESS_DONE_HOOK(guessSeq) is expanded + as part of the zzGUESS_DONE macro. This is executed + whether the guess succeeds or fails as part of closing + the guess. + + The guessSeq is a sequence number which is assigned to each + guess and is incremented by 1 for each guess which becomes + active. It is needed by the user to associate the start of + a guess with the failure and/or completion (closing) of a + guess. + + Guesses are nested. They must be closed in the reverse + of the order that they are opened. + + In order to free memory used by a variable during a guess + a user must write a routine which can be called to + register the variable along with the current guess sequence + number provided by the zzUSER_GUESS_HOOK macro. If the guess + fails, all variables tagged with the corresponding guess + sequence number should be released. This is ugly, but + it would require a major rewrite of antlr 1.33 to use + some mechanism other than setjmp()/longjmp(). + + The order of calls for a *successful* guess would be: + + zzUSER_GUESS_HOOK(guessSeq,0); + zzUSER_GUESS_DONE_HOOK(guessSeq); + + The order of calls for a *failed* guess would be: + + zzUSER_GUESS_HOOK(guessSeq,0); + zzUSER_GUESS_HOOK(guessSeq,1); + zzUSER_GUESS_DONE_HOOK(guessSeq); + + The default definitions of these macros are empty strings. + + Here is an example in C++ mode. The zzUSER_GUESS_HOOK and + zzUSER_GUESS_DONE_HOOK macros and myGuessHook() routine + can be used without change in both C and C++ versions. + + ---------------------------------------------------------------------- + << + + #include "AToken.h" + + typedef ANTLRCommonToken ANTLRToken; + + #include "DLGLexer.h" + + int main() { + + { + DLGFileInput in(stdin); + DLGLexer lexer(&in,2000); + ANTLRTokenBuffer pipe(&lexer,1); + ANTLRCommonToken aToken; + P parser(&pipe); + + lexer.setToken(&aToken); + parser.init(); + parser.start(); + }; + + fclose(stdin); + fclose(stdout); + return 0; + } + + >> + + << + char *s=NULL; + + #undef zzUSER_GUESS_HOOK + #define zzUSER_GUESS_HOOK(guessSeq,zzrv) myGuessHook(guessSeq,zzrv); + #undef zzUSER_GUESS_DONE_HOOK + #define zzUSER_GUESS_DONE_HOOK(guessSeq) myGuessHook(guessSeq,2); + + void myGuessHook(int guessSeq,int zzrv) { + if (zzrv == 0) { + fprintf(stderr,"User hook: starting guess #%d\n",guessSeq); + } else if (zzrv == 1) { + free (s); + s=NULL; + fprintf(stderr,"User hook: failed guess #%d\n",guessSeq); + } else if (zzrv == 2) { + free (s); + s=NULL; + fprintf(stderr,"User hook: ending guess #%d\n",guessSeq); + }; + } + + >> + + #token A "a" + #token "[\t \ \n]" <> + + class P { + + start : (top)+ + ; + + top : (which) ? <> + | other <> + ; <> + + which : which2 + ; + + which2 : which3 + ; + which3 + : (label)? <> + | (global)? <> + | (exclamation)? <> + ; + + label : <getText());>> A ":" ; + + global : <getText());>> A "::" ; + + exclamation : <getText());>> A "!" ; + + other : <getText());>> "other" ; + + } + ---------------------------------------------------------------------- + + This is a silly example, but illustrates the idea. For the input + "a ::" with tracing enabled the output begins: + + ---------------------------------------------------------------------- + enter rule "start" depth 1 + enter rule "top" depth 2 + User hook: starting guess #1 + enter rule "which" depth 3 guessing + enter rule "which2" depth 4 guessing + enter rule "which3" depth 5 guessing + User hook: starting guess #2 + enter rule "label" depth 6 guessing + guess failed + User hook: failed guess #2 + guess done - returning to rule "which3" at depth 5 (guess mode continues + - an enclosing guess is still active) + User hook: ending guess #2 + User hook: starting guess #3 + enter rule "global" depth 6 guessing + exit rule "global" depth 6 guessing + guess done - returning to rule "which3" at depth 5 (guess mode continues + - an enclosing guess is still active) + User hook: ending guess #3 + enter rule "global" depth 6 guessing + exit rule "global" depth 6 guessing + exit rule "which3" depth 5 guessing + exit rule "which2" depth 4 guessing + exit rule "which" depth 3 guessing + guess done - returning to rule "top" at depth 2 (guess mode ends) + User hook: ending guess #1 + enter rule "which" depth 3 + ..... + ---------------------------------------------------------------------- + + Remember: + + (a) Only init-actions are executed during guess mode. + (b) A rule can be invoked multiple times during guess mode. + (c) If the guess succeeds the rule will be called once more + without guess mode so that normal actions will be executed. + This means that the init-action might need to distinguish + between guess mode and non-guess mode using the variable + [zz]guessing. + +#101. (Changed in 1.33MR10) antlr -info command line switch + + -info + + p - extra predicate information in generated file + + t - information about tnode use: + at the end of each rule in generated file + summary on stderr at end of program + + m - monitor progress + prints name of each rule as it is started + flushes output at start of each rule + + f - first/follow set information to stdout + + 0 - no operation (added in 1.33MR11) + + The options may be combined and may appear in any order. + For example: + + antlr -info ptm -CC -gt -mrhoist on mygrammar.g + +#100a. (Changed in 1.33MR10) Predicate tree simplification + + When the same predicates can be referenced in more than one + alternative of a block large predicate trees can be formed. + + The difference that these optimizations make is so dramatic + that I have decided to use it even when -mrhoist is not selected. + + Consider the following grammar: + + start : ( all )* ; + + all : a + | d + | e + | f + ; + + a : c A B + | c A C + ; + + c : <>? + ; + + d : <>? B C + ; + + e : <>? B C + ; + + f : e X Y + ; + + In rule "a" there is a reference to rule "c" in both alternatives. + The length of the predicate AAA is k=2 and it can be followed in + alternative 1 only by (A B) while in alternative 2 it can be + followed only by (A C). Thus they do not have identical context. + + In rule "all" the alternatives which refer to rules "e" and "f" allow + elimination of the duplicate reference to predicate CCC. + + The table below summarized the kind of simplification performed by + 1.33MR10. In the table, X and Y stand for single predicates + (not trees). + + (OR X (OR Y (OR Z))) => (OR X Y Z) + (AND X (AND Y (AND Z))) => (AND X Y Z) + + (OR X (... (OR X Y) ... )) => (OR X (... Y ... )) + (AND X (... (AND X Y) ... )) => (AND X (... Y ... )) + (OR X (... (AND X Y) ... )) => (OR X (... ... )) + (AND X (... (OR X Y) ... )) => (AND X (... ... )) + + (AND X) => X + (OR X) => X + + In a test with a complex grammar for a real application, a predicate + tree with six OR nodes and 12 leaves was reduced to "(OR X Y Z)". + + In 1.33MR10 there is a greater effort to release memory used + by predicates once they are no longer in use. + +#100b. (Changed in 1.33MR10) Suppression of extra predicate tests + + The following optimizations require that -mrhoist be selected. + + It is relatively easy to optimize the code generated for predicate + gates when they are of the form: + + (AND X Y Z ...) + or (OR X Y Z ...) + + where X, Y, Z, and "..." represent individual predicates (leaves) not + predicate trees. + + If the predicate is an AND the contexts of the X, Y, Z, etc. are + ANDed together to create a single Tree context for the group and + context tests for the individual predicates are suppressed: + + -------------------------------------------------- + Note: This was incorrect. The contexts should be + ORed together. This has been fixed. A more + complete description is available in item #152. + --------------------------------------------------- + + Optimization 1: (AND X Y Z ...) + + Suppose the context for Xtest is LA(1)==LP and the context for + Ytest is LA(1)==LP && LA(2)==ID. + + Without the optimization the code would resemble: + + if (lookaheadContext && + !(LA(1)==LP && LA(1)==LP && LA(2)==ID) || + ( (! LA(1)==LP || Xtest) && + (! (LA(1)==LP || LA(2)==ID) || Xtest) + )) {... + + With the -mrhoist optimization the code would resemble: + + if (lookaheadContext && + ! (LA(1)==LP && LA(2)==ID) || (Xtest && Ytest) {... + + Optimization 2: (OR X Y Z ...) with identical contexts + + Suppose the context for Xtest is LA(1)==ID and for Ytest + the context is also LA(1)==ID. + + Without the optimization the code would resemble: + + if (lookaheadContext && + ! (LA(1)==ID || LA(1)==ID) || + (LA(1)==ID && Xtest) || + (LA(1)==ID && Ytest) {... + + With the -mrhoist optimization the code would resemble: + + if (lookaheadContext && + (! LA(1)==ID) || (Xtest || Ytest) {... + + Optimization 3: (OR X Y Z ...) with distinct contexts + + Suppose the context for Xtest is LA(1)==ID and for Ytest + the context is LA(1)==LP. + + Without the optimization the code would resemble: + + if (lookaheadContext && + ! (LA(1)==ID || LA(1)==LP) || + (LA(1)==ID && Xtest) || + (LA(1)==LP && Ytest) {... + + With the -mrhoist optimization the code would resemble: + + if (lookaheadContext && + (zzpf=0, + (LA(1)==ID && (zzpf=1) && Xtest) || + (LA(1)==LP && (zzpf=1) && Ytest) || + !zzpf) { + + These may appear to be of similar complexity at first, + but the non-optimized version contains two tests of each + context while the optimized version contains only one + such test, as well as eliminating some of the inverted + logic (" !(...) || "). + + Optimization 4: Computation of predicate gate trees + + When generating code for the gates of predicate expressions + antlr 1.33 vanilla uses a recursive procedure to generate + "&&" and "||" expressions for testing the lookahead. As each + layer of the predicate tree is exposed a new set of "&&" and + "||" expressions on the lookahead are generated. In many + cases the lookahead being tested has already been tested. + + With -mrhoist a lookahead tree is computed for the entire + lookahead expression. This means that predicates with identical + context or context which is a subset of another predicate's + context disappear. + + This is especially important for predicates formed by rules + like the following: + + uppperCaseVowel : <>? vowel; + vowel: : <>? LETTERS; + + These predicates are combined using AND since both must be + satisfied for rule upperCaseVowel. They have identical + context which makes this optimization very effective. + + The affect of Items #100a and #100b together can be dramatic. In + a very large (but real world) grammar one particular predicate + expression was reduced from an (unreadable) 50 predicate leaves, + 195 LA(1) terms, and 5500 characters to an (easily comprehensible) + 3 predicate leaves (all different) and a *single* LA(1) term. + +#98. (Changed in 1.33MR10) Option "-info p" + + When the user selects option "-info p" the program will generate + detailed information about predicates. If the user selects + "-mrhoist on" additional detail will be provided explaining + the promotion and suppression of predicates. The output is part + of the generated file and sandwiched between #if 0/#endif statements. + + Consider the following k=1 grammar: + + start : ( all ) * ; + + all : ( a + | b + ) + ; + + a : c B + ; + + c : <>? + | B + ; + + b : <>? X + ; + + Below is an excerpt of the output for rule "start" for the three + predicate options (off, on, and maintenance release style hoisting). + + For those who do not wish to use the "-mrhoist on" option for code + generation the option can be used in a "diagnostic" mode to provide + valuable information: + + a. where one should insert null actions to inhibit hoisting + b. a chain of rule references which shows where predicates are + being hoisted + + ====================================================================== + Example of "-info p" with "-mrhoist on" + ====================================================================== + #if 0 + + Hoisting of predicate suppressed by alternative without predicate. + The alt without the predicate includes all cases where the + predicate is false. + + WITH predicate: line 11 v36.g + WITHOUT predicate: line 12 v36.g + + The context set for the predicate: + + B + + The lookahead set for alt WITHOUT the semantic predicate: + + B + + The predicate: + + pred << LATEXT(1)>>? depth=k=1 rule c line 11 v36.g + + set context: + B + tree context: null + + Chain of referenced rules: + + #0 in rule start (line 1 v36.g) to rule all + #1 in rule all (line 3 v36.g) to rule a + #2 in rule a (line 8 v36.g) to rule c + #3 in rule c (line 11 v36.g) + + #endif + && + #if 0 + + pred << LATEXT(1)>>? depth=k=1 rule b line 15 v36.g + + set context: + X + tree context: null + + #endif + ====================================================================== + Example of "-info p" with the default -prc setting ( "-prc off") + ====================================================================== + #if 0 + + OR + pred << LATEXT(1)>>? depth=k=1 rule c line 11 v36.g + + set context: + nil + tree context: null + + pred << LATEXT(1)>>? depth=k=1 rule b line 15 v36.g + + set context: + nil + tree context: null + + #endif + ====================================================================== + Example of "-info p" with "-prc on" and "-mrhoist off" + ====================================================================== + #if 0 + + OR + pred << LATEXT(1)>>? depth=k=1 rule c line 11 v36.g + + set context: + B + tree context: null + + pred << LATEXT(1)>>? depth=k=1 rule b line 15 v36.g + + set context: + X + tree context: null + + #endif + ====================================================================== + +#60. (Changed in 1.33MR7) Major changes to exception handling + + There were significant problems in the handling of exceptions + in 1.33 vanilla. The general problem is that it can only + process one level of exception handler. For example, a named + exception handler, an exception handler for an alternative, or + an exception for a subrule always went to the rule's exception + handler if there was no "catch" which matched the exception. + + In 1.33MR7 the exception handlers properly "nest". If an + exception handler does not have a matching "catch" then the + nextmost outer exception handler is checked for an appropriate + "catch" clause, and so on until an exception handler with an + appropriate "catch" is found. + + There are still undesirable features in the way exception + handlers are implemented, but I do not have time to fix them + at the moment: + + The exception handlers for alternatives are outside the + block containing the alternative. This makes it impossible + to access variables declared in a block or to resume the + parse by "falling through". The parse can still be easily + resumed in other ways, but not in the most natural fashion. + + This results in an inconsistentcy between named exception + handlers and exception handlers for alternatives. When + an exception handler for an alternative "falls through" + it goes to the nextmost outer handler - not the "normal + action". + + A major difference between 1.33MR7 and 1.33 vanilla is + the default action after an exception is caught: + + 1.33 Vanilla + ------------ + In 1.33 vanilla the signal value is set to zero ("NoSignal") + and the code drops through to the code following the exception. + For named exception handlers this is the "normal action". + For alternative exception handlers this is the rule's handler. + + 1.33MR7 + ------- + In 1.33MR7 the signal value is NOT automatically set to zero. + + There are two cases: + + For named exception handlers: if the signal value has been + set to zero the code drops through to the "normal action". + + For all other cases the code branches to the nextmost outer + exception handler until it reaches the handler for the rule. + + The following macros have been defined for convenience: + + C/C++ Mode Name + -------------------- + (zz)suppressSignal + set signal & return signal arg to 0 ("NoSignal") + (zz)setSignal(intValue) + set signal & return signal arg to some value + (zz)exportSignal + copy the signal value to the return signal arg + + I'm not sure why PCCTS make a distinction between the local + signal value and the return signal argument, but I'm loathe + to change the code. The burden of copying the local signal + value to the return signal argument can be given to the + default signal handler, I suppose. + +#53. (Explanation for 1.33MR6) What happens after an exception is caught ? + + The Book is silent about what happens after an exception + is caught. + + The following code fragment prints "Error Action" followed + by "Normal Action". + + test : Word ex:Number <> + exception[ex] + catch NoViableAlt: + <> + ; + + The reason for "Normal Action" is that the normal flow of the + program after a user-written exception handler is to "drop through". + In the case of an exception handler for a rule this results in + the exection of a "return" statement. In the case of an + exception handler attached to an alternative, rule, or token + this is the code that would have executed had there been no + exception. + + The user can achieve the desired result by using a "return" + statement. + + test : Word ex:Number <> + exception[ex] + catch NoViableAlt: + <> + ; + + The most powerful mechanism for recovery from parse errors + in pccts is syntactic predicates because they provide + backtracking. Exceptions allow "return", "break", + "consumeUntil(...)", "goto _handler", "goto _fail", and + changing the _signal value. + +#41. (Added in 1.33MR6) antlr -stdout + + Using "antlr -stdout ..." forces the text that would + normally go to the grammar.c or grammar.cpp file to + stdout. + +#40. (Added in 1.33MR6) antlr -tab to change tab stops + + Using "antlr -tab number ..." changes the tab stops + for the grammar.c or grammar.cpp file. The number + must be between 0 and 8. Using 0 gives tab characters, + values between 1 and 8 give the appropriate number of + space characters. + +#34. (Added to 1.33MR1) Add public DLGLexerBase::set_line(int newValue) + + Previously there was no public function for changing the line + number maintained by the lexer. + +#28. (Added to 1.33MR1) More control over DLG header + + Version 1.33MR1 adds the following directives to PCCTS + for C++ mode: + + #lexprefix <> + + Adds source code to the DLGLexer.h file + after the #include "DLexerBase.h" but + before the start of the class definition. + + #lexmember <> + + Adds source code to the DLGLexer.h file + as part of the DLGLexer class body. It + appears immediately after the start of + the class and a "public: statement. + diff --git a/Tools/CodeTools/Source/Pccts/KNOWN_PROBLEMS.txt b/Tools/CodeTools/Source/Pccts/KNOWN_PROBLEMS.txt new file mode 100644 index 0000000000..5a9b22e1bd --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/KNOWN_PROBLEMS.txt @@ -0,0 +1,241 @@ + + ======================================================= + Known Problems In PCCTS - Last revised 14 November 1998 + ======================================================= + +#17. The dlg fix for handling characters up to 255 is incorrect. + + See item #207. + + Reported by Frank Hartmann. + +#16. A note about "&&" predicates (Mike Dimmick) + + Mike Dimmick has pointed out a potential pitfall in the use of the + "&&" style predicate. Consider: + + r0: (g)? => <

>? r1 + | ... + ; + r1: A | B; + + If the context guard g is not a subset of the lookahead context for r1 + (in other words g is neither A nor B) then the code may execute r1 + even when the lookahead context is not satisfied. This is an error + by the person coding the grammer, and the error should be reported to + the user, but it isn't. expect. Some examples I've run seem to + indicate that such an error actually results in the rule becoming + unreachable. + + When g is properly coded the code is correct, the problem is when g + is not properly coded. + + A second problem reported by Mike Dimmick is that the test for a + failed validation predicate is equivalent to a test on the predicate + along. In other words, if the "&&" has not been hoisted then it may + falsely report a validation error. + +#15. (Changed in MR23) Warning for LT(i), LATEXT(i) in token match actions + + An bug (or at least an oddity) is that a reference to LT(1), LA(1), + or LATEXT(1) in an action which immediately follows a token match + in a rule refers to the token matched, not the token which is in + the lookahead buffer. Consider: + + r : abc <> D <> E; + + In this case LT(1) in action alpha will refer to the next token in + the lookahead buffer ("D"), but LT(1) in action beta will refer to + the token matched by D - the preceding token. + + A warning has been added which warns users about this when an action + following a token match contains a reference to LT(1), LA(1), or LATEXT(1). + + This behavior should be changed, but it appears in too many programs + now. Another problem, perhaps more significant, is that the obvious + fix (moving the consume() call to before the action) could change the + order in which input is requested and output appears in existing programs. + + This problem was reported, along with a fix by Benjamin Mandel + (beny@sd.co.il). However, I felt that changing the behavior was too + dangerous for existing code. + +#14. Parsing bug in dlg + + THM: I have been unable to reproduce this problem. + + Reported by Rick Howard Mijenix Corporation (rickh@mijenix.com). + + The regular expression parser (in rexpr.c) fails while + trying to parse the following regular expression: + + {[a-zA-Z]:}(\\\\[a-zA-Z0-9]*)+ + + See my comment in the following excerpt from rexpr.c: + + /* + * ::= ( '|' {} )* + * + * Return -1 if syntax error + * Return 0 if none found + * Return 1 if a regExrp was found + */ + static + regExpr(g) + GraphPtr g; + { + Graph g1, g2; + + if ( andExpr(&g1) == -1 ) + { + return -1; + } + + while ( token == '|' ) + { + int a; + next(); + a = andExpr(&g2); + if ( a == -1 ) return -1; /* syntax error below */ + else if ( !a ) return 1; /* empty alternative */ + g1 = BuildNFA_AorB(g1, g2); + } + + if ( token!='\0' ) return -1; + ***** + ***** It appears to fail here becuause token is 125 - the closing '}' + ***** If I change it to: + ***** if ( token!='\0' && token!='}' && token!= ')' ) return -1; + ***** + ***** It succeeds, but I'm not sure this is the corrrect approach. + ***** + *g = g1; + return 1; + } + +#13. dlg reports an invalid range for: [\0x00-\0xff] + + Diagnosed by Piotr Eljasiak (eljasiak@no-spam.zt.gdansk.tpsa.pl): + + Fixed in MR16. + +#12. Strings containing comment actions + + Sequences that looked like C style comments appearing in string + literals are improperly parsed by antlr/dlg. + + << fprintf(out," /* obsolete */ "); + + For this case use: + + << fprintf(out," \/\* obsolete \*\/ "); + + Reported by K.J. Cummings (cummings@peritus.com). + +#11. User hook for deallocation of variables on guess fail + + The mechanism outlined in Item #108 works only for + heap allocated variables. + +#10. Label re-initialization in ( X {y:Y} )* + + If a label assignment is optional and appears in a + (...)* or (...)+ block it will not be reset to NULL + when it is skipped by a subsequent iteration. + + Consider the example: + + ( X { y:Y })* Z + + with input: + + X Y X Z + + The first time through the block Y will be matched and + y will be set to point to the token. On the second + iteration of the (...)* block there is no match for Y. + But y will not be reset to NULL, as the user might + expect, it will contain a reference to the Y that was + matched in the first iteration. + + The work-around is to manually reset y: + + ( X << y = NULL; >> { y:Y } )* Z + + or + + ( X ( y:Y | << y = NULL; >> /* epsilon */ ) )* Z + + Reported by Jeff Vincent (JVincent@novell.com). + +#9. PCCTAST.h PCCTSAST::setType() is a noop + +#8. #tokdefs with ~Token and . + + THM: I have been unable to reproduce this problem. + + When antlr uses #tokdefs to define tokens the fields of + #errclass and #tokclass do not get properly defined. + When it subsequently attempts to take the complement of + the set of tokens (using ~Token or .) it can refer to + tokens which don't have names, generating a fatal error. + +#7. DLG crashes on some invalid inputs + + THM: In MR20 have fixed the most common cases. + + The following token defintion will cause DLG to crash. + + #token "()" + + Reported by Mengue Olivier (dolmen@bigfoot.com). + +#6. On MS systems \n\r is treated as two new lines + + Fixed. + +#5. Token expressions in #tokclass + + #errclass does not support TOK1..TOK2 or ~TOK syntax. + #tokclass does not support ~TOKEN syntax + + A workaround for #errclass TOK1..TOK2 is to use a + #tokclass. + + Reported by Dave Watola (dwatola@amtsun.jpl.nasa.gov) + +#4. A #tokdef must appear "early" in the grammar file. + + The "early" section of the grammar file is the only + place where the following directives may appear: + + #header + #first + #tokdefs + #parser + + Any other kind of statement signifiies the end of the + "early" section. + +#3. Use of PURIFY macro for C++ mode + + Item #93 of the CHANGES_FROM_1.33 describes the use of + the PURIFY macro to zero arguments to be passed by + upward inheritance. + + #define PURIFY(r, s) memset((char *) &(r), '\0', (s)); + + This may not be the right thing to do for C++ objects that + have constructors. Reported by Bonny Rais (bonny@werple.net.au). + + For those cases one should #define PURIFY to be an empty macro + in the #header or #first actions. + +#2. Fixed in 1.33MR10 - See CHANGES_FROM_1.33 Item #80. + +#1. The quality of support for systems with 8.3 file names leaves + much to be desired. Since the kit is distributed using the + long file names and the make file uses long file names it requires + some effort to generate. This will probably not be changed due + to the large number of systems already written using the long + file names. diff --git a/Tools/CodeTools/Source/Pccts/MPW_Read_Me b/Tools/CodeTools/Source/Pccts/MPW_Read_Me new file mode 100644 index 0000000000..70a9d1bcad --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/MPW_Read_Me @@ -0,0 +1,21 @@ + +1. You can control the creator type of generated files by changing a value of + #if control statement. + + + pccts:h:pcctscfg.h + + line 225-231 + + #if 0 + #define MAC_FILE_CREATOR 'MPS ' /* MPW Text files */ + #endif + #if 0 + #define MAC_FILE_CREATOR 'KAHL' /* THINK C/Symantec C++ Text files */ + #endif + #if 0 + #define MAC_FILE_CREATOR 'CWIE' /* Metrowerks C/C++ Text files */ + #endif + +2. If you want to build 68K version. You must convert all source files to Macintosh + format before compile. diff --git a/Tools/CodeTools/Source/Pccts/NOTES.bcc b/Tools/CodeTools/Source/Pccts/NOTES.bcc new file mode 100644 index 0000000000..1ac05b17c5 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/NOTES.bcc @@ -0,0 +1,184 @@ +March 95 +Version 1.32 of pccts + +At the moment this file is available via anonymous FTP at + + Node: marvin.ecn.purdue.edu + File: pub/pccts/1.32/NOTES.BCC + +Mail corrections or additions to David Seidel <71333.1575@compuserve.com> +=============================================================================== +Notes on Building PCCTS 1.32 with Borland C++ + +David Seidel, Innovative Data Concepts Incorporated +CompuServe: 71333,1575 +Internet: 71333.1575@compuserve.com + dseidel@delphi.com + +I have gotten ANTLR and DLG to succesfully build with BCC 4.0, but have found +from experience that ANTLR, in particular, is likely to run out of memory +with grammars over a certain size, or with larger values for the -k and -ck +options. Now that BCC 4.02 and the new Borland Power Pack for DOS is now +available, I feel that there is no excuse not to build these tools as +32-bit executables, as they ought to be. + +For people without the Power Pack, the makefiles below should be fairly easily +modified to build 16-bit real-mode executables, but I don't really recommend +it. As an alternative, you might consider the highly regarded DJGPP compiler +(a DOS port of the Gnu GCC compiler, with a DOS extender included). Hopefully +some other PCCTS who has DJGPP can provode whatever advice is necessary. The +Watcom compiler is also an excellent possibility (albeit a commercial one), +and I hope to make available Watcom makefiles in the near future. + +Here are the makefiles I am using. Both makefiles use a compiler configuration +file that contains compiler switches such as optimization settings. I call +this file bor32.cfg and keep a copy in both the ANTLR and DLG subdirectories. + +==== File: bor32.cfg (cut here) =============================================== +-w- +-RT- +-x- +-N- +-k- +-d +-O2-e-l +-Z +-D__STDC__=1 +==== End of file bor32.cfg (cut here) ========================================= + +==== File: antlr\bor32.mak (cut here) ========================================= +# +# ANTLR 1.32 Makefile for Borland C++ 4.02 with DPMI 32-bit DOS extender by +# David Seidel +# Innovative Data Concepts Incorporated +# 71333.1575@compuserve.com (or) dseidel@delphi.com +# +# Notes: 1. Compiler switches (optimization etc.) are contained in the +# file bor32.cfg. +# 2. This makefile requires Borland C++ 4.02 or greater with +# the DOS Power Pack add-on package. +# 3. Change the BCCDIR macro below to the topmost directory in +# which BCC is installed on your system. +# + +BCCDIR = d:\bc4 +CC = bcc32 +SET = ..\support\set +PCCTS_H = ..\h +ANTLR = ..\bin\antlr +DLG = ..\bin\dlg +CFLAGS = -I$(BCCDIR)\include -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN \ + +bor32.cfg +LIBS = dpmi32 cw32 +OBJ_EXT = obj +OBJS = antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj fset.obj \ + gen.obj globals.obj hash.obj lex.obj main.obj misc.obj pred.obj dialog.obj \ + set.obj + +.c.obj: + $(CC) -c $(CFLAGS) {$&.c } + +antlr.exe: $(OBJS) + tlink32 @&&| +-Tpe -ax -c -s -L$(BCCDIR)\lib + +$(BCCDIR)\lib\c0x32 $** +$@ + +$(LIBS) +; +| + copy *.exe ..\bin + + +# *********** Target list of PC machines *********** +# +# Don't worry about the ambiguity messages coming from antlr +# for making antlr.c etc... [should be 10 of them, I think] +# + +# leave this commented out for initial build! +#antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g +# $(ANTLR) antlr.g + +antlr.$(OBJ_EXT): antlr.c mode.h tokens.h + +scan.$(OBJ_EXT): scan.c mode.h tokens.h + +# leave this commented out for initial build! +#scan.c mode.h: parser.dlg +# $(DLG) -C2 parser.dlg scan.c + +set.$(OBJ_EXT): $(SET)\set.c + $(CC) -c $(CFLAGS) $(SET)\set.c + +==== End of file antlr\bor32.mak (cut here) =================================== + +==== File: dlg\bor32.mak (cut here) =========================================== +# +# DLG 1.32 Makefile for Borland C++ 4.02 with DPMI 32-bit DOS extender by +# David Seidel +# Innovative Data Concepts Incorporated +# 71333.1575@compuserve.com (or) dseidel@delphi.com +# +# Notes: 1. Compiler switches (optimization etc.) are contained in the +# file bor32.cfg. +# 2. This makefile requires Borland C++ 4.02 or greater with +# the DOS Power Pack add-on package. +# 3. Change the BCCDIR macro below to the topmost directory in +# which BCC is installed on your system. +# + + +BCCDIR = d:\bc4 +CC = bcc32 +SET = ..\support\set +PCCTS_H = ..\h +ANTLR = ..\bin\antlr +DLG = ..\bin\dlg +CFLAGS = -I$(BCCDIR)\include -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN \ + +bor32.cfg +LIBS = dpmi32 cw32 +OBJ_EXT = obj +OBJS = dlg_p.obj dlg_a.obj main.obj err.obj support.obj \ + output.obj relabel.obj automata.obj set.obj + +.c.obj: + $(CC) -c $(CFLAGS) {$&.c } + +dlg.exe : $(OBJS) + tlink32 @&&| +-Tpe -ax -c -s -L$(BCCDIR)\lib + +c0x32 $** +$@ + +$(LIBS) +; +| + copy *.exe ..\bin + +dlg_p.obj: dlg_p.c + +dlg_a.obj: dlg_a.c + +main.obj: main.c + +err.obj: err.c + +support.obj: support.c + +output.obj: output.c + +relabel.obj: relabel.c + +automata.obj: automata.c + +set.$(OBJ_EXT): $(SET)\set.c + $(CC) -c $(CFLAGS) $(SET)\set.c + +==== End of file dlg\bor32.mak (cut here) ===================================== + + + + + + diff --git a/Tools/CodeTools/Source/Pccts/NOTES.msvc b/Tools/CodeTools/Source/Pccts/NOTES.msvc new file mode 100644 index 0000000000..86f8ed66e0 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/NOTES.msvc @@ -0,0 +1,189 @@ + + Microsoft Visual C Stuff + + +[Tom Moog 2-Oct-98 + + Users of Microsoft Visual C++ should download a separate + ready-to-run zip file from my web site. It contains + binaries, static library, and a sample project. +] + +[ + Two notes added by Tom Moog 23-Sep-97. I believe the *.dsp and + *.mak files that were once at the end of this file are now obsolete. + + The following MSVC .dsp and .mak files for pccts and sorcerer + were contributed by Stanislaw Bochnak (S.Bochnak@microtool.com.pl) + and Jeff Vincent (jvincent@novell.com) + + PCCTS Distribution Kit + ---------------------- + pccts/antlr/AntlrMSVC50.dsp + pccts/antlr/AntlrMSVC50.mak + + pccts/dlg/DlgMSVC50.dsp + pccts/dlg/DlgMSVC50.mak + + pccts/support/genmk/watgenmk.mak + pccts/support/msvc.dsp + + Sorcerer Distribution Kit + ------------------------- + pccts/sorcerer/SorcererMSVC50.dsp + pccts/sorcerer/SorcererMSVC50.mak + + pccts/sorcerer/lib/msvc.dsp + + I do not have an MS based computer. If you discover problems + please report them so as to save trouble for others in the future. +] + +[ + Modified by Terence Parr (September 1995) to change .C to .cpp +] + +[ + This file contains notes on MSVC for Windows NT console execs by Dave + Seidel and an explanation of flags etc.. by John Hall; good luck, + Terence +] + +=============================================================================== +Date: Sat, 31 Dec 1994 11:40:36 -0500 (EST) +From: David Seidel <75342.2034@compuserve.com> + +I've succesfully build 1.31b3 with djgpp for DOS and MSVC 2.0 for Windows +NT. The only (minor) problem I had was that GNU make (version 3.71, in the +djgpp port) complained about "multiple targets" in both the antlr and dlg +makefiles. I got around the error by, in each makefile, commenting out the +$(SRC) dependency, for example: + + antlr: $(OBJ) #$(SRC) + +I don't know why this is happenning, since you haven't changed that part of +the makefile at all, and I think this used to work ok... + +Here are the makefiles I built from within the MSVC 2.0 environment for antlr +and dlg and Windows NT console executables. Please feel free to pass them +on. Of course, as soon as 1.31 "goes gold", I will send you nice new +binaries. I'm not going to bother to keep doing both Borland and djgpp for +DOS however. Instead, I'll just keep the djgpp version up to date and also +provide WinNT binaries. + +Dave +=============================================================================== + + How to port PCCTS 1.10 (and 1.32 hopefully) to Visual C++ + + By + + John Hall + +Here is how to compile an ANTLR grammar in Visual C++. These steps +describe how to have your ANTLR grammar parse the input file the user +selects when they choose File Open in your Windows application. (Even +if you aren't using Visual C++, the steps should be portable enough to +other compilers.) + + * Make sure that ANTLR and DLG generate ANSI code (use the -ga + switch). + + * Set the following compiler flags in Visual C++ (these are in the + Memory Model category of the compiler options in the Project + Options menu): + + FLAG MEANING + ==== ============================================================== + /AL Large memory model (multiple data segments; data items must be + smaller than 64K). + + /Gtn Allocates all items whose size is greater than or equal to n + in a new data segment. (I let n be 256: /Gt256.) + + /Gx- All references to data items are done with far addressing in + case they are placed in a far segment. + + * Add the following member variable to the attributes section of your + derived CDocument class (you will need to make sure you also + include stdio.h): + + FILE *fp; + + * Add the following method to your derived CDocument class: + + BOOL CAppDoc::OnOpenDocument(const char* pszPathName) + { + // Call CDocument's OnOpenDocument to do housekeeping for us + // DON'T add anything to the loading section of Serialize + if (!CDocument::OnOpenDocument(pszPathName)) + return FALSE; + + // Open input file + if ((fp = fopen(pszPathName, "r")) == NULL) + return FALSE; + + // Parse input file + ANTLR(start(), fp); + + // Close input file + fclose(fp); + return TRUE; + } + + (Note: additional code may be necessary, depending on your parser. + For example, if your parser uses PCCTS's symbol table library, you + will need to insert calls to zzs_init and zzs_done.) + + * Compile the generated C files as C++ files. (I renamed the files + to have a .CPP extension to fool Visual C++ into thinking they were + C++ files. One might also use the /Tp switch, but that switch + requires you separately include the filename.) [I used this step + as an easy out for all the external linking errors I was getting + that I couldn't fix by declaring things extern "C".] + + * Make sure the __STDC__ portion of the generated files gets + compiled. (Either define __STDC__ yourself or else change all + occurrences of __STDC__ to __cplusplus in the generated files. You + can define __STDC__ in the Preprocessor category of the compiler + options.) + + ================================================================ + = Note 23-Sep-97: This is probably not necessary any more. = + = With 1.33MRxxx the use of __STDC__ was replaced with the = + = macro __USE_PROTOS to control the compilation of prototypes. = + ================================================================ + +That last step is important for Visual C++, but may not apply to other +compilers. For C++ compilers, whether __STDC__ is defined is +implementation dependent (ARM, page 379). Apparently, Visual C++ does +not to define it; it also does not support "old style" C function +definitions (which is okay, according to page 404 of the ARM). Those +two things together caused problems when trying to port the code. +When it saw this: + +#ifdef __STDC__ +void +globals(AST **_root) +#else +globals(_root) +AST **_root; +#endif + +it skipped the __STDC__ section and tried to process the "old style" +function definition, where it choked. + +When you finally get your parser to compile and link without error, +you may get General Protection Fault errors at run time. The problem +I had was that a NULL was passed to a variable argument function +without an explicit cast. The function grabbed a pointer (32-bits) +off the stack using va_arg, but the NULL was passed silently as the +integer 0 (16 bits), making the resulting pointer was invalid. (This +was in PCCTS's sample C parser.) + +There is one other thing I might suggest to help you avoid a run-time +error. Make sure you redefine the default error reporting function, +zzsyn. To do this, put "#define USER_ZZSYN" in your #header section +and put your own zzsyn somewhere. You can then pop up a MessageBox or +print the error to some output window. +=============================================================================== diff --git a/Tools/CodeTools/Source/Pccts/README b/Tools/CodeTools/Source/Pccts/README new file mode 100644 index 0000000000..d089b638b4 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/README @@ -0,0 +1,159 @@ + + Parr Research Corporation + with + Purdue University Electrical Engineering + and + University of Minnesota, AHPCRC + + Terence Parr + Russell Quong + Will Cohen + Hank Dietz + + +A central place for information about PCCTS 1.33 is: + + http://www.polhode.com/pccts.html + +The maintenance release is available from: + + http://www.polhode.com/pccts133mr.zip + +There is a ready-to-run version for win32 for Microsoft Visual Studio +at the same site. It is available from: + + http://www.polhode.com/win32.zip + +New users should visit http://www.polhode.com/pccts.html in +order to get the following document: + + "Notes For New Users of PCCTS" + +This is a Postscript file of about 40 pages which is extremely +useful for someone starting out. It is a based on 1.33mr21 + +When you have a little more experience, be sure to review the +following documents in the distribution kit: + + CHANGES_FROM_133.txt + CHANGES_FROM_133_BEFORE_MR13.txt + KNOWN_PROBLEMS.txt + +------------------------------------------------------------------------- + INSTALLATION (Unix) +------------------------------------------------------------------------- +0. Download http://www.polhode.com/pccts133mr.zip + +1. Unzip the distribution kit to your preferred location. + If there are newline problems try using zip -a ... + +2. cd to the main pccts directory. + +3. make + + This will create: + + antlr + dlg + sorcerer + genmk + +4. Copy to /usr/local/bin or /usr/local/bin if you like. If you + don't wish to then add pccts/bin to your path. + +5. To get an up-to-date list of program options execute the + program with no command line options. To get up-to-date + documentation read CHANGES_FROM_133*.txt and KNOWN_PROBLEMS.txt + at: + + http://www.polhode.com/pccts.html + +6. You need not create a library. The makefile created by genmk + assumes that the files are not part of a library. + + If you wish to create a library from elements of pccts/h: + + If the first letter of the filename is lowercase (uppercase) it is + related to the code generated using the pccts C mode (C++ mode). + Some of the .c and .cpp files in the h directory are not meant to + be placed in a library and will not compile because they are meant + to be #include in pccts generated files which are grammar specific. + + For C++ users place the following elements in the library: + + AParser.cpp + ASTBase.cpp + ATokenBuffer.cpp + BufFileInput.cpp (optional) + DLexerBase.cpp + PCCTSAST.cpp + SList.cpp + +------------------------------------------------------------------------- + INSTALLATION (Win32) +------------------------------------------------------------------------- + +I've tried to keep the win32 kit to the minimum necessary to get +up and running. The complete kit contains additional information +(some historical), source code, and DevStudio projects for +rebuilding pccts from the source code. + +The kit is now distributed with both MSVC 5 and MSVC6 style projects. + +0. Download http://www.polhode.com/win32.zip. + + You may also wish to download: + + http://www.polhode.com/CHANGES_FROM_133.txt + http://www.polhode.com/CHANGES_FROM_133_BEFORE_MR13.txt + http://www.polhode.com/KNOWN_PROBLEMS.txt + +1. Unzip the distribution kit to your preferred location. + + This will create: + + a pccts directory tree + pccts/bin/*.exe + pccts/lib/*.lib + pccts/h/* + sorcerer/lib/* + sorcerer/h/* + + an example directory tree + pccts\example\calcAST\* + pccts\example\simple\* + +2. Define the environment variable PCCTS to point to the main + pccts directory. + +3. Try building the simple project: pccts\example\simple\simple50.dsw + or simple60.dsw. + +4. Try building the complex project: pccts\example\calcAST\calcAST50.dsw + or calcAST60.dsw. + +------------------------------------------------------------------------- + INSTALLATION (DEC/VMS) +------------------------------------------------------------------------- + +DEC/VMS support added by Piéronne Jean-François (jfp@altavista.net) + +0. Download http://www.polhode.com/pccts133mr.zip + +1. Unzip the distribution kit to your preferred location. + +2. set default to the main pccts directory. + +3. @makefile.vms + + This will create in directory [.bin]: + + antlr.exe + dlg.exe + sorcerer.exe + genmk.exe + +5. To get an up-to-date list of program options execute the + program with no command line options. To get up-to-date + documentation read CHANGES_FROM_133*.txt and KNOWN_PROBLEMS.txt + at http://www.polhode.com/pccts.html. diff --git a/Tools/CodeTools/Source/Pccts/RIGHTS b/Tools/CodeTools/Source/Pccts/RIGHTS new file mode 100644 index 0000000000..9db175ff40 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/RIGHTS @@ -0,0 +1,26 @@ + +SOFTWARE RIGHTS + +We reserve no LEGAL rights to the Purdue Compiler Construction Tool +Set (PCCTS) -- PCCTS is in the public domain. An individual or +company may do whatever they wish with source code distributed with +PCCTS or the code generated by PCCTS, including the incorporation of +PCCTS, or its output, into commerical software. + +We encourage users to develop software with PCCTS. However, we do ask +that credit is given to us for developing PCCTS. By "credit", we mean +that if you incorporate our source code into one of your programs +(commercial product, research project, or otherwise) that you +acknowledge this fact somewhere in the documentation, research report, +etc... If you like PCCTS and have developed a nice tool with the +output, please mention that you developed it using PCCTS. In +addition, we ask that this header remain intact in our source code. +As long as these guidelines are kept, we expect to continue enhancing +this system and expect to make other tools available as they are +completed. + +ANTLR 1.33 +Terence Parr +Parr Research Corporation +with Purdue University and AHPCRC, University of Minnesota +1989-1995 diff --git a/Tools/CodeTools/Source/Pccts/antlr/AntlrMS.mak b/Tools/CodeTools/Source/Pccts/antlr/AntlrMS.mak new file mode 100644 index 0000000000..7c14993ee0 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/AntlrMS.mak @@ -0,0 +1,233 @@ +# PCCTS directory + +# You will need to set the LIB variable similar to this. +# LIB="C:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/lib;c:/Microsoft Visual Studio .NET 2003/Vc7/PlatformSDK/Lib" + +# PCCTS_HOME= +PCCTS_HOME=$(WORKSPACE)\Tools\Source\TianoTools\Pccts +ANTLR_SRC=$(PCCTS_HOME)\antlr +PCCTS_H=$(PCCTS_HOME)\h + + +# Support directories +SET=$(PCCTS_HOME)\support\set + + +# Compiler stuff +CC = cl +CFLAGS = /nologo -I "." -I "$(PCCTS_H)" -I "$(SET)" -D "USER_ZZSYN" -D "PC" \ + -D "ZZLEXBUFSIZE=65536" /D "LONGFILENAMES" /Zi /W3 -D__USE_PROTOS /wd4700 + +ANTLR_OBJS = antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \ + fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \ + misc.obj pred.obj egman.obj mrhoist.obj fcache.obj + +SUPPORT_OBJS = set.obj + +# Dependencies + +$(WORKSPACE)\Tools\bin\antlr.exe: $(ANTLR_OBJS) $(SUPPORT_OBJS) + $(CC) $(CFLAGS) -o antlr.exe $(ANTLR_OBJS) $(SUPPORT_OBJS) + del *.obj + move antlr.exe $(WORKSPACE)\Tools\bin + + +antlr.obj: $(ANTLR_SRC)\antlr.c \ + $(PCCTS_H)\antlr.h \ + $(PCCTS_H)\config.h \ + $(PCCTS_H)\dlgdef.h \ + $(SET)\set.h \ + $(ANTLR_SRC)\generic.h \ + $(ANTLR_SRC)\hash.h \ + $(ANTLR_SRC)\mode.h \ + $(ANTLR_SRC)\proto.h \ + $(ANTLR_SRC)\syn.h \ + $(ANTLR_SRC)\tokens.h \ + + $(CC) -c $(CFLAGS) $(ANTLR_SRC)\antlr.c + +scan.obj: $(ANTLR_SRC)\scan.c \ + $(PCCTS_H)\antlr.h \ + $(PCCTS_H)\config.h \ + $(PCCTS_H)\dlgauto.h \ + $(PCCTS_H)\dlgdef.h \ + $(SET)\set.h \ + $(ANTLR_SRC)\generic.h \ + $(ANTLR_SRC)\hash.h \ + $(ANTLR_SRC)\mode.h \ + $(ANTLR_SRC)\proto.h \ + $(ANTLR_SRC)\syn.h \ + $(ANTLR_SRC)\tokens.h \ + + $(CC) -c $(CFLAGS) $(ANTLR_SRC)\scan.c + +err.obj: $(ANTLR_SRC)\err.c \ + $(PCCTS_H)\antlr.h \ + $(PCCTS_H)\config.h \ + $(PCCTS_H)\dlgdef.h \ + $(PCCTS_H)\err.h \ + $(SET)\set.h \ + $(ANTLR_SRC)\generic.h \ + $(ANTLR_SRC)\hash.h \ + $(ANTLR_SRC)\proto.h \ + $(ANTLR_SRC)\syn.h \ + $(ANTLR_SRC)\tokens.h \ + + $(CC) -c $(CFLAGS) $(ANTLR_SRC)\err.c + +bits.obj: $(ANTLR_SRC)\bits.c \ + $(PCCTS_H)\config.h \ + $(PCCTS_H)\dlgdef.h \ + $(SET)\set.h \ + $(ANTLR_SRC)\generic.h \ + $(ANTLR_SRC)\hash.h \ + $(ANTLR_SRC)\proto.h \ + $(ANTLR_SRC)\syn.h \ + + $(CC) -c $(CFLAGS) $(ANTLR_SRC)\bits.c + +build.obj: $(ANTLR_SRC)\build.c \ + $(PCCTS_H)\config.h \ + $(PCCTS_H)\dlgdef.h \ + $(SET)\set.h \ + $(ANTLR_SRC)\generic.h \ + $(ANTLR_SRC)\hash.h \ + $(ANTLR_SRC)\proto.h \ + $(ANTLR_SRC)\syn.h \ + + $(CC) -c $(CFLAGS) $(ANTLR_SRC)\build.c + +fset2.obj: $(ANTLR_SRC)\fset2.c \ + $(PCCTS_H)\config.h \ + $(PCCTS_H)\dlgdef.h \ + $(SET)\set.h \ + $(ANTLR_SRC)\generic.h \ + $(ANTLR_SRC)\hash.h \ + $(ANTLR_SRC)\proto.h \ + $(ANTLR_SRC)\syn.h \ + + $(CC) -c $(CFLAGS) $(ANTLR_SRC)\fset2.c + +fset.obj: $(ANTLR_SRC)\fset.c \ + $(PCCTS_H)\config.h \ + $(PCCTS_H)\dlgdef.h \ + $(SET)\set.h \ + $(ANTLR_SRC)\generic.h \ + $(ANTLR_SRC)\hash.h \ + $(ANTLR_SRC)\proto.h \ + $(ANTLR_SRC)\syn.h \ + + $(CC) -c $(CFLAGS) $(ANTLR_SRC)\fset.c + +gen.obj: $(ANTLR_SRC)\gen.c \ + $(PCCTS_H)\config.h \ + $(PCCTS_H)\dlgdef.h \ + $(SET)\set.h \ + $(ANTLR_SRC)\generic.h \ + $(ANTLR_SRC)\hash.h \ + $(ANTLR_SRC)\proto.h \ + $(ANTLR_SRC)\syn.h \ + + $(CC) -c $(CFLAGS) $(ANTLR_SRC)\gen.c + +globals.obj: $(ANTLR_SRC)\globals.c \ + $(PCCTS_H)\config.h \ + $(SET)\set.h \ + $(ANTLR_SRC)\generic.h \ + $(ANTLR_SRC)\hash.h \ + $(ANTLR_SRC)\proto.h \ + $(ANTLR_SRC)\syn.h \ + + $(CC) -c $(CFLAGS) $(ANTLR_SRC)\globals.c + +hash.obj: $(ANTLR_SRC)\hash.c \ + $(PCCTS_H)\config.h \ + $(ANTLR_SRC)\hash.h \ + + $(CC) -c $(CFLAGS) $(ANTLR_SRC)\hash.c + +lex.obj: $(ANTLR_SRC)\lex.c \ + $(PCCTS_H)\config.h \ + $(SET)\set.h \ + $(ANTLR_SRC)\generic.h \ + $(ANTLR_SRC)\hash.h \ + $(ANTLR_SRC)\proto.h \ + $(ANTLR_SRC)\syn.h \ + + $(CC) -c $(CFLAGS) $(ANTLR_SRC)\lex.c + +main.obj: $(ANTLR_SRC)\main.c \ + $(PCCTS_H)\antlr.h \ + $(PCCTS_H)\config.h \ + $(PCCTS_H)\dlgdef.h \ + $(SET)\set.h \ + $(ANTLR_SRC)\generic.h \ + $(ANTLR_SRC)\hash.h \ + $(ANTLR_SRC)\mode.h \ + $(ANTLR_SRC)\proto.h \ + $(ANTLR_SRC)\stdpccts.h \ + $(ANTLR_SRC)\syn.h \ + $(ANTLR_SRC)\tokens.h \ + + $(CC) -c $(CFLAGS) $(ANTLR_SRC)\main.c + +misc.obj: $(ANTLR_SRC)\misc.c \ + $(PCCTS_H)\config.h \ + $(PCCTS_H)\dlgdef.h \ + $(SET)\set.h \ + $(ANTLR_SRC)\generic.h \ + $(ANTLR_SRC)\hash.h \ + $(ANTLR_SRC)\proto.h \ + $(ANTLR_SRC)\syn.h \ + + $(CC) -c $(CFLAGS) $(ANTLR_SRC)\misc.c + +pred.obj: $(ANTLR_SRC)\pred.c \ + $(PCCTS_H)\config.h \ + $(PCCTS_H)\dlgdef.h \ + $(SET)\set.h \ + $(ANTLR_SRC)\generic.h \ + $(ANTLR_SRC)\hash.h \ + $(ANTLR_SRC)\proto.h \ + $(ANTLR_SRC)\syn.h \ + + $(CC) -c $(CFLAGS) $(ANTLR_SRC)\pred.c + +egman.obj: $(ANTLR_SRC)\egman.c \ + $(PCCTS_H)\config.h \ + $(SET)\set.h \ + $(ANTLR_SRC)\generic.h \ + $(ANTLR_SRC)\hash.h \ + $(ANTLR_SRC)\proto.h \ + $(ANTLR_SRC)\syn.h \ + + $(CC) -c $(CFLAGS) $(ANTLR_SRC)\egman.c + +mrhoist.obj: $(ANTLR_SRC)\mrhoist.c \ + $(ANTLR_SRC)\generic.h \ + $(ANTLR_SRC)\hash.h \ + $(ANTLR_SRC)\proto.h \ + $(ANTLR_SRC)\syn.h \ + + $(CC) -c $(CFLAGS) $(ANTLR_SRC)\mrhoist.c + +fcache.obj: $(ANTLR_SRC)\fcache.c \ + $(ANTLR_SRC)\generic.h \ + $(ANTLR_SRC)\hash.h \ + $(ANTLR_SRC)\proto.h \ + $(ANTLR_SRC)\syn.h \ + + $(CC) -c $(CFLAGS) $(ANTLR_SRC)\fcache.c + +set.obj: $(SET)\set.c \ + $(PCCTS_H)\config.h \ + $(SET)\set.h \ + + $(CC) -c $(CFLAGS) $(SET)\set.c + +clean: + del *.obj + +distclean: + del *.obj + del $(WORKSPACE)\Tools\bin\antlr.exe diff --git a/Tools/CodeTools/Source/Pccts/antlr/AntlrPPC.mak b/Tools/CodeTools/Source/Pccts/antlr/AntlrPPC.mak new file mode 100644 index 0000000000..9ede60d64c --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/AntlrPPC.mak @@ -0,0 +1,101 @@ +# Target: antlrPPC +# Sources: ::support:set:set.c +# antlr.c +# bits.c +# build.c +# egman.c +# err.c +# fcache.c +# fset2.c +# fset.c +# gen.c +# globals.c +# hash.c +# lex.c +# main.c +# misc.c +# mrhoist.c +# pred.c +# scan.c +# Created: Sunday, May 17, 1998 10:24:53 PM +# Author: Kenji Tanaka +MAKEFILE = antlrPPC.make +¥MondoBuild¥ = {MAKEFILE} # Make blank to avoid rebuilds when makefile is modified +Includes = ¶ + -i "::h:" ¶ + -i "::support:set:" +Sym¥PPC = +ObjDir¥PPC = :Obj: +PPCCOptions = {Includes} {Sym¥PPC} -w off -d MPW -d __STDC__=1 -d USER_ZZSYN +Objects¥PPC = ¶ + "{ObjDir¥PPC}set.c.x" ¶ + "{ObjDir¥PPC}antlr.c.x" ¶ + "{ObjDir¥PPC}bits.c.x" ¶ + "{ObjDir¥PPC}build.c.x" ¶ + "{ObjDir¥PPC}egman.c.x" ¶ + "{ObjDir¥PPC}err.c.x" ¶ + "{ObjDir¥PPC}fcache.c.x" ¶ + "{ObjDir¥PPC}fset2.c.x" ¶ + "{ObjDir¥PPC}fset.c.x" ¶ + "{ObjDir¥PPC}gen.c.x" ¶ + "{ObjDir¥PPC}globals.c.x" ¶ + "{ObjDir¥PPC}hash.c.x" ¶ + "{ObjDir¥PPC}lex.c.x" ¶ + "{ObjDir¥PPC}main.c.x" ¶ + "{ObjDir¥PPC}misc.c.x" ¶ + "{ObjDir¥PPC}mrhoist.c.x" ¶ + "{ObjDir¥PPC}pred.c.x" ¶ + "{ObjDir¥PPC}scan.c.x" +antlrPPC ÄÄ {¥MondoBuild¥} {Objects¥PPC} + PPCLink ¶ + -o {Targ} {Sym¥PPC} ¶ + {Objects¥PPC} ¶ + -t 'MPST' ¶ + -c 'MPS ' ¶ + "{SharedLibraries}InterfaceLib" ¶ + "{SharedLibraries}StdCLib" ¶ + #"{SharedLibraries}MathLib" ¶ + "{PPCLibraries}StdCRuntime.o" ¶ + "{PPCLibraries}PPCCRuntime.o" ¶ + "{PPCLibraries}PPCToolLibs.o" +"{ObjDir¥PPC}set.c.x" Ä {¥MondoBuild¥} "::support:set:set.c" + {PPCC} "::support:set:set.c" -o {Targ} {PPCCOptions} +"{ObjDir¥PPC}antlr.c.x" Ä {¥MondoBuild¥} antlr.c + {PPCC} antlr.c -o {Targ} {PPCCOptions} +"{ObjDir¥PPC}bits.c.x" Ä {¥MondoBuild¥} bits.c + {PPCC} bits.c -o {Targ} {PPCCOptions} +"{ObjDir¥PPC}build.c.x" Ä {¥MondoBuild¥} build.c + {PPCC} build.c -o {Targ} {PPCCOptions} +"{ObjDir¥PPC}egman.c.x" Ä {¥MondoBuild¥} egman.c + {PPCC} egman.c -o {Targ} {PPCCOptions} +"{ObjDir¥PPC}err.c.x" Ä {¥MondoBuild¥} err.c + {PPCC} err.c -o {Targ} {PPCCOptions} +"{ObjDir¥PPC}fcache.c.x" Ä {¥MondoBuild¥} fcache.c + {PPCC} fcache.c -o {Targ} {PPCCOptions} +"{ObjDir¥PPC}fset2.c.x" Ä {¥MondoBuild¥} fset2.c + {PPCC} fset2.c -o {Targ} {PPCCOptions} +"{ObjDir¥PPC}fset.c.x" Ä {¥MondoBuild¥} fset.c + {PPCC} fset.c -o {Targ} {PPCCOptions} +"{ObjDir¥PPC}gen.c.x" Ä {¥MondoBuild¥} gen.c + {PPCC} gen.c -o {Targ} {PPCCOptions} +"{ObjDir¥PPC}globals.c.x" Ä {¥MondoBuild¥} globals.c + {PPCC} globals.c -o {Targ} {PPCCOptions} +"{ObjDir¥PPC}hash.c.x" Ä {¥MondoBuild¥} hash.c + {PPCC} hash.c -o {Targ} {PPCCOptions} +"{ObjDir¥PPC}lex.c.x" Ä {¥MondoBuild¥} lex.c + {PPCC} lex.c -o {Targ} {PPCCOptions} +"{ObjDir¥PPC}main.c.x" Ä {¥MondoBuild¥} main.c + {PPCC} main.c -o {Targ} {PPCCOptions} +"{ObjDir¥PPC}misc.c.x" Ä {¥MondoBuild¥} misc.c + {PPCC} misc.c -o {Targ} {PPCCOptions} +"{ObjDir¥PPC}mrhoist.c.x" Ä {¥MondoBuild¥} mrhoist.c + {PPCC} mrhoist.c -o {Targ} {PPCCOptions} +"{ObjDir¥PPC}pred.c.x" Ä {¥MondoBuild¥} pred.c + {PPCC} pred.c -o {Targ} {PPCCOptions} +"{ObjDir¥PPC}scan.c.x" Ä {¥MondoBuild¥} scan.c + {PPCC} scan.c -o {Targ} {PPCCOptions} + +antlrPPC ÄÄ antlr.r + Rez antlr.r -o antlrPPC -a +Install Ä antlrPPC + Duplicate -y antlrPPC "{MPW}"Tools:antlr diff --git a/Tools/CodeTools/Source/Pccts/antlr/README b/Tools/CodeTools/Source/Pccts/antlr/README new file mode 100644 index 0000000000..d7fc95916e --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/README @@ -0,0 +1,19 @@ + ANTLR 1.33 + +This directory contains the files necessary to build ANTLR. + +If you do a "make scrub", ANTLR will have to run on antlr.g and DLG +will have to run on parser.dlg. Either + +(1) ANTLR uses the previous antlr in that directory to rebuild itself +(2) Needs to find antlr on the search path + +You will find that running "antlr -gh antlr.g" will result in about +10 ambiguity warnings. These are normal. Don't worry. + +If you do a "make clean" right after installation, ANTLR and DLG should +not need to run; only the C files will compile. + +Don't forget to go into the makefile to uncomment the appropriate +definitions for your OS/architecture/compiler or see the appropriate +NOTES.?? file. diff --git a/Tools/CodeTools/Source/Pccts/antlr/antlr.1 b/Tools/CodeTools/Source/Pccts/antlr/antlr.1 new file mode 100644 index 0000000000..acfa85b066 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/antlr.1 @@ -0,0 +1,209 @@ +.TH ANTLR 1 "September 1995" "ANTLR" "PCCTS Manual Pages" +.SH NAME +antlr \- ANother Tool for Language Recognition +.SH SYNTAX +.LP +\fBantlr\fR [\fIoptions\fR] \fIgrammar_files\fR +.SH DESCRIPTION +.PP +\fIAntlr\fP converts an extended form of context-free grammar into a +set of C functions which directly implement an efficient form of +deterministic recursive-descent LL(k) parser. Context-free grammars +may be augmented with predicates to allow semantics to influence +parsing; this allows a form of context-sensitive parsing. Selective +backtracking is also available to handle non-LL(k) and even +non-LALR(k) constructs. \fIAntlr\fP also produces a definition of a +lexer which can be automatically converted into C code for a DFA-based +lexer by \fIdlg\fR. Hence, \fIantlr\fR serves a function much like +that of \fIyacc\fR, however, it is notably more flexible and is more +integrated with a lexer generator (\fIantlr\fR directly generates +\fIdlg\fR code, whereas \fIyacc\fR and \fIlex\fR are given independent +descriptions). Unlike \fIyacc\fR which accepts LALR(1) grammars, +\fIantlr\fR accepts LL(k) grammars in an extended BNF notation \(em +which eliminates the need for precedence rules. +.PP +Like \fIyacc\fR grammars, \fIantlr\fR grammars can use +automatically-maintained symbol attribute values referenced as dollar +variables. Further, because \fIantlr\fR generates top-down parsers, +arbitrary values may be inherited from parent rules (passed like +function parameters). \fIAntlr\fP also has a mechanism for creating +and manipulating abstract-syntax-trees. +.PP +There are various other niceties in \fIantlr\fR, including the ability to +spread one grammar over multiple files or even multiple grammars in a single +file, the ability to generate a version of the grammar with actions stripped +out (for documentation purposes), and lots more. +.SH OPTIONS +.IP "\fB-ck \fIn\fR" +Use up to \fIn\fR symbols of lookahead when using compressed (linear +approximation) lookahead. This type of lookahead is very cheap to +compute and is attempted before full LL(k) lookahead, which is of +exponential complexity in the worst case. In general, the compressed +lookahead can be much deeper (e.g, \f(CW-ck 10\fP) than the full +lookahead (which usually must be less than 4). +.IP \fB-CC\fP +Generate C++ output from both ANTLR and DLG. +.IP \fB-cr\fP +Generate a cross-reference for all rules. For each rule, print a list +of all other rules that reference it. +.IP \fB-e1\fP +Ambiguities/errors shown in low detail (default). +.IP \fB-e2\fP +Ambiguities/errors shown in more detail. +.IP \fB-e3\fP +Ambiguities/errors shown in excruciating detail. +.IP "\fB-fe\fP file" +Rename \fBerr.c\fP to file. +.IP "\fB-fh\fP file" +Rename \fBstdpccts.h\fP header (turns on \fB-gh\fP) to file. +.IP "\fB-fl\fP file" +Rename lexical output, \fBparser.dlg\fP, to file. +.IP "\fB-fm\fP file" +Rename file with lexical mode definitions, \fBmode.h\fP, to file. +.IP "\fB-fr\fP file" +Rename file which remaps globally visible symbols, \fBremap.h\fP, to file. +.IP "\fB-ft\fP file" +Rename \fBtokens.h\fP to file. +.IP \fB-ga\fP +Generate ANSI-compatible code (default case). This has not been +rigorously tested to be ANSI XJ11 C compliant, but it is close. The +normal output of \fIantlr\fP is currently compilable under both K&R, +ANSI C, and C++\(emthis option does nothing because \fIantlr\fP +generates a bunch of #ifdef's to do the right thing depending on the +language. +.IP \fB-gc\fP +Indicates that \fIantlr\fP should generate no C code, i.e., only +perform analysis on the grammar. +.IP \fB-gd\fP +C code is inserted in each of the \fIantlr\fR generated parsing functions to +provide for user-defined handling of a detailed parse trace. The inserted +code consists of calls to the user-supplied macros or functions called +\fBzzTRACEIN\fR and \fBzzTRACEOUT\fP. The only argument is a +\fIchar *\fR pointing to a C-style string which is the grammar rule +recognized by the current parsing function. If no definition is given +for the trace functions, upon rule entry and exit, a message will be +printed indicating that a particular rule as been entered or exited. +.IP \fB-ge\fP +Generate an error class for each non-terminal. +.IP \fB-gh\fP +Generate \fBstdpccts.h\fP for non-ANTLR-generated files to include. +This file contains all defines needed to describe the type of parser +generated by \fIantlr\fP (e.g. how much lookahead is used and whether +or not trees are constructed) and contains the \fBheader\fP action +specified by the user. +.IP \fB-gk\fP +Generate parsers that delay lookahead fetches until needed. Without +this option, \fIantlr\fP generates parsers which always have \fIk\fP +tokens of lookahead available. +.IP \fB-gl\fP +Generate line info about grammar actions in C parser of the form +\fB#\ \fIline\fP\ "\fIfile\fP"\fR which makes error messages from +the C/C++ compiler make more sense as they will \*Qpoint\*U into the +grammar file not the resulting C file. Debugging is easier as well, +because you will step through the grammar not C file. +.IP \fB-gs\fR +Do not generate sets for token expression lists; instead generate a +\fB||\fP-separated sequence of \fBLA(1)==\fItoken_number\fR. The +default is to generate sets. +.IP \fB-gt\fP +Generate code for Abstract-Syntax Trees. +.IP \fB-gx\fP +Do not create the lexical analyzer files (dlg-related). This option +should be given when the user wishes to provide a customized lexical +analyzer. It may also be used in \fImake\fR scripts to cause only the +parser to be rebuilt when a change not affecting the lexical structure +is made to the input grammars. +.IP "\fB-k \fIn\fR" +Set k of LL(k) to \fIn\fR; i.e. set tokens of look-ahead (default==1). +.IP "\fB-o\fP dir +Directory where output files should go (default="."). This is very +nice for keeping the source directory clear of ANTLR and DLG spawn. +.IP \fB-p\fP +The complete grammar, collected from all input grammar files and +stripped of all comments and embedded actions, is listed to +\fBstdout\fP. This is intended to aid in viewing the entire grammar +as a whole and to eliminate the need to keep actions concisely stated +so that the grammar is easier to read. Hence, it is preferable to +embed even complex actions directly in the grammar, rather than to +call them as subroutines, since the subroutine call overhead will be +saved. +.IP \fB-pa\fP +This option is the same as \fB-p\fP except that the output is +annotated with the first sets determined from grammar analysis. +.IP "\fB-prc on\fR +Turn on the computation and hoisting of predicate context. +.IP "\fB-prc off\fR +Turn off the computation and hoisting of predicate context. This +option makes 1.10 behave like the 1.06 release with option \fB-pr\fR +on. Context computation is off by default. +.IP "\fB-rl \fIn\fR +Limit the maximum number of tree nodes used by grammar analysis to +\fIn\fP. Occasionally, \fIantlr\fP is unable to analyze a grammar +submitted by the user. This rare situation can only occur when the +grammar is large and the amount of lookahead is greater than one. A +nonlinear analysis algorithm is used by PCCTS to handle the general +case of LL(k) parsing. The average complexity of analysis, however, is +near linear due to some fancy footwork in the implementation which +reduces the number of calls to the full LL(k) algorithm. An error +message will be displayed, if this limit is reached, which indicates +the grammar construct being analyzed when \fIantlr\fP hit a +non-linearity. Use this option if \fIantlr\fP seems to go out to +lunch and your disk start thrashing; try \fIn\fP=10000 to start. Once +the offending construct has been identified, try to remove the +ambiguity that \fIantlr\fP was trying to overcome with large lookahead +analysis. The introduction of (...)? backtracking blocks eliminates +some of these problems\ \(em \fIantlr\fP does not analyze alternatives +that begin with (...)? (it simply backtracks, if necessary, at run +time). +.IP \fB-w1\fR +Set low warning level. Do not warn if semantic predicates and/or +(...)? blocks are assumed to cover ambiguous alternatives. +.IP \fB-w2\fR +Ambiguous parsing decisions yield warnings even if semantic predicates +or (...)? blocks are used. Warn if predicate context computed and +semantic predicates incompletely disambiguate alternative productions. +.IP \fB-\fR +Read grammar from standard input and generate \fBstdin.c\fP as the +parser file. +.SH "SPECIAL CONSIDERATIONS" +.PP +\fIAntlr\fP works... we think. There is no implicit guarantee of +anything. We reserve no \fBlegal\fP rights to the software known as +the Purdue Compiler Construction Tool Set (PCCTS) \(em PCCTS is in the +public domain. An individual or company may do whatever they wish +with source code distributed with PCCTS or the code generated by +PCCTS, including the incorporation of PCCTS, or its output, into +commercial software. We encourage users to develop software with +PCCTS. However, we do ask that credit is given to us for developing +PCCTS. By "credit", we mean that if you incorporate our source code +into one of your programs (commercial product, research project, or +otherwise) that you acknowledge this fact somewhere in the +documentation, research report, etc... If you like PCCTS and have +developed a nice tool with the output, please mention that you +developed it using PCCTS. As long as these guidelines are followed, +we expect to continue enhancing this system and expect to make other +tools available as they are completed. +.SH FILES +.IP *.c +output C parser. +.IP *.cpp +output C++ parser when C++ mode is used. +.IP \fBparser.dlg\fP +output \fIdlg\fR lexical analyzer. +.IP \fBerr.c\fP +token string array, error sets and error support routines. Not used in +C++ mode. +.IP \fBremap.h\fP +file that redefines all globally visible parser symbols. The use of +the #parser directive creates this file. Not used in +C++ mode. +.IP \fBstdpccts.h\fP +list of definitions needed by C files, not generated by PCCTS, that +reference PCCTS objects. This is not generated by default. Not used in +C++ mode. +.IP \fBtokens.h\fP +output \fI#defines\fR for tokens used and function prototypes for +functions generated for rules. +.SH "SEE ALSO" +.LP +dlg(1), pccts(1) diff --git a/Tools/CodeTools/Source/Pccts/antlr/antlr.c b/Tools/CodeTools/Source/Pccts/antlr/antlr.c new file mode 100644 index 0000000000..8aaef794e1 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/antlr.c @@ -0,0 +1,3564 @@ +/* + * A n t l r T r a n s l a t i o n H e a d e r + * + * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001 + * Purdue University Electrical Engineering + * With AHPCRC, University of Minnesota + * ANTLR Version 1.33MR33 + * + * ..\bin\antlr -gh antlr.g + * + */ + +#define ANTLR_VERSION 13333 +#include "pcctscfg.h" +#include "pccts_stdio.h" + +#include "pcctscfg.h" +#include "set.h" +#include +#include "syn.h" +#include "hash.h" +#include "generic.h" +#define zzcr_attr(attr,tok,t) +#define zzSET_SIZE 20 +#include "antlr.h" +#include "tokens.h" +#include "dlgdef.h" +#include "mode.h" + +/* MR23 In order to remove calls to PURIFY use the antlr -nopurify option */ + +#ifndef PCCTS_PURIFY +#define PCCTS_PURIFY(r,s) memset((char *) &(r),'\0',(s)); +#endif + +ANTLR_INFO + + +/* MR20 G. Hobbelt For Borland C++ 4.x & 5.x compiling with ALL warnings enabled */ +#if defined(__TURBOC__) +#pragma warn -aus /* unused assignment of 'xxx' */ +#endif + + +#ifdef __USE_PROTOS +static void chkToken(char *, char *, char *, int); +#else +static void chkToken(); +#endif + +#ifdef __USE_PROTOS +static int isDLGmaxToken(char *Token); /* MR3 */ +#else +static int isDLGmaxToken(); /* MR3 */ +#endif + +static int class_nest_level = 0; + +/* MR20 G. Hobbelt extern definitions moved to antlr.h */ + + + +void +#ifdef __USE_PROTOS +grammar(void) +#else +grammar() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + Graph g; + { + zzBLOCK(zztasp2); + zzMake0; + { + for (;;) { + if ( !((setwd1[LA(1)]&0x1))) break; + if ( (LA(1)==94) ) { + zzmatch(94); zzCONSUME; + zzmatch(Action); + + if ( HdrAction==NULL ) { + HdrAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(HdrAction!=NULL, "rule grammar: cannot allocate header action"); + strcpy(HdrAction, LATEXT(1)); + } + else warn("additional #header statement ignored"); + zzCONSUME; + + } + else { + if ( (LA(1)==95) ) { + zzmatch(95); zzCONSUME; + zzmatch(Action); + + if ( FirstAction==NULL ) { + FirstAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(FirstAction!=NULL, "rule grammar: cannot allocate #first action"); + strcpy(FirstAction, LATEXT(1)); + } else { + warn("additional #first statement ignored"); + }; + zzCONSUME; + + } + else { + if ( (LA(1)==96) ) { + zzmatch(96); zzCONSUME; + zzmatch(QuotedTerm); + + if ( GenCC ) { + warn("#parser meta-op incompatible with -CC; ignored"); + } + else { + if ( strcmp(ParserName,"zzparser")==0 ) { + ParserName=StripQuotes(mystrdup(LATEXT(1))); + if ( RulePrefix[0]!='\0' ) + { + warn("#parser meta-op incompatible with '-gp prefix'; '-gp' ignored"); + RulePrefix[0]='\0'; + } + } + else warn("additional #parser statement ignored"); + } + zzCONSUME; + + } + else { + if ( (LA(1)==97) ) { + zzmatch(97); zzCONSUME; + zzmatch(QuotedTerm); + { + char *fname; + zzantlr_state st; FILE *f; struct zzdlg_state dst; + UserTokenDefsFile = mystrdup(LATEXT(1)); + zzsave_antlr_state(&st); + zzsave_dlg_state(&dst); + fname = mystrdup(LATEXT(1)); + f = fopen(StripQuotes(fname), "r"); + if ( f==NULL ) {warn(eMsg1("cannot open token defs file '%s'", fname+1));} + else { + ANTLRm(enum_file(fname+1), f, PARSE_ENUM_FILE); + UserDefdTokens = 1; + } + zzrestore_antlr_state(&st); + zzrestore_dlg_state(&dst); + } + zzCONSUME; + + } + else break; /* MR6 code for exiting loop "for sure" */ + } + } + } + zzLOOP(zztasp2); + } + zzEXIT(zztasp2); + } + } + { + zzBLOCK(zztasp2); + zzMake0; + { + for (;;) { + if ( !((setwd1[LA(1)]&0x2))) break; + if ( (LA(1)==Action) ) { + zzmatch(Action); + { + UserAction *ua = newUserAction(LATEXT(1)); + ua->file = action_file; ua->line = action_line; + if ( class_nest_level>0 ) list_add(&class_before_actions, ua); + else list_add(&BeforeActions, ua); + } + zzCONSUME; + + } + else { + if ( (LA(1)==108) ) { + laction(); + } + else { + if ( (LA(1)==109) ) { + lmember(); + } + else { + if ( (LA(1)==110) ) { + lprefix(); + } + else { + if ( (LA(1)==116) ) { + aLexclass(); + } + else { + if ( (LA(1)==120) ) { + token(); + } + else { + if ( (LA(1)==117) ) { + error(); + } + else { + if ( (LA(1)==118) ) { + tclass(); + } + else { + if ( (LA(1)==111) ) { + aPred(); + } + else { + if ( (LA(1)==133) ) { + default_exception_handler(); + } + else { + if ( (LA(1)==99) ) { + class_def(); + } + else { + if ( (LA(1)==98) ) { + zzmatch(98); + + if ( class_nest_level==0 ) + warn("missing class definition for trailing '}'"); + class_nest_level--; + zzCONSUME; + + } + else break; /* MR6 code for exiting loop "for sure" */ + } + } + } + } + } + } + } + } + } + } + } + zzLOOP(zztasp2); + } + zzEXIT(zztasp2); + } + } + rule(); + g=zzaArg(zztasp1,3); SynDiag = (Junction *) zzaArg(zztasp1,3 ).left; + { + zzBLOCK(zztasp2); + zzMake0; + { + for (;;) { + if ( !((setwd1[LA(1)]&0x4))) break; + if ( (LA(1)==NonTerminal) ) { + rule(); + if ( zzaArg(zztasp2,1 ).left!=NULL ) { + g.right = NULL; + +/* MR21a */ /* Avoid use of a malformed graph when CannotContinue */ + /* MR21a */ /* is already set */ + /* MR21a */ + /* MR21a */ if (! (CannotContinue && g.left == NULL)) { + /* MR21a */ g = Or(g, zzaArg(zztasp2,1)); + /* MR21a */ } + /* MR21a */ } + } + else { + if ( (LA(1)==116) ) { + aLexclass(); + } + else { + if ( (LA(1)==120) ) { + token(); + } + else { + if ( (LA(1)==117) ) { + error(); + } + else { + if ( (LA(1)==118) ) { + tclass(); + } + else { + if ( (LA(1)==111) ) { + aPred(); + } + else { + if ( (LA(1)==99) ) { + class_def(); + } + else { + if ( (LA(1)==98) ) { + zzmatch(98); + + if ( class_nest_level==0 ) + warn("missing class definition for trailing '}'"); + class_nest_level--; + zzCONSUME; + + } + else break; /* MR6 code for exiting loop "for sure" */ + } + } + } + } + } + } + } + zzLOOP(zztasp2); + } + zzEXIT(zztasp2); + } + } + { + zzBLOCK(zztasp2); + zzMake0; + { + for (;;) { + if ( !((setwd1[LA(1)]&0x8))) break; + if ( (LA(1)==Action) ) { + zzmatch(Action); + { + UserAction *ua = newUserAction(LATEXT(1)); + ua->file = action_file; ua->line = action_line; + if ( class_nest_level>0 ) list_add(&class_after_actions, ua); + else list_add(&AfterActions, ua); + } + zzCONSUME; + + } + else { + if ( (LA(1)==108) ) { + laction(); + } + else { + if ( (LA(1)==109) ) { + lmember(); + } + else { + if ( (LA(1)==110) ) { + lprefix(); + } + else { + if ( (LA(1)==117) ) { + error(); + } + else { + if ( (LA(1)==118) ) { + tclass(); + } + else { + if ( (LA(1)==99) ) { + class_def(); + } + else { + if ( (LA(1)==111) ) { + aPred(); + } + else { + if ( (LA(1)==98) ) { + zzmatch(98); + + if ( class_nest_level==0 ) + warn("missing class definition for trailing '}'"); + class_nest_level--; + zzCONSUME; + + } + else break; /* MR6 code for exiting loop "for sure" */ + } + } + } + } + } + } + } + } + zzLOOP(zztasp2); + } + zzEXIT(zztasp2); + } + } + zzmatch(Eof); zzCONSUME; + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + CannotContinue=TRUE; + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd1, 0x10); + } +} + +void +#ifdef __USE_PROTOS +class_def(void) +#else +class_def() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + int go=1; char name[MaxRuleName+1]; + zzmatch(99); zzCONSUME; + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==NonTerminal) ) { + zzmatch(NonTerminal); + if(go) strncpy(name,LATEXT(1),MaxRuleName); + zzCONSUME; + + } + else { + if ( (LA(1)==TokenTerm) ) { + zzmatch(TokenTerm); + if(go) strncpy(name,LATEXT(1),MaxRuleName); + zzCONSUME; + + } + else {zzFAIL(1,zzerr1,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + + if ( CurrentClassName[0]!='\0' && strcmp(CurrentClassName,name)!=0 + && GenCC ) { + err("only one grammar class allowed in this release"); + go = 0; + } + else strcpy(CurrentClassName, name); + if ( !GenCC ) { err("class meta-op used without C++ option"); } + { + zzBLOCK(zztasp2); + zzMake0; + { + while ( (setwd1[LA(1)]&0x20) ) { + zzsetmatch(zzerr2, zzerr3); + if (ClassDeclStuff == NULL) { + /* MR10 */ ClassDeclStuff=(char *)calloc(MaxClassDeclStuff+1,sizeof(char)); + /* MR10 */ }; + /* MR10 */ strncat(ClassDeclStuff," ",MaxClassDeclStuff); + /* MR10 */ strncat(ClassDeclStuff,LATEXT(1),MaxClassDeclStuff); + /* MR22 */ do { + /* MR22 */ if (0 == strcmp(LATEXT(1),"public")) break; + /* MR22 */ if (0 == strcmp(LATEXT(1),"private")) break; + /* MR22 */ if (0 == strcmp(LATEXT(1),"protected")) break; + /* MR22 */ if (0 == strcmp(LATEXT(1),"virtual")) break; + /* MR22 */ if (0 == strcmp(LATEXT(1),",")) break; + /* MR22 */ if (0 == strcmp(LATEXT(1),":")) break; + /* MR22 */ if (BaseClassName != NULL) break; + /* MR22 */ BaseClassName=(char *)calloc(strlen(LATEXT(1))+1,sizeof(char)); + /* MR22 */ require(BaseClassName!=NULL, "rule grammar: cannot allocate base class name"); + /* MR22 */ strcpy(BaseClassName,LATEXT(1)); + /* MR22 */ } while (0); + /* MR10 */ + zzCONSUME; + + zzLOOP(zztasp2); + } + zzEXIT(zztasp2); + } + } + zzmatch(102); + + no_classes_found = 0; + if ( class_nest_level>=1 ) {warn("cannot have nested classes");} + else class_nest_level++; + zzCONSUME; + + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + CannotContinue=TRUE; + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd1, 0x40); + } +} + +void +#ifdef __USE_PROTOS +rule(void) +#else +rule() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + + + ExceptionGroup *eg; + RuleEntry *q; Junction *p; Graph r; int f, l; ECnode *e; + set toksrefd, rulesrefd; + char *pdecl=NULL, *ret=NULL, *a; CurRetDef = CurParmDef = NULL; + CurExGroups = NULL; + CurElementLabels = NULL; + CurAstLabelsInActions = NULL; /* MR27 */ + /* We want a new element label hash table for each rule */ + if ( Elabel!=NULL ) killHashTable(Elabel); + Elabel = newHashTable(); + attribsRefdFromAction = empty; + zzmatch(NonTerminal); + q=NULL; + if ( hash_get(Rname, LATEXT(1))!=NULL ) { + err(eMsg1("duplicate rule definition: '%s'",LATEXT(1))); + CannotContinue=TRUE; + } + else + { + q = (RuleEntry *)hash_add(Rname, + LATEXT(1), + (Entry *)newRuleEntry(LATEXT(1))); + CurRule = q->str; + } + CurRuleNode = q; + f = CurFile; l = zzline; + NumRules++; + zzCONSUME; + + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==103) ) { + zzmatch(103); + if ( q!=NULL ) q->noAST = TRUE; + zzCONSUME; + + } + else { + if ( (setwd1[LA(1)]&0x80) ) { + } + else {zzFAIL(1,zzerr4,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + { + zzBLOCK(zztasp2); + zzMake0; + { + ; + if ( (setwd2[LA(1)]&0x1) ) { + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (LA(1)==104) ) { + zzmatch(104); zzCONSUME; + } + else { + if ( (LA(1)==PassAction) ) { + } + else {zzFAIL(1,zzerr5,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp3); + } + } + zzmatch(PassAction); + pdecl = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(pdecl!=NULL, "rule rule: cannot allocate param decl"); + strcpy(pdecl, LATEXT(1)); + CurParmDef = pdecl; + zzCONSUME; + + } + else { + if ( (setwd2[LA(1)]&0x2) ) { + } + else {zzFAIL(1,zzerr6,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==105) ) { + zzmatch(105); zzCONSUME; + zzmatch(PassAction); + ret = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(ret!=NULL, "rule rule: cannot allocate ret type"); + strcpy(ret, LATEXT(1)); + CurRetDef = ret; + zzCONSUME; + + } + else { + if ( (setwd2[LA(1)]&0x4) ) { + } + else {zzFAIL(1,zzerr7,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==QuotedTerm) ) { + zzmatch(QuotedTerm); + if ( q!=NULL ) q->egroup=mystrdup(LATEXT(1)); + zzCONSUME; + + } + else { + if ( (LA(1)==106) ) { + } + else {zzFAIL(1,zzerr8,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + + if ( GenEClasseForRules && q!=NULL ) { + e = newECnode; + require(e!=NULL, "cannot allocate error class node"); + if ( q->egroup == NULL ) {a = q->str; a[0] = (char)toupper(a[0]);} + else a = q->egroup; + if ( Tnum( a ) == 0 ) + { + e->tok = addTname( a ); + list_add(&eclasses, (char *)e); + if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]); + /* refers to itself */ + list_add(&(e->elist), mystrdup(q->str)); + } + else { + warn(eMsg1("default errclass for '%s' would conflict with token/errclass/tokclass",a)); + if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]); + free((char *)e); + } + } + BlkLevel++; + if (BlkLevel >= MAX_BLK_LEVEL) fatal("Blocks nested too deeply"); + /* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID; + /* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; + zzmatch(106); + inAlt=1; + zzCONSUME; + + block( &toksrefd, &rulesrefd ); + r = makeBlk(zzaArg(zztasp1,7),0, NULL /* pFirstSetSymbol */ ); + CurRuleBlk = (Junction *)r.left; + CurRuleBlk->blockid = CurBlockID; + CurRuleBlk->jtype = RuleBlk; + if ( q!=NULL ) CurRuleBlk->rname = q->str; + CurRuleBlk->file = f; + CurRuleBlk->line = l; + CurRuleBlk->pdecl = pdecl; + CurRuleBlk->ret = ret; + CurRuleBlk->lock = makelocks(); + CurRuleBlk->pred_lock = makelocks(); + CurRuleBlk->tokrefs = toksrefd; + CurRuleBlk->rulerefs = rulesrefd; + p = newJunction(); /* add EndRule Node */ + ((Junction *)r.right)->p1 = (Node *)p; + r.right = (Node *) p; + p->jtype = EndRule; + p->lock = makelocks(); + p->pred_lock = makelocks(); + CurRuleBlk->end = p; + if ( q!=NULL ) q->rulenum = NumRules; + zzaArg(zztasp1,7) = r; + + /* MR23 */ CurBlockID_array[BlkLevel] = (-1); + /* MR23 */ CurAltNum_array[BlkLevel] = (-1); + --BlkLevel; + altFixup();leFixup();egFixup(); + zzmatch(107); + inAlt=0; + zzCONSUME; + + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==Action) ) { + zzmatch(Action); + a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(a!=NULL, "rule rule: cannot allocate error action"); + strcpy(a, LATEXT(1)); + CurRuleBlk->erraction = a; + zzCONSUME; + + } + else { + if ( (setwd2[LA(1)]&0x8) ) { + } + else {zzFAIL(1,zzerr9,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + { + zzBLOCK(zztasp2); + zzMake0; + { + while ( (LA(1)==133) ) { + eg = exception_group(); + + if ( eg!=NULL ) { + list_add(&CurExGroups, (void *)eg); + if (eg->label == NULL || *eg->label=='\0' ) q->has_rule_exception = 1; + } + zzLOOP(zztasp2); + } + zzEXIT(zztasp2); + } + } + if ( q==NULL ) zzaArg(zztasp1,0 ).left = NULL; else zzaArg(zztasp1,0) = zzaArg(zztasp1,7); + CurRuleBlk->exceptions = CurExGroups; + CurRuleBlk->el_labels = CurElementLabels; + CurRuleNode->ast_labels_in_actions = CurAstLabelsInActions; + CurRuleNode = NULL; + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + CannotContinue=TRUE; + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd2, 0x10); + } +} + +void +#ifdef __USE_PROTOS +laction(void) +#else +laction() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + char *a; + zzmatch(108); zzCONSUME; + zzmatch(Action); + + a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(a!=NULL, "rule laction: cannot allocate action"); + strcpy(a, LATEXT(1)); + list_add(&LexActions, a); + zzCONSUME; + + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + CannotContinue=TRUE; + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd2, 0x20); + } +} + +void +#ifdef __USE_PROTOS +lmember(void) +#else +lmember() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + char *a; + zzmatch(109); zzCONSUME; + zzmatch(Action); + + /* MR1 */ if (! GenCC) { + /* MR1 */ err("Use #lexmember only in C++ mode (to insert code in DLG class header"); + /* MR1 */ } else { + /* MR1 */ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + /* MR1 */ require(a!=NULL, "rule lmember: cannot allocate action"); + /* MR1 */ strcpy(a, LATEXT(1)); + /* MR1 */ list_add(&LexMemberActions, a); + /* MR1 */ }; + /* MR1 */ + zzCONSUME; + + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + CannotContinue=TRUE; + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd2, 0x40); + } +} + +void +#ifdef __USE_PROTOS +lprefix(void) +#else +lprefix() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + char *a; + zzmatch(110); zzCONSUME; + zzmatch(Action); + + /* MR1 */ if (! GenCC) { + /* MR1 */ err("Use #lexprefix only in C++ mode (to insert code in DLG class header"); + /* MR1 */ } else { + /* MR1 */ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + /* MR1 */ require(a!=NULL, "rule lprefix: cannot allocate action"); + /* MR1 */ strcpy(a, LATEXT(1)); + /* MR1 */ list_add(&LexPrefixActions, a); + /* MR1 */ }; + /* MR1 */ + zzCONSUME; + + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + CannotContinue=TRUE; + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd2, 0x80); + } +} + +void +#ifdef __USE_PROTOS +aPred(void) +#else +aPred() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + PredEntry *predEntry=NULL; + char *name=NULL; + Predicate *predExpr=NULL; + char *predLiteral=NULL; + int save_file; + int save_line; + int predExprPresent=0; + zzmatch(111); + + MR_usingPredNames=1; /* will need to use -mrhoist version of genPredTree */ + zzCONSUME; + + zzmatch(TokenTerm); + name=mystrdup(LATEXT(1)); + zzCONSUME; + + + /* don't free - referenced in predicates */ + + CurPredName=(char *)calloc(1,strlen(name) + 10); + strcat(CurPredName,"#pred "); + strcat(CurPredName,name); + + predEntry=(PredEntry *) hash_get(Pname,name); + if (predEntry != NULL) { + warnFL(eMsg1("#pred %s previously defined - ignored",name), + FileStr[action_file],action_line); + name=NULL; +}; + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==Pred) ) { + zzmatch(Pred); + predLiteral=mystrdup(LATEXT(1)); + save_line=action_line; + save_file=action_file; + zzCONSUME; + + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (setwd3[LA(1)]&0x1) ) { + predExpr = predOrExpr(); + + predExprPresent=1; + } + else { + if ( (setwd3[LA(1)]&0x2) ) { + } + else {zzFAIL(1,zzerr10,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp3); + } + } + if (predLiteral != NULL && name != NULL) { + + /* + * predExpr may be NULL due to syntax errors + * or simply omitted by the user + */ + + predEntry=newPredEntry(name); + predEntry->file=save_file; + predEntry->line=save_line; + predExpr=MR_predFlatten(predExpr); + predEntry->predLiteral=predLiteral; + if (! predExprPresent || predExpr == NULL) { + predExpr=new_pred(); + predExpr->expr=predLiteral; + predExpr->source=newActionNode(); + predExpr->source->action=predExpr->expr; + predExpr->source->rname=CurPredName; + predExpr->source->line=action_line; + predExpr->source->file=action_file; + predExpr->source->is_predicate=1; + predExpr->k=predicateLookaheadDepth(predExpr->source); + }; + predEntry->pred=predExpr; + hash_add(Pname,name,(Entry *)predEntry); + predExpr=NULL; + }; + predicate_free(predExpr); + } + else { + if ( (setwd3[LA(1)]&0x4) ) { + save_line=zzline; save_file=CurFile; + predExpr = predOrExpr(); + + if (predExpr != NULL && name != NULL) { + predEntry=newPredEntry(name); + predEntry->file=CurFile; + predEntry->line=zzline; + predExpr=MR_predFlatten(predExpr); + predEntry->pred=predExpr; + hash_add(Pname,name,(Entry *)predEntry); + predExpr=NULL; + }; + predicate_free(predExpr); + } + else {zzFAIL(1,zzerr11,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==107) ) { + zzmatch(107); zzCONSUME; + } + else { + if ( (setwd3[LA(1)]&0x8) ) { + } + else {zzFAIL(1,zzerr12,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + predicate_free(predExpr); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd3, 0x10); + } +} + +Predicate * +#ifdef __USE_PROTOS +predOrExpr(void) +#else +predOrExpr() +#endif +{ + Predicate * _retv; + zzRULE; + zzBLOCK(zztasp1); + PCCTS_PURIFY(_retv,sizeof(Predicate * )) + zzMake0; + { + Predicate *ORnode; + Predicate *predExpr; + Predicate **tail=NULL; + predExpr = predAndExpr(); + + + ORnode=new_pred(); + ORnode->expr=PRED_OR_LIST; + if (predExpr != NULL) { + ORnode->down=predExpr; + tail=&predExpr->right; + }; + { + zzBLOCK(zztasp2); + zzMake0; + { + while ( (LA(1)==112) ) { + zzmatch(112); zzCONSUME; + predExpr = predAndExpr(); + + + if (predExpr != NULL) { + *tail=predExpr; + tail=&predExpr->right; + }; + zzLOOP(zztasp2); + } + zzEXIT(zztasp2); + } + } + + _retv=ORnode; + ORnode=NULL; + zzEXIT(zztasp1); + return _retv; +fail: + zzEXIT(zztasp1); + predicate_free(ORnode); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd3, 0x20); + return _retv; + } +} + +Predicate * +#ifdef __USE_PROTOS +predAndExpr(void) +#else +predAndExpr() +#endif +{ + Predicate * _retv; + zzRULE; + zzBLOCK(zztasp1); + PCCTS_PURIFY(_retv,sizeof(Predicate * )) + zzMake0; + { + Predicate *ANDnode; + Predicate *predExpr; + Predicate **tail=NULL; + predExpr = predPrimary(); + + + ANDnode=new_pred(); + ANDnode->expr=PRED_AND_LIST; + if (predExpr != NULL) { + ANDnode->down=predExpr; + tail=&predExpr->right; + }; + { + zzBLOCK(zztasp2); + zzMake0; + { + while ( (LA(1)==113) ) { + zzmatch(113); zzCONSUME; + predExpr = predPrimary(); + + + if (predExpr != NULL) { + *tail=predExpr; + tail=&predExpr->right; + }; + zzLOOP(zztasp2); + } + zzEXIT(zztasp2); + } + } + + _retv=ANDnode; + ANDnode=NULL; + zzEXIT(zztasp1); + return _retv; +fail: + zzEXIT(zztasp1); + predicate_free(ANDnode); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd3, 0x40); + return _retv; + } +} + +Predicate * +#ifdef __USE_PROTOS +predPrimary(void) +#else +predPrimary() +#endif +{ + Predicate * _retv; + zzRULE; + zzBLOCK(zztasp1); + PCCTS_PURIFY(_retv,sizeof(Predicate * )) + zzMake0; + { + + char *name=NULL; + PredEntry *predEntry=NULL; + Predicate *predExpr=NULL; + if ( (LA(1)==TokenTerm) ) { + zzmatch(TokenTerm); + name=mystrdup(LATEXT(1)); + zzCONSUME; + + + predEntry=(PredEntry *) hash_get(Pname,name); + if (predEntry == NULL) { + warnFL(eMsg1("no previously defined #pred with name \"%s\"",name), + FileStr[CurFile],zzline); + name=NULL; + _retv=NULL; + } else { + predExpr=predicate_dup(predEntry->pred); + predExpr->predEntry=predEntry; + _retv=predExpr; + }; + } + else { + if ( (LA(1)==114) ) { + zzmatch(114); zzCONSUME; + predExpr = predOrExpr(); + + zzmatch(115); + + _retv=predExpr; + zzCONSUME; + + } + else { + if ( (LA(1)==103) ) { + zzmatch(103); zzCONSUME; + predExpr = predPrimary(); + + + predExpr->inverted=!predExpr->inverted; + _retv=predExpr; + } + else {zzFAIL(1,zzerr13,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + } + zzEXIT(zztasp1); + return _retv; +fail: + zzEXIT(zztasp1); + + predicate_free(predExpr); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd3, 0x80); + return _retv; + } +} + +void +#ifdef __USE_PROTOS +aLexclass(void) +#else +aLexclass() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + zzmatch(116); zzCONSUME; + zzmatch(TokenTerm); + lexclass(mystrdup(LATEXT(1))); + zzCONSUME; + + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + CannotContinue=TRUE; + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd4, 0x1); + } +} + +void +#ifdef __USE_PROTOS +error(void) +#else +error() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + char *t=NULL; ECnode *e; int go=1; TermEntry *p; + zzmatch(117); zzCONSUME; + { + zzBLOCK(zztasp2); + zzMake0; + { + ; + if ( (LA(1)==TokenTerm) ) { + zzmatch(TokenTerm); + t=mystrdup(LATEXT(1)); + zzCONSUME; + + } + else { + if ( (LA(1)==QuotedTerm) ) { + zzmatch(QuotedTerm); + t=mystrdup(LATEXT(1)); + zzCONSUME; + + } + else {zzFAIL(1,zzerr14,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + e = newECnode; + require(e!=NULL, "cannot allocate error class node"); + e->lexclass = CurrentLexClass; + if ( Tnum( (t=StripQuotes(t)) ) == 0 ) + { + if ( hash_get(Texpr, t) != NULL ) + warn(eMsg1("errclass name conflicts with regular expression '%s'",t)); + e->tok = addTname( t ); + set_orel(e->tok, &imag_tokens); + require((p=(TermEntry *)hash_get(Tname, t)) != NULL, + "hash table mechanism is broken"); + p->classname = 1; /* entry is errclass name, not token */ + list_add(&eclasses, (char *)e); + } + else + { + warn(eMsg1("redefinition of errclass or conflict w/token or tokclass '%s'; ignored",t)); + free( (char *)e ); + go=0; +} + zzmatch(102); zzCONSUME; + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==NonTerminal) ) { + zzmatch(NonTerminal); + if ( go ) t=mystrdup(LATEXT(1)); + zzCONSUME; + + } + else { + if ( (LA(1)==TokenTerm) ) { + zzmatch(TokenTerm); + if ( go ) t=mystrdup(LATEXT(1)); + zzCONSUME; + + } + else { + if ( (LA(1)==QuotedTerm) ) { + zzmatch(QuotedTerm); + if ( go ) t=mystrdup(LATEXT(1)); + zzCONSUME; + + } + else {zzFAIL(1,zzerr15,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + } + zzEXIT(zztasp2); + } + } + if ( go ) list_add(&(e->elist), t); + { + zzBLOCK(zztasp2); + zzMake0; + { + while ( (setwd4[LA(1)]&0x2) ) { + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (LA(1)==NonTerminal) ) { + zzmatch(NonTerminal); + if ( go ) t=mystrdup(LATEXT(1)); + zzCONSUME; + + } + else { + if ( (LA(1)==TokenTerm) ) { + zzmatch(TokenTerm); + if ( go ) t=mystrdup(LATEXT(1)); + zzCONSUME; + + } + else { + if ( (LA(1)==QuotedTerm) ) { + zzmatch(QuotedTerm); + if ( go ) t=mystrdup(LATEXT(1)); + zzCONSUME; + + } + else {zzFAIL(1,zzerr16,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + } + zzEXIT(zztasp3); + } + } + if ( go ) list_add(&(e->elist), t); + zzLOOP(zztasp2); + } + zzEXIT(zztasp2); + } + } + zzmatch(98); zzCONSUME; + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + CannotContinue=TRUE; + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd4, 0x4); + } +} + +void +#ifdef __USE_PROTOS +tclass(void) +#else +tclass() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + char *t=NULL; TCnode *e; int go=1,tok,totok; TermEntry *p, *term, *toterm; + char *akaString=NULL; int save_file; int save_line; + char *totext=NULL; + zzmatch(118); zzCONSUME; + zzmatch(TokenTerm); + t=mystrdup(LATEXT(1)); + zzCONSUME; + + e = newTCnode; + require(e!=NULL, "cannot allocate token class node"); + e->lexclass = CurrentLexClass; + if ( Tnum( t ) == 0 ) + { + e->tok = addTname( t ); + set_orel(e->tok, &imag_tokens); + set_orel(e->tok, &tokclasses); + require((p=(TermEntry *)hash_get(Tname, t)) != NULL, + "hash table mechanism is broken"); + p->classname = 1; /* entry is class name, not token */ + p->tclass = e; /* save ptr to this tclass def */ + list_add(&tclasses, (char *)e); + } + else + { + warn(eMsg1("redefinition of tokclass or conflict w/token '%s'; ignored",t)); + free( (char *)e ); + go=0; +} + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==114) ) { + zzmatch(114); zzCONSUME; + zzmatch(QuotedTerm); + akaString=mystrdup(StripQuotes(LATEXT(1))); + /* MR11 */ save_file=CurFile;save_line=zzline; + /* MR23 */ + zzCONSUME; + + zzmatch(115); zzCONSUME; + } + else { + if ( (LA(1)==102) ) { + } + else {zzFAIL(1,zzerr17,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + + /* MR23 */ if (p!= NULL && akaString != NULL) { + /* MR23 */ if (p->akaString != NULL) { + /* MR23 */ if (strcmp(p->akaString,akaString) != 0) { + /* MR23 */ warnFL(eMsg2("this #tokclass statment conflicts with a previous #tokclass %s(\"%s\") statement", + /* MR23 */ t,p->akaString), + /* MR23 */ FileStr[save_file],save_line); + /* MR23 */ }; + /* MR23 */ } else { + /* MR23 */ p->akaString=akaString; + /* MR23 */ }; + /* MR23 */ }; + /* MR23 */ + zzmatch(102); zzCONSUME; + { + zzBLOCK(zztasp2); + int zzcnt=1; + zzMake0; + { + do { + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (LA(1)==TokenTerm) ) { + zzmatch(TokenTerm); + if ( go ) { + term = (TermEntry *) hash_get(Tname, LATEXT(1)); + if ( term==NULL && UserDefdTokens ) { + err("implicit token definition not allowed with #tokdefs"); + go = 0; + } + else {t=mystrdup(LATEXT(1)); tok=addTname(LATEXT(1));} + } + zzCONSUME; + + { + zzBLOCK(zztasp4); + zzMake0; + { + if ( (LA(1)==119) ) { + zzmatch(119); zzCONSUME; + zzmatch(TokenTerm); + if ( go ) { + toterm = (TermEntry *) hash_get(Tname, LATEXT(1)); + if ( toterm==NULL && UserDefdTokens ) { + err("implicit token definition not allowed with #tokdefs"); + go = 0; + } else { + totext=mystrdup(LATEXT(1)); totok=addTname(LATEXT(1)); + } + } + zzCONSUME; + + } + else { + if ( (setwd4[LA(1)]&0x8) ) { + } + else {zzFAIL(1,zzerr18,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp4); + } + } + } + else { + if ( (LA(1)==QuotedTerm) ) { + zzmatch(QuotedTerm); + if ( go ) { + term = (TermEntry *) hash_get(Texpr, LATEXT(1)); + if ( term==NULL && UserDefdTokens ) { + err("implicit token definition not allowed with #tokdefs"); + go = 0; + } + else {t=mystrdup(LATEXT(1)); tok=addTexpr(LATEXT(1));} + } + zzCONSUME; + + } + else {zzFAIL(1,zzerr19,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp3); + } + } + if ( go ) { + if (totext == NULL) { + list_add(&(e->tlist), t); + } else { + list_add(&(e->tlist),".."); + list_add(&(e->tlist),t); + list_add(&(e->tlist),totext); + } + totext=NULL; + } + zzLOOP(zztasp2); + } while ( (setwd4[LA(1)]&0x10) ); + zzEXIT(zztasp2); + } + } + zzmatch(98); zzCONSUME; + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + CannotContinue=TRUE; + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd4, 0x20); + } +} + +void +#ifdef __USE_PROTOS +token(void) +#else +token() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + char *t=NULL, *e=NULL, *a=NULL; int tnum=0; + char *akaString=NULL; TermEntry *te;int save_file=0,save_line=0; + zzmatch(120); + tokenActionActive=1; + zzCONSUME; + + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==TokenTerm) ) { + zzmatch(TokenTerm); + t=mystrdup(LATEXT(1)); + zzCONSUME; + + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (LA(1)==114) ) { + zzmatch(114); zzCONSUME; + zzmatch(QuotedTerm); + akaString=mystrdup(StripQuotes(LATEXT(1))); + /* MR11 */ save_file=CurFile;save_line=zzline; + /* MR11 */ + zzCONSUME; + + zzmatch(115); zzCONSUME; + } + else { + if ( (setwd4[LA(1)]&0x40) ) { + } + else {zzFAIL(1,zzerr20,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp3); + } + } + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (LA(1)==121) ) { + zzmatch(121); zzCONSUME; + zzmatch(122); + tnum = atoi(LATEXT(1)); + zzCONSUME; + + } + else { + if ( (setwd4[LA(1)]&0x80) ) { + } + else {zzFAIL(1,zzerr21,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp3); + } + } + } + else { + if ( (setwd5[LA(1)]&0x1) ) { + } + else {zzFAIL(1,zzerr22,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==QuotedTerm) ) { + zzmatch(QuotedTerm); + e=mystrdup(LATEXT(1)); + zzCONSUME; + + } + else { + if ( (setwd5[LA(1)]&0x2) ) { + } + else {zzFAIL(1,zzerr23,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==Action) ) { + zzmatch(Action); + + a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(a!=NULL, "rule token: cannot allocate action"); + strcpy(a, LATEXT(1)); + zzCONSUME; + + } + else { + if ( (setwd5[LA(1)]&0x4) ) { + } + else {zzFAIL(1,zzerr24,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==107) ) { + zzmatch(107); zzCONSUME; + } + else { + if ( (setwd5[LA(1)]&0x8) ) { + } + else {zzFAIL(1,zzerr25,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + chkToken(t, e, a, tnum); + if (t != NULL) { + te=(TermEntry *)hash_get(Tname,t); + if (te != NULL && akaString != NULL) { + if (te->akaString != NULL) { + if (strcmp(te->akaString,akaString) != 0) { + warnFL(eMsg2("this #token statment conflicts with a previous #token %s(\"%s\") statement", + t,te->akaString), + FileStr[save_file],save_line); + }; + } else { + te->akaString=akaString; + }; + }; + }; + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + CannotContinue=TRUE; + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd5, 0x10); + } +} + +void +#ifdef __USE_PROTOS +block(set * toksrefd,set * rulesrefd) +#else +block(toksrefd,rulesrefd) + set *toksrefd; +set *rulesrefd ; +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + + Graph g, b; + set saveblah; + int saveinalt = inAlt; + ExceptionGroup *eg; + * toksrefd = empty; + * rulesrefd = empty; + set_clr(AST_nodes_refd_in_actions); + CurBlockID++; + /* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID; + CurAltNum = 1; + /* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; + saveblah = attribsRefdFromAction; + attribsRefdFromAction = empty; + alt( toksrefd,rulesrefd ); + b = g = zzaArg(zztasp1,1); + + if ( ((Junction *)g.left)->p1->ntype == nAction ) + { + ActionNode *actionNode=(ActionNode *) + ( ( (Junction *)g.left) ->p1); + if (!actionNode->is_predicate ) + { + actionNode->init_action = TRUE; + /* MR12c */ if (actionNode->noHoist) { + /* MR12c */ errFL("<> appears as init-action - use <<>> <>", + /* MR12c */ FileStr[actionNode->file],actionNode->line); + /* MR12c */ }; + } + } + ((Junction *)g.left)->blockid = CurBlockID; + { + zzBLOCK(zztasp2); + zzMake0; + { + while ( (LA(1)==133) ) { + eg = exception_group(); + + + if ( eg!=NULL ) { + /* MR7 ***** eg->altID = makeAltID(CurBlockID,CurAltNum); *****/ + /* MR7 ***** CurAltStart->exception_label = eg->altID; *****/ + list_add(&CurExGroups, (void *)eg); + } + zzLOOP(zztasp2); + } + zzEXIT(zztasp2); + } + } + CurAltNum++; + /* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; + { + zzBLOCK(zztasp2); + zzMake0; + { + while ( (LA(1)==123) ) { + zzmatch(123); + inAlt=1; + zzCONSUME; + + alt( toksrefd,rulesrefd ); + g = Or(g, zzaArg(zztasp2,2)); + + ((Junction *)g.left)->blockid = CurBlockID; + { + zzBLOCK(zztasp3); + zzMake0; + { + while ( (LA(1)==133) ) { + eg = exception_group(); + + + if ( eg!=NULL ) { + /* MR7 ***** eg->altID = makeAltID(CurBlockID,CurAltNum); *****/ + /* MR7 ***** CurAltStart->exception_label = eg->altID; *****/ + list_add(&CurExGroups, (void *)eg); + } + zzLOOP(zztasp3); + } + zzEXIT(zztasp3); + } + } + CurAltNum++; + /* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; + zzLOOP(zztasp2); + } + zzEXIT(zztasp2); + } + } + zzaArg(zztasp1,0) = b; + attribsRefdFromAction = saveblah; inAlt = saveinalt; + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + CannotContinue=TRUE; + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd5, 0x20); + } +} + +void +#ifdef __USE_PROTOS +alt(set * toksrefd,set * rulesrefd) +#else +alt(toksrefd,rulesrefd) + set *toksrefd; +set *rulesrefd ; +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + int n=0; Graph g; int e_num=0, old_not=0; Node *node; set elems, dif; + int first_on_line = 1, use_def_MT_handler = 0; + g.left=NULL; g.right=NULL; + + CurAltStart = NULL; + elems = empty; + inAlt = 1; + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==88) ) { + zzmatch(88); + use_def_MT_handler = 1; + zzCONSUME; + + } + else { + if ( (setwd5[LA(1)]&0x40) ) { + } + else {zzFAIL(1,zzerr26,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + { + zzBLOCK(zztasp2); + zzMake0; + { + ; + while ( (setwd5[LA(1)]&0x80) ) { + { + zzBLOCK(zztasp3); + zzMake0; + { + old_not=0; + if ( (LA(1)==124) ) { + zzmatch(124); + old_not=1; + zzCONSUME; + + } + else { + if ( (setwd6[LA(1)]&0x1) ) { + } + else {zzFAIL(1,zzerr27,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp3); + } + } + node = element( old_not, first_on_line, use_def_MT_handler ); + + if ( node!=NULL && node->ntype!=nAction ) first_on_line = 0; + + if ( zzaArg(zztasp2,2 ).left!=NULL ) { + g = Cat(g, zzaArg(zztasp2,2)); + n++; + if ( node!=NULL ) { + if ( node->ntype!=nAction ) e_num++; + /* record record number of all rule and token refs */ + if ( node->ntype==nToken ) { + TokNode *tk = (TokNode *)((Junction *)zzaArg(zztasp2,2 ).left)->p1; + tk->elnum = e_num; + set_orel(e_num, &elems); + } + else if ( node->ntype==nRuleRef ) { + RuleRefNode *rn = (RuleRefNode *)((Junction *)zzaArg(zztasp2,2 ).left)->p1; + rn->elnum = e_num; + set_orel(e_num, rulesrefd); + } + } + } + zzLOOP(zztasp2); + } + zzEXIT(zztasp2); + } + } + if ( n == 0 ) g = emptyAlt(); + zzaArg(zztasp1,0) = g; + /* We want to reduce number of LT(i) calls and the number of + * local attribute variables in C++ mode (for moment, later we'll + * do for C also). However, if trees are being built, they + * require most of the attrib variables to create the tree nodes + * with; therefore, we gen a token ptr for each token ref in C++ + */ + if ( GenCC && !GenAST ) + { + /* This now free's the temp set -ATG 5/6/95 */ + set temp; + temp = set_and(elems, attribsRefdFromAction); + set_orin( toksrefd, temp); + set_free(temp); +} +else set_orin( toksrefd, elems); +if ( GenCC ) { + dif = set_dif(attribsRefdFromAction, elems); + if ( set_deg(dif)>0 ) + err("one or more $i in action(s) refer to non-token elements"); + set_free(dif); +} +set_free(elems); +set_free(attribsRefdFromAction); +inAlt = 0; + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + CannotContinue=TRUE; + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd6, 0x2); + } +} + +LabelEntry * +#ifdef __USE_PROTOS +element_label(void) +#else +element_label() +#endif +{ + LabelEntry * _retv; + zzRULE; + zzBLOCK(zztasp1); + PCCTS_PURIFY(_retv,sizeof(LabelEntry * )) + zzMake0; + { + TermEntry *t=NULL; LabelEntry *l=NULL; RuleEntry *r=NULL; char *lab; + zzmatch(LABEL); + lab = mystrdup(LATEXT(1)); + zzCONSUME; + + + UsedNewStyleLabel = 1; + if ( UsedOldStyleAttrib ) err("cannot mix with new-style labels with old-style $i"); + t = (TermEntry *) hash_get(Tname, lab); + if ( t==NULL ) t = (TermEntry *) hash_get(Texpr, lab); + if ( t==NULL ) r = (RuleEntry *) hash_get(Rname, lab); + if ( t!=NULL ) { + err(eMsg1("label definition clashes with token/tokclass definition: '%s'", lab)); + _retv = NULL; + } + else if ( r!=NULL ) { + err(eMsg1("label definition clashes with rule definition: '%s'", lab)); + _retv = NULL; + } + else { + /* we don't clash with anybody else */ + l = (LabelEntry *) hash_get(Elabel, lab); + if ( l==NULL ) { /* ok to add new element label */ + l = (LabelEntry *)hash_add(Elabel, + lab, + (Entry *)newLabelEntry(lab)); + /* add to list of element labels for this rule */ + list_add(&CurElementLabels, (void *)lab); + /* MR7 */ leAdd(l); /* list of labels waiting for exception group definitions */ + _retv = l; + } + else { + err(eMsg1("label definitions must be unique per rule: '%s'", lab)); + _retv = NULL; +} +} + zzmatch(106); zzCONSUME; + zzEXIT(zztasp1); + return _retv; +fail: + zzEXIT(zztasp1); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd6, 0x4); + return _retv; + } +} + +Node * +#ifdef __USE_PROTOS +element(int old_not,int first_on_line,int use_def_MT_handler) +#else +element(old_not,first_on_line,use_def_MT_handler) + int old_not; +int first_on_line; +int use_def_MT_handler ; +#endif +{ + Node * _retv; + zzRULE; + zzBLOCK(zztasp1); + PCCTS_PURIFY(_retv,sizeof(Node * )) + zzMake0; + { + + Attrib blk; + Predicate *pred = NULL; + int local_use_def_MT_handler=0; + ActionNode *act; + RuleRefNode *rr; + set toksrefd, rulesrefd; + TermEntry *term; + TokNode *p=NULL; RuleRefNode *q; int approx=0; + LabelEntry *label=NULL; + int predMsgDone=0; + int semDepth=0; + int ampersandStyle; + int height; /* MR11 */ + int equal_height; /* MR11 */ + + char* pFirstSetSymbol = NULL; /* MR21 */ + + _retv = NULL; + if ( (setwd6[LA(1)]&0x8) ) { + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==LABEL) ) { + label = element_label(); + + } + else { + if ( (setwd6[LA(1)]&0x10) ) { + } + else {zzFAIL(1,zzerr28,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==TokenTerm) ) { + zzmatch(TokenTerm); + + term = (TermEntry *) hash_get(Tname, LATEXT(1)); + if ( term==NULL && UserDefdTokens ) { + err("implicit token definition not allowed with #tokdefs"); + zzaRet.left = zzaRet.right = NULL; + } + else { + zzaRet = buildToken(LATEXT(1)); + p=((TokNode *)((Junction *)zzaRet.left)->p1); + term = (TermEntry *) hash_get(Tname, LATEXT(1)); + require( term!= NULL, "hash table mechanism is broken"); + p->tclass = term->tclass; + p->complement = old_not; + if ( label!=NULL ) { + p->el_label = label->str; + label->elem = (Node *)p; + } + } + zzCONSUME; + + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (LA(1)==119) ) { + zzmatch(119); zzCONSUME; + { + zzBLOCK(zztasp4); + zzMake0; + { + if ( (LA(1)==QuotedTerm) ) { + zzmatch(QuotedTerm); + if ( p!=NULL ) setUpperRange(p, LATEXT(1)); + zzCONSUME; + + } + else { + if ( (LA(1)==TokenTerm) ) { + zzmatch(TokenTerm); + if ( p!=NULL ) setUpperRange(p, LATEXT(1)); + zzCONSUME; + + } + else {zzFAIL(1,zzerr29,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp4); + } + } + } + else { + if ( (setwd6[LA(1)]&0x20) ) { + } + else {zzFAIL(1,zzerr30,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp3); + } + } + + if ( p!=NULL && (p->upper_range!=0 || p->tclass || old_not) ) + list_add(&MetaTokenNodes, (void *)p); + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (LA(1)==125) ) { + zzmatch(125); + if ( p!=NULL ) p->astnode=ASTroot; + zzCONSUME; + + } + else { + if ( (setwd6[LA(1)]&0x40) ) { + if ( p!=NULL ) p->astnode=ASTchild; + } + else { + if ( (LA(1)==103) ) { + zzmatch(103); + if ( p!=NULL ) p->astnode=ASTexclude; + zzCONSUME; + + } + else {zzFAIL(1,zzerr31,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + } + zzEXIT(zztasp3); + } + } + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (LA(1)==88) ) { + zzmatch(88); + local_use_def_MT_handler = 1; + zzCONSUME; + + } + else { + if ( (setwd6[LA(1)]&0x80) ) { + } + else {zzFAIL(1,zzerr32,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp3); + } + } + + if ( p!=NULL && first_on_line ) { + CurAltStart = (Junction *)zzaRet.left; + altAdd(CurAltStart); /* MR7 */ + p->altstart = CurAltStart; + } + if ( p!=NULL ) + p->use_def_MT_handler = use_def_MT_handler || local_use_def_MT_handler; + _retv = (Node *)p; + } + else { + if ( (LA(1)==QuotedTerm) ) { + zzmatch(QuotedTerm); + + term = (TermEntry *) hash_get(Texpr, LATEXT(1)); + if ( term==NULL && UserDefdTokens ) { + err("implicit token definition not allowed with #tokdefs"); + zzaRet.left = zzaRet.right = NULL; + } + else { + zzaRet = buildToken(LATEXT(1)); p=((TokNode *)((Junction *)zzaRet.left)->p1); + p->complement = old_not; + if ( label!=NULL ) { + p->el_label = label->str; + label->elem = (Node *)p; + } + } + zzCONSUME; + + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (LA(1)==119) ) { + zzmatch(119); zzCONSUME; + { + zzBLOCK(zztasp4); + zzMake0; + { + if ( (LA(1)==QuotedTerm) ) { + zzmatch(QuotedTerm); + if ( p!=NULL ) setUpperRange(p, LATEXT(1)); + zzCONSUME; + + } + else { + if ( (LA(1)==TokenTerm) ) { + zzmatch(TokenTerm); + if ( p!=NULL ) setUpperRange(p, LATEXT(1)); + zzCONSUME; + + } + else {zzFAIL(1,zzerr33,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp4); + } + } + } + else { + if ( (setwd7[LA(1)]&0x1) ) { + } + else {zzFAIL(1,zzerr34,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp3); + } + } + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (LA(1)==125) ) { + zzmatch(125); + if ( p!=NULL ) p->astnode=ASTroot; + zzCONSUME; + + } + else { + if ( (setwd7[LA(1)]&0x2) ) { + if ( p!=NULL ) p->astnode=ASTchild; + } + else { + if ( (LA(1)==103) ) { + zzmatch(103); + if ( p!=NULL ) p->astnode=ASTexclude; + zzCONSUME; + + } + else {zzFAIL(1,zzerr35,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + } + zzEXIT(zztasp3); + } + } + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (LA(1)==88) ) { + zzmatch(88); + local_use_def_MT_handler = 1; + zzCONSUME; + + } + else { + if ( (setwd7[LA(1)]&0x4) ) { + } + else {zzFAIL(1,zzerr36,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp3); + } + } + + if ( p!=NULL && (p->upper_range!=0 || p->tclass || old_not) ) + list_add(&MetaTokenNodes, (void *)p); + + if ( first_on_line ) { + CurAltStart = (Junction *)zzaRet.left; + altAdd(CurAltStart); /* MR7 */ + p->altstart = CurAltStart; + } + if ( p!=NULL ) + p->use_def_MT_handler = use_def_MT_handler || local_use_def_MT_handler; + _retv = (Node *)p; + } + else { + if ( (LA(1)==WildCard) ) { + if ( old_not ) warn("~ WILDCARD is an undefined operation (implies 'nothing')"); + zzmatch(WildCard); + zzaRet = buildWildCard(LATEXT(1)); p=((TokNode *)((Junction *)zzaRet.left)->p1); + zzCONSUME; + + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (LA(1)==125) ) { + zzmatch(125); + p->astnode=ASTroot; + zzCONSUME; + + } + else { + if ( (setwd7[LA(1)]&0x8) ) { + p->astnode=ASTchild; + } + else { + if ( (LA(1)==103) ) { + zzmatch(103); + p->astnode=ASTexclude; + zzCONSUME; + + } + else {zzFAIL(1,zzerr37,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + } + zzEXIT(zztasp3); + } + } + list_add(&MetaTokenNodes, (void *)p); + + if ( first_on_line ) { + CurAltStart = (Junction *)zzaRet.left; + altAdd(CurAltStart); /* MR7 */ + p->altstart = CurAltStart; + if ( label!=NULL ) { + p->el_label = label->str; + label->elem = (Node *)p; + } + } + _retv = (Node *)p; + } + else { + if ( (LA(1)==NonTerminal) ) { + if ( old_not ) warn("~ NONTERMINAL is an undefined operation"); + zzmatch(NonTerminal); + zzaRet = buildRuleRef(LATEXT(1)); + zzCONSUME; + + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (LA(1)==103) ) { + zzmatch(103); + q = (RuleRefNode *) ((Junction *)zzaRet.left)->p1; + q->astnode=ASTexclude; + zzCONSUME; + + } + else { + if ( (setwd7[LA(1)]&0x10) ) { + } + else {zzFAIL(1,zzerr38,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp3); + } + } + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (setwd7[LA(1)]&0x20) ) { + { + zzBLOCK(zztasp4); + zzMake0; + { + if ( (LA(1)==104) ) { + zzmatch(104); zzCONSUME; + } + else { + if ( (LA(1)==PassAction) ) { + } + else {zzFAIL(1,zzerr39,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp4); + } + } + zzmatch(PassAction); + addParm(((Junction *)zzaRet.left)->p1, LATEXT(1)); + zzCONSUME; + + } + else { + if ( (setwd7[LA(1)]&0x40) ) { + } + else {zzFAIL(1,zzerr40,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp3); + } + } + rr=(RuleRefNode *) ((Junction *)zzaRet.left)->p1; + { + zzBLOCK(zztasp3); + zzMake0; + { + char *a; + if ( (LA(1)==105) ) { + zzmatch(105); zzCONSUME; + zzmatch(PassAction); + + a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(a!=NULL, "rule element: cannot allocate assignment"); + strcpy(a, LATEXT(1)); + rr->assign = a; + zzCONSUME; + + } + else { + if ( (setwd7[LA(1)]&0x80) ) { + } + else {zzFAIL(1,zzerr41,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp3); + } + } + + if ( label!=NULL ) { + rr->el_label = label->str; + label->elem = (Node *)rr; + } + if ( first_on_line ) { + CurAltStart = (Junction *)zzaRet.left; + altAdd(CurAltStart); /* MR7 */ + ((RuleRefNode *)((Junction *)zzaRet.left)->p1)->altstart = CurAltStart; + } + _retv = (Node *)rr; + } + else {zzFAIL(1,zzerr42,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + } + } + zzEXIT(zztasp2); + } + } + } + else { + if ( (LA(1)==Action) ) { + if ( old_not ) warn("~ ACTION is an undefined operation"); + zzmatch(Action); + zzaArg(zztasp1,0) = buildAction(LATEXT(1),action_file,action_line, 0); + zzCONSUME; + + if ( first_on_line ) { /* MR7 */ + CurAltStart = (Junction *)zzaArg(zztasp1,0 ).left; /* MR7 */ + altAdd(CurAltStart); /* MR7 */ + }; + _retv = (Node *) ((Junction *)zzaArg(zztasp1,0 ).left)->p1; + } + else { + if ( (LA(1)==Pred) ) { + if ( old_not ) warn("~ SEMANTIC-PREDICATE is an undefined operation"); + zzmatch(Pred); + zzaArg(zztasp1,0) = buildAction(LATEXT(1),action_file,action_line, 1); + zzCONSUME; + + act = (ActionNode *) ((Junction *)zzaArg(zztasp1,0 ).left)->p1; + if (numericActionLabel) { /* MR10 */ + list_add(&NumericPredLabels,act); /* MR10 */ + numericActionLabel=0; /* MR10 */ + }; /* MR10 */ + { + zzBLOCK(zztasp2); + zzMake0; + { + char *a; + if ( (LA(1)==PassAction) ) { + zzmatch(PassAction); + + a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(a!=NULL, "rule element: cannot allocate predicate fail action"); + strcpy(a, LATEXT(1)); + act->pred_fail = a; + zzCONSUME; + + } + else { + if ( (setwd8[LA(1)]&0x1) ) { + } + else {zzFAIL(1,zzerr43,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + if ( first_on_line ) { /* MR7 */ + CurAltStart = (Junction *)zzaArg(zztasp1,0 ).left; /* MR7 */ + altAdd(CurAltStart); /* MR7 */ + }; + _retv = (Node *)act; + } + else { + if ( (setwd8[LA(1)]&0x2) ) { + if ( old_not ) warn("~ BLOCK is an undefined operation"); + BlkLevel++; + if (BlkLevel >= MAX_BLK_LEVEL) fatal("Blocks nested too deeply"); + /* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID; + /* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==Pragma) ) { + zzmatch(Pragma); zzCONSUME; + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (LA(1)==126) ) { + zzmatch(126); + approx=LL_k; + zzCONSUME; + + } + else { + if ( (LA(1)==127) ) { + zzmatch(127); + approx = 1; + zzCONSUME; + + } + else { + if ( (LA(1)==128) ) { + zzmatch(128); + approx = 2; + zzCONSUME; + + } + else {zzFAIL(1,zzerr44,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + } + zzEXIT(zztasp3); + } + } + } + else { + if ( (setwd8[LA(1)]&0x4) ) { + } + else {zzFAIL(1,zzerr45,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==FirstSetSymbol) ) { + zzmatch(FirstSetSymbol); zzCONSUME; + zzmatch(114); zzCONSUME; + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (LA(1)==NonTerminal) ) { + zzmatch(NonTerminal); + + /* MR21 */ pFirstSetSymbol = (char *) calloc(strlen(LATEXT(1))+1, + /* MR21 */ sizeof(char)); + /* MR21 */ require(pFirstSetSymbol!=NULL, + /* MR21 */ "cannot allocate first set name"); + /* MR21 */ strcpy(pFirstSetSymbol, LATEXT(1)); + /* MR21 */ + zzCONSUME; + + } + else { + if ( (LA(1)==TokenTerm) ) { + zzmatch(TokenTerm); + + /* MR21 */ pFirstSetSymbol = (char *) calloc(strlen(LATEXT(1))+1, + /* MR21 */ sizeof(char)); + /* MR21 */ require(pFirstSetSymbol!=NULL, + /* MR21 */ "cannot allocate first set name"); + /* MR21 */ strcpy(pFirstSetSymbol, LATEXT(1)); + /* MR21 */ + zzCONSUME; + + } + else {zzFAIL(1,zzerr46,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp3); + } + } + zzmatch(115); zzCONSUME; + } + else { + if ( (setwd8[LA(1)]&0x8) ) { + } + else {zzFAIL(1,zzerr47,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==114) ) { + zzmatch(114); zzCONSUME; + block( &toksrefd,&rulesrefd ); + zzmatch(115); + blk = zzaRet = zzaArg(zztasp2,2); + /* MR23 */ CurBlockID_array[BlkLevel] = (-1); + /* MR23 */ CurAltNum_array[BlkLevel] = (-1); + --BlkLevel; + zzCONSUME; + + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (LA(1)==129) ) { + zzmatch(129); + zzaRet = makeLoop(zzaRet,approx,pFirstSetSymbol); + zzCONSUME; + + } + else { + if ( (LA(1)==130) ) { + zzmatch(130); + zzaRet = makePlus(zzaRet,approx,pFirstSetSymbol); + zzCONSUME; + + } + else { + if ( (LA(1)==131) ) { + zzmatch(131); zzCONSUME; + { + zzBLOCK(zztasp4); + zzMake0; + { + if ( (setwd8[LA(1)]&0x10) ) { + { + zzBLOCK(zztasp5); + zzMake0; + { + if ( (LA(1)==132) ) { + zzmatch(132); + ampersandStyle=0; + zzCONSUME; + + } + else { + if ( (LA(1)==113) ) { + zzmatch(113); + ampersandStyle=1; + zzCONSUME; + + } + else {zzFAIL(1,zzerr48,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp5); + } + } + zzmatch(Pred); + zzaRet = buildAction(LATEXT(1),action_file,action_line,1); + zzCONSUME; + + act = (ActionNode *) ((Junction *)zzaRet.left)->p1; + semDepth=predicateLookaheadDepth(act); + if (numericActionLabel) { /* MR10 */ + list_add(&NumericPredLabels,act); /* MR10 */ + numericActionLabel=0; /* MR10 */ + }; /* MR10 */ + { + zzBLOCK(zztasp5); + zzMake0; + { + char *a; + if ( (LA(1)==PassAction) ) { + zzmatch(PassAction); + + a = (char *)calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(a!=NULL, "rule element: cannot allocate predicate fail action"); + strcpy(a, LATEXT(1)); + act->pred_fail = a; + zzCONSUME; + + } + else { + if ( (setwd8[LA(1)]&0x20) ) { + } + else {zzFAIL(1,zzerr49,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp5); + } + } + if ( first_on_line) { /* MR7 */ + CurAltStart=(Junction *)zzaRet.left; /* MR7 */ + altAdd(CurAltStart); /* MR7 */ + }; + _retv = (Node *)act; + + pred = computePredFromContextGuard(blk,&predMsgDone); /* MR10 */ + if ( pred==NULL) { /* MR10 */ + if ( !predMsgDone) err("invalid or missing context guard"); /* MR10 */ + predMsgDone=1; /* MR10 */ + } else { /* MR10 */ + act->guardNodes=(Junction *)blk.left; /* MR11 */ + pred->expr = act->action; + pred->source = act; + /* MR10 */ pred->ampersandStyle = ampersandStyle; /* 0 means (g)? => ... 1 means (g)? && ... */ + /* MR13 */ if (pred->tcontext != NULL) { + /* MR13 */ height=MR_max_height_of_tree(pred->tcontext); + /* MR13 */ equal_height=MR_all_leaves_same_height(pred->tcontext,height); + /* MR13 */ if (! equal_height) { + /* MR13 */ errFL("in guarded predicates all tokens in the guard must be at the same height", + /* MR13 */ FileStr[act->file],act->line); + /* MR13 */ }; + /* MR13 */ } + /* MR10 */ if (ampersandStyle) { + /* MR10 */ act->ampersandPred = pred; + /* MR11 */ if (! HoistPredicateContext) { + /* MR11 */ errFL("without \"-prc on\" (guard)? && <>? ... doesn't make sense", + /* MR11 */ FileStr[act->file],act->line); + /* MR11 */ }; + /* MR10 */ } else { + /* MR10 */ act->guardpred = pred; + /* MR10 */ }; + /* MR10 */ if (pred->k != semDepth) { + /* MR10 */ warn(eMsgd2("length of guard (%d) does not match the length of semantic predicate (%d)", + /* MR10 */ pred->k,semDepth)); + /* MR10 */ }; + } + } + else { + if ( (setwd8[LA(1)]&0x40) ) { + zzaRet = makeBlk(zzaRet,approx,pFirstSetSymbol); + FoundGuessBlk = 1; + ((Junction *) ((Junction *)zzaRet.left)->p1)->guess=1; + if ( ! first_on_line ) { + err("(...)? predicate must be first element of production"); + } + } + else {zzFAIL(1,zzerr50,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp4); + } + } + } + else { + if ( (setwd8[LA(1)]&0x80) ) { + zzaRet = makeBlk(zzaRet,approx,pFirstSetSymbol); + } + else {zzFAIL(1,zzerr51,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + } + } + zzEXIT(zztasp3); + } + } + + if ( pred==NULL && !predMsgDone) { /* MR10 */ + ((Junction *)((Junction *)zzaRet.left)->p1)->blockid = CurBlockID; + ((Junction *)((Junction *)zzaRet.left)->p1)->tokrefs = toksrefd; + ((Junction *)((Junction *)zzaRet.left)->p1)->rulerefs = rulesrefd; + if ( first_on_line ) { /* MR7 */ + CurAltStart = (Junction *)((Junction *)((Junction *)zzaRet.left)->p1); /* MR7 */ + altAdd(CurAltStart); /* MR7 */ + }; /* MR7 */ + _retv = (Node *) ((Junction *)zzaRet.left)->p1; + } + } + else { + if ( (LA(1)==102) ) { + zzmatch(102); zzCONSUME; + block( &toksrefd,&rulesrefd ); + zzaRet = makeOpt(zzaArg(zztasp2,2),approx,pFirstSetSymbol); + /* MR23 */ CurBlockID_array[BlkLevel] = (-1); + /* MR23 */ CurAltNum_array[BlkLevel] = (-1); + --BlkLevel; + zzmatch(98); + + ((Junction *)((Junction *)zzaRet.left)->p1)->blockid = CurBlockID; + ((Junction *)((Junction *)zzaRet.left)->p1)->tokrefs = toksrefd; + ((Junction *)((Junction *)zzaRet.left)->p1)->rulerefs = rulesrefd; + zzCONSUME; + + if ( first_on_line ) { /* MR7 */ + CurAltStart = (Junction *) ((Junction *)((Junction *)zzaRet.left)->p1); /* MR7 */ + altAdd(CurAltStart); /* MR7 */ + }; + _retv = (Node *) ((Junction *)zzaRet.left)->p1; + } + else {zzFAIL(1,zzerr52,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + } + else { + if ( (LA(1)==129) ) { + zzmatch(129); + warn("don't you want a ')' with that '*'?"); CannotContinue=TRUE; + zzCONSUME; + + } + else { + if ( (LA(1)==130) ) { + zzmatch(130); + warn("don't you want a ')' with that '+'?"); CannotContinue=TRUE; + zzCONSUME; + + } + else { + if ( (LA(1)==105) ) { + zzmatch(105); + warn("'>' can only appear after a nonterminal"); CannotContinue=TRUE; + zzCONSUME; + + } + else { + if ( (LA(1)==PassAction) ) { + zzmatch(PassAction); + warn("[...] out of context 'rule > [...]'"); + CannotContinue=TRUE; + zzCONSUME; + + } + else {zzFAIL(1,zzerr53,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + } + } + } + } + } + } + zzEXIT(zztasp1); + return _retv; +fail: + zzEXIT(zztasp1); + CannotContinue=TRUE; + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd9, 0x1); + return _retv; + } +} + +void +#ifdef __USE_PROTOS +default_exception_handler(void) +#else +default_exception_handler() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + DefaultExGroup = exception_group(); + + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd9, 0x2); + } +} + +ExceptionGroup * +#ifdef __USE_PROTOS +exception_group(void) +#else +exception_group() +#endif +{ + ExceptionGroup * _retv; + zzRULE; + zzBLOCK(zztasp1); + PCCTS_PURIFY(_retv,sizeof(ExceptionGroup * )) + zzMake0; + { + ExceptionHandler *h; LabelEntry *label=NULL; /* MR6 */ + FoundException = 1; FoundExceptionGroup = 1; + zzmatch(133); + _retv = (ExceptionGroup *)calloc(1, sizeof(ExceptionGroup)); + zzCONSUME; + + { + zzBLOCK(zztasp2); + zzMake0; + { + char *p; + if ( (LA(1)==PassAction) ) { + zzmatch(PassAction); + + p = LATEXT(1)+1; + p[strlen(p)-1] = '\0'; /* kill trailing space */ + label = (LabelEntry *) hash_get(Elabel, LATEXT(1)+1); + if ( label==NULL ) + { + err(eMsg1("unknown label in exception handler: '%s'", LATEXT(1)+1)); + } + zzCONSUME; + + } + else { + if ( (setwd9[LA(1)]&0x4) ) { + } + else {zzFAIL(1,zzerr54,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + { + zzBLOCK(zztasp2); + zzMake0; + { + while ( (LA(1)==135) ) { + h = exception_handler(); + + list_add(&(_retv->handlers), (void *)h); + zzLOOP(zztasp2); + } + zzEXIT(zztasp2); + } + } + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==134) ) { + zzmatch(134); zzCONSUME; + zzmatch(106); zzCONSUME; + zzmatch(Action); + { + ExceptionHandler *eh = (ExceptionHandler *) + calloc(1, sizeof(ExceptionHandler)); + char *a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(eh!=NULL, "exception: cannot allocate handler"); + require(a!=NULL, "exception: cannot allocate action"); + strcpy(a, LATEXT(1)); + eh->action = a; + eh->signalname = (char *) calloc(strlen("default")+1, sizeof(char)); + require(eh->signalname!=NULL, "exception: cannot allocate sig name"); + strcpy(eh->signalname, "default"); + list_add(&(_retv->handlers), (void *)eh); + } + zzCONSUME; + + } + else { + if ( (setwd9[LA(1)]&0x8) ) { + } + else {zzFAIL(1,zzerr55,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + + if ( label!=NULL ) { + /* Record ex group in sym tab for this label */ + if ( label->ex_group!=NULL ) { + err(eMsg1("duplicate exception handler for label '%s'",label->str)); + } else { + label->ex_group = _retv; + /* Label the exception group itself */ + _retv->label = label->str; + /* Make the labelled element pt to the exception also */ + /* MR6 */ if (label->elem == NULL) { + /* MR6 */ err(eMsg1("reference in exception handler to undefined label '%s'",label->str)); + /* MR6 */ } else { + switch ( label->elem->ntype ) { + case nRuleRef : + { + RuleRefNode *r = (RuleRefNode *)label->elem; + r->ex_group = _retv; + break; + } + case nToken : + { + TokNode *t = (TokNode *)label->elem; + t->ex_group = _retv; + break; + } + } /* end switch */ + /* MR6 */ }; /* end test on label->elem */ + } /* end test on label->ex_group */ + + } /* end test on exception label */ + +/* MR7 */ + /* MR7 */ if (BlkLevel == 1 && label == NULL) { + /* MR7 */ _retv->forRule=1; + /* MR7 */ } else if (label == NULL) { + /* MR7 */ _retv->altID = makeAltID(CurBlockID_array[BlkLevel], CurAltNum_array[BlkLevel]); + /* MR7 */ egAdd(_retv); + /* MR7 */ } else { + /* MR7 */ _retv->labelEntry=label; + /* MR7 */ }; + /* MR7 */ + /* MR7 */ /* You may want to remove this exc from the rule list */ + /* MR7 */ /* and handle at the labeled element site. */ + /* MR7 */ + /* MR7 */ if (label != NULL) { + /* MR7 */ _retv = NULL; + /* MR7 */ }; + zzEXIT(zztasp1); + return _retv; +fail: + zzEXIT(zztasp1); + CannotContinue=TRUE; + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd9, 0x10); + return _retv; + } +} + +ExceptionHandler * +#ifdef __USE_PROTOS +exception_handler(void) +#else +exception_handler() +#endif +{ + ExceptionHandler * _retv; + zzRULE; + zzBLOCK(zztasp1); + PCCTS_PURIFY(_retv,sizeof(ExceptionHandler * )) + zzMake0; + { + ; + zzmatch(135); + + _retv = (ExceptionHandler *)calloc(1, sizeof(ExceptionHandler)); + require(_retv!=NULL, "exception: cannot allocate handler"); + zzCONSUME; + + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==NonTerminal) ) { + zzmatch(NonTerminal); + + _retv->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(_retv->signalname!=NULL, "exception: cannot allocate sig name"); + strcpy(_retv->signalname, LATEXT(1)); + zzCONSUME; + + } + else { + if ( (LA(1)==TokenTerm) ) { + zzmatch(TokenTerm); + + _retv->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(_retv->signalname!=NULL, "exception: cannot allocate sig name"); + strcpy(_retv->signalname, LATEXT(1)); + zzCONSUME; + + } + else {zzFAIL(1,zzerr56,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + zzmatch(106); zzCONSUME; + { + zzBLOCK(zztasp2); + zzMake0; + { + _retv->action = NULL; + if ( (LA(1)==Action) ) { + zzmatch(Action); + + _retv->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(_retv->action!=NULL, "exception: cannot allocate action"); + strcpy(_retv->action, LATEXT(1)); + zzCONSUME; + + } + else { + if ( (setwd9[LA(1)]&0x20) ) { + } + else {zzFAIL(1,zzerr57,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + zzEXIT(zztasp1); + return _retv; +fail: + zzEXIT(zztasp1); + CannotContinue=TRUE; + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd9, 0x40); + return _retv; + } +} + +void +#ifdef __USE_PROTOS +enum_file(char * fname) +#else +enum_file(fname) + char *fname ; +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + if ( (setwd9[LA(1)]&0x80) ) { + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==143) ) { + zzmatch(143); zzCONSUME; + zzmatch(ID); zzCONSUME; + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (LA(1)==149) ) { + zzmatch(149); zzCONSUME; + zzmatch(ID); zzCONSUME; + } + else { + if ( (setwd10[LA(1)]&0x1) ) { + } + else {zzFAIL(1,zzerr58,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp3); + } + } + } + else { + if ( (setwd10[LA(1)]&0x2) ) { + } + else {zzFAIL(1,zzerr59,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==151) ) { + { + zzBLOCK(zztasp3); + int zzcnt=1; + zzMake0; + { + do { + enum_def( fname ); + zzLOOP(zztasp3); + } while ( (LA(1)==151) ); + zzEXIT(zztasp3); + } + } + } + else { + if ( (LA(1)==149) ) { + defines( fname ); + } + else {zzFAIL(1,zzerr60,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + } + else { + if ( (LA(1)==Eof) ) { + } + else {zzFAIL(1,zzerr61,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd10, 0x4); + } +} + +void +#ifdef __USE_PROTOS +defines(char * fname) +#else +defines(fname) + char *fname ; +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + int v; int maxt=(-1); char *t; + { + zzBLOCK(zztasp2); + int zzcnt=1; + zzMake0; + { + do { + zzmatch(149); zzCONSUME; + zzmatch(ID); + t = mystrdup(LATEXT(1)); + zzCONSUME; + + zzmatch(INT); + + v = atoi(LATEXT(1)); + /* fprintf(stderr, "#token %s=%d\n", t, v);*/ + + /* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */ + /* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */ + /* MR2 Don't let #tokdefs be confused by */ + /* MR2 DLGminToken and DLGmaxToken */ + + if ( ! isDLGmaxToken(t)) { /* MR2 */ + TokenNum = v; + if ( v>maxt ) maxt=v; + if ( Tnum( t ) == 0 ) { + addForcedTname( t, v ); + } else { + warnFL(eMsg1("redefinition of token %s; ignored",t), fname,zzline); + }; +}; + zzCONSUME; + + zzLOOP(zztasp2); + } while ( (LA(1)==149) ); + zzEXIT(zztasp2); + } + } + TokenNum = maxt + 1; + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd10, 0x8); + } +} + +void +#ifdef __USE_PROTOS +enum_def(char * fname) +#else +enum_def(fname) + char *fname ; +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + int v= 0; int maxt=(-1); char *t; + zzmatch(151); zzCONSUME; + zzmatch(ID); zzCONSUME; + zzmatch(152); zzCONSUME; + zzmatch(ID); + t = mystrdup(LATEXT(1)); + zzCONSUME; + + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==153) ) { + zzmatch(153); zzCONSUME; + zzmatch(INT); + v=atoi(LATEXT(1)); + zzCONSUME; + + } + else { + if ( (setwd10[LA(1)]&0x10) ) { + v++; + } + else {zzFAIL(1,zzerr62,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + + /* fprintf(stderr, "#token %s=%d\n", t, v);*/ + TokenNum = v; + if ( v>maxt ) maxt=v; /* MR3 */ + if ( Tnum( t ) == 0 ) addForcedTname( t, v ); + else { + warnFL(eMsg1("redefinition of token %s; ignored",t), fname,zzline); + } + { + zzBLOCK(zztasp2); + zzMake0; + { + while ( (LA(1)==154) ) { + zzmatch(154); zzCONSUME; + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (LA(1)==ID)&&(isDLGmaxToken(LATEXT(1))) ) { + if (!(isDLGmaxToken(LATEXT(1))) ) {zzfailed_pred(" isDLGmaxToken(LATEXT(1))",0 /* report */, { 0; /* no user action */ } );} + zzmatch(ID); zzCONSUME; + { + zzBLOCK(zztasp4); + zzMake0; + { + if ( (LA(1)==153) ) { + zzmatch(153); zzCONSUME; + zzmatch(INT); zzCONSUME; + } + else { + if ( (setwd10[LA(1)]&0x20) ) { + } + else {zzFAIL(1,zzerr63,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp4); + } + } + } + else { + if ( (LA(1)==ID) ) { + zzmatch(ID); + t = mystrdup(LATEXT(1)); + zzCONSUME; + + { + zzBLOCK(zztasp4); + zzMake0; + { + if ( (LA(1)==153) ) { + zzmatch(153); zzCONSUME; + zzmatch(INT); + v=atoi(LATEXT(1)); + zzCONSUME; + + } + else { + if ( (setwd10[LA(1)]&0x40) ) { + v++; + } + else {zzFAIL(1,zzerr64,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp4); + } + } + + /* fprintf(stderr, "#token %s=%d\n", t, v);*/ + TokenNum = v; + if ( v>maxt ) maxt=v; /* MR3 */ + if ( Tnum( t ) == 0 ) addForcedTname( t, v ); + else { + warnFL(eMsg1("redefinition of token %s; ignored",t), fname,zzline); + } + } + else { + if ( (setwd10[LA(1)]&0x80) ) { + } + else {zzFAIL(1,zzerr65,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + } + zzEXIT(zztasp3); + } + } + zzLOOP(zztasp2); + } + zzEXIT(zztasp2); + } + } + zzmatch(155); zzCONSUME; + zzmatch(156); + TokenNum = maxt + 1; + zzCONSUME; + + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd11, 0x1); + } +} + + +/* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */ +/* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */ +/* MR2 Don't let #tokdefs be confused by */ +/* MR2 DLGminToken and DLGmaxToken */ + +/* semantic check on DLGminToken and DLGmaxmaxToken in #tokdefs */ + +#ifdef __USE_PROTOS +static int isDLGmaxToken(char *Token) +#else +static int isDLGmaxToken(Token) +char * Token; +#endif +{ +static char checkStr1[] = "DLGmaxToken"; +static char checkStr2[] = "DLGminToken"; + + if (strcmp(Token, checkStr1) == 0) +return 1; +else if (strcmp(Token, checkStr2) == 0) +return 1; +else +return 0; +} + +/* semantics of #token */ +static void +#ifdef __USE_PROTOS +chkToken(char *t, char *e, char *a, int tnum) +#else +chkToken(t,e,a,tnum) +char *t, *e, *a; +int tnum; +#endif +{ +TermEntry *p; + + /* check to see that they don't try to redefine a token as a token class */ +if ( t!=NULL ) { +p = (TermEntry *) hash_get(Tname, t); +if ( p!=NULL && p->classname ) { + err(eMsg1("redefinition of #tokclass '%s' to #token not allowed; ignored",t)); + if ( a!=NULL ) free((char *)a); + return; +} +} + + if ( t==NULL && e==NULL ) { /* none found */ +err("#token requires at least token name or rexpr"); +} +else if ( t!=NULL && e!=NULL ) { /* both found */ +if ( UserDefdTokens ) { /* if #tokdefs, must not define new */ + p = (TermEntry *) hash_get(Tname, t); + if ( p == NULL) { + err(eMsg1("new token definition '%s' not allowed - only #token with name already defined by #tokdefs file allowed",t)); + return; + }; +} +Tklink(t, e); +if ( a!=NULL ) { + if ( hasAction(e) ) { + err(eMsg1("redefinition of action for %s; ignored",e)); + } + else setHasAction(e, a); +} +} +else if ( t!=NULL ) { /* only one found */ +if ( UserDefdTokens ) { + p = (TermEntry *) hash_get(Tname, t); + if (p == NULL) { + err(eMsg1("new token definition '%s' not allowed - only #token with name already defined by #tokdefs file allowed",t)); + }; + return; +} +if ( Tnum( t ) == 0 ) addTname( t ); +else { + err(eMsg1("redefinition of token %s; ignored",t)); +} +if ( a!=NULL ) { + err(eMsg1("action cannot be attached to a token name (%s); ignored",t)); + free((char *)a); +} +} +else if ( e!=NULL ) { +if ( Tnum( e ) == 0 ) addTexpr( e ); +else { + if ( hasAction(e) ) { + err(eMsg1("redefinition of action for expr %s; ignored",e)); + } + else if ( a==NULL ) { + err(eMsg1("redefinition of expr %s; ignored",e)); + } +} +if ( a!=NULL ) setHasAction(e, a); +} + + /* if a token type number was specified, then add the token ID and 'tnum' +* pair to the ForcedTokens list. (only applies if an id was given) +*/ +if ( t!=NULL && tnum>0 ) +{ +if ( set_el(tnum, reserved_positions) ) +{ + err(eMsgd("a token has already been forced to token number %d; ignored", tnum)); +} +else +{ + list_add(&ForcedTokens, newForcedToken(t,tnum)); + set_orel(tnum, &reserved_positions); +} +} +} + +static int +#ifdef __USE_PROTOS +match_token(char *s, char **nxt) +#else +match_token(s,nxt) +char *s; +char **nxt; +#endif +{ + if ( !(*s>='A' && *s<='Z') ) return 0; + s++; + while ( (*s>='a' && *s<='z') || + (*s>='A' && *s<='Z') || + (*s>='0' && *s<='9') || + *s=='_' ) + { + s++; + } + if ( *s!=' ' && *s!='}' ) return 0; + *nxt = s; + return 1; +} + +static int +#ifdef __USE_PROTOS +match_rexpr(char *s, char **nxt) +#else +match_rexpr(s,nxt) +char *s; +char **nxt; +#endif +{ + if ( *s!='"' ) return 0; + s++; + while ( *s!='"' ) + { + if ( *s=='\n' || *s=='\r' ) /* MR13 */ + warn("eoln found in regular expression"); + if ( *s=='\\' ) s++; + s++; + } + *nxt = s+1; + return 1; +} + +/* +* Walk a string "{ A .. Z }" where A..Z is a space separated list +* of token references (either labels or reg exprs). Return a +* string "inlineX_set" for some unique integer X. Basically, +* we pretend as if we had seen "#tokclass inlineX { A .. Z }" +* on the input stream outside of an action. +*/ +char * +#ifdef __USE_PROTOS +inline_set(char *s) +#else +inline_set(s) +char *s; +#endif +{ + char *nxt; + fprintf(stderr, "found consumeUntil( {...} )\n"); + while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;} + if ( *s!='{' ) + { + err("malformed consumeUntil( {...} ); missing '{'"); + return "bad_set"; + } + s++; + while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;} + while ( *s!='}' ) + { + if ( match_token(s,&nxt) ) fprintf(stderr, "found token %s\n", s); + else if ( match_rexpr(s,&nxt) ) fprintf(stderr, "found rexpr %s\n", s); + else { + err("invalid element in consumeUntil( {...} )"); + return "bad_set"; + } + s = nxt; + while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;} + } + return "inlineX_set"; +} + +/* ANTLR-specific syntax error message generator +* (define USER_ZZSYN when compiling so don't get 2 definitions) +*/ +void +#ifdef __USE_PROTOS +zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, +int k, char *bad_text) +#else +zzsyn(text, tok, egroup, eset, etok, k, bad_text) +char *text, *egroup, *bad_text; +int tok; +int etok; +int k; +SetWordType *eset; +#endif +{ +fprintf(stderr, ErrHdr, FileStr[CurFile]!=NULL?FileStr[CurFile]:"stdin", zzline); +fprintf(stderr, " syntax error at \"%s\"", (tok==zzEOF_TOKEN)?"EOF":text); +if ( !etok && !eset ) {fprintf(stderr, "\n"); return;} +if ( k==1 ) fprintf(stderr, " missing"); +else +{ +fprintf(stderr, "; \"%s\" not", bad_text); +if ( zzset_deg(eset)>1 ) fprintf(stderr, " in"); +} +if ( zzset_deg(eset)>0 ) zzedecode(eset); +else fprintf(stderr, " %s", zztokens[etok]); +if ( strlen(egroup) > (size_t)0 ) fprintf(stderr, " in %s", egroup); +fprintf(stderr, "\n"); +} diff --git a/Tools/CodeTools/Source/Pccts/antlr/antlr.g b/Tools/CodeTools/Source/Pccts/antlr/antlr.g new file mode 100644 index 0000000000..e6eda6010c --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/antlr.g @@ -0,0 +1,2586 @@ +/* + * antlr.g -- PCCTS Version 1.xx ANTLR + * + * Parse an antlr input grammar and build a syntax-diagram. + * + * Written in itself (needs at least 1.06 to work) + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-1995 + */ + +/* MR1 */ +/* MR1 10-Apr-97 MR1 Replace #if logic with #include "pcctscfg.h" */ +/* MR1 */ + +#header << + #include "pcctscfg.h" + #include "set.h" + #include + #include "syn.h" + #include "hash.h" + #include "generic.h" + #define zzcr_attr(attr,tok,t) + >> + +<< + +/* MR20 G. Hobbelt For Borland C++ 4.x & 5.x compiling with ALL warnings enabled */ +#if defined(__TURBOC__) +#pragma warn -aus /* unused assignment of 'xxx' */ +#endif + + +#ifdef __USE_PROTOS +static void chkToken(char *, char *, char *, int); +#else +static void chkToken(); +#endif + +#ifdef __USE_PROTOS +static int isDLGmaxToken(char *Token); /* MR3 */ +#else +static int isDLGmaxToken(); /* MR3 */ +#endif + +static int class_nest_level = 0; + +/* MR20 G. Hobbelt extern definitions moved to antlr.h */ + +>> + +#lexaction << +/* maintained, but not used for now */ +set AST_nodes_refd_in_actions = set_init; +int inAlt = 0; +set attribsRefdFromAction = set_init; /* MR20 */ +int UsedOldStyleAttrib = 0; +int UsedNewStyleLabel = 0; +#ifdef __USE_PROTOS +char *inline_set(char *); +#else +char *inline_set(); +#endif + +/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */ +/* MR1 in DLG action */ + +int tokenActionActive=0; /* MR1 */ + +>> + +#lexclass STRINGS +#token QuotedTerm "\"" << zzmode(START); >> +#token "\n|\r|\r\n" << + zzline++; + warn("eoln found in string"); + zzskip(); + >> +#token "\\(\n|\r|\r\n)" << zzline++; zzmore(); >> +#token "\\~[]" << zzmore(); >> +#token "~[\n\r\"\\]+" << zzmore(); >> + +#lexclass ACTION_STRINGS +#token "\"" << zzmode(ACTIONS); zzmore(); >> +#token "\n|\r|\r\n" << + zzline++; + warn("eoln found in string (in user action)"); + zzskip(); + >> +#token "\\(\n|\r|\r\n)" << zzline++; zzmore(); >> +#token "\\~[]" << zzmore(); >> +#token "~[\n\r\"\\]+" << zzmore(); >> + +#lexclass ACTION_CHARS +#token "'" << zzmode(ACTIONS); zzmore(); >> +#token "\n|\r|\r\n" << + zzline++; + warn("eoln found in char literal (in user action)"); + zzskip(); + >> +#token "\\~[]" << zzmore(); >> +#token "~[\n\r'\\]+" << zzmore(); >> + +#lexclass ACTION_COMMENTS +#token "\*/" << zzmode(ACTIONS); zzmore(); >> +#token "\*" << zzmore(); >> +#token "\n|\r|\r\n" << zzline++; zzmore(); DAWDLE; >> +#token "~[\n\r\*]+" << zzmore(); >> + +#lexclass TOK_DEF_COMMENTS +#token "\*/" << zzmode(PARSE_ENUM_FILE); + zzmore(); >> +#token "\*" << zzmore(); >> +#token "\n|\r|\r\n" << zzline++; zzmore(); DAWDLE; >> +#token "~[\n\r\*]+" << zzmore(); >> + +#lexclass TOK_DEF_CPP_COMMENTS +#token "\n|\r|\r\n" << zzline++; zzmode(PARSE_ENUM_FILE); zzskip(); DAWDLE; >> +#token "~[\n\r]+" << zzskip(); >> + +#lexclass ACTION_CPP_COMMENTS +#token "\n|\r|\r\n" << zzline++; zzmode(ACTIONS); zzmore(); DAWDLE; >> +#token "~[\n\r]+" << zzmore(); >> + +#lexclass CPP_COMMENTS +#token "\n|\r|\r\n" << zzline++; zzmode(START); zzskip(); DAWDLE; >> +#token "~[\n\r]+" << zzskip(); >> + +#lexclass COMMENTS +#token "\*/" << zzmode(START); zzskip(); >> +#token "\*" << zzskip(); >> +#token "\n|\r|\r\n" << zzline++; zzskip(); DAWDLE; >> +#token "~[\n\r\*]+" << zzskip(); >> + +/* + * This lexical class accepts actions of type [..] and <<..>> + * + * It translates the following special items for C: + * + * $j --> "zzaArg(current zztasp, j)" + * $i.j --> "zzaArg(zztaspi, j)" + * $i.nondigit> "zzaArg(current zztasp, i).nondigit" + * $$ --> "zzaRet" + * $alnum --> "alnum" (used to ref parameters) + * $rule --> "zzaRet" + * $retval --> "_retv.retval" if > 1 return values else "_retv" + * $[token, text] --> "zzconstr_attr(token, text)" + * $[] --> "zzempty_attr()" + * + * It translates the following special items for C++: + * (attributes are now stored with 'Token' and $i's are only + * pointers to the Tokens. Rules don't have attributes now.) + * + * $j --> "_tbj" where b is the block level + * $i.j --> "_tij" + * $j->nondigit> "_tbj->nondigit" + * $$ --> "$$" + * $alnum --> "alnum" (used to ref parameters) + * $rule --> "$rule" + * $retval --> "_retv.retval" if > 1 return values else "_retv" + * $[token, text] --> invalid + * $[] --> invalid + * + * And, for trees: + * + * #0 --> "(*_root)" + * #i --> "zzastArg(i)" + * #[args] --> "zzmk_ast(zzastnew(), args)" + * #[] --> "zzastnew()" + * #( root, child1, ..., childn ) + * --> "zztmake(root, child1, ...., childn, NULL)" + * #() --> "NULL" + * + * For C++, ... + * + * #0 --> "(*_root)" + * #i --> "_astbi" where b is the block level + * #alnum --> "alnum_ast" (used to ref #label) + * #[args] --> "new AST(args)" + * #[] --> "new AST" + * #( root, child1, ..., childn ) + * --> "AST::tmake(root, child1, ...., childn, NULL)" + * #() --> "NULL" + * + * To escape, + * + * \] --> ] + * \) --> ) + * \$ --> $ + * \# --> # + * + * A stack is used to nest action terminators because they can be nested + * like crazy: << #[$[..],..] >> + */ +#lexclass ACTIONS +#token Action "\>\>" << /* these do not nest */ + zzmode(START); + NLATEXT[0] = ' '; + NLATEXT[1] = ' '; + zzbegexpr[0] = ' '; + zzbegexpr[1] = ' '; + if ( zzbufovf ) { + err( eMsgd("action buffer overflow; size %d",ZZLEXBUFSIZE)); + } + +/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */ +/* MR1 in DLG action */ +/* MR1 Doesn't matter what kind of action it is - reset*/ + + tokenActionActive=0; /* MR1 */ + >> +#token Pred "\>\>?" << /* these do not nest */ + zzmode(START); + NLATEXT[0] = ' '; + NLATEXT[1] = ' '; + zzbegexpr[0] = '\0'; + if ( zzbufovf ) { + err( eMsgd("predicate buffer overflow; size %d",ZZLEXBUFSIZE)); + }; +#ifdef __cplusplus__ +/* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); +#else +#ifdef __STDC__ +/* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); +#else +#ifdef __USE_PROTOS +/* MRxx */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); +#else +/* MR10 */ list_apply(CurActionLabels,mark_label_used_in_sem_pred); +#endif +#endif +#endif + >> +#token PassAction "\]" << if ( topint() == ']' ) { + popint(); + if ( istackempty() ) /* terminate action */ + { + zzmode(START); + NLATEXT[0] = ' '; + zzbegexpr[0] = ' '; + if ( zzbufovf ) { + err( eMsgd("parameter buffer overflow; size %d",ZZLEXBUFSIZE)); + } + } + else { + /* terminate $[..] and #[..] */ + if ( GenCC ) zzreplstr("))"); + else zzreplstr(")"); + zzmore(); + } + } + else if ( topint() == '|' ) { /* end of simple [...] */ + popint(); + zzmore(); + } + else zzmore(); + >> +#token "consumeUntil\( [\ \t]* \{~[\}]+\} [\ \t]* \)" + << + zzmore(); + zzreplstr(inline_set(zzbegexpr+ + strlen("consumeUntil("))); + >> +#token "consumeUntil\( ~[\)]+ \)" + << zzmore(); >> +#token "\n|\r|\r\n" << zzline++; zzmore(); DAWDLE; >> +#token "\>" << zzmore(); >> +#token "$" << zzmore(); >> +#token "$$" << if ( !GenCC ) {zzreplstr("zzaRet"); zzmore();} + else err("$$ use invalid in C++ mode"); >> + +#token "$\[\]" << if ( !GenCC ) {zzreplstr("zzempty_attr"); zzmore();} + else err("$[] use invalid in C++ mode"); >> +#token "$\[" << + pushint(']'); + if ( !GenCC ) zzreplstr("zzconstr_attr("); + else err("$[..] use invalid in C++ mode"); + zzmore(); + >> +#token "$[0-9]+" <<{ + static char buf[100]; + numericActionLabel=1; /* MR10 */ + if ( strlen(zzbegexpr)>(size_t)85 ) + fatal("$i attrib ref too big"); + set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction); + if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s)", + BlkLevel-1,zzbegexpr+1); + else sprintf(buf,"_t%d%s", + BlkLevel-1,zzbegexpr+1); + zzreplstr(buf); + zzmore(); + UsedOldStyleAttrib = 1; + if ( UsedNewStyleLabel ) + err("cannot mix old-style $i with new-style labels"); + } + >> +#token "$[0-9]+." <<{ + static char buf[100]; + numericActionLabel=1; /* MR10 */ + if ( strlen(zzbegexpr)>(size_t)85 ) + fatal("$i.field attrib ref too big"); + zzbegexpr[strlen(zzbegexpr)-1] = ' '; + set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction); + if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s).", + BlkLevel-1,zzbegexpr+1); + else sprintf(buf,"_t%d%s.", + BlkLevel-1,zzbegexpr+1); + zzreplstr(buf); + zzmore(); + UsedOldStyleAttrib = 1; + if ( UsedNewStyleLabel ) + err("cannot mix old-style $i with new-style labels"); + } + >> +#token "$[0-9]+.[0-9]+" <<{ + static char buf[100]; + static char i[20], j[20]; + char *p,*q; + numericActionLabel=1; /* MR10 */ + if (strlen(zzbegexpr)>(size_t)85) fatal("$i.j attrib ref too big"); + for (p=zzbegexpr+1,q= &i[0]; *p!='.'; p++) { + if ( q == &i[20] ) + fatalFL("i of $i.j attrib ref too big", + FileStr[CurFile], zzline ); + *q++ = *p; + } + *q = '\0'; + for (p++, q= &j[0]; *p!='\0'; p++) { + if ( q == &j[20] ) + fatalFL("j of $i.j attrib ref too big", + FileStr[CurFile], zzline ); + *q++ = *p; + } + *q = '\0'; + if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%s,%s)",i,j); + else sprintf(buf,"_t%s%s",i,j); + zzreplstr(buf); + zzmore(); + UsedOldStyleAttrib = 1; + if ( UsedNewStyleLabel ) + err("cannot mix old-style $i with new-style labels"); + } + >> +#token "$[_a-zA-Z][_a-zA-Z0-9]*" + <<{ static char buf[300]; LabelEntry *el; + zzbegexpr[0] = ' '; + if ( CurRule != NULL && + strcmp(CurRule, &zzbegexpr[1])==0 ) { + if ( !GenCC ) zzreplstr("zzaRet"); + } + else if ( CurRetDef != NULL && + strmember(CurRetDef, &zzbegexpr[1])) { + if ( hasMultipleOperands( CurRetDef ) ) { + require (strlen(zzbegexpr)<=(size_t)285, + "$retval attrib ref too big"); + sprintf(buf,"_retv.%s",&zzbegexpr[1]); + zzreplstr(buf); + } + else zzreplstr("_retv"); + } + else if ( CurParmDef != NULL && + strmember(CurParmDef, &zzbegexpr[1])) { + ; + } + else if ( Elabel==NULL ) { + { err("$-variables in actions outside of rules are not allowed"); } + } else if ( (el=(LabelEntry *)hash_get(Elabel, &zzbegexpr[1]))!=NULL ) { +/* MR10 */ +/* MR10 */ /* element labels might exist without an elem when */ +/* MR10 */ /* it is a forward reference (to a rule) */ +/* MR10 */ +/* MR10 */ if ( GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) ) +/* MR10 */ { err(eMsg1("There are no token ptrs for rule references: '$%s'",&zzbegexpr[1])); } +/* MR10 */ +/* MR10 */ if ( !GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) && GenAST) { +/* MR10 */ err("You can no longer use attributes returned by rules when also using ASTs"); +/* MR10 */ err(" Use upward inheritance (\"rule >[Attrib a] : ... <<$a=...\>\>\")"); +/* MR10 */ }; +/* MR10 */ +/* MR10 */ /* keep track of <<... $label ...>> for semantic predicates in guess mode */ +/* MR10 */ /* element labels contain pointer to the owners node */ +/* MR10 */ +/* MR10 */ if (el->elem != NULL && el->elem->ntype == nToken) { +/* MR10 */ list_add(&CurActionLabels,el); +/* MR10 */ }; + } + else + warn(eMsg1("$%s not parameter, return value, (defined) element label",&zzbegexpr[1])); + } + zzmore(); + >> +#token "#0" << zzreplstr("(*_root)"); zzmore(); chkGTFlag(); >> +#token "#\[\]" << if ( GenCC ) { + if (NewAST) zzreplstr("(newAST)"); + else zzreplstr("(new AST)");} + else {zzreplstr("zzastnew()");} zzmore(); + chkGTFlag(); + >> +#token "#\(\)" << zzreplstr("NULL"); zzmore(); chkGTFlag(); >> +#token "#[0-9]+" <<{ + static char buf[100]; + if ( strlen(zzbegexpr)>(size_t)85 ) + fatal("#i AST ref too big"); + if ( GenCC ) sprintf(buf,"_ast%d%s",BlkLevel-1,zzbegexpr+1); + else sprintf(buf,"zzastArg(%s)",zzbegexpr+1); + zzreplstr(buf); + zzmore(); + set_orel(atoi(zzbegexpr+1), &AST_nodes_refd_in_actions); + chkGTFlag(); + } + >> + +/* MR14 Arpad Beszedes 26-May-98 + Add support for #line directives when antlr source is pre-processed + #lexclass ACTIONS +*/ + +#token "#line[\ \t]* [0-9]+ {[\ \t]* \"~[\"]+\" ([\ \t]* [0-9]*)* } (\n|\r|\r\n)" + << + zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore(); + getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr); + >> + +#token "#line ~[\n\r]* (\n|\r|\r\n)" + << + zzline++; zzmore(); + >> + +/* MR14 end of a block to support #line in antlr source code */ + +#token "#[_a-zA-Z][_a-zA-Z0-9]*" + << + if ( !(strcmp(zzbegexpr, "#ifdef")==0 || + strcmp(zzbegexpr, "#if")==0 || + strcmp(zzbegexpr, "#else")==0 || + strcmp(zzbegexpr, "#endif")==0 || + strcmp(zzbegexpr, "#ifndef")==0 || + strcmp(zzbegexpr, "#define")==0 || + strcmp(zzbegexpr, "#pragma")==0 || + strcmp(zzbegexpr, "#undef")==0 || + strcmp(zzbegexpr, "#import")==0 || + strcmp(zzbegexpr, "#line")==0 || + strcmp(zzbegexpr, "#include")==0 || + strcmp(zzbegexpr, "#error")==0) ) + { + static char buf[100]; + sprintf(buf, "%s_ast", zzbegexpr+1); +/* MR27 */ list_add(&CurAstLabelsInActions, mystrdup(zzbegexpr+1)); + zzreplstr(buf); + chkGTFlag(); + } + zzmore(); + >> +#token "#\[" << + pushint(']'); + if ( GenCC ) { + if (NewAST) zzreplstr("(newAST("); + else zzreplstr("(new AST("); } + else zzreplstr("zzmk_ast(zzastnew(),"); + zzmore(); + chkGTFlag(); + >> +#token "#\(" << + pushint('}'); + if ( GenCC ) { + if (tmakeInParser) { + zzreplstr("tmake("); + } + else { + zzreplstr("ASTBase::tmake("); + } + } + else { + zzreplstr("zztmake("); + } + zzmore(); + chkGTFlag(); + >> +#token "#" << zzmore(); >> +#token "\)" << + if ( istackempty() ) + zzmore(); + else if ( topint()==')' ) { + popint(); + } + else if ( topint()=='}' ) { + popint(); + /* terminate #(..) */ + zzreplstr(", NULL)"); + } + zzmore(); + >> +#token "\[" << + pushint('|'); /* look for '|' to terminate simple [...] */ + zzmore(); + >> +#token "\(" << + pushint(')'); + zzmore(); + >> + +#token "\\\]" << zzreplstr("]"); zzmore(); >> +#token "\\\)" << zzreplstr(")"); zzmore(); >> + +/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */ +/* MR1 in DLG action */ + +#token "\\>" << if (! tokenActionActive) zzreplstr(">"); /* MR1 */ + zzmore(); /* MR1 */ + >> /* MR1 */ + + +#token "'" << zzmode(ACTION_CHARS); zzmore();>> +#token "\"" << zzmode(ACTION_STRINGS); zzmore();>> +#token "\\$" << zzreplstr("$"); zzmore(); >> +#token "\\#" << zzreplstr("#"); zzmore(); >> +#token "\\(\n|\r|\r\n)" << zzline++; zzmore(); >> +#token "\\~[\]\)>$#]" << zzmore(); >> /* escaped char, always ignore */ +#token "/" << zzmore(); >> +#token "/\*" << zzmode(ACTION_COMMENTS); zzmore(); >> +#token "\*/" << warn("Missing /*; found dangling */ in action"); zzmore(); >> +#token "//" << zzmode(ACTION_CPP_COMMENTS); zzmore(); >> +#token "~[\n\r\)\(\\$#\>\]\[\"'/]+" << zzmore(); >> + +#lexclass START +#token "[\t\ ]+" << zzskip(); >> /* Ignore White */ +#token "\n|\r|\r\n" << zzline++; zzskip(); >> /* Track Line # */ +#token "\[" << zzmode(ACTIONS); zzmore(); + istackreset(); + pushint(']'); >> +#token "\<\<" << action_file=CurFile; action_line=zzline; + zzmode(ACTIONS); zzmore(); + list_free(&CurActionLabels,0); /* MR10 */ + numericActionLabel=0; /* MR10 */ + istackreset(); + pushint('>'); >> +#token "\"" << zzmode(STRINGS); zzmore(); >> +#token "/\*" << zzmode(COMMENTS); zzskip(); >> +#token "\*/" << warn("Missing /*; found dangling */"); zzskip(); >> +#token "//" << zzmode(CPP_COMMENTS); zzskip(); >> + +/* MR14 Arpad Beszedes 26-May-98 + Add support for #line directives when antlr source is pre-processed + #lexclass START +*/ + +#token "#line[\ \t]* [0-9]+ {[\ \t]* \"~[\"]+\" ([\ \t]* [0-9]*)* } (\n|\r|\r\n)" + << + zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore(); + getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr); + >> + +#token "#line ~[\n\r]* (\n|\r|\r\n)" + << + zzline++; zzmore(); + >> + +/* MR14 end of a block to support #line in antlr source code */ + +/* */ +/* 8-Apr-97 Regularize escape sequence for ">>" */ +/* appearing in string literals */ +/* */ + +#token "\>\>" << warn("Missing <<; found dangling \>\>"); zzskip(); >> /* MR1 */ +#token WildCard "." +#token "\@" <> /* MR6 */ +#token Eof "@" + << /* L o o k F o r A n o t h e r F i l e */ + { + FILE *new_input; + new_input = NextFile(); + if ( new_input == NULL ) { NLA=Eof; return; } + fclose( input ); + input = new_input; + zzrdstream( input ); + zzskip(); /* Skip the Eof (@) char i.e continue */ + } + >> + +#token LABEL + +#errclass "grammar-element" { element } +#errclass "meta-symbol" { "\}" "!" ";" "\|" "\~" "^" "\)" } + +#token Pragma "{\\}#pragma" /* MR21 */ +#token FirstSetSymbol "{\\}#FirstSetSymbol" /* MR21 */ +/* + * Get a grammar -- Build a list of rules like: + * + * o-->Rule1--o + * | + * o-->Rule2--o + * | + * ... + * | + * o-->RuleN--o + */ + +/* rule grammar */ + +grammar : <> + ( "{\\}#header" Action /* MR13 */ + << + if ( HdrAction==NULL ) { + HdrAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(HdrAction!=NULL, "rule grammar: cannot allocate header action"); + strcpy(HdrAction, LATEXT(1)); + } + else warn("additional #header statement ignored"); + >> + | "{\\}#first" Action + << + if ( FirstAction==NULL ) { + FirstAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(FirstAction!=NULL, "rule grammar: cannot allocate #first action"); + strcpy(FirstAction, LATEXT(1)); + } else { + warn("additional #first statement ignored"); + }; + >> + + | "{\\}#parser" QuotedTerm + << + if ( GenCC ) { + warn("#parser meta-op incompatible with -CC; ignored"); + } + else { + if ( strcmp(ParserName,"zzparser")==0 ) { + ParserName=StripQuotes(mystrdup(LATEXT(1))); + if ( RulePrefix[0]!='\0' ) + { + warn("#parser meta-op incompatible with '-gp prefix'; '-gp' ignored"); + RulePrefix[0]='\0'; + } + } + else warn("additional #parser statement ignored"); + } + >> + | "{\\}#tokdefs" QuotedTerm + <<{ + char *fname; + zzantlr_state st; FILE *f; struct zzdlg_state dst; + UserTokenDefsFile = mystrdup(LATEXT(1)); + zzsave_antlr_state(&st); + zzsave_dlg_state(&dst); + fname = mystrdup(LATEXT(1)); + f = fopen(StripQuotes(fname), "r"); + if ( f==NULL ) {warn(eMsg1("cannot open token defs file '%s'", fname+1));} + else { + ANTLRm(enum_file(fname+1), f, PARSE_ENUM_FILE); + UserDefdTokens = 1; + } + zzrestore_antlr_state(&st); + zzrestore_dlg_state(&dst); + }>> + )* + ( Action + <<{ + UserAction *ua = newUserAction(LATEXT(1)); + ua->file = action_file; ua->line = action_line; + if ( class_nest_level>0 ) list_add(&class_before_actions, ua); + else list_add(&BeforeActions, ua); + }>> + | laction + | lmember /* MR1 */ + | lprefix /* MR1 */ + | aLexclass + | token + | error + | tclass + | aPred /* MR11 */ + | default_exception_handler + | class_def + | "\}" + << + if ( class_nest_level==0 ) + warn("missing class definition for trailing '}'"); + class_nest_level--; + >> + )* + + rule <> + ( rule + + <> + + | aLexclass + | token + | error + | tclass + | aPred /* MR11 */ + | class_def + | "\}" + << + if ( class_nest_level==0 ) + warn("missing class definition for trailing '}'"); + class_nest_level--; + >> + )* + ( Action + <<{ + UserAction *ua = newUserAction(LATEXT(1)); + ua->file = action_file; ua->line = action_line; + if ( class_nest_level>0 ) list_add(&class_after_actions, ua); + else list_add(&AfterActions, ua); + }>> + | laction + | lmember /* MR1 */ + | lprefix /* MR1 */ + | error + | tclass + | class_def + | aPred /* MR11 */ + | "\}" + << + if ( class_nest_level==0 ) + warn("missing class definition for trailing '}'"); + class_nest_level--; + >> + )* + Eof + ; + <> + +/* rule class_def */ + +class_def + : <> + "class" + ( NonTerminal <> + | TokenTerm <> + ) + << + if ( CurrentClassName[0]!='\0' && strcmp(CurrentClassName,name)!=0 + && GenCC ) { + err("only one grammar class allowed in this release"); + go = 0; + } + else strcpy(CurrentClassName, name); + >> + <> + +/* MR10 */ (~ "\{" +/* MR10 */ <> +/* MR10 */ )* + + "\{" + << + no_classes_found = 0; + if ( class_nest_level>=1 ) {warn("cannot have nested classes");} + else class_nest_level++; + >> + ; + <> + +/* + * Build -o-->o-R-o-->o- where -o-R-o- is the block from rule 'block'. + * Construct the RuleBlk front and EndRule node on the end of the + * block. This is used to add FOLLOW pointers to the rule end. Add the + * new rule name to the Rname hash table and sets its rulenum. + * Store the parameter definitions if any are found. + * + * Note that locks are required on the RuleBlk and EndRule nodes to thwart + * infinite recursion. + * + * Return the left graph pointer == NULL to indicate error/dupl rule def. + */ + +/* rule rule */ + +rule : << + + ExceptionGroup *eg; + RuleEntry *q; Junction *p; Graph r; int f, l; ECnode *e; + set toksrefd, rulesrefd; + char *pdecl=NULL, *ret=NULL, *a; CurRetDef = CurParmDef = NULL; + CurExGroups = NULL; + CurElementLabels = NULL; + CurAstLabelsInActions = NULL; /* MR27 */ + /* We want a new element label hash table for each rule */ + if ( Elabel!=NULL ) killHashTable(Elabel); + Elabel = newHashTable(); + attribsRefdFromAction = empty; + >> + NonTerminal + <str; + } + CurRuleNode = q; + f = CurFile; l = zzline; + NumRules++; + >> + { "!" <noAST = TRUE;>> } + { <<;>> + {"\<"} + PassAction + << pdecl = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(pdecl!=NULL, "rule rule: cannot allocate param decl"); + strcpy(pdecl, LATEXT(1)); + CurParmDef = pdecl; + >> + } + { "\>" + PassAction + << ret = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(ret!=NULL, "rule rule: cannot allocate ret type"); + strcpy(ret, LATEXT(1)); + CurRetDef = ret; + >> + } + { QuotedTerm <egroup=mystrdup(LATEXT(1));>> } + << + if ( GenEClasseForRules && q!=NULL ) { + e = newECnode; + require(e!=NULL, "cannot allocate error class node"); + if ( q->egroup == NULL ) {a = q->str; a[0] = (char)toupper(a[0]);} + else a = q->egroup; + if ( Tnum( a ) == 0 ) + { + e->tok = addTname( a ); + list_add(&eclasses, (char *)e); + if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]); + /* refers to itself */ + list_add(&(e->elist), mystrdup(q->str)); + } + else { + warn(eMsg1("default errclass for '%s' would conflict with token/errclass/tokclass",a)); + if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]); + free((char *)e); + } + } + >> + <= MAX_BLK_LEVEL) fatal("Blocks nested too deeply"); +/* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID; +/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; + >> + + ":" <> + block[&toksrefd, &rulesrefd] + <blockid = CurBlockID; + CurRuleBlk->jtype = RuleBlk; + if ( q!=NULL ) CurRuleBlk->rname = q->str; + CurRuleBlk->file = f; + CurRuleBlk->line = l; + CurRuleBlk->pdecl = pdecl; + CurRuleBlk->ret = ret; + CurRuleBlk->lock = makelocks(); + CurRuleBlk->pred_lock = makelocks(); + CurRuleBlk->tokrefs = toksrefd; + CurRuleBlk->rulerefs = rulesrefd; + p = newJunction(); /* add EndRule Node */ + ((Junction *)r.right)->p1 = (Node *)p; + r.right = (Node *) p; + p->jtype = EndRule; + p->lock = makelocks(); + p->pred_lock = makelocks(); + CurRuleBlk->end = p; + if ( q!=NULL ) q->rulenum = NumRules; + $7 = r; + >> + << + /* MR23 */ CurBlockID_array[BlkLevel] = (-1); + /* MR23 */ CurAltNum_array[BlkLevel] = (-1); + --BlkLevel; + >> + <> /* MR7 */ + ";" <> + { Action + << a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(a!=NULL, "rule rule: cannot allocate error action"); + strcpy(a, LATEXT(1)); + CurRuleBlk->erraction = a; + >> + } + ( exception_group > [eg] + <label == NULL || *eg->label=='\0' ) q->has_rule_exception = 1; + } + >> + )* + <> + <exceptions = CurExGroups;>> + <el_labels = CurElementLabels;>> + <ast_labels_in_actions = CurAstLabelsInActions;>> /* MR27 */ + <> /* MR27 Moved */ + ; + <> + +/* + * pragma : "{\\}#pragma" "dup\-labeled\-tokens" + * <> + * ; + */ + +/* rule laction */ + +laction : <> + + "{\\}#lexaction" + Action + << + a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(a!=NULL, "rule laction: cannot allocate action"); + strcpy(a, LATEXT(1)); + list_add(&LexActions, a); + >> + ; + <> + +/* MR1 */ +/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ +/* MR1 via #lexmember <<....>> & #lexprefix <<...>> */ +/* MR1 */ + +/* rule lmember */ + +lmember: <> /* MR1 */ + +/* MR1 */ "{\\}#lexmember" +/* MR1 */ Action +/* MR1 */ << +/* MR1 */ if (! GenCC) { +/* MR1 */ err("Use #lexmember only in C++ mode (to insert code in DLG class header"); +/* MR1 */ } else { +/* MR1 */ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); +/* MR1 */ require(a!=NULL, "rule lmember: cannot allocate action"); +/* MR1 */ strcpy(a, LATEXT(1)); +/* MR1 */ list_add(&LexMemberActions, a); +/* MR1 */ }; +/* MR1 */ >> +/* MR1 */ ; +/* MR1 */ <> + +/* rule lprefix */ + +lprefix: <> /* MR1 */ + +/* MR1 */ "{\\}#lexprefix" +/* MR1 */ Action +/* MR1 */ << +/* MR1 */ if (! GenCC) { +/* MR1 */ err("Use #lexprefix only in C++ mode (to insert code in DLG class header"); +/* MR1 */ } else { +/* MR1 */ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); +/* MR1 */ require(a!=NULL, "rule lprefix: cannot allocate action"); +/* MR1 */ strcpy(a, LATEXT(1)); +/* MR1 */ list_add(&LexPrefixActions, a); +/* MR1 */ }; +/* MR1 */ >> +/* MR1 */ ; +/* MR1 */ <> + +/* + * #pred upper <>? predicate literal + * #pred lower <>? predicate literal + * #pred up_or_low upper || lower predicate expression + * concealed interdependence + * #pred up_or_low_2 <>? A || B predicate literal equals predicate expr + * analyze using lower||upper + * generate using isLetter() + */ + +/* rule aPref */ + +aPred: <> + + "{\\}#pred" + + << + MR_usingPredNames=1; /* will need to use -mrhoist version of genPredTree */ + >> + + /* used to allow NonTerminal but it caused problems + when a rule name immediately followed a #pred statement */ + + TokenTerm <> + + << + /* don't free - referenced in predicates */ + + CurPredName=(char *)calloc(1,strlen(name) + 10); + strcat(CurPredName,"#pred "); + strcat(CurPredName,name); + + predEntry=(PredEntry *) hash_get(Pname,name); + if (predEntry != NULL) { + warnFL(eMsg1("#pred %s previously defined - ignored",name), + FileStr[action_file],action_line); + name=NULL; + }; + >> + + ( + + Pred <> + + { + predOrExpr>[predExpr] <> + } + + <file=save_file; + predEntry->line=save_line; + predExpr=MR_predFlatten(predExpr); + predEntry->predLiteral=predLiteral; + if (! predExprPresent || predExpr == NULL) { + predExpr=new_pred(); + predExpr->expr=predLiteral; + predExpr->source=newActionNode(); + predExpr->source->action=predExpr->expr; + predExpr->source->rname=CurPredName; + predExpr->source->line=action_line; + predExpr->source->file=action_file; + predExpr->source->is_predicate=1; + predExpr->k=predicateLookaheadDepth(predExpr->source); + }; + predEntry->pred=predExpr; + hash_add(Pname,name,(Entry *)predEntry); + predExpr=NULL; + }; + predicate_free(predExpr); + >> + + | + <> + + predOrExpr>[predExpr] + + <file=CurFile; + predEntry->line=zzline; + predExpr=MR_predFlatten(predExpr); + predEntry->pred=predExpr; + hash_add(Pname,name,(Entry *)predEntry); + predExpr=NULL; + }; + predicate_free(predExpr); + >> + ) + {";"} +; + +/* fail */ + +<> + +/* rule predOrExpr */ + +predOrExpr>[Predicate *result] : + <> + predAndExpr>[predExpr] + << + ORnode=new_pred(); + ORnode->expr=PRED_OR_LIST; + if (predExpr != NULL) { + ORnode->down=predExpr; + tail=&predExpr->right; + }; + >> + ( "\|\|" predAndExpr>[predExpr] + << + if (predExpr != NULL) { + *tail=predExpr; + tail=&predExpr->right; + }; + >> + )* + << + $result=ORnode; + ORnode=NULL; + >> +; + +/* fail */ + +<> + +/* rule predAndExpr */ + +predAndExpr>[Predicate *result] : + <> + predPrimary>[predExpr] + << + ANDnode=new_pred(); + ANDnode->expr=PRED_AND_LIST; + if (predExpr != NULL) { + ANDnode->down=predExpr; + tail=&predExpr->right; + }; + >> + ( "&&" predPrimary>[predExpr] + << + if (predExpr != NULL) { + *tail=predExpr; + tail=&predExpr->right; + }; + >> + )* + << + $result=ANDnode; + ANDnode=NULL; + >> +; + +/* fail */ + +<> + + +/* rule predPrimary */ + +predPrimary>[Predicate *result] : + << + char *name=NULL; + PredEntry *predEntry=NULL; + Predicate *predExpr=NULL; + >> + + TokenTerm <> + + << + predEntry=(PredEntry *) hash_get(Pname,name); + if (predEntry == NULL) { + warnFL(eMsg1("no previously defined #pred with name \"%s\"",name), + FileStr[CurFile],zzline); + name=NULL; + $result=NULL; + } else { + predExpr=predicate_dup(predEntry->pred); + predExpr->predEntry=predEntry; + $result=predExpr; + }; + >> + + | "\(" predOrExpr>[predExpr] "\)" + << + $result=predExpr; + >> + + | "!" predPrimary>[predExpr] + << + predExpr->inverted=!predExpr->inverted; + $result=predExpr; + >> +; + +/* fail */ << + predicate_free(predExpr); + >> + +/* rule aLexclass */ + +aLexclass: "{\\}#lexclass" TokenTerm <> + ; + <> + +/* rule error */ + +error : <> + "{\\}#errclass" + (<<;>> TokenTerm <> + | QuotedTerm <> + ) + <lexclass = CurrentLexClass; + if ( Tnum( (t=StripQuotes(t)) ) == 0 ) + { + if ( hash_get(Texpr, t) != NULL ) + warn(eMsg1("errclass name conflicts with regular expression '%s'",t)); + e->tok = addTname( t ); + set_orel(e->tok, &imag_tokens); + require((p=(TermEntry *)hash_get(Tname, t)) != NULL, + "hash table mechanism is broken"); + p->classname = 1; /* entry is errclass name, not token */ + list_add(&eclasses, (char *)e); + } + else + { + warn(eMsg1("redefinition of errclass or conflict w/token or tokclass '%s'; ignored",t)); + free( (char *)e ); + go=0; + } + >> + "\{" + ( NonTerminal <> + | TokenTerm <> + | QuotedTerm <> + ) + <elist), t);>> + ( + ( NonTerminal <> + | TokenTerm <> + | QuotedTerm <> + ) + <elist), t);>> + )* + "\}" + ; + <> + +/* rule tclass */ + +tclass : <> + <> + <> + "{\\}#tokclass" TokenTerm <> + <lexclass = CurrentLexClass; + if ( Tnum( t ) == 0 ) + { + e->tok = addTname( t ); + set_orel(e->tok, &imag_tokens); + set_orel(e->tok, &tokclasses); + require((p=(TermEntry *)hash_get(Tname, t)) != NULL, + "hash table mechanism is broken"); + p->classname = 1; /* entry is class name, not token */ + p->tclass = e; /* save ptr to this tclass def */ + list_add(&tclasses, (char *)e); + } + else + { + warn(eMsg1("redefinition of tokclass or conflict w/token '%s'; ignored",t)); + free( (char *)e ); + go=0; + } + >> +/* MR23 */ { +/* MR23 */ "\(" +/* MR23 */ QuotedTerm +/* MR23 */ <> +/* MR23 */ "\)" +/* MR23 */ } +/* MR23 */ +/* MR23 */ +/* MR23 */ << +/* MR23 */ if (p!= NULL && akaString != NULL) { +/* MR23 */ if (p->akaString != NULL) { +/* MR23 */ if (strcmp(p->akaString,akaString) != 0) { +/* MR23 */ warnFL(eMsg2("this #tokclass statment conflicts with a previous #tokclass %s(\"%s\") statement", +/* MR23 */ t,p->akaString), +/* MR23 */ FileStr[save_file],save_line); +/* MR23 */ }; +/* MR23 */ } else { +/* MR23 */ p->akaString=akaString; +/* MR23 */ }; +/* MR23 */ }; +/* MR23 */ >> + + "\{" + ( + ( TokenTerm + <> + + { + ".." + TokenTerm + + <> + } + + | QuotedTerm + <> + ) + <tlist), t); + } else { + list_add(&(e->tlist),".."); + list_add(&(e->tlist),t); + list_add(&(e->tlist),totext); + } + totext=NULL; + } + >> + )+ // MR15 Manfred Kogler - forbid empty #tokclass sets (was "+") + "\}" + ; + <> + +/* rule token */ + +token : <> + <> /* MR11 */ + "{\\}#token" + +/* MR1 10-Apr-97 MR1 Allow shift right operator in DLG actions */ +/* MR1 Danger when parser feedback to lexer */ +/* MR1 */ + + <> /* MR1 */ + { TokenTerm <> + +/* MR11 */ { +/* MR11 */ "\(" +/* MR11 */ QuotedTerm +/* MR11 */ <> +/* MR11 */ "\)" +/* MR11 */ } + + { "=" "[0-9]+" /* define the token type number */ + <> + } + } + { QuotedTerm <> } + { Action + << + a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(a!=NULL, "rule token: cannot allocate action"); + strcpy(a, LATEXT(1)); + >> + } + + { ";" } /* MR11 */ + + <> + + <akaString != NULL) { + if (strcmp(te->akaString,akaString) != 0) { + warnFL(eMsg2("this #token statment conflicts with a previous #token %s(\"%s\") statement", + t,te->akaString), + FileStr[save_file],save_line); + }; + } else { + te->akaString=akaString; + }; + }; + }; + >> + ; + <> + +/* rule block */ + +block[set *toksrefd, set *rulesrefd] + : << + Graph g, b; + set saveblah; + int saveinalt = inAlt; + ExceptionGroup *eg; + *$toksrefd = empty; + *$rulesrefd = empty; + set_clr(AST_nodes_refd_in_actions); + CurBlockID++; +/* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID; + CurAltNum = 1; +/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; + saveblah = attribsRefdFromAction; + attribsRefdFromAction = empty; + >> + + alt[toksrefd,rulesrefd] <> + + << + if ( ((Junction *)g.left)->p1->ntype == nAction ) + { + ActionNode *actionNode=(ActionNode *) + ( ( (Junction *)g.left) ->p1); + if (!actionNode->is_predicate ) + { + actionNode->init_action = TRUE; +/* MR12c */ if (actionNode->noHoist) { +/* MR12c */ errFL("<> appears as init-action - use <<>> <>", +/* MR12c */ FileStr[actionNode->file],actionNode->line); +/* MR12c */ }; + } + } + ((Junction *)g.left)->blockid = CurBlockID; + >> + + ( exception_group > [eg] + << + if ( eg!=NULL ) { +/* MR7 ***** eg->altID = makeAltID(CurBlockID,CurAltNum); *****/ +/* MR7 ***** CurAltStart->exception_label = eg->altID; *****/ + list_add(&CurExGroups, (void *)eg); + } + >> + )* + <> + + ( "\|" <> + alt[toksrefd,rulesrefd] <> + << + ((Junction *)g.left)->blockid = CurBlockID; + >> + + ( exception_group > [eg] + << + if ( eg!=NULL ) { +/* MR7 ***** eg->altID = makeAltID(CurBlockID,CurAltNum); *****/ +/* MR7 ***** CurAltStart->exception_label = eg->altID; *****/ + list_add(&CurExGroups, (void *)eg); + } + >> + )* + + <> + + )* + <<$0 = b;>> + <> + ; + <> + +/* rule alt */ + +alt[set *toksrefd, set *rulesrefd] + : <> + { "\@" /* handle MismatchedToken signals with default handler */ + <> + } + + ( <<;>> /* MR9 Removed unreferenced variable "tok" */ + { <> "\~" <> } + element[old_not, first_on_line, use_def_MT_handler] > [node] + <ntype!=nAction ) first_on_line = 0;>> + << + if ( $2.left!=NULL ) { + g = Cat(g, $2); + n++; + if ( node!=NULL ) { + if ( node->ntype!=nAction ) e_num++; + /* record record number of all rule and token refs */ + if ( node->ntype==nToken ) { + TokNode *tk = (TokNode *)((Junction *)$2.left)->p1; + tk->elnum = e_num; + set_orel(e_num, &elems); + } + else if ( node->ntype==nRuleRef ) { + RuleRefNode *rn = (RuleRefNode *)((Junction *)$2.left)->p1; + rn->elnum = e_num; + set_orel(e_num, $rulesrefd); + } + } + } + >> + )* + <0 ) + err("one or more $i in action(s) refer to non-token elements"); + set_free(dif); + } + set_free(elems); + set_free(attribsRefdFromAction); + inAlt = 0; + >> + ; + <> + +/* rule element_label */ + +element_label > [LabelEntry *label] + : <> + LABEL <> + << + UsedNewStyleLabel = 1; + if ( UsedOldStyleAttrib ) err("cannot mix with new-style labels with old-style $i"); + t = (TermEntry *) hash_get(Tname, lab); + if ( t==NULL ) t = (TermEntry *) hash_get(Texpr, lab); + if ( t==NULL ) r = (RuleEntry *) hash_get(Rname, lab); + if ( t!=NULL ) { + err(eMsg1("label definition clashes with token/tokclass definition: '%s'", lab)); + $label = NULL; + } + else if ( r!=NULL ) { + err(eMsg1("label definition clashes with rule definition: '%s'", lab)); + $label = NULL; + } + else { + /* we don't clash with anybody else */ + l = (LabelEntry *) hash_get(Elabel, lab); + if ( l==NULL ) { /* ok to add new element label */ + l = (LabelEntry *)hash_add(Elabel, + lab, + (Entry *)newLabelEntry(lab)); + /* add to list of element labels for this rule */ + list_add(&CurElementLabels, (void *)lab); +/* MR7 */ leAdd(l); /* list of labels waiting for exception group definitions */ + $label = l; + } + else { + err(eMsg1("label definitions must be unique per rule: '%s'", lab)); + $label = NULL; + } + } + >> + ":" + ; + +/* rule element */ + +element[int old_not, int first_on_line, int use_def_MT_handler] > [Node *node] + : << + Attrib blk; + Predicate *pred = NULL; + int local_use_def_MT_handler=0; + ActionNode *act; + RuleRefNode *rr; + set toksrefd, rulesrefd; + TermEntry *term; + TokNode *p=NULL; RuleRefNode *q; int approx=0; + LabelEntry *label=NULL; + int predMsgDone=0; + int semDepth=0; + int ampersandStyle; + int height; /* MR11 */ + int equal_height; /* MR11 */ + + char* pFirstSetSymbol = NULL; /* MR21 */ + + $node = NULL; + >> + {element_label>[label]} + ( TokenTerm + << + term = (TermEntry *) hash_get(Tname, LATEXT(1)); + if ( term==NULL && UserDefdTokens ) { + err("implicit token definition not allowed with #tokdefs"); + $$.left = $$.right = NULL; + } + else { + $$ = buildToken(LATEXT(1)); + p=((TokNode *)((Junction *)$$.left)->p1); + term = (TermEntry *) hash_get(Tname, LATEXT(1)); + require( term!= NULL, "hash table mechanism is broken"); + p->tclass = term->tclass; + p->complement = $old_not; + if ( label!=NULL ) { + p->el_label = label->str; + label->elem = (Node *)p; + } + } + >> + { ".." + ( QuotedTerm + <> + | TokenTerm + <> + ) + } + << + if ( p!=NULL && (p->upper_range!=0 || p->tclass || $old_not) ) + list_add(&MetaTokenNodes, (void *)p); + >> + ( "^" <astnode=ASTroot;>> + | <astnode=ASTchild;>> + | "!" <astnode=ASTexclude;>> + ) + { "\@" <> } + << + if ( p!=NULL && $first_on_line ) { + CurAltStart = (Junction *)$$.left; + altAdd(CurAltStart); /* MR7 */ + p->altstart = CurAltStart; + } + if ( p!=NULL ) + p->use_def_MT_handler = $use_def_MT_handler || local_use_def_MT_handler; + $node = (Node *)p; + >> + | QuotedTerm + << + term = (TermEntry *) hash_get(Texpr, LATEXT(1)); + if ( term==NULL && UserDefdTokens ) { + err("implicit token definition not allowed with #tokdefs"); + $$.left = $$.right = NULL; + } + else { + $$ = buildToken(LATEXT(1)); p=((TokNode *)((Junction *)$$.left)->p1); + p->complement = $old_not; + if ( label!=NULL ) { + p->el_label = label->str; + label->elem = (Node *)p; + } + } + >> + { ".." + ( QuotedTerm + <> + | TokenTerm + <> + ) + } + ( "^" <astnode=ASTroot;>> + | <astnode=ASTchild;>> + | "!" <astnode=ASTexclude;>> + ) + { "\@" <> } + << + if ( p!=NULL && (p->upper_range!=0 || p->tclass || $old_not) ) + list_add(&MetaTokenNodes, (void *)p); + >> + << + if ( $first_on_line ) { + CurAltStart = (Junction *)$$.left; + altAdd(CurAltStart); /* MR7 */ + p->altstart = CurAltStart; + } + if ( p!=NULL ) + p->use_def_MT_handler = $use_def_MT_handler || local_use_def_MT_handler; + $node = (Node *)p; + >> + + | <> + "." + <<$$ = buildWildCard(LATEXT(1)); p=((TokNode *)((Junction *)$$.left)->p1);>> + ( "^" <astnode=ASTroot;>> + | <astnode=ASTchild;>> + | "!" <astnode=ASTexclude;>> + ) + <> + << + if ( $first_on_line ) { + CurAltStart = (Junction *)$$.left; + altAdd(CurAltStart); /* MR7 */ + p->altstart = CurAltStart; + if ( label!=NULL ) { + p->el_label = label->str; + label->elem = (Node *)p; + } + } + $node = (Node *)p; + >> + + | <> + NonTerminal + <<$$ = buildRuleRef(LATEXT(1));>> + { "!" <p1; + q->astnode=ASTexclude;>> + } + { {"\<"} + PassAction <p1, LATEXT(1));>> + } + <p1;>> + { <> + "\>" + PassAction + << + a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(a!=NULL, "rule element: cannot allocate assignment"); + strcpy(a, LATEXT(1)); + rr->assign = a; + >> + } + << + if ( label!=NULL ) { + rr->el_label = label->str; + label->elem = (Node *)rr; + } + if ( $first_on_line ) { + CurAltStart = (Junction *)$$.left; + altAdd(CurAltStart); /* MR7 */ + ((RuleRefNode *)((Junction *)$$.left)->p1)->altstart = CurAltStart; + } + $node = (Node *)rr; + >> + ) + + | <> + Action <<$0 = buildAction(LATEXT(1),action_file,action_line, 0);>> + <> /* MR7 */ + <<$node = (Node *) ((Junction *)$0.left)->p1;>> + + | <> + Pred <<$0 = buildAction(LATEXT(1),action_file,action_line, 1);>> + <p1;>> + <> + { <> + PassAction + << + a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(a!=NULL, "rule element: cannot allocate predicate fail action"); + strcpy(a, LATEXT(1)); + act->pred_fail = a; + >> + } + <> /* MR7 */ + <<$node = (Node *)act;>> + + | <> + <= MAX_BLK_LEVEL) fatal("Blocks nested too deeply"); +/* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID; +/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; + >> + { Pragma + ( "approx" <> + | "LL\(1\)" <> /* MR20 */ + | "LL\(2\)" <> /* MR20 */ + ) + } + +/* MR21 */ { FirstSetSymbol +/* MR21 */ "\(" +/* MR21 */ ( NonTerminal +/* MR21 */ << +/* MR21 */ pFirstSetSymbol = (char *) calloc(strlen(LATEXT(1))+1, +/* MR21 */ sizeof(char)); +/* MR21 */ require(pFirstSetSymbol!=NULL, +/* MR21 */ "cannot allocate first set name"); +/* MR21 */ strcpy(pFirstSetSymbol, LATEXT(1)); +/* MR21 */ >> +/* MR21 */ | TokenTerm +/* MR21 */ << +/* MR21 */ pFirstSetSymbol = (char *) calloc(strlen(LATEXT(1))+1, +/* MR21 */ sizeof(char)); +/* MR21 */ require(pFirstSetSymbol!=NULL, +/* MR21 */ "cannot allocate first set name"); +/* MR21 */ strcpy(pFirstSetSymbol, LATEXT(1)); +/* MR21 */ >> +/* MR21 */ ) +/* MR21 */ "\)" +/* MR21 */ } + + ( + + "\(" block[&toksrefd,&rulesrefd] "\)" + <> + + ( "\*" <<$$ = makeLoop($$,approx,pFirstSetSymbol);>> + | "\+" <<$$ = makePlus($$,approx,pFirstSetSymbol);>> + | "?" + ( + ( "=>" <> + | "&&" <> /* MR10 (g)? && <

>? */ + ) + Pred /* generalized predicate */ + /* first make into a predicate */ + <<$$ = buildAction(LATEXT(1),action_file,action_line,1);>> + <p1;>> + <> /* MR10 */ + <> + { <> + PassAction + << + a = (char *)calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(a!=NULL, "rule element: cannot allocate predicate fail action"); + strcpy(a, LATEXT(1)); + act->pred_fail = a; + >> + } + <> + <<$node = (Node *)act;>> + + /* for now, just snag context */ + << + pred = computePredFromContextGuard(blk,&predMsgDone); /* MR10 */ + if ( pred==NULL) { /* MR10 */ + if ( !predMsgDone) err("invalid or missing context guard"); /* MR10 */ + predMsgDone=1; /* MR10 */ + } else { /* MR10 */ + act->guardNodes=(Junction *)blk.left; /* MR11 */ + pred->expr = act->action; + pred->source = act; +/* MR10 */ pred->ampersandStyle = ampersandStyle; /* 0 means (g)? => ... 1 means (g)? && ... */ +/* MR13 */ if (pred->tcontext != NULL) { +/* MR13 */ height=MR_max_height_of_tree(pred->tcontext); +/* MR13 */ equal_height=MR_all_leaves_same_height(pred->tcontext,height); +/* MR13 */ if (! equal_height) { +/* MR13 */ errFL("in guarded predicates all tokens in the guard must be at the same height", +/* MR13 */ FileStr[act->file],act->line); +/* MR13 */ }; +/* MR13 */ } +/* MR10 */ if (ampersandStyle) { +/* MR10 */ act->ampersandPred = pred; +/* MR11 */ if (! HoistPredicateContext) { +/* MR11 */ errFL("without \"-prc on\" (guard)? && <>? ... doesn't make sense", +/* MR11 */ FileStr[act->file],act->line); +/* MR11 */ }; +/* MR10 */ } else { +/* MR10 */ act->guardpred = pred; +/* MR10 */ }; +/* MR10 */ if (pred->k != semDepth) { +/* MR10 */ warn(eMsgd2("length of guard (%d) does not match the length of semantic predicate (%d)", +/* MR10 */ pred->k,semDepth)); +/* MR10 */ }; + } + >> + | <<$$ = makeBlk($$,approx,pFirstSetSymbol); + FoundGuessBlk = 1; + ((Junction *) ((Junction *)$$.left)->p1)->guess=1; + if ( !$first_on_line ) { + err("(...)? predicate must be first element of production"); + } + >> + ) + | <<$$ = makeBlk($$,approx,pFirstSetSymbol);>> + ) + << + if ( pred==NULL && !predMsgDone) { /* MR10 */ + ((Junction *)((Junction *)$$.left)->p1)->blockid = CurBlockID; + ((Junction *)((Junction *)$$.left)->p1)->tokrefs = toksrefd; + ((Junction *)((Junction *)$$.left)->p1)->rulerefs = rulesrefd; + if ( $first_on_line ) { /* MR7 */ + CurAltStart = (Junction *)((Junction *)((Junction *)$$.left)->p1); /* MR7 */ + altAdd(CurAltStart); /* MR7 */ + }; /* MR7 */ + $node = (Node *) ((Junction *)$$.left)->p1; + } + >> + + | "\{" block[&toksrefd,&rulesrefd] + <<$$ = makeOpt($2,approx,pFirstSetSymbol); + /* MR23 */ CurBlockID_array[BlkLevel] = (-1); + /* MR23 */ CurAltNum_array[BlkLevel] = (-1); + --BlkLevel; + >> + "\}" + << + ((Junction *)((Junction *)$$.left)->p1)->blockid = CurBlockID; + ((Junction *)((Junction *)$$.left)->p1)->tokrefs = toksrefd; + ((Junction *)((Junction *)$$.left)->p1)->rulerefs = rulesrefd; + >> + <p1); /* MR7 */ + altAdd(CurAltStart); /* MR7 */ + }; + >> + <<$node = (Node *) ((Junction *)$$.left)->p1;>> + + ) + +/* Error catching alternatives */ + | "\*" <> + | "\+" <> + | "\>" <' can only appear after a nonterminal"); CannotContinue=TRUE;>> + | PassAction < [...]'"); + CannotContinue=TRUE;>> + ; + <> + +/* rule default_exception_handler */ + +default_exception_handler + : exception_group > [DefaultExGroup] + ; + +/* rule exception_group */ + +exception_group > [ExceptionGroup *eg] + : <> /* MR6 */ + + "exception" <<$eg = (ExceptionGroup *)calloc(1, sizeof(ExceptionGroup));>> + { <> + PassAction /* did they attach a label? */ + << + p = LATEXT(1)+1; + p[strlen(p)-1] = '\0'; /* kill trailing space */ + label = (LabelEntry *) hash_get(Elabel, LATEXT(1)+1); + if ( label==NULL ) + { + err(eMsg1("unknown label in exception handler: '%s'", LATEXT(1)+1)); + } + >> + } + ( exception_handler > [h] + <handlers), (void *)h);>> + )* + { "default" ":" Action + <<{ + ExceptionHandler *eh = (ExceptionHandler *) + calloc(1, sizeof(ExceptionHandler)); + char *a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require(eh!=NULL, "exception: cannot allocate handler"); + require(a!=NULL, "exception: cannot allocate action"); + strcpy(a, LATEXT(1)); + eh->action = a; + eh->signalname = (char *) calloc(strlen("default")+1, sizeof(char)); + require(eh->signalname!=NULL, "exception: cannot allocate sig name"); + strcpy(eh->signalname, "default"); + list_add(&($eg->handlers), (void *)eh); + }>> + } + + << + if ( label!=NULL ) { + /* Record ex group in sym tab for this label */ + if ( label->ex_group!=NULL ) { + err(eMsg1("duplicate exception handler for label '%s'",label->str)); + } else { + label->ex_group = $eg; + /* Label the exception group itself */ + $eg->label = label->str; + /* Make the labelled element pt to the exception also */ +/* MR6 */ if (label->elem == NULL) { +/* MR6 */ err(eMsg1("reference in exception handler to undefined label '%s'",label->str)); +/* MR6 */ } else { + switch ( label->elem->ntype ) { + case nRuleRef : + { + RuleRefNode *r = (RuleRefNode *)label->elem; + r->ex_group = $eg; + break; + } + case nToken : + { + TokNode *t = (TokNode *)label->elem; + t->ex_group = $eg; + break; + } + } /* end switch */ +/* MR6 */ }; /* end test on label->elem */ + } /* end test on label->ex_group */ + + } /* end test on exception label */ + +/* MR7 */ +/* MR7 */ if (BlkLevel == 1 && label == NULL) { +/* MR7 */ $eg->forRule=1; +/* MR7 */ } else if (label == NULL) { +/* MR7 */ $eg->altID = makeAltID(CurBlockID_array[BlkLevel], CurAltNum_array[BlkLevel]); +/* MR7 */ egAdd($eg); +/* MR7 */ } else { +/* MR7 */ $eg->labelEntry=label; +/* MR7 */ }; +/* MR7 */ +/* MR7 */ /* You may want to remove this exc from the rule list */ +/* MR7 */ /* and handle at the labeled element site. */ +/* MR7 */ +/* MR7 */ if (label != NULL) { +/* MR7 */ $eg = NULL; +/* MR7 */ }; + + >> + ; + <> + +/* rule exception_handler */ + +exception_handler > [ExceptionHandler *eh] + : <<;>> /* MR9 Removed unreferenced variable "a" */ + "catch" + << + $eh = (ExceptionHandler *)calloc(1, sizeof(ExceptionHandler)); + require($eh!=NULL, "exception: cannot allocate handler"); + >> + ( NonTerminal + << + $eh->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require($eh->signalname!=NULL, "exception: cannot allocate sig name"); + strcpy($eh->signalname, LATEXT(1)); + >> + | TokenTerm + << + $eh->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require($eh->signalname!=NULL, "exception: cannot allocate sig name"); + strcpy($eh->signalname, LATEXT(1)); + >> + ) + ":" + { <<$eh->action = NULL;>> + Action + << + $eh->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + require($eh->action!=NULL, "exception: cannot allocate action"); + strcpy($eh->action, LATEXT(1)); + >> + } + ; + <> + +#token NonTerminal "[a-z] [A-Za-z0-9_]*" + << + while ( zzchar==' ' || zzchar=='\t' ) { + zzadvance(); + } + if ( zzchar == ':' && inAlt ) NLA = LABEL; + >> +#token TokenTerm "[A-Z] [A-Za-z0-9_]*" + << + while ( zzchar==' ' || zzchar=='\t' ) { + zzadvance(); + } + if ( zzchar == ':' && inAlt ) NLA = LABEL; + >> +#token "{\\}#[A-Za-z0-9_]*" <> + +#lexclass PARSE_ENUM_FILE + +#token "[\t\ ]+" << zzskip(); >> /* Ignore White */ +#token "\n|\r|\r\n" << zzline++; zzskip(); >> /* Track Line # */ +#token "//" << zzmode(TOK_DEF_CPP_COMMENTS); zzmore(); >> +#token "/\*" << zzmode(TOK_DEF_COMMENTS); zzskip(); >> +#token "#ifdef" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> +#token "#if" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> +#token "#ifndef" << ; >> +#token "#else" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> +#token "#endif" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> +#token "#undef" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> +#token "#import" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> +#token "@" << ; >> + +/* rule enum_file */ + +enum_file[char *fname] + : { "#ifndef" ID + { "#define" ID /* ignore if it smells like a gate */ + /* First #define after the first #ifndef (if any) is ignored */ + } + } + ( ( enum_def[$fname] )+ + | defines[$fname] + ) + | + ; + +/* rule defines */ + +defines[char *fname] + : <> /* MR3 */ + ( + "#define" ID + <> + INT + << + v = atoi(LATEXT(1)); +/* fprintf(stderr, "#token %s=%d\n", t, v);*/ + + /* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */ + /* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */ + /* MR2 Don't let #tokdefs be confused by */ + /* MR2 DLGminToken and DLGmaxToken */ + + if ( ! isDLGmaxToken(t)) { /* MR2 */ + TokenNum = v; + if ( v>maxt ) maxt=v; + if ( Tnum( t ) == 0 ) { + addForcedTname( t, v ); + } else { + warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline); + }; + }; + >> + )+ + <> + ; + +/* rule enum_def */ + +enum_def[char *fname] + : <> /* MR3 */ + "enum" ID + "\{" + ID + <> + ( "=" INT <> + | <> + ) + << +/* fprintf(stderr, "#token %s=%d\n", t, v);*/ + TokenNum = v; + if ( v>maxt ) maxt=v; /* MR3 */ + if ( Tnum( t ) == 0 ) addForcedTname( t, v ); + else { + warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline); + } + >> + ( "," + + /* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */ + /* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */ + /* MR2 Don't let #tokdefs be confused by */ + /* MR2 DLGminToken and DLGmaxToken */ + + { + <>? ID { "=" INT } /* MR2 */ + | ID /* MR2 */ + <> + ( "=" INT <> + | <> + ) + << +/* fprintf(stderr, "#token %s=%d\n", t, v);*/ + TokenNum = v; + if ( v>maxt ) maxt=v; /* MR3 */ + if ( Tnum( t ) == 0 ) addForcedTname( t, v ); + else { + warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline); + } + >> + } + )* + "\}" + ";" + <> /* MR3 */ + ; + +#token INT "[0-9]+" +#token ID "[a-zA-Z_][_a-zA-Z0-9]*" + +#lexclass START + +/* MR14 Arpad Beszedes 26-May-98 + Add support for #line directives when antlr source is pre-processed +*/ + +#lexaction +<< + +static char * +#ifdef __USE_PROTOS +getFileNameFromTheLineInfo(char *toStr, char *fromStr) +#else +getFileNameFromTheLineInfo(toStr, fromStr) +char *toStr, *fromStr; +#endif +{ + int i, j, k; + + if (!fromStr || !toStr) return toStr; + + /* find the first " */ + + for (i=0; + (i> + +<< + +/* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */ +/* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */ +/* MR2 Don't let #tokdefs be confused by */ +/* MR2 DLGminToken and DLGmaxToken */ + +/* semantic check on DLGminToken and DLGmaxmaxToken in #tokdefs */ + +#ifdef __USE_PROTOS +static int isDLGmaxToken(char *Token) +#else +static int isDLGmaxToken(Token) + char * Token; +#endif +{ + static char checkStr1[] = "DLGmaxToken"; + static char checkStr2[] = "DLGminToken"; + + if (strcmp(Token, checkStr1) == 0) + return 1; + else if (strcmp(Token, checkStr2) == 0) + return 1; + else + return 0; +} + +/* semantics of #token */ +static void +#ifdef __USE_PROTOS +chkToken(char *t, char *e, char *a, int tnum) +#else +chkToken(t,e,a,tnum) +char *t, *e, *a; +int tnum; +#endif +{ + TermEntry *p; + + /* check to see that they don't try to redefine a token as a token class */ + if ( t!=NULL ) { + p = (TermEntry *) hash_get(Tname, t); + if ( p!=NULL && p->classname ) { + err(eMsg1("redefinition of #tokclass '%s' to #token not allowed; ignored",t)); + if ( a!=NULL ) free((char *)a); + return; + } + } + + if ( t==NULL && e==NULL ) { /* none found */ + err("#token requires at least token name or rexpr"); + } + else if ( t!=NULL && e!=NULL ) { /* both found */ + if ( UserDefdTokens ) { /* if #tokdefs, must not define new */ + p = (TermEntry *) hash_get(Tname, t); + if ( p == NULL) { +err(eMsg1("new token definition '%s' not allowed - only #token with name already defined by #tokdefs file allowed",t)); + return; + }; + } + Tklink(t, e); + if ( a!=NULL ) { + if ( hasAction(e) ) { + err(eMsg1("redefinition of action for %s; ignored",e)); + } + else setHasAction(e, a); + } + } + else if ( t!=NULL ) { /* only one found */ + if ( UserDefdTokens ) { + p = (TermEntry *) hash_get(Tname, t); + if (p == NULL) { +err(eMsg1("new token definition '%s' not allowed - only #token with name already defined by #tokdefs file allowed",t)); + }; + return; + } + if ( Tnum( t ) == 0 ) addTname( t ); + else { + err(eMsg1("redefinition of token %s; ignored",t)); + } + if ( a!=NULL ) { + err(eMsg1("action cannot be attached to a token name (%s); ignored",t)); + free((char *)a); + } + } + else if ( e!=NULL ) { + if ( Tnum( e ) == 0 ) addTexpr( e ); + else { + if ( hasAction(e) ) { + err(eMsg1("redefinition of action for expr %s; ignored",e)); + } + else if ( a==NULL ) { + err(eMsg1("redefinition of expr %s; ignored",e)); + } + } + if ( a!=NULL ) setHasAction(e, a); + } + + /* if a token type number was specified, then add the token ID and 'tnum' + * pair to the ForcedTokens list. (only applies if an id was given) + */ + if ( t!=NULL && tnum>0 ) + { + if ( set_el(tnum, reserved_positions) ) + { + err(eMsgd("a token has already been forced to token number %d; ignored", tnum)); + } + else + { + list_add(&ForcedTokens, newForcedToken(t,tnum)); + set_orel(tnum, &reserved_positions); + } + } +} +>> + +<< +static int +#ifdef __USE_PROTOS +match_token(char *s, char **nxt) +#else +match_token(s,nxt) +char *s; +char **nxt; +#endif +{ + if ( !(*s>='A' && *s<='Z') ) return 0; + s++; + while ( (*s>='a' && *s<='z') || + (*s>='A' && *s<='Z') || + (*s>='0' && *s<='9') || + *s=='_' ) + { + s++; + } + if ( *s!=' ' && *s!='}' ) return 0; + *nxt = s; + return 1; +} + +static int +#ifdef __USE_PROTOS +match_rexpr(char *s, char **nxt) +#else +match_rexpr(s,nxt) +char *s; +char **nxt; +#endif +{ + if ( *s!='"' ) return 0; + s++; + while ( *s!='"' ) + { + if ( *s=='\n' || *s=='\r' ) /* MR13 */ + warn("eoln found in regular expression"); + if ( *s=='\\' ) s++; + s++; + } + *nxt = s+1; + return 1; +} + +/* + * Walk a string "{ A .. Z }" where A..Z is a space separated list + * of token references (either labels or reg exprs). Return a + * string "inlineX_set" for some unique integer X. Basically, + * we pretend as if we had seen "#tokclass inlineX { A .. Z }" + * on the input stream outside of an action. + */ +char * +#ifdef __USE_PROTOS +inline_set(char *s) +#else +inline_set(s) +char *s; +#endif +{ + char *nxt; + fprintf(stderr, "found consumeUntil( {...} )\n"); + while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;} + if ( *s!='{' ) + { + err("malformed consumeUntil( {...} ); missing '{'"); + return "bad_set"; + } + s++; + while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;} + while ( *s!='}' ) + { + if ( match_token(s,&nxt) ) fprintf(stderr, "found token %s\n", s); + else if ( match_rexpr(s,&nxt) ) fprintf(stderr, "found rexpr %s\n", s); + else { + err("invalid element in consumeUntil( {...} )"); + return "bad_set"; + } + s = nxt; + while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;} + } + return "inlineX_set"; +} +>> + +<< +/* ANTLR-specific syntax error message generator + * (define USER_ZZSYN when compiling so don't get 2 definitions) + */ +void +#ifdef __USE_PROTOS +zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, +int k, char *bad_text) +#else +zzsyn(text, tok, egroup, eset, etok, k, bad_text) +char *text, *egroup, *bad_text; +int tok; +int etok; +int k; +SetWordType *eset; +#endif +{ + fprintf(stderr, ErrHdr, FileStr[CurFile]!=NULL?FileStr[CurFile]:"stdin", zzline); + fprintf(stderr, " syntax error at \"%s\"", (tok==zzEOF_TOKEN)?"EOF":text); + if ( !etok && !eset ) {fprintf(stderr, "\n"); return;} + if ( k==1 ) fprintf(stderr, " missing"); + else + { + fprintf(stderr, "; \"%s\" not", bad_text); + if ( zzset_deg(eset)>1 ) fprintf(stderr, " in"); + } + if ( zzset_deg(eset)>0 ) zzedecode(eset); + else fprintf(stderr, " %s", zztokens[etok]); + if ( strlen(egroup) > (size_t)0 ) fprintf(stderr, " in %s", egroup); + fprintf(stderr, "\n"); +} +>> + +#lexaction << +#ifdef __USE_PROTOS +void mark_label_used_in_sem_pred(LabelEntry *le) /* MR10 */ +#else +void mark_label_used_in_sem_pred(le) /* MR10 */ + LabelEntry *le; +#endif +{ + TokNode *tn; + require (le->elem->ntype == nToken,"mark_label_used... ntype != nToken"); + tn=(TokNode *)le->elem; + require (tn->label != 0,"mark_label_used... TokNode has no label"); + tn->label_used_in_semantic_pred=1; +} +>> diff --git a/Tools/CodeTools/Source/Pccts/antlr/antlr.r b/Tools/CodeTools/Source/Pccts/antlr/antlr.r new file mode 100644 index 0000000000..e3de38759f --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/antlr.r @@ -0,0 +1,787 @@ +/* + File: antlrMPW.r + Target: antlr 133MR + Created: Monday, June 15, 1998 4:41:11 AM + Author: Kenji Tanaka (kentar@osa.att.ne.jp) +*/ + +#include "cmdo.r" + +resource 'cmdo' (128, "Antlr") { + { /* array dialogs: 5 elements */ + /* [1] */ + 295, + "ANTLR -- Purdue Compiler Construction To" + "ol Set (PCCTS) LL(k) parser generator.", + { /* array itemArray: 12 elements */ + /* [1] */ + NotDependent { + + }, + CheckOption { + NotSet, + {18, 23, 33, 223}, + "Read grammar from stdin", + "-", + "Read grammar from stdin." + }, + /* [2] */ + NotDependent { + + }, + CheckOption { + NotSet, + {38, 23, 53, 310}, + "Send grammar.c/grammar.cpp to stdout", + "-stdout", + "Send grammar.c/grammar.cpp to stdout." + }, + /* [3] */ + NotDependent { + + }, + MultiFiles { + "Grammar File(s)É", + "Choose the grammar specification files y" + "ou wish to have ANTLR process.", + {79, 22, 98, 152}, + "Grammar specification:", + "", + MultiInputFiles { + { /* array MultiTypesArray: 1 elements */ + /* [1] */ + text + }, + ".g", + "Files ending in .g", + "All text files" + } + }, + /* [4] */ + NotDependent { + + }, + Files { + DirOnly, + OptionalFile { + {58, 168, 74, 298}, + {79, 169, 98, 299}, + "Output Directory", + ":", + "-o", + "", + "Choose the directory where ANTLR will pu" + "t its output.", + dim, + "Output DirectoryÉ", + "", + "" + }, + NoMore { + + } + }, + /* [5] */ + NotDependent { + + }, + Redirection { + StandardOutput, + {126, 27} + }, + /* [6] */ + NotDependent { + + }, + Redirection { + DiagnosticOutput, + {126, 178} + }, + /* [7] */ + NotDependent { + + }, + TextBox { + gray, + {117, 20, 167, 300}, + "Redirection" + }, + /* [8] */ + NotDependent { + + }, + NestedDialog { + 5, + {20, 324, 40, 460}, + "Parse OptionsÉ", + "Parse control options may be set with th" + "is button." + }, + /* [9] */ + NotDependent { + + }, + NestedDialog { + 2, + {50, 324, 70, 460}, + "Generate OptionsÉ", + "Various command line options may be set " + "with this button." + }, + /* [10] */ + NotDependent { + + }, + NestedDialog { + 3, + {78, 324, 98, 460}, + "More OptionsÉ", + "Antlr has ALOT of options. There are eve" + "n more to be found with this button." + }, + /* [11] */ + NotDependent { + + }, + NestedDialog { + 4, + {106, 324, 126, 460}, + "Rename OptionsÉ", + "Options for renaming output files may be" + " set with this button." + }, + /* [12] */ + NotDependent { + + }, + VersionDialog { + VersionString { + "1.33MR" + }, + "PCCTS was written by Terence Parr, Russe" + "ll Quong, Will Cohen, and Hank Dietz: 19" + "89-1998. MPW port by Scott Haney.", + noDialog + } + }, + /* [2] */ + 295, + "Use this dialog to specify command line " + "Generate Options.", + { /* array itemArray: 15 elements */ + /* [1] */ + NotDependent { + + }, + CheckOption { + NotSet, + {18, 25, 33, 225}, + "Generate C++ code", + "-CC", + "Generate C++ output from both ANTLR and " + "DLG." + }, + /* [2] */ + NotDependent { + + }, + CheckOption { + NotSet, + {38, 25, 53, 225}, + "Generate ASTs", + "-gt", + "Generate code for Abstract-Syntax-Trees " + "(ASTs)." + }, + /* [3] */ + NotDependent { + + }, + CheckOption { + NotSet, + {58, 25, 73, 225}, + "Generate line info", + "-gl", + "If this option is checked, ANTLR will ge" + "nerate line info about grammaractions, t" + "hereby making debugging easier since com" + "pile errors will point to the grammar fi" + "le." + }, + /* [4] */ + NotDependent { + + }, + CheckOption { + NotSet, + {78, 25, 93, 225}, + "Generate error classes", + "-ge", + "If this option is checked, ANTLR will ge" + "nerate an error class foreach non-termin" + "al." + }, + /* [5] */ + NotDependent { + + }, + CheckOption { + NotSet, + {98, 25, 113, 225}, + "Don't generate Code", + "-gc", + "If this option is checked, ANTLR will ge" + "nerate no code, i.e. it will only perfor" + "m analysis on the grammar." + }, + /* [6] */ + NotDependent { + + }, + CheckOption { + NotSet, + {118, 25, 133, 225}, + "Delay lookahead fetches", + "-gk", + "If this option is checked, ANTLR will ge" + "nerate a parser that delays lookahead fe" + "tches until needed." + }, + /* [7] */ + NotDependent { + + }, + CheckOption { + NotSet, + {138, 25, 153, 225}, + "Use newAST(...)", + "-newAST", + "In C++ mode use \"newAST(...)\" rather tha" + "n \"new AST(...)\"" + }, + /* [8] */ + NotDependent { + + }, + CheckOption { + NotSet, + {18, 235, 33, 435}, + "Support parse traces", + "-gd", + "If this option is checked, ANTLR inserts" + " code in each parsing function to provid" + "e for user-defined handling of a detaile" + "d parse trace. The code consists of call" + "s to zzTRACEIN and zzTRACEOUT." + }, + /* [9] */ + NotDependent { + + }, + CheckOption { + NotSet, + {38, 235, 53, 435}, + "Generate cross-references", + "-cr", + "If this option is checked, ANTLR will ge" + "nerate a cross reference for all rules. " + "For each rule it will print a list of al" + "l other rules that refrence it." + }, + /* [10] */ + NotDependent { + + }, + CheckOption { + NotSet, + {58, 235, 73, 435}, + "Don't create Lexer files", + "-gx", + "If this option is checked, ANTLR will no" + "t generate DLG-related output files. Thi" + "s option should be used if one wants a c" + "ustom lexical analyzer or if one has mad" + "e changes to the grammar not affecting t" + "he lexical structure." + }, + /* [11] */ + NotDependent { + + }, + CheckOption { + NotSet, + {78, 235, 93, 460}, + "Don't generate token expr sets", + "-gs", + "If this option is checked, ANTLR will no" + "t generate sets for token expression set" + "s; instead, it will generate a || separa" + "ted sequence of LA(1)==token #. " + }, + /* [12] */ + NotDependent { + + }, + CheckOption { + NotSet, + {98, 235, 113, 460}, + "Generate ANSI-compatible", + "-ga", + "Generate ANSI-compatible code (default=F" + "ALSE)" + }, + /* [13] */ + NotDependent { + + }, + CheckOption { + NotSet, + {118, 235, 133, 460}, + "Don't generate tokens.h", + "-gxt", + "Do not generate tokens.h (default=FALSE)" + }, + /* [13] */ + NotDependent { + + }, + CheckOption { + NotSet, + {138, 235, 153, 460}, + "Provide \"(alpha)? beta\" info", + "-alpha", + "Provide additional information for \"(alpha)? beta\" error messages" + }, + /* [14] */ + NotDependent { + + }, + RegularEntry { + "Tabs(1 to 8):", + {162, 23, 177, 117}, + {163, 125, 179, 196}, + "", + keepCase, + "-tab", + "Width of tabs (1 to 8) for grammar.c/gra" + "mmar.cpp files." + }, + /* [15] */ + NotDependent { + + }, + RegularEntry { + "Function Prefix:", + {161, 236, 177, 342}, + {162, 345, 177, 454}, + "", + keepCase, + "-gp", + "Prefix all generated rule functions with" + " a string." + } + }, + /* [3] */ + 295, + "Use this dialog to specify still more co" + "mmand line options.", + { /* array itemArray: 12 elements */ + /* [1] */ + NotDependent { + + }, + RadioButtons { + { /* array radioArray: 3 elements */ + /* [1] */ + {38, 25, 53, 85}, "None", "", Set, "When this option is selected, ANTLR will" + " not print the grammar to stdout.", + /* [2] */ + {38, 100, 53, 160}, "Yes", "-p", NotSet, "When this option is selected, ANTLR will" + " print the grammar, stripped of all acti" + "ons and comments, to stdout.", + /* [3] */ + {38, 175, 53, 235}, "More", "-pa", NotSet, "When this option is selected, ANTLR will" + " print the grammar, stripped of all acti" + "ons and comments, to stdout. It will als" + "o annotate the output with the first set" + "s determined from grammar analysis." + } + }, + /* [2] */ + NotDependent { + + }, + TextBox { + gray, + {28, 15, 60, 250}, + "Grammar Printing" + }, + /* [3] */ + NotDependent { + + }, + RadioButtons { + { /* array radioArray: 3 elements */ + /* [1] */ + {88, 25, 103, 85}, "Low", "", Set, "When this option is selected, ANTLR will" + " show ambiguities/errors in low detail.", + /* [2] */ + {88, 100, 103, 160}, "Medium", "-e2", NotSet, "When this option is selected, ANTLR will" + " show ambiguities/errors in more detail.", + /* [3] */ + {88, 175, 103, 235}, "High", "-e3", NotSet, "When this option is selected, ANTLR will" + " show ambiguities/errors in excruciating" + " detail." + } + }, + /* [4] */ + NotDependent { + + }, + TextBox { + gray, + {78, 15, 110, 250}, + "Error reporting" + }, + /* [5] */ + NotDependent { + + }, + CheckOption { + NotSet, + {130, 22, 145, 222}, + "More warnings", + "-w2", + "If this option is checked, ANTLR will wa" + "rn if semantic predicates and/or (É)? bl" + "ocks are assumed to cover ambiguous alte" + "rnatives." + }, + /* [6] */ + NotDependent { + + }, + RegularEntry { + "Report when tnode usage exceeds:", + {162, 23, 180, 253}, + {162, 255, 178, 326}, + "", + keepCase, + "-treport", + "Report when tnode usage exceeds value du" + "ring ambiguity resolution." + }, + /* [7] */ + NotDependent { + + }, + CheckOption { + NotSet, + {40, 292, 55, 431}, + "Predicate", + "-info p", + "With the antlr \"-info p\" switch the user" + " will receive information about the pred" + "icate suppression in the generated file." + }, + /* [8] */ + NotDependent { + + }, + CheckOption { + NotSet, + {60, 292, 75, 430}, + "Tree Nodes", + "-info t", + "Using \"-info t\" gives information about " + "the total number of tnodes created and t" + "he peak number of tnodes." + }, + /* [9] */ + NotDependent { + + }, + CheckOption { + NotSet, + {80, 292, 95, 425}, + "First/follow", + "-info f", + "first/follow set information." + }, + /* [10] */ + NotDependent { + + }, + CheckOption { + NotSet, + {100, 292, 115, 425}, + "Monitor progress", + "-info m", + "prints name of each rule as it is starte" + "d and flushes output at start of each rule." + }, + /* [11] */ + NotDependent { + + }, + CheckOption { + NotSet, + {120, 292, 135, 416}, + "Orphan rules", + "-info o", + "If there is more than one rule which is " + "not referenced by any other rule then al" + "l such rules are listed." + }, + /* [12] */ + NotDependent { + + }, + TextBox { + gray, + {28, 279, 147, 451}, + "Extra info" + } + }, + /* [4] */ + 295, + "Use this dialog to specify command line " + "options relating to renaming output file" + "s.", + { /* array itemArray: 7 elements */ + /* [1] */ + NotDependent { + + }, + RegularEntry { + "Errors file name:", + {35, 25, 50, 205}, + {35, 205, 51, 300}, + "err.c", + keepCase, + "-fe", + "This entry specifies the name ANTLR uses" + " for the errors file." + }, + /* [2] */ + NotDependent { + + }, + RegularEntry { + "Lexical output name:", + {60, 25, 75, 205}, + {60, 205, 76, 300}, + "parser.dlg", + keepCase, + "-fl", + "This entry specifies the name ANTLR uses" + " for the lexical output file." + }, + /* [3] */ + NotDependent { + + }, + RegularEntry { + "Lexical modes name:", + {85, 25, 100, 205}, + {85, 205, 101, 300}, + "mode.h", + keepCase, + "-fm", + "This entry specifies the name ANTLR uses" + " for the lexical mode definitions file." + }, + /* [4] */ + NotDependent { + + }, + RegularEntry { + "Remap file name:", + {110, 25, 125, 205}, + {110, 205, 126, 300}, + "remap.h", + keepCase, + "-fr", + "This entry specifies the name ANTLR uses" + " for the file that remaps globally visib" + "le symbols." + }, + /* [5] */ + NotDependent { + + }, + RegularEntry { + "Tokens file name:", + {135, 25, 150, 205}, + {135, 205, 151, 300}, + "tokens.h", + keepCase, + "-ft", + "This entry specifies the name ANTLR uses" + " for the tokens file." + }, + /* [6] */ + NotDependent { + + }, + CheckOption { + NotSet, + {160, 25, 175, 175}, + "Create std header", + "-gh", + "If this option is checked, ANTLR will cr" + "eate a standard header file named, by de" + "fault 'stdpccts.h'. This name can be alt" + "ered using the entry right next door." + }, + /* [7] */ + Or { + { /* array OrArray: 1 elements */ + /* [1] */ + 6 + } + }, + RegularEntry { + "Std header file name:", + {160, 175, 175, 355}, + {160, 355, 176, 450}, + "stdpccts.h", + keepCase, + "-fh", + "This entry specifies the name ANTLR uses" + " for the standard header file." + } + }, + /* [5] */ + 295, + "Use this dialog to specify parse options" + ".", + { /* array itemArray: 9 elements */ + /* [1] */ + NotDependent { + + }, + RegularEntry { + "Lookahead:", + {23, 27, 38, 152}, + {46, 29, 62, 154}, + "1", + keepCase, + "-k", + "This entry specifies the number of token" + "s of lookahead." + }, + /* [2] */ + NotDependent { + + }, + RegularEntry { + "Compr lookahead:", + {22, 167, 37, 292}, + {46, 172, 62, 297}, + "", + keepCase, + "-ck", + "This entry specifies the number of token" + "s of lookahead when using compressed (li" + "near approximation) lookahead. In genera" + "l, the compressed lookahead is much deep" + "er than the full lookahead." + }, + /* [3] */ + NotDependent { + + }, + RegularEntry { + "Max tree nodes:", + {22, 312, 37, 437}, + {46, 315, 62, 445}, + "", + keepCase, + "-rl", + "This entry specifies the maximum number " + "of tokens of tree nodes used by the gram" + "mar analysis." + }, + /* [4] */ + NotDependent { + + }, + CheckOption { + NotSet, + {76, 25, 91, 350}, + "Maintenance Release style hoisting", + "-mrhoist", + "Turn on/off k=1 Maintenance Release styl" + "e hoisting." + }, + /* [5] */ + NotDependent { + + }, + CheckOption { + NotSet, + {96, 25, 111, 431}, + "EXPERIMENTAL Maintenance Release style h" + "oisting", + "-mrhoistk", + "Turn on/off k>1 EXPERIMENTAL Maintenance" + " Release style hoisting." + }, + /* [6] */ + NotDependent { + + }, + CheckOption { + NotSet, + {116, 25, 131, 363}, + "Compute context for hoisted predicates", + "-prc on", + "Turn on/off computation of context for h" + "oisted predicates." + }, + /* [7] */ + NotDependent { + + }, + RegularEntry { + "Ambiguity aid:", + {140, 27, 155, 125}, + {141, 135, 155, 209}, + "", + keepCase, + "-aa", + "Ambiguity aid for a rule (rule name or l" + "ine number)." + }, + /* [8] */ + NotDependent { + + }, + RegularEntry { + "Limits exp growth:", + {140, 236, 155, 361}, + {139, 372, 155, 452}, + "", + keepCase, + "-aad", + "Limits exp growth of -aa listing - defau" + "lt=1 (max=ck value)." + }, + /* [9] */ + NotDependent { + + }, + CheckOption { + NotSet, + {164, 26, 179, 366}, + "Lookahead token may appear multiple time" + "s", + "-aam", + "Lookahead token may appear multiple time" + "s in -aa listing." + } + } + } +}; + diff --git a/Tools/CodeTools/Source/Pccts/antlr/antlr1.txt b/Tools/CodeTools/Source/Pccts/antlr/antlr1.txt new file mode 100644 index 0000000000..4a7d22e7f2 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/antlr1.txt @@ -0,0 +1,264 @@ + + + +ANTLR(1) PCCTS Manual Pages ANTLR(1) + + + +NAME + antlr - ANother Tool for Language Recognition + +SYNTAX + antlr [_o_p_t_i_o_n_s] _g_r_a_m_m_a_r__f_i_l_e_s + +DESCRIPTION + _A_n_t_l_r converts an extended form of context-free grammar into + a set of C functions which directly implement an efficient + form of deterministic recursive-descent LL(k) parser. + Context-free grammars may be augmented with predicates to + allow semantics to influence parsing; this allows a form of + context-sensitive parsing. Selective backtracking is also + available to handle non-LL(k) and even non-LALR(k) con- + structs. _A_n_t_l_r also produces a definition of a lexer which + can be automatically converted into C code for a DFA-based + lexer by _d_l_g. Hence, _a_n_t_l_r serves a function much like that + of _y_a_c_c, however, it is notably more flexible and is more + integrated with a lexer generator (_a_n_t_l_r directly generates + _d_l_g code, whereas _y_a_c_c and _l_e_x are given independent + descriptions). Unlike _y_a_c_c which accepts LALR(1) grammars, + _a_n_t_l_r accepts LL(k) grammars in an extended BNF notation - + which eliminates the need for precedence rules. + + Like _y_a_c_c grammars, _a_n_t_l_r grammars can use automatically- + maintained symbol attribute values referenced as dollar + variables. Further, because _a_n_t_l_r generates top-down + parsers, arbitrary values may be inherited from parent rules + (passed like function parameters). _A_n_t_l_r also has a mechan- + ism for creating and manipulating abstract-syntax-trees. + + There are various other niceties in _a_n_t_l_r, including the + ability to spread one grammar over multiple files or even + multiple grammars in a single file, the ability to generate + a version of the grammar with actions stripped out (for + documentation purposes), and lots more. + +OPTIONS + -ck _n + Use up to _n symbols of lookahead when using compressed + (linear approximation) lookahead. This type of looka- + head is very cheap to compute and is attempted before + full LL(k) lookahead, which is of exponential complex- + ity in the worst case. In general, the compressed loo- + kahead can be much deeper (e.g, -ck 10) _t_h_a_n _t_h_e _f_u_l_l + _l_o_o_k_a_h_e_a_d (_w_h_i_c_h _u_s_u_a_l_l_y _m_u_s_t _b_e _l_e_s_s _t_h_a_n _4). + + -CC Generate C++ output from both ANTLR and DLG. + + -cr Generate a cross-reference for all rules. For each + rule, print a list of all other rules that reference + it. + + -e1 Ambiguities/errors shown in low detail (default). + + -e2 Ambiguities/errors shown in more detail. + + -e3 Ambiguities/errors shown in excruciating detail. + + -fe file + Rename err.c to file. + + -fh file + Rename stdpccts.h header (turns on -gh) to file. + + -fl file + Rename lexical output, parser.dlg, to file. + + -fm file + Rename file with lexical mode definitions, mode.h, to + file. + + -fr file + Rename file which remaps globally visible symbols, + remap.h, to file. + + -ft file + Rename tokens.h to file. + + -ga Generate ANSI-compatible code (default case). This has + not been rigorously tested to be ANSI XJ11 C compliant, + but it is close. The normal output of _a_n_t_l_r is + currently compilable under both K&R, ANSI C, and C++- + this option does nothing because _a_n_t_l_r generates a + bunch of #ifdef's to do the right thing depending on + the language. + + -gc Indicates that _a_n_t_l_r should generate no C code, i.e., + only perform analysis on the grammar. + + -gd C code is inserted in each of the _a_n_t_l_r generated pars- + ing functions to provide for user-defined handling of a + detailed parse trace. The inserted code consists of + calls to the user-supplied macros or functions called + zzTRACEIN and zzTRACEOUT. The only argument is a _c_h_a_r + * pointing to a C-style string which is the grammar + rule recognized by the current parsing function. If no + definition is given for the trace functions, upon rule + entry and exit, a message will be printed indicating + that a particular rule as been entered or exited. + + -ge Generate an error class for each non-terminal. + + -gh Generate stdpccts.h for non-ANTLR-generated files to + include. This file contains all defines needed to + describe the type of parser generated by _a_n_t_l_r (e.g. + how much lookahead is used and whether or not trees are + constructed) and contains the header action specified + by the user. + + -gk Generate parsers that delay lookahead fetches until + needed. Without this option, _a_n_t_l_r generates parsers + which always have _k tokens of lookahead available. + + -gl Generate line info about grammar actions in C parser of + the form # _l_i_n_e "_f_i_l_e" which makes error messages from + the C/C++ compiler make more sense as they will point + into the grammar file not the resulting C file. + Debugging is easier as well, because you will step + through the grammar not C file. + + -gs Do not generate sets for token expression lists; + instead generate a ||-separated sequence of + LA(1)==_t_o_k_e_n__n_u_m_b_e_r. The default is to generate sets. + + -gt Generate code for Abstract-Syntax Trees. + + -gx Do not create the lexical analyzer files (dlg-related). + This option should be given when the user wishes to + provide a customized lexical analyzer. It may also be + used in _m_a_k_e scripts to cause only the parser to be + rebuilt when a change not affecting the lexical struc- + ture is made to the input grammars. + + -k _n Set k of LL(k) to _n; i.e. set tokens of look-ahead + (default==1). + + -o dir + Directory where output files should go (default="."). + This is very nice for keeping the source directory + clear of ANTLR and DLG spawn. + + -p The complete grammar, collected from all input grammar + files and stripped of all comments and embedded + actions, is listed to stdout. This is intended to aid + in viewing the entire grammar as a whole and to elim- + inate the need to keep actions concisely stated so that + the grammar is easier to read. Hence, it is preferable + to embed even complex actions directly in the grammar, + rather than to call them as subroutines, since the sub- + routine call overhead will be saved. + + -pa This option is the same as -p except that the output is + annotated with the first sets determined from grammar + analysis. + + -prc on + Turn on the computation and hoisting of predicate con- + text. + + -prc off + Turn off the computation and hoisting of predicate con- + text. This option makes 1.10 behave like the 1.06 + release with option -pr on. Context computation is off + by default. + + -rl _n + Limit the maximum number of tree nodes used by grammar + analysis to _n. Occasionally, _a_n_t_l_r is unable to + analyze a grammar submitted by the user. This rare + situation can only occur when the grammar is large and + the amount of lookahead is greater than one. A non- + linear analysis algorithm is used by PCCTS to handle + the general case of LL(k) parsing. The average com- + plexity of analysis, however, is near linear due to + some fancy footwork in the implementation which reduces + the number of calls to the full LL(k) algorithm. An + error message will be displayed, if this limit is + reached, which indicates the grammar construct being + analyzed when _a_n_t_l_r hit a non-linearity. Use this + option if _a_n_t_l_r seems to go out to lunch and your disk + start thrashing; try _n=10000 to start. Once the + offending construct has been identified, try to remove + the ambiguity that _a_n_t_l_r was trying to overcome with + large lookahead analysis. The introduction of (...)? + backtracking blocks eliminates some of these problems - + _a_n_t_l_r does not analyze alternatives that begin with + (...)? (it simply backtracks, if necessary, at run + time). + + -w1 Set low warning level. Do not warn if semantic + predicates and/or (...)? blocks are assumed to cover + ambiguous alternatives. + + -w2 Ambiguous parsing decisions yield warnings even if + semantic predicates or (...)? blocks are used. Warn if + predicate context computed and semantic predicates + incompletely disambiguate alternative productions. + + - Read grammar from standard input and generate stdin.c + as the parser file. + +SPECIAL CONSIDERATIONS + _A_n_t_l_r works... we think. There is no implicit guarantee of + anything. We reserve no legal rights to the software known + as the Purdue Compiler Construction Tool Set (PCCTS) - PCCTS + is in the public domain. An individual or company may do + whatever they wish with source code distributed with PCCTS + or the code generated by PCCTS, including the incorporation + of PCCTS, or its output, into commercial software. We + encourage users to develop software with PCCTS. However, we + do ask that credit is given to us for developing PCCTS. By + "credit", we mean that if you incorporate our source code + into one of your programs (commercial product, research pro- + ject, or otherwise) that you acknowledge this fact somewhere + in the documentation, research report, etc... If you like + PCCTS and have developed a nice tool with the output, please + mention that you developed it using PCCTS. As long as these + guidelines are followed, we expect to continue enhancing + this system and expect to make other tools available as they + are completed. + +FILES + *.c output C parser. + + *.cpp + output C++ parser when C++ mode is used. + + parser.dlg + output _d_l_g lexical analyzer. + + err.c + token string array, error sets and error support rou- + tines. Not used in C++ mode. + + remap.h + file that redefines all globally visible parser sym- + bols. The use of the #parser directive creates this + file. Not used in C++ mode. + + stdpccts.h + list of definitions needed by C files, not generated by + PCCTS, that reference PCCTS objects. This is not gen- + erated by default. Not used in C++ mode. + + tokens.h + output #_d_e_f_i_n_e_s for tokens used and function prototypes + for functions generated for rules. + + +SEE ALSO + dlg(1), pccts(1) + + + + + diff --git a/Tools/CodeTools/Source/Pccts/antlr/bits.c b/Tools/CodeTools/Source/Pccts/antlr/bits.c new file mode 100644 index 0000000000..ddd9bd6053 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/bits.c @@ -0,0 +1,1025 @@ +/* bits.c -- manage creation and output of bit sets used by the parser. + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2001 + */ + +#include +#include +#include +#include +#include "pcctscfg.h" +#include "set.h" +#include "syn.h" +#include "hash.h" +#include "generic.h" +#include "dlgdef.h" + +/* char is only thing that is pretty much always known == 8 bits + * This allows output of antlr (set stuff, anyway) to be androgynous (portable) + */ +typedef unsigned char SetWordType; +#define BitsPerByte 8 +#define BitsPerWord BitsPerByte*sizeof(SetWordType) + +static SetWordType *setwd = NULL; +int setnum = -1; +int wordnum = 0; + +int esetnum = 0; + +/* Used to convert native wordsize, which ANTLR uses (via set.c) to manipulate sets, + to bytes that are most portable size-wise. + */ +void +#ifdef __USE_PROTOS +DumpIntAsChars( FILE *f, char *format, unsigned wd ) +#else +DumpIntAsChars( f, format, wd ) +FILE *f; +char *format; +unsigned wd; +#endif +{ + int i; + /* uses max of 32 bit unsigned integer for the moment */ + static unsigned long byte_mask[sizeof(unsigned long)] = + { 0xFF, 0xFF00UL, 0xFF0000UL, 0xFF000000UL }; /* MR20 G. Hobbelt */ +/* 0xFF00000000, 0xFF0000000000, 0xFF000000000000, 0xFF00000000000000 };*/ + + /* for each byte in the word */ + assert(sizeof(unsigned) <= 4); /* M20 G. Hobbelt Sanity check */ + for (i=0; i>(i*BitsPerByte)); + if ( itok))); + return empty; + } + r = RulePtr[q->rulenum]; + r->end->halt = TRUE; /* don't let reach fall off end of rule here */ + rk = empty; + REACH(r, 1, &rk, a); + r->end->halt = FALSE; + return a; +} + +/* + * scan the list of tokens/eclasses/nonterminals filling the new eclass + * with the set described by the list. Note that an eclass can be + * quoted to allow spaces etc... However, an eclass must not conflict + * with a reg expr found elsewhere. The reg expr will be taken over + * the eclass name. + */ +static void +#ifdef __USE_PROTOS +doEclass( char *eclass ) +#else +doEclass( eclass ) +char *eclass; +#endif +{ + TermEntry *q; + ECnode *p; + TCnode *tcnode; + ListNode *e; + unsigned int t; + unsigned deg=0; + set a; + require(eclass!=NULL, "doEclass: NULL eset"); + + p = (ECnode *) eclass; + lexmode(p->lexclass); /* switch to lexclass where errclass is defined */ + p->eset = empty; + for (e = (p->elist)->next; e!=NULL; e=e->next) + { + q = NULL; /* MR23 */ + + if ( islower( *((char *)e->elem) ) ) /* is it a rule ref? (alias FIRST request) */ + { + a = Efirst((char *)e->elem, p); + set_orin(&p->eset, a); + deg += set_deg(a); + set_free( a ); + continue; + } + else if ( *((char *)e->elem)=='"' ) + { + t = 0; + q = (TermEntry *) hash_get(Texpr, (char *) e->elem); + if ( q == NULL ) + { + /* if quoted and not an expr look for eclass name */ + q = (TermEntry *) hash_get(Tname, *((char **)&(e->elem))=StripQuotes((char *)e->elem)); + if ( q != NULL ) t = q->token; + } + else t = q->token; + } + else /* labelled token/eclass/tokclass */ + { + q = (TermEntry *) hash_get(Tname, (char *)e->elem); + if ( q != NULL ) + { + if ( strcmp((char *)e->elem, TokenString(p->tok))==0 ) + { + warnNoFL(eMsg1("self-referential error class '%s'; ignored", + (char *)e->elem)); + continue; + } + else + t = q->token; + } + else t=0; + } + if ( t!=0 ) + { + if (isTermEntryTokClass(q)) { /* MR23 */ + tcnode = q->tclass; /* MR23 */ + set_orin(&p->eset, tcnode->tset); /* MR23 */ + deg = set_deg(p->eset); /* MR23 */ + } /* MR23 */ + else { + set_orel(t, &p->eset); + deg++; + } + } + else warnNoFL(eMsg2("undefined token '%s' referenced in errclass '%s'; ignored", + (char *)e->elem, TokenString(p->tok))); + } + p->setdeg = deg; +} + +void +#ifdef __USE_PROTOS +ComputeErrorSets( void ) +#else +ComputeErrorSets( ) +#endif +{ +#ifdef __cplusplus + list_apply(eclasses, (void (*)(void *)) doEclass); +#else +#ifdef __USE_PROTOS + list_apply(eclasses, (void (*)(void *)) doEclass); +#else + list_apply(eclasses, doEclass); +#endif +#endif +} + +void +#ifdef __USE_PROTOS +ComputeTokSets( void ) +#else +ComputeTokSets( ) +#endif +{ + ListNode *t, *e = NULL, *e1, *e2; + int something_changed; + int i; + TCnode *p; + TermEntry *q, *q1, *q2; + + if ( tclasses == NULL ) return; + + /* turn lists of token/tokclass references into sets */ + for (t = tclasses->next; t!=NULL; t=t->next) + { + p = (TCnode *) t->elem; + + /* if wild card, then won't have entries in tclass, assume all_tokens */ + if ( p->tok == WildCardToken ) + { + p->tset = set_dup(all_tokens); + continue; + } + + lexmode(p->lexclass); /* switch to lexclass where tokclass is defined */ + p->tset = empty; + + /* instantiate all tokens/token_classes into the tset */ + for (e = (p->tlist)->next; e!=NULL; e=e->next) + { + char *tokstr; + tokstr = (char *)e->elem; + if ( *tokstr == '"' ) { + q = (TermEntry *) hash_get(Texpr, tokstr); + require(q!=NULL, "ComputeTokSets: no token def"); + set_orel(q->token, &p->tset); + } else if (tokstr[0] == '.') { + e1=e->next; + e2=e1->next; + e=e2; + q1= (TermEntry *) hash_get(Tname, (char *)e1->elem); + require(q1!=NULL, "ComputeTokSets: no token def"); + q2= (TermEntry *) hash_get(Tname, (char *)e2->elem); + require(q2!=NULL, "ComputeTokSets: no token def"); + + if (set_el(q1->token,imag_tokens)) { +errNoFL(eMsg2("can't define #tokclass %s using #tokclass or #errclass %s", + TokenString(p->tok),(char *)e1->elem) ); + } + if (set_el(q2->token,imag_tokens)) { +errNoFL(eMsg2("can't define #tokclass %s using #tokclass or #errclass %s", + TokenString(p->tok),(char *)e2->elem) ); + } + if (q1->token > q2->token) { +errNoFL(eMsg3("for #tokclass %s %s..%s - first token number > second token number", + TokenString(p->tok),(char *)e1->elem,(char *)e2->elem) ); + for (i=q2->token; i<=q1->token; i++) { set_orel(i, &p->tset); } + } else { + for (i=q1->token; i<=q2->token; i++) { set_orel(i, &p->tset); } + } + } else { + q = (TermEntry *) hash_get(Tname, tokstr); + require(q!=NULL, "ComputeTokSets: no token def"); + set_orel(q->token, &p->tset); + } + } + } + + /* Go thru list of tokclasses again looking for tokclasses in sets */ +again: + something_changed = 0; + for (t = tclasses->next; t!=NULL; t=t->next) + { + set tcl; + p = (TCnode *) t->elem; + tcl = set_and(p->tset, tokclasses); + if ( !set_nil(tcl) ) + { + int tk; + /* replace refs to tokclasses with the associated set of tokens */ + something_changed = 1; + while ( !set_nil(tcl) ) + { + tk = set_int(tcl); /* grab one of the tok class refs */ + set_rm(tk, tcl); + if ( p->tok != tk ) /* tokclass ref to yourself? */ + { + q = (TermEntry *) hash_get(Tname, TokenString(tk)); + require(q!=NULL, "#tokclass not in hash table"); + set_orin(&p->tset, q->tclass->tset); + } + set_rm(tk, p->tset); /* remove ref that we replaced */ + } + } + set_free(tcl); + } + if ( something_changed ) goto again; +} + +void +#ifdef __USE_PROTOS +DumpRemainingTokSets(void) +#else +DumpRemainingTokSets() +#endif +{ + TCnode *p; + ListNode *t; + + /* Go thru tclasses (for the last time) and dump the sets not dumped + * during code gen; yes, this is a bogus way to do this, but ComputeTokSets() + * can't dump the defs as the error file and tok file has not been created + * yet etc... + */ + if ( tclasses==NULL ) return; + for (t = tclasses->next; t!=NULL; t=t->next) + { + unsigned e; + p = (TCnode *) t->elem; + if ( p->dumped ) continue; + e = DefErrSet(&(p->tset), 0, TokenString(p->tok)); + p->dumped = 1; + p->setnum = e; + } +} + + +/* replace a subset of an error set with an error class name if a subset is found + * repeat process until no replacements made + */ +void +#ifdef __USE_PROTOS +SubstErrorClass( set *f ) +#else +SubstErrorClass( f ) +set *f; +#endif +{ + int max, done = 0; + ListNode *p; + ECnode *ec, *maxclass = NULL; + set a; + require(f!=NULL, "SubstErrorClass: NULL eset"); + + if ( eclasses == NULL ) return; + while ( !done ) + { + max = 0; + maxclass = NULL; + for (p=eclasses->next; p!=NULL; p=p->next) /* chk all error classes */ + { + ec = (ECnode *) p->elem; + if ( ec->setdeg > max ) + { + if ( set_sub(ec->eset, *f) || set_equ(ec->eset, *f) ) + {maxclass = ec; max=ec->setdeg;} + } + } + if ( maxclass != NULL ) /* if subset found, replace with token */ + { + a = set_dif(*f, maxclass->eset); + set_orel((unsigned)maxclass->tok, &a); + set_free(*f); + *f = a; + } + else done = 1; + } +} + +int +#ifdef __USE_PROTOS +DefErrSet1(int nilOK, set *f, int subst, char *name ) +#else +DefErrSet1(nilOK, f, subst, name ) +int nilOK; +set *f; +int subst; /* should be substitute error classes? */ +char *name; +#endif +{ + if ( GenCC ) return DefErrSetForCC1(nilOK, f, subst, name, "_set"); + else return DefErrSetForC1(nilOK, f, subst, name, "_set"); +} + +int +#ifdef __USE_PROTOS +DefErrSet( set *f, int subst, char *name ) +#else +DefErrSet( f, subst, name ) +set *f; +int subst; /* should be substitute error classes? */ +char *name; +#endif +{ + return DefErrSet1(0,f,subst,name); +} + +int +#ifdef __USE_PROTOS +DefErrSetWithSuffix(int nilOK, set *f, int subst, char *name, const char* suffix) +#else +DefErrSetWithSuffix(nilOK, f, subst, name, suffix ) +int nilOK; +set *f; +int subst; /* should be substitute error classes? */ +char *name; +char *suffix; +#endif +{ + if ( GenCC ) return DefErrSetForCC1(nilOK, f, subst, name, suffix ); + else return DefErrSetForC1(nilOK, f, subst, name, suffix); +} + +/* Define a new error set. WARNING...set-implementation dependent. + */ +int +#ifdef __USE_PROTOS +DefErrSetForC1(int nilOK, set *f, int subst, char * name, const char * suffix) +#else +DefErrSetForC1(nilOK, f, subst, name, suffix) +int nilOK; /* MR13 */ +set *f; +int subst; /* should be substitute error classes? */ +char *name; +const char *suffix; +#endif +{ + unsigned *p, *endp; + int e=1; + + if (!nilOK) require(!set_nil(*f), "DefErrSetForC1: nil set to dump?"); + + if ( subst ) SubstErrorClass(f); + p = f->setword; + endp = &(f->setword[f->n]); + esetnum++; + if ( name!=NULL ) + fprintf(DefFile, "extern SetWordType %s%s[];\n", name, suffix); + else + fprintf(DefFile, "extern SetWordType zzerr%d[];\n", esetnum); + if ( name!=NULL ) { + fprintf(ErrFile, "SetWordType %s%s[%d] = {", + name, + suffix, + NumWords(TokenNum-1)*sizeof(unsigned)); + } + else { + fprintf(ErrFile, "SetWordType zzerr%d[%d] = {", + esetnum, + NumWords(TokenNum-1)*sizeof(unsigned)); + } + while ( p < endp ) + { + if ( e > 1 ) fprintf(ErrFile, ", "); + DumpIntAsChars(ErrFile, "0x%x", *p++); + if ( e == 3 ) + { + DAWDLE; + if ( p < endp ) fprintf(ErrFile, ","); + fprintf(ErrFile, "\n\t"); + e=1; + } + else e++; + } + fprintf(ErrFile, "};\n"); + + return esetnum; +} + +int +#ifdef __USE_PROTOS +DefErrSetForC( set *f, int subst, char *name ) +#else +DefErrSetForC( f, subst, name ) +set *f; +int subst; /* should be substitute error classes? */ +char *name; +#endif +{ + return DefErrSetForC1(0,f,subst,name, "_set"); +} + +/* Define a new error set. WARNING...set-implementation dependent; + * Only used when -CC on. + */ + +int +#ifdef __USE_PROTOS +DefErrSetForCC1(int nilOK, set *f, int subst, char *name, const char *suffix ) +#else +DefErrSetForCC1(nilOK, f, subst, name, suffix ) +int nilOK; /* MR13 */ +set *f; +int subst; /* should be substitute error classes? */ +char *name; +const char *suffix; +#endif +{ + unsigned *p, *endp; + int e=1; + + if (!nilOK) require(!set_nil(*f), "DefErrSetForCC1: nil set to dump?"); + + if ( subst ) SubstErrorClass(f); + p = f->setword; + endp = &(f->setword[f->n]); + esetnum++; + + if ( name!=NULL ) { + fprintf(Parser_h, "\tstatic SetWordType %s%s[%d];\n", name, suffix, + NumWords(TokenNum-1)*sizeof(unsigned)); + fprintf(Parser_c, "SetWordType %s::%s%s[%d] = {", + CurrentClassName, + name, + suffix, + NumWords(TokenNum-1)*sizeof(unsigned)); + } + else { + fprintf(Parser_c, "SetWordType %s::err%d[%d] = {", + CurrentClassName, + esetnum, + NumWords(TokenNum-1)*sizeof(unsigned)); + fprintf(Parser_h, "\tstatic SetWordType err%d[%d];\n", esetnum, + NumWords(TokenNum-1)*sizeof(unsigned)); + } + + while ( p < endp ) + { + if ( e > 1 ) fprintf(Parser_c, ", "); + DumpIntAsChars(Parser_c, "0x%x", *p++); + if ( e == 3 ) + { + if ( p < endp ) fprintf(Parser_c, ","); + fprintf(Parser_c, "\n\t"); + e=1; + } + else e++; + } + fprintf(Parser_c, "};\n"); + + return esetnum; +} + +int +#ifdef __USE_PROTOS +DefErrSetForCC( set *f, int subst, char *name ) +#else +DefErrSetForCC( f, subst, name ) +set *f; +int subst; /* should be substitute error classes? */ +char *name; +#endif +{ + return DefErrSetForCC1(0,f,subst,name, "_set"); +} + +void +#ifdef __USE_PROTOS +GenParser_c_Hdr(void) +#else +GenParser_c_Hdr() +#endif +{ + int i,j; + TermEntry *te; + char * hasAkaName = NULL; /* MR23 */ + + hasAkaName = (char *) malloc(TokenNum+1); /* MR23 */ + require(hasAkaName!=NULL, "Cannot alloc hasAkaName\n"); /* MR23 */ + for (i = 0; i < TokenNum; i++) hasAkaName[i]='0'; /* MR23 */ + hasAkaName[TokenNum] = 0; /* MR23 */ + + fprintf(Parser_c, "/*\n"); + fprintf(Parser_c, " * %s: P a r s e r S u p p o r t\n", CurrentClassName); + fprintf(Parser_c, " *\n"); + fprintf(Parser_c, " * Generated from:"); + for (i=0; i=LastTokenCounted ) + { + fprintf(Parser_c, ",\n\t/* %02d */\t\"invalid\"", i); + continue; + } + if ( TokenString(i) != NULL ) { + te=(TermEntry *) hash_get(Tname,TokenString(i)); /* MR11 */ + if (te == NULL || te->akaString == NULL) { /* MR11 */ + fprintf(Parser_c, ",\n\t/* %02d */\t\"%s\"", i, TokenString(i)); + } else { + hasAkaName[i] = '1'; /* MR23 */ + fprintf(Parser_c, ",\n\t/* %02d */\t\"%s\"", i, te->akaString); /* MR11 */ + } + } + else + { + /* look in all lexclasses for the reg expr */ + for (j=0; j=NumLexClasses ) + { + if ( UserDefdTokens ) + { + fprintf(Parser_c, ",\n\t/* %02d */\t\"\"", i); + } + else + fatal_internal(eMsgd("No label or expr for token %d",i)); + } + } + } + fprintf(Parser_c, "\n};\n"); + + /* Build constructors */ + fprintf(Parser_c, "\n%s::", CurrentClassName); + fprintf(Parser_c, "%s(ANTLRTokenBuffer *input) : %s(input,%d,%d,%d,%d)\n", + CurrentClassName, + (BaseClassName == NULL ? "ANTLRParser" : BaseClassName), + OutputLL_k, + FoundGuessBlk, + DemandLookahead, + NumWords(TokenNum-1)*sizeof(unsigned)); + fprintf(Parser_c, "{\n"); + fprintf(Parser_c, "\ttoken_tbl = _token_tbl;\n"); + if (TraceGen) { + fprintf(Parser_c, "\ttraceOptionValueDefault=1;\t\t// MR10 turn trace ON\n"); + } else { + fprintf(Parser_c, "\ttraceOptionValueDefault=0;\t\t// MR10 turn trace OFF\n"); + }; + fprintf(Parser_c, "}\n\n"); + free ( (void *) hasAkaName); +} + +void +#ifdef __USE_PROTOS +GenParser_h_Hdr(void) +#else +GenParser_h_Hdr() +#endif +{ + int i; + + fprintf(Parser_h, "/*\n"); + fprintf(Parser_h, " * %s: P a r s e r H e a d e r \n", CurrentClassName); + fprintf(Parser_h, " *\n"); + fprintf(Parser_h, " * Generated from:"); + for (i=0; i 1 ) fprintf(ErrFile, "#define LL_K %d\n", OutputLL_k); +#ifdef DUM + if ( LexGen ) fprintf(ErrFile, "#define zzEOF_TOKEN %d\n", (TokenInd!=NULL?TokenInd[EofToken]:EofToken)); +#endif + fprintf(ErrFile, "#define zzSET_SIZE %d\n", NumWords(TokenNum-1)*sizeof(unsigned)); + if ( DemandLookahead ) fprintf(ErrFile, "#define DEMAND_LOOK\n"); + fprintf(ErrFile, "#include \"antlr.h\"\n"); + if ( GenAST ) fprintf(ErrFile, "#include \"ast.h\"\n"); + + if ( UserDefdTokens ) fprintf(ErrFile, "#include %s\n", UserTokenDefsFile); + /* still need this one as it has the func prototypes */ + fprintf(ErrFile, "#include \"%s\"\n", DefFileName); + fprintf(ErrFile, "#include \"dlgdef.h\"\n"); + fprintf(ErrFile, "#include \"err.h\"\n\n"); + + /* Dump a zztokens for each automaton */ + if ( strcmp(ParserName, DefaultParserName)!=0 ) + { + fprintf(ErrFile, "ANTLRChar *%s_zztokens[%d]={\n", ParserName, TokenNum-1); + } + else + { + fprintf(ErrFile, "ANTLRChar *zztokens[%d]={\n", TokenNum-1); + } + fprintf(ErrFile, "\t/* 00 */\t\"Invalid\""); + for (i=1; i=LastTokenCounted ) + { + fprintf(ErrFile, ",\n\t/* %02d */\t\"invalid\"", i); + continue; + } + if ( TokenString(i) != NULL ) { + te=(TermEntry *) hash_get(Tname,TokenString(i)); /* MR11 */ + if (te == NULL || te->akaString == NULL) { /* MR11 */ + fprintf(ErrFile, ",\n\t/* %02d */\t\"%s\"", i, TokenString(i)); + } else { + fprintf(ErrFile, ",\n\t/* %02d */\t\"%s\"", i, te->akaString); /* MR11 */ + } + } + else + { + /* look in all lexclasses for the reg expr */ + for (j=0; j=NumLexClasses ) + { + if ( UserDefdTokens ) + { + fprintf(ErrFile, ",\n\t/* %02d */\t\"\"", i); + } + else + fatal_internal(eMsgd("No label or expr for token %d",i)); + } + } + } + fprintf(ErrFile, "\n};\n"); +} + +void +#ifdef __USE_PROTOS +dumpExpr( FILE *f, char *e ) +#else +dumpExpr( f, e ) +FILE *f; +char *e; +#endif +{ + while ( *e!='\0' ) + { + if ( *e=='\\' && *(e+1)=='\\' ) + {putc('\\', f); putc('\\', f); e+=2;} + else if ( *e=='\\' && *(e+1)=='"' ) + {putc('\\', f); putc('"', f); e+=2;} + else if ( *e=='\\' ) {putc('\\', f); putc('\\', f); e++;} + else {putc(*e, f); e++;} + } +} + +int +#ifdef __USE_PROTOS +isTermEntryTokClass(TermEntry *te) +#else +isTermEntryTokClass(te) +TermEntry *te; +#endif +{ + ListNode *t; + TCnode *p; + TermEntry *q; + char *tokstr; + + if (tclasses == NULL) return 0; + + for (t = tclasses->next; t!=NULL; t=t->next) + { + p = (TCnode *) t->elem; + tokstr = TokenString(p->tok); + lexmode(p->lexclass); /* switch to lexclass where tokclass is defined */ + q = (TermEntry *) hash_get(Tname, tokstr); + if (q == te) return 1; + } + return 0; +} diff --git a/Tools/CodeTools/Source/Pccts/antlr/build.c b/Tools/CodeTools/Source/Pccts/antlr/build.c new file mode 100644 index 0000000000..4eb3b02af1 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/build.c @@ -0,0 +1,813 @@ +/* + * build.c -- functions associated with building syntax diagrams. + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2001 + */ + +#include +#include +#include +#include "pcctscfg.h" +#include "set.h" +#include "syn.h" +#include "hash.h" +#include "generic.h" +#include "dlgdef.h" + +#define SetBlk(g, t, approx, first_set_symbol) { \ + ((Junction *)g.left)->jtype = t; \ + ((Junction *)g.left)->approx = approx; \ + ((Junction *)g.left)->pFirstSetSymbol = first_set_symbol; \ + ((Junction *)g.left)->end = (Junction *) g.right; \ + ((Junction *)g.right)->jtype = EndBlk;} + +/* Add the parameter string 'parm' to the parms field of a block-type junction + * g.left points to the sentinel node on a block. i.e. g.left->p1 points to + * the actual junction with its jtype == some block-type. + */ +void +#ifdef __USE_PROTOS +addParm( Node *p, char *parm ) +#else +addParm( p, parm ) +Node *p; +char *parm; +#endif +{ + char *q = (char *) malloc( strlen(parm) + 1 ); + require(p!=NULL, "addParm: NULL object\n"); + require(q!=NULL, "addParm: unable to alloc parameter\n"); + + strcpy(q, parm); + if ( p->ntype == nRuleRef ) + { + ((RuleRefNode *)p)->parms = q; + } + else if ( p->ntype == nJunction ) + { + ((Junction *)p)->parm = q; /* only one parameter allowed on subrules */ + } + else fatal_internal("addParm: invalid node for adding parm"); +} + +/* + * Build an action node for the syntax diagram + * + * buildAction(ACTION) ::= --o-->ACTION-->o-- + * + * Where o is a junction node. + */ +Graph +#ifdef __USE_PROTOS +buildAction( char *action, int file, int line, int is_predicate ) +#else +buildAction( action, file, line, is_predicate ) +char *action; +int file; +int line; +int is_predicate; +#endif +{ + Junction *j1, *j2; + Graph g; + ActionNode *a; + require(action!=NULL, "buildAction: invalid action"); + + j1 = newJunction(); + j2 = newJunction(); + a = newActionNode(); + a->action = (char *) malloc( strlen(action)+1 ); + require(a->action!=NULL, "buildAction: cannot alloc space for action\n"); + strcpy(a->action, action); + j1->p1 = (Node *) a; + a->next = (Node *) j2; + a->is_predicate = is_predicate; + + if (is_predicate) { + PredEntry *predEntry; + char *t; + char *key; + char *u; + int inverted=0; + + t=key=(char *)calloc(1,strlen(a->action)+1); + + for (u=a->action; *u != '\0' ; u++) { + if (*u != ' ') { + if (t==key && *u=='!') { + inverted=!inverted; + } else { + *t++=*u; + }; + }; + }; + + *t='\0'; + + + predEntry=(PredEntry *)hash_get(Pname,key); + a->predEntry=predEntry; + if (predEntry != NULL) a->inverted=inverted; + } else { +/* MR12c */ char *strStart=a->action; +/* MR12c */ char *strEnd; +/* MR12c */ strEnd=strStart+strlen(strStart)-1; +/* MR12c */ for ( ; strEnd >= strStart && isspace(*strEnd); strEnd--) *strEnd=0; +/* MR12c */ while (*strStart != '\0' && isspace(*strStart)) strStart++; +/* MR12c */ if (ci_strequ(strStart,"nohoist")) { +/* MR12c */ a->noHoist=1; +/* MR12c */ } + } + + g.left = (Node *) j1; g.right = (Node *) j2; + a->file = file; + a->line = line; + a->rname = CurRule; /* MR10 */ + return g; +} + +/* + * Build a token node for the syntax diagram + * + * buildToken(TOKEN) ::= --o-->TOKEN-->o-- + * + * Where o is a junction node. + */ +Graph +#ifdef __USE_PROTOS +buildToken( char *text ) +#else +buildToken( text ) +char *text; +#endif +{ + Junction *j1, *j2; + Graph g; + TokNode *t; + require(text!=NULL, "buildToken: invalid token name"); + + j1 = newJunction(); + j2 = newJunction(); + t = newTokNode(); + t->altstart = CurAltStart; + if ( *text == '"' ) {t->label=FALSE; t->token = addTexpr( text );} + else {t->label=TRUE; t->token = addTname( text );} + j1->p1 = (Node *) t; + t->next = (Node *) j2; + g.left = (Node *) j1; g.right = (Node *) j2; + return g; +} + +/* + * Build a wild-card node for the syntax diagram + * + * buildToken(TOKEN) ::= --o-->'.'-->o-- + * + * Where o is a junction node. + */ +Graph +#ifdef __USE_PROTOS +buildWildCard( char *text ) +#else +buildWildCard( text ) +char *text; +#endif +{ + Junction *j1, *j2; + Graph g; + TokNode *t; + TCnode *w; + TermEntry *p; + require(text!=NULL, "buildWildCard: invalid token name"); + + j1 = newJunction(); + j2 = newJunction(); + t = newTokNode(); + + /* If the ref a wild card, make a token class for it */ + if ( Tnum(WildCardString) == 0 ) + { + w = newTCnode; + w->tok = addTname( WildCardString ); + set_orel(w->tok, &imag_tokens); + set_orel(w->tok, &tokclasses); + WildCardToken = w->tok; + require((p=(TermEntry *)hash_get(Tname, WildCardString)) != NULL, + "hash table mechanism is broken"); + p->classname = 1; /* entry is class name, not token */ + p->tclass = w; /* save ptr to this tclass def */ + list_add(&tclasses, (char *)w); + } + else { + p=(TermEntry *)hash_get(Tname, WildCardString); + require( p!= NULL, "hash table mechanism is broken"); + w = p->tclass; + } + + t->token = w->tok; + t->wild_card = 1; + t->tclass = w; + + t->altstart = CurAltStart; + j1->p1 = (Node *) t; + t->next = (Node *) j2; + g.left = (Node *) j1; g.right = (Node *) j2; + return g; +} + +void +#ifdef __USE_PROTOS +setUpperRange(TokNode *t, char *text) +#else +setUpperRange(t, text) +TokNode *t; +char *text; +#endif +{ + require(t!=NULL, "setUpperRange: NULL token node"); + require(text!=NULL, "setUpperRange: NULL token string"); + + if ( *text == '"' ) {t->upper_range = addTexpr( text );} + else {t->upper_range = addTname( text );} +} + +/* + * Build a rule reference node of the syntax diagram + * + * buildRuleRef(RULE) ::= --o-->RULE-->o-- + * + * Where o is a junction node. + * + * If rule 'text' has been defined already, don't alloc new space to store string. + * Set r->text to point to old copy in string table. + */ +Graph +#ifdef __USE_PROTOS +buildRuleRef( char *text ) +#else +buildRuleRef( text ) +char *text; +#endif +{ + Junction *j1, *j2; + Graph g; + RuleRefNode *r; + RuleEntry *p; + require(text!=NULL, "buildRuleRef: invalid rule name"); + + j1 = newJunction(); + j2 = newJunction(); + r = newRNode(); + r->altstart = CurAltStart; + r->assign = NULL; + if ( (p=(RuleEntry *)hash_get(Rname, text)) != NULL ) r->text = p->str; + else r->text = mystrdup( text ); + j1->p1 = (Node *) r; + r->next = (Node *) j2; + g.left = (Node *) j1; g.right = (Node *) j2; + return g; +} + +/* + * Or two subgraphs into one graph via: + * + * Or(G1, G2) ::= --o-G1-o-- + * | ^ + * v | + * o-G2-o + * + * Set the altnum of junction starting G2 to 1 + altnum of junction starting G1. + * If, however, the G1 altnum is 0, make it 1 and then + * make G2 altnum = G1 altnum + 1. + */ +Graph +#ifdef __USE_PROTOS +Or( Graph g1, Graph g2 ) +#else +Or( g1, g2 ) +Graph g1; +Graph g2; +#endif +{ + Graph g; + require(g1.left != NULL, "Or: invalid graph"); + require(g2.left != NULL && g2.right != NULL, "Or: invalid graph"); + + ((Junction *)g1.left)->p2 = g2.left; + ((Junction *)g2.right)->p1 = g1.right; + /* set altnums */ + if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1; + ((Junction *)g2.left)->altnum = ((Junction *)g1.left)->altnum + 1; + g.left = g2.left; + g.right = g1.right; + return g; +} + +/* + * Catenate two subgraphs + * + * Cat(G1, G2) ::= --o-G1-o-->o-G2-o-- + * Cat(NULL,G2)::= --o-G2-o-- + * Cat(G1,NULL)::= --o-G1-o-- + */ +Graph +#ifdef __USE_PROTOS +Cat( Graph g1, Graph g2 ) +#else +Cat( g1, g2 ) +Graph g1; +Graph g2; +#endif +{ + Graph g; + + if ( g1.left == NULL && g1.right == NULL ) return g2; + if ( g2.left == NULL && g2.right == NULL ) return g1; + ((Junction *)g1.right)->p1 = g2.left; + g.left = g1.left; + g.right = g2.right; + return g; +} + +/* + * Make a subgraph an optional block + * + * makeOpt(G) ::= --o-->o-G-o-->o-- + * | ^ + * v | + * o-------o + * + * Note that this constructs {A|B|...|Z} as if (A|B|...|Z|) was found. + * + * The node on the far right is added so that every block owns its own + * EndBlk node. + */ +Graph +#ifdef __USE_PROTOS +makeOpt( Graph g1, int approx, char * pFirstSetSymbol ) +#else +makeOpt( g1, approx, pFirstSetSymbol ) +Graph g1; +int approx; +char * pFirstSetSymbol; +#endif +{ + Junction *j1,*j2,*p; + Graph g; + require(g1.left != NULL && g1.right != NULL, "makeOpt: invalid graph"); + + j1 = newJunction(); + j2 = newJunction(); + ((Junction *)g1.right)->p1 = (Node *) j2; /* add node to G at end */ + + /* MR21 + * + * There is code in genBlk which recognizes the node created + * by emptyAlt() as a special case and bypasses it. We don't + * want this to happen for the optBlk. + */ + + g = emptyAlt3(); /* MR21 */ + if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1; + ((Junction *)g.left)->altnum = ((Junction *)g1.left)->altnum + 1; + for(p=(Junction *)g1.left; p->p2!=NULL; p=(Junction *)p->p2) + {;} /* find last alt */ + p->p2 = g.left; /* add optional alternative */ + ((Junction *)g.right)->p1 = (Node *)j2; /* opt alt points to EndBlk */ + g1.right = (Node *)j2; + SetBlk(g1, aOptBlk, approx, pFirstSetSymbol); + j1->p1 = g1.left; /* add generic node in front */ + g.left = (Node *) j1; + g.right = g1.right; + return g; +} + +/* + * Make a graph into subblock + * + * makeBlk(G) ::= --o-->o-G-o-->o-- + * + * The node on the far right is added so that every block owns its own + * EndBlk node. + */ +Graph +#ifdef __USE_PROTOS +makeBlk( Graph g1, int approx, char * pFirstSetSymbol ) +#else +makeBlk( g1, approx, pFirstSetSymbol ) +Graph g1; +int approx; +char * pFirstSetSymbol; +#endif +{ + Junction *j,*j2; + Graph g; + require(g1.left != NULL && g1.right != NULL, "makeBlk: invalid graph"); + + j = newJunction(); + j2 = newJunction(); + ((Junction *)g1.right)->p1 = (Node *) j2; /* add node to G at end */ + g1.right = (Node *)j2; + SetBlk(g1, aSubBlk, approx, pFirstSetSymbol); + j->p1 = g1.left; /* add node in front */ + g.left = (Node *) j; + g.right = g1.right; + + return g; +} + +/* + * Make a subgraph into a loop (closure) block -- (...)* + * + * makeLoop(G) ::= |---| + * v | + * --o-->o-->o-G-o-->o-- + * | ^ + * v | + * o-----------o + * + * After making loop, always place generic node out front. It becomes + * the start of enclosing block. The aLoopBlk is the target of the loop. + * + * Loop blks have TWO EndBlk nodes--the far right and the node that loops back + * to the aLoopBlk node. Node with which we can branch past loop == aLoopBegin and + * one which is loop target == aLoopBlk. + * The branch-past (initial) aLoopBegin node has end + * pointing to the last EndBlk node. The loop-target node has end==NULL. + * + * Loop blocks have a set of locks (from 1..CLL_k) on the aLoopBlk node. + */ +Graph +#ifdef __USE_PROTOS +makeLoop( Graph g1, int approx, char * pFirstSetSymbol ) +#else +makeLoop( g1, approx, pFirstSetSymbol) +Graph g1; +int approx; +char * pFirstSetSymbol; +#endif +{ + Junction *back, *front, *begin; + Graph g; + require(g1.left != NULL && g1.right != NULL, "makeLoop: invalid graph"); + + back = newJunction(); + front = newJunction(); + begin = newJunction(); + g = emptyAlt3(); + ((Junction *)g1.right)->p2 = g1.left; /* add loop branch to G */ + ((Junction *)g1.right)->p1 = (Node *) back; /* add node to G at end */ + ((Junction *)g1.right)->jtype = EndBlk; /* mark 1st EndBlk node */ + ((Junction *)g1.left)->jtype = aLoopBlk; /* mark 2nd aLoopBlk node */ + ((Junction *)g1.left)->end = (Junction *) g1.right; + ((Junction *)g1.left)->lock = makelocks(); + ((Junction *)g1.left)->pred_lock = makelocks(); + g1.right = (Node *) back; + begin->p1 = (Node *) g1.left; + g1.left = (Node *) begin; + begin->p2 = (Node *) g.left; /* make bypass arc */ + ((Junction *)g.right)->p1 = (Node *) back; + SetBlk(g1, aLoopBegin, approx, pFirstSetSymbol); + front->p1 = g1.left; /* add node to front */ + g1.left = (Node *) front; + + return g1; +} + +/* + * Make a subgraph into a plus block -- (...)+ -- 1 or more times + * + * makePlus(G) ::= |---| + * v | + * --o-->o-G-o-->o-- + * + * After making loop, always place generic node out front. It becomes + * the start of enclosing block. The aPlusBlk is the target of the loop. + * + * Plus blks have TWO EndBlk nodes--the far right and the node that loops back + * to the aPlusBlk node. + * + * Plus blocks have a set of locks (from 1..CLL_k) on the aPlusBlk node. + */ +Graph +#ifdef __USE_PROTOS +makePlus( Graph g1, int approx, char * pFirstSetSymbol) +#else +makePlus( g1, approx, pFirstSetSymbol) +Graph g1; +int approx; +char * pFirstSetSymbol; +#endif +{ + int has_empty_alt_already = 0; + Graph g; + Junction *j2, *j3, *first_alt; + Junction *last_alt=NULL, *p; + require(g1.left != NULL && g1.right != NULL, "makePlus: invalid graph"); + + first_alt = (Junction *)g1.left; + j2 = newJunction(); + j3 = newJunction(); + if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1; + ((Junction *)g1.right)->p2 = g1.left; /* add loop branch to G */ + ((Junction *)g1.right)->p1 = (Node *) j2; /* add node to G at end */ + ((Junction *)g1.right)->jtype = EndBlk; /* mark 1st EndBlk node */ + g1.right = (Node *) j2; + SetBlk(g1, aPlusBlk, approx, pFirstSetSymbol); + ((Junction *)g1.left)->lock = makelocks(); + ((Junction *)g1.left)->pred_lock = makelocks(); + j3->p1 = g1.left; /* add node to front */ + g1.left = (Node *) j3; + + /* add an optional branch which is the "exit" branch of loop */ + /* FIRST, check to ensure that there does not already exist + * an optional path. + */ + /* find last alt */ + for(p=first_alt; p!=NULL; p=(Junction *)p->p2) + { + if ( p->p1->ntype == nJunction && + p->p1!=NULL && + ((Junction *)p->p1)->jtype==Generic && + ((Junction *)p->p1)->p1!=NULL && + ((Junction *)((Junction *)p->p1)->p1)->jtype==EndBlk ) + { + has_empty_alt_already = 1; + } + last_alt = p; + } + if ( !has_empty_alt_already ) + { + require(last_alt!=NULL, "last_alt==NULL; bad (..)+"); + g = emptyAlt(); + last_alt->p2 = g.left; + ((Junction *)g.right)->p1 = (Node *) j2; + + /* make sure lookahead computation ignores this alt for + * FIRST("(..)+"); but it's still used for computing the FIRST + * of each alternative. + */ + ((Junction *)g.left)->ignore = 1; + } + + return g1; +} + +/* + * Return an optional path: --o-->o-- + */ + +Graph +#ifdef __USE_PROTOS +emptyAlt( void ) +#else +emptyAlt( ) +#endif +{ + Junction *j1, *j2; + Graph g; + + j1 = newJunction(); + j2 = newJunction(); + j1->p1 = (Node *) j2; + g.left = (Node *) j1; + g.right = (Node *) j2; + + return g; +} + +/* MR21 + * + * There is code in genBlk which recognizes the node created + * by emptyAlt() as a special case and bypasses it. We don't + * want this to happen for the optBlk. + */ + +Graph +#ifdef __USE_PROTOS +emptyAlt3( void ) +#else +emptyAlt3( ) +#endif +{ + Junction *j1, *j2, *j3; + Graph g; + + j1 = newJunction(); + j2 = newJunction(); + j3 = newJunction(); + j1->p1 = (Node *) j2; + j2->p1 = (Node *) j3; + g.left = (Node *) j1; + g.right = (Node *) j3; + + return g; +} + +/* N o d e A l l o c a t i o n */ + +TokNode * +#ifdef __USE_PROTOS +newTokNode( void ) +#else +newTokNode( ) +#endif +{ + static TokNode *FreeList = NULL; + TokNode *p, *newblk; + + if ( FreeList == NULL ) + { + newblk = (TokNode *)calloc(TokenBlockAllocSize, sizeof(TokNode)); + if ( newblk == NULL ) + fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule)); + for (p=newblk; p<&(newblk[TokenBlockAllocSize]); p++) + { + p->next = (Node *)FreeList; /* add all new token nodes to FreeList */ + FreeList = p; + } + } + p = FreeList; + FreeList = (TokNode *)FreeList->next;/* remove a TokNode node */ + p->next = NULL; /* NULL the ptr we used */ + memset( (char *) p, 0, sizeof(TokNode)); /* MR10 */ + p->ntype = nToken; + p->rname = CurRule; + p->file = CurFile; + p->line = zzline; + p->altstart = NULL; + + return p; +} + +RuleRefNode * +#ifdef __USE_PROTOS +newRNode( void ) +#else +newRNode( ) +#endif +{ + static RuleRefNode *FreeList = NULL; + RuleRefNode *p, *newblk; + + if ( FreeList == NULL ) + { + newblk = (RuleRefNode *)calloc(RRefBlockAllocSize, sizeof(RuleRefNode)); + if ( newblk == NULL ) + fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule)); + for (p=newblk; p<&(newblk[RRefBlockAllocSize]); p++) + { + p->next = (Node *)FreeList; /* add all new rref nodes to FreeList */ + FreeList = p; + } + } + p = FreeList; + FreeList = (RuleRefNode *)FreeList->next;/* remove a Junction node */ + p->next = NULL; /* NULL the ptr we used */ + memset( (char *) p, 0, sizeof(RuleRefNode)); /* MR10 */ + p->ntype = nRuleRef; + p->rname = CurRule; + p->file = CurFile; + p->line = zzline; + p->astnode = ASTinclude; + p->altstart = NULL; + + return p; +} + +static int junctionSeqNumber=0; /* MR10 */ + +Junction * +#ifdef __USE_PROTOS +newJunction( void ) +#else +newJunction( ) +#endif +{ + static Junction *FreeList = NULL; + Junction *p, *newblk; + + if ( FreeList == NULL ) + { + newblk = (Junction *)calloc(JunctionBlockAllocSize, sizeof(Junction)); + if ( newblk == NULL ) + fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule)); + for (p=newblk; p<&(newblk[JunctionBlockAllocSize]); p++) + { + p->p1 = (Node *)FreeList; /* add all new Junction nodes to FreeList */ + FreeList = p; + } + } + p = FreeList; + FreeList = (Junction *)FreeList->p1;/* remove a Junction node */ + p->p1 = NULL; /* NULL the ptr we used */ + memset( (char *) p, 0, sizeof(Junction)); /* MR10 */ + p->ntype = nJunction; + p->visited = 0; + p->jtype = Generic; + p->rname = CurRule; + p->file = CurFile; + p->line = zzline; + p->exception_label = NULL; + p->fset = (set *) calloc(CLL_k+1, sizeof(set)); + require(p->fset!=NULL, "cannot allocate fset in newJunction"); + p->seq=++junctionSeqNumber; /* MR10 */ + + return p; +} + +ActionNode * +#ifdef __USE_PROTOS +newActionNode( void ) +#else +newActionNode( ) +#endif +{ + static ActionNode *FreeList = NULL; + ActionNode *p, *newblk; + + if ( FreeList == NULL ) + { + newblk = (ActionNode *)calloc(ActionBlockAllocSize, sizeof(ActionNode)); + if ( newblk == NULL ) + fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule)); + for (p=newblk; p<&(newblk[ActionBlockAllocSize]); p++) + { + p->next = (Node *)FreeList; /* add all new Action nodes to FreeList */ + FreeList = p; + } + } + p = FreeList; + FreeList = (ActionNode *)FreeList->next;/* remove an Action node */ + memset( (char *) p, 0, sizeof(ActionNode)); /* MR10 */ + p->ntype = nAction; + p->next = NULL; /* NULL the ptr we used */ + p->done = 0; + p->pred_fail = NULL; + p->guardpred = NULL; + p->ampersandPred = NULL; + return p; +} + +/* + * allocate the array of locks (1..CLL_k) used to inhibit infinite recursion. + * Infinite recursion can occur in (..)* blocks, FIRST calcs and FOLLOW calcs. + * Therefore, we need locks on aLoopBlk, RuleBlk, EndRule nodes. + * + * if ( lock[k]==TRUE ) then we have been here before looking for k tokens + * of lookahead. + */ +char * +#ifdef __USE_PROTOS +makelocks( void ) +#else +makelocks( ) +#endif +{ + char *p = (char *) calloc(CLL_k+1, sizeof(char)); + require(p!=NULL, "cannot allocate lock array"); + + return p; +} + +#if 0 +** #ifdef __USE_PROTOS +** void my_memset(char *p,char value,int count) +** #else +** void my_memset(p,value,count) +** char *p; +** char value; +** int count; +** #endif +** { +** int i; +** +** for (i=0; i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/Pccts/antlr/dumpcycles.c b/Tools/CodeTools/Source/Pccts/antlr/dumpcycles.c new file mode 100644 index 0000000000..8156159f71 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/dumpcycles.c @@ -0,0 +1,67 @@ +#include +#include + +#include "set.h" +#include "syn.h" +#include "hash.h" +#include "generic.h" + +void +#ifdef __USE_PROTOS +dumpcycles(void) +#else +dumpcycles() +#endif +{ + Cycle *c; + CacheEntry *f; + ListNode *p; + int i=0; + int k; + int degree; + + for (k=1; k <= CLL_k; k++) { + if (Cycles[k] == NULL) continue; + + for (p = Cycles[k]->next; p!=NULL; p=p->next) { + c = (Cycle *) p->elem; + degree=set_deg(c->cyclicDep); + fprintf(stderr,"Cycle %d: (degree %d) %s -->\n", i++, degree, RulePtr[c->croot]->rname); + fprintf(stderr," *self*\n"); + MR_dumpRuleSet(c->cyclicDep); + fprintf(stderr,"\n"); + f = (CacheEntry *) + hash_get(Fcache,Fkey(RulePtr[c->croot]->rname,'o',k)); + if (f == NULL) { + fprintf(stderr," *** FOLLOW(%s) must be in cache but isn't ***\n", + RulePtr[c->croot]->rname); + }; + }; + }; +} + +void +#ifdef __USE_PROTOS +dumpfostack(int k) +#else +dumpfostack(k) +int k; +#endif +{ + int i=0; + int *pi; + + fprintf(stderr,"\n"); + if (FoStack[k] == NULL) { + fprintf(stderr,"FoStack[%d] is null\n",k); + }; + if (FoTOS[k] == NULL) { + fprintf(stderr,"FoTOS[%d] is null\n",k); + } + if (FoTOS[k] != NULL && FoStack[k] != NULL) { + for (pi=FoStack[k]; pi <= FoTOS[k]; pi++) { + i++; + fprintf(stderr,"#%d rule %d %s\n",i,*pi,RulePtr[*pi]->rname); + } + } +} diff --git a/Tools/CodeTools/Source/Pccts/antlr/dumpnode.c b/Tools/CodeTools/Source/Pccts/antlr/dumpnode.c new file mode 100644 index 0000000000..2a34c6fcd5 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/dumpnode.c @@ -0,0 +1,423 @@ +#include +#include + +#include "set.h" +#include "syn.h" +#include "hash.h" +#include "generic.h" + +#ifdef __USE_PROTOS +void dumpset1(set s) +#else +void dumpset1(s) + set s; +#endif +{ + if (set_nil(s)) { + fprintf(stderr,"{}"); + } else { + s_fprT(stderr,s); + }; +} + +#ifdef __USE_PROTOS +void dumpset(set s) +#else +void dumpset(s) + set s; +#endif +{ + dumpset1(s); + fprintf(stderr,"\n"); +} + +#ifdef __USE_PROTOS +int isEndRule(Node * p) +#else +int isEndRule(p) + Node * p; +#endif +{ + int result=0; + if ( p->ntype == nJunction && + ( (Junction *) p)->jtype == EndRule) { + result=1; + }; + return result; +} + +#ifdef __USE_PROTOS +void dumppred1(int depth,Predicate *p) +#else +void dumppred1(depth,p) + int depth; + Predicate *p; +#endif +{ + int i; + int k; + + for (i=0; iexpr == PRED_AND_LIST || + p->expr == PRED_OR_LIST) { + fprintf(stderr," %s", (p->expr == NULL ? "null expr" : p->expr)); + if (p->inverted) fprintf(stderr," predicate inverted !"); + if (p->redundant) { + fprintf(stderr," Redundant!"); + }; + if (p->isConst) fprintf(stderr," const %d !",p->constValue); + fprintf(stderr,"\n"); + } else { + fprintf(stderr,"predicate k=%d",p->k); + k=set_int(p->completionSet); + if (k >= 0) { + fprintf(stderr," Incomplete Set=%d !",k); + }; + k=set_int(p->completionTree); + if (k >= 0) { + fprintf(stderr," Incomplete Tree=%d !",k); + }; + if (p->redundant) { + fprintf(stderr," Redundant!"); + }; + fprintf(stderr," \"%s\" (%x)", (p->expr == NULL ? "null expr" : p->expr) ,p); + if (p->source != NULL) { + fprintf(stderr,"line %d",p->source->line); + }; + if (p->inverted) fprintf(stderr," predicate inverted !"); + fprintf(stderr,"\n"); + for (i=0; iscontext[1]); + for (i=0; itcontext); + fprintf(stderr,"\n"); + }; + fprintf(stderr,"\n"); + if (p->down != NULL) { + dumppred1(depth+1,p->down); + }; + if (p->right != NULL) { + dumppred1(depth,p->right); + }; +} + +#ifdef __USE_PROTOS +void dumppred(Predicate *p) +#else +void dumppred(p) + Predicate *p; +#endif +{ + fprintf(stderr,"---------------------------------\n"); + dumppred1(0,p); + fprintf(stderr,"\n"); +} + +#ifdef __USE_PROTOS +void dumppredtree(Predicate *p) +#else +void dumppredtree(p) + Predicate *p; +#endif +{ + fprintf(stderr,"predicate k=%d \"%s\" line %d\n",p->k,p->expr,p->source->line); + dumpset(p->scontext[1]); +} + +#ifdef __USE_PROTOS +void dumppredexpr(Predicate *p) +#else +void dumppredexpr(p) + Predicate *p; +#endif +{ + fprintf(stderr," pred expr \"%s\"\n",p->expr); +} + +#ifdef __USE_PROTOS +void dt(Tree *t) +#else +void dt(t) + Tree *t; +#endif +{ + MR_dumpTreeF(stderr,0,t,5); +} + +#ifdef __USE_PROTOS +void d(Node * p) +#else +void d(p) + Node * p; +#endif +{ + + Junction *j; + RuleRefNode *r; + TokNode *t; + ActionNode *a; + + if (p==NULL) { + fprintf(stderr,"dumpNode: Node is NULL"); + return; + }; + + switch (p->ntype) { + case nJunction : + j = (Junction *) p; + fprintf(stderr, "Junction (#%d in rule %s line %d) ",j->seq,j->rname,j->line); + if (j->guess) fprintf(stderr,"guess block "); + switch (j->jtype ) { + case aSubBlk : + fprintf(stderr,"aSubBlk"); + break; + case aOptBlk : + fprintf(stderr,"aOptBlk"); + break; + case aLoopBegin : + fprintf(stderr,"aLoopBeginBlk"); + break; + case aLoopBlk : + fprintf(stderr,"aLoopBlk"); + break; + case aPlusBlk : + fprintf(stderr,"aPlusBlk"); + break; + case EndBlk : + fprintf(stderr,"EndBlk"); + break; + case RuleBlk : + fprintf(stderr,"RuleBlk"); + break; + case Generic : + fprintf(stderr,"Generic"); + break; + case EndRule : + fprintf(stderr,"EndRule"); + break; + }; + if (j->halt) fprintf(stderr," halt!"); + if (j->p1) fprintf(stderr," p1 valid"); + if (j->p2) { + if (j->p2->ntype == nJunction) { + fprintf(stderr," (p2=#%d)",( (Junction *) j->p2)->seq); + } else { + fprintf(stderr," (p2 valid)"); + }; + }; + if (j->ignore) fprintf(stderr, " ignore/plus-block-bypass"); + if (j->fset != NULL && set_deg(*j->fset) != 0) { + fprintf(stderr,"\nfset:\n"); + dumpset(*j->fset); + }; + if (j->ftree != NULL) { + fprintf(stderr,"\nftree:\n"); + preorder(j->ftree); + }; + fprintf(stderr,"\n"); + break; + case nRuleRef : + r = (RuleRefNode *) p; + fprintf(stderr, "RuleRefNode (in rule %s line %d) to rule %s\n", r->rname,r->line,r->text); + break; + case nToken : + t = (TokNode *) p; + fprintf(stderr, "TokNode (in rule %s line %d) token %s\n",t->rname,t->line,TerminalString(t->token)); + break; + case nAction : + a =(ActionNode *) p; + if (a->is_predicate) { + fprintf(stderr, "Predicate (in rule %s line %d) %s",a->rname,a->line,a->action); + if (a->inverted) fprintf(stderr," action inverted !"); + if (a->guardpred != NULL) { + fprintf(stderr," guarded"); + dumppredexpr(a->guardpred); + if (a->ampersandPred) { + fprintf(stderr," \"&&\" style"); + } else { + fprintf(stderr," \"=>\" style"); + }; + }; + if (a->predEntry != NULL) fprintf(stderr," predEntry \"%s\" ",a->predEntry->str); + fprintf(stderr,"\n"); + } else if (a->init_action) { + fprintf(stderr, "Init-Action (in rule %s line %d) %s\n",a->rname,a->line,a->action); + } else { + fprintf(stderr, "Action (in rule %s line %d) %s\n",a->rname,a->line,a->action); + }; + break; + }; +} + +#ifdef __USE_PROTOS +Node * dp1(Node * p) +#else +Node * dp1(p) + Node * p; +#endif +{ + Node *result=NULL; + + if (p->ntype == nJunction) { + result=( (Junction *) p )->p1; + d(result); + } else { + fprintf(stderr,"dp1: Not a Junction node"); + }; + return result; +} + +#ifdef __USE_PROTOS +Node * dp2(Node * p) +#else +Node * dp2(p) + Node * p; +#endif +{ + Node *result=NULL; + + if (p->ntype == nJunction) { + result=( (Junction *) p )->p2; + d(result); + } else { + fprintf(stderr,"dp2: Not a Junction node"); + }; + return result; +} + +#ifdef __USE_PROTOS +Node * dn(Node * p) +#else +Node * dn(p) + Node * p; +#endif + +{ + Node *result=NULL; + + if (p->ntype == nRuleRef) { + result=( (RuleRefNode *)p )->next; + } else if (p->ntype == nAction) { + result=( (ActionNode *)p )->next; + } else if (p->ntype == nToken) { + result=( (TokNode *)p )->next; + } else { + fprintf(stderr,"No next field: Neither a RuleRefNode, ActionNode, nor TokNode"); + }; + if (result != NULL) d(result); + return result; +} + +#ifdef __USE_PROTOS +void df(Node * p) +#else +void df(p) + Node * p; +#endif +{ + int count=0; + Node *next; + + fprintf(stderr,"\n#%d ",++count); + d(p); + + for (next=p; next != NULL && !isEndRule(next) ; ) { + fprintf(stderr,"#%d ",++count); + if (next->ntype == nJunction) { + next=dp1(next); + } else { + next=dn(next); + }; + }; +} + +#ifdef __USE_PROTOS +Node * dfn(Node * p,int target) +#else +Node * dfn(p,target) + Node * p; + int target; +#endif +{ + Node *result=NULL; + int count=0; + Node *next; + + fprintf(stderr,"#%d ",++count); + d(p); + + for (next=p; next != NULL && !isEndRule(next) ; ) { + fprintf(stderr,"#%d ",++count); + if (next->ntype == nJunction) { + next=dp1(next); + } else { + next=dn(next); + }; + if (count == target) { + result=next; + break; + }; + }; + return result; +} + + +static int findnodeMatch; + +#ifdef __USE_PROTOS +Junction *findnode1(Node *n) +#else +Junction *findnode1(n) + Node *n; +#endif +{ + Node *next; + Junction *j; + Junction *match; + + if (n == NULL) return NULL; + if (n->ntype == nJunction) { + j=(Junction *) n; + if (j->seq == findnodeMatch) return j; + if (j->jtype == EndRule) return NULL; + if (j->jtype != RuleBlk && j->jtype != EndBlk) { + if (j->p2 != NULL && !j->ignore) { + match=findnode1(j->p2); + if (match != NULL) return match; + }; + }; + }; + next=MR_advance(n); + return findnode1(next); +} + +#ifdef __USE_PROTOS +Junction *findnode(int match) +#else +Junction *findnode(match) + int match; +#endif +{ + Junction *j; + Junction *result=NULL; + + findnodeMatch=match; + + for (j=SynDiag; j != NULL; j=(Junction *)j->p2) { + require (j->ntype == nJunction && j->jtype == RuleBlk,"Not a rule block"); + result=findnode1( (Node *) j); + if (result != NULL) break; + }; + if (result != NULL) { + d( (Node *) result); + }; + return result; +} diff --git a/Tools/CodeTools/Source/Pccts/antlr/egman.c b/Tools/CodeTools/Source/Pccts/antlr/egman.c new file mode 100644 index 0000000000..c8a633fc06 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/egman.c @@ -0,0 +1,328 @@ +/* + * egman.c + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33MR10 + * 2001 + * + */ + +#include +#include + +#include "set.h" +#include "syn.h" +#include "hash.h" +#include "generic.h" +#include "proto.h" + +static ExceptionGroup **egArray=NULL; /* ExceptionGroup by BlkLevel */ +static LabelEntry **leArray=NULL; /* LabelEntry by BlkLevel */ +static Junction **altArray=NULL; /* start of alternates */ +static int arraySize=0; +static int highWater=0; +static ExceptionGroup *lastEG=NULL; /* used in altFixup() */ +static int lastBlkLevel=0; /* used in altFixup() */ + +#ifdef __USE_PROTOS +static void arrayCheck(void); +#else +static void arrayCheck(); +#endif + +/* Called to add an exception group for an alternative EG */ + +#ifdef __USE_PROTOS +void egAdd(ExceptionGroup * eg) +#else +void egAdd(eg) +ExceptionGroup *eg; +#endif +{ + int i; + + ExceptionGroup *nextEG; + ExceptionGroup *innerEG; + + LabelEntry *nextLE; + LabelEntry *innerLE; + + Junction *nextAlt; + Junction *innerAlt; + + lastEG=eg; + lastBlkLevel=BlkLevel; + + arrayCheck(); + eg->pendingLink=egArray[BlkLevel]; + egArray[BlkLevel]=eg; + + /* EG for alternates already have their altID filled in */ + + for (i=BlkLevel+1; i<=highWater ; i++) { + for (innerEG=egArray[i]; innerEG != NULL ; innerEG=nextEG) { + nextEG=innerEG->pendingLink; + innerEG->pendingLink=NULL; + innerEG->outerEG=eg; + }; + egArray[i]=NULL; + }; + + /* + * for patching up the LabelEntry you might use an EG for the + * current alternative - unlike patching up an alternative EG + * i.e. start the loop at BlkLevel rather than (BlkLevel+1) + * fill it in only if the EG and the LE are for the very + * same alternative if they're at the same BlkLevel + * it's easier to leave the LE on this list (filled in) rather than + * trying to selectively remove it. It will eventually be + * removed anyway when the BlkLevel gets small enough. + */ + + for (i=BlkLevel; i<=highWater ; i++) { + for (innerLE=leArray[i]; innerLE != NULL ; innerLE=nextLE) { + nextLE=innerLE->pendingLink; + if (BlkLevel != i || + innerLE->curAltNum == CurAltNum_array[BlkLevel]) { + if (innerLE->outerEG == NULL) { + innerLE->outerEG=eg; + }; + }; + }; + if (BlkLevel != i) leArray[i]=NULL; + }; + +/* + * For the start of alternatives it is necessary to make a + * distinction between the exception group for the current + * alternative and the "fallback" EG for the block which + * contains the alternative + * + * The fallback outerEG is used to handle the case where + * no alternative of a block matches. In that case the + * signal is "NoViableAlt" (or "NoSemViableAlt" and the + * generator needs the EG of the block CONTAINING the + * current one. + * + * rule: ( ( ( a + * | b + * ) + * | c + * ) + * | d + * ); + */ + + for (i=BlkLevel; i <= highWater ; i++) { + for (innerAlt=altArray[i]; innerAlt != NULL ; innerAlt=nextAlt) { + nextAlt=innerAlt->pendingLink; + + /* first fill in the EG for the current alternative */ + /* but leave it on the list in order to get the fallback EG */ + /* if the EG is at the same LEVEL as the alternative then */ + /* fill it in only if in the very same alternative */ + /* */ + /* rule: ( a */ + /* | b */ + /* | c exception ... */ + /* ) */ + /* */ + /* if the EG is outside the alternative (e.g. BlkLevel < i) */ + /* then it doesn't matter about the alternative */ + /* */ + /* rule: ( a */ + /* | b */ + /* | c */ + /* ) exception ... */ + /* */ + +#if 0 + printf("BlkLevel=%d i=%d altnum=%d CurAltNum=%d altID=%s\n", + BlkLevel,i,innerAlt->curAltNum,CurAltNum_array[BlkLevel],eg->altID); +#endif + if (BlkLevel != i || + innerAlt->curAltNum == CurAltNum_array[BlkLevel]) { + if (innerAlt->exception_label == NULL) { + innerAlt->exception_label=eg->altID; + }; + }; + + /* ocurs at a later pass then for the exception_label */ + /* if an outerEG has been found then fill in the outer EG */ + /* remove if from the list when the BlkLevel gets smaller */ + + if (BlkLevel != i) { + if (innerAlt->outerEG == NULL) { + innerAlt->outerEG=eg; + }; + }; + }; + if (BlkLevel != i) altArray[i]=NULL; + }; +} + +#ifdef __USE_PROTOS +void leAdd(LabelEntry * le) +#else +void leAdd(le) +LabelEntry *le; +#endif + +{ + arrayCheck(); + le->pendingLink=leArray[BlkLevel]; + le->curAltNum=CurAltNum_array[BlkLevel]; + leArray[BlkLevel]=le; +} + +#ifdef __USE_PROTOS +void altAdd(Junction *alt) +#else +void altAdd(alt) +Junction *alt; +#endif + +{ + arrayCheck(); +#if 0 + printf("BlkLevel=%d CurAltNum=%d\n", + BlkLevel,CurAltNum_array[BlkLevel]); +#endif + alt->curAltNum=CurAltNum_array[BlkLevel]; + alt->pendingLink=altArray[BlkLevel]; + altArray[BlkLevel]=alt; +} + +static void +#ifdef __USE_PROTOS +arrayCheck(void) +#else +arrayCheck() +#endif +{ + ExceptionGroup **egArrayNew; + LabelEntry **leArrayNew; + Junction **altArrayNew; + int arraySizeNew; + int i; + + if (BlkLevel > highWater) highWater=BlkLevel; + + if (BlkLevel >= arraySize) { + arraySizeNew=BlkLevel+5; /* MR20 */ + egArrayNew=(ExceptionGroup **) + calloc(arraySizeNew,sizeof(ExceptionGroup *)); + leArrayNew=(LabelEntry **) + calloc(arraySizeNew,sizeof(LabelEntry *)); + altArrayNew=(Junction **) + calloc(arraySizeNew,sizeof(Junction *)); + for (i=0; ipendingLink; + innerEG->pendingLink=NULL; + }; + egArray[i]=NULL; + }; + lastEG=NULL; + lastBlkLevel=0; +} + +/* always call leFixup() BEFORE egFixup() */ + +#ifdef __USE_PROTOS +void leFixup(void) +#else +void leFixup() +#endif +{ + + int i; + LabelEntry *nextLE; + LabelEntry *innerLE; + + for (i=BlkLevel; i<=highWater ; i++) { + for (innerLE=leArray[i]; innerLE != NULL ; innerLE=nextLE) { + nextLE=innerLE->pendingLink; + innerLE->pendingLink=NULL; + }; + leArray[i]=NULL; + }; +} + +/* always call altFixup() BEFORE egFixup() */ + +#ifdef __USE_PROTOS +void altFixup(void) +#else +void altFixup() +#endif +{ + + int i; + Junction *nextAlt; + Junction *innerAlt; + + for (i=BlkLevel; i<=highWater ; i++) { + for (innerAlt=altArray[i]; innerAlt != NULL ; innerAlt=nextAlt) { + + /* if an outerEG has been found then fill in the outer EG */ + + if (lastBlkLevel <= i) { + if (innerAlt->outerEG == NULL) { + innerAlt->outerEG=lastEG; + }; + }; + nextAlt=innerAlt->pendingLink; + innerAlt->pendingLink=NULL; + }; + altArray[i]=NULL; + }; +} + diff --git a/Tools/CodeTools/Source/Pccts/antlr/err.c b/Tools/CodeTools/Source/Pccts/antlr/err.c new file mode 100644 index 0000000000..ca239398cf --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/err.c @@ -0,0 +1,538 @@ +/* + * A n t l r S e t s / E r r o r F i l e H e a d e r + * + * Generated from: antlr.g + * + * Terence Parr, Russell Quong, Will Cohen, and Hank Dietz: 1989-2001 + * Parr Research Corporation + * with Purdue University Electrical Engineering + * With AHPCRC, University of Minnesota + * ANTLR Version 1.33MR33 + */ + +#define ANTLR_VERSION 13333 +#include "pcctscfg.h" +#include "pccts_stdio.h" + +#include "pcctscfg.h" +#include "set.h" +#include +#include "syn.h" +#include "hash.h" +#include "generic.h" +#define zzcr_attr(attr,tok,t) +#define zzSET_SIZE 20 +#include "antlr.h" +#include "tokens.h" +#include "dlgdef.h" +#include "err.h" + +ANTLRChar *zztokens[157]={ + /* 00 */ "Invalid", + /* 01 */ "Eof", + /* 02 */ "QuotedTerm", + /* 03 */ "\\n|\\r|\\r\\n", + /* 04 */ "\\(\\n|\\r|\\r\\n)", + /* 05 */ "\\~[]", + /* 06 */ "~[\\n\\r\"\\]+", + /* 07 */ "\"", + /* 08 */ "\\n|\\r|\\r\\n", + /* 09 */ "\\(\\n|\\r|\\r\\n)", + /* 10 */ "\\~[]", + /* 11 */ "~[\\n\\r\"\\]+", + /* 12 */ "'", + /* 13 */ "\\n|\\r|\\r\\n", + /* 14 */ "\\~[]", + /* 15 */ "~[\\n\\r'\\]+", + /* 16 */ "\\*/", + /* 17 */ "\\*", + /* 18 */ "\\n|\\r|\\r\\n", + /* 19 */ "~[\\n\\r\\*]+", + /* 20 */ "\\*/", + /* 21 */ "\\*", + /* 22 */ "\\n|\\r|\\r\\n", + /* 23 */ "~[\\n\\r\\*]+", + /* 24 */ "\\n|\\r|\\r\\n", + /* 25 */ "~[\\n\\r]+", + /* 26 */ "\\n|\\r|\\r\\n", + /* 27 */ "~[\\n\\r]+", + /* 28 */ "\\n|\\r|\\r\\n", + /* 29 */ "~[\\n\\r]+", + /* 30 */ "\\*/", + /* 31 */ "\\*", + /* 32 */ "\\n|\\r|\\r\\n", + /* 33 */ "~[\\n\\r\\*]+", + /* 34 */ "Action", + /* 35 */ "Pred", + /* 36 */ "PassAction", + /* 37 */ "consumeUntil\\( [\\ \\t]* \\{~[\\}]+\\} [\\ \\t]* \\)", + /* 38 */ "consumeUntil\\( ~[\\)]+ \\)", + /* 39 */ "\\n|\\r|\\r\\n", + /* 40 */ "\\>", + /* 41 */ "$", + /* 42 */ "$$", + /* 43 */ "$\\[\\]", + /* 44 */ "$\\[", + /* 45 */ "$[0-9]+", + /* 46 */ "$[0-9]+.", + /* 47 */ "$[0-9]+.[0-9]+", + /* 48 */ "$[_a-zA-Z][_a-zA-Z0-9]*", + /* 49 */ "#0", + /* 50 */ "#\\[\\]", + /* 51 */ "#\\(\\)", + /* 52 */ "#[0-9]+", + /* 53 */ "#line[\\ \\t]* [0-9]+ {[\\ \\t]* \"~[\"]+\" ([\\ \\t]* [0-9]*)* } (\\n|\\r|\\r\\n)", + /* 54 */ "#line ~[\\n\\r]* (\\n|\\r|\\r\\n)", + /* 55 */ "#[_a-zA-Z][_a-zA-Z0-9]*", + /* 56 */ "#\\[", + /* 57 */ "#\\(", + /* 58 */ "#", + /* 59 */ "\\)", + /* 60 */ "\\[", + /* 61 */ "\\(", + /* 62 */ "\\\\]", + /* 63 */ "\\\\)", + /* 64 */ "\\>", + /* 65 */ "'", + /* 66 */ "\"", + /* 67 */ "\\$", + /* 68 */ "\\#", + /* 69 */ "\\(\\n|\\r|\\r\\n)", + /* 70 */ "\\~[\\]\\)>$#]", + /* 71 */ "/", + /* 72 */ "/\\*", + /* 73 */ "\\*/", + /* 74 */ "//", + /* 75 */ "~[\\n\\r\\)\\(\\$#\\>\\]\\[\"'/]+", + /* 76 */ "[\\t\\ ]+", + /* 77 */ "\\n|\\r|\\r\\n", + /* 78 */ "\\[", + /* 79 */ "\\<\\<", + /* 80 */ "\"", + /* 81 */ "/\\*", + /* 82 */ "\\*/", + /* 83 */ "//", + /* 84 */ "#line[\\ \\t]* [0-9]+ {[\\ \\t]* \"~[\"]+\" ([\\ \\t]* [0-9]*)* } (\\n|\\r|\\r\\n)", + /* 85 */ "#line ~[\\n\\r]* (\\n|\\r|\\r\\n)", + /* 86 */ "\\>\\>", + /* 87 */ "WildCard", + /* 88 */ "\\@", + /* 89 */ "LABEL", + /* 90 */ "grammar-element", + /* 91 */ "meta-symbol", + /* 92 */ "Pragma", + /* 93 */ "FirstSetSymbol", + /* 94 */ "{\\}#header", + /* 95 */ "{\\}#first", + /* 96 */ "{\\}#parser", + /* 97 */ "{\\}#tokdefs", + /* 98 */ "\\}", + /* 99 */ "class", + /* 100 */ "NonTerminal", + /* 101 */ "TokenTerm", + /* 102 */ "\\{", + /* 103 */ "!", + /* 104 */ "\\<", + /* 105 */ "\\>", + /* 106 */ ":", + /* 107 */ ";", + /* 108 */ "{\\}#lexaction", + /* 109 */ "{\\}#lexmember", + /* 110 */ "{\\}#lexprefix", + /* 111 */ "{\\}#pred", + /* 112 */ "\\|\\|", + /* 113 */ "&&", + /* 114 */ "\\(", + /* 115 */ "\\)", + /* 116 */ "{\\}#lexclass", + /* 117 */ "{\\}#errclass", + /* 118 */ "{\\}#tokclass", + /* 119 */ "..", + /* 120 */ "{\\}#token", + /* 121 */ "=", + /* 122 */ "[0-9]+", + /* 123 */ "\\|", + /* 124 */ "\\~", + /* 125 */ "^", + /* 126 */ "approx", + /* 127 */ "LL\\(1\\)", + /* 128 */ "LL\\(2\\)", + /* 129 */ "\\*", + /* 130 */ "\\+", + /* 131 */ "?", + /* 132 */ "=>", + /* 133 */ "exception", + /* 134 */ "default", + /* 135 */ "catch", + /* 136 */ "{\\}#[A-Za-z0-9_]*", + /* 137 */ "[\\t\\ ]+", + /* 138 */ "\\n|\\r|\\r\\n", + /* 139 */ "//", + /* 140 */ "/\\*", + /* 141 */ "#ifdef", + /* 142 */ "#if", + /* 143 */ "#ifndef", + /* 144 */ "#else", + /* 145 */ "#endif", + /* 146 */ "#undef", + /* 147 */ "#import", + /* 148 */ "ID", + /* 149 */ "#define", + /* 150 */ "INT", + /* 151 */ "enum", + /* 152 */ "\\{", + /* 153 */ "=", + /* 154 */ ",", + /* 155 */ "\\}", + /* 156 */ ";" +}; +SetWordType zzerr1[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr2[20] = {0xfc,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xf3, + 0xbf,0xff,0xff,0xff, 0xff,0xff,0xff,0x1f}; +SetWordType zzerr3[20] = {0xfc,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xfb, + 0x3b,0xf7,0xf7,0xc7, 0xff,0xff,0xff,0x1f}; +SetWordType zzerr4[20] = {0x4,0x0,0x0,0x0, 0x10,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x80,0x7,0x0,0x0, 0x0,0x0,0x0,0x0}; +SetWordType setwd1[157] = {0x0,0x50,0xa0,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x6a,0x20,0xa0,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x0,0x0,0x20,0x20,0x21, + 0x21,0x21,0x21,0x6e,0x6e,0x64,0x20,0x0, + 0x20,0xa0,0xa0,0xa0,0x20,0x6a,0x6a,0x6a, + 0x6e,0x20,0x20,0x20,0x20,0x66,0x6e,0x6e, + 0x20,0x66,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20}; +SetWordType zzerr5[20] = {0x0,0x0,0x0,0x0, 0x10,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x0,0x1,0x0,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr6[20] = {0x4,0x0,0x0,0x0, 0x10,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x0,0x7,0x0,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr7[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x0,0x6,0x0,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr8[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x0,0x4,0x0,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr9[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x1c,0xf0,0x70,0x1, 0x20,0x0,0x0,0x0}; +SetWordType setwd2[157] = {0x0,0xf8,0x6,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0xf8,0x0,0x1,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0xf8,0xf8,0xf8,0x0,0x0, + 0x0,0x1,0x2,0x6,0x0,0xf8,0xf8,0xf8, + 0xf8,0x0,0x0,0x0,0x0,0xf8,0xf8,0xf8, + 0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0xe8,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0}; +SetWordType zzerr10[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0xbc,0xf8,0x74,0x1, 0x20,0x0,0x0,0x0}; +SetWordType zzerr11[20] = {0x0,0x0,0x0,0x0, 0x8,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0xa0,0x0,0x4,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr12[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x1c,0xf8,0x70,0x1, 0x20,0x0,0x0,0x0}; +SetWordType zzerr13[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0xa0,0x0,0x4,0x0, 0x0,0x0,0x0,0x0}; +SetWordType setwd3[157] = {0x0,0xfa,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0xfa,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0xfa,0xfa,0xfa,0x5,0x0, + 0x5,0x0,0x0,0x0,0xe2,0xfa,0xfa,0xfa, + 0xfa,0xc0,0x80,0x5,0xe0,0xfa,0xfa,0xfa, + 0x0,0xfa,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0xfa,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0}; +SetWordType zzerr14[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x20,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr15[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr16[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr17[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x40,0x0,0x4,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr18[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x24,0x0,0x80,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr19[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x20,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr20[20] = {0x6,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x1c,0xf8,0x74,0x3, 0x20,0x0,0x0,0x0}; +SetWordType zzerr21[20] = {0x6,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x1c,0xf8,0x70,0x3, 0x20,0x0,0x0,0x0}; +SetWordType setwd4[157] = {0x0,0xe5,0xda,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0xe5,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0xed,0xe5,0xe7,0x1a,0x0, + 0x0,0x0,0x0,0x0,0xc0,0xe5,0xe5,0xe5, + 0xe5,0x0,0x0,0x0,0x0,0xe5,0xe5,0xe5, + 0x0,0xe5,0x40,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0xe5,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0}; +SetWordType zzerr22[20] = {0x6,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x3c,0xf8,0x70,0x1, 0x20,0x0,0x0,0x0}; +SetWordType zzerr23[20] = {0x6,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x1c,0xf8,0x70,0x1, 0x20,0x0,0x0,0x0}; +SetWordType zzerr24[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x1c,0xf8,0x70,0x1, 0x20,0x0,0x0,0x0}; +SetWordType zzerr25[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x1c,0xf8,0x70,0x1, 0x20,0x0,0x0,0x0}; +SetWordType zzerr26[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x5, + 0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0}; +SetWordType setwd5[157] = {0x0,0x1f,0xc1,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0xdf,0xc0,0xc0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0xc0,0x0,0xc0,0x0,0x0,0xc0,0xc0,0x0, + 0x0,0x0,0x0,0x7f,0x1f,0xdf,0xc0,0xc0, + 0x0,0x0,0xc0,0x0,0x67,0x1f,0x1f,0x1f, + 0x1f,0x0,0x0,0xc0,0x60,0x1f,0x1f,0x1f, + 0x0,0x1f,0x0,0x0,0x40,0xc0,0x0,0x0, + 0x0,0x0,0xc0,0xc0,0x0,0x0,0x5f,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0}; +SetWordType zzerr27[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4, + 0x0,0x0,0x0,0x10, 0x0,0x0,0x0,0x0}; +SetWordType zzerr28[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x80,0x2, + 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr29[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x20,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr30[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xd, + 0x0,0x0,0x80,0x0, 0x20,0x0,0x0,0x0}; +SetWordType zzerr31[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xd, + 0x0,0x0,0x0,0x0, 0x20,0x0,0x0,0x0}; +SetWordType zzerr32[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x5, + 0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0}; +SetWordType zzerr33[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x20,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; +SetWordType setwd6[157] = {0x0,0x0,0xfd,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0xe1,0xe1,0xe1,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0xfd,0x60,0xe9,0x0,0x0,0xe1,0xe1,0x0, + 0x0,0x0,0x0,0xe2,0x0,0xfd,0xfd,0xe1, + 0x20,0x0,0xe1,0x0,0xe2,0x0,0x0,0x0, + 0x0,0x0,0x0,0xe1,0xe2,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0xe2,0xe0,0x20,0x0, + 0x0,0x0,0xe1,0xe1,0x0,0x0,0xe2,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0}; +SetWordType zzerr34[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xd, + 0x0,0x0,0x80,0x0, 0x20,0x0,0x0,0x0}; +SetWordType zzerr35[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xd, + 0x0,0x0,0x0,0x0, 0x20,0x0,0x0,0x0}; +SetWordType zzerr36[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x5, + 0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0}; +SetWordType zzerr37[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xc, + 0x0,0x0,0x0,0x0, 0x20,0x0,0x0,0x0}; +SetWordType zzerr38[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4, + 0x84,0x9,0x8,0x18, 0x20,0x0,0x0,0x0}; +SetWordType zzerr39[20] = {0x0,0x0,0x0,0x0, 0x10,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x0,0x1,0x0,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr40[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4, + 0x4,0x9,0x8,0x18, 0x20,0x0,0x0,0x0}; +SetWordType zzerr41[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4, + 0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0}; +SetWordType zzerr42[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x80,0x0, + 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; +SetWordType setwd7[157] = {0x0,0x0,0xdf,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0xdf,0xdf,0xff,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0xdf,0x3,0xdf,0x0,0x0,0xdf,0xdf,0x0, + 0x0,0x0,0x0,0xdf,0x0,0xdf,0xdf,0xdf, + 0x1,0x30,0xdf,0x0,0xdf,0x0,0x0,0x0, + 0x0,0x0,0x0,0xdf,0xdf,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0xdf,0xdf,0x1,0x0, + 0x0,0x0,0xdf,0xdf,0x0,0x0,0xdf,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0}; +SetWordType zzerr43[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4, + 0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0}; +SetWordType zzerr44[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0xc0, 0x1,0x0,0x0,0x0}; +SetWordType zzerr45[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x30, + 0x40,0x0,0x4,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr46[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr47[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x20, + 0x40,0x0,0x4,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr48[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x0,0x0,0x2,0x0, 0x10,0x0,0x0,0x0}; +SetWordType zzerr49[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4, + 0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0}; +SetWordType zzerr50[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4, + 0x4,0x8,0xa,0x18, 0x30,0x0,0x0,0x0}; +SetWordType zzerr51[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4, + 0x4,0x8,0x8,0x18, 0x28,0x0,0x0,0x0}; +SetWordType zzerr52[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x40,0x0,0x4,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr53[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4, + 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; +SetWordType setwd8[157] = {0x0,0x0,0xe1,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0xe1,0xe1,0xe1,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0xe1,0x0,0xe1,0x0,0x0,0xe3,0xe7,0x0, + 0x0,0x0,0x0,0xe1,0x0,0xe1,0xe1,0xef, + 0x0,0x0,0xe1,0x0,0xe1,0x0,0x0,0x0, + 0x0,0x0,0x10,0xef,0xe1,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0xe1,0xe1,0x0,0x0, + 0x0,0x0,0xe1,0xe1,0x0,0x10,0xe1,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0}; +SetWordType zzerr54[20] = {0x2,0x0,0x0,0x0, 0x14,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x1c,0xf8,0x78,0x9, 0xe0,0x0,0x0,0x0}; +SetWordType zzerr55[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x1c,0xf8,0x78,0x9, 0x60,0x0,0x0,0x0}; +SetWordType zzerr56[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr57[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x1c,0xf8,0x78,0x9, 0xe0,0x0,0x0,0x0}; +SetWordType setwd9[157] = {0x0,0x7c,0x1,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x7f,0x1,0x1,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x1,0x0,0x1,0x0,0x0,0x1,0x1,0x0, + 0x0,0x0,0x0,0x7f,0x7e,0x7f,0x1,0x1, + 0x0,0x0,0x1,0x0,0x7d,0x7e,0x7e,0x7e, + 0x7e,0x0,0x0,0x1,0x7d,0x7e,0x7e,0x7e, + 0x0,0x7e,0x0,0x0,0x7d,0x1,0x0,0x0, + 0x0,0x0,0x1,0x1,0x0,0x0,0x7f,0x64, + 0x64,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x80,0x0,0x0,0x0,0x0,0x0,0x80,0x0, + 0x80,0x0,0x0,0x0,0x0,0x0}; +SetWordType zzerr58[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0, 0x0,0x0,0xa0,0x0}; +SetWordType zzerr59[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0, 0x0,0x80,0xa0,0x0}; +SetWordType zzerr60[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0, 0x0,0x0,0xa0,0x0}; +SetWordType zzerr61[20] = {0x2,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0, 0x0,0x80,0xa0,0x0}; +SetWordType zzerr62[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xe}; +SetWordType zzerr63[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xe}; +SetWordType zzerr64[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xe}; +SetWordType zzerr65[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0, 0x0,0x0,0x10,0xc}; +SetWordType setwd10[157] = {0x0,0xc,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0, + 0x3,0x0,0x0,0xf0,0xf0,0x0}; +SetWordType setwd11[157] = {0x0,0x1,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, + 0x1,0x0,0x0,0x0,0x0,0x0}; diff --git a/Tools/CodeTools/Source/Pccts/antlr/fcache.c b/Tools/CodeTools/Source/Pccts/antlr/fcache.c new file mode 100644 index 0000000000..ff7dcdfdd5 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/fcache.c @@ -0,0 +1,123 @@ +/* + * fcache.c + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33MR10 + * + */ + +#include +#include + +#include "pcctscfg.h" + +#include "set.h" +#include "syn.h" +#include "hash.h" +#include "generic.h" + +#ifdef __USE_PROTOS +CacheEntry *dumpFcache1(char *prev) +#else +CacheEntry *dumpFcache1(prev) + char *prev; +#endif +{ + Entry **table=Fcache; + + int low=0; + int hi=0; + + CacheEntry *least=NULL; + + Entry **p; + + for (p=table; p<&(table[HashTableSize]); p++) { + + CacheEntry *q =(CacheEntry *) *p; + + if ( q != NULL && low==0 ) low = p-table; + while ( q != NULL ) { + if (strcmp(q->str,prev) > 0) { + if (least == NULL) { + least=q; + } else { + if (strcmp(q->str,least->str) < 0) { + least=q; + }; + }; + }; + q = q->next; + }; + + if ( *p != NULL ) hi = p-table; + } + return least; +} + +#ifdef __USE_PROTOS +void reportFcache(CacheEntry *q) +#else +void reportFcache(q) + CacheEntry *q; +#endif +{ + char *qstr; + + fprintf(stdout,"\nrule "); + for (qstr=q->str; *qstr != '*' ; qstr++) { + fprintf(stdout,"%c",*qstr); + }; + + qstr++; + if (*qstr == 'i') fprintf(stdout," First["); + if (*qstr == 'o') fprintf(stdout," Follow["); + qstr++; + fprintf(stdout,"%s]",qstr); + if (q->incomplete) fprintf(stdout," *** incomplete ***"); + fprintf(stdout,"\n"); + MR_dumpTokenSet(stdout,1,q->fset); +} + +void +#ifdef __USE_PROTOS +DumpFcache(void) +#else +DumpFcache() +#endif +{ + + char *prev=""; + int n=0; + CacheEntry *next; + + fprintf(stdout,"\n\nDump of First/Follow Cache\n"); + + for(;;) { + next=dumpFcache1(prev); + if (next == NULL) break; + reportFcache(next); + ++n; + prev=next->str; + }; + fprintf(stdout,"\nEnd dump of First/Follow Cache\n"); +} diff --git a/Tools/CodeTools/Source/Pccts/antlr/fset.c b/Tools/CodeTools/Source/Pccts/antlr/fset.c new file mode 100644 index 0000000000..e1a76ec620 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/fset.c @@ -0,0 +1,1555 @@ +/* + * fset.c + * + * Compute FIRST and FOLLOW sets. + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2001 + */ + +#include +#include + +#include "pcctscfg.h" + +#include "set.h" +#include "syn.h" +#include "hash.h" +#include "generic.h" +#include "dlgdef.h" +#include "limits.h" + +#ifdef __USE_PROTOS +static void ensure_predicates_cover_ambiguous_lookahead_sequences + (Junction *, Junction *, char *, Tree *); +#else +static void ensure_predicates_cover_ambiguous_lookahead_sequences(); +#endif + +/* + * What tokens are k tokens away from junction q? + * + * Follow both p1 and p2 paths (unless RuleBlk) to collect the tokens k away from this + * node. + * We lock the junction according to k--the lookahead. If we have been at this + * junction before looking for the same, k, number of lookahead tokens, we will + * do it again and again...until we blow up the stack. Locks are only used on aLoopBlk, + * RuleBlk, aPlusBlk and EndRule junctions to remove/detect infinite recursion from + * FIRST and FOLLOW calcs. + * + * If p->jtype == EndRule we are going to attempt a FOLLOW. (FOLLOWs are really defined + * in terms of FIRST's, however). To proceed with the FOLLOW, p->halt cannot be + * set. p->halt is set to indicate that a reference to the current rule is in progress + * and the FOLLOW is not desirable. + * + * If we attempt a FOLLOW and find that there is no FOLLOW or REACHing beyond the EndRule + * junction yields an empty set, replace the empty set with EOF. No FOLLOW means that + * only EOF can follow the current rule. This normally occurs only on the start symbol + * since all other rules are referenced by another rule somewhere. + * + * Normally, both p1 and p2 are followed. However, checking p2 on a RuleBlk node is + * the same as checking the next rule which is clearly incorrect. + * + * Cycles in the FOLLOW sense are possible. e.g. Fo(c) requires Fo(b) which requires + * Fo(c). Both Fo(b) and Fo(c) are defined to be Fo(b) union Fo(c). Let's say + * Fo(c) is attempted first. It finds all of the FOLLOW symbols and then attempts + * to do Fo(b) which finds of its FOLLOW symbols. So, we have: + * + * Fo(c) + * / \ + * a set Fo(b) + * / \ + * a set Fo(c) .....Hmmmm..... Infinite recursion! + * + * The 2nd Fo(c) is not attempted and Fo(b) is left deficient, but Fo(c) is now + * correctly Fo(c) union Fo(b). We wish to pick up where we left off, so the fact + * that Fo(b) terminated early means that we lack Fo(c) in the Fo(b) set already + * laying around. SOOOOoooo, we track FOLLOW cycles. All FOLLOW computations are + * cached in a hash table. After the sequence of FOLLOWs finish, we reconcile all + * cycles --> correct all Fo(rule) sets in the cache. + * + * Confused? Good! Read my MS thesis [Purdue Technical Report TR90-30]. + * TJP 8/93 -- can now read PhD thesis from Purdue. + * + * Also, FIRST sets are cached in the hash table. Keys are (rulename,Fi/Fo,k). + * Only FIRST sets, for which the FOLLOW is not included, are stored. + * + * SPECIAL CASE of (...)+ blocks: + * I added an optional alt so that the alts could see what + * was behind the (...)+ block--thus using enough lookahead + * to branch out rather than just enough to distinguish + * between alts in the (...)+. However, when the FIRST("(...)+") is + * is needed, must not use this last "optional" alt. This routine + * turns off this path by setting a new 'ignore' flag for + * the alt and then resetting it afterwards. + */ + +set +#ifdef __USE_PROTOS +rJunc( Junction *p, int k, set *rk ) +#else +rJunc( p, k, rk ) +Junction *p; +int k; +set *rk; +#endif +{ + set a, b; + + require(p!=NULL, "rJunc: NULL node"); + require(p->ntype==nJunction, "rJunc: not junction"); + +#ifdef DBG_LL1 + if ( p->jtype == RuleBlk ) fprintf(stderr, "FIRST(%s,%d) \n",((Junction *)p)->rname,k); + else fprintf(stderr, "rJunc: %s in rule %s\n", + decodeJType[p->jtype], ((Junction *)p)->rname); +#endif + /* if this is one of the added optional alts for (...)+ then return */ + + /* no need to pop backtrace - hasn't been pushed */ + + if ( p->ignore ) return empty; + + if (MR_MaintainBackTrace) MR_pointerStackPush(&MR_BackTraceStack,p); + +/* MR14 */ if (AlphaBetaTrace && p->alpha_beta_guess_end) { +/* MR14 */ warnFL( +/* MR14 */ "not possible to compute follow set for alpha in an \"(alpha)? beta\" block. ", +/* MR14 */ FileStr[p->file],p->line); +/* MR14 */ MR_alphaBetaTraceReport(); +/* MR14 */ }; + +/* MR14 */ if (p->alpha_beta_guess_end) { +/* MR14 */ if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); +/* MR14 */ return empty; +/* MR14 */ } + + /* locks are valid for aLoopBlk,aPlusBlk,RuleBlk,EndRule junctions only */ + if ( p->jtype==aLoopBlk || p->jtype==RuleBlk || + p->jtype==aPlusBlk || p->jtype==EndRule ) + { + require(p->lock!=NULL, "rJunc: lock array is NULL"); + if ( p->lock[k] ) + { + if ( p->jtype == EndRule ) /* FOLLOW cycle? */ + { +#ifdef DBG_LL1 + fprintf(stderr, "FOLLOW cycle to %s: panic!\n", p->rname); +#endif + if (! MR_AmbSourceSearch) RegisterCycle(p->rname, k); + } + if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); + return empty; + } + if ( p->jtype == RuleBlk && + p->end->halt && + ! MR_AmbSourceSearch) /* check for FIRST cache */ + { + CacheEntry *q = (CacheEntry *) hash_get(Fcache, Fkey(p->rname,'i',k)); + if ( q != NULL ) + { + set_orin(rk, q->rk); + if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); + return set_dup( q->fset ); + } + } + if ( p->jtype == EndRule && + !p->halt && /* MR11 was using cache even when halt set */ + ! MR_AmbSourceSearch) /* FOLLOW set cached already? */ + { + CacheEntry *q = (CacheEntry *) hash_get(Fcache, Fkey(p->rname,'o',k)); + if ( q != NULL ) + { +#ifdef DBG_LL1 + fprintf(stderr, "cache for FOLLOW(%s,%d):", p->rname,k); + s_fprT(stderr, q->fset); + if ( q->incomplete ) fprintf(stderr, " (incomplete)"); + fprintf(stderr, "\n"); +#endif + if ( !q->incomplete ) + { + if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); + return set_dup( q->fset ); + } + } + } + p->lock[k] = TRUE; /* This rule is busy */ + } + + a = b = empty; + + if ( p->jtype == EndRule ) + { + if (p->halt ) /* don't want FOLLOW here? */ /* unless MR10 hoisting */ + { + p->lock[k] = FALSE; + set_orel(k, rk); /* indicate this k value needed */ + if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); + return empty; + } + if (! MR_AmbSourceSearch) FoPush(p->rname, k); /* Attempting FOLLOW */ + if ( p->p1 == NULL ) set_orel((TokenInd!=NULL?TokenInd[EofToken]:EofToken), &a);/* if no FOLLOW assume EOF */ +#ifdef DBG_LL1 + fprintf(stderr, "-->FOLLOW(%s,%d)\n", p->rname,k); +#endif + } + + if ( p->p1 != NULL ) { +/* MR14 */ if (p->guess) { +/* MR14 */ if (p->guess_analysis_point == NULL) { +/* MR14 */ Node * guess_point; +/* MR14 */ guess_point=(Node *)analysis_point(p); +/* MR14 */ if (guess_point == (Node *)p) { +/* MR14 */ guess_point=p->p1; +/* MR14 */ } +/* MR14 */ p->guess_analysis_point=guess_point; +/* MR14 */ } +/* MR14 */ REACH(p->guess_analysis_point, k, rk, a); + } else { + REACH(p->p1, k, rk, a); + } + } + + /* C a c h e R e s u l t s */ + + if ( p->jtype == RuleBlk && p->end->halt && ! MR_AmbSourceSearch) /* can save FIRST set? */ + { + CacheEntry *q = newCacheEntry( Fkey(p->rname,'i',k) ); + /*fprintf(stderr, "Caching %s FIRST %d\n", p->rname, k);*/ + hash_add(Fcache, Fkey(p->rname,'i',k), (Entry *)q); + q->fset = set_dup( a ); + q->rk = set_dup( *rk ); + } + + if ( p->jtype == EndRule && + !p->halt && /* MR11 was using cache even with halt set */ + ! MR_AmbSourceSearch) /* just completed FOLLOW? */ + { + /* Cache Follow set */ + CacheEntry *q = (CacheEntry *) hash_get(Fcache, Fkey(p->rname,'o',k)); + if ( q==NULL ) + { + q = newCacheEntry( Fkey(p->rname,'o',k) ); + hash_add(Fcache, Fkey(p->rname,'o',k), (Entry *)q); + } + /*fprintf(stderr, "Caching %s FOLLOW %d\n", p->rname, k);*/ + if ( set_nil(a) && !q->incomplete ) + { + /* Don't ever save a nil set as complete. + * Turn it into an eof set. + */ + set_orel(EofToken, &a); + } + set_orin(&(q->fset), a); + FoPop( k ); + if ( FoTOS[k] == NULL && Cycles[k] != NULL ) ResolveFoCycles(k); +#ifdef DBG_LL1 + fprintf(stderr, "saving FOLLOW(%s,%d):", p->rname, k); + s_fprT(stderr, q->fset); + if ( q->incomplete ) fprintf(stderr, " (incomplete)"); + fprintf(stderr, "\n"); +#endif + } + + if (p->jtype != RuleBlk && p->p2 != NULL && /* MR14 */ ! p->guess) { + REACH(p->p2, k, rk, b); + } + + if ( p->jtype==aLoopBlk || p->jtype==RuleBlk || + p->jtype==aPlusBlk || p->jtype==EndRule ) + p->lock[k] = FALSE; /* unlock node */ + + set_orin(&a, b); + set_free(b); + if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); + return a; +} + +set +#ifdef __USE_PROTOS +rRuleRef( RuleRefNode *p, int k, set *rk_out ) +#else +rRuleRef( p, k, rk_out ) +RuleRefNode *p; +int k; +set *rk_out; +#endif +{ + set rk; + Junction *r; + int k2; + set a, rk2, b; + int save_halt; + RuleEntry *q = (RuleEntry *) hash_get(Rname, p->text); + require(p!=NULL, "rRuleRef: NULL node"); + require(p->ntype==nRuleRef, "rRuleRef: not rule ref"); + +#ifdef DBG_LL1 + fprintf(stderr, "rRuleRef: %s\n", p->text); +#endif + + if (MR_MaintainBackTrace) MR_pointerStackPush(&MR_BackTraceStack,p); + + if ( q == NULL ) + { + warnFL( eMsg1("rule %s not defined",p->text), FileStr[p->file], p->line ); + REACH(p->next, k, rk_out, a); + if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); + return a; + } + rk2 = empty; + +/* MR9 Problems with rule references in guarded predicates */ +/* MR9 Perhaps can use hash table to find rule ? */ + +/* MR9 */ if (RulePtr == NULL) { +/* MR9 */ fatalFL(eMsg2("Rule %s uses rule %s via RulePtr before it has been initialized", +/* MR9 */ p->rname,q->str),FileStr[p->file],p->line); +/* MR9 */ }; + + r = RulePtr[q->rulenum]; + if ( r->lock[k] ) + { + errNoFL( eMsg2("infinite left-recursion to rule %s from rule %s", + r->rname, p->rname) ); + + if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); + + return empty; + } + + save_halt = r->end->halt; + r->end->halt = TRUE; /* don't let reach fall off end of rule here */ + rk = empty; + REACH(r, k, &rk, a); + r->end->halt = save_halt; + while ( !set_nil(rk) ) { + k2 = set_int(rk); /* MR11 this messes up the ambiguity search routine */ + set_rm(k2, rk); + REACH(p->next, k2, &rk2, b); /* MR11 by changing the value of k */ + set_orin(&a, b); + set_free(b); + } + set_free(rk); /* this has no members, but free it's memory */ + set_orin(rk_out, rk2); /* remember what we couldn't do */ + set_free(rk2); + if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); + return a; +} + +/* + * Return FIRST sub k ( token_node ) + * + * TJP 10/11/93 modified this so that token nodes that are actually + * ranges (T1..T2) work. + */ +set +#ifdef __USE_PROTOS +rToken( TokNode *p, int k, set *rk ) +#else +rToken( p, k, rk ) +TokNode *p; +int k; +set *rk; +#endif +{ + set a; + + require(p!=NULL, "rToken: NULL node"); + require(p->ntype==nToken, "rToken: not token node"); + +#ifdef DBG_LL1 + fprintf(stderr, "rToken: %s\n", (TokenString(p->token)!=NULL)?TokenString(p->token): + ExprString(p->token)); +#endif + + + if (MR_MaintainBackTrace) MR_pointerStackPush(&MR_BackTraceStack,p); + + if (MR_AmbSourceSearch && (k-1) == 0) { + + set localConstrain; + set intersection; + + localConstrain=fset[maxk-k+1]; + + if (! set_nil(p->tset)) { + intersection=set_and(localConstrain,p->tset); + if (! set_nil(intersection)) { + MR_backTraceReport(); + }; + set_free(intersection); + } else { + if (set_el( (unsigned) p->token,localConstrain)) { + MR_backTraceReport(); + } + }; + }; + + if ( k-1 == 0 ) { + + if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); + + if ( !set_nil(p->tset) ) { + return set_dup(p->tset); + } else { + return set_of(p->token); + }; + } + + REACH(p->next, k-1, rk, a); + + if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); + + return a; +} + +set +#ifdef __USE_PROTOS +rAction( ActionNode *p, int k, set *rk ) +#else +rAction( p, k, rk ) +ActionNode *p; +int k; +set *rk; +#endif +{ + set a; + + require(p!=NULL, "rJunc: NULL node"); + require(p->ntype==nAction, "rJunc: not action"); + +/* MR11 */ if (p->is_predicate && p->ampersandPred != NULL) { +/* MR11 */ Predicate *pred=p->ampersandPred; +/* MR11 */ if (k <= pred->k) { +/* MR11 */ REACH(p->guardNodes,k,rk,a); +/* MR11 */ return a; +/* MR11 */ }; +/* MR11 */ }; + + /* it might be a good idea when doing an MR_AmbSourceSearch + to *not* look behind predicates under some circumstances + we'll look into that later + */ + + REACH(p->next, k, rk, a); /* ignore actions */ + return a; +} + + /* A m b i g u i t y R e s o l u t i o n */ + + +void +#ifdef __USE_PROTOS +dumpAmbigMsg( set *fset, FILE *f, int want_nls ) +#else +dumpAmbigMsg( fset, f, want_nls ) +set *fset; +FILE *f; +int want_nls; +#endif +{ + int i; + + set copy; /* MR11 */ + + if ( want_nls ) fprintf(f, "\n\t"); + else fprintf(f, " "); + + for (i=1; i<=CLL_k; i++) + { + copy=set_dup(fset[i]); /* MR11 */ + + if ( i>1 ) + { + if ( !want_nls ) fprintf(f, ", "); + } + if ( set_deg(copy) > 3 && elevel == 1 ) + { + int e,m; + fprintf(f, "{"); + for (m=1; m<=3; m++) + { + e=set_int(copy); + fprintf(f, " %s", TerminalString(e)); + set_rm(e, copy); + } + fprintf(f, " ... }"); + } + else s_fprT(f, copy); + if ( want_nls ) fprintf(f, "\n\t"); + set_free(copy); + } + fprintf(f, "\n"); + +} + +static void +#ifdef __USE_PROTOS +verify_context(Predicate *predicate) +#else +verify_context(predicate) +Predicate *predicate; +#endif +{ + if ( predicate == NULL ) return; + + if ( predicate->expr == PRED_OR_LIST || + predicate->expr == PRED_AND_LIST ) + { + verify_context(predicate->down); + verify_context(predicate->right); /* MR10 */ + return; + } + + if ( !predicate->source->ctxwarned && predicate->source->guardpred==NULL && + ((predicate->k > 1 && + !is_single_tuple(predicate->tcontext)) || + ( predicate->k == 1 && + set_deg(predicate->scontext[1])>1 )) ) + { + +/* MR9 Suppress annoying messages caused by our own clever(?) fix */ + + fprintf(stderr, ErrHdr, FileStr[predicate->source->file], + predicate->source->line); + fprintf(stderr, " warning: predicate applied for >1 lookahead %d-sequences\n", predicate->k); + fprintf(stderr, ErrHdr, FileStr[predicate->source->file], + predicate->source->line); + fprintf(stderr, " predicate text: \"%s\"\n", + (predicate->expr == NULL ? "(null)" : predicate->expr) ); + fprintf(stderr, ErrHdr, FileStr[predicate->source->file], + predicate->source->line); + fprintf(stderr, " You may only want one lookahead %d-sequence to apply\n", predicate->k); + fprintf(stderr, ErrHdr, FileStr[predicate->source->file], + predicate->source->line); + fprintf(stderr, " Try using a context guard '(...)? =>'\n"); + predicate->source->ctxwarned = 1; + } + verify_context(predicate->right); /* MR10 */ +} + +/* + * If delta is the set of ambiguous lookahead sequences, then make sure that + * the predicate(s) for productions alt1,alt2 cover the sequences in delta. + * + * For example, + * a : <>? (A B|A C) + * | b + * ; + * b : <>? A B + * | A C + * ; + * + * This should give a warning that (A C) predicts both productions and alt2 + * does not have a predicate in the production that generates (A C). + * + * The warning detection is simple. Let delta = LOOK(alt1) intersection LOOK(alt2). + * Now, if ( delta set-difference context(predicates-for-alt1) != empty then + * alt1 does not "cover" all ambiguous sequences. + * + * If ambig is nonempty, then ambig in LL(k) sense -> use tree info; else use fset + * info. Actually, sets are used only if k=1 for this grammar. + */ +static void +#ifdef __USE_PROTOS +ensure_predicates_cover_ambiguous_lookahead_sequences + ( Junction *alt1, Junction *alt2, char *sub, Tree *ambig ) +#else +ensure_predicates_cover_ambiguous_lookahead_sequences( alt1, alt2, sub, ambig ) +Junction *alt1; +Junction *alt2; +char *sub; +Tree *ambig; +#endif +{ + if ( !ParseWithPredicates ) return; + + if ( ambig!=NULL ) + { + Tree *non_covered = NULL; + if ( alt1->predicate!=NULL ) + non_covered = tdif(ambig, alt1->predicate, alt1->fset, alt2->fset); + if ( (non_covered!=NULL || alt1->predicate==NULL) && WarningLevel>1 ) + { + fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line); + fprintf(stderr, " warning: alt %d %shas no predicate to resolve ambiguity", + alt1->altnum, sub); + if ( alt1->predicate!=NULL && non_covered!=NULL ) + { + fprintf(stderr, " upon"); + preorder(non_covered); + } + else if ( alt1->predicate==NULL ) + { + fprintf(stderr, " upon"); + preorder(ambig->down); + } + fprintf(stderr, "\n"); + } + Tfree(non_covered); + non_covered = NULL; + if ( alt2->predicate!=NULL ) + non_covered = tdif(ambig, alt2->predicate, alt1->fset, alt2->fset); + if ( (non_covered!=NULL || alt2->predicate==NULL) && WarningLevel>1 ) + { + fprintf(stderr, ErrHdr, FileStr[alt2->file], alt2->line); + fprintf(stderr, " warning: alt %d %shas no predicate to resolve ambiguity", + alt2->altnum, sub); + if ( alt2->predicate!=NULL && non_covered!=NULL ) + { + fprintf(stderr, " upon"); + preorder(non_covered); + } + else if ( alt2->predicate==NULL ) + { + fprintf(stderr, " upon"); + preorder(ambig->down); + } + fprintf(stderr, "\n"); + } + Tfree(non_covered); + } + else if ( !set_nil(alt1->fset[1]) ) + { + set delta, non_covered; + delta = set_and(alt1->fset[1], alt2->fset[1]); + non_covered = set_dif(delta, covered_set(alt1->predicate)); + if ( set_deg(non_covered)>0 && WarningLevel>1 ) + { + fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line); + fprintf(stderr, " warning: alt %d %shas no predicate to resolve ambiguity", + alt1->altnum, sub); + if ( alt1->predicate!=NULL ) + { + fprintf(stderr, " upon "); + s_fprT(stderr, non_covered); + } + fprintf(stderr, "\n"); + } + set_free( non_covered ); + non_covered = set_dif(delta, covered_set(alt2->predicate)); + if ( set_deg(non_covered)>0 && WarningLevel>1 ) + { + fprintf(stderr, ErrHdr, FileStr[alt2->file], alt2->line); + fprintf(stderr, " warning: alt %d %shas no predicate to resolve ambiguity", + alt2->altnum, sub); + if ( alt2->predicate!=NULL ) + { + fprintf(stderr, " upon "); + s_fprT(stderr, non_covered); + } + fprintf(stderr, "\n"); + } + set_free( non_covered ); + set_free( delta ); + } + else fatal_internal("productions have no lookahead in predicate checking routine"); +} + +#ifdef __USE_PROTOS +void MR_doPredicatesHelp(int inGuessBlock,Junction *alt1,Junction *alt2,int jtype,char *sub) +#else +void MR_doPredicatesHelp(inGuessBlock,alt1,alt2,jtype,sub) + int inGuessBlock; + Junction *alt1; + Junction *alt2; + int jtype; + char *sub; +#endif +{ + Predicate *p1; + Predicate *p2; + + Junction *parentRule=MR_nameToRuleBlk(alt1->rname); + + if (inGuessBlock && WarningLevel <= 1) return; + + /* let antlr give the usual error message */ + + if (alt1->predicate == NULL && alt2->predicate == NULL) return; + + if ( (jtype == RuleBlk || jtype == aSubBlk) + && (alt1->predicate == NULL && alt2->predicate != NULL)) { + fprintf(stderr, ErrHdr, FileStr[parentRule->file],parentRule->line); + fprintf(stderr," warning: alt %d line %d and alt %d line %d of %s\n%s%s%s", + alt1->altnum, + alt1->line, + alt2->altnum, + alt2->line, + sub, + " These alts have ambig lookahead sequences resolved by a predicate for\n", + " the second choice. The second choice may not be reachable.\n", + " You may want to use a complementary predicate or rearrange the alts\n" + ); + return; + }; + + /* first do the easy comparison. then do the hard one */ + + if (MR_comparePredicates(alt1->predicate,alt2->predicate)) { + + if (jtype == aLoopBegin || jtype == aPlusBlk ) { + + /* I'm not sure this code is reachable. + Predicates following a (...)+ or (...)* block are probably + considered validation predicates and therefore not + participate in the predication expression + */ + + fprintf(stderr, ErrHdr,FileStr[parentRule->file],parentRule->line); + fprintf(stderr," warning: %s of %s in rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s", + "the predicates used to disambiguate optional/exit paths of ", + sub, + CurRule, + FileStr[alt1->file], + alt1->altnum, + alt1->line, + alt2->altnum, + alt2->line, + " are identical and have no resolving power\n"); + } else { + fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line); + fprintf(stderr," warning: %s rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s", + "the predicates used to disambiguate", + CurRule, + FileStr[alt1->file], + alt1->altnum, + alt1->line, + alt2->altnum, + alt2->line, + " are identical and have no resolving power\n"); + }; + } else { + p1=predicate_dup_without_context(alt1->predicate); + p1=MR_unfold(p1); + MR_clearPredEntry(p1); + MR_simplifyInverted(p1,0); + p1=MR_predSimplifyALL(p1); + p2=predicate_dup_without_context(alt2->predicate); + p2=MR_unfold(p2); + MR_clearPredEntry(p2); + MR_simplifyInverted(p2,0); + p2=MR_predSimplifyALL(p2); + if (MR_comparePredicates(p1,p2)) { + if (jtype == aLoopBegin || jtype == aPlusBlk ) { + fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line); + fprintf(stderr," warning: %s of %s in rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s%s", + "the predicates used to disambiguate optional/exit paths of ", + sub, + CurRule, + FileStr[alt1->file], + alt1->altnum, + alt1->line, + alt2->altnum, + alt2->line, + " are identical when compared without context and may have no\n", + " resolving power for some lookahead sequences.\n"); + } else { + fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line); + fprintf(stderr," warning: %s rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s%s", + "the predicates used to disambiguate", + CurRule, + FileStr[alt1->file], + alt1->altnum, + alt1->line, + alt2->altnum, + alt2->line, + " are identical when compared without context and may have no\n", + " resolving power for some lookahead sequences.\n"); + }; + if (InfoP) { + fprintf(output,"\n#if 0\n\n"); + fprintf(output,"The following predicates are identical when compared without\n"); + fprintf(output," lookahead context information. For some ambiguous lookahead\n"); + fprintf(output," sequences they may not have any power to resolve the ambiguity.\n"); + fprintf(output,"\n"); + + fprintf(output,"Choice 1: %s alt %d line %d file %s\n\n", + MR_ruleNamePlusOffset( (Node *) alt1), + alt1->altnum, + alt1->line, + FileStr[alt1->file]); + fprintf(output," The original predicate for choice 1 with available context information:\n\n"); + MR_dumpPred1(2,alt1->predicate,1); + fprintf(output," The predicate for choice 1 after expansion (but without context information):\n\n"); + MR_dumpPred1(2,p1,0); + if (p1 == NULL) { + Predicate *phelp; + fprintf(output," The predicate for choice 1 after expansion (but before simplification)\n\n"); + phelp=predicate_dup_without_context(alt1->predicate); + phelp=MR_unfold(phelp); + MR_clearPredEntry(phelp); + MR_simplifyInverted(phelp,0); + phelp=MR_predSimplifyALLX(phelp,1); + MR_dumpPred1(2,phelp,0); + predicate_free(phelp); + }; + fprintf(output,"\n"); + + fprintf(output,"Choice 2: %s alt %d line %d file %s\n\n", + MR_ruleNamePlusOffset( (Node *) alt2), + alt2->altnum, + alt2->line, + FileStr[alt2->file]); + fprintf(output," The original predicate for choice 2 with available context information:\n\n"); + MR_dumpPred1(1,alt2->predicate,1); + fprintf(output," The predicate for choice 2 after expansion (but without context information):\n\n"); + MR_dumpPred1(1,p2,0); + if (p2 == NULL) { + Predicate *phelp; + fprintf(output," The predicate for choice 2 after expansion (but before simplification)\n\n"); + phelp=predicate_dup_without_context(alt2->predicate); + phelp=MR_unfold(phelp); + MR_clearPredEntry(phelp); + MR_simplifyInverted(phelp,0); + phelp=MR_predSimplifyALLX(phelp,1); + MR_dumpPred1(2,phelp,0); + predicate_free(phelp); + }; + fprintf(output,"\n#endif\n"); + }; + } else if (MR_secondPredicateUnreachable(p1,p2)) { + if (jtype == aLoopBegin || jtype == aPlusBlk ) { + fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line); + fprintf(stderr," warning: %s of %s in rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s%s", + "the predicate used to disambiguate the first choice of the optional/exit paths of ", + sub, + CurRule, + FileStr[alt1->file], + alt1->altnum, + alt1->line, + alt2->altnum, + alt2->line, + " appears to \"cover\" the second predicate when compared without context.\n", + " The second predicate may have no resolving power for some lookahead sequences.\n"); + } else { + fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line); + fprintf(stderr," warning: %s rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s%s", + "the predicate used to disambiguate the first choice of", + CurRule, + FileStr[alt1->file], + alt1->altnum, + alt1->line, + alt2->altnum, + alt2->line, + " appears to \"cover\" the second predicate when compared without context.\n", + " The second predicate may have no resolving power for some lookahead sequences.\n"); + }; + if (InfoP) { + fprintf(output,"\n#if 0\n\n"); + fprintf(output,"The first predicate appears to \"cover\" the second predicate when they\n"); + fprintf(output," are compared without lookahead context information. For some ambiguous\n"); + fprintf(output," lookahead sequences the second predicate may not have any power to\n"); + fprintf(output," resolve the ambiguity.\n"); + fprintf(output,"\n"); + fprintf(output,"Choice 1: %s alt %d line %d file %s\n\n", + MR_ruleNamePlusOffset( (Node *) alt1), + alt1->altnum, + alt1->line, + FileStr[alt1->file]); + fprintf(output," The original predicate for choice 1 with available context information:\n\n"); + MR_dumpPred1(2,alt1->predicate,1); + fprintf(output," The predicate for choice 1 after expansion (but without context information):\n\n"); + MR_dumpPred1(2,p1,0); + if (p1 == NULL) { + Predicate *phelp; + fprintf(output," The predicate for choice 1 after expansion (but before simplification)\n\n"); + phelp=predicate_dup_without_context(alt1->predicate); + phelp=MR_unfold(phelp); + MR_clearPredEntry(phelp); + MR_simplifyInverted(phelp,0); + phelp=MR_predSimplifyALLX(phelp,1); + MR_dumpPred1(2,phelp,0); + predicate_free(phelp); + }; + fprintf(output,"\n"); + + fprintf(output,"Choice 2: %s alt %d line %d file %s\n\n", + MR_ruleNamePlusOffset( (Node *) alt2), + alt2->altnum, + alt2->line, + FileStr[alt2->file]); + fprintf(output," The original predicate for choice 2 with available context information:\n\n"); + MR_dumpPred1(1,alt2->predicate,1); + fprintf(output," The predicate for choice 2 after expansion (but without context information):\n\n"); + MR_dumpPred1(1,p2,0); + if (p2 == NULL) { + Predicate *phelp; + fprintf(output," The predicate for choice 2 after expansion (but before simplification)\n\n"); + phelp=predicate_dup_without_context(alt2->predicate); + phelp=MR_unfold(phelp); + MR_clearPredEntry(phelp); + MR_simplifyInverted(phelp,0); + phelp=MR_predSimplifyALLX(phelp,1); + MR_dumpPred1(2,phelp,0); + predicate_free(phelp); + }; + fprintf(output,"\n#endif\n"); + }; + }; + predicate_free(p1); + predicate_free(p2); + }; +} + +static int totalOverflow=0; /* MR9 */ + +void +#ifdef __USE_PROTOS +HandleAmbiguity( Junction *block, Junction *alt1, Junction *alt2, int jtype ) +#else +HandleAmbiguity( block, alt1, alt2, jtype ) +Junction *block; +Junction *alt1; +Junction *alt2; +int jtype; +#endif +{ + unsigned **ftbl; + set *fset, b; + int i, numAmbig,n2; + Tree *ambig=NULL, *t, *u; + char *sub = ""; + long n; + int thisOverflow=0; /* MR9 */ + long set_deg_value; /* MR10 */ + long threshhold; /* MR10 */ + + require(block!=NULL, "NULL block"); + require(block->ntype==nJunction, "invalid block"); + + /* These sets are used to constrain LL_k set, but are made CLL_k long anyway */ + fset = (set *) calloc(CLL_k+1, sizeof(set)); + require(fset!=NULL, "cannot allocate fset"); + ftbl = (unsigned **) calloc(CLL_k+1, sizeof(unsigned *)); + require(ftbl!=NULL, "cannot allocate ftbl"); + + /* create constraint table and count number of possible ambiguities (use<=LL_k) */ + for (n=1,i=1; i<=CLL_k; i++) + { + b = set_and(alt1->fset[i], alt2->fset[i]); +/* MR9 */ set_deg_value = set_deg(b); +/* MR10 */ if (n > 0) { +/* MR10 */ threshhold = LONG_MAX / n; +/* MR10 */ if (set_deg_value <= threshhold) { +/* MR10 */ n *= set_deg_value; +/* MR10 */ } else { +/* MR10 */ n=LONG_MAX; +/* MR9 */ if (totalOverflow == 0) { +#if 0 + /* MR10 comment this out because it just makes users worry */ + +/* MR9 */ warnNoFL("Overflow in computing number of possible ambiguities in HandleAmbiguity\n"); +#endif +/* MR9 */ }; +/* MR9 */ thisOverflow++; +/* MR9 */ totalOverflow++; +/* MR9 */ }; +/* MR10 */ } else { +/* MR10 */ n *= set_deg_value; +/* MR9 */ }; + fset[i] = set_dup(b); + ftbl[i] = set_pdq(b); + set_free(b); + } + + switch ( jtype ) + { + case aSubBlk: sub = "of (..) "; break; + case aOptBlk: sub = "of {..} "; break; + case aLoopBegin: sub = "of (..)* "; break; + case aLoopBlk: sub = "of (..)* "; break; + case aPlusBlk: sub = "of (..)+ "; break; + case RuleBlk: sub = "of the rule itself "; break; + default : sub = ""; break; + } + + /* If the block is marked as a compressed lookahead only block, then + * simply return; ambiguity warning is given only at warning level 2. + */ + if ( block->approx>0 ) + { + if ( ParseWithPredicates ) + { + if (alt1->predicate != NULL) predicate_free(alt1->predicate); /* MR12 */ + if (alt2->predicate != NULL) predicate_free(alt2->predicate); /* MR12 */ + + require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); + alt1->predicate = MR_find_predicates_and_supp((Node *)alt1->p1); + require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); + require (MR_predicate_context_completed(alt1->predicate),"predicate alt 1 not completed"); + alt1->predicate=MR_predSimplifyALL(alt1->predicate); + + require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); + alt2->predicate = MR_find_predicates_and_supp((Node *)alt2->p1); + require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); + require (MR_predicate_context_completed(alt2->predicate),"predicate alt 2 not completed"); + alt2->predicate=MR_predSimplifyALL(alt2->predicate); + + MR_doPredicatesHelp(0,alt1,alt2,jtype,sub); + + if ( HoistPredicateContext + && (alt1->predicate!=NULL||alt2->predicate!=NULL) ) + { + verify_context(alt1->predicate); + verify_context(alt2->predicate); + } + + if ( HoistPredicateContext + && (alt1->predicate!=NULL||alt2->predicate!=NULL) + && WarningLevel>1 ) + ensure_predicates_cover_ambiguous_lookahead_sequences(alt1, alt2, sub, ambig); + } + + if ( WarningLevel>1 ) + { + fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line); + if ( jtype == aLoopBegin || jtype == aPlusBlk ) + fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub); + else + fprintf(stderr, " warning(approx): alts %d and %d %sambiguous upon", + alt1->altnum, alt2->altnum, sub); + dumpAmbigMsg(fset, stderr, 0); + MR_traceAmbSource(fset,alt1,alt2); + } + for (i=1; i<=CLL_k; i++) set_free( fset[i] ); + free((char *)fset); + for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] ); + free((char *)ftbl); + return; + } + + /* if all sets have degree 1 for k=1 permutation; + * don't bother doing full LL(k) analysis. + * (This "if" block handles the LL(1) case) + */ + + n2 = 0; + for (i=1; ifset[i])+set_deg(alt2->fset[i]); + + /* here STARTS the special case in which the lookahead sets for alt1 and alt2 + all have degree 1 for kp1)!=NULL ) + { + if ( WarningLevel==1 ) + { + for (i=1; i<=CLL_k; i++) set_free( fset[i] ); + free((char *)fset); + for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] ); + free((char *)ftbl); + return; + } + + fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line); + if ( jtype == aLoopBegin || jtype == aPlusBlk ) + fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub); + else + fprintf(stderr, " warning: alts %d and %d %sambiguous upon", + alt1->altnum, alt2->altnum, sub); + dumpAmbigMsg(fset, stderr, 0); + MR_traceAmbSource(fset,alt1,alt2); + } + + ambig = NULL; + if ( LL_k>1 ) ambig = make_tree_from_sets(alt1->fset, alt2->fset); + if ( ParseWithPredicates ) + { + if (alt1->predicate != NULL) predicate_free(alt1->predicate); /* MR12 */ + if (alt2->predicate != NULL) predicate_free(alt2->predicate); /* MR12 */ + + require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); + alt1->predicate = MR_find_predicates_and_supp((Node *)alt1->p1); + require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); + require (MR_predicate_context_completed(alt1->predicate),"predicate alt 1 not completed"); + alt1->predicate=MR_predSimplifyALL(alt1->predicate); + + require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); + alt2->predicate = MR_find_predicates_and_supp((Node *)alt2->p1); + require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); + require (MR_predicate_context_completed(alt2->predicate),"predicate alt 2 not completed"); + alt2->predicate=MR_predSimplifyALL(alt2->predicate); + + MR_doPredicatesHelp(0,alt1,alt2,jtype,sub); + + if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) ) + { + verify_context(alt1->predicate); + verify_context(alt2->predicate); + } + if (HoistPredicateContext&&(alt1->predicate!=NULL||alt2->predicate!=NULL) && WarningLevel>1) + ensure_predicates_cover_ambiguous_lookahead_sequences(alt1, alt2, sub, ambig); + if ( WarningLevel == 1 && + (alt1->predicate!=NULL||alt2->predicate!=NULL)) + { + for (i=1; i<=CLL_k; i++) set_free( fset[i] ); + free((char *)fset); + for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] ); + free((char *)ftbl); + Tfree(ambig); + return; + } + } +/* end TJP (10/24/93) */ + + fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line); + if ( jtype == aLoopBegin || jtype == aPlusBlk ) + fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub); + else + fprintf(stderr, " warning: alts %d and %d %sambiguous upon", + alt1->altnum, alt2->altnum, sub); + if ( elevel == 3 && LL_k>1 ) + { + preorder(ambig); + fprintf(stderr, "\n"); + for (i=1; i<=CLL_k; i++) set_free( fset[i] ); + free((char *)fset); + for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] ); + free((char *)ftbl); + Tfree(ambig); + return; + }; + + Tfree(ambig); + dumpAmbigMsg(fset, stderr, 0); + + /* because this is a special case in which both alt1 and alt2 have + lookahead sets of degree 1 for kaltnum; + CurAmbigAlt2 = alt2->altnum; + CurAmbigbtype = sub; + CurAmbigfile = alt1->file; + CurAmbigline = alt1->line; + + /* Don't do full LL(n) analysis if (...)? block because the block, + by definition, defies LL(n) analysis. + If guess (...)? block and ambiguous then don't remove anything from + 2nd alt to resolve ambig. + Want to predict with LL sup 1 ( n ) decision not LL(n) if guess block + since it is much cheaper than LL(n). LL sup 1 ( n ) "covers" the LL(n) + lookahead information. + + Note: LL(n) context cannot be computed for semantic predicates when + followed by (..)?. + + If (..)? then we scream "AAAHHHH! No LL(n) analysis will help" + + Is 'ambig' always defined if we enter this if? I hope so + because the 'ensure...()' func references it. TJP Nov 1993. + */ + + /* THM MR30: Instead of using first_item_is_guss_block we use + first_item_is_guess_block_extra which will look inside a + loop block for a guess block. In other words ( (...)? )*. + It there is an ambiguity in this circumstance then we suppress + the normal methods of resolving ambiguities. + */ + + if ( first_item_is_guess_block_extra((Junction *)alt1->p1)!=NULL ) + { + if ( ParseWithPredicates ) + { + if (alt1->predicate != NULL) predicate_free(alt1->predicate); /* MR12 */ + if (alt2->predicate != NULL) predicate_free(alt2->predicate); /* MR12 */ + require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); + alt1->predicate = MR_find_predicates_and_supp((Node *)alt1->p1); + require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); + require (MR_predicate_context_completed(alt1->predicate),"predicate alt 1 not completed"); + alt1->predicate=MR_predSimplifyALL(alt1->predicate); + + require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); + alt2->predicate = MR_find_predicates_and_supp((Node *)alt2->p1); + require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); + require (MR_predicate_context_completed(alt2->predicate),"predicate alt 2 not completed"); + alt2->predicate=MR_predSimplifyALL(alt2->predicate); + + MR_doPredicatesHelp(1,alt1,alt2,jtype,sub); + + if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) ) + { + verify_context(alt1->predicate); + verify_context(alt2->predicate); + } + if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) && WarningLevel>1 ) + ensure_predicates_cover_ambiguous_lookahead_sequences(alt1, alt2, sub, ambig); + if ( WarningLevel==1 && + (alt1->predicate!=NULL||alt2->predicate!=NULL)) + { + for (i=1; i<=CLL_k; i++) set_free( fset[i] ); + free((char *)fset); + for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] ); + free((char *)ftbl); + return; + } + } + + if ( WarningLevel>1 ) + { + fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line); + if ( jtype == aLoopBegin || jtype == aPlusBlk ) + fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub); + else + fprintf(stderr, " warning: alts %d and %d %sambiguous upon", + alt1->altnum, alt2->altnum, sub); + dumpAmbigMsg(fset, stderr, 0); + MR_traceAmbSource(fset,alt1,alt2); + } + + for (i=1; i<=CLL_k; i++) set_free( fset[i] ); + free((char *)fset); + for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] ); + free((char *)ftbl); + return; + } + + /* Not resolved with (..)? block. Do full LL(n) analysis */ + + /* ambig is the set of k-tuples truly in common between alt 1 and alt 2 */ + /* MR11 VerifyAmbig once used fset destructively */ + + ambig = VerifyAmbig(alt1, alt2, ftbl, fset, &t, &u, &numAmbig); + + /* are all things in intersection really ambigs? */ + + if (thisOverflow || numAmbig < n ) /* MR9 */ + { + Tree *v; + + /* remove ambig permutation from 2nd alternative to resolve ambig; + * We want to compute the set of artificial tuples, arising from + * LL sup 1 (n) compression, that collide with real tuples from the + * 2nd alternative. This is the set of "special case" tuples that + * the LL sup 1 (n) decision template maps incorrectly. + */ + + /* when generating code in genExpr() it does + * + * if ( genExprSets(j->fset) && !genExprTree(j->ftree)) {... + * + * Sooooo the j->ftree is the tree of alt2 + * after removal of conflicts, not alt1 ! + */ + + if ( ambig!=NULL ) + { + /* at the top of ambig is an ALT node */ + + for (v=ambig->down; v!=NULL; v=v->right) + { + u = trm_perm(u, v); /* remove v FROM u */ + } +/* fprintf(stderr, "after rm alt2:"); preorder(u); fprintf(stderr, "\n");*/ + } + Tfree( t ); + alt1->ftree = tappend(alt1->ftree, u); + alt1->ftree = tleft_factor(alt1->ftree); + } + + if ( ambig==NULL ) + { + for (i=1; i<=CLL_k; i++) set_free( fset[i] ); + free((char *)fset); + for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] ); + free((char *)ftbl); + return; + } + + ambig = tleft_factor(ambig); + +/* TJP: + * At this point, we surely have an LL(k) ambiguity. Check for predicates + */ + if ( ParseWithPredicates ) + { + if (alt1->predicate != NULL) predicate_free(alt1->predicate); /* MR12 */ + if (alt2->predicate != NULL) predicate_free(alt2->predicate); /* MR12 */ + require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); + alt1->predicate = MR_find_predicates_and_supp((Node *)alt1->p1); + require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); + require (MR_predicate_context_completed(alt1->predicate),"predicate alt 1 not completed"); + alt1->predicate=MR_predSimplifyALL(alt1->predicate); + + require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); + alt2->predicate = MR_find_predicates_and_supp((Node *)alt2->p1); + require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); + require (MR_predicate_context_completed(alt2->predicate),"predicate alt 2 not completed"); + alt2->predicate=MR_predSimplifyALL(alt2->predicate); + + MR_doPredicatesHelp(0,alt1,alt2,jtype,sub); + + if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) ) + { + verify_context(alt1->predicate); + verify_context(alt2->predicate); + } + if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) && WarningLevel>1 ) + ensure_predicates_cover_ambiguous_lookahead_sequences(alt1, alt2, sub, ambig); + if ( WarningLevel==1 && + (alt1->predicate!=NULL||alt2->predicate!=NULL)) + { + + /* We found at least one pred for at least one of the alts; + * If warnings are low, just return. + */ + + Tfree(ambig); + for (i=1; i<=CLL_k; i++) set_free( fset[i] ); + free((char *)fset); + for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] ); + free((char *)ftbl); + return; + } + /* else we're gonna give a warning */ + } +/* end TJP addition */ + + fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line); + if ( jtype == aLoopBegin || jtype == aPlusBlk ) + fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub); + else + fprintf(stderr, " warning: alts %d and %d %sambiguous upon", + alt1->altnum, alt2->altnum, sub); + if ( elevel == 3 ) + { + preorder(ambig->down); /* <===== k>1 ambiguity message data */ + fprintf(stderr, "\n"); + } else { + MR_skipped_e3_report=1; + dumpAmbigMsg(fset, stderr, 0); + }; + + MR_traceAmbSourceK(ambig,alt1,alt2); /* <====== k>1 ambiguity aid */ + + Tfree(ambig); + + for (i=1; i<=CLL_k; i++) set_free( fset[i] ); + free((char *)fset); + for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] ); + free((char *)ftbl); +} + +/* Don't analyze alpha block of (alpha)?beta; if (alpha)? then analyze + * Return the 1st node of the beta block if present else return j. + */ +Junction * +#ifdef __USE_PROTOS +analysis_point( Junction *j ) +#else +analysis_point( j ) +Junction *j; +#endif +{ + Junction *gblock; + + /* MR13b When there was an action/predicate preceding a guess block + the guess block became invisible at the analysis_point. + + first_item_is_guess_block accepts any kind of node, + despite the fact that the formal is a junction. But + I don't want to have to change it all over the place + until I know it works. + */ + + if ( j->ntype != nJunction && j->ntype != nAction) return j; + + gblock = first_item_is_guess_block((Junction *)j); + + if ( gblock!=NULL ) + { + Junction *past = gblock->end; + Junction *p; + require(past!=NULL, "analysis_point: no end block on (...)? block"); + + for (p=(Junction *)past->p1; p!=NULL; ) + { + if ( p->ntype==nAction ) + { + p=(Junction *)((ActionNode *)p)->next; + continue; + } + if ( p->ntype!=nJunction ) + { + past->alpha_beta_guess_end=1; /* MR14 */ + return (Junction *)past->p1; + } + if ( p->jtype==EndBlk || p->jtype==EndRule ) + { + return j; + } +/* MR6 */ +/* MR6 A guess block is of the form "(alpha)? beta" or "(alpha)?". */ +/* MR6 When beta is omitted (second form) this means "(alpha)? alpha". */ +/* MR6 The program does not store another copy of alpha in this case. */ +/* MR6 During analysis when the program needs to know what follows the */ +/* MR6 guess clause. It calls this routine. */ +/* MR6 */ +/* MR6 If it is of the form "(alpha)? beta" it returns a pointer to beta.*/ +/* MR6 */ +/* MR6 If it is of the form "(alpha)?" it returns a pointer to the guess */ +/* MR6 block itself thereby reusing the junction tree. */ +/* MR6 */ +/* MR6 It works by searching the "next in sequence" chain (skipping actions) */ +/* MR6 searching for a RuleRef or Token node. (Those are the only 4 kinds */ +/* MR6 of nodes: Junctions, RuleRef, Token, and Action.) */ +/* MR6 */ +/* MR6 This won't work for the special case "(alpha)? ()" because it has no */ +/* MR6 rule references or token nodes. It eventually encounters a */ +/* MR6 junction of type EndBlk or EndRule and says to its caller: nothing */ +/* MR6 more here to analyze - must be of the form "(alpha)?". */ +/* MR6 */ +/* MR6 In the case of "(alpha)? ()" it should return a pointer to "()" */ +/* MR6 */ +/* MR6 I think. */ +/* MR6 */ + if ( p->jtype!=Generic) { /* MR6 */ + past->alpha_beta_guess_end=1; /* MR14 */ + return (Junction *)past->p1; /* MR6 */ + }; /* MR6 */ + p=(Junction *)p->p1; + } + } + return j; +} + +set +#ifdef __USE_PROTOS +First( Junction *j, int k, int jtype, int *max_k ) +#else +First( j, k, jtype, max_k ) +Junction *j; +int k; +int jtype; +int *max_k; +#endif +{ + Junction *alt1, *alt2; + set a, rk, fCurBlk; + int savek; + int p1, p2; + + int save_maintainBackTrace; + + require(j->ntype==nJunction, "First: non junction passed"); + + /* C o m p u t e F I R S T s e t w i t h k l o o k a h e a d */ + fCurBlk = rk = empty; + for (alt1=j; alt1!=NULL; alt1 = (Junction *)alt1->p2 ) + { + Junction * p = NULL; + Junction * p1junction = NULL; + p = analysis_point((Junction *)alt1->p1); + p1junction = (Junction *) (alt1->p1); +#if 0 + if (p != p1junction) { + fprintf(stdout,"Analysis point for #%d is #%d", p1junction->seq, p->seq); /* debug */ + } +#endif + REACH(p, k, &rk, alt1->fset[k]); + require(set_nil(rk), "rk != nil"); + set_free(rk); + set_orin(&fCurBlk, alt1->fset[k]); + } + + /* D e t e c t A m b i g u i t i e s */ + *max_k = 1; + for (p1=1,alt1=j; alt1!=NULL; alt1 = (Junction *)alt1->p2, p1++) + { + for (p2=1,alt2=(Junction *)alt1->p2; alt2!=NULL; alt2 = (Junction *)alt2->p2, p2++) + { + savek = k; + a = set_and(alt1->fset[k], alt2->fset[k]); + while ( !set_nil(a) ) + { + /* if we have hit the max k requested, just give warning */ + if ( j->approx==k ) { + } + + if ( k==CLL_k ) + { +#ifdef NOT_USED +*** int save_LL_k = LL_k; +*** int save_CLL_k = CLL_k; +*** /* Get new LL_k from interactive feature if enabled */ +*** if ( AImode ) +*** AmbiguityDialog(j, jtype, alt1, alt2, &CLL_k, &LL_k); +#endif + *max_k = CLL_k; + save_maintainBackTrace=MR_MaintainBackTrace; + if (AlphaBetaTrace) MR_MaintainBackTrace=0; + HandleAmbiguity(j, alt1, alt2, jtype); + MR_MaintainBackTrace=save_maintainBackTrace; + break; + } + else + { + Junction *p = analysis_point((Junction *)alt1->p1); + Junction *q = analysis_point((Junction *)alt2->p1); + k++; /* attempt ambig alts again with more lookahead */ + + REACH(p, k, &rk, alt1->fset[k]); + require(set_nil(rk), "rk != nil"); + REACH(q, k, &rk, alt2->fset[k]); + require(set_nil(rk), "rk != nil"); + set_free(a); + a = set_and(alt1->fset[k], alt2->fset[k]); + if ( k > *max_k ) *max_k = k; + } + } + set_free(a); + k = savek; + } + } + + return fCurBlk; +} diff --git a/Tools/CodeTools/Source/Pccts/antlr/fset2.c b/Tools/CodeTools/Source/Pccts/antlr/fset2.c new file mode 100644 index 0000000000..7f686a53d5 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/fset2.c @@ -0,0 +1,2250 @@ +/* + * fset2.c + * + * Compute FIRST sets for full LL(k) + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2001 + */ + +#include +#include "pcctscfg.h" +#include + +#ifdef PCCTS_USE_STDARG +#include +#else +#include +#endif + +#include "set.h" +#include "syn.h" +#include "hash.h" +#include "generic.h" +#include "dlgdef.h" + +/* ick! globals. Used by permute() to track which elements of a set have been used */ + +static int *findex; +set *fset; /* MR11 make global */ +static unsigned **ftbl; +static set *constrain; /* pts into fset. constrains tToken() to 'constrain' */ +int ConstrainSearch; +int maxk; /* set to initial k upon tree construction request */ + /* MR11 make global */ +static Tree *FreeList = NULL; + +#ifdef __USE_PROTOS +static int tmember_of_context(Tree *, Predicate *); +#else +static int tmember_of_context(); +#endif + +#if TREE_DEBUG +set set_of_tnodes_in_use; +int stop_on_tnode_seq_number=(-1); /* (-1) to disable */ +#endif + +/* Do root + * Then each sibling + */ + +void +#ifdef __USE_PROTOS +preorder( Tree *tree ) +#else +preorder( tree ) +Tree *tree; +#endif +{ + if ( tree == NULL ) return; + if ( tree->down != NULL ) fprintf(stderr, " ("); + if ( tree->token == ALT ) fprintf(stderr, " ALT"); + else fprintf(stderr, " %s", TerminalString(tree->token)); + if ( tree->token==EpToken ) fprintf(stderr, "(%d)", tree->v.rk); + preorder(tree->down); + if ( tree->down != NULL ) fprintf(stderr, " )"); + preorder(tree->right); +} + +#ifdef __USE_PROTOS +int MR_tree_matches_constraints(int k,set * constrain,Tree *t) +#else +int MR_tree_matches_constraints(k,constrain,t) + int k; + set * constrain; + Tree * t; +#endif +{ + int i; + Tree *u; + + if (k == 0) return 1; + + /* for testing guard predicates: if the guard tree is shorter + than the constraint then it is a match. The reason is that + a guard of (A B) should be equivalent to a guard of (A B . . .) + where "." matches every token. Thus a match which runs out + of tree before constraint is a match. + */ + + if (t == NULL) return 1; + require (set_deg(constrain[0]) == 1, + "MR_tree_matches_constraints: set_deg != 1"); + i=set_int(constrain[0]); + if (t->token != i) return 0; + if (k-1 == 0) return 1; + for (u=t->down; u != NULL; u=u->right) { + if (MR_tree_matches_constraints(k-1,&constrain[1],u)) { + return 1; + }; + }; + return 0; +} + +/* check the depth of each primary sibling to see that it is exactly + * k deep. e.g.; + * + * ALT + * | + * A ------- B + * | | + * C -- D E + * + * Remove all branches <= k deep. + * + * Added by TJP 9-23-92 to make the LL(k) constraint mechanism to work. + */ + +static int pruneCount=0; +static int prunePeak=200; + +Tree * +#ifdef __USE_PROTOS +prune( Tree *t, int k ) +#else +prune( t, k ) +Tree *t; +int k; +#endif +{ + pruneCount++; + if (pruneCount > prunePeak+100) { + prunePeak=pruneCount; +#if 0 +*** fprintf(stderr,"pruneCount=%d\n",pruneCount); +/*** preorder(t); ***/ +*** fprintf(stderr,"\n",pruneCount); +#endif + }; + if ( t == NULL ) { + pruneCount--; + return NULL; + }; + if ( t->token == ALT ) fatal_internal("prune: ALT node in FIRST tree"); + if ( t->right!=NULL ) t->right = prune(t->right, k); + if ( k>1 ) + { + if ( t->down!=NULL ) t->down = prune(t->down, k-1); + if ( t->down == NULL ) + { + Tree *r = t->right; + t->right = NULL; + Tfree(t); + pruneCount--; + return r; + } + } + pruneCount--; + return t; +} + +/* build a tree (root child1 child2 ... NULL) */ +#ifdef PCCTS_USE_STDARG +Tree *tmake(Tree *root, ...) +#else +Tree *tmake(va_alist) +va_dcl +#endif +{ + Tree *w; + va_list ap; + Tree *child, *sibling=NULL, *tail=NULL; +#ifndef PCCTS_USE_STDARG + Tree *root; +#endif + +#ifdef PCCTS_USE_STDARG + va_start(ap, root); +#else + va_start(ap); + root = va_arg(ap, Tree *); +#endif + child = va_arg(ap, Tree *); + while ( child != NULL ) + { +#ifdef DUM + /* added "find end of child" thing TJP March 1994 */ + for (w=child; w->right!=NULL; w=w->right) {;} /* find end of child */ +#else + w = child; +#endif + + if ( sibling == NULL ) {sibling = child; tail = w;} + else {tail->right = child; tail = w;} + child = va_arg(ap, Tree *); + } + + /* was "root->down = sibling;" */ + if ( root==NULL ) root = sibling; + else root->down = sibling; + + va_end(ap); + return root; +} + +Tree * +#ifdef __USE_PROTOS +tnode( int tok ) +#else +tnode( tok ) +int tok; +#endif +{ + Tree *p, *newblk; + static int n=0; + + if ( FreeList == NULL ) + { + /*fprintf(stderr, "tnode: %d more nodes\n", TreeBlockAllocSize);*/ + if ( TreeResourceLimit > 0 ) + { + if ( (n+TreeBlockAllocSize) >= TreeResourceLimit ) + { + fprintf(stderr, ErrHdr, FileStr[CurAmbigfile], CurAmbigline); + fprintf(stderr, " hit analysis resource limit while analyzing alts %d and %d %s\n", + CurAmbigAlt1, + CurAmbigAlt2, + CurAmbigbtype); + exit(PCCTS_EXIT_FAILURE); + } + } + newblk = (Tree *)calloc(TreeBlockAllocSize, sizeof(Tree)); + if ( newblk == NULL ) + { + fprintf(stderr, ErrHdr, FileStr[CurAmbigfile], CurAmbigline); + fprintf(stderr, " out of memory while analyzing alts %d and %d %s\n", + CurAmbigAlt1, + CurAmbigAlt2, + CurAmbigbtype); + exit(PCCTS_EXIT_FAILURE); + } + n += TreeBlockAllocSize; + for (p=newblk; p<&(newblk[TreeBlockAllocSize]); p++) + { + p->right = FreeList; /* add all new Tree nodes to Free List */ + FreeList = p; + } + } + p = FreeList; + FreeList = FreeList->right; /* remove a tree node */ + p->right = NULL; /* zero out ptrs */ + p->down = NULL; + p->token = tok; + + TnodesAllocated++; /* MR10 */ + TnodesInUse++; /* MR10 */ + if (TnodesInUse > TnodesPeak) TnodesPeak=TnodesInUse; /* MR10 */ + +#ifdef TREE_DEBUG + require(!p->in_use, "tnode: node in use!"); + p->in_use = 1; + p->seq=TnodesAllocated; + set_orel( (unsigned) TnodesAllocated,&set_of_tnodes_in_use); + if (stop_on_tnode_seq_number == p->seq) { + fprintf(stderr,"\n*** just allocated tnode #%d ***\n", + stop_on_tnode_seq_number); + }; +#endif + return p; +} + +static Tree * +#ifdef __USE_PROTOS +eofnode( int k ) +#else +eofnode( k ) +int k; +#endif +{ + Tree *t=NULL; + int i; + + for (i=1; i<=k; i++) + { + t = tmake(tnode((TokenInd!=NULL?TokenInd[EofToken]:EofToken)), t, NULL); + } + return t; +} + + + +void +#ifdef __USE_PROTOS +_Tfree( Tree *t ) +#else +_Tfree( t ) +Tree *t; +#endif +{ + if ( t!=NULL ) + { +#ifdef TREE_DEBUG + if (t->seq == stop_on_tnode_seq_number) { + fprintf(stderr,"\n*** just freed tnode #%d ***\n",t->seq); + }; + require(t->in_use, "_Tfree: node not in use!"); + t->in_use = 0; + set_rm( (unsigned) t->seq,set_of_tnodes_in_use); +#endif + t->right = FreeList; + FreeList = t; + TnodesInUse--; /* MR10 */ + } +} + +/* tree duplicate */ +Tree * +#ifdef __USE_PROTOS +tdup( Tree *t ) +#else +tdup( t ) +Tree *t; +#endif +{ + Tree *u; + + if ( t == NULL ) return NULL; + u = tnode(t->token); + u->v.rk = t->v.rk; + u->right = tdup(t->right); + u->down = tdup(t->down); + return u; +} + +/* tree duplicate (assume tree is a chain downwards) */ +Tree * +#ifdef __USE_PROTOS +tdup_chain( Tree *t ) +#else +tdup_chain( t ) +Tree *t; +#endif +{ + Tree *u; + + if ( t == NULL ) return NULL; + u = tnode(t->token); + u->v.rk = t->v.rk; + u->down = tdup(t->down); + return u; +} + +Tree * +#ifdef __USE_PROTOS +tappend( Tree *t, Tree *u ) +#else +tappend( t, u ) +Tree *t; +Tree *u; +#endif +{ + Tree *w; + +/*** fprintf(stderr, "tappend("); + *** preorder(t); fprintf(stderr, ","); + *** preorder(u); fprintf(stderr, " )\n"); +*/ + if ( t == NULL ) return u; + if ( t->token == ALT && t->right == NULL ) return tappend(t->down, u); + for (w=t; w->right!=NULL; w=w->right) {;} + w->right = u; + return t; +} + +/* dealloc all nodes in a tree */ +void +#ifdef __USE_PROTOS +Tfree( Tree *t ) +#else +Tfree( t ) +Tree *t; +#endif +{ + if ( t == NULL ) return; + Tfree( t->down ); + Tfree( t->right ); + _Tfree( t ); +} + +/* find all children (alts) of t that require remaining_k nodes to be LL_k + * tokens long. + * + * t-->o + * | + * a1--a2--...--an <-- LL(1) tokens + * | | | + * b1 b2 ... bn <-- LL(2) tokens + * | | | + * . . . + * . . . + * z1 z2 ... zn <-- LL(LL_k) tokens + * + * We look for all [Ep] needing remaining_k nodes and replace with u. + * u is not destroyed or actually used by the tree (a copy is made). + */ +Tree * +#ifdef __USE_PROTOS +tlink( Tree *t, Tree *u, int remaining_k ) +#else +tlink( t, u, remaining_k ) +Tree *t; +Tree *u; +int remaining_k; +#endif +{ + Tree *p; + require(remaining_k!=0, "tlink: bad tree"); + + if ( t==NULL ) return NULL; + /*fprintf(stderr, "tlink: u is:"); preorder(u); fprintf(stderr, "\n");*/ + if ( t->token == EpToken && t->v.rk == remaining_k ) + { + require(t->down==NULL, "tlink: invalid tree"); + if ( u == NULL ) { +/* MR10 */ Tree *tt=t->right; +/* MR10 */ _Tfree(t); +/* MR10 */ return tt; + }; + p = tdup( u ); + p->right = t->right; + _Tfree( t ); + return p; + } + t->down = tlink(t->down, u, remaining_k); + t->right = tlink(t->right, u, remaining_k); + return t; +} + +/* remove as many ALT nodes as possible while still maintaining semantics */ +Tree * +#ifdef __USE_PROTOS +tshrink( Tree *t ) +#else +tshrink( t ) +Tree *t; +#endif +{ + if ( t == NULL ) return NULL; + t->down = tshrink( t->down ); + t->right = tshrink( t->right ); + if ( t->down == NULL ) + { + if ( t->token == ALT ) + { + Tree *u = t->right; + _Tfree(t); + return u; /* remove useless alts */ + } + return t; + } + + /* (? (ALT (? ...)) s) ==> (? (? ...) s) where s = sibling, ? = match any */ + if ( t->token == ALT && t->down->right == NULL) + { + Tree *u = t->down; + u->right = t->right; + _Tfree( t ); + return u; + } + /* (? (A (ALT t)) s) ==> (? (A t) s) where A is a token; s,t siblings */ + if ( t->token != ALT && t->down->token == ALT && t->down->right == NULL ) + { + Tree *u = t->down->down; + _Tfree( t->down ); + t->down = u; + return t; + } + return t; +} + +Tree * +#ifdef __USE_PROTOS +tflatten( Tree *t ) +#else +tflatten( t ) +Tree *t; +#endif +{ + if ( t == NULL ) return NULL; + t->down = tflatten( t->down ); + t->right = tflatten( t->right ); + if ( t->down == NULL ) return t; + + if ( t->token == ALT ) + { + Tree *u; + /* find tail of children */ + for (u=t->down; u->right!=NULL; u=u->right) {;} + u->right = t->right; + u = t->down; + _Tfree( t ); + return u; + } + return t; +} + +Tree * +#ifdef __USE_PROTOS +tJunc( Junction *p, int k, set *rk ) +#else +tJunc( p, k, rk ) +Junction *p; +int k; +set *rk; +#endif +{ + Tree *t=NULL, *u=NULL; + Junction *alt; + Tree *tail=NULL, *r; + +#ifdef DBG_TRAV + fprintf(stderr, "tJunc(%d): %s in rule %s\n", k, + decodeJType[p->jtype], ((Junction *)p)->rname); +#endif + +/* MR14 */ if (AlphaBetaTrace && p->alpha_beta_guess_end) { +/* MR14 */ warnFL( +/* MR14 */ "not possible to compute follow set for alpha in an \"(alpha)? beta\" block. ", +/* MR14 */ FileStr[p->file],p->line); +/* MR14 */ MR_alphaBetaTraceReport(); +/* MR14 */ }; + +/* MR14 */ if (p->alpha_beta_guess_end) { +/* MR14 */ return NULL; +/* MR14 */ } + + if ( p->jtype==aLoopBlk || p->jtype==RuleBlk || + p->jtype==aPlusBlk || p->jtype==aSubBlk || p->jtype==aOptBlk ) + { + if ( p->jtype!=aSubBlk && p->jtype!=aOptBlk ) { + require(p->lock!=NULL, "rJunc: lock array is NULL"); + if ( p->lock[k] ) return NULL; + p->lock[k] = TRUE; + } + +/* MR10 */ if (MR_MaintainBackTrace) { +/* MR10 */ if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p); +/* MR10 */ }; + + TRAV(p->p1, k, rk, tail); + +/* MR10 */ if (MR_MaintainBackTrace) { +/* MR10 */ if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack); +/* MR10 */ }; + + if ( p->jtype==RuleBlk ) {p->lock[k] = FALSE; return tail;} + r = tmake(tnode(ALT), tail, NULL); + for (alt=(Junction *)p->p2; alt!=NULL; alt = (Junction *)alt->p2) + { + /* if this is one of the added optional alts for (...)+ then break */ + if ( alt->ignore ) break; + + if ( tail==NULL ) {TRAV(alt->p1, k, rk, tail); r->down = tail;} + else + { +/* MR10 */ if (MR_MaintainBackTrace) { +/* MR10 */ if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p); +/* MR10 */ }; + + TRAV(alt->p1, k, rk, tail->right); + +/* MR10 */ if (MR_MaintainBackTrace) { +/* MR10 */ if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack); +/* MR10 */ }; + if ( tail->right != NULL ) tail = tail->right; + } + } + if ( p->jtype!=aSubBlk && p->jtype!=aOptBlk ) p->lock[k] = FALSE; +#ifdef DBG_TREES + fprintf(stderr, "blk(%s) returns:",((Junction *)p)->rname); preorder(r); fprintf(stderr, "\n"); +#endif + if ( r->down == NULL ) {_Tfree(r); return NULL;} + return r; + } + + if ( p->jtype==EndRule ) + { + if ( p->halt ) /* don't want FOLLOW here? */ + { +/**** if ( ContextGuardTRAV ) return NULL; ****/ + set_orel( (unsigned) k, rk); /* indicate this k value needed */ /* MR10 cast */ + t = tnode(EpToken); + t->v.rk = k; + return t; + } + require(p->lock!=NULL, "rJunc: lock array is NULL"); + if ( p->lock[k] ) return NULL; + /* if no FOLLOW assume k EOF's */ + if ( p->p1 == NULL ) return eofnode(k); + p->lock[k] = TRUE; + } + +/* MR14 */ if (p->p1 != NULL && p->guess && p->guess_analysis_point == NULL) { +/* MR14 */ Node * guess_point; +/* MR14 */ guess_point=(Node *)analysis_point(p); +/* MR14 */ if (guess_point == (Node *)p) { +/* MR14 */ guess_point=p->p1; +/* MR14 */ } +/* MR14 */ p->guess_analysis_point=guess_point; +/* MR14 */ } + + if ( p->p2 == NULL ) + { + +/* MR10 */ if (MR_MaintainBackTrace) { +/* MR10 */ if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p); +/* MR10 */ }; + +/* M14 */ if (p->guess_analysis_point != NULL) { +/* M14 */ TRAV(p->guess_analysis_point, k, rk,t); +/* M14 */ } else { + TRAV(p->p1, k, rk,t); +/* M14 */ } + +/* MR10 */ if (MR_MaintainBackTrace) { +/* MR10 */ if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack); +/* MR10 */ }; + + if ( p->jtype==EndRule ) p->lock[k]=FALSE; + return t; + } + +/* MR10 */ if (MR_MaintainBackTrace) { +/* MR10 */ if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p); +/* MR10 */ }; + +/* M14 */ if (p->guess_analysis_point != NULL) { +/* M14 */ TRAV(p->guess_analysis_point, k, rk,t); +/* M14 */ } else { + TRAV(p->p1, k, rk,t); +/* M14 */ } + +/* MR10 */ if (MR_MaintainBackTrace) { +/* MR10 */ if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack); +/* MR10 */ }; + + if ( p->jtype!=RuleBlk && /* MR14 */ !p->guess) TRAV(p->p2, k, rk, u); + + if ( p->jtype==EndRule ) p->lock[k] = FALSE;/* unlock node */ + + if ( t==NULL ) return tmake(tnode(ALT), u, NULL); + return tmake(tnode(ALT), t, u, NULL); +} + +Tree * +#ifdef __USE_PROTOS +tRuleRef( RuleRefNode *p, int k, set *rk_out ) +#else +tRuleRef( p, k, rk_out ) +RuleRefNode *p; +int k; +set *rk_out; +#endif +{ + int k2; + Tree *t=NULL, *u=NULL; + Junction *r; + set rk, rk2; + int save_halt; + RuleEntry *q = (RuleEntry *) hash_get(Rname, p->text); + +#ifdef DBG_TRAV + fprintf(stderr, "tRuleRef: %s\n", p->text); +#endif + if ( q == NULL ) + { + TRAV(p->next, k, rk_out, t);/* ignore undefined rules */ + return t; + } + rk = rk2 = empty; + if (RulePtr == NULL) fatal("RulePtr==NULL"); + r = RulePtr[q->rulenum]; + if ( r->lock[k] ) return NULL; + save_halt = r->end->halt; + r->end->halt = TRUE; /* don't let reach fall off end of rule here */ + +/* MR10 */ if (MR_MaintainBackTrace) { +/* MR10 */ MR_pointerStackPush(&MR_BackTraceStack,p); +/* MR10 */ }; + + TRAV(r, k, &rk, t); + +/* MR10 */ if (MR_MaintainBackTrace) { +/* MR10 */ MR_pointerStackPop(&MR_BackTraceStack); +/* MR10 */ }; + + r->end->halt = save_halt; +#ifdef DBG_TREES + fprintf(stderr, "after ruleref, t is:"); preorder(t); fprintf(stderr, "\n"); +#endif + t = tshrink( t ); + while ( !set_nil(rk) ) { /* any k left to do? if so, link onto tree */ + k2 = set_int(rk); + set_rm(k2, rk); + +/* MR10 */ if (MR_MaintainBackTrace) { +/* MR10 */ MR_pointerStackPush(&MR_BackTraceStack,p); +/* MR10 */ }; + + TRAV(p->next, k2, &rk2, u); + +/* MR10 */ if (MR_MaintainBackTrace) { +/* MR10 */ MR_pointerStackPop(&MR_BackTraceStack); +/* MR10 */ }; + + t = tlink(t, u, k2); /* any alts missing k2 toks, add u onto end */ + Tfree(u); /* MR10 */ + } + set_free(rk); /* rk is empty, but free it's memory */ + set_orin(rk_out, rk2); /* remember what we couldn't do */ + set_free(rk2); + return t; +} + +Tree * +#ifdef __USE_PROTOS +tToken( TokNode *p, int k, set *rk ) +#else +tToken( p, k, rk ) +TokNode *p; +int k; +set *rk; +#endif +{ + Tree *t=NULL, *tset=NULL, *u; + + if (ConstrainSearch) { + if (MR_AmbSourceSearch) { + require(constrain>=fset&&constrain<=&(fset[CLL_k]),"tToken: constrain is not a valid set"); + } else { + require(constrain>=fset&&constrain<=&(fset[LL_k]),"tToken: constrain is not a valid set"); + }; + constrain = &fset[maxk-k+1]; + } + +#ifdef DBG_TRAV + fprintf(stderr, "tToken(%d): %s\n", k, TerminalString(p->token)); + if ( ConstrainSearch ) { + fprintf(stderr, "constrain is:"); s_fprT(stderr, *constrain); fprintf(stderr, "\n"); + } +#endif + + /* is it a meta token (set of tokens)? */ + + if ( !set_nil(p->tset) ) + { + unsigned e=0; + set a; + Tree *n, *tail = NULL; + + if ( ConstrainSearch ) { + a = set_and(p->tset, *constrain); + if (set_nil(a)) { /* MR10 */ + set_free(a); /* MR11 */ + return NULL; /* MR10 */ + }; /* MR10 */ + } else { + a = set_dup(p->tset); + }; + + for (; !set_nil(a); set_rm(e, a)) + { + e = set_int(a); + n = tnode(e); + if ( tset==NULL ) { tset = n; tail = n; } + else { tail->right = n; tail = n; } + } + set_free( a ); + } + else if ( ConstrainSearch && !set_el(p->token, *constrain) ) + { +/* fprintf(stderr, "ignoring token %s(%d)\n", TerminalString(p->token), + k);*/ + return NULL; + } + else { + tset = tnode( p->token ); + }; + +/* MR10 */ if (MR_MaintainBackTrace) { +/* MR10 */ if (k == 1) { +/* MR10 */ MR_pointerStackPush(&MR_BackTraceStack,p); +/* MR13 */ if (MR_SuppressSearch) { +/* MR13 */ MR_suppressSearchReport(); +/* MR13 */ } else { +/* MR10 */ MR_backTraceReport(); +/* MR13 */ }; +/* MR10 */ MR_pointerStackPop(&MR_BackTraceStack); +/* MR11 */ Tfree(tset); +/* MR11 */ return NULL; +/* MR10 */ }; +/* MR10 */ }; + + if ( k == 1 ) return tset; + + if (MR_MaintainBackTrace) { + MR_pointerStackPush(&MR_BackTraceStack,p); + }; + + TRAV(p->next, k-1, rk, t); + + if (MR_MaintainBackTrace) { + Tfree(t); + Tfree(tset); + MR_pointerStackPop(&MR_BackTraceStack); + return NULL; + }; + + /* here, we are positive that, at least, this tree will not contribute + * to the LL(2) tree since it will be too shallow, IF t==NULL. + * If doing a context guard walk, then don't prune. + */ + if ( t == NULL && !ContextGuardTRAV ) /* tree will be too shallow */ + { + if ( tset!=NULL ) Tfree( tset ); + return NULL; + } +#ifdef DBG_TREES + fprintf(stderr, "tToken(%d)->next:",k); preorder(t); fprintf(stderr, "\n"); +#endif + + /* if single token root, then just make new tree and return */ + /* MR10 - set_nil(p->tset) isn't a good test because of ConstraintSearch */ + + if (tset->right == NULL) return tmake(tset, t, NULL); /* MR10 */ + + /* here we must make a copy of t as a child of each element of the tset; + * e.g., "T1..T3 A" would yield ( nil ( T1 A ) ( T2 A ) ( T3 A ) ) + */ + for (u=tset; u!=NULL; u=u->right) + { + /* make a copy of t and hook it onto bottom of u */ + u->down = tdup(t); + } + Tfree( t ); +#ifdef DBG_TREES + fprintf(stderr, "range is:"); preorder(tset); fprintf(stderr, "\n"); +#endif + return tset; +} + +Tree * +#ifdef __USE_PROTOS +tAction( ActionNode *p, int k, set *rk ) +#else +tAction( p, k, rk ) +ActionNode *p; +int k; +set *rk; +#endif +{ + Tree *t=NULL; + set *save_fset=NULL; + int i; + + /* fprintf(stderr, "tAction\n"); */ + +/* An MR_SuppressSearch is looking for things that can be + reached even when the predicate is false. + + There are three kinds of predicates: + plain: r1: <

>? r2 + guarded: r1: (A)? => <

>? r2 + ampersand style: r1: (A)? && <

>? r2 + + Of the three kinds of predicates, only a guard predicate + has things which are reachable even when the predicate + is false. To be reachable the constraint must *not* + match the guard. + +*/ + + if (p->is_predicate && MR_SuppressSearch) { + + Predicate *pred=p->guardpred; + + if (pred == NULL) { + t=NULL; + goto EXIT; + }; + constrain = &fset[maxk-k+1]; + if (pred->k == 1) { + set dif; + dif=set_dif(*constrain,pred->scontext[1]); + if (set_nil(dif)) { + set_free(dif); + t=NULL; + goto EXIT; + }; + set_free(dif); + } else { + if (MR_tree_matches_constraints(k,constrain,pred->tcontext)) { + t=NULL; + goto EXIT; + }; + } + }; + + /* The ampersand predicate differs from the + other predicates because its first set + is a subset of the first set behind the predicate + + r1: (A)? && <

>? r2 ; + r2: A | B; + + In this case first[1] of r1 is A, even + though first[1] of r2 is {A B}. + */ + + if (p->is_predicate && p->ampersandPred != NULL) { + + Predicate *pred=p->ampersandPred; + Tree *tAND; + Tree *tset; + + if (k <= pred->k) { + if (MR_MaintainBackTrace) MR_pointerStackPush(&MR_BackTraceStack,p); + TRAV(p->guardNodes,k,rk,t); + if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); + return t; + } else { + require (k>1,"tAction for ampersandpred: k <= 1"); + if (ConstrainSearch) { + if (MR_AmbSourceSearch) { + require(constrain>=fset&&constrain<=&(fset[CLL_k]), + "tToken: constrain is not a valid set"); + } else { + require(constrain>=fset&&constrain<=&(fset[LL_k]), + "tToken: constrain is not a valid set"); + }; + save_fset=(set *) calloc (CLL_k+1,sizeof(set)); + require (save_fset != NULL,"tAction save_fset alloc"); + for (i=1; i <= CLL_k ; i++) { + save_fset[i]=set_dup(fset[i]); + }; + if (pred->k == 1) { + constrain = &fset[maxk-k+1]; + set_andin(constrain,pred->scontext[1]); + if (set_nil(*constrain)) { + t=NULL; + goto EXIT; + }; + } else { + constrain = &fset[maxk-k+1]; + if (! MR_tree_matches_constraints(pred->k,constrain,pred->tcontext)) { + t=NULL; + goto EXIT; + }; /* end loop on i */ + }; /* end loop on pred scontext/tcontext */ + }; /* end if on k > pred->k */ + }; /* end if on constrain search */ + + TRAV(p->next,k,rk,t); + + if (t != NULL) { + t=tshrink(t); + t=tflatten(t); + t=tleft_factor(t); + if (pred->tcontext != NULL) { + tAND=MR_computeTreeAND(t,pred->tcontext); + } else { + tset=MR_make_tree_from_set(pred->scontext[1]); + tAND=MR_computeTreeAND(t,tset); + Tfree(tset); + }; + Tfree(t); + t=tAND; + }; + goto EXIT; + + }; /* end if on ampersand predicate */ + + TRAV(p->next,k,rk,t); + +EXIT: + if (save_fset != NULL) { + for (i=1 ; i <= CLL_k ; i++) { + set_free(fset[i]); + fset[i]=save_fset[i]; + }; + free ( (char *) save_fset); + }; + return t; +} + +/* see if e exists in s as a possible input permutation (e is always a chain) */ + +int +#ifdef __USE_PROTOS +tmember( Tree *e, Tree *s ) +#else +tmember( e, s ) +Tree *e; +Tree *s; +#endif +{ + if ( e==NULL||s==NULL ) return 0; +/** fprintf(stderr, "tmember("); +*** preorder(e); fprintf(stderr, ","); +*** preorder(s); fprintf(stderr, " )\n"); +*/ + if ( s->token == ALT && s->right == NULL ) return tmember(e, s->down); + if ( e->token!=s->token ) + { + if ( s->right==NULL ) return 0; + return tmember(e, s->right); + } + if ( e->down==NULL && s->down == NULL ) return 1; + if ( tmember(e->down, s->down) ) return 1; + if ( s->right==NULL ) return 0; + return tmember(e, s->right); +} + +/* see if e exists in s as a possible input permutation (e is always a chain); + * Only check s to the depth of e. In other words, 'e' can be a shorter + * sequence than s. + */ +int +#ifdef __USE_PROTOS +tmember_constrained( Tree *e, Tree *s) +#else +tmember_constrained( e, s ) +Tree *e; +Tree *s; +#endif +{ + if ( e==NULL||s==NULL ) return 0; +/** fprintf(stderr, "tmember_constrained("); +*** preorder(e); fprintf(stderr, ","); +*** preorder(s); fprintf(stderr, " )\n"); +**/ + if ( s->token == ALT && s->right == NULL ) + return tmember_constrained(e, s->down); + if ( e->token!=s->token ) + { + if ( s->right==NULL ) return 0; + return tmember_constrained(e, s->right); + } + if ( e->down == NULL ) return 1; /* if s is matched to depth of e return */ + if ( tmember_constrained(e->down, s->down) ) return 1; + if ( s->right==NULL ) return 0; + return tmember_constrained(e, s->right); +} + +/* combine (? (A t) ... (A u) ...) into (? (A t u)) */ +Tree * +#ifdef __USE_PROTOS +tleft_factor( Tree *t ) +#else +tleft_factor( t ) +Tree *t; +#endif +{ + Tree *u, *v, *trail, *w; + + /* left-factor what is at this level */ + if ( t == NULL ) return NULL; + for (u=t; u!=NULL; u=u->right) + { + trail = u; + v=u->right; + while ( v!=NULL ) + { + if ( u->token == v->token ) + { + if ( u->down!=NULL ) + { + for (w=u->down; w->right!=NULL; w=w->right) {;} + w->right = v->down; /* link children together */ + } + else u->down = v->down; + trail->right = v->right; /* unlink factored node */ + _Tfree( v ); + v = trail->right; + } + else {trail = v; v=v->right;} + } + } + /* left-factor what is below */ + for (u=t; u!=NULL; u=u->right) u->down = tleft_factor( u->down ); + return t; +} + +/* remove the permutation p from t if present */ +Tree * +#ifdef __USE_PROTOS +trm_perm( Tree *t, Tree *p ) +#else +trm_perm( t, p ) +Tree *t; +Tree *p; +#endif +{ + /* + fprintf(stderr, "trm_perm("); + preorder(t); fprintf(stderr, ","); + preorder(p); fprintf(stderr, " )\n"); + */ + if ( t == NULL || p == NULL ) return NULL; + if ( t->token == ALT ) + { + t->down = trm_perm(t->down, p); + if ( t->down == NULL ) /* nothing left below, rm cur node */ + { + Tree *u = t->right; + _Tfree( t ); + return trm_perm(u, p); + } + t->right = trm_perm(t->right, p); /* look for more instances of p */ + return t; + } + if ( p->token != t->token ) /* not found, try a sibling */ + { + t->right = trm_perm(t->right, p); + return t; + } + t->down = trm_perm(t->down, p->down); + if ( t->down == NULL ) /* nothing left below, rm cur node */ + { + Tree *u = t->right; + _Tfree( t ); + return trm_perm(u, p); + } + t->right = trm_perm(t->right, p); /* look for more instances of p */ + return t; +} + +/* add the permutation 'perm' to the LL_k sets in 'fset' */ +void +#ifdef __USE_PROTOS +tcvt( set *fset, Tree *perm ) +#else +tcvt( fset, perm ) +set *fset; +Tree *perm; +#endif +{ + if ( perm==NULL ) return; + set_orel(perm->token, fset); + tcvt(fset+1, perm->down); +} + +/* for each element of ftbl[k], make it the root of a tree with permute(ftbl[k+1]) + * as a child. + */ +Tree * +#ifdef __USE_PROTOS +permute( int k, int max_k ) +#else +permute( k, max_k ) +int k, max_k; +#endif +{ + Tree *t, *u; + + if ( k>max_k ) return NULL; + if ( ftbl[k][findex[k]] == nil ) return NULL; + t = permute(k+1, max_k); + if ( t==NULL&&k maxk will have to change. + */ +Tree * +#ifdef __USE_PROTOS +VerifyAmbig( Junction *alt1, Junction *alt2, unsigned **ft, set *fs, Tree **t, Tree **u, int *numAmbig ) +#else +VerifyAmbig( alt1, alt2, ft, fs, t, u, numAmbig ) +Junction *alt1; +Junction *alt2; +unsigned **ft; +set *fs; +Tree **t; +Tree **u; +int *numAmbig; +#endif +{ + set rk; + Tree *perm, *ambig=NULL; + Junction *p; + int k; + int tnodes_at_start=TnodesAllocated; + int tnodes_at_end; + int tnodes_used; + set *save_fs; + int j; + + save_fs=(set *) calloc(CLL_k+1,sizeof(set)); + require(save_fs != NULL,"save_fs calloc"); + + for (j=0; j <= CLL_k ; j++) save_fs[j]=set_dup(fs[j]); + + maxk = LL_k; /* NOTE: for now, we look for LL_k */ + ftbl = ft; + fset = fs; + constrain = &(fset[1]); + findex = (int *) calloc(LL_k+1, sizeof(int)); + if ( findex == NULL ) + { + fprintf(stderr, ErrHdr, FileStr[CurAmbigfile], CurAmbigline); + fprintf(stderr, " out of memory while analyzing alts %d and %d of %s\n", + CurAmbigAlt1, + CurAmbigAlt2, + CurAmbigbtype); + exit(PCCTS_EXIT_FAILURE); + } + for (k=1; k<=LL_k; k++) findex[k] = 0; + + rk = empty; + ConstrainSearch = 1; /* consider only tokens in ambig sets */ + + p = analysis_point((Junction *)alt1->p1); + TRAV(p, LL_k, &rk, *t); + *t = tshrink( *t ); + *t = tflatten( *t ); + *t = tleft_factor( *t ); /* MR10 */ + *t = prune(*t, LL_k); + *t = tleft_factor( *t ); + +/*** fprintf(stderr, "after shrink&flatten&prune&left_factor:"); preorder(*t); fprintf(stderr, "\n");*/ + if ( *t == NULL ) + { +/*** fprintf(stderr, "TreeIncomplete --> no LL(%d) ambiguity\n", LL_k);*/ + Tfree( *t ); /* kill if impossible to have ambig */ + *t = NULL; + } + + p = analysis_point((Junction *)alt2->p1); + + TRAV(p, LL_k, &rk, *u); + *u = tshrink( *u ); + *u = tflatten( *u ); + *t = tleft_factor( *t ); /* MR10 */ + *u = prune(*u, LL_k); + *u = tleft_factor( *u ); +/* fprintf(stderr, "after shrink&flatten&prune&lfactor:"); preorder(*u); fprintf(stderr, "\n");*/ + if ( *u == NULL ) + { +/* fprintf(stderr, "TreeIncomplete --> no LL(%d) ambiguity\n", LL_k);*/ + Tfree( *u ); + *u = NULL; + } + + for (k=1; k<=LL_k; k++) set_clr( fs[k] ); + + ambig = tnode(ALT); + k = 0; + if ( *t!=NULL && *u!=NULL ) + { + while ( (perm=permute(1,LL_k))!=NULL ) + { +/* fprintf(stderr, "chk perm:"); preorder(perm); fprintf(stderr, "\n");*/ + if ( tmember(perm, *t) && tmember(perm, *u) ) + { +/* fprintf(stderr, "ambig upon"); preorder(perm); fprintf(stderr, "\n");*/ + + k++; + perm->right = ambig->down; + ambig->down = perm; + tcvt(&(fs[1]), perm); + } + else Tfree( perm ); + } + } + + for (j=0; j <= CLL_k ; j++) fs[j]=save_fs[j]; + free( (char *) save_fs); + + tnodes_at_end=TnodesAllocated; + tnodes_used=tnodes_at_end - tnodes_at_start; + + if (TnodesReportThreshold > 0 && tnodes_used > TnodesReportThreshold) { + fprintf(stdout,"There were %d tuples whose ambiguity could not be resolved by full lookahead\n",k); + fprintf(stdout,"There were %d tnodes created to resolve ambiguity between:\n\n",tnodes_used); + fprintf(stdout," Choice 1: %s line %d file %s\n", + MR_ruleNamePlusOffset( (Node *) alt1),alt1->line,FileStr[alt1->file]); + fprintf(stdout," Choice 2: %s line %d file %s\n", + MR_ruleNamePlusOffset( (Node *) alt2),alt2->line,FileStr[alt2->file]); + for (j=1; j <= CLL_k ; j++) { + fprintf(stdout,"\n Intersection of lookahead[%d] sets:\n",j); + MR_dumpTokenSet(stdout,2,fs[j]); + }; + fprintf(stdout,"\n"); + }; + + *numAmbig = k; + if ( ambig->down == NULL ) {_Tfree(ambig); ambig = NULL;} + free( (char *)findex ); +/* fprintf(stderr, "final ambig:"); preorder(ambig); fprintf(stderr, "\n");*/ + return ambig; +} + +static Tree * +#ifdef __USE_PROTOS +bottom_of_chain( Tree *t ) +#else +bottom_of_chain( t ) +Tree *t; +#endif +{ + if ( t==NULL ) return NULL; + for (; t->down != NULL; t=t->down) {;} + return t; +} + +/* + * Make a tree from k sets where the degree of the first k-1 sets is 1. + */ +Tree * +#ifdef __USE_PROTOS +make_tree_from_sets( set *fset1, set *fset2 ) +#else +make_tree_from_sets( fset1, fset2 ) +set *fset1; +set *fset2; +#endif +{ + set inter; + int i; + Tree *t=NULL, *n, *u; + unsigned *p,*q; + require(LL_k>1, "make_tree_from_sets: LL_k must be > 1"); + + /* do the degree 1 sets first */ + for (i=1; i<=LL_k-1; i++) + { + inter = set_and(fset1[i], fset2[i]); + require(set_deg(inter)==1, "invalid set to tree conversion"); + n = tnode(set_int(inter)); + if (t==NULL) t=n; else tmake(t, n, NULL); + set_free(inter); + } + + /* now add the chain of tokens at depth k */ + u = bottom_of_chain(t); + inter = set_and(fset1[LL_k], fset2[LL_k]); + if ( (q=p=set_pdq(inter)) == NULL ) fatal_internal("Can't alloc space for set_pdq"); + /* first one is linked to bottom, then others are sibling linked */ + n = tnode(*p++); + u->down = n; + u = u->down; + while ( *p != nil ) + { + n = tnode(*p); + u->right = n; + u = u->right; + p++; + } + free((char *)q); + + return t; +} + +/* create and return the tree of lookahead k-sequences that are in t, but not + * in the context of predicates in predicate list p. + */ +Tree * +#ifdef __USE_PROTOS +tdif( Tree *ambig_tuples, Predicate *p, set *fset1, set *fset2 ) +#else +tdif( ambig_tuples, p, fset1, fset2 ) +Tree *ambig_tuples; +Predicate *p; +set *fset1; +set *fset2; +#endif +{ + unsigned **ft; + Tree *dif=NULL; + Tree *perm; + set b; + int i,k; + + if ( p == NULL ) return tdup(ambig_tuples); + + ft = (unsigned **) calloc(CLL_k+1, sizeof(unsigned *)); + require(ft!=NULL, "cannot allocate ft"); + for (i=1; i<=CLL_k; i++) + { + b = set_and(fset1[i], fset2[i]); + ft[i] = set_pdq(b); + set_free(b); + } + findex = (int *) calloc(LL_k+1, sizeof(int)); + if ( findex == NULL ) + { + fatal_internal("out of memory in tdif while checking predicates"); + } + for (k=1; k<=LL_k; k++) findex[k] = 0; + +#ifdef DBG_TRAV + fprintf(stderr, "tdif_%d[", p->k); + preorder(ambig_tuples); + fprintf(stderr, ","); + preorder(p->tcontext); + fprintf(stderr, "] ="); +#endif + + ftbl = ft; + while ( (perm=permute(1,p->k))!=NULL ) + { +#ifdef DBG_TRAV + fprintf(stderr, "test perm:"); preorder(perm); fprintf(stderr, "\n"); +#endif + if ( tmember_constrained(perm, ambig_tuples) && + !tmember_of_context(perm, p) ) + { +#ifdef DBG_TRAV + fprintf(stderr, "satisfied upon"); preorder(perm); fprintf(stderr, "\n"); +#endif + k++; + if ( dif==NULL ) dif = perm; + else + { + perm->right = dif; + dif = perm; + } + } + else Tfree( perm ); + } + +#ifdef DBG_TRAV + preorder(dif); + fprintf(stderr, "\n"); +#endif + + for (i=1; i<=CLL_k; i++) free( (char *)ft[i] ); + free((char *)ft); + free((char *)findex); + + return dif; +} + +/* is lookahead sequence t a member of any context tree for any + * predicate in p? + */ +static int +#ifdef __USE_PROTOS +tmember_of_context( Tree *t, Predicate *p ) +#else +tmember_of_context( t, p ) +Tree *t; +Predicate *p; +#endif +{ + for (; p!=NULL; p=p->right) + { + if ( p->expr==PRED_AND_LIST || p->expr==PRED_OR_LIST ) + return tmember_of_context(t, p->down); + if ( tmember_constrained(t, p->tcontext) ) return 1; + if ( tmember_of_context(t, p->down) ) return 1; + } + return 0; +} + +int +#ifdef __USE_PROTOS +is_single_tuple( Tree *t ) +#else +is_single_tuple( t ) +Tree *t; +#endif +{ + if ( t == NULL ) return 0; + if ( t->right != NULL ) return 0; + if ( t->down == NULL ) return 1; + return is_single_tuple(t->down); +} + + +/* MR10 Check that a context guard contains only allowed things */ +/* MR10 (mainly token references). */ + +#ifdef __USE_PROTOS +int contextGuardOK(Node *p,int h,int *hmax) +#else +int contextGuardOK(p,h,hmax) + Node *p; + int h; + int *hmax; +#endif +{ + Junction *j; + TokNode *tn; + + if (p == NULL) return 1; + if (p->ntype == nToken) { + h++; + if (h > *hmax) *hmax=h; + tn=(TokNode *)p; + if (tn->el_label != NULL) { + warnFL(eMsg1("a label (\"%s\") for a context guard element is meaningless",tn->el_label), + FileStr[p->file],p->line); + }; + return contextGuardOK( ( (TokNode *) p)->next,h,hmax); + } else if (p->ntype == nAction) { + goto Fail; + } else if (p->ntype == nRuleRef) { + goto Fail; + } else { + require (p->ntype == nJunction,"Unexpected ntype"); + j=(Junction *) p; + if (j->jtype != Generic && + j->jtype != aSubBlk && /* pretty sure this one is allowed */ +/**** j->jtype != aOptBlk && ****/ /* pretty sure this one is allowed */ /* MR11 not any more ! */ + j->jtype != EndBlk) { + errFL("A context guard may not contain an option block: {...} or looping block: (...)* or (...)+", + FileStr[p->file],p->line); + contextGuardOK(j->p1,h,hmax); + return 0; + }; + /* do both p1 and p2 so use | rather than || */ + return contextGuardOK(j->p2,h,hmax) | contextGuardOK(j->p1,h,hmax); + }; +Fail: + errFL("A context guard may contain only Token references - guard will be ignored", + FileStr[p->file],p->line); + contextGuardOK( ( (ActionNode *) p)->next,h,hmax); + return 0; +} + +/* + * Look at a (...)? generalized-predicate context-guard and compute + * either a lookahead set (k==1) or a lookahead tree for k>1. The + * k level is determined by the guard itself rather than the LL_k + * variable. For example, ( A B )? is an LL(2) guard and ( ID )? + * is an LL(1) guard. For the moment, you can only have a single + * tuple in the guard. Physically, the block must look like this + * --o-->TOKEN-->o-->o-->TOKEN-->o-- ... -->o-->TOKEN-->o-- + * An error is printed for any other type. + */ +Predicate * +#ifdef __USE_PROTOS +computePredFromContextGuard(Graph blk,int *msgDone) /* MR10 */ +#else +computePredFromContextGuard(blk,msgDone) /* MR10 */ + Graph blk; + int *msgDone; /* MR10 */ +#endif +{ + Junction *junc = (Junction *)blk.left, *p; + Tree *t=NULL; + Predicate *pred = NULL; + set scontext, rk; + int ok; + int hmax=0; + + require(junc!=NULL && junc->ntype == nJunction, "bad context guard"); + +/* MR10 Check for anything other than Tokens and generic junctions */ + + *msgDone=0; /* MR10 */ + ok=contextGuardOK( (Node *)junc,0,&hmax); /* MR10 */ + if (! ok) { /* MR10 */ + *msgDone=1; /* MR10 */ + return NULL; /* MR10 */ + }; /* MR10 */ + if (hmax == 0) { +errFL("guard is 0 tokens long",FileStr[junc->file],junc->line); /* MR11 */ + *msgDone=1; + return NULL; + }; + if (hmax > CLL_k) { /* MR10 */ +errFL(eMsgd2("guard is %d tokens long - lookahead is limited to max(k,ck)==%d", /* MR10 */ + hmax,CLL_k), /* MR10 */ + FileStr[junc->file],junc->line); /* MR10 */ + *msgDone=1; /* MR10 */ + return NULL; /* MR10 */ + }; /* MR10 */ + + rk = empty; + p = junc; + pred = new_pred(); + pred->k = hmax; /* MR10 should be CLL_k, not LLK ? */ + if (hmax > 1 ) /* MR10 was LL_k */ + { + ConstrainSearch = 0; + ContextGuardTRAV = 1; + TRAV(p, hmax, &rk, t); /* MR10 was LL_k */ + ContextGuardTRAV = 0; + set_free(rk); + t = tshrink( t ); + t = tflatten( t ); + t = tleft_factor( t ); +/* + fprintf(stderr, "ctx guard:"); + preorder(t); + fprintf(stderr, "\n"); +*/ + pred->tcontext = t; + } + else + { + REACH(p, 1, &rk, scontext); + require(set_nil(rk), "rk != nil"); + set_free(rk); +/* + fprintf(stderr, "LL(1) ctx guard is:"); + s_fprT(stderr, scontext); + fprintf(stderr, "\n"); +*/ + pred->scontext[1] = scontext; + } + + list_add(&ContextGuardPredicateList,pred); /* MR13 */ + + return pred; +} + +/* MR13 + When the context guard is originally computed the + meta-tokens are not known. +*/ + +#ifdef __USE_PROTOS +void recomputeContextGuard(Predicate *pred) +#else +void recomputeContextGuard(pred) + Predicate *pred; +#endif +{ + Tree * t=NULL; + set scontext; + set rk; + ActionNode * actionNode; + Junction * p; + + actionNode=pred->source; + require (actionNode != NULL,"context predicate's source == NULL"); + + p=actionNode->guardNodes; + require (p != NULL,"context predicate's guardNodes == NULL"); + + rk = empty; + if (pred->k > 1 ) + { + ConstrainSearch = 0; + ContextGuardTRAV = 1; + TRAV(p, pred->k, &rk, t); + ContextGuardTRAV = 0; + set_free(rk); + t = tshrink( t ); + t = tflatten( t ); + t = tleft_factor( t ); + Tfree(pred->tcontext); + pred->tcontext = t; + } + else + { + REACH(p, 1, &rk, scontext); + require(set_nil(rk), "rk != nil"); + set_free(rk); + set_free(pred->scontext[1]); + pred->scontext[1] = scontext; + } +} + +/* MR11 - had enough of flags yet ? */ + +int MR_AmbSourceSearch=0; +int MR_AmbSourceSearchGroup=0; +int MR_AmbSourceSearchChoice=0; +int MR_AmbSourceSearchLimit=0; +int MR_matched_AmbAidRule=0; + +static set *matchSets[2]={NULL,NULL}; +static int *tokensInChain=NULL; +static Junction *MR_AmbSourceSearchJ[2]; + +void MR_traceAmbSourceKclient() +{ + int i; + set *save_fset; + int save_ConstrainSearch; + set incomplete; + Tree *t; + + if (matchSets[0] == NULL) { + matchSets[0]=(set *) calloc (CLL_k+1,sizeof(set)); + require (matchSets[0] != NULL,"matchSets[0] alloc"); + matchSets[1]=(set *) calloc (CLL_k+1,sizeof(set)); + require (matchSets[1] != NULL,"matchSets[1] alloc"); + }; + + for (i=1 ; i <= MR_AmbSourceSearchLimit ; i++) { + set_clr(matchSets[0][i]); + set_orel( (unsigned) tokensInChain[i], + &matchSets[0][i]); + set_clr(matchSets[1][i]); + set_orel( (unsigned) tokensInChain[i], + &matchSets[1][i]); + }; + + save_fset=fset; + save_ConstrainSearch=ConstrainSearch; + + + + for (i=0 ; i < 2 ; i++) { + +#if 0 +** fprintf(stdout," Choice:%d Depth:%d ",i+1,MR_AmbSourceSearchLimit); +** fprintf(stdout,"("); +** for (j=1 ; j <= MR_AmbSourceSearchLimit ; j++) { +** if (j != 1) fprintf(stdout," "); +** fprintf(stdout,"%s",TerminalString(tokensInChain[j])); +** }; +** fprintf(stdout,")\n\n"); +#endif + + fset=matchSets[i]; + + MR_AmbSourceSearch=1; + MR_MaintainBackTrace=1; + MR_AmbSourceSearchChoice=i; + ConstrainSearch=1; + + maxk = MR_AmbSourceSearchLimit; + + incomplete=empty; + t=NULL; + + constrain = &(fset[1]); + MR_pointerStackReset(&MR_BackTraceStack); + + TRAV(MR_AmbSourceSearchJ[i],maxk,&incomplete,t); + + Tfree(t); + + require (set_nil(incomplete),"MR_traceAmbSourceK TRAV incomplete"); + require (MR_BackTraceStack.count == 0,"K: MR_BackTraceStack.count != 0"); + + set_free(incomplete); + }; + + ConstrainSearch=save_ConstrainSearch; + fset=save_fset; + MR_AmbSourceSearch=0; + MR_MaintainBackTrace=0; + MR_AmbSourceSearchChoice=0; +} + +#ifdef __USE_PROTOS +Tree *tTrunc(Tree *t,int depth) +#else +Tree *tTrunc(t,depth) + Tree *t; +#endif +{ + Tree *u; + + require ( ! (t == NULL && depth > 0),"tree too short"); + + if (depth == 0) return NULL; + + if (t->token == ALT) { + u=tTrunc(t->down,depth); + } else { + u=tnode(t->token); + u->down=tTrunc(t->down,depth-1); + }; + if (t->right != NULL) u->right=tTrunc(t->right,depth); + return u; +} + +#ifdef __USE_PROTOS +void MR_iterateOverTree(Tree *t,int chain[]) +#else +void MR_iterateOverTree(t,chain) + Tree *t; + int chain[]; +#endif +{ + if (t == NULL) return; + chain[0]=t->token; + if (t->down != NULL) { + MR_iterateOverTree(t->down,&chain[1]); + } else { + MR_traceAmbSourceKclient(); + }; + MR_iterateOverTree(t->right,&chain[0]); + chain[0]=0; +} + +#ifdef __USE_PROTOS +void MR_traceAmbSourceK(Tree *t,Junction *alt1,Junction *alt2) +#else +void MR_traceAmbSourceK(t,alt1,alt2) + Tree *t; + Junction *alt1; + Junction *alt2; +#endif +{ + int i; + int depth; + int maxDepth; + Tree *truncatedTree; + + if (MR_AmbAidRule == NULL) return; + + if ( ! ( + strcmp(MR_AmbAidRule,alt1->rname) == 0 || + strcmp(MR_AmbAidRule,alt2->rname) == 0 || + MR_AmbAidLine==alt1->line || + MR_AmbAidLine==alt2->line + ) + ) return; + + MR_matched_AmbAidRule++; + + /* there are no token sets in trees, only in TokNodes */ + + MR_AmbSourceSearchJ[0]=analysis_point( (Junction *) alt1->p1); + MR_AmbSourceSearchJ[1]=analysis_point( (Junction *) alt2->p1); + + if (tokensInChain == NULL) { + tokensInChain=(int *) calloc (CLL_k+1,sizeof(int)); + require (tokensInChain != NULL,"tokensInChain alloc"); + }; + + MR_AmbSourceSearchGroup=0; + + fprintf(stdout,"\n"); + fprintf(stdout," Ambiguity Aid "); + fprintf(stdout, + (MR_AmbAidDepth <= LL_k ? + "(-k %d -aa %s %s -aad %d)\n\n" : + "(-k %d -aa %s %s [-k value limits -aad %d])\n\n"), + LL_k, + MR_AmbAidRule, + (MR_AmbAidMultiple ? "-aam" : ""), + MR_AmbAidDepth); + + for (i=0 ; i < 2 ; i++) { + fprintf(stdout," Choice %d: %-25s line %d file %s\n", + (i+1), + MR_ruleNamePlusOffset( (Node *) MR_AmbSourceSearchJ[i]), + MR_AmbSourceSearchJ[i]->line, + FileStr[MR_AmbSourceSearchJ[i]->file]); + }; + + fprintf(stdout,"\n"); + + if (MR_AmbAidDepth < LL_k) { + maxDepth=MR_AmbAidDepth; + } else { + maxDepth=LL_k; + }; + + for (depth=1 ; depth <= maxDepth; depth++) { + MR_AmbSourceSearchLimit=depth; + if (depth < LL_k) { + truncatedTree=tTrunc(t,depth); + truncatedTree=tleft_factor(truncatedTree); + MR_iterateOverTree(truncatedTree,&tokensInChain[1]); /* <===== */ + Tfree(truncatedTree); + } else { + MR_iterateOverTree(t,tokensInChain); /* <===== */ + }; + fflush(stdout); + fflush(stderr); + }; + + fprintf(stdout,"\n"); + MR_AmbSourceSearch=0; + MR_MaintainBackTrace=0; + MR_AmbSourceSearchGroup=0; + MR_AmbSourceSearchChoice=0; + MR_AmbSourceSearchLimit=0; + +} + + +/* this if for k=1 grammars only + + this is approximate only because of the limitations of linear + approximation lookahead. Don't want to do a k=3 search when + the user only specified a ck=3 grammar +*/ + +#ifdef __USE_PROTOS +void MR_traceAmbSource(set *matchSets,Junction *alt1, Junction *alt2) +#else +void MR_traceAmbSource(matchSets,alt1,alt2) + set *matchSets; + Junction *alt1; + Junction *alt2; +#endif +{ + set *save_fset; + Junction *p[2]; + int i; + int j; + set *dup_matchSets; + set intersection; + set incomplete; + set tokensUsed; + int depth; + + if (MR_AmbAidRule == NULL) return; + if ( ! ( + strcmp(MR_AmbAidRule,alt1->rname) == 0 || + strcmp(MR_AmbAidRule,alt2->rname) == 0 || + MR_AmbAidLine==alt1->line || + MR_AmbAidLine==alt2->line + ) + ) return; + + MR_matched_AmbAidRule++; + + save_fset=fset; + + dup_matchSets=(set *) calloc(CLL_k+1,sizeof(set)); + require (dup_matchSets != NULL,"Can't allocate dup_matchSets"); + + p[0]=analysis_point( (Junction *) alt1->p1); + p[1]=analysis_point( (Junction *) alt2->p1); + + fprintf(stdout,"\n"); + + fprintf(stdout," Ambiguity Aid "); + fprintf(stdout, + (MR_AmbAidDepth <= CLL_k ? + "(-ck %d -aa %s %s -aad %d)\n\n" : + "(-ck %d -aa %s %s [-ck value limits -aad %d])\n\n"), + CLL_k, + MR_AmbAidRule, + (MR_AmbAidMultiple ? "-aam" : ""), + MR_AmbAidDepth); + + for (i=0 ; i < 2 ; i++) { + fprintf(stdout," Choice %d: %-25s line %d file %s\n", + (i+1), + MR_ruleNamePlusOffset( (Node *) p[i]), + p[i]->line,FileStr[p[i]->file]); + }; + + for (j=1; j <= CLL_k ; j++) { + fprintf(stdout,"\n Intersection of lookahead[%d] sets:\n",j); + intersection=set_and(alt1->fset[j],alt2->fset[j]); + MR_dumpTokenSet(stdout,2,intersection); + set_free(intersection); + }; + + fprintf(stdout,"\n"); + + require (1 <= MR_AmbAidDepth && MR_AmbAidDepth <= CLL_k, + "illegal MR_AmbAidDepth"); + + MR_AmbSourceSearchGroup=0; + for (depth=1; depth <= MR_AmbAidDepth; depth++) { + MR_AmbSourceSearchLimit=depth; + for (i=0 ; i < 2 ; i++) { + +/*** fprintf(stdout," Choice:%d Depth:%d\n\n",i+1,depth); ***/ + + for (j=0 ; j <= CLL_k ; j++) { dup_matchSets[j]=set_dup(matchSets[j]); }; + fset=dup_matchSets; + + fflush(output); + fflush(stdout); + + MR_AmbSourceSearch=1; + MR_MaintainBackTrace=1; + MR_AmbSourceSearchChoice=i; + + maxk = depth; + tokensUsed=empty; + incomplete=empty; + + constrain = &(fset[1]); + MR_pointerStackReset(&MR_BackTraceStack); + + REACH(p[i],depth,&incomplete,tokensUsed); + + fflush(output); + fflush(stdout); + + require (set_nil(incomplete),"MR_traceAmbSource REACH incomplete"); + require (MR_BackTraceStack.count == 0,"1: MR_BackTraceStack.count != 0"); + + set_free(incomplete); + set_free(tokensUsed); + + for (j=0 ; j <= CLL_k ; j++) { set_free(dup_matchSets[j]); }; + }; + }; + + fprintf(stdout,"\n"); + + MR_AmbSourceSearch=0; + MR_MaintainBackTrace=0; + MR_AmbSourceSearchGroup=0; + MR_AmbSourceSearchChoice=0; + MR_AmbSourceSearchLimit=0; + + fset=save_fset; + free ( (char *) dup_matchSets); +} + +static int itemCount; + +void MR_backTraceDumpItemReset() { + itemCount=0; +} + +#ifdef __USE_PROTOS +void MR_backTraceDumpItem(FILE *f,int skip,Node *n) +#else +void MR_backTraceDumpItem(f,skip,n) + FILE *f; + int skip; + Node *n; +#endif +{ + TokNode *tn; + RuleRefNode *rrn; + Junction *j; + ActionNode *a; + + switch (n->ntype) { + case nToken: + itemCount++; if (skip) goto EXIT; + tn=(TokNode *)n; + if (set_nil(tn->tset)) { + fprintf(f," %2d #token %-23s",itemCount,TerminalString(tn->token)); + } else { + fprintf(f," %2d #tokclass %-20s",itemCount,TerminalString(tn->token)); + }; + break; + case nRuleRef: + itemCount++; if (skip) goto EXIT; + rrn=(RuleRefNode *)n; + fprintf(f," %2d to %-27s",itemCount,rrn->text); + break; + case nAction: + a=(ActionNode *)n; + goto EXIT; + case nJunction: + + j=(Junction *)n; + + switch (j->jtype) { + case aSubBlk: + if (j->guess) { + itemCount++; if (skip) goto EXIT; + fprintf(f," %2d %-30s",itemCount,"in (...)? block at"); + break; + }; +/****** fprintf(f," %2d %-32s",itemCount,"in (...) block at"); *******/ +/****** break; *******/ + goto EXIT; + case aOptBlk: + itemCount++; if (skip) goto EXIT; + fprintf(f," %2d %-30s",itemCount,"in {...} block"); + break; + case aLoopBlk: + itemCount++; if (skip) goto EXIT; + fprintf(f," %2d %-30s",itemCount,"in (...)* block"); + break; + case EndBlk: + if (j->alpha_beta_guess_end) { + itemCount++; if (skip) goto EXIT; + fprintf(f," %2d %-30s",itemCount,"end (...)? block at"); + break; + }; + goto EXIT; +/****** fprintf(f," %2d %-32s",itemCount,"end of a block at"); *****/ +/****** break; *****/ + case RuleBlk: + itemCount++; if (skip) goto EXIT; + fprintf(f," %2d %-30s",itemCount,j->rname); + break; + case Generic: + goto EXIT; + case EndRule: + itemCount++; if (skip) goto EXIT; + fprintf (f," %2d end %-26s",itemCount,j->rname); + break; + case aPlusBlk: + itemCount++; if (skip) goto EXIT; + fprintf(f," %2d %-30s",itemCount,"in (...)+ block"); + break; + case aLoopBegin: + goto EXIT; + }; + break; + }; + fprintf(f," %-23s line %-4d %s\n",MR_ruleNamePlusOffset(n),n->line,FileStr[n->file]); +EXIT: + return; +} + + +static PointerStack previousBackTrace={0,0,NULL}; + +#ifdef __USE_PROTOS +void MR_backTraceReport(void) +#else +void MR_backTraceReport() +#endif +{ + int i; + int match = 0; + int limitMatch; + + Node *p; + TokNode *tn; + set remainder; + int depth; + + /* Even when doing a k=2 search this routine can get + called when there is only 1 token on the stack. + This is because something like rRuleRef can change + the search value of k from 2 to 1 temporarily. + It does this because the it wants to know the k=1 + first set before it does a k=2 search + */ + + depth=0; + for (i=0; i < MR_BackTraceStack.count ; i++) { + p=(Node *) MR_BackTraceStack.data[i]; + if (p->ntype == nToken) depth++; + }; + +/* MR14 */ if (MR_AmbSourceSearch) { +/* MR14 */ require (depth <= MR_AmbSourceSearchLimit,"depth > MR_AmbSourceSearchLimit"); +/* MR14 */ } + + /* MR23 THM - Traceback report was being called at the wrong time for -alpha reports */ + /* Reported by Arpad Beszedes (beszedes@inf.u-szeged.hu) */ + + if (MR_AmbSourceSearchLimit == 0 || depth < MR_AmbSourceSearchLimit) { + return; + }; + + MR_backTraceDumpItemReset(); + + limitMatch=MR_BackTraceStack.count; + if (limitMatch > previousBackTrace.count) { + limitMatch=previousBackTrace.count; + }; + + for (match=0; match < limitMatch; match++) { + if (MR_BackTraceStack.data[match] != + previousBackTrace.data[match]) { + break; + }; + }; + + /* not sure at the moment why there would be duplicates */ + + if (match != MR_BackTraceStack.count) { + + fprintf(stdout," Choice:%d Depth:%d Group:%d", + (MR_AmbSourceSearchChoice+1), + MR_AmbSourceSearchLimit, + ++MR_AmbSourceSearchGroup); + + depth=0; + fprintf(stdout," ("); + for (i=0; i < MR_BackTraceStack.count ; i++) { + p=(Node *) MR_BackTraceStack.data[i]; + if (p->ntype != nToken) continue; + tn=(TokNode *)p; + if (depth != 0) fprintf(stdout," "); + fprintf(stdout,TerminalString(tn->token)); + depth++; + if (! MR_AmbAidMultiple) { + if (set_nil(tn->tset)) { + set_rm( (unsigned) tn->token,fset[depth]); + } else { + remainder=set_dif(fset[depth],tn->tset); + set_free(fset[depth]); + fset[depth]=remainder; + }; + }; + }; + fprintf(stdout,")\n"); + + for (i=0; i < MR_BackTraceStack.count ; i++) { + MR_backTraceDumpItem(stdout, (i +#include +#include +#include "pcctscfg.h" +#include "set.h" +#include "syn.h" +#include "hash.h" +#include "generic.h" +#include "dlgdef.h" + +#define NumExprPerLine 4 +static int on1line=0; +static set tokensRefdInBlock; + + /* T r a n s l a t i o n T a b l e s */ + +/* C_Trans[node type] == pointer to function that knows how to translate that node. */ +#ifdef __cplusplus +void (*C_Trans[NumNodeTypes+1])(...) = { + NULL, + NULL, /* See next table. +Junctions have many types */ + (void (*)(...)) genRuleRef, + (void (*)(...)) genToken, + (void (*)(...)) genAction + }; +#else +void (*C_Trans[NumNodeTypes+1])() = { + NULL, + NULL, /* See next table. +Junctions have many types */ + genRuleRef, + genToken, + genAction + }; +#endif + +/* C_JTrans[Junction type] == pointer to function that knows how to translate that + * kind of junction node. + */ +#ifdef __cplusplus +void (*C_JTrans[NumJuncTypes+1])(...) = { + NULL, + (void (*)(...)) genSubBlk, + (void (*)(...)) genOptBlk, + (void (*)(...)) genLoopBlk, + (void (*)(...)) genEndBlk, + (void (*)(...)) genRule, + (void (*)(...)) genJunction, + (void (*)(...)) genEndRule, + (void (*)(...)) genPlusBlk, + (void (*)(...)) genLoopBegin + }; +#else +void (*C_JTrans[NumJuncTypes+1])() = { + NULL, + genSubBlk, + genOptBlk, + genLoopBlk, + genEndBlk, + genRule, + genJunction, + genEndRule, + genPlusBlk, + genLoopBegin + }; +#endif + +#define PastWhiteSpace(s) while (*(s) == ' ' || *(s) == '\t') {s++;} + +static int tabs = 0; + +/* MR6 Got tired of text running off page when using standard tab stops */ + +#define TAB { int i; \ + if (TabWidth==0) { \ + for (i=0; irname);} + else gen1("zzTRACEOUT((ANTLRChar *)\"%s\");\n", q->rname); + } +} + +static void +#ifdef __USE_PROTOS +warn_about_using_gk_option(void) +#else +warn_about_using_gk_option() +#endif +{ + static int warned_already=0; + + if ( !DemandLookahead || warned_already ) return; + warned_already = 1; + warnNoFL("-gk option could cause trouble for <<...>>? predicates"); +} + +void +#ifdef __USE_PROTOS +freeBlkFsets( Junction *q ) +#else +freeBlkFsets( q ) +Junction *q; +#endif +{ + int i; + Junction *alt; + require(q!=NULL, "freeBlkFsets: invalid node"); + + for (alt=q; alt != NULL; alt= (Junction *) alt->p2 ) + { + for (i=1; i<=CLL_k; i++) set_free(alt->fset[i]); + } +} + +/* + * Generate a local variable allocation for each token references + * in this block. + */ +static void +#ifdef __USE_PROTOS +genTokenPointers( Junction *q ) +#else +genTokenPointers( q ) +Junction *q; +#endif +{ + /* Rule refs are counted and can be referenced, but their + * value is not set to anything useful ever. + * + * The ptrs are to be named _tij where i is the current level + * and j is the element number within an alternative. + */ + int first=1, t=0; + set a; + tokensRefdInBlock = q->tokrefs; + + if ( set_deg(q->tokrefs) == 0 ) return; + a = set_dup(q->tokrefs); + gen("ANTLRTokenPtr "); + for (; !set_nil(a); set_rm(t, a)) + { + t = set_int(a); + if ( first ) first = 0; + else _gen(","); + if ( !DontCopyTokens ) _gen2("_tv%d%d,", BlkLevel, t); + _gen2("_t%d%d", BlkLevel, t); + if ( !DontCopyTokens ) {_gen2("= &_tv%d%d", BlkLevel, t);} + else _gen("=NULL"); + } + _gen(";\n"); + set_free(a); +} + +static int +#ifdef __USE_PROTOS +hasDefaultException(ExceptionGroup *eg) +#else +hasDefaultException(eg) +ExceptionGroup *eg; +#endif +{ + ListNode *q; + + for (q = eg->handlers->next; q!=NULL; q=q->next) + { + ExceptionHandler *eh = (ExceptionHandler *)q->elem; + if ( strcmp("default", eh->signalname)==0 ) { + return 1; + } + } + return 0; +} +static void +#ifdef __USE_PROTOS +dumpException(ExceptionGroup *eg, int no_default_case) +#else +dumpException(eg, no_default_case) +ExceptionGroup *eg; +int no_default_case; +#endif +{ + char *outerLabel; /* MR7 */ + int altHandler=0; /* MR7 */ + int namedHandler=0; /* MR7 */ + + outerLabel=findOuterHandlerLabel(eg); /* MR7 */ + + if (eg->label != NULL) { /* MR7 */ + namedHandler=1; /* MR7 */ + } else if (eg->forRule) { /* MR7 */ + /* nothing */ /* MR20 */ + } else { /* MR7 */ + altHandler=1; /* MR7 */ + }; /* MR7 */ + +#if 0 +** if (! eg->used) { /* MR7 */ +** warnFL("exception group never used", /* MR7 */ +** FileStr[eg->altstart->file],eg->altstart->line); /* MR7 */ +** }; /* MR7 */ +#endif + + if (namedHandler) { /* MR7 */ + gen1("switch ( _signal ) { /* [%s] */\n",eg->label); /* MR7 */ + } else { /* MR7 */ + gen("switch ( _signal ) {\n"); /* MR7 */ + gen("case NoSignal: break; /* MR7 */\n"); /* MR7 */ + }; /* MR7 */ + { + ListNode *q; + for (q = eg->handlers->next; q!=NULL; q=q->next) + { + ExceptionHandler *eh = (ExceptionHandler *)q->elem; + if ( strcmp("default", eh->signalname)==0 ) { + gen("default :\n"); + tabs++; + dumpAction(eh->action, output, tabs, -1, 1, 1); + gen("_signal=NoSignal; /* MR7 */\n"); /* MR7 */ + gen("break; /* MR7 */\n"); /* MR7 */ + tabs--; + gen("}\n"); + + /* copied from later code in dumpException */ /* MR7 */ + + if (namedHandler) { /* MR7 */ + gen("if (_signal != NoSignal)"); /* MR7 */ + _gen1(" goto %s_handler; /* MR7 */\n",outerLabel);/* MR7 */ + } else if (altHandler) { /* MR7 */ + gen1("goto %s_handler; /* MR7 */\n",outerLabel); /* MR7 */ + }; + return; + } + gen1("case %s :\n", eh->signalname); + tabs++; + if ( eh->action != NULL ) + { + dumpAction(eh->action, output, tabs, -1, 1, 1); + gen("break; /* MR7 */\n"); /* MR7 */ + } + tabs--; + } + } + if ( no_default_case ) return; + + gen("default :\n"); + tabs++; /* MR7 */ + gen("break; /* MR7 */\n"); /* MR7 */ + tabs--; /* MR7 */ + + tabs++; +/***** gen("*_retsignal = _signal;\n"); *****/ + + tabs--; + gen("}\n"); + + if (namedHandler) { /* MR7 */ + gen("if (_signal != NoSignal)"); /* MR7 */ + _gen1(" goto %s_handler; /* MR7 */\n",outerLabel); /* MR7 */ + } else if (altHandler) { /* MR7 */ + gen1("goto %s_handler; /* MR7 */\n",outerLabel); /* MR7 */ + }; + +} + +static void +#ifdef __USE_PROTOS +dumpExceptions(ListNode *list) +#else +dumpExceptions(list) +ListNode *list; +#endif +{ + ListNode *p; + + for (p = list->next; p!=NULL; p=p->next) + { + ExceptionGroup *eg = (ExceptionGroup *) p->elem; + _gen2("%s%s_handler:\n", + eg->label==NULL?"":eg->label, + eg->altID==NULL?"":eg->altID); + if ( eg->altID!=NULL ) dumpException(eg, 0); + else { + /* This must be the rule exception handler */ + dumpException(eg, 1); + if ( !hasDefaultException(eg) ) + { + gen("default :\n"); + tabs++; + gen("zzdflthandlers(_signal,_retsignal);\n"); + tabs--; + gen("}\n"); + } + } + } +} + +/* For each element label that is found in a rule, generate a unique + * Attribute (and AST pointer if GenAST) variable. + */ +void +#ifdef __USE_PROTOS +genElementLabels(ListNode *list) +#else +genElementLabels(list) +ListNode *list; +#endif +{ + int first=1; + ListNode *p; + + if ( GenCC ) {gen("ANTLRTokenPtr");} + else {gen("Attrib");} + for (p = list->next; p!=NULL; p=p->next) + { + char *ep = (char *)p->elem; + if ( first ) first = 0; + else _gen(","); + if ( GenCC ) {_gen1(" %s=NULL",ep);} + else {_gen1(" %s",ep);} + } + _gen(";\n"); + + if ( !GenAST ) return; + + first = 1; + gen("AST"); + for (p = list->next; p!=NULL; p=p->next) + { + char *ep = (char *)p->elem; + if ( first ) first = 0; + else _gen(","); + _gen1(" *%s_ast=NULL",ep); + } + _gen(";\n"); +} + +/* + * Generate a local variable allocation for each token or rule reference + * in this block. + */ +static void +#ifdef __USE_PROTOS +genASTPointers( Junction *q ) +#else +genASTPointers( q ) +Junction *q; +#endif +{ + int first=1, t; + set a; + + a = set_or(q->tokrefs, q->rulerefs); + if ( set_deg(a) > 0 ) + { + gen("AST "); + for (; !set_nil(a); set_rm(t, a)) + { + t = set_int(a); + if ( first ) first = 0; + else _gen(","); + _gen2("*_ast%d%d=NULL", BlkLevel, t); + } + set_free(a); + } + _gen(";\n"); +} + +static void +#ifdef __USE_PROTOS +BLOCK_Head( void ) +#else +BLOCK_Head( ) +#endif +{ + gen("{\n"); + tabs++; + if ( !GenCC ) gen1("zzBLOCK(zztasp%d);\n", BlkLevel); +} + +static void +#ifdef __USE_PROTOS +BLOCK_Tail( void ) +#else +BLOCK_Tail( ) +#endif +{ + if ( !GenCC ) gen1("zzEXIT(zztasp%d);\n", BlkLevel); + if ( !GenCC ) gen("}\n"); + tabs--; + gen("}\n"); +} + +static void +#ifdef __USE_PROTOS +BLOCK_Preamble( Junction *q ) +#else +BLOCK_Preamble( q ) +Junction *q; +#endif +{ + ActionNode *a; + Junction *begin; + + BLOCK_Head(); + if ( GenCC ) genTokenPointers(q); + if ( GenCC&&GenAST ) genASTPointers(q); + if ( q->jtype == aPlusBlk ) gen("int zzcnt=1;\n"); + if ( q->parm != NULL && !q->predparm ) gen1("zzaPush(%s);\n", q->parm) + else if ( !GenCC ) gen("zzMake0;\n"); + if ( !GenCC ) gen("{\n"); + if ( q->jtype == aLoopBegin ) begin = (Junction *) ((Junction *)q->p1); + else begin = q; + if ( has_guess_block_as_first_item(begin) ) + { + gen("zzGUESS_BLOCK\n"); + } + if ( q->jtype == aLoopBegin ) + a = findImmedAction( ((Junction *)q->p1)->p1 ); /* look at aLoopBlk */ + else + a = findImmedAction( q->p1 ); + if ( a!=NULL && !a->is_predicate) { +/* MR21 */ if (!a->noHoist) dumpActionPlus(a, a->action, output, tabs, a->file, a->line, 1); + a->done = 1; /* remove action. We have already handled it */ + } +} + +void +#ifdef __USE_PROTOS +genCombinedPredTreeContextOrig( Predicate *p ) +#else +genCombinedPredTreeContextOrig( p ) +Predicate *p; +#endif +{ + static set *ctx=NULL; /* genExprSets() is destructive, make copy*/ + require(p!=NULL, "can't make context tree for NULL pred tree"); + +#ifdef DBG_PRED + fprintf(stderr, "enter genCombinedPredTreeContextOrig(%s,0x%x) with sets:\n", p->expr, p); + s_fprT(stderr, p->scontext[1]); + fprintf(stderr, "\n"); +#endif + if ( p->down == NULL ) + { +/*** if ( p->k>1 && p->tcontext!=NULL ) ***/ + if ( p->tcontext!=NULL ) + { + _gen("("); + genExprTree(p->tcontext, 1); + _gen(")"); + } +/*** else if ( p->k==1 && set_deg(p->scontext[1])>0 ) ***/ + else if ( set_deg(p->scontext[1])>0 ) + { + if ( ctx==NULL ) ctx = (set *)calloc(CLL_k+1, sizeof(set)); + require(ctx!=NULL, "ctx cannot allocate"); + ctx[0]=empty; + ctx[1]=set_dup(p->scontext[1]); + _gen("("); + genExprSets(&(ctx[0]), p->k); + _gen(")"); + set_free(ctx[1]); + } + else if ( p->expr==PRED_AND_LIST || p->expr==PRED_OR_LIST ) { + fatal_internal("pred tree is orphan OR or AND list"); + } + else { + if (! HoistPredicateContext) { + _gen(" 1 /* no context: prc is off */ "); + } else { + fatal_internal("pred tree context is empty"); + }; + } + return; + } + +/* MR10 - make AND just like OR */ + + if ( p->expr == PRED_AND_LIST ) + { + Predicate *list = p->down; + for (; list!=NULL; list=list->right) + { + genCombinedPredTreeContextOrig(list); + if ( list->right!=NULL ) _gen("|| /* MR10 was wrong */ "); + }; + return; + } + + if ( p->expr == PRED_OR_LIST ) + { + Predicate *list = p->down; + for (; list!=NULL; list=list->right) + { + genCombinedPredTreeContextOrig(list); + if ( list->right!=NULL ) _gen("||"); + }; + return; + }; + + fatal("pred tree is really wacked"); +} + +/* [genCombinedPredTreeContext] */ + +void +#ifdef __USE_PROTOS +genCombinedPredTreeContext( Predicate *p ) +#else +genCombinedPredTreeContext( p ) +Predicate *p; +#endif +{ + Tree *t; + int predDepth=0; + + if (0 && ! MR_usingPredNames && ! MRhoisting) { + genCombinedPredTreeContextOrig(p); + } else { +/* MR13 */ MR_pred_depth(p,&predDepth); +/* MR13 */ if (predDepth == 1) { +/* MR13 */ +/* MR13 */ set scontext[2]; +/* MR13 */ scontext[0]=empty; +/* MR13 */ scontext[1]=MR_compute_pred_set(p); +/* MR13 */ if (set_nil(scontext[1])) { +/* MR13 */ _gen(" 1 /* MR12 no context (-prc off) */ "); +/* MR13 */ } else { +/* MR13 */ _gen("("); +/* MR13 */ genExprSets(&scontext[0], 1); +/* MR13 */ set_free(scontext[1]); +/* MR13 */ _gen(")"); +/* MR13 */ }; + + } else { + t=MR_compute_pred_tree_context(p); + if (t == NULL) { + _gen(" 1 /* MR12 no context (-prc off) */ "); + } else { + _gen("("); + genExprTree(t, 1); + Tfree(t); /* MR10 */ + _gen(")"); + }; + }; + }; +} + +/* [genPredTreeGate] */ + +void +#ifdef __USE_PROTOS +genPredTreeGate( Predicate *p, int in_and_expr ) +#else +genPredTreeGate( p, in_and_expr ) +Predicate *p; +int in_and_expr; +#endif +{ + if ( in_and_expr ) + { + _gen("!("); + genCombinedPredTreeContext(p); + _gen(")||"); + if ( p->down!=NULL ) _gen("\n"); + } + else + { + _gen("("); + genCombinedPredTreeContext(p); + _gen(")&&"); + if ( p->down!=NULL ) _gen("\n"); + } +} + +#ifdef __USE_PROTOS +void genPredEntry(Predicate *p,int outer) +#else +void genPredEntry(p,outer) + Predicate *p; + int outer; +#endif +{ + int inverted=0; + Predicate *q; + int localOuter=outer; + int needRP=0; + + if (p == NULL) return; + + if (p->predEntry != NULL && p->predEntry->predLiteral != NULL) { + if (p->inverted != p->predEntry->pred->inverted) { + _gen("! /* inverted pred */ ("); + needRP=1; + } else { + if (!localOuter) _gen("("); + needRP=1; + }; + dumpAction(p->predEntry->predLiteral,output,0,p->source->file,p->source->line,0); + if (needRP) _gen(")"); + return; + }; + + inverted=p->inverted; + + if (inverted) { + _gen(" ! /* inverted pred */ ("); + localOuter=1; + }; + + if (p->expr == PRED_OR_LIST) { + if (!localOuter) _gen("("); + for (q=p->down; q != NULL ; q=q->right) { + genPredEntry(q,0); + if (q->right != NULL) _gen(" || "); + }; + if (!localOuter) _gen(")"); + } else if (p->expr == PRED_AND_LIST) { + if (!localOuter) _gen("("); + for (q=p->down; q != NULL ; q=q->right) { + genPredEntry(q,0); + if (q->right != NULL) _gen(" && "); + }; + if (!localOuter) _gen(")"); + } else { + if (!localOuter) _gen("("); + require (p->source != NULL,"predEntry->source == NULL"); + require (p->source->inverted == 0,"dumpPredEntry p->source->inverted != 0"); + dumpAction(p->source->action,output,0,p->source->file,p->source->line,0); + if (!localOuter) _gen(")"); + }; + + if (inverted) { + _gen(")"); + } +} + +void +#ifdef __USE_PROTOS +dumpPredAction(ActionNode *anode, + char *s,FILE *output,int tabs,int file,int line,int final_newline) +#else +dumpPredAction(anode, + s,output,tabs,file,line,final_newline) + + ActionNode *anode; + char *s; + FILE *output; + int tabs; + int file; + int line; + int final_newline; +#endif +{ + PredEntry *predEntry=anode->predEntry; + int inverted=anode->inverted; + Predicate *workPred; + + if (predEntry == NULL) { + + /* inline predicate literal */ + + require(inverted == 0,"dumpPredAction action->inverted"); + dumpAction(s,output,tabs,file,line,final_newline); + + } else { + + /* a reference to a predicate - possibly with an inverted source */ + + if (predEntry->predLiteral != NULL) { + if (inverted) _gen("! /* inverted pred */ ("); + dumpAction(predEntry->predLiteral,output,0,anode->file,anode->line,0); + if (inverted) _gen(")"); + } else { + workPred=predicate_dup(predEntry->pred); + if (inverted) workPred->inverted=!workPred->inverted; + genPredEntry(workPred,1); + predicate_free(workPred); + }; + }; +} + +/* [genPred] */ + +void +#ifdef __USE_PROTOS +genPred(Predicate *p, Node *j,int suppress_sva) +#else +genPred(p,j,suppress_sva) + Predicate *p; + Node *j; + int suppress_sva; +#endif +{ + if ( FoundException && !suppress_sva) {_gen("(_sva=(");} /* MR11 suppress_sva */ + else {_gen("(");} + if ( GenLineInfo && j->file != -1 ) _gen("\n"); + if (p->source != NULL && p->source->ampersandPred != NULL) { + if (p->source->ampersandPred->k == 1) { + + set ctx[2]; + + ctx[0]=empty; + ctx[1]=set_dup(p->source->ampersandPred->scontext[1]); + + _gen("("); + genExprSets(&(ctx[0]), p->k); + _gen(") && "); + set_free(ctx[1]); + } else { + _gen("( "); + genExprTree(p->source->ampersandPred->tcontext,1); + _gen(" ) && "); + }; + }; + + dumpPredAction((ActionNode *)p->source, + p->expr, output, 0, -1 /*indicates no line info*/, j->line, 0); + + if ( FoundException && !suppress_sva) /* MR11 suppress_sva */ + {_gen("),_sva)");} /* MR10 - get red of "meant ==" messages */ + else {_gen(")");} +} + +void +#ifdef __USE_PROTOS +MR_distinctORcontextOpt(Predicate *p,Node *j,int in_and_expr) +#else +MR_distinctORcontextOpt(p,j,in_and_expr) + Predicate *p; + Node *j; + int in_and_expr; +#endif +{ + Predicate *q; + + _gen(" /* MR10 Distinct OR context optimization */ \n"); + + if (in_and_expr) { + gen("zzpf=0,\n"); + for (q=p->down; q != NULL; q=q->right) { + gen("( "); + genCombinedPredTreeContext(q); + _gen(" && (zzpf=1, "); + genPred(q,j,0); + _gen(" )) ||\n"); + }; + gen("!zzpf)"); + } else { + require (0, + "MR_distinctORcontextOpt: can't get here when using MR_predSimplify"); +#if 0 +** for (q=p->down; q != NULL; q=q->right) { +** gen("( "); +** genCombinedPredTreeContext(q); +** _gen(" && "); +** genPred(q,j); +** if (q->right != NULL) { +** _gen(" ) ||\n"); +** }; +** }; +** gen(")"); +#endif + }; +} + +void +#ifdef __USE_PROTOS +genPredTreeOrig( Predicate *p, Node *j, int in_and_expr ) +#else +genPredTreeOrig( p, j, in_and_expr ) +Predicate *p; +Node *j; +int in_and_expr; +#endif +{ + +/* MR10 */ int allHaveContext=1; +/* MR10 */ int noneHaveContext=1; + +/* MR10 */ MR_predContextPresent(p,&allHaveContext,&noneHaveContext); + + if ( ! noneHaveContext ) /* MR10 context guards ignored when -prc off */ + { + _gen("("); + genPredTreeGate(p, in_and_expr); + } + + /* if leaf node, just gen predicate */ + + if ( p->down==NULL ) + { + genPred(p,j,0); + if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */ + return; + } + + /* if AND list, do both preds (only two possible) */ + if ( p->expr == PRED_AND_LIST ) + { +#if 0 +** _gen("("); +** genPredTreeOrig(p->down, j, 1); +** _gen("&&"); +** genPredTreeOrig(p->down->right, j, 1); +** _gen(")"); +** if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */ +** return; +#endif + /* MR11 - make it work with AND with more than two children - like OR */ + + Predicate *list; + _gen("("); + list = p->down; + for (; list!=NULL; list=list->right) + { + genPredTreeOrig(list, j, 1); + if ( list->right!=NULL ) _gen("&&"); + } + _gen(")"); + if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */ + return; + }; + + if ( p->expr == PRED_OR_LIST ) + { + Predicate *list; + _gen("("); + list = p->down; + for (; list!=NULL; list=list->right) + { + genPredTreeOrig(list, j, 0); + if ( list->right!=NULL ) _gen("||"); + } + _gen(")"); + if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */ + return; + } + + fatal_internal("genPredTreeOrig: predicate tree is wacked"); +} + +#if 0 +** Predicate member dummyPredDepth is no longer used in MR10 +** but we might need it again in the future +** +** if (MRhoisting) { +** if ( !noneHaveContext && +** ! in_and_expr && +** p->source != NULL && +** p->source->dummyPredicateDepth > 0 && +** p->down == NULL) { +** _gen("("); +** genCombinedPredTreeContext(p); +** _gen(" )\n"); +** return; +** }; +** }; +#endif + +/* [genPredTree] */ + +/* in_and_expr + + what to do if the context is wrong + what to do if the context is correct but the predicate is false + + remember: if the context is wrong it's the same as if the + predicate is true as far as enabling an alternative + + Consider (AND p q r) + + if in an ... && ... expression then you don't want + the entire predicate chain to fail just because the + context for one component is wrong: so return true + + Consider (OR p q r) + + if in an ... || ... expression then you don't want + the entire predicate chain to succeed just because + the context for one component is correct when the + corresponding test is false: so return false when + the context is correct but the test is false. +*/ + +void +#ifdef __USE_PROTOS +genPredTree( Predicate *p, Node *j, int in_and_expr, int suppress_sva ) +#else +genPredTree( p, j, in_and_expr, suppress_sva) + Predicate *p; + Node *j; + int in_and_expr; + int suppress_sva; +#endif +{ + + int allHaveContext=1; + int noneHaveContext=1; + Tree *groupTree; + Tree *oneTree; + Predicate *q; + int identicalORcontextOptimization=0; + int identicalANDcontextOptimization=0; + + if (0 && !MR_usingPredNames && !MRhoisting) { + genPredTreeOrig(p,j,in_and_expr); + return; + }; + + MR_predContextPresent(p,&allHaveContext,&noneHaveContext); + + if ( ! noneHaveContext ) { /* MR10 context guards ignored when -prc off */ + + _gen("("); + + /* MR10 optimize OR predicates which are all leaves */ + + if (p->expr == PRED_OR_LIST && MR_allPredLeaves(p->down)) { + groupTree=MR_compute_pred_tree_context(p); + for (q=p->down ; q != NULL ; q=q->right) { + oneTree=MR_compute_pred_tree_context(q); + if (! MR_tree_equ(groupTree,oneTree)) { + Tfree(oneTree); + break; + }; + Tfree(oneTree); + }; + Tfree(groupTree); + if (q == NULL) { + _gen("/* MR10 individual OR gates suppressed when all predicates are leaves"); + _gen(" with identical context */\n"); + genPredTreeGate(p,in_and_expr); /* use the parent's in_and_expr for this gate */ + identicalORcontextOptimization=1; + } else { + MR_distinctORcontextOpt(p,j,in_and_expr); + return; + }; + } else if (p->expr == PRED_AND_LIST && MR_allPredLeaves(p->down)) { + + /* MR12 optimize AND predicates which are all leaves */ + + groupTree=MR_compute_pred_tree_context(p); + for (q=p->down ; q != NULL ; q=q->right) { + oneTree=MR_compute_pred_tree_context(q); + if (! MR_tree_equ(groupTree,oneTree)) { + Tfree(oneTree); + break; + }; + Tfree(oneTree); + }; + Tfree(groupTree); + if (q == NULL) { + _gen("/* MR12 individual AND gates suppressed when all predicates are leaves"); + _gen(" with identical context */\n"); + genPredTreeGate(p,in_and_expr); /* use the parent's in_and_expr for this gate */ + identicalANDcontextOptimization=1; + } else { + genPredTreeGate(p, in_and_expr); + }; + } else { + genPredTreeGate(p, in_and_expr); + }; + } + + /* if leaf node, just gen predicate */ + + if ( p->down==NULL ) + { + genPred(p,j,suppress_sva); + if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */ + return; + } + + /* if AND list, do both preds (only two possible) */ + /* MR10 not any more ! */ + + if ( p->expr == PRED_AND_LIST ) + { + Predicate *list; + _gen("("); + list = p->down; + for (; list != NULL; list=list->right) { + if (identicalANDcontextOptimization) { + genPred(list, j,suppress_sva); + } else { + genPredTree(list, j, 1, suppress_sva); /* in and context */ + }; + if ( list->right!=NULL ) _gen("&&"); + }; + _gen(")"); + if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */ + return; + } + + if ( p->expr == PRED_OR_LIST ) + { + Predicate *list; + _gen("("); + list = p->down; + for (; list!=NULL; list=list->right) + { + if (identicalORcontextOptimization) { + genPred(list, j,suppress_sva); + } else { + genPredTree(list, j, 0, suppress_sva); + }; + if ( list->right!=NULL ) _gen("||"); + } + _gen(")"); + if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */ + return; + } + + fatal_internal("predicate tree is wacked"); +} + +/* [genPredTreeMainXX] */ + +Predicate * /* MR10 */ +#ifdef __USE_PROTOS +genPredTreeMainXX( Predicate *p, Node *j ,int in_and_expr) +#else +genPredTreeMainXX( p, j ,in_and_expr) + Predicate *p; + Node *j; + int in_and_expr; +#endif +{ + + int allHaveContext=1; + int noneHaveContext=1; + +#if 0 + fprintf(stderr,"Pred before\n"); + dumppred(p); + fprintf(stderr,"\n"); + fprintf(stderr,"Pred after\n"); + dumppred(p); + fprintf(stderr,"\n"); +#endif + + p=MR_predSimplifyALL(p); /* MR10 */ + + require (MR_predicate_context_completed(p),"predicate context is not complete"); + + MR_cleanup_pred_trees(p); /* MR10 */ + + MR_predContextPresent(p,&allHaveContext,&noneHaveContext); + if (!noneHaveContext & !allHaveContext) { + warnFL("predicate contains elements both with and without context", + FileStr[j->file],j->line); + }; + + if (InfoP) { + _gen("\n#if 0\n\n"); + MR_dumpPred(p,1); + _gen("#endif\n"); + }; + genPredTree(p,j,in_and_expr,0); + return p; +} + +Predicate * /* MR10 */ +#ifdef __USE_PROTOS +genPredTreeMain( Predicate *p, Node *j) +#else +genPredTreeMain( p, j) + Predicate *p; + Node *j; +#endif +{ + return genPredTreeMainXX(p,j,1); +} + +static void +#ifdef __USE_PROTOS +genExprTreeOriginal( Tree *t, int k ) +#else +genExprTreeOriginal( t, k ) +Tree *t; +int k; +#endif +{ + require(t!=NULL, "genExprTreeOriginal: NULL tree"); + + if ( t->token == ALT ) + { + _gen("("); genExprTreeOriginal(t->down, k); _gen(")"); + if ( t->right!=NULL ) + { + _gen("||"); + on1line++; + if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); } + _gen("("); genExprTreeOriginal(t->right, k); _gen(")"); + } + return; + } + if ( t->down!=NULL ) _gen("("); + _gen1("LA(%d)==",k); + if ( TokenString(t->token) == NULL ) _gen1("%d", t->token) + else _gen1("%s", TokenString(t->token)); + if ( t->down!=NULL ) + { + _gen("&&"); + on1line++; + if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); } + _gen("("); genExprTreeOriginal(t->down, k+1); _gen(")"); + } + if ( t->down!=NULL ) _gen(")"); + if ( t->right!=NULL ) + { + _gen("||"); + on1line++; + if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); } + _gen("("); genExprTreeOriginal(t->right, k); _gen(")"); + } +} + +#ifdef __USE_PROTOS +static void MR_LAtokenString(int k,int token) +#else +static void MR_LAtokenString(k,token) + int k; + int token; +#endif +{ + char *ts; + + ts=TokenString(token); + if (ts == NULL) { + _gen2(" LA(%d)==%d",k,token); + } else { + _gen2(" LA(%d)==%s",k,ts); + }; +} + + +#ifdef __USE_PROTOS +static int MR_countLeaves(Tree *t) +#else +static int MR_countLeaves(t) + Tree *t; +#endif +{ + if (t == NULL) return 0; + if (t->token == ALT) { + return MR_countLeaves(t->down)+MR_countLeaves(t->right); + } else { + return 1+MR_countLeaves(t->down)+MR_countLeaves(t->right); + }; +} + +#ifdef __USE_PROTOS +static void MR_genOneLine(Tree *tree,int k) +#else +static void MR_genOneLine(tree,k) + Tree *tree; + int k; +#endif +{ + if (tree == NULL) return; + if (tree->token == ALT) { + MR_genOneLine(tree->down,k); + } else { + MR_LAtokenString(k,tree->token); + if (tree->down != NULL && + tree->down->right == NULL) { + _gen(" &&"); + MR_genOneLine(tree->down,k+1); + } else if (tree->down != NULL) { + _gen(" && ("); + MR_genOneLine(tree->down,k+1); + _gen(")"); + }; + }; + if (tree->right != NULL) { + _gen(" ||"); + MR_genOneLine(tree->right,k); + }; +} + +static int across; +static int depth; +static int lastkonline; + +#ifdef __USE_PROTOS +static void MR_genMultiLine(Tree *tree,int k) +#else +static void MR_genMultiLine(tree,k) + Tree *tree; + int k; +#endif +{ + int i; + + if (tree == NULL) return; + if (tree->token == ALT) { + MR_genMultiLine(tree,k); + } else { + MR_LAtokenString(k,tree->token); + lastkonline=k; + across++; + if (tree->down != NULL && tree->down->right == NULL) { + if (across > 3) { + _gen("\n"); + across=0; + lastkonline=0; + for (i=0 ; i < depth+k ; i++) _gen(" "); + _gen("&&"); + } else { + _gen(" &&"); + }; + MR_genMultiLine(tree->down,k+1); + } else if (tree->down != NULL) { + _gen("\n"); + lastkonline=0; + across=0; + for (i=0 ; i < depth+k ; i++) _gen(" "); + _gen("&& ("); + MR_genMultiLine(tree->down,k+1); + _gen(")"); + }; + }; + if (tree->right != NULL) { + if (k < lastkonline) { + _gen("\n"); + across=0; + lastkonline=0; + for (i=0; i < depth+k-1 ; i++) _gen(" "); + _gen("||"); + } else if (across > 3 ) { + _gen("\n"); + across=0; + lastkonline=0; + for (i=0; i < depth+k ; i++) _gen(" "); + _gen("||"); + } else { + _gen(" ||"); + }; + MR_genMultiLine(tree->right,k); + }; +} + +#ifdef __USE_PROTOS +static void genExprTree(Tree *tree,int k) +#else +static void genExprTree(tree,k) + Tree *tree; + int k; +#endif +{ + int count; + +#if 0 + /* MR20 THM This was probably an error. + The routine should probably reference that static + "across" and this declaration hides it. + */ + + int across; +#endif + + require (tree != NULL,"genExprTree: tree is NULL"); + require (k > 0,"genExprTree: k <= 0"); + + if (0 && !MRhoisting) { /* MR11 make new version standard */ + genExprTreeOriginal(tree,k); + } else { + count=MR_countLeaves(tree); + if (count < 5) { + MR_genOneLine(tree,k); + } else { + _gen("\n"); + across=0; + depth=0; + lastkonline=0; + MR_genMultiLine(tree,k); + _gen("\n"); + }; + }; +} + + +/* + * Generate LL(k) type expressions of the form: + * + * (LA(1) == T1 || LA(1) == T2 || ... || LA(1) == Tn) && + * (LA(2) == T1 || LA(2) == T2 || ... || LA(2) == Tn) && + * ..... + * (LA(k) == T1 || LA(k) == T2 || ... || LA(k) == Tn) + * + * If GenExprSetsOpt generate: + * + * (setwdi[LA(1)]&(1<= 1. + * + * This routine is visible only to this file and cannot answer a TRANS message. + * + */ + +/* [genExpr] */ + +static int +#ifdef __USE_PROTOS +genExpr( Junction *j ) +#else +genExpr( j ) +Junction *j; +#endif +{ + int max_k; + + /* if full LL(k) is sufficient, then don't use approximate (-ck) lookahead + * from CLL_k..LL_k + */ + { + int limit; + if ( j->ftree!=NULL ) limit = LL_k; + else limit = CLL_k; + max_k = genExprSets(j->fset, limit); + } + + /* Do tests for real tuples from other productions that conflict with + * artificial tuples generated by compression (using sets of tokens + * rather than k-trees). + */ + if ( j->ftree != NULL ) + { + _gen(" && !("); genExprTree(j->ftree, 1); _gen(")"); + } + + if ( ParseWithPredicates && j->predicate!=NULL ) + { + Predicate *p = j->predicate; + warn_about_using_gk_option(); + _gen("&&"); + j->predicate=genPredTreeMain(p, (Node *)j); /* MR10 */ + } + + return max_k; +} + +static int +#ifdef __USE_PROTOS +genExprSets( set *fset, int limit ) +#else +genExprSets( fset, limit ) +set *fset; +int limit; +#endif +{ + int k = 1; + int max_k = 0; + unsigned *e, *g, firstTime=1; + + if (set_nil(fset[1])) { + _gen(" 0 /* MR13 empty set expression - undefined rule ? infinite left recursion ? */ "); + MR_BadExprSets++; + }; + + if ( GenExprSetsOpt ) + { + while ( k <= limit && !set_nil(fset[k]) ) /* MR11 */ + { + if ( set_deg(fset[k])==1 ) /* too simple for a set? */ + { + int e; + _gen1("(LA(%d)==",k); + e = set_int(fset[k]); + if ( TokenString(e) == NULL ) _gen1("%d)", e) + else _gen1("%s)", TokenString(e)); + } + else + { + NewSet(); + FillSet( fset[k] ); + _gen3("(setwd%d[LA(%d)]&0x%x)", wordnum, k, 1<max_k ) max_k = k; + if ( k == CLL_k ) break; + k++; + if ( k<=limit && !set_nil(fset[k]) ) _gen(" && "); /* MR11 */ + on1line++; + if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); } + } + return max_k; + } + + while ( k<= limit && !set_nil(fset[k]) ) /* MR11 */ + { + if ( (e=g=set_pdq(fset[k])) == NULL ) fatal_internal("genExpr: cannot allocate IF expr pdq set"); + for (; *e!=nil; e++) + { + if ( !firstTime ) _gen(" || ") else { _gen("("); firstTime = 0; } + on1line++; + if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); } + _gen1("LA(%d)==",k); + if ( TokenString(*e) == NULL ) _gen1("%d", *e) + else _gen1("%s", TokenString(*e)); + } + free( (char *)g ); + _gen(")"); + if ( k>max_k ) max_k = k; + if ( k == CLL_k ) break; + k++; + if ( k <= limit && !set_nil(fset[k]) ) { firstTime=1; _gen(" && "); } /* MR11 */ + on1line++; + if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); } + } + return max_k; +} + +/* + * Generate code for any type of block. If the last alternative in the block is + * empty (not even an action) don't bother doing it. This permits us to handle + * optional and loop blocks as well. + * + * Only do this block, return after completing the block. + * This routine is visible only to this file and cannot answer a TRANS message. + */ +static set +#ifdef __USE_PROTOS +genBlk( Junction *q, int jtype, int *max_k, int *need_right_curly, int * lastAltEmpty /* MR23 */) +#else +genBlk( q, jtype, max_k, need_right_curly, lastAltEmpty /* MR23 */) +Junction *q; +int jtype; +int *max_k; +int *need_right_curly; +int *lastAltEmpty; /* MR23 */ +#endif +{ + set f; + Junction *alt; + int a_guess_in_block = 0; + require(q!=NULL, "genBlk: invalid node"); + require(q->ntype == nJunction, "genBlk: not junction"); + *need_right_curly=0; + *lastAltEmpty = 0; /* MR23 */ + if ( q->p2 == NULL ) /* only one alternative? Then don't need if */ + { + if (first_item_is_guess_block((Junction *)q->p1)!=NULL ) + { + if (jtype != aLoopBlk && jtype != aOptBlk && jtype != aPlusBlk) { + warnFL("(...)? as only alternative of block is unnecessary", FileStr[q->file], q->line); + }; + gen("zzGUESS\n"); /* guess anyway to make output code consistent */ +/* MR10 disable */ /**** gen("if ( !zzrv )\n"); ****/ +/* MR10 */ gen("if ( !zzrv ) {\n"); tabs++; (*need_right_curly)++; + }; + TRANS(q->p1); + return empty; /* no decision to be made-->no error set */ + } + + f = First(q, 1, jtype, max_k); + for (alt=q; alt != NULL; alt= (Junction *) alt->p2 ) + { + if ( alt->p2 == NULL ) /* chk for empty alt */ + { + Node *p = alt->p1; + if ( p->ntype == nJunction ) + { + /* we have empty alt */ +/* MR23 + There is a conflict between giving good error information for non-exceptions + and making life easy for those using parser exception handling. Consider: + + r: { A } b; + b: B; + + with input "C" + + Before MR21 the error message would be "expecting B - found C". After MR21 + the error message would be "expcect A, B - found C". This was good, but it + caused problems for those using parser exceptions because the reference to + B was generated inside the {...} where B really wasn't part of the block. + + In MR23 this has been changed for the case where exceptions are in use to + not generate the extra check in the tail of the {A} block. +*/ + + +/* MR23 */ if (isEmptyAlt( ((Junction *)p)->p1, (Node *)q->end)) { +/* MR23 */ *lastAltEmpty = 1; +/* MR23 */ if (FoundException) { +/* MR23 */ /* code to restore state if a prev alt didn't follow guess */ +/* MR23 */ if ( a_guess_in_block && jtype != aPlusBlk) { +/* MR23 */ gen("if ( !zzrv ) zzGUESS_DONE; /* MR28 */\n"); +/* MR23 */ } +/* MR23 */ break; +/* MR23 */ }; +/* MR28 */ if (jtype == aPlusBlk) { +/* MR28 */ break; +/* MR28 */ } +/* MR23 */ } + } + } /* end of for loop on alt */ + +/* MR10 */ if (alt->p2 == NULL && +/* MR10 */ ( q->jtype == aSubBlk || q->jtype == RuleBlk) ) { +/* MR10 */ if (first_item_is_guess_block(alt)) { +/* MR10 */ warnFL("(...)? as last alternative of block is unnecessary", +/* MR10 */ FileStr[alt->file],alt->line); +/* MR10 */ }; +/* MR10 */ }; + + if ( alt != q ) gen("else ") + else + { + if ( DemandLookahead ) { + if ( !GenCC ) {gen1("LOOK(%d);\n", *max_k);} + else gen1("look(%d);\n", *max_k); + } + } + + if ( alt!=q ) + { + _gen("{\n"); + tabs++; + (*need_right_curly)++; + /* code to restore state if a prev alt didn't follow guess */ + if ( a_guess_in_block ) + gen("if ( !zzrv ) zzGUESS_DONE;\n"); + } + if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL ) + { + a_guess_in_block = 1; + gen("zzGUESS\n"); + } + gen("if ( "); + if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL ) _gen("!zzrv && "); + genExpr(alt); + _gen(" ) "); + _gen("{\n"); + tabs++; + TRANS(alt->p1); + --tabs; + gen("}\n"); +/* MR10 */ if (alt->p2 == NULL) { +/* MR10 */ if (first_item_is_guess_block(alt)) { +/* MR10 */ gen("/* MR10 */ else {\n"); +/* MR10 */ tabs++; +/* MR10 */ (*need_right_curly)++; +/* MR10 */ /* code to restore state if a prev alt didn't follow guess */ +/* MR10 */ gen("/* MR10 */ if ( !zzrv ) zzGUESS_DONE;\n"); +/* MR10 */ gen("/* MR10 */ if (0) {} /* last alternative of block is guess block */\n"); +/* MR10 */ }; +/* MR10 */ }; + } + return f; +} + +static int +#ifdef __USE_PROTOS +has_guess_block_as_first_item( Junction *q ) +#else +has_guess_block_as_first_item( q ) +Junction *q; +#endif +{ + Junction *alt; + + for (alt=q; alt != NULL; alt= (Junction *) alt->p2 ) + { + if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL ) return 1; + } + return 0; +} + +static int +#ifdef __USE_PROTOS +has_guess_block_as_last_item( Junction *q ) +#else +has_guess_block_as_last_item( q ) +Junction *q; +#endif +{ + Junction *alt; + + if (q == NULL) return 0; + for (alt=q; alt->p2 != NULL && !( (Junction *) alt->p2)->ignore; alt= (Junction *) alt->p2 ) {}; + return first_item_is_guess_block( (Junction *) alt->p1) != NULL; +} + +/* MR30 See description of first_item_is_guess_block for background */ + +Junction * +#ifdef __USE_PROTOS +first_item_is_guess_block_extra(Junction *q ) +#else +first_item_is_guess_block_extra(q) +Junction *q; +#endif +{ + while ( q!=NULL && + ( ( q->ntype==nAction ) || + ( q->ntype==nJunction && + (q->jtype==Generic || q->jtype == aLoopBlk) + ) + ) + ) + { + if ( q->ntype==nJunction ) q = (Junction *)q->p1; + else q = (Junction *) ((ActionNode *)q)->next; + } + + if ( q==NULL ) return NULL; + if ( q->ntype!=nJunction ) return NULL; + if ( q->jtype!=aSubBlk ) return NULL; + if ( !q->guess ) return NULL; + + return q; +} + +/* return NULL if 1st item of alt is NOT (...)? block; else return ptr to aSubBlk node + * of (...)?; This function ignores actions and predicates. + */ + +Junction * +#ifdef __USE_PROTOS +first_item_is_guess_block( Junction *q ) +#else +first_item_is_guess_block( q ) +Junction *q; +#endif +{ + Junction * qOriginal = q; /* DEBUG */ + + /* MR14 Couldn't find aSubBlock which was a guess block when it lay + behind aLoopBlk. The aLoopBlk only appear in conjunction with + aLoopBegin, but the routine didn't know that. I think. + + MR14a Added extra parentheses to clarify precedence + + MR30 This appears to have been a mistake. The First set was then + computed incorrectly for: + + r : ( (A)? B + | C + )* + + The routine analysis_point was seeing the guess block when + it was still analyzing the loopBegin block. As a consequence, + when it looked for the analysis_point it was processing the B, but + skipping over the C alternative altogether because it thought + it was looking at a guess block, not realizing there was a loop + block in front of the loopBegin. + + loopBegin loopBlk subBlk/guess A G EB G B EB EB EB ER + | | | ^ ^ + | | | | + | +-> G C G ----------------------+ | + | | + +--- G G G -------------------------------------+ + + Reported by Arpad Beszedes (beszedes@inf.u-szeged.hu). + + MR30 This is still more complicated. This fix caused ambiguity messages + to be reported for "( (A B)? )* A B" but not for "( (A B)? )+". Why is + there a difference when these are outwardly identical ? It is because the + start of a (...)* block is represented by two nodes: a loopBegin block + followed by a loopBlock whereas the start of a (...)+ block is + represented as a single node: a plusBlock. So if first_item_is_guess_block + is called when the current node is a loopBegin it starts with the + loop block rather than the the sub block which follows the loop block. + However, we can't just skip past the loop block because some routines + depend on the old implementation. So, we provide a new implementation + which does skip the loopBlock. However, which should be called when ? + I'm not sure, but my guess is that first_item_is_guess_block_extra (the + new one) should only be called for the ambiguity routines. + + */ + + while ( q!=NULL && + ( ( q->ntype==nAction ) || + ( q->ntype==nJunction && + (q->jtype==Generic /*** || q->jtype == aLoopBlk ***/ ) /*** MR30 Undo MR14 change ***/ + ) + ) + ) + { + if ( q->ntype==nJunction ) q = (Junction *)q->p1; + else q = (Junction *) ((ActionNode *)q)->next; + } + + if ( q==NULL ) return NULL; + if ( q->ntype!=nJunction ) return NULL; + if ( q->jtype!=aSubBlk ) return NULL; + if ( !q->guess ) return NULL; + + return q; +} + +/* MR1 */ +/* MR1 10-Apr-97 MR1 Routine to stringize failed semantic predicates msgs */ +/* MR1 */ + +#define STRINGIZEBUFSIZE 1024 + +static char stringizeBuf[STRINGIZEBUFSIZE]; +char * +#ifdef __USE_PROTOS +stringize(char * s) +#else +stringize(s) +char *s; +#endif + +{ + char *p; + char *stop; + + p=stringizeBuf; + stop=&stringizeBuf[1015]; + + if (s != 0) { + while (*s != 0) { + if (p >= stop) { + goto stringizeStop; + } else if (*s == '\n') { + *p++='\\'; + *p++='n'; + *p++='\\'; + *p++=*s++; + } else if (*s == '\\') { + *p++=*s; + *p++=*s++; + } else if (*s == '\"') { + *p++='\\'; + *p++=*s++; + while (*s != 0) { + if (p >= stop) { + goto stringizeStop; + } else if (*s == '\n') { + *p++='\\'; + *p++=*s++; + } else if (*s == '\\') { + *p++=*s++; + *p++=*s++; + } else if (*s == '\"') { + *p++='\\'; + *p++=*s++; + break; + } else { + *p++=*s++; + }; + }; + } else if (*s == '\'') { + *p++=*s++; + while (*s != 0) { + if (p >= stop) { + goto stringizeStop; + } else if (*s == '\'') { + *p++=*s++; + break; + } else if (*s == '\\') { + *p++=*s++; + *p++=*s++; + } else if (*s == '\"') { + *p++='\\'; + *p++=*s++; + break; + } else { + *p++=*s++; + }; + }; + } else { + *p++=*s++; + }; + }; + }; + goto stringizeExit; +stringizeStop: + *p++='.'; + *p++='.'; + *p++='.'; +stringizeExit: + *p=0; + return stringizeBuf; +} + +#ifdef __USE_PROTOS +int isNullAction(char *s) +#else +int isNullAction(s) + char *s; +#endif +{ + char *p; + for (p=s; *p != '\0' ; p++) { + if (*p != ';' && *p !=' ') return 0; + }; + return 1; +} +/* MR1 */ +/* MR1 End of Routine to stringize code for failed predicates msgs */ +/* MR1 */ + +/* Generate an action. Don't if action is NULL which means that it was already + * handled as an init action. + */ +void +#ifdef __USE_PROTOS +genAction( ActionNode *p ) +#else +genAction( p ) +ActionNode *p; +#endif +{ + require(p!=NULL, "genAction: invalid node and/or rule"); + require(p->ntype==nAction, "genAction: not action"); + + if ( !p->done ) /* MR10 */ /* MR11 */ + { + if ( p->is_predicate) + { + if ( p->guardpred != NULL ) + { + Predicate *guardDup=predicate_dup(p->guardpred); /* MR10 */ + gen("if (!"); + guardDup=genPredTreeMain(guardDup, (Node *)p); + predicate_free(guardDup); + } +/* MR10 */ else if (p->ampersandPred != NULL) { +/* MR10 */ gen("if (!"); +/* MR10 */ p->ampersandPred=genPredTreeMain(p->ampersandPred, (Node *)p); +/* MR10 */ } + else + { + gen("if (!("); + /* make sure that '#line n' is on front of line */ + if ( GenLineInfo && p->file != -1 ) _gen("\n"); + dumpPredAction(p,p->action, output, 0, p->file, p->line, 0); + _gen(")"); + } + +/* MR23 Change failed predicate macro to have three arguments: + + macro arg 1: The stringized predicate itself + macro arg 2: 0 => no user-defined error action + 1 => user-defined error action + macro arg 3: The user-defined error action + + This gives the user more control of the error action. +*/ + tabs++; + gen3(") {zzfailed_pred(\"%s\",%s, { %s } );}\n", /* MR23 */ + stringize(p->action), /* MR23 */ + (p->pred_fail == NULL ? /* MR23/MR27 */ + "0 /* report */" : "1 /* user action */"), /* MR23/MR27 */ + (p->pred_fail == NULL ? /* MR23 */ + "0; /* no user action */" : p->pred_fail)); /* MR23 */ + tabs--; + } + else /* not a predicate */ + { + if (! isNullAction(p->action) && !p->noHoist) { + if ( FoundGuessBlk ) { + if ( GenCC ) { + gen("if ( !guessing ) {\n"); + } else { + gen("zzNON_GUESS_MODE {\n"); + }; + }; + dumpActionPlus(p, p->action, output, tabs, p->file, p->line, 1); /* MR21 */ + if ( FoundGuessBlk ) gen("}\n"); + }; + } + } + TRANS(p->next) +} + +/* + * if invoking rule has !noAST pass zzSTR to rule ref and zzlink it in + * else pass addr of temp root ptr (&_ast) (don't zzlink it in). + * + * if ! modifies rule-ref, then never link it in and never pass zzSTR. + * Always pass address of temp root ptr. + */ +void +#ifdef __USE_PROTOS +genRuleRef( RuleRefNode *p ) +#else +genRuleRef( p ) +RuleRefNode *p; +#endif +{ + Junction *q; + char *handler_id = ""; + RuleEntry *r, *r2; + char *parm = "", *exsig = ""; + + int genRuleRef_emittedGuessGuard=0; /* MR10 */ + + require(p!=NULL, "genRuleRef: invalid node and/or rule"); + require(p->ntype==nRuleRef, "genRuleRef: not rule reference"); + + if ( p->altstart!=NULL && p->altstart->exception_label!=NULL ) + handler_id = p->altstart->exception_label; + + r = (RuleEntry *) hash_get(Rname, p->text); + if ( r == NULL ) + { + warnFL( eMsg1("rule %s not defined", + p->text), FileStr[p->file], p->line ); + return; + } + +/* MR8 5-Aug-97 Reported by S.Bochnak@microtool.com.pl */ +/* Don't do assign when no return values declared */ +/* Move definition of q up and use it to guard p->assign */ + + q = RulePtr[r->rulenum]; /* find definition of ref'd rule */ /* MR8 */ + + r2 = (RuleEntry *) hash_get(Rname, p->rname); + if ( r2 == NULL ) {warnNoFL("Rule hash table is screwed up beyond belief"); return;} + + OutLineInfo(output,p->line,FileStr[p->file]); + + if ( GenCC && GenAST ) { + gen("_ast = NULL;\n"); + } + + if ( FoundGuessBlk && p->assign!=NULL && q->ret != NULL ) { /* MR8 */ + if ( GenCC ) { + gen("if ( !guessing ) {\n"); + } else { + gen("zzNON_GUESS_MODE {\n"); + }; + tabs++; /* MR11 */ + genRuleRef_emittedGuessGuard=1; /* MR11 */ + }; + + if ( FoundException ) exsig = "&_signal"; + + tab(); + if ( GenAST ) + { + if ( GenCC ) { +/**** if ( r2->noAST || p->astnode==ASTexclude ) +****/ + { +/**** _gen("_ast = NULL;\n"); +****/ + parm = "&_ast"; + } +/*** we always want to set just a pointer now, then set correct +pointer after + + else { + _gen("_astp = +(_tail==NULL)?(&_sibling):(&(_tail->_right));\n"); + parm = "_astp"; + } +****/ + } + else { + if ( r2->noAST || p->astnode==ASTexclude ) + { + _gen("_ast = NULL; "); + parm = "&_ast"; + } + else parm = "zzSTR"; + } + if ( p->assign!=NULL && q->ret!=NULL ) /* MR8 */ + { + if ( !hasMultipleOperands(p->assign) ) {_gen1("%s = ",p->assign);} /* MR23 */ + else _gen1("{ struct _rv%d _trv; _trv = ", r->rulenum); + } + if ( FoundException ) { + _gen5("%s%s(%s,&_signal%s%s); ", + RulePrefix, + p->text, + parm, + (p->parms!=NULL)?",":"", + (p->parms!=NULL)?p->parms:""); + if ( p->ex_group!=NULL ) { + _gen("\n"); + gen("if (_signal) {\n"); + tabs++; + dumpException(p->ex_group, 0); + tabs--; + gen("}"); + } + else { + _gen1("if (_signal) goto %s_handler;", handler_id); + } + } + else { + _gen5("%s%s(%s%s%s);", + RulePrefix, + p->text, + parm, + (p->parms!=NULL)?",":"", + (p->parms!=NULL)?p->parms:""); + } + if ( GenCC && (r2->noAST || p->astnode==ASTexclude) ) + { + /* rule has a ! or element does */ + /* still need to assign to #i so we can play with it */ + _gen("\n"); + gen2("_ast%d%d = (AST *)_ast;", BlkLevel-1, p->elnum); + } + else if ( !r2->noAST && p->astnode == ASTinclude ) + { + /* rule doesn't have a ! and neither does element */ +/* MR10 */ if (FoundGuessBlk && !genRuleRef_emittedGuessGuard) { +/* MR10 */ _gen("\n"); +/* MR10 */ if (GenCC) gen ("if (!guessing) { /* MR10 */") +/* MR10 */ else gen ("if (!zzguessing) { /* MR10 */\n"); +/* MR10 */ tabs++; +/* MR10 */ }; + if ( GenCC ) { + _gen("\n"); + gen("if ( _tail==NULL ) _sibling = _ast; else _tail->setRight(_ast);\n"); + gen2("_ast%d%d = (AST *)_ast;\n", BlkLevel-1, p->elnum); + tab(); + } + else _gen(" "); + if ( GenCC ) { + _gen("ASTBase::"); } + else _gen("zz"); + _gen("link(_root, &_sibling, &_tail);"); + +/* MR10 */ if (FoundGuessBlk && !genRuleRef_emittedGuessGuard) { /* MR10 */ +/* MR10 */ _gen("\n"); +/* MR10 */ tabs--; +/* MR10 */ if (GenCC) gen ("}; /* MR10 */") +/* MR10 */ else gen ("}; /* MR10 */"); +/* MR10 */ }; + } + } + else + { + if ( p->assign!=NULL && q->ret!=NULL ) /* MR8 */ + { + if ( !hasMultipleOperands(p->assign) ) {_gen1("%s = ",p->assign);} /* MR23 */ + else _gen1("{ struct _rv%d _trv; _trv = ", r->rulenum); + } + if ( FoundException ) { + _gen4("%s%s(&_signal%s%s); ", + RulePrefix, + p->text, + (p->parms!=NULL)?",":"", + (p->parms!=NULL)?p->parms:""); + if ( p->ex_group!=NULL ) { + _gen("\n"); + gen("if (_signal) {\n"); + tabs++; + dumpException(p->ex_group, 0); + tabs--; + gen("}"); + } + else { + _gen1("if (_signal) goto %s_handler;", handler_id); + } + } + else { + _gen3("%s%s(%s);", + RulePrefix, + p->text, + (p->parms!=NULL)?p->parms:""); + } + if ( p->assign!=NULL && q->ret!=NULL ) _gen("\n"); /* MR8 */ + } + + if ( p->assign!=NULL && q->ret!=NULL) { /* MR8 */ + if ( hasMultipleOperands(p->assign) ) /* MR23 */ + { + _gen("\n"); + dumpRetValAssign(p->assign, q->ret, p); /* MR30 */ + _gen("}"); + } + } + _gen("\n"); + + /* Handle element labels now */ + if ( p->el_label!=NULL ) + { + if ( GenAST ) + { + if ( GenCC ) { + gen3("%s_ast = _ast%d%d;\n", p->el_label, BlkLevel-1, p->elnum); + } + else {gen1("%s_ast = zzastCur;\n", p->el_label);} + } + else if (!GenCC ) { + gen1("%s = zzaCur;\n", p->el_label); + } + } + + if ( FoundGuessBlk && p->assign!=NULL && q->ret!=NULL ) { /* MR8 */ + /* in guessing mode, don't branch to handler upon error */ + tabs--; /* MR11 */ + gen("} else {\n"); + tabs++; /* MR11 */ + if ( FoundException ) { + gen6("%s%s(%s%s&_signal%s%s);\n", + RulePrefix, + p->text, + parm, + (*parm!='\0')?",":"", + (p->parms!=NULL)?",":"", + (p->parms!=NULL)?p->parms:""); + } + else { + gen5("%s%s(%s%s%s);\n", + RulePrefix, + p->text, + parm, + (p->parms!=NULL && *parm!='\0')?",":"", + (p->parms!=NULL)?p->parms:""); + } + tabs--; /* MR11 */ + gen("}\n"); + } + TRANS(p->next) +} + +/* + * Generate code to match a token. + * + * Getting the next token is tricky. We want to ensure that any action + * following a token is executed before the next GetToken(); + */ +void +#ifdef __USE_PROTOS +genToken( TokNode *p ) +#else +genToken( p ) +TokNode *p; +#endif +{ + RuleEntry *r; + char *handler_id = ""; + ActionNode *a; + char *set_name; + char *set_nameErrSet; + int complement; + int ast_label_in_action = 0; /* MR27 */ + int pushedCmodeAST = 0; /* MR27 */ + + require(p!=NULL, "genToken: invalid node and/or rule"); + require(p->ntype==nToken, "genToken: not token"); + if ( p->altstart!=NULL && p->altstart->exception_label!=NULL ) + handler_id = p->altstart->exception_label; + + r = (RuleEntry *) hash_get(Rname, p->rname); + if ( r == NULL ) {warnNoFL("Rule hash table is screwed up beyond belief"); return;} + +/* + * MR27 Has the element label been referenced as an AST (with the # operator) ? + * If so, then we'll want to build the AST even though the user has used + * the ! operator. + */ +/* MR27 */ if (GenAST && p->el_label != NULL) { +/* MR27 */ ast_label_in_action = list_search_cstring(r->ast_labels_in_actions, +/* MR27 */ p->el_label); +/* MR27 */ } + + OutLineInfo(output,p->line,FileStr[p->file]); + + if ( !set_nil(p->tset) ) /* implies '.', ~Tok, or tokenclass */ + { + unsigned e; + unsigned eErrSet = 0; + set b; + set bErrSet; /* MR23 */ + b = set_dup(p->tset); + bErrSet = set_dup(p->tset); /* MR23 */ + complement = p->complement; /* MR23 */ + if ( p->tclass!=NULL && complement == 0 /* MR23 */) { /* token class not complemented*/ + static char buf[MaxRuleName+20]; /* MR23 */ + static char bufErrSet[MaxRuleName+20]; /* MR23 */ + if ( p->tclass->dumped ) { + e = p->tclass->setnum; + eErrSet = p->tclass->setnumErrSet; + } + else { + e = DefErrSet(&b, 0, TokenString(p->token)); + eErrSet = DefErrSetWithSuffix(0, &bErrSet, 1, TokenString(p->token), "_errset"); + p->tclass->dumped = 1; /* indicate set has been created */ + p->tclass->setnum = e; + p->tclass->setnumErrSet = eErrSet; /* MR23 */ + } + sprintf(buf, "%s_set", TokenString(p->token)); + sprintf(bufErrSet, "%s_errset", TokenString(p->token)); /* MR23 */ + set_name = buf; + set_nameErrSet = bufErrSet; /* MR23 */ + } + + /* MR23 - Forgot about the case of ~TOKCLASS. */ + + else if ( p->tclass!=NULL && complement != 0 /* MR23 */) + { + static char buf[MaxRuleName+20]; /* MR23 */ + static char bufErrSet[MaxRuleName+20]; /* MR23 */ + if ( p->tclass->dumpedComplement ) { + e = p->tclass->setnumComplement; + eErrSet = p->tclass->setnumErrSetComplement; + } + else { + e = DefErrSetWithSuffix(0, &b, 0, TokenString(p->token), "_setbar"); + eErrSet = DefErrSetWithSuffix(0, &bErrSet, 1, TokenString(p->token), "_errsetbar"); + p->tclass->dumpedComplement = 1; /* indicate set has been created */ + p->tclass->setnumComplement = e; + p->tclass->setnumErrSetComplement = eErrSet; /* MR23 */ + } + sprintf(buf, "%s_setbar", TokenString(p->token)); + sprintf(bufErrSet, "%s_errsetbar", TokenString(p->token)); /* MR23 */ + set_name = buf; + set_nameErrSet = bufErrSet; /* MR23 */ + } + else { /* wild card */ + static char buf[sizeof("zzerr")+10]; + static char bufErrSet[sizeof("zzerr")+10]; + int n = DefErrSet( &b, 0, NULL ); + int nErrSet = DefErrSetWithSuffix(0, &bErrSet, 1, NULL, "_set"); + if ( GenCC ) sprintf(buf, "err%d", n); + else sprintf(buf, "zzerr%d", n); + if ( GenCC ) sprintf(bufErrSet, "err%d", nErrSet); + else sprintf(bufErrSet, "zzerr%d", nErrSet); + set_name = buf; + set_nameErrSet = bufErrSet; + } + + if ( !FoundException ) { +/* MR23 */ gen2("zzsetmatch(%s, %s);", set_name, set_nameErrSet); + } + else if ( p->ex_group==NULL ) { + if ( p->use_def_MT_handler ) + gen3("zzsetmatch_wdfltsig(%s,(ANTLRTokenType)%d,%s);", + set_name, + p->token, + tokenFollowSet(p)) + else + gen2("zzsetmatch_wsig(%s, %s_handler);", + set_name, + handler_id); + } + else + { + gen1("if ( !_setmatch_wsig(%s) ) {\n", set_name); + tabs++; +/* MR6 */ if (FoundGuessBlk) { +/* MR6 */ if ( GenCC ) {gen("if ( guessing ) goto fail;\n");} +/* MR6 */ else gen("if ( zzguessing ) goto fail;\n"); +/* MR6 */ }; + gen("_signal=MismatchedToken;\n"); + dumpException(p->ex_group, 0); + tabs--; + gen("}\n"); + } + set_free(b); + set_free(bErrSet); + } + else if ( TokenString(p->token)!=NULL ) + { + if ( FoundException ) { + if ( p->use_def_MT_handler ) + gen2("zzmatch_wdfltsig(%s,%s);",TokenString(p->token),tokenFollowSet(p)) + else if ( p->ex_group==NULL ) + { + gen2("zzmatch_wsig(%s, %s_handler);", + TokenString(p->token), + handler_id); + } + else + { +/* MR6 */ if (GenCC) { +/* MR6 */ gen1("if ( !_match_wsig(%s) ) {\n", TokenString(p->token)); +/* MR6 */ } else { +/* MR6 */ gen1("if ( !_zzmatch_wsig(%s) ) {\n", TokenString(p->token)); +/* MR6 */ }; + tabs++; +/* MR6 */ if (FoundGuessBlk) { +/* MR6 */ if ( GenCC ) {gen("if ( guessing ) goto fail;\n");} +/* MR6 */ else gen("if ( zzguessing ) goto fail;\n"); +/* MR6 */ }; + gen("_signal=MismatchedToken;\n"); + dumpException(p->ex_group, 0); + tabs--; + gen("}\n"); + } + } + else gen1("zzmatch(%s);", TokenString(p->token)); + } + else { + if ( FoundException ) { + if ( p->use_def_MT_handler ) + gen2("zzmatch_wdfltsig((ANTLRTokenType)%d,%s);", + p->token,tokenFollowSet(p)) + else + gen2("zzmatch_wsig(%d,%s_handler);",p->token,handler_id); + } + else {gen1("zzmatch(%d);", p->token);} + } + + a = findImmedAction( p->next ); + /* generate the token labels */ + if ( GenCC && p->elnum>0 ) + { + /* If building trees in C++, always gen the LT() assigns */ + if ( set_el(p->elnum, tokensRefdInBlock) || GenAST ) + { +/* MR10 */ if ( FoundGuessBlk ) { +/* MR10 */ gen("\n"); +/* MR10 */ if (p->label_used_in_semantic_pred) { +/* MR10 */ gen2(" _t%d%d = (ANTLRTokenPtr)LT(1); /* MR10 */\n", BlkLevel-1, p->elnum); +/* MR10 */ } else { +/* MR10 */ gen("if ( !guessing ) {\n"); tab(); +/* MR10 */ _gen2(" _t%d%d = (ANTLRTokenPtr)LT(1);\n", BlkLevel-1, p->elnum); +/* MR10 */ gen("}\n"); +/* MR10 */ }; +/* MR10 */ } else { +/* MR10 */ _gen2(" _t%d%d = (ANTLRTokenPtr)LT(1);", BlkLevel-1, p->elnum); +/* MR10 */ }; +/* MR10 */ + } + +/* + * MR23 labase is never used in the C++ runtime library. + * and this code is generated only in C++ mode + */ + +/*** if ( LL_k>1 ) / * MR23 disabled */ +/*** if ( !DemandLookahead ) _gen(" labase++;"); / * MR23 disabled */ +/*** _gen("\n"); / * MR23 disabled */ +/*** tab(); / * MR23 disabled */ + } + if ( GenAST ) + { + if ( FoundGuessBlk && + (ast_label_in_action || !(p->astnode == ASTexclude || r->noAST)) ) + { + if ( GenCC ) {_gen("if ( !guessing ) {\n"); tab();} + else {_gen("zzNON_GUESS_MODE {\n"); tab();} + } + +/* MR27 addition when labels referenced when operator ! used */ + + pushedCmodeAST = 0; /* MR27 */ + if (ast_label_in_action && (p->astnode == ASTexclude || r->noAST)) { + _gen("\n"); + if (GenCC) { +/* MR13 */ if (NewAST) { +/* MR13 */ gen4("_ast%d%d = newAST(_t%d%d); /* MR27 */\n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum); +/* MR13 */ } else { +/* MR13 */ gen4("_ast%d%d = new AST(_t%d%d); /* MR27 */\n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum); +/* MR13 */ } + } + else { + pushedCmodeAST = 1; + gen("zzastPush(zzmk_ast(zzastnew(),zzaCur)); /* MR27 */"); + } + } + +/* end MR27 addition for labels referenced when operator ! used */ + + if (!r->noAST ) + { + if (GenCC && !(p->astnode == ASTexclude) ) { + _gen("\n"); +/* MR13 */ if (NewAST) { +/* MR13 */ gen4("_ast%d%d = newAST(_t%d%d);\n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum); +/* MR13 */ } else { +/* MR13 */ gen4("_ast%d%d = new AST(_t%d%d);\n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum); +/* MR13 */ } + tab(); + } + if ( GenCC && !(p->astnode == ASTexclude) ) + {_gen2("_ast%d%d->", BlkLevel-1, p->elnum);} + else _gen(" "); + if ( p->astnode==ASTchild ) { + if ( !GenCC ) _gen("zz"); + _gen("subchild(_root, &_sibling, &_tail);"); + } + else if ( p->astnode==ASTroot ) { + if ( !GenCC ) _gen("zz"); + _gen("subroot(_root, &_sibling, &_tail);"); + } + if ( GenCC && !(p->astnode == ASTexclude) ) { + _gen("\n"); + tab(); + } + } + else if ( !GenCC ) { + if (! pushedCmodeAST) _gen(" zzastDPush;"); + } + if ( FoundGuessBlk && + (ast_label_in_action || !(p->astnode == ASTexclude || r->noAST)) ) + {gen("}\n"); tab();} + } + + /* Handle element labels now */ + if ( p->el_label!=NULL ) + { + int done_NON_GUESSMODE=0; + + _gen("\n"); + +/* MR10 */ /* do Attrib / Token ptr for token label used in semantic pred */ +/* MR10 */ /* for these cases do assign even in guess mode */ +/* MR10 */ +/* MR10 */ if (p->label_used_in_semantic_pred) { +/* MR10 */ if ( GenCC ) { +/* MR10 */ if ( set_el(p->elnum, tokensRefdInBlock) || GenAST ) { +/* MR10 */ gen3("%s = _t%d%d;", p->el_label, BlkLevel-1, p->elnum); +/* MR10 */ } else { +/* MR10 */ gen1("%s = (ANTLRTokenPtr)LT(1);\n", p->el_label); +/* MR10 */ }; +/* MR10 */ } else { +/* MR10 */ gen1("%s = zzaCur;", p->el_label); +/* MR10 */ }; +/* MR10 */ if (FoundGuessBlk) _gen(" /* MR10 */"); +/* MR10 */ _gen("\n"); +/* MR10 */ }; + + /* Do Attrib / Token ptr */ + +/* MR10 */ if (! p->label_used_in_semantic_pred) { +/* MR10 */ +/* MR10 */ if ( FoundGuessBlk ) { +/* MR10 */ if (! done_NON_GUESSMODE) { +/* MR10 */ done_NON_GUESSMODE=1; +/* MR10 */ if ( GenCC ) {gen("if ( !guessing ) {\n"); tab();} +/* MR10 */ else {gen("zzNON_GUESS_MODE {\n"); tab();} +/* MR10 */ }; +/* MR10 */ }; +/* MR10 */ +/* MR10 */ if ( GenCC ) { +/* MR10 */ if ( set_el(p->elnum, tokensRefdInBlock) || GenAST ) { +/* MR10 */ gen3("%s = _t%d%d;\n", p->el_label, BlkLevel-1, p->elnum); +/* MR10 */ } else { +/* MR10 */ gen1("%s = (ANTLRTokenPtr)LT(1);\n", p->el_label); +/* MR10 */ }; +/* MR10 */ } else { +/* MR10 */ gen1("%s = zzaCur;\n", p->el_label); +/* MR10 */ }; +/* MR10 */ }; + + /* Do AST ptr */ + + if (GenAST && (ast_label_in_action || !(p->astnode == ASTexclude || r->noAST) )) /* MR27 */ + { + +/* MR10 */ if ( FoundGuessBlk ) { +/* MR10 */ if (! done_NON_GUESSMODE) { +/* MR10 */ done_NON_GUESSMODE=1; +/* MR10 */ if ( GenCC ) {gen("if ( !guessing ) {\n"); tab();} +/* MR10 */ else {gen("zzNON_GUESS_MODE {\n"); tab();} +/* MR10 */ }; +/* MR10 */ }; + + if ( GenCC ) { + gen3("%s_ast = _ast%d%d;\n", p->el_label, BlkLevel-1, p->elnum); + } + else {gen1("%s_ast = zzastCur;\n", p->el_label);} + } + +/* MR10 */ if (done_NON_GUESSMODE) { +/* MR10 */ gen("}\n"); tab(); +/* MR10 */ }; + + } + + /* Handle any actions immediately following action */ + if ( a != NULL ) /* MR10 */ /* MR11 */ + { + /* delay next token fetch until after action */ + _gen("\n"); + if ( a->is_predicate) + { +#if 0 +/* Disabled in MR30 ************************************************************ + And moved into genAction + ***************************************************************************** +*/ + + gen("if (!("); + + /* make sure that '#line n' is on front of line */ /* MR14 */ + if ( GenLineInfo && p->file != -1 ) _gen("\n"); /* MR14 */ + dumpPredAction(a,a->action, output, 0, a->file, a->line, 0); + +/* MR23 Change failed predicate macro to have three arguments: + + macro arg 1: The stringized predicate itself + macro arg 2: 0 => no user-defined error action + 1 => user-defined error action + macro arg 3: The user-defined error action + + This gives the user more control of the error action. +*/ + _gen(")) \n"); + tabs++; + gen3(" {zzfailed_pred(\"%s\",%s,{ %s } );}\n", /* MR23 */ + stringize(a->action), /* MR23 */ + (a->pred_fail == NULL ? /* MR23/MR27 */ + "0 /* report */" : "1 /* user action */"), /* MR23/MR27 */ + (a->pred_fail == NULL ? /* MR23 */ + "0; /* no user action */" : a->pred_fail)); /* MR23 */ + tabs--; +/* Disabled in MR30 ************************************************************ + And moved into genAction + ***************************************************************************** +*/ +#endif + } + else /* MR9 a regular action - not a predicate action */ + { + +/* MR23: Search an action which is not a predicate for LT(i), + LA(i), or LATEXT(i) in order to warn novice users that + it refers to the previous matched token, not the next + one. This is different than the case for semantic + predicates. +*/ + +/* MR23 */ if (GenCC) { +/* MR23 */ if (strstr(a->action, "LT(") != NULL) LTinTokenAction = 1; +/* MR23 */ } +/* MR23 */ else { +/* MR23 */ if (strstr(a->action, "LA(") != NULL) LTinTokenAction = 1; +/* MR23 */ if (strstr(a->action, "LATEXT(") != NULL) LTinTokenAction = 1; +/* MR23 */ } + + if ( FoundGuessBlk ) { + if ( GenCC ) {gen("if ( !guessing ) {\n");} + else gen("zzNON_GUESS_MODE {\n"); + } + dumpActionPlus(a, a->action, output, tabs, a->file, a->line, 1); /* MR21 */ + if ( FoundGuessBlk ) gen("}\n"); + a->done = 1; /* MR30 */ + } +/*** a->done = 1; MR30 Moved up into then branch for true actions, but not predicates ***/ + if ( !DemandLookahead ) { + if ( GenCC ) { + if ( FoundException && p->use_def_MT_handler ) gen("if (!_signal)"); + _gen(" consume();") + if ( FoundException && p->use_def_MT_handler ) + _gen(" _signal=NoSignal;"); + _gen("\n"); + } + else + { + if ( FoundException && p->use_def_MT_handler ) _gen("if (!_signal)"); + _gen(" zzCONSUME;\n"); + if ( FoundException && p->use_def_MT_handler ) _gen(" _signal=NoSignal;"); + _gen("\n"); + } + } + else gen("\n"); + if (a->done) { /* MR30 */ + TRANS( a->next ); /* MR30 */ + } /* MR30 */ + else { /* MR30 */ + TRANS( p->next ); /* MR30 */ + } /* MR30 */ + } + else + { + if ( !DemandLookahead ) { + if ( GenCC ) { + if (FoundException && p->use_def_MT_handler) _gen("if (!_signal)"); + _gen(" consume();") + if (FoundException&&p->use_def_MT_handler) _gen(" _signal=NoSignal;"); + _gen("\n"); + } + else { + if (FoundException && p->use_def_MT_handler) _gen("if (!_signal)"); + _gen(" zzCONSUME;"); + if ( FoundException && p->use_def_MT_handler ) _gen(" _signal=NoSignal;"); + _gen("\n"); + } + } + else _gen("\n"); + TRANS(p->next); + } +} + +/* MR21 + * + * There was a bug in the code generation for {...} which causes it + * to omit the optional tokens from the error messages. The easiest + * way to fix this was to make the opt block look like a sub block: + * + * { a | b | c } + * + * becomes (internally): + * + * ( a | b | c | ) + * + * The code for genOptBlk is now identical to genSubBlk except for + * cosmetic changes. + */ + +void +#ifdef __USE_PROTOS +genOptBlk( Junction *q ) +#else +genOptBlk( q ) +Junction *q; +#endif +{ + int max_k; + set f; + int need_right_curly; + set savetkref; + int lastAltEmpty; /* MR23 */ + savetkref = tokensRefdInBlock; + require(q->ntype == nJunction, "genOptBlk: not junction"); + require(q->jtype == aOptBlk, "genOptBlk: not opt block"); + + OutLineInfo(output,q->line,FileStr[q->file]); + BLOCK_Preamble(q); + BlkLevel++; + BlockPreambleOption(q,q->pFirstSetSymbol); /* MR21 */ + f = genBlk(q, aOptBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */); +/* MR23 + Bypass error clause generation when exceptions are used in {...} block + See multi-line note in genBlk near call to isEmptyAlt. +*/ + if (! FoundException) { + if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k,0 /* use plus block bypass ? */ );} + } + else { + gen("/* MR23 skip error clause for {...} when exceptions in use */\n"); + } + { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} } + freeBlkFsets(q); + --BlkLevel; + BLOCK_Tail(); + + if ( q->guess ) + { + gen("zzGUESS_DONE\n"); + } + + /* must duplicate if (alpha)?; one guesses (validates), the + * second pass matches */ + if ( q->guess && analysis_point(q)==q ) + { + OutLineInfo(output,q->line,FileStr[q->file]); + BLOCK_Preamble(q); + BlkLevel++; + f = genBlk(q, aSubBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */); + if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k,0 /* use plus block bypass ? */ );} + { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} } + freeBlkFsets(q); + --BlkLevel; + BLOCK_Tail(); + } + + tokensRefdInBlock = savetkref; + if (q->end->p1 != NULL) TRANS(q->end->p1); +} + +/* + * Generate code for a loop blk of form: + * + * |---| + * v | + * --o-G-o-->o-- + */ +void +#ifdef __USE_PROTOS +genLoopBlk( Junction *begin, Junction *q, Junction *start, int max_k ) +#else +genLoopBlk( begin, q, start, max_k ) +Junction *begin; +Junction *q; +Junction *start; /* where to start generating code from */ +int max_k; +#endif +{ + set f; + int need_right_curly; + set savetkref; + Junction *guessBlock; /* MR10 */ + int singleAlt; /* MR10 */ + int lastAltEmpty; /* MR23 */ + + savetkref = tokensRefdInBlock; + require(q->ntype == nJunction, "genLoopBlk: not junction"); + require(q->jtype == aLoopBlk, "genLoopBlk: not loop block"); + + if ( q->visited ) return; + q->visited = TRUE; + + /* first_item_is_guess_block doesn't care what kind of node it is */ + + guessBlock=first_item_is_guess_block( (Junction *) q->p1); /* MR10 */ + singleAlt=q->p2==NULL; /* MR10 */ + + if (singleAlt && !guessBlock) /* MR10 */ /* only one alternative? */ + { + if ( DemandLookahead ) { + if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);} + else gen1("look(%d);\n", max_k); + } + gen("while ( "); + if ( begin!=NULL ) genExpr(begin); + else genExpr(q); + /* if no predicates have been hoisted for this single alt (..)* + * do so now + */ + require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); + if ( ParseWithPredicates && begin->predicate==NULL ) + { + Predicate *a = MR_find_predicates_and_supp((Node *)q->p1); + require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); + + if ( a!=NULL ) + { + _gen("&&"); + a=genPredTreeMain(a, (Node *)q); /* MR10 */ + } +/* MR10 */ if (MRhoisting) { +/* MR10 */ predicate_free(a); +/* MR10 */ }; + } + _gen(" ) {\n"); + tabs++; + TRANS(q->p1); + if ( !GenCC ) gen1("zzLOOP(zztasp%d);\n", BlkLevel-1); + if ( DemandLookahead ) { + if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);} + else gen1("look(%d);\n", max_k); + } + --tabs; + gen("}\n"); + freeBlkFsets(q); + q->visited = FALSE; + tokensRefdInBlock = savetkref; + return; + } + gen("for (;;) {\n"); /* MR20 G. Hobbelt */ + tabs++; +/* MR6 */ +/* MR6 "begin" can never be null when called from genLoopBegin */ +/* MR6 because q==(Junction *)begin->p1 and we know q is valid */ +/* MR6 */ +/* MR6 from genLoopBegin: */ +/* MR6 */ +/* MR6 if ( LL_k>1 && !set_nil(q->fset[2]) ) */ +/* MR6 genLoopBlk( q, (Junction *)q->p1, q, max_k ); */ +/* MR6 else genLoopBlk( q, (Junction *)q->p1, NULL, max_k ); */ +/* MR6 */ + if ( begin!=NULL ) + { + if ( DemandLookahead ) + { + if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);} + else gen1("look(%d);\n", max_k); + } + /* The bypass arc of the (...)* predicts what to do when you fail, but + * ONLY after having tested the loop start expression. To avoid this, + * we simply break out of the (...)* loop when we find something that + * is not in the prediction of the loop (all alts thereof). + */ + gen("if ( !("); + +/*** TJP says: It used to use the prediction expression for the bypass arc + of the (...)*. HOWEVER, if a non LL^1(k) decision was found, this + thing would miss the ftree stored in the aLoopBegin node and generate + an LL^1(k) decision anyway. + + *** genExpr((Junction *)begin->p2); + ***/ + + genExpr((Junction *)begin); + _gen(")) break;\n"); + + } + + /* generate code for terminating loop (this is optional branch) */ + + f = genBlk(q, aLoopBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */); + set_free(f); + freeBlkFsets(q); + + /* generate code for terminating loop (this is optional branch) */ + +/* MR6 */ +/* MR6 30-May-97 Bug reported by Manuel Ornato */ +/* MR6 A definite bug involving the exit from a loop block */ +/* MR6 In 1.23 and later versions (including 1.33) Instead */ +/* MR6 exiting the block and reporting a syntax error the */ +/* MR6 code loops forever. */ +/* MR6 Looking at 1.20 which generates proper code it is not */ +/* MR6 clear which of two changes should be undone. */ +/* MR6 This is my best guess. */ +/* MR6 From earlier MR6 note we know that begin can never be */ +/* MR6 null when genLoopBlk called from genLoopBegin */ +/* MR6 */ +/* MR6 */ if ( begin==NULL) { +/* MR6 */ /* code for exiting loop "for sure" */ +/* MR6 */ gen("/* Suppressed by MR6 */ /*** else break; ***/\n"); +/* MR6 */ }; + +/* MR10 */if (singleAlt && guessBlock) { +/* MR10 */ tabs--; +/* MR6 */ gen("} else break; /* MR6 code for exiting loop \"for sure\" */\n"); +/* MR10 */ need_right_curly--; +/* MR10 */ } else { +/* MR6 */ gen("else break; /* MR6 code for exiting loop \"for sure\" */\n"); +/* MR10 */ }; + + { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} } + if ( !GenCC ) gen1("zzLOOP(zztasp%d);\n", BlkLevel-1); + --tabs; + gen("}\n"); + q->visited = FALSE; + tokensRefdInBlock = savetkref; +} + +/* + * Generate code for a loop blk of form: + * + * |---| + * v | + * --o-->o-->o-G-o-->o-- + * | ^ + * v | + * o-----------o + * + * q->end points to the last node (far right) in the blk. + * + * Note that q->end->jtype must be 'EndBlk'. + * + * Generate code roughly of the following form: + * + * do { + * ... code for alternatives ... + * } while ( First Set of aLoopBlk ); + * + * OR if > 1 alternative + * + * do { + * ... code for alternatives ... + * else break; + * } while ( 1 ); + */ +void +#ifdef __USE_PROTOS +genLoopBegin( Junction *q ) +#else +genLoopBegin( q ) +Junction *q; +#endif +{ + set f; + int i; + int max_k; + set savetkref; + savetkref = tokensRefdInBlock; + require(q!=NULL, "genLoopBegin: invalid node and/or rule"); + require(q->ntype == nJunction, "genLoopBegin: not junction"); + require(q->jtype == aLoopBegin, "genLoopBegin: not loop block"); + require(q->p2!=NULL, "genLoopBegin: invalid Loop Graph"); + + OutLineInfo(output,q->line,FileStr[q->file]); + + BLOCK_Preamble(q); + BlkLevel++; + BlockPreambleOption(q,q->pFirstSetSymbol); /* MR21 */ + f = First(q, 1, aLoopBegin, &max_k); + /* If not simple LL(1), must specify to start at LoopBegin, not LoopBlk */ + if ( LL_k>1 && !set_nil(q->fset[2]) ) + genLoopBlk( q, (Junction *)q->p1, q, max_k ); + else genLoopBlk( q, (Junction *)q->p1, NULL, max_k ); + + for (i=1; i<=CLL_k; i++) set_free(q->fset[i]); + for (i=1; i<=CLL_k; i++) set_free(((Junction *)q->p2)->fset[i]); + --BlkLevel; + BLOCK_Tail(); + set_free(f); + tokensRefdInBlock = savetkref; +/* MR21 */ if (MR_BlkErr) { +/* MR21 */ set f, fArray[2]; +/* MR21 */ f = ComputeErrorSet(q,1,0 /* use plus block bypass ? */ ); +/* MR21 */ fArray[0]= empty; +/* MR21 */ fArray[1]= set_dup(f); +/* MR21 */ gen("if ("); +/* MR21 */ genExprSets(fArray,1); /* note: destroys set arguments */ +/* MR21 */ _gen(") { /* MR21 option -mrblksynerr */\n"); +/* MR21 */ tabs++; +/* MR21 */ tab(); +/* MR21 */ _gen("/* nothing */ }\n"); +/* MR21 */ tab(); +/* MR21 */ makeErrorClause(q,f,1,0 /* use plus block bypass ? */ ); /* frees set */ +/* MR21 */ tabs--; +/* MR21 */ }; + if (q->end->p1 != NULL) TRANS(q->end->p1); +} + +/* + * Generate code for a loop blk of form: + * + * |---| + * v | + * --o-G-o-->o-- + * + * q->end points to the last node (far right) in the blk. + * Note that q->end->jtype must be 'EndBlk'. + * + * Generate code roughly of the following form: + * + * do { + * ... code for alternatives ... + * } while ( First Set of aPlusBlk ); + * + * OR if > 1 alternative + * + * do { + * ... code for alternatives ... + * else if not 1st time through, break; + * } while ( 1 ); + */ +void +#ifdef __USE_PROTOS +genPlusBlk( Junction *q ) +#else +genPlusBlk( q ) +Junction *q; +#endif +{ + int max_k; + set f; + int need_right_curly; + int lastAltEmpty; /* MR23 */ + set savetkref; + Junction *guessBlock; /* MR10 */ + int singleAlt; /* MR10 */ + + savetkref = tokensRefdInBlock; + require(q!=NULL, "genPlusBlk: invalid node and/or rule"); + require(q->ntype == nJunction, "genPlusBlk: not junction"); + require(q->jtype == aPlusBlk, "genPlusBlk: not Plus block"); + require(q->p2 != NULL, "genPlusBlk: not a valid Plus block"); + + if ( q->visited ) return; + q->visited = TRUE; + OutLineInfo(output,q->line,FileStr[q->file]); + BLOCK_Preamble(q); + BlkLevel++; + + BlockPreambleOption((Junction *)q, q->pFirstSetSymbol); /* MR21 */ + + /* first_item_is_guess_block doesn't care what kind of node it is */ + + guessBlock=first_item_is_guess_block( (Junction *)q->p1); /* MR10 */ + + /* if the ignore flag is set on the 2nd alt and that alt is empty, + * then it is the implied optional alternative that we added for (...)+ + * and, hence, only 1 alt. + */ + +/* MR10 Reported by Pulkkinen Esa (esap@cs.tut.fi) + * Outer code for guess blocks ignored when there is only one alt + * for a (...)+ block. + * Force use of regular code rather than "optimized" code for that case + */ + + singleAlt=( ( (Junction *) q->p2)->p2 == NULL) && + ( ( (Junction *) q->p2)->ignore ); /* only one alternative? */ + + if (singleAlt && !guessBlock) /* MR10 */ + { + + Predicate *a=NULL; + /* if the only alt has a semantic predicate, hoist it; must test before + * entering loop. + */ + if ( ParseWithPredicates ) + { + require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); + a = MR_find_predicates_and_supp((Node *)q); + require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); + + if ( a!=NULL ) { + gen("if ("); + a=genPredTreeMain(a, (Node *)q); /* MR10 */ + _gen(") {\n"); + } + } + gen("do {\n"); + tabs++; + TRANS(q->p1); + if ( !GenCC ) gen1("zzLOOP(zztasp%d);\n", BlkLevel-1); + f = First(q, 1, aPlusBlk, &max_k); + if ( DemandLookahead ) { + if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);} + else gen1("look(%d);\n", max_k); + } + --tabs; + gen("} while ( "); + if ( q->parm!=NULL && q->predparm ) _gen1("(%s) && ", q->parm); + genExpr(q); + if ( ParseWithPredicates && a!=NULL ) + { + if (! MR_comparePredicates(q->predicate,a)) { + _gen("&&"); + a=genPredTreeMain(a, (Node *)q); /* MR10 */ + }; + } + _gen(" );\n"); + if ( ParseWithPredicates && a!=NULL ) gen("}\n"); + --BlkLevel; + BLOCK_Tail(); + q->visited = FALSE; + freeBlkFsets(q); + set_free(f); + tokensRefdInBlock = savetkref; +/* MR21 */ if (MR_BlkErr) { +/* MR21 */ set f, fArray[2]; +/* MR21 */ f = ComputeErrorSet(q,1,1 /* use plus block bypass ? */ ); +/* MR21 */ fArray[0]= empty; +/* MR21 */ fArray[1]= set_dup(f); +/* MR21 */ gen("if ("); +/* MR21 */ genExprSets(fArray,1); /* note: destroys set arguments */ +/* MR21 */ _gen(") { /* MR21 option -mrblksynerr */\n"); +/* MR21 */ tabs++; +/* MR21 */ tab(); +/* MR21 */ _gen("/* nothing */ }\n"); +/* MR21 */ tab(); +/* MR21 */ makeErrorClause(q,f,1,1 /* use plus block bypass ? */ ); /* frees set */ +/* MR21 */ tabs--; +/* MR21 */ }; + if (q->end->p1 != NULL) TRANS(q->end->p1); +/* MR10 */ if (MRhoisting) { +/* MR10 */ predicate_free(a); +/* MR10 */ }; + return; + } + gen("do {\n"); + tabs++; + f = genBlk(q, aPlusBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */); +/* MR6 */ +/* MR6 Sinan Karasu (sinan@tardis.ds.boeing.com) */ +/* MR6 Failed to turn off guess mode when leaving block */ +/* MR6 */ +/* MR6 */ if ( has_guess_block_as_last_item(q) ) { +/* MR10 */ gen("/* MR10 ()+ */ else {\n"); +/* MR10 */ tabs++; +/* MR10 */ need_right_curly++; +/* MR10 */ gen("/* MR10 ()+ */ if ( !zzrv ) zzGUESS_DONE;\n"); +/* MR6 */ gen("/* MR10 ()+ */ if ( zzcnt > 1 ) break;\n"); +/* MR10 */ } else { +/* MR10 */ gen("/* MR10 ()+ */ else {\n"); +/* MR10 */ tabs++; +/* MR10 */ need_right_curly++; +/* MR10 */ gen("if ( zzcnt > 1 ) break;\n"); +/* MR10 */ }; + +/* MR21 */ if (MR_BlkErr && 1 >= max_k) { +/* MR21 */ set f; +/* MR21 */ f = ComputeErrorSet(q,1,0 /* use plus block bypass ? */ ); +/* MR21 */ tabs++; +/* MR21 */ tab(); +/* MR21 */ makeErrorClause(q,f,1,0 /* use plus block bypass ? */ ); /* frees set */ +/* MR21 */ tabs--; +/* MR21 */ } +/* MR21 */ else { + tab(); + makeErrorClause(q,f,max_k,1 /* use plus block bypass ? */); + /* MR21 I think this generates the wrong set ? */ + /* MR21 because it includes the plus block bypass ? */ + /* MR21 but I'm afraid to change it without additional checking */ + } + + { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} } + freeBlkFsets(q); + gen("zzcnt++;"); + if ( !GenCC ) _gen1(" zzLOOP(zztasp%d);", BlkLevel-1); + _gen("\n"); + if ( DemandLookahead ) { + if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);} + else gen1("look(%d);\n", max_k); + } + --tabs; + if ( q->parm!=NULL && q->predparm ) {gen1("} while (%s);\n", q->parm);} + else gen("} while ( 1 );\n"); + --BlkLevel; + BLOCK_Tail(); + q->visited = FALSE; + tokensRefdInBlock = savetkref; +/* MR21 */ if (MR_BlkErr) { +/* MR21 */ set f, fArray[2]; +/* MR21 */ f = ComputeErrorSet(q,1,1 /* use plus block bypass ? */ ); +/* MR21 */ fArray[0]= empty; +/* MR21 */ fArray[1]= set_dup(f); +/* MR21 */ gen("if ("); +/* MR21 */ genExprSets(fArray,1); /* note: destroys set arguments */ +/* MR21 */ _gen(") { /* MR21 option -mrblksynerr */\n"); +/* MR21 */ tabs++; +/* MR21 */ tab(); +/* MR21 */ _gen("/* nothing */ }\n"); +/* MR21 */ tab(); +/* MR21 */ makeErrorClause(q,f,1,1 /* use plus block bypass ? */ ); /* frees set */ +/* MR21 */ tabs--; +/* MR21 */ }; + if (q->end->p1 != NULL) TRANS(q->end->p1); +} + +/* + * Generate code for a sub blk of alternatives of form: + * + * --o-G1--o-- + * | ^ + * v /| + * o-G2-o| + * | ^ + * v | + * .......... + * | ^ + * v / + * o-Gn-o + * + * q points to the 1st junction of blk (upper-left). + * q->end points to the last node (far right) in the blk. + * Note that q->end->jtype must be 'EndBlk'. + * The last node in every alt points to q->end. + * + * Generate code of the following form: + * if ( First(G1) ) { + * ...code for G1... + * } + * else if ( First(G2) ) { + * ...code for G2... + * } + * ... + * else { + * ...code for Gn... + * } + */ + +void +#ifdef __USE_PROTOS +genSubBlk( Junction *q ) +#else +genSubBlk( q ) +Junction *q; +#endif +{ + int max_k; + set f; + int need_right_curly; + int lastAltEmpty; /* MR23 */ + set savetkref; + savetkref = tokensRefdInBlock; + require(q->ntype == nJunction, "genSubBlk: not junction"); + require(q->jtype == aSubBlk, "genSubBlk: not subblock"); + + OutLineInfo(output,q->line,FileStr[q->file]); + BLOCK_Preamble(q); + BlkLevel++; + BlockPreambleOption(q,q->pFirstSetSymbol); /* MR21 */ + f = genBlk(q, aSubBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */); + +/* MR23 + Bypass error clause generation when exceptions are used in a sub block + in which the last alternative is epsilon. Example: "(A | B | )". + See multi-line note in genBlk near call to isEmptyAlt. +*/ + if (FoundException && lastAltEmpty) { + gen("/* MR23 skip error clause for (...| epsilon) when exceptions in use */\n"); + } + else { + if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k,0 /* use plus block bypass ? */ );} + } + + { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} } + freeBlkFsets(q); + --BlkLevel; + BLOCK_Tail(); + + if ( q->guess ) + { + gen("zzGUESS_DONE\n"); + } + + /* must duplicate if (alpha)?; one guesses (validates), the + * second pass matches */ + if ( q->guess && analysis_point(q)==q ) + { + OutLineInfo(output,q->line,FileStr[q->file]); + BLOCK_Preamble(q); + BlkLevel++; + f = genBlk(q, aSubBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */); + if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k,0 /* use plus block bypass ? */);} + { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} } + freeBlkFsets(q); + --BlkLevel; + BLOCK_Tail(); + } + + tokensRefdInBlock = savetkref; + if (q->end->p1 != NULL) TRANS(q->end->p1); +} + +static int TnodesAllocatedPrevRule=0; + +/* + * Generate code for a rule. + * + * rule--> o-->o-Alternatives-o-->o + * Or, + * rule--> o-->o-Alternative-o-->o + * + * The 1st junction is a RuleBlk. The second can be a SubBlk or just a junction + * (one alternative--no block), the last is EndRule. + * The second to last is EndBlk if more than one alternative exists in the rule. + * + * To get to the init-action for a rule, we must bypass the RuleBlk, + * and possible SubBlk. + * Mark any init-action as generated so genBlk() does not regenerate it. + */ +void +#ifdef __USE_PROTOS +genRule( Junction *q ) +#else +genRule( q ) +Junction *q; +#endif +{ + + const char * returnValueInitializer; + +do { /* MR10 Change recursion into iteration */ + + int max_k; + set follow, rk, f; + ActionNode *a; + RuleEntry *r; + int lastAltEmpty; /* MR23 */ + static int file = -1; + int need_right_curly; + require(q->ntype == nJunction, "genRule: not junction"); + require(q->jtype == RuleBlk, "genRule: not rule"); + +/* MR14 */ require (MR_BackTraceStack.count == 0,"-alpha MR_BackTraceStack.count != 0"); +/* MR14 */ MR_pointerStackReset(&MR_BackTraceStack); +/* MR14 */ if (AlphaBetaTrace) MR_MaintainBackTrace=1; + + CurRule=q->rname; /* MR11 */ + + r = (RuleEntry *) hash_get(Rname, q->rname); + if ( r == NULL ) warnNoFL("Rule hash table is screwed up beyond belief"); + if ( q->file != file ) /* open new output file if need to */ + { +/* MR6 */ +/* MR6 Simpler to debug when output goes to stdout rather than a file */ +/* MR6 */ +/* MR6 */ if (UseStdout) { +/* MR6 */ output = stdout; +/* MR6 */ } else { +/* MR6 */ if ( output != NULL) fclose( output ); +/* MR6 */ output = fopen(OutMetaName(outname(FileStr[q->file])), "w"); +/* MR6 */ }; + require(output != NULL, "genRule: can't open output file"); + +#ifdef SPECIAL_FOPEN + special_fopen_actions(OutMetaName(outname(FileStr[q->file]))); /* MR1 */ +#endif + if ( file == -1 ) genHdr1(q->file); + else genHdr(q->file); + file = q->file; + } + + if (InfoM) { + fprintf(stderr," rule %s\n",q->rname); + fflush(output); + }; + +#if 0 + if (strcmp(q->rname,"***debug***") == 0) { + fprintf(stderr,"***debug*** %s reached\n",q->rname); + MR_break(); + }; +#endif + + DumpFuncHeader(q,r); + tabs++; + + /* MR23 + + If there is a single return value then it can be initialized in + the declaration using assignment syntax. If there are multiple + return values then antlr creates a struct and initialization takes + place element by element for each element of the struct. For + multiple elements the initialization is by assignment so we have + to wait until all declarations are done before emitting that code - + because of restrictions in C which don't exist in C++. + + In the past (before MR23) the only kind of initialization was + the PURIFY macro which was just a memset() of 0. Now we allow + the user to specify an initial value. PURIFY is still used in C + mode because C does not have constructors. However, PURIFY is + not used in C++ mode because it might overwrite information created + by elements which have their own ctor. + + */ + + if ( q->ret!=NULL ) + { + if ( hasMultipleOperands(q->ret) ) /* MR23 */ + { + + /* Emit initialization code later. */ + + gen1("struct _rv%d _retv;\n",r->rulenum); + } + else + { + /* Emit initialization code now. */ + + tab(); + DumpType(q->ret, output); + returnValueInitializer = getInitializer(q->ret); + if (returnValueInitializer == NULL) { /* MR23 */ + gen(" _retv;\n"); /* MR1 MR3 */ + } /* MR23 */ + else { /* MR23 */ + gen1(" _retv = %s;\n", returnValueInitializer); /* MR23 */ + } /* MR23 */ + } + } + + OutLineInfo(output,q->line,FileStr[q->file]); + + if (InfoM) { + fflush(output); + }; + + gen("zzRULE;\n"); + if ( FoundException ) + { + gen("int _sva=1;\n"); + } + if ( GenCC && GenAST ) + gen("ASTBase *_ast = NULL, *_sibling = NULL, *_tail = NULL;\n"); + if ( GenCC ) genTokenPointers(q); + if ( GenCC&&GenAST ) genASTPointers(q); + if ( q->el_labels!=NULL ) genElementLabels(q->el_labels); + if ( FoundException ) gen("int _signal=NoSignal;\n"); + + if ( !GenCC ) gen1("zzBLOCK(zztasp%d);\n", BlkLevel); + +/* MR10 */ /* move zzTRACEIN to before init action */ + +/* MR10 */ if ( TraceGen ) { +/* MR10 */ if ( GenCC ) {gen1("zzTRACEIN(\"%s\");\n", q->rname);} +/* MR10 */ else gen1("zzTRACEIN((ANTLRChar *)\"%s\");\n", q->rname); +/* MR10 */ } + +/* MR7 Moved PURIFY() to after all local variables have been declared */ +/* MR7 so that the generated code is valid C as well as C++ */ +/* MR7 Jan Mikkelsen 10-June-1997 */ + + + /* + MR23 Do the PURIFY macro only for C mode. + C++ users should use constructors or initialization expressions. + */ + + if ( q->ret != NULL ) /* MR7 */ + { /* MR7 */ + if (hasMultipleOperands(q->ret)) { /* MR23 */ + if (PURIFY == TRUE) { + gen1("PCCTS_PURIFY(_retv,sizeof(struct _rv%d))\n",r->rulenum); /* MR23 */ + } + } /* MR7 */ + else { /* MR7 */ + + /* MR23 + If there were only one return value operand and + it had an initializer then it would have been + initiailized in the declaration. + */ + + returnValueInitializer = getInitializer(q->ret); /* MR23 */ + if (returnValueInitializer == NULL) { /* MR23 */ + if (PURIFY == TRUE) { + gen("PCCTS_PURIFY(_retv,sizeof("); /* MR23 */ + DumpType(q->ret, output); /* MR7 */ + gen("))\n"); /* MR7 */ + } + } /* MR23 */ + } /* MR7 */ + + if (hasMultipleOperands(q->ret)) { /* MR23 */ + DumpInitializers(output, r, q->ret); /* MR23 */ + } + + } + if ( !GenCC ) gen("zzMake0;\n"); + if ( FoundException ) gen("*_retsignal = NoSignal;\n"); + + if ( !GenCC ) gen("{\n"); + + if ( has_guess_block_as_first_item((Junction *)q->p1) ) + { + gen("zzGUESS_BLOCK\n"); + } + + /* L o o k F o r I n i t A c t i o n */ + if ( ((Junction *)q->p1)->jtype == aSubBlk ) + a = findImmedAction( ((Junction *)q->p1)->p1 ); + else + a = findImmedAction( q->p1 ); /* only one alternative in rule */ + if ( a!=NULL && !a->is_predicate) + { + /* MR21 */ if (!a->noHoist) dumpActionPlus(a, a->action, output, tabs, a->file, a->line, 1); + a->done = 1; /* ignore action. We have already handled it */ + } + + BlkLevel++; + q->visited = TRUE; /* mark RULE as visited for FIRST/FOLLOW */ + BlockPreambleOption((Junction *)q->p1, NULL); /* MR21 */ + f = genBlk((Junction *)q->p1, RuleBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */); + if ( q->p1 != NULL ) + if ( ((Junction *)q->p1)->p2 != NULL ) + {tab(); makeErrorClause((Junction *)q->p1,f,max_k,0 /* use plus block bypass ? */);} + { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} } + freeBlkFsets((Junction *)q->p1); + q->visited = FALSE; + --BlkLevel; + if ( !GenCC ) gen1("zzEXIT(zztasp%d);\n", BlkLevel); + + genTraceOut(q); + + if ( q->ret!=NULL ) gen("return _retv;\n") else gen("return;\n"); + /* E r r o r R e c o v e r y */ + NewSet(); + rk = empty; + +/* MR14 */ if (r->dontComputeErrorSet) { +/* MR14 */ follow=empty; + } else { + MR_pointerStackReset(&MR_BackTraceStack); /* MR14 */ + MR_ErrorSetComputationActive=1; + REACH(q->end, 1, &rk, follow); + MR_ErrorSetComputationActive=0; + require (MR_BackTraceStack.count == 0,"K: MR_BackTraceStack.count != 0"); + } + + FillSet( follow ); + set_free( follow ); + + /* MR20 G. Hobbelt + Isn't it so that "fail:" is ONLY referenced when: + + !FoundException || FoundGuessBlk ? + + Therefore add the "if" around this piece of code generation... + + Should guessing mode also use _handler label instead of "fail" + when exception handling is active? gen can automatically put + "if (guessing)" there so as to skip all kinds of user code. + + */ + + if ( !FoundException || FoundGuessBlk ) /* MR20 G. Hobbelt */ + { /* MR20 G. Hobbelt */ + _gen("fail:\n"); + if ( !GenCC ) gen("zzEXIT(zztasp1);\n"); + if ( FoundGuessBlk ) { + if ( !GenCC ) {gen("if ( zzguessing ) zzGUESS_FAIL;\n");} + else gen("if ( guessing ) zzGUESS_FAIL;\n"); + } + if ( q->erraction!=NULL ) + dumpAction(q->erraction, output, tabs, q->file, q->line, 1); + if ( GenCC ) + { + gen1("syn(zzBadTok, %s, zzMissSet, zzMissTok, zzErrk);\n", + r->egroup==NULL?"(ANTLRChar *)\"\"":r->egroup); + } + else + { + gen1("zzsyn(zzMissText, zzBadTok, %s, zzMissSet, zzMissTok, zzErrk, zzBadText);\n", + r->egroup==NULL?"(ANTLRChar *)\"\"":r->egroup); + } + gen3("%sresynch(setwd%d, 0x%x);\n", GenCC?"":"zz", wordnum, 1<ret!=NULL ) { + genTraceOut(q); + gen("return _retv;\n"); + } else if ( q->exceptions!=NULL ) { + genTraceOut(q); + gen("return;\n"); + } else if (!FoundException) { /* MR10 */ + genTraceOut(q); /* MR10 */ + }; + + } /* MR20 G. Hobbelt */ + + if ( !GenCC ) gen("}\n"); + + /* Gen code for exception handlers */ + /* make sure each path out contains genTraceOut() */ + + if ( q->exceptions!=NULL ) + { + + gen("/* exception handlers */\n"); + + dumpExceptions(q->exceptions); + + if ( !r->has_rule_exception ) + { + _gen("_handler:\n"); + gen("zzdflthandlers(_signal,_retsignal);\n"); + } +/* MR20 G. Gobbelt The label "adios" is never referenced */ + +#if 0 + _gen("_adios:\n"); +#endif + if ( q->ret!=NULL ) { + genTraceOut(q); + gen("return _retv;\n"); + } + else { + genTraceOut(q); + gen("return;\n"); + } + } + else if ( FoundException ) + { + _gen("_handler:\n"); + gen("zzdflthandlers(_signal,_retsignal);\n"); + +/* MR1 */ +/* MR1 7-Apr-97 Fix suggested by: John Bair (jbair@iftime.com) */ +/* MR1 */ + + if ( q->ret != NULL) { /* MR1 */ + genTraceOut(q); /* MR10 */ + gen("return _retv;\n"); /* MR1 */ + } else { /* MR1 */ + genTraceOut(q); /* MR10 */ + gen("return;\n") ; /* MR1 */ + }; /* MR1 */ + } + + tabs--; + gen("}\n"); + +/* MR10 Tired of looking at stacks that are as deep as the number of */ +/* MR10 rules. Changes recursion to iteration. */ + + MR_releaseResourcesUsedInRule( (Node *) q ); /* MR10 */ + + if (InfoT) { + fprintf(output,"\n/* tnodes created for rule %s: %d */\n", + q->rname, (TnodesAllocated-TnodesAllocatedPrevRule) ); + }; + + TnodesAllocatedPrevRule=TnodesAllocated; + + if (q->p2 == NULL) dumpAfterActions( output ); + q=(Junction *)q->p2; + require(q==NULL || q->jtype==RuleBlk,"RuleBlk p2 does not point to another RuleBlk"); + +} while (q != NULL); + +/**** The old code ****/ +/**** if ( q->p2 != NULL ) {TRANS(q->p2);} ****/ /* generate code for next rule too */ +/**** else dumpAfterActions( output ); ****/ + +} + + +/* This is for the function definition, not the declaration. */ + +static void +#ifdef __USE_PROTOS +DumpFuncHeader( Junction *q, RuleEntry *r ) +#else +DumpFuncHeader( q, r ) +Junction *q; +RuleEntry *r; +#endif +{ +/* */ +/* MR1 10-Apr-97 MR1 Simplify insertion of commas in function header */ +/* */ + int needComma; /* MR1 */ + + + /* A N S I */ + _gen("\n"); + if ( q->ret!=NULL ) + { + if ( hasMultipleOperands(q->ret) ) /* MR23 */ + { + if (GenCC) gen2("%s::_rv%d\n", CurrentClassName, r->rulenum) + else gen1("struct _rv%d\n",r->rulenum); + } + else + { + DumpType(q->ret, output); + gen("\n"); + } + } + else + { + _gen("void\n"); + } +/* MR1 */ +/* MR1 10-Apr-97 133MR1 Replace __STDC__ with __USE_PROTOS */ +/* MR1 */ + if ( !GenCC ) _gen("#ifdef __USE_PROTOS\n"); /* MR1 */ + if ( !GenCC ) gen2("%s%s(", RulePrefix, q->rname) + else gen3("%s::%s%s(", CurrentClassName, RulePrefix,q->rname); + + /* If we generate C++ method names, we must hide default arguments */ + /* which can appear in the parameter declaration list. */ + /* NOTICE: this is done only here, for the method definition, but */ + /* not for the method declaration inside the class */ + /* definition. This is exactly the behaviour defined in */ + /* C++ standard for default paramters. */ + + DumpANSIFunctionArgDef(output,q, 0 /* emit initializers ? */); + _gen("\n"); + + if ( GenCC ) { + gen("{\n"); + return; + } + + /* K & R */ + gen("#else\n"); + gen2("%s%s(", RulePrefix, q->rname); + needComma=0; /* MR1 */ + if ( GenAST ) /* MR1 */ + { /* MR1 */ + _gen("_root"); /* MR1 */ + needComma=1; /* MR1 */ + } /* MR1 */ + if ( FoundException ) /* MR1 */ + { /* MR1 */ + if (needComma) {_gen(",");needComma=0;}; /* MR1 */ + _gen("_retsignal"); /* MR1 */ + needComma=1; /* MR1 */ + } /* MR1 */ +/* MR5 Change below by Jan Mikkelsen (janm@zeta.org.au) 26-May-97 MR5 */ + DumpListOfParmNames( q->pdecl, output, needComma ); /* MR5 */ + gen(")\n"); + if ( GenAST ) gen("AST **_root;\n"); + if ( FoundException ) gen("int *_retsignal;\n"); + DumpOldStyleParms( q->pdecl, output ); + gen("#endif\n"); + gen("{\n"); +} + +void +#ifdef __USE_PROTOS +DumpANSIFunctionArgDef(FILE *f, Junction *q, int bInitializer) +#else +DumpANSIFunctionArgDef(f,q,bInitializer) +FILE *f; +Junction *q; +int bInitializer; +#endif +{ + if ( GenAST ) + { + if ( GenCC ) {fprintf(f,"ASTBase **_root");} + else fprintf(f,"AST**_root"); + if ( !FoundException && q->pdecl!=NULL ) fprintf(f,","); + } + if ( FoundException ) + { + if ( GenAST ) fprintf(f,","); + fprintf(f,"int *_retsignal"); + if ( q->pdecl!=NULL ) { + fprintf(f,","); + } + } + if ( q->pdecl!=NULL ) { + DumpFormals(f, q->pdecl, bInitializer); /* MR23 */ + } + else { + if ( !GenAST && !FoundException ) { + fprintf(f,"void"); + } + } + fprintf(f,")"); +} + +void +#ifdef __USE_PROTOS +genJunction( Junction *q ) +#else +genJunction( q ) +Junction *q; +#endif +{ + require(q->ntype == nJunction, "genJunction: not junction"); + require(q->jtype == Generic, "genJunction: not generic junction"); + + if ( q->p1 != NULL ) TRANS(q->p1); + if ( q->p2 != NULL ) TRANS(q->p2); +} + +void +#ifdef __USE_PROTOS +genEndBlk( Junction *q ) +#else +genEndBlk( q ) +Junction *q; +#endif +{ +} + +void +#ifdef __USE_PROTOS +genEndRule( Junction *q ) +#else +genEndRule( q ) +Junction *q; +#endif +{ +} + +void +#ifdef __USE_PROTOS +genHdr( int file ) +#else +genHdr( file ) +int file; +#endif +{ + int i; + + _gen("/*\n"); + _gen(" * A n t l r T r a n s l a t i o n H e a d e r\n"); + _gen(" *\n"); + _gen(" * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n"); + _gen(" * Purdue University Electrical Engineering\n"); + _gen(" * With AHPCRC, University of Minnesota\n"); + _gen1(" * ANTLR Version %s\n", Version); + _gen(" *\n"); +/* MR10 */ _gen(" * "); +/* MR10 */ for (i=0 ; i < Save_argc ; i++) { +/* MR10 */ _gen(" "); +/* MR10 */ _gen(Save_argv[i]); +/* MR10 */ }; + _gen("\n"); + _gen(" *\n"); + _gen(" */\n\n"); + if (FirstAction != NULL ) dumpAction( FirstAction, output, 0, -1, 0, 1); /* MR11 MR15b */ + _gen1("#define ANTLR_VERSION %s\n", VersionDef); + _gen("#include \"pcctscfg.h\"\n"); + _gen("#include \"pccts_stdio.h\"\n"); + if ( strcmp(ParserName, DefaultParserName)!=0 ) + _gen2("#define %s %s\n", DefaultParserName, ParserName); + if ( strcmp(ParserName, DefaultParserName)!=0 ) + {_gen1("#include \"%s\"\n", RemapFileName);} + OutLineInfo(output,1,FileStr[file]); + if ( GenCC ) { + if ( UserTokenDefsFile != NULL ) + fprintf(output, "#include %s\n", UserTokenDefsFile); + else + fprintf(output, "#include \"%s\"\n", DefFileName); + } + + if ( HdrAction != NULL ) dumpAction( HdrAction, output, 0, -1, 0, 1); + if ( !GenCC && FoundGuessBlk ) + { + _gen("#define ZZCAN_GUESS\n"); + _gen("#include \"pccts_setjmp.h\"\n"); /* MR15 K.J. Cummings (cummings@peritus.com) */ + } + if ( FoundException ) + { + _gen("#define EXCEPTION_HANDLING\n"); + _gen1("#define NUM_SIGNALS %d\n", NumSignals); + } + if ( !GenCC && OutputLL_k > 1 ) _gen1("#define LL_K %d\n", OutputLL_k); + if ( GenAST&&!GenCC ) _gen("#define GENAST\n\n"); + if ( GenAST ) { + if ( GenCC ) {_gen1("#include \"%s\"\n\n", ASTBASE_H);} + else _gen("#include \"ast.h\"\n\n"); + } + if ( !GenCC && DemandLookahead ) _gen("#define DEMAND_LOOK\n\n"); +#ifdef DUM + if ( !GenCC && LexGen ) { + _gen1("#define zzEOF_TOKEN %d\n", (TokenInd!=NULL?TokenInd[EofToken]:EofToken)); + } +#endif + /* ###WARNING: This will have to change when SetWordSize changes */ + if ( !GenCC ) _gen1("#define zzSET_SIZE %d\n", NumWords(TokenNum-1)*sizeof(unsigned)); + if (TraceGen) { + _gen("#ifndef zzTRACE_RULES\n"); /* MR20 */ + _gen("#define zzTRACE_RULES\n"); /* MR20 */ + _gen("#endif\n"); /* MR22 */ + }; + if ( !GenCC ) {_gen("#include \"antlr.h\"\n");} + else { + _gen1("#include \"%s\"\n", APARSER_H); + _gen1("#include \"%s.h\"\n", CurrentClassName); + } + if ( !GenCC ) { + if ( UserDefdTokens ) + {_gen1("#include %s\n", UserTokenDefsFile);} + /* still need this one as it has the func prototypes */ + _gen1("#include \"%s\"\n", DefFileName); + } + /* still need this one as it defines the DLG interface */ + if ( !GenCC ) _gen("#include \"dlgdef.h\"\n"); + if ( LexGen && GenCC ) _gen1("#include \"%s\"\n", DLEXERBASE_H); + if ( GenCC ) _gen1("#include \"%s\"\n", ATOKPTR_H); + if ( !GenCC && LexGen ) _gen1("#include \"%s\"\n", ModeFileName); + +/* MR10 Ofer Ben-Ami (gremlin@cs.huji.ac.il) */ +/* MR10 Finally, a definition of the Purify macro */ + + if (PURIFY == TRUE) { /* MR23 */ + _gen("\n/* MR23 In order to remove calls to PURIFY use the antlr"); /* MR23 */ + _gen(" -nopurify option */\n\n"); /* MR23 */ + _gen("#ifndef PCCTS_PURIFY\n"); + _gen("#define PCCTS_PURIFY(r,s) memset((char *) &(r),'\\0',(s));\n"); + _gen("#endif\n\n"); + } /* MR23 */ +} + +void +#ifdef __USE_PROTOS +genHdr1( int file ) +#else +genHdr1( file ) +int file; +#endif +{ + ListNode *p; + + genHdr(file); + if ( GenAST ) + { + if ( !GenCC ) { + _gen("#include \"ast.c\"\n"); + _gen("zzASTgvars\n\n"); + } + } + if ( !GenCC ) _gen("ANTLR_INFO\n"); + if ( BeforeActions != NULL ) + { + for (p = BeforeActions->next; p!=NULL; p=p->next) + { + UserAction *ua = (UserAction *)p->elem; + dumpAction( ua->action, output, 0, ua->file, ua->line, 1); + } + } + + if ( !FoundException ) return; + + if ( GenCC ) + { + _gen1("\nvoid %s::\n", CurrentClassName); + _gen("zzdflthandlers( int _signal, int *_retsignal )\n"); + _gen("{\n"); + } + else + { + _gen("\nvoid\n"); +/* MR1 */ +/* MR1 10-Apr-97 133MR1 Replace __STDC__ with __USE_PROTOS */ +/* MR1 */ + _gen("#ifdef __USE_PROTOS\n"); /* MR1 */ + _gen("zzdflthandlers( int _signal, int *_retsignal )\n"); + _gen("#else\n"); + _gen("zzdflthandlers( _signal, _retsignal )\n"); + _gen("int _signal;\n"); + _gen("int *_retsignal;\n"); + _gen("#endif\n"); + _gen("{\n"); + } + tabs++; + if ( DefaultExGroup!=NULL ) + { + dumpException(DefaultExGroup, 1); + if ( !hasDefaultException(DefaultExGroup) ) + { + gen("default :\n"); + tabs++; + gen("*_retsignal = _signal;\n"); + tabs--; + gen("}\n"); + } + } + else { + gen("*_retsignal = _signal;\n"); + } + + tabs--; + _gen("}\n\n"); +} + +void +#ifdef __USE_PROTOS +genStdPCCTSIncludeFile( FILE *f,char *gate ) /* MR10 */ +#else +genStdPCCTSIncludeFile( f , gate) /* MR10 */ +FILE *f; +char * gate; /* MR10 */ +#endif +{ +/* MR10 Ramanathan Santhanam (ps@kumaran.com) */ +/* MR10 Same preprocessor symbol use to gate stdpccts.h */ +/* MR10 even when two grammars are in use. */ +/* MR10 Derive gate symbol from -fh filename */ + + if (gate == NULL) { + fprintf(f,"#ifndef STDPCCTS_H\n"); /* MR10 */ + fprintf(f,"#define STDPCCTS_H\n"); /* MR10 */ + } else { + fprintf(f,"#ifndef STDPCCTS_%s_H\n",gate); /* MR10 */ + fprintf(f,"#define STDPCCTS_%s_H\n",gate); /* MR10 */ + }; + fprintf(f,"/*\n"); + if (gate == NULL) { + fprintf(f," * %s -- P C C T S I n c l u d e\n", stdpccts); + } else { + fprintf(f," * Standard PCCTS include file with -fh %s -- P C C T S I n c l u d e\n", stdpccts); + } + fprintf(f," *\n"); + fprintf(f," * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n"); + fprintf(f," * Purdue University Electrical Engineering\n"); + fprintf(f," * With AHPCRC, University of Minnesota\n"); + fprintf(f," * ANTLR Version %s\n", Version); + fprintf(f," */\n\n"); + + fprintf(f,"#ifndef ANTLR_VERSION\n"); + fprintf(f,"#define ANTLR_VERSION %s\n", VersionDef); + fprintf(f,"#endif\n\n"); + + if (FirstAction != NULL ) dumpAction(FirstAction, f, 0, -1, 0, 1); /* MR11 */ + + fprintf(f,"#include \"pcctscfg.h\"\n"); + fprintf(f,"#include \"pccts_stdio.h\"\n"); + if ( GenCC ) + { + if ( UserDefdTokens ) + fprintf(f, "#include %s\n", UserTokenDefsFile); + else { + fprintf(f, "#include \"%s\"\n", DefFileName); + } + + fprintf(f, "#include \"%s\"\n", ATOKEN_H); + + if ( HdrAction != NULL ) dumpAction( HdrAction, f, 0, -1, 0, 1); + + fprintf(f, "#include \"%s\"\n", ATOKENBUFFER_H); + + if ( OutputLL_k > 1 ) fprintf(f,"static const unsigned LL_K=%d;\n", OutputLL_k); + if ( GenAST ) { + fprintf(f, "#include \"%s\"\n", ASTBASE_H); + } + + if (TraceGen) { + fprintf(f,"#ifndef zzTRACE_RULES\n"); /* MR20 */ + fprintf(f,"#define zzTRACE_RULES\n"); /* MR20 */ + fprintf(f,"#endif\n"); /* MR22 */ + }; + + fprintf(f,"#include \"%s\"\n", APARSER_H); + fprintf(f,"#include \"%s.h\"\n", CurrentClassName); + if ( LexGen ) fprintf(f,"#include \"%s\"\n", DLEXERBASE_H); + fprintf(f, "#endif\n"); + return; + } + + if ( strcmp(ParserName, DefaultParserName)!=0 ) + fprintf(f, "#define %s %s\n", DefaultParserName, ParserName); + if ( strcmp(ParserName, DefaultParserName)!=0 ) + fprintf(f, "#include \"%s\"\n", RemapFileName); + if ( UserTokenDefsFile != NULL ) + fprintf(f, "#include %s\n", UserTokenDefsFile); + if ( HdrAction != NULL ) dumpAction( HdrAction, f, 0, -1, 0, 1); + if ( FoundGuessBlk ) + { + fprintf(f,"#define ZZCAN_GUESS\n"); + fprintf(f,"#include \"pccts_setjmp.h\"\n"); + } + if (TraceGen) { + fprintf(f,"#ifndef zzTRACE_RULES\n"); /* MR20 */ + fprintf(f,"#define zzTRACE_RULES\n"); /* MR20 */ + fprintf(f,"#endif\n"); /* MR22 */ + }; + if ( OutputLL_k > 1 ) fprintf(f,"#define LL_K %d\n", OutputLL_k); + if ( GenAST ) fprintf(f,"#define GENAST\n"); + if ( FoundException ) + { +/* MR1 7-Apr-97 1.33MR1 */ +/* MR1 Fix suggested by: */ +/* MR1 Francois-Xavier Fontaine (fontaine_f@istvax.ist.lu) */ + + fprintf(f,"#define EXCEPTION_HANDLING\n"); /* MR1 */ + fprintf(f,"#define NUM_SIGNALS %d\n", NumSignals); /* MR1 */ + } + if ( DemandLookahead ) fprintf(f,"#define DEMAND_LOOK\n"); +#ifdef DUM + if ( LexGen ) fprintf(f, "#define zzEOF_TOKEN %d\n", (TokenInd!=NULL?TokenInd[EofToken]:EofToken)); +#endif + /* ###WARNING: This will have to change when SetWordSize changes */ + fprintf(f, "#define zzSET_SIZE %d\n", NumWords(TokenNum-1)*sizeof(unsigned)); + if (TraceGen) { + fprintf(f,"#ifndef zzTRACE_RULES\n"); /* MR20 */ + fprintf(f,"#define zzTRACE_RULES\n"); /* MR20 */ + fprintf(f,"#endif\n"); /* MR22 */ + }; + fprintf(f,"#include \"antlr.h\"\n"); + if ( GenAST ) fprintf(f,"#include \"ast.h\"\n"); + if ( UserDefdTokens ) + fprintf(f, "#include %s\n", UserTokenDefsFile); + /* still need this one as it has the func prototypes */ + fprintf(f, "#include \"%s\"\n", DefFileName); + /* still need this one as it defines the DLG interface */ + fprintf(f,"#include \"dlgdef.h\"\n"); + /* don't need this one unless DLG is used */ + if ( LexGen ) fprintf(f,"#include \"%s\"\n", ModeFileName); + fprintf(f,"#endif\n"); +} + +/* dump action 's' to file 'output' starting at "local" tab 'tabs' + Dump line information in front of action if GenLineInfo is set + If file == -1 then GenLineInfo is ignored. + The user may redefine the LineInfoFormatStr to his/her liking + most compilers will like the default, however. + + June '93; changed so that empty lines are left alone so that + line information is correct for the compiler/debuggers. +*/ +void +#ifdef __USE_PROTOS +dumpAction( char *s, FILE *output, int tabs, int file, int line, +int final_newline ) +#else +dumpAction( s, output, tabs, file, line, final_newline ) +char *s; +FILE *output; +int tabs; +int file; +int line; +int final_newline; +#endif +{ + int inDQuote, inSQuote; + require(s!=NULL, "dumpAction: NULL action"); + require(output!=NULL, eMsg1("dumpAction: output FILE is NULL for %s",s)); + + if ( GenLineInfo && file != -1 ) + { + OutLineInfo(output,line,FileStr[file]); + } + PastWhiteSpace( s ); + /* don't print a tab if first non-white char is a # (preprocessor command) */ + if ( *s!='#' ) {TAB;} + inDQuote = inSQuote = FALSE; + while ( *s != '\0' ) + { + if ( *s == '\\' ) + { + fputc( *s++, output ); /* Avoid '"' Case */ + if ( *s == '\0' ) return; + if ( *s == '\'' ) fputc( *s++, output ); + if ( *s == '\"' ) fputc( *s++, output ); + } + if ( *s == '\'' ) + { + if ( !inDQuote ) inSQuote = !inSQuote; + } + if ( *s == '"' ) + { + if ( !inSQuote ) inDQuote = !inDQuote; + } + if ( *s == '\n' ) + { + fputc('\n', output); + s++; + PastWhiteSpace( s ); + if ( *s == '}' ) + { + --tabs; + TAB; + fputc( *s++, output ); + continue; + } + if ( *s == '\0' ) return; + if ( *s != '#' ) /* #define, #endif etc.. start at col 1 */ + { + TAB; + } + } + if ( *s == '}' && !(inSQuote || inDQuote) ) + { + --tabs; /* Indent one fewer */ + } + if ( *s == '{' && !(inSQuote || inDQuote) ) + { + tabs++; /* Indent one more */ + } + fputc( *s, output ); + s++; + } + if ( final_newline ) fputc('\n', output); +} + +static void +#ifdef __USE_PROTOS +dumpAfterActions( FILE *output ) +#else +dumpAfterActions( output ) +FILE *output; +#endif +{ + ListNode *p; + require(output!=NULL, "dumpAfterActions: output file was NULL for some reason"); + if ( AfterActions != NULL ) + { + for (p = AfterActions->next; p!=NULL; p=p->next) + { + UserAction *ua = (UserAction *)p->elem; + dumpAction( ua->action, output, 0, ua->file, ua->line, 1); + } + } + fclose( output ); +} + +/* + * Find the next action in the stream of execution. Do not pass + * junctions with more than one path leaving them. + * Only pass generic junctions. + * + * Scan forward while (generic junction with p2==NULL) + * If we stop on an action, return ptr to the action + * else return NULL; + */ +static ActionNode * +#ifdef __USE_PROTOS +findImmedAction( Node *q ) +#else +findImmedAction( q ) +Node *q; +#endif +{ + Junction *j; + require(q!=NULL, "findImmedAction: NULL node"); + require(q->ntype>=1 && q->ntype<=NumNodeTypes, "findImmedAction: invalid node"); + + while ( q->ntype == nJunction ) + { + j = (Junction *)q; + if ( j->jtype != Generic || j->p2 != NULL ) return NULL; + q = j->p1; + if ( q == NULL ) return NULL; + } + if ( q->ntype == nAction ) return (ActionNode *)q; + return NULL; +} + +static void +#ifdef __USE_PROTOS +dumpRetValAssign( char *retval, char *ret_def, RuleRefNode * ruleRef /* MR30 */) +#else +dumpRetValAssign( retval, ret_def, ruleRef /* MR30 */) +char *retval; +char *ret_def; +RuleRefNode *ruleRefNode; +#endif +{ + char *q = ret_def; + + tab(); + while ( *retval != '\0' && *q != '\0') + { + while ( isspace((*retval)) ) retval++; + while ( *retval!=',' && *retval!='\0' ) fputc(*retval++, output); + fprintf(output, " = _trv."); + + DumpNextNameInDef(&q, output); + while ( isspace(*q) ) q++; + fputc(';', output); fputc(' ', output); + if ( *retval == ',' ) retval++; + } + if (*retval == '\0' && *q != '\0') { +/* MR30 */ errFL("Fewer output values than output formals for rule reference", +/* MR30 */ FileStr[ruleRef->file],ruleRef->line); + } + if (*retval != '\0' && *q == '\0') { +/* MR30 */ errFL("More output actuals than output formals for rule reference", +/* MR30 */ FileStr[ruleRef->file],ruleRef->line); + } +} + +/* This function computes the set of tokens that can possibly be seen k + * tokens in the future from point j + */ + +static set +#ifdef __USE_PROTOS +ComputeErrorSet( Junction *j, int k, int usePlusBlockBypass) +#else +ComputeErrorSet( j, k, usePlusBlockBypass ) +Junction *j; +int k; +int usePlusBlockBypass; +#endif +{ + Junction *alt1; + set a, rk, f; + require(j->ntype==nJunction, "ComputeErrorSet: non junction passed"); + + f = rk = empty; + for (alt1=j; alt1!=NULL; alt1 = (Junction *)alt1->p2) + { + if (alt1->ignore && ! usePlusBlockBypass) continue; /* MR21 - Ignore aPlusBlk forward p2 */ + REACH(alt1->p1, k, &rk, a); + require(set_nil(rk), "ComputeErrorSet: rk != nil"); + set_free(rk); + set_orin(&f, a); + set_free(a); + } + return f; +} + +static char * +#ifdef __USE_PROTOS +tokenFollowSet(TokNode *p) +#else +tokenFollowSet(p) +TokNode *p; +#endif +{ + static char buf[100]; + set rk, a; + int n; + rk = empty; + + REACH(p->next, 1, &rk, a); + require(set_nil(rk), "rk != nil"); + set_free(rk); + n = DefErrSet( &a, 0, NULL ); + set_free(a); + if ( GenCC ) + sprintf(buf, "err%d", n); + else + sprintf(buf, "zzerr%d", n); + return buf; +} + +static void +#ifdef __USE_PROTOS +makeErrorClause( Junction *q, set f, int max_k, int usePlusBlockBypass ) +#else +makeErrorClause( q, f, max_k, usePlusBlockBypass ) +Junction *q; +set f; +int max_k; +int usePlusBlockBypass; +#endif +{ + char * handler_id=""; /* MR7 */ + int nilf=0; /* MR13 */ + RuleEntry *ruleEntry; /* MR14 */ + + if ( FoundException ) + { + _gen("else {\n"); + tabs++; + if ( FoundGuessBlk ) + { + if ( GenCC ) {gen("if ( guessing ) goto fail;\n");} + else gen("if ( zzguessing ) goto fail;\n"); + } + gen("if (_sva) _signal=NoViableAlt;\n"); + gen("else _signal=NoSemViableAlt;\n"); + if (q->outerEG != NULL) { + handler_id=q->outerEG->altID; +#if 0 + } else { + printf("q->curAltNum=%d q->exception_label=%s\n",q->curAltNum,q->exception_label); + gen("*** DEBUG *** outerEG==NULL\n"); +#endif + }; + gen1("goto %s_handler; /* MR7 */\n",handler_id); /* MR7 */ + tabs--; + gen("}\n"); + return; + } + + if ( max_k == 1 ) + { +/* MR13 */ nilf=set_nil(f); + if ( GenCC ) { + _gen1("else {FAIL(1,err%d", DefErrSet1(1,&f,1,NULL)); + } else { + _gen1("else {zzFAIL(1,zzerr%d", DefErrSet1(1,&f,1,NULL)); + }; + set_free(f); + } + else + { + int i; + set_free(f); + if ( GenCC ) {_gen1("else {FAIL(%d", max_k);} + else _gen1("else {zzFAIL(%d", max_k); + + ruleEntry = (RuleEntry *) hash_get(Rname,q->rname); + + for (i=1; i<=max_k; i++) + { +/* MR14 */ if (ruleEntry->dontComputeErrorSet) { +/* MR14 */ f=empty; + } else { + f = ComputeErrorSet(q, i, usePlusBlockBypass /* use plus block bypass ? */ ); + } + + if ( GenCC ) {_gen1(",err%d", DefErrSet( &f, 1, NULL ));} + else _gen1(",zzerr%d", DefErrSet( &f, 1, NULL )); + + set_free(f); + } + } + _gen(",&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}\n"); +/* MR13 */ if (nilf) { +/* MR13 */ errFL("empty error set for alt - probably because of undefined rule or infinite left recursion", +/* MR13 */ FileStr[q->file],q->line); +/* MR13 */ gen(" /* MR13 empty error set for this alt - undef rule ? infinite left recursion ? */"); +/* MR13 */ }; +} + +static /* MR7 */ +#ifdef __USE_PROTOS +char * findOuterHandlerLabel(ExceptionGroup *eg) /* MR7 */ +#else +char * findOuterHandlerLabel(eg) /* MR7 */ +ExceptionGroup *eg; /* MR7 */ +#endif +{ + char *label=NULL; /* MR7 */ + ExceptionGroup *outerEG; /* MR7 */ + + if (eg->forRule == 0) { /* MR7 */ + if (eg->labelEntry != NULL) { /* MR7 */ + outerEG=eg->labelEntry->outerEG; /* MR7 */ + if (outerEG != NULL) { /* MR7 */ + label=outerEG->altID; /* MR7 */ + outerEG->used=1; /* MR7 */ + }; /* MR7 */ + } else if (eg->outerEG != NULL) { /* MR7 */ + outerEG=eg->outerEG; /* MR7 */ + label=outerEG->altID; /* MR7 */ + outerEG->used=1; /* MR7 */ + }; /* MR7 */ + }; /* MR7 */ + return (label==NULL ? "" : label); /* MR7 */ +} /* MR7 */ + +/*** debug ***/ +#if 0 +** static /* MR7 */ +** #ifdef __USE_PROTOS +** char * findOuterAltHandlerLabel(Junction *startJ) /* MR7 */ +** #else +** char * findOuterAltHandlerLabel(startJ) /* MR7 */ +** Junction *startJ; /* MR7 */ +** #endif +** { /* MR7 */ +** char *label=NULL; /* MR7 */ +** Junction *alt; /* MR7 */ +** /* MR7 */ +** for (alt=startJ; alt != NULL; alt=alt->outerAltstart) { /* MR7 */ +** label=alt->exception_label; /* MR7 */ +** if (label != NULL) break; /* MR7 */ +** }; /* MR7 */ +** return (label==NULL ? "" : label); /* MR7 */ +** } /* MR7 */ +#endif + +#ifdef __USE_PROTOS +static void OutLineInfo(FILE *file,int line,char *fileName) +#else +static void OutLineInfo(file,line,fileName) + FILE * file; + int line; + char * fileName; +#endif +{ + static char * prevFileName=NULL; + static char * prevFileNameMS=NULL; + + char * p; + char * q; + + if (! GenLineInfo) return; + + if (!GenLineInfoMS) { + fprintf(file, LineInfoFormatStr,line,fileName); + } else { + if (fileName == prevFileName) { + fprintf(file, LineInfoFormatStr,line,prevFileNameMS); + } else { + if (prevFileNameMS != NULL) free (prevFileNameMS); + prevFileNameMS=(char *)calloc(1,strlen(fileName)+1); + require(prevFileNameMS != NULL,"why not do this in calloc wrapper"); + q=prevFileNameMS; + for (p=fileName; *p != 0; p++) { + *q=*p; + if (*q == '\\') *q='/'; + q++; + } + } + prevFileName=fileName; + }; +} + +#if 0 + +/* MR21 */ + +#ifdef __USE_PROTOS +void OutFirstSetSymbol(Junction *q, char * pSymbol) +#else +void OutFirstSetSymbol(q, pSymbol) + Junction* q; + char * pSymbol +#endif +{ + + set f; + if (pSymbol == NULL) return; + gen1("/** #FirstSetSymbol(%s) **/\n",pSymbol); + f = ComputeErrorSet(q, 1, 0 /* use plus block bypass ? */); + DefErrSetWithSuffix (0 /* nil ok */, &f,0 /* no substitute */, pSymbol, ""); + set_free(f); +} +#endif + +/* MR21 */ + +#ifdef __USE_PROTOS +void BlockPreambleOption(Junction *q, char * pSymbol) +#else +void BlockPreambleOption(q, pSymbol) + Junction* q; + char * pSymbol; +#endif +{ + set f = empty; + if (pSymbol != NULL) { + f = ComputeErrorSet(q, 1, 0 /* use plus block bypass ? */); + gen1("/** #FirstSetSymbol(%s) **/\n",pSymbol); + DefErrSetWithSuffix (0 /* nil ok */, &f,0 /* no substitute */, pSymbol, ""); + } + set_free(f); +} + +/* MR21 */ + +void +#ifdef __USE_PROTOS +dumpActionPlus(ActionNode *a, char *s, FILE *output, int tabs, int file, int line, +int final_newline ) +#else +dumpActionPlus(a, s, output, tabs, file, line, final_newline ) +ActionNode *a; +char *s; +FILE *output; +int tabs; +int file; +int line; +int final_newline; +#endif +{ + dumpAction(s,output,tabs,file,line,final_newline); +} + + +#if 0 +** #ifdef __USE_PROTOS +** void MR_ErrorSets(Junction *q, int max_k, int usePlusBlockBypass) +** #else +** void MR_ErrorSets(q, max_k, usePlusBlockBypass) +** Junction *q; +** int max_k; +** int usePlusBlockBypass; +** #endif +** { +** int k; +** set setResult; +** Junction* alt1; +** Junction* p; +** set rk; +** +** require (max_k <= CLL_k, "k > CLL_k"); +** +** +** for (k = 1; k <= CLL_k; k++) {set_clr(q->fset[k]); } +** +** for (k = 1; k <= max_k; k++) { +** for (alt1=q; alt1 != NULL; alt1 = (Junction *)alt1->p2) +** { +** if (alt1->ignore && ! usePlusBlockBypass) continue; +** p = analysis_point((Junction *)alt1->p1); +** REACH(p, k, &rk, setResult); +** require(set_nil(rk), "rk != nil"); +** set_orin(&q->fset[k], setResult); +** } +** } +** } +#endif + + +#ifdef __USE_PROTOS +void DumpInitializers(FILE* output, RuleEntry *r, char * pReturn) +#else +void DumpInitializers(output, r, pReturn) +FILE* output; +RuleEntry *r; +char * pReturn; +#endif +{ + char *p = pReturn; + char *pDataType; + char *pSymbol; + char *pEqualSign; + char *pValue; + char *pSeparator; + int nest = 0; + char *q; + + require(pReturn!=NULL, "DumpInitializer: invalid string"); + + while (*p != 0) { + p = endFormal(p, + &pDataType, + &pSymbol, + &pEqualSign, + &pValue, + &pSeparator, + &nest); + if (nest != 0) return; + if (pValue != NULL) { + tab(); + q = strBetween(pSymbol, pEqualSign, pSeparator); + fprintf(output, "_retv.%s", q); + q = strBetween(pValue, NULL, pSeparator); + fprintf(output, " = %s;\n", q); + } + } +} + +#ifdef __USE_PROTOS +void DumpFormals(FILE* output, char * pReturn, int bInitializer) +#else +void DumpFormals(output, pReturn, bInitializer) +FILE* output; +char * pReturn; +int bInitializer; +#endif +{ + char *p = pReturn; + char *pDataType; + char *pSymbol; + char *pEqualSign; + char *pValue; + char *pSeparator; + int nest = 0; + char *q; + int count = 0; + + require(pReturn!=NULL, "DumpFormals: invalid string"); + + while (*p != 0) { + p = endFormal(p, + &pDataType, + &pSymbol, + &pEqualSign, + &pValue, + &pSeparator, + &nest); + if (nest != 0) return; + if (count > 0) fprintf(output,","); + if (pDataType != NULL && pSymbol != NULL) { + q = strBetween(pDataType, pSymbol, pSeparator); + fprintf(output, "%s", q); + q = strBetween(pSymbol, pEqualSign, pSeparator); + fprintf(output," %s",q); + if (pValue != NULL) { + q = strBetween(pValue, NULL, pSeparator); + if (bInitializer != 0) { + fprintf(output, " = %s", q); + } + } + } + count++; + } +} + +/* MR23 Check for empty alt in a more intelligent way. + Previously, an empty alt for genBlk had to point directly + to the endBlock. This did not work once I changed {...} + blocks to look like (...|...| epsilon) since there were + intervening generics. This fixes the problem for this + particular case. Things like actions or empty blocks of + various kinds will still cause problems, but I wasnt't + prepared to handle pathological cases like (A|()*). It + does handle (A | ()), which is a recommended idiom for + epsilon. + + Actually, this isn't quite correct since it doesn't handle + the case of the ignore bit in the plus block bypass, but + I'm too tired to figure out the correct fix, and will just + work around it. +*/ + +#ifdef __USE_PROTOS +int isEmptyAlt(Node * alt, Node * endBlock) +#else +int isEmptyAlt(alt, endBlock) +Node * alt; +Node * endBlock; +#endif +{ + Node * n = alt; + Junction * j; + while (n != endBlock) { + switch (n->ntype) { + + case nRuleRef: + return 0; + + case nToken: + return 0; + + case nAction: + return 0; + + case nJunction: + goto JUNCTION; + + default: + fatal_internal("Invalid node type"); + return 0; + } +JUNCTION: + j = (Junction *) n; + + switch (j->jtype) { + case Generic: + { + n = j->p1; + goto NEXT; + } + + case aSubBlk: + { + n = j->p1; /* MR26 */ + goto NEXT; /* MR26 */ + } + + case EndBlk: + return 0; + + case EndRule: + return 1; + + default: + return 0; + } +NEXT: continue; + } + return 1; +} diff --git a/Tools/CodeTools/Source/Pccts/antlr/generic.h b/Tools/CodeTools/Source/Pccts/antlr/generic.h new file mode 100644 index 0000000000..8d736d5200 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/generic.h @@ -0,0 +1,286 @@ +/* + * generic.h -- generic include stuff for new PCCTS ANTLR. + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2001 + */ + +#define StrSame 0 + +#define DefaultParserName "zzparser" + +/* MR9 JVincent@novell.com Allow user to override default ZZLEXBUFSIZE */ +/* MR11 thm Raise antlr's own default ZZLEXBUFSIZE to 8k */ +/* MR22 thm Raise antlr's own default ZZLEXBUFSIZE to 32k */ + +#ifndef ZZLEXBUFSIZE +#define ZZLEXBUFSIZE 32000 +#endif + +/* Tree/FIRST/FOLLOW defines -- valid only after all grammar has been read */ +#define ALT TokenNum+1 +#define SET TokenNum+2 +#define TREE_REF TokenNum+3 + + /* E r r o r M a c r o s */ + +#define fatal(err) fatalFL(err, __FILE__, __LINE__) +#define fatal_internal(err) fatal_intern(err, __FILE__, __LINE__) + + +#define eMsg1(s,a) eMsg3(s,a,NULL,NULL) +#define eMsg2(s,a,b) eMsg3(s,a,b,NULL) + + /* S a n i t y C h e c k i n g */ + +#ifndef require +#define require(expr, err) {if ( !(expr) ) fatal_internal(err);} +#endif + + /* L i s t N o d e s */ + +typedef struct _ListNode { + void *elem; /* pointer to any kind of element */ + struct _ListNode *next; + } ListNode; + +/* Define a Cycle node which is used to track lists of cycles for later + * reconciliation by ResolveFoCycles(). + */ +typedef struct _c { + int croot; /* cycle root */ + set cyclicDep; /* cyclic dependents */ + unsigned deg; /* degree of FOLLOW set of croot */ + } Cycle; + +typedef struct _e { + int tok; /* error class name == TokenStr[tok] */ + ListNode *elist; /* linked list of elements in error set */ + set eset; + int setdeg; /* how big is the set */ + int lexclass; /* which lex class is it in? */ + } ECnode; + +typedef struct _TCnode { + int tok; /* token class name */ + ListNode *tlist; /* linked list of elements in token set */ + set tset; + int lexclass; /* which lex class is it in? */ + unsigned char dumped; /* this def has been been dumped */ + unsigned char dumpedComplement; /* this def has been been dumped */ + unsigned setnum; /* which set number is this guy? (if dumped) */ + unsigned setnumComplement; /* MR23 */ + unsigned setnumErrSet; /* MR23 which set is this #tokclass error set (if dumped) */ + unsigned setnumErrSetComplement; /* MR23 */ + } TCnode; + +typedef struct _ft { + char *token; /* id of token type to remap */ + int tnum; /* move token type to which token position */ + } ForcedToken; + +typedef struct _ContextGuardPredicates { /* MR13 */ + Predicate *pred; /* MR13 */ + } ContextGuardPredicates; /* MR13 */ + +#define newListNode (ListNode *) calloc(1, sizeof(ListNode)); +#define newCycle (Cycle *) calloc(1, sizeof(Cycle)); +#define newECnode (ECnode *) calloc(1, sizeof(ECnode)); +#define newTCnode (TCnode *) calloc(1, sizeof(TCnode)); + + + /* H a s h T a b l e E n t r i e s */ + +typedef struct _t { /* Token name or expression */ + char *str; + struct _t *next; + int token; /* token number */ + unsigned char classname; /* is it a err/tok class name or token */ + TCnode *tclass; /* ptr to token class */ + char *action; + char *akaString; + } TermEntry; + +typedef struct _r { /* Rule name and ptr to start of rule */ + char *str; + struct _t *next; + int rulenum; /* RulePtr[rulenum]== ptr to RuleBlk junction */ + unsigned char noAST;/* gen AST construction code? (def==gen code) */ + char *egroup; /* which error group (err reporting stuff) */ +#if 0 + /* MR27 This appears to never be used. Delete this code later. */ + + ListNode *el_labels;/* list of element labels ref in all of rule */ +#endif + ListNode *ast_labels_in_actions; /* MR27 */ + unsigned char has_rule_exception; + char dontComputeErrorSet; /* MR14 - don't compute error set + special for rule in alpha part of + (alpha)? beta block */ + } RuleEntry; + +typedef struct _f { /* cache Fi/Fo set */ + char *str; /* key == (rulename, computation, k) */ + struct _f *next; + set fset; /* First/Follow of rule */ + set rk; /* set of k's remaining to be done after ruleref */ + int incomplete; /* only w/FOLLOW sets. Use only if complete */ + } CacheEntry; + +typedef struct _LabelEntry { /* element labels */ + char *str; + struct _f *next; + Node *elem; /* which element does it point to? */ + ExceptionGroup *ex_group; + /* Is there an exception attached to label? */ + ExceptionGroup *outerEG; /* MR7 */ + /* next EG if ex_group doesn't catch it MR7 */ + struct _LabelEntry *pendingLink; /* MR7 */ + /* too lazy to use ListNode ? MR7 */ + int curAltNum; /* MR7 */ + } LabelEntry; + +typedef struct _SignalEntry { + char *str; + struct _f *next; + int signum; /* unique signal number */ + } SignalEntry; + +typedef struct _PredEntry { /* MR11 predicate name and ptr to string */ + char *str; + struct _PredEntry *next; + int file; + int line; + Predicate *pred; + char *predLiteral; + } PredEntry; + +typedef struct _PointerStack { /* MR10 */ + int count; + int size; + void **data; + } PointerStack; + +#define newTermEntry(s) (TermEntry *) newEntry(s, sizeof(TermEntry)) +#define newRuleEntry(s) (RuleEntry *) newEntry(s, sizeof(RuleEntry)) +#define newCacheEntry(s) (CacheEntry *) newEntry(s, sizeof(CacheEntry)) +#define newLabelEntry(s) (LabelEntry *) newEntry(s, sizeof(LabelEntry)) +#define newSignalEntry(s) (SignalEntry *) newEntry(s, sizeof(SignalEntry)) +#define newPredEntry(s) (PredEntry *) newEntry(s,sizeof(PredEntry)) + +typedef struct _UserAction { + char *action; + int file, line; + } UserAction; + + + /* L e x i c a l C l a s s */ + +/* to switch lex classes, switch ExprStr and Texpr (hash table) */ +typedef struct _lc { + char *classnum, **exprs; + Entry **htable; + } LClass; + +typedef struct _exprOrder { + char *expr; + int lclass; + } Expr; + + +typedef Graph Attrib; + + /* M a x i m u m s */ + +/* MR20 Note G. Hobbelt These values are superceded by values in hash.h */ + +#ifndef HashTableSize +#define HashTableSize 253 +#endif +#ifndef StrTableSize +#define StrTableSize 15000 /* all tokens, nonterminals, rexprs stored here */ +#endif +#define MaxLexClasses 50 /* how many automatons */ +/* TokenStart and EofToken are ignored if #tokdefs meta-op is used */ +#define TokenStart 2 /* MUST be in 1 + EofToken */ +#define EofToken 1 /* Always predefined to be 1 */ + +#ifndef MaxNumFiles +#define MaxNumFiles 99 +#endif + +/**** MR9 JVincent@novell.com Move to pcctscfg.h */ +/**** #define MaxFileName 300 ****/ /* MR9 Move to pcctscfg.h */ /* largest file name size */ + +#define MaxRuleName 100 /* largest rule name size */ +#define TSChunk 100 /* how much to expand TokenStr/ExprStr each time */ +#define TIChunk TSChunk /* expand TokenInd by same as TokenStr to mirror them */ +#define FoStackSize 100 /* deepest FOLLOW recursion possible */ + +#define MaxClassDeclStuff 256 /* MR10 */ + +#define NumPredefinedSignals 3 + + /* S t a n d a r d S i g n a l s */ + +#define sigNoSignal 0 +#define sigMismatchedToken 1 +#define sigNoViableAlt 2 +#define sigNoSemViableAlt 3 + + + +/* AST token types */ +#define ASTexclude 0 +#define ASTchild 1 +#define ASTroot 2 +#define ASTinclude 3 /* include subtree made by rule ref */ + + +#define PredictionVariable "zzpr_expr" +#define PredictionLexClassSuffix "_zzpred" + +#define WildCardString "WildCard" + +#if 0 + /* Removed in version 1.33MR19 + Don't understand why this never caused problems before + */ + + /********************************************************* + #ifndef ANTLRm + #define ANTLRm(st, f, _m) zzbufsize = ZZLEXBUFSIZE;\ + zzmode(_m); \ + zzenterANTLR(f); \ + st; ++zzasp; \ + zzleaveANTLR(f); + #endif + *********************************************************/ +#endif + +#include "proto.h" +#include "pcctscfg.h" /* MR14 */ +#include diff --git a/Tools/CodeTools/Source/Pccts/antlr/globals.c b/Tools/CodeTools/Source/Pccts/antlr/globals.c new file mode 100644 index 0000000000..59d00320a0 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/globals.c @@ -0,0 +1,484 @@ +/* + * globals.c -- File containing all variables/tables visible to all files. + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2001 + */ + +#include + +#include "pcctscfg.h" + +#include "set.h" +#include "syn.h" +#include "hash.h" +#include "generic.h" + +char Version[] = "1.33MR33" ; /* PCCTS version number */ /* MRXXX */ +char VersionDef[] = "13333"; /* same (except int equiv for preproc symbol) */ /* MRXXX */ + +char LexStartSymbol[] = "START";/* Name of starting lexical class/automaton */ +char *RemapFileName = "remap.h"; +char *DlgFileName = "parser.dlg"; +char *DefFileName = "tokens.h"; +char *ErrFileName = "err.c"; +char *ModeFileName = "mode.h"; +char *StdMsgName = NULL; + +char *ParserName = DefaultParserName; + +/* list of PCCTS supplied support symbols; these are renamed when more than + * one ANTLR-generated parsers are linked together to avoid name conflicts. + * Can't use '##' ANSIC preprocessor concat operator with K&R and: + * #define zzskip zzparser ## skip + * will not work for ANSI/C++ as 'zzparserskip' is created w/o zzparser + * being substituted--ack!!! + */ +char *StandardSymbols[] = { +/* ANTLR stuff */ + "zzStackOvfMsg", + "zzasp", + "zzaStack", + "inf_tokens", + "inf_text", + "inf_text_buffer", + "inf_text_buffer_ptr", + "inf_text_buffer_size", + "inf_labase", + "inf_last", + "inf_lap", + "zztokenLA", + "zztextLA", + "zzlap", + "zzlabase", + "zztoktext", + "zztoken", + "zzdirty", + "zzguessing", + "zzguess_start", + "zzresynch", + "zzinf_tokens", + "zzinf_text", + "zzinf_text_buffer", + "zzinf_labase", + "zzinf_last", + "zzfill_inf_look", + "zzFAIL", + "zzsave_antlr_state", + "zzrestore_antlr_state", + "zzsyn", + "zzset_el", + "zzset_deg", + "zzedecode", + "_zzsetmatch", + "_zzmatch", + "_inf_zzgettok", + "zzconsumeUntil", + "zzconsumeUntilToken", + "_zzmatch_wsig", + "_zzsetmatch_wsig", + "_zzmatch_wdfltsig", + "_zzsetmatch_wdfltsig", + "zzdflthandlers", +/* DLG stuff */ + "zzreal_line", + "zzcharfull", + "zzerr", + "zzlextext", + "zzbegexpr", + "zzendexpr", + "zzbufsize", + "zzbegcol", + "zzendcol", + "zzline", + "zzchar", + "zzbufovf", + "zzrdstream", + "zzrdfunc", + "zzrdstr", + "zzclose_stream", + "zzsave_dlg_state", + "zzrestore_dlg_state", + "zzmode", + "zzskip", + "zzmore", + "zzreplchar", + "zzreplstr", + "zzgettok", + "zzadvance", + "zzerrstd", + "zzerr_in", + "zzconstr_attr", + "zzempty_attr", + "zzerraction", + "zztokens", /* list of token regular expressions */ + "dfa", + "accepts", + "actions", + "zzTraceOptionValue", /* MR10 */ + "zzTraceGuessOptionValue", /* MR10 */ + "zzTraceCurrentRuleName", /* MR10 */ + "zzTraceDepth", /* MR10 */ + "zzGuessSeq", /* MR10 */ + "zzSyntaxErrCount", /* MR11 */ + "zzLexErrCount", /* MR11 */ + "zzTraceGuessDone", /* MR13 - BJS */ + "zzTraceGuessFail", /* MR13 - BJS */ + "zzTraceGuessOption", /* MR13 - BJS */ + "zzTraceIn", /* MR13 - BJS */ + "zzTraceOption", /* MR13 - BJS */ + "zzTraceOut", /* MR13 - BJS */ + "zzTraceReset", /* MR13 - BJS */ + NULL /* must be present */ +}; + +/* list of PCCTS supplied support functions; these are renamed when more than + * one ANTLR-generated parsers are linked together to avoid name conflicts. + */ +char *ASTSymbols[] = { + "AST", + "zzast_sp", + "zzastStack", + "zzlink", + "zzastnew", + "zzsubchild", + "zzsubroot", + "zzpre_ast", + "zzfree_ast", + "zztmake", + "zzdup_ast", + "zztfree", + "zzdouble_link", + NULL /* must be present */ +}; + +/* Current ambiguity examination information */ +int CurAmbigAlt1, CurAmbigAlt2, CurAmbigline, CurAmbigfile; +char *CurAmbigbtype; + + + /* M e t h o d T a b l e s */ +/* + * The following tables are used to fill syntax diagram nodes with the correct + * function pointers for computing FIRST sets and printing themselves. + */ + +/* fpTraverse[node type] == pointer to function that calculates trees + * representing the FIRST sets for that node (maintains spatial info). + * We use 'struct _tree' not 'tree' due to a g++ 2.4.3 bug. + */ +#ifdef __cplusplus +struct _tree *(*fpTraverse[NumNodeTypes+1])(... /* Node *, int, set * */) = { + NULL, + (struct _tree *(*)(...)) tJunc, + (struct _tree *(*)(...)) tRuleRef, + (struct _tree *(*)(...)) tToken, + (struct _tree *(*)(...)) tAction +}; +#else +Tree *(*fpTraverse[NumNodeTypes+1])() = { + NULL, + tJunc, + tRuleRef, + tToken, + tAction +}; +#endif + +/* fpReach[node type] == pointer to function that calculates FIRST set for + * that node. (r stands for reach). We use 'struct _set' not 'set' + * due to a g++ 2.4.3 bug. + */ +#ifdef __cplusplus +struct _set (*fpReach[NumNodeTypes+1])(... /* Node *, int, set * */) = { + NULL, + (struct _set (*)(...)) rJunc, + (struct _set (*)(...)) rRuleRef, + (struct _set (*)(...)) rToken, + (struct _set (*)(...)) rAction +}; +#else +set (*fpReach[NumNodeTypes+1])() = { + NULL, + rJunc, + rRuleRef, + rToken, + rAction +}; +#endif + +/* fpPrint[node type] == pointer to function that knows how to print that node. */ +#ifdef __cplusplus +void (*fpPrint[NumNodeTypes+1])(... /* Node * */) = { + NULL, + (void (*)(...)) pJunc, + (void (*)(...)) pRuleRef, + (void (*)(...)) pToken, + (void (*)(...)) pAction +}; +#else +void (*fpPrint[NumNodeTypes+1])() = { + NULL, + pJunc, + pRuleRef, + pToken, + pAction +}; +#endif + +char *decodeJType[] = { + "invalid", + "aSubBlk", + "aOptBlk", + "aLoopBlk", + "EndBlk", + "RuleBlk", + "Generic", + "EndRule", + "aPlusBlk", + "aLoopBegin" +}; + + + /* H a s h T a b l e s */ + +Entry **Tname, /* Table of all token names (maps name to tok num)*/ + **Texpr, /* Table of all token expressions + (maps expr to tok num) */ + **Rname, /* Table of all Rules (has ptr to start of rule) */ + **Fcache, /* Cache of First/Follow Computations */ + **Tcache; /* Tree cache; First/Follow for permute trees */ +Entry **Elabel; /* Table of all element label names */ +Entry **Sname; /* Signal names */ +Entry **Pname; /* symbolic predicate names MR11 */ + + + /* V a r i a b l e s */ + +int Save_argc; /* MR10 */ +char **Save_argv; /* MR10 */ +int EpToken=0; /* Imaginary Epsilon token number */ +int WildCardToken=0; +int CurFile= -1; /* Index into FileStr table */ +char *CurPredName=NULL; /* MR11 */ +char *CurRule=NULL; /* Pointer to current rule name */ +int CurRuleDebug=0; /* MR13 debug flag */ +RuleEntry *CurRuleNode=NULL;/* Pointer to current rule node in syntax tree */ +char *CurRetDef=NULL; /* Pointer to current return type definition */ +char *CurParmDef=NULL; /* Pointer to current parameter definition */ +Junction *CurRuleBlk=NULL; /* Pointer to current block node for enclosing block */ +ListNode *CurExGroups=NULL; /* Current list of exception groups for rule/alts */ +ListNode *CurElementLabels=NULL; +ListNode *CurAstLabelsInActions=NULL; /* MR27 */ + +/* MR10 used by <<>>? to set "label_used_in_semantic_pred" */ +/* MR10 this will force LT(i) assignment even in guess mode */ + +ListNode *CurActionLabels=NULL; /* MR10 Element Labels appearing in last action */ +int numericActionLabel=0 ; /* MR10 << ... $1 ... >> or << ... $1 ... >>? */ +ListNode *NumericPredLabels=NULL; /* MR10 << ... $1 ... >>? ONLY */ +ListNode *ContextGuardPredicateList=NULL; /* MR13 for re-evaluating predicates + after meta tokens are defined */ + +int CurBlockID=0; /* Unique int for each block */ +int CurAltNum=0; +Junction *CurAltStart = NULL; /* Junction node that starts the alt */ +Junction *OuterAltStart = NULL; /* For chaining exception groups MR7 */ +int NumRules=0; /* Rules are from 1 to n */ +FILE *output=NULL; /* current parser output file */ +FILE *input=NULL; /* current grammar input file */ +char *FileStr[MaxNumFiles];/* Ptr to array of file names on command-line */ +int NumFiles=0; /* current grammar file number */ +#ifdef __cplusplus +void (**fpTrans)(...), /* array of ptrs to funcs that translate nodes */ + (**fpJTrans)(...); /* ... that translate junctions */ +#else +void (**fpTrans)(), /* array of ptrs to funcs that translate nodes */ + (**fpJTrans)(); /* ... that translate junctions */ +#endif +int **FoStack; /* Array of LL_k ptrs to stacks of rule numbers */ +int **FoTOS; /* FOLLOW stack top-of-stack pointers */ +Junction *SynDiag = NULL; /* Pointer to start of syntax diagram */ +int BlkLevel=1; /* Current block level. Set by antlr.g, used by + * scanner to translate $i.j attributes */ +set reserved_positions; /* set of token positions reserved by '#token T=i' cmds */ +set all_tokens; /* set of all token types */ +set imag_tokens; /* set of all imaginary token types (EpToken, errclasses...) */ +set tokclasses; /* set of all token class token types */ +ListNode *ForcedTokens = 0; /* list of token_id/token_num pairs to remap */ +ListNode *MetaTokenNodes=NULL; /* list of meta token refs such as token classes etc... */ +int *TokenInd=NULL; /* an indirection level between token num and position + * of that token def in TokenStr and ExprStr */ +int LastTokenCounted=0; /* ==TokenNum if no token renumbering (same as old TokenNum) */ +int TokenNum=TokenStart; +char **TokenStr=NULL; /* map token # to token name */ +char **ExprStr=NULL; /* map token # to expr */ +Junction **RulePtr=NULL; /* map rule # to RuleBlk node of rule */ +ListNode *ExprOrder=NULL; /* list of exprs as they are found in grammar */ +ListNode *BeforeActions=NULL;/* list of grammar actions before rules */ +ListNode *AfterActions=NULL;/* list of grammar actions after rules */ +ListNode *LexActions=NULL; /* list of lexical actions */ + +/* MR1 */ +/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ +/* MR1 via #lexmember <<....>> */ +/* MR1 via #lexprefix <<....>> */ +/* MR1 */ + +ListNode *LexMemberActions=NULL;/* list of lexical header member decl MR1 */ +ListNode *LexPrefixActions=NULL;/* list of lexical header #include decl MR1 */ +ListNode **Cycles=NULL; /* list of cycles (for each k) found when + doing FOLLOWs */ +ListNode *eclasses=NULL; /* list of error classes */ +ListNode *tclasses=NULL; /* list of token classes */ +LClass lclass[MaxLexClasses]; /* array of lex class definitions */ +int CurrentLexClass; /* index into lclass */ +int NumLexClasses=0; /* in range 1..MaxLexClasses (init 0) */ + +char *HdrAction=NULL; /* action defined with #header */ +char *FirstAction=NULL; /* action defined with #first MR11 */ +FILE *ErrFile; /* sets and error recovery stuff */ +FILE *DefFile=NULL; /* list of tokens, return value structs, setwd defs */ +FILE *MRinfoFile=NULL; /* MR10 information file */ +int MRinfo=0; /* MR10 */ +int MRinfoSeq=0; /* MR10 */ +int InfoP=0; /* MR10 predicates */ +int InfoT=0; /* MR10 tnodes */ +int InfoF=0; /* MR10 first/follow sets */ +int InfoM=0; /* MR10 monitor progress */ +int InfoO=0; /* MR12 orphan rules */ +int TnodesInUse=0; /* MR10 */ +int TnodesPeak=0; /* MR10 */ +int TnodesAllocated=0; /* MR10 */ +int TnodesReportThreshold=0; /* MR11 */ +int PotentialSuppression=0; /* MR10 */ +int PotentialDummy=0; /* MR10 */ +int CannotContinue=FALSE; +int OutputLL_k = 1; /* LL_k for parsing must be power of 2 */ +int action_file; /* used to track start of action */ +int action_line; +int FoundGuessBlk=0; /* there is a (...)? block somewhere in grammar */ +int FoundException=0; /* there is an exception somewhere in grammar */ +/* MR6 Distinguish between @ operator and real exception */ +/* MR6 by keeping separate flags for @ operator and real exceptions */ +int FoundAtOperator=0; /* MR6 */ +int FoundExceptionGroup=0; /* MR6 */ +int pLevel=0; /* print Level */ +int pAlt1,pAlt2; /* print "==>" in front of these alts */ + +/* C++ output stuff */ +FILE *Parser_h, /* where subclass of ANTLRParser goes */ + *Parser_c; /* where code for subclass of ANTLRParser goes */ +char Parser_h_Name[MaxFileName+1] = ""; +char Parser_c_Name[MaxFileName+1] = ""; +char MRinfoFile_Name[MaxFileName+1] = ""; /* MR10 */ +char *ClassDeclStuff=NULL; /* MR10 */ +char *BaseClassName=NULL; /* MR22 */ +/* list of actions inside the #class {...} defs */ +ListNode *class_before_actions=NULL; +ListNode *class_after_actions=NULL; + +char CurrentClassName[MaxRuleName]=""; +int no_classes_found=1; +char *UserTokenDefsFile; +int UserDefdTokens=0; /* found #tokdefs? */ +char *OutputDirectory=TopDirectory; +ExceptionGroup *DefaultExGroup = NULL; +int NumSignals = NumPredefinedSignals; +int ContextGuardTRAV=0; + +char *MR_AmbAidRule=NULL; /* MR11 */ +int MR_AmbAidLine=0; /* MR11 */ +int MR_AmbAidDepth=0; /* MR11 */ +int MR_AmbAidMultiple=0; /* MR11 */ +int MR_skipped_e3_report=0; /* MR11 */ +int MR_usingPredNames=0; /* MR11 */ +int MR_BadExprSets=0; /* MR13 */ +int MR_Inhibit_Tokens_h_Gen=0; /* MR13 */ +int NewAST=0; /* MR13 */ +int tmakeInParser=0; /* MR23 */ +int AlphaBetaTrace=0; /* MR14 */ +int MR_BlkErr=0; /* MR21 */ +int MR_AlphaBetaMessageCount=0; /* MR14 */ +int MR_AlphaBetaWarning=0; /* MR14 */ +int MR_ErrorSetComputationActive=0; /* MR14 */ +int MR_MaintainBackTrace=0; /* MR14 */ +set MR_CompromisedRules; /* MR14 */ + +Junction *MR_RuleBlkWithHalt; /* MR10 */ + + /* C m d - L i n e O p t i o n s */ + +int LL_k=1; /* how many tokens of full lookahead */ +int CLL_k= -1; /* how many tokens of compressed lookahead */ +int PrintOut = FALSE; /* print out the grammar */ +int PrintAnnotate = FALSE;/* annotate printout with FIRST sets */ +int CodeGen=TRUE; /* Generate output code? */ +int LexGen=TRUE; /* Generate lexical files? (tokens.h, parser.dlg) */ +int GenAST=FALSE; /* Generate AST's? */ +int GenANSI=FALSE; /* Generate ANSI code where necessary */ +int GenExprSetsOpt=TRUE;/* use sets not (LA(1)==tok) expression lists */ +int GenCR=FALSE; /* Generate cross reference? */ +int GenLineInfo=FALSE; /* Generate # line "file" stuff? */ +int GenLineInfoMS=FALSE;/* Like -gl but replace "\" with "/" for MS C/C++ systems */ +int TraceGen=FALSE; /* Generate code to trace rule invocation */ +int elevel=1; /* error level for ambiguity messages */ +int GenEClasseForRules=0;/* don't generate eclass for each rule */ +int TreeResourceLimit= -1;/* don't limit tree resource */ +int DemandLookahead = 0;/* demand/delayed lookahead or not */ +char *RulePrefix = ""; /* prefix each generated rule with this */ +char *stdpccts = "stdpccts.h";/* where to generate std pccts include file */ +int GenStdPccts = 0; /* don't gen stdpccts.h? */ +int ParseWithPredicates = 1; +int WarningLevel = 1; +int UseStdout = 0; /* MR6 */ +int TabWidth = 2; /* MR6 */ /* MR27 */ +int HoistPredicateContext = 0; +int MRhoisting = 0; /* MR9 */ +int MRhoistingk = 0; /* MR13 */ +int MR_debugGenRule=0; /* MR11 */ + +int GenCC = 0; /* Generate C++ output */ + +PointerStack MR_BackTraceStack={0,0,NULL}; /* MR10 */ +PointerStack MR_PredRuleRefStack={0,0,NULL}; /* MR10 */ +PointerStack MR_RuleBlkWithHaltStack={0,0,NULL}; /* MR10 */ + +/* DontCopyTokens and Pragma_DupLabeledTokens were a bad idea. I've just + turned them off rather than backpatching the code. Who knows? We + may need them in the future. + */ +int DontCopyTokens = 1; /* in C++, don't copy ANTLRToken passed to ANTLR */ + +/* Remember if LT(i), LA(i), or LATEXT(i) used in an action which is not + a predicate. If so, give a warning for novice users. +*/ + +int LTinTokenAction = 0; /* MR23 */ +int PURIFY = 1; /* MR23 */ + +int CurBlockID_array[MAX_BLK_LEVEL]; /* MR23 */ +int CurAltNum_array[MAX_BLK_LEVEL]; /* MR23 */ diff --git a/Tools/CodeTools/Source/Pccts/antlr/hash.c b/Tools/CodeTools/Source/Pccts/antlr/hash.c new file mode 100644 index 0000000000..68fe8fd227 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/hash.c @@ -0,0 +1,221 @@ +/* + * hash.c + * + * Manage hash tables. + * + * The following functions are visible: + * + * char *mystrdup(char *); Make space and copy string + * Entry **newHashTable(); Create and return initialized hash table + * Entry *hash_add(Entry **, char *, Entry *) + * Entry *hash_get(Entry **, char *) + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2001 + */ + +#include +#include "pcctscfg.h" +#include "hash.h" + +#ifdef __USE_PROTOS +#include +#else +#ifdef VAXC +#include +#else +#include +#endif +#endif +#include + +#define StrSame 0 + +#define fatal(err) \ + {fprintf(stderr, "%s(%d):", __FILE__, __LINE__); \ + fprintf(stderr, " %s\n", err); exit(PCCTS_EXIT_FAILURE);} +#define require(expr, err) {if ( !(expr) ) fatal(err);} + +static unsigned size = HashTableSize; +static char *strings = NULL; +static char *strp; +static unsigned strsize = StrTableSize; + +/* create the hash table and string table for terminals (string table only once) */ +Entry ** +#ifdef __USE_PROTOS +newHashTable( void ) +#else +newHashTable( ) +#endif +{ + Entry **table; + + table = (Entry **) calloc(size, sizeof(Entry *)); + require( table != NULL, "cannot allocate hash table"); + if ( strings == NULL ) + { + strings = (char *) calloc(strsize, sizeof(char)); + require( strings != NULL, "cannot allocate string table"); + strp = strings; + } + return table; +} + +void +#ifdef __USE_PROTOS +killHashTable( Entry **table ) +#else +killHashTable( table ) +Entry **table; +#endif +{ + /* for now, just free table, forget entries */ + free( (char *) table ); /* MR10 cast */ +} + +/* Given a table, add 'rec' with key 'key' (add to front of list). return ptr to entry */ +Entry * +#ifdef __USE_PROTOS +hash_add( Entry **table, char *key, Entry *rec ) +#else +hash_add( table, key, rec ) +Entry **table; +char *key; +Entry *rec; +#endif +{ + unsigned h=0; + char *p=key; + require(table!=NULL && key!=NULL && rec!=NULL, "add: invalid addition"); + + Hash(p,h,size); + rec->next = table[h]; /* Add to singly-linked list */ + table[h] = rec; + return rec; +} + +/* Return ptr to 1st entry found in table under key (return NULL if none found) */ +Entry * +#ifdef __USE_PROTOS +hash_get( Entry **table, char *key ) +#else +hash_get( table, key ) +Entry **table; +char *key; +#endif +{ + unsigned h=0; + char *p=key; + Entry *q; +/* require(table!=NULL && key!=NULL, "get: invalid table and/or key");*/ + if ( !(table!=NULL && key!=NULL) ) *((char *) 34) = 3; + + Hash(p,h,size); + for (q = table[h]; q != NULL; q = q->next) + { + if ( strcmp(key, q->str) == StrSame ) return( q ); + } + return( NULL ); +} + +#ifdef DEBUG_HASH +void +#ifdef __USE_PROTOS +hashStat( Entry **table ) +#else +hashStat( table ) +Entry **table; +#endif +{ + static unsigned short count[20]; + int i,n=0,low=0, hi=0; + Entry **p; + float avg=0.0; + + for (i=0; i<20; i++) count[i] = 0; + for (p=table; p<&(table[size]); p++) + { + Entry *q = *p; + int len; + + if ( q != NULL && low==0 ) low = p-table; + len = 0; + if ( q != NULL ) fprintf(stderr, "[%d]", p-table); + while ( q != NULL ) + { + len++; + n++; + fprintf(stderr, " %s", q->str); + q = q->next; + if ( q == NULL ) fprintf(stderr, "\n"); + } + count[len]++; + if ( *p != NULL ) hi = p-table; + } + + fprintf(stderr, "Storing %d recs used %d hash positions out of %d\n", + n, size-count[0], size); + fprintf(stderr, "%f %% utilization\n", + ((float)(size-count[0]))/((float)size)); + for (i=0; i<20; i++) + { + if ( count[i] != 0 ) + { + avg += (((float)(i*count[i]))/((float)n)) * i; + fprintf(stderr, "Bucket len %d == %d (%f %% of recs)\n", + i, count[i], ((float)(i*count[i]))/((float)n)); + } + } + fprintf(stderr, "Avg bucket length %f\n", avg); + fprintf(stderr, "Range of hash function: %d..%d\n", low, hi); +} +#endif + +/* Add a string to the string table and return a pointer to it. + * Bump the pointer into the string table to next avail position. + */ +char * +#ifdef __USE_PROTOS +mystrdup( char *s ) +#else +mystrdup( s ) +char *s; +#endif +{ + char *start=strp; + require(s!=NULL, "mystrdup: NULL string"); + + while ( *s != '\0' ) + { + require( strp <= &(strings[strsize-2]), + "string table overflow\nIncrease StrTableSize in hash.h and recompile hash.c\n"); + *strp++ = *s++; + } + *strp++ = '\0'; + + return( start ); +} diff --git a/Tools/CodeTools/Source/Pccts/antlr/hash.h b/Tools/CodeTools/Source/Pccts/antlr/hash.h new file mode 100644 index 0000000000..3969c40b4a --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/hash.h @@ -0,0 +1,73 @@ +/* + * hash.h -- define hash table entries, sizes, hash function... + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2001 + */ + + /* H a s h T a b l e S t u f f */ + +#ifndef HashTableSize +#define HashTableSize 553 +#endif + +#ifndef StrTableSize +#ifdef PC32 +#define StrTableSize 1000000 +#endif +#endif + +#ifndef StrTableSize +#ifdef PC +#define StrTableSize 655200 +#endif +#endif + +#ifndef StrTableSize +#define StrTableSize 1000000 +#endif + +typedef struct _entry { /* Minimum hash table entry -- superclass */ + char *str; + struct _entry *next; + } Entry; + +/* Hash 's' using 'size', place into h (s is modified) */ +#define Hash(s,h,size) \ + {while ( *s != '\0' ) h = (h<<1) + *s++; \ + h %= size;} + +#ifdef __USE_PROTOS +Entry *hash_get(Entry **, char *), + **newHashTable(void), + *hash_add(Entry **, char *, Entry *); + +void killHashTable(Entry **); + +#else +Entry *hash_get(), **newHashTable(), *hash_add(); +void killHashTable(); /* MR9 23-Sep-97 */ +#endif diff --git a/Tools/CodeTools/Source/Pccts/antlr/lex.c b/Tools/CodeTools/Source/Pccts/antlr/lex.c new file mode 100644 index 0000000000..8c524fe465 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/lex.c @@ -0,0 +1,878 @@ +/* + * lex.c -- Generate all of the lexical type files: parser.dlg tokens.h + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2001 + */ + +#include +#include +/* MR1 */ +/* MR1 10-Apr-97 MR1 Replace use of __STDC__ with __USE_PROTOS */ +/* MR1 */ +#include "pcctscfg.h" +#include "set.h" +#include "syn.h" +#include "hash.h" +#include "generic.h" + +#define DLGErrorString "invalid token" + +/* Generate a complete lexical description of the lexemes found in the grammar */ +void +#ifdef __USE_PROTOS +genLexDescr( void ) +#else +genLexDescr( ) +#endif +{ + ListNode *p; + FILE *dlgFile = fopen(OutMetaName(DlgFileName), "w"); + require(dlgFile!=NULL, eMsg1("genLexFile: cannot open %s", OutMetaName(DlgFileName)) ); +#ifdef SPECIAL_FOPEN + special_fopen_actions(OutMetaName(DlgFileName)); /* MR1 */ +#endif + fprintf(dlgFile, "<<\n"); + fprintf(dlgFile, "/* %s -- DLG Description of scanner\n", DlgFileName); + fprintf(dlgFile, " *\n"); + fprintf(dlgFile, " * Generated from:"); + {int i; for (i=0; i 1 ) fprintf(dlgFile, "#define LL_K %d\n", OutputLL_k); + if ( DemandLookahead ) fprintf(dlgFile, "#define DEMAND_LOOK\n"); + if (TraceGen) { + fprintf(dlgFile,"#ifndef zzTRACE_RULES\n"); /* MR20 */ + fprintf(dlgFile,"#define zzTRACE_RULES\n"); /* MR20 */ + fprintf(dlgFile,"#endif\n"); /* MR22 */ + }; + fprintf(dlgFile, "#include \"antlr.h\"\n"); + if ( GenAST ) { + fprintf(dlgFile, "#include \"ast.h\"\n"); + } + if ( UserDefdTokens ) + fprintf(dlgFile, "#include %s\n", UserTokenDefsFile); + /* still need this one as it has the func prototypes */ + fprintf(dlgFile, "#include \"%s\"\n", DefFileName); + fprintf(dlgFile, "#include \"dlgdef.h\"\n"); + fprintf(dlgFile, "LOOKAHEAD\n"); + fprintf(dlgFile, "\n"); + fprintf(dlgFile, "void\n"); + fprintf(dlgFile, "#ifdef __USE_PROTOS\n"); + fprintf(dlgFile, "zzerraction(void)\n"); + fprintf(dlgFile, "#else\n"); + fprintf(dlgFile, "zzerraction()\n"); + fprintf(dlgFile, "#endif\n"); + fprintf(dlgFile, "{\n"); + fprintf(dlgFile, "\t(*zzerr)(\"%s\");\n", DLGErrorString); + fprintf(dlgFile, "\tzzadvance();\n"); + fprintf(dlgFile, "\tzzskip();\n"); + fprintf(dlgFile, "}\n"); + } + fprintf(dlgFile, ">>\n\n"); + + /* dump all actions */ + +/* MR1 */ +/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ +/* MR1 via <<%%lexmember ....>> & <<%%lexprefix ...>> */ +/* MR1 */ + if (LexActions != NULL) { + for (p = LexActions->next; p!=NULL; p=p->next) + { +/* MR1 */ fprintf(dlgFile, "<<%%%%lexaction\n"); + dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 ); + fprintf(dlgFile, ">>\n\n"); + } + }; + +/* MR1 */ if (GenCC) { +/* MR1 */ fprintf(dlgFile,"<<%%%%parserclass %s>>\n\n",CurrentClassName); +/* MR1 */ }; + +/* MR1 */ if (LexPrefixActions != NULL) { +/* MR1 */ for (p = LexPrefixActions->next; p!=NULL; p=p->next) +/* MR1 */ { +/* MR1 */ fprintf(dlgFile, "<<%%%%lexprefix\n"); +/* MR1 */ dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 ); +/* MR1 */ fprintf(dlgFile, ">>\n\n"); +/* MR1 */ } +/* MR1 */ }; + +/* MR1 */ if (LexMemberActions != NULL) { +/* MR1 */ for (p = LexMemberActions->next; p!=NULL; p=p->next) +/* MR1 */ { +/* MR1 */ fprintf(dlgFile, "<<%%%%lexmember\n"); +/* MR1 */ dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 ); +/* MR1 */ fprintf(dlgFile, ">>\n\n"); +/* MR1 */ } +/* MR1 */ }; + + /* dump all regular expression rules/actions (skip sentinel node) */ + if ( ExprOrder == NULL ) { + warnNoFL("no regular expressions found in grammar"); + } + else dumpLexClasses(dlgFile); + fprintf(dlgFile, "%%%%\n"); + fclose( dlgFile ); +} + +/* For each lexical class, scan ExprOrder looking for expressions + * in that lexical class. Print out only those that match. + * Each element of the ExprOrder list has both an expr and an lclass + * field. + */ +void +#ifdef __USE_PROTOS +dumpLexClasses( FILE *dlgFile ) +#else +dumpLexClasses( dlgFile ) +FILE *dlgFile; +#endif +{ + int i; + TermEntry *t; + ListNode *p; + Expr *q; + + for (i=0; inext; p!=NULL; p=p->next) + { + q = (Expr *) p->elem; + if ( q->lclass != i ) continue; + lexmode(i); + t = (TermEntry *) hash_get(Texpr, q->expr); + require(t!=NULL, eMsg1("genLexDescr: rexpr %s not in hash table",q->expr) ); + if ( t->token == EpToken ) continue; + fprintf(dlgFile, "%s\n\t<<\n", StripQuotes(q->expr)); + /* replace " killed by StripQuotes() */ + q->expr[ strlen(q->expr) ] = '"'; + if ( !GenCC ) { + if ( TokenString(t->token) != NULL ) + fprintf(dlgFile, "\t\tNLA = %s;\n", TokenString(t->token)); + else + fprintf(dlgFile, "\t\tNLA = %d;\n", t->token); + } + if ( t->action != NULL ) dumpAction( t->action, dlgFile, 2,-1,0,1 ); + if ( GenCC ) { + if ( TokenString(t->token) != NULL ) + fprintf(dlgFile, "\t\treturn %s;\n", TokenString(t->token)); + else + fprintf(dlgFile, "\t\treturn (ANTLRTokenType)%d;\n", t->token); + } + fprintf(dlgFile, "\t>>\n\n"); + } + } +} + +/* Strip the leading path (if any) from a filename */ +char * +#ifdef __USE_PROTOS +StripPath( char *fileName ) +#else +StripPath( fileName ) +char *fileName; +#endif +{ + char *p; + static char dirSym[2] = DirectorySymbol; + + if(NULL != (p = strrchr(fileName, dirSym[0]))) + p++; + else + p = fileName; + + return(p); +} + +/* Generate a list of #defines && list of struct definitions for + * aggregate retv's */ +void +#ifdef __USE_PROTOS +genDefFile( void ) +#else +genDefFile( ) +#endif +{ + int i; + + /* If C++ mode and #tokdef used, then don't need anything in here since + * C++ puts all definitions in the class file name. + */ + if ( GenCC && UserTokenDefsFile ) return; + if ( MR_Inhibit_Tokens_h_Gen) return; + + DefFile = fopen(OutMetaName(DefFileName), "w"); + require(DefFile!=NULL, eMsg1("genDefFile: cannot open %s", OutMetaName(DefFileName)) ); +#ifdef SPECIAL_FOPEN + special_fopen_actions(OutMetaName(DefFileName)); /* MR1 */ +#endif + fprintf(DefFile, "#ifndef %s\n", StripPath(gate_symbol(DefFileName))); + fprintf(DefFile, "#define %s\n", StripPath(gate_symbol(DefFileName))); + + fprintf(DefFile, "/* %s -- List of labelled tokens and stuff\n", DefFileName); + fprintf(DefFile, " *\n"); + fprintf(DefFile, " * Generated from:"); + for (i=0; i1 ) + { + int j; + /* look in all lexclasses for the reg expr */ + +/* MR10 Derek Pappas */ +/* MR10 A #tokclass doesn't have associated regular expressiones */ +/* MR10 so don't warn user about it's omission */ + + p = (TermEntry *) hash_get(Tname, TokenString(i)); + + if (p != NULL && ! p->classname) { + for (j=0; j=NumLexClasses ) + { + warnNoFL(eMsg1("token label has no associated rexpr: %s",TokenString(i))); + } + }; + } + require((p=(TermEntry *)hash_get(Tname, TokenString(i))) != NULL, + "token not in sym tab when it should be"); + if ( !p->classname ) + { + if ( GenCC ) { + if ( !first ) fprintf(DefFile, ",\n"); + first = 0; + fprintf(DefFile, "\t%s=%d", TokenString(i), i); + } + else + fprintf(DefFile, "#define %s %d\n", TokenString(i), i); + } + } + } +/* MR1 */ +/* MR1 10-Apr-97 133MR1 Prevent use of varying sizes of integer */ +/* MR1 for the enum ANTLRTokenType */ +/* MR1 */ + if ( GenCC ) { /* MR1 */ + if ( !first ) fprintf(DefFile, ",\n"); /* MR14 */ + fprintf(DefFile, "\tDLGminToken=0"); /* MR1 */ + fprintf(DefFile, ",\n\tDLGmaxToken=9999};\n"); /* MR1 */ + }; /* MR1 */ + } + + if ( !GenCC ) GenRulePrototypes(DefFile, SynDiag); + + fprintf(DefFile, "\n#endif\n"); +} + +void +#ifdef __USE_PROTOS +GenRemapFile( void ) +#else +GenRemapFile( ) +#endif +{ + if ( strcmp(ParserName, DefaultParserName)!=0 ) + { + FILE *f; + int i; + + f = fopen(OutMetaName(RemapFileName), "w"); + require(f!=NULL, eMsg1("GenRemapFile: cannot open %s", OutMetaName(RemapFileName)) ); +#ifdef SPECIAL_FOPEN + special_fopen_actions(OutMetaName(RemapFileName)); /* MR1 */ +#endif + fprintf(f, "/* %s -- List of symbols to remap\n", RemapFileName); + fprintf(f, " *\n"); + fprintf(f, " * Generated from:"); + for (i=0; irname, ParserName, p->rname); + p = (Junction *)p->p2; + } +} + +/* Generate a bunch of #defines that rename all standard symbols to be + * "ParserName_symbol". The list of standard symbols to change is in + * globals.c. + */ +void +#ifdef __USE_PROTOS +GenPredefinedSymbolRedefs( FILE *f ) +#else +GenPredefinedSymbolRedefs( f ) +FILE *f; +#endif +{ + char **p; + + fprintf(f, "\n/* rename PCCTS-supplied symbols to be 'ParserName_symbol' */\n"); + for (p = &StandardSymbols[0]; *p!=NULL; p++) + { + fprintf(f, "#define %s %s_%s\n", *p, ParserName, *p); + } +} + +/* Generate a bunch of #defines that rename all AST symbols to be + * "ParserName_symbol". The list of AST symbols to change is in + * globals.c. + */ +void +#ifdef __USE_PROTOS +GenASTSymbolRedefs( FILE *f ) +#else +GenASTSymbolRedefs( f ) +FILE *f; +#endif +{ + char **p; + + fprintf(f, "\n/* rename PCCTS-supplied AST symbols to be 'ParserName_symbol' */\n"); + for (p = &ASTSymbols[0]; *p!=NULL; p++) + { + fprintf(f, "#define %s %s_%s\n", *p, ParserName, *p); + } +} + +/* redefine all sets generated by ANTLR; WARNING: 'zzerr', 'setwd' must match + * use in bits.c (DumpSetWd() etc...) + */ +void +#ifdef __USE_PROTOS +GenSetRedefs( FILE *f ) +#else +GenSetRedefs( f ) +FILE *f; +#endif +{ + int i; + + for (i=1; i<=wordnum; i++) + { + fprintf(f, "#define setwd%d %s_setwd%d\n", i, ParserName, i); + } + for (i=1; i<=esetnum; i++) + { + fprintf(f, "#define zzerr%d %s_err%d\n", i, ParserName, i); + } +} + +/* Find all return types/parameters that require structs and def + * all rules with ret types. + * + * This is for the declaration, not the definition. + */ +void +#ifdef __USE_PROTOS +GenRulePrototypes( FILE *f, Junction *p ) +#else +GenRulePrototypes( f, p ) +FILE *f; +Junction *p; +#endif +{ + int i; + + i = 1; + while ( p!=NULL ) + { + if ( p->ret != NULL ) + { +/* MR23 */ if ( hasMultipleOperands(p->ret) ) + { + DumpRetValStruct(f, p->ret, i); + } + fprintf(f, "\n#ifdef __USE_PROTOS\n"); +/* MR23 */ if ( hasMultipleOperands(p->ret) ) + { + fprintf(f, "extern struct _rv%d", i); + } + else + { + fprintf(f, "extern "); + DumpType(p->ret, f); + } + fprintf(f, " %s%s(", RulePrefix, p->rname); + DumpANSIFunctionArgDef(f,p,1 /* emit initializers ? */); + fprintf(f, ";\n"); + fprintf(f, "#else\n"); +/* MR23 */ if ( hasMultipleOperands(p->ret) ) + { + fprintf(f, "extern struct _rv%d", i); + } + else + { + fprintf(f, "extern "); + DumpType(p->ret, f); + } + fprintf(f, " %s%s();\n", RulePrefix, p->rname); + fprintf(f, "#endif\n"); + } + else + { + fprintf(f, "\n#ifdef __USE_PROTOS\n"); + fprintf(f, "void %s%s(", RulePrefix, p->rname); + DumpANSIFunctionArgDef(f,p, 1 /* emit initializers ? */ ); + fprintf(f, ";\n"); +#ifdef OLD + if ( p->pdecl != NULL || GenAST ) + { + if ( GenAST ) { + fprintf(f, "AST **%s",(p->pdecl!=NULL)?",":""); + } + if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl); + } + else fprintf(f, "void"); + fprintf(f, ");\n"); +#endif + fprintf(f, "#else\n"); + fprintf(f, "extern void %s%s();\n", RulePrefix, p->rname); + fprintf(f, "#endif\n"); + } + i++; + p = (Junction *)p->p2; + } +} + +/* Define all rules in the class.h file; generate any required + * struct definitions first, however. + */ +void +#ifdef __USE_PROTOS +GenRuleMemberDeclarationsForCC( FILE *f, Junction *q ) +#else +GenRuleMemberDeclarationsForCC( f, q ) +FILE *f; +Junction *q; +#endif +{ + Junction *p = q; + int i; + + fprintf(f, "private:\n"); + + /* Dump dflt handler declaration */ + fprintf(f, "\tvoid zzdflthandlers( int _signal, int *_retsignal );\n\n"); + + fprintf(f, "public:\n"); + + /* Dump return value structs */ + i = 1; + while ( p!=NULL ) + { + if ( p->ret != NULL ) + { +/* MR23 */ if ( hasMultipleOperands(p->ret) ) + { + DumpRetValStruct(f, p->ret, i); + } + } + i++; + p = (Junction *)p->p2; + } + + /* Dump member func defs && CONSTRUCTOR */ + fprintf(f, "\t%s(ANTLRTokenBuffer *input);\n", CurrentClassName); +/* + fprintf(f, "\t%s(ANTLRTokenBuffer *input, ANTLRTokenType eof);\n", + CurrentClassName); +*/ + + i = 1; + p = q; + while ( p!=NULL ) + { + if ( p->ret != NULL ) + { +/* MR23 */ if ( hasMultipleOperands(p->ret) ) + { + fprintf(f, "\tstruct _rv%d", i); + } + else + { + fprintf(f, "\t"); + DumpType(p->ret, f); + } + fprintf(f, " %s%s(",RulePrefix,p->rname); + DumpANSIFunctionArgDef(f,p, 1 /* emit initializers ? */ ); + fprintf(f, ";\n"); +#ifdef OLD + if ( p->pdecl != NULL || GenAST ) + { + if ( GenAST ) fprintf(f, "ASTBase **%s",(p->pdecl!=NULL)?",":""); + if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl); + } + fprintf(f, ");\n"); +#endif + } + else + { + fprintf(f, "\tvoid %s%s(",RulePrefix,p->rname); + DumpANSIFunctionArgDef(f,p, 1 /* emit initializers ? */); + fprintf(f, ";\n"); +#ifdef OLD + if ( p->pdecl != NULL || GenAST ) + { + if ( GenAST ) fprintf(f, "ASTBase **%s",(p->pdecl!=NULL)?",":""); + if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl); + } + fprintf(f, ");\n"); +#endif + } + i++; + p = (Junction *)p->p2; + } +} + +/* Given a list of ANSI-style parameter declarations, print out a + * comma-separated list of the symbols (w/o types). + * Basically, we look for a comma, then work backwards until start of + * the symbol name. Then print it out until 1st non-alnum char. Now, + * move on to next parameter. + * + */ + +/* MR5 Jan Mikkelsen 26-May-97 - added initalComma parameter */ + +void +#ifdef __USE_PROTOS +DumpListOfParmNames(char *pdecl, FILE *output, int initialComma) /* MR5 */ +#else +DumpListOfParmNames(pdecl, output, initialComma) /* MR5 */ +char *pdecl; /* MR5 */ +FILE *output; /* MR5 */ +int initialComma; /* MR5 */ +#endif +{ + int firstTime = 1, done = 0; + require(output!=NULL, "DumpListOfParmNames: NULL parm"); + + if ( pdecl == NULL ) return; + while ( !done ) + { + if ( !firstTime || initialComma ) putc(',', output); /* MR5 */ + done = DumpNextNameInDef(&pdecl, output); + firstTime = 0; + } +} + +/* given a list of parameters or return values, dump the next + * name to output. Return 1 if last one just printed, 0 if more to go. + */ + +/* MR23 Total rewrite */ + +int +#ifdef __USE_PROTOS +DumpNextNameInDef( char **q, FILE *output ) +#else +DumpNextNameInDef( q, output ) +char **q; +FILE *output; +#endif +{ + char *p; + char *t; + char *pDataType; + char *pSymbol; + char *pEqualSign; + char *pValue; + char *pSeparator; + int nest = 0; + + p = endFormal(*q, + &pDataType, + &pSymbol, + &pEqualSign, + &pValue, + &pSeparator, + &nest); + + /* MR26 Handle rule arguments such as: IIR_Bool (IIR_Decl::*contstraint)() + For this we need to strip off anything which follows the symbol. + */ + +/* MR26 */ t = pSymbol; +/* MR26 */ if (t != NULL) { +/* MR26 */ for (t = pSymbol; *t != 0; t++) { +/* MR26 */ if (! (isalpha(*t) || isdigit(*t) || *t == '_' || *t == '$')) break; +/* MR26 */ } +/* MR26 */ } +/* MR26 */ fprintf(output,strBetween(pSymbol, t, pSeparator)); + + *q = p; + return (*pSeparator == 0); +} + +/* Given a list of ANSI-style parameter declarations, dump K&R-style + * declarations, one per line for each parameter. Basically, convert + * comma to semi-colon, newline. + */ +void +#ifdef __USE_PROTOS +DumpOldStyleParms( char *pdecl, FILE *output ) +#else +DumpOldStyleParms( pdecl, output ) +char *pdecl; +FILE *output; +#endif +{ + require(output!=NULL, "DumpOldStyleParms: NULL parm"); + + if ( pdecl == NULL ) return; + while ( *pdecl != '\0' ) + { + if ( *pdecl == ',' ) + { + pdecl++; + putc(';', output); putc('\n', output); + while ( *pdecl==' ' || *pdecl=='\t' || *pdecl=='\n' ) pdecl++; + } + else {putc(*pdecl, output); pdecl++;} + } + putc(';', output); + putc('\n', output); +} + +/* Take in a type definition (type + symbol) and print out type only */ +/* MR23 Total rewrite */ + +void +#ifdef __USE_PROTOS +DumpType( char *s, FILE *f ) +#else +DumpType( s, f ) +char *s; +FILE *f; +#endif +{ + char *p; + char *pDataType; + char *pSymbol; + char *pEqualSign; + char *pValue; + char *pSeparator; + int nest = 0; + + require(s!=NULL, "DumpType: invalid type string"); + + p = endFormal(s, + &pDataType, + &pSymbol, + &pEqualSign, + &pValue, + &pSeparator, + &nest); + fprintf(f,strBetween(pDataType, pSymbol, pSeparator)); +} + +/* check to see if string e is a word in string s */ +int +#ifdef __USE_PROTOS +strmember( char *s, char *e ) +#else +strmember( s, e ) +char *s; +char *e; +#endif +{ + register char *p; + require(s!=NULL&&e!=NULL, "strmember: NULL string"); + + if ( *e=='\0' ) return 1; /* empty string is always member */ + do { + while ( *s!='\0' && !isalnum(*s) && *s!='_' ) + ++s; + p = e; + while ( *p!='\0' && *p==*s ) {p++; s++;} + if ( *p=='\0' ) { + if ( *s=='\0' ) return 1; + if ( !isalnum (*s) && *s != '_' ) return 1; + } + while ( isalnum(*s) || *s == '_' ) + ++s; + } while ( *s!='\0' ); + return 0; +} + +#if 0 + +/* MR23 Replaced by hasMultipleOperands() */ + +int +#ifdef __USE_PROTOS +HasComma( char *s ) +#else +HasComma( s ) +char *s; +#endif +{ + while (*s!='\0') + if ( *s++ == ',' ) return 1; + return 0; +} +#endif + + +/* MR23 Total rewrite */ + +void +#ifdef __USE_PROTOS +DumpRetValStruct( FILE *f, char *ret, int i ) +#else +DumpRetValStruct( f, ret, i ) +FILE *f; +char *ret; +int i; +#endif +{ + char *p = ret; + char *pDataType; + char *pSymbol; + char *pEqualSign; + char *pValue; + char *pSeparator; + int nest = 0; + + fprintf(f, "\nstruct _rv%d {\n", i); + while (*p != 0 && nest == 0) { + p = endFormal(p, + &pDataType, + &pSymbol, + &pEqualSign, + &pValue, + &pSeparator, + &nest); + fprintf(f,"\t"); + fprintf(f,strBetween(pDataType, pSymbol, pSeparator)); + fprintf(f," "); + fprintf(f,strBetween(pSymbol, pEqualSign, pSeparator)); + fprintf(f,";\n"); + } + fprintf(f,"};\n"); +} + +/* given "s" yield s -- DESTRUCTIVE (we modify s if starts with " else return s) */ +char * +#ifdef __USE_PROTOS +StripQuotes( char *s ) +#else +StripQuotes( s ) +char *s; +#endif +{ + if ( *s == '"' ) + { + s[ strlen(s)-1 ] = '\0'; /* remove last quote */ + return( s+1 ); /* return address past initial quote */ + } + return( s ); +} diff --git a/Tools/CodeTools/Source/Pccts/antlr/main.c b/Tools/CodeTools/Source/Pccts/antlr/main.c new file mode 100644 index 0000000000..051ee4ec5d --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/main.c @@ -0,0 +1,1747 @@ +/* + * main.c -- main program for PCCTS ANTLR. + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2001 + */ + +/* To set a breakpoint just before exit look for "cleanUp". */ +/* To set a breakpoint for fatal error look for "fatal_intern" */ + +#include + +#include "pcctscfg.h" +#include "stdpccts.h" + +#define MAX_INT_STACK 50 +static int istack[MAX_INT_STACK]; /* Int stack */ +static int isp = MAX_INT_STACK; + +static int DontAcceptFiles = 0; /* if stdin, don't read files */ +static int DontAcceptStdin = 0; /* if files seen first, don't accept stdin */ + +static int tnodes_used_in_guard_predicates_etc; /* MR10 */ + + /* C m d - L i n e O p t i o n S t r u c t & F u n c s */ + +typedef struct _Opt { + char *option; + int arg; +#ifdef __cplusplus + void (*process)(...); +#else + void (*process)(); +#endif + char *descr; + } Opt; + +#ifdef __USE_PROTOS +extern void ProcessArgs(int, char **, Opt *); +#else +extern void ProcessArgs(); +#endif + +#ifdef __USE_PROTOS +int ci_strequ(char *a,char *b) +#else +int ci_strequ(a,b) + char *a; + char *b; +#endif +{ + for ( ;*a != 0 && *b != 0; a++, b++) { + if (toupper(*a) != toupper(*b)) return 0; + } + return (*a == *b); +} + +static void +#ifdef __USE_PROTOS +pStdin( void ) +#else +pStdin( ) +#endif +{ + if ( DontAcceptStdin ) + { + warnNoFL("'-' (stdin) ignored as files were specified first"); + return; + } + + require(NumFiles 8 ) { /* MR6 */ + warnNoFL("tab width must be between 1 and 8"); /* MR6 */ + TabWidth=0; /* MR6 */ + } /* MR6 */ +} /* MR6 */ + +static int ambAidDepthSpecified=0; /* MR11 */ + +static void /* MR11 */ +#ifdef __USE_PROTOS +pAAd( char *s, char *t ) /* MR11 */ +#else +pAAd( s, t ) /* MR11 */ +char *s; /* MR11 */ +char *t; /* MR11 */ +#endif +{ /* MR11 */ + ambAidDepthSpecified=1; /* MR11 */ + MR_AmbAidDepth = atoi(t); /* MR11 */ +} /* MR11 */ + +static void /* MR11 */ +#ifdef __USE_PROTOS +pTreport( char *s, char *t ) /* MR11 */ +#else +pTreport( s, t ) /* MR11 */ + char *s; /* MR11 */ + char *t; /* MR11 */ +#endif +{ /* MR11 */ + TnodesReportThreshold = atoi(t); /* MR11 */ +} /* MR11 */ + +#ifdef __USE_PROTOS +void chkGTFlag(void) /* 7-Apr-97 MR1 */ +#else +void chkGTFlag() /* 7-Apr-97 MR1 */ +#endif +{ + if ( !GenAST ) + warn("#-variable or other AST item referenced w/o -gt option"); +} + + +#ifdef __USE_PROTOS +static void pInfo(char *s, char *t) /* MR10 */ +#else +static void pInfo(s,t) /* MR10 */ + char *s; + char *t; +#endif +{ + char *p; + int q; + for (p=t; *p != 0; p++) { + q=tolower(*p); + if (q=='t') { + InfoT=1; + } else if (q=='p') { + InfoP=1; + } else if (q=='m') { + InfoM=1; + } else if (q=='o') { + InfoO=1; + } else if (q=='0') { + ; /* nothing */ + } else if (q=='f') { + InfoF=1; + } else { + warnNoFL(eMsgd("unrecognized -info option \"%c\"",(int)*p)); + }; + }; +} + +#ifdef __USE_PROTOS +static void pCGen(void) { CodeGen = FALSE; LexGen = FALSE; } +static void pLGen(void) { LexGen = FALSE; } +static void pXTGen(void){ MR_Inhibit_Tokens_h_Gen = TRUE; } +static void pTGen(void) { TraceGen = TRUE; } +static void pSGen(void) { GenExprSetsOpt = FALSE; } +static void pPrt(void) { PrintOut = TRUE; pCGen(); pLGen(); } +static void pPrtA(void) { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); } +static void pAst(void) { GenAST = TRUE; } +static void pANSI(void) { GenANSI = TRUE; } +static void pCr(void) { GenCR = TRUE; } +static void pNOPURIFY(void) { PURIFY = FALSE; } +/*static void pCt(void) { warnNoFL("-ct option is now the default"); }*/ +static void pLI(void) { GenLineInfo = TRUE; GenLineInfoMS = FALSE; } /* MR14 */ +static void pLIms(void) { GenLineInfo = TRUE; GenLineInfoMS = TRUE; } /* MR14 */ +static void pFr(char *s, char *t) {RemapFileName = t;} +static void pFe(char *s, char *t) {ErrFileName = t;} +static void pFl(char *s, char *t) {DlgFileName = t;} +static void pFm(char *s, char *t) {ModeFileName = t;} +static void pFt(char *s, char *t) {DefFileName = t;} + +static void pE1(void) { elevel = 1; } +static void pE2(void) { elevel = 2; } +static void pE3(void) { elevel = 3; } +static void pEGen(void) { GenEClasseForRules = 1; } +static void pDL(void) + { + DemandLookahead = 1; + if ( GenCC ) { + warnNoFL("-gk does not work currently in C++ mode; -gk turned off"); + DemandLookahead = 0; + } + } + +static void pAA(char *s,char *t) {MR_AmbAidRule = t;} /* MR11 */ +static void pAAm(char *s){MR_AmbAidMultiple = 1;} /* MR11 */ +static void pGHdr(void) { GenStdPccts = 1; } +static void pFHdr(char *s, char *t) { stdpccts = t; pGHdr(); } +static void pW1(void) { WarningLevel = 1; } +static void pNewAST(void) { NewAST = 1; } /* MR13 */ +static void ptmakeInParser(void) { tmakeInParser = 1; } /* MR23 */ +static void pAlpha(void) { AlphaBetaTrace = 1; } /* MR14 */ +static void pMR_BlkErr(void) { MR_BlkErr = 1; } /* MR21 */ +static void pStdout(void) {UseStdout = 1; } /* MR6 */ +static void pW2(void) { WarningLevel = 2; } +static void pCC(void) { GenCC = TRUE; } +#else +static void pCGen() { CodeGen = FALSE; LexGen = FALSE; } +static void pLGen() { LexGen = FALSE; } +static void pXTGen(){ MR_Inhibit_Tokens_h_Gen = TRUE; } /* MR14 */ +static void pTGen() { TraceGen = TRUE; } +static void pSGen() { GenExprSetsOpt = FALSE; } +static void pPrt() { PrintOut = TRUE; pCGen(); pLGen(); } +static void pPrtA() { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); } +static void pAst() { GenAST = TRUE; } +static void pANSI() { GenANSI = TRUE; } +static void pCr() { GenCR = TRUE; } +static void pNOPURIFY() { PURIFY = FALSE; } + +/*static void pCt() { warnNoFL("-ct option is now the default"); }*/ +static void pLI() { GenLineInfo = TRUE; GenLineInfoMS = FALSE; } /* MR14 */ +static void pLIms() { GenLineInfo = TRUE; GenLineInfoMS = TRUE; } /* MR14 */ +static void pFr(s,t) char *s, *t; {RemapFileName = t;} +static void pFe(s,t) char *s, *t; {ErrFileName = t;} +static void pFl(s,t) char *s, *t; {DlgFileName = t;} +static void pFm(s,t) char *s, *t; {ModeFileName = t;} +static void pFt(s,t) char *s, *t; {DefFileName = t;} + +static void pE1() { elevel = 1; } +static void pE2() { elevel = 2; } +static void pE3() { elevel = 3; } +static void pEGen() { GenEClasseForRules = 1; } +static void pDL() + { + DemandLookahead = 1; + if ( GenCC ) { + warnNoFL("-gk does not work currently in C++ mode; -gk turned off"); + DemandLookahead = 0; + } + } + +static void pAA(s,t) char *s; char *t; {MR_AmbAidRule = t;} /* MR11 BJS 20-Mar-98 */ +static void pAAm(s) char *s; {MR_AmbAidMultiple = 1;} /* MR11 BJS 20-Mar-98 */ +static void pGHdr() { GenStdPccts = 1; } +static void pFHdr(s,t) char *s, *t; { stdpccts = t; pGHdr(); } +static void pW1() { WarningLevel = 1; } +static void pNewAST() { NewAST = 1; } /* MR13 */ +static void ptmakeInParser() { tmakeInParser = 1; } /* MR23 */ +static void pAlpha() { AlphaBetaTrace = 1; } /* MR14 */ +static void pMR_BlkErr() { MR_BlkErr = 1; } /* MR21 */ +static void pStdout() {UseStdout = 1; } /* MR6 */ +static void pW2() { WarningLevel = 2; } +static void pCC() { GenCC = TRUE; } +#endif + +static void +#ifdef __USE_PROTOS +pPre( char *s, char *t ) +#else +pPre( s, t ) +char *s; +char *t; +#endif +{ + RulePrefix = t; +} + +static void +#ifdef __USE_PROTOS +pOut( char *s, char *t ) +#else +pOut( s, t ) +char *s; +char *t; +#endif +{ + OutputDirectory = t; +} + +static void +#ifdef __USE_PROTOS +pPred( void ) +#else +pPred( ) +#endif +{ + warnNoFL("-pr is no longer used (predicates employed if present); see -prc, -mrhoist, -mrhoistk"); +/* +** if ( DemandLookahead ) +** warnNoFL("-gk conflicts with -pr; -gk turned off"); +** DemandLookahead = 0; +** HoistPredicateContext = 0; +*/ +} + +static void +#ifdef __USE_PROTOS +pPredCtx( char *s, char *t ) +#else +pPredCtx(s,t) +char *s; +char *t; +#endif +{ + if ( ci_strequ(t,"on")) HoistPredicateContext = 1; + else if ( ci_strequ(t,"off")) HoistPredicateContext = 0; + if ( DemandLookahead ) + { + warnNoFL("-gk incompatible with semantic predicate usage; -gk turned off"); + DemandLookahead = 0; + } +} + +static void +#ifdef __USE_PROTOS +pMRhoist( char *s, char *t ) +#else +pMRhoist(s,t) +char *s; +char *t; +#endif +{ + if ( ci_strequ(t,"on")) MRhoisting = 1; + else if ( ci_strequ(t,"off")==0 ) MRhoisting = 0; + if (MRhoisting) { + fprintf(stderr,"Maintenance Release style hoisting enabled for predicates with lookahead depth = 1\n"); + fprintf(stderr," No longer considered experimental\n"); + fprintf(stderr," Can't consider suppression for predicates with lookahead depth > 1\n"); + fprintf(stderr," Implies -prc on but does *not* imply -mrhoistk for k>1 predicates\n"); + fprintf(stderr," This is a reminder, not a warning or error.\n"); + }; +} + +static void +#ifdef __USE_PROTOS +pMRhoistk( char *s, char *t ) +#else +pMRhoistk(s,t) +char *s; +char *t; +#endif +{ + if ( ci_strequ(t,"on")) MRhoistingk = 1; + else if ( ci_strequ(t,"off")==0 ) MRhoistingk = 0; + if (MRhoistingk) { + fprintf(stderr,"EXPERIMENTAL Maintenance Release style hoisting enabled\n"); + fprintf(stderr," Applies to predicates with lookahead depth > 1\n"); + fprintf(stderr," Implies -prc on and -mrhoist on\n"); + }; +} + +static void +#ifdef __USE_PROTOS +pTRes( char *s, char *t ) +#else +pTRes( s, t ) +char *s; +char *t; +#endif +{ + TreeResourceLimit = atoi(t); + if ( TreeResourceLimit <= 0 ) + { + warnNoFL("analysis resource limit (# of tree nodes) must be greater than 0"); + TreeResourceLimit = -1; /* set to no limit */ + } +} + +Opt options[] = { +#ifdef __cplusplus + { "-CC", 0, (void (*)(...)) pCC, "Generate C++ output (default=FALSE)"}, + { "-ck", 1, (void (*)(...)) pCk, "Set compressed lookahead depth; fast approximate lookahead"}, + { "-cr", 0, (void (*)(...)) pCr, "Generate cross reference (default=FALSE)"}, + { "-e1", 0, (void (*)(...)) pE1, "Ambiguities/errors shown in low detail (default)"}, + { "-e2", 0, (void (*)(...)) pE2, "Ambiguities/errors shown in more detail"}, + { "-e3", 0, (void (*)(...)) pE3, + "Ambiguities for k>1 grammars shown with exact tuples (not lookahead sets)"}, + { "-f", 1, (void (*)(...)) pFileList,"Read names of grammar files from specified file"}, /* MR14 */ + { "-fe", 1, (void (*)(...)) pFe, "Rename err.c"}, + { "-fh", 1, (void (*)(...)) pFHdr, "Rename stdpccts.h header (turns on -gh)"}, + { "-fl", 1, (void (*)(...)) pFl, "Rename lexical output--parser.dlg"}, + { "-fm", 1, (void (*)(...)) pFm, "Rename mode.h"}, + { "-fr", 1, (void (*)(...)) pFr, "Rename remap.h"}, + { "-ft", 1, (void (*)(...)) pFt, "Rename tokens.h"}, + { "-ga", 0, (void (*)(...)) pANSI, "Generate ANSI-compatible code (default=FALSE)"}, + { "-gc", 0, (void (*)(...)) pCGen, "Do not generate output parser code (default=FALSE)"}, + { "-gd", 0, (void (*)(...)) pTGen, "Generate code to trace rule invocation (default=FALSE)"}, + { "-ge", 0, (void (*)(...)) pEGen, "Generate an error class for each non-terminal (default=FALSE)"}, + { "-gh", 0, (void (*)(...)) pGHdr, "Generate stdpccts.h for non-ANTLR-generated-files to include"}, + { "-gk", 0, (void (*)(...)) pDL, "Generate parsers that delay lookahead fetches until needed"}, + { "-gl", 0, (void (*)(...)) pLI, "Generate line info about grammar actions in parser"}, + { "-glms", 0, (void (*)(...)) pLIms,"Like -gl but replace '\\' with '/' in #line filenames for MS C/C++ systems"}, + { "-gp", 1, (void (*)(...)) pPre, "Prefix all generated rule functions with a string"}, + { "-gs", 0, (void (*)(...)) pSGen, "Do not generate sets for token expression lists (default=FALSE)"}, + { "-gt", 0, (void (*)(...)) pAst, "Generate code for Abstract-Syntax-Trees (default=FALSE)"}, + { "-gx", 0, (void (*)(...)) pLGen, "Do not generate lexical (dlg-related) files (default=FALSE)"}, + { "-gxt",0, (void (*)(...)) pXTGen, "Do not generate tokens.h (default=FALSE)"}, + { "-k", 1, (void (*)(...)) pLLK, "Set full LL(k) lookahead depth (default==1)"}, + { "-o", 1, (void (*)(...)) pOut, OutputDirectoryOption}, + { "-p", 0, (void (*)(...)) pPrt, "Print out the grammar w/o actions (default=no)"}, + { "-pa", 0, (void (*)(...)) pPrtA, "Print out the grammar w/o actions & w/FIRST sets (default=no)"}, + { "-pr",0, (void (*)(...)) pPred, "no longer used; predicates employed if present"}, + { "-prc", 1, (void (*)(...)) pPredCtx,"Turn on/off computation of context for hoisted predicates"}, + { "-rl", 1, (void (*)(...)) pTRes, "Limit max # of tree nodes used by grammar analysis"}, + { "-stdout",0, (void (*)(...)) pStdout,"Send grammar.c/grammar.cpp to stdout"}, /* MR6 */ + { "-tab", 1, (void (*)(...)) pTab, "Width of tabs (1 to 8) for grammar.c/grammar.cpp files"}, /* MR6 */ + { "-w1", 0, (void (*)(...)) pW1, "Set the warning level to 1 (default)"}, + { "-w2", 0, (void (*)(...)) pW2, "Ambiguities yield warnings even if predicates or (...)? block"}, + { "-", 0, (void (*)(...)) pStdin, "Read grammar from stdin" }, + { "-mrhoist",1, (void (*)(...)) pMRhoist, /* MR9 */ + "Turn on/off k=1 Maintenance Release style hoisting"}, /* MR9 */ + { "-mrhoistk",1, (void (*)(...)) pMRhoistk, /* MR9 */ + "Turn on/off EXPERIMENTAL k>1 Maintenance Release style hoisting"}, /* MR13 */ + { "-aa" , 1, (void (*)(...)) pAA, "Ambiguity aid for a rule (rule name or line number)"}, /* MR11 */ + { "-aam" , 0, (void (*)(...)) pAAm, + "Lookahead token may appear multiple times in -aa listing"}, /* MR11 */ + { "-aad" , 1, (void (*)(...)) pAAd, + "Limits exp growth of -aa listing - default=1 (max=ck value)"}, /* MR11 */ + { "-info", 1, (void (*)(...)) pInfo, + "Extra info: p=pred t=tnodes f=first/follow m=monitor o=orphans 0=noop"}, /* MR12 */ + { "-treport",1,(void (*)(...)) pTreport, + "Report when tnode usage exceeds value during ambiguity resolution"}, /* MR11 */ + { "-newAST", 0, (void (*)(...)) pNewAST, + "In C++ mode use \"newAST(...)\" rather than \"new AST(...)\""}, /* MR13 */ + { "-tmake", 0, (void (*)(...)) ptmakeInParser, + "In C++ mode use parser's tmake method rather than \"ASTBase::tmake(...)\""}, /* MR23 */ + { "-alpha",0,(void (*)(...)) pAlpha, + "Provide additional information for \"(alpha)? beta\" error messages"}, /* MR14 */ + { "-mrblkerr",0,(void (*)(...)) pMR_BlkErr, /* MR21 */ + "EXPERIMENTAL change to (...)* and (...)+ syntax error sets"}, /* MR21 */ + { "-nopurify",0,(void (*)(...)) pNOPURIFY, + "Don't use the notorious PURIFY macro (replaced by MR23 initial value syntax) to zero return arguments of rules"}, /* MR23 */ + { "*", 0, (void (*)(...)) pFile, "" }, /* anything else is a file */ +#else + { "-CC", 0, pCC, "Generate C++ output (default=FALSE)"}, + { "-cr", 0, pCr, "Generate cross reference (default=FALSE)"}, + { "-ck", 1, pCk, "Set compressed lookahead depth; fast approximate lookahead"}, + { "-e1", 0, pE1, "Ambiguities/errors shown in low detail (default)"}, + { "-e2", 0, pE2, "Ambiguities/errors shown in more detail"}, + { "-e3", 0, pE3, "Ambiguities for k>1 grammars shown with exact tuples (not lookahead sets)"}, + { "-f", 1, pFileList,"Read names of grammar files from specified file"}, /* MR14 */ + { "-fe", 1, pFe, "Rename err.c"}, + { "-fh", 1, pFHdr, "Rename stdpccts.h header (turns on -gh)"}, + { "-fl", 1, pFl, "Rename lexical output--parser.dlg"}, + { "-fm", 1, pFm, "Rename mode.h"}, + { "-fr", 1, pFr, "Rename remap.h"}, + { "-ft", 1, pFt, "Rename tokens.h"}, + { "-ga", 0, pANSI, "Generate ANSI-compatible code (default=FALSE)"}, + { "-gc", 0, pCGen, "Do not generate output parser code (default=FALSE)"}, + { "-gd", 0, pTGen, "Generate code to trace rule invocation (default=FALSE)"}, + { "-ge", 0, pEGen, "Generate an error class for each non-terminal (default=FALSE)"}, + { "-gh", 0, pGHdr, "Generate stdpccts.h for non-ANTLR-generated-files to include"}, + { "-gk", 0, pDL, "Generate parsers that delay lookahead fetches until needed"}, + { "-gl", 0, pLI, "Generate line info about grammar actions in C parser"}, + { "-glms", 0, pLIms,"Like -gl but replace '\\' with '/' in #line filenames for MS C/C++ systems"}, + { "-gp", 1, pPre, "Prefix all generated rule functions with a string"}, + { "-gs", 0, pSGen, "Do not generate sets for token expression lists (default=FALSE)"}, + { "-gt", 0, pAst, "Generate code for Abstract-Syntax-Trees (default=FALSE)"}, + { "-gx", 0, pLGen, "Do not generate lexical (dlg-related) files (default=FALSE)"}, + { "-gxt",0, pXTGen, "Do not generate tokens.h (default=FALSE)"}, + { "-k", 1, pLLK, "Set full LL(k) lookahead depth (default==1)"}, + { "-o", 1, pOut, OutputDirectoryOption}, + { "-p", 0, pPrt, "Print out the grammar w/o actions (default=no)"}, + { "-pa", 0, pPrtA, "Print out the grammar w/o actions & w/FIRST sets (default=no)"}, + { "-pr",0, pPred, "no longer used; predicates employed if present"}, + { "-prc", 1, pPredCtx,"Turn on/off computation of context for hoisted predicates"}, + { "-rl", 1, pTRes, "Limit max # of tree nodes used by grammar analysis"}, + { "-stdout",0, pStdout, "Send grammar.c/grammar.cpp to stdout"}, /* MR6 */ + { "-tab", 1, pTab, "Width of tabs (1 to 8) for grammar.c/grammar.cpp files"}, /* MR6 */ + { "-w1", 0, pW1, "Set the warning level to 1 (default)"}, + { "-w2", 0, pW2, "Ambiguities yield warnings even if predicates or (...)? block"}, + { "-mrhoist",1,pMRhoist, /* MR9 */ + "Turn on/off k=1 Maintenance Release style hoisting"}, /* MR9 */ + { "-mrhoistk",1,pMRhoistk, /* MR13 */ + "Turn on/off k>1 EXPERIMENTAL Maintenance Release style hoisting"}, /* MR13 */ + { "-aa" ,1,pAA, "Ambiguity aid for a rule (rule name or line number)"}, /* MR11 */ + { "-aam" ,0,pAAm, + "Lookahead token may appear multiple times in -aa listing"}, /* MR11 */ + { "-aad" ,1,pAAd, + "Limits exp growth of -aa listing - default=1 (max=ck value)"}, /* MR11 */ + { "-info",1,pInfo, + "Extra info: p=pred t=tnodes f=first/follow m=monitor o=orphans 0=noop"}, /* MR11 */ + { "-treport",1,pTreport, + "Report when tnode usage exceeds value during ambiguity resolution"}, /* MR11 */ + { "-newAST", 0, pNewAST, + "In C++ mode use \"newAST(...)\" rather than \"new AST(...)\""}, /* MR13 */ + { "-tmake", 0, ptmakeInParser, + "In C++ mode use parser's tmake method rather than \"ASTBase::tmake(...)\""}, /* MR23 */ + { "-alpha",0, pAlpha, + "Provide additional information for \"(alpha)? beta\" error messages"}, /* MR14 */ + { "-mrblkerr",0,pMR_BlkErr, /* MR21 */ + "EXPERIMENTAL change to (...)* and (...)+ syntax error sets"}, /* MR21 */ + { "-nopurify",0,pNOPURIFY, + "Don't use the notorious PURIFY macro (replaced by MR23 initial value syntax) to zero return arguments of rules"}, /* MR23 */ + { "-", 0, pStdin, "Read grammar from stdin" }, + { "*", 0, pFile, "" }, /* anything else is a file */ +#endif + { NULL, 0, NULL } + }; + +void readDescr(); +void cleanUp(); + +#ifdef __USE_PROTOS +static void buildRulePtr( void ); +static void help( void ); +static void init( void ); +static void CompleteTokenSetRefs( void ); +static void ensure_no_C_file_collisions(char *); +static void CompleteContextGuards(void); +#else +static void buildRulePtr( ); +static void help( ); +static void init( ); +static void CompleteTokenSetRefs( ); +static void ensure_no_C_file_collisions(); +static void CompleteContextGuards(); +#endif + +static void +#ifdef __USE_PROTOS /* */ +report_numericPredLabels(ActionNode *a) +#else +report_numericPredLabels(a) +ActionNode *a; +#endif +{ /* MR10 */ + warnFL("numeric references to attributes (e.g. $i or $i.j) in semantic pred will be null during guess mode", /* MR10 */ + FileStr[a->file],a->line); /* MR10 */ +} /* MR10 */ + + /* M a i n */ + +int +#ifdef __USE_PROTOS +main( int argc, char *argv[] ) +#else +main( argc, argv ) +int argc; +char *argv[]; +#endif +{ + int i; + static char EPSTR[] = "[Ep]"; + + Save_argc=argc; /* MR10 */ + Save_argv=argv; /* MR10 */ + +/* malloc_debug(8);*/ + +#ifdef SPECIAL_INITS + special_inits(); /* MR1 */ +#endif + fprintf(stderr, "Antlr parser generator Version %s 1989-2001\n", Version); + if ( argc == 1 ) { help(); zzDIE; } + ProcessArgs(argc-1, &(argv[1]), options); + +/* MR14 */ if (MR_AmbAidRule && AlphaBetaTrace) { +/* MR14 */ fatal("Can't specify both -aa (ambiguity aid) and -alpha (\"(alpha)? beta\" aid)"); +/* MR14 */ } + + if (MRhoistingk) { /* MR13 */ + HoistPredicateContext=1; /* MR13 */ + MRhoisting=1; /* MR13 */ + }; /* MR13 */ + if (MRhoisting && ! HoistPredicateContext) { +/*** warnNoFL("Using \"-mrhoist\" forces \"-prc on\""); ***/ + HoistPredicateContext=1; + }; + if (HoistPredicateContext && ! MRhoisting) { + warnNoFL("When using predicate context (-prc on) -mrhoist on is recommended"); + } + /* Fix lookahead depth */ + /* Compressed lookahead must always be larger than or equal to full lookahead */ + if ( CLL_k < LL_k && CLL_k>0 ) + { + warnNoFL("must have compressed lookahead >= full LL(k) lookahead (setting -ck to -k)"); + CLL_k = LL_k; + } + if ( CLL_k == -1 ) CLL_k = LL_k; + OutputLL_k = CLL_k; + if ( ((CLL_k-1)&CLL_k)!=0 ) { /* output ll(k) must be power of 2 */ + int n; + for(n=1; n 1) { + warnNoFL("The -mrblkerr option is designed only for k=1 ck=1 grammars"); + } + }; + + if ( ! ambAidDepthSpecified) { + MR_AmbAidDepth=1; + } else { + if (MR_AmbAidDepth > CLL_k || MR_AmbAidDepth <= 0) { + warnNoFL(eMsgd( + "Ambiguity aid depth (\"-aad ...\") must be a number between 1 and max(k,ck)=%d",CLL_k)); + MR_AmbAidDepth=1; + }; + if (MR_AmbAidDepth == 0) { + MR_AmbAidDepth=2; + }; + }; + + if (MR_AmbAidRule != NULL) MR_AmbAidLine=atoi(MR_AmbAidRule); + + fpTrans = &(C_Trans[0]); /* Translate to C Language */ + fpJTrans = &(C_JTrans[0]); + init(); + lexclass(LexStartSymbol); + + readDescr(); + LastTokenCounted = TokenNum; + RemapForcedTokens(); + if ( CannotContinue ) {cleanUp(); zzDIE;} + if ( GenCC && no_classes_found ) fatal("required grammar class not found (exiting...)"); + if ( WarningLevel>1 && HdrAction == NULL ) + warnNoFL("no #header action was found"); + if ( FoundAtOperator && ! FoundExceptionGroup) { + warnNoFL("found the exception operator '@' - but no exception group was found"); + }; + EpToken = addTname(EPSTR); /* add imaginary token epsilon */ + set_orel(EpToken, &imag_tokens); + + /* this won't work for hand-built scanners since EofToken is not + * known. Forces EOF to be token type 1. + */ + set_orel(EofToken, &imag_tokens); + + set_size(NumWords(TokenNum-1)); + + /* compute the set of all known token types + * It represents the set of tokens from 1 to last_token_num + the + * reserved positions above that (if any). Don't include the set of + * imaginary tokens such as the token/error classes or EOF. + */ + { + set a; + a = set_dup(reserved_positions); + for (i=1; inext; p!=NULL; p=p->next) + { + UserAction *ua = (UserAction *)p->elem; + dumpAction( ua->action, Parser_h, 0, ua->file, ua->line, 1); + } + } + GenParser_c_Hdr(); + fprintf(Parser_h, "protected:\n"); /* MR20 */ + NewSetWd(); + TRANS(SynDiag); /* Translate to the target language */ + DumpSetWd(); + GenRuleMemberDeclarationsForCC(Parser_h, SynDiag); + if ( class_after_actions != NULL ) + { + ListNode *p; + for (p = class_after_actions->next; p!=NULL; p=p->next) + { + UserAction *ua = (UserAction *)p->elem; + dumpAction( ua->action, Parser_h, 0, ua->file, ua->line, 1); + } + } + DumpRemainingTokSets(); + fprintf(Parser_h, "};\n"); + fprintf(Parser_h, "\n#endif /* %s_h */\n", CurrentClassName); + fclose( Parser_h ); + fclose( Parser_c ); + } + } + + MR_orphanRules(stderr); + if (LTinTokenAction && WarningLevel >= 2) { + if (GenCC) { + warnNoFL("At least one <> following a token match contains a reference to LT(...)\n this will reference the immediately preceding token,\n not the one which follows as is the case with semantic predicates."); + } + warnNoFL("At least one <> following a token match contains a reference to LA(...) or LATEXT(...)\n this will reference the immediately preceding token,\n not the one which follows as is the case with semantic predicates."); + } + + if ( PrintOut ) + { + if ( SynDiag == NULL ) {warnNoFL("no grammar description recognized");} + else PRINT(SynDiag); + } + +#ifdef DBG_LL1 +#endif + GenRemapFile(); /* create remap.h */ +/* MR10 */ if (FoundGuessBlk) { +#ifdef __cplusplus__ +/* MR10 */ list_apply(NumericPredLabels, (void (*)(void *))report_numericPredLabels); +#else +#ifdef __USE_PROTOS +/* MR10 */ list_apply(NumericPredLabels, (void (*)(void *))report_numericPredLabels); +#else +/* MR10 */ list_apply(NumericPredLabels,report_numericPredLabels); +#endif +#endif +/* MR10 */ }; + + if (InfoT && TnodesAllocated > 0) { + if (TnodesPeak > 10000) { + fprintf(stdout,"\nTree Nodes: peak %dk created %dk lost %d\n", + (TnodesPeak/1000), + (TnodesAllocated/1000), + TnodesInUse-tnodes_used_in_guard_predicates_etc); + } else { + fprintf(stdout,"\nTree Nodes: peak %d created %d lost %d\n", + TnodesPeak, + TnodesAllocated, + TnodesInUse-tnodes_used_in_guard_predicates_etc); + }; + }; + if (InfoF) { + DumpFcache(); + }; + if (MR_skipped_e3_report) { + fprintf(stderr,"note: use -e3 to get exact information on ambiguous tuples\n"); + }; + if (MR_BadExprSets != 0) { + fprintf(stderr,"note: Unreachable C or C++ code was generated for empty expression sets,\n"); + fprintf(stderr," probably due to undefined rules or infinite left recursion.\n"); + fprintf(stderr," To locate: search the generated code for \"empty set expression\"\n"); + }; + if (MR_AmbAidRule != NULL && MR_matched_AmbAidRule==0) { + RuleEntry *q = (RuleEntry *) hash_get(Rname,MR_AmbAidRule); + if (MR_AmbAidLine == 0 && q == NULL) { + warnNoFL(eMsg2("there is no rule \"%s\" so \"-aa %s\" will never match", + MR_AmbAidRule,MR_AmbAidRule)); + } else { + warnNoFL(eMsg1("there was no ambiguity that matched \"-aa %s\"",MR_AmbAidRule)); + }; + }; + if (AlphaBetaTrace) { + + if (MR_AlphaBetaMessageCount == 0) { + fprintf(stderr,"note: there were no messages about \"(alpha)? beta\" blocks added to the generated code\n"); + } else { + fprintf(stderr,"note: there were %d messages about \"(alpha)? beta\" blocks added to the generated code\n", + MR_AlphaBetaMessageCount); + } + + if (set_null(MR_CompromisedRules)) { + fprintf(stderr,"note: the list of rules with compromised follow sets is empty\n"); + } else { + fprintf(stderr,"note: the following is a list of rules which *may* have incorrect\n"); + fprintf(stderr," follow sets computed as a result of an \"(alpha)? beta\" block\n"); + fprintf(stderr,"\n"); + MR_dumpRuleSet(MR_CompromisedRules); + fprintf(stderr,"\n"); + } + } + cleanUp(); + exit(PCCTS_EXIT_SUCCESS); + return 0; /* MR11 make compilers happy */ +} + +static void +#ifdef __USE_PROTOS +init( void ) +#else +init( ) +#endif +{ + SignalEntry *q; + + Tname = newHashTable(); + Rname = newHashTable(); + Fcache = newHashTable(); + Tcache = newHashTable(); + Sname = newHashTable(); + Pname = newHashTable(); /* MR11 */ + + /* Add default signal names */ + q = (SignalEntry *)hash_add(Sname, + "NoViableAlt", + (Entry *)newSignalEntry("NoViableAlt")); + require(q!=NULL, "cannot alloc signal entry"); + q->signum = sigNoViableAlt; + q = (SignalEntry *)hash_add(Sname, + "MismatchedToken", + (Entry *)newSignalEntry("MismatchedToken")); + require(q!=NULL, "cannot alloc signal entry"); + q->signum = sigMismatchedToken; + q = (SignalEntry *)hash_add(Sname, + "NoSemViableAlt", + (Entry *)newSignalEntry("NoSemViableAlt")); + require(q!=NULL, "cannot alloc signal entry"); + q->signum = sigNoSemViableAlt; + + reserved_positions = empty; + all_tokens = empty; + imag_tokens = empty; + tokclasses = empty; + TokenStr = (char **) calloc(TSChunk, sizeof(char *)); + require(TokenStr!=NULL, "main: cannot allocate TokenStr"); + FoStack = (int **) calloc(CLL_k+1, sizeof(int *)); + require(FoStack!=NULL, "main: cannot allocate FoStack"); + FoTOS = (int **) calloc(CLL_k+1, sizeof(int *)); + require(FoTOS!=NULL, "main: cannot allocate FoTOS"); + Cycles = (ListNode **) calloc(CLL_k+1, sizeof(ListNode *)); + require(Cycles!=NULL, "main: cannot allocate Cycles List"); + MR_CompromisedRules=empty; /* MR14 */ +} + +static void +#ifdef __USE_PROTOS +help( void ) +#else +help( ) +#endif +{ + Opt *p = options; + fprintf(stderr, "antlr [options] f1 f2 ... fn\n"); + while ( *(p->option) != '*' ) + { + fprintf(stderr, " %-9s%s %s\n", + p->option, + (p->arg)?"___":" ", + p->descr); + p++; + } +} + +/* The RulePtr array is filled in here. RulePtr exists primarily + * so that sets of rules can be maintained for the FOLLOW caching + * mechanism found in rJunc(). RulePtr maps a rule num from 1 to n + * to a pointer to its RuleBlk junction where n is the number of rules. + */ +static void +#ifdef __USE_PROTOS +buildRulePtr( void ) +#else +buildRulePtr( ) +#endif +{ + int r=1; + Junction *p = SynDiag; + RulePtr = (Junction **) calloc(NumRules+1, sizeof(Junction *)); + require(RulePtr!=NULL, "cannot allocate RulePtr array"); + + while ( p!=NULL ) + { + require(r<=NumRules, "too many rules???"); + RulePtr[r++] = p; + p = (Junction *)p->p2; + } +} + +void +#ifdef __USE_PROTOS +dlgerror(const char *s) +#else +dlgerror(s) +char *s; +#endif +{ + fprintf(stderr, ErrHdr, FileStr[CurFile], zzline); + fprintf(stderr, " lexical error: %s (text was '%s')\n", + ((s == NULL) ? "Lexical error" : s), zzlextext); +} + +void +#ifdef __USE_PROTOS +readDescr( void ) +#else +readDescr( ) +#endif +{ + zzerr = dlgerror; + input = NextFile(); + if ( input==NULL ) fatal("No grammar description found (exiting...)"); + ANTLR(grammar(), input); + tnodes_used_in_guard_predicates_etc=TnodesInUse; /* MR10 */ +} + +FILE * +#ifdef __USE_PROTOS +NextFile( void ) +#else +NextFile( ) +#endif +{ + FILE *f; + + for (;;) + { + CurFile++; + if ( CurFile >= NumFiles ) return(NULL); + if ( ci_strequ(FileStr[CurFile],"stdin")) return stdin; + f = fopen(FileStr[CurFile], "r"); + if ( f == NULL ) + { + warnNoFL( eMsg1("file %s doesn't exist; ignored", FileStr[CurFile]) ); + } + else + { + return(f); + } + } +} + +/* + * Return a string corresponding to the output file name associated + * with the input file name passed in. + * + * Observe the following rules: + * + * f.e --> f".c" + * f --> f".c" + * f. --> f".c" + * f.e.g --> f.e".c" + * + * Where f,e,g are arbitrarily long sequences of characters in a file + * name. + * + * In other words, if a ".x" appears on the end of a file name, make it + * ".c". If no ".x" appears, append ".c" to the end of the file name. + * + * C++ mode using .cpp not .c. + * + * Use malloc() for new string. + */ + +char * +#ifdef __USE_PROTOS +outname( char *fs ) +#else +outname( fs ) +char *fs; +#endif +{ + if ( GenCC) { + return outnameX(fs,CPP_FILE_SUFFIX); + } else { + return outnameX(fs,".c"); + }; +} + +char * +#ifdef __USE_PROTOS +outnameX( char *fs ,char *suffix) +#else +outnameX( fs , suffix ) +char *fs; +char *suffix; +#endif +{ + static char buf[MaxFileName+1]; + char *p; + require(fs!=NULL&&*fs!='\0', "outname: NULL filename"); + + p = buf; + strcpy(buf, fs); + while ( *p != '\0' ) {p++;} /* Stop on '\0' */ + while ( *p != '.' && p != buf ) {--p;} /* Find '.' */ + if ( p != buf ) *p = '\0'; /* Found '.' */ + require(strlen(buf) + 2 < (size_t)MaxFileName, "outname: filename too big"); + strcat(buf,suffix); + return( buf ); +} + +void +#ifdef __USE_PROTOS +fatalFL( char *err_, char *f, int l ) +#else +fatalFL( err_, f, l ) +char *err_; +char *f; +int l; +#endif +{ + fprintf(stderr, ErrHdr, f, l); + fprintf(stderr, " %s\n", err_); + cleanUp(); + exit(PCCTS_EXIT_FAILURE); +} + +void +#ifdef __USE_PROTOS +fatal_intern( char *err_, char *f, int l ) +#else +fatal_intern( err_, f, l ) +char *err_; +char *f; +int l; +#endif +{ + fprintf(stderr, ErrHdr, f, l); + fprintf(stderr, " #$%%*&@# internal error: %s\n", err_); + fprintf(stderr, ErrHdr, f, l); + fprintf(stderr, " [complain to nearest government official\n"); + fprintf(stderr, ErrHdr, f, l); + fprintf(stderr, " or send hate-mail to parrt@parr-research.com;\n"); + fprintf(stderr, ErrHdr, f, l); + fprintf(stderr, " please pray to the ``bug'' gods that there is a trival fix.]\n"); + cleanUp(); + exit(PCCTS_EXIT_FAILURE); +} + +void +#ifdef __USE_PROTOS +cleanUp( void ) +#else +cleanUp( ) +#endif +{ + if ( DefFile != NULL) fclose( DefFile ); +} + +/* sprintf up to 3 strings */ +char * +#ifdef __USE_PROTOS +eMsg3( char *s, char *a1, char *a2, char *a3 ) +#else +eMsg3( s, a1, a2, a3 ) +char *s; +char *a1; +char *a2; +char *a3; +#endif +{ + static char buf[250]; /* DANGEROUS as hell !!!!!! */ + + sprintf(buf, s, a1, a2, a3); + return( buf ); +} + +/* sprintf a decimal */ +char * +#ifdef __USE_PROTOS +eMsgd( char *s, int d ) +#else +eMsgd( s, d ) +char *s; +int d; +#endif +{ + static char buf[250]; /* DANGEROUS as hell !!!!!! */ + + sprintf(buf, s, d); + return( buf ); +} + +char * +#ifdef __USE_PROTOS +eMsgd2( char *s, int d1,int d2) +#else +eMsgd2( s, d1, d2 ) +char *s; +int d1; +int d2; +#endif +{ + static char buf[250]; /* DANGEROUS as hell !!!!!! */ + + sprintf(buf, s, d1, d2); + return( buf ); +} + +void +#ifdef __USE_PROTOS +s_fprT( FILE *f, set e ) +#else +s_fprT( f, e ) +FILE *f; +set e; +#endif +{ + register unsigned *p; + unsigned *q; + + if ( set_nil(e) ) return; + if ( (q=p=set_pdq(e)) == NULL ) fatal_internal("Can't alloc space for set_pdq"); + fprintf(f, "{"); + while ( *p != nil ) + { + fprintf(f, " %s", TerminalString(*p)); + p++; + } + fprintf(f, " }"); + free((char *)q); +} + +/* Return the token name or regular expression for a token number. */ +char * +#ifdef __USE_PROTOS +TerminalString( int token ) +#else +TerminalString( token ) +int token; +#endif +{ + int j; + static char imag_name[20]; + + /* look in all lexclasses for the token */ + if ( TokenString(token) != NULL ) return TokenString(token); + for (j=0; j0, "pushint: stack overflow"); + istack[--isp] = i; +} + +int +#ifdef __USE_PROTOS +popint( void ) +#else +popint( ) +#endif +{ + require(isp 0 ) + { + p = options; + while ( p->option != NULL ) + { + if ( strcmp(p->option, "*") == 0 || + ci_strequ(p->option, *argv) == 1 ) + { + if ( p->arg ) + { +/* MR9 26-Sep-97 Check for argv valid */ + if (argc-- > 0) { + (*p->process)( *argv, *(argv+1) ); + argv++; + } else { +fprintf(stderr,"error: required argument for option %s omitted\n",*argv); +exit(PCCTS_EXIT_FAILURE); + }; + } + else + (*p->process)( *argv ); + break; + } + p++; + } + argv++; + } +} + +static void +#ifdef __USE_PROTOS +CompleteContextGuards(void) +#else +CompleteContextGuards() +#endif +{ + ListNode * p; + Predicate * pred; + + if (ContextGuardPredicateList == NULL) return; + + for (p=ContextGuardPredicateList->next; p != NULL; p=p->next) { + pred=(Predicate *)p->elem; + recomputeContextGuard(pred); + } +} + +/* Go back into the syntax diagram and compute all meta tokens; i.e. + * turn all '.', ranges, token class refs etc... into actual token sets + */ +static void +#ifdef __USE_PROTOS +CompleteTokenSetRefs(void) +#else +CompleteTokenSetRefs() +#endif +{ + ListNode *p; + + if ( MetaTokenNodes==NULL ) return; + for (p = MetaTokenNodes->next; p!=NULL; p=p->next) + { + set a,b; + + TokNode *q = (TokNode *)p->elem; + if ( q->wild_card ) + { + q->tset = all_tokens; + } + else if ( q->tclass!=NULL ) + { + if ( q->complement ) q->tset = set_dif(all_tokens, q->tclass->tset); + else q->tset = q->tclass->tset; + } + else if ( q->upper_range!=0 ) + { + /* we have a range on our hands: make a set from q->token .. q->upper_range */ + int i; + a = empty; + for (i=q->token; i<=q->upper_range; i++) { set_orel(i, &a); } /* MR13 */ + +/* MR13 */ if (q->complement) { +/* MR13 */ q->tset = set_dif(all_tokens, a); +/* MR13 */ set_free(a); +/* MR13 */ } else { +/* MR13 */ q->tset = a; +/* MR13 */ } + + } + + /* at this point, it can only be a complemented single token */ + else if ( q->complement ) + { + a = set_of(q->token); + b = set_dif(all_tokens, a); + set_free(a); + q->tset=b; + } + else fatal("invalid meta token"); + } +} + +/* MR10: Jeff Vincent + MR10: Changed to remove directory information from n only if + MR10: if OutputDirectory was changed by user (-o option) +*/ + +char * +#ifdef __USE_PROTOS +OutMetaName(char *n) +#else +OutMetaName(n) +char *n; +#endif +{ + static char *dir_sym = DirectorySymbol; + static char newname[MaxFileName+1]; + char *p; + + /* If OutputDirectory is same as TopDirectory (platform default) then leave n alone. */ + if (strcmp(OutputDirectory, TopDirectory) == 0) /* TopDirectory is "." on Unix. */ + return n; + + /* p will point to filename without path information */ + if ((p = strrchr(n, *dir_sym)) != NULL) /* Directory symbol is "/" on Unix. */ + p++; + else + p = n; + + /* Copy new output directory into newname[] */ + strcpy(newname, OutputDirectory); + + /* if new output directory does not have trailing dir_sym, add it! */ + if (newname[strlen(newname)-1] != *dir_sym) { + strcat(newname, dir_sym); + } + strcat(newname, p); + return newname; +} + +char * +#ifdef __USE_PROTOS +pcctsBaseName(char *n) /* MR32 */ +#else +pcctsBaseName(n) +char *n; +#endif +{ + static char newname[MaxFileName+1]; + static char* dir_sym = DirectorySymbol; + int count = 0; + char *p; + + p = n; + + while ( *p != '\0' ) {p++;} /* go to end of string */ + while ( (*p != *dir_sym) && (p != n) ) {--p;} /* Find last DirectorySymbol */ + while ( *p == *dir_sym) p++; /* step forward if we're on a dir symbol */ + while ( *p != '\0' && *p != '.') + { + newname[count++] = *p; + p++; + } /* create a new name */ + newname[count] = '\0'; + return newname; +} + +static void +#ifdef __USE_PROTOS +ensure_no_C_file_collisions(char *class_c_file) +#else +ensure_no_C_file_collisions(class_c_file) +char *class_c_file; +#endif +{ + int i; + + for (i=0; i= NumFiles && CurFile >= 1 ) CurFile--; + fprintf(stderr, ErrHdr, FileStr[CurFile], zzline); + fprintf(stderr, " warning: %s\n", err); +} + +void +#ifdef __USE_PROTOS +warnNoCR( char *err ) +#else +warnNoCR( err ) +char *err; +#endif +{ + /* back up the file number if we hit an error at the end of the last file */ + if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--; + fprintf(stderr, ErrHdr, FileStr[CurFile], zzline); + fprintf(stderr, " warning: %s", err); +} + +void +#ifdef __USE_PROTOS +errNoFL(char *err) +#else +errNoFL(err) +char *err; +#endif +{ + fprintf(stderr, "error: %s\n", err); +} + +void +#ifdef __USE_PROTOS +errFL(char *err,char *f,int l) +#else +errFL(err,f,l) +char *err; +char *f; +int l; +#endif +{ + fprintf(stderr, ErrHdr, f, l); + fprintf(stderr, " error: %s\n", err); +} + +void +#ifdef __USE_PROTOS +err(char *err) +#else +err(err) +char *err; +#endif +{ + /* back up the file number if we hit an error at the end of the last file */ + if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--; + fprintf(stderr, ErrHdr, FileStr[CurFile], zzline); + fprintf(stderr, " error: %s\n", err); +} + +void +#ifdef __USE_PROTOS +errNoCR( char *err ) +#else +errNoCR( err ) +char *err; +#endif +{ + /* back up the file number if we hit an error at the end of the last file */ + if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--; + fprintf(stderr, ErrHdr, FileStr[CurFile], zzline); + fprintf(stderr, " error: %s", err); +} + +UserAction * +#ifdef __USE_PROTOS +newUserAction(char *s) +#else +newUserAction(s) +char *s; +#endif +{ + UserAction *ua = (UserAction *) calloc(1, sizeof(UserAction)); + require(ua!=NULL, "cannot allocate UserAction"); + + ua->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); + strcpy(ua->action, s); + return ua; +} + +/* Added by TJP September 1994 */ +/* Take in file.h and return file_h; names w/o '.'s are left alone */ +char * +#ifdef __USE_PROTOS +gate_symbol(char *name) +#else +gate_symbol(name) +char *name; +#endif +{ + static char buf[100]; + char *p; + sprintf(buf, "%s", name); + + for (p=buf; *p!='\0'; p++) + { + if ( *p=='.' ) *p = '_'; + } + return buf; +} + +char * +#ifdef __USE_PROTOS +makeAltID(int blockid, int altnum) +#else +makeAltID(blockid, altnum) +int blockid; +int altnum; +#endif +{ + static char buf[100]; + char *p; + sprintf(buf, "_blk%d_alt%d", blockid, altnum); + p = (char *)malloc(strlen(buf)+1); + strcpy(p, buf); + return p; +} diff --git a/Tools/CodeTools/Source/Pccts/antlr/makefile b/Tools/CodeTools/Source/Pccts/antlr/makefile new file mode 100644 index 0000000000..2aa6cdfc34 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/makefile @@ -0,0 +1,218 @@ +# +# Makefile for ANTLR 1.33 +# +# SOFTWARE RIGHTS +# +# We reserve no LEGAL rights to the Purdue Compiler Construction Tool +# Set (PCCTS) -- PCCTS is in the public domain. An individual or +# company may do whatever they wish with source code distributed with +# PCCTS or the code generated by PCCTS, including the incorporation of +# PCCTS, or its output, into commerical software. +# +# We encourage users to develop software with PCCTS. However, we do ask +# that credit is given to us for developing PCCTS. By "credit", +# we mean that if you incorporate our source code into one of your +# programs (commercial product, research project, or otherwise) that you +# acknowledge this fact somewhere in the documentation, research report, +# etc... If you like PCCTS and have developed a nice tool with the +# output, please mention that you developed it using PCCTS. In +# addition, we ask that this header remain intact in our source code. +# As long as these guidelines are kept, we expect to continue enhancing +# this system and expect to make other tools available as they are +# completed. +# +# ANTLR 1.33 +# Terence Parr +# Parr Research Corporation +# with Purdue University +# and AHPCRC, University of Minnesota +# 1989-1995 +# +# Ported to Borland C++, IBM C-Set/2 and Microsoft 6.0 by +# Ed Harfmann +# Micro Data Base Systems +# Lafayette, Indiana +# +SET=../support/set +PCCTS_H=../h + +## +## Uncomment the appropriate section to build +## (both targets and 'make' variable definitions) +## Note that UNIX is the default +## + +# +# OS/2 & DOS 16 bit using MSC 6.0 +# +#CC=cl +#ANTLR=..\bin\antlr +#DLG=..\bin\dlg +#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) /AL /Za /W3 -DPC -DUSER_ZZSYN +#OUT_OBJ = -Fo +#LIBS=/NOD:LLIBCE LLIBCEP +#OBJ_EXT = obj +# +#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \ +# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \ +# misc.obj set.obj pred.obj egamn.obj +# link @<< +#$** /NOI +#$@ /STACK:14336 +# +#$(LIBS: = +^ +#) +#$(DEF_FILE) $(LFLAGS) ; +#<< +# bind $@ c:\os2\doscalls.lib +# copy *.exe ..\bin +# + +# +# Borland C++ for DOS +# +#CC=bcc +#ANTLR=..\bin\antlr +#DLG=..\bin\dlg +#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) -ml -ff- -w- -DPC -DUSER_ZZSYN +#OUT_OBJ = -o +#LIBS= emu mathl cl +#OBJ_EXT = obj +# +#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \ +# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \ +# misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj +# tlink @&&| +#C0L $** +#$@ /Tde /c +# +#$(LIBS) +#$(DEF_FILE) $(LFLAGS) ; +#| +# copy *.exe ..\bin +# + +# +# C-Set/2 for OS/2 +# +#CC=icc +#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) /Sa /W3 -DUSER_ZZSYN -D__STDC__ +#OUT_OBJ = -Fo +#LIBS= +#ANTLR=..\bin\antlr +#DLG=..\bin\dlg +#OBJ_EXT = obj +# +#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \ +# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \ +# misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj +# link386 @<< +#$** /NOI +#$@ /STACK:32768 +# +#$(LIBS: = +^ +#) +#$(DEF_FILE) $(LFLAGS) ; +#<< +# copy *.exe ..\bin +# + +# +# Borland C++ for OS/2 +# +#CC=bcc +#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) -w- -v -DUSER_ZZSYN +#OUT_OBJ = -o +#LIBS= c2 os2 +# +#ANTLR=..\bin\antlr +#DLG=..\bin\dlg +#OBJ_EXT = obj +#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \ +# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \ +# misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj +# tlink @&&| +#c02 $** -c -v +#antlr.exe +# +#C2 os2 +# +#| +# copy *.exe ..\bin +# + +# *********** Target list of PC machines *********** +# +# Don't worry about the ambiguity messages coming from antlr +# for making antlr.c etc... [should be 10 of them, I think] +# +#antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g +# $(ANTLR) antlr.g +# +#antlr.$(OBJ_EXT): antlr.c mode.h tokens.h +# +#scan.$(OBJ_EXT): scan.c mode.h tokens.h +# +#scan.c mode.h: parser.dlg +# $(DLG) -C2 parser.dlg scan.c +# +#set.$(OBJ_EXT): $(SET)/set.c +# $(CC) $(CFLAGS) -c $(OUT_OBJ)set.$(OBJ_EXT) $(SET)/set.c + + + +# +# UNIX (default) +# +CC=gcc +COPT=-O +ANTLR=${BIN_DIR}/antlr +DLG=${BIN_DIR}/dlg +OBJ_EXT=o +OUT_OBJ = -o +CFLAGS= $(COPT) -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN $(COTHER) -DZZLEXBUFSIZE=65536 +# +# SGI Users, use this CFLAGS +# +#CFLAGS= -O -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN -woff 3262 +OBJ=antlr.o scan.o err.o bits.o build.o fset2.o fset.o gen.o \ + globals.o hash.o lex.o main.o misc.o set.o pred.o egman.o mrhoist.o fcache.o + +antlr : $(OBJ) $(SRC) + $(CC) $(CFLAGS) -o $(BIN_DIR)/antlr $(OBJ) + +# what files does PCCTS generate (both ANTLR and DLG) +PCCTS_GEN=antlr.c scan.c err.c tokens.h mode.h parser.dlg stdpccts.h remap.h + +SRC=antlr.c scan.c err.c bits.c build.c fset2.c fset.c gen.c globals.c \ + hash.c lex.c main.c misc.c $(SET)/set.c pred.c egman.c mrhoist.c fcache.c + +# +# Don't worry about the ambiguity messages coming from antlr +# for making antlr.c etc... [should be 10 of them, I think] +# +#antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g +# $(ANTLR) -gh antlr.g + +antlr.o : antlr.c mode.h tokens.h + +scan.o : scan.c mode.h tokens.h + +#scan.c mode.h: parser.dlg +# $(DLG) -C2 parser.dlg scan.c + +set.o : $(SET)/set.c + $(CC) $(CFLAGS) -c -o set.o $(SET)/set.c + + +# +# ****** These next targets are common to UNIX and PC world ******** +# + +#clean up all the intermediate files +clean: + rm -f *.$(OBJ_EXT) core + +#remove everything in clean plus the PCCTS files generated +scrub: + rm -f $(PCCTS_GEN) *.$(OBJ_EXT) core diff --git a/Tools/CodeTools/Source/Pccts/antlr/makefile.cygwin b/Tools/CodeTools/Source/Pccts/antlr/makefile.cygwin new file mode 100644 index 0000000000..956de0be07 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/makefile.cygwin @@ -0,0 +1,219 @@ +# +# Makefile for ANTLR 1.33 +# +# SOFTWARE RIGHTS +# +# We reserve no LEGAL rights to the Purdue Compiler Construction Tool +# Set (PCCTS) -- PCCTS is in the public domain. An individual or +# company may do whatever they wish with source code distributed with +# PCCTS or the code generated by PCCTS, including the incorporation of +# PCCTS, or its output, into commerical software. +# +# We encourage users to develop software with PCCTS. However, we do ask +# that credit is given to us for developing PCCTS. By "credit", +# we mean that if you incorporate our source code into one of your +# programs (commercial product, research project, or otherwise) that you +# acknowledge this fact somewhere in the documentation, research report, +# etc... If you like PCCTS and have developed a nice tool with the +# output, please mention that you developed it using PCCTS. In +# addition, we ask that this header remain intact in our source code. +# As long as these guidelines are kept, we expect to continue enhancing +# this system and expect to make other tools available as they are +# completed. +# +# ANTLR 1.33 +# Terence Parr +# Parr Research Corporation +# with Purdue University +# and AHPCRC, University of Minnesota +# 1989-1995 +# +# Ported to Borland C++, IBM C-Set/2 and Microsoft 6.0 by +# Ed Harfmann +# Micro Data Base Systems +# Lafayette, Indiana +# +SET=../support/set +PCCTS_H=../h + +## +## Uncomment the appropriate section to build +## (both targets and 'make' variable definitions) +## Note that UNIX is the default +## + +# +# OS/2 & DOS 16 bit using MSC 6.0 +# +#CC=cl +#ANTLR=..\bin\antlr +#DLG=..\bin\dlg +#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) /AL /Za /W3 -DPC -DUSER_ZZSYN +#OUT_OBJ = -Fo +#LIBS=/NOD:LLIBCE LLIBCEP +#OBJ_EXT = obj +# +#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \ +# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \ +# misc.obj set.obj pred.obj egamn.obj +# link @<< +#$** /NOI +#$@ /STACK:14336 +# +#$(LIBS: = +^ +#) +#$(DEF_FILE) $(LFLAGS) ; +#<< +# bind $@ c:\os2\doscalls.lib +# copy *.exe ..\bin +# + +# +# Borland C++ for DOS +# +#CC=bcc +#ANTLR=..\bin\antlr +#DLG=..\bin\dlg +#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) -ml -ff- -w- -DPC -DUSER_ZZSYN +#OUT_OBJ = -o +#LIBS= emu mathl cl +#OBJ_EXT = obj +# +#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \ +# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \ +# misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj +# tlink @&&| +#C0L $** +#$@ /Tde /c +# +#$(LIBS) +#$(DEF_FILE) $(LFLAGS) ; +#| +# copy *.exe ..\bin +# + +# +# C-Set/2 for OS/2 +# +#CC=icc +#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) /Sa /W3 -DUSER_ZZSYN -D__STDC__ +#OUT_OBJ = -Fo +#LIBS= +#ANTLR=..\bin\antlr +#DLG=..\bin\dlg +#OBJ_EXT = obj +# +#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \ +# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \ +# misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj +# link386 @<< +#$** /NOI +#$@ /STACK:32768 +# +#$(LIBS: = +^ +#) +#$(DEF_FILE) $(LFLAGS) ; +#<< +# copy *.exe ..\bin +# + +# +# Borland C++ for OS/2 +# +#CC=bcc +#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) -w- -v -DUSER_ZZSYN +#OUT_OBJ = -o +#LIBS= c2 os2 +# +#ANTLR=..\bin\antlr +#DLG=..\bin\dlg +#OBJ_EXT = obj +#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \ +# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \ +# misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj +# tlink @&&| +#c02 $** -c -v +#antlr.exe +# +#C2 os2 +# +#| +# copy *.exe ..\bin +# + +# *********** Target list of PC machines *********** +# +# Don't worry about the ambiguity messages coming from antlr +# for making antlr.c etc... [should be 10 of them, I think] +# +#antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g +# $(ANTLR) antlr.g +# +#antlr.$(OBJ_EXT): antlr.c mode.h tokens.h +# +#scan.$(OBJ_EXT): scan.c mode.h tokens.h +# +#scan.c mode.h: parser.dlg +# $(DLG) -C2 parser.dlg scan.c +# +#set.$(OBJ_EXT): $(SET)/set.c +# $(CC) $(CFLAGS) -c $(OUT_OBJ)set.$(OBJ_EXT) $(SET)/set.c + + + +# +# UNIX (default) +# +BIN_DIR=../../../../bin +CC=gcc +COPT=-O +ANTLR=$(BIN_DIR)/antlr.exe +DLG=${BIN_DIR}/dlg.exe +OBJ_EXT=o +OUT_OBJ = -o +CFLAGS= $(COPT) -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN $(COTHER) -DZZLEXBUFSIZE=65536 +# +# SGI Users, use this CFLAGS +# +#CFLAGS= -O -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN -woff 3262 +OBJ=antlr.o scan.o err.o bits.o build.o fset2.o fset.o gen.o \ + globals.o hash.o lex.o main.o misc.o set.o pred.o egman.o mrhoist.o fcache.o + +antlr : $(OBJ) $(SRC) + $(CC) $(CFLAGS) -o $(BIN_DIR)/antlr.exe $(OBJ) + +# what files does PCCTS generate (both ANTLR and DLG) +PCCTS_GEN=antlr.c scan.c err.c tokens.h mode.h parser.dlg stdpccts.h remap.h + +SRC=antlr.c scan.c err.c bits.c build.c fset2.c fset.c gen.c globals.c \ + hash.c lex.c main.c misc.c $(SET)/set.c pred.c egman.c mrhoist.c fcache.c + +# +# Don't worry about the ambiguity messages coming from antlr +# for making antlr.c etc... [should be 10 of them, I think] +# +#antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g +# $(ANTLR) -gh antlr.g + +antlr.o : antlr.c mode.h tokens.h + +scan.o : scan.c mode.h tokens.h + +#scan.c mode.h: parser.dlg +# $(DLG) -C2 parser.dlg scan.c + +set.o : $(SET)/set.c + $(CC) $(CFLAGS) -c -o set.o $(SET)/set.c + + +# +# ****** These next targets are common to UNIX and PC world ******** +# + +#clean up all the intermediate files +clean: + rm -f *.$(OBJ_EXT) core + +#remove everything in clean plus the PCCTS files generated +scrub: + rm -f $(PCCTS_GEN) *.$(OBJ_EXT) core diff --git a/Tools/CodeTools/Source/Pccts/antlr/makefile1 b/Tools/CodeTools/Source/Pccts/antlr/makefile1 new file mode 100644 index 0000000000..dffc709478 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/makefile1 @@ -0,0 +1,96 @@ +# +# Makefile for ANTLR 1.33 +# +# SOFTWARE RIGHTS +# +# We reserve no LEGAL rights to the Purdue Compiler Construction Tool +# Set (PCCTS) -- PCCTS is in the public domain. An individual or +# company may do whatever they wish with source code distributed with +# PCCTS or the code generated by PCCTS, including the incorporation of +# PCCTS, or its output, into commerical software. +# +# We encourage users to develop software with PCCTS. However, we do ask +# that credit is given to us for developing PCCTS. By "credit", +# we mean that if you incorporate our source code into one of your +# programs (commercial product, research project, or otherwise) that you +# acknowledge this fact somewhere in the documentation, research report, +# etc... If you like PCCTS and have developed a nice tool with the +# output, please mention that you developed it using PCCTS. In +# addition, we ask that this header remain intact in our source code. +# As long as these guidelines are kept, we expect to continue enhancing +# this system and expect to make other tools available as they are +# completed. +# +# ANTLR 1.33 +# Terence Parr +# Parr Research Corporation +# with Purdue University +# and AHPCRC, University of Minnesota +# 1989-1995 +# +# Ported to Borland C++, IBM C-Set/2 and Microsoft 6.0 by +# Ed Harfmann +# Micro Data Base Systems +# Lafayette, Indiana +# +SET=../support/set +PCCTS_H=../h + +# +# UNIX (default) +# +CC=cc +ANTLR=${WORKSPACE}/Tools/bin/antlr +DLG=${WORKSPACE}/Tools/bin/dlg +OBJ_EXT=o +OUT_OBJ = -o +ANSI=-ansi +AOTHER= +CFLAGS= -O0 -g -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN $(COTHER) $(ANSI) -DZZLEXBUFSIZE=32000 +# +# SGI Users, use this CFLAGS +# +#CFLAGS= -O -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN -woff 3262 + +OBJ=antlr.o scan.o err.o bits.o build.o fset2.o fset.o gen.o \ + globals.o hash.o lex.o main.o misc.o set.o pred.o egman.o mrhoist.o fcache.o $(OBJOTHER) + +antlr : $(OBJ) $(SRC) + $(CC) $(CFLAGS) -o antlr $(OBJ) + mv antlr ${WORKSPACE}/Tools/bin + +# what files does PCCTS generate (both ANTLR and DLG) +PCCTS_GEN=antlr.c scan.c err.c tokens.h mode.h parser.dlg stdpccts.h remap.h + +SRC=antlr.c scan.c err.c bits.c build.c fset2.c fset.c gen.c globals.c \ + hash.c lex.c main.c misc.c $(SET)/set.c pred.c egman.c mrhoist.c fcache.c + +# +# Don't worry about the ambiguity messages coming from antlr +# for making antlr.c etc... [should be 10 of them, I think] +# +antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g + $(ANTLR) -gh antlr.g $(AOTHER) + +antlr.o : antlr.c mode.h tokens.h + +scan.o : scan.c mode.h tokens.h + +scan.c mode.h: parser.dlg + $(DLG) -C2 parser.dlg scan.c + +set.o : $(SET)/set.c + $(CC) $(CFLAGS) -c -o set.o $(SET)/set.c + + +# +# ****** These next targets are common to UNIX and PC world ******** +# + +#clean up all the intermediate files +clean: + rm -f *.$(OBJ_EXT) core + +#remove everything in clean plus the PCCTS files generated +scrub: + rm -f $(PCCTS_GEN) *.$(OBJ_EXT) core diff --git a/Tools/CodeTools/Source/Pccts/antlr/misc.c b/Tools/CodeTools/Source/Pccts/antlr/misc.c new file mode 100644 index 0000000000..3f58da34c5 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/misc.c @@ -0,0 +1,1864 @@ +/* + * misc.c + * + * Manage tokens, regular expressions. + * Print methods for debugging + * Compute follow lists onto tail ends of rules. + * + * The following functions are visible: + * + * int addTname(char *); Add token name + * int addTexpr(char *); Add token expression + * int Tnum(char *); Get number of expr/token + * void Tklink(char *, char *); Link a name with an expression + * int hasAction(expr); Does expr already have action assigned? + * void setHasAction(expr); Indicate that expr now has an action + * Entry *newEntry(char *,int); Create new table entry with certain size + * void list_add(ListNode **list, char *e) + * void list_free(ListNode **list, int freeData); *** MR10 *** + * void list_apply(ListNode *list, void (*f)()) + * void lexclass(char *m); switch to new/old lexical class + * void lexmode(int i); switch to old lexical class i + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2001 + */ + +#include +#include "pcctscfg.h" +#include "set.h" +#include "syn.h" +#include "hash.h" +#include "generic.h" +#include "dlgdef.h" +#include + +static int tsize=TSChunk; /* size of token str arrays */ + +static void +#ifdef __USE_PROTOS +RemapForcedTokensInSyntaxDiagram(Node *); +#else +RemapForcedTokensInSyntaxDiagram(); +#endif + + /* T o k e n M a n i p u l a t i o n */ + +/* + * add token 't' to the TokenStr/Expr array. Make more room if necessary. + * 't' is either an expression or a token name. + * + * There is only one TokenStr array, but multiple ExprStr's. Therefore, + * for each lex class (element of lclass) we must extend the ExprStr array. + * ExprStr's and TokenStr are always all the same size. + * + * Also, there is a Texpr hash table for each automaton. + */ +static void +#ifdef __USE_PROTOS +Ttrack( char *t ) +#else +Ttrack( t ) +char *t; +#endif +{ + if ( TokenNum >= tsize ) /* terminal table overflow? */ + { + char **p; + int i, more, j; + + more = TSChunk * (1 + ((TokenNum-tsize) / TSChunk)); + tsize += more; + TokenStr = (char **) realloc((char *)TokenStr, tsize*sizeof(char *)); + require(TokenStr != NULL, "Ttrack: can't extend TokenStr"); + for (i=0; iexpr = e; + p->lclass = CurrentLexClass; + return p; +} + +/* switch to lexical class/mode m. This amounts to creating a new + * lex mode if one does not already exist and making ExprStr point + * to the correct char string array. We must also switch Texpr tables. + * + * BTW, we need multiple ExprStr arrays because more than one automaton + * may have the same label for a token, but with different expressions. + * We need to track an expr for each automaton. If we disallowed this + * feature, only one ExprStr would be required. + */ +void +#ifdef __USE_PROTOS +lexclass( char *m ) +#else +lexclass( m ) +char *m; +#endif +{ + int i; + TermEntry *p; + static char EOFSTR[] = "\"@\""; + + if ( hash_get(Tname, m) != NULL ) + { + warn(eMsg1("lexclass name conflicts with token/errclass label '%s'",m)); + } + /* does m already exist? */ + i = LexClassIndex(m); + if ( i != -1 ) {lexmode(i); return;} + /* must make new one */ + NumLexClasses++; + CurrentLexClass = NumLexClasses-1; + require(NumLexClasses<=MaxLexClasses, "number of allowable lexclasses exceeded\nIncrease MaxLexClasses in generic.h and recompile all C files"); + lclass[CurrentLexClass].classnum = m; + lclass[CurrentLexClass].exprs = (char **) calloc(tsize, sizeof(char *)); + require(lclass[CurrentLexClass].exprs!=NULL, + "lexclass: cannot allocate ExprStr"); + lclass[CurrentLexClass].htable = newHashTable(); + ExprStr = lclass[CurrentLexClass].exprs; + Texpr = lclass[CurrentLexClass].htable; + /* define EOF for each automaton */ + p = newTermEntry( EOFSTR ); + p->token = EofToken; /* couldn't have remapped tokens yet, use EofToken */ + hash_add(Texpr, EOFSTR, (Entry *)p); + list_add(&ExprOrder, (void *)newExpr(EOFSTR)); + /* note: we use the actual ExprStr array + * here as TokenInd doesn't exist yet + */ + ExprStr[EofToken] = EOFSTR; +} + +void +#ifdef __USE_PROTOS +lexmode( int i ) +#else +lexmode( i ) +int i; +#endif +{ + require(iaction!=NULL); +} + +void +#ifdef __USE_PROTOS +setHasAction( char *expr, char *action ) +#else +setHasAction( expr, action ) +char *expr; +char *action; +#endif +{ + TermEntry *p; + require(expr!=NULL, "setHasAction: invalid expr"); + + p = (TermEntry *) hash_get(Texpr, expr); + require(p!=NULL, eMsg1("setHasAction: expr '%s' doesn't exist",expr)); + p->action = action; +} + +ForcedToken * +#ifdef __USE_PROTOS +newForcedToken(char *token, int tnum) +#else +newForcedToken(token, tnum) +char *token; +int tnum; +#endif +{ + ForcedToken *ft = (ForcedToken *) calloc(1, sizeof(ForcedToken)); + require(ft!=NULL, "out of memory"); + ft->token = token; + ft->tnum = tnum; + return ft; +} + +/* + * Make a token indirection array that remaps token numbers and then walk + * the appropriate symbol tables and SynDiag to change token numbers + */ +void +#ifdef __USE_PROTOS +RemapForcedTokens(void) +#else +RemapForcedTokens() +#endif +{ + ListNode *p; + ForcedToken *q; + int max_token_number=0; /* MR9 23-Sep-97 Removed "unsigned" */ + int i; + + if ( ForcedTokens == NULL ) return; + + /* find max token num */ + for (p = ForcedTokens->next; p!=NULL; p=p->next) + { + q = (ForcedToken *) p->elem; + if ( q->tnum > max_token_number ) max_token_number = q->tnum; + } + fprintf(stderr, "max token number is %d\n", max_token_number); + + /* make token indirection array */ + TokenInd = (int *) calloc(max_token_number+1, sizeof(int)); + LastTokenCounted = TokenNum; + TokenNum = max_token_number+1; + require(TokenInd!=NULL, "RemapForcedTokens: cannot allocate TokenInd"); + + /* fill token indirection array and change token id htable ; swap token indices */ + for (i=1; inext; p!=NULL; p=p->next) + { + TermEntry *te; + int old_pos, t; + + q = (ForcedToken *) p->elem; + fprintf(stderr, "%s forced to %d\n", q->token, q->tnum); + te = (TermEntry *) hash_get(Tname, q->token); + require(te!=NULL, "RemapForcedTokens: token not in hash table"); + old_pos = te->token; + fprintf(stderr, "Before: TokenInd[old_pos==%d] is %d\n", old_pos, TokenInd[old_pos]); + fprintf(stderr, "Before: TokenInd[target==%d] is %d\n", q->tnum, TokenInd[q->tnum]); + q = (ForcedToken *) p->elem; + t = TokenInd[old_pos]; + TokenInd[old_pos] = q->tnum; + TokenInd[q->tnum] = t; + te->token = q->tnum; /* update token type id symbol table */ + fprintf(stderr, "After: TokenInd[old_pos==%d] is %d\n", old_pos, TokenInd[old_pos]); + fprintf(stderr, "After: TokenInd[target==%d] is %d\n", q->tnum, TokenInd[q->tnum]); + + /* Change the token number in the sym tab entry for the exprs + * at the old position of the token id and the target position + */ + /* update expr at target (if any) of forced token id */ + if ( q->tnum < TokenNum ) /* is it a valid position? */ + { + for (i=0; itnum]!=NULL ) + { + /* update the symbol table for this expr */ + TermEntry *e = (TermEntry *) hash_get(lclass[i].htable, lclass[i].exprs[q->tnum]); + require(e!=NULL, "RemapForcedTokens: expr not in hash table"); + e->token = old_pos; + fprintf(stderr, "found expr '%s' at target %d in lclass[%d]; changed to %d\n", + lclass[i].exprs[q->tnum], q->tnum, i, old_pos); + } + } + } + /* update expr at old position (if any) of forced token id */ + for (i=0; itoken = q->tnum; + fprintf(stderr, "found expr '%s' for id %s in lclass[%d]; changed to %d\n", + lclass[i].exprs[old_pos], q->token, i, q->tnum); + } + } + } + + /* Update SynDiag */ + RemapForcedTokensInSyntaxDiagram((Node *)SynDiag); +} + +static void +#ifdef __USE_PROTOS +RemapForcedTokensInSyntaxDiagram(Node *p) +#else +RemapForcedTokensInSyntaxDiagram(p) +Node *p; +#endif +{ + Junction *j = (Junction *) p; + RuleRefNode *r = (RuleRefNode *) p; + TokNode *t = (TokNode *)p; + + if ( p==NULL ) return; + require(p->ntype>=1 && p->ntype<=NumNodeTypes, "Remap...: invalid diagram node"); + switch ( p->ntype ) + { + case nJunction : + if ( j->visited ) return; + if ( j->jtype == EndRule ) return; + j->visited = TRUE; + RemapForcedTokensInSyntaxDiagram( j->p1 ); + RemapForcedTokensInSyntaxDiagram( j->p2 ); + j->visited = FALSE; + return; + case nRuleRef : + RemapForcedTokensInSyntaxDiagram( r->next ); + return; + case nToken : + if ( t->remapped ) return; /* we've been here before */ + t->remapped = 1; + fprintf(stderr, "remapping %d to %d\n", t->token, TokenInd[t->token]); + t->token = TokenInd[t->token]; + RemapForcedTokensInSyntaxDiagram( t->next ); + return; + case nAction : + RemapForcedTokensInSyntaxDiagram( ((ActionNode *)p)->next ); + return; + default : + fatal_internal("invalid node type"); + } +} + +/* + * Add a token name. Return the token number associated with it. If it already + * exists, then return the token number assigned to it. + * + * Track the order in which tokens are found so that the DLG output maintains + * that order. It also lets us map token numbers to strings. + */ +int +#ifdef __USE_PROTOS +addTname( char *token ) +#else +addTname( token ) +char *token; +#endif +{ + TermEntry *p; + require(token!=NULL, "addTname: invalid token name"); + + if ( (p=(TermEntry *)hash_get(Tname, token)) != NULL ) return p->token; + p = newTermEntry( token ); + Ttrack( p->str ); + p->token = TokenNum++; + hash_add(Tname, token, (Entry *)p); + return p->token; +} + +/* This is the same as addTname except we force the TokenNum to be tnum. + * We don't have to use the Forced token stuff as no tokens will have + * been defined with #tokens when this is called. This is only called + * when a #tokdefs meta-op is used. + */ +int +#ifdef __USE_PROTOS +addForcedTname( char *token, int tnum ) +#else +addForcedTname( token, tnum ) +char *token; +int tnum; +#endif +{ + TermEntry *p; + require(token!=NULL, "addTname: invalid token name"); + + if ( (p=(TermEntry *)hash_get(Tname, token)) != NULL ) return p->token; + p = newTermEntry( token ); + Ttrack( p->str ); + p->token = tnum; + hash_add(Tname, token, (Entry *)p); + return p->token; +} + +/* + * Add a token expr. Return the token number associated with it. If it already + * exists, then return the token number assigned to it. + */ +int +#ifdef __USE_PROTOS +addTexpr( char *expr ) +#else +addTexpr( expr ) +char *expr; +#endif +{ + TermEntry *p; + require(expr!=NULL, "addTexpr: invalid regular expression"); + + if ( (p=(TermEntry *)hash_get(Texpr, expr)) != NULL ) return p->token; + p = newTermEntry( expr ); + Ttrack( p->str ); + /* track the order in which they occur */ + list_add(&ExprOrder, (void *)newExpr(p->str)); + p->token = TokenNum++; + hash_add(Texpr, expr, (Entry *)p); + return p->token; +} + +/* return the token number of 'term'. Return 0 if no 'term' exists */ +int +#ifdef __USE_PROTOS +Tnum( char *term ) +#else +Tnum( term ) +char *term; +#endif +{ + TermEntry *p; + require(term!=NULL, "Tnum: invalid terminal"); + + if ( *term=='"' ) p = (TermEntry *) hash_get(Texpr, term); + else p = (TermEntry *) hash_get(Tname, term); + if ( p == NULL ) return 0; + else return p->token; +} + +/* associate a Name with an expr. If both have been already assigned + * token numbers, then an error is reported. Add the token or expr + * that has not been added if no error. This 'represents' the #token + * ANTLR pseudo-op. If both have not been defined, define them both + * linked to same token number. + */ +void +#ifdef __USE_PROTOS +Tklink( char *token, char *expr ) +#else +Tklink( token, expr ) +char *token; +char *expr; +#endif +{ + TermEntry *p, *q; + require(token!=NULL && expr!=NULL, "Tklink: invalid token name and/or expr"); + + p = (TermEntry *) hash_get(Tname, token); + q = (TermEntry *) hash_get(Texpr, expr); + if ( p != NULL && q != NULL ) /* both defined */ + { + warn( eMsg2("token name %s and rexpr %s already defined; ignored", + token, expr) ); + return; + } + if ( p==NULL && q==NULL ) /* both not defined */ + { + int t = addTname( token ); + q = newTermEntry( expr ); + hash_add(Texpr, expr, (Entry *)q); + q->token = t; + /* note: we use the actual ExprStr array + * here as TokenInd doesn't exist yet + */ + ExprStr[t] = q->str; + /* track the order in which they occur */ + list_add(&ExprOrder, (void *)newExpr(q->str)); + return; + } + if ( p != NULL ) /* one is defined, one is not */ + { + q = newTermEntry( expr ); + hash_add(Texpr, expr, (Entry *)q); + q->token = p->token; + ExprStr[p->token] = q->str; /* both expr and token str defined now */ + list_add(&ExprOrder, (void *)newExpr(q->str)); + } + else /* trying to associate name with expr here*/ + { + p = newTermEntry( token ); + hash_add(Tname, token, (Entry *)p); + p->token = q->token; + TokenStr[p->token] = p->str;/* both expr and token str defined now */ + } +} + +/* + * Given a string, this function allocates and returns a pointer to a + * hash table record of size 'sz' whose "str" pointer is reset to a position + * in the string table. + */ +Entry * +#ifdef __USE_PROTOS +newEntry( char *text, int sz ) +#else +newEntry( text, sz ) +char *text; +int sz; +#endif +{ + Entry *p; + require(text!=NULL, "new: NULL terminal"); + + if ( (p = (Entry *) calloc(1,sz)) == 0 ) + { + fatal_internal("newEntry: out of memory for terminals\n"); + exit(PCCTS_EXIT_FAILURE); + } + p->str = mystrdup(text); + + return(p); +} + +/* + * add an element to a list. + * + * Any non-empty list has a sentinel node whose 'elem' pointer is really + * a pointer to the last element. (i.e. length(list) = #elemIn(list)+1). + * Elements are appended to the list. + */ +void +#ifdef __USE_PROTOS +list_add( ListNode **list, void *e ) +#else +list_add( list, e ) +ListNode **list; +void *e; +#endif +{ + ListNode *p, *tail; + require(e!=NULL, "list_add: attempting to add NULL list element"); + + p = newListNode; + require(p!=NULL, "list_add: cannot alloc new list node"); + p->elem = e; + if ( *list == NULL ) + { + ListNode *sentinel = newListNode; + require(sentinel!=NULL, "list_add: cannot alloc sentinel node"); + *list=sentinel; + sentinel->next = p; + sentinel->elem = (char *)p; /* set tail pointer */ + } + else /* find end of list */ + { + tail = (ListNode *) (*list)->elem; /* get tail pointer */ + tail->next = p; + (*list)->elem = (char *) p; /* reset tail */ + } +} + +/* MR10 list_free() frees the ListNode elements in the list */ +/* MR10 if freeData then free the data elements of the list too */ + +void +#ifdef __USE_PROTOS +list_free(ListNode **list,int freeData) +#else +list_free(list,freeData) + ListNode **list; + int freeData; +#endif +{ + ListNode *p; + ListNode *next; + + if (list == NULL) return; + if (*list == NULL) return; + for (p=*list; p != NULL; p=next) { + next=p->next; + if (freeData && p->elem != NULL) { + free( (char *) p->elem); + }; + free( (char *) p); + }; + *list=NULL; +} + +void +#ifdef __USE_PROTOS +list_apply( ListNode *list, void (*f)(void *) ) +#else +list_apply( list, f ) +ListNode *list; +void (*f)(); +#endif +{ + ListNode *p; + require(f!=NULL, "list_apply: NULL function to apply"); + + if ( list == NULL ) return; + for (p = list->next; p!=NULL; p=p->next) (*f)( p->elem ); +} + +/* MR27 */ + +#ifdef __USE_PROTOS +int list_search_cstring(ListNode *list, char * cstring) +#else +int list_search_cstring(list, cstring) + ListNode * list; + char * cstring; +#endif +{ + ListNode *p; + if (list == NULL ) return 0; + for (p = list->next; p!=NULL; p=p->next) { + if (p->elem == NULL) continue; + if (0 == strcmp((char *) p->elem , cstring)) return 1; + } + return 0; +} + + /* F O L L O W C y c l e S t u f f */ + +/* make a key based upon (rulename, computation, k value). + * Computation values are 'i'==FIRST, 'o'==FOLLOW. + */ + +/* MR10 Make the key all characters so it can be read easily */ +/* MR10 by a simple dump program. Also, separates */ +/* MR10 'o' and 'i' from rule name */ + +char * +#ifdef __USE_PROTOS +Fkey( char *rule, int computation, int k ) +#else +Fkey( rule, computation, k ) +char *rule; +int computation; +int k; +#endif +{ + static char key[MaxRuleName+2+2+1]; /* MR10 */ + int i; + + if ( k > 99 ) /* MR10 */ + fatal("k>99 is too big for this implementation of ANTLR!\n"); /* MR10 */ + if ( (i=strlen(rule)) > MaxRuleName ) /* MR10 */ + fatal( eMsgd("rule name > max of %d\n", MaxRuleName) ); /* MR10 */ + strcpy(key,rule); + +/* MR10 */ key[i]='*'; +/* MR10 */ key[i+1] = (char) computation; /* MR20 G. Hobbelt */ +/* MR10 */ if (k < 10) { +/* MR10 */ key[i+2] = (char) ( '0' + k); +/* MR10 */ key[i+3] = '\0'; +/* MR10 */ } else { +/* MR10 */ key[i+2] = (char) ( '0' + k/10); +/* MR10 */ key[i+3] = (char) ( '0' + k % 10); +/* MR10 */ key[i+4] = '\0'; +/* MR10 */ }; + + return key; +} + +/* Push a rule onto the kth FOLLOW stack */ +void +#ifdef __USE_PROTOS +FoPush( char *rule, int k ) +#else +FoPush( rule, k ) +char *rule; +int k; +#endif +{ + RuleEntry *r; + require(rule!=NULL, "FoPush: tried to push NULL rule"); + require(k<=CLL_k, "FoPush: tried to access non-existent stack"); + + /*fprintf(stderr, "FoPush(%s)\n", rule);*/ + r = (RuleEntry *) hash_get(Rname, rule); + if ( r == NULL ) {fatal_internal( eMsg1("rule %s must be defined but isn't", rule) );} + if ( FoStack[k] == NULL ) /* Does the kth stack exist yet? */ + { + /*fprintf(stderr, "allocating FoStack\n");*/ + FoStack[k] = (int *) calloc(FoStackSize, sizeof(int)); + require(FoStack[k]!=NULL, "FoPush: cannot allocate FOLLOW stack\n"); + } + if ( FoTOS[k] == NULL ) + { + FoTOS[k]=FoStack[k]; + *(FoTOS[k]) = r->rulenum; + } + else + { +#ifdef MEMCHK + require(valid(FoStack[k]), "FoPush: invalid FoStack"); +#endif + if ( FoTOS[k] >= &(FoStack[k][FoStackSize-1]) ) + fatal( eMsgd("exceeded max depth of FOLLOW recursion (%d)\n", + FoStackSize) ); + require(FoTOS[k]>=FoStack[k], + eMsg1("FoPush: FoStack stack-ptr is playing out of its sandbox", + rule)); + ++(FoTOS[k]); + *(FoTOS[k]) = r->rulenum; + } + { + /* +**** int *p; +**** fprintf(stderr, "FoStack[k=%d]:\n", k); +**** for (p=FoStack[k]; p<=FoTOS[k]; p++) +**** { +**** fprintf(stderr, "\t%s\n", RulePtr[*p]->rname); +**** } + */ + } +} + +/* Pop one rule off of the FOLLOW stack. TOS ptr is NULL if empty. */ +void +#ifdef __USE_PROTOS +FoPop( int k ) +#else +FoPop( k ) +int k; +#endif +{ + require(k<=CLL_k, "FoPop: tried to access non-existent stack"); + /*fprintf(stderr, "FoPop\n");*/ + require(FoTOS[k]>=FoStack[k]&&FoTOS[k]<=&(FoStack[k][FoStackSize-1]), + "FoPop: FoStack stack-ptr is playing out of its sandbox"); + if ( FoTOS[k] == FoStack[k] ) FoTOS[k] = NULL; + else (FoTOS[k])--; +} + +/* Compute FOLLOW cycle. + * Mark all FOLLOW sets for rules in cycle as incomplete. + * Then, save cycle on the cycle list (Cycles) for later resolution. + * The Cycle is stored in the form: + * (head of cycle==croot, rest of rules in cycle==cyclicDep) + * + * e.g. (Fo means "FOLLOW of", "-->" means requires or depends on) + * + * Fo(x)-->Fo(a)-->Fo(b)-->Fo(c)-->Fo(x) + * ^----Infinite recursion (cycle) + * + * the cycle would be: x -> {a,b,c} or stored as (x,{a,b,c}). Fo(x) depends + * on the FOLLOW of a,b, and c. The root of a cycle is always complete after + * Fo(x) finishes. Fo(a,b,c) however are not. It turns out that all rules + * in a FOLLOW cycle have the same FOLLOW set. + */ +void +#ifdef __USE_PROTOS +RegisterCycle( char *rule, int k ) +#else +RegisterCycle( rule, k ) +char *rule; +int k; +#endif +{ + CacheEntry *f; + Cycle *c; + int *p; + RuleEntry *r; + require(rule!=NULL, "RegisterCycle: tried to register NULL rule"); + require(k<=CLL_k, "RegisterCycle: tried to access non-existent stack"); + + /*fprintf(stderr, "RegisterCycle(%s)\n", rule);*/ + /* Find cycle start */ + r = (RuleEntry *) hash_get(Rname, rule); + require(r!=NULL,eMsg1("rule %s must be defined but isn't", rule)); + require(FoTOS[k]>=FoStack[k]&&FoTOS[k]<=&(FoStack[k][FoStackSize-1]), + eMsg1("RegisterCycle(%s): FoStack stack-ptr is playing out of its sandbox", + rule)); +/*** if ( FoTOS[k]&(FoStack[k][FoStackSize-1]) ) +**** { +**** fprintf(stderr, "RegisterCycle(%s): FoStack stack-ptr is playing out of its sandbox\n", +**** rule); +**** fprintf(stderr, "RegisterCycle: sp==0x%x out of bounds 0x%x...0x%x\n", +**** FoTOS[k], FoStack[k], &(FoStack[k][FoStackSize-1])); +**** exit(PCCTS_EXIT_FAILURE); +**** } +****/ + +#ifdef MEMCHK + require(valid(FoStack[k]), "RegisterCycle: invalid FoStack"); +#endif + for (p=FoTOS[k]; *p != r->rulenum && p >= FoStack[k]; --p) {;} + require(p>=FoStack[k], "RegisterCycle: FoStack is screwed up beyond belief"); + if ( p == FoTOS[k] ) return; /* don't worry about cycles to oneself */ + + /* compute cyclic dependents (rules in cycle except head) */ + c = newCycle; + require(c!=NULL, "RegisterCycle: couldn't alloc new cycle"); + c->cyclicDep = empty; + c->croot = *p++; /* record root of cycle */ + for (; p<=FoTOS[k]; p++) + { + /* Mark all dependent rules as incomplete */ + f = (CacheEntry *) hash_get(Fcache, Fkey(RulePtr[*p]->rname,'o',k)); + if ( f==NULL ) + { + f = newCacheEntry( Fkey(RulePtr[*p]->rname,'o',k) ); + hash_add(Fcache, Fkey(RulePtr[*p]->rname,'o',k), (Entry *)f); + } + f->incomplete = TRUE; + + set_orel(*p, &(c->cyclicDep)); /* mark rule as dependent of croot */ + } + list_add(&(Cycles[k]), (void *)c); +} + +/* make all rules in cycle complete + * + * while ( some set has changed ) do + * for each cycle do + * if degree of FOLLOW set for croot > old degree then + * update all FOLLOW sets for rules in cyclic dependency + * change = TRUE + * endif + * endfor + * endwhile + */ +void +#ifdef __USE_PROTOS +ResolveFoCycles( int k ) +#else +ResolveFoCycles( k ) +int k; +#endif +{ + ListNode *p, *q; + Cycle *c; + int changed = 1; + CacheEntry *f,*g; + int r; +/* int i; */ /* MR10 not useful */ + unsigned d; + + unsigned *cursor; /* MR10 */ + unsigned *origin; /* MR10 */ + + /*fprintf(stderr, "Resolving following cycles for %d\n", k);*/ + while ( changed ) + { + changed = 0; +/* MR10 i = 0; */ + for (p = Cycles[k]->next; p!=NULL; p=p->next) + { + c = (Cycle *) p->elem; + /*fprintf(stderr, "cycle %d: %s -->", i++, RulePtr[c->croot]->rname);*/ + /*s_fprT(stderr, c->cyclicDep);*/ + /*fprintf(stderr, "\n");*/ + f = (CacheEntry *) + hash_get(Fcache, Fkey(RulePtr[c->croot]->rname,'o',k)); + require(f!=NULL, eMsg1("FOLLOW(%s) must be in cache but isn't", RulePtr[c->croot]->rname) ); + if ( (d=set_deg(f->fset)) > c->deg ) + { + /*fprintf(stderr, "Fo(%s) has changed\n", RulePtr[c->croot]->rname);*/ + changed = 1; + c->deg = d; /* update cycle FOLLOW set degree */ + +/* MR10 */ origin=set_pdq(c->cyclicDep); +/* MR10 */ for (cursor=origin; *cursor != nil; cursor++) { +/* MR10 */ r=*cursor; + +/******** while ( !set_nil(c->cyclicDep) ) { *****/ +/******** r = set_int(c->cyclicDep); *****/ +/******** set_rm(r, c->cyclicDep); *****/ + + /*fprintf(stderr, "updating Fo(%s)\n", RulePtr[r]->rname);*/ + g = (CacheEntry *) + hash_get(Fcache, Fkey(RulePtr[r]->rname,'o',k)); + require(g!=NULL, eMsg1("FOLLOW(%s) must be in cache but isn't", RulePtr[r]->rname) ); + set_orin(&(g->fset), f->fset); + g->incomplete = FALSE; + } +/* MR10 */ free( (char *) origin); +/* MR10 */ origin=NULL; + } + } +/* MR10 - this if statement appears to be meaningless since i is always 0 */ +/* MR10 if ( i == 1 ) changed = 0; */ /* if only 1 cycle, no need to repeat */ + } + /* kill Cycle list */ + for (q = Cycles[k]->next; q != NULL; q=p) + { + p = q->next; + set_free( ((Cycle *)q->elem)->cyclicDep ); + free((char *)q); + } + free( (char *)Cycles[k] ); + Cycles[k] = NULL; +} + + + /* P r i n t i n g S y n t a x D i a g r a m s */ + +static void +#ifdef __USE_PROTOS +pBlk( Junction *q, int btype ) +#else +pBlk( q, btype ) +Junction *q; +int btype; +#endif +{ + int k,a; + Junction *alt, *p; + + q->end->pvisited = TRUE; + if ( btype == aLoopBegin ) + { + require(q->p2!=NULL, "pBlk: invalid ()* block"); + PRINT(q->p1); + alt = (Junction *)q->p2; + PRINT(alt->p1); + if ( PrintAnnotate ) + { + printf(" /* Opt "); + k = 1; + while ( !set_nil(alt->fset[k]) ) + { + s_fprT(stdout, alt->fset[k]); + if ( k++ == CLL_k ) break; + if ( !set_nil(alt->fset[k]) ) printf(", "); + } + printf(" */\n"); + } + return; + } + for (a=1,alt=q; alt != NULL; alt= (Junction *) alt->p2, a++) + { + if ( alt->p1 != NULL ) PRINT(alt->p1); + if ( PrintAnnotate ) + { + printf( " /* [%d] ", alt->altnum); + k = 1; + while ( !set_nil(alt->fset[k]) ) + { + s_fprT(stdout, alt->fset[k]); + if ( k++ == CLL_k ) break; + if ( !set_nil(alt->fset[k]) ) printf(", "); + } + if ( alt->p2 == NULL && btype == aOptBlk ) + printf( " (optional branch) */\n"); + else printf( " */\n"); + } + + /* ignore implied empty alt of Plus blocks */ + if ( alt->p2 != NULL && ((Junction *)alt->p2)->ignore ) break; + + if ( alt->p2 != NULL && !(((Junction *)alt->p2)->p2==NULL && btype == aOptBlk) ) + { + if ( pLevel == 1 ) + { + printf("\n"); + if ( a+1==pAlt1 || a+1==pAlt2 ) printf("=>"); + printf("\t"); + } + else printf(" "); + printf("|"); + if ( pLevel == 1 ) + { + p = (Junction *) ((Junction *)alt->p2)->p1; + while ( p!=NULL ) + { + if ( p->ntype==nAction ) + { + p=(Junction *)((ActionNode *)p)->next; + continue; + } + if ( p->ntype!=nJunction ) + { + break; + } + if ( p->jtype==EndBlk || p->jtype==EndRule ) + { + p = NULL; + break; + } + p = (Junction *)p->p1; + } + if ( p==NULL ) printf("\n\t"); /* Empty alt? */ + } + } + } + q->end->pvisited = FALSE; +} + +/* How to print out a junction */ +void +#ifdef __USE_PROTOS +pJunc( Junction *q ) +#else +pJunc( q ) +Junction *q; +#endif +{ + int dum_k; + int doing_rule; + require(q!=NULL, "pJunc: NULL node"); + require(q->ntype==nJunction, "pJunc: not junction"); + + if ( q->pvisited == TRUE ) return; + q->pvisited = TRUE; + switch ( q->jtype ) + { + case aSubBlk : + if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k); + if ( q->end->p1 != NULL && ((Junction *)q->end->p1)->ntype==nJunction && + ((Junction *)q->end->p1)->jtype == EndRule ) doing_rule = 1; + else doing_rule = 0; + pLevel++; + if ( pLevel==1 ) + { + if ( pAlt1==1 ) printf("=>"); + printf("\t"); + } + else printf(" "); + if ( doing_rule ) + { + if ( pLevel==1 ) printf(" "); + pBlk(q,q->jtype); + } + else { + printf("("); + if ( pLevel==1 ) printf(" "); + pBlk(q,q->jtype); + if ( pLevel>1 ) printf(" "); + printf(")"); + } + if ( q->guess ) printf("?"); + pLevel--; + if ( PrintAnnotate ) freeBlkFsets(q); + if ( q->end->p1 != NULL ) PRINT(q->end->p1); + break; + case aOptBlk : + if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k); + pLevel++; + if ( pLevel==1 ) + { + if ( pAlt1==1 ) printf("=>"); + printf("\t"); + } + else printf(" "); + printf("{"); + if ( pLevel==1 ) printf(" "); + pBlk(q,q->jtype); + if ( pLevel>1 ) printf(" "); + else printf("\n\t"); + printf("}"); + pLevel--; + if ( PrintAnnotate ) freeBlkFsets(q); + if ( q->end->p1 != NULL ) PRINT(q->end->p1); + break; + case aLoopBegin : + if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k); + pLevel++; + if ( pLevel==1 ) + { + if ( pAlt1==1 ) printf("=>"); + printf("\t"); + } + else printf(" "); + printf("("); + if ( pLevel==1 ) printf(" "); + pBlk(q,q->jtype); + if ( pLevel>1 ) printf(" "); + else printf("\n\t"); + printf(")*"); + pLevel--; + if ( PrintAnnotate ) freeBlkFsets(q); + if ( q->end->p1 != NULL ) PRINT(q->end->p1); + break; + case aLoopBlk : + if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k); + pBlk(q,q->jtype); + if ( PrintAnnotate ) freeBlkFsets(q); + break; + case aPlusBlk : + if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k); + pLevel++; + if ( pLevel==1 ) + { + if ( pAlt1==1 ) printf("=>"); + printf("\t"); + } + else printf(" "); + printf("("); + if ( pLevel==1 ) printf(" "); + pBlk(q,q->jtype); + if ( pLevel>1 ) printf(" "); + printf(")+"); + pLevel--; + if ( PrintAnnotate ) freeBlkFsets(q); + if ( q->end->p1 != NULL ) PRINT(q->end->p1); + break; + case EndBlk : + break; + case RuleBlk : + printf( "\n%s :\n", q->rname); + PRINT(q->p1); + if ( q->p2 != NULL ) PRINT(q->p2); + break; + case Generic : + if ( q->p1 != NULL ) PRINT(q->p1); + q->pvisited = FALSE; + if ( q->p2 != NULL ) PRINT(q->p2); + break; + case EndRule : + printf( "\n\t;\n"); + break; + } + q->pvisited = FALSE; +} + +/* How to print out a rule reference node */ +void +#ifdef __USE_PROTOS +pRuleRef( RuleRefNode *p ) +#else +pRuleRef( p ) +RuleRefNode *p; +#endif +{ + require(p!=NULL, "pRuleRef: NULL node"); + require(p->ntype==nRuleRef, "pRuleRef: not rule ref node"); + + printf( " %s", p->text); + PRINT(p->next); +} + +/* How to print out a terminal node */ +void +#ifdef __USE_PROTOS +pToken( TokNode *p ) +#else +pToken( p ) +TokNode *p; +#endif +{ + require(p!=NULL, "pToken: NULL node"); + require(p->ntype==nToken, "pToken: not token node"); + + if ( p->wild_card ) printf(" ."); + printf( " %s", TerminalString(p->token)); + PRINT(p->next); +} + +/* How to print out a terminal node */ +void +#ifdef __USE_PROTOS +pAction( ActionNode *p ) +#else +pAction( p ) +ActionNode *p; +#endif +{ + require(p!=NULL, "pAction: NULL node"); + require(p->ntype==nAction, "pAction: not action node"); + + PRINT(p->next); +} + + /* F i l l F o l l o w L i s t s */ + +/* + * Search all rules for all rule reference nodes, q to rule, r. + * Add q->next to follow list dangling off of rule r. + * i.e. + * + * r: -o-R-o-->o--> Ptr to node following rule r in another rule + * | + * o--> Ptr to node following another reference to r. + * + * This is the data structure employed to avoid FOLLOW set computation. We + * simply compute the FIRST (reach) of the EndRule Node which follows the + * list found at the end of all rules which are referenced elsewhere. Rules + * not invoked by other rules have no follow list (r->end->p1==NULL). + * Generally, only start symbols are not invoked by another rule. + * + * Note that this mechanism also gives a free cross-reference mechanism. + * + * The entire syntax diagram is layed out like this: + * + * SynDiag + * | + * v + * o-->R1--o + * | + * o-->R2--o + * | + * ... + * | + * o-->Rn--o + * + */ +void +#ifdef __USE_PROTOS +FoLink( Node *p ) +#else +FoLink( p ) +Node *p; +#endif +{ + RuleEntry *q; + Junction *j = (Junction *) p; + RuleRefNode *r = (RuleRefNode *) p; + + if ( p==NULL ) return; + require(p->ntype>=1 && p->ntype<=NumNodeTypes, + eMsgd("FoLink: invalid diagram node: ntype==%d",p->ntype)); + switch ( p->ntype ) + { + case nJunction : + if ( j->fvisited ) return; + if ( j->jtype == EndRule ) return; + j->fvisited = TRUE; + FoLink( j->p1 ); + FoLink( j->p2 ); +/* MR14 */ +/* MR14 */ /* Need to determine whether the guess block is an */ +/* MR14 */ /* of the form (alpha)? beta before follow sets are */ +/* MR14 */ /* computed. This is necessary to solve problem */ +/* MR14 */ /* of doing follow on the alpha of an (alpha)? beta block. */ +/* MR14 */ +/* MR14 */ /* This is performed by analysis_point as a side-effect. */ +/* MR14 */ +/* MR14 */ +/* MR14 */ if (j->jtype == aSubBlk && j->guess) { +/* MR14 */ Junction *ignore; +/* MR14 */ ignore=analysis_point(j); +/* MR14 */ } +/* MR14 */ + return; + case nRuleRef : + if ( r->linked ) return; + q = (RuleEntry *) hash_get(Rname, r->text); + if ( q == NULL ) + { + warnFL( eMsg1("rule %s not defined",r->text), FileStr[r->file], r->line ); + } + else + { + if ( r->parms!=NULL && RulePtr[q->rulenum]->pdecl==NULL ) + { + warnFL( eMsg1("rule %s accepts no parameter(s)", r->text), + FileStr[r->file], r->line ); + } + if ( r->parms==NULL && RulePtr[q->rulenum]->pdecl!=NULL ) + { + warnFL( eMsg1("rule %s requires parameter(s)", r->text), + FileStr[r->file], r->line ); + } + if ( r->assign!=NULL && RulePtr[q->rulenum]->ret==NULL ) + { + warnFL( eMsg1("rule %s yields no return value(s)", r->text), + FileStr[r->file], r->line ); + } + if ( r->assign==NULL && RulePtr[q->rulenum]->ret!=NULL ) + { + warnFL( eMsg1("rule %s returns a value(s)", r->text), + FileStr[r->file], r->line ); + } + if ( !r->linked ) + { + addFoLink( r->next, r->rname, RulePtr[q->rulenum] ); + r->linked = TRUE; + } + } + FoLink( r->next ); + return; + case nToken : + FoLink( ((TokNode *)p)->next ); + return; + case nAction : + FoLink( ((ActionNode *)p)->next ); + return; + default : + fatal_internal("invalid node type"); + } +} + +/* + * Add a reference to the end of a rule. + * + * 'r' points to the RuleBlk node in a rule. r->end points to the last node + * (EndRule jtype) in a rule. + * + * Initial: + * r->end --> o + * + * After: + * r->end --> o-->o--> Ptr to node following rule r in another rule + * | + * o--> Ptr to node following another reference to r. + * + * Note that the links are added to the head of the list so that r->end->p1 + * always points to the most recently added follow-link. At the end, it should + * point to the last reference found in the grammar (starting from the 1st rule). + */ +void +#ifdef __USE_PROTOS +addFoLink( Node *p, char *rname, Junction *r ) +#else +addFoLink( p, rname, r ) +Node *p; +char *rname; +Junction *r; +#endif +{ + Junction *j; + require(r!=NULL, "addFoLink: incorrect rule graph"); + require(r->end!=NULL, "addFoLink: incorrect rule graph"); + require(r->end->jtype==EndRule, "addFoLink: incorrect rule graph"); + require(p!=NULL, "addFoLink: NULL FOLLOW link"); + + j = newJunction(); + j->rname = rname; /* rname on follow links point to target rule */ + j->p1 = p; /* link to other rule */ + j->p2 = (Node *) r->end->p1;/* point to head of list */ + r->end->p1 = (Node *) j; /* reset head to point to new node */ +} + +void +#ifdef __USE_PROTOS +GenCrossRef( Junction *p ) +#else +GenCrossRef( p ) +Junction *p; +#endif +{ + set a; + Junction *j; + RuleEntry *q; + unsigned e; + require(p!=NULL, "GenCrossRef: why are you passing me a null grammar?"); + + printf("Cross Reference:\n\n"); + a = empty; + for (; p!=NULL; p = (Junction *)p->p2) + { + printf("Rule %20s referenced by {", p->rname); + /* make a set of rules for uniqueness */ + for (j = (Junction *)(p->end)->p1; j!=NULL; j = (Junction *)j->p2) + { + q = (RuleEntry *) hash_get(Rname, j->rname); + require(q!=NULL, "GenCrossRef: FoLinks are screwed up"); + set_orel(q->rulenum, &a); + } + for (; !set_nil(a); set_rm(e, a)) + { + e = set_int(a); + printf(" %s", RulePtr[e]->rname); + } + printf(" }\n"); + } + set_free( a ); +} + +/* + The single argument is a pointer to the start of an element of a + C++ style function prototypet list. Given a pointer to the start of + an formal we must locate the comma (or the end of the string) + and locate the datatype, formal name, and initial value expression. + + The function returns a pointer to the character following the comma + which terminates the formal declaration, or a pointer to the end of + the string if none was found. + + I thought we were parsing specialists, how come I'm doing this by + hand written code ? + + Examples of input: + + Foo f, + Foo f = Foo(1), + Foo f = Foo(1,2), + Foo f = &farray[1,2], + Foo f = ",", + Foo f = ',', + TFoo f = TFoo(1,2), + + A non-zero value for nesting indicates a problem matching '(' and ')', + '[' and ']', '<' and '>', '{' and '}', or improperly terminated string + or character literal. + +*/ + + +/* + * Don't care if it is a valid string literal or not, just find the end + * Start with pointer to leading "\"" + */ + +#ifdef __USE_PROTOS +char * skipStringLiteral(char *pCurrent) +#else +char * skipStringLiteral(pCurrent) +char *pCurrent; +#endif +{ + char *p = pCurrent; + if (*p == 0) return p; + require (*p == '\"', "skipStringLiteral") + p++; + for (p = p; *p != 0; p++) { + if (*p == '\\') { + p++; + if (*p == 0) break; + p++; + } + if (*p == '\"') { + p++; + break; + } + } + return p; +} + +/* + * Don't care if it is a valid character literal or not, just find the end + * Start with pointer to leading "'" + */ + +#ifdef __USE_PROTOS +char * skipCharLiteral(char *pStart) +#else +char * skipCharLiteral(pStart) + char *pStart; +#endif +{ + char *p = pStart; + if (*p == 0) return p; + require (*p == '\'', "skipCharLiteral") + p++; + for (p = p; *p != 0; p++) { + if (*p == '\\') { + p++; + if (*p == 0) break; + p++; + } + if (*p == '\'') { + p++; + break; + } + } + return p; +} + +#ifdef __USE_PROTOS +char * skipSpaces(char *pStart) +#else +char * skipSpaces(pStart) +char * pStart; +#endif +{ + char *p = pStart; + while (*p != 0 && isspace(*p)) p++; + return p; +} + +#ifdef __USE_PROTOS +char * skipToSeparatorOrEqualSign(char *pStart, int *pNest) +#else +char * skipToSeparatorOrEqualSign(pStart, pNest) +char *pStart; +int *pNest; +#endif +{ + char *p = pStart; + + int nest = 0; + + *pNest = (-1); + + while (*p != 0) { + switch (*p) { + + case '(' : + case '[' : + case '<' : + case '{' : + nest++; + p++; + break; + + case ')' : + case ']' : + case '>' : + case '}' : + nest--; + p++; + break; + + case '"' : + p = skipStringLiteral(p); + break; + + case '\'' : + p = skipCharLiteral(p); + break; + + case '\\': + p++; + if (*p == 0) goto EXIT; + p++; + break; + + case ',': + case '=': + if (nest == 0) goto EXIT; + p++; + break; + + default: + p++; + } + } +EXIT: + *pNest = nest; + return p; +} + +#ifdef __USE_PROTOS +char * skipToSeparator(char *pStart, int *pNest) +#else +char * skipToSeparator(pStart, pNest) +char *pStart; +int *pNest; +#endif +{ + char * p = pStart; + for ( ; ; ) { + p = skipToSeparatorOrEqualSign(p, pNest); + if (*pNest != 0) return p; + if (*p == ',') return p; + if (*p == 0) return p; + p++; + } +} + +/* skip to just past the "=" separating the declaration from the initialization value */ + +#ifdef __USE_PROTOS +char * getInitializer(char *pStart) +#else +char * getInitializer(pStart) +char * pStart; +#endif +{ + char *p; + char *pDataType; + char *pSymbol; + char *pEqualSign; + char *pValue; + char *pSeparator; + int nest = 0; + + require(pStart!=NULL, "getInitializer: invalid string"); + + p = endFormal(pStart, + &pDataType, + &pSymbol, + &pEqualSign, + &pValue, + &pSeparator, + &nest); + if (nest != 0) return NULL; + if (pEqualSign == NULL) return NULL; + if (pValue == NULL) return NULL; + return strBetween(pValue, NULL, pSeparator); +} + +/* + Examines the string from pStart to pEnd-1. + If the string has 0 length or is entirely white space + returns 1. Otherwise 0. +*/ + +#ifdef __USE_PROTOS +int isWhiteString(const char *pStart, const char *pEnd) +#else +int isWhiteString(pStart, pEnd) +const char *pStart; +const char *pEnd; +#endif +{ + const char *p; + for (p = pStart; p < pEnd; p++) { + if (! isspace(*p)) return 0; + } + return 1; +} + +/* + This replaces HasComma() which couldn't distinguish + + foo ["a,b"] + + from: + + foo[a,b] + +*/ + +#ifdef __USE_PROTOS +int hasMultipleOperands(char *pStart) +#else +int hasMultipleOperands(pStart) +char *pStart; +#endif +{ + char *p = pStart; + int nest = 0; + + p = skipSpaces(p); + if (*p == 0) return 0; + p = skipToSeparator(p, &nest); + if (nest == 0 && *p == ',') return 1; + return 0; +} + + +#define MAX_STR_BETWEEN_WORK_AREA 1000 + +static char strBetweenWorkArea[MAX_STR_BETWEEN_WORK_AREA]; + + +/* + strBetween(pStart, pNext, pStop) + + Creates a null terminated string by copying the text between two pointers + to a work area. The start of the string is pStart. The end of the string + is the character before pNext, or if pNext is null then the character before + pStop. Trailing spaces are not included in the copy operation. + + This is used when a string contains several parts. The pNext part may be + optional. The pStop will stop the scan when the optional part is not present + (is a null pointer). +*/ + +#ifdef __USE_PROTOS +char *strBetween(char *pStart, char *pNext, char *pStop) +#else +char *strBetween(pStart, pNext, pStop) +char *pStart; +char *pNext; +char *pStop; +#endif +{ + char *p; + char *q = strBetweenWorkArea; + const char *pEnd; + + pEnd = (pNext != NULL) ? pNext : pStop; + + require (pEnd != NULL, "pEnd == NULL"); + require (pEnd >= pStart, "pEnd < pStart"); + for (pEnd--; pEnd >= pStart; pEnd--) { /* MR31 */ + if (! isspace(*pEnd)) break; + } + for (p = pStart; + p <= pEnd && q < &strBetweenWorkArea[MAX_STR_BETWEEN_WORK_AREA-2]; + p++, q++) { + *q = *p; + } + *q = 0; + return strBetweenWorkArea; +} + +/* + function Returns pointer to character following separator at + value which to continue search for next formal. If at the + end of the string a pointer to the null byte at the + end of the string is returned. + + pStart Pointer to the starting position of the formal list + + This may be the middle of a longer string, for example + when looking for the end of formal #3 starting from + the middle of the complete formal list. + + ppDataType Returns a pointer to the start of the data type in the + formal. Example: pointer to "Foo". + + ppSymbol Returns a pointer to the start of the formal symbol. + Example: pointer to "f". + + ppEqualSign Returns a pointer to the equal sign separating the + formal symbol from the initial value. If there is + no "=" then this will be NULL. + + ppValue Returns a pointer to the initial value part of the + formal declaration. Example: pointer to "&farray[1,2]" + + ppSeparator Returns a pointer to the character which terminated the + scan. This should be a pointer to a comma or a null + byte which terminates the string. + + pNest Returns the nesting level when a separator was found. + This is non-zero for any kind of error. This is zero + for a successful parse of this portion of the formal + list. + +*/ + +#ifdef __USE_PROTOS +char * endFormal(char *pStart, + char **ppDataType, + char **ppSymbol, + char **ppEqualSign, + char **ppValue, + char **ppSeparator, + int *pNest) +#else +char * endFormal(pStart, + ppDataType, + ppSymbol, + ppEqualSign, + ppValue, + ppSeparator, + pNest) +char *pStart; +char **ppDataType; +char **ppSymbol; +char **ppEqualSign; +char **ppValue; +char **ppSeparator; +int *pNest; + +#endif +{ + char *p = pStart; + char *q; + + *ppDataType = NULL; + *ppSymbol = NULL; + *ppEqualSign = NULL; + *ppValue = NULL; + *ppSeparator = NULL; + + *pNest = 0; + + /* The first non-blank is the start of the datatype */ + + p = skipSpaces(p); + if (*p == 0) goto EXIT; + *ppDataType = p; + + /* We are not looking for the symbol, we are looking + for the separator that follows the symbol. Then + we'll back up. + + Search for the ',' or '=" or null terminator. + */ + + p = skipToSeparatorOrEqualSign(p, pNest); + + if (*pNest != 0) goto EXIT; + + /* + Work backwards to find start of symbol + Skip spaces between the end of symbol and separator + Assume that there are no spaces in the formal, but + there is a space preceding the formal + */ + + for (q = &p[-1]; q >= *ppDataType; q--) { + if (! isspace(*q)) break; + } + if (q < *ppDataType) goto EXIT; + + /* + MR26 Handle things like: IIR_Bool (IIR_Decl::*constraint)() + Backup until we hit the end of a symbol string, then find the + start of the symbol string. This wont' work for functions + with prototypes, but works for the most common cases. For + others, use typedef names. + */ + +/* MR26 */ for (q = q; q >= *ppDataType; q--) { +/* MR26 */ if (isalpha(*q) || isdigit(*q) || *q == '_' || *q == '$') break; +/* MR26 */ } +/* MR26 */ if (q < *ppDataType) goto EXIT; + + for (q = q; q >= *ppDataType; q--) { + if ( ! (isalpha(*q) || isdigit(*q) || *q == '_' || *q == '$')) break; + } + + *ppSymbol = &q[1]; + + if (*p == ',' || *p == 0) { + *ppSeparator = p; + goto EXIT; + } + + *ppEqualSign = p; + p = skipSpaces(++p); + *ppValue = p; + if (*p == 0) goto EXIT; + + + while (*p != 0 && *pNest == 0 && *p != ',') { + p = skipToSeparator(p, pNest); + } + if (*pNest == 0) *ppSeparator = p; + +EXIT: + if (*p == ',') p++; + return p; +} diff --git a/Tools/CodeTools/Source/Pccts/antlr/mode.h b/Tools/CodeTools/Source/Pccts/antlr/mode.h new file mode 100644 index 0000000000..c08bf31ac7 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/mode.h @@ -0,0 +1,12 @@ +#define START 0 +#define STRINGS 1 +#define ACTION_STRINGS 2 +#define ACTION_CHARS 3 +#define ACTION_COMMENTS 4 +#define TOK_DEF_COMMENTS 5 +#define TOK_DEF_CPP_COMMENTS 6 +#define ACTION_CPP_COMMENTS 7 +#define CPP_COMMENTS 8 +#define COMMENTS 9 +#define ACTIONS 10 +#define PARSE_ENUM_FILE 11 diff --git a/Tools/CodeTools/Source/Pccts/antlr/mrhoist.c b/Tools/CodeTools/Source/Pccts/antlr/mrhoist.c new file mode 100644 index 0000000000..110bf5996f --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/mrhoist.c @@ -0,0 +1,3030 @@ +/* + * mrhoist.c + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33MR10 + * + */ + +#include + +#include "pcctscfg.h" + +#include "set.h" +#include "syn.h" +#include "hash.h" +#include "generic.h" +#include "dlgdef.h" +#include + +#ifdef __USE_PROTOS +void dumppred(Predicate *); +#else +void dumppred(); +#endif + +/* + Try to determine whether predicate "first" is true for + all cases where "second" is true. Comparison takes place + without regard to context. + Assumes that predicate symbols have been expanded. + Assumes that there are no NAND or NOR nodes + +*/ + +#ifdef __USE_PROTOS +int MR_secondPredicateUnreachable(Predicate *first,Predicate *second) +#else +int MR_secondPredicateUnreachable(first,second) + Predicate *first; + Predicate *second; +#endif +{ + Predicate *f; + Predicate *s; + + if (first == NULL) { + return 1; + } else if (second == NULL) { + return 0; + } else if (first->down == NULL && second->down == NULL) { + if (first->source == second->source && + first->inverted == second->inverted) { + return 1; /* look identical - will never reach alt2 */ + } else { + return 0; /* look different */ + }; + } else if (first->down == NULL && second->down != NULL) { + + if (second->expr == PRED_AND_LIST) { + + /* unreachable if first covers any child of second */ + + for (s=second->down; s != NULL; s=s->right) { + if (MR_secondPredicateUnreachable(first,s)) { + return 1; + }; + }; + return 0; + } else if (second->expr == PRED_OR_LIST) { + + /* unreachable if first covers every child of second */ + + for (s=second->down; s != NULL; s=s->right) { + if (!MR_secondPredicateUnreachable(first,s)) { + return 0; + }; + }; + return 1; + } else { + require (0,"Illegal pred->expr"); + return 0; /* MR20 Make compiler happy */ + }; + } else if (first->down != NULL && second->down == NULL) { + if (first->expr == PRED_AND_LIST) { + + /* unreachable if every child of first covers second */ + + for (f=first->down; f != NULL; f=f->right) { + if (!MR_secondPredicateUnreachable(f,second)) { + return 0; + }; + }; + return 1; + } else if (first->expr == PRED_OR_LIST) { + + /* unreachable if any child of first covers second */ + + for (f=first->down; f != NULL; f=f->right) { + if (MR_secondPredicateUnreachable(f,second)) { + return 1; + }; + }; + return 0; + } else { + require (0,"Illegal predicate->expr"); + return 0; /* MR20 Make compiler happy */ + }; + } else { + + if (first->expr == PRED_AND_LIST && second->expr == PRED_AND_LIST) { + + /* unreachable if each child of first covers at least one child of second */ + + for (f=first->down; f != NULL ; f=f->right) { + for (s=second->down; s != NULL ; s=s->right) { + if (MR_secondPredicateUnreachable(f,s)) goto A_next_f; + }; + return 0; +A_next_f: + continue; + }; + return 1; + + } else if (first->expr == PRED_AND_LIST && second->expr == PRED_OR_LIST) { + + /* unreachable if each child of first covers ALL of second's children */ + + for (f=first->down; f != NULL ; f=f->right) { + for (s=second->down; s != NULL ; s=s->right) { + if (!MR_secondPredicateUnreachable(f,s)) return 0; + }; + }; + return 1; + + } else if (first->expr == PRED_OR_LIST && second->expr == PRED_AND_LIST) { + + /* unreachable if any child of second is covered by any child of first */ + + for (f=first->down; f != NULL ; f=f->right) { + for (s=second->down; s != NULL ; s=s->right) { + if (MR_secondPredicateUnreachable(f,s)) return 1; + }; + }; + return 0; + + } else if (first->expr == PRED_OR_LIST && second->expr == PRED_OR_LIST) { + + /* unreachable if every child of second is covered by some child of first */ + + for (f=first->down; f != NULL ; f=f->right) { + for (s=second->down; s != NULL ; s=s->right) { + if (MR_secondPredicateUnreachable(f,s)) goto B_next_f; + }; + return 0; +B_next_f: + continue; + }; + return 1; + + } else { + require (0,"Illegal predicate->expr"); + return 0; /* MR20 Make compiler happy */ + }; + }; + return 0; /* MR20 MSVC 5.0 complains about missing return statement */ +} + +#ifdef __USE_PROTOS +void MR_xxxIndent(FILE *f,int depth) +#else +void MR_xxxIndent(f,depth) + FILE *f; + int depth; +#endif +{ + int i; + + for (i=0; irname,rrn->line,FileStr[rrn->file],rrn->text); + }; + lastOne=MR_ruleReferenced(rrn); + if (lastOne != NULL) { + for (j=0; jrname,lastOne->line,FileStr[lastOne->file]); + }; +} + +#ifdef __USE_PROTOS +void MR_dumpTreeF(FILE *f,int depth,Tree *tree,int across) +#else +void MR_dumpTreeF(f,depth,tree,across) + FILE *f; + Tree *tree; + int depth; + int across; +#endif +{ + int newAcross=across; + + if (tree == NULL ) return; + if (tree->down != NULL ) { + fprintf(output,"\n"); + MR_outputIndent(depth); + fprintf(output, "(root ="); + }; + if (tree->token == ALT ) { + fprintf(output," %-16s","Alt"); + } else if (tree->token==EpToken ) { + fprintf(output,"(%d)%13s",tree->v.rk," "); + } else { + fprintf(output," %-16s",TerminalString(tree->token)); + }; + if (tree->down != NULL) { + fprintf(output,"\n"); + MR_outputIndent(depth+1); + MR_dumpTreeF(f,depth+1,tree->down,1); + newAcross=0; + fprintf(output,"\n"); + MR_outputIndent(depth); + fprintf(output,")"); + }; + if (newAcross > 3) { + fprintf(output,"\n"); + MR_outputIndent(depth); + newAcross=0; + }; + MR_dumpTreeF(f,depth,tree->right,newAcross+1); +} + +#ifdef __USE_PROTOS +void MR_dumpTreeX(int depth,Tree *tree,int across) +#else +void MR_dumpTreeX(depth,tree,across) + Tree *tree; + int depth; + int across; +#endif +{ + MR_dumpTreeF(output,depth,tree,across); +} + +#ifdef __USE_PROTOS +void MR_dumpTokenSet(FILE *f,int depth,set s) +#else +void MR_dumpTokenSet(f,depth,s) + FILE *f; + int depth; + set s; +#endif +{ + int i; + int j; + + unsigned *pdq; + + if (set_nil(s)) { + fprintf(f,"\n"); + MR_xxxIndent(f,depth+1); + fprintf(f,"nil\n"); + return; + }; + + pdq=set_pdq(s); + require(pdq != NULL,"set_pdq failed"); + i=0; + for (i=0 ; ; i=i+4) { + fprintf(f,"\n"); + MR_xxxIndent(f,depth+1); + for (j=0; j < 4 ; j++) { + if (pdq[i+j] == nil) break; + fprintf(f," %-16s",TerminalString(pdq[i+j])); + }; + if (pdq[i+j] == nil) break; + }; + fprintf(f,"\n"); + free( (char *) pdq); +} + +#ifdef __USE_PROTOS +void MR_dumpPred1(int depth,Predicate *p,int withContext) +#else +void MR_dumpPred1(depth,p,withContext) + int depth; + Predicate *p; + int withContext; +#endif +{ + unsigned k; + + if (p == NULL) { + MR_outputIndent(depth); + fprintf(output,"The predicate is empty (or always true)\n\n"); + return; + }; + if (p->down != NULL) { + MR_outputIndent(depth); + if (p->inverted) { + + /* MR14a Left out print expression in fprintf + Reported by Manuel Kessler (mlkessle@cip.physik.uni-wuerzburg.de) + */ + + if (p->expr == PRED_AND_LIST) fprintf(output,"%s NAND (not AND) expr\n\n",p->expr); + if (p->expr == PRED_OR_LIST) fprintf(output,"%s NOR (not OR) expr\n\n",p->expr); + } else { + fprintf(output,"%s expr\n\n",p->expr); + }; + } else { + MR_outputIndent(depth); + fprintf(output,"pred %s <<%s>>?\n", + (p->inverted ? " *not*" : ""), + (p->expr == NULL ? "null expr" : p->expr)); + MR_outputIndent(depth+1); + fprintf(output," "); + fprintf(output," depth=k=%d",p->k); + if (p->source != NULL && p->source->guardpred) { + fprintf(output," (\"=>\" guard)"); + } + if (p->source != NULL && p->source->ampersandPred != NULL) { + fprintf(output," (\"&&\" guard)"); + }; + k=set_int(p->completionSet); + if (k != nil) { + fprintf(output," Incomplete Set at k=%d !",k); + }; + k=set_int(p->completionTree); + if (k != nil) { + fprintf(output," Incomplete Tree at k=%d !",k); + }; + if (p->source != NULL) { + fprintf(output," rule %s line %d %s", + p->source->rname,p->source->line,FileStr[p->source->file]); + }; + fprintf(output,"\n"); + if (withContext && + (HoistPredicateContext || + ! set_nil(p->scontext[1]) || + p->tcontext != NULL)) { + if (p->k == 1) { + MR_outputIndent(depth+1); + fprintf(output,"set context: "); + MR_dumpTokenSet(output,depth+1,p->scontext[1]); + } + if (p->k != 1) { + MR_outputIndent(depth+1); + fprintf(output,"tree context:"); + if (p->tcontext == NULL) { + fprintf(output," null"); + } else { + MR_dumpTreeX(depth+2,p->tcontext,0); + }; + fprintf(output,"\n"); + }; + }; + fprintf(output,"\n"); + }; + if (p->down != NULL) { + MR_dumpPred1(depth+1,p->down,withContext); + }; + if (p->right != NULL) { + MR_dumpPred1(depth,p->right,withContext); + }; +} + +#ifdef __USE_PROTOS +void MR_dumpPred(Predicate *p,int withContext) +#else +void MR_dumpPred(p,withContext) + Predicate *p; + int withContext; +#endif +{ + MR_dumpPred1(0,p,withContext); +} + +#ifdef __USE_PROTOS +Tree * MR_make_tree_from_set(set s) +#else +Tree * MR_make_tree_from_set(s) + set s; +#endif +{ + Tree *t=NULL; + Tree *node; + Tree **tp=&t; + int i; + + unsigned *pdq=set_pdq(s); + + if (pdq != NULL) { + for (i=0 ; pdq[i] != nil ; i++) { + node=tnode( (int) pdq[i]); + *tp=node; + tp=&(node->right); + }; + *tp=NULL; + free ( (char *) pdq); + }; + return t; +} + +#ifdef __USE_PROTOS +void MR_check_pred_too_long(Predicate *p,set completion) +#else +void MR_check_pred_too_long(p,completion) + Predicate *p; + set completion; +#endif +{ + if (p != NULL && + p->source != NULL && + ! p->source->predTooLong) { + if ( !set_nil(completion)) { + p->source->predTooLong=1; +warnFL("It is unusual (but ok) for a semantic predicate to test context past the end of its own rule", + FileStr[p->source->file],p->source->line); + }; + }; +} + +#ifdef __USE_PROTOS +int MR_predicate_context_completed(Predicate *p) +#else +int MR_predicate_context_completed(p) + Predicate *p; +#endif +{ + if (p == NULL) return 1; + if (p->expr != PRED_AND_LIST && + p->expr != PRED_OR_LIST) { + if ( ! set_nil(p->completionSet)) return 0; + if ( ! set_nil(p->completionTree)) return 0; + }; + return MR_predicate_context_completed(p->down) & + MR_predicate_context_completed(p->right); +} + +#ifdef __USE_PROTOS +Node * MR_advance(Node *n) +#else +Node * MR_advance(n) + Node *n; +#endif +{ + if (n == NULL) return NULL; + switch (n->ntype) { + case nJunction: return ((Junction *)n)->p1; + case nToken: return ((TokNode *)n)->next; + case nRuleRef: return ((RuleRefNode *)n)->next; + case nAction: return ((ActionNode *)n)->next; + default: return NULL; + }; + return NULL; /* MSVC 5.0 complains about missing return statement */ +} + +#ifdef __USE_PROTOS +Junction * MR_find_endRule(Node *n) +#else +Junction * MR_find_endRule(n) + Node *n; +#endif +{ + Node *next; + if (n == NULL) return NULL; + for (next=n; next != NULL; next=MR_advance(next)) { + if (next->ntype == nJunction && + ( (Junction *) next)->jtype == EndRule) { + break; + }; + }; + return (Junction *)next; +} + +/* + Intersection: a branch which is shorter is chosen + over one which is longer: (A B C) intersect (A B) yields (A B). + + AND: a branch which is longer is chosen over the one + which is shorter: (A B C) AND (A B) yields (A B C) + +*/ + +#ifdef __USE_PROTOS +Tree *MR_computeTreeIntersection(Tree *l,Tree *r) +#else +Tree *MR_computeTreeIntersection(l,r) + Tree *l; + Tree *r; +#endif +{ + Tree *result=NULL; + Tree **tail; + Tree *p; + Tree *q; + Tree *match; + + if (l == NULL || r == NULL) return NULL; + for (p=l; p != NULL; p=p->right) { + require(p->token != EpToken,"MR_computeTreeIntersection: p->EpToken unexpected\n"); + require (p->token != ALT,"MR_computeTreeIntersection: p->ALT unexpected\n"); + }; + for (q=r; q != NULL; q=q->right) { + require(q->token != EpToken,"MR_computeTreeIntersection: q->EpToken unexpected\n"); + require(q->token != ALT,"MR_computeTreeIntersection: q->ALT unexpected\n"); + }; + + result=tnode(ALT); + tail=&(result->down); + + for (p=l; p != NULL ; p=p->right) { + for (q=r; q != NULL ; q=q->right) { + if (p->token == q->token) { + match=tnode(p->token); + match->down=MR_computeTreeIntersection(p->down,q->down); + *tail=match; + tail=&(match->right); + }; + }; + }; + + *tail=NULL; + result=tshrink(result); + result=tflatten( result ); + result=tleft_factor( result ); + return result; +} + +/* the predicates which are ANDed together have a common + context: they must all have common roots. Thus the + AND operation is more like an OR operation because + branches which are longer are grafted onto shorter + branches of the AND tree. For instance combining + (A B C) with (A B C D) gives (A B C D). There + should never be a case of (A B C) and (A B D) because + they have the same context. + + Actually, this may not be true once one throws in + guard predicates which are defined by the user, not + the context. +*/ + +/* requires input trees to be in "canonical" format */ + +#ifdef __USE_PROTOS +Tree *MR_computeTreeAND(Tree *l,Tree *r) +#else +Tree *MR_computeTreeAND(l,r) + Tree *l; + Tree *r; +#endif +{ + Tree *result=NULL; + Tree **tail; + Tree *p; + Tree *q; + Tree *match; + + if (l == NULL) return tdup(r); + if (r == NULL) return tdup(l); + + for (p=l; p != NULL; p=p->right) { +/**** require(p->token != EpToken,"MR_computeTreeAND: p->EpToken unexpected\n"); ****/ + require (p->token != ALT,"MR_computeTreeAND: p->ALT unexpected\n"); + }; + for (q=r; q != NULL; q=q->right) { +/**** require(q->token != EpToken,"MR_computeTreeAND: q->EpToken unexpected\n"); ****/ + require(q->token != ALT,"MR_computeTreeAND: q->ALT unexpected\n"); + }; + + result=tnode(ALT); + tail=&(result->down); + + for (p=l; p != NULL ; p=p->right) { + for (q=r; q != NULL ; q=q->right) { + if (p->token == q->token) { + match=tnode(p->token); + match->down=MR_computeTreeAND(p->down,q->down); + *tail=match; + tail=&(match->right); + }; + }; + }; + + *tail=NULL; + result=tshrink(result); + result=tflatten( result ); + result=tleft_factor( result ); + return result; +} + +#ifdef __USE_PROTOS +void MR_union_plain_sets1(Predicate *p,set *theUnion) +#else +void MR_union_plain_sets1(p,theUnion) + Predicate *p; + set *theUnion; +#endif +{ + if (p == NULL) return; + MR_union_plain_sets1(p->down,theUnion); + MR_union_plain_sets1(p->right,theUnion); + set_orin(theUnion,p->plainSet); + return; +} + +#ifdef __USE_PROTOS +set MR_union_plain_sets(Predicate *p) +#else +set MR_union_plain_sets(p) + Predicate *p; +#endif +{ + set theUnion; + + theUnion=empty; + + MR_union_plain_sets1(p,&theUnion); + return theUnion; +} + +/* does NOT left factor: do not want to merge + (A B) with (A) to get (A B) + in fact the opposite: (A B) with (A) gives (A) +*/ + +#ifdef __USE_PROTOS +Tree *MR_compute_pred_tree_ctxXX(Predicate *p) +#else +Tree *MR_compute_pred_tree_ctxXX(p) + Predicate *p; +#endif +{ + Tree *result=NULL; + Predicate *q; + Tree *t; + + if (p == NULL) return NULL; + +/* this appears strange: why do we OR the context + of and AND predicate ? It is because of the way + that predicates are evaluated: if the context is + wrong then it's the same as if the predicate was + true. That means that even when one leg of an + AND has unmatched context, if the other leg has + matched context and is true then the predicate + succeeds. It's only when all the legs have unmatched + context that this one can skip evaluation of the + predicates. +*/ + if (p->expr == PRED_OR_LIST || + p->expr == PRED_AND_LIST) { + for (q=p->down; q != NULL ; q=q->right) { + t=MR_compute_pred_tree_ctxXX(q); + result=tappend(result,t); + t=NULL; + }; + + result=tshrink(result); + result=tflatten( result ); + +/* does NOT left factor: do not want to merge + (A B) with (A) to get (A B) + in fact the opposite: (A B) with (A) gives (A) +*/ + +/**** result=tleft_factor( result ); ****/ + return result; + }; + +#if 0 +** if (p->expr == PRED_AND_LIST) { +** +** Predicate *l; +** Predicate *r; +** Tree *l1; +** Tree *r1; +** Tree *prevl1; +** +** l=p->down; +** require (l->right != NULL,"MR_compute_pred_tree - AND has only one child"); +** +**/* l1 and r1 should already be in "canonical" format */ +** +** l1=MR_compute_pred_tree(l); +** for (r=l->right; r != NULL; r=r->right) { +** r1=MR_compute_pred_tree(r); +** prevl1=l1; +** l1=MR_computeTreeAND(l1,r1); +** Tfree(r1); +** Tfree(prevl1); +** }; +** +**/* result from computeTreeAND should be in "canonical" format */ +** +** result=l1; +** +**/* result of MR_computeTreeAND should be in "canonical" format */ +** +** return result; +** }; +#endif + + if (p->k == 1) { + result=MR_make_tree_from_set(p->scontext[1]); + } else { + result=tdup(p->tcontext); + result=MR_remove_epsilon_from_tree(result); + result=tshrink(result); + result=tflatten(result); + result=tleft_factor(result); + }; + return result; +} + +#ifdef __USE_PROTOS +void MR_pred_depth(Predicate *p,int *maxDepth) +#else +void MR_pred_depth(p,maxDepth) + Predicate *p; + int *maxDepth; +#endif +{ + if (p == NULL) return; + if (p->expr != PRED_OR_LIST && + p->expr != PRED_AND_LIST) { + if (p->k > *maxDepth) *maxDepth=p->k; + }; + MR_pred_depth(p->down,maxDepth); + MR_pred_depth(p->right,maxDepth); +} + +/* this computes the OR of all the contexts */ + +#ifdef __USE_PROTOS +set MR_compute_pred_set(Predicate *p) +#else +set MR_compute_pred_set(p) + Predicate *p; +#endif +{ + set result; + Predicate *q; + + result=empty; + + if (p == NULL) return empty; + + if (p->expr == PRED_OR_LIST || + p->expr == PRED_AND_LIST) { /* yes, I do mean PRED_AND_LIST ! */ + /* remember: r1: (A)? => <

>? r2; */ + /* r2: (B)? => <>? r3; */ + set t; + + t=empty; + result=empty; + + for (q=p->down; q != NULL; q=q->right) { + t=MR_compute_pred_set(q); + set_orin(&result,t); + set_free(t); + }; + return result; + } else if (p->k > 1) { + return empty; + } else { + return set_dup(p->scontext[1]); + }; +} + +#ifdef __USE_PROTOS +set MR_First(int ck,Junction *j,set *incomplete) +#else +set MR_First(ck,j,incomplete) + int ck; + Junction *j; + set *incomplete; +#endif +{ + Junction *p; + set tokensUsed; + + tokensUsed=empty; + + require(j->ntype==nJunction, "MR_First: non junction passed"); + + p = analysis_point((Junction *)j->p1); + + REACH(p,ck,incomplete,tokensUsed); + + return tokensUsed; +} + +#ifdef __USE_PROTOS +void MR_cleanup_pred_trees(Predicate *p) +#else +void MR_cleanup_pred_trees(p) + Predicate *p; +#endif +{ + Tree *t; + + if (p == NULL) return; + if (p->expr != PRED_OR_LIST && + p->expr != PRED_AND_LIST) { + t=p->tcontext; + t=tshrink(t); + t=tflatten(t); + t=tleft_factor(t); + p->tcontext=t; + }; + MR_cleanup_pred_trees(p->down); + MR_cleanup_pred_trees(p->right); +} + +/* does NOT return canonical tree */ + +#ifdef __USE_PROTOS +Tree * MR_remove_epsilon_from_tree(Tree *t) +#else +Tree * MR_remove_epsilon_from_tree(t) + Tree *t; +#endif +{ + if (t == NULL) return NULL; + + /* I think ALT can be ignored as a special case */ + + if (t->token != EpToken) { + t->down=MR_remove_epsilon_from_tree(t->down); + t->right=MR_remove_epsilon_from_tree(t->right); + return t; + } else { + Tree *u; + u=MR_remove_epsilon_from_tree(t->right); + t->right=NULL; + Tfree(t); + return u; + }; +} + +#ifdef __USE_PROTOS +void MR_complete_set(int predDepth,set *tokensUsed,set *incomplete) +#else +void MR_complete_set(predDepth,tokensUsed,incomplete) + int predDepth; + set *tokensUsed; + set *incomplete; +#endif +{ + int i; + RuleRefNode *ruleRef; + set rk2; + set b; + int k2; + Junction *save_MR_RuleBlkWithHalt; + + if (set_int(*incomplete) > (unsigned) predDepth) { + return; + }; + + require(MR_PredRuleRefStack.count == MR_RuleBlkWithHaltStack.count, + "RuleRefStack and RuleBlkWithHaltStack not same size"); + + require(MR_RuleBlkWithHalt == NULL || + (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == TRUE), + "RuleBlkWithHalt has no halt set"); + + save_MR_RuleBlkWithHalt=MR_RuleBlkWithHalt; + + if (MR_RuleBlkWithHalt != NULL) { + MR_RuleBlkWithHalt->end->halt=FALSE; + }; + + for (i=MR_PredRuleRefStack.count-1; i >= 0 ; i--) { + ruleRef=(RuleRefNode *)MR_PredRuleRefStack.data[i]; + if (ruleRef == NULL) continue; + + MR_RuleBlkWithHalt=(Junction *)MR_RuleBlkWithHaltStack.data[i]; + if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=TRUE; + + rk2=empty; + b=empty; + + while ( !set_nil(*incomplete) ) { + k2=set_int(*incomplete); + if (k2 > predDepth) break; /* <=== another exit from loop */ + set_rm(k2,*incomplete); + REACH(ruleRef->next,k2,&rk2,b); + set_orin(tokensUsed,b); + set_free(b); + }; + + if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=FALSE; + + set_orin(incomplete,rk2); /* remember what we couldn't do */ + set_free(rk2); + if (set_int(*incomplete) > (unsigned) predDepth) break; /* <=== another exit from loop */ + }; + + MR_RuleBlkWithHalt=save_MR_RuleBlkWithHalt; + if (MR_RuleBlkWithHalt != NULL) { + MR_RuleBlkWithHalt->end->halt=TRUE; + }; +} + +#ifdef __USE_PROTOS +void MR_complete_tree(int predDepth,Tree **t,set *incomplete) +#else +void MR_complete_tree(predDepth,t,incomplete) + int predDepth; + Tree **t; + set *incomplete; +#endif +{ + int i; + RuleRefNode *ruleRef; + set rk2; + Tree *u; + unsigned k2; + Junction *save_MR_RuleBlkWithHalt; + int saveConstrainSearch; + + if (set_int(*incomplete) > (unsigned) predDepth) { + return; + }; + + require(MR_PredRuleRefStack.count == MR_RuleBlkWithHaltStack.count, + "RuleRefStack and RuleBlkWithHaltStack not same size"); + + require(MR_RuleBlkWithHalt == NULL || + (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == TRUE), + "RuleBlkWithHalt has no halt set"); + + save_MR_RuleBlkWithHalt=MR_RuleBlkWithHalt; + saveConstrainSearch=ConstrainSearch; + ConstrainSearch=0; + + if (MR_RuleBlkWithHalt != NULL) { + MR_RuleBlkWithHalt->end->halt=FALSE; + }; + + for (i=MR_PredRuleRefStack.count-1; i >= 0 ; i--) { + ruleRef=(RuleRefNode *)MR_PredRuleRefStack.data[i]; + if (ruleRef == NULL) continue; + + MR_RuleBlkWithHalt=(Junction *)MR_RuleBlkWithHaltStack.data[i]; + + if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=TRUE; + + rk2=empty; + + while ( !set_nil(*incomplete) ) { + k2 = set_int(*incomplete); + if (k2 > (unsigned) predDepth) break; /* <=== another exit from loop */ + set_rm(k2,*incomplete); + u = NULL; + + TRAV(ruleRef->next,k2,&rk2,u); + + /* any subtrees missing k2 tokens, add u onto end */ + + *t=tlink(*t,u,k2); + Tfree(u); + } + + set_orin(incomplete,rk2); /* remember what we couldn't do */ + set_free(rk2); + + if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=FALSE; + + if (set_int(*incomplete) > (unsigned) predDepth) break; /* <=== another exit from loop */ + }; + + MR_RuleBlkWithHalt=save_MR_RuleBlkWithHalt; + + if (MR_RuleBlkWithHalt != NULL) { + MR_RuleBlkWithHalt->end->halt=TRUE; + }; + ConstrainSearch=saveConstrainSearch; +} + +#ifdef __USE_PROTOS +void MR_complete_predicates(int predDepth,Predicate *pred) +#else +void MR_complete_predicates(predDepth,pred) + int predDepth; + Predicate *pred; +#endif +{ + if (pred == NULL) return; + if (pred->expr != PRED_AND_LIST && + pred->expr != PRED_OR_LIST) { + MR_complete_set(predDepth,&(pred->scontext[1]),&(pred->completionSet)); + MR_complete_tree(predDepth,&(pred->tcontext),&(pred->completionTree)); + }; + MR_complete_predicates(predDepth,pred->down); + MR_complete_predicates(predDepth,pred->right); +} + +#ifdef __USE_PROTOS +Junction * MR_junctionWithoutP2(Junction *j) +#else +Junction * MR_junctionWithoutP2(j) + Junction *j; +#endif +{ + Junction *thisAlt; + +/* don't want to follow p2 to the next alternative of this rule */ +/* insert a generic node with null p2 if necessary */ +/* however FIRST requires a junction */ + + thisAlt=j; + if (thisAlt->p2 != NULL) { + if (thisAlt->p1->ntype == nJunction) { + thisAlt=(Junction *) thisAlt->p1; + } else { + thisAlt=newJunction(); + thisAlt->p1=j->p1; + thisAlt->rname=j->rname; + thisAlt->file=j->file; + thisAlt->line=j->line; + j->p1=(Node *)thisAlt; + }; + }; + return thisAlt; +} + +#ifdef __USE_PROTOS +int MR_tree_equ(Tree *big, Tree *small) { +#else +int MR_tree_equ(big,small) + Tree *big; + Tree *small; +{ +#endif + + Tree *b; + Tree *s; + int bcount=0; + int scount=0; + + if (small == NULL && big == NULL) return 1; + if (small == NULL) return 0; + if (big == NULL) return 0; + + if (small->token == ALT) { + require(small->right == NULL, + "MR_tree_equ: small: ALT node has siblings"); + return MR_tree_equ(big,small->down); + }; + if (big->token == ALT) { + require(big->right == NULL, + "MR_tree_equ: big: ALT node has siblings"); + return MR_tree_equ(big->down,small); + }; + for (s=small; s != NULL; s=s->right) { + scount++; + require(s->token != EpToken,"MR_tree_equ: s->EpToken unexpected\n"); + }; + for (b=big; b != NULL; b=b->right) { + bcount++; + require(b->token != EpToken,"MR_tree_equ: b->EpToken unexpected\n"); + }; + + if (bcount != scount) return 0; + + for (s=small; s != NULL; s=s->right) { + for (b=big; b!= NULL; b=b->right) { + if (s->token == b->token) { + if (MR_tree_equ(b->down,s->down)) goto next_s; + }; + }; + return 0; +next_s: + continue; + }; + return 1; +} + +/* this does not compare sources - only contexts ! */ + +#ifdef __USE_PROTOS +int MR_identicalContext(Predicate *p,Predicate *q) +#else +int MR_identicalContext(p,q) + Predicate *p; + Predicate *q; +#endif +{ + if (p->k != q->k) return 0; + require ( (p->tcontext == NULL) == (q->tcontext == NULL), + "tcontext inconsistent"); + if (p->k == 1) { + return set_equ(p->scontext[1],q->scontext[1]); + } else { + return MR_tree_equ(p->tcontext,q->tcontext); + }; +} + +#ifdef __USE_PROTOS +void MR_reportSetSuppression(int predDepth, + set predSet,set plainSet,Junction *jPred,Junction *jPlain,Predicate *p) +#else +void MR_reportSetSuppression(predDepth,predSet,plainSet,jPred,jPlain,p) + int predDepth; + set predSet; + set plainSet; + Junction *jPred; + Junction *jPlain; + Predicate *p; +#endif +{ + if (InfoP) { + fprintf(output,"\n#if 0\n\n"); + fprintf(output,"Hoisting of predicate suppressed by alternative without predicate.\n"); + fprintf(output,"The alt without the predicate includes all cases where the predicate is false.\n\n"); + fprintf(output," WITH predicate: line %d %s\n",jPred->line,FileStr[jPred->file]); + if (jPlain != NULL) { + fprintf(output," WITHOUT predicate: line %d %s\n",jPlain->line,FileStr[jPlain->file]); + } else { + fprintf(output," WITHOUT predicate: all alternatives without predicates (combined)\n"); + }; + if (predDepth == 1) { + fprintf(output,"\nThe context set for the predicate:\n"); + MR_dumpTokenSet(output,1,predSet); + }; + fprintf(output,"\nThe lookahead set for the alt WITHOUT the semantic predicate:\n"); + MR_dumpTokenSet(output,1,plainSet); + fprintf(output,"\nThe predicate:\n\n"); + MR_dumpPred1(1,p,1); + fprintf(output,"Chain of referenced rules:\n\n"); + MR_dumpPredRuleRefStack(output,4); + fprintf(output,"\n#endif\n"); + }; +} + +#ifdef __USE_PROTOS +void MR_reportSetRestriction(int predDepth,set predSet,set plainSet, + Junction *jPred,Junction *jPlain,Predicate *origPred,Predicate *newPred) +#else +void MR_reportSetRestriction(predDepth,predSet,plainSet,jPred,jPlain,origPred,newPred) + int predDepth; + set predSet; + set plainSet; + Junction *jPred; + Junction *jPlain; + Predicate *origPred; + Predicate *newPred; +#endif +{ + set intersect; + + intersect=empty; + + if (! InfoP) return; + fprintf(output,"\n#if 0\n\n"); + fprintf(output,"Restricting the context of a predicate because of overlap in the lookahead set\n"); + fprintf(output," between the alternative with the semantic predicate and one without\n"); + fprintf(output,"Without this restriction the alternative without the predicate could not\n"); + fprintf(output," be reached when input matched the context of the predicate and the predicate\n"); + fprintf(output," was false.\n\n"); + + fprintf(output," WITH predicate: line %d %s\n",jPred->line,FileStr[jPred->file]); + if (jPlain != NULL) { + fprintf(output," WITHOUT predicate: line %d %s\n",jPlain->line,FileStr[jPlain->file]); + } else { + fprintf(output," WITHOUT predicate: all alternatives without predicates (combined)\n"); + }; + if (predDepth == 1) { + fprintf(output,"\nThe original context set for the predicate:\n"); + MR_dumpTokenSet(output,1,predSet); + }; + fprintf(output,"\nThe lookahead set for the alt WITHOUT the semantic predicate:\n"); + MR_dumpTokenSet(output,1,plainSet); + if (predDepth == 1) { + fprintf(output,"\nThe intersection of the two sets\n"); + intersect=set_and(predSet,plainSet); + MR_dumpTokenSet(output,1,intersect); + set_free(intersect); + }; + fprintf(output,"\nThe original predicate:\n\n"); + MR_dumpPred1(1,origPred,1); + fprintf(output,"The new (modified) form of the predicate:\n\n"); + MR_dumpPred1(1,newPred,1); + fprintf(output,"#endif\n"); +} + +/* don't use Pass3 by itself unless you know that inverted is not important */ + +#ifdef __USE_PROTOS +Predicate * MR_removeRedundantPredPass3(Predicate *p) +#else +Predicate * MR_removeRedundantPredPass3(p) + Predicate *p; +#endif +{ + Predicate *q; + + if (p == NULL) return NULL; + p->right=MR_removeRedundantPredPass3(p->right); + p->down=MR_removeRedundantPredPass3(p->down); + if (p->redundant) { + q=p->right; + p->right=NULL; + predicate_free(p); + return q; + }; + if (p->expr == PRED_AND_LIST || + p->expr == PRED_OR_LIST) { + if (p->down == NULL) { + q=p->right; + p->right=NULL; + predicate_free(p); + return q; + }; + if (p->down != NULL && p->down->right == NULL) { + q=p->down; + q->right=p->right; + p->right=NULL; + p->down=NULL; + return q; + }; + }; + return p; +} + +#ifdef __USE_PROTOS +void MR_removeRedundantPredPass2(Predicate *p) +#else +void MR_removeRedundantPredPass2(p) + Predicate *p; +#endif +{ + Predicate *q; + + if (p == NULL) return; + + if (p->expr == PRED_AND_LIST) { + for (q=p->down ; q != NULL ; q=q->right) { + MR_removeRedundantPredPass2(q); + if (q->isConst) { + if (q->constValue == 0) { + p->isConst=1; + p->constValue=0; + return; + } else { + q->redundant=1; + }; + }; + }; + }; + + if (p->expr == PRED_OR_LIST) { + for (q=p->down ; q != NULL ; q=q->right) { + MR_removeRedundantPredPass2(q); + if (q->isConst) { + if (q->constValue == 0) { + q->redundant=1; + } else { + p->isConst=1; + p->constValue=1; + return; + }; + }; + }; + }; + + return; +} + +#if 0 + this totally ignores the implications of guarded predicates + in which the part after the guard could possibly cover a predicate. + that would be much harder: + + rule : (A)? => <

>? sub1; /* 1 */ + | (B)? => <>? sub2 /* 2 */ + sub1 : (A)? => <>? A B /* 3 */ + | B /* 4 - suppresses line 2 */ + ; +#endif + +#ifdef __USE_PROTOS +void MR_apply_restriction1(Predicate *pred,set *plainSet,int *changed) +#else +void MR_apply_restriction1(pred,plainSet,changed) + Predicate *pred; + set *plainSet; + int *changed; +#endif +{ + if (pred == NULL) return; + MR_apply_restriction1(pred->right,plainSet,changed); + if (pred->down != NULL) { + MR_apply_restriction1(pred->down,plainSet,changed); + } else { + set t; + if (pred->k == 1) { + t=set_dif(pred->scontext[1],*plainSet); + if (*changed == 0 && + !set_equ(t,pred->scontext[1])) { + *changed=1; + }; + if (set_nil(t)) { + pred->redundant=1; + }; + set_free(pred->scontext[1]); + pred->scontext[1]=t; + }; + }; +} + +#ifdef __USE_PROTOS +void MR_orin_plainSet(Predicate *p,set plainSet) +#else +void MR_orin_plainSet(p,plainSet) + Predicate *p; + set plainSet; +#endif +{ + if (p == NULL) return; + MR_orin_plainSet(p->down,plainSet); + MR_orin_plainSet(p->right,plainSet); + set_orin(&p->plainSet,plainSet); +} + +Predicate *PRED_SUPPRESS; + +#ifdef __USE_PROTOS +Predicate * MR_find_in_aSubBlk(Junction *alt) +#else +Predicate * MR_find_in_aSubBlk(alt) + Junction *alt; +#endif +{ + Predicate *root=NULL; + Predicate **tail=NULL; + + Junction *p; + + int nAlts=0; + Junction **jList; + Predicate **predList; + int *matchList; + set predSet; + int i; + int j; + int m; + int predDepth; + set incomplete; + set union_plainSet; + set setChange; + int changed; + Predicate *newPred; + set setDif; + Predicate *origPred; + int depth1=1; /* const int */ + set *plainContext; + set plainSet; + + predSet=empty; + incomplete=empty; + union_plainSet=empty; + setChange=empty; + setDif=empty; + plainSet=empty; + + if (PRED_SUPPRESS == NULL) { + PRED_SUPPRESS=new_pred(); + PRED_SUPPRESS->expr="Predicate Suppressed"; + }; + + /* this section just counts the number of "interesting" alternatives */ + /* in order to allocate arrays */ + + for (p=alt; p!=NULL; p=(Junction *)p->p2) { + /* ignore empty alts */ + if ( p->p1->ntype != nJunction || + ((Junction *)p->p1)->jtype != EndBlk ) { + nAlts++; + }; + }; + + /* if this is a (...)+ block then don't count the last alt because + it can't be taken until at least one time through the block. + In other words it isn't a real choice until the (...)+ is entered + at which point the hoisting issue is moot. + Maybe look at "ignore" instead ? + */ + + if (alt->jtype == aPlusBlk) { + nAlts--; + }; + + jList=(Junction **)calloc(nAlts,sizeof(Junction *)); + require(jList!=NULL,"cannot allocate MR_find_in_aSubBlk jList"); + + plainContext=(set *)calloc(nAlts,sizeof(set)); + require(plainContext!=NULL,"cannot allocate MR_find_in_aSubBlk plainContext"); + for (m=0; m < nAlts; m++) plainContext[m]=empty; + + predList=(Predicate **)calloc(nAlts,sizeof(Predicate *)); + require(predList!=NULL,"cannot allocate MR_find_in_aSubBlk predList"); + + matchList=(int *)calloc(nAlts,sizeof(int)); + require(matchList!=NULL,"cannot allocate MR_find_in_aSubBlk matchList"); + + /* this section just fills in the arrays previously allocated */ + /* the most interesting one is matchList[] */ + /* */ + /* bit 0 => this alt has a semantic pred which is "covered" */ + /* by an alt without a semantic pred. Don't hoist. */ + + for (i=0,p=alt; + p!=NULL && ip2) { + + /* ignore empty alts */ + + if ( p->p1->ntype != nJunction || + ((Junction *)p->p1)->jtype != EndBlk ) { + jList[i]=MR_junctionWithoutP2(p); + predList[i]=find_predicates(p->p1); /* should be jList ????? */ + if (predList[i] != NULL) { + MR_cleanup_pred_trees(predList[i]); /* flatten & left factor */ + plainContext[i]=MR_union_plain_sets(predList[i]); + } else { + MR_set_reuse(&plainSet); + MR_set_reuse(&incomplete); + plainSet=MR_First(depth1,jList[i],&incomplete); + MR_complete_set(depth1,&plainSet,&incomplete); + require(set_nil(incomplete),"couldn't complete k=1"); + plainContext[i]=plainSet; + plainSet=empty; + }; + set_orin(&union_plainSet,plainContext[i]); + }; + }; + + if (nAlts == 1) { + goto EXIT_SIMPLE; + }; + +/* + * Looking for cases where alt i has a semantic pred and alt j does not. + * Don't care about cases where lookahead for semantic predicates overlap + * because normal predicate hoisting does the correct thing automatically. + * Don't care about cases where lookahead for alts without semantic predicates + * overlap because normal prediction does the correct thing automatically. + * + * When we find such a case check for one of three subcases: + * + * 1. if lookahead for alt i is contained in the lookahead for any + * alt j then ignore semantic predicate of alt i + * 2. if lookahead for alt i is not contained in the lookahead for + * any alt j then add add predicate i to the OR list to be hoisted + * 3. if lookahead for alt i overlaps the lookahead for some alt j then + * add a dummy semantic predicate for alt j + * + * There is an implicit assumption that the context of all alternatives following + * the rule being processed here are identical (but may vary from hoist to + * hoist depending on the place where the rule was invoked that led to hoisting + * these predicates. In othere words in the fragment: + * + * ( <>? a1 a2 a3 | <>? b1 b2 b3 ) + * + * both a3 and b3 have the same follow sets because they are both at the end of + * alternatives in the same block. + */ + + for (i=0; i < nAlts; i++) { + if (jList[i] == NULL) continue; + if (predList[i] == NULL) continue; + + /* if the predicate depth turns out to be one token only */ + /* then it is can be easily represented as a set and */ + /* compared to the junction set create by MR_First() */ + + predDepth=0; + MR_pred_depth(predList[i],&predDepth); + require (predDepth >= 1,"MR_find_in_aSubBlk: pred depth < 1"); + require (predDepth <= CLL_k,"MR_find_in_aSubBlk: predDepth > CLL_k"); + + /* complete predicates to predDepth + If completed to depth=1 then the context would be incomplete. + The context would be truncated and the predicate simplify routine + would have incomplete information. It would lead to + either false matches of failure to find true matches. + */ + + MR_complete_predicates(predDepth,predList[i]); + + if (predList[i] != NULL) { + MR_cleanup_pred_trees(predList[i]); /* flatten & left factor */ + }; + + /* If the predicate depth is 1 then it is possible to suppress + a predicate completely using a single plain alt. Check for suppression + by a single plain alt first because it gives better messages. If that + fails try the union of all the plain alts. + */ + + if (predDepth == 1) { + + MR_set_reuse(&predSet); + predSet=MR_compute_pred_set(predList[i]); /* ignores k>1 predicates */ + + for (j=0; j < nAlts; j++) { + if (jList[j] == NULL) continue; + if (j == i) continue; + + MR_set_reuse(&setDif); + setDif=set_dif(predSet,plainContext[j]); + if (set_nil(setDif)) { + matchList[i] |= 1; + MR_reportSetSuppression(predDepth,predSet,plainContext[j],jList[i],jList[j],predList[i]); + predicate_free(predList[i]); + predList[i]=PRED_SUPPRESS; + goto next_i; + }; + + }; /* end loop on j */ + + changed=0; + + /* predicate_dup is only to give good error messages */ + /* remember to do a predicate_free() */ + + origPred=predicate_dup(predList[i]); + MR_apply_restriction1(predList[i],&union_plainSet,&changed); + if (changed) { + + /* don't use Pass3 by itself unless you know that inverted is not important */ + + newPred=MR_removeRedundantPredPass3(predList[i]); + newPred=MR_predSimplifyALL(newPred); + if (newPred == NULL) { + matchList[i] |= 1; + MR_reportSetSuppression(predDepth,predSet,union_plainSet,jList[i], + NULL,origPred); + predList[i]=PRED_SUPPRESS; + } else { + MR_reportSetRestriction(predDepth,predSet,union_plainSet,jList[i], + NULL,origPred,newPred); + predList[i]=newPred; + }; + }; + predicate_free(origPred); + origPred=NULL; + }; + + /* + If the predicate depth is > 1 then it can't be suppressed completely + because the code doesn't support inspection of such things. They're + much messier than k=1 sets. + */ + + if (predDepth > 1 ) { + + changed=0; + + /* predicate_dup is only to give good error messages */ + /* remember to do a predicate_free() */ + + origPred=predicate_dup(predList[i]); + MR_apply_restriction1(predList[i],&union_plainSet,&changed); + if (changed) { + newPred=MR_removeRedundantPredPass3(predList[i]); + newPred=MR_predSimplifyALL(newPred); + if (newPred == NULL) { + matchList[i] |= 1; + MR_reportSetSuppression(predDepth,predSet,union_plainSet,jList[i], + NULL,origPred); + predList[i]=PRED_SUPPRESS; + } else { + MR_reportSetRestriction(predDepth,predSet,union_plainSet,jList[i], + NULL,origPred,newPred); + predList[i]=newPred; + }; + }; + predicate_free(origPred); + origPred=NULL; + }; +next_i: + continue; + }; + +EXIT_SIMPLE: + + root = new_pred(); + root->expr=PRED_OR_LIST; + tail = &(root->down); + + for (i=0 ; i< nAlts ; i++) { + if (jList[i] == NULL) continue; + + if (predList[i] == NULL) { + continue; + } else if ( (matchList[i] & 1) != 0) { + if (predList[i] != PRED_SUPPRESS) { + predicate_free(predList[i]); + }; + continue; + }; + + /* make an OR list of predicates */ + + *tail=predList[i]; + tail=&(predList[i]->right); + }; + + /* if just one pred, remove OR root */ + + if (root->down == NULL) { + predicate_free(root); + root=NULL; + } else if (root->down->right == NULL) { + Predicate *p=root->down; + root->down=NULL; + predicate_free(root); + root=p; + } + + root=MR_predSimplifyALL(root); + + MR_orin_plainSet(root,union_plainSet); + + set_free(predSet); + set_free(union_plainSet); + set_free(incomplete); + set_free(setChange); + set_free(setDif); + + for (m=0; m < nAlts; m++) set_free(plainContext[m]); + + free ( (char *) jList); + free ( (char *) predList); + free ( (char *) matchList); + free ( (char *) plainContext); + + return root; +} + +#ifdef __USE_PROTOS +void MR_predContextPresent(Predicate *p,int *allHaveContext,int *noneHaveContext) +#else +void MR_predContextPresent(p,allHaveContext,noneHaveContext) + Predicate *p; + int *allHaveContext; + int *noneHaveContext; +#endif +{ + if (p == NULL) return; + MR_predContextPresent(p->right,allHaveContext,noneHaveContext); + if (p->expr != PRED_AND_LIST && + p->expr != PRED_OR_LIST) { + if (set_nil(p->scontext[1]) == 0 || + (p->tcontext != NULL)) { + *noneHaveContext=0; + } else { + *allHaveContext=0; + }; + }; + MR_predContextPresent(p->down,allHaveContext,noneHaveContext); +} + +#ifdef __USE_PROTOS +int MR_pointerStackPush(PointerStack *ps,void *dataPointer) +#else +int MR_pointerStackPush(ps,dataPointer) + PointerStack *ps; + void *dataPointer; +#endif +{ + void **newStack; + int newSize; + int i; + + if (ps->count == ps->size) { + newSize=20+ps->size*2; + newStack=(void **)calloc(newSize,sizeof(void *)); + require (newStack != NULL,"cannot allocate PointerStack"); + for (i=0; i < ps->size; i++) { + newStack[i]=ps->data[i]; + }; + if (ps->data != NULL) free( (char *) ps->data); + ps->data=newStack; + ps->size=newSize; + }; + ps->data[ps->count]=dataPointer; + ps->count++; + return ps->count-1; +} + +#ifdef __USE_PROTOS +void * MR_pointerStackPop(PointerStack *ps) +#else +void * MR_pointerStackPop(ps) + PointerStack *ps; +#endif +{ + void *dataPointer; + + require(ps->count > 0,"MR_pointerStackPop underflow"); + + dataPointer=ps->data[ps->count-1]; + ps->data[ps->count-1]=NULL; + (ps->count)--; + return dataPointer; +} + +#ifdef __USE_PROTOS +void * MR_pointerStackTop(PointerStack *ps) +#else +void * MR_pointerStackTop(ps) + PointerStack *ps; +#endif +{ + require(ps->count > 0,"MR_pointerStackTop underflow"); + return ps->data[ps->count-1]; +} + +#ifdef __USE_PROTOS +void MR_pointerStackReset(PointerStack *ps) +#else +void MR_pointerStackReset(ps) + PointerStack *ps; +#endif +{ + int i; + if (ps->data != NULL) { + for (i=0; i < ps->count ; i++) { + ps->data[i]=NULL; + }; + }; + ps->count=0; +} + +#ifdef __USE_PROTOS +Junction *MR_nameToRuleBlk(char *name) +#else +Junction *MR_nameToRuleBlk(name) + char *name; +#endif +{ + RuleEntry *q; + + require (RulePtr != NULL,"MR_nameToRule: RulePtr not initialized"); + + if (name == NULL) return NULL; + + q = (RuleEntry *) hash_get(Rname,name); + + if ( q == NULL ) { + return NULL; + } else { + return RulePtr[q->rulenum]; + }; +} + +#ifdef __USE_PROTOS +Junction * MR_ruleReferenced(RuleRefNode *rrn) +#else +Junction * MR_ruleReferenced(rrn) + RuleRefNode *rrn; +#endif +{ + return MR_nameToRuleBlk(rrn->text); +} + +#ifdef __USE_PROTOS +void MR_comparePredLeaves(Predicate *me,Predicate *myParent,Predicate *him,Predicate *hisParent) +#else +void MR_comparePredLeaves(me,myParent,him,hisParent) + Predicate *me; + Predicate *myParent; + Predicate *him; + Predicate *hisParent; +#endif +{ + if (me == NULL) return; + if (me == him) { + MR_comparePredLeaves(me->right,myParent,him,hisParent); + return; + } else if (me->expr == PRED_AND_LIST || + me->expr == PRED_OR_LIST) { + MR_comparePredLeaves(me->down,me,him,hisParent); + MR_comparePredLeaves(me->right,myParent,him,hisParent); + return; + } else { + if (me->source != NULL) { + + /* predicate->invert can be set only in the predEntry predicates */ + /* thus they are only visible after the predEntry predicates have been "unfolded" */ + + int sameSource=(me->source == him->source); + int sameInvert=1 & + (1 + me->inverted + him->inverted + me->source->inverted + him->source->inverted); + int samePredEntry=(me->source->predEntry != NULL + && him->source->predEntry != NULL + && me->source->predEntry == him->source->predEntry); + if (sameInvert && (sameSource || samePredEntry)) { + if (MR_identicalContext(me,him)) { + + /* identical predicates */ + + if (hisParent->expr == PRED_OR_LIST && + myParent->expr == PRED_OR_LIST) { + me->redundant=1; + } else if (hisParent->expr == PRED_AND_LIST && + myParent->expr == PRED_AND_LIST) { + me->redundant=1; + } else if ( (hisParent->expr == PRED_OR_LIST && + myParent->expr == PRED_AND_LIST) + || + (hisParent->expr == PRED_AND_LIST && + myParent->expr == PRED_OR_LIST) + ) { + myParent->redundant=1; + } else { + require (0,"MR_comparePredLeaves: not both PRED_LIST"); + }; + }; + }; /* end same source or same predEntrr with same invert sense */ + + /* same predEntry but opposite invert sense */ + + if (!sameInvert && (sameSource || samePredEntry)) { + if (MR_identicalContext(me,him)) { + if (hisParent->expr == PRED_OR_LIST && + myParent->expr == PRED_OR_LIST) { + myParent->isConst=1; + myParent->constValue=1; + } else if (hisParent->expr == PRED_AND_LIST && + myParent->expr == PRED_AND_LIST) { + myParent->isConst=1; + myParent->constValue=0; + } else if ( (hisParent->expr == PRED_OR_LIST && + myParent->expr == PRED_AND_LIST) + || + (hisParent->expr == PRED_AND_LIST && + myParent->expr == PRED_OR_LIST) + ) { + me->redundant=1; + } else { + require (0,"MR_comparePredLeaves: not both PRED_LIST"); + }; + }; + }; /* end same predEntry with opposite invert sense */ + }; + + MR_comparePredLeaves(me->right,myParent,him,hisParent); + return; + }; +} + +#ifdef __USE_PROTOS +void MR_removeRedundantPredPass1(Predicate *me,Predicate *myParent) +#else +void MR_removeRedundantPredPass1(me,myParent) + Predicate *me; + Predicate *myParent; +#endif +{ + if (me == NULL) return; + if (me->redundant) { + MR_removeRedundantPredPass1(me->right,myParent); + return; + }; + if (me->expr == PRED_AND_LIST || + me->expr == PRED_OR_LIST) { + MR_removeRedundantPredPass1(me->down,me); + MR_removeRedundantPredPass1(me->right,myParent); + } else { + require (me->source != NULL,"me->source == NULL"); + if (myParent != NULL) { + MR_comparePredLeaves(myParent->down,myParent,me,myParent); + }; + MR_removeRedundantPredPass1(me->right,myParent); + }; +} + +/* pretty much ignores things with the inverted bit set */ + +#ifdef __USE_PROTOS +Predicate *MR_predFlatten(Predicate *p) +#else +Predicate *MR_predFlatten(p) + Predicate *p; +#endif +{ + if (p == NULL) return NULL; + if (p->expr == PRED_OR_LIST + || p->expr == PRED_AND_LIST) { + + Predicate *child; + Predicate *gchild; + Predicate **tail; + Predicate *next; + char *PRED_XXX_LIST=p->expr; + + require (p->down != NULL,"MR_predFlatten AND/OR no child"); + + + p->down=MR_predFlatten(p->down); + p->right=MR_predFlatten(p->right); + child=p->down; + if (child->right == NULL) { + child->right=p->right; + p->right=NULL; + p->down=NULL; + if (p->inverted) child->inverted=!child->inverted; + predicate_free(p); + return child; + }; + + /* make a single list of all children and grandchildren */ + + tail=&(p->down); + for (child=p->down; child != NULL; child=next) { + if (child->expr != PRED_XXX_LIST + || child->inverted + || child->predEntry != NULL) { + *tail=child; + tail=&(child->right); + next=child->right; + } else { + for (gchild=child->down; + gchild != NULL; + gchild=gchild->right) { + *tail=gchild; + tail=&(gchild->right); + }; + next=child->right; + child->right=NULL; + child->down=NULL; + predicate_free(child); + }; + }; + *tail=NULL; + return p; + } else { + p->right=MR_predFlatten(p->right); + return p; + }; +} + +static char *alwaysFalseWarning=NULL; + +#ifdef __USE_PROTOS +Predicate *checkPredicateConflict(Predicate *p) +#else +Predicate *checkPredicateConflict(p) + Predicate *p; +#endif +{ + if (p->isConst) { + if (p->constValue == 1) { + predicate_free(p); + return NULL; + } else { + if (InfoP && !p->conflictReported) { + p->conflictReported=1; + fprintf(output,"\n#if 0\n\n"); + fprintf(output,"The following predicate expression will always be false:\n\n"); + MR_dumpPred1(1,p,1); + fprintf(output,"\n#endif\n"); + }; + + if (alwaysFalseWarning != CurRule) { + alwaysFalseWarning=CurRule; + if (InfoP) { + warnNoFL(eMsg1("one (or more) predicate expression hoisted into rule \"%s\" are always false \ +- see output file for more information",CurRule)); + } else { + warnNoFL(eMsg1("one (or more) predicate expressions hoisted into rule \"%s\" are always false \ +- use \"-info p\" for more information",CurRule)); + }; + }; + }; + }; + return p; +} + + +#ifdef __USE_PROTOS +int MR_countPredNodes(Predicate *p) +#else +int MR_countPredNodes(p) + Predicate *p; +#endif +{ + if (p == NULL) return 0; + return 1 + MR_countPredNodes(p->down) + MR_countPredNodes(p->right); +} + +#ifdef __USE_PROTOS +Predicate *MR_predSimplifyALLX(Predicate *p,int skipPass3) +#else +Predicate *MR_predSimplifyALLX(p,skipPass3) + Predicate *p; + int skipPass3; +#endif +{ + int countBefore; + int countAfter; + + countAfter=MR_countPredNodes(p); + + do { + if (p == NULL) return NULL; + if (p->right == NULL && p->down == NULL) return p; + countBefore=countAfter; + MR_simplifyInverted(p,0); + p=MR_predFlatten(p); + MR_removeRedundantPredPass1(p,NULL); + MR_removeRedundantPredPass2(p); + if (! skipPass3) { + p=checkPredicateConflict(p); + p=MR_removeRedundantPredPass3(p); + }; + countAfter=MR_countPredNodes(p); + } while (countBefore != countAfter); + + return p; +} + +#ifdef __USE_PROTOS +Predicate *MR_predSimplifyALL(Predicate *p) +#else +Predicate *MR_predSimplifyALL(p) + Predicate *p; +#endif +{ + return MR_predSimplifyALLX(p,0); +} + +#ifdef __USE_PROTOS +void MR_releaseResourcesUsedInRule(Node *n) +#else +void MR_releaseResourcesUsedInRule(n) + Node *n; +#endif +{ + Node *next; + Junction *j; + int i; + + if (n == NULL) return; + if (n->ntype == nJunction) { + j=(Junction *) n; + + if (j->predicate != NULL) { + predicate_free(j->predicate); + j->predicate=NULL; + }; + for (i=0; i< CLL_k; i++) { + set_free(j->fset[i]); + j->fset[i]=empty; + }; + if (j->ftree != NULL) { + Tfree(j->ftree); + j->ftree=NULL; + }; + if (j->jtype == EndRule) return; + if (j->jtype != RuleBlk && j->jtype != EndBlk) { + if (j->p2 != NULL && !j->ignore) { /* MR11 */ + MR_releaseResourcesUsedInRule(j->p2); + }; + }; + }; + next=MR_advance(n); + MR_releaseResourcesUsedInRule(next); +} + +#ifdef __USE_PROTOS +int MR_allPredLeaves(Predicate *p) +#else +int MR_allPredLeaves(p) + Predicate *p; +#endif +{ + Predicate *q; + + if (p == NULL) return 1; + + for (q=p; q != NULL; q=q->right) { + if (q->down != NULL) return 0; + }; + return 1; +} + +/* make sure it works for the last rule in a file */ + +#ifdef __USE_PROTOS +int MR_offsetFromRule(Node *n) +#else +int MR_offsetFromRule(n) + Node *n; +#endif +{ + Junction *j; + int offset=(-1); + + for (j=SynDiag; j != NULL; j=(Junction *)j->p2) { + + require (j->ntype == nJunction && j->jtype == RuleBlk,"Not a rule block"); + + if (n->file < j->file) { + return offset; + }; + if (n->file == j->file) { + if (n->line < j->line) { + return (offset < 0) ? 0 : offset; + } else { + offset=n->line - j->line; + if (offset == 0) return 0; + }; + }; + }; + return offset; +} + +#define ruleNameMax 50 + +static char ruleNameStatic1[ruleNameMax]; +static char ruleNameStatic2[ruleNameMax+10]; + +#ifdef __USE_PROTOS +char * MR_ruleNamePlusOffset(Node *n) +#else +char * MR_ruleNamePlusOffset(n) + Node *n; +#endif +{ + int offset=MR_offsetFromRule(n); + + strncpy(ruleNameStatic1,n->rname,ruleNameMax); + if (offset < 0) { + sprintf(ruleNameStatic2,"%s/?",ruleNameStatic1); + } else { + sprintf(ruleNameStatic2,"%s/%d",ruleNameStatic1,offset+1); + }; + return ruleNameStatic2; +} + +#ifdef __USE_PROTOS +int MR_max_height_of_tree(Tree *t) +#else +int MR_max_height_of_tree(t) + Tree *t; +#endif +{ + int h; + int height=0; + Tree *u; + + if (t == NULL) return 0; + + require (t->token != ALT && t->token != EpToken,"MR_max_height_of_tree ALT or EpToken"); + + for (u=t; u != NULL; u=u->right) { + h=MR_max_height_of_tree(u->down)+1; + if (h > height) height=h; + }; + return height; +} + +#ifdef __USE_PROTOS +int MR_all_leaves_same_height(Tree *t,int depth) +#else +int MR_all_leaves_same_height(t,depth) + Tree *t; + int depth; +#endif +{ + if (t == NULL) { + return (depth==0); + }; + + require (t->token != ALT && t->token != EpToken,"MR_all_leaves_same_height ALT or EpToken"); + + if (depth == 0) { + return 0; + } else { + if ( ! MR_all_leaves_same_height(t->down,depth-1)) { + return 0; + }; + if (t->right == NULL) { + return 1; + } else { + return MR_all_leaves_same_height(t->right,depth); + }; + }; +} + +#ifdef __USE_PROTOS +void MR_projectTreeOntoSet(Tree *tree,int ck,set *ckset) +#else +void MR_projectTreeOntoSet(tree,ck,ckset) + Tree *tree; + int ck; + set *ckset; +#endif +{ + if (tree == NULL) return; + + require(tree->token != EpToken,"MR_projectTreeOntoSet: EpToken unexpected\n"); + + MR_projectTreeOntoSet(tree->right,ck,ckset); + if (tree->token == ALT) { + MR_projectTreeOntoSet(tree->down,ck,ckset); + } else { + if (ck > 1) { + MR_projectTreeOntoSet(tree->down,ck-1,ckset); + } else { + set_orel(tree->token,ckset); + }; + }; +} + +#ifdef __USE_PROTOS +int MR_comparePredicates(Predicate *a,Predicate *b) +#else +int MR_comparePredicates(a,b) + Predicate *a; + Predicate *b; +#endif +{ + Predicate *p; + Predicate *q; + + if (a == b) return 1; + if (a == NULL || b == NULL ) return 0; + if (a->down == NULL && b->down == NULL) { + + /* predicate->invert can be set only in the predEntry predicates */ + /* thus they are only visible after the predEntry predicates have been "unfolded" */ + + int sameSource=(a->source == b->source); + int sameInvert= 1 & (1 +a->inverted + b->inverted + + a->source->inverted + b->source->inverted); + int samePredEntry=(a->source->predEntry != NULL + && b->source->predEntry != NULL + && a->source->predEntry == b->source->predEntry); + if (sameInvert && (sameSource || samePredEntry)) { + if (MR_identicalContext(a,b)) { + return 1; + }; + }; + return 0; + }; + if (a->down == NULL || b->down == NULL) return 0; + if (a->expr != b->expr) return 0; + + for (p=a->down; p != NULL; p=p->right) { + for (q=b->down; q != NULL; q=q->right) { + if (MR_comparePredicates(p,q)) goto NEXT_P; + }; + return 0; +NEXT_P: + continue; + }; + return 1; +} + +/* + * action->inverted can be set only when a predicate symbol appears in + * a rule: "rule : <>? X". It cannot be set under any + * other circumstances. In particular it cannot be set by + * "#pred NotA !A" or by "#pred Nota <>?". The first case + * creates a predEntry and the predicate expression of that predEntry + * has inverted set. In the second case, the code for handling "!" + * is only present in buildAction, which is not called by the #pred + * semantic routines, only when a <<...>>? is recognized as part of + * a rule definition. + * + * predicate->inverted can only be set by a predicate created by a #pred + * expression, such as "#pred NotA !A" or "#pred NotXY ! (X && Y) or + * "#pred XbarY !(X && Y)". In particular, it cannot be set by any + * predicate expression occurring under any other circumstances. + * The #pred predicate expresssions are stored with in predEntry->pred + * and do not normally appear anywhere else until the predicates are + * "unfolded" in order to recognize redundancies, conflicts, and + * tautologies. + * + * The unfold routine expands all references to #pred expressions. + * + * The simplifyInvert goes through and propagates the invert bit so that + * all OR and AND nodes are un-inverted. + * + * Note that !(A and B) => (!A or !B) + * !(A or B) => (!A and !B) + * + * MR_unfold() is called to expand predicate symbols by replacing predicates + * that reference predicate entries with the copies of the predicate entries. + * Each reference receives a duplicate of the original. This is necessary + * because the next phase involves simplification and removal of redundant + * predicate nodes. Anyway, the point I'm making is that predicate->invert + * should not be set in any predicate until it has been expanded. + * + * This is a recursive structure, but there is no need for "recursive expansion" + * by which I mean a predicate symbol refers to other predicate symbols which + * must also be expanded. + * + * Recursive expansion is *not* performed by this routine because it is not + * necessary. Expansion of references is performed by predPrimary when + * a new predicate symbol is created by referring to others in the pred expr. + */ + +#ifdef __USE_PROTOS +Predicate *MR_unfold(Predicate *pred) +#else +Predicate *MR_unfold(pred) + Predicate *pred; +#endif +{ + Predicate *result; + + if (pred == NULL) return NULL; + + pred->right=MR_unfold(pred->right); + + if (pred->down == NULL) { + if (pred->source->predEntry != NULL) { + if (pred->source->predEntry->pred == NULL) { + ; /* do nothing */ /* a reference to a literal #pred (perhaps with "!" */ + } else { + result=predicate_dup_without_context(pred->source->predEntry->pred); + if (pred->inverted) { + result->inverted=!result->inverted; + }; + if (pred->source->inverted) { + result->inverted=!result->inverted; + }; + result->right=pred->right; + pred->right=NULL; + predicate_free(pred); +/*** result=MR_unfold(result); *** not necessary */ /* recursive expansion */ + return result; + }; + } else { + ; /* do nothing */ /* an inline literal predicate */ + }; + } else { + pred->down=MR_unfold(pred->down); + }; + return pred; +} + +/* this should be called immediately after MR_unfold() and + at no other times +*/ + +#ifdef __USE_PROTOS +void MR_simplifyInverted(Predicate *pred,int inverted) +#else +void MR_simplifyInverted(pred,inverted) + Predicate *pred; + int inverted; +#endif +{ + int newInverted; + + if (pred == NULL) return; + + MR_simplifyInverted(pred->right,inverted); + + newInverted= 1 & (inverted + pred->inverted); + + if (pred->down == NULL) { + pred->inverted=newInverted; + } else { + if (newInverted != 0) { + if (pred->expr == PRED_AND_LIST) { + pred->expr=PRED_OR_LIST; + } else { + pred->expr=PRED_AND_LIST; + }; + }; + pred->inverted=0; + MR_simplifyInverted(pred->down,newInverted); + }; +} + +/* only remove it from AND and OR nodes, not leaves */ + +#ifdef __USE_PROTOS +void MR_clearPredEntry(Predicate *p) +#else +void MR_clearPredEntry(p) + Predicate *p; +#endif +{ + if (p == NULL) return; + MR_clearPredEntry(p->down); + MR_clearPredEntry(p->right); + if (p->down != NULL) p->predEntry=NULL; +} + + +#ifdef __USE_PROTOS +void MR_orphanRules(FILE *f) +#else +void MR_orphanRules(f) + FILE *f; +#endif +{ + set a; + Junction *p; + unsigned e; + RuleEntry *re; + + a=empty; + + if (! InfoO) return; + + for (p=SynDiag; p!=NULL; p = (Junction *)p->p2) { + if ( (Junction *) (p->end)->p1 == NULL) { + re=(RuleEntry *) hash_get(Rname,p->rname); + require (re != NULL,"RuleEntry == NULL"); + set_orel(re->rulenum, &a); + } + } + + if (set_deg(a) > 1) { + fprintf(f,"note: Start rules: {"); + for (; !set_nil(a); set_rm(e,a)) { + e=set_int(a); + fprintf(f," %s",RulePtr[e]->rname); + }; + fprintf(f," }\n"); + }; + set_free( a ); +} + +/* merge (X Y) and (X) to create (X) */ + +static int *mergeChain; +static Tree *mergeTree; + +#ifdef __USE_PROTOS +Tree *MR_merge_tree_contexts_client(Tree *t,int chain[]) +#else +Tree *MR_merge_tree_contexts_client(t,chain) + Tree *t; + int chain[]; +#endif +{ + if (t == NULL) return NULL; + if (chain[0] == 0) { + Tree *u=t->right; + t->right=NULL; + Tfree(t); + return MR_merge_tree_contexts_client(u,&chain[0]); + } + if (chain[0] == t->token) { + t->down=MR_merge_tree_contexts_client(t->down,&chain[1]); + }; + t->right=MR_merge_tree_contexts_client(t->right,&chain[0]); + return t; +} + +#ifdef __USE_PROTOS +void MR_iterateOverTreeContexts(Tree *t,int chain[]) +#else +void MR_iterateOverTreeContexts(t,chain) + Tree *t; + int chain[]; +#endif +{ + if (t == NULL) return; + chain[0]=t->token; + if (t->down != NULL) { + MR_iterateOverTreeContexts(t->down,&chain[1]); + } else { + MR_merge_tree_contexts_client(mergeTree,mergeChain); + }; + MR_iterateOverTreeContexts(t->right,&chain[0]); + chain[0]=0; +} + +#ifdef __USE_PROTOS +Tree *MR_merge_tree_contexts(Tree *t) +#else +Tree *MR_merge_tree_contexts(t) + Tree *t; +#endif +{ + int h=MR_max_height_of_tree(t); + + mergeTree=t; + mergeChain=(int *) calloc(h+1,sizeof(int)); + require (mergeChain != NULL,"MR_merge_tree_contexts: can't alloc chain"); + MR_iterateOverTreeContexts(t,mergeChain); + t=tshrink(t); + t=tflatten(t); + t=tleft_factor(t); + free ( (char *) mergeChain); + mergeChain=NULL; + return t; +} + +#ifdef __USE_PROTOS +Tree *MR_compute_pred_tree_context(Predicate *p) +#else +Tree *MR_compute_pred_tree_context(p) + Predicate *p; +#endif +{ + Tree *t; + + t=MR_compute_pred_tree_ctxXX(p); + MR_merge_tree_contexts(t); + return t; +} + +#ifdef __USE_PROTOS +void MR_guardPred_plainSet(ActionNode *anode,Predicate *pred) +#else +void MR_guardPred_plainSet(anode,pred) + ActionNode *anode; + Predicate *pred; +#endif +{ + Junction *j; + Predicate *workPred; + set maskSet; + + maskSet=empty; + + if (!MRhoisting) return; + + /* it doesn't really matter whether the predicate has + depth k=1 or k>1 because we're not really looking + at the predicate itself, just the stuff "behind" + the predicate. + */ + + /* shouldn't have to worry about REACHing off the end + of the rule containing the predicate because the + Rule->end->halt should have been set already by the + the code which handles RuleRef nodes. + + We don't want to REACH off the end of the rule because + this would give the "global" follow context rather than + the "local" context. + + r1a : (A)? => <

>? r2 (A|B) + r1b : (A)? => <

>? r2 (A|C) + r2 : (); + + For r1a we want follow of predicate = {A B} + we want plainSet = {B} + For r1b we want follow of predicate = {A C} + we want plainSet = {C} + */ + + require (anode->next->ntype == nJunction,"MR_guardpred_plainSet not Junction"); + j=(Junction *)(anode->next); + + workPred=predicate_dup_without_context(pred); + workPred->k=1; + workPred->scontext[1]=MR_First(1,j, &(workPred->completionSet) ); + MR_complete_predicates(1,workPred); + if (pred->k == 1) { + maskSet=pred->scontext[1]; + } else { + MR_projectTreeOntoSet(pred->tcontext,1,&maskSet); + } + pred->plainSet=set_dif(workPred->scontext[1],maskSet); + predicate_free(workPred); +} + +/*******************************************************************************/ + +static Tree * suppressTree; +static int * suppressChain; /* element 0 not used */ +static set * suppressSets; +static Node * suppressNode; +static int suppressChainLength; +int MR_SuppressSearch=0; +static int suppressSucceeded; +static Predicate * suppressPredicate; + +#ifdef __USE_PROTOS +int MR_isChain(Tree *t) +#else +int MR_isChain(t) + Tree *t; +#endif +{ + Tree *u; + + for (u=t; u != NULL; u=u->down) { + if (u->right != NULL) return 0; + } + return 1; +} + +#ifdef __USE_PROTOS +int MR_suppressK_client(Tree *tree,int tokensInChain[]) +#else +int MR_suppressK_client(tree,tokensInChain) + Tree *tree; + int tokensInChain[]; +#endif +{ + int i; + set *save_fset; + int save_ConstrainSearch; + set incomplete; + Tree *t; + + suppressSucceeded=0; /* volatile */ + + if (suppressSets == NULL) { + suppressSets=(set *) calloc (CLL_k+1,sizeof(set)); + require (suppressSets != NULL,"MR_suppressK_client: suppressSets alloc"); + }; + + for (suppressChainLength=1; + tokensInChain[suppressChainLength+1] != 0; + suppressChainLength++) {}; + + require (suppressChainLength != 0,"MR_suppressK_client: chain empty"); + + for (i=1 ; i <= suppressChainLength ; i++) { + set_clr(suppressSets[i]); + set_orel( (unsigned) tokensInChain[i], + &suppressSets[i]); + }; + + save_fset=fset; + save_ConstrainSearch=ConstrainSearch; + + fset=suppressSets; + + MR_SuppressSearch=1; + MR_AmbSourceSearch=1; + MR_MaintainBackTrace=1; + ConstrainSearch=1; + + maxk = suppressChainLength; + + incomplete=empty; + t=NULL; + +/*** constrain = &(fset[1]); ***/ + + MR_setConstrainPointer(&(fset[1])); /* MR18 */ + + MR_pointerStackReset(&MR_BackTraceStack); + + TRAV(suppressNode,maxk,&incomplete,t); + + Tfree(t); + + require (set_nil(incomplete),"MR_suppressK_client TRAV incomplete"); + require (MR_BackTraceStack.count == 0, + "MR_suppressK_client: MR_BackTraceStack.count != 0"); + set_free(incomplete); + + ConstrainSearch=save_ConstrainSearch; + fset=save_fset; + + MR_AmbSourceSearch=0; + MR_MaintainBackTrace=0; + MR_SuppressSearch=0; + return suppressSucceeded; +} + +#ifdef __USE_PROTOS +Tree * MR_iterateOverTreeSuppressK(Tree *t,int chain[]) +#else +Tree * MR_iterateOverTreeSuppressK(t,chain) + Tree *t; + int chain[]; +#endif +{ + if (t == NULL) return NULL; + t->right=MR_iterateOverTreeSuppressK(t->right,&chain[0]); + chain[0]=t->token; + if (t->down != NULL) { + t->down=MR_iterateOverTreeSuppressK(t->down,&chain[1]); + if (t->down == NULL) { + Tree *u=t->right; + t->right=NULL; + Tfree(t); + chain[0]=0; + return u; + }; + } else { + MR_suppressK_client(suppressTree,suppressChain); + if (suppressSucceeded) { + Tree *u=t->right; + t->right=NULL; + Tfree(t); + chain[0]=0; + return u; + }; + }; + chain[0]=0; + return t; +} + +/* @@@ */ + +#ifdef __USE_PROTOS +Predicate * MR_suppressK(Node *j,Predicate *p) +#else +Predicate * MR_suppressK(j,p) + Node *j; + Predicate *p; +#endif +{ + Predicate *result; + int guardPred=0; + int ampersandPred=0; + Node *nodePrime; + + if (! MRhoistingk) { + return p; + } + + if (! MRhoisting) return p; + if (CLL_k == 1) return p; + + if (suppressChain == NULL) { + suppressChain=(int *) calloc(CLL_k+2,sizeof(int)); + require (suppressChain != NULL,"MR_suppressK: can't allocate chain"); + } + + if (p == NULL) return NULL; + + if (j->ntype == nJunction) { + nodePrime=(Node *) MR_junctionWithoutP2( (Junction *) j); + } else { + nodePrime=j; + }; + + p->down=MR_suppressK(j,p->down); + p->right=MR_suppressK(j,p->right); + if (p->down != NULL) { + result=p; + goto EXIT; + }; + if (p->k == 1) { + result=p; + goto EXIT; + }; + + if (p->source != NULL) { + if (p->source->guardpred != NULL) guardPred=1; + if (p->source->ampersandPred != NULL) ampersandPred=1; + } + + suppressPredicate=p; + suppressNode=nodePrime; /* was j*/ + + suppressTree=p->tcontext; + + if (guardPred || ampersandPred) { + p->tcontext=MR_iterateOverTreeSuppressK(suppressTree,&suppressChain[1]); + if (p->tcontext == NULL) { + predicate_free(p); + result=NULL; + goto EXIT; + }; + } else { + if (MR_isChain(p->tcontext)) { + p->tcontext=MR_iterateOverTreeSuppressK(suppressTree,&suppressChain[1]); + if (p->tcontext == NULL) { + predicate_free(p); + result=NULL; + goto EXIT; + }; + } + } + result=p; +EXIT: + return result; +} + +#ifdef __USE_PROTOS +void MR_suppressSearchReport(void) +#else +void MR_suppressSearchReport() +#endif +{ + int i; + Node *p; + TokNode *tn; + int depth; + set setAnd; + + /* number of tokens in back trace stack matches length of chain */ + + depth=0; + for (i=0; i < MR_BackTraceStack.count ; i++) { + p=(Node *) MR_BackTraceStack.data[i]; + if (p->ntype == nToken) depth++; + }; + + require (depth == suppressChainLength,"depth > suppressChainLength"); + + /* token codes match chain */ + + depth=0; + for (i=0; i < MR_BackTraceStack.count ; i++) { + p=(Node *) MR_BackTraceStack.data[i]; + if (p->ntype != nToken) continue; + tn=(TokNode *) p; + depth++; + if (set_nil(tn->tset)) { + require(set_el( (unsigned) tn->token,fset[depth]), + "MR_suppressSearchReport: no match to #token in chain"); + } else { + setAnd=set_and(fset[depth],tn->tset); + require(!set_nil(setAnd), + "MR_suppressSearchReport: no match to #token set in chain"); + set_free(setAnd); + }; + }; + + /* have a match - now remove it from the predicate */ + + suppressSucceeded=1; + + if (suppressSucceeded) { + fprintf(output,"\n"); + fprintf(output,"#if 0\n"); + fprintf(output,"\n"); + fprintf(output,"Part (or all) of predicate with depth > 1 suppressed by "); + fprintf(output,"alternative without predicate\n\n"); + MR_dumpPred(suppressPredicate,1); + fprintf(output,"The token sequence which is suppressed:"); + fprintf(output," ("); + for (i=1; i <= suppressChainLength; i++) { + fprintf(output," %s",TerminalString(suppressChain[i])); + }; + fprintf(output," )\n"); + fprintf(output,"The sequence of references which generate that sequence of tokens:\n\n"); + + MR_backTraceDumpItemReset(); + + for (i=0; i < MR_BackTraceStack.count ; i++) { + MR_backTraceDumpItem(output,0,(Node *) MR_BackTraceStack.data[i]); + }; + fprintf(output,"\n"); + fprintf(output,"#endif\n"); + } +} + +#ifdef __USE_PROTOS +void MR_markCompromisedRule(Node *n) +#else +void MR_markCompromisedRule(n) + Node *n; +#endif +{ + RuleEntry *q; + Node *mark=NULL; + Junction *j; + + if (n->ntype == nRuleRef) { + mark=(Node *) MR_ruleReferenced( (RuleRefNode *) n); + } else if (n->ntype == nToken) { + mark=n; + } else if (n->ntype == nJunction) { + j=(Junction *)n; + switch (j->jtype) { + case aOptBlk: + case aLoopBlk: + case RuleBlk: + case EndRule: + case aPlusBlk: + case aLoopBegin: + mark=n; + break; + default: + break; + }; + } + + if (mark == NULL) return; + + require (RulePtr != NULL,"RulePtr not initialized"); + + q = (RuleEntry *) hash_get(Rname,mark->rname); + require (q != NULL,"RuleEntry not found"); + set_orel(q->rulenum,&MR_CompromisedRules); +} + +#ifdef __USE_PROTOS +void MR_alphaBetaTraceReport(void) +#else +void MR_alphaBetaTraceReport() +#endif +{ + int i; + + if (! AlphaBetaTrace) return; + + MR_AlphaBetaMessageCount++; + + fprintf(output,"\n"); + fprintf(output,"#if 0\n"); + fprintf(output,"\n"); + fprintf(output,"Trace of references leading to attempt to compute the follow set of\n"); + fprintf(output,"alpha in an \"(alpha)? beta\" block. It is not possible for antlr to\n"); + fprintf(output,"compute this follow set because it is not known what part of beta has\n"); + fprintf(output,"already been matched by alpha and what part remains to be matched.\n"); + fprintf(output,"\n"); + fprintf(output,"Rules which make use of the incorrect follow set will also be incorrect\n"); + fprintf(output,"\n"); + + MR_backTraceDumpItemReset(); + + for (i=0; i < MR_BackTraceStack.count ; i++) { + MR_backTraceDumpItem(output,0,(Node *) MR_BackTraceStack.data[i]); + if (i < MR_BackTraceStack.count-1) { + MR_markCompromisedRule( (Node *) MR_BackTraceStack.data[i]); + }; + }; + fprintf(output,"\n"); + fprintf(output,"#endif\n"); +} + +#ifdef __USE_PROTOS +void MR_dumpRuleSet(set s) +#else +void MR_dumpRuleSet(s) + set s; +#endif +{ + unsigned *cursor; + unsigned *origin=set_pdq(s); + + require(origin != NULL,"set_pdq failed"); + + if (RulePtr == NULL) { + fprintf(stderr,"RulePtr[] not yet initialized"); + } else { + for (cursor=origin; *cursor != nil ; cursor++) { +/**** if (cursor != origin) fprintf(stderr,","); ****/ + fprintf(stderr," %s",RulePtr[*cursor]->rname); + fprintf(stderr,"\n"); + }; + free( (char *) origin); + }; +} diff --git a/Tools/CodeTools/Source/Pccts/antlr/parser.dlg b/Tools/CodeTools/Source/Pccts/antlr/parser.dlg new file mode 100644 index 0000000000..8c43dff300 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/parser.dlg @@ -0,0 +1,1387 @@ +<< +/* parser.dlg -- DLG Description of scanner + * + * Generated from: antlr.g + * + * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001 + * Purdue University Electrical Engineering + * With AHPCRC, University of Minnesota + * ANTLR Version 1.33MR33 + */ + +#define ANTLR_VERSION 13333 +#include "pcctscfg.h" +#include "pccts_stdio.h" + +#include "pcctscfg.h" +#include "set.h" +#include +#include "syn.h" +#include "hash.h" +#include "generic.h" +#define zzcr_attr(attr,tok,t) +#include "antlr.h" +#include "tokens.h" +#include "dlgdef.h" +LOOKAHEAD + +void +#ifdef __USE_PROTOS +zzerraction(void) +#else +zzerraction() +#endif +{ + (*zzerr)("invalid token"); + zzadvance(); + zzskip(); +} +>> + +<<%%lexaction + +/* maintained, but not used for now */ +set AST_nodes_refd_in_actions = set_init; +int inAlt = 0; +set attribsRefdFromAction = set_init; /* MR20 */ +int UsedOldStyleAttrib = 0; +int UsedNewStyleLabel = 0; +#ifdef __USE_PROTOS +char *inline_set(char *); +#else +char *inline_set(); +#endif + +/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */ +/* MR1 in DLG action */ + +int tokenActionActive=0; /* MR1 */ + + +>> + +<<%%lexaction + + +static char * +#ifdef __USE_PROTOS +getFileNameFromTheLineInfo(char *toStr, char *fromStr) +#else +getFileNameFromTheLineInfo(toStr, fromStr) +char *toStr, *fromStr; +#endif +{ + int i, j, k; + + if (!fromStr || !toStr) return toStr; + + /* find the first " */ + + for (i=0; + (i> + +<<%%lexaction + +#ifdef __USE_PROTOS +void mark_label_used_in_sem_pred(LabelEntry *le) /* MR10 */ +#else +void mark_label_used_in_sem_pred(le) /* MR10 */ +LabelEntry *le; +#endif +{ + TokNode *tn; + require (le->elem->ntype == nToken,"mark_label_used... ntype != nToken"); + tn=(TokNode *)le->elem; + require (tn->label != 0,"mark_label_used... TokNode has no label"); + tn->label_used_in_semantic_pred=1; +} +>> + + +%%START + +@ + << + NLA = Eof; + /* L o o k F o r A n o t h e r F i l e */ + { + FILE *new_input; + new_input = NextFile(); + if ( new_input == NULL ) { NLA=Eof; return; } + fclose( input ); + input = new_input; + zzrdstream( input ); + zzskip(); /* Skip the Eof (@) char i.e continue */ + } + >> + +[\t\ ]+ + << + NLA = 76; + zzskip(); + >> + +\n|\r|\r\n + << + NLA = 77; + zzline++; zzskip(); + >> + +\[ + << + NLA = 78; + zzmode(ACTIONS); zzmore(); + istackreset(); + pushint(']'); + >> + +\<\< + << + NLA = 79; + action_file=CurFile; action_line=zzline; + zzmode(ACTIONS); zzmore(); + list_free(&CurActionLabels,0); /* MR10 */ + numericActionLabel=0; /* MR10 */ + istackreset(); + pushint('>'); + >> + +\" + << + NLA = 80; + zzmode(STRINGS); zzmore(); + >> + +/\* + << + NLA = 81; + zzmode(COMMENTS); zzskip(); + >> + +\*/ + << + NLA = 82; + warn("Missing /*; found dangling */"); zzskip(); + >> + +// + << + NLA = 83; + zzmode(CPP_COMMENTS); zzskip(); + >> + +#line[\ \t]* [0-9]+ {[\ \t]* \"~[\"]+\" ([\ \t]* [0-9]*)* } (\n|\r|\r\n) + << + NLA = 84; + + zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore(); + getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr); + >> + +#line ~[\n\r]* (\n|\r|\r\n) + << + NLA = 85; + + zzline++; zzmore(); + >> + +\>\> + << + NLA = 86; + warn("Missing <<; found dangling \>\>"); zzskip(); + >> + +. + << + NLA = WildCard; + >> + +\@ + << + NLA = 88; + FoundException = 1; /* MR6 */ + FoundAtOperator = 1; + >> + +{\\}#pragma + << + NLA = Pragma; + >> + +{\\}#FirstSetSymbol + << + NLA = FirstSetSymbol; + >> + +{\\}#header + << + NLA = 94; + >> + +{\\}#first + << + NLA = 95; + >> + +{\\}#parser + << + NLA = 96; + >> + +{\\}#tokdefs + << + NLA = 97; + >> + +\} + << + NLA = 98; + >> + +class + << + NLA = 99; + >> + +\{ + << + NLA = 102; + >> + +! + << + NLA = 103; + >> + +\< + << + NLA = 104; + >> + +\> + << + NLA = 105; + >> + +: + << + NLA = 106; + >> + +; + << + NLA = 107; + >> + +{\\}#lexaction + << + NLA = 108; + >> + +{\\}#lexmember + << + NLA = 109; + >> + +{\\}#lexprefix + << + NLA = 110; + >> + +{\\}#pred + << + NLA = 111; + >> + +\|\| + << + NLA = 112; + >> + +&& + << + NLA = 113; + >> + +\( + << + NLA = 114; + >> + +\) + << + NLA = 115; + >> + +{\\}#lexclass + << + NLA = 116; + >> + +{\\}#errclass + << + NLA = 117; + >> + +{\\}#tokclass + << + NLA = 118; + >> + +.. + << + NLA = 119; + >> + +{\\}#token + << + NLA = 120; + >> + += + << + NLA = 121; + >> + +[0-9]+ + << + NLA = 122; + >> + +\| + << + NLA = 123; + >> + +\~ + << + NLA = 124; + >> + +^ + << + NLA = 125; + >> + +approx + << + NLA = 126; + >> + +LL\(1\) + << + NLA = 127; + >> + +LL\(2\) + << + NLA = 128; + >> + +\* + << + NLA = 129; + >> + +\+ + << + NLA = 130; + >> + +? + << + NLA = 131; + >> + +=> + << + NLA = 132; + >> + +exception + << + NLA = 133; + >> + +default + << + NLA = 134; + >> + +catch + << + NLA = 135; + >> + +[a-z] [A-Za-z0-9_]* + << + NLA = NonTerminal; + + while ( zzchar==' ' || zzchar=='\t' ) { + zzadvance(); + } + if ( zzchar == ':' && inAlt ) NLA = LABEL; + >> + +[A-Z] [A-Za-z0-9_]* + << + NLA = TokenTerm; + + while ( zzchar==' ' || zzchar=='\t' ) { + zzadvance(); + } + if ( zzchar == ':' && inAlt ) NLA = LABEL; + >> + +{\\}#[A-Za-z0-9_]* + << + NLA = 136; + warn(eMsg1("unknown meta-op: %s",LATEXT(1))); zzskip(); + >> + + +%%STRINGS + +@ + << + NLA = Eof; + >> + +\" + << + NLA = QuotedTerm; + zzmode(START); + >> + +\n|\r|\r\n + << + NLA = 3; + + zzline++; + warn("eoln found in string"); + zzskip(); + >> + +\\(\n|\r|\r\n) + << + NLA = 4; + zzline++; zzmore(); + >> + +\\~[] + << + NLA = 5; + zzmore(); + >> + +~[\n\r\"\\]+ + << + NLA = 6; + zzmore(); + >> + + +%%ACTION_STRINGS + +@ + << + NLA = Eof; + >> + +\" + << + NLA = 7; + zzmode(ACTIONS); zzmore(); + >> + +\n|\r|\r\n + << + NLA = 8; + + zzline++; + warn("eoln found in string (in user action)"); + zzskip(); + >> + +\\(\n|\r|\r\n) + << + NLA = 9; + zzline++; zzmore(); + >> + +\\~[] + << + NLA = 10; + zzmore(); + >> + +~[\n\r\"\\]+ + << + NLA = 11; + zzmore(); + >> + + +%%ACTION_CHARS + +@ + << + NLA = Eof; + >> + +' + << + NLA = 12; + zzmode(ACTIONS); zzmore(); + >> + +\n|\r|\r\n + << + NLA = 13; + + zzline++; + warn("eoln found in char literal (in user action)"); + zzskip(); + >> + +\\~[] + << + NLA = 14; + zzmore(); + >> + +~[\n\r'\\]+ + << + NLA = 15; + zzmore(); + >> + + +%%ACTION_COMMENTS + +@ + << + NLA = Eof; + >> + +\*/ + << + NLA = 16; + zzmode(ACTIONS); zzmore(); + >> + +\* + << + NLA = 17; + zzmore(); + >> + +\n|\r|\r\n + << + NLA = 18; + zzline++; zzmore(); DAWDLE; + >> + +~[\n\r\*]+ + << + NLA = 19; + zzmore(); + >> + + +%%TOK_DEF_COMMENTS + +@ + << + NLA = Eof; + >> + +\*/ + << + NLA = 20; + zzmode(PARSE_ENUM_FILE); + zzmore(); + >> + +\* + << + NLA = 21; + zzmore(); + >> + +\n|\r|\r\n + << + NLA = 22; + zzline++; zzmore(); DAWDLE; + >> + +~[\n\r\*]+ + << + NLA = 23; + zzmore(); + >> + + +%%TOK_DEF_CPP_COMMENTS + +@ + << + NLA = Eof; + >> + +\n|\r|\r\n + << + NLA = 24; + zzline++; zzmode(PARSE_ENUM_FILE); zzskip(); DAWDLE; + >> + +~[\n\r]+ + << + NLA = 25; + zzskip(); + >> + + +%%ACTION_CPP_COMMENTS + +@ + << + NLA = Eof; + >> + +\n|\r|\r\n + << + NLA = 26; + zzline++; zzmode(ACTIONS); zzmore(); DAWDLE; + >> + +~[\n\r]+ + << + NLA = 27; + zzmore(); + >> + + +%%CPP_COMMENTS + +@ + << + NLA = Eof; + >> + +\n|\r|\r\n + << + NLA = 28; + zzline++; zzmode(START); zzskip(); DAWDLE; + >> + +~[\n\r]+ + << + NLA = 29; + zzskip(); + >> + + +%%COMMENTS + +@ + << + NLA = Eof; + >> + +\*/ + << + NLA = 30; + zzmode(START); zzskip(); + >> + +\* + << + NLA = 31; + zzskip(); + >> + +\n|\r|\r\n + << + NLA = 32; + zzline++; zzskip(); DAWDLE; + >> + +~[\n\r\*]+ + << + NLA = 33; + zzskip(); + >> + + +%%ACTIONS + +@ + << + NLA = Eof; + >> + +\>\> + << + NLA = Action; + /* these do not nest */ + zzmode(START); + NLATEXT[0] = ' '; + NLATEXT[1] = ' '; + zzbegexpr[0] = ' '; + zzbegexpr[1] = ' '; + if ( zzbufovf ) { + err( eMsgd("action buffer overflow; size %d",ZZLEXBUFSIZE)); + } + +/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */ + /* MR1 in DLG action */ + /* MR1 Doesn't matter what kind of action it is - reset*/ + + tokenActionActive=0; /* MR1 */ + >> + +\>\>? + << + NLA = Pred; + /* these do not nest */ + zzmode(START); + NLATEXT[0] = ' '; + NLATEXT[1] = ' '; + zzbegexpr[0] = '\0'; + if ( zzbufovf ) { + err( eMsgd("predicate buffer overflow; size %d",ZZLEXBUFSIZE)); + }; +#ifdef __cplusplus__ + /* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); +#else +#ifdef __STDC__ + /* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); +#else +#ifdef __USE_PROTOS + /* MRxx */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); +#else + /* MR10 */ list_apply(CurActionLabels,mark_label_used_in_sem_pred); +#endif +#endif +#endif + >> + +\] + << + NLA = PassAction; + if ( topint() == ']' ) { + popint(); + if ( istackempty() ) /* terminate action */ + { + zzmode(START); + NLATEXT[0] = ' '; + zzbegexpr[0] = ' '; + if ( zzbufovf ) { + err( eMsgd("parameter buffer overflow; size %d",ZZLEXBUFSIZE)); + } + } + else { + /* terminate $[..] and #[..] */ + if ( GenCC ) zzreplstr("))"); + else zzreplstr(")"); + zzmore(); + } + } + else if ( topint() == '|' ) { /* end of simple [...] */ + popint(); + zzmore(); + } + else zzmore(); + >> + +consumeUntil\( [\ \t]* \{~[\}]+\} [\ \t]* \) + << + NLA = 37; + + zzmore(); + zzreplstr(inline_set(zzbegexpr+ + strlen("consumeUntil("))); + >> + +consumeUntil\( ~[\)]+ \) + << + NLA = 38; + zzmore(); + >> + +\n|\r|\r\n + << + NLA = 39; + zzline++; zzmore(); DAWDLE; + >> + +\> + << + NLA = 40; + zzmore(); + >> + +$ + << + NLA = 41; + zzmore(); + >> + +$$ + << + NLA = 42; + if ( !GenCC ) {zzreplstr("zzaRet"); zzmore();} + else err("$$ use invalid in C++ mode"); + >> + +$\[\] + << + NLA = 43; + if ( !GenCC ) {zzreplstr("zzempty_attr"); zzmore();} + else err("$[] use invalid in C++ mode"); + >> + +$\[ + << + NLA = 44; + + pushint(']'); + if ( !GenCC ) zzreplstr("zzconstr_attr("); + else err("$[..] use invalid in C++ mode"); + zzmore(); + >> + +$[0-9]+ + << + NLA = 45; + { + static char buf[100]; + numericActionLabel=1; /* MR10 */ + if ( strlen(zzbegexpr)>(size_t)85 ) + fatal("$i attrib ref too big"); + set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction); + if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s)", + BlkLevel-1,zzbegexpr+1); + else sprintf(buf,"_t%d%s", + BlkLevel-1,zzbegexpr+1); + zzreplstr(buf); + zzmore(); + UsedOldStyleAttrib = 1; + if ( UsedNewStyleLabel ) + err("cannot mix old-style $i with new-style labels"); + } + >> + +$[0-9]+. + << + NLA = 46; + { + static char buf[100]; + numericActionLabel=1; /* MR10 */ + if ( strlen(zzbegexpr)>(size_t)85 ) + fatal("$i.field attrib ref too big"); + zzbegexpr[strlen(zzbegexpr)-1] = ' '; + set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction); + if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s).", + BlkLevel-1,zzbegexpr+1); + else sprintf(buf,"_t%d%s.", + BlkLevel-1,zzbegexpr+1); + zzreplstr(buf); + zzmore(); + UsedOldStyleAttrib = 1; + if ( UsedNewStyleLabel ) + err("cannot mix old-style $i with new-style labels"); + } + >> + +$[0-9]+.[0-9]+ + << + NLA = 47; + { + static char buf[100]; + static char i[20], j[20]; + char *p,*q; + numericActionLabel=1; /* MR10 */ + if (strlen(zzbegexpr)>(size_t)85) fatal("$i.j attrib ref too big"); + for (p=zzbegexpr+1,q= &i[0]; *p!='.'; p++) { + if ( q == &i[20] ) + fatalFL("i of $i.j attrib ref too big", + FileStr[CurFile], zzline ); + *q++ = *p; + } + *q = '\0'; + for (p++, q= &j[0]; *p!='\0'; p++) { + if ( q == &j[20] ) + fatalFL("j of $i.j attrib ref too big", + FileStr[CurFile], zzline ); + *q++ = *p; + } + *q = '\0'; + if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%s,%s)",i,j); + else sprintf(buf,"_t%s%s",i,j); + zzreplstr(buf); + zzmore(); + UsedOldStyleAttrib = 1; + if ( UsedNewStyleLabel ) + err("cannot mix old-style $i with new-style labels"); + } + >> + +$[_a-zA-Z][_a-zA-Z0-9]* + << + NLA = 48; + { static char buf[300]; LabelEntry *el; + zzbegexpr[0] = ' '; + if ( CurRule != NULL && + strcmp(CurRule, &zzbegexpr[1])==0 ) { + if ( !GenCC ) zzreplstr("zzaRet"); + } + else if ( CurRetDef != NULL && + strmember(CurRetDef, &zzbegexpr[1])) { + if ( hasMultipleOperands( CurRetDef ) ) { + require (strlen(zzbegexpr)<=(size_t)285, + "$retval attrib ref too big"); + sprintf(buf,"_retv.%s",&zzbegexpr[1]); + zzreplstr(buf); + } + else zzreplstr("_retv"); + } + else if ( CurParmDef != NULL && + strmember(CurParmDef, &zzbegexpr[1])) { + ; + } + else if ( Elabel==NULL ) { + { err("$-variables in actions outside of rules are not allowed"); } + } else if ( (el=(LabelEntry *)hash_get(Elabel, &zzbegexpr[1]))!=NULL ) { + /* MR10 */ + /* MR10 */ /* element labels might exist without an elem when */ + /* MR10 */ /* it is a forward reference (to a rule) */ + /* MR10 */ + /* MR10 */ if ( GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) ) + /* MR10 */ { err(eMsg1("There are no token ptrs for rule references: '$%s'",&zzbegexpr[1])); } + /* MR10 */ + /* MR10 */ if ( !GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) && GenAST) { + /* MR10 */ err("You can no longer use attributes returned by rules when also using ASTs"); + /* MR10 */ err(" Use upward inheritance (\"rule >[Attrib a] : ... <<$a=...\>\>\")"); + /* MR10 */ }; + /* MR10 */ + /* MR10 */ /* keep track of <<... $label ...>> for semantic predicates in guess mode */ + /* MR10 */ /* element labels contain pointer to the owners node */ + /* MR10 */ + /* MR10 */ if (el->elem != NULL && el->elem->ntype == nToken) { + /* MR10 */ list_add(&CurActionLabels,el); + /* MR10 */ }; +} +else +warn(eMsg1("$%s not parameter, return value, (defined) element label",&zzbegexpr[1])); +} +zzmore(); + >> + +#0 + << + NLA = 49; + zzreplstr("(*_root)"); zzmore(); chkGTFlag(); + >> + +#\[\] + << + NLA = 50; + if ( GenCC ) { + if (NewAST) zzreplstr("(newAST)"); + else zzreplstr("(new AST)");} + else {zzreplstr("zzastnew()");} zzmore(); + chkGTFlag(); + >> + +#\(\) + << + NLA = 51; + zzreplstr("NULL"); zzmore(); chkGTFlag(); + >> + +#[0-9]+ + << + NLA = 52; + { + static char buf[100]; + if ( strlen(zzbegexpr)>(size_t)85 ) + fatal("#i AST ref too big"); + if ( GenCC ) sprintf(buf,"_ast%d%s",BlkLevel-1,zzbegexpr+1); + else sprintf(buf,"zzastArg(%s)",zzbegexpr+1); + zzreplstr(buf); + zzmore(); + set_orel(atoi(zzbegexpr+1), &AST_nodes_refd_in_actions); + chkGTFlag(); + } + >> + +#line[\ \t]* [0-9]+ {[\ \t]* \"~[\"]+\" ([\ \t]* [0-9]*)* } (\n|\r|\r\n) + << + NLA = 53; + + zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore(); + getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr); + >> + +#line ~[\n\r]* (\n|\r|\r\n) + << + NLA = 54; + + zzline++; zzmore(); + >> + +#[_a-zA-Z][_a-zA-Z0-9]* + << + NLA = 55; + + if ( !(strcmp(zzbegexpr, "#ifdef")==0 || + strcmp(zzbegexpr, "#if")==0 || + strcmp(zzbegexpr, "#else")==0 || + strcmp(zzbegexpr, "#endif")==0 || + strcmp(zzbegexpr, "#ifndef")==0 || + strcmp(zzbegexpr, "#define")==0 || + strcmp(zzbegexpr, "#pragma")==0 || + strcmp(zzbegexpr, "#undef")==0 || + strcmp(zzbegexpr, "#import")==0 || + strcmp(zzbegexpr, "#line")==0 || + strcmp(zzbegexpr, "#include")==0 || + strcmp(zzbegexpr, "#error")==0) ) + { + static char buf[100]; + sprintf(buf, "%s_ast", zzbegexpr+1); + /* MR27 */ list_add(&CurAstLabelsInActions, mystrdup(zzbegexpr+1)); + zzreplstr(buf); + chkGTFlag(); + } + zzmore(); + >> + +#\[ + << + NLA = 56; + + pushint(']'); + if ( GenCC ) { + if (NewAST) zzreplstr("(newAST("); + else zzreplstr("(new AST("); } + else zzreplstr("zzmk_ast(zzastnew(),"); + zzmore(); + chkGTFlag(); + >> + +#\( + << + NLA = 57; + + pushint('}'); + if ( GenCC ) { + if (tmakeInParser) { + zzreplstr("tmake("); + } + else { + zzreplstr("ASTBase::tmake("); + } + } + else { + zzreplstr("zztmake("); + } + zzmore(); + chkGTFlag(); + >> + +# + << + NLA = 58; + zzmore(); + >> + +\) + << + NLA = 59; + + if ( istackempty() ) + zzmore(); + else if ( topint()==')' ) { + popint(); + } + else if ( topint()=='}' ) { + popint(); + /* terminate #(..) */ + zzreplstr(", NULL)"); + } + zzmore(); + >> + +\[ + << + NLA = 60; + + pushint('|'); /* look for '|' to terminate simple [...] */ + zzmore(); + >> + +\( + << + NLA = 61; + + pushint(')'); + zzmore(); + >> + +\\\] + << + NLA = 62; + zzreplstr("]"); zzmore(); + >> + +\\\) + << + NLA = 63; + zzreplstr(")"); zzmore(); + >> + +\\> + << + NLA = 64; + if (! tokenActionActive) zzreplstr(">"); /* MR1 */ + zzmore(); /* MR1 */ + >> + +' + << + NLA = 65; + zzmode(ACTION_CHARS); zzmore(); + >> + +\" + << + NLA = 66; + zzmode(ACTION_STRINGS); zzmore(); + >> + +\\$ + << + NLA = 67; + zzreplstr("$"); zzmore(); + >> + +\\# + << + NLA = 68; + zzreplstr("#"); zzmore(); + >> + +\\(\n|\r|\r\n) + << + NLA = 69; + zzline++; zzmore(); + >> + +\\~[\]\)>$#] + << + NLA = 70; + zzmore(); + >> + +/ + << + NLA = 71; + zzmore(); + >> + +/\* + << + NLA = 72; + zzmode(ACTION_COMMENTS); zzmore(); + >> + +\*/ + << + NLA = 73; + warn("Missing /*; found dangling */ in action"); zzmore(); + >> + +// + << + NLA = 74; + zzmode(ACTION_CPP_COMMENTS); zzmore(); + >> + +~[\n\r\)\(\\$#\>\]\[\"'/]+ + << + NLA = 75; + zzmore(); + >> + + +%%PARSE_ENUM_FILE + +@ + << + NLA = Eof; + ; + >> + +[\t\ ]+ + << + NLA = 137; + zzskip(); + >> + +\n|\r|\r\n + << + NLA = 138; + zzline++; zzskip(); + >> + +// + << + NLA = 139; + zzmode(TOK_DEF_CPP_COMMENTS); zzmore(); + >> + +/\* + << + NLA = 140; + zzmode(TOK_DEF_COMMENTS); zzskip(); + >> + +#ifdef + << + NLA = 141; + zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); + >> + +#if + << + NLA = 142; + zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); + >> + +#ifndef + << + NLA = 143; + ; + >> + +#else + << + NLA = 144; + zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); + >> + +#endif + << + NLA = 145; + zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); + >> + +#undef + << + NLA = 146; + zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); + >> + +#import + << + NLA = 147; + zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); + >> + +#define + << + NLA = 149; + >> + +enum + << + NLA = 151; + >> + +\{ + << + NLA = 152; + >> + += + << + NLA = 153; + >> + +, + << + NLA = 154; + >> + +\} + << + NLA = 155; + >> + +; + << + NLA = 156; + >> + +[0-9]+ + << + NLA = INT; + >> + +[a-zA-Z_][_a-zA-Z0-9]* + << + NLA = ID; + >> + +%% diff --git a/Tools/CodeTools/Source/Pccts/antlr/pred.c b/Tools/CodeTools/Source/Pccts/antlr/pred.c new file mode 100644 index 0000000000..eb11c4d950 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/pred.c @@ -0,0 +1,821 @@ +/* + * pred.c -- source for predicate detection, manipulation + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2001 + */ + +#include +#include "pcctscfg.h" +#include "set.h" +#include "syn.h" +#include "hash.h" +#include "generic.h" +#include "dlgdef.h" +#include + +#ifdef __USE_PROTOS +static void complete_context_sets(RuleRefNode *, Predicate *); +static void complete_context_trees(RuleRefNode *, Predicate *); +#else +static void complete_context_sets(); +static void complete_context_trees(); +#endif + +char *PRED_AND_LIST = "AND"; +char *PRED_OR_LIST = "OR"; + +/* + * In C mode, return the largest constant integer found as the + * sole argument to LATEXT(i). + * + * In C++ mode, return the largest constant integer found as the + * sole argument to LT(i) given that the char before is nonalpha. + */ + +int +#ifdef __USE_PROTOS +predicateLookaheadDepth(ActionNode *a) +#else +predicateLookaheadDepth(a) +ActionNode *a; +#endif +{ + int max_k=0; + + if (a->predEntry != NULL) { + MR_pred_depth(a->predEntry->pred,&max_k); + goto PREDENTRY_EXIT; + } + + if ( GenCC ) + { + /* scan for LT(i) */ + int k = 0; + char *p = a->action; + while ( p!=NULL ) + { + p = strstr(p, "LT("); + if ( p!=NULL ) + { + if ( p>=a->action && !isalpha(*(p-1)) ) + { + k = atoi(p+strlen("LT(")); + if ( k>max_k ) max_k=k; + } + p += strlen("LT("); + } + } + } + else { + /* scan for LATEXT(i) */ + int k = 0; + char *p = a->action; + while ( p!=NULL ) + { + p = strstr(p, "LATEXT("); + if ( p!=NULL ) + { + p += strlen("LATEXT("); + k = atoi(p); + if ( k>max_k ) max_k=k; + } + } + } + + if (max_k==0) { + max_k = 1; /* MR33 Badly designed if didn't set max_k when CLL_k = 1 */ + if (CLL_k > 1) /* MR27 Don't warn if max(k,ck) == 1 */ + { + if ( !a->frmwarned ) + { + a->frmwarned = 1; + warnFL(eMsg1("predicate: %s missing, bad, or with i=0; assuming i=1", + GenCC?"LT(i)":"LATEXT(i)"), + FileStr[a->file], a->line); + } + } + } + +/* MR10 */ if ( max_k > CLL_k) { +/* MR10 */ if ( !a->frmwarned ) +/* MR10 */ { +/* MR10 */ a->frmwarned = 1; +/* MR11 */ errFL(eMsgd2("predicate refers to lookahead token %d. Semantic lookahead is limited to max(k,ck)==%d", +/* MR10 */ max_k,CLL_k), +/* MR10 */ FileStr[a->file],a->line); +/* MR10 */ if (max_k >= OutputLL_k) { +/* MR10 */ if (!GenCC) { +/* MR10 */ errFL(eMsgd(" the lookahead buffer size in C mode is %d token(s) (including the one just recognized)", +/* MR10 */ OutputLL_k), +/* MR10 */ FileStr[a->file],a->line); +/* MR10 */ }; +/* MR10 */ }; +/* MR10 */ }; +/* MR10 */ max_k= CLL_k; +/* MR10 */ }; + +PREDENTRY_EXIT: + return max_k; +} + +/* Find all predicates in a block of alternatives. DO NOT find predicates + * behind the block because that predicate could depend on things set in + * one of the nonoptional blocks + */ + +Predicate * +#ifdef __USE_PROTOS +find_in_aSubBlk( Junction *alt ) +#else +find_in_aSubBlk( alt ) +Junction *alt; +#endif +{ + Predicate *a, *head=NULL, *tail=NULL, *root=NULL; + Junction *p = alt; + + if (MRhoisting) { + return MR_find_in_aSubBlk(alt); + }; + for (; p!=NULL; p=(Junction *)p->p2) + { + /* ignore empty alts */ + if ( p->p1->ntype != nJunction || + ((Junction *)p->p1)->jtype != EndBlk ) + { + a = find_predicates(p->p1); /* get preds for this alt */ + if ( a==NULL ) continue; + + /* make an OR list of predicates */ + if ( head==NULL ) + { + root = new_pred(); + root->expr = PRED_OR_LIST; + head = tail = a; + root->down = head; + } + else { + tail->right = a; + a->left = tail; + a->up = tail->up; + tail = a; + } + } + } + + /* if just one pred, remove OR root */ + if ( root!=NULL && root->down->right == NULL ) + { + Predicate *d = root->down; + free( (char *) root); + return d; + } + + return root; +} + +Predicate * +#ifdef __USE_PROTOS +find_in_aOptBlk( Junction *alt ) +#else +find_in_aOptBlk( alt ) +Junction *alt; +#endif +{ + return find_in_aSubBlk( alt ); +} + +Predicate * +#ifdef __USE_PROTOS +find_in_aLoopBegin( Junction *alt ) +#else +find_in_aLoopBegin( alt ) +Junction *alt; +#endif +{ + return find_in_aSubBlk( (Junction *) alt->p1 ); /* get preds in alts */ +} + +Predicate * +#ifdef __USE_PROTOS +find_in_aPlusBlk( Junction *alt ) +#else +find_in_aPlusBlk( alt ) +Junction *alt; +#endif +{ + require(alt!=NULL&&alt->p2!=NULL, "invalid aPlusBlk"); + return find_in_aSubBlk( alt ); +} + +/* Look for a predicate; + * + * Do not pass anything but Junction nodes; no Actions, Tokens, RuleRefs. + * This means that a "hoisting distance" of zero is the only distance + * allowable. Init actions are ignored. + * + * WARNING: + * Assumes no (..)? block after predicate for the moment. + * Does not check to see if pred is in production that can generate + * a sequence contained in the set of ambiguous tuples. + * + * Return the predicate found if any. + */ + + +Predicate * +#ifdef __USE_PROTOS +find_predicates( Node *alt ) +#else +find_predicates( alt ) +Node *alt; +#endif +{ +#ifdef DBG_PRED + Junction *j; + RuleRefNode *r; + TokNode *t; +#endif + Predicate *pred; + + if ( alt==NULL ) return NULL; + +#ifdef DBG_PRED + switch ( alt->ntype ) + { + case nJunction : + j = (Junction *) alt; + fprintf(stderr, "Junction(in %s)", j->rname); + switch ( j->jtype ) + { + case aSubBlk : + fprintf(stderr,"aSubBlk\n"); + break; + case aOptBlk : + fprintf(stderr,"aOptBlk\n"); + break; + case aLoopBegin : + fprintf(stderr,"aLoopBeginBlk\n"); + break; + case aLoopBlk : + fprintf(stderr,"aLoopBlk\n"); + break; + case aPlusBlk : + fprintf(stderr,"aPlusBlk\n"); + break; + case EndBlk : + fprintf(stderr,"EndBlk\n"); + break; + case RuleBlk : + fprintf(stderr,"RuleBlk\n"); + break; + case Generic : + fprintf(stderr,"Generic\n"); + break; + case EndRule : + fprintf(stderr,"EndRule\n"); + break; + } + break; + case nRuleRef : + r = (RuleRefNode *) alt; + fprintf(stderr, "RuleRef(in %s)\n", r->rname); + break; + case nToken : + t = (TokNode *) alt; + fprintf(stderr, "TokenNode(in %s)%s\n", t->rname, TokenString(t->token)); + break; + case nAction : + fprintf(stderr, "Action\n"); + break; + } +#endif + + switch ( alt->ntype ) + { + case nJunction : + { + Predicate *a, *b; + Junction *p = (Junction *) alt; + + /* lock nodes */ + if ( p->jtype==aLoopBlk || p->jtype==RuleBlk || + p->jtype==aPlusBlk || p->jtype==EndRule ) + { + require(p->pred_lock!=NULL, "rJunc: lock array is NULL"); + if ( p->pred_lock[1] ) + { + return NULL; + } + p->pred_lock[1] = TRUE; + } + + switch ( p->jtype ) + { + case aSubBlk : + a = find_in_aSubBlk(p); + return a; /* nothing is visible past this guy */ + case aOptBlk : + a = find_in_aOptBlk(p); + return a; + case aLoopBegin : + a = find_in_aLoopBegin(p); + return a; + case aLoopBlk : + a = find_in_aSubBlk(p); + p->pred_lock[1] = FALSE; + return a; + case aPlusBlk : + a = find_in_aPlusBlk(p); + p->pred_lock[1] = FALSE; + return a; /* nothing is visible past this guy */ + case RuleBlk : + a = find_predicates(p->p1); + p->pred_lock[1] = FALSE; + return a; + case Generic : + a = find_predicates(p->p1); + b = find_predicates(p->p2); + if ( p->pred_lock!=NULL ) p->pred_lock[1] = FALSE; + if ( a==NULL ) return b; + if ( b==NULL ) return a; + /* otherwise OR the two preds together */ + { + fatal_internal("hit unknown situation during predicate hoisting"); + } + case EndBlk : + case EndRule : /* Find no predicates after a rule ref */ + return NULL; + default: + fatal_internal("this cannot be printed\n"); + break; + } + } + case nAction : + { + ActionNode *p = (ActionNode *) alt; + if ( p->noHoist) return NULL; /* MR12c */ + if ( p->init_action ) return find_predicates(p->next); + if ( p->is_predicate ) + { + Tree *t=NULL; +#ifdef DBG_PRED + fprintf(stderr, "predicate: <<%s>>?\n", p->action); +#endif + if ( p->guardpred!=NULL ) + { + pred = predicate_dup(p->guardpred); + MR_guardPred_plainSet(p,pred); /* MR12c */ + } + else + { + pred = new_pred(); + pred->k = predicateLookaheadDepth(p); + pred->source = p; + pred->expr = p->action; + if ( HoistPredicateContext && pred->k > 1 ) + { + /* MR30 No need to use first_item_is_guess_block_extra + since we know this is an action, not a (...)* or + (...)+ block. + */ + + if ( first_item_is_guess_block((Junction *)p->next) ) + { + warnFL("cannot compute context of predicate in front of (..)? block", + FileStr[p->file], p->line); + } + else + { + ConstrainSearch = 0; +/* MR11 */ if (p->ampersandPred != NULL) { +/* MR11 */ TRAV(p, +/* MR11 */ pred->k, +/* MR11 */ &(pred->completionTree), t); +/* MR11 */ } else { + TRAV(p->next, + pred->k, + &(pred->completionTree), t); + }; + pred->tcontext = t; + MR_check_pred_too_long(pred,pred->completionTree); +#ifdef DBG_PRED + fprintf(stderr, "LL(%d) context:", pred->k); + preorder(t); + fprintf(stderr, "\n"); +#endif + } + } + else if ( HoistPredicateContext && pred->k == 1 ) + { + pred->scontext[1] = empty; + /* MR30 No need to use first_item_is_guess_block_extra + since we know this is an action. + */ + if ( first_item_is_guess_block((Junction *)p->next) ) + { + warnFL("cannot compute context of predicate in front of (..)? block", + FileStr[p->file], p->line); + } + else + { + REACH((Junction *)p->next, + 1, + &(pred->completionSet), + pred->scontext[1]); + MR_check_pred_too_long(pred,pred->completionSet); +#ifdef DBG_PRED + fprintf(stderr, "LL(1) context:"); + s_fprT(stderr, pred->scontext[1]); + fprintf(stderr, "\n"); +#endif + } + } + } + { + Predicate *d = find_predicates(p->next); + Predicate *root; + +/* Warning: Doesn't seem like the up pointers will all be set correctly; + * TJP: that's ok, we're not using them now. + */ + if ( d!=NULL ) + { + root = new_pred(); + root->expr = PRED_AND_LIST; + root->down = pred; + pred->right = d; + pred->up = root; + d->left = pred; + d->up = pred->up; + return root; + } + } + return pred; + } + return NULL; + } + case nRuleRef : + { + Predicate *a; + RuleRefNode *p = (RuleRefNode *) alt; + Junction *r; + Junction *save_MR_RuleBlkWithHalt; + + RuleEntry *q = (RuleEntry *) hash_get(Rname, p->text); + if ( q == NULL ) + { + warnFL( eMsg1("rule %s not defined",p->text), FileStr[p->file], p->line ); + return NULL; + } + r = RulePtr[q->rulenum]; + if ( r->pred_lock[1] ) + { + /* infinite left-recursion; ignore 'cause LL sup 1 (k) analysis + * must have seen it earlier. + */ + return NULL; + } + + /* MR10 There should only be one halt set at a time. */ + /* MR10 Life would have been easier with a global variable */ + /* MR10 (at least for this particular need) */ + /* MR10 Unset the old one and set the new one, later undo. */ + + require(r->end->halt == FALSE,"should only have one halt at a time"); + +/* MR10 */ require(MR_RuleBlkWithHalt == NULL || +/* MR10 */ (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == TRUE), +/* MR10 */ "RuleBlkWithHalt->end not RuleBlk or does not have halt set"); +/* MR10 */ if (MR_RuleBlkWithHalt != NULL) { +/* MR10 */ MR_RuleBlkWithHalt->end->halt=FALSE; +/* MR10 */ }; + +/*** fprintf(stderr,"\nSetting halt on junction #%d\n",r->end->seq); ***/ + + require(r->end->halt == FALSE,"rule->end->halt already set"); + + save_MR_RuleBlkWithHalt=MR_RuleBlkWithHalt; + +/* MR10 */ MR_pointerStackPush(&MR_RuleBlkWithHaltStack,MR_RuleBlkWithHalt); +/* MR10 */ MR_pointerStackPush(&MR_PredRuleRefStack,p); + + r->end->halt = TRUE; +/* MR10 */ MR_RuleBlkWithHalt=r; + + a = find_predicates((Node *)r); + + require(r->end->halt == TRUE,"rule->end->halt not set"); + r->end->halt = FALSE; + +/* MR10 */ MR_pointerStackPop(&MR_PredRuleRefStack); +/* MR10 */ MR_RuleBlkWithHalt=(Junction *) MR_pointerStackPop(&MR_RuleBlkWithHaltStack); + + require (MR_RuleBlkWithHalt==save_MR_RuleBlkWithHalt, + "RuleBlkWithHaltStack not consistent"); + +/* MR10 */ require(MR_RuleBlkWithHalt == NULL || +/* MR10 */ (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == FALSE), +/* MR10 */ "RuleBlkWithHalt->end not RuleBlk or has no halt set"); +/* MR10 */ if (MR_RuleBlkWithHalt != NULL) { +/* MR10 */ MR_RuleBlkWithHalt->end->halt=TRUE; +/* MR10 */ }; + +/*** fprintf(stderr,"\nRestoring halt on junction #%d\n",r->end->seq); ***/ + + if ( a==NULL ) return NULL; + + /* attempt to compute the "local" FOLLOW just like in normal lookahead + * computation if needed + */ + + complete_context_sets(p,a); + complete_context_trees(p,a); + +/* MR10 */ MR_cleanup_pred_trees(a); + + return a; + } + case nToken : + break; + } + + return NULL; +} + +#ifdef __USE_PROTOS +Predicate *MR_find_predicates_and_supp(Node *alt) +#else +Predicate *MR_find_predicates_and_supp(alt) + Node *alt; +#endif +{ + Predicate *p; + + p=find_predicates(alt); + p=MR_suppressK(alt,p); + return p; +} + +Predicate * +#ifdef __USE_PROTOS +new_pred( void ) +#else +new_pred( ) +#endif +{ + Predicate *p = (Predicate *) calloc(1,sizeof(Predicate)); /* MR10 */ + require(p!=NULL, "new_pred: cannot alloc predicate"); + p->scontext[0]=empty; + p->scontext[1]=empty; + p->completionTree=empty; + p->completionSet=empty; + p->plainSet=empty; + return p; +} + +static void +#ifdef __USE_PROTOS +complete_context_sets( RuleRefNode *p, Predicate *a ) +#else +complete_context_sets( p, a ) +RuleRefNode *p; +Predicate *a; +#endif +{ + set rk2, b; + int k2; + +#ifdef DBG_PRED + fprintf(stderr, "enter complete_context_sets\n"); +#endif + for (; a!=NULL; a=a->right) + { + if ( a->expr == PRED_AND_LIST || a->expr == PRED_OR_LIST ) + { + complete_context_sets(p,a->down); + continue; + } + rk2 = b = empty; + while ( !set_nil(a->completionSet) ) + { + k2 = set_int(a->completionSet); + set_rm(k2, a->completionSet); + + REACH(p->next, k2, &rk2, b); + set_orin(&(a->scontext[1]), b); + set_free(b); + } + + set_orin(&(a->completionSet), rk2);/* remember what we couldn't do */ + set_free(rk2); +#ifdef DBG_PRED + fprintf(stderr, "LL(1) context for %s(addr 0x%x) after ruleref:", a->expr, a); + s_fprT(stderr, a->scontext[1]); + fprintf(stderr, "\n"); +#endif +/* complete_context_sets(p, a->down);*/ + } +#ifdef DBG_PRED + fprintf(stderr, "exit complete_context_sets\n"); +#endif +} + +static void +#ifdef __USE_PROTOS +complete_context_trees( RuleRefNode *p, Predicate *a ) +#else +complete_context_trees( p, a ) +RuleRefNode *p; +Predicate *a; +#endif +{ + set rk2; + int k2; + Tree *u; + +#ifdef DBG_PRED + fprintf(stderr, "enter complete_context_trees\n"); +#endif + for (; a!=NULL; a=a->right) + { + if ( a->expr == PRED_AND_LIST || a->expr == PRED_OR_LIST ) + { + complete_context_trees(p, a->down); + continue; + } + rk2 = empty; + + /* any k left to do? if so, link onto tree */ + while ( !set_nil(a->completionTree) ) + { + k2 = set_int(a->completionTree); + set_rm(k2, a->completionTree); + u = NULL; + + TRAV(p->next, k2, &rk2, u); + + /* any subtrees missing k2 tokens, add u onto end */ + a->tcontext = tlink(a->tcontext, u, k2); + Tfree(u); /* MR10 */ + } + set_orin(&(a->completionTree), rk2);/* remember what we couldn't do */ + set_free(rk2); +#ifdef DBG_PRED + fprintf(stderr, "LL(i<%d) context after ruleref:", LL_k); + preorder(a->tcontext); + fprintf(stderr, "\n"); +#endif +/* complete_context_trees(p, a->down);*/ + } +#ifdef DBG_PRED + fprintf(stderr, "exit complete_context_trees\n"); +#endif +} + +/* Walk a list of predicates and return the set of all tokens in scontext[1]'s */ +set +#ifdef __USE_PROTOS +covered_set( Predicate *p ) +#else +covered_set( p ) +Predicate *p; +#endif +{ + set a; + + a = empty; + for (; p!=NULL; p=p->right) + { + if ( p->expr == PRED_AND_LIST || p->expr == PRED_OR_LIST ) + { + set_orin(&a, covered_set(p->down)); + continue; + } + set_orin(&a, p->scontext[1]); + set_orin(&a, covered_set(p->down)); + } + return a; +} + +/* MR10 predicate_free() + MR10 Don't free the leaf nodes since they are part of the action node +*/ + +#ifdef __USE_PROTOS +void predicate_free(Predicate *p) +#else +void predicate_free(p) + Predicate *p; +#endif +{ + if (p == NULL) return; + predicate_free(p->right); + predicate_free(p->down); + if (p->cloned || + p->source == NULL || + p->source->guardpred == NULL || + p->expr == PRED_AND_LIST || + p->expr == PRED_OR_LIST) { + set_free(p->scontext[1]); + set_free(p->completionSet); + set_free(p->completionTree); + set_free(p->plainSet); + Tfree(p->tcontext); + free( (char *) p); + } else { + p->right=NULL; + p->down=NULL; /* MR13 *** debug */ + }; +} + +/* MR10 predicate_dup() */ + +#ifdef __USE_PROTOS +Predicate * predicate_dup_xxx(Predicate *p,int contextToo) +#else +Predicate * predicate_dup_xxx(p,contextToo) + Predicate *p; + int contextToo; +#endif +{ + Predicate *q; + + if (p == NULL) return NULL; + q=new_pred(); + q->down=predicate_dup(p->down); + q->right=predicate_dup(p->right); + + /* + don't replicate expr - it is read-only + and address comparison is used to look + for identical predicates. + */ + + q->expr=p->expr; + q->k=p->k; + q->source=p->source; + q->cloned=1; + q->ampersandStyle=p->ampersandStyle; + q->inverted=p->inverted; + q->predEntry=p->predEntry; + q->plainSet=set_dup(p->plainSet); + + if (contextToo) { + q->tcontext=tdup(p->tcontext); + q->scontext[0]=set_dup(p->scontext[0]); + q->scontext[1]=set_dup(p->scontext[1]); + q->completionTree=set_dup(p->completionTree); + q->completionSet=set_dup(p->completionSet); + }; + + /* don't need to dup "redundant" */ + + return q; + +} + +#ifdef __USE_PROTOS +Predicate * predicate_dup_without_context(Predicate *p) +#else +Predicate * predicate_dup_without_context(p) + Predicate *p; +#endif +{ + return predicate_dup_xxx(p,0); +} + +#ifdef __USE_PROTOS +Predicate * predicate_dup(Predicate *p) +#else +Predicate * predicate_dup(p) + Predicate *p; +#endif +{ + return predicate_dup_xxx(p,1); +} + diff --git a/Tools/CodeTools/Source/Pccts/antlr/proto.h b/Tools/CodeTools/Source/Pccts/antlr/proto.h new file mode 100644 index 0000000000..53035e720e --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/proto.h @@ -0,0 +1,852 @@ +/* + * proto.h -- function prototypes + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2001 + */ + + /* V a r i a b l e s */ + +extern int tp; +extern Junction *SynDiag; +extern char Version[]; +extern char VersionDef[]; +#ifdef __cplusplus +extern void (*fpPrint[])(...); +#else +extern void (*fpPrint[])(); +#endif +#ifdef __cplusplus +extern struct _set (*fpReach[])(...); +#else +extern struct _set (*fpReach[])(); +#endif +#ifdef __cplusplus +extern struct _tree *(*fpTraverse[])(...); +#else +extern struct _tree *(*fpTraverse[])(); +#endif +#ifdef __cplusplus +extern void (**fpTrans)(...); +#else +extern void (**fpTrans)(); +#endif +#ifdef __cplusplus +extern void (**fpJTrans)(...); +#else +extern void (**fpJTrans)(); +#endif +#ifdef __cplusplus +extern void (*C_Trans[NumNodeTypes+1])(...); +#else +extern void (*C_Trans[])(); +#endif +#ifdef __cplusplus +extern void (*C_JTrans[NumJuncTypes+1])(...); +#else +extern void (*C_JTrans[])(); +#endif +extern int BlkLevel; +extern int CurFile; +extern char *CurPredName; +extern char *CurRule; +extern int CurRuleDebug; /* MR13 */ +extern Junction *CurRuleBlk; +extern RuleEntry *CurRuleNode; +extern ListNode *CurElementLabels; +extern ListNode *CurAstLabelsInActions; /* MR27 */ +extern ListNode *ContextGuardPredicateList; /* MR13 */ +extern ListNode *CurActionLabels; +extern int numericActionLabel; /* MR10 << ... $1 ... >> or << ... $1 ... >>? */ +extern ListNode *NumericPredLabels; /* MR10 << ... $1 ... >>? ONLY */ +extern char *FileStr[]; +extern int NumFiles; +extern int EpToken; +extern int WildCardToken; +extern Entry **Tname, + **Texpr, + **Rname, + **Fcache, + **Tcache, + **Elabel, + **Sname, + **Pname; /* MR11 */ +extern ListNode *ExprOrder; +extern ListNode **Cycles; +extern int TokenNum; +extern int LastTokenCounted; +extern ListNode *BeforeActions, *AfterActions, *LexActions; + +/* MR1 */ +/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ +/* MR1 via #lexmember <<....>> & #lexprefix <<...>> */ +/* MR1 */ + +extern ListNode *LexMemberActions; /* MR1 */ +extern ListNode *LexPrefixActions; /* MR1 */ + +extern set *fset; /* for constrained search */ /* MR11 */ +extern int maxk; /* for constrained search */ /* MR11 */ +extern int Save_argc; /* MR10 */ +extern char **Save_argv; /* MR10 */ +extern ListNode *eclasses, *tclasses; +extern char *HdrAction; +extern char *FirstAction; /* MR11 */ +extern FILE *ErrFile; +extern char *RemapFileName; +extern char *ErrFileName; +extern char *DlgFileName; +extern char *DefFileName; +extern char *ModeFileName; +extern char *StdMsgName; +extern int NumRules; +extern Junction **RulePtr; +extern int LL_k; +extern int CLL_k; +extern char *decodeJType[]; +extern int PrintOut; +extern int PrintAnnotate; +extern int CodeGen; +extern int LexGen; +extern int esetnum; +extern int setnum; +extern int wordnum; +extern int GenAST; +extern int GenANSI; +extern int **FoStack; +extern int **FoTOS; +extern int GenExprSetsOpt; +extern FILE *DefFile; +extern int CannotContinue; +extern int GenCR; +extern int GenLineInfo; +extern int GenLineInfoMS; +extern int action_file, action_line; +extern int TraceGen; +extern int CurAmbigAlt1, CurAmbigAlt2, CurAmbigline, CurAmbigfile; +extern char *CurAmbigbtype; +extern int elevel; +extern int GenEClasseForRules; +extern FILE *input, *output; +extern char **TokenStr, **ExprStr; +extern int CurrentLexClass, NumLexClasses; +extern LClass lclass[]; +extern char LexStartSymbol[]; +extern char *CurRetDef; +extern char *CurParmDef; +extern int OutputLL_k; +extern int TreeResourceLimit; +extern int DemandLookahead; +extern char *RulePrefix; +extern int GenStdPccts; +extern char *stdpccts; +extern int ParseWithPredicates; +extern int ConstrainSearch; +extern int PURIFY; /* MR23 */ + +extern set MR_CompromisedRules; /* MR14 */ +extern int MR_AmbSourceSearch; /* MR11 */ +extern int MR_SuppressSearch; /* MR13 */ +extern int MR_AmbSourceSearchGroup; /* MR11 */ +extern int MR_AmbSourceSearchChoice; /* MR11 */ +extern int MR_AmbSourceSearchLimit; /* MR11 */ +extern int MR_usingPredNames; /* MR11 */ +extern int MR_ErrorSetComputationActive; /* MR14 */ +extern char *MR_AmbAidRule; /* MR11 */ +extern int MR_AmbAidLine; /* MR11 */ +extern int MR_AmbAidMultiple; /* MR11 */ +extern int MR_AmbAidDepth; /* MR11 */ +extern int MR_skipped_e3_report; /* MR11 */ +extern int MR_matched_AmbAidRule; /* MR11 */ +extern int MR_Inhibit_Tokens_h_Gen; /* MR13 */ +extern int NewAST; /* MR13 */ +extern int tmakeInParser; /* MR23 */ +extern int AlphaBetaTrace; /* MR14 */ +extern int MR_BlkErr; /* MR21 */ +extern int MR_AlphaBetaWarning; /* MR14 */ +extern int MR_AlphaBetaMessageCount; /* MR14 */ +extern int MR_MaintainBackTrace; /* MR14 */ +extern int MR_BadExprSets; /* MR13 */ +extern int FoundGuessBlk; +extern int FoundException; +extern int FoundAtOperator; /* MR6 */ +extern int FoundExceptionGroup; /* MR6 */ +extern int WarningLevel; +extern int UseStdout; /* MR6 */ +extern int TabWidth; /* MR6 */ +extern int pLevel; +extern int pAlt1; +extern int pAlt2; +extern int AImode; +extern int HoistPredicateContext; +extern int MRhoisting; /* MR9 */ +extern int MRhoistingk; /* MR13 */ +extern int MR_debugGenRule; /* MR11 */ +extern int GenCC; +extern char *ParserName; +extern char *StandardSymbols[]; +extern char *ASTSymbols[]; +extern set reserved_positions; +extern set all_tokens; +extern set imag_tokens; +extern set tokclasses; +extern ListNode *ForcedTokens; +extern int *TokenInd; +extern FILE *Parser_h, *Parser_c; +extern char CurrentClassName[]; +extern int no_classes_found; +extern char Parser_h_Name[]; +extern char Parser_c_Name[]; +extern char MRinfoFile_Name[]; /* MR10 */ +extern FILE *MRinfoFile; /* MR10 */ +extern int MRinfo; /* MR10 */ +extern int MRinfoSeq; /* MR10 */ +extern int InfoP; /* MR10 */ +extern int InfoT; /* MR10 */ +extern int InfoF; /* MR10 */ +extern int InfoM; /* MR10 */ +extern int InfoO; /* MR12 */ +extern int PotentialSuppression; /* MR10 */ +extern int PotentialDummy; /* MR10 */ +extern int TnodesInUse; /* MR10 */ +extern int TnodesPeak; /* MR10 */ +extern int TnodesReportThreshold; /* MR11 */ +extern int TnodesAllocated; /* MR10 */ +extern char *ClassDeclStuff; /* MR10 */ +extern char *BaseClassName; /* MR22 */ +extern ListNode *class_before_actions, *class_after_actions; +extern char *UserTokenDefsFile; +extern int UserDefdTokens; +extern ListNode *MetaTokenNodes; +extern char *OutputDirectory; +extern int DontCopyTokens; +extern int LTinTokenAction; /* MR23 */ +extern set AST_nodes_refd_in_actions; +extern ListNode *CurExGroups; +extern int CurBlockID; +extern int CurAltNum; +extern Junction *CurAltStart; +extern Junction *OuterAltStart; /* chain exception groups MR7 */ +extern ExceptionGroup *DefaultExGroup; +extern int NumSignals; +extern int ContextGuardTRAV; +extern Junction *MR_RuleBlkWithHalt; /* MR10 */ +extern PointerStack MR_BackTraceStack; /* MR10 */ +extern PointerStack MR_PredRuleRefStack; /* MR10 */ +extern PointerStack MR_RuleBlkWithHaltStack; /* MR10 */ + +/* */ +/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */ +/* MR1 in DLG action */ +/* */ +extern int tokenActionActive; /* MR1 */ + +extern char *PRED_OR_LIST; /* MR10 */ +extern char *PRED_AND_LIST; /* MR10 */ + +#ifdef __VMS +#define STRICMP strcasecmp /* MR21 */ +#else +#define STRICMP stricmp /* MR21 */ +#endif + +/* MR26 */ +#ifdef PCCTS_USE_STDARG +extern Tree *tmake(Tree *root, ...); +#else +extern Tree *tmake(); +#endif + +#ifdef __USE_PROTOS +extern int STRICMP(const char*, const char*); +extern void istackreset(void); +extern int istacksize(void); +extern void pushint(int); +extern int popint( void ); +extern int istackempty( void ); +extern int topint( void ); +extern void NewSetWd( void ); +extern void DumpSetWd( void ); +extern void DumpSetWdForC( void ); +extern void DumpSetWdForCC( void ); +extern void NewSet( void ); +extern void FillSet( set ); +extern void ComputeErrorSets( void ); +extern void ComputeTokSets( void ); +extern void SubstErrorClass( set * ); +extern int DefErrSet( set *, int, char * ); +extern int DefErrSetForC( set *, int, char * ); +extern int DefErrSetForCC( set *, int, char * ); +extern int DefErrSet1(int, set *, int, char *); /* MR21 */ +extern int DefErrSetForC1(int, set *, int, char *, const char* ); /* MR21 */ +extern int DefErrSetForCC1(int, set *, int, char *, const char* ); /* MR21 */ +extern int DefErrSetWithSuffix(int, set *, int, char *, const char *); /* MR21 */ +extern void GenErrHdr( void ); +extern void dumpExpr( FILE *, char * ); +extern void addParm( Node *, char * ); +extern Graph buildAction( char *, int, int, int ); +extern Graph buildToken( char * ); +extern Graph buildWildCard( char * ); +extern Graph buildRuleRef( char * ); +extern Graph Or( Graph, Graph ); +extern Graph Cat( Graph, Graph ); +extern Graph makeOpt( Graph, int, char *); +extern Graph makeBlk( Graph, int, char *); +extern Graph makeLoop( Graph, int, char *); +extern Graph makePlus( Graph, int, char *); +extern Graph emptyAlt( void ); +extern Graph emptyAlt3( void ); +extern TokNode * newTokNode( void ); +extern RuleRefNode * newRNode( void ); +extern Junction * newJunction( void ); +extern ActionNode * newActionNode( void ); +extern char * makelocks( void ); +extern void preorder( Tree * ); +extern Tree * tnode( int ); +extern void _Tfree( Tree * ); +extern Tree * tdup( Tree * ); +extern int is_single_tuple( Tree * ); +extern Tree * tappend( Tree *, Tree * ); +extern void Tfree( Tree * ); +extern Tree * tlink( Tree *, Tree *, int ); +extern Tree * tshrink( Tree * ); +extern Tree * tflatten( Tree * ); +extern Tree * tJunc( Junction *, int, set * ); +extern Tree * tRuleRef( RuleRefNode *, int, set * ); +extern Tree * tToken( TokNode *, int, set * ); +extern Tree * tAction( ActionNode *, int, set * ); +extern int tmember( Tree *, Tree * ); +extern int tmember_constrained( Tree *, Tree * ); +extern Tree * tleft_factor( Tree * ); +extern Tree * trm_perm( Tree *, Tree * ); +extern void tcvt( set *, Tree * ); +extern Tree * permute( int, int ); +extern Tree * VerifyAmbig( Junction *, Junction *, unsigned **, set *, Tree **, Tree **, int * ); +extern set rJunc( Junction *, int, set * ); +extern set rRuleRef( RuleRefNode *, int, set * ); +extern set rToken( TokNode *, int, set * ); +extern set rAction( ActionNode *, int, set * ); +extern void HandleAmbiguity( Junction *, Junction *, Junction *, int ); +extern set First( Junction *, int, int, int * ); +extern void freeBlkFsets( Junction * ); +extern void genAction( ActionNode * ); +extern void genRuleRef( RuleRefNode * ); +extern void genToken( TokNode * ); +extern void genOptBlk( Junction * ); +extern void genLoopBlk( Junction *, Junction *, Junction *, int ); +extern void genLoopBegin( Junction * ); +extern void genPlusBlk( Junction * ); +extern void genSubBlk( Junction * ); +extern void genRule( Junction * ); +extern void genJunction( Junction * ); +extern void genEndBlk( Junction * ); +extern void genEndRule( Junction * ); +extern void genHdr( int ); +extern void genHdr1( int ); +extern void dumpAction( char *, FILE *, int, int, int, int ); +extern void dumpActionPlus(ActionNode*, char *, FILE *, int, int, int, int ); /* MR21 */ +extern Entry ** newHashTable( void ); +extern Entry * hash_add( Entry **, char *, Entry * ); +extern Entry * hash_get( Entry **, char * ); +extern void hashStat( Entry ** ); +extern char * mystrdup( char * ); +extern void genLexDescr( void ); +extern void dumpLexClasses( FILE * ); +extern void genDefFile( void ); +extern void DumpListOfParmNames( char *, FILE *, int ); /* MR5 janm 26-May-97 */ +extern int DumpNextNameInDef( char **, FILE * ); +extern void DumpOldStyleParms( char *, FILE * ); +extern void DumpType( char *, FILE * ); +extern int strmember( char *, char * ); +/* extern int HasComma( char * ); MR23 Replaced by hasMultipleOperands() */ +extern void DumpRetValStruct( FILE *, char *, int ); +extern char * StripQuotes( char * ); +extern int main( int, char *[] ); +extern void readDescr( void ); +extern FILE * NextFile( void ); +extern char * outnameX( char *, char *); +extern char * outname( char * ); +extern void fatalFL( char *, char *, int ); +extern void fatal_intern( char *, char *, int ); +extern void cleanUp( void ); +extern char * eMsg3( char *, char *, char *, char * ); +extern char * eMsgd( char *, int ); +extern char * eMsgd2( char *, int, int ); +extern void s_fprT( FILE *, set ); +extern char * TerminalString( int ); +extern void lexclass( char * ); +extern void lexmode( int ); +extern int LexClassIndex( char * ); +extern int hasAction( char * ); +extern void setHasAction( char *, char * ); +extern int addTname( char * ); +extern int addTexpr( char * ); +extern int Tnum( char * ); +extern void Tklink( char *, char * ); +extern Entry * newEntry( char *, int ); +extern void list_add( ListNode **, void * ); +extern void list_free( ListNode **, int freeData ); /* MR10 */ +extern void list_apply( ListNode *, void (*)(void *) ); +extern int list_search_cstring (ListNode *, char *); /* MR27 */ +extern char * Fkey( char *, int, int ); +extern void FoPush( char *, int ); +extern void FoPop( int ); +extern void RegisterCycle( char *, int ); +extern void ResolveFoCycles( int ); +extern void pJunc( Junction * ); +extern void pRuleRef( RuleRefNode * ); +extern void pToken( TokNode * ); +extern void pAction( ActionNode * ); +extern void FoLink( Node * ); +extern void addFoLink( Node *, char *, Junction * ); +extern void GenCrossRef( Junction * ); +extern void defErr( char *, long, long, long, long, long, long ); +extern void genStdPCCTSIncludeFile(FILE *,char *); /* MR10 */ +extern char * pcctsBaseName(char *); /* MR32 */ +extern Predicate *find_predicates(Node *); /* MR10 */ +extern Predicate *MR_find_predicates_and_supp(Node *); /* MR13 */ +extern int predicateLookaheadDepth(ActionNode *); /* MR10 */ +extern void predicate_free(Predicate *); /* MR10 */ +extern Predicate * predicate_dup(Predicate *); /* MR10 */ +extern Predicate * predicate_dup_without_context(Predicate *); /* MR11 */ +extern void GenRulePrototypes(FILE *, Junction *); +extern Junction *first_item_is_guess_block(Junction *); +extern Junction *first_item_is_guess_block_extra(Junction * q); /* MR30 */ +extern Junction *analysis_point(Junction *); +extern Tree *make_tree_from_sets(set *, set *); +extern Tree *tdup_chain(Tree *); +extern Tree *tdif(Tree *, Predicate *, set *, set *); +extern set covered_set(Predicate *); +extern void AmbiguityDialog(Junction *, int, Junction *, Junction *, int *, int *); +extern void dumpAmbigMsg(set *, FILE *, int); +extern void GenRuleFuncRedefs(FILE *, Junction *); +extern void GenPredefinedSymbolRedefs(FILE *); +extern void GenASTSymbolRedefs(FILE *); +extern void GenRemapFile(void); +extern void GenSetRedefs(FILE *); +extern ForcedToken *newForcedToken(char *, int); +extern void RemapForcedTokens(void); +extern char *TokenOrExpr(int); +extern void setUpperRange(TokNode *, char *); +extern void GenParser_c_Hdr(void); +extern void GenParser_h_Hdr(void); +extern void GenRuleMemberDeclarationsForCC(FILE *, Junction *); +extern int addForcedTname( char *, int ); +extern char *OutMetaName(char *); +extern void OutFirstSetSymbol(Junction *q, char *); /* MR21 */ +extern void warnNoFL(char *err); +extern void warnFL(char *err,char *f,int l); +extern void warn(char *err); +extern void warnNoCR( char *err ); +extern void errNoFL(char *err); +extern void errFL(char *err,char *f,int l); +extern void err(char *err); +extern void errNoCR( char *err ); +extern void genPredTree( Predicate *p, Node *j, int ,int); +extern UserAction *newUserAction(char *); +extern char *gate_symbol(char *name); +extern char *makeAltID(int blockid, int altnum); +extern void DumpRemainingTokSets(void); +extern void DumpANSIFunctionArgDef(FILE *f, Junction *q, int bInit); /* MR23 */ +extern void DumpFormals(FILE *, char *, int bInit); /* MR23 */ +extern char* hideDefaultArgs(const char* pdecl); /* MR22 VHS */ +extern Predicate *computePredFromContextGuard(Graph,int *msgDone); /* MR21 */ +extern void recomputeContextGuard(Predicate *); /* MR13 */ +extern Predicate *new_pred(void); +extern void chkGTFlag(void); +extern void leAdd(LabelEntry *); /* MR7 */ +extern void leFixup(void); /* MR7 */ +extern void egAdd(ExceptionGroup *); /* MR7 */ +extern void egFixup(void); /* MR7 */ +extern void altAdd(Junction *); /* MR7 */ +extern void altFixup(void); /* MR7 */ +extern Predicate * MR_find_in_aSubBlk(Junction *alt); /* MR10 */ +extern Predicate * MR_predFlatten(Predicate *p); /* MR10 */ +extern Predicate * MR_predSimplifyALL(Predicate *p); /* MR10 */ +extern Predicate * MR_predSimplifyALLX(Predicate *p,int skipPass3); /* MR10 */ +extern int MR_allPredLeaves(Predicate *p); /* MR10 */ +extern void MR_cleanup_pred_trees(Predicate *p); /* MR10 */ +extern int MR_predicate_context_completed(Predicate *p); /* MR10 */ +extern void MR_check_pred_too_long(Predicate *p,set completion); /* MR10 */ +extern Tree * MR_remove_epsilon_from_tree(Tree *t); /* MR10 */ +extern Tree * MR_computeTreeAND(Tree *l,Tree *r); /* MR10 */ +extern int MR_tree_equ(Tree *big, Tree *small); /* MR10 */ +extern set MR_First(int ck,Junction *j,set *incomplete); /* MR10 */ +extern set MR_compute_pred_set(Predicate *p); /* MR10 */ +extern Tree * MR_compute_pred_tree_context(Predicate *p); /* MR10 */ +extern int MR_pointerStackPush(PointerStack *,void *); /* MR10 */ +extern void * MR_pointerStackPop(PointerStack *); /* MR10 */ +extern void * MR_pointerStackTop(PointerStack *); /* MR10 */ +extern void MR_pointerStackReset(PointerStack *); /* MR10 */ +extern void MR_backTraceReport(void); /* MR10 */ +extern void MR_alphaBetaTraceReport(void); /* MR14 */ +extern void MR_dumpRuleSet(set); /* MR14 */ +extern void MR_predContextPresent(Predicate *p,int *,int *); /* MR10 */ +extern void MR_dumpPred(Predicate *p,int withContext); /* MR10 */ +extern void MR_dumpPred1(int,Predicate *p,int withContext); /* MR10 */ +extern void MR_xxxIndent(FILE *f,int depth); /* MR11 */ +extern void MR_outputIndent(int depth); /* MR11 */ +extern void MR_stderrIndent(int depth); /* MR11 */ +extern Junction * MR_ruleReferenced(RuleRefNode *rrn); /* MR10 */ +extern Junction * MR_nameToRuleBlk(char *); /* MR10 */ +extern void MR_releaseResourcesUsedInRule(Node *); /* MR10 */ +extern void MR_dumpTreeX(int depth,Tree *t,int across); /* MR10 */ +extern void MR_dumpTreeF(FILE *f,int depth,Tree *t,int across); /* MR10 */ +extern void DumpFcache(void); /* MR10 */ +extern void MR_dumpTokenSet(FILE *f,int depth,set s); /* MR10 */ +extern void MR_traceAmbSource(set *,Junction *,Junction *); /* MR11 */ +extern void MR_traceAmbSourceK(Tree *,Junction *a1,Junction *a2); /* MR11 */ +extern void MR_traceAmbSourceKclient(void); /* MR20 */ +extern Node *MR_advance(Node *); /* MR11 */ +extern int MR_offsetFromRule(Node *); /* MR11 */ +extern char *MR_ruleNamePlusOffset(Node *); /* MR11 */ +extern int MR_max_height_of_tree(Tree *); /* MR11 */ +extern int MR_all_leaves_same_height(Tree *,int); /* MR11 */ +extern void MR_projectTreeOntoSet(Tree *t,int k,set *); /* MR11 */ +extern Tree *MR_make_tree_from_set(set); /* MR11 */ +extern Predicate *MR_removeRedundantPredPass3(Predicate *); /* MR11 */ +extern void MR_pred_depth(Predicate *,int *); /* MR11 */ +extern int MR_comparePredicates(Predicate *,Predicate *); /* MR11 */ +extern Predicate * MR_unfold(Predicate *); /* MR11 */ +extern void MR_simplifyInverted(Predicate *,int); /* MR11 */ +extern int MR_secondPredicateUnreachable /* MR11 */ + (Predicate *first,Predicate *second); /* MR11 */ +extern void MR_clearPredEntry(Predicate *); /* MR11 */ +extern void MR_orphanRules(FILE *); /* MR12 */ +extern void MR_merge_contexts(Tree *); /* MR12 */ +extern int ci_strequ(char *,char *); /* MR12 */ +extern void MR_guardPred_plainSet(ActionNode *anode,Predicate *); /* MR12c */ +extern void MR_suppressSearchReport(void); /* MR12c */ +extern Predicate * MR_suppressK(Node *,Predicate *); /* MR13 */ +extern void MR_backTraceDumpItem(FILE *,int skip,Node *n); /* MR13 */ +extern void MR_backTraceDumpItemReset(void); /* MR13 */ +extern Junction * MR_junctionWithoutP2(Junction *); /* MR13 */ +extern void MR_setConstrainPointer(set *); /* MR18 */ +extern void BlockPreambleOption(Junction *q, char * pSymbol); /* MR23 */ +extern char* getInitializer(char *); /* MR23 */ +extern char *endFormal(char *pStart, /* MR23 */ + char **ppDataType, /* MR23 */ + char **ppSymbol, /* MR23 */ + char **ppEqualSign, /* MR23 */ + char **ppValue, /* MR23 */ + char **ppSeparator, /* MR23 */ + int *pNext); /* MR23 */ +extern char *strBetween(char *pStart, /* MR23 */ + char *pNext, /* MR23 */ + char *pStop); /* MR23 */ +extern int hasMultipleOperands(char *); /* MR23 */ +extern void DumpInitializers(FILE*, RuleEntry*, char*); /* MR23 */ +extern int isTermEntryTokClass(TermEntry *); /* MR23 */ +extern int isEmptyAlt(Node *, Node *); /* MR23 */ +#else +extern int STRICMP(); +extern void istackreset(); +extern int istacksize(); +extern void pushint(); +extern int popint(); +extern int istackempty(); +extern int topint(); +extern void NewSetWd(); +extern void DumpSetWd(); +extern void DumpSetWdForC(); +extern void DumpSetWdForCC(); +extern void NewSet(); +extern void FillSet(); +extern void ComputeErrorSets(); +extern void ComputeTokSets(); +extern void SubstErrorClass(); +extern int DefErrSet(); +extern int DefErrSetForC(); +extern int DefErrSetForCC(); +extern int DefErrSet1(); +extern int DefErrSetForC1(); +extern int DefErrSetForCC1(); +extern int DefErrSetWithSuffix(); /* MR21 */ +extern void GenErrHdr(); +extern void dumpExpr(); +extern void addParm(); +extern Graph buildAction(); +extern Graph buildToken(); +extern Graph buildWildCard(); +extern Graph buildRuleRef(); +extern Graph Or(); +extern Graph Cat(); +extern Graph makeOpt(); +extern Graph makeBlk(); +extern Graph makeLoop(); +extern Graph makePlus(); +extern Graph emptyAlt(); +extern Graph emptyAlt3(); +extern TokNode * newTokNode(); +extern RuleRefNode * newRNode(); +extern Junction * newJunction(); +extern ActionNode * newActionNode(); +extern char * makelocks(); +extern void preorder(); +extern Tree * tnode(); +extern void _Tfree(); +extern Tree * tdup(); +extern int is_single_tuple(); +extern Tree * tappend(); +extern void Tfree(); +extern Tree * tlink(); +extern Tree * tshrink(); +extern Tree * tflatten(); +extern Tree * tJunc(); +extern Tree * tRuleRef(); +extern Tree * tToken(); +extern Tree * tAction(); +extern int tmember(); +extern int tmember_constrained(); +extern Tree * tleft_factor(); +extern Tree * trm_perm(); +extern void tcvt(); +extern Tree * permute(); +extern Tree * VerifyAmbig(); +extern set rJunc(); +extern set rRuleRef(); +extern set rToken(); +extern set rAction(); +extern void HandleAmbiguity(); +extern set First(); +extern void freeBlkFsets(); +extern void genAction(); +extern void genRuleRef(); +extern void genToken(); +extern void genOptBlk(); +extern void genLoopBlk(); +extern void genLoopBegin(); +extern void genPlusBlk(); +extern void genSubBlk(); +extern void genRule(); +extern void genJunction(); +extern void genEndBlk(); +extern void genEndRule(); +extern void genHdr(); +extern void genHdr1(); +extern void dumpAction(); +extern void dumpActionPlus(); /* MR21 */ +extern Entry ** newHashTable(); +extern Entry * hash_add(); +extern Entry * hash_get(); +extern void hashStat(); +extern char * mystrdup(); +extern void genLexDescr(); +extern void dumpLexClasses(); +extern void genDefFile(); +extern void DumpListOfParmNames(); /* MR5 janm 26-May-97 */ +extern int DumpNextNameInDef(); +extern void DumpOldStyleParms(); +extern void DumpType(); +extern int strmember(); +/* extern int HasComma(); MR23 Replaced by hasMultipleOperands() */ +extern void DumpRetValStruct(); +extern char * StripQuotes(); +extern int main(); +extern void readDescr(); +extern FILE * NextFile(); +extern char * outnameX(); +extern char * outname(); +extern void fatalFL(); +extern void fatal_intern(); +extern void cleanUp(); +extern char * eMsg3(); +extern char * eMsgd(); +extern char * eMsgd2(); +extern void s_fprT(); +extern char * TerminalString(); +extern void lexclass(); +extern void lexmode(); +extern int LexClassIndex(); +extern int hasAction(); +extern void setHasAction(); +extern int addTname(); +extern int addTexpr(); +extern int Tnum(); +extern void Tklink(); +extern Entry * newEntry(); +extern void list_add(); +extern void list_free(); /* MR10 */ +extern void list_apply(); +extern int list_search_cstring (); /* MR27 */ +extern char * Fkey(); +extern void FoPush(); +extern void FoPop(); +extern void RegisterCycle(); +extern void ResolveFoCycles(); +extern void pJunc(); +extern void pRuleRef(); +extern void pToken(); +extern void pAction(); +extern void FoLink(); +extern void addFoLink(); +extern void GenCrossRef(); +extern void defErr(); +extern void genStdPCCTSIncludeFile(); +extern char * pcctsBaseName(); /* MR32 */ +extern Predicate *find_predicates(); +extern Predicate *MR_find_predicates_and_supp(); /* MR13 */ +extern int predicateLookaheadDepth(); /* MR10 */ +extern void predicate_free(); /* MR10 */ +extern Predicate * predicate_dup(); /* MR10 */ +extern Predicate * predicate_dup_without_context(); /* MR11 */ +extern void GenRulePrototypes(); +extern Junction *first_item_is_guess_block(); +extern Junction *first_item_is_guess_block_extra(); /* MR30 */ +extern Junction *analysis_point(); +extern Tree *make_tree_from_sets(); +extern Tree *tdup_chain(); +extern Tree *tdif(); +extern set covered_set(); +extern void AmbiguityDialog(); +extern void dumpAmbigMsg(); +extern void GenRuleFuncRedefs(); +extern void GenPredefinedSymbolRedefs(); +extern void GenASTSymbolRedefs(); +extern void GenRemapFile(); +extern void GenSetRedefs(); +extern ForcedToken *newForcedToken(); +extern void RemapForcedTokens(); +extern char *TokenOrExpr(); +extern void setUpperRange(); +extern void GenParser_c_Hdr(); +extern void GenParser_h_Hdr(); +extern void GenRuleMemberDeclarationsForCC(); +extern int addForcedTname(); +extern char *OutMetaName(); +extern void OutFirstSetSymbol(); /* MR21 */ +extern void warnNoFL(); +extern void warnFL(); +extern void warn(); +extern void warnNoCR(); +extern void errNoFL(); +extern void errFL(); +extern void err(); +extern void errNoCR(); +extern void genPredTree(); +extern UserAction *newUserAction(); +extern char *gate_symbol(); +extern char *makeAltID(); +extern void DumpRemainingTokSets(); +extern void DumpANSIFunctionArgDef(); +extern void DumpFormals(); /* MR23 */ +extern char* hideDefaultArgs(); /* MR22 VHS */ +extern Predicate *computePredFromContextGuard(); +extern void recomputeContextGuard(); /* MR13 */ +extern Predicate *new_pred(); +extern void chkGTFlag(); +extern void leAdd(); /* MR7 */ +extern void leFixup(); /* MR7 */ +extern void egAdd(); /* MR7 */ +extern void egFixup(); /* MR7 */ +extern void altAdd(); /* MR7 */ +extern void altFixup(); /* MR7 */ +extern Predicate * MR_find_in_aSubBlk(); /* MR10 */ +extern Predicate * MR_predFlatten(); /* MR10 */ +extern Predicate * MR_predSimplifyALL(); /* MR10 */ +extern Predicate * MR_predSimplifyALLX(); /* MR10 */ +extern void MR_cleanup_pred_trees(); /* MR10 */ +extern int MR_allPredLeaves(); /* MR10 */ +extern int MR_predicate_context_completed(); /* MR10 */ +extern void MR_check_pred_too_long(); /* MR10 */ +extern Tree * MR_remove_epsilon_from_tree(); /* MR10 */ +extern Tree * MR_computeTreeAND(); /* MR10 */ +extern int MR_tree_equ(); /* MR10 */ +extern set MR_First(); /* MR10 */ +extern set MR_compute_pred_set(); /* MR10 */ +extern Tree * MR_compute_pred_tree_context(); /* MR10 */ +extern int MR_pointerStackPush(); /* MR10 */ +extern void * MR_pointerStackPop(); /* MR10 */ +extern void * MR_pointerStackTop(); /* MR10 */ +extern void MR_pointerStackReset(); /* MR10 */ +extern void MR_backTraceReport(); /* MR10 */ +extern void MR_alphaBetaTraceReport(); /* MR14 */ +extern void MR_dumpRuleSet(); /* MR14 */ +extern void MR_predContextPresent(); /* MR10 */ +extern void MR_dumpPred(); /* MR10 */ +extern void MR_dumpPred1(); /* MR10 */ +extern void MR_xxxIndent(); /* MR11 */ +extern void MR_stderrIndent(); /* MR11 */ +extern void MR_outputIndent(); /* MR11 */ +extern Junction * MR_ruleReferenced(); /* MR10 */ +extern void MR_releaseResourcesUsedInRule(); /* MR10 */ +extern void MR_dumpTreeX(); /* MR10 */ +extern void MR_dumpTreeF(); /* MR10 */ +extern void DumpFcache(); /* MR10 */ +extern void MR_dumpTokenSet(); /* MR10 */ +extern void MR_traceAmbSource(); /* MR11 */ +extern Node *MR_advance(); /* MR11 */ +extern int MR_offsetFromRule(); /* MR11 */ +extern char *MR_ruleNamePlusOffset(); /* MR11 */ +extern void MR_traceAmbSourceK(); /* MR11 */ +extern void MR_traceAmbSourceKclient(); /* [i_a] added */ +extern int MR_max_height_of_tree(); /* MR11 */ +extern int MR_all_leaves_same_height(); /* MR11 */ +extern void MR_projectTreeOntoSet(); /* MR11 */ +extern Tree *MR_make_tree_from_set(); /* MR11 */ +extern Predicate *MR_removeRedundantPredPass3(); /* MR11 */ +extern void MR_pred_depth(); /* MR11 */ +extern int MR_comparePredicates(); /* MR11 */ +extern Predicate * MR_unfold(); /* MR11 */ +extern void MR_simplifyInverted(); /* MR11 */ +extern int MR_secondPredicateUnreachable(); /* MR11 */ +extern Junction * MR_nameToRuleBlk(); /* MR10 */ +extern void MR_clearPredEntry(); /* MR11 */ +extern void MR_orphanRules(); /* MR12 */ +extern void MR_merge_contexts(); /* MR12 */ +extern int ci_strequ(); /* MR12 */ +extern void MR_guardPred_plainSet(); /* MR12c */ +extern void MR_suppressSearchReport(); /* MR12c */ +extern Predicate * MR_suppressK(); /* MR13 */ +extern void MR_backTraceDumpItem(); /* MR13 */ +extern void MR_backTraceDumpItemReset(); /* MR13 */ +extern Junction * MR_junctionWithoutP2(); /* MR13 */ +extern void MR_setConstrainPointer(); /* MR18 */ +extern void BlockPreambleOption(); /* MR23 */ +extern char* getInitializer(); /* MR23 */ +extern int hasMultipleOperands(); /* MR23 */ +extern char *endFormal(); /* MR23 */ +extern char *strBetween(); /* MR23 */ +extern void DumpInitializers(); /* MR23 */ +extern int isTermEntryTokClass(); /* MR23 */ +extern int isEmptyAlt(); + +#endif + +#ifdef __USE_PROTOS +#include +#endif + +/* MR20 G. Hobbelt Create proper externs for dlg variables */ + +extern set attribsRefdFromAction; +extern int inAlt; +extern int UsedOldStyleAttrib; +extern int UsedNewStyleLabel; + +#define MAX_BLK_LEVEL 100 /* MR23 */ +extern int CurBlockID_array[MAX_BLK_LEVEL]; /* MR23 */ +extern int CurAltNum_array[MAX_BLK_LEVEL]; /* MR23 */ diff --git a/Tools/CodeTools/Source/Pccts/antlr/scan.c b/Tools/CodeTools/Source/Pccts/antlr/scan.c new file mode 100644 index 0000000000..9b4bde08e6 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/scan.c @@ -0,0 +1,5735 @@ + +/* parser.dlg -- DLG Description of scanner + * + * Generated from: antlr.g + * + * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001 + * Purdue University Electrical Engineering + * With AHPCRC, University of Minnesota + * ANTLR Version 1.33MR33 + */ + +#define ANTLR_VERSION 13333 +#include "pcctscfg.h" +#include "pccts_stdio.h" + +#include "pcctscfg.h" +#include "set.h" +#include +#include "syn.h" +#include "hash.h" +#include "generic.h" +#define zzcr_attr(attr,tok,t) +#include "antlr.h" +#include "tokens.h" +#include "dlgdef.h" +LOOKAHEAD + +void +#ifdef __USE_PROTOS +zzerraction(void) +#else +zzerraction() +#endif +{ + (*zzerr)("invalid token"); + zzadvance(); + zzskip(); +} +/* + * D L G tables + * + * Generated from: parser.dlg + * + * 1989-2001 by Will Cohen, Terence Parr, and Hank Dietz + * Purdue University Electrical Engineering + * DLG Version 1.33MR33 + */ + +#include "mode.h" + + + + +/* maintained, but not used for now */ +set AST_nodes_refd_in_actions = set_init; +int inAlt = 0; +set attribsRefdFromAction = set_init; /* MR20 */ +int UsedOldStyleAttrib = 0; +int UsedNewStyleLabel = 0; +#ifdef __USE_PROTOS +char *inline_set(char *); +#else +char *inline_set(); +#endif + +/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */ +/* MR1 in DLG action */ + +int tokenActionActive=0; /* MR1 */ + + + + + +static char * +#ifdef __USE_PROTOS +getFileNameFromTheLineInfo(char *toStr, char *fromStr) +#else +getFileNameFromTheLineInfo(toStr, fromStr) +char *toStr, *fromStr; +#endif +{ + int i, j, k; + + if (!fromStr || !toStr) return toStr; + + /* find the first " */ + + for (i=0; + (ielem->ntype == nToken,"mark_label_used... ntype != nToken"); + tn=(TokNode *)le->elem; + require (tn->label != 0,"mark_label_used... TokNode has no label"); + tn->label_used_in_semantic_pred=1; +} + +static void act1() +{ + NLA = Eof; + /* L o o k F o r A n o t h e r F i l e */ + { + FILE *new_input; + new_input = NextFile(); + if ( new_input == NULL ) { NLA=Eof; return; } + fclose( input ); + input = new_input; + zzrdstream( input ); + zzskip(); /* Skip the Eof (@) char i.e continue */ + } + } + + +static void act2() +{ + NLA = 76; + zzskip(); + } + + +static void act3() +{ + NLA = 77; + zzline++; zzskip(); + } + + +static void act4() +{ + NLA = 78; + zzmode(ACTIONS); zzmore(); + istackreset(); + pushint(']'); + } + + +static void act5() +{ + NLA = 79; + action_file=CurFile; action_line=zzline; + zzmode(ACTIONS); zzmore(); + list_free(&CurActionLabels,0); /* MR10 */ + numericActionLabel=0; /* MR10 */ + istackreset(); + pushint('>'); + } + + +static void act6() +{ + NLA = 80; + zzmode(STRINGS); zzmore(); + } + + +static void act7() +{ + NLA = 81; + zzmode(COMMENTS); zzskip(); + } + + +static void act8() +{ + NLA = 82; + warn("Missing /*; found dangling */"); zzskip(); + } + + +static void act9() +{ + NLA = 83; + zzmode(CPP_COMMENTS); zzskip(); + } + + +static void act10() +{ + NLA = 84; + + zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore(); + getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr); + } + + +static void act11() +{ + NLA = 85; + + zzline++; zzmore(); + } + + +static void act12() +{ + NLA = 86; + warn("Missing <<; found dangling >>"); zzskip(); + } + + +static void act13() +{ + NLA = WildCard; + } + + +static void act14() +{ + NLA = 88; + FoundException = 1; /* MR6 */ + FoundAtOperator = 1; + } + + +static void act15() +{ + NLA = Pragma; + } + + +static void act16() +{ + NLA = FirstSetSymbol; + } + + +static void act17() +{ + NLA = 94; + } + + +static void act18() +{ + NLA = 95; + } + + +static void act19() +{ + NLA = 96; + } + + +static void act20() +{ + NLA = 97; + } + + +static void act21() +{ + NLA = 98; + } + + +static void act22() +{ + NLA = 99; + } + + +static void act23() +{ + NLA = 102; + } + + +static void act24() +{ + NLA = 103; + } + + +static void act25() +{ + NLA = 104; + } + + +static void act26() +{ + NLA = 105; + } + + +static void act27() +{ + NLA = 106; + } + + +static void act28() +{ + NLA = 107; + } + + +static void act29() +{ + NLA = 108; + } + + +static void act30() +{ + NLA = 109; + } + + +static void act31() +{ + NLA = 110; + } + + +static void act32() +{ + NLA = 111; + } + + +static void act33() +{ + NLA = 112; + } + + +static void act34() +{ + NLA = 113; + } + + +static void act35() +{ + NLA = 114; + } + + +static void act36() +{ + NLA = 115; + } + + +static void act37() +{ + NLA = 116; + } + + +static void act38() +{ + NLA = 117; + } + + +static void act39() +{ + NLA = 118; + } + + +static void act40() +{ + NLA = 119; + } + + +static void act41() +{ + NLA = 120; + } + + +static void act42() +{ + NLA = 121; + } + + +static void act43() +{ + NLA = 122; + } + + +static void act44() +{ + NLA = 123; + } + + +static void act45() +{ + NLA = 124; + } + + +static void act46() +{ + NLA = 125; + } + + +static void act47() +{ + NLA = 126; + } + + +static void act48() +{ + NLA = 127; + } + + +static void act49() +{ + NLA = 128; + } + + +static void act50() +{ + NLA = 129; + } + + +static void act51() +{ + NLA = 130; + } + + +static void act52() +{ + NLA = 131; + } + + +static void act53() +{ + NLA = 132; + } + + +static void act54() +{ + NLA = 133; + } + + +static void act55() +{ + NLA = 134; + } + + +static void act56() +{ + NLA = 135; + } + + +static void act57() +{ + NLA = NonTerminal; + + while ( zzchar==' ' || zzchar=='\t' ) { + zzadvance(); + } + if ( zzchar == ':' && inAlt ) NLA = LABEL; + } + + +static void act58() +{ + NLA = TokenTerm; + + while ( zzchar==' ' || zzchar=='\t' ) { + zzadvance(); + } + if ( zzchar == ':' && inAlt ) NLA = LABEL; + } + + +static void act59() +{ + NLA = 136; + warn(eMsg1("unknown meta-op: %s",LATEXT(1))); zzskip(); + } + +static unsigned char shift0[257] = { + 0, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 1, 2, 58, 58, 3, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 1, 40, 6, 9, 58, 58, 45, + 58, 46, 47, 8, 52, 58, 58, 18, 7, 16, + 14, 15, 16, 16, 16, 16, 16, 16, 16, 41, + 42, 5, 48, 17, 53, 19, 56, 56, 56, 56, + 56, 26, 56, 56, 56, 56, 56, 51, 56, 56, + 56, 56, 56, 56, 29, 56, 56, 56, 56, 56, + 56, 56, 4, 20, 58, 50, 57, 58, 23, 31, + 38, 34, 13, 35, 24, 33, 11, 55, 36, 10, + 25, 12, 32, 21, 55, 22, 27, 28, 54, 55, + 55, 43, 30, 55, 39, 44, 37, 49, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58 +}; + + +static void act60() +{ + NLA = Eof; + } + + +static void act61() +{ + NLA = QuotedTerm; + zzmode(START); + } + + +static void act62() +{ + NLA = 3; + + zzline++; + warn("eoln found in string"); + zzskip(); + } + + +static void act63() +{ + NLA = 4; + zzline++; zzmore(); + } + + +static void act64() +{ + NLA = 5; + zzmore(); + } + + +static void act65() +{ + NLA = 6; + zzmore(); + } + +static unsigned char shift1[257] = { + 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 2, 5, 5, 3, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 1, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5 +}; + + +static void act66() +{ + NLA = Eof; + } + + +static void act67() +{ + NLA = 7; + zzmode(ACTIONS); zzmore(); + } + + +static void act68() +{ + NLA = 8; + + zzline++; + warn("eoln found in string (in user action)"); + zzskip(); + } + + +static void act69() +{ + NLA = 9; + zzline++; zzmore(); + } + + +static void act70() +{ + NLA = 10; + zzmore(); + } + + +static void act71() +{ + NLA = 11; + zzmore(); + } + +static unsigned char shift2[257] = { + 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 2, 5, 5, 3, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 1, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5 +}; + + +static void act72() +{ + NLA = Eof; + } + + +static void act73() +{ + NLA = 12; + zzmode(ACTIONS); zzmore(); + } + + +static void act74() +{ + NLA = 13; + + zzline++; + warn("eoln found in char literal (in user action)"); + zzskip(); + } + + +static void act75() +{ + NLA = 14; + zzmore(); + } + + +static void act76() +{ + NLA = 15; + zzmore(); + } + +static unsigned char shift3[257] = { + 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 2, 5, 5, 3, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5 +}; + + +static void act77() +{ + NLA = Eof; + } + + +static void act78() +{ + NLA = 16; + zzmode(ACTIONS); zzmore(); + } + + +static void act79() +{ + NLA = 17; + zzmore(); + } + + +static void act80() +{ + NLA = 18; + zzline++; zzmore(); DAWDLE; + } + + +static void act81() +{ + NLA = 19; + zzmore(); + } + +static unsigned char shift4[257] = { + 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 3, 5, 5, 4, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 1, 5, 5, 5, 5, 2, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5 +}; + + +static void act82() +{ + NLA = Eof; + } + + +static void act83() +{ + NLA = 20; + zzmode(PARSE_ENUM_FILE); + zzmore(); + } + + +static void act84() +{ + NLA = 21; + zzmore(); + } + + +static void act85() +{ + NLA = 22; + zzline++; zzmore(); DAWDLE; + } + + +static void act86() +{ + NLA = 23; + zzmore(); + } + +static unsigned char shift5[257] = { + 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 3, 5, 5, 4, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 1, 5, 5, 5, 5, 2, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5 +}; + + +static void act87() +{ + NLA = Eof; + } + + +static void act88() +{ + NLA = 24; + zzline++; zzmode(PARSE_ENUM_FILE); zzskip(); DAWDLE; + } + + +static void act89() +{ + NLA = 25; + zzskip(); + } + +static unsigned char shift6[257] = { + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 1, 3, 3, 2, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3 +}; + + +static void act90() +{ + NLA = Eof; + } + + +static void act91() +{ + NLA = 26; + zzline++; zzmode(ACTIONS); zzmore(); DAWDLE; + } + + +static void act92() +{ + NLA = 27; + zzmore(); + } + +static unsigned char shift7[257] = { + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 1, 3, 3, 2, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3 +}; + + +static void act93() +{ + NLA = Eof; + } + + +static void act94() +{ + NLA = 28; + zzline++; zzmode(START); zzskip(); DAWDLE; + } + + +static void act95() +{ + NLA = 29; + zzskip(); + } + +static unsigned char shift8[257] = { + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 1, 3, 3, 2, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3 +}; + + +static void act96() +{ + NLA = Eof; + } + + +static void act97() +{ + NLA = 30; + zzmode(START); zzskip(); + } + + +static void act98() +{ + NLA = 31; + zzskip(); + } + + +static void act99() +{ + NLA = 32; + zzline++; zzskip(); DAWDLE; + } + + +static void act100() +{ + NLA = 33; + zzskip(); + } + +static unsigned char shift9[257] = { + 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 3, 5, 5, 4, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 1, 5, 5, 5, 5, 2, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5 +}; + + +static void act101() +{ + NLA = Eof; + } + + +static void act102() +{ + NLA = Action; + /* these do not nest */ + zzmode(START); + NLATEXT[0] = ' '; + NLATEXT[1] = ' '; + zzbegexpr[0] = ' '; + zzbegexpr[1] = ' '; + if ( zzbufovf ) { + err( eMsgd("action buffer overflow; size %d",ZZLEXBUFSIZE)); + } + +/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */ + /* MR1 in DLG action */ + /* MR1 Doesn't matter what kind of action it is - reset*/ + + tokenActionActive=0; /* MR1 */ + } + + +static void act103() +{ + NLA = Pred; + /* these do not nest */ + zzmode(START); + NLATEXT[0] = ' '; + NLATEXT[1] = ' '; + zzbegexpr[0] = '\0'; + if ( zzbufovf ) { + err( eMsgd("predicate buffer overflow; size %d",ZZLEXBUFSIZE)); + }; +#ifdef __cplusplus__ + /* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); +#else +#ifdef __STDC__ + /* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); +#else +#ifdef __USE_PROTOS + /* MRxx */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); +#else + /* MR10 */ list_apply(CurActionLabels,mark_label_used_in_sem_pred); +#endif +#endif +#endif + } + + +static void act104() +{ + NLA = PassAction; + if ( topint() == ']' ) { + popint(); + if ( istackempty() ) /* terminate action */ + { + zzmode(START); + NLATEXT[0] = ' '; + zzbegexpr[0] = ' '; + if ( zzbufovf ) { + err( eMsgd("parameter buffer overflow; size %d",ZZLEXBUFSIZE)); + } + } + else { + /* terminate $[..] and #[..] */ + if ( GenCC ) zzreplstr("))"); + else zzreplstr(")"); + zzmore(); + } + } + else if ( topint() == '|' ) { /* end of simple [...] */ + popint(); + zzmore(); + } + else zzmore(); + } + + +static void act105() +{ + NLA = 37; + + zzmore(); + zzreplstr(inline_set(zzbegexpr+ + strlen("consumeUntil("))); + } + + +static void act106() +{ + NLA = 38; + zzmore(); + } + + +static void act107() +{ + NLA = 39; + zzline++; zzmore(); DAWDLE; + } + + +static void act108() +{ + NLA = 40; + zzmore(); + } + + +static void act109() +{ + NLA = 41; + zzmore(); + } + + +static void act110() +{ + NLA = 42; + if ( !GenCC ) {zzreplstr("zzaRet"); zzmore();} + else err("$$ use invalid in C++ mode"); + } + + +static void act111() +{ + NLA = 43; + if ( !GenCC ) {zzreplstr("zzempty_attr"); zzmore();} + else err("$[] use invalid in C++ mode"); + } + + +static void act112() +{ + NLA = 44; + + pushint(']'); + if ( !GenCC ) zzreplstr("zzconstr_attr("); + else err("$[..] use invalid in C++ mode"); + zzmore(); + } + + +static void act113() +{ + NLA = 45; + { + static char buf[100]; + numericActionLabel=1; /* MR10 */ + if ( strlen(zzbegexpr)>(size_t)85 ) + fatal("$i attrib ref too big"); + set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction); + if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s)", + BlkLevel-1,zzbegexpr+1); + else sprintf(buf,"_t%d%s", + BlkLevel-1,zzbegexpr+1); + zzreplstr(buf); + zzmore(); + UsedOldStyleAttrib = 1; + if ( UsedNewStyleLabel ) + err("cannot mix old-style $i with new-style labels"); + } + } + + +static void act114() +{ + NLA = 46; + { + static char buf[100]; + numericActionLabel=1; /* MR10 */ + if ( strlen(zzbegexpr)>(size_t)85 ) + fatal("$i.field attrib ref too big"); + zzbegexpr[strlen(zzbegexpr)-1] = ' '; + set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction); + if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s).", + BlkLevel-1,zzbegexpr+1); + else sprintf(buf,"_t%d%s.", + BlkLevel-1,zzbegexpr+1); + zzreplstr(buf); + zzmore(); + UsedOldStyleAttrib = 1; + if ( UsedNewStyleLabel ) + err("cannot mix old-style $i with new-style labels"); + } + } + + +static void act115() +{ + NLA = 47; + { + static char buf[100]; + static char i[20], j[20]; + char *p,*q; + numericActionLabel=1; /* MR10 */ + if (strlen(zzbegexpr)>(size_t)85) fatal("$i.j attrib ref too big"); + for (p=zzbegexpr+1,q= &i[0]; *p!='.'; p++) { + if ( q == &i[20] ) + fatalFL("i of $i.j attrib ref too big", + FileStr[CurFile], zzline ); + *q++ = *p; + } + *q = '\0'; + for (p++, q= &j[0]; *p!='\0'; p++) { + if ( q == &j[20] ) + fatalFL("j of $i.j attrib ref too big", + FileStr[CurFile], zzline ); + *q++ = *p; + } + *q = '\0'; + if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%s,%s)",i,j); + else sprintf(buf,"_t%s%s",i,j); + zzreplstr(buf); + zzmore(); + UsedOldStyleAttrib = 1; + if ( UsedNewStyleLabel ) + err("cannot mix old-style $i with new-style labels"); + } + } + + +static void act116() +{ + NLA = 48; + { static char buf[300]; LabelEntry *el; + zzbegexpr[0] = ' '; + if ( CurRule != NULL && + strcmp(CurRule, &zzbegexpr[1])==0 ) { + if ( !GenCC ) zzreplstr("zzaRet"); + } + else if ( CurRetDef != NULL && + strmember(CurRetDef, &zzbegexpr[1])) { + if ( hasMultipleOperands( CurRetDef ) ) { + require (strlen(zzbegexpr)<=(size_t)285, + "$retval attrib ref too big"); + sprintf(buf,"_retv.%s",&zzbegexpr[1]); + zzreplstr(buf); + } + else zzreplstr("_retv"); + } + else if ( CurParmDef != NULL && + strmember(CurParmDef, &zzbegexpr[1])) { + ; + } + else if ( Elabel==NULL ) { + { err("$-variables in actions outside of rules are not allowed"); } + } else if ( (el=(LabelEntry *)hash_get(Elabel, &zzbegexpr[1]))!=NULL ) { + /* MR10 */ + /* MR10 */ /* element labels might exist without an elem when */ + /* MR10 */ /* it is a forward reference (to a rule) */ + /* MR10 */ + /* MR10 */ if ( GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) ) + /* MR10 */ { err(eMsg1("There are no token ptrs for rule references: '$%s'",&zzbegexpr[1])); } + /* MR10 */ + /* MR10 */ if ( !GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) && GenAST) { + /* MR10 */ err("You can no longer use attributes returned by rules when also using ASTs"); + /* MR10 */ err(" Use upward inheritance (\"rule >[Attrib a] : ... <<$a=...>>\")"); + /* MR10 */ }; + /* MR10 */ + /* MR10 */ /* keep track of <<... $label ...>> for semantic predicates in guess mode */ + /* MR10 */ /* element labels contain pointer to the owners node */ + /* MR10 */ + /* MR10 */ if (el->elem != NULL && el->elem->ntype == nToken) { + /* MR10 */ list_add(&CurActionLabels,el); + /* MR10 */ }; +} +else +warn(eMsg1("$%s not parameter, return value, (defined) element label",&zzbegexpr[1])); +} +zzmore(); + } + + +static void act117() +{ + NLA = 49; + zzreplstr("(*_root)"); zzmore(); chkGTFlag(); + } + + +static void act118() +{ + NLA = 50; + if ( GenCC ) { + if (NewAST) zzreplstr("(newAST)"); + else zzreplstr("(new AST)");} + else {zzreplstr("zzastnew()");} zzmore(); + chkGTFlag(); + } + + +static void act119() +{ + NLA = 51; + zzreplstr("NULL"); zzmore(); chkGTFlag(); + } + + +static void act120() +{ + NLA = 52; + { + static char buf[100]; + if ( strlen(zzbegexpr)>(size_t)85 ) + fatal("#i AST ref too big"); + if ( GenCC ) sprintf(buf,"_ast%d%s",BlkLevel-1,zzbegexpr+1); + else sprintf(buf,"zzastArg(%s)",zzbegexpr+1); + zzreplstr(buf); + zzmore(); + set_orel(atoi(zzbegexpr+1), &AST_nodes_refd_in_actions); + chkGTFlag(); + } + } + + +static void act121() +{ + NLA = 53; + + zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore(); + getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr); + } + + +static void act122() +{ + NLA = 54; + + zzline++; zzmore(); + } + + +static void act123() +{ + NLA = 55; + + if ( !(strcmp(zzbegexpr, "#ifdef")==0 || + strcmp(zzbegexpr, "#if")==0 || + strcmp(zzbegexpr, "#else")==0 || + strcmp(zzbegexpr, "#endif")==0 || + strcmp(zzbegexpr, "#ifndef")==0 || + strcmp(zzbegexpr, "#define")==0 || + strcmp(zzbegexpr, "#pragma")==0 || + strcmp(zzbegexpr, "#undef")==0 || + strcmp(zzbegexpr, "#import")==0 || + strcmp(zzbegexpr, "#line")==0 || + strcmp(zzbegexpr, "#include")==0 || + strcmp(zzbegexpr, "#error")==0) ) + { + static char buf[100]; + sprintf(buf, "%s_ast", zzbegexpr+1); + /* MR27 */ list_add(&CurAstLabelsInActions, mystrdup(zzbegexpr+1)); + zzreplstr(buf); + chkGTFlag(); + } + zzmore(); + } + + +static void act124() +{ + NLA = 56; + + pushint(']'); + if ( GenCC ) { + if (NewAST) zzreplstr("(newAST("); + else zzreplstr("(new AST("); } + else zzreplstr("zzmk_ast(zzastnew(),"); + zzmore(); + chkGTFlag(); + } + + +static void act125() +{ + NLA = 57; + + pushint('}'); + if ( GenCC ) { + if (tmakeInParser) { + zzreplstr("tmake("); + } + else { + zzreplstr("ASTBase::tmake("); + } + } + else { + zzreplstr("zztmake("); + } + zzmore(); + chkGTFlag(); + } + + +static void act126() +{ + NLA = 58; + zzmore(); + } + + +static void act127() +{ + NLA = 59; + + if ( istackempty() ) + zzmore(); + else if ( topint()==')' ) { + popint(); + } + else if ( topint()=='}' ) { + popint(); + /* terminate #(..) */ + zzreplstr(", NULL)"); + } + zzmore(); + } + + +static void act128() +{ + NLA = 60; + + pushint('|'); /* look for '|' to terminate simple [...] */ + zzmore(); + } + + +static void act129() +{ + NLA = 61; + + pushint(')'); + zzmore(); + } + + +static void act130() +{ + NLA = 62; + zzreplstr("]"); zzmore(); + } + + +static void act131() +{ + NLA = 63; + zzreplstr(")"); zzmore(); + } + + +static void act132() +{ + NLA = 64; + if (! tokenActionActive) zzreplstr(">"); /* MR1 */ + zzmore(); /* MR1 */ + } + + +static void act133() +{ + NLA = 65; + zzmode(ACTION_CHARS); zzmore(); + } + + +static void act134() +{ + NLA = 66; + zzmode(ACTION_STRINGS); zzmore(); + } + + +static void act135() +{ + NLA = 67; + zzreplstr("$"); zzmore(); + } + + +static void act136() +{ + NLA = 68; + zzreplstr("#"); zzmore(); + } + + +static void act137() +{ + NLA = 69; + zzline++; zzmore(); + } + + +static void act138() +{ + NLA = 70; + zzmore(); + } + + +static void act139() +{ + NLA = 71; + zzmore(); + } + + +static void act140() +{ + NLA = 72; + zzmode(ACTION_COMMENTS); zzmore(); + } + + +static void act141() +{ + NLA = 73; + warn("Missing /*; found dangling */ in action"); zzmore(); + } + + +static void act142() +{ + NLA = 74; + zzmode(ACTION_CPP_COMMENTS); zzmore(); + } + + +static void act143() +{ + NLA = 75; + zzmore(); + } + +static unsigned char shift10[257] = { + 0, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 16, 19, 33, 33, 20, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 16, 33, 28, 27, 21, 33, 33, + 30, 15, 18, 32, 33, 33, 33, 25, 31, 23, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 33, + 33, 33, 33, 1, 2, 33, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 11, 26, 26, 26, + 26, 26, 22, 29, 3, 33, 26, 33, 26, 26, + 4, 26, 10, 26, 26, 26, 13, 26, 26, 14, + 9, 6, 5, 26, 26, 26, 7, 12, 8, 26, + 26, 26, 26, 26, 17, 33, 34, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33 +}; + + +static void act144() +{ + NLA = Eof; + ; + } + + +static void act145() +{ + NLA = 137; + zzskip(); + } + + +static void act146() +{ + NLA = 138; + zzline++; zzskip(); + } + + +static void act147() +{ + NLA = 139; + zzmode(TOK_DEF_CPP_COMMENTS); zzmore(); + } + + +static void act148() +{ + NLA = 140; + zzmode(TOK_DEF_COMMENTS); zzskip(); + } + + +static void act149() +{ + NLA = 141; + zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); + } + + +static void act150() +{ + NLA = 142; + zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); + } + + +static void act151() +{ + NLA = 143; + ; + } + + +static void act152() +{ + NLA = 144; + zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); + } + + +static void act153() +{ + NLA = 145; + zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); + } + + +static void act154() +{ + NLA = 146; + zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); + } + + +static void act155() +{ + NLA = 147; + zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); + } + + +static void act156() +{ + NLA = 149; + } + + +static void act157() +{ + NLA = 151; + } + + +static void act158() +{ + NLA = 152; + } + + +static void act159() +{ + NLA = 153; + } + + +static void act160() +{ + NLA = 154; + } + + +static void act161() +{ + NLA = 155; + } + + +static void act162() +{ + NLA = 156; + } + + +static void act163() +{ + NLA = INT; + } + + +static void act164() +{ + NLA = ID; + } + +static unsigned char shift11[257] = { + 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 1, 2, 27, 27, 3, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 1, 27, 27, 6, 27, 27, 27, + 27, 27, 27, 5, 27, 22, 27, 27, 4, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 27, + 24, 27, 21, 27, 27, 27, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 27, 27, 27, 27, 26, 27, 26, 26, + 26, 9, 10, 8, 26, 26, 7, 26, 26, 12, + 15, 11, 17, 16, 26, 18, 13, 19, 14, 26, + 26, 26, 26, 26, 20, 27, 23, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27 +}; + +#define DfaStates 436 +typedef unsigned short DfaState; + +static DfaState st0[60] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 11, 11, 12, 13, 13, 13, 14, 15, 16, + 17, 11, 11, 18, 11, 11, 19, 11, 11, 19, + 11, 11, 11, 11, 20, 11, 11, 21, 22, 23, + 24, 25, 26, 11, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 11, 11, 19, 436, 436, 436 +}; + +static DfaState st1[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st2[60] = { + 436, 2, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st3[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st4[60] = { + 436, 436, 37, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st5[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st6[60] = { + 436, 436, 436, 436, 436, 38, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st7[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st8[60] = { + 436, 436, 436, 436, 436, 436, 436, 39, 40, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st9[60] = { + 436, 436, 436, 436, 436, 436, 436, 41, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st10[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 42, 43, 43, 44, 43, 43, 43, 436, 436, 436, + 436, 45, 43, 43, 43, 43, 46, 43, 47, 43, + 43, 43, 43, 48, 43, 49, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st11[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st12[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 51, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st13[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 13, 13, 13, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st14[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 52, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st15[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 53, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st16[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st17[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 54, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st18[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 55, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st19[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 56, 56, 56, 56, 56, 56, 56, 436, 436, 436, + 436, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 436, 56, 436, + 436, 436, 436, 56, 436, 436, 436, 436, 436, 436, + 436, 56, 436, 436, 56, 56, 56, 56, 436, 436 +}; + +static DfaState st20[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 57, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st21[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st22[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 58, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 59, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st23[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st24[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st25[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st26[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st27[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 60, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st28[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 61, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st29[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st30[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st31[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 62, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st32[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st33[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st34[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 56, 56, 56, 56, 56, 56, 56, 436, 436, 436, + 436, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 436, 56, 436, + 436, 436, 436, 56, 436, 436, 436, 436, 436, 436, + 436, 63, 436, 436, 56, 56, 56, 56, 436, 436 +}; + +static DfaState st35[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st36[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st37[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st38[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st39[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st40[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st41[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st42[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 64, 43, 65, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st43[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st44[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 66, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st45[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 67, 68, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st46[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 69, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st47[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 70, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st48[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 71, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st49[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 72, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st50[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st51[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 73, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st52[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st53[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st54[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 74, 43, 43, 44, 43, 43, 43, 436, 436, 436, + 436, 45, 43, 43, 43, 43, 46, 43, 47, 43, + 43, 43, 43, 48, 43, 49, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st55[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 75, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st56[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 56, 56, 56, 56, 56, 56, 56, 436, 436, 436, + 436, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 436, 56, 436, + 436, 436, 436, 56, 436, 436, 436, 436, 436, 436, + 436, 56, 436, 436, 56, 56, 56, 56, 436, 436 +}; + +static DfaState st57[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 76, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st58[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 77, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st59[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 78, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st60[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st61[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st62[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st63[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 56, 56, 56, 56, 56, 56, 56, 436, 436, 436, + 436, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 436, 56, 436, + 436, 436, 436, 56, 436, 436, 79, 436, 436, 436, + 436, 56, 436, 436, 56, 56, 56, 56, 436, 436 +}; + +static DfaState st64[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 80, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st65[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 81, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st66[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 82, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st67[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 83, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 84, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st68[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 85, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st69[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 86, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st70[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 87, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st71[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 88, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st72[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 89, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st73[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 90, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st74[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 65, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st75[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 91, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st76[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 92, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st77[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 93, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st78[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 94, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st79[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 95, 96, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st80[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 97, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st81[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 98, 43, 99, 43, 100, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 101, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st82[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 102, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st83[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 103, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st84[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 104, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st85[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 105, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st86[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 106, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st87[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 107, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 108, 43, 43, 436, 109, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st88[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 110, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st89[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 111, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st90[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 112, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st91[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 113, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st92[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 114, 50, 50, 50, 436, 436 +}; + +static DfaState st93[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 115, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st94[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 116, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st95[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 117, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st96[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 118, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st97[60] = { + 436, 119, 120, 121, 122, 122, 122, 122, 122, 122, + 123, 123, 123, 123, 124, 124, 124, 122, 122, 122, + 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 122, 123, 122, + 122, 122, 122, 123, 122, 122, 122, 122, 122, 122, + 122, 123, 122, 122, 123, 123, 123, 123, 122, 436 +}; + +static DfaState st98[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 125, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st99[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 126, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st100[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 127, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st101[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 128, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st102[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 129, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st103[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st104[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 130, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st105[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 131, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st106[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 132, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st107[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 133, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st108[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 134, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st109[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 135, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st110[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 136, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st111[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 137, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st112[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 138, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st113[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 139, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st114[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 140, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st115[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st116[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st117[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st118[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st119[60] = { + 436, 119, 120, 121, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 141, 141, 141, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 436 +}; + +static DfaState st120[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st121[60] = { + 436, 436, 142, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st122[60] = { + 436, 122, 120, 121, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 436 +}; + +static DfaState st123[60] = { + 436, 122, 120, 121, 122, 122, 122, 122, 122, 122, + 123, 123, 123, 123, 123, 123, 123, 122, 122, 122, + 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 122, 123, 122, + 122, 122, 122, 123, 122, 122, 122, 122, 122, 122, + 122, 123, 122, 122, 123, 123, 123, 123, 122, 436 +}; + +static DfaState st124[60] = { + 436, 143, 144, 145, 122, 122, 146, 122, 122, 122, + 123, 123, 123, 123, 124, 124, 124, 122, 122, 122, + 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 122, 123, 122, + 122, 122, 122, 123, 122, 122, 122, 122, 122, 122, + 122, 123, 122, 122, 123, 123, 123, 123, 122, 436 +}; + +static DfaState st125[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 147, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st126[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 148, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st127[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 149, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st128[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 150, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st129[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 151, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st130[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 152, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st131[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 153, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st132[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 154, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st133[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st134[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 155, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st135[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 156, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st136[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 157, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st137[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st138[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 158, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st139[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st140[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 159, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st141[60] = { + 436, 143, 144, 145, 122, 122, 146, 122, 122, 122, + 122, 122, 122, 122, 141, 141, 141, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 436 +}; + +static DfaState st142[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st143[60] = { + 436, 143, 120, 121, 122, 122, 146, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 436 +}; + +static DfaState st144[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st145[60] = { + 436, 436, 160, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st146[60] = { + 436, 161, 162, 163, 161, 161, 122, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 436 +}; + +static DfaState st147[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 164, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st148[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 165, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st149[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 166, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st150[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 167, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st151[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 168, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st152[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st153[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st154[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 169, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st155[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 170, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st156[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 171, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st157[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st158[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 172, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st159[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st160[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st161[60] = { + 436, 161, 162, 163, 161, 161, 173, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 436 +}; + +static DfaState st162[60] = { + 436, 174, 174, 174, 174, 174, 175, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 436 +}; + +static DfaState st163[60] = { + 436, 174, 176, 174, 174, 174, 175, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 436 +}; + +static DfaState st164[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 177, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st165[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 178, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st166[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 179, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st167[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 180, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st168[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 181, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st169[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 182, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st170[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st171[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 183, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st172[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 184, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st173[60] = { + 436, 185, 144, 145, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 186, 186, 186, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 436 +}; + +static DfaState st174[60] = { + 436, 174, 174, 174, 174, 174, 175, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 436 +}; + +static DfaState st175[60] = { + 436, 187, 188, 189, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 190, 190, 190, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st176[60] = { + 436, 174, 174, 174, 174, 174, 175, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 436 +}; + +static DfaState st177[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 191, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st178[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 192, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st179[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 193, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st180[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st181[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st182[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 194, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st183[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st184[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, + 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, + 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, + 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 +}; + +static DfaState st185[60] = { + 436, 185, 144, 145, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 186, 186, 186, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 436 +}; + +static DfaState st186[60] = { + 436, 185, 144, 145, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 186, 186, 186, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 436 +}; + +static DfaState st187[60] = { + 436, 187, 188, 189, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 190, 190, 190, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st188[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st189[60] = { + 436, 436, 195, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st190[60] = { + 436, 187, 188, 189, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 190, 190, 190, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st191[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st192[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st193[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st194[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 196, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st195[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st196[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 197, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st197[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 198, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st198[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 199, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st199[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 200, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st200[60] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, + 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, + 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, + 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 +}; + +static DfaState st201[7] = { + 202, 203, 204, 205, 206, 207, 436 +}; + +static DfaState st202[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st203[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st204[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st205[7] = { + 436, 436, 208, 436, 436, 436, 436 +}; + +static DfaState st206[7] = { + 436, 209, 210, 211, 209, 209, 436 +}; + +static DfaState st207[7] = { + 436, 436, 436, 436, 436, 207, 436 +}; + +static DfaState st208[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st209[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st210[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st211[7] = { + 436, 436, 212, 436, 436, 436, 436 +}; + +static DfaState st212[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st213[7] = { + 214, 215, 216, 217, 218, 219, 436 +}; + +static DfaState st214[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st215[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st216[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st217[7] = { + 436, 436, 220, 436, 436, 436, 436 +}; + +static DfaState st218[7] = { + 436, 221, 222, 223, 221, 221, 436 +}; + +static DfaState st219[7] = { + 436, 436, 436, 436, 436, 219, 436 +}; + +static DfaState st220[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st221[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st222[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st223[7] = { + 436, 436, 224, 436, 436, 436, 436 +}; + +static DfaState st224[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st225[7] = { + 226, 227, 228, 229, 230, 231, 436 +}; + +static DfaState st226[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st227[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st228[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st229[7] = { + 436, 436, 232, 436, 436, 436, 436 +}; + +static DfaState st230[7] = { + 436, 233, 233, 233, 233, 233, 436 +}; + +static DfaState st231[7] = { + 436, 436, 436, 436, 436, 231, 436 +}; + +static DfaState st232[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st233[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st234[7] = { + 235, 236, 237, 238, 239, 237, 436 +}; + +static DfaState st235[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st236[7] = { + 436, 436, 240, 436, 436, 436, 436 +}; + +static DfaState st237[7] = { + 436, 436, 237, 436, 436, 237, 436 +}; + +static DfaState st238[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st239[7] = { + 436, 436, 436, 241, 436, 436, 436 +}; + +static DfaState st240[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st241[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st242[7] = { + 243, 244, 245, 246, 247, 245, 436 +}; + +static DfaState st243[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st244[7] = { + 436, 436, 248, 436, 436, 436, 436 +}; + +static DfaState st245[7] = { + 436, 436, 245, 436, 436, 245, 436 +}; + +static DfaState st246[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st247[7] = { + 436, 436, 436, 249, 436, 436, 436 +}; + +static DfaState st248[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st249[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st250[5] = { + 251, 252, 253, 254, 436 +}; + +static DfaState st251[5] = { + 436, 436, 436, 436, 436 +}; + +static DfaState st252[5] = { + 436, 436, 436, 436, 436 +}; + +static DfaState st253[5] = { + 436, 255, 436, 436, 436 +}; + +static DfaState st254[5] = { + 436, 436, 436, 254, 436 +}; + +static DfaState st255[5] = { + 436, 436, 436, 436, 436 +}; + +static DfaState st256[5] = { + 257, 258, 259, 260, 436 +}; + +static DfaState st257[5] = { + 436, 436, 436, 436, 436 +}; + +static DfaState st258[5] = { + 436, 436, 436, 436, 436 +}; + +static DfaState st259[5] = { + 436, 261, 436, 436, 436 +}; + +static DfaState st260[5] = { + 436, 436, 436, 260, 436 +}; + +static DfaState st261[5] = { + 436, 436, 436, 436, 436 +}; + +static DfaState st262[5] = { + 263, 264, 265, 266, 436 +}; + +static DfaState st263[5] = { + 436, 436, 436, 436, 436 +}; + +static DfaState st264[5] = { + 436, 436, 436, 436, 436 +}; + +static DfaState st265[5] = { + 436, 267, 436, 436, 436 +}; + +static DfaState st266[5] = { + 436, 436, 436, 266, 436 +}; + +static DfaState st267[5] = { + 436, 436, 436, 436, 436 +}; + +static DfaState st268[7] = { + 269, 270, 271, 272, 273, 271, 436 +}; + +static DfaState st269[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st270[7] = { + 436, 436, 274, 436, 436, 436, 436 +}; + +static DfaState st271[7] = { + 436, 436, 271, 436, 436, 271, 436 +}; + +static DfaState st272[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st273[7] = { + 436, 436, 436, 275, 436, 436, 436 +}; + +static DfaState st274[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st275[7] = { + 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st276[36] = { + 277, 278, 279, 280, 281, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 282, 279, 279, 283, 284, + 285, 286, 287, 279, 279, 279, 279, 288, 289, 290, + 291, 292, 293, 279, 279, 436 +}; + +static DfaState st277[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st278[36] = { + 436, 294, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st279[36] = { + 436, 436, 279, 436, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 436, 279, 279, 436, 436, + 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, + 436, 436, 279, 279, 279, 436 +}; + +static DfaState st280[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st281[36] = { + 436, 436, 279, 436, 279, 295, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 436, 279, 279, 436, 436, + 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, + 436, 436, 279, 279, 279, 436 +}; + +static DfaState st282[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st283[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st284[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st285[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 296, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st286[36] = { + 436, 436, 436, 436, 297, 297, 297, 297, 297, 297, + 297, 297, 297, 297, 297, 436, 436, 436, 436, 436, + 436, 298, 299, 300, 300, 436, 297, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st287[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st288[36] = { + 436, 436, 436, 436, 301, 301, 301, 301, 301, 301, + 301, 301, 301, 301, 302, 303, 436, 436, 436, 436, + 436, 436, 304, 305, 306, 436, 301, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st289[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st290[36] = { + 436, 307, 308, 309, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 310, 311, + 312, 313, 308, 308, 308, 308, 308, 314, 308, 308, + 308, 308, 308, 308, 308, 436 +}; + +static DfaState st291[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st292[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 315, 316, 436, 436, 436 +}; + +static DfaState st293[36] = { + 436, 436, 279, 436, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 436, 279, 279, 436, 436, + 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, + 436, 317, 279, 279, 279, 436 +}; + +static DfaState st294[36] = { + 436, 436, 318, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st295[36] = { + 436, 436, 279, 436, 279, 279, 319, 279, 279, 279, + 279, 279, 279, 279, 279, 436, 279, 279, 436, 436, + 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, + 436, 436, 279, 279, 279, 436 +}; + +static DfaState st296[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st297[36] = { + 436, 436, 436, 436, 320, 320, 320, 320, 320, 320, + 320, 320, 320, 320, 320, 436, 436, 436, 436, 436, + 436, 436, 436, 320, 320, 436, 320, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st298[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st299[36] = { + 436, 436, 436, 321, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st300[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 300, 300, 322, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st301[36] = { + 436, 436, 436, 436, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 436, 436, 436, 436, 436, + 436, 436, 436, 323, 323, 436, 323, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st302[36] = { + 436, 436, 436, 436, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 324, 323, 436, 436, 436, 436, 436, + 436, 436, 436, 323, 323, 436, 323, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st303[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 325, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st304[36] = { + 436, 436, 436, 326, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st305[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 306, 306, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st306[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 306, 306, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st307[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st308[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st309[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st310[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st311[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st312[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 327, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st313[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st314[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st315[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st316[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st317[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st318[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st319[36] = { + 436, 436, 279, 436, 279, 279, 279, 328, 279, 279, + 279, 279, 279, 279, 279, 436, 279, 279, 436, 436, + 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, + 436, 436, 279, 279, 279, 436 +}; + +static DfaState st320[36] = { + 436, 436, 436, 436, 320, 320, 320, 320, 320, 320, + 320, 320, 320, 320, 320, 436, 436, 436, 436, 436, + 436, 436, 436, 320, 320, 436, 320, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st321[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st322[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 329, 329, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st323[36] = { + 436, 436, 436, 436, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 436, 436, 436, 436, 436, + 436, 436, 436, 323, 323, 436, 323, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st324[36] = { + 436, 436, 436, 436, 323, 323, 330, 323, 323, 323, + 323, 323, 323, 323, 323, 436, 436, 436, 436, 436, + 436, 436, 436, 323, 323, 436, 323, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st325[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st326[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st327[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st328[36] = { + 436, 436, 279, 436, 279, 279, 279, 279, 331, 279, + 279, 279, 279, 279, 279, 436, 279, 279, 436, 436, + 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, + 436, 436, 279, 279, 279, 436 +}; + +static DfaState st329[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 329, 329, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st330[36] = { + 436, 436, 436, 436, 323, 323, 323, 323, 323, 323, + 332, 323, 323, 323, 323, 436, 436, 436, 436, 436, + 436, 436, 436, 323, 323, 436, 323, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st331[36] = { + 436, 436, 279, 436, 279, 279, 279, 279, 279, 333, + 279, 279, 279, 279, 279, 436, 279, 279, 436, 436, + 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, + 436, 436, 279, 279, 279, 436 +}; + +static DfaState st332[36] = { + 436, 334, 334, 334, 335, 335, 335, 335, 335, 335, + 335, 335, 335, 335, 335, 334, 336, 334, 334, 337, + 338, 334, 334, 339, 339, 334, 335, 334, 334, 334, + 334, 334, 334, 334, 334, 436 +}; + +static DfaState st333[36] = { + 436, 436, 279, 436, 279, 279, 279, 279, 279, 279, + 340, 279, 279, 279, 279, 436, 279, 279, 436, 436, + 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, + 436, 436, 279, 279, 279, 436 +}; + +static DfaState st334[36] = { + 436, 334, 334, 334, 334, 334, 334, 334, 334, 334, + 334, 334, 334, 334, 334, 334, 334, 334, 334, 337, + 338, 334, 334, 334, 334, 334, 334, 334, 334, 334, + 334, 334, 334, 334, 334, 436 +}; + +static DfaState st335[36] = { + 436, 334, 334, 334, 335, 335, 335, 335, 335, 335, + 335, 335, 335, 335, 335, 334, 334, 334, 334, 337, + 338, 334, 334, 335, 335, 334, 335, 334, 334, 334, + 334, 334, 334, 334, 334, 436 +}; + +static DfaState st336[36] = { + 436, 334, 334, 334, 334, 334, 334, 334, 334, 334, + 334, 334, 334, 334, 334, 334, 336, 334, 334, 337, + 338, 334, 334, 341, 341, 334, 334, 334, 334, 334, + 334, 334, 334, 334, 334, 436 +}; + +static DfaState st337[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st338[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 342, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st339[36] = { + 436, 334, 334, 334, 335, 335, 335, 335, 335, 335, + 335, 335, 335, 335, 335, 334, 343, 334, 334, 344, + 345, 334, 334, 339, 339, 334, 335, 334, 346, 334, + 334, 334, 334, 334, 334, 436 +}; + +static DfaState st340[36] = { + 436, 436, 279, 436, 279, 279, 279, 279, 279, 279, + 279, 347, 279, 279, 279, 436, 279, 279, 436, 436, + 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, + 436, 436, 279, 279, 279, 436 +}; + +static DfaState st341[36] = { + 436, 334, 334, 334, 334, 334, 334, 334, 334, 334, + 334, 334, 334, 334, 334, 334, 343, 334, 334, 344, + 345, 334, 334, 341, 341, 334, 334, 334, 346, 334, + 334, 334, 334, 334, 334, 436 +}; + +static DfaState st342[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st343[36] = { + 436, 334, 334, 334, 334, 334, 334, 334, 334, 334, + 334, 334, 334, 334, 334, 334, 343, 334, 334, 337, + 338, 334, 334, 334, 334, 334, 334, 334, 346, 334, + 334, 334, 334, 334, 334, 436 +}; + +static DfaState st344[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st345[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 348, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st346[36] = { + 436, 349, 349, 349, 349, 349, 349, 349, 349, 349, + 349, 349, 349, 349, 349, 349, 349, 349, 349, 350, + 351, 349, 349, 349, 349, 349, 349, 349, 334, 349, + 349, 349, 349, 349, 349, 436 +}; + +static DfaState st347[36] = { + 436, 436, 279, 436, 279, 279, 352, 279, 279, 279, + 279, 279, 279, 279, 279, 436, 279, 279, 436, 436, + 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, + 436, 436, 279, 279, 279, 436 +}; + +static DfaState st348[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st349[36] = { + 436, 349, 349, 349, 349, 349, 349, 349, 349, 349, + 349, 349, 349, 349, 349, 349, 349, 349, 349, 350, + 351, 349, 349, 349, 349, 349, 349, 349, 353, 349, + 349, 349, 349, 349, 349, 436 +}; + +static DfaState st350[36] = { + 436, 354, 354, 354, 354, 354, 354, 354, 354, 354, + 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, + 354, 354, 354, 354, 354, 354, 354, 354, 355, 354, + 354, 354, 354, 354, 354, 436 +}; + +static DfaState st351[36] = { + 436, 354, 354, 354, 354, 354, 354, 354, 354, 354, + 354, 354, 354, 354, 354, 354, 354, 354, 354, 356, + 354, 354, 354, 354, 354, 354, 354, 354, 355, 354, + 354, 354, 354, 354, 354, 436 +}; + +static DfaState st352[36] = { + 436, 436, 279, 436, 279, 279, 279, 279, 279, 279, + 279, 279, 357, 279, 279, 436, 279, 279, 436, 436, + 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, + 436, 436, 279, 279, 279, 436 +}; + +static DfaState st353[36] = { + 436, 334, 334, 334, 334, 334, 334, 334, 334, 334, + 334, 334, 334, 334, 334, 334, 358, 334, 334, 344, + 345, 334, 334, 359, 359, 334, 334, 334, 334, 334, + 334, 334, 334, 334, 334, 436 +}; + +static DfaState st354[36] = { + 436, 354, 354, 354, 354, 354, 354, 354, 354, 354, + 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, + 354, 354, 354, 354, 354, 354, 354, 354, 355, 354, + 354, 354, 354, 354, 354, 436 +}; + +static DfaState st355[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 360, 436, 436, 361, + 362, 436, 436, 363, 363, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st356[36] = { + 436, 354, 354, 354, 354, 354, 354, 354, 354, 354, + 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, + 354, 354, 354, 354, 354, 354, 354, 354, 355, 354, + 354, 354, 354, 354, 354, 436 +}; + +static DfaState st357[36] = { + 436, 436, 279, 436, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 364, 279, 436, 279, 279, 436, 436, + 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, + 436, 436, 279, 279, 279, 436 +}; + +static DfaState st358[36] = { + 436, 334, 334, 334, 334, 334, 334, 334, 334, 334, + 334, 334, 334, 334, 334, 334, 358, 334, 334, 344, + 345, 334, 334, 359, 359, 334, 334, 334, 334, 334, + 334, 334, 334, 334, 334, 436 +}; + +static DfaState st359[36] = { + 436, 334, 334, 334, 334, 334, 334, 334, 334, 334, + 334, 334, 334, 334, 334, 334, 358, 334, 334, 344, + 345, 334, 334, 359, 359, 334, 334, 334, 334, 334, + 334, 334, 334, 334, 334, 436 +}; + +static DfaState st360[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 360, 436, 436, 361, + 362, 436, 436, 363, 363, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st361[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st362[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 365, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st363[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 360, 436, 436, 361, + 362, 436, 436, 363, 363, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st364[36] = { + 436, 436, 279, 436, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 366, 436, 279, 279, 436, 436, + 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, + 436, 436, 279, 279, 279, 436 +}; + +static DfaState st365[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st366[36] = { + 436, 436, 279, 436, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 367, 279, 279, 436, 436, + 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, + 436, 436, 279, 279, 279, 436 +}; + +static DfaState st367[36] = { + 436, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 369, 370, 436, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 436 +}; + +static DfaState st368[36] = { + 436, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 371, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 436 +}; + +static DfaState st369[36] = { + 436, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 369, 370, 371, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 436 +}; + +static DfaState st370[36] = { + 436, 372, 372, 372, 372, 372, 372, 372, 372, 372, + 372, 372, 372, 372, 372, 372, 372, 372, 373, 372, + 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, + 372, 372, 372, 372, 368, 436 +}; + +static DfaState st371[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st372[36] = { + 436, 372, 372, 372, 372, 372, 372, 372, 372, 372, + 372, 372, 372, 372, 372, 372, 372, 372, 373, 372, + 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, + 372, 372, 372, 372, 374, 436 +}; + +static DfaState st373[36] = { + 436, 375, 375, 375, 375, 375, 375, 375, 375, 375, + 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, + 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, + 375, 375, 375, 375, 376, 436 +}; + +static DfaState st374[36] = { + 436, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 377, 368, 378, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 436 +}; + +static DfaState st375[36] = { + 436, 375, 375, 375, 375, 375, 375, 375, 375, 375, + 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, + 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, + 375, 375, 375, 375, 376, 436 +}; + +static DfaState st376[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 379, 436, 380, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st377[36] = { + 436, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 377, 368, 378, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 436 +}; + +static DfaState st378[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st379[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 379, 436, 380, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st380[36] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436 +}; + +static DfaState st381[28] = { + 382, 383, 384, 385, 386, 436, 387, 388, 388, 388, + 389, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 390, 391, 392, 393, 394, 395, 388, 436 +}; + +static DfaState st382[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st383[28] = { + 436, 383, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st384[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st385[28] = { + 436, 436, 396, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st386[28] = { + 436, 436, 436, 436, 397, 398, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st387[28] = { + 436, 436, 436, 436, 436, 436, 436, 399, 436, 400, + 401, 436, 436, 436, 402, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st388[28] = { + 436, 436, 436, 436, 436, 436, 436, 403, 403, 403, + 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, + 436, 436, 436, 436, 436, 403, 403, 436 +}; + +static DfaState st389[28] = { + 436, 436, 436, 436, 436, 436, 436, 403, 403, 403, + 403, 404, 403, 403, 403, 403, 403, 403, 403, 403, + 436, 436, 436, 436, 436, 403, 403, 436 +}; + +static DfaState st390[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st391[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st392[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st393[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st394[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st395[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 395, 436, 436 +}; + +static DfaState st396[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st397[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st398[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st399[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 405, 436, + 436, 436, 436, 436, 436, 406, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st400[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 407, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st401[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 408, 409, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st402[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 410, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st403[28] = { + 436, 436, 436, 436, 436, 436, 436, 403, 403, 403, + 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, + 436, 436, 436, 436, 436, 403, 403, 436 +}; + +static DfaState st404[28] = { + 436, 436, 436, 436, 436, 436, 436, 403, 403, 403, + 403, 403, 403, 403, 411, 403, 403, 403, 403, 403, + 436, 436, 436, 436, 436, 403, 403, 436 +}; + +static DfaState st405[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 412, + 436, 413, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st406[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 414, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st407[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 415, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st408[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 416, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st409[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 417, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st410[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 418, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st411[28] = { + 436, 436, 436, 436, 436, 436, 436, 403, 403, 403, + 403, 403, 403, 403, 403, 419, 403, 403, 403, 403, + 436, 436, 436, 436, 436, 403, 403, 436 +}; + +static DfaState st412[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 420, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st413[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 421, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st414[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 422, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st415[28] = { + 436, 436, 436, 436, 436, 436, 436, 423, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st416[28] = { + 436, 436, 436, 436, 436, 436, 436, 424, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st417[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 425, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st418[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 426, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st419[28] = { + 436, 436, 436, 436, 436, 436, 436, 403, 403, 403, + 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, + 436, 436, 436, 436, 436, 403, 403, 436 +}; + +static DfaState st420[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 427, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st421[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 428, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st422[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 429, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st423[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 430, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st424[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 431, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st425[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st426[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 432, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st427[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st428[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 433, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st429[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 434, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st430[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 435, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st431[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st432[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st433[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st434[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + +static DfaState st435[28] = { + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436 +}; + + +DfaState *dfa[436] = { + st0, + st1, + st2, + st3, + st4, + st5, + st6, + st7, + st8, + st9, + st10, + st11, + st12, + st13, + st14, + st15, + st16, + st17, + st18, + st19, + st20, + st21, + st22, + st23, + st24, + st25, + st26, + st27, + st28, + st29, + st30, + st31, + st32, + st33, + st34, + st35, + st36, + st37, + st38, + st39, + st40, + st41, + st42, + st43, + st44, + st45, + st46, + st47, + st48, + st49, + st50, + st51, + st52, + st53, + st54, + st55, + st56, + st57, + st58, + st59, + st60, + st61, + st62, + st63, + st64, + st65, + st66, + st67, + st68, + st69, + st70, + st71, + st72, + st73, + st74, + st75, + st76, + st77, + st78, + st79, + st80, + st81, + st82, + st83, + st84, + st85, + st86, + st87, + st88, + st89, + st90, + st91, + st92, + st93, + st94, + st95, + st96, + st97, + st98, + st99, + st100, + st101, + st102, + st103, + st104, + st105, + st106, + st107, + st108, + st109, + st110, + st111, + st112, + st113, + st114, + st115, + st116, + st117, + st118, + st119, + st120, + st121, + st122, + st123, + st124, + st125, + st126, + st127, + st128, + st129, + st130, + st131, + st132, + st133, + st134, + st135, + st136, + st137, + st138, + st139, + st140, + st141, + st142, + st143, + st144, + st145, + st146, + st147, + st148, + st149, + st150, + st151, + st152, + st153, + st154, + st155, + st156, + st157, + st158, + st159, + st160, + st161, + st162, + st163, + st164, + st165, + st166, + st167, + st168, + st169, + st170, + st171, + st172, + st173, + st174, + st175, + st176, + st177, + st178, + st179, + st180, + st181, + st182, + st183, + st184, + st185, + st186, + st187, + st188, + st189, + st190, + st191, + st192, + st193, + st194, + st195, + st196, + st197, + st198, + st199, + st200, + st201, + st202, + st203, + st204, + st205, + st206, + st207, + st208, + st209, + st210, + st211, + st212, + st213, + st214, + st215, + st216, + st217, + st218, + st219, + st220, + st221, + st222, + st223, + st224, + st225, + st226, + st227, + st228, + st229, + st230, + st231, + st232, + st233, + st234, + st235, + st236, + st237, + st238, + st239, + st240, + st241, + st242, + st243, + st244, + st245, + st246, + st247, + st248, + st249, + st250, + st251, + st252, + st253, + st254, + st255, + st256, + st257, + st258, + st259, + st260, + st261, + st262, + st263, + st264, + st265, + st266, + st267, + st268, + st269, + st270, + st271, + st272, + st273, + st274, + st275, + st276, + st277, + st278, + st279, + st280, + st281, + st282, + st283, + st284, + st285, + st286, + st287, + st288, + st289, + st290, + st291, + st292, + st293, + st294, + st295, + st296, + st297, + st298, + st299, + st300, + st301, + st302, + st303, + st304, + st305, + st306, + st307, + st308, + st309, + st310, + st311, + st312, + st313, + st314, + st315, + st316, + st317, + st318, + st319, + st320, + st321, + st322, + st323, + st324, + st325, + st326, + st327, + st328, + st329, + st330, + st331, + st332, + st333, + st334, + st335, + st336, + st337, + st338, + st339, + st340, + st341, + st342, + st343, + st344, + st345, + st346, + st347, + st348, + st349, + st350, + st351, + st352, + st353, + st354, + st355, + st356, + st357, + st358, + st359, + st360, + st361, + st362, + st363, + st364, + st365, + st366, + st367, + st368, + st369, + st370, + st371, + st372, + st373, + st374, + st375, + st376, + st377, + st378, + st379, + st380, + st381, + st382, + st383, + st384, + st385, + st386, + st387, + st388, + st389, + st390, + st391, + st392, + st393, + st394, + st395, + st396, + st397, + st398, + st399, + st400, + st401, + st402, + st403, + st404, + st405, + st406, + st407, + st408, + st409, + st410, + st411, + st412, + st413, + st414, + st415, + st416, + st417, + st418, + st419, + st420, + st421, + st422, + st423, + st424, + st425, + st426, + st427, + st428, + st429, + st430, + st431, + st432, + st433, + st434, + st435 +}; + + +DfaState accepts[437] = { + 0, 1, 2, 3, 3, 4, 25, 6, 0, 50, + 59, 57, 57, 43, 26, 13, 14, 0, 57, 58, + 57, 21, 57, 23, 24, 27, 28, 44, 0, 35, + 36, 42, 45, 46, 58, 51, 52, 3, 5, 9, + 7, 8, 59, 59, 59, 59, 59, 59, 59, 59, + 57, 57, 12, 40, 59, 57, 58, 57, 57, 57, + 33, 34, 53, 58, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 57, 59, 57, 57, 57, 57, 0, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 57, 57, 57, 57, 57, 0, 0, 59, 59, 59, + 59, 59, 59, 32, 59, 59, 59, 59, 59, 59, + 59, 59, 57, 57, 57, 22, 56, 48, 49, 0, + 11, 11, 0, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 41, 59, 59, 59, 18, 57, 47, + 57, 0, 11, 0, 10, 10, 0, 59, 59, 59, + 59, 59, 15, 19, 59, 59, 59, 17, 57, 55, + 10, 0, 11, 11, 59, 59, 59, 59, 59, 59, + 20, 59, 57, 0, 0, 0, 11, 59, 59, 59, + 37, 38, 59, 39, 54, 0, 0, 0, 10, 10, + 0, 31, 29, 30, 59, 10, 59, 59, 59, 59, + 16, 0, 60, 61, 62, 62, 0, 65, 62, 64, + 63, 63, 63, 0, 66, 67, 68, 68, 0, 71, + 68, 70, 69, 69, 69, 0, 72, 73, 74, 74, + 0, 76, 74, 75, 0, 77, 79, 81, 80, 80, + 78, 80, 0, 82, 84, 86, 85, 85, 83, 85, + 0, 87, 88, 88, 89, 88, 0, 90, 91, 91, + 92, 91, 0, 93, 94, 94, 95, 94, 0, 96, + 98, 100, 99, 99, 97, 99, 0, 101, 108, 143, + 104, 143, 129, 127, 107, 107, 109, 128, 126, 134, + 0, 133, 139, 143, 102, 143, 107, 116, 110, 112, + 113, 123, 123, 125, 124, 117, 120, 132, 138, 130, + 131, 137, 137, 135, 136, 142, 140, 141, 103, 143, + 116, 111, 114, 123, 123, 119, 118, 137, 143, 115, + 123, 143, 123, 143, 0, 123, 0, 122, 122, 123, + 143, 0, 122, 0, 121, 121, 0, 143, 121, 0, + 122, 122, 143, 0, 0, 0, 122, 143, 0, 0, + 0, 121, 121, 0, 143, 121, 143, 0, 0, 0, + 0, 106, 0, 106, 0, 0, 0, 0, 105, 0, + 105, 0, 144, 145, 146, 146, 0, 0, 164, 164, + 158, 159, 160, 161, 162, 163, 146, 147, 148, 0, + 0, 0, 0, 164, 164, 150, 0, 0, 0, 0, + 0, 164, 0, 0, 0, 0, 0, 0, 0, 157, + 0, 0, 0, 0, 0, 152, 0, 149, 0, 0, + 0, 153, 154, 151, 155, 156, 0 +}; + +void (*actions[165])() = { + zzerraction, + act1, + act2, + act3, + act4, + act5, + act6, + act7, + act8, + act9, + act10, + act11, + act12, + act13, + act14, + act15, + act16, + act17, + act18, + act19, + act20, + act21, + act22, + act23, + act24, + act25, + act26, + act27, + act28, + act29, + act30, + act31, + act32, + act33, + act34, + act35, + act36, + act37, + act38, + act39, + act40, + act41, + act42, + act43, + act44, + act45, + act46, + act47, + act48, + act49, + act50, + act51, + act52, + act53, + act54, + act55, + act56, + act57, + act58, + act59, + act60, + act61, + act62, + act63, + act64, + act65, + act66, + act67, + act68, + act69, + act70, + act71, + act72, + act73, + act74, + act75, + act76, + act77, + act78, + act79, + act80, + act81, + act82, + act83, + act84, + act85, + act86, + act87, + act88, + act89, + act90, + act91, + act92, + act93, + act94, + act95, + act96, + act97, + act98, + act99, + act100, + act101, + act102, + act103, + act104, + act105, + act106, + act107, + act108, + act109, + act110, + act111, + act112, + act113, + act114, + act115, + act116, + act117, + act118, + act119, + act120, + act121, + act122, + act123, + act124, + act125, + act126, + act127, + act128, + act129, + act130, + act131, + act132, + act133, + act134, + act135, + act136, + act137, + act138, + act139, + act140, + act141, + act142, + act143, + act144, + act145, + act146, + act147, + act148, + act149, + act150, + act151, + act152, + act153, + act154, + act155, + act156, + act157, + act158, + act159, + act160, + act161, + act162, + act163, + act164 +}; + +static DfaState dfa_base[] = { + 0, + 201, + 213, + 225, + 234, + 242, + 250, + 256, + 262, + 268, + 276, + 381 +}; + +static unsigned char *b_class_no[] = { + shift0, + shift1, + shift2, + shift3, + shift4, + shift5, + shift6, + shift7, + shift8, + shift9, + shift10, + shift11 +}; + + + +#define ZZSHIFT(c) (b_class_no[zzauto][1+c]) +#define MAX_MODE 12 +#include "dlgauto.h" diff --git a/Tools/CodeTools/Source/Pccts/antlr/stdpccts.h b/Tools/CodeTools/Source/Pccts/antlr/stdpccts.h new file mode 100644 index 0000000000..ccdc21c3c9 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/stdpccts.h @@ -0,0 +1,31 @@ +#ifndef STDPCCTS_H +#define STDPCCTS_H +/* + * stdpccts.h -- P C C T S I n c l u d e + * + * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001 + * Purdue University Electrical Engineering + * With AHPCRC, University of Minnesota + * ANTLR Version 1.33MR33 + */ + +#ifndef ANTLR_VERSION +#define ANTLR_VERSION 13333 +#endif + +#include "pcctscfg.h" +#include "pccts_stdio.h" + +#include "pcctscfg.h" +#include "set.h" +#include +#include "syn.h" +#include "hash.h" +#include "generic.h" +#define zzcr_attr(attr,tok,t) +#define zzSET_SIZE 20 +#include "antlr.h" +#include "tokens.h" +#include "dlgdef.h" +#include "mode.h" +#endif diff --git a/Tools/CodeTools/Source/Pccts/antlr/syn.h b/Tools/CodeTools/Source/Pccts/antlr/syn.h new file mode 100644 index 0000000000..a23d196d77 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/syn.h @@ -0,0 +1,390 @@ +/* + * syn.h + * + * This file includes definitions and macros associated with syntax diagrams + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2001 + */ + +#include "set.h" + +#define NumNodeTypes 4 +#define NumJuncTypes 9 + +/* List the different node types */ +#define nJunction 1 +#define nRuleRef 2 +#define nToken 3 +#define nAction 4 + +/* Different types of junctions */ +#define aSubBlk 1 +#define aOptBlk 2 +#define aLoopBlk 3 +#define EndBlk 4 +#define RuleBlk 5 +#define Generic 6 /* just a junction--no unusual characteristics */ +#define EndRule 7 +#define aPlusBlk 8 +#define aLoopBegin 9 + +typedef int NodeType; + +#define TreeBlockAllocSize 500 +#define JunctionBlockAllocSize 200 +#define ActionBlockAllocSize 50 +#define RRefBlockAllocSize 100 +#define TokenBlockAllocSize 100 + +#ifdef __cplusplus +class ActionNode; +class Junction; +#endif + +/* note that 'right' is used by the tree node allocator as a ptr for linked list */ +typedef struct _tree { + struct _tree *down, *right; + int token; + union { + int rk; /* if token==EpToken, => how many more tokens req'd */ + struct _tree *tref; /* if token==TREE_REF */ + set sref; /* if token==SET */ + } v; +#ifdef TREE_DEBUG + int in_use; + int seq; +#endif + } Tree; + + +/* a predicate is defined to be a predicate action and a token tree with + * context info (if used); later, this struct may include the + * "hoisting distance" when we hoist past tokens. + * + * A tree is used to indicate && vs || + * + * p + * | + * q--r + * + * indicates p && (q||r). + * + * If expr is PRED_AND_LIST or PRED_OR_LIST, then it's an operation node + * and indicates the start of an && or || list. + */ + +typedef struct _Predicate { + struct _Predicate *down, *right; /* these have to be first */ + struct _Predicate *up, *left; /* doubly-link me */ + char *expr; + Tree *tcontext; /* used if lookahead depth of > one is needed (tree) */ + int k; /* lookahead depth for this tcontext */ + set scontext[2];/* used if lookahead depth of one is needed (set) */ + /* scontext[0] is not used; only needed so genExprSets() + routine works (it expects an array) + */ + set completionTree; /* which lookahead depths are required to complete tcontext? */ + set completionSet; /* MR10 separate completion set for sets and trees */ + struct _PredEntry *predEntry; /* MR11 */ + +#ifdef __cplusplus + ActionNode *source; /* where did this predicate come from? */ +#else + struct _anode *source; /* where did this predicate come from? */ +#endif + + char cloned; /* MR10 don't want to free original guard pred */ + char redundant; /* MR10 predicate tree simplification */ + char ampersandStyle; /* MR10 (g)? && <

>? */ + char inverted; /* MR11 ! predName */ + char isConst; /* MR11 */ + char constValue; /* MR11 */ + char conflictReported; /* MR11 */ + + set plainSet; /* MR12b */ + + /*** remember to change new_predicate() and predicate_dup() when changing this ***/ + +} Predicate; + +typedef struct _ExceptionHandler { + char *signalname; + char *action; + } ExceptionHandler; + +typedef struct _ExceptionGroup { + struct _ListNode *handlers; /* list of ExceptionHandler's */ + char *label; /* label==""; implies not attached to any + * particular rule ref. + */ + char *altID; /* which alt did it come from (blk#:alt#) */ + + struct _ExceptionGroup *pendingLink; /* for alternative EG MR7 */ + struct _ExceptionGroup *outerEG; /* for alternative EG MR7 */ + struct _LabelEntry *labelEntry; /* for alternative EG MR7 */ + int forRule; /* MR7 */ + int used; /* MR7 */ + } ExceptionGroup ; + + +#define TokenString(_i) ((TokenInd!=NULL)?TokenStr[TokenInd[_i]]:TokenStr[_i]) +#define ExprString(_i) ((TokenInd!=NULL)?ExprStr[TokenInd[_i]]:ExprStr[_i]) + + + /* M e s s a g e P a s s i n g T o N o d e s */ + +/* + * assumes a 'Junction *r' exists. This macro calls a function with + * the pointer to the node to operate on and a pointer to the rule + * in which it is enclosed. + */ +#define TRANS(p) {if ( (p)==NULL ) fatal("TRANS: NULL object"); \ + if ( (p)->ntype == nJunction ) (*(fpJTrans[((Junction *)(p))->jtype]))( p );\ + else (*(fpTrans[(p)->ntype]))( p );} + +#define PRINT(p) {if ( (p)==NULL ) fatal("PRINT: NULL object");\ + (*(fpPrint[(p)->ntype]))( p );} + +#define REACH(p,k,rk,a) {if ( (p)==NULL ) fatal("REACH: NULL object");\ + (a) = (*(fpReach[(p)->ntype]))( p, k, rk );} + +#define TRAV(p,k,rk,a) {if ( (p)==NULL ) {\ + if ( ContextGuardTRAV ) (a)=NULL; \ + else fatal("TRAV: NULL object");\ + } \ + else (a) = (*(fpTraverse[(p)->ntype]))( p, k, rk );} + +/** +*** #define TRAV(p,k,rk,a) {if ( (p)==NULL ) fatal("TRAV: NULL object");\ +*** (a) = (*(fpTraverse[(p)->ntype]))( p, k, rk );} +**/ + +/* All syntax diagram nodes derive from Node -- superclass + */ +#ifdef __cplusplus +class Node { +public: + NodeType ntype; + char *rname; /* what rule does this element live in? */ + int file; /* index in FileStr */ + int line; /* line number that element occurs on */ + }; +#else +typedef struct _node { + NodeType ntype; + char *rname; /* what rule does this element live in? */ + int file; /* index in FileStr */ + int line; /* line number that element occurs on */ + } Node; +#endif + +#ifdef __cplusplus +class ActionNode : public Node { +public: +#else +typedef struct _anode { + NodeType ntype; + char *rname; /* what rule does this action live in? */ + int file; /* index in FileStr (name of file with action) */ + int line; /* line number that action occurs on */ +#endif + Node *next; + char *action; + int is_predicate; /* true if action is a <<...>>? predicate action */ + int done; /* don't dump if action dumped (used for predicates) */ + int init_action; /* is this the 1st action of 1st prod of block? */ + char *pred_fail; /* what to do/print when predicate fails */ + Predicate *guardpred; /* if '(context)? =>' was present, already done */ + unsigned char frmwarned;/* have we dumped a warning for pred yet? */ + unsigned char ctxwarned;/* have we dumped a warning for pred yet? */ + unsigned char predTooLong; /* MR10 have we dumped warning for pred yet */ + unsigned char noHoist; /* MR12 literally "noHoist" */ + Predicate *ampersandPred; /* MR10 (g)? && <

>? expr */ +#ifdef __cplusplus + Junction *guardNodes; /* MR11 */ +#else + struct _junct *guardNodes; /* MR11 */ +#endif + struct _PredEntry *predEntry; /* MR11 */ + int inverted; /* MR11 <>? */ +#ifdef __cplusplus + }; +#else + } ActionNode; +#endif + +#ifdef __cplusplus +class TokNode : public Node { +public: +#else +typedef struct _toknode { + NodeType ntype; + char *rname; /* name of rule it's in */ + int file; /* index in FileStr (name of file with rule) */ + int line; /* line number that token occurs on */ +#endif + Node *next; + int token; + int astnode; /* leaf/root/excluded (used to build AST's) */ + unsigned char label;/* token label or expression ? */ + unsigned char remapped; + /* used if token id's are forced to certain positions; + * a function walks the tree reassigning token numbers */ + int upper_range; /* MR13 - was char */ + /* used only if Token is of type T1..T2; in this case, + * use token..upper_range as the range; else + * upper_range must be 0 */ + unsigned char wild_card; + /* indicates that the token is the "." wild-card; + * field token is ignored if wild_card is set + */ + unsigned int elnum; /* element number within the alternative */ +#ifdef __cplusplus + Junction *altstart; /* pointer to node that starts alt */ +#else + struct _junct *altstart; /* pointer to node that starts alt */ +#endif + struct _TCnode *tclass; /* token class if tokclass ref */ + set tset; /* set of tokens represented by meta token */ + char *el_label; /* el_label:toknode */ + unsigned char complement; /* complement the set? */ + ExceptionGroup *ex_group; /* any exception[el_label] attached? */ + unsigned char use_def_MT_handler; + unsigned char label_used_in_semantic_pred; /* MR10 */ +#ifdef __cplusplus + }; +#else + } TokNode; +#endif + +#ifdef __cplusplus +class RuleRefNode : public Node { +public: +#else +typedef struct _rrnode { + NodeType ntype; + char *rname; /* name of rule it's in */ + int file; /* index in FileStr (name of file with rule) + it's in */ + int line; /* line number that rule ref occurs on */ +#endif + Node *next; + char *text; /* reference to which rule */ + char *parms; /* point to parameters of rule invocation + (if present) */ + char *assign; /* point to left-hand-side of assignment + (if any) */ + int linked; /* Has a FoLink already been established? */ + int astnode; /* excluded? (used to build AST's) */ + unsigned int elnum; /* element number within the alternative */ +#ifdef __cplusplus + Junction *altstart; +#else + struct _junct *altstart; +#endif + char *el_label; /* el_label:rrnode */ + ExceptionGroup *ex_group; /* any exception[el_label] attached? */ +#ifdef __cplusplus + }; +#else + } RuleRefNode; +#endif + +#ifdef __cplusplus +class Junction : public Node { +public: +#else +typedef struct _junct { + NodeType ntype; + char *rname; /* name of rule junction is in */ + int file; /* index in FileStr (name of file with rule) + if blk == RuleBlk */ + int line; /* line number that rule occurs on */ +#endif + int seq; /* MR10 sequence number */ + char ignore; /* used by FIRST computation to ignore + empty alt added for the (...)+ blks */ + char visited; /* used by recursive routines to avoid + infinite recursion */ + char pvisited; /* used by print routines to avoid + infinite recursion */ + char fvisited; /* used by FoLink() to avoid + infinite recursion */ + char *lock; /* used by REACH to track infinite recursion */ + char *pred_lock; /* used by find_predicates to track infinite recursion */ + int altnum; /* used in subblocks. altnum==0 means not an + alt of subrule */ + int jtype; /* annotation for code-gen/FIRST/FOLLOW. + Junction type */ +#ifdef __cplusplus + Junction *end; /* pointer to node with EndBlk in it + if blk == a block type */ +#else + struct _junct *end; /* pointer to node with EndBlk in it + if blk == a block type */ +#endif + Node *p1, *p2; + char halt; /* never move past a junction with halt==TRUE */ /* MR10 was int */ + char *pdecl; /* point to declaration of parameters on rule + (if present) */ + char *parm; /* point to parameter of block invocation + (if present) */ + char predparm; /* indicates that the 'parm' is a predicate + * to be used in the while loop generated + * for blocks */ /* MR10 was int */ + char *ret; /* point to return type of rule (if present) */ + char *erraction; /* point to error action (if present) */ + int blockid; /* this is a unique ID */ + char *exception_label; /* goto label for this alt */ + set *fset; /* used for code generation */ + Tree *ftree; /* used for code generation */ + Predicate *predicate;/* predicate that can be used to disambiguate */ + char guess; /* true if (...)? block */ + char alpha_beta_guess_end; /* MR14 1 => end block of guess sub block */ + Node *guess_analysis_point; /* MR14 */ + char approx; /* limit block to use linear approx lookahead? */ + set tokrefs; /* if ith element of alt is tokref then i is member */ + set rulerefs; /* if ith element of alt is rule ref then i is member */ + struct _ListNode *exceptions; /* list of exceptions groups for rule */ + struct _ListNode *el_labels; /* list of element labels for rule */ + ExceptionGroup *outerEG; /* MR7 */ + int curAltNum; /* MR7 */ + char* pFirstSetSymbol; /* #pragma FirstSetSymbol(Foo) MR21 */ +#ifdef __cplusplus + Junction *pendingLink; /* MR7 */ +#else + struct _junct *pendingLink; /* MR7 */ +#endif + char overlap_warning; /* MR10 */ +#ifdef __cplusplus + }; +#else + } Junction; +#endif + +typedef struct { Node *left, *right;} Graph; + diff --git a/Tools/CodeTools/Source/Pccts/antlr/tokens.h b/Tools/CodeTools/Source/Pccts/antlr/tokens.h new file mode 100644 index 0000000000..91a53a8471 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/antlr/tokens.h @@ -0,0 +1,246 @@ +#ifndef tokens_h +#define tokens_h +/* tokens.h -- List of labelled tokens and stuff + * + * Generated from: antlr.g + * + * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001 + * Purdue University Electrical Engineering + * ANTLR Version 1.33MR33 + */ +#define zzEOF_TOKEN 1 +#define Eof 1 +#define QuotedTerm 2 +#define Action 34 +#define Pred 35 +#define PassAction 36 +#define WildCard 87 +#define LABEL 89 +#define Pragma 92 +#define FirstSetSymbol 93 +#define NonTerminal 100 +#define TokenTerm 101 +#define ID 148 +#define INT 150 + +#ifdef __USE_PROTOS +void grammar(void); +#else +extern void grammar(); +#endif + +#ifdef __USE_PROTOS +void class_def(void); +#else +extern void class_def(); +#endif + +#ifdef __USE_PROTOS +void rule(void); +#else +extern void rule(); +#endif + +#ifdef __USE_PROTOS +void laction(void); +#else +extern void laction(); +#endif + +#ifdef __USE_PROTOS +void lmember(void); +#else +extern void lmember(); +#endif + +#ifdef __USE_PROTOS +void lprefix(void); +#else +extern void lprefix(); +#endif + +#ifdef __USE_PROTOS +void aPred(void); +#else +extern void aPred(); +#endif + +#ifdef __USE_PROTOS +extern Predicate * predOrExpr(void); +#else +extern Predicate * predOrExpr(); +#endif + +#ifdef __USE_PROTOS +extern Predicate * predAndExpr(void); +#else +extern Predicate * predAndExpr(); +#endif + +#ifdef __USE_PROTOS +extern Predicate * predPrimary(void); +#else +extern Predicate * predPrimary(); +#endif + +#ifdef __USE_PROTOS +void aLexclass(void); +#else +extern void aLexclass(); +#endif + +#ifdef __USE_PROTOS +void error(void); +#else +extern void error(); +#endif + +#ifdef __USE_PROTOS +void tclass(void); +#else +extern void tclass(); +#endif + +#ifdef __USE_PROTOS +void token(void); +#else +extern void token(); +#endif + +#ifdef __USE_PROTOS +void block(set * toksrefd,set * rulesrefd); +#else +extern void block(); +#endif + +#ifdef __USE_PROTOS +void alt(set * toksrefd,set * rulesrefd); +#else +extern void alt(); +#endif + +#ifdef __USE_PROTOS +extern LabelEntry * element_label(void); +#else +extern LabelEntry * element_label(); +#endif + +#ifdef __USE_PROTOS +extern Node * element(int old_not,int first_on_line,int use_def_MT_handler); +#else +extern Node * element(); +#endif + +#ifdef __USE_PROTOS +void default_exception_handler(void); +#else +extern void default_exception_handler(); +#endif + +#ifdef __USE_PROTOS +extern ExceptionGroup * exception_group(void); +#else +extern ExceptionGroup * exception_group(); +#endif + +#ifdef __USE_PROTOS +extern ExceptionHandler * exception_handler(void); +#else +extern ExceptionHandler * exception_handler(); +#endif + +#ifdef __USE_PROTOS +void enum_file(char * fname); +#else +extern void enum_file(); +#endif + +#ifdef __USE_PROTOS +void defines(char * fname); +#else +extern void defines(); +#endif + +#ifdef __USE_PROTOS +void enum_def(char * fname); +#else +extern void enum_def(); +#endif + +#endif +extern SetWordType zzerr1[]; +extern SetWordType zzerr2[]; +extern SetWordType zzerr3[]; +extern SetWordType zzerr4[]; +extern SetWordType setwd1[]; +extern SetWordType zzerr5[]; +extern SetWordType zzerr6[]; +extern SetWordType zzerr7[]; +extern SetWordType zzerr8[]; +extern SetWordType zzerr9[]; +extern SetWordType setwd2[]; +extern SetWordType zzerr10[]; +extern SetWordType zzerr11[]; +extern SetWordType zzerr12[]; +extern SetWordType zzerr13[]; +extern SetWordType setwd3[]; +extern SetWordType zzerr14[]; +extern SetWordType zzerr15[]; +extern SetWordType zzerr16[]; +extern SetWordType zzerr17[]; +extern SetWordType zzerr18[]; +extern SetWordType zzerr19[]; +extern SetWordType zzerr20[]; +extern SetWordType zzerr21[]; +extern SetWordType setwd4[]; +extern SetWordType zzerr22[]; +extern SetWordType zzerr23[]; +extern SetWordType zzerr24[]; +extern SetWordType zzerr25[]; +extern SetWordType zzerr26[]; +extern SetWordType setwd5[]; +extern SetWordType zzerr27[]; +extern SetWordType zzerr28[]; +extern SetWordType zzerr29[]; +extern SetWordType zzerr30[]; +extern SetWordType zzerr31[]; +extern SetWordType zzerr32[]; +extern SetWordType zzerr33[]; +extern SetWordType setwd6[]; +extern SetWordType zzerr34[]; +extern SetWordType zzerr35[]; +extern SetWordType zzerr36[]; +extern SetWordType zzerr37[]; +extern SetWordType zzerr38[]; +extern SetWordType zzerr39[]; +extern SetWordType zzerr40[]; +extern SetWordType zzerr41[]; +extern SetWordType zzerr42[]; +extern SetWordType setwd7[]; +extern SetWordType zzerr43[]; +extern SetWordType zzerr44[]; +extern SetWordType zzerr45[]; +extern SetWordType zzerr46[]; +extern SetWordType zzerr47[]; +extern SetWordType zzerr48[]; +extern SetWordType zzerr49[]; +extern SetWordType zzerr50[]; +extern SetWordType zzerr51[]; +extern SetWordType zzerr52[]; +extern SetWordType zzerr53[]; +extern SetWordType setwd8[]; +extern SetWordType zzerr54[]; +extern SetWordType zzerr55[]; +extern SetWordType zzerr56[]; +extern SetWordType zzerr57[]; +extern SetWordType setwd9[]; +extern SetWordType zzerr58[]; +extern SetWordType zzerr59[]; +extern SetWordType zzerr60[]; +extern SetWordType zzerr61[]; +extern SetWordType zzerr62[]; +extern SetWordType zzerr63[]; +extern SetWordType zzerr64[]; +extern SetWordType zzerr65[]; +extern SetWordType setwd10[]; +extern SetWordType setwd11[]; diff --git a/Tools/CodeTools/Source/Pccts/build.xml b/Tools/CodeTools/Source/Pccts/build.xml new file mode 100644 index 0000000000..4f4e0a9e7c --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/build.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/Pccts/dlg/DlgMS.mak b/Tools/CodeTools/Source/Pccts/dlg/DlgMS.mak new file mode 100644 index 0000000000..4a9019b1c6 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/dlg/DlgMS.mak @@ -0,0 +1,121 @@ +# PCCTS directory + +# You will need to set the LIB variable similar to this. +# LIB="C:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/lib;c:/Microsoft Visual Studio .NET 2003/Vc7/PlatformSDK/Lib" + +# PCCTS_HOME= +PCCTS_HOME=$(WORKSPACE)\Tools\Source\TianoTools\Pccts +DLG_SRC=$(PCCTS_HOME)\dlg +PCCTS_H=$(PCCTS_HOME)\h + + +# Support directories +SET=$(PCCTS_HOME)\support\set + + +# Compiler stuff +CC = cl +CFLAGS = /nologo -I "." -I "$(PCCTS_H)" -I "$(SET)" -D "USER_ZZSYN" -D "PC" \ + -D "ZZLEXBUFSIZE=65536" /D "LONGFILENAMES" /W3 /Zi + +DLG_OBJS = dlg_p.obj dlg_a.obj main.obj err.obj support.obj \ + output.obj relabel.obj automata.obj + +SUPPORT_OBJS = set.obj + +# Dependencies + +dlg.exe: $(DLG_OBJS) $(SUPPORT_OBJS) + $(CC) $(CFLAGS) -o dlg.exe $(DLG_OBJS) $(SUPPORT_OBJS) + del *.obj + del *.ilk + del *.pdb + move dlg.exe $(WORKSPACE)\Tools\bin\. + +dlg_p.obj: $(DLG_SRC)\dlg_p.c \ + $(PCCTS_H)\antlr.h \ + $(PCCTS_H)\config.h \ + $(PCCTS_H)\dlgdef.h \ + $(SET)\set.h \ + $(DLG_SRC)\dlg.h \ + $(DLG_SRC)\mode.h \ + $(DLG_SRC)\tokens.h \ + + $(CC) -c $(CFLAGS) $(DLG_SRC)\dlg_p.c + +dlg_a.obj: $(DLG_SRC)\dlg_a.c \ + $(PCCTS_H)\antlr.h \ + $(PCCTS_H)\config.h \ + $(PCCTS_H)\dlgauto.h \ + $(PCCTS_H)\dlgdef.h \ + $(SET)\set.h \ + $(DLG_SRC)\dlg.h \ + $(DLG_SRC)\mode.h \ + $(DLG_SRC)\tokens.h \ + + $(CC) -c $(CFLAGS) $(DLG_SRC)\dlg_a.c + +main.obj: $(DLG_SRC)\main.c \ + $(PCCTS_H)\antlr.h \ + $(PCCTS_H)\config.h \ + $(PCCTS_H)\dlgdef.h \ + $(SET)\set.h \ + $(DLG_SRC)\dlg.h \ + $(DLG_SRC)\mode.h \ + $(DLG_SRC)\stdpccts.h \ + $(DLG_SRC)\tokens.h \ + + $(CC) -c $(CFLAGS) $(DLG_SRC)\main.c + +err.obj: $(DLG_SRC)\err.c \ + $(PCCTS_H)\antlr.h \ + $(PCCTS_H)\config.h \ + $(PCCTS_H)\dlgdef.h \ + $(PCCTS_H)\err.h \ + $(SET)\set.h \ + $(DLG_SRC)\dlg.h \ + $(DLG_SRC)\tokens.h \ + + $(CC) -c $(CFLAGS) $(DLG_SRC)\err.c + +support.obj: $(DLG_SRC)\support.c \ + $(PCCTS_H)\config.h \ + $(SET)\set.h \ + $(DLG_SRC)\dlg.h \ + + $(CC) -c $(CFLAGS) $(DLG_SRC)\support.c + +output.obj: $(DLG_SRC)\output.c \ + $(PCCTS_H)\config.h \ + $(SET)\set.h \ + $(DLG_SRC)\dlg.h \ + + $(CC) -c $(CFLAGS) $(DLG_SRC)\output.c + +relabel.obj: $(DLG_SRC)\relabel.c \ + $(PCCTS_H)\config.h \ + $(SET)\set.h \ + $(DLG_SRC)\dlg.h \ + + $(CC) -c $(CFLAGS) $(DLG_SRC)\relabel.c + +automata.obj: $(DLG_SRC)\automata.c \ + $(PCCTS_H)\config.h \ + $(SET)\set.h \ + $(DLG_SRC)\dlg.h \ + + $(CC) -c $(CFLAGS) $(DLG_SRC)\automata.c + + +set.obj: $(SET)\set.c \ + $(PCCTS_H)\config.h \ + $(SET)\set.h \ + + $(CC) -c $(CFLAGS) $(SET)\set.c + +clean: + del *.obj + +distclean: + del *.obj + del $(WORKSPACE)\Tools\bin\dlg.exe diff --git a/Tools/CodeTools/Source/Pccts/dlg/DlgPPC.mak b/Tools/CodeTools/Source/Pccts/dlg/DlgPPC.mak new file mode 100644 index 0000000000..55b643ad88 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/dlg/DlgPPC.mak @@ -0,0 +1,84 @@ +# File: dlgPPC.make +# Target: dlgPPC +# Sources: automata.c +# dlg_a.c +# dlg_p.c +# err.c +# main.c +# output.c +# relabel.c +# support.c +# ::support:set:set.c +# Created: Sunday, May 17, 1998 11:34:20 PM +# Author: Kenji Tanaka + + +MAKEFILE = dlgPPC.make +Â¥MondoBuildÂ¥ = {MAKEFILE} # Make blank to avoid rebuilds when makefile is modified +Includes = ¶ + -i "::h:" ¶ + -i "::support:set:" +SymÂ¥PPC = +ObjDirÂ¥PPC = ":Obj:" + +PPCCOptions = {Includes} {SymÂ¥PPC} -w off -d MPW -d __STDC__=1 -d USER_ZZSYN + +ObjectsÂ¥PPC = ¶ + "{ObjDirÂ¥PPC}automata.c.x" ¶ + "{ObjDirÂ¥PPC}dlg_a.c.x" ¶ + "{ObjDirÂ¥PPC}dlg_p.c.x" ¶ + "{ObjDirÂ¥PPC}err.c.x" ¶ + "{ObjDirÂ¥PPC}main.c.x" ¶ + "{ObjDirÂ¥PPC}output.c.x" ¶ + "{ObjDirÂ¥PPC}relabel.c.x" ¶ + "{ObjDirÂ¥PPC}support.c.x" ¶ + "{ObjDirÂ¥PPC}set.c.x" + + +dlgPPC ÄÄ {Â¥MondoBuildÂ¥} {ObjectsÂ¥PPC} + PPCLink ¶ + -o {Targ} {SymÂ¥PPC} ¶ + {ObjectsÂ¥PPC} ¶ + -t 'MPST' ¶ + -c 'MPS ' ¶ + "{SharedLibraries}InterfaceLib" ¶ + "{SharedLibraries}StdCLib" ¶ + "{SharedLibraries}MathLib" ¶ + "{PPCLibraries}StdCRuntime.o" ¶ + "{PPCLibraries}PPCCRuntime.o" ¶ + "{PPCLibraries}PPCToolLibs.o" + + +"{ObjDirÂ¥PPC}automata.c.x" Ä {Â¥MondoBuildÂ¥} automata.c + {PPCC} automata.c -o {Targ} {PPCCOptions} + +"{ObjDirÂ¥PPC}dlg_a.c.x" Ä {Â¥MondoBuildÂ¥} dlg_a.c + {PPCC} dlg_a.c -o {Targ} {PPCCOptions} + +"{ObjDirÂ¥PPC}dlg_p.c.x" Ä {Â¥MondoBuildÂ¥} dlg_p.c + {PPCC} dlg_p.c -o {Targ} {PPCCOptions} + +"{ObjDirÂ¥PPC}err.c.x" Ä {Â¥MondoBuildÂ¥} err.c + {PPCC} err.c -o {Targ} {PPCCOptions} + +"{ObjDirÂ¥PPC}main.c.x" Ä {Â¥MondoBuildÂ¥} main.c + {PPCC} main.c -o {Targ} {PPCCOptions} + +"{ObjDirÂ¥PPC}output.c.x" Ä {Â¥MondoBuildÂ¥} output.c + {PPCC} output.c -o {Targ} {PPCCOptions} + +"{ObjDirÂ¥PPC}relabel.c.x" Ä {Â¥MondoBuildÂ¥} relabel.c + {PPCC} relabel.c -o {Targ} {PPCCOptions} + +"{ObjDirÂ¥PPC}support.c.x" Ä {Â¥MondoBuildÂ¥} support.c + {PPCC} support.c -o {Targ} {PPCCOptions} + +"{ObjDirÂ¥PPC}set.c.x" Ä {Â¥MondoBuildÂ¥} "::support:set:set.c" + {PPCC} "::support:set:set.c" -o {Targ} {PPCCOptions} + + +dlgPPC ÄÄ dlg.r + Rez dlg.r -o dlgPPC -a + +Install Ä dlgPPC + Duplicate -y dlgPPC "{MPW}"Tools:dlg diff --git a/Tools/CodeTools/Source/Pccts/dlg/automata.c b/Tools/CodeTools/Source/Pccts/dlg/automata.c new file mode 100644 index 0000000000..d6d5d7809d --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/dlg/automata.c @@ -0,0 +1,353 @@ +/* Automata conversion functions for DLG + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * DLG 1.33 + * Will Cohen + * With mods by Terence Parr; AHPCRC, University of Minnesota + * 1989-2001 + */ + +#include +#include "pcctscfg.h" +#include "dlg.h" +#ifdef MEMCHK +#include "trax.h" +#else +#ifdef __STDC__ +#include +#else +#include +#endif /* __STDC__ */ +#endif + +#define hash_list struct _hash_list_ +hash_list{ + hash_list *next; /* next thing in list */ + dfa_node *node; + }; + +int dfa_allocated = 0; /* keeps track of number of dfa nodes */ +dfa_node **dfa_array; /* root of binary tree that stores dfa array */ +dfa_node *dfa_model_node; +hash_list *dfa_hash[HASH_SIZE]; /* used to quickly find */ + /* desired dfa node */ + +void +#ifdef __USE_PROTOS +make_dfa_model_node(int width) +#else +make_dfa_model_node(width) +int width; +#endif +{ + register int i; + dfa_model_node = (dfa_node*) malloc(sizeof(dfa_node) + + sizeof(int)*width); + dfa_model_node->node_no = -1; /* impossible value for real dfa node */ + dfa_model_node->dfa_set = 0; + dfa_model_node->alternatives = FALSE; + dfa_model_node->done = FALSE; + dfa_model_node->nfa_states = empty; + for(i = 0; itrans[i] = NIL_INDEX; + } +} + + +/* adds a new nfa to the binary tree and returns a pointer to it */ +dfa_node * +#ifdef __USE_PROTOS +new_dfa_node(set nfa_states) +#else +new_dfa_node(nfa_states) +set nfa_states; +#endif +{ + register int j; + register dfa_node *t; + static int dfa_size=0; /* elements dfa_array[] can hold */ + + ++dfa_allocated; + if (dfa_size<=dfa_allocated){ + /* need to redo array */ + if (!dfa_array){ + /* need some to do inital allocation */ + dfa_size=dfa_allocated+DFA_MIN; + dfa_array=(dfa_node **) malloc(sizeof(dfa_node*)* + dfa_size); + }else{ + /* need more space */ + dfa_size=2*(dfa_allocated+1); + dfa_array=(dfa_node **) realloc(dfa_array, + sizeof(dfa_node*)*dfa_size); + } + } + /* fill out entry in array */ + t = (dfa_node*) malloc(sizeof(nfa_node)+sizeof(int)*class_no); + *t = *dfa_model_node; + for (j=0; jtrans[j] = NIL_INDEX; + t->node_no = dfa_allocated; + t->nfa_states = set_dup(nfa_states); + dfa_array[dfa_allocated] = t; + return t; +} + + +/* past a pointer to the start start of the nfa graph + * nfa_to_dfa convers this graph to dfa. The function returns + * a pointer to the first dfa state. + * NOTE: The function that prints out the table will have to figure out how + * to find the other dfa states given the first dfa_state and the number of dfa + * nodes allocated + */ +dfa_node ** +#ifdef __USE_PROTOS +nfa_to_dfa(nfa_node *start) +#else +nfa_to_dfa(start) +nfa_node *start; +#endif +{ + register dfa_node *d_state, *trans_d_state; + register int a; + set t; + int last_done; + unsigned *nfa_list; + unsigned *reach_list; + + reach_list = (unsigned *) malloc((2+nfa_allocated)*sizeof(unsigned)); + if (!start) return NULL; + t = set_of(NFA_NO(start)); + _set_pdq(t,reach_list); + closure(&t,reach_list); + /* Make t a dfa state */ + d_state = dfastate(t); + last_done = DFA_NO(d_state); + + do { + /* Mark dfa state x as "done" */ + d_state->done = TRUE; + nfa_list = set_pdq(d_state->nfa_states); + for (a = 0; at, labeled with a */ + d_state->trans[a] = DFA_NO(trans_d_state); + d_state->alternatives = TRUE; + } + } + free(nfa_list); + ++last_done; /* move forward in queue */ + /* And so forth until nothing isn't done */ + d_state = DFA(last_done); + } while (last_done<=dfa_allocated); + + free(reach_list); + set_free(t); + + /* returns pointer to the array that holds the automaton */ + return dfa_array; +} + +void +#ifdef __USE_PROTOS +clear_hash(void) +#else +clear_hash() +#endif +{ + register int i; + + for(i=0; inext; + } + total+=j; + fprintf(f,"bin[%d] has %d\n",i,j); + } + fprintf(f,"total = %d\n",total); +} +#endif + +/* Returns a pointer to a dfa node that has the same nfa nodes in it. + * This may or maynot be a newly created node. + */ +dfa_node * +#ifdef __USE_PROTOS +dfastate(set nfa_states) +#else +dfastate(nfa_states) +set nfa_states; +#endif +{ + register hash_list *p; + int bin; + + /* hash using set and see if it exists */ + bin = set_hash(nfa_states,HASH_SIZE); + p = dfa_hash[bin]; + while(p && !set_equ(nfa_states,(p->node)->nfa_states)){ + p = p->next; + } + if(!p){ + /* next state to add to hash table */ + p = (hash_list*)malloc(sizeof(hash_list)); + p->node = new_dfa_node(nfa_states); + p->next = dfa_hash[bin]; + dfa_hash[bin] = p; + } + return (p->node); +} + + +/* this reach assumes the closure has been done already on set */ +int +#ifdef __USE_PROTOS +reach(unsigned *nfa_list, register int a, unsigned *reach_list) +#else +reach(nfa_list, a, reach_list) +unsigned *nfa_list; +register int a; +unsigned *reach_list; +#endif +{ + register unsigned *e; + register nfa_node *node; + int t=0; + + e = nfa_list; + if (e){ + while (*e != nil){ + node = NFA(*e); + if (set_el(a,node->label)){ + t=1; + *reach_list=NFA_NO(node->trans[0]); + ++reach_list; + } + ++e; + } + } + *reach_list=nil; + return t; +} + +/* finds all the nodes that can be reached by epsilon transitions + from the set of a nodes and returns puts them back in set b */ +set +#ifdef __USE_PROTOS +closure(set *b, unsigned *reach_list) +#else +closure(b, reach_list) +set *b; +unsigned *reach_list; +#endif +{ + register nfa_node *node,*n; /* current node being examined */ + register unsigned *e; + + ++operation_no; +#if 0 + t = e = set_pdq(*b); +#else + e=reach_list; +#endif + while (*e != nil){ + node = NFA(*e); + set_orel(NFA_NO(node),b); + /* mark it done */ + node->nfa_set = operation_no; + if ((n=node->trans[0]) != NIL_INDEX && set_nil(node->label) && + (n->nfa_set != operation_no)){ + /* put in b */ + set_orel(NFA_NO(n),b); + close1(n,operation_no,b); + } + if ((n=node->trans[1]) != NIL_INDEX && + (n->nfa_set != operation_no)){ + /* put in b */ + set_orel(NFA_NO(node->trans[1]),b); + close1(n,operation_no,b); + } + ++e; + } +#if 0 + free(t); +#endif + return *b; +} + +#ifdef __USE_PROTOS +void close1(nfa_node *node, int o, set *b) +#else +void close1(node,o,b) +nfa_node *node; +int o; /* marker to avoid cycles */ +set *b; +#endif +{ + register nfa_node *n; /* current node being examined */ + + /* mark it done */ + node->nfa_set = o; + if ((n=node->trans[0]) != NIL_INDEX && set_nil(node->label) && + (n->nfa_set != o)){ + /* put in b */ + set_orel(NFA_NO(n),b); + close1(n,o,b); + } + if ((n=node->trans[1]) != NIL_INDEX && + (n->nfa_set != o)){ + /* put in b */ + set_orel(NFA_NO(node->trans[1]),b); + close1(n,o,b); + } +} diff --git a/Tools/CodeTools/Source/Pccts/dlg/build.xml b/Tools/CodeTools/Source/Pccts/dlg/build.xml new file mode 100644 index 0000000000..4195950c7b --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/dlg/build.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/Pccts/dlg/dlg.1 b/Tools/CodeTools/Source/Pccts/dlg/dlg.1 new file mode 100644 index 0000000000..f68e3ae8a7 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/dlg/dlg.1 @@ -0,0 +1,79 @@ +.TH dlg 1 "April 1994" "DLG" "PCCTS Manual Pages" +.SH NAME +dlg \- DFA Lexical Analyzer Generator +.SH SYNTAX +.LP +\fBdlg\fR [\fIoptions\fR] \fIlexical_spec\fR [\fIoutput_file\fR] +.SH DESCRIPTION +.B dlg +is a tool that produces fast deterministic finite automata for recognizing +regular expressions in input. +.SH OPTIONS +.IP "\fB-CC\fR" +Generate C++ output. The \fIoutput_file\fP is not specified in this +case. +.IP "\fB-C\fR[\fP level\fR] +Where \fPlevel\fR is the compression level used. 0 indications no +compression, 1 removes all unused characters from the transition from table, +and 2 maps equivalent characters into the same character classes. It is +suggested that level -C2 is used, since it will significantly reduce the size +of the dfa produced for lexical analyzer. +.IP "\fB-m\fP +Produces the header file for the lexical mode with a name other than +the default name of "mode.h". +.IP \fB-i\fP +An interactive, or as interactive as possible, parser is produced. A character +is only obtained when required to decide which state to go to. Some care +must be taken to obtain accept states that do not require look ahead at the +next character to determine if that is the stop state. Any regular expression +with a Kleene closure at the end is guaranteed to require another character +of look ahead. +.IP "\fB-cl\fP class +Specify a class name for DLG to generate. The default is DLGLexer. +'class' will be a subclass of DLGLexerBase; only used for -CC. +.IP \fB-ci\fP +The automaton will treat upper and lower case characters identically. +This is accomplished in the automaton; the characters in the lexical +buffer are unmodified. +.IP \fB-cs\fP +Upper and lower case characters are treated as distinct. This is the +default. +.IP "\fB-o\fP dir +Directory where output files should go (default="."). This is very +nice for keeping the source directory clear of ANTLR and DLG spawn. +.IP \fB-Wambiguity\fP +Warns if more than one regular expression could match the same character +sequence. The warnings give the numbers of the expressions in the dlg +lexical specification file. The numbering of the expressions starts at one. +Multiple warnings may be print for the same expressions. +.IP \- +Used in place of file names to get input from standard in or send output +to standard out. +.SH "SPECIAL CONSIDERATIONS" +.PP +\fIDlg\fP works... we think. There is no implicit guarantee of +anything. We reserve no \fBlegal\fP rights to the software known as +the Purdue Compiler Construction Tool Set (PCCTS) \(em PCCTS is in the +public domain. An individual or company may do whatever they wish +with source code distributed with PCCTS or the code generated by +PCCTS, including the incorporation of PCCTS, or its output, into +commercial software. We encourage users to develop software with +PCCTS. However, we do ask that credit is given to us for developing +PCCTS. By "credit", we mean that if you incorporate our source code +into one of your programs (commercial product, research project, or +otherwise) that you acknowledge this fact somewhere in the +documentation, research report, etc... If you like PCCTS and have +developed a nice tool with the output, please mention that you +developed it using PCCTS. As long as these guidelines are followed, we +expect to continue enhancing this system and expect to make other +tools available as they are completed. +.SH FILES +.B mode.h +, +.B dlgauto.h +, +.B dlgdef.h +.SH SEE ALSO +.BR antlr (1), +.BR pccts (1) +.SH BUGS diff --git a/Tools/CodeTools/Source/Pccts/dlg/dlg.h b/Tools/CodeTools/Source/Pccts/dlg/dlg.h new file mode 100644 index 0000000000..9f387c0a1c --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/dlg/dlg.h @@ -0,0 +1,250 @@ +/* dlg header file + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * DLG 1.33 + * Will Cohen + * With mods by Terence Parr; AHPCRC, University of Minnesota + * 1989-2001 + */ + +/* MR1 Move pcctscfg.h to top of file */ + +#include "pcctscfg.h" + +/* turn off warnings for unreferenced labels */ + +#ifdef _MSC_VER +#pragma warning(disable:4102) +#endif + +#include "set.h" + +#define TRUE 1 +#define FALSE 0 + +/***** output related stuff *******************/ +#define IN input_stream +#define OUT output_stream + +#define MAX_MODES 50 /* number of %%names allowed */ +#define MAX_ON_LINE 10 + +#define NFA_MIN 64 /* minimum nfa_array size */ +#define DFA_MIN 64 /* minimum dfa_array size */ + +#define DEFAULT_CLASSNAME "DLGLexer" + +/* these macros allow the size of the character set to be easily changed */ +/* NOTE: do NOT change MIN_CHAR since EOF is the lowest char, -1 */ +#define MIN_CHAR (-1) /* lowest possible character possible on input */ +#define MAX_CHAR 255 /* highest possible character possible on input */ +#define CHAR_RANGE (1+(MAX_CHAR) - (MIN_CHAR)) + +/* indicates that the not an "array" reference */ +#define NIL_INDEX 0 + +/* size of hash table used to find dfa_states quickly */ +#define HASH_SIZE 211 + +#define nfa_node struct _nfa_node +nfa_node { + int node_no; + int nfa_set; + int accept; /* what case to use */ + nfa_node *trans[2]; + set label; /* one arc always labelled with epsilon */ +}; + +#define dfa_node struct _dfa_node +dfa_node { + int node_no; + int dfa_set; + int alternatives; /* used for interactive mode */ + /* are more characters needed */ + int done; + set nfa_states; + int trans[1];/* size of transition table depends on + * number of classes required for automata. + */ + + +}; + +/******** macros for accessing the NFA and DFA nodes ****/ +#define NFA(x) (nfa_array[x]) +#define DFA(x) (dfa_array[x]) +#define DFA_NO(x) ( (x) ? (x)->node_no : NIL_INDEX) +#define NFA_NO(x) ( (x) ? (x)->node_no : NIL_INDEX) + +/******** wrapper for memory checking ***/ +/*#define malloc(x) dlg_malloc((x),__FILE__,__LINE__)*/ + +/*#define calloc(x,y) dlg_calloc((x),(y),__FILE__,__LINE__)*/ + +/******** antlr attributes *************/ +typedef struct { + unsigned char letter; + nfa_node *l,*r; + set label; + } Attrib; + +#define zzcr_attr(attr, token, text) { \ + (attr)->letter = text[0]; (attr)->l = NULL; \ + (attr)->r = NULL; (attr)->label = empty; \ +} +#define zzd_attr(a) set_free((a)->label); + +/******************** Variable ******************************/ +extern char program[]; /* tells what program this is */ +extern char version[]; /* tells what version this is */ +extern char *file_str[]; /* file names being used */ +extern int err_found; /* flag to indicate error occured */ +extern int action_no; /* last action function printed */ +extern int func_action; /* should actions be turned into functions?*/ +extern set used_chars; /* used to label trans. arcs */ +extern set used_classes; /* classes or chars used to label trans. arcs */ +extern int class_no; /* number of classes used */ +extern set class_sets[]; /* shows char. in each class */ +extern set normal_chars; /* mask off unused portion of set */ +extern int comp_level; /* what compression level to use */ +extern int interactive; /* interactive scanner (avoid lookahead)*/ +extern int mode_counter; /* keeps track of the number of %%name */ +extern int dfa_basep[]; /* start of each group of dfa */ +extern int dfa_class_nop[];/* number of transistion arcs in */ + /* each dfa in each mode */ +extern int nfa_allocated; +extern int dfa_allocated; +extern nfa_node **nfa_array; /* start of nfa "array" */ +extern dfa_node **dfa_array; /* start of dfa "array" */ +extern int operation_no; /* unique number for each operation */ +extern FILE *input_stream; /* where description read from */ +extern FILE *output_stream; /* where to put the output */ +extern FILE *mode_stream; /* where to put the mode output */ +extern FILE *class_stream; +extern char *mode_file; /* name of file for mode output */ +extern int gen_ansi; /* produce ansi compatible code */ +extern int case_insensitive;/* ignore case of input spec. */ +extern int warn_ambig; /* show if regular expressions ambiguous */ +extern int gen_cpp; +extern char *cl_file_str; +extern int firstLexMember; /* MR1 */ +extern char *OutputDirectory; +extern char *class_name; + +/******************** Functions ******************************/ +#ifdef __USE_PROTOS +extern char *dlg_malloc(int, char *, int); /* wrapper malloc */ +extern char *dlg_calloc(int, int, char *, int); /* wrapper calloc */ +extern int reach(unsigned *, register int, unsigned *); +extern set closure(set *, unsigned *); +extern dfa_node *new_dfa_node(set); +extern nfa_node *new_nfa_node(void); +extern dfa_node *dfastate(set); +extern dfa_node **nfa_to_dfa(nfa_node *); +extern void internal_error(char *, char *, int); /* MR9 23-Sep-97 */ +extern FILE *read_stream(char *); /* opens file for reading */ +extern FILE *write_stream(char *); /* opens file for writing */ +extern void make_nfa_model_node(void); +extern void make_dfa_model_node(int); +extern char *ClassName(char *); +extern char *OutMetaName(char *); +extern void error(char*, int); +extern void warning(char*, int); +extern void p_head(void); +extern void p_class_hdr(void); +extern void p_includes(void); +extern void p_tables(void); +extern void p_tail(void); /* MR1 */ +extern void p_class_def1(void); /* MR1 */ +extern void new_automaton_mode(void); /* MR1 */ +extern int relabel(nfa_node *,int); /* MR1 */ +extern void p_shift_table(int); /* MR1 */ +extern void p_bshift_table(void); /* MR1 */ +extern void p_class_table(void); /* MR1 */ +extern void p_mode_def(char *,int); /* MR1 */ +extern void init(void); /* MR1 */ +extern void p_class_def2(void); /* MR1 */ +extern void clear_hash(void); /* MR1 */ +extern void p_alternative_table(void); /* MR1 */ +extern void p_node_table(void); /* MR1 */ +extern void p_dfa_table(void); /* MR1 */ +extern void p_accept_table(void); /* MR1 */ +extern void p_action_table(void); /* MR1 */ +extern void p_base_table(void); /* MR1 */ +extern void p_single_node(int,int); /* MR1 */ +extern char * minsize(int); /* MR1 */ +extern void close1(nfa_node *,int,set *); /* MR1 */ +extern void partition(nfa_node *,int); /* MR1 */ +extern void intersect_nfa_labels(nfa_node *,set *); /* MR1 */ +extern void r_intersect(nfa_node *,set *); /* MR1 */ +extern void label_node(nfa_node *); /* MR1 */ +extern void label_with_classes(nfa_node *); /* MR1 */ + +#else +extern char *dlg_malloc(); /* wrapper malloc */ +extern char *dlg_calloc(); /* wrapper calloc */ +extern int reach(); +extern set closure(); +extern dfa_node *new_dfa_node(); +extern nfa_node *new_nfa_node(); +extern dfa_node *dfastate(); +extern dfa_node **nfa_to_dfa(); +extern void internal_error(); /* MR9 23-Sep-97 */ +extern FILE *read_stream(); /* opens file for reading */ +extern FILE *write_stream(); /* opens file for writing */ +extern void make_nfa_model_node(); +extern void make_dfa_model_node(); +extern char *ClassName(); +extern char *OutMetaName(); +extern void error(); +extern void warning(); +extern void p_head(); /* MR9 */ +extern void p_class_hdr(); /* MR9 */ +extern void p_includes(); /* MR9 */ +extern void p_tables(); /* MR9 */ +extern void p_tail(); /* MR1 */ +extern void p_class_def1(); /* MR1 */ +extern void new_automaton_mode(); /* MR1 */ +extern int relabel(); /* MR1 */ +extern void p_shift_table(); /* MR1 */ +extern void p_bshift_table(); /* MR1 */ +extern void p_class_table(); /* MR1 */ +extern void p_mode_def(); /* MR1 */ +extern void init(); /* MR1 */ +extern void p_class_def2(); /* MR1 */ +extern void clear_hash(); /* MR1 */ +extern void p_alternative_table(); /* MR1 */ +extern void p_node_table(); /* MR1 */ +extern void p_dfa_table(); /* MR1 */ +extern void p_accept_table(); /* MR1 */ +extern void p_action_table(); /* MR1 */ +extern void p_base_table(); /* MR1 */ +extern void p_single_node(); /* MR1 */ +extern char * minsize(); /* MR1 */ +extern void close1(); /* MR1 */ +extern void partition(); /* MR1 */ +extern void intersect_nfa_labels(); /* MR1 */ +extern void r_intersect(); /* MR1 */ +extern void label_node(); /* MR1 */ +extern void label_with_classes(); /* MR1 */ + +#endif diff --git a/Tools/CodeTools/Source/Pccts/dlg/dlg.r b/Tools/CodeTools/Source/Pccts/dlg/dlg.r new file mode 100644 index 0000000000..c5311fa1b8 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/dlg/dlg.r @@ -0,0 +1,275 @@ +/* + File: dlgMPW.r + Target: dlg 133MR + Created: Monday, June 15, 1998 4:44:11 AM + Author: Kenji Tanaka (kentar@osa.att.ne.jp) +*/ + +#include "cmdo.r" + +resource 'cmdo' (128, "Dlg") { + { /* array dialogs: 1 elements */ + /* [1] */ + 295, + "DLG -- Purdue Compiler Construction Tool" + " Set (PCCTS) lexical analyzer generator.", + { /* array itemArray: 18 elements */ + /* [1] */ + NotDependent { + + }, + CheckOption { + NotSet, + {35, 175, 50, 225}, + "On", + "-CC", + "When this control is checked, DLG genera" + "tes a scanner using C++ classes rather t" + "han C functions." + }, + /* [2] */ + Or { + { /* array OrArray: 1 elements */ + /* [1] */ + 1 + } + }, + RegularEntry { + "Lexer Class Name:", + {35, 225, 50, 355}, + {35, 355, 51, 450}, + "DLGLexer", + keepCase, + "-cl", + "This entry specifies the name DLG uses f" + "or the C++ lexer class." + }, + /* [3] */ + NotDependent { + + }, + TextBox { + gray, + {25, 165, 60, 460}, + "C++ Code Generation" + }, + /* [4] */ + NotDependent { + + }, + Files { + InputFile, + RequiredFile { + {37, 25, 56, 135}, + "Input File", + "", + "Choose the lexical description file for " + "DLG to process." + }, + Additional { + "", + "", + "", + "", + { /* array TypesArray: 1 elements */ + /* [1] */ + text + } + } + }, + /* [5] */ + Or { + { /* array OrArray: 1 elements */ + /* [1] */ + -1 + } + }, + Files { + OutputFile, + RequiredFile { + {66, 25, 85, 135}, + "Output File", + "", + "Choose the name of the file that will ho" + "ld the DLG-produced scanner." + }, + NoMore { + + } + }, + /* [6] */ + Or { + { /* array OrArray: 2 elements */ + /* [1] */ + 1, + /* [2] */ + 5 + } + }, + Dummy { + + }, + /* [7] */ + NotDependent { + + }, + Redirection { + DiagnosticOutput, + {90, 25} + }, + /* [8] */ + NotDependent { + + }, + TextBox { + gray, + {25, 20, 132, 145}, + "Files" + }, + /* [9] */ + NotDependent { + + }, + Files { + DirOnly, + OptionalFile { + {68, 175, 84, 305}, + {88, 175, 107, 305}, + "Output Directory", + ":", + "-o", + "", + "Choose the directory where DLG will put " + "its output.", + dim, + "Output DirectoryI", + "", + "" + }, + NoMore { + + } + }, + /* [10] */ + NotDependent { + + }, + RegularEntry { + "Mode File Name:", + {68, 315, 83, 450}, + {88, 315, 104, 450}, + "mode.h", + keepCase, + "-m", + "This entry specifies the name DLG uses f" + "or its lexical mode output file." + }, + /* [11] */ + NotDependent { + + }, + RadioButtons { + { /* array radioArray: 3 elements */ + /* [1] */ + {134, 175, 149, 255}, "None", "", Set, "When this option is selected, DLG will n" + "ot compress its tables.", + /* [2] */ + {134, 265, 149, 345}, "Level 1", "-C1", NotSet, "When this option is selected, DLG will r" + "emove all unused characters from the tra" + "nsition-from table.", + /* [3] */ + {134, 360, 149, 450}, "Level 2", "-C2", NotSet, "When this option is selected, DLG will p" + "erform level 1 compression plus it will " + "map equivalent characters into the same " + "character classes." + } + }, + /* [12] */ + NotDependent { + + }, + TextBox { + gray, + {124, 165, 156, 460}, + "Table Compression" + }, + /* [13] */ + NotDependent { + + }, + CheckOption { + Set, + {165, 20, 180, 145}, + "Case Sensitive", + "-ci", + "When this control is checked, the DLG au" + "tomaton will treat upper and lower case " + "characters identically." + }, + /* [14] */ + NotDependent { + + }, + CheckOption { + NotSet, + {165, 150, 180, 300}, + "Interactive Scanner", + "-i", + "When this control is checked, DLG will g" + "enerate as interactive a scanner as poss" + "ible." + }, + /* [15] */ + NotDependent { + + }, + CheckOption { + NotSet, + {165, 310, 180, 460}, + "Ambiguity Warnings", + "-Wambiguity", + "When this control is checked, DLG warns " + "if more than one regular expression coul" + "d match the same character sequence." + }, + /* [16] */ + NotDependent { + + }, + VersionDialog { + VersionString { + "1.33MR" + }, + "PCCTS was written by Terence Parr, Russe" + "ll Quong, Will Cohen, and Hank Dietz: 19" + "89-1998. MPW port by Scott Haney.", + noDialog + }, + /* [17] */ + And { + { /* array AndArray: 2 elements */ + /* [1] */ + 4, + /* [2] */ + 6 + } + }, + DoItButton { + + }, + /* [18] */ + NotDependent { + + }, + CheckOption { + NotSet, + {142, 20, 157, 148}, + "Generate ANSI C", + "-ga", + "When this control is checked, DLG genera" + "tes ANSI C compatible code." + } + } + } +}; + diff --git a/Tools/CodeTools/Source/Pccts/dlg/dlg1.txt b/Tools/CodeTools/Source/Pccts/dlg/dlg1.txt new file mode 100644 index 0000000000..06b320de2a --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/dlg/dlg1.txt @@ -0,0 +1,132 @@ + + + +dlg(1) PCCTS Manual Pages dlg(1) + + + +NAME + dlg - DFA Lexical Analyzer Generator + +SYNTAX + dlg [_o_p_t_i_o_n_s] _l_e_x_i_c_a_l__s_p_e_c [_o_u_t_p_u_t__f_i_l_e] + +DESCRIPTION + dlg is a tool that produces fast deterministic finite auto- + mata for recognizing regular expressions in input. + +OPTIONS + -CC Generate C++ output. The _o_u_t_p_u_t__f_i_l_e is not specified + in this case. + + -C[ level] + Where level is the compression level used. 0 indica- + tions no compression, 1 removes all unused characters + from the transition from table, and 2 maps equivalent + characters into the same character classes. It is sug- + gested that level -C2 is used, since it will signifi- + cantly reduce the size of the dfa produced for lexical + analyzer. + + -m Produces the header file for the lexical mode with a + name other than the default name of "mode.h". + + -i An interactive, or as interactive as possible, parser + is produced. A character is only obtained when + required to decide which state to go to. Some care + must be taken to obtain accept states that do not + require look ahead at the next character to determine + if that is the stop state. Any regular expression with + a Kleene closure at the end is guaranteed to require + another character of look ahead. + + -cl class + Specify a class name for DLG to generate. The default + is DLGLexer. + + -ci The automaton will treat upper and lower case charac- + ters identically. This is accomplished in the automa- + ton; the characters in the lexical buffer are unmodi- + fied. + + -cs Upper and lower case characters are treated as dis- + tinct. This is the default. + + -o dir + Directory where output files should go (default="."). + This is very nice for keeping the source directory + clear of ANTLR and DLG spawn. + + -Wambiguity + Warns if more than one regular expression could match + the same character sequence. The warnings give the + numbers of the expressions in the dlg lexical specifi- + cation file. The numbering of the expressions starts + at one. Multiple warnings may be print for the same + expressions. + + - Used in place of file names to get input from standard + in or send output to standard out. + +SPECIAL CONSIDERATIONS + _D_l_g works... we think. There is no implicit guarantee of + anything. We reserve no legal rights to the software known + as the Purdue Compiler Construction Tool Set (PCCTS) - PCCTS + is in the public domain. An individual or company may do + whatever they wish with source code distributed with PCCTS + or the code generated by PCCTS, including the incorporation + of PCCTS, or its output, into commercial software. We + encourage users to develop software with PCCTS. However, we + do ask that credit is given to us for developing PCCTS. By + "credit", we mean that if you incorporate our source code + into one of your programs (commercial product, research pro- + ject, or otherwise) that you acknowledge this fact somewhere + in the documentation, research report, etc... If you like + PCCTS and have developed a nice tool with the output, please + mention that you developed it using PCCTS. As long as these + guidelines are followed, we expect to continue enhancing + this system and expect to make other tools available as they + are completed. + +FILES + mode.h , dlgauto.h , dlgdef.h + +SEE ALSO + antlr(1), pccts(1) + +BUGS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/Pccts/dlg/dlg_a.c b/Tools/CodeTools/Source/Pccts/dlg/dlg_a.c new file mode 100644 index 0000000000..0b8982cf2a --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/dlg/dlg_a.c @@ -0,0 +1,1414 @@ + +/* parser.dlg -- DLG Description of scanner + * + * Generated from: dlg_p.g + * + * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001 + * Purdue University Electrical Engineering + * With AHPCRC, University of Minnesota + * ANTLR Version 1.33MR33 + */ + +#define ANTLR_VERSION 13333 +#include "pcctscfg.h" +#include "pccts_stdio.h" + +#include +#include "dlg.h" +#include "antlr.h" +#include "tokens.h" +#include "dlgdef.h" +LOOKAHEAD + +void +#ifdef __USE_PROTOS +zzerraction(void) +#else +zzerraction() +#endif +{ + (*zzerr)("invalid token"); + zzadvance(); + zzskip(); +} +/* + * D L G tables + * + * Generated from: parser.dlg + * + * 1989-2001 by Will Cohen, Terence Parr, and Hank Dietz + * Purdue University Electrical Engineering + * DLG Version 1.33MR33 + */ + +#include "mode.h" + + + + +int func_action; /* should actions be turned into functions?*/ +int lex_mode_counter = 0; /* keeps track of the number of %%names */ +/* MR1 */ +/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ +/* MR1 via <<%%lexmember...>> */ +/* MR1 */ +int lexMember = 0; /* <<%%lexmemeber ...>> MR1 */ +int lexAction = 0; /* <<%%lexaction ...>> MR1 */ +int parserClass = 0; /* <<%%parserclass ...>> MR1 */ +int lexPrefix = 0; /* <<%%lexprefix ...>> MR1 */ +char theClassName[100]; /* MR11 */ +char *pClassName=theClassName; /* MR11 */ +int firstLexMember=1; /* MR1 */ + +#ifdef __USE_PROTOS +void xxputc(int c) { /* MR1 */ +#else + void xxputc(c) /* MR1 */ + int c; /* MR1 */ + { /* MR1 */ +#endif + if (parserClass) { /* MR1 */ + *pClassName++=c; /* MR1 */ + *pClassName=0; /* MR1 */ + } else if (lexMember || lexPrefix) { /* MR1 */ + if (class_stream != NULL) fputc(c,class_stream); /* MR1 */ + } else { /* MR1 */ + fputc(c,OUT); /* MR1 */ + }; /* MR1 */ + } /* MR1 */ + +#ifdef __USE_PROTOS + void xxprintf(char *format,char *string) { /* MR1 */ +#else + void xxprintf(format,string) /* MR1 */ + char *format; /* MR1 */ + char *string; /* MR1 */ + { /* MR1 */ +#endif + if (lexMember || lexPrefix || parserClass) { /* MR1 */ + if (class_stream != NULL) /* MR1 */ + fprintf(class_stream,format,string); /* MR1 */ + } else { /* MR1 */ + fprintf(OUT,format,string); /* MR1 */ + }; /* MR1 */ + } /* MR1 */ + +static void act1() +{ + NLA = 1; + } + + +static void act2() +{ + NLA = 2; + zzskip(); + } + + +static void act3() +{ + NLA = 3; + zzline++; zzskip(); DAWDLE; + } + + +static void act4() +{ + NLA = L_EOF; + } + + +static void act5() +{ + NLA = PER_PER; + } + + +static void act6() +{ + NLA = NAME_PER_PER; + p_mode_def(&zzlextext[2],lex_mode_counter++); + } + + +static void act7() +{ + NLA = LEXMEMBER; + lexMember=1; /* MR1 */ + if (firstLexMember != 0) { /* MR1 */ + firstLexMember=0; /* MR1 */ + p_class_def1(); /* MR1 */ + }; /* MR1 */ + zzmode(ACT); /* MR1 */ + } + + +static void act8() +{ + NLA = LEXACTION; + lexAction=1;zzmode(ACT); + } + + +static void act9() +{ + NLA = PARSERCLASS; + parserClass=1; /* MR1 */ + zzmode(ACT); /* MR1 */ + } + + +static void act10() +{ + NLA = LEXPREFIX; + lexPrefix=1;zzmode(ACT); + } + + +static void act11() +{ + NLA = ACTION; + if (func_action) + fprintf(OUT,"\n%s %sact%d()\n{ ", + gen_cpp?"ANTLRTokenType":"static void", + gen_cpp?ClassName("::"):"", ++action_no); + zzmode(ACT); zzskip(); + } + + +static void act12() +{ + NLA = GREAT_GREAT; + } + + +static void act13() +{ + NLA = L_BRACE; + } + + +static void act14() +{ + NLA = R_BRACE; + } + + +static void act15() +{ + NLA = L_PAR; + } + + +static void act16() +{ + NLA = R_PAR; + } + + +static void act17() +{ + NLA = L_BRACK; + } + + +static void act18() +{ + NLA = R_BRACK; + } + + +static void act19() +{ + NLA = ZERO_MORE; + } + + +static void act20() +{ + NLA = ONE_MORE; + } + + +static void act21() +{ + NLA = OR; + } + + +static void act22() +{ + NLA = RANGE; + } + + +static void act23() +{ + NLA = NOT; + } + + +static void act24() +{ + NLA = OCTAL_VALUE; + {int t; sscanf(&zzlextext[1],"%o",&t); zzlextext[0] = t;} + } + + +static void act25() +{ + NLA = HEX_VALUE; + {int t; sscanf(&zzlextext[3],"%x",&t); zzlextext[0] = t;} + } + + +static void act26() +{ + NLA = DEC_VALUE; + {int t; sscanf(&zzlextext[1],"%d",&t); zzlextext[0] = t;} + } + + +static void act27() +{ + NLA = TAB; + zzlextext[0] = '\t'; + } + + +static void act28() +{ + NLA = NL; + zzlextext[0] = '\n'; + } + + +static void act29() +{ + NLA = CR; + zzlextext[0] = '\r'; + } + + +static void act30() +{ + NLA = BS; + zzlextext[0] = '\b'; + } + + +static void act31() +{ + NLA = CONTINUATION; + zzline++; zzskip(); + } + + +static void act32() +{ + NLA = LIT; + zzlextext[0] = zzlextext[1]; + } + + +static void act33() +{ + NLA = REGCHAR; + } + +static unsigned char shift0[257] = { + 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 1, 2, 40, 40, 1, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 1, 40, 40, 40, 40, 4, 40, + 40, 30, 31, 34, 35, 40, 37, 40, 40, 23, + 24, 24, 24, 24, 24, 24, 24, 25, 25, 40, + 40, 26, 40, 27, 40, 3, 21, 21, 21, 21, + 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 20, + 22, 22, 32, 39, 33, 40, 22, 40, 11, 9, + 12, 21, 6, 19, 22, 22, 14, 22, 22, 5, + 8, 16, 15, 17, 22, 10, 18, 13, 22, 22, + 22, 7, 22, 22, 28, 36, 29, 38, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40 +}; + + +static void act34() +{ + NLA = 1; + error("unterminated action", zzline); zzmode(START); + } + + +static void act35() +{ + NLA = ACTION; + if (func_action) fprintf(OUT,"}\n\n"); + zzmode(START); + /* MR1 */ + /* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ + /* MR1 via <<%%lexmember ...>> */ + /* MR1 This is a consequence of not saving actions */ + /* MR1 */ + /* MR1 */ parserClass=0; + /* MR1 */ lexPrefix=0; + /* MR1 */ lexAction=0; + /* MR1 */ lexMember=0; + } + + +static void act36() +{ + NLA = 34; + xxputc(zzlextext[0]); zzskip(); + } + + +static void act37() +{ + NLA = 35; + xxputc('>'); zzskip(); + } + + +static void act38() +{ + NLA = 36; + xxputc('\\'); zzskip(); + } + + +static void act39() +{ + NLA = 37; + xxputc(zzlextext[0]); ++zzline; zzskip(); + } + + +static void act40() +{ + NLA = 38; + zzmode(ACTION_COMMENTS); /* MR1 */ + xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ + } + + +static void act41() +{ + NLA = 39; + zzmode(ACTION_CPP_COMMENTS); /* MR1 */ + xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ + } + + +static void act42() +{ + NLA = 40; + xxputc(zzlextext[0]); zzskip(); + } + +static unsigned char shift1[257] = { + 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 3, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 5, 6, 6, 6, 6, 4, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 1, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 2, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6 +}; + + +static void act43() +{ + NLA = 1; + } + + +static void act44() +{ + NLA = 41; + zzmode(ACT); /* MR1 */ + xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ + } + + +static void act45() +{ + NLA = 42; + zzline++; xxputc(zzlextext[0]); zzskip(); + } + + +static void act46() +{ + NLA = 43; + xxputc(zzlextext[0]); zzskip(); + } + +static unsigned char shift2[257] = { + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 3, 4, 4, 3, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 1, 4, 4, 4, 4, 2, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4 +}; + + +static void act47() +{ + NLA = 1; + } + + +static void act48() +{ + NLA = 44; + zzmode(ACT); zzline++; /* MR1 */ + xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ + } + + +static void act49() +{ + NLA = 45; + xxputc(zzlextext[0]); zzskip(); + } + +static unsigned char shift3[257] = { + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2 +}; + +#define DfaStates 94 +typedef unsigned char DfaState; + +static DfaState st0[42] = { + 1, 2, 3, 4, 5, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 6, 94 +}; + +static DfaState st1[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st2[42] = { + 94, 21, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st3[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st4[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st5[42] = { + 94, 94, 94, 94, 22, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st6[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st7[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 23, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st8[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 24, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st9[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st10[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st11[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st12[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st13[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st14[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st15[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st16[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st17[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st18[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st19[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st20[42] = { + 94, 25, 26, 25, 25, 25, 25, 25, 25, 27, + 28, 25, 25, 29, 25, 25, 30, 25, 25, 25, + 25, 25, 25, 31, 32, 32, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 94 +}; + +static DfaState st21[42] = { + 94, 21, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st22[42] = { + 94, 94, 94, 94, 94, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st23[42] = { + 94, 94, 94, 94, 34, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st24[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st25[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st26[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st27[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st28[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st29[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st30[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st31[42] = { + 94, 94, 94, 94, 94, 94, 94, 35, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 35, 94, 94, 36, 36, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st32[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 37, 37, 37, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st33[42] = { + 94, 94, 94, 94, 94, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st34[42] = { + 94, 94, 94, 94, 39, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st35[42] = { + 94, 94, 94, 94, 94, 94, 40, 94, 94, 40, + 94, 40, 40, 94, 94, 94, 94, 94, 94, 40, + 94, 40, 94, 40, 40, 40, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st36[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 36, 36, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st37[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 37, 37, 37, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st38[42] = { + 94, 94, 94, 94, 94, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st39[42] = { + 94, 94, 94, 94, 94, 41, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 42, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st40[42] = { + 94, 94, 94, 94, 94, 94, 40, 94, 94, 40, + 94, 40, 40, 94, 94, 94, 94, 94, 94, 40, + 94, 40, 94, 40, 40, 40, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st41[42] = { + 94, 94, 94, 94, 94, 94, 43, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st42[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 44, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st43[42] = { + 94, 94, 94, 94, 94, 94, 94, 45, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st44[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 46, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st45[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 47, 94, + 94, 48, 94, 94, 94, 94, 94, 49, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st46[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 50, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st47[42] = { + 94, 94, 94, 94, 94, 94, 51, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st48[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 52, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st49[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 53, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st50[42] = { + 94, 94, 94, 94, 94, 94, 54, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st51[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 55, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st52[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 56, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st53[42] = { + 94, 94, 94, 94, 94, 94, 57, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st54[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 58, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st55[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 59, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st56[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 60, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st57[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 61, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st58[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 62, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st59[42] = { + 94, 94, 94, 94, 94, 94, 63, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st60[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 64, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st61[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 65, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st62[42] = { + 94, 94, 94, 94, 94, 66, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st63[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 67, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st64[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 68, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st65[42] = { + 94, 94, 94, 94, 94, 94, 94, 69, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st66[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 70, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st67[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st68[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st69[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st70[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 71, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st71[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 72, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st72[42] = { + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94 +}; + +static DfaState st73[8] = { + 74, 75, 76, 77, 78, 79, 79, 94 +}; + +static DfaState st74[8] = { + 94, 94, 94, 94, 94, 94, 94, 94 +}; + +static DfaState st75[8] = { + 94, 80, 94, 94, 94, 94, 94, 94 +}; + +static DfaState st76[8] = { + 94, 81, 94, 94, 94, 94, 94, 94 +}; + +static DfaState st77[8] = { + 94, 94, 94, 94, 94, 94, 94, 94 +}; + +static DfaState st78[8] = { + 94, 94, 94, 94, 82, 83, 94, 94 +}; + +static DfaState st79[8] = { + 94, 94, 94, 94, 94, 94, 94, 94 +}; + +static DfaState st80[8] = { + 94, 94, 94, 94, 94, 94, 94, 94 +}; + +static DfaState st81[8] = { + 94, 94, 94, 94, 94, 94, 94, 94 +}; + +static DfaState st82[8] = { + 94, 94, 94, 94, 94, 94, 94, 94 +}; + +static DfaState st83[8] = { + 94, 94, 94, 94, 94, 94, 94, 94 +}; + +static DfaState st84[6] = { + 85, 86, 87, 88, 87, 94 +}; + +static DfaState st85[6] = { + 94, 94, 94, 94, 94, 94 +}; + +static DfaState st86[6] = { + 94, 94, 89, 94, 94, 94 +}; + +static DfaState st87[6] = { + 94, 94, 94, 94, 94, 94 +}; + +static DfaState st88[6] = { + 94, 94, 94, 94, 94, 94 +}; + +static DfaState st89[6] = { + 94, 94, 94, 94, 94, 94 +}; + +static DfaState st90[4] = { + 91, 92, 93, 94 +}; + +static DfaState st91[4] = { + 94, 94, 94, 94 +}; + +static DfaState st92[4] = { + 94, 94, 94, 94 +}; + +static DfaState st93[4] = { + 94, 94, 94, 94 +}; + + +DfaState *dfa[94] = { + st0, + st1, + st2, + st3, + st4, + st5, + st6, + st7, + st8, + st9, + st10, + st11, + st12, + st13, + st14, + st15, + st16, + st17, + st18, + st19, + st20, + st21, + st22, + st23, + st24, + st25, + st26, + st27, + st28, + st29, + st30, + st31, + st32, + st33, + st34, + st35, + st36, + st37, + st38, + st39, + st40, + st41, + st42, + st43, + st44, + st45, + st46, + st47, + st48, + st49, + st50, + st51, + st52, + st53, + st54, + st55, + st56, + st57, + st58, + st59, + st60, + st61, + st62, + st63, + st64, + st65, + st66, + st67, + st68, + st69, + st70, + st71, + st72, + st73, + st74, + st75, + st76, + st77, + st78, + st79, + st80, + st81, + st82, + st83, + st84, + st85, + st86, + st87, + st88, + st89, + st90, + st91, + st92, + st93 +}; + + +DfaState accepts[95] = { + 0, 1, 2, 3, 4, 33, 33, 33, 33, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 0, 2, 5, 11, 12, 32, 31, 30, 29, 27, + 28, 24, 26, 6, 0, 0, 24, 26, 6, 0, + 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7, 8, 10, + 0, 0, 9, 0, 34, 36, 38, 39, 42, 42, + 35, 37, 41, 40, 0, 43, 46, 46, 45, 44, + 0, 47, 48, 49, 0 +}; + +void (*actions[50])() = { + zzerraction, + act1, + act2, + act3, + act4, + act5, + act6, + act7, + act8, + act9, + act10, + act11, + act12, + act13, + act14, + act15, + act16, + act17, + act18, + act19, + act20, + act21, + act22, + act23, + act24, + act25, + act26, + act27, + act28, + act29, + act30, + act31, + act32, + act33, + act34, + act35, + act36, + act37, + act38, + act39, + act40, + act41, + act42, + act43, + act44, + act45, + act46, + act47, + act48, + act49 +}; + +static DfaState dfa_base[] = { + 0, + 73, + 84, + 90 +}; + +static unsigned char *b_class_no[] = { + shift0, + shift1, + shift2, + shift3 +}; + + + +#define ZZSHIFT(c) (b_class_no[zzauto][1+c]) +#define MAX_MODE 4 +#include "dlgauto.h" diff --git a/Tools/CodeTools/Source/Pccts/dlg/dlg_p.c b/Tools/CodeTools/Source/Pccts/dlg/dlg_p.c new file mode 100644 index 0000000000..e726ae3983 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/dlg/dlg_p.c @@ -0,0 +1,959 @@ +/* + * A n t l r T r a n s l a t i o n H e a d e r + * + * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001 + * Purdue University Electrical Engineering + * With AHPCRC, University of Minnesota + * ANTLR Version 1.33MR33 + * + * ..\bin\antlr dlg_p.g -gh + * + */ + +#define ANTLR_VERSION 13333 +#include "pcctscfg.h" +#include "pccts_stdio.h" + +#include +#include "dlg.h" +#define zzSET_SIZE 8 +#include "antlr.h" +#include "tokens.h" +#include "dlgdef.h" +#include "mode.h" + +/* MR23 In order to remove calls to PURIFY use the antlr -nopurify option */ + +#ifndef PCCTS_PURIFY +#define PCCTS_PURIFY(r,s) memset((char *) &(r),'\0',(s)); +#endif + +ANTLR_INFO + + +/* MR20 G. Hobbelt +Fix for Borland C++ 4.x & 5.x compiling with ALL warnings enabled +*/ + +#ifdef __TURBOC__ +#pragma warn -aus /* unused assignment of 'xxx' */ +#endif + +int action_no = 0; /* keep track of actions outputed */ +int nfa_allocated = 0; /* keeps track of number of nfa nodes */ +nfa_node **nfa_array = NULL;/* root of binary tree that stores nfa array */ +nfa_node nfa_model_node; /* model to initialize new nodes */ +set used_chars; /* used to label trans. arcs */ +set used_classes; /* classes or chars used to label trans. arcs */ +set normal_chars; /* mask to get rid elements that aren't used +in set */ +int flag_paren = FALSE; +int flag_brace = FALSE; +int mode_counter = 0; /* keep track of number of %%names */ + + + +void +#ifdef __USE_PROTOS +grammar(void) +#else +grammar() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + p_head(); p_class_hdr(); func_action = FALSE; + { + zzBLOCK(zztasp2); + zzMake0; + { + while ( (setwd1[LA(1)]&0x1) ) { + { + zzBLOCK(zztasp3); + zzMake0; + { + if ( (LA(1)==LEXACTION) ) { + zzmatch(LEXACTION); zzCONSUME; + } + else { + if ( (LA(1)==LEXMEMBER) ) { + zzmatch(LEXMEMBER); zzCONSUME; + } + else { + if ( (LA(1)==LEXPREFIX) ) { + zzmatch(LEXPREFIX); zzCONSUME; + } + else { + if ( (LA(1)==PARSERCLASS) ) { + zzmatch(PARSERCLASS); zzCONSUME; + } + else { + if ( (LA(1)==ACTION) ) { + } + else {zzFAIL(1,zzerr1,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + } + } + } + zzEXIT(zztasp3); + } + } + zzmatch(ACTION); zzCONSUME; + zzLOOP(zztasp2); + } + zzEXIT(zztasp2); + } + } + if ( gen_cpp ) p_includes(); + start_states(); + func_action = FALSE; p_tables(); p_tail(); + { + zzBLOCK(zztasp2); + zzMake0; + { + while ( (LA(1)==ACTION) ) { + zzmatch(ACTION); zzCONSUME; + zzLOOP(zztasp2); + } + zzEXIT(zztasp2); + } + } + zzmatch(1); + if (firstLexMember != 0) p_class_def1(); + zzCONSUME; + + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd1, 0x2); + } +} + +void +#ifdef __USE_PROTOS +start_states(void) +#else +start_states() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==PER_PER) ) { + zzmatch(PER_PER); zzCONSUME; + do_conversion(); + } + else { + if ( (LA(1)==NAME_PER_PER) ) { + zzmatch(NAME_PER_PER); zzCONSUME; + do_conversion(); + { + zzBLOCK(zztasp3); + zzMake0; + { + while ( (LA(1)==NAME_PER_PER) ) { + zzmatch(NAME_PER_PER); zzCONSUME; + do_conversion(); + zzLOOP(zztasp3); + } + zzEXIT(zztasp3); + } + } + } + else {zzFAIL(1,zzerr2,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + zzmatch(PER_PER); zzCONSUME; + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd1, 0x4); + } +} + +void +#ifdef __USE_PROTOS +do_conversion(void) +#else +do_conversion() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + new_automaton_mode(); func_action = TRUE; + rule_list(); + + dfa_class_nop[mode_counter] = + relabel(zzaArg(zztasp1,1 ).l,comp_level); + if (comp_level) + p_shift_table(mode_counter); + dfa_basep[mode_counter] = dfa_allocated+1; + make_dfa_model_node(dfa_class_nop[mode_counter]); + nfa_to_dfa(zzaArg(zztasp1,1 ).l); + ++mode_counter; + func_action = FALSE; +#ifdef HASH_STAT + fprint_hash_stats(stderr); +#endif + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd1, 0x8); + } +} + +void +#ifdef __USE_PROTOS +rule_list(void) +#else +rule_list() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + if ( (setwd1[LA(1)]&0x10) ) { + rule(); + zzaRet.l=zzaArg(zztasp1,1 ).l; zzaRet.r=zzaArg(zztasp1,1 ).r; + { + zzBLOCK(zztasp2); + zzMake0; + { + while ( (setwd1[LA(1)]&0x20) ) { + rule(); + {nfa_node *t1; + t1 = new_nfa_node(); + (t1)->trans[0]=zzaRet.l; + (t1)->trans[1]=zzaArg(zztasp2,1 ).l; + /* all accept nodes "dead ends" */ + zzaRet.l=t1; zzaRet.r=NULL; + } + zzLOOP(zztasp2); + } + zzEXIT(zztasp2); + } + } + } + else { + if ( (setwd1[LA(1)]&0x40) ) { + zzaRet.l = new_nfa_node(); zzaRet.r = NULL; + warning("no regular expressions", zzline); + } + else {zzFAIL(1,zzerr3,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd1, 0x80); + } +} + +void +#ifdef __USE_PROTOS +rule(void) +#else +rule() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + if ( (setwd2[LA(1)]&0x1) ) { + reg_expr(); + zzmatch(ACTION); + if (zzaArg(zztasp1,1 ).r != NULL) { + zzaRet.l=zzaArg(zztasp1,1 ).l; zzaRet.r=zzaArg(zztasp1,1 ).r; (zzaArg(zztasp1,1 ).r)->accept=action_no; + } + zzCONSUME; + + } + else { + if ( (LA(1)==ACTION) ) { + zzmatch(ACTION); + zzaRet.l = NULL; zzaRet.r = NULL; + error("no expression for action ", zzline); + zzCONSUME; + + } + else {zzFAIL(1,zzerr4,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd2, 0x2); + } +} + +void +#ifdef __USE_PROTOS +reg_expr(void) +#else +reg_expr() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + and_expr(); + zzaRet.l=zzaArg(zztasp1,1 ).l; zzaRet.r=zzaArg(zztasp1,1 ).r; + { + zzBLOCK(zztasp2); + zzMake0; + { + while ( (LA(1)==OR) ) { + zzmatch(OR); zzCONSUME; + and_expr(); + {nfa_node *t1, *t2; + t1 = new_nfa_node(); t2 = new_nfa_node(); + (t1)->trans[0]=zzaRet.l; + (t1)->trans[1]=zzaArg(zztasp2,2 ).l; + /* MR23 */ if (zzaRet.r != NULL) (zzaRet.r)->trans[1]=t2; + if (zzaArg(zztasp2,2 ).r) { + (zzaArg(zztasp2,2 ).r)->trans[1]=t2; /* MR20 */ + } + zzaRet.l=t1; zzaRet.r=t2; + } + zzLOOP(zztasp2); + } + zzEXIT(zztasp2); + } + } + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd2, 0x4); + } +} + +void +#ifdef __USE_PROTOS +and_expr(void) +#else +and_expr() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + repeat_expr(); + + zzaRet.l=zzaArg(zztasp1,1 ).l; zzaRet.r=zzaArg(zztasp1,1 ).r; + { + zzBLOCK(zztasp2); + zzMake0; + { + while ( (setwd2[LA(1)]&0x8) ) { + repeat_expr(); + if (zzaRet.r != NULL) { + (zzaRet.r)->trans[1]=zzaArg(zztasp2,1 ).l; + zzaRet.r=zzaArg(zztasp2,1 ).r; + } + zzLOOP(zztasp2); + } + zzEXIT(zztasp2); + } + } + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd2, 0x10); + } +} + +void +#ifdef __USE_PROTOS +repeat_expr(void) +#else +repeat_expr() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + if ( (setwd2[LA(1)]&0x20) ) { + expr(); + zzaRet.l=zzaArg(zztasp1,1 ).l; zzaRet.r=zzaArg(zztasp1,1 ).r; + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==ZERO_MORE) ) { + zzmatch(ZERO_MORE); + { nfa_node *t1,*t2; + /* MR23 */ if (zzaRet.r != NULL) (zzaRet.r)->trans[0] = zzaRet.l; + t1 = new_nfa_node(); t2 = new_nfa_node(); + t1->trans[0]=zzaRet.l; + t1->trans[1]=t2; + /* MR23 */ if (zzaRet.r != NULL) (zzaRet.r)->trans[1]=t2; + zzaRet.l=t1;zzaRet.r=t2; + } + zzCONSUME; + + } + else { + if ( (LA(1)==ONE_MORE) ) { + zzmatch(ONE_MORE); + if (zzaRet.r != NULL) (zzaRet.r)->trans[0] = zzaRet.l; + zzCONSUME; + + } + else { + if ( (setwd2[LA(1)]&0x40) ) { + } + else {zzFAIL(1,zzerr5,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + } + zzEXIT(zztasp2); + } + } + } + else { + if ( (LA(1)==ZERO_MORE) ) { + zzmatch(ZERO_MORE); + error("no expression for *", zzline); + zzCONSUME; + + } + else { + if ( (LA(1)==ONE_MORE) ) { + zzmatch(ONE_MORE); + error("no expression for +", zzline); + zzCONSUME; + + } + else {zzFAIL(1,zzerr6,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + } + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd2, 0x80); + } +} + +void +#ifdef __USE_PROTOS +expr(void) +#else +expr() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + zzaRet.l = new_nfa_node(); + zzaRet.r = new_nfa_node(); + if ( (LA(1)==L_BRACK) ) { + zzmatch(L_BRACK); zzCONSUME; + atom_list(); + zzmatch(R_BRACK); + + /* MR23 */ if (zzaRet.l != NULL) { + (zzaRet.l)->trans[0] = zzaRet.r; + (zzaRet.l)->label = set_dup(zzaArg(zztasp1,2 ).label); + set_orin(&used_chars,(zzaRet.l)->label); + } + zzCONSUME; + + } + else { + if ( (LA(1)==NOT) ) { + zzmatch(NOT); zzCONSUME; + zzmatch(L_BRACK); zzCONSUME; + atom_list(); + zzmatch(R_BRACK); + + /* MR23 */ if (zzaRet.l != NULL) { + (zzaRet.l)->trans[0] = zzaRet.r; + (zzaRet.l)->label = set_dif(normal_chars,zzaArg(zztasp1,3 ).label); + set_orin(&used_chars,(zzaRet.l)->label); + } + zzCONSUME; + + } + else { + if ( (LA(1)==L_PAR) ) { + zzmatch(L_PAR); zzCONSUME; + reg_expr(); + zzmatch(R_PAR); + + /* MR23 */ if (zzaRet.l != NULL) { + (zzaRet.l)->trans[0] = zzaArg(zztasp1,2 ).l; + if (zzaArg(zztasp1,2 ).r) { + (zzaArg(zztasp1,2 ).r)->trans[1] = zzaRet.r; /* MR20 */ + } + } + zzCONSUME; + + } + else { + if ( (LA(1)==L_BRACE) ) { + zzmatch(L_BRACE); zzCONSUME; + reg_expr(); + zzmatch(R_BRACE); + + /* MR23 */ if (zzaRet.l != NULL) { + (zzaRet.l)->trans[0] = zzaArg(zztasp1,2 ).l; + (zzaRet.l)->trans[1] = zzaRet.r; + if (zzaArg(zztasp1,2 ).r) { + (zzaArg(zztasp1,2 ).r)->trans[1] = zzaRet.r; /* MR20 */ + } + } + zzCONSUME; + + } + else { + if ( (setwd3[LA(1)]&0x1) ) { + atom(); + + /* MR23 */ if (zzaRet.l != NULL) { + (zzaRet.l)->trans[0] = zzaRet.r; + (zzaRet.l)->label = set_dup(zzaArg(zztasp1,1 ).label); + set_orin(&used_chars,(zzaRet.l)->label); + } + } + else {zzFAIL(1,zzerr7,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + } + } + } + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd3, 0x2); + } +} + +void +#ifdef __USE_PROTOS +atom_list(void) +#else +atom_list() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + set_free(zzaRet.label); + { + zzBLOCK(zztasp2); + zzMake0; + { + while ( (setwd3[LA(1)]&0x4) ) { + near_atom(); + set_orin(&(zzaRet.label),zzaArg(zztasp2,1 ).label); + zzLOOP(zztasp2); + } + zzEXIT(zztasp2); + } + } + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd3, 0x8); + } +} + +void +#ifdef __USE_PROTOS +near_atom(void) +#else +near_atom() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + register int i; + register int i_prime; + anychar(); + zzaRet.letter=zzaArg(zztasp1,1 ).letter; zzaRet.label=set_of(zzaArg(zztasp1,1 ).letter); + i_prime = zzaArg(zztasp1,1 ).letter + MIN_CHAR; + if (case_insensitive && islower(i_prime)) + set_orel(toupper(i_prime)-MIN_CHAR, + &(zzaRet.label)); + if (case_insensitive && isupper(i_prime)) + set_orel(tolower(i_prime)-MIN_CHAR, + &(zzaRet.label)); + { + zzBLOCK(zztasp2); + zzMake0; + { + if ( (LA(1)==RANGE) ) { + zzmatch(RANGE); zzCONSUME; + anychar(); + if (case_insensitive){ + i_prime = zzaRet.letter+MIN_CHAR; + zzaRet.letter = (islower(i_prime) ? + toupper(i_prime) : i_prime)-MIN_CHAR; + i_prime = zzaArg(zztasp2,2 ).letter+MIN_CHAR; + zzaArg(zztasp2,2 ).letter = (islower(i_prime) ? + toupper(i_prime) : i_prime)-MIN_CHAR; + } + /* check to see if range okay */ + { + int debugLetter1 = zzaRet.letter; + int debugLetter2 = zzaArg(zztasp2,2 ).letter; + } + if (zzaRet.letter > zzaArg(zztasp2,2 ).letter + && zzaArg(zztasp2,2 ).letter != 0xff){ /* MR16 */ + error("invalid range ", zzline); + } + for (i=zzaRet.letter; i<= (int)zzaArg(zztasp2,2 ).letter; ++i){ + set_orel(i,&(zzaRet.label)); + i_prime = i+MIN_CHAR; + if (case_insensitive && islower(i_prime)) + set_orel(toupper(i_prime)-MIN_CHAR, + &(zzaRet.label)); + if (case_insensitive && isupper(i_prime)) + set_orel(tolower(i_prime)-MIN_CHAR, + &(zzaRet.label)); + } + } + else { + if ( (setwd3[LA(1)]&0x10) ) { + } + else {zzFAIL(1,zzerr8,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + zzEXIT(zztasp2); + } + } + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd3, 0x20); + } +} + +void +#ifdef __USE_PROTOS +atom(void) +#else +atom() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + register int i_prime; + anychar(); + zzaRet.label = set_of(zzaArg(zztasp1,1 ).letter); + i_prime = zzaArg(zztasp1,1 ).letter + MIN_CHAR; + if (case_insensitive && islower(i_prime)) + set_orel(toupper(i_prime)-MIN_CHAR, + &(zzaRet.label)); + if (case_insensitive && isupper(i_prime)) + set_orel(tolower(i_prime)-MIN_CHAR, + &(zzaRet.label)); + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd3, 0x40); + } +} + +void +#ifdef __USE_PROTOS +anychar(void) +#else +anychar() +#endif +{ + zzRULE; + zzBLOCK(zztasp1); + zzMake0; + { + if ( (LA(1)==REGCHAR) ) { + zzmatch(REGCHAR); + zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR; + zzCONSUME; + + } + else { + if ( (LA(1)==OCTAL_VALUE) ) { + zzmatch(OCTAL_VALUE); + zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR; + zzCONSUME; + + } + else { + if ( (LA(1)==HEX_VALUE) ) { + zzmatch(HEX_VALUE); + zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR; + zzCONSUME; + + } + else { + if ( (LA(1)==DEC_VALUE) ) { + zzmatch(DEC_VALUE); + zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR; + zzCONSUME; + + } + else { + if ( (LA(1)==TAB) ) { + zzmatch(TAB); + zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR; + zzCONSUME; + + } + else { + if ( (LA(1)==NL) ) { + zzmatch(NL); + zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR; + zzCONSUME; + + } + else { + if ( (LA(1)==CR) ) { + zzmatch(CR); + zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR; + zzCONSUME; + + } + else { + if ( (LA(1)==BS) ) { + zzmatch(BS); + zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR; + zzCONSUME; + + } + else { + if ( (LA(1)==LIT) ) { + zzmatch(LIT); + zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR; + zzCONSUME; + + } + else { + if ( (LA(1)==L_EOF) ) { + zzmatch(L_EOF); + zzaRet.letter = 0; + zzCONSUME; + + } + else {zzFAIL(1,zzerr9,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} + } + } + } + } + } + } + } + } + } + zzEXIT(zztasp1); + return; +fail: + zzEXIT(zztasp1); + /* empty action */ + zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); + zzresynch(setwd3, 0x80); + } +} + +/* adds a new nfa to the binary tree and returns a pointer to it */ +nfa_node * +#ifdef __USE_PROTOS +new_nfa_node(void) +#else +new_nfa_node() +#endif +{ + register nfa_node *t; + static int nfa_size=0; /* elements nfa_array[] can hold */ + + ++nfa_allocated; + if (nfa_size<=nfa_allocated){ + /* need to redo array */ + if (!nfa_array){ + /* need some to do inital allocation */ + nfa_size=nfa_allocated+NFA_MIN; + nfa_array=(nfa_node **) malloc(sizeof(nfa_node*)* + nfa_size); + }else{ + /* need more space */ + nfa_size=2*(nfa_allocated+1); + nfa_array=(nfa_node **) realloc(nfa_array, + sizeof(nfa_node*)*nfa_size); + } + } + /* fill out entry in array */ + t = (nfa_node*) malloc(sizeof(nfa_node)); + nfa_array[nfa_allocated] = t; + *t = nfa_model_node; + t->node_no = nfa_allocated; + return t; +} + + +/* initialize the model node used to fill in newly made nfa_nodes */ +void +#ifdef __USE_PROTOS +make_nfa_model_node(void) +#else +make_nfa_model_node() +#endif +{ + nfa_model_node.node_no = -1; /* impossible value for real nfa node */ + nfa_model_node.nfa_set = 0; + nfa_model_node.accept = 0; /* error state default*/ + nfa_model_node.trans[0] = NULL; + nfa_model_node.trans[1] = NULL; + nfa_model_node.label = empty; +} + +#if defined(DEBUG) || defined(_DEBUG) + +/* print out the pointer value and the node_number */ +void +#ifdef __USE_PROTOS +fprint_dfa_pair(FILE *f, nfa_node *p) +#else +fprint_dfa_pair(f, p) +FILE *f; +nfa_node *p; +#endif +{ + if (p){ + fprintf(f, "%x (%d)", p, p->node_no); + }else{ + fprintf(f, "(nil)"); + } +} + +/* print out interest information on a set */ +void +#ifdef __USE_PROTOS +fprint_set(FILE *f, set s) +#else +fprint_set(f,s) +FILE *f; +set s; +#endif +{ + unsigned int *x; + + fprintf(f, "n = %d,", s.n); + if (s.setword){ + fprintf(f, "setword = %x, ", s.setword); + /* print out all the elements in the set */ + x = set_pdq(s); + while (*x!=nil){ + fprintf(f, "%d ", *x); + ++x; + } + }else{ + fprintf(f, "setword = (nil)"); + } +} + +/* code to be able to dump out the nfas +return 0 if okay dump +return 1 if screwed up +*/ +int +#ifdef __USE_PROTOS +dump_nfas(int first_node, int last_node) +#else +dump_nfas(first_node, last_node) +int first_node; +int last_node; +#endif +{ + register int i; + nfa_node *t; + + for (i=first_node; i<=last_node; ++i){ + t = NFA(i); + if (!t) break; + fprintf(stderr, "nfa_node %d {\n", t->node_no); + fprintf(stderr, "\n\tnfa_set = %d\n", t->nfa_set); + fprintf(stderr, "\taccept\t=\t%d\n", t->accept); + fprintf(stderr, "\ttrans\t=\t("); + fprint_dfa_pair(stderr, t->trans[0]); + fprintf(stderr, ","); + fprint_dfa_pair(stderr, t->trans[1]); + fprintf(stderr, ")\n"); + fprintf(stderr, "\tlabel\t=\t{ "); + fprint_set(stderr, t->label); + fprintf(stderr, "\t}\n"); + fprintf(stderr, "}\n\n"); + } + return 0; +} +#endif + +/* DLG-specific syntax error message generator +* (define USER_ZZSYN when compiling so don't get 2 definitions) +*/ +void +#ifdef __USE_PROTOS +zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, int k, char *bad_text) +#else +zzsyn(text, tok, egroup, eset, etok, k, bad_text) +char *text, *egroup, *bad_text; +int tok; +int etok; +int k; +SetWordType *eset; +#endif +{ +fprintf(stderr, ErrHdr, file_str[0]!=NULL?file_str[0]:"stdin", zzline); +fprintf(stderr, " syntax error at \"%s\"", (tok==zzEOF_TOKEN)?"EOF":text); +if ( !etok && !eset ) {fprintf(stderr, "\n"); return;} +if ( k==1 ) fprintf(stderr, " missing"); +else +{ +fprintf(stderr, "; \"%s\" not", bad_text); +if ( zzset_deg(eset)>1 ) fprintf(stderr, " in"); +} +if ( zzset_deg(eset)>0 ) zzedecode(eset); +else fprintf(stderr, " %s", zztokens[etok]); +if ( strlen(egroup) > (size_t)0 ) fprintf(stderr, " in %s", egroup); +fprintf(stderr, "\n"); +} diff --git a/Tools/CodeTools/Source/Pccts/dlg/dlg_p.g b/Tools/CodeTools/Source/Pccts/dlg/dlg_p.g new file mode 100644 index 0000000000..58ca110693 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/dlg/dlg_p.g @@ -0,0 +1,614 @@ +/* This is the parser for the dlg + * This is a part of the Purdue Compiler Construction Tool Set + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * DLG 1.33 + * Will Cohen + * With mods by Terence Parr; AHPCRC, University of Minnesota + * 1989-1995 + */ + +#header << +#include +#include "dlg.h" +>> + +<< + +/* MR20 G. Hobbelt + Fix for Borland C++ 4.x & 5.x compiling with ALL warnings enabled +*/ + +#ifdef __TURBOC__ +#pragma warn -aus /* unused assignment of 'xxx' */ +#endif + +int action_no = 0; /* keep track of actions outputed */ +int nfa_allocated = 0; /* keeps track of number of nfa nodes */ +nfa_node **nfa_array = NULL;/* root of binary tree that stores nfa array */ +nfa_node nfa_model_node; /* model to initialize new nodes */ +set used_chars; /* used to label trans. arcs */ +set used_classes; /* classes or chars used to label trans. arcs */ +set normal_chars; /* mask to get rid elements that aren't used + in set */ +int flag_paren = FALSE; +int flag_brace = FALSE; +int mode_counter = 0; /* keep track of number of %%names */ + +>> + +#lexaction << +int func_action; /* should actions be turned into functions?*/ +int lex_mode_counter = 0; /* keeps track of the number of %%names */ +/* MR1 */ +/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ +/* MR1 via <<%%lexmember...>> */ +/* MR1 */ +int lexMember = 0; /* <<%%lexmemeber ...>> MR1 */ +int lexAction = 0; /* <<%%lexaction ...>> MR1 */ +int parserClass = 0; /* <<%%parserclass ...>> MR1 */ +int lexPrefix = 0; /* <<%%lexprefix ...>> MR1 */ +char theClassName[100]; /* MR11 */ +char *pClassName=theClassName; /* MR11 */ +int firstLexMember=1; /* MR1 */ + +#ifdef __USE_PROTOS +void xxputc(int c) { /* MR1 */ +#else +void xxputc(c) /* MR1 */ + int c; /* MR1 */ +{ /* MR1 */ +#endif + if (parserClass) { /* MR1 */ + *pClassName++=c; /* MR1 */ + *pClassName=0; /* MR1 */ + } else if (lexMember || lexPrefix) { /* MR1 */ + if (class_stream != NULL) fputc(c,class_stream); /* MR1 */ + } else { /* MR1 */ + fputc(c,OUT); /* MR1 */ + }; /* MR1 */ +} /* MR1 */ + +#ifdef __USE_PROTOS +void xxprintf(char *format,char *string) { /* MR1 */ +#else +void xxprintf(format,string) /* MR1 */ + char *format; /* MR1 */ + char *string; /* MR1 */ +{ /* MR1 */ +#endif + if (lexMember || lexPrefix || parserClass) { /* MR1 */ + if (class_stream != NULL) /* MR1 */ + fprintf(class_stream,format,string); /* MR1 */ + } else { /* MR1 */ + fprintf(OUT,format,string); /* MR1 */ + }; /* MR1 */ +} /* MR1 */ +>> + +#token "[\r\t\ ]+" << zzskip(); >> /* Ignore white */ +#token "\n" << zzline++; zzskip(); DAWDLE; >> /* Track Line # */ +#token L_EOF "\@" +#token PER_PER "\%\%" +#token NAME_PER_PER "\%\%[a-zA-Z_][a-zA-Z0-9_]*" + << p_mode_def(&zzlextext[2],lex_mode_counter++); >> + +#token LEXMEMBER "\<\<\%\%lexmember" /* MR1 */ + <> /* MR1 */ +#token LEXACTION "\<\<\%\%lexaction" /* MR1 */ + <> /* MR1 */ +#token PARSERCLASS "\<\<\%\%parserclass" /* MR1 */ + <> /* MR1 */ +#token LEXPREFIX "\<\<\%\%lexprefix" /* MR1 */ + <> /* MR1 */ + +#token ACTION "\<\<" + << if (func_action) + fprintf(OUT,"\n%s %sact%d()\n{ ", + gen_cpp?"ANTLRTokenType":"static void", + gen_cpp?ClassName("::"):"", ++action_no); + zzmode(ACT); zzskip(); + >> +#token GREAT_GREAT "\>\>" +#token L_BRACE "\{" +#token R_BRACE "\}" +#token L_PAR "\(" +#token R_PAR "\)" +#token L_BRACK "\[" +#token R_BRACK "\]" +#token ZERO_MORE "\*" +#token ONE_MORE "\+" +#token OR "\|" +#token RANGE "\-" +#token NOT "\~" +#token OCTAL_VALUE "\\0[0-7]*" + << {int t; sscanf(&zzlextext[1],"%o",&t); zzlextext[0] = t;}>> +#token HEX_VALUE "\\0[Xx][0-9a-fA-F]+" + << {int t; sscanf(&zzlextext[3],"%x",&t); zzlextext[0] = t;}>> +#token DEC_VALUE "\\[1-9][0-9]*" + << {int t; sscanf(&zzlextext[1],"%d",&t); zzlextext[0] = t;}>> +#token TAB "\\t" << zzlextext[0] = '\t';>> +#token NL "\\n" << zzlextext[0] = '\n';>> +#token CR "\\r" << zzlextext[0] = '\r';>> +#token BS "\\b" << zzlextext[0] = '\b';>> + +/* MR1 */ +/* MR1 10-Apr-97 MR1 Allow #token regular expressions to cross lines */ +/* MR1 */ +#token CONTINUATION "\\ \n" << zzline++; zzskip();>> /* MR1 */ + +/* NOTE: this takes ANYTHING after the \ */ +#token LIT "\\~[tnrb]" << zzlextext[0] = zzlextext[1];>> + +/* NOTE: this takes ANYTHING that doesn't match the other tokens */ +#token REGCHAR "~[\\]" + + +grammar : << p_head(); p_class_hdr(); func_action = FALSE;>> + ( {LEXACTION | LEXMEMBER | LEXPREFIX | PARSERCLASS } ACTION)* /* MR1 */ + <> + start_states + << func_action = FALSE; p_tables(); p_tail(); >> + (ACTION)* "@" + << if (firstLexMember != 0) p_class_def1(); >> /* MR1 */ + ; + +start_states : ( PER_PER do_conversion + | NAME_PER_PER do_conversion (NAME_PER_PER do_conversion)*) + PER_PER + ; + +do_conversion : <> + rule_list + << + dfa_class_nop[mode_counter] = + relabel($1.l,comp_level); + if (comp_level) + p_shift_table(mode_counter); + dfa_basep[mode_counter] = dfa_allocated+1; + make_dfa_model_node(dfa_class_nop[mode_counter]); + nfa_to_dfa($1.l); + ++mode_counter; + func_action = FALSE; +#ifdef HASH_STAT + fprint_hash_stats(stderr); +#endif + >> + ; + +rule_list : rule <<$$.l=$1.l; $$.r=$1.r;>> + (rule + <<{nfa_node *t1; + t1 = new_nfa_node(); + (t1)->trans[0]=$$.l; + (t1)->trans[1]=$1.l; + /* all accept nodes "dead ends" */ + $$.l=t1; $$.r=NULL; + } + >> + )* + | /* empty */ + <<$$.l = new_nfa_node(); $$.r = NULL; + warning("no regular expressions", zzline); + >> + ; + +rule : reg_expr ACTION +/* MR23 */ << if ($1.r != NULL) { + $$.l=$1.l; $$.r=$1.r; ($1.r)->accept=action_no; + } + >> + | ACTION + <<$$.l = NULL; $$.r = NULL; + error("no expression for action ", zzline); + >> + ; + +reg_expr : and_expr <<$$.l=$1.l; $$.r=$1.r;>> + (OR and_expr + <<{nfa_node *t1, *t2; + t1 = new_nfa_node(); t2 = new_nfa_node(); + (t1)->trans[0]=$$.l; + (t1)->trans[1]=$2.l; +/* MR23 */ if ($$.r != NULL) ($$.r)->trans[1]=t2; + if ($2.r) { + ($2.r)->trans[1]=t2; /* MR20 */ + } + $$.l=t1; $$.r=t2; + } + >> + )* + ; + +and_expr : repeat_expr + << + $$.l=$1.l; $$.r=$1.r; + >> + (repeat_expr +/* MR23 */ << if ($$.r != NULL) { + ($$.r)->trans[1]=$1.l; + $$.r=$1.r; + } + >> + )* + ; + +repeat_expr : expr <<$$.l=$1.l; $$.r=$1.r;>> + { ZERO_MORE + <<{ nfa_node *t1,*t2; +/* MR23 */ if ($$.r != NULL) ($$.r)->trans[0] = $$.l; + t1 = new_nfa_node(); t2 = new_nfa_node(); + t1->trans[0]=$$.l; + t1->trans[1]=t2; +/* MR23 */ if ($$.r != NULL) ($$.r)->trans[1]=t2; + $$.l=t1;$$.r=t2; + } + >> + | ONE_MORE +/* MR23 */ <trans[0] = $$.l;>> + } + | ZERO_MORE + << error("no expression for *", zzline);>> + | ONE_MORE + << error("no expression for +", zzline);>> + ; + +expr : << $$.l = new_nfa_node(); + $$.r = new_nfa_node(); + >> + L_BRACK atom_list R_BRACK + << +/* MR23 */ if ($$.l != NULL) { + ($$.l)->trans[0] = $$.r; + ($$.l)->label = set_dup($2.label); + set_orin(&used_chars,($$.l)->label); + } + >> + | NOT L_BRACK atom_list R_BRACK + << +/* MR23 */ if ($$.l != NULL) { + ($$.l)->trans[0] = $$.r; + ($$.l)->label = set_dif(normal_chars,$3.label); + set_orin(&used_chars,($$.l)->label); + } + >> + | L_PAR reg_expr R_PAR + << +/* MR23 */ if ($$.l != NULL) { + ($$.l)->trans[0] = $2.l; + if ($2.r) { + ($2.r)->trans[1] = $$.r; /* MR20 */ + } + } + >> + | L_BRACE reg_expr R_BRACE + << +/* MR23 */ if ($$.l != NULL) { + ($$.l)->trans[0] = $2.l; + ($$.l)->trans[1] = $$.r; + if ($2.r) { + ($2.r)->trans[1] = $$.r; /* MR20 */ + } + } + >> + | atom + << +/* MR23 */ if ($$.l != NULL) { + ($$.l)->trans[0] = $$.r; + ($$.l)->label = set_dup($1.label); + set_orin(&used_chars,($$.l)->label); + } + >> + ; + +atom_list : << set_free($$.label); >> + (near_atom <>)* + ; + +near_atom : << register int i; + register int i_prime; + >> + anychar + <<$$.letter=$1.letter; $$.label=set_of($1.letter); + i_prime = $1.letter + MIN_CHAR; + if (case_insensitive && islower(i_prime)) + set_orel(toupper(i_prime)-MIN_CHAR, + &($$.label)); + if (case_insensitive && isupper(i_prime)) + set_orel(tolower(i_prime)-MIN_CHAR, + &($$.label)); + >> + { RANGE anychar + << if (case_insensitive){ + i_prime = $$.letter+MIN_CHAR; + $$.letter = (islower(i_prime) ? + toupper(i_prime) : i_prime)-MIN_CHAR; + i_prime = $2.letter+MIN_CHAR; + $2.letter = (islower(i_prime) ? + toupper(i_prime) : i_prime)-MIN_CHAR; + } + /* check to see if range okay */ + { + int debugLetter1 = $$.letter; + int debugLetter2 = $2.letter; + } + if ($$.letter > $2.letter + && $2.letter != 0xff){ /* MR16 */ + error("invalid range ", zzline); + } + for (i=$$.letter; i<= (int)$2.letter; ++i){ + set_orel(i,&($$.label)); + i_prime = i+MIN_CHAR; + if (case_insensitive && islower(i_prime)) + set_orel(toupper(i_prime)-MIN_CHAR, + &($$.label)); + if (case_insensitive && isupper(i_prime)) + set_orel(tolower(i_prime)-MIN_CHAR, + &($$.label)); + } + >> + } + ; + +atom : << register int i_prime;>> + anychar + <<$$.label = set_of($1.letter); + i_prime = $1.letter + MIN_CHAR; + if (case_insensitive && islower(i_prime)) + set_orel(toupper(i_prime)-MIN_CHAR, + &($$.label)); + if (case_insensitive && isupper(i_prime)) + set_orel(tolower(i_prime)-MIN_CHAR, + &($$.label)); + >> + ; + +anychar : REGCHAR <<$$.letter = $1.letter - MIN_CHAR;>> + | OCTAL_VALUE <<$$.letter = $1.letter - MIN_CHAR;>> + | HEX_VALUE <<$$.letter = $1.letter - MIN_CHAR;>> + | DEC_VALUE <<$$.letter = $1.letter - MIN_CHAR;>> + | TAB <<$$.letter = $1.letter - MIN_CHAR;>> + | NL <<$$.letter = $1.letter - MIN_CHAR;>> + | CR <<$$.letter = $1.letter - MIN_CHAR;>> + | BS <<$$.letter = $1.letter - MIN_CHAR;>> + | LIT <<$$.letter = $1.letter - MIN_CHAR;>> + /* NOTE: LEX_EOF is ALWAYS shifted to 0 = MIN_CHAR - MIN_CHAR*/ + | L_EOF <<$$.letter = 0;>> + ; + +<> + +#lexclass ACT +#token "@" << error("unterminated action", zzline); zzmode(START); >> +#token ACTION "\>\>" + << if (func_action) fprintf(OUT,"}\n\n"); + zzmode(START); +/* MR1 */ +/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ +/* MR1 via <<%%lexmember ...>> */ +/* MR1 This is a consequence of not saving actions */ +/* MR1 */ +/* MR1 */ parserClass=0; +/* MR1 */ lexPrefix=0; +/* MR1 */ lexAction=0; +/* MR1 */ lexMember=0; + >> +#token "\>" << xxputc(zzlextext[0]); zzskip(); >> /* MR1 */ +#token "\\\>" << xxputc('>'); zzskip(); >> /* MR1 */ +#token "\\" << xxputc('\\'); zzskip(); >> /* MR1 */ +#token "\n" << xxputc(zzlextext[0]); ++zzline; zzskip(); >> /* MR1 */ +#token "/\*" << zzmode(ACTION_COMMENTS); /* MR1 */ + xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ + >> /* MR1 */ +#token "//" << zzmode(ACTION_CPP_COMMENTS); /* MR1 */ + xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ + >> /* MR1 */ +#token "~[]" << xxputc(zzlextext[0]); zzskip(); >> /* MR1 */ + /* MR1 */ +#lexclass ACTION_COMMENTS /* MR1 */ +#token "\*/" << zzmode(ACT); /* MR1 */ + xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ + >> /* MR1 */ +#token "[\n\r]" << zzline++; xxputc(zzlextext[0]); zzskip();>> /* MR1 */ +#token "~[]" << xxputc(zzlextext[0]); zzskip();>> /* MR1 */ + /* MR1 */ +#lexclass ACTION_CPP_COMMENTS /* MR1 */ +#token "[\n\r]" << zzmode(ACT); zzline++; /* MR1 */ + xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ + >> /* MR1 */ +#token "~[]" << xxputc(zzlextext[0]); zzskip();>> /* MR1 */ + +<< +/* adds a new nfa to the binary tree and returns a pointer to it */ +nfa_node * +#ifdef __USE_PROTOS +new_nfa_node(void) +#else +new_nfa_node() +#endif +{ + register nfa_node *t; + static int nfa_size=0; /* elements nfa_array[] can hold */ + + ++nfa_allocated; + if (nfa_size<=nfa_allocated){ + /* need to redo array */ + if (!nfa_array){ + /* need some to do inital allocation */ + nfa_size=nfa_allocated+NFA_MIN; + nfa_array=(nfa_node **) malloc(sizeof(nfa_node*)* + nfa_size); + }else{ + /* need more space */ + nfa_size=2*(nfa_allocated+1); + nfa_array=(nfa_node **) realloc(nfa_array, + sizeof(nfa_node*)*nfa_size); + } + } + /* fill out entry in array */ + t = (nfa_node*) malloc(sizeof(nfa_node)); + nfa_array[nfa_allocated] = t; + *t = nfa_model_node; + t->node_no = nfa_allocated; + return t; +} + + +/* initialize the model node used to fill in newly made nfa_nodes */ +void +#ifdef __USE_PROTOS +make_nfa_model_node(void) +#else +make_nfa_model_node() +#endif +{ + nfa_model_node.node_no = -1; /* impossible value for real nfa node */ + nfa_model_node.nfa_set = 0; + nfa_model_node.accept = 0; /* error state default*/ + nfa_model_node.trans[0] = NULL; + nfa_model_node.trans[1] = NULL; + nfa_model_node.label = empty; +} +>> + +<< +#if defined(DEBUG) || defined(_DEBUG) + +/* print out the pointer value and the node_number */ +void +#ifdef __USE_PROTOS +fprint_dfa_pair(FILE *f, nfa_node *p) +#else +fprint_dfa_pair(f, p) +FILE *f; +nfa_node *p; +#endif +{ + if (p){ + fprintf(f, "%x (%d)", p, p->node_no); + }else{ + fprintf(f, "(nil)"); + } +} + +/* print out interest information on a set */ +void +#ifdef __USE_PROTOS +fprint_set(FILE *f, set s) +#else +fprint_set(f,s) +FILE *f; +set s; +#endif +{ + unsigned int *x; + + fprintf(f, "n = %d,", s.n); + if (s.setword){ + fprintf(f, "setword = %x, ", s.setword); + /* print out all the elements in the set */ + x = set_pdq(s); + while (*x!=nil){ + fprintf(f, "%d ", *x); + ++x; + } + }else{ + fprintf(f, "setword = (nil)"); + } +} + +/* code to be able to dump out the nfas + return 0 if okay dump + return 1 if screwed up + */ +int +#ifdef __USE_PROTOS +dump_nfas(int first_node, int last_node) +#else +dump_nfas(first_node, last_node) +int first_node; +int last_node; +#endif +{ + register int i; + nfa_node *t; + + for (i=first_node; i<=last_node; ++i){ + t = NFA(i); + if (!t) break; + fprintf(stderr, "nfa_node %d {\n", t->node_no); + fprintf(stderr, "\n\tnfa_set = %d\n", t->nfa_set); + fprintf(stderr, "\taccept\t=\t%d\n", t->accept); + fprintf(stderr, "\ttrans\t=\t("); + fprint_dfa_pair(stderr, t->trans[0]); + fprintf(stderr, ","); + fprint_dfa_pair(stderr, t->trans[1]); + fprintf(stderr, ")\n"); + fprintf(stderr, "\tlabel\t=\t{ "); + fprint_set(stderr, t->label); + fprintf(stderr, "\t}\n"); + fprintf(stderr, "}\n\n"); + } + return 0; +} +#endif +>> + +<< +/* DLG-specific syntax error message generator + * (define USER_ZZSYN when compiling so don't get 2 definitions) + */ +void +#ifdef __USE_PROTOS +zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, int k, char *bad_text) +#else +zzsyn(text, tok, egroup, eset, etok, k, bad_text) +char *text, *egroup, *bad_text; +int tok; +int etok; +int k; +SetWordType *eset; +#endif +{ + fprintf(stderr, ErrHdr, file_str[0]!=NULL?file_str[0]:"stdin", zzline); + fprintf(stderr, " syntax error at \"%s\"", (tok==zzEOF_TOKEN)?"EOF":text); + if ( !etok && !eset ) {fprintf(stderr, "\n"); return;} + if ( k==1 ) fprintf(stderr, " missing"); + else + { + fprintf(stderr, "; \"%s\" not", bad_text); + if ( zzset_deg(eset)>1 ) fprintf(stderr, " in"); + } + if ( zzset_deg(eset)>0 ) zzedecode(eset); + else fprintf(stderr, " %s", zztokens[etok]); + if ( strlen(egroup) > (size_t)0 ) fprintf(stderr, " in %s", egroup); + fprintf(stderr, "\n"); +} +>> diff --git a/Tools/CodeTools/Source/Pccts/dlg/err.c b/Tools/CodeTools/Source/Pccts/dlg/err.c new file mode 100644 index 0000000000..c3eaeae6d1 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/dlg/err.c @@ -0,0 +1,99 @@ +/* + * A n t l r S e t s / E r r o r F i l e H e a d e r + * + * Generated from: dlg_p.g + * + * Terence Parr, Russell Quong, Will Cohen, and Hank Dietz: 1989-2001 + * Parr Research Corporation + * with Purdue University Electrical Engineering + * With AHPCRC, University of Minnesota + * ANTLR Version 1.33MR33 + */ + +#define ANTLR_VERSION 13333 +#include "pcctscfg.h" +#include "pccts_stdio.h" + +#include +#include "dlg.h" +#define zzSET_SIZE 8 +#include "antlr.h" +#include "tokens.h" +#include "dlgdef.h" +#include "err.h" + +ANTLRChar *zztokens[46]={ + /* 00 */ "Invalid", + /* 01 */ "@", + /* 02 */ "[\\r\\t\\ ]+", + /* 03 */ "\\n", + /* 04 */ "L_EOF", + /* 05 */ "PER_PER", + /* 06 */ "NAME_PER_PER", + /* 07 */ "LEXMEMBER", + /* 08 */ "LEXACTION", + /* 09 */ "PARSERCLASS", + /* 10 */ "LEXPREFIX", + /* 11 */ "ACTION", + /* 12 */ "GREAT_GREAT", + /* 13 */ "L_BRACE", + /* 14 */ "R_BRACE", + /* 15 */ "L_PAR", + /* 16 */ "R_PAR", + /* 17 */ "L_BRACK", + /* 18 */ "R_BRACK", + /* 19 */ "ZERO_MORE", + /* 20 */ "ONE_MORE", + /* 21 */ "OR", + /* 22 */ "RANGE", + /* 23 */ "NOT", + /* 24 */ "OCTAL_VALUE", + /* 25 */ "HEX_VALUE", + /* 26 */ "DEC_VALUE", + /* 27 */ "TAB", + /* 28 */ "NL", + /* 29 */ "CR", + /* 30 */ "BS", + /* 31 */ "CONTINUATION", + /* 32 */ "LIT", + /* 33 */ "REGCHAR", + /* 34 */ "\\>", + /* 35 */ "\\\\>", + /* 36 */ "\\", + /* 37 */ "\\n", + /* 38 */ "/\\*", + /* 39 */ "//", + /* 40 */ "~[]", + /* 41 */ "\\*/", + /* 42 */ "[\\n\\r]", + /* 43 */ "~[]", + /* 44 */ "[\\n\\r]", + /* 45 */ "~[]" +}; +SetWordType zzerr1[8] = {0x80,0xf,0x0,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr2[8] = {0x60,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; +SetWordType zzerr3[8] = {0x70,0xa8,0x9a,0x7f, 0x3,0x0,0x0,0x0}; +SetWordType setwd1[46] = {0x0,0x6,0x0,0x0,0x30,0xc8,0xc8, + 0x1,0x1,0x1,0x1,0x35,0x0,0x30,0x0, + 0x30,0x0,0x30,0x0,0x30,0x30,0x0,0x0, + 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30, + 0x0,0x30,0x30,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0}; +SetWordType zzerr4[8] = {0x10,0xa8,0x9a,0x7f, 0x3,0x0,0x0,0x0}; +SetWordType zzerr5[8] = {0x10,0xe8,0xbb,0x7f, 0x3,0x0,0x0,0x0}; +SetWordType zzerr6[8] = {0x10,0xa0,0x9a,0x7f, 0x3,0x0,0x0,0x0}; +SetWordType setwd2[46] = {0x0,0x0,0x0,0x0,0xeb,0x2,0x2, + 0x0,0x0,0x0,0x0,0xd6,0x0,0xeb,0xd4, + 0xeb,0xd4,0xeb,0x0,0xcb,0xcb,0xd0,0x0, + 0xeb,0xeb,0xeb,0xeb,0xeb,0xeb,0xeb,0xeb, + 0x0,0xeb,0xeb,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0}; +SetWordType zzerr7[8] = {0x10,0xa0,0x82,0x7f, 0x3,0x0,0x0,0x0}; +SetWordType zzerr8[8] = {0x10,0x0,0x44,0x7f, 0x3,0x0,0x0,0x0}; +SetWordType zzerr9[8] = {0x10,0x0,0x0,0x7f, 0x3,0x0,0x0,0x0}; +SetWordType setwd3[46] = {0x0,0x0,0x0,0x0,0xf7,0x0,0x0, + 0x0,0x0,0x0,0x0,0xc2,0x0,0xc2,0xc2, + 0xc2,0xc2,0xc2,0xb8,0xc2,0xc2,0xc2,0x80, + 0xc2,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7, + 0x0,0xf7,0xf7,0x0,0x0,0x0,0x0,0x0, + 0x0,0x0,0x0,0x0,0x0,0x0,0x0}; diff --git a/Tools/CodeTools/Source/Pccts/dlg/main.c b/Tools/CodeTools/Source/Pccts/dlg/main.c new file mode 100644 index 0000000000..35bd827f8c --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/dlg/main.c @@ -0,0 +1,281 @@ +/* Main function for dlg version + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * DLG 1.33 + * Will Cohen + * With mods by Terence Parr; AHPCRC, University of Minnesota + * 1989-2001 + */ + +#include +#include "stdpccts.h" + +char program[] = "dlg"; +char version[] = "1.33MR33"; /* MRXXX */ +int numfiles = 0; +char *file_str[2] = {NULL, NULL}; +char *mode_file = "mode.h"; +char *class_name = DEFAULT_CLASSNAME; +char *OutputDirectory = TopDirectory; + +/* Option variables */ +int comp_level = 0; +int interactive = FALSE; +int case_insensitive = FALSE; +int warn_ambig = FALSE; +int gen_cpp = FALSE; + +#ifdef __USE_PROTOS +static int ci_strequ(char *a,char *b) +#else +static int ci_strequ(a,b) + char *a; + char *b; +#endif +{ + for ( ;*a != 0 && *b != 0; a++, b++) { + if (toupper(*a) != toupper(*b)) return 0; + } + return (*a == *b); +} + +/* Option List Stuff */ +#ifdef __USE_PROTOS +void p_comp0(void) {comp_level = 0;} +void p_comp1(void) {comp_level = 1;} +void p_comp2(void) {comp_level = 2;} +void p_stdio(void) { file_str[numfiles++] = NULL;} +void p_file(char *s) { file_str[numfiles++] = s;} +void p_cl_name(char *s, char *t) + { + if ( gen_cpp ) { + class_name = t; + } + else { + warning("-cl only valid in C++ mode; -cl ignored...",0); + } + } +void p_mode_file(char *s, char *t){mode_file=t;} +void p_outdir(char *s,char *t) {OutputDirectory=t;} +void p_ansi(void) {gen_ansi = TRUE;} +void p_interactive(void) {interactive = TRUE;} +void p_case_s(void) { case_insensitive = FALSE; } +void p_case_i(void) { case_insensitive = TRUE; } +void p_warn_ambig(void) { warn_ambig = TRUE; } +void p_cpp(void) { gen_cpp = TRUE; } +#else +void p_comp0() {comp_level = 0;} +void p_comp1() {comp_level = 1;} +void p_comp2() {comp_level = 2;} +void p_stdio() { file_str[numfiles++] = NULL;} +void p_file(s) char *s; { file_str[numfiles++] = s;} +void p_cl_name(s,t) + char *s, *t; + { + if ( gen_cpp ) { + class_name = t; + } + else { + warning("-cl only valid in C++ mode; -cl ignored...",0); + } + } +void p_mode_file(s,t) char *s,*t;{mode_file=t;} +void p_outdir(s,t) char *s,*t;{OutputDirectory=t;} +void p_ansi() {gen_ansi = TRUE;} +void p_interactive() {interactive = TRUE;} +void p_case_s() { case_insensitive = FALSE; } +void p_case_i() { case_insensitive = TRUE; } +void p_warn_ambig() { warn_ambig = TRUE; } +void p_cpp() { gen_cpp = TRUE; } +#endif + +#ifdef __cplusplus +typedef void (*WildFunc)(...); +#else +typedef void (*WildFunc)(); +#endif + +typedef struct { + char *option; + int arg; + WildFunc process; + char *descr; + } Opt; + +Opt options[] = { + { "-CC", 0, (WildFunc)p_cpp, "Generate C++ output" }, + { "-C0", 0, (WildFunc)p_comp0, "No compression (default)" }, + { "-C1", 0, (WildFunc)p_comp1, "Compression level 1" }, + { "-C2", 0, (WildFunc)p_comp2, "Compression level 2" }, + { "-ga", 0, (WildFunc)p_ansi, "Generate ansi C"}, + { "-Wambiguity", 0, (WildFunc)p_warn_ambig, "Warn if expressions ambiguous"}, + { "-m", 1, (WildFunc)p_mode_file, "Rename lexical mode output file"}, + { "-i", 0, (WildFunc)p_interactive, "Build interactive scanner (not valid for C++ mode)"}, + { "-ci", 0, (WildFunc)p_case_i, "Make lexical analyzer case insensitive"}, + { "-cl", 1, (WildFunc)p_cl_name, "Rename lexer class (DLGLexer); only used for -CC"}, + { "-cs", 0, (WildFunc)p_case_s, "Make lexical analyzer case sensitive (default)"}, + { "-o", 1, (WildFunc)p_outdir, OutputDirectoryOption}, + { "-", 0, (WildFunc)p_stdio, "Use standard i/o rather than file"}, + { "*", 0, (WildFunc)p_file, ""}, /* anything else is a file */ + { NULL, 0, NULL } + }; + +#ifdef __USE_PROTOS +void ProcessArgs(int argc, char **argv, Opt *options) +#else +void ProcessArgs(argc, argv, options) +int argc; +char **argv; +Opt *options; +#endif +{ + Opt *p; + + while ( argc-- > 0 ) + { + p = options; + while ( p->option != NULL ) + { + if ( strcmp(p->option, "*") == 0 || + ci_strequ(p->option,*argv) ) + { + if ( p->arg ) + { + (*p->process)( *argv, *(argv+1) ); + argv++; + argc--; + } + else + (*p->process)( *argv ); + break; + } + p++; + } + argv++; + } +} + +#ifdef __USE_PROTOS +int main(int argc, char *argv[]) +#else +int main(argc, argv) +int argc; +char *argv[]; +#endif +{ + init(); + fprintf(stderr, "%s Version %s 1989-2001\n", &(program[0]), + &(version[0])); + if ( argc == 1 ) + { + Opt *p = options; + fprintf(stderr, "%s [options] f1 f2 ... fn\n",argv[0]); + while ( *(p->option) != '*' ) + { + fprintf(stderr, "\t%s %s\t%s\n", + p->option, + (p->arg)?"___":" ", + p->descr); + p++; + } + }else{ + ProcessArgs(argc-1, &(argv[1]), options); + if (interactive && gen_cpp) { + fprintf(stderr,"\n"); +/*** MR21a This statement is wrong ! ***/ +#if 0 +*** fprintf(stderr,"Interactive lexer option (\"-i\") has no effect when in C++ mode\n"); +*** fprintf(stderr,"because of extra buffering provided by ANTLRTokenBuffer class.\n"); +*** fprintf(stderr,"\n"); +#endif + } + input_stream = read_stream(file_str[0]); + if (input_stream) { + /* don't overwrite unless input okay */ + if ( gen_cpp ) { + output_stream = write_stream(ClassName(CPP_FILE_SUFFIX)); + if ( file_str[1]!=NULL ) { + warning("output file implicit in C++ mode; ignored...",0); + } + class_stream = write_stream(ClassName(".h")); + mode_stream = class_stream; + } + else { + output_stream = write_stream(file_str[1]); + mode_stream = write_stream(mode_file); + } + } + /* make sure that error reporting routines in grammar + know what the file really is */ + /* make sure that reading and writing somewhere */ + if (input_stream && output_stream && mode_stream){ + ANTLR(grammar(), input_stream); + } + p_class_def2(); /* MR1 */ + } + if ( output_stream!=NULL ) fclose(output_stream); + if ( !gen_cpp && mode_stream!=NULL ) fclose(mode_stream); + if ( class_stream!=NULL ) fclose(class_stream); + exit(PCCTS_EXIT_SUCCESS); + return 0; /* get rid of warning message MR1 */ +} + +/* initialize all the variables */ +void +#ifdef __USE_PROTOS +init(void) +#else +init() +#endif +{ + register int i; + +#ifdef SPECIAL_INITS + special_inits(); /* MR1 */ +#endif + used_chars = empty; + used_classes = empty; + /* make the valid character set */ + normal_chars = empty; + /* NOTE: MIN_CHAR is EOF */ + /* NOTE: EOF is not quite a valid char, it is special. Skip it*/ + for (i = 1; i +#include +#include "dlg.h" +#ifdef MEMCHK +#include "trax.h" +#else +#ifdef __STDC__ +#include +#else +#include +#endif /* __STDC__ */ +#endif + +static char *mode_name[MAX_MODES]; +static int mode_number[MAX_MODES]; +static int cur_mode=0; + +int operation_no = 0; /* used to mark nodes so that infinite loops avoided */ +int dfa_basep[MAX_MODES]; /* start of each group of states */ +int dfa_class_nop[MAX_MODES]; /* number of elements in each group of states*/ + +int gen_ansi = FALSE; /* allows ansi code to be generated */ + +FILE *input_stream; /* where to read description from */ +FILE *output_stream; /* where to put the output */ +FILE *mode_stream; /* where to put the mode.h stuff */ +FILE *class_stream; /* where to put the scan.h stuff (if gen_cpp) */ + +/* NOTE: This section is MACHINE DEPENDENT */ +#define DIF_SIZE 4 +#if defined(PC) && !defined(PC32) +unsigned long typesize[DIF_SIZE] = { 0x7f, 0x7fff, 0x7ffful, 0x7ffffffful }; /* MR20 */ +char t0[] = "unsigned char"; +char t1[] = "unsigned short"; +char t2[] = "unsigned int"; +char t3[] = "unsigned long"; +char *typevar[DIF_SIZE] = { t0, t1, t2, t3}; +#else +unsigned long typesize[DIF_SIZE] = { 0x7f, 0x7fff, 0x7ffffffful, 0x7ffffffful }; /* MR20 */ +char t0[] = "unsigned char"; +char t1[] = "unsigned short"; +char t2[] = "unsigned int"; +char t3[] = "unsigned long"; +char *typevar[DIF_SIZE] = { t0, t1, t2, t3}; +#endif + +/* Added by TJP August 1994 */ +/* Take in MyLexer and return MyLexer_h */ + +static char * +#ifdef __USE_PROTOS +gate_symbol(char *name) +#else +gate_symbol(name) +char *name; +#endif +{ + static char buf[100]; + sprintf(buf, "%s_h", name); + return buf; +} + +/* Added by TJP August 1994 */ +static char * +#ifdef __USE_PROTOS +mystrdup(char *s) +#else +mystrdup(s) +char *s; +#endif +{ + char *p = (char *)malloc(strlen(s)+1); + strcpy(p, s); + return p; +} + +#ifdef __USE_PROTOS +void p_class_hdr(void) +#else +void p_class_hdr() +#endif +{ + if ( class_stream == NULL ) return; + fprintf(class_stream, "#ifndef %s\n", gate_symbol(ClassName(""))); + fprintf(class_stream, "#define %s\n", gate_symbol(ClassName(""))); + fprintf(class_stream, "/*\n"); + fprintf(class_stream, " * D L G L e x e r C l a s s D e f i n i t i o n\n"); + fprintf(class_stream, " *\n"); + fprintf(class_stream, " * Generated from:"); + fprintf(class_stream, " %s", file_str[0]); + fprintf(class_stream, "\n"); + fprintf(class_stream, " *\n"); + fprintf(class_stream, " * 1989-2001 by Will Cohen, Terence Parr, and Hank Dietz\n"); + fprintf(class_stream, " * Purdue University Electrical Engineering\n"); + fprintf(class_stream, " * DLG Version %s\n", version); + fprintf(class_stream, " */\n\n"); + fprintf(class_stream, "\n"); + fprintf(class_stream, "#include \"%s\"\n", DLEXERBASE_H); +} + +/* MR1 */ +/* MR1 16-Apr-97 Split printing of class header up into several parts */ +/* MR1 so that #lexprefix <<...>>and #lexmember <<...>> */ +/* MR1 can be inserted in the appropriate spots */ +/* MR1 */ + +#ifdef __USE_PROTOS +void p_class_def1(void) +#else +void p_class_def1() +#endif +{ + if ( class_stream == NULL ) return; + fprintf(class_stream, "\nclass %s : public DLGLexerBase {\n", ClassName("")); + fprintf(class_stream, "public:\n"); +} + +#ifdef __USE_PROTOS +void p_class_def2(void) +#else +void p_class_def2() +#endif +{ + int i, m; + if ( class_stream == NULL ) return; + fprintf(class_stream, "public:\n"); + fprintf(class_stream, "\tstatic const int MAX_MODE;\n"); + fprintf(class_stream, "\tstatic const int DfaStates;\n"); + for (i=0; i> */ +/* MR1 */ +/* MR1 */ fprintf(class_stream,"//\n"); +/* MR1 */ fprintf(class_stream, +/* MR1 */ "// 133MR1 Deprecated feature to allow inclusion of "); +/* MR1 */ fprintf(class_stream, +/* MR1 */ "user-defined code in DLG class header\n"); +/* MR1 */ fprintf(class_stream,"//\n"); +/* MR1 */ +/* MR1 */ fprintf(class_stream,"#ifdef DLGLexerIncludeFile\n"); +/* MR1 */ fprintf(class_stream,"#include DLGLexerIncludeFile\n"); +/* MR1 */ fprintf(class_stream,"#endif\n"); + + fprintf(class_stream, "};\n"); + + fprintf(class_stream, "typedef ANTLRTokenType (%s::*Ptr%sMemberFunc)();\n", + ClassName(""), ClassName("")); + + fprintf(class_stream, "#endif\n"); +} + +/* generate required header on output */ + +#ifdef __USE_PROTOS +void p_head(void) +#else +void p_head() +#endif +{ + fprintf(OUT, "/*\n"); + fprintf(OUT, " * D L G tables\n"); + fprintf(OUT, " *\n"); + fprintf(OUT, " * Generated from:"); + fprintf(OUT, " %s", file_str[0]); + fprintf(OUT, "\n"); + fprintf(OUT, " *\n"); + fprintf(OUT, " * 1989-2001 by Will Cohen, Terence Parr, and Hank Dietz\n"); + fprintf(OUT, " * Purdue University Electrical Engineering\n"); + fprintf(OUT, " * DLG Version %s\n", version); + fprintf(OUT, " */\n\n"); + if ( gen_cpp) fprintf(OUT, "#include \"pcctscfg.h\"\n"); + if ( gen_cpp ) fprintf(OUT, "#include \"pccts_stdio.h\"\n"); + if ( !gen_cpp ) fprintf(OUT, "#include \"%s\"\n\n", mode_file); + fprintf(OUT,"\n"); +} + +#ifdef __USE_PROTOS +void p_includes(void) +#else +void p_includes() +#endif +{ + fprintf(OUT, "#include \"%s\"\n", APARSER_H); + fprintf(OUT, "#include \"%s\"\n", DLEXERBASE_H); + fprintf(OUT, "#include \"%s\"\n", ClassName(".h")); +} + +/* generate code to tie up any loose ends */ + +#ifdef __USE_PROTOS +void p_tail(void) /* MR1 */ +#else +void p_tail() /* MR1 */ +#endif +{ + if ( gen_cpp ) { + if ( strcmp(ClassName(""), DEFAULT_CLASSNAME)!=0 ) + fprintf(OUT, "#define DLGLexer %s\n", ClassName("")); + fprintf(OUT, "#include \"%s\"\n", DLEXER_H); /* MR23 Rename DLexer.cpp to DLexer.h */ + return; + } + fprintf(OUT, "\n"); + fprintf(OUT, "\n"); + if (comp_level) + fprintf(OUT, "#define ZZSHIFT(c) (b_class_no[zzauto][1+c])\n"); + else + fprintf(OUT, "#define ZZSHIFT(c) (1+c)\n"); + if ( !gen_cpp ) fprintf(OUT, "#define MAX_MODE %d\n",mode_counter); + fprintf(OUT, "#include \"dlgauto.h\"\n"); +} + + +/* output the table of DFA for general use */ + +#ifdef __USE_PROTOS +void p_tables() +#else +void p_tables() +#endif +{ + if ( !gen_cpp ) { + fprintf(OUT, "#define DfaStates\t%d\n", dfa_allocated); + fprintf(OUT, "typedef %s DfaState;\n\n", minsize(dfa_allocated)); + } + + if ( gen_cpp ) { + int i; + fprintf(OUT, "\n"); + fprintf(OUT, "const int %s::MAX_MODE=%d;\n", + ClassName(""), + mode_counter); + fprintf(OUT, "const int %s::DfaStates=%d;\n", + ClassName(""), + dfa_allocated); + for (i=0; i typesize[i]) /* MR20 */ + ++i; + return typevar[i]; +} + + +#ifdef __USE_PROTOS +void p_node_table(void) +#else +void p_node_table() +#endif +{ + register int i; + register int m = 0; + + for(m=0; m<(mode_counter-1); ++m){ + for(i=dfa_basep[m]; itrans[j]; + if (trans == NIL_INDEX) + trans = dfa_allocated+1; + /* all of DFA moved down one in array */ + fprintf(OUT, "%d", trans-1); + fprintf(OUT, ", "); + if (!(--items_on_line)){ + fprintf(OUT, "\n "); + items_on_line = MAX_ON_LINE; + } + } +#if 1 + /* put in jump to error state */ + fprintf(OUT, "%d\n};\n\n", dfa_allocated); +#else + fprintf(OUT, "\n};\n\n"); +#endif +} + + +#ifdef __USE_PROTOS +void p_dfa_table(void) +#else +void p_dfa_table() +#endif +{ + register int i; + + fprintf(OUT, "\n%sDfaState *%sdfa[%d] = {\n", + gen_cpp?ClassName("::"):"",gen_cpp?ClassName("::"):"", dfa_allocated); + for (i=0; i<(dfa_allocated-1); ++i){ + fprintf(OUT, "\tst%d,\n", i); + } + fprintf(OUT, "\tst%d\n", i); + fprintf(OUT, "};\n\n"); +} + + +#ifdef __USE_PROTOS +void p_accept_table(void) +#else +void p_accept_table() +#endif +{ + register int i = 1; + register int items_on_line = 0; + int true_interactive = TRUE; + + /* make sure element for one past (zzerraction) -WEC 12/16/92 */ + fprintf(OUT,"\n%sDfaState %saccepts[%d] = {\n ", + gen_cpp?ClassName("::"):"", + gen_cpp?ClassName("::"):"", + dfa_allocated+1); + /* don't do anything if no dfa nodes */ + if (i>dfa_allocated) goto skip_accepts; + for (;;) { + int accept=0; /* MR14a - Manuel Kessler (mlkessle@cip.physik.uni-wuerzburg.de) */ + set accept_set; + set nfa_states; + unsigned int *t, *nfa_i; + unsigned int *q, *regular_expr; + + accept_set = empty; + nfa_states = DFA(i)->nfa_states; + t = nfa_i = set_pdq(nfa_states); + /* NOTE: picks lowest accept because accepts monotonic */ + /* with respect to nfa node numbers and set_pdq */ + /* returns in that order */ + while((*nfa_i != nil) && (!(accept = NFA(*nfa_i)->accept))){ + nfa_i++; + } + + /* figure out if more than one accept state there */ + if (warn_ambig ){ + set_orel(accept, &accept_set); + while(*nfa_i != nil){ + set_orel(NFA(*nfa_i)->accept, &accept_set); + nfa_i++; + } + /* remove error action from consideration */ + set_rm(0, accept_set); + + if( set_deg(accept_set)>1){ + fprintf(stderr, "dlg warning: ambiguous regular expression "); + q = regular_expr = set_pdq(accept_set); + while(*regular_expr != nil){ + fprintf(stderr," %d ", *regular_expr); + ++regular_expr; + } + fprintf(stderr, "\n"); + free(q); + } + } + + if ((DFA(i)->alternatives) && (accept != 0)){ + true_interactive = FALSE; + } + fprintf(OUT, "%d, ", accept); + + /* free up memory before we "break" below -ATG 4/6/95 */ + free(t); + set_free(accept_set); + + if ((++i)>dfa_allocated) + break; + if ((++items_on_line)>=MAX_ON_LINE){ + fprintf(OUT,"\n "); + items_on_line = 0; + } +/* + free(t); + set_free(accept_set); +*/ + } + /* make sure element for one past (zzerraction) -WEC 12/16/92 */ +skip_accepts: + fprintf(OUT, "0\n};\n\n"); +} + + +#ifdef __USE_PROTOS +void p_action_table(void) +#else +void p_action_table() +#endif +{ + register int i; + char* theClassName = ClassName(""); + + if ( gen_cpp ) + fprintf(OUT, "Ptr%sMemberFunc %s::actions[%d] = {\n", theClassName, + theClassName, action_no+1); + else + fprintf(OUT, "void (*actions[%d])() = {\n", action_no+1); + if ( gen_cpp ) +/* fprintf(OUT, "\t(Ptr%sMemberFunc)&%s::erraction,\n", theClassName, theClassName);*/ + fprintf(OUT, "\t&%s::erraction,\n", theClassName); + else + fprintf(OUT, "\tzzerraction,\n"); + for (i=1; i=CHAR_RANGE) + break; + fprintf(OUT,", "); + if ((++items_on_line)>=MAX_ON_LINE){ + fprintf(OUT,"\n "); + items_on_line = 0; + } + } + fprintf(OUT, "\n};\n\n"); +} + + +#ifdef __USE_PROTOS +void p_base_table(void) +#else +void p_base_table() +#endif +{ + register int m; + + fprintf(OUT, "%sDfaState %sdfa_base[] = {\n", + gen_cpp?ClassName("::"):"static ", + gen_cpp?ClassName("::"):""); + for(m=0; m<(mode_counter-1); ++m) + fprintf(OUT, "\t%d,\n", dfa_basep[m]-1); + fprintf(OUT, "\t%d\n};\n\n", dfa_basep[m]-1); +} + + +#ifdef __USE_PROTOS +void p_class_table(void) /* MR1 */ +#else +void p_class_table() /* MR1 */ +#endif +{ +#if 0 + register int m; + + fprintf(OUT,"%s int %sdfa_class_no[] = {\n", + gen_cpp?"":"static", + gen_cpp?ClassName("::"):""); + for(m=0; m<(mode_counter-1); ++m) + fprintf(OUT,"\t%d,\n", dfa_class_nop[m]); + fprintf(OUT,"\t%d\n};\n\n", dfa_class_nop[m]); +#endif +} + + +#ifdef __USE_PROTOS +void p_bshift_table(void) /* MR1 */ +#else +void p_bshift_table() /* MR1 */ +#endif +{ + register int m; + + fprintf(OUT,"%s unsigned char *%sb_class_no[] = {\n", + gen_cpp?"":"static", + gen_cpp?ClassName("::"):""); + for(m=0; m<(mode_counter-1); ++m) + fprintf(OUT, "\tshift%d,\n", m); + fprintf(OUT, "\tshift%d\n};\n\n", m); +} + + +#ifdef __USE_PROTOS +void p_alternative_table(void) /* MR1 */ +#else +void p_alternative_table() /* MR1 */ +#endif +{ + register int i; + + if ( !gen_cpp ) fprintf(OUT, "#define ZZINTERACTIVE\n\n"); + if ( gen_cpp ) + fprintf(OUT, "DLGChar %salternatives[%d] = {\n", /* mr23 vhs %sDfaStates+1 */ + ClassName("::"), + dfa_allocated+1); /* vhs ClassName("::")); */ + else + fprintf(OUT, "static %s zzalternatives[DfaStates+1] = {\n", + minsize(dfa_allocated)); + + for(i=1; i<=dfa_allocated; ++i) + fprintf(OUT, "\t%d,\n", DFA(i)->alternatives); + fprintf(OUT, "/* must have 0 for zzalternatives[DfaStates] */\n"); + fprintf(OUT, "\t0\n};\n\n"); +} + + +#ifdef __USE_PROTOS +void p_mode_def(char *s,int m) /* MR1 */ +#else +void p_mode_def(s,m) /* MR1 */ +char *s; +int m; +#endif +{ + if ( gen_cpp ) + { + mode_name[cur_mode] = mystrdup(s); + mode_number[cur_mode] = m; + cur_mode++; + } + else + fprintf(mode_stream, "#define %s %d\n", s, m); +} + +#ifdef __USE_PROTOS +char * ClassName(char *suffix) +#else +char * ClassName(suffix) +char *suffix; +#endif +{ + static char buf[200]; + extern char *class_name; + + sprintf(buf, "%s%s", class_name, suffix); + return buf; +} + +#ifdef DEBUG + +/* print out a particular nfa node that is pointed to by p */ + +#ifdef __USE_PROTOS +void p_nfa_node(nfa_node *p) +#else +void p_nfa_node(p) +nfa_node *p; +#endif +{ + register nfa_node *t; + + if (p != NIL_INDEX){ + printf("NFA state : %d\naccept state : %d\n", + NFA_NO(p),p->accept); + if (p->trans[0] != NIL_INDEX){ + printf("trans[0] => %d on ", NFA_NO(p->trans[0])); + p_set(p->label); + printf("\n"); + } + else + printf("trans[0] => nil\n"); + if (p->trans[1] != NIL_INDEX) + printf("trans[1] => %d on epsilon\n", + NFA_NO(p->trans[1])); + else + printf("trans[1] => nil\n"); + printf("\n"); + } +} +#endif + +#ifdef DEBUG + +/* code to print out special structures when using a debugger */ + +#ifdef __USE_PROTOS +void p_nfa(p) +#else +void p_nfa(nfa_node *p) +nfa_node *p; /* state number also index into array */ +#endif +{ +/* each node has a marker on it so it only gets printed once */ + + operation_no++; /* get new number */ + s_p_nfa(p); +} + +#ifdef __USE_PROTOS +void s_p_nfa(nfa_node *p) +#else +void s_p_nfa(p) +nfa_node *p; /* state number also index into array */ +#endif +{ + if ((p != NIL_INDEX) && (p->nfa_set != operation_no)){ + /* so it is only printed once */ + p->nfa_set = operation_no; + p_nfa_node(p); + s_p_nfa(p->trans[0]); + s_p_nfa(p->trans[1]); + } +} + +#ifdef __USE_PROTOS +void p_dfa_node(dfa_node *p) +#else +void p_dfa_node(p) +dfa_node *p; +#endif +{ + int i; + + if (p != NIL_INDEX){ + printf("DFA state :%d\n",NFA_NO(p)); + if (p->done) + printf("done\n"); + else + printf("undone\n"); + printf("from nfa states : "); + p_set(p->nfa_states); + printf("\n"); + /* NOTE: trans arcs stored as ints rather than pointer*/ + for (i=0; itrans[i]); + } + printf("\n\n"); + } +} + +#ifdef __USE_PROTOS +void p_dfa(void) +#else +void p_dfa() +#endif +{ +/* prints out all the dfa nodes actually allocated */ + + int i; + + for (i = 1; i<=dfa_allocated; i++) + p_dfa_node(NFA(i)); +} + + +/* print out numbers in the set label */ + +#ifdef __USE_PROTOS +void p_set(set label) +#else +void p_set(label) +set label; +#endif +{ + unsigned *t, *e; + + if (set_nil(label)){ + printf("epsilon\n"); + }else{ + t = e = set_pdq(label); + while(*e != nil){ + printf("%d ", (*e+MIN_CHAR)); + e++; + } + printf("\n"); + free(t); + } + +} +#endif diff --git a/Tools/CodeTools/Source/Pccts/dlg/parser.dlg b/Tools/CodeTools/Source/Pccts/dlg/parser.dlg new file mode 100644 index 0000000000..df9a637f9e --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/dlg/parser.dlg @@ -0,0 +1,398 @@ +<< +/* parser.dlg -- DLG Description of scanner + * + * Generated from: dlg_p.g + * + * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001 + * Purdue University Electrical Engineering + * With AHPCRC, University of Minnesota + * ANTLR Version 1.33MR33 + */ + +#define ANTLR_VERSION 13333 +#include "pcctscfg.h" +#include "pccts_stdio.h" + +#include +#include "dlg.h" +#include "antlr.h" +#include "tokens.h" +#include "dlgdef.h" +LOOKAHEAD + +void +#ifdef __USE_PROTOS +zzerraction(void) +#else +zzerraction() +#endif +{ + (*zzerr)("invalid token"); + zzadvance(); + zzskip(); +} +>> + +<<%%lexaction + +int func_action; /* should actions be turned into functions?*/ +int lex_mode_counter = 0; /* keeps track of the number of %%names */ +/* MR1 */ +/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ +/* MR1 via <<%%lexmember...>> */ +/* MR1 */ +int lexMember = 0; /* <<%%lexmemeber ...>> MR1 */ +int lexAction = 0; /* <<%%lexaction ...>> MR1 */ +int parserClass = 0; /* <<%%parserclass ...>> MR1 */ +int lexPrefix = 0; /* <<%%lexprefix ...>> MR1 */ +char theClassName[100]; /* MR11 */ +char *pClassName=theClassName; /* MR11 */ +int firstLexMember=1; /* MR1 */ + +#ifdef __USE_PROTOS +void xxputc(int c) { /* MR1 */ +#else + void xxputc(c) /* MR1 */ + int c; /* MR1 */ + { /* MR1 */ +#endif + if (parserClass) { /* MR1 */ + *pClassName++=c; /* MR1 */ + *pClassName=0; /* MR1 */ + } else if (lexMember || lexPrefix) { /* MR1 */ + if (class_stream != NULL) fputc(c,class_stream); /* MR1 */ + } else { /* MR1 */ + fputc(c,OUT); /* MR1 */ + }; /* MR1 */ + } /* MR1 */ + +#ifdef __USE_PROTOS + void xxprintf(char *format,char *string) { /* MR1 */ +#else + void xxprintf(format,string) /* MR1 */ + char *format; /* MR1 */ + char *string; /* MR1 */ + { /* MR1 */ +#endif + if (lexMember || lexPrefix || parserClass) { /* MR1 */ + if (class_stream != NULL) /* MR1 */ + fprintf(class_stream,format,string); /* MR1 */ + } else { /* MR1 */ + fprintf(OUT,format,string); /* MR1 */ + }; /* MR1 */ + } /* MR1 */ +>> + + +%%START + +@ + << + NLA = 1; + >> + +[\r\t\ ]+ + << + NLA = 2; + zzskip(); + >> + +\n + << + NLA = 3; + zzline++; zzskip(); DAWDLE; + >> + +\@ + << + NLA = L_EOF; + >> + +\%\% + << + NLA = PER_PER; + >> + +\%\%[a-zA-Z_][a-zA-Z0-9_]* + << + NLA = NAME_PER_PER; + p_mode_def(&zzlextext[2],lex_mode_counter++); + >> + +\<\<\%\%lexmember + << + NLA = LEXMEMBER; + lexMember=1; /* MR1 */ + if (firstLexMember != 0) { /* MR1 */ + firstLexMember=0; /* MR1 */ + p_class_def1(); /* MR1 */ + }; /* MR1 */ + zzmode(ACT); /* MR1 */ + >> + +\<\<\%\%lexaction + << + NLA = LEXACTION; + lexAction=1;zzmode(ACT); + >> + +\<\<\%\%parserclass + << + NLA = PARSERCLASS; + parserClass=1; /* MR1 */ + zzmode(ACT); /* MR1 */ + >> + +\<\<\%\%lexprefix + << + NLA = LEXPREFIX; + lexPrefix=1;zzmode(ACT); + >> + +\<\< + << + NLA = ACTION; + if (func_action) + fprintf(OUT,"\n%s %sact%d()\n{ ", + gen_cpp?"ANTLRTokenType":"static void", + gen_cpp?ClassName("::"):"", ++action_no); + zzmode(ACT); zzskip(); + >> + +\>\> + << + NLA = GREAT_GREAT; + >> + +\{ + << + NLA = L_BRACE; + >> + +\} + << + NLA = R_BRACE; + >> + +\( + << + NLA = L_PAR; + >> + +\) + << + NLA = R_PAR; + >> + +\[ + << + NLA = L_BRACK; + >> + +\] + << + NLA = R_BRACK; + >> + +\* + << + NLA = ZERO_MORE; + >> + +\+ + << + NLA = ONE_MORE; + >> + +\| + << + NLA = OR; + >> + +\- + << + NLA = RANGE; + >> + +\~ + << + NLA = NOT; + >> + +\\0[0-7]* + << + NLA = OCTAL_VALUE; + {int t; sscanf(&zzlextext[1],"%o",&t); zzlextext[0] = t;} + >> + +\\0[Xx][0-9a-fA-F]+ + << + NLA = HEX_VALUE; + {int t; sscanf(&zzlextext[3],"%x",&t); zzlextext[0] = t;} + >> + +\\[1-9][0-9]* + << + NLA = DEC_VALUE; + {int t; sscanf(&zzlextext[1],"%d",&t); zzlextext[0] = t;} + >> + +\\t + << + NLA = TAB; + zzlextext[0] = '\t'; + >> + +\\n + << + NLA = NL; + zzlextext[0] = '\n'; + >> + +\\r + << + NLA = CR; + zzlextext[0] = '\r'; + >> + +\\b + << + NLA = BS; + zzlextext[0] = '\b'; + >> + +\\ \n + << + NLA = CONTINUATION; + zzline++; zzskip(); + >> + +\\~[tnrb] + << + NLA = LIT; + zzlextext[0] = zzlextext[1]; + >> + +~[\\] + << + NLA = REGCHAR; + >> + + +%%ACT + +@ + << + NLA = 1; + error("unterminated action", zzline); zzmode(START); + >> + +\>\> + << + NLA = ACTION; + if (func_action) fprintf(OUT,"}\n\n"); + zzmode(START); + /* MR1 */ + /* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ + /* MR1 via <<%%lexmember ...>> */ + /* MR1 This is a consequence of not saving actions */ + /* MR1 */ + /* MR1 */ parserClass=0; + /* MR1 */ lexPrefix=0; + /* MR1 */ lexAction=0; + /* MR1 */ lexMember=0; + >> + +\> + << + NLA = 34; + xxputc(zzlextext[0]); zzskip(); + >> + +\\\> + << + NLA = 35; + xxputc('>'); zzskip(); + >> + +\\ + << + NLA = 36; + xxputc('\\'); zzskip(); + >> + +\n + << + NLA = 37; + xxputc(zzlextext[0]); ++zzline; zzskip(); + >> + +/\* + << + NLA = 38; + zzmode(ACTION_COMMENTS); /* MR1 */ + xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ + >> + +// + << + NLA = 39; + zzmode(ACTION_CPP_COMMENTS); /* MR1 */ + xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ + >> + +~[] + << + NLA = 40; + xxputc(zzlextext[0]); zzskip(); + >> + + +%%ACTION_COMMENTS + +@ + << + NLA = 1; + >> + +\*/ + << + NLA = 41; + zzmode(ACT); /* MR1 */ + xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ + >> + +[\n\r] + << + NLA = 42; + zzline++; xxputc(zzlextext[0]); zzskip(); + >> + +~[] + << + NLA = 43; + xxputc(zzlextext[0]); zzskip(); + >> + + +%%ACTION_CPP_COMMENTS + +@ + << + NLA = 1; + >> + +[\n\r] + << + NLA = 44; + zzmode(ACT); zzline++; /* MR1 */ + xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ + >> + +~[] + << + NLA = 45; + xxputc(zzlextext[0]); zzskip(); + >> + +%% diff --git a/Tools/CodeTools/Source/Pccts/dlg/relabel.c b/Tools/CodeTools/Source/Pccts/dlg/relabel.c new file mode 100644 index 0000000000..0b8bc163d1 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/dlg/relabel.c @@ -0,0 +1,217 @@ +/* This group of functions does the character class compression. + It goes over the dfa and relabels the arcs with the partitions + of characters in the NFA. The partitions are stored in the + array class. + + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * DLG 1.33 + * Will Cohen + * With mods by Terence Parr; AHPCRC, University of Minnesota + * 1989-2001 + */ + +#include +#include "dlg.h" +#ifdef MEMCHK +#include "trax.h" +#else +#ifdef __STDC__ +#include +#else +#include +#endif /* __STDC__ */ +#endif + +int class_no = CHAR_RANGE; /* number of classes for labels */ +int first_el[CHAR_RANGE]; /* first element in each class partition */ +set class_sets[CHAR_RANGE]; /* array holds partitions from class */ + /* compression */ + +/* goes through labels on NFA graph and partitions the characters into + * character classes. This reduces the amount of space required for each + * dfa node, since only one arc is required each class instead of one arc + * for each character + * level: + * 0 no compression done + * 1 remove unused characters from classes + * 2 compress equivalent characters into same class + * + * returns the number of character classes required + */ +#ifdef __USE_PROTOS +int relabel(nfa_node* start,int level) +#else +int relabel(start,level) +int level; +nfa_node *start; +#endif +{ + if (level){ + set_free(used_classes); + partition(start,level); + label_with_classes(start); + }else{ + /* classes equivalent to all characters in alphabet */ + class_no = CHAR_RANGE; + } + return class_no; +} + +/* makes character class sets for new labels */ +#ifdef __USE_PROTOS +void partition(nfa_node* start,int level) +#else +void partition(start,level) +nfa_node *start; /* beginning of nfa graph */ +int level; /* compression level to uses */ +#endif +{ + set current_class; + set unpart_chars; + set temp; + + unpart_chars = set_dup(used_chars); +#if 0 + /* EOF (-1+1) alway in class 0 */ + class_sets[0] = set_of(0); + first_el[0] = 0; + used_classes = set_of(0); + temp = set_dif(unpart_chars, class_sets[0]); + set_free(unpart_chars); + unpart_chars = temp; + class_no = 1; +#else + class_no = 0; +#endif + while (!set_nil(unpart_chars)){ + /* don't look for equivalent labels if c <= 1 */ + if (level <= 1){ + current_class = set_of(set_int(unpart_chars)); + }else{ + current_class = set_dup(unpart_chars); + intersect_nfa_labels(start,¤t_class); + } + set_orel(class_no,&used_classes); + first_el[class_no] = set_int(current_class); + class_sets[class_no] = current_class; + temp = set_dif(unpart_chars,current_class); + set_free(unpart_chars); + unpart_chars = temp; + ++class_no; + } + + /* free unpart_chars -ATG 5/6/95 */ + set_free(unpart_chars); + +#if 0 + /* group all the other unused characters into a class */ + set_orel(class_no,&used_classes); + first_el[class_no] = set_int(current_class); + class_sets[class_no] = set_dif(normal_chars,used_chars); + ++class_no; +#endif +} + + +/* given pointer to beginning of graph and recursively walks it trying + * to find a maximal partition. This partion in returned in maximal_class + */ +#ifdef __USE_PROTOS +void intersect_nfa_labels(nfa_node* start,set* maximal_class) +#else +void intersect_nfa_labels(start,maximal_class) +nfa_node *start; +set *maximal_class; +#endif +{ + /* pick a new operation number */ + ++operation_no; + r_intersect(start,maximal_class); +} + +#ifdef __USE_PROTOS +void r_intersect(nfa_node* start,set* maximal_class) +#else +void r_intersect(start,maximal_class) +nfa_node *start; +set * maximal_class; +#endif +{ + set temp; + + if(start && start->nfa_set != operation_no) + { + start->nfa_set = operation_no; + temp = set_and(*maximal_class,start->label); + if (!set_nil(temp)) + { + set_free(*maximal_class); + *maximal_class = temp; + }else{ + set_free(temp); + } + r_intersect(start->trans[0],maximal_class); + r_intersect(start->trans[1],maximal_class); + } +} + + +/* puts class labels in place of old character labels */ +#ifdef __USE_PROTOS +void label_with_classes(nfa_node* start) +#else +void label_with_classes(start) +nfa_node *start; +#endif +{ + ++operation_no; + label_node(start); +} + +#ifdef __USE_PROTOS +void label_node(nfa_node *start) +#else +void label_node(start) +nfa_node *start; +#endif +{ + set new_label; + register int i; + + /* only do node if it hasn't been done before */ + if (start && start->nfa_set != operation_no){ + start->nfa_set = operation_no; + new_label = empty; + for (i = 0; ilabel)) + set_orel(i,&new_label); + } + set_free(start->label); + start->label = new_label; + /* do any nodes that can be reached from this one */ + label_node(start->trans[0]); + label_node(start->trans[1]); + } +} diff --git a/Tools/CodeTools/Source/Pccts/dlg/stdpccts.h b/Tools/CodeTools/Source/Pccts/dlg/stdpccts.h new file mode 100644 index 0000000000..06ec67e44d --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/dlg/stdpccts.h @@ -0,0 +1,26 @@ +#ifndef STDPCCTS_H +#define STDPCCTS_H +/* + * stdpccts.h -- P C C T S I n c l u d e + * + * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001 + * Purdue University Electrical Engineering + * With AHPCRC, University of Minnesota + * ANTLR Version 1.33MR33 + */ + +#ifndef ANTLR_VERSION +#define ANTLR_VERSION 13333 +#endif + +#include "pcctscfg.h" +#include "pccts_stdio.h" + +#include +#include "dlg.h" +#define zzSET_SIZE 8 +#include "antlr.h" +#include "tokens.h" +#include "dlgdef.h" +#include "mode.h" +#endif diff --git a/Tools/CodeTools/Source/Pccts/dlg/support.c b/Tools/CodeTools/Source/Pccts/dlg/support.c new file mode 100644 index 0000000000..84fe99d69c --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/dlg/support.c @@ -0,0 +1,240 @@ +/* + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * DLG 1.33 + * Will Cohen + * With mods by Terence Parr; AHPCRC, University of Minnesota + * 1989-2001 + */ + +#include +#include +#include "dlg.h" +#ifdef MEMCHK +#include "trax.h" +#else +#ifdef __STDC__ +#include +#else +#include +#endif /* __STDC__ */ +#endif + +int err_found = 0; /* indicates whether problem found */ + +#ifdef __USE_PROTOS +void internal_error(char *s, char *file,int line) /* MR9 23-Sep-97 */ +#else +void internal_error(s,file,line) /* MR9 23-Sep-97 */ +char *s,*file; +int line; +#endif +{ + fprintf(stderr,s,file,line); + exit(PCCTS_EXIT_FAILURE); +} + +#ifdef __USE_PROTOS +char *dlg_malloc(int bytes,char *file,int line) +#else +char *dlg_malloc(bytes,file,line) +int bytes; +char *file; +int line; +#endif +{ + char *t; + + t = (char *) malloc(bytes); + if (!t){ + /* error */ + internal_error("%s(%d): unable to allocate memory\n", + file,line); + } + return t; +} + + +#ifdef __USE_PROTOS +char *dlg_calloc(int n,int bytes,char *file,int line) +#else +char *dlg_calloc(n,bytes,file,line) +int n,bytes; +char *file; +int line; +#endif +{ + char *t; + + t = (char *) calloc(n,bytes); + if (!t){ + /* error */ + internal_error("%s(%d): unable to allocate memory\n", + file,line); + } + return t; +} + + +#ifdef __USE_PROTOS +FILE *read_stream(char *name) +#else +FILE *read_stream(name) +char *name; +#endif +{ + FILE *f; + + if (name){ + if (name[0] == '-') { + fprintf(stderr, "dlg: invalid option: '%s'\n", name); + f = NULL; + }else{ + f = fopen(name, "r"); + if (f == NULL){ + /* couldn't open file */ + fprintf(stderr, + "dlg: Warning: Can't read file %s.\n", + name); + } + } + }else{ + /* open stdin if nothing there */ + f = stdin; + } + return f; +} + +#ifdef __USE_PROTOS +FILE *write_stream(char *name) +#else +FILE *write_stream(name) +char *name; +#endif +{ + FILE *f; + + if (name){ + if (name[0] == '-') { + fprintf(stderr, "dlg: invalid option: '%s'\n", name); + f = NULL; + }else{ + f = fopen(OutMetaName(name), "w"); + if (f == NULL){ + /* couldn't open file */ + fprintf(stderr, + "dlg: Warning: Can't write to file %s.\n", + name); + } + else +#ifdef SPECIAL_FOPEN + special_fopen_actions(OutMetaName(name)); /* MR1 */ +#else + ; /* MR1 */ +#endif + } + }else{ + /* open stdout if nothing there */ + f = stdout; + } + return f; +} + + +#ifdef __USE_PROTOS +void fatal(char *message,int line_no) +#else +void fatal(message,line_no) +char *message; +int line_no; +#endif +{ + fprintf(stderr,ErrHdr, + (file_str[0] ? file_str[0] : "stdin"), line_no); + fprintf(stderr, " Fatal: %s\n", message); + exit(PCCTS_EXIT_FAILURE); +} + +#ifdef __USE_PROTOS +void error(char *message,int line_no) +#else +void error(message,line_no) +char *message; +int line_no; +#endif +{ + fprintf(stderr,ErrHdr, + (file_str[0] ? file_str[0] : "stdin"), line_no); + fprintf(stderr, " Error: %s\n", message); + err_found = 1; +} + +#ifdef __USE_PROTOS +void warning(char *message,int line_no) +#else +void warning(message,line_no) +char *message; +int line_no; +#endif +{ + fprintf(stderr,ErrHdr, + (file_str[0] ? file_str[0] : "stdin"), line_no); + fprintf(stderr, " Warning: %s\n", message); +} + +/* MR10: Jeff Vincent + MR10: Changed to remove directory information from n only if + MR10: if OutputDirectory was changed by user (-o option) +*/ + +#ifdef __USE_PROTOS +char *OutMetaName(char *n) +#else +char *OutMetaName(n) +char *n; +#endif +{ + static char *dir_sym = DirectorySymbol; + static char newname[MaxFileName+1]; + char *p; + + /* If OutputDirectory is same as TopDirectory (platform default) then leave n alone. */ + if (strcmp(OutputDirectory, TopDirectory) == 0) + return n; + + /* p will point to filename without path information */ + if ((p = strrchr(n, *dir_sym)) != NULL) + p++; + else + p = n; + + /* Copy new output directory into newname[] */ + strcpy(newname, OutputDirectory); + + /* if new output directory does not have trailing dir_sym, add it! */ + if (newname[strlen(newname)-1] != *dir_sym) + strcat(newname, dir_sym); + + /* contatenate FILE NAME ONLY to new output directory */ + strcat(newname, p); + + return newname; +} diff --git a/Tools/CodeTools/Source/Pccts/dlg/tokens.h b/Tools/CodeTools/Source/Pccts/dlg/tokens.h new file mode 100644 index 0000000000..73e502b7e1 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/dlg/tokens.h @@ -0,0 +1,133 @@ +#ifndef tokens_h +#define tokens_h +/* tokens.h -- List of labelled tokens and stuff + * + * Generated from: dlg_p.g + * + * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001 + * Purdue University Electrical Engineering + * ANTLR Version 1.33MR33 + */ +#define zzEOF_TOKEN 1 +#define L_EOF 4 +#define PER_PER 5 +#define NAME_PER_PER 6 +#define LEXMEMBER 7 +#define LEXACTION 8 +#define PARSERCLASS 9 +#define LEXPREFIX 10 +#define ACTION 11 +#define GREAT_GREAT 12 +#define L_BRACE 13 +#define R_BRACE 14 +#define L_PAR 15 +#define R_PAR 16 +#define L_BRACK 17 +#define R_BRACK 18 +#define ZERO_MORE 19 +#define ONE_MORE 20 +#define OR 21 +#define RANGE 22 +#define NOT 23 +#define OCTAL_VALUE 24 +#define HEX_VALUE 25 +#define DEC_VALUE 26 +#define TAB 27 +#define NL 28 +#define CR 29 +#define BS 30 +#define CONTINUATION 31 +#define LIT 32 +#define REGCHAR 33 + +#ifdef __USE_PROTOS +void grammar(void); +#else +extern void grammar(); +#endif + +#ifdef __USE_PROTOS +void start_states(void); +#else +extern void start_states(); +#endif + +#ifdef __USE_PROTOS +void do_conversion(void); +#else +extern void do_conversion(); +#endif + +#ifdef __USE_PROTOS +void rule_list(void); +#else +extern void rule_list(); +#endif + +#ifdef __USE_PROTOS +void rule(void); +#else +extern void rule(); +#endif + +#ifdef __USE_PROTOS +void reg_expr(void); +#else +extern void reg_expr(); +#endif + +#ifdef __USE_PROTOS +void and_expr(void); +#else +extern void and_expr(); +#endif + +#ifdef __USE_PROTOS +void repeat_expr(void); +#else +extern void repeat_expr(); +#endif + +#ifdef __USE_PROTOS +void expr(void); +#else +extern void expr(); +#endif + +#ifdef __USE_PROTOS +void atom_list(void); +#else +extern void atom_list(); +#endif + +#ifdef __USE_PROTOS +void near_atom(void); +#else +extern void near_atom(); +#endif + +#ifdef __USE_PROTOS +void atom(void); +#else +extern void atom(); +#endif + +#ifdef __USE_PROTOS +void anychar(void); +#else +extern void anychar(); +#endif + +#endif +extern SetWordType zzerr1[]; +extern SetWordType zzerr2[]; +extern SetWordType zzerr3[]; +extern SetWordType setwd1[]; +extern SetWordType zzerr4[]; +extern SetWordType zzerr5[]; +extern SetWordType zzerr6[]; +extern SetWordType setwd2[]; +extern SetWordType zzerr7[]; +extern SetWordType zzerr8[]; +extern SetWordType zzerr9[]; +extern SetWordType setwd3[]; diff --git a/Tools/CodeTools/Source/Pccts/h/AParser.cpp b/Tools/CodeTools/Source/Pccts/h/AParser.cpp new file mode 100644 index 0000000000..720fe75af1 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/AParser.cpp @@ -0,0 +1,871 @@ +/* ANTLRParser.C + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +#include "pcctscfg.h" + +#include "pccts_stdlib.h" +#include "pccts_stdarg.h" +#include "pccts_string.h" +#include "pccts_stdio.h" + +PCCTS_NAMESPACE_STD + +/* I have to put this here due to C++ limitation + * that you can't have a 'forward' decl for enums. + * I hate C++!!!!!!!!!!!!!!! + * Of course, if I could use real templates, this would go away. + */ +// MR1 +// MR1 10-Apr-97 133MR1 Prevent use of varying sizes for the +// MR1 ANTLRTokenType enum +// MR1 + +enum ANTLRTokenType { TER_HATES_CPP=0, ITS_TOO_COMPLICATED=9999}; // MR1 + +#define ANTLR_SUPPORT_CODE + +#include ATOKEN_H +#include ATOKENBUFFER_H +#include APARSER_H + +static const int zzINF_DEF_TOKEN_BUFFER_SIZE = 2000; /* MR14 */ +static const int zzINF_BUFFER_TOKEN_CHUNK_SIZE = 1000; /* MR14 */ + + /* L o o k a h e a d M a c r o s */ + +/* maximum of 32 bits/unsigned int and must be 8 bits/byte; + * we only use 8 bits of it. + */ +SetWordType ANTLRParser::bitmask[sizeof(SetWordType)*8] = { + 0x00000001, 0x00000002, 0x00000004, 0x00000008, + 0x00000010, 0x00000020, 0x00000040, 0x00000080 +}; + +char ANTLRParser::eMsgBuffer[500] = ""; + +ANTLRParser:: +~ANTLRParser() +{ + delete [] token_type; + delete [] zzFAILtext; // MR16 Manfred Kogler +} + +ANTLRParser:: +ANTLRParser(ANTLRTokenBuffer *_inputTokens, + int k, + int use_inf_look, + int dlook, + int ssize) +{ + LLk = k; + can_use_inf_look = use_inf_look; +/* MR14 */ if (dlook != 0) { +/* MR14 */ panic("ANTLRParser::ANTLRParser - Demand lookahead not supported in C++ mode"); +/* MR14 */ +/* MR14 */ }; + demand_look = 0; /* demand_look = dlook; */ + bsetsize = ssize; + guessing = 0; + token_tbl = NULL; + eofToken = (ANTLRTokenType)1; + + // allocate lookahead buffer + token_type = new ANTLRTokenType[LLk]; + lap = 0; + labase = 0; +#ifdef ZZDEFER_FETCH + stillToFetch = 0; // MR19 +#endif + dirty = 0; + inf_labase = 0; // MR7 + inf_last = 0; // MR7 + /* prime lookahead buffer, point to inputTokens */ + this->inputTokens = _inputTokens; + this->inputTokens->setMinTokens(k); + _inputTokens->setParser(this); // MR1 + resynchConsumed=1; // MR8 + zzFAILtext=NULL; // MR9 + traceOptionValueDefault=0; // MR10 + traceReset(); // MR10 + zzGuessSeq=0; // MR10 + syntaxErrCount=0; // MR11 +} + +void ANTLRParser::init() +{ + prime_lookahead(); + resynchConsumed=1; // MR8 + traceReset(); // MR10 +} + +void ANTLRParser::traceReset() +{ + traceOptionValue=traceOptionValueDefault; + traceGuessOptionValue=1; + traceCurrentRuleName=NULL; + traceDepth=0; +} + + +#ifdef _MSC_VER // MR23 +//Turn off warning: +//interaction between '_setjmp' and C++ object destruction is non-portable +#pragma warning(disable : 4611) +#endif +int ANTLRParser:: +guess(ANTLRParserState *st) +{ + saveState(st); + guessing = 1; + return setjmp(guess_start.state); +} +#ifdef _MSC_VER // MR23 +#pragma warning(default: 4611) +#endif + +void ANTLRParser:: +saveState(ANTLRParserState *buf) +{ + buf->guess_start = guess_start; + buf->guessing = guessing; + buf->inf_labase = inf_labase; + buf->inf_last = inf_last; + buf->dirty = dirty; + buf->traceOptionValue=traceOptionValue; /* MR10 */ + buf->traceGuessOptionValue=traceGuessOptionValue; /* MR10 */ + buf->traceCurrentRuleName=traceCurrentRuleName; /* MR10 */ + buf->traceDepth=traceDepth; /* MR10 */ +} + +void ANTLRParser:: +restoreState(ANTLRParserState *buf) +{ + int i; + int prevTraceOptionValue; + + guess_start = buf->guess_start; + guessing = buf->guessing; + inf_labase = buf->inf_labase; + inf_last = buf->inf_last; + dirty = buf->dirty; + + // restore lookahead buffer from k tokens before restored TokenBuffer position + // if demand_look, then I guess we don't look backwards for these tokens. + for (i=1; i<=LLk; i++) token_type[i-1] = + inputTokens->bufferedToken(i-LLk)->getType(); + lap = 0; + labase = 0; + + /* MR10 */ + + prevTraceOptionValue=traceOptionValue; + traceOptionValue=buf->traceOptionValue; + if ( (prevTraceOptionValue > 0) != + (traceOptionValue > 0)) { + if (traceCurrentRuleName != NULL) { /* MR21 */ + if (traceOptionValue > 0) { + /* MR23 */ printMessage(stderr, + "trace enable restored in rule %s depth %d\n", + traceCurrentRuleName, + traceDepth); + }; + if (traceOptionValue <= 0) { + /* MR23 */ printMessage(stderr, + "trace disable restored in rule %s depth %d\n", + traceCurrentRuleName, /* MR21 */ + traceDepth); + }; + } + }; + traceGuessOptionValue=buf->traceGuessOptionValue; + traceCurrentRuleName=buf->traceCurrentRuleName; + traceDepth=buf->traceDepth; + traceGuessDone(buf); +} + +/* Get the next symbol from the input stream; put it into lookahead buffer; + * fill token_type[] fast reference cache also. NLA is the next place where + * a lookahead ANTLRAbstractToken should go. + */ +void ANTLRParser:: +consume() +{ + +#ifdef ZZDEBUG_CONSUME_ACTION + zzdebug_consume_action(); +#endif + +// MR19 V.H. Simonis +// Defer Fetch feature +// Moves action of consume() into LA() function + +#ifdef ZZDEFER_FETCH + stillToFetch++; +#else + NLA = inputTokens->getToken()->getType(); + dirty--; + lap = (lap+1)&(LLk-1); +#endif + +} + +_ANTLRTokenPtr ANTLRParser:: +LT(int i) +{ + +// MR19 V.H. Simonis +// Defer Fetch feature +// Moves action of consume() into LA() function + +#ifdef ZZDEFER_FETCH + undeferFetch(); +#endif + +#ifdef DEBUG_TOKENBUFFER + if ( i >= inputTokens->bufferSize() || inputTokens->minTokens() < LLk ) /* MR20 Was "<=" */ + { + char buf[2000]; /* MR20 Was "static" */ + sprintf(buf, "The minimum number of tokens you requested that the\nANTLRTokenBuffer buffer is not enough to satisfy your\nLT(%d) request; increase 'k' argument to constructor for ANTLRTokenBuffer\n", i); + panic(buf); + } +#endif + return inputTokens->bufferedToken(i-LLk); +} + +void +ANTLRParser:: +look(int k) +{ + int i, c = k - (LLk-dirty); + for (i=1; i<=c; i++) consume(); +} + +/* fill the lookahead buffer up with k symbols (even if DEMAND_LOOK); + */ +void +ANTLRParser:: +prime_lookahead() +{ + int i; + for(i=1;i<=LLk; i++) consume(); + dirty=0; + // lap = 0; // MR14 Sinan Karasu (sinan.karasu@boeing.com) + // labase = 0; // MR14 + labase=lap; // MR14 +} + +/* check to see if the current input symbol matches '_t'. + * During NON demand lookahead mode, dirty will always be 0 and + * hence the extra code for consuming tokens in _match is never + * executed; the same routine can be used for both modes. + */ +int ANTLRParser:: +_match(ANTLRTokenType _t, ANTLRChar **MissText, + ANTLRTokenType *MissTok, _ANTLRTokenPtr *BadTok, + SetWordType **MissSet) +{ + if ( dirty==LLk ) { + consume(); + } + if ( LA(1)!=_t ) { + *MissText=NULL; + *MissTok= _t; + *BadTok = LT(1); + *MissSet=NULL; + return 0; + } + dirty++; + labase = (labase+1)&(LLk-1); // labase maintained even if !demand look + return 1; +} + +/* check to see if the current input symbol matches '_t'. + * Used during exception handling. + */ +int ANTLRParser:: +_match_wsig(ANTLRTokenType _t) +{ + if ( dirty==LLk ) { + consume(); + } + if ( LA(1)!=_t ) return 0; + dirty++; + labase = (labase+1)&(LLk-1); // labase maintained even if !demand look + return 1; +} + +/* check to see if the current input symbol matches any token in a set. + * During NON demand lookahead mode, dirty will always be 0 and + * hence the extra code for consuming tokens in _match is never + * executed; the same routine can be used for both modes. + */ +int ANTLRParser:: +_setmatch(SetWordType *tset, ANTLRChar **MissText, + ANTLRTokenType *MissTok, _ANTLRTokenPtr *BadTok, + SetWordType **MissSet, SetWordType *tokclassErrset) +{ + if ( dirty==LLk ) { + consume(); + } + if ( !set_el(LA(1), tset) ) { + *MissText=NULL; /* MR23 */ + *MissTok=(ANTLRTokenType) 0; /* MR23 */ + *BadTok=LT(1); /* MR23 */ + *MissSet=tokclassErrset; /* MR23 */ + return 0; + } + dirty++; + labase = (labase+1)&(LLk-1); // labase maintained even if !demand look + return 1; +} + +int ANTLRParser:: +_setmatch_wsig(SetWordType *tset) +{ + if ( dirty==LLk ) { + consume(); + } + if ( !set_el(LA(1), tset) ) return 0; + dirty++; + labase = (labase+1)&(LLk-1); // labase maintained even if !demand look + return 1; +} + + /* Exception handling routines */ +// +// 7-Apr-97 133MR1 +// Change suggested by Eli Sternheim (eli@interhdl.com) +// +void ANTLRParser:: +consumeUntil(SetWordType *st) +{ + ANTLRTokenType tmp; // MR1 + const int Eof=1; // MR1 + while ( !set_el( (tmp=LA(1)), st) && tmp!=Eof) { consume(); } // MR1 +} + +// +// 7-Apr-97 133MR1 +// Change suggested by Eli Sternheim (eli@interhdl.com) +// +void ANTLRParser:: +consumeUntilToken(int t) +{ + int tmp; // MR1 + const int Eof=1; // MR1 + while ( (tmp=LA(1)) !=t && tmp!=Eof) { consume(); } // MR1 +} + + + /* Old error stuff */ + +void ANTLRParser:: +resynch(SetWordType *wd,SetWordType mask) +{ + +/* MR8 S.Bochnak@microtool.com.pl */ +/* MR8 Change file scope static "consumed" to instance var */ + + /* if you enter here without having consumed a token from last resynch + * force a token consumption. + */ +/* MR8 */ if ( !resynchConsumed ) {consume(); resynchConsumed=1; return;} + + /* if current token is in resynch set, we've got what we wanted */ + +/* MR8 */ if ( wd[LA(1)]&mask || LA(1) == eofToken ) {resynchConsumed=0; return;} + + /* scan until we find something in the resynch set */ + + while ( !(wd[LA(1)]&mask) && LA(1) != eofToken ) {consume();} + +/* MR8 */ resynchConsumed=1; +} + +/* standard error reporting function that assumes DLG-based scanners; + * you should redefine in subclass to change it or if you use your + * own scanner. + */ + +/* MR23 THM There appears to be a parameter "badText" passed to syn() + which is not present in the parameter list. This may be + because in C mode there is no attribute function which + returns the text, so the text representation of the token + must be passed explicitly. I think. +*/ + +void ANTLRParser:: +syn(_ANTLRTokenPtr /*tok MR23*/, ANTLRChar *egroup, SetWordType *eset, + ANTLRTokenType etok, int k) +{ + int line; + + line = LT(1)->getLine(); + + syntaxErrCount++; /* MR11 */ + + /* MR23 If the token is not an EOF token, then use the ->getText() value. + + If the token is the EOF token the text returned by ->getText() + may be garbage. If the text from the token table is "@" use + "" instead, because end-users don't know what "@" means. + If the text is not "@" then use that text, which must have been + supplied by the grammar writer. + */ + const char * errorAt = LT(1)->getText(); + if (LA(1) == eofToken) { + errorAt = parserTokenName(LA(1)); + if (errorAt[0] == '@') errorAt = ""; + } + /* MR23 */ printMessage(stderr, "line %d: syntax error at \"%s\"", + line, errorAt); + if ( !etok && !eset ) {/* MR23 */ printMessage(stderr, "\n"); return;} + if ( k==1 ) /* MR23 */ printMessage(stderr, " missing"); + else + { + /* MR23 */ printMessage(stderr, "; \"%s\" not", LT(k)->getText()); // MR23 use LT(k) since k>1 + if ( set_deg(eset)>1 ) /* MR23 */ printMessage(stderr, " in"); + } + if ( set_deg(eset)>0 ) edecode(eset); + else /* MR23 */ printMessage(stderr, " %s", token_tbl[etok]); + if ( strlen(egroup) > 0 ) /* MR23 */ printMessage(stderr, " in %s", egroup); + /* MR23 */ printMessage(stderr, "\n"); +} + +/* is b an element of set p? */ +int ANTLRParser:: +set_el(ANTLRTokenType b, SetWordType *p) +{ + return( p[DIVWORD(b)] & bitmask[MODWORD(b)] ); +} + +int ANTLRParser:: +set_deg(SetWordType *a) +{ + /* Fast compute degree of a set... the number + of elements present in the set. Assumes + that all word bits are used in the set + */ + register SetWordType *p = a; + register SetWordType *endp = &(a[bsetsize]); + register int degree = 0; + + if ( a == NULL ) return 0; + while ( p < endp ) + { + register SetWordType t = *p; + register SetWordType *b = &(bitmask[0]); + do { + if (t & *b) ++degree; + } while (++b < &(bitmask[sizeof(SetWordType)*8])); + p++; + } + + return(degree); +} + +void ANTLRParser:: +edecode(SetWordType *a) +{ + register SetWordType *p = a; + register SetWordType *endp = &(p[bsetsize]); + register unsigned e = 0; + + if ( set_deg(a)>1 ) /* MR23 */ printMessage(stderr, " {"); + do { + register SetWordType t = *p; + register SetWordType *b = &(bitmask[0]); + do { + if ( t & *b ) /* MR23 */ printMessage(stderr, " %s", token_tbl[e]); + e++; + } while (++b < &(bitmask[sizeof(SetWordType)*8])); + } while (++p < endp); + if ( set_deg(a)>1 ) /* MR23 */ printMessage(stderr, " }"); +} + +/* input looks like: + * zzFAIL(k, e1, e2, ...,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk) + * where the zzMiss stuff is set here to the token that did not match + * (and which set wasn't it a member of). + */ + +// MR9 29-Sep-97 Stan Bochnak (S.Bochnak@microTool.com.pl) +// MR9 Original fix to static allocated text didn't +// MR9 work because a pointer to it was passed back +// MR9 to caller. Replace with instance variable. + +const int SETWORDCOUNT=20; + +void +ANTLRParser::FAIL(int k, ...) +{ +// +// MR1 10-Apr-97 +// + + if (zzFAILtext == NULL) zzFAILtext=new char [1000]; // MR9 + SetWordType **f=new SetWordType *[SETWORDCOUNT]; // MR1 // MR9 + SetWordType **miss_set; + ANTLRChar **miss_text; + _ANTLRTokenPtr *bad_tok; + ANTLRChar **bad_text; +// +// 7-Apr-97 133MR1 +// err_k is passed as a "int *", not "unsigned *" +// + int *err_k; // MR1 + int i; + va_list ap; + + va_start(ap, k); + + zzFAILtext[0] = '\0'; + if ( k > SETWORDCOUNT ) panic("FAIL: overflowed buffer"); + for (i=1; i<=k; i++) /* collect all lookahead sets */ + { + f[i-1] = va_arg(ap, SetWordType *); + } + for (i=1; i<=k; i++) /* look for offending token */ + { + if ( i>1 ) strcat(zzFAILtext, " "); + strcat(zzFAILtext, LT(i)->getText()); + if ( !set_el(LA(i), f[i-1]) ) break; + } + miss_set = va_arg(ap, SetWordType **); + miss_text = va_arg(ap, ANTLRChar **); + bad_tok = va_arg(ap, _ANTLRTokenPtr *); + bad_text = va_arg(ap, ANTLRChar **); + err_k = va_arg(ap, int *); // MR1 + if ( i>k ) + { + /* bad; lookahead is permutation that cannot be matched, + * but, the ith token of lookahead is valid at the ith position + * (The old LL sub 1 (k) versus LL(k) parsing technique) + */ + *miss_set = NULL; + *miss_text = LT(1)->getText(); + *bad_tok = LT(1); + *bad_text = (*bad_tok)->getText(); + *err_k = k; +// +// MR4 20-May-97 erroneously deleted contents of f[] +// MR4 reported by Bruce Guenter (bruceg@qcc.sk.ca) +// MR1 10-Apr-97 release temporary storage +// + delete [] f; // MR1 + return; // MR1 + } +/* MR23 printMessage(stderr, "%s not in %dth set\n", zztokens[LA(i)], i);*/ + *miss_set = f[i-1]; + *miss_text = zzFAILtext; + *bad_tok = LT(i); + *bad_text = (*bad_tok)->getText(); + if ( i==1 ) *err_k = 1; + else *err_k = k; +// +// MR4 20-May-97 erroneously deleted contents of f[] +// MR4 reported by Bruce Guenter (bruceg@qcc.sk.ca) +// MR1 10-Apr-97 release temporary storage +// + delete [] f; // MR1 + return; // MR1 +} + +int ANTLRParser:: +_match_wdfltsig(ANTLRTokenType tokenWanted, SetWordType *whatFollows) +{ + if ( dirty==LLk ) consume(); + + if ( LA(1)!=tokenWanted ) + { + syntaxErrCount++; /* MR11 */ + /* MR23 */ printMessage(stderr, + "line %d: syntax error at \"%s\" missing %s\n", + LT(1)->getLine(), + (LA(1)==eofToken && LT(1)->getText()[0] == '@')?"":LT(1)->getText(), /* MR21a */ + token_tbl[tokenWanted]); + consumeUntil( whatFollows ); + return 0; + } + else { + dirty++; + labase = (labase+1)&(LLk-1); // labase maintained even if !demand look +/* if ( !demand_look ) consume(); */ + return 1; + } +} + + +int ANTLRParser:: +_setmatch_wdfltsig(SetWordType *tokensWanted, + ANTLRTokenType tokenTypeOfSet, + SetWordType *whatFollows) +{ + if ( dirty==LLk ) consume(); + if ( !set_el(LA(1), tokensWanted) ) + { + syntaxErrCount++; /* MR11 */ + /* MR23 */ printMessage(stderr, + "line %d: syntax error at \"%s\" missing %s\n", + LT(1)->getLine(), + (LA(1)==eofToken && LT(1)->getText()[0] == '@')?"":LT(1)->getText(), /* MR21a */ + token_tbl[tokenTypeOfSet]); + consumeUntil( whatFollows ); + return 0; + } + else { + dirty++; + labase = (labase+1)&(LLk-1); // labase maintained even if !demand look +/* if ( !demand_look ) consume(); */ + return 1; + } +} + +char *ANTLRParser:: +eMsgd(char *err,int d) +{ + sprintf(eMsgBuffer, err, d); // dangerous, but I don't care + return eMsgBuffer; +} + +char *ANTLRParser:: +eMsg(char *err, char *s) +{ + sprintf(eMsgBuffer, err, s); + return eMsgBuffer; +} + +char *ANTLRParser:: +eMsg2(char *err,char *s, char *t) +{ + sprintf(eMsgBuffer, err, s, t); + return eMsgBuffer; +} + +void ANTLRParser:: +panic(const char *msg) // MR20 const +{ + /* MR23 */ printMessage(stderr, "ANTLR panic: %s\n", msg); + exit(PCCTS_EXIT_FAILURE); // MR1 +} + +const ANTLRChar *ANTLRParser:: // MR1 +parserTokenName(int tok) { // MR1 + return token_tbl[tok]; // MR1 +} // MR1 + +void ANTLRParser::traceGuessDone(const ANTLRParserState *state) { + + int doIt=0; + + if (traceCurrentRuleName == NULL) return; + + if (traceOptionValue <= 0) { + doIt=0; + } else if (traceGuessOptionValue <= 0) { + doIt=0; + } else { + doIt=1; + }; + + if (doIt) { + /* MR23 */ printMessage(stderr,"guess done - returning to rule %s {\"%s\"} at depth %d", + state->traceCurrentRuleName, + LT(1)->getType() == eofToken ? "@" : LT(1)->getText(), + state->traceDepth); + if (state->guessing != 0) { + /* MR23 */ printMessage(stderr," (guess mode continues - an enclosing guess is still active)"); + } else { + /* MR23 */ printMessage(stderr," (guess mode ends)"); + }; + /* MR23 */ printMessage(stderr,"\n"); + }; +} + +void ANTLRParser::traceGuessFail() { + + int doIt=0; + + if (traceCurrentRuleName == NULL) return; /* MR21 */ + + if (traceOptionValue <= 0) { + doIt=0; + } else if (guessing && traceGuessOptionValue <= 0) { + doIt=0; + } else { + doIt=1; + }; + + if (doIt) { + /* MR23 */ printMessage(stderr,"guess failed in %s\n",traceCurrentRuleName); + }; +} + +/* traceOption: + zero value turns off trace +*/ + +void ANTLRParser::tracein(const ANTLRChar * rule) { + + int doIt=0; + + traceDepth++; + traceCurrentRuleName=rule; + + if (traceOptionValue <= 0) { + doIt=0; + } else if (guessing && traceGuessOptionValue <= 0) { + doIt=0; + } else { + doIt=1; + }; + + if (doIt) { + /* MR23 */ printMessage(stderr,"enter rule %s {\"%s\"} depth %d", + rule, + LT(1)->getType() == eofToken ? "@" : LT(1)->getText(), + traceDepth); + if (guessing) /* MR23 */ printMessage(stderr," guessing"); + /* MR23 */ printMessage(stderr,"\n"); + }; + return; +} + +void ANTLRParser::traceout(const ANTLRChar * rule) { + + int doIt=0; + + traceDepth--; + + if (traceOptionValue <= 0) { + doIt=0; + } else if (guessing && traceGuessOptionValue <= 0) { + doIt=0; + } else { + doIt=1; + }; + + if (doIt) { + /* MR23 */ printMessage(stderr,"exit rule %s {\"%s\"} depth %d", + rule, + LT(1)->getType() == eofToken ? "@" : LT(1)->getText(), + traceDepth+1); + if (guessing) /* MR23 */ printMessage(stderr," guessing"); + /* MR23 */ printMessage(stderr,"\n"); + }; +} + +int ANTLRParser::traceOption(int delta) { + + int prevValue=traceOptionValue; + + traceOptionValue=traceOptionValue+delta; + + if (traceCurrentRuleName != NULL) { + if (prevValue <= 0 && traceOptionValue > 0) { + /* MR23 */ printMessage(stderr,"trace enabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth); + }; + if (prevValue > 0 && traceOptionValue <= 0) { + /* MR23 */ printMessage(stderr,"trace disabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth); + }; + }; + + return prevValue; +} + +int ANTLRParser::traceGuessOption(int delta) { + + int prevValue=traceGuessOptionValue; + + traceGuessOptionValue=traceGuessOptionValue+delta; + + if (traceCurrentRuleName != NULL) { + if (prevValue <= 0 && traceGuessOptionValue > 0) { + /* MR23 */ printMessage(stderr,"guess trace enabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth); + }; + if (prevValue > 0 && traceGuessOptionValue <= 0) { + /* MR23 */ printMessage(stderr,"guess trace disabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth); + }; + }; + return prevValue; +} + +// MR19 V.H. Simonis Defer Fetch feature + +void ANTLRParser::undeferFetch() +{ + +#ifdef ZZDEFER_FETCH + if (stillToFetch) { + for (int stillToFetch_x = 0; stillToFetch_x < stillToFetch; ++stillToFetch_x) { + NLA = inputTokens->getToken()->getType(); + dirty--; + lap = (lap+1)&(LLk-1); + } + stillToFetch = 0; + } +#else + return; +#endif + +} + +int ANTLRParser::isDeferFetchEnabled() +{ +#ifdef ZZDEFER_FETCH + return 1; +#else + return 0; +#endif +} + +//MR23 +int ANTLRParser::printMessage(FILE* pFile, const char* pFormat, ...) +{ + va_list marker; + va_start( marker, pFormat ); + int iRet = printMessageV(pFile, pFormat, marker); + va_end( marker ); + return iRet; +} + +int ANTLRParser::printMessageV(FILE* pFile, const char* pFormat, va_list arglist) // MR23 +{ + return vfprintf(pFile, pFormat, arglist); +} + +// MR23 Move semantic predicate error handling from macro to virtual function +// +// Called by the zzfailed_pred + +void ANTLRParser::failedSemanticPredicate(const char* predicate) +{ + printMessage(stdout,"line %d: semantic error; failed predicate: '%s'\n", + LT(1)->getLine(), predicate); +} diff --git a/Tools/CodeTools/Source/Pccts/h/AParser.h b/Tools/CodeTools/Source/Pccts/h/AParser.h new file mode 100644 index 0000000000..fe405f4167 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/AParser.h @@ -0,0 +1,376 @@ +/* ANTLRParser.h + * + * Define the generic ANTLRParser superclass, which is subclassed to + * define an actual parser. + * + * Before entry into this file: ANTLRTokenType must be set. + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +#ifndef APARSER_H_GATE +#define APARSER_H_GATE + +#include "pcctscfg.h" + +#include "pccts_stdio.h" +#include "pccts_setjmp.h" + +PCCTS_NAMESPACE_STD + +#include ATOKEN_H +#include ATOKENBUFFER_H + +#ifdef ZZCAN_GUESS +#ifndef ZZINF_LOOK +#define ZZINF_LOOK +#endif +#endif + + +#define NLA (token_type[lap&(LLk-1)])/* --> next LA */ + +typedef unsigned char SetWordType; + +/* Define external bit set stuff (for SetWordType) */ +#define EXT_WORDSIZE (sizeof(char)*8) +#define EXT_LOGWORDSIZE 3 + + /* s y n t a c t i c p r e d i c a t e s t u f f */ + +#ifndef zzUSER_GUESS_HOOK +#define zzUSER_GUESS_HOOK(seqFrozen,zzrv) +#endif + +#ifndef zzUSER_GUESS_DONE_HOOK +#define zzUSER_GUESS_DONE_HOOK(seqFrozen) +#endif + +/* MR14 Add zzUSER_GUESS_FAIL_HOOK and related code */ + +#define zzUSER_GUESS_FAIL_HOOK_INTERNAL zzUSER_GUESS_FAIL_HOOK(SeqFrozen) +#ifndef zzUSER_GUESS_FAIL_HOOK +#define zzUSER_GUESS_FAIL_HOOK(zzGuessSeq) +#endif + + +typedef struct _zzjmp_buf { + jmp_buf state; + } zzjmp_buf; + +/* these need to be macros not member functions */ +#define zzGUESS_BLOCK ANTLRParserState zzst; int zzrv; int _marker; int zzGuessSeqFrozen; +#define zzNON_GUESS_MODE if ( !guessing ) +#define zzGUESS_FAIL guess_fail(); + +/* Note: zzGUESS_DONE does not execute longjmp() */ + +#define zzGUESS_DONE {zzrv=1; inputTokens->rewind(_marker); guess_done(&zzst);zzUSER_GUESS_DONE_HOOK(zzGuessSeqFrozen) } +#define zzGUESS saveState(&zzst); \ + guessing = 1; \ + zzGuessSeqFrozen = ++zzGuessSeq; \ + _marker = inputTokens->mark(); \ + zzrv = setjmp(guess_start.state); \ + zzUSER_GUESS_HOOK(zzGuessSeqFrozen,zzrv) \ + if ( zzrv ) zzGUESS_DONE + +#define zzTRACEdata const ANTLRChar *zzTracePrevRuleName = NULL; + +#ifndef zzTRACEIN +#define zzTRACEIN(r) zzTracePrevRuleName=traceCurrentRuleName;tracein(r); +#endif +#ifndef zzTRACEOUT +#define zzTRACEOUT(r) traceout(r);traceCurrentRuleName=zzTracePrevRuleName; +#endif + + /* a n t l r p a r s e r d e f */ + +struct ANTLRParserState { + /* class variables */ + zzjmp_buf guess_start; + int guessing; + + int inf_labase; + int inf_last; + + int dirty; + + int traceOptionValue; // MR10 + int traceGuessOptionValue; // MR10 + const ANTLRChar *traceCurrentRuleName; // MR10 + int traceDepth; // MR10 + +}; + +/* notes: + * + * multiple inheritance is a cool way to include what stuff is needed + * in this structure (like guess stuff). however, i'm not convinced that + * multiple inheritance works correctly on all platforms. not that + * much space is used--just include all possibly useful members. + * + * the class should also be a template with arguments for the lookahead + * depth and so on. that way, more than one parser can be defined (as + * each will probably have different lookahead requirements). however, + * am i sure that templates work? no, i'm not sure. + * + * no attributes are maintained and, hence, the 'asp' variable is not + * needed. $i can still be referenced, but it refers to the token + * associated with that rule element. question: where are the token's + * stored if not on the software stack? in local variables created + * and assigned to by antlr. + */ +class ANTLRParser { +protected: + /* class variables */ + static SetWordType bitmask[sizeof(SetWordType)*8]; + static char eMsgBuffer[500]; + +protected: + int LLk; // number of lookahead symbols (old LL_K) + int demand_look; + ANTLRTokenType eofToken; // when do I stop during resynch()s + int bsetsize; // size of bitsets created by ANTLR in + // units of SetWordType + + ANTLRTokenBuffer *inputTokens; //place to get input tokens + + zzjmp_buf guess_start; // where to jump back to upon failure + int guessing; // if guessing (using (...)? predicate) + + // infinite lookahead stuff + int can_use_inf_look; // set by subclass (generated by ANTLR) + int inf_lap; + int inf_labase; + int inf_last; + int *_inf_line; + + const ANTLRChar **token_tbl; // pointer to table of token type strings MR20 const + + int dirty; // used during demand lookahead + + ANTLRTokenType *token_type; // fast reference cache of token.getType() +// ANTLRLightweightToken **token; // the token with all its attributes + int lap; + int labase; +#ifdef ZZDEFER_FETCH + int stillToFetch; // MR19 V.H. Simonis +#endif + +private: + void fill_inf_look(); + +protected: + virtual void guess_fail() { // MR9 27-Sep-97 make virtual + traceGuessFail(); // MR10 + longjmp(guess_start.state, 1); } // MR9 + virtual void guess_done(ANTLRParserState *st) { // MR9 27-Sep-97 make virtual + restoreState(st); } // MR9 + virtual int guess(ANTLRParserState *); // MR9 27-Sep-97 make virtual + void look(int); + int _match(ANTLRTokenType, ANTLRChar **, ANTLRTokenType *, + _ANTLRTokenPtr *, SetWordType **); + int _setmatch(SetWordType *, ANTLRChar **, ANTLRTokenType *, + _ANTLRTokenPtr *, SetWordType **, + SetWordType * tokclassErrset /* MR23 */); + int _match_wsig(ANTLRTokenType); + int _setmatch_wsig(SetWordType *); + virtual void consume(); + virtual void resynch(SetWordType *wd,SetWordType mask); // MR21 + void prime_lookahead(); + virtual void tracein(const ANTLRChar *r); // MR10 + virtual void traceout(const ANTLRChar *r); // MR10 + static unsigned MODWORD(unsigned x) {return x & (EXT_WORDSIZE-1);} // x % EXT_WORDSIZE // MR9 + static unsigned DIVWORD(unsigned x) {return x >> EXT_LOGWORDSIZE;} // x / EXT_WORDSIZE // MR9 + int set_deg(SetWordType *); + int set_el(ANTLRTokenType, SetWordType *); + virtual void edecode(SetWordType *); // MR1 + virtual void FAIL(int k, ...); // MR1 + int traceOptionValue; // MR10 + int traceGuessOptionValue; // MR10 + const ANTLRChar *traceCurrentRuleName; // MR10 + int traceDepth; // MR10 + void traceReset(); // MR10 + virtual void traceGuessFail(); // MR10 + virtual void traceGuessDone(const ANTLRParserState *); // MR10 + int zzGuessSeq; // MR10 + +public: + ANTLRParser(ANTLRTokenBuffer *, + int k=1, + int use_inf_look=0, + int demand_look=0, + int bsetsize=1); + virtual ~ANTLRParser(); + + virtual void init(); + + ANTLRTokenType LA(int i) + { +// +// MR14 demand look will always be 0 for C++ mode +// +//// return demand_look ? token_type[(labase+(i)-1)&(LLk-1)] : +//// token_type[(lap+(i)-1)&(LLk-1)]; + +// MR19 V.H. Simonis Defer fetch feature + +#ifdef ZZDEFER_FETCH + undeferFetch(); +#endif + return token_type[(lap+(i)-1)&(LLk-1)]; + } + _ANTLRTokenPtr LT(int i); + + void setEofToken(ANTLRTokenType t) { eofToken = t; } + ANTLRTokenType getEofToken() const { return eofToken; } // MR14 + + void noGarbageCollectTokens() { inputTokens->noGarbageCollectTokens(); } + void garbageCollectTokens() { inputTokens->garbageCollectTokens(); } + + virtual void syn(_ANTLRTokenPtr tok, ANTLRChar *egroup, + SetWordType *eset, ANTLRTokenType etok, int k); + virtual void saveState(ANTLRParserState *); // MR9 27-Sep-97 make virtual + virtual void restoreState(ANTLRParserState *); // MR9 27-Sep-97 make virtual + + virtual void panic(const char *msg); // MR20 const + + static char *eMsgd(char *,int); + static char *eMsg(char *,char *); + static char *eMsg2(char *,char *,char *); + + virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23 + virtual int printMessageV(FILE* pFile, const char* pFormat, va_list arglist); // MR23 + + void consumeUntil(SetWordType *st); + void consumeUntilToken(int t); + + virtual int _setmatch_wdfltsig(SetWordType *tokensWanted, + ANTLRTokenType tokenTypeOfSet, + SetWordType *whatFollows); + virtual int _match_wdfltsig(ANTLRTokenType tokenWanted, + SetWordType *whatFollows); + + const ANTLRChar * parserTokenName(int tok); // MR1 + + int traceOptionValueDefault; // MR11 + int traceOption(int delta); // MR11 + int traceGuessOption(int delta); // MR11 + +// MR8 5-Aug-97 S.Bochnak@microtool.com.pl +// MR8 Move resynch static local variable +// MR8 to class instance + + int syntaxErrCount; // MR12 + ANTLRTokenStream *getLexer() const { // MR12 + return inputTokens ? inputTokens->getLexer() : 0; } // MR12 +protected: // MR8 + int resynchConsumed; // MR8 + char *zzFAILtext; // workarea required by zzFAIL // MR9 + void undeferFetch(); // MR19 V.H. Simonis + int isDeferFetchEnabled(); // MR19 V.H. Simonis + virtual void failedSemanticPredicate(const char* predicate); /* MR23 */ +}; + +#define zzmatch(_t) \ + if ( !_match((ANTLRTokenType)_t, &zzMissText, &zzMissTok, \ + (_ANTLRTokenPtr *) &zzBadTok, &zzMissSet) ) goto fail; + +#define zzmatch_wsig(_t,handler) \ + if ( !_match_wsig((ANTLRTokenType)_t) ) if ( guessing ) zzGUESS_FAIL else {_signal=MismatchedToken; goto handler;} + +#define zzsetmatch(_ts,_tokclassErrset) \ + if ( !_setmatch(_ts, &zzMissText, &zzMissTok, \ + (_ANTLRTokenPtr *) &zzBadTok, &zzMissSet, _tokclassErrset) ) goto fail; + +#define zzsetmatch_wsig(_ts, handler) \ + if ( !_setmatch_wsig(_ts) ) if ( guessing ) zzGUESS_FAIL else {_signal=MismatchedToken; goto handler;} + +/* For the dflt signal matchers, a FALSE indicates that an error occurred + * just like the other matchers, but in this case, the routine has already + * recovered--we do NOT want to consume another token. However, when + * the match was successful, we do want to consume hence _signal=0 so that + * a token is consumed by the "if (!_signal) consume(); _signal=NoSignal;" + * preamble. + */ +#define zzsetmatch_wdfltsig(tokensWanted, tokenTypeOfSet, whatFollows) \ + if ( !_setmatch_wdfltsig(tokensWanted, tokenTypeOfSet, whatFollows) ) \ + _signal = MismatchedToken; + +#define zzmatch_wdfltsig(tokenWanted, whatFollows) \ + if ( !_match_wdfltsig(tokenWanted, whatFollows) ) _signal = MismatchedToken; + + +// MR1 10-Apr-97 zzfailed_pred() macro does not backtrack in guess mode. +// MR1 Identification and correction due to J. Lilley +// +// MR23 Call virtual method to report error. +// MR23 Provide more control over failed predicate action +// without any need for user to worry about guessing internals. + +#ifndef zzfailed_pred +#define zzfailed_pred(_p,_hasuseraction,_useraction) \ + if (guessing) { \ + zzGUESS_FAIL; \ + } else { \ + zzfailed_pred_action(_p,_hasuseraction,_useraction) \ + } +#endif + +// MR23 Provide more control over failed predicate action +// without any need for user to worry about guessing internals. +// _hasuseraction == 0 => no user specified error action +// _hasuseraction == 1 => user specified error action + +#ifndef zzfailed_pred_action +#define zzfailed_pred_action(_p,_hasuseraction,_useraction) \ + if (_hasuseraction) { _useraction } else { failedSemanticPredicate(_p); } +#endif + +#define zzRULE \ + SetWordType *zzMissSet=NULL; ANTLRTokenType zzMissTok=(ANTLRTokenType)0; \ + _ANTLRTokenPtr zzBadTok=NULL; ANTLRChar *zzBadText=(ANTLRChar *)""; \ + int zzErrk=1,zzpf=0; \ + zzTRACEdata \ + ANTLRChar *zzMissText=(ANTLRChar *)""; + +#endif + + /* S t a n d a r d E x c e p t i o n S i g n a l s */ + +#define NoSignal 0 +#define MismatchedToken 1 +#define NoViableAlt 2 +#define NoSemViableAlt 3 + +/* MR7 Allow more control over signalling */ +/* by adding "Unwind" and "SetSignal" */ + +#define Unwind 4 +#define setSignal(newValue) *_retsignal=_signal=(newValue) +#define suppressSignal *_retsignal=_signal=0 +#define exportSignal *_retsignal=_signal diff --git a/Tools/CodeTools/Source/Pccts/h/ASTBase.cpp b/Tools/CodeTools/Source/Pccts/h/ASTBase.cpp new file mode 100644 index 0000000000..a94f080c86 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/ASTBase.cpp @@ -0,0 +1,256 @@ +/* Abstract syntax tree manipulation functions + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +#include "pcctscfg.h" + +#include "pccts_stdio.h" +#include "pccts_stdarg.h" + +PCCTS_NAMESPACE_STD + +#define ANTLR_SUPPORT_CODE + +#include "ASTBase.h" + +/* ensure that tree manipulation variables are current after a rule + * reference + */ +void +ASTBase::link(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail) +{ + if ( *_sibling == NULL ) return; + if ( *_root == NULL ) *_root = *_sibling; + else if ( *_root != *_sibling ) (*_root)->_down = *_sibling; + if ( *_tail==NULL ) *_tail = *_sibling; + while ( (*_tail)->_right != NULL ) *_tail = (*_tail)->_right; +} + +/* add a child node to the current sibling list */ +void +ASTBase::subchild(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail) +{ + if ( *_tail != NULL ) (*_tail)->_right = this; + else { + *_sibling = this; + if ( *_root != NULL ) (*_root)->_down = *_sibling; + } + *_tail = this; + if ( *_root == NULL ) *_root = *_sibling; +} + +/* make a new AST node. Make the newly-created + * node the root for the current sibling list. If a root node already + * exists, make the newly-created node the root of the current root. + */ +void +ASTBase::subroot(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail) +{ + if ( *_root != NULL ) + if ( (*_root)->_down == *_sibling ) *_sibling = *_tail = *_root; + *_root = this; + (*_root)->_down = *_sibling; +} + +/* Apply preorder_action(), etc.. to root then each sibling */ +// +// 7-Apr-97 133MR1 +// Fix suggested by Ron House (house@helios.usq.edu.au) +// +void +ASTBase::preorder(void* pData /*= NULL*/ /* MR23 */) +{ + ASTBase *tree = this; + + while ( tree!= NULL ) + { + if ( tree->_down != NULL ) { + tree->preorder_before_action(pData); // MR1 + }; + tree->preorder_action(pData); + if ( tree->_down!=NULL ) + { + tree->_down->preorder(pData); + tree->preorder_after_action(pData); // MR1 + } + tree = tree->_right; + } +} + +/* free all AST nodes in tree; apply func to each before freeing */ +void +ASTBase::destroy() +{ + ASTBase* tree = this; + while (tree) { + if (tree->_down) tree->_down->destroy(); + + ASTBase* cur = tree; + tree = tree->_right; + delete cur; + } +} + +/* build a tree (root child1 child2 ... NULL) + * If root is NULL, simply make the children siblings and return ptr + * to 1st sibling (child1). If root is not single node, return NULL. + * + * Siblings that are actually siblins lists themselves are handled + * correctly. For example #( NULL, #( NULL, A, B, C), D) results + * in the tree ( NULL A B C D ). + * + * Requires at least two parameters with the last one being NULL. If + * both are NULL, return NULL. + */ +ASTBase * +ASTBase::tmake(ASTBase *root, ...) +{ + va_list ap; + register ASTBase *child, *sibling=NULL, *tail=NULL /*MR23*/, *w; + + va_start(ap, root); + + if ( root != NULL ) + if ( root->_down != NULL ) { + root->reportOverwriteOfDownPointer(); /* MR21 Report problem which almost always an error */ + return NULL; + } + child = va_arg(ap, ASTBase *); + while ( child != NULL ) + { + for (w=child; w->_right!=NULL; w=w->_right) {;} /* find end of child */ + if ( sibling == NULL ) {sibling = child; tail = w;} + else {tail->_right = child; tail = w;} + child = va_arg(ap, ASTBase *); + } + if ( root==NULL ) root = sibling; + else root->_down = sibling; + va_end(ap); + return root; +} + +#ifndef PCCTS_NOT_USING_SOR + +/* tree duplicate */ +// forgot to check for NULL this (TJP July 23,1995) +ASTBase * +ASTBase::dup() +{ + ASTBase *u, *t=this; + + if ( t == NULL ) return NULL; +/* + u = new ASTBase; + *u = *t; +*/ + u = (ASTBase *)this->shallowCopy(); + if ( t->_right!=NULL ) u->_right = t->_right->dup(); + else u->_right = NULL; + if ( t->_down!=NULL ) u->_down = t->_down->dup(); + else u->_down = NULL; + return u; +} +#endif + +// +// 7-Apr-97 133MR1 +// Fix suggested by Asgeir Olafsson (olafsson@cstar.ac.com) +// +/* tree duplicate */ + +#ifndef PCCTS_NOT_USING_SOR + +ASTBase * +ASTDoublyLinkedBase::dup() +{ + ASTDoublyLinkedBase *u, *t=this; + + if ( t == NULL ) return NULL; + u = (ASTDoublyLinkedBase *)this->shallowCopy(); + u->_up = NULL; /* set by calling invocation */ + u->_left = NULL; + if (t->_right!=NULL) { // MR1 + u->_right=t->_right->dup(); // MR1 + ((ASTDoublyLinkedBase *)u->_right)->_left = u; // MR1 + } else { // MR1 + u->_right = NULL; // MR1 + }; // MR1 + if (t->_down!=NULL) { // MR1 + u->_down = t->_down->dup(); // MR1 + ((ASTDoublyLinkedBase *)u->_down)->_up = u; // MR1 + } else { // MR1 + u->_down = NULL; // MR1 + }; // MR1 + return u; +} + +#endif + +/* + * Set the 'up', and 'left' pointers of all nodes in 't'. + * Initial call is double_link(your_tree, NULL, NULL). + */ +void +ASTDoublyLinkedBase::double_link(ASTBase *left, ASTBase *up) +{ + ASTDoublyLinkedBase *t = this; + + t->_left = (ASTDoublyLinkedBase *) left; + t->_up = (ASTDoublyLinkedBase *) up; + if (t->_down != NULL) + ((ASTDoublyLinkedBase *)t->_down)->double_link(NULL, t); + if (t->_right != NULL) + ((ASTDoublyLinkedBase *)t->_right)->double_link(t, up); +} + +// MR21 ASTBase::reportOverwriteOfDownPointer + +void ASTBase::reportOverwriteOfDownPointer() +{ + panic("Attempt to overwrite down pointer in ASTBase::tmake"); +} + +// MR21 ASTBase::panic + +void ASTBase::panic(const char *msg) +{ + /* MR23 */ printMessage(stderr,"ASTBase panic: %s\n", msg); + exit(PCCTS_EXIT_FAILURE); +} + +#ifdef PCCTS_NOT_USING_SOR +//MR23 +int ASTBase::printMessage(FILE* pFile, const char* pFormat, ...) +{ + va_list marker; + va_start( marker, pFormat ); + int iRet = vfprintf(pFile, pFormat, marker); + va_end( marker ); + return iRet; +} +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/ASTBase.h b/Tools/CodeTools/Source/Pccts/h/ASTBase.h new file mode 100644 index 0000000000..912f4b8482 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/ASTBase.h @@ -0,0 +1,122 @@ +/* Abstract syntax tree + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +#ifndef ASTBase_H +#define ASTBase_H + +#include "pcctscfg.h" + +#include "pccts_stdio.h" +#include "pccts_stdlib.h" + +PCCTS_NAMESPACE_STD + +#ifndef PCCTS_NOT_USING_SOR +#include "PCCTSAST.h" +#endif + +/* + * Notes: + * + * To specify a copy constructor, subclass one of these classes and + * give the copy constructor. To use dup(), you must define shallowCopy(). + * shallowCopy() can use either a copy constructor or just copy the node + * itself. + */ + +#ifdef PCCTS_NOT_USING_SOR +class DllExportPCCTS ASTBase { +#else +class DllExportPCCTS ASTBase : public PCCTS_AST { +#endif + +protected: + ASTBase *_right, *_down; + +public: + +#ifdef PCCTS_NOT_USING_SOR + ASTBase *right() { return _right; } + ASTBase *down() { return _down; } + void setRight(ASTBase *t) { _right = (ASTBase *)t; } + void setDown(ASTBase *t) { _down = (ASTBase *)t; } +#else + PCCTS_AST *right() { return _right; } // define the SORCERER interface + PCCTS_AST *down() { return _down; } + void setRight(PCCTS_AST *t) { _right = (ASTBase *)t; } + void setDown(PCCTS_AST *t) { _down = (ASTBase *)t; } +#endif + ASTBase() { _right = _down = NULL; } + virtual ~ASTBase() { ; } +#ifndef PCCTS_NOT_USING_SOR + virtual ASTBase *dup(); +#endif + void destroy(); + void preorder(void* pData = NULL /* MR23 */); + static ASTBase *tmake(ASTBase *, ...); + static void link(ASTBase **, ASTBase **, ASTBase **); + void subchild(ASTBase **, ASTBase **, ASTBase **); + void subroot(ASTBase **, ASTBase **, ASTBase **); + virtual void preorder_action(void* /*pData*/ = NULL /* MR23 */) { ; } + virtual void preorder_before_action(void* /*pData*/ = NULL /* MR23 */) { /* MR23 */ printMessage(stdout, " ("); } + virtual void preorder_after_action(void* /*pData*/ = NULL /* MR23 */) { /* MR23 */ printMessage(stdout, " )"); } + virtual void panic(const char *msg); /* MR21 */ + virtual void reportOverwriteOfDownPointer(); /* MR21 */ +#ifdef PCCTS_NOT_USING_SOR + virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23 +#endif +}; + +class DllExportPCCTS ASTDoublyLinkedBase : public ASTBase { +protected: + ASTDoublyLinkedBase *_left, *_up; + +public: + void double_link(ASTBase *left, ASTBase *up); + +#ifndef PCCTS_NOT_USING_SOR + virtual ASTBase *dup(); +#endif + +#ifdef PCCTS_NOT_USING_SOR + ASTBase *left() { return _left; } + ASTBase *up() { return _up; } + void setLeft(ASTBase *t) { _left = (ASTDoublyLinkedBase *)t; } // MR6 + void setUp(ASTBase *t) { _up = (ASTDoublyLinkedBase *)t; } // MR6 +#else + PCCTS_AST *left() { return _left; } + PCCTS_AST *up() { return _up; } + void setLeft(PCCTS_AST *t) { _left = (ASTDoublyLinkedBase *)t; } // MR6 + void setUp(PCCTS_AST *t) { _up = (ASTDoublyLinkedBase *)t; } // MR6 +#endif + +}; + +class AST; // announce that this class will be coming along shortly +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/ATokPtr.h b/Tools/CodeTools/Source/Pccts/h/ATokPtr.h new file mode 100644 index 0000000000..75b4c86cbf --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/ATokPtr.h @@ -0,0 +1,88 @@ +/* ATokPtr.h + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Written by Russell Quong June 30, 1995 + * Adapted by Terence Parr to ANTLR stuff + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +#ifndef ATokPtr_h +#define ATokPtr_h + +#include "pcctscfg.h" + +#include "pccts_stdio.h" + +PCCTS_NAMESPACE_STD + +// pointer to a reference counted object +// robust in that an unused ANTLRTokenPtr can point to NULL. + +class ANTLRAbstractToken; + +class DllExportPCCTS ANTLRTokenPtr { +public: + ANTLRTokenPtr(ANTLRAbstractToken *addr=NULL){ptr_ = addr; ref();} + ANTLRTokenPtr(const ANTLRTokenPtr &lhs) {ptr_ = lhs.ptr_; lhs.ref();} + ~ANTLRTokenPtr(); + + // use ANTLRTokenPtr as a pointer to ANTLRToken +// +// 8-Apr-97 MR1 Make operator -> a const member function +// as well as some other member functions +// + ANTLRAbstractToken *operator-> () const { return ptr_; } // MR1 +// +// 7-Apr-97 133MR1 +// Fix suggested by Andreas Magnusson +// (Andreas.Magnusson@mailbox.swipnet.se) + void operator = (const ANTLRTokenPtr & lhs); // MR1 + void operator = (ANTLRAbstractToken *addr); + int operator != (const ANTLRTokenPtr &q) const // MR1 // MR11 unsigned -> int + { return this->ptr_ != q.ptr_; } + int operator == (const ANTLRTokenPtr &q) const // MR1 // MR11 unsigned -> int + { return this->ptr_ == q.ptr_; } + int operator == (const ANTLRAbstractToken *addr) const // MR11 + { return this->ptr_ == addr; } + int operator != (const ANTLRAbstractToken *addr) const // MR11 + { return this->ptr_ != addr; } + + void ref() const; + void deref(); + +protected: + ANTLRAbstractToken *ptr_; +}; + +//typedef ANTLRTokenPtr _ANTLRTokenPtr; + +/* + * Since you cannot redefine operator->() to return one of the user's + * token object types, we must down cast. This is a drag. Here's + * a macro that helps. template: "mytoken(a-smart-ptr)->myfield". + */ +#define mytoken(tk) ((ANTLRToken *)(tk.operator->())) + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/ATokPtrImpl.h b/Tools/CodeTools/Source/Pccts/h/ATokPtrImpl.h new file mode 100644 index 0000000000..9c07cf52a9 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/ATokPtrImpl.h @@ -0,0 +1,88 @@ +/* + * ATokPtrImpl.h (formerly ATokPtr.cpp) + * + * This is #included in ATokBuffer.cpp for historical reasons. + * It has been renamed because of problems with the .cpp extension + * when used with IDE. + * + * + * ANTLRToken MUST be defined before entry to this file. + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Written by Russell Quong June 30, 1995 + * Adapted by Terence Parr to ANTLR stuff + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +#include "pcctscfg.h" + +PCCTS_NAMESPACE_STD + +#include "ATokPtr.h" + +void ANTLRTokenPtr::ref() const +{ + if (ptr_ != NULL) { + ptr_->ref(); + } +} + +void ANTLRTokenPtr::deref() +{ + if (ptr_ != NULL) + { + ptr_->deref(); + if ( ptr_->nref()==0 ) + { + delete ptr_; + ptr_ = NULL; + } + } +} + +ANTLRTokenPtr::~ANTLRTokenPtr() +{ + deref(); +} + +// +// 8-Apr-97 MR1 Make operator -> a const member function +// as weall as some other member functions +// +void ANTLRTokenPtr::operator = (const ANTLRTokenPtr & lhs) // MR1 +{ + lhs.ref(); // protect against "xp = xp"; ie same underlying object + deref(); + ptr_ = lhs.ptr_; +} + +void ANTLRTokenPtr::operator = (ANTLRAbstractToken *addr) +{ + if (addr != NULL) { + addr->ref(); + } + deref(); + ptr_ = addr; +} diff --git a/Tools/CodeTools/Source/Pccts/h/AToken.h b/Tools/CodeTools/Source/Pccts/h/AToken.h new file mode 100644 index 0000000000..6167c21ef5 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/AToken.h @@ -0,0 +1,325 @@ +/* ANTLRToken.h + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +#ifndef ATOKEN_H_GATE +#define ATOKEN_H_GATE + +#include "pcctscfg.h" + +#include "pccts_string.h" +#include "pccts_stdio.h" +#include "pccts_stdlib.h" +#include "pccts_stdarg.h" // MR23 + +PCCTS_NAMESPACE_STD + +// MR9 RJV (JVincent@novell.com) Not needed for variable length strings + +//// MR9 #ifndef ANTLRCommonTokenTEXTSIZE +//// MR9 #define ANTLRCommonTokenTEXTSIZE 100 +//// MR9 #endif + + +/* must define what a char looks like; can make this a class too */ +typedef char ANTLRChar; + +/* D E F I N E S M A R T P O I N T E R S */ + +//#include ATOKPTR_H not tested yet, leave out +class ANTLRAbstractToken; +typedef ANTLRAbstractToken *_ANTLRTokenPtr; + +class ANTLRAbstractToken { +public: + virtual ~ANTLRAbstractToken() {;} + virtual ANTLRTokenType getType() const = 0; + virtual void setType(ANTLRTokenType t) = 0; + virtual int getLine() const = 0; + virtual void setLine(int line) = 0; + virtual ANTLRChar *getText() const = 0; + virtual void setText(const ANTLRChar *) = 0; + + /* This function will disappear when I can use templates */ + virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt, + ANTLRChar *text, + int line) = 0; + + /* define to satisfy ANTLRTokenBuffer's need to determine whether or + not a token object can be destroyed. If nref()==0, no one has + a reference, and the object may be destroyed. This function defaults + to 1, hence, if you use deleteTokens() message with a token object + not derived from ANTLRCommonRefCountToken, the parser will compile + but will not delete objects after they leave the token buffer. + */ + + virtual unsigned nref() const { return 1; } // MR11 + virtual void ref() {;} + virtual void deref() {;} + + virtual void panic(const char *msg) // MR20 const + { + /* MR23 */ printMessage(stderr, "ANTLRAbstractToken panic: %s\n", msg); + exit(PCCTS_EXIT_FAILURE); + } + + virtual int printMessage(FILE* pFile, const char* pFormat, ...) // MR23 + { + va_list marker; + va_start( marker, pFormat ); + int iRet = vfprintf(pFile, pFormat, marker); + va_end( marker ); + return iRet; + } +}; + +/* This class should be subclassed. It cannot store token type or text */ + +class ANTLRRefCountToken : public ANTLRAbstractToken { +public: +#ifdef DBG_REFCOUNTTOKEN + static int ctor; + static int dtor; +#endif +protected: + unsigned refcnt_; +#ifdef DBG_REFCOUNTTOKEN + char object[200]; +#endif + +public: + + // MR23 - No matter what you do, you're hammered. + // Don't give names to formals something breaks. + // Give names to formals and don't use them it breaks. + +#ifndef DBG_REFCOUNTTOKEN + ANTLRRefCountToken(ANTLRTokenType /* t MR23 */, const ANTLRChar * /* s MR23 */) +#else + ANTLRRefCountToken(ANTLRTokenType t, const ANTLRChar * s) +#endif + +#ifndef DBG_REFCOUNTTOKEN + { + refcnt_ = 0; + } +#else + { + ctor++; + refcnt_ = 0; + if ( t==1 ) sprintf(object,"tok_EOF"); + else sprintf(object,"tok_%s",s); + /* MR23 */ printMessage(stderr, "ctor %s #%d\n",object,ctor); + } +#endif + ANTLRRefCountToken() +#ifndef DBG_REFCOUNTTOKEN + { refcnt_ = 0; } +#else + { + ctor++; + refcnt_ = 0; + sprintf(object,"tok_blank"); + /* MR23 */ printMessage(stderr, "ctor %s #%d\n",object,ctor); + } + virtual ~ANTLRRefCountToken() + { + dtor++; + if ( dtor>ctor ) /* MR23 */ printMessage(stderr, "WARNING: dtor>ctor\n"); + /* MR23 */ printMessage(stderr, "dtor %s #%d\n", object, dtor); + object[0]='\0'; + } +#endif + + // reference counting stuff needed by ANTLRTokenPtr. + // User should not access these; for C++ language reasons, we had + // to make these public. Yuck. + + void ref() { refcnt_++; } + void deref() { refcnt_--; } + unsigned nref() const { return refcnt_; } // MR11 + + virtual ANTLRAbstractToken *makeToken(ANTLRTokenType /*tt MR23*/, + ANTLRChar * /*txt MR23*/, + int /*line MR23*/) + { + panic("call to ANTLRRefCountToken::makeToken()\n"); + return NULL; + } +}; + +class ANTLRCommonNoRefCountToken : public ANTLRAbstractToken { +protected: + ANTLRTokenType _type; + int _line; + ANTLRChar *_text; // MR9 RJV + +public: + ANTLRCommonNoRefCountToken(ANTLRTokenType t, const ANTLRChar *s) + { setType(t); _line = 0; _text = NULL; setText(s); } + ANTLRCommonNoRefCountToken() + { setType((ANTLRTokenType)0); _line = 0; _text = NULL; setText(""); } + + ~ANTLRCommonNoRefCountToken() { if (_text) delete [] _text; } // MR9 RJV: Added Destructor to remove string + + ANTLRTokenType getType() const { return _type; } + void setType(ANTLRTokenType t) { _type = t; } + virtual int getLine() const { return _line; } + void setLine(int line) { _line = line; } + ANTLRChar *getText() const { return _text; } + int getLength() const { return strlen(getText()); } // MR11 + +// MR9 RJV: Added code for variable length strings to setText() + + void setText(const ANTLRChar *s) + { if (s != _text) { + if (_text) delete [] _text; + if (s != NULL) { + _text = new ANTLRChar[strlen(s)+1]; + if (_text == NULL) panic("ANTLRCommonNoRefCountToken::setText new failed"); + strcpy(_text,s); + } else { + _text = new ANTLRChar[1]; + if (_text == NULL) panic("ANTLRCommonNoRefCountToken::setText new failed"); + strcpy(_text,""); + }; + }; + } + + virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt, + ANTLRChar *txt, + int line) + { + ANTLRAbstractToken *t = new ANTLRCommonNoRefCountToken; + t->setType(tt); t->setText(txt); t->setLine(line); + return t; + } + +// MR9 THM Copy constructor required when heap allocated string is used with copy semantics + + ANTLRCommonNoRefCountToken (const ANTLRCommonNoRefCountToken& from) : + ANTLRAbstractToken(from) { + setType(from._type); + setLine(from._line); + _text=NULL; + setText(from._text); + }; + +// MR9 THM operator =() required when heap allocated string is used with copy semantics + + virtual ANTLRCommonNoRefCountToken& operator =(const ANTLRCommonNoRefCountToken& rhs) { + +////// MR15 WatCom can't hack use of operator =() +////// Use this: *( (ANTRLAbstractToken *) this)=rhs; + + *( (ANTLRAbstractToken *) this ) = rhs; + + setType(rhs._type); + setLine(rhs._line); + setText(rhs._text); + return *this; + }; +}; + +class ANTLRCommonToken : public ANTLRRefCountToken { +protected: + ANTLRTokenType _type; + int _line; + ANTLRChar *_text; // MR9 RJV:Added + +public: + ANTLRCommonToken(ANTLRTokenType t, const ANTLRChar *s) : ANTLRRefCountToken(t,s) + { setType(t); _line = 0; _text = NULL; setText(s); } // MR9 + ANTLRCommonToken() + { setType((ANTLRTokenType)0); _line = 0; _text = NULL; setText(""); } // MR9 + + virtual ~ANTLRCommonToken() { if (_text) delete [] _text; } // MR9 RJV: Added Destructor to remove string + + ANTLRTokenType getType() const { return _type; } + void setType(ANTLRTokenType t) { _type = t; } + virtual int getLine() const { return _line; } + void setLine(int line) { _line = line; } + ANTLRChar *getText() const { return _text; } + int getLength() const { return strlen(getText()); } // MR11 + +// MR9 RJV: Added code for variable length strings to setText() + + void setText(const ANTLRChar *s) + { if (s != _text) { + if (_text) delete [] _text; + if (s != NULL) { + _text = new ANTLRChar[strlen(s)+1]; + if (_text == NULL) panic("ANTLRCommonToken::setText new failed"); + strcpy(_text,s); + } else { + _text = new ANTLRChar[1]; + if (_text == NULL) panic("ANTLRCommonToken::setText new failed"); + strcpy(_text,""); + }; + }; + } + + virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt, + ANTLRChar *txt, + int line) + { + ANTLRAbstractToken *t = new ANTLRCommonToken(tt,txt); + t->setLine(line); + return t; + } + +// MR9 THM Copy constructor required when heap allocated string is used with copy semantics + + ANTLRCommonToken (const ANTLRCommonToken& from) : + ANTLRRefCountToken(from) { + setType(from._type); + setLine(from._line); + _text=NULL; + setText(from._text); + }; + +// MR9 THM operator =() required when heap allocated string is used with copy semantics + + virtual ANTLRCommonToken& operator =(const ANTLRCommonToken& rhs) { + +////// MR15 WatCom can't hack use of operator =() +////// Use this instead: *( (ANTRLRRefCountToken *) this)=rhs; + + *( (ANTLRRefCountToken *) this) = rhs; + + setType(rhs._type); + setLine(rhs._line); + setText(rhs._text); + return *this; + }; +}; + +// used for backward compatibility +typedef ANTLRCommonToken ANTLRCommonBacktrackingToken; + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/ATokenBuffer.cpp b/Tools/CodeTools/Source/Pccts/h/ATokenBuffer.cpp new file mode 100644 index 0000000000..9a2f2fc88b --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/ATokenBuffer.cpp @@ -0,0 +1,374 @@ +/* ANTLRTokenBuffer.cpp + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +typedef int ANTLRTokenType; // fool AToken.h into compiling + +class ANTLRParser; /* MR1 */ + +#define ANTLR_SUPPORT_CODE + +#include "pcctscfg.h" + +#include ATOKENBUFFER_H +#include APARSER_H // MR23 + +typedef ANTLRAbstractToken *_ANTLRTokenPtr; + +#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW) +static unsigned char test[1000]; +#endif + +#ifdef DBG_REFCOUNTTOKEN +int ANTLRRefCountToken::ctor = 0; /* MR23 */ +int ANTLRRefCountToken::dtor = 0; /* MR23 */ +#endif + +ANTLRTokenBuffer:: +ANTLRTokenBuffer(ANTLRTokenStream *_input, int _k, int _chunk_size_formal) /* MR14 */ +{ + this->input = _input; + this->k = _k; + buffer_size = chunk_size = _chunk_size_formal; + buffer = (_ANTLRTokenPtr *) + calloc(chunk_size+1,sizeof(_ANTLRTokenPtr )); + if ( buffer == NULL ) { + panic("cannot alloc token buffer"); + } + buffer++; // leave the first elem empty so tp-1 is valid ptr + + tp = &buffer[0]; + last = tp-1; + next = &buffer[0]; + num_markers = 0; + end_of_buffer = &buffer[buffer_size-1]; + threshold = &buffer[(int)(buffer_size/2)]; // MR23 - Used to be 1.0/2.0 ! + _deleteTokens = 1; // assume we delete tokens + parser=NULL; // MR5 - uninitialized reference +} + +static void f() {;} +ANTLRTokenBuffer:: +~ANTLRTokenBuffer() +{ + f(); + // Delete all remaining tokens (from 0..last inclusive) + if ( _deleteTokens ) + { + _ANTLRTokenPtr *z; + for (z=buffer; z<=last; z++) + { + (*z)->deref(); +// z->deref(); +#ifdef DBG_REFCOUNTTOKEN + /* MR23 */ printMessage(stderr, "##########dtor: deleting token '%s' (ref %d)\n", + ((ANTLRCommonToken *)*z)->getText(), (*z)->nref()); +#endif + if ( (*z)->nref()==0 ) + { + delete (*z); + } + } + } + + if ( buffer!=NULL ) free((char *)(buffer-1)); +} + +#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW) +#include "pccts_stdio.h" +PCCTS_NAMESPACE_STD +#endif + +_ANTLRTokenPtr ANTLRTokenBuffer:: +getToken() +{ + if ( tp <= last ) // is there any buffered lookahead still to be read? + { + return *tp++; // read buffered lookahead + } + // out of buffered lookahead, get some more "real" + // input from getANTLRToken() + if ( num_markers==0 ) + { + if( next > threshold ) + { +#ifdef DBG_TBUF +/* MR23 */ printMessage(stderr,"getToken: next > threshold (high water is %d)\n", threshold-buffer); +#endif + makeRoom(); + } + } + else { + if ( next > end_of_buffer ) + { +#ifdef DBG_TBUF +/* MR23 */ printMessage(stderr,"getToken: next > end_of_buffer (size is %d)\n", buffer_size); +#endif + extendBuffer(); + } + } + *next = getANTLRToken(); + (*next)->ref(); // say we have a copy of this pointer in buffer + last = next; + next++; + tp = last; + return *tp++; +} + +void ANTLRTokenBuffer:: +rewind(int pos) +{ +#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW) + /* MR23 */ printMessage(stderr, "rewind(%d)[nm=%d,from=%d,%d.n=%d]\n", pos, num_markers, tp-buffer,pos,test[pos]); + test[pos]--; +#endif + tp = &buffer[pos]; + num_markers--; +} + +/* + * This function is used to specify that the token pointers read + * by the ANTLRTokenBuffer should be buffered up (to be reused later). + */ +int ANTLRTokenBuffer:: +mark() +{ +#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW) + test[tp-buffer]++; + /* MR23 */ printMessage(stderr,"mark(%d)[nm=%d,%d.n=%d]\n",tp-buffer,num_markers+1,tp-buffer,test[tp-buffer]); +#endif + num_markers++; + return tp - buffer; +} + +/* + * returns the token pointer n positions ahead. + * This implies that bufferedToken(1) gets the NEXT symbol of lookahead. + * This is used in conjunction with the ANTLRParser lookahead buffer. + * + * No markers are set or anything. A bunch of input is buffered--that's all. + * The tp pointer is left alone as the lookahead has not been advanced + * with getToken(). The next call to getToken() will find a token + * in the buffer and won't have to call getANTLRToken(). + * + * If this is called before a consume() is done, how_many_more_i_need is + * set to 'n'. + */ +_ANTLRTokenPtr ANTLRTokenBuffer:: +bufferedToken(int n) +{ +// int how_many_more_i_need = (last-tp < 0) ? n : n-(last-tp)-1; + int how_many_more_i_need = (tp > last) ? n : n-(last-tp)-1; + // Make sure that at least n tokens are available in the buffer +#ifdef DBG_TBUF + /* MR23 */ printMessage(stderr, "bufferedToken(%d)\n", n); +#endif + for (int i=1; i<=how_many_more_i_need; i++) + { + if ( next > end_of_buffer ) // buffer overflow? + { + extendBuffer(); + } + *next = getANTLRToken(); + (*next)->ref(); // say we have a copy of this pointer in buffer + last = next; + next++; + } + return tp[n - 1]; +} + +/* If no markers are set, the none of the input needs to be saved (except + * for the lookahead Token pointers). We save only k-1 token pointers as + * we are guaranteed to do a getANTLRToken() right after this because otherwise + * we wouldn't have needed to extend the buffer. + * + * If there are markers in the buffer, we need to save things and so + * extendBuffer() is called. + */ +void ANTLRTokenBuffer:: +makeRoom() +{ +#ifdef DBG_TBUF + /* MR23 */ printMessage(stderr, "in makeRoom.................\n"); + /* MR23 */ printMessage(stderr, "num_markers==%d\n", num_markers); +#endif +/* + if ( num_markers == 0 ) + { +*/ +#ifdef DBG_TBUF + /* MR23 */ printMessage(stderr, "moving lookahead and resetting next\n"); + + _ANTLRTokenPtr *r; + /* MR23 */ printMessage(stderr, "tbuf = ["); + for (r=buffer; r<=last; r++) + { + if ( *r==NULL ) /* MR23 */ printMessage(stderr, " xxx"); + else /* MR23 */ printMessage(stderr, " '%s'", ((ANTLRCommonToken *)*r)->getText()); + } + /* MR23 */ printMessage(stderr, " ]\n"); + + /* MR23 */ printMessage(stderr, + "before: tp=%d, last=%d, next=%d, threshold=%d\n",tp-buffer,last-buffer,next-buffer,threshold-buffer); +#endif + + // Delete all tokens from 0..last-(k-1) inclusive + if ( _deleteTokens ) + { + _ANTLRTokenPtr *z; + for (z=buffer; z<=last-(k-1); z++) + { + (*z)->deref(); +// z->deref(); +#ifdef DBG_REFCOUNTTOKEN + /* MR23 */ printMessage(stderr, "##########makeRoom: deleting token '%s' (ref %d)\n", + ((ANTLRCommonToken *)*z)->getText(), (*z)->nref()); +#endif + if ( (*z)->nref()==0 ) + { + delete (*z); + } + } + } + + // reset the buffer to initial conditions, but move k-1 symbols + // to the beginning of buffer and put new input symbol at k + _ANTLRTokenPtr *p = buffer, *q = last-(k-1)+1; +// ANTLRAbstractToken **p = buffer, **q = end_of_buffer-(k-1)+1; +#ifdef DBG_TBUF + /* MR23 */ printMessage(stderr, "lookahead buffer = ["); +#endif + for (int i=1; i<=(k-1); i++) + { + *p++ = *q++; +#ifdef DBG_TBUF + /* MR23 */ printMessage(stderr, + " '%s'", ((ANTLRCommonToken *)buffer[i-1])->getText()); +#endif + } +#ifdef DBG_TBUF + /* MR23 */ printMessage(stderr, " ]\n"); +#endif + next = &buffer[k-1]; + tp = &buffer[k-1]; // tp points to what will be filled in next + last = tp-1; +#ifdef DBG_TBUF + /* MR23 */ printMessage(stderr, + "after: tp=%d, last=%d, next=%d\n", + tp-buffer, last-buffer, next-buffer); +#endif +/* + } + else { + extendBuffer(); + } +*/ +} + +/* This function extends 'buffer' by chunk_size and returns with all + * pointers at the same relative positions in the buffer (the buffer base + * address could have changed in realloc()) except that 'next' comes + * back set to where the next token should be stored. All other pointers + * are untouched. + */ +void +ANTLRTokenBuffer:: +extendBuffer() +{ + int save_last = last-buffer, save_tp = tp-buffer, save_next = next-buffer; +#ifdef DBG_TBUF + /* MR23 */ printMessage(stderr, "extending physical buffer\n"); +#endif + buffer_size += chunk_size; + buffer = (_ANTLRTokenPtr *) + realloc((char *)(buffer-1), + (buffer_size+1)*sizeof(_ANTLRTokenPtr )); + if ( buffer == NULL ) { + panic("cannot alloc token buffer"); + } + buffer++; // leave the first elem empty so tp-1 is valid ptr + + tp = buffer + save_tp; // put the pointers back to same relative position + last = buffer + save_last; + next = buffer + save_next; + end_of_buffer = &buffer[buffer_size-1]; + threshold = &buffer[(int)(buffer_size*(1.0/2.0))]; + +/* + // zero out new token ptrs so we'll know if something to delete in buffer + ANTLRAbstractToken **p = end_of_buffer-chunk_size+1; + for (; p<=end_of_buffer; p++) *p = NULL; +*/ +} + +ANTLRParser * ANTLRTokenBuffer:: // MR1 +setParser(ANTLRParser *p) { // MR1 + ANTLRParser *old=parser; // MR1 + parser=p; // MR1 + input->setParser(p); // MR1 + return old; // MR1 +} // MR1 + // MR1 +ANTLRParser * ANTLRTokenBuffer:: // MR1 +getParser() { // MR1 + return parser; // MR1 +} // MR1 + +void ANTLRTokenBuffer::panic(const char *msg) // MR23 +{ + if (parser) //MR23 + parser->panic(msg); //MR23 + else //MR23 + exit(PCCTS_EXIT_FAILURE); +} + +//MR23 +int ANTLRTokenBuffer::printMessage(FILE* pFile, const char* pFormat, ...) +{ + va_list marker; + va_start( marker, pFormat ); + + int iRet = 0; + if (parser) + parser->printMessageV(pFile, pFormat, marker); + else + iRet = vfprintf(pFile, pFormat, marker); + + va_end( marker ); + return iRet; +} + +/* to avoid having to link in another file just for the smart token ptr + * stuff, we include it here. Ugh. + * + * MR23 This causes nothing but problems for IDEs. + * Change from .cpp to .h + * + */ + +#include ATOKPTR_IMPL_H diff --git a/Tools/CodeTools/Source/Pccts/h/ATokenBuffer.h b/Tools/CodeTools/Source/Pccts/h/ATokenBuffer.h new file mode 100644 index 0000000000..1c008fd59e --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/ATokenBuffer.h @@ -0,0 +1,109 @@ +/* ANTLRTokenBuffer.h + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +#ifndef ATOKENBUFFER_H_GATE +#define ATOKENBUFFER_H_GATE + +#include "pcctscfg.h" + +#include "pccts_stdlib.h" + +PCCTS_NAMESPACE_STD + +#include ATOKEN_H +#include ATOKENSTREAM_H + +/* + * The parser is "attached" to an ANTLRTokenBuffer via interface + * functions: getToken() and bufferedToken(). The object that actually + * consumes characters and constructs tokens is connected to the + * ANTLRTokenBuffer via interface function ANTLRTokenStream::getToken(); + * where ANTLRTokenStream is really just a behavior (class with no data). + * C++ does not have this abstraction and hence we simply have come up + * with a fancy name for "void *". See the note in ANTLRTokenStream.h on + * the "behavior" of ANTLRTokenStream. + */ + +class ANTLRParser; // MR1 + +class DllExportPCCTS ANTLRTokenBuffer { +protected: + ANTLRTokenStream *input; // where do I get tokens + int buffer_size; + int chunk_size; + int num_markers; + int k; // Need at least this many tokens in buffer + _ANTLRTokenPtr *buffer; // buffer used for arbitrary lookahead + _ANTLRTokenPtr *tp; // pts into buffer; current token ptr + _ANTLRTokenPtr *last; // pts to last valid token in buffer + _ANTLRTokenPtr *next; // place to put token from getANTLRToken() + _ANTLRTokenPtr *end_of_buffer; + /* when you try to write a token past this and there are no markers + set, then move k-1 tokens back to the beginning of the buffer. + We want to stay away from the end of the buffer because we have + to extend it if a marker is set and we reach the end (we cannot + move tokens to the beginning of the buffer in this case). + */ + _ANTLRTokenPtr *threshold; + unsigned char _deleteTokens; + + // This function is filled in by the subclass; it initiates fetch of input + virtual _ANTLRTokenPtr getANTLRToken() { return input->getToken(); } + void makeRoom(); + void extendBuffer(); + +public: + ANTLRTokenBuffer(ANTLRTokenStream *in, int k=1, int chksz=50); + virtual ~ANTLRTokenBuffer(); + virtual _ANTLRTokenPtr getToken(); + virtual void rewind(int pos); + virtual int mark(); + virtual _ANTLRTokenPtr bufferedToken(int i); + + void noGarbageCollectTokens() { _deleteTokens=0; } + void garbageCollectTokens() { _deleteTokens=1; } + + virtual int bufferSize() { return buffer_size; } + virtual int minTokens() { return k; } + virtual void setMinTokens(int k_new) { k = k_new; } + + virtual void panic(const char *msg); /* MR20 const */ + + virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23 + +protected: // MR1 + ANTLRParser *parser; // MR1 +public: // MR1 + ANTLRParser *setParser(ANTLRParser *p); // MR1 + ANTLRParser *getParser(); // MR1 + ANTLRTokenStream *getLexer() const { // MR12 + return input;} // MR12 +}; + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/ATokenStream.h b/Tools/CodeTools/Source/Pccts/h/ATokenStream.h new file mode 100644 index 0000000000..3dfea6ebff --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/ATokenStream.h @@ -0,0 +1,51 @@ +/* ANTLRTokenStream.h + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +#ifndef ATOKENSTREAM_H_GATE +#define ATOKENSTREAM_H_GATE + +#include "pcctscfg.h" + +/* This is really a behavior or protocol; it merely indicates the behavior + * required of the input and output of an ANTLRTokenBuffer. You could + * subclass it, but you can also just pass any old pointer to ANTLRTokenBuffer + * with a type cast (in which case, your getANTLRToken() would have to + * explicitly cast the input pointer to your REAL type (typically your lexer)). + */ + +class ANTLRParser; // MR1 + +class DllExportPCCTS ANTLRTokenStream { +public: + virtual _ANTLRTokenPtr getToken() = 0; + virtual ANTLRParser * setParser(ANTLRParser * /*p MR23*/) {return 0; }; // MR12 + virtual ANTLRParser * getParser() { return 0; }; // MR12 +}; + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/BufFileInput.cpp b/Tools/CodeTools/Source/Pccts/h/BufFileInput.cpp new file mode 100644 index 0000000000..99d08a42a4 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/BufFileInput.cpp @@ -0,0 +1,100 @@ +// FILE: BufFileInput.cpp +// AUTHOR: Alexey Demakov (AVD) demakov@kazbek.ispras.ru +// CREATION: 26-JAN-1998 +// DESCRIPTION: File Input Stream with lookahead for Scanner. +// See file BufFileInput.h for details + +// Change History: +// +// 22-Jun-1998 assert.h -> PCCTS_ASSERT_H +// string.h -> PCCTS_STRING_H +// +// 28-May-1998 Add virtual destructor to release buffer. +// +// Add dummy definition for ANTLRTokenType +// to allow compilation without knowing +// token type codes. +// +// Manfred Kogler (km@cast.uni-linz.ac.at) +// (1.33MR14) +// +// 20-Jul-1998 MR14a - Reorder initialization list for ctor. +// + +enum ANTLRTokenType {TER_HATES_CPP=0, SO_DO_OTHERS=9999 }; + +#include "pcctscfg.h" +#include "pccts_assert.h" +#include "pccts_string.h" + +PCCTS_NAMESPACE_STD + +#include "BufFileInput.h" + +BufFileInput::BufFileInput( FILE *f, int buf_size ) +: input( f ), + buf( new int[buf_size] ), + size( buf_size ), + start( 0 ), + len( 0 ) +{ +} + +BufFileInput::~BufFileInput() +{ + delete [] buf; +} + +int BufFileInput::nextChar( void ) +{ + if( len > 0 ) + { + // get char from buffer + int c = buf[start]; + + if( c != EOF ) + { + start++; start %= size; + len--; + } + return c; + } else { + // get char from file + int c = getc( input ); + + if( c == EOF ) + { + // if EOF - put it in the buffer as indicator + buf[start] = EOF; + len++; + } + return c; + } +} + +int BufFileInput::lookahead( char* s ) +{ + int l = strlen( s ); + + assert( 0 < l && l <= size ); + + while( len < l ) + { + int c = getc( input ); + + buf[ (start+len) % size ] = c; + + len++; + + if( c == EOF ) return 0; + } + + for( int i = 0; i < l; i++ ) + { + if( s[i] != buf[ (start+i) % size ] ) return 0; + } + return 1; +} + +// End of file BufFileInput.cpp + diff --git a/Tools/CodeTools/Source/Pccts/h/BufFileInput.h b/Tools/CodeTools/Source/Pccts/h/BufFileInput.h new file mode 100644 index 0000000000..ea54c0ee26 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/BufFileInput.h @@ -0,0 +1,53 @@ +// FILE: BufFileInput.h +// AUTHOR: Alexey Demakov (AVD) demakov@kazbek.ispras.ru +// CREATION: 26-JAN-1998 +// DESCRIPTION: File Input Stream with lookahead for Scanner +// Tested under Win32 with ANTLR 1.33 MR10 and MSVC 5.0 + +// Change History: +// +// 28-May-1998 Add virtual destructor to release buffer +// Manfred Kogler (km@cast.uni-linz.ac.at) +// (1.33MR14) + +#ifndef BufFileInput_h +#define BufFileInput_h + +#include "pcctscfg.h" + +#include "pccts_stdio.h" + +PCCTS_NAMESPACE_STD + +#include "DLexerBase.h" + +class DllExportPCCTS BufFileInput : public DLGInputStream +{ +public: + // constructor + // f - input stream + // buf_size - size of buffer (maximal length for string in is_in) + + BufFileInput(FILE *f, int buf_size = 8 ); + + virtual ~BufFileInput(); + + // gets next char from stream + + virtual int nextChar( void ); + + // looks in stream and compares next l characters with s + // returns the result of comparision + + int lookahead( char* s ); + +private: + FILE *input; // input stream; + int* buf; // buffer + int size; // size of buffer + int start; // position of the first symbol in buffer + int len; // count of characters in buffers +}; + +#endif +// end of file BufFileInput.h diff --git a/Tools/CodeTools/Source/Pccts/h/DLG_stream_input.h b/Tools/CodeTools/Source/Pccts/h/DLG_stream_input.h new file mode 100644 index 0000000000..d2147f5217 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/DLG_stream_input.h @@ -0,0 +1,98 @@ + +/************************************************************/ +/* */ +/* Predefined char stream: Input from (c++) stream. */ +/* */ +/* By Hubert Holin (Hubert.Holin@Bigfoot.com), 1998. */ +/* */ +/* This is completely free stuff, do whatever you want with */ +/* it (but then, I will take no responsability for whatever */ +/* may happen if you do either... caveat emptor!). */ +/* */ +/************************************************************/ + +#ifndef _DLG_STREAM_INPUT_H +#define _DLG_STREAM_INPUT_H + +#include "pccts_istream.h" + +PCCTS_NAMESPACE_STD + +#ifndef DLGX_H +#include "DLexerBase.h" +#endif + + +// NOTES: The semantics of the copy constructor +// and the affectation operator may be unwaranted... +// and the stream may not be reset. +// +// It would have been so much nicer for nextChar() +// to throw (of for the DLGInputStream to change status) +// upon hiting EOF than to return an "int"... + +template < + class E, + class T = ::std::char_traits + > +class DLG_stream_input : public DLGInputStream +{ +public: + + DLG_stream_input(::std::basic_istream * p_input_stream) + : input(p_input_stream) + { + // nothing to do! + }; + + DLG_stream_input(const DLG_stream_input & a_recopier) + : input(a_recopier.input) + { + // nothing to do! + }; + + virtual ~DLG_stream_input() + { + this->purge(); // bloody templarized lookup... + }; + + DLG_stream_input operator = (const DLG_stream_input & a_affecter) + { + if (this != &a_affecter) + { + input = a_affecter.input; + } + + return(*this); + }; + + virtual int nextChar() + { + E extracted_stuff; + + input->get(extracted_stuff); + + if (*input) + { + return(int(extracted_stuff)); + } + else + { + return(EOF); + } + }; + +protected: + + ::std::basic_istream * input; + +private: + + void purge() + { + // nothing to do! + }; +}; + +#endif /* _DLG_STREAM_INPUT_H */ + diff --git a/Tools/CodeTools/Source/Pccts/h/DLexer.h b/Tools/CodeTools/Source/Pccts/h/DLexer.h new file mode 100644 index 0000000000..37cac24f14 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/DLexer.h @@ -0,0 +1,191 @@ +/* DLexer.h (formerly DLexer.cpp) + * + * This was renamed because the use of the .cpp extension caused problems + * with IDEs. + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +#define ZZINC {if ( track_columns ) (++_endcol);} + +#define ZZGETC {ch = input->nextChar(); cl = ZZSHIFT(ch);} + +#define ZZNEWSTATE (newstate = dfa[state][cl]) + +#ifndef ZZCOPY +#define ZZCOPY \ + /* Truncate matching buffer to size (not an error) */ \ + if (nextpos < lastpos){ \ + *(nextpos++) = ch; \ + }else{ \ + bufovf = 1; \ + } +#endif + +void DLGLexer:: +mode( int m ) +{ + /* points to base of dfa table */ + if (m*actions[accepts[state]])(); + +// MR1 +// MR1 11-Apr-97 Help for tracking DLG results +// MR1 + +#ifdef DEBUG_LEXER + +/* MR1 */ if (debugLexerFlag) { +/* MR1 */ if (parser != NULL) { +/* MR1 */ /* MR23 */ printMessage(stdout, "\ntoken name=%s",parser->parserTokenName(tk)); +/* MR1 */ } else { +/* MR1 */ /* MR23 */ printMessage(stdout, "\ntoken nnumber=%d",tk); +/* MR1 */ }; +/* MR1 */ /* MR23 */ printMessage(stdout, " lextext=(%s) mode=%d", +/* MR1 */ (_lextext[0]=='\n' && _lextext[1]==0) ? +/* MR1 */ "newline" : _lextext, +/* MR1 */ automaton); +/* MR1 */ if (interactive && !charfull) { +/* MR1 */ /* MR23 */ printMessage(stdout, " char=empty"); +/* MR1 */ } else { +/* MR1 */ if (ch=='\n') { +/* MR1 */ /* MR23 */ printMessage(stdout, " char=newline"); +/* MR1 */ } else { +/* MR1 */ /* MR23 */ printMessage(stdout, " char=(%c)",ch); +/* MR1 */ }; +/* MR1 */ }; +/* MR1 */ /* MR23 */ printMessage(stdout, " %s\n", +/* MR1 */ (add_erase==1 ? "skip()" : +/* MR1 */ add_erase==2 ? "more()" : +/* MR1 */ "")); +/* MR1 */ }; + +#endif + + switch (add_erase) { + case 1: goto skip; + case 2: goto more; + } + return tk; +} + +void DLGLexer:: +advance() +{ + if ( input==NULL ) err_in(); + ZZGETC; charfull = 1; ZZINC; +} diff --git a/Tools/CodeTools/Source/Pccts/h/DLexerBase.cpp b/Tools/CodeTools/Source/Pccts/h/DLexerBase.cpp new file mode 100644 index 0000000000..b218afc038 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/DLexerBase.cpp @@ -0,0 +1,302 @@ +/* DLGLexerBase.c + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +#include "pcctscfg.h" + +#include "pccts_stdio.h" +#include "pccts_stdlib.h" + +PCCTS_NAMESPACE_STD + +/* I have to put this here due to C++ limitation + * that you can't have a 'forward' decl for enums. + * I hate C++!!!!!!!!!!!!!!! + */ + +// MR1 +// MR1 10-Apr-97 133MR1 Prevent use of varying sizes for the +// MR1 ANTLRTokenType enum +// MR1 + +enum ANTLRTokenType { TER_HATES_CPP=0, ITS_UTTER_GARBAGE, // MR1 + WITH_SOME_GOOD_IDEAS=9999}; // MR1 + +#define ANTLR_SUPPORT_CODE + +#include "pcctscfg.h" +#include DLEXERBASE_H +#include APARSER_H // MR23 + +DLGLexerBase:: +DLGLexerBase(DLGInputStream *in, + unsigned bufsize, + int _interactive, + int _track_columns) +{ + this->_bufsize = bufsize; + this->_lextext = new DLGChar[_bufsize]; + if ( this->_lextext==NULL ) { + panic("text buffer is NULL"); + } + this->_begexpr = this->_endexpr = NULL; + this->ch = this->bufovf = 0; + this->nextpos = NULL; + this->cl = 0; + this->add_erase = 0; + this->input = in; + this->_begcol = 0; + this->_endcol = 0; + this->_line = 1; + this->charfull = 0; + this->automaton = 0; + this->token_to_fill = NULL; + this->interactive = _interactive; + this->track_columns = _track_columns; + this->debugLexerFlag = 0; // MR1 + this->parser = NULL; // MR1 + this->lexErrCount=0; // MR11 +} + +// MR19 THM + +void DLGLexerBase::reset() +{ + this->charfull = 0; + this->_begcol = 0; + this->_endcol = 0; + this->automaton = 0; + this->_line=1; + this->lexErrCount=0; +} + +void DLGLexerBase:: +setInputStream( DLGInputStream *in ) +{ + this->input = in; + _line = 1; + charfull = 0; +} + +/* saves dlg state, but not what feeds dlg (such as file position) */ +void DLGLexerBase:: +saveState(DLGState *state) +{ + state->input = input; + state->interactive = interactive; + state->track_columns = track_columns; + state->auto_num = automaton; + state->add_erase = add_erase; + state->lookc = ch; + state->char_full = charfull; + state->begcol = _begcol; + state->endcol = _endcol; + state->line = _line; + state->lextext = _lextext; + state->begexpr = _begexpr; + state->endexpr = _endexpr; + state->bufsize = _bufsize; + state->bufovf = bufovf; + state->nextpos = nextpos; + state->class_num = cl; + state->debugLexerFlag = debugLexerFlag; // MR1 + state->parser = parser; // MR1 +} + +void DLGLexerBase:: +restoreState(DLGState *state) +{ + input = state->input; + interactive = state->interactive; + track_columns = state->track_columns; + automaton = state->auto_num; + add_erase = state->add_erase; + ch = state->lookc; + charfull = state->char_full; + _begcol = state->begcol; + _endcol = state->endcol; + _line = state->line; + _lextext = state->lextext; + _begexpr = state->begexpr; + _endexpr = state->endexpr; + _bufsize = state->bufsize; + bufovf = state->bufovf; + nextpos = state->nextpos; + cl = state->class_num; + debugLexerFlag = state->debugLexerFlag; // MR1 + parser = state->parser; // MR1 +} + +/* erase what is currently in the buffer, and get a new reg. expr */ +void DLGLexerBase:: +skip() +{ + add_erase = 1; +} + +/* don't erase what is in the lextext buffer, add on to it */ +void DLGLexerBase:: +more() +{ + add_erase = 2; +} + +/* substitute c for the reg. expr last matched and is in the buffer */ +void DLGLexerBase:: +replchar(DLGChar c) +{ + /* can't allow overwriting null at end of string */ + if (_begexpr < &_lextext[_bufsize-1]){ + *_begexpr = c; + *(_begexpr+1) = '\0'; + } + _endexpr = _begexpr; + if (c != '\0') { + nextpos = _begexpr + 1; + } + else { + nextpos = _begexpr; /* MR30 Zero terminates string. */ + } +} + +/* replace the string s for the reg. expr last matched and in the buffer */ + +#ifdef _MSC_VER // MR23 +//Turn off "assignment within conditional expression" warning +#pragma warning(disable : 4706) +#endif +void DLGLexerBase:: +replstr(const DLGChar *s) /* MR20 const */ +{ + register DLGChar *l= &_lextext[_bufsize -1]; + + nextpos = _begexpr; + if (s){ + while ((nextpos <= l) && (*(nextpos++) = *(s++))){ + /* empty */ + } + /* correct for NULL at end of string */ + nextpos--; + } + if ((nextpos <= l) && (*(--s) == 0)){ + bufovf = 0; + }else{ + bufovf = 1; + } + *(nextpos) = '\0'; + _endexpr = nextpos - 1; +} +#ifdef _MSC_VER // MR23 +#pragma warning(default: 4706) +#endif + +void DLGLexerBase:: +errstd(const char *s) /* MR20 const */ +{ + lexErrCount++; /* MR11 */ + /* MR23 */ printMessage(stderr, + "%s near line %d (text was '%s')\n", + ((s == NULL) ? "Lexical error" : s), + _line,_lextext); +} + +int DLGLexerBase:: +err_in() +{ + /* MR23 */ printMessage(stderr,"No input stream, function, or string\n"); + /* return eof to get out gracefully */ + return EOF; +} + +ANTLRTokenType DLGLexerBase:: +erraction() +{ + errstd("invalid token"); + advance(); + skip(); + return (ANTLRTokenType) 0; // bogus, but satisfies compiler +} + +_ANTLRTokenPtr DLGLexerBase:: +getToken() +{ + if ( token_to_fill==NULL ) panic("NULL token_to_fill"); + ANTLRTokenType tt = nextTokenType(); + _ANTLRTokenPtr tk = token_to_fill->makeToken(tt, _lextext,_line); + return tk; +} + +void DLGLexerBase:: +panic(const char *msg) /* MR20 const */ +{ + if (parser) //MR23 + parser->panic(msg); //MR23 + else //MR23 + { + /* MR23 */ printMessage(stderr, "DLG panic: %s\n", msg); + // + // 7-Apr-97 133MR1 + // + exit(PCCTS_EXIT_FAILURE); // MR1 + } +} + +ANTLRParser * DLGLexerBase:: // MR1 +setParser(ANTLRParser *p) { // MR1 + ANTLRParser *oldValue=parser; // MR1 + parser=p; // MR1 + return oldValue; // MR1 +} // MR1 + // MR1 +ANTLRParser * DLGLexerBase:: // MR1 +getParser() { // MR1 + return parser; // MR1 +} // MR1 + // MR1 +int DLGLexerBase:: // MR1 +debugLexer(int newValue) { // MR1 + int oldValue=debugLexerFlag; // MR1 + debugLexerFlag=newValue; // MR1 + return oldValue; // MR1 +} // MR1 + +//MR23 +int DLGLexerBase::printMessage(FILE* pFile, const char* pFormat, ...) +{ + va_list marker; + va_start( marker, pFormat ); + + int iRet = 0; + if (parser) + parser->printMessageV(pFile, pFormat, marker); + else + iRet = vfprintf(pFile, pFormat, marker); + + va_end( marker ); + return iRet; +} diff --git a/Tools/CodeTools/Source/Pccts/h/DLexerBase.h b/Tools/CodeTools/Source/Pccts/h/DLexerBase.h new file mode 100644 index 0000000000..db6cc1890c --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/DLexerBase.h @@ -0,0 +1,198 @@ +/* DLGLexerBase.h + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +#ifndef DLGX_H +#define DLGX_H + +#include "pcctscfg.h" +#include "pccts_stdio.h" + +PCCTS_NAMESPACE_STD + +#include ATOKEN_H +#include ATOKENSTREAM_H + +class ANTLRParser; // MR1 + +/* must define what a char looks like; can make this a class too */ +typedef char DLGChar; + +/* Can have it as a class too: (ack this looks weird; is it right?) +class DllExportPCCTS DLGChar { +private: + int c; +public: + DLGChar(int ch) { c = ch; } + int atom() { return c; } +}; +*/ + +/* user must subclass this */ +class DllExportPCCTS DLGInputStream { +public: + virtual int nextChar() = 0; +}; + +/* Predefined char stream: Input from FILE */ +class DllExportPCCTS DLGFileInput : public DLGInputStream { +private: + int found_eof; + FILE *input; +public: + DLGFileInput(FILE *f) { input = f; found_eof = 0; } + int nextChar() { + int c; + if ( found_eof ) return EOF; + else { + c=getc(input); + if ( c==EOF ) found_eof = 1; + return c; + } + } + void DLGFileReset(FILE *f) {input=f; found_eof = 0; }; // MR11 +}; + +// MR9 Suggested by Bruce Guenter (bruceg@qcc.sk.ca) +// MR9 Make DLGStringInput const correct + +/* Predefined char stream: Input from string */ +class DllExportPCCTS DLGStringInput : public DLGInputStream { +private: + const DLGChar *input; // MR9 + const DLGChar *p; // MR9 +public: + DLGStringInput(const DLGChar *s) { input = s; p = &input[0];} // MR9 + int nextChar() + { + if (*p) return (int) (unsigned char) *p++; // MR14 + else return EOF; + } + + void DLGStringReset(const DLGChar *s) {input=s; p= &input[0]; }; // MR11 // MR16 +}; + +class DllExportPCCTS DLGState { +public: + DLGInputStream *input; + int interactive; + int track_columns; + int auto_num; + int add_erase; + int lookc; + int char_full; + int begcol, endcol; + int line; + DLGChar *lextext, *begexpr, *endexpr; + int bufsize; + int bufovf; + DLGChar *nextpos; + int class_num; + int debugLexerFlag; // MR1 + ANTLRParser *parser; // MR1 +}; + +/* user must subclass this */ +class DllExportPCCTS DLGLexerBase : public ANTLRTokenStream { +public: + virtual ANTLRTokenType erraction(); + +protected: + DLGInputStream *input; + int interactive; + int track_columns; + DLGChar *_lextext; /* text of most recently matched token */ + DLGChar *_begexpr; /* beginning of last reg expr recogn. */ + DLGChar *_endexpr; /* beginning of last reg expr recogn. */ + int _bufsize; /* number of characters in lextext */ + int _begcol; /* column that first character of token is in*/ + int _endcol; /* column that last character of token is in */ + int _line; /* line current token is on */ + int ch; /* character to determine next state */ + int bufovf; /* indicates that buffer too small for text */ + int charfull; + DLGChar *nextpos; /* points to next available position in lextext*/ + int cl; + int automaton; + int add_erase; + DLGChar ebuf[70]; + _ANTLRTokenPtr token_to_fill; + + int debugLexerFlag; // MR1 + ANTLRParser *parser; // MR1 +public: + virtual _ANTLRTokenPtr getToken(); // MR12 public + virtual void advance(void) = 0; + void skip(void); /* erase lextext, look for antoher token */ + void more(void); /* keep lextext, look for another token */ + void mode(int k); /* switch to automaton 'k' */ + void saveState(DLGState *); + void restoreState(DLGState *); + virtual ANTLRTokenType nextTokenType(void)=0;/* get next token */ + void replchar(DLGChar c); /* replace last recognized reg. expr. with + a character */ + void replstr(const DLGChar *s); /* replace last recognized reg. expr. with + a string */ /* MR20 const */ + virtual int err_in(); // MR1 + virtual void errstd(const char *); // MR1 MR20 const + int line() { return _line; } + void set_line(int newValue) { _line=newValue; }; // MR1 + virtual void newline() { _line++; } + DLGChar *lextext() { return _lextext; } + + int begcol() { return _begcol; } + int endcol() { return _endcol; } + void set_begcol(int a) { _begcol=a; } + void set_endcol(int a) { _endcol=a; } + DLGChar *begexpr() { return _begexpr; } + DLGChar *endexpr() { return _endexpr; } + int bufsize() { return _bufsize; } + + void setToken(ANTLRAbstractToken *t) { token_to_fill = t; } + + void setInputStream(DLGInputStream *); + DLGLexerBase(DLGInputStream *in, + unsigned bufsize=2000, + int interactive=0, + int track_columns=0); + void reset(); // MR19 + virtual ~DLGLexerBase() { delete [] _lextext; } + virtual void panic(const char *msg); // MR1 MR20 const + void trackColumns() { + track_columns = 1; + this->_begcol = 0; + this->_endcol = 0; + }; + virtual ANTLRParser *setParser(ANTLRParser *p); // MR1 + virtual ANTLRParser *getParser(); // MR1 + virtual int debugLexer(int value); // MR1 + int lexErrCount; // MR12 + virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23 +}; + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/PBlackBox.h b/Tools/CodeTools/Source/Pccts/h/PBlackBox.h new file mode 100644 index 0000000000..d25b8d6939 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/PBlackBox.h @@ -0,0 +1,134 @@ +#ifndef PBLACKBOX_H +#define PBLACKBOX_H + +/* + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +/* Completely rewritten by Chris Uzdavinis (chris@atdesk.com) for MR23 */ + +#include "pcctscfg.h" + +#include "pccts_iostream.h" + +PCCTS_NAMESPACE_STD + +// MR20 Added #include for "DLexerBase.h" + +#include "DLexerBase.h" + +// +// The default buffer size of the lexer is given by the +// second argument of the lexer's ctor. It is optional +// and defaults to 2000 +// + +template +class DllExportPCCTS ParserBlackBox { +private: + // no copy construction allowed + ParserBlackBox(ParserBlackBox const &); + + // no copy assignment allowed + ParserBlackBox & operator=(ParserBlackBox const &); + +protected: + DLGFileInput *in; + Lexer *scan; + _ANTLRTokenPtr tok; + ANTLRTokenBuffer *pipe; + Parser *_parser; + FILE *file; + int openByBlackBox; /* MR21 Don't close what we haven't opened */ +public: + + ParserBlackBox(FILE *f) + : in(0) + , scan(0) + , tok(0) + , pipe(0) + , _parser(0) + , file(0) + , openByBlackBox(0) + { + if (f == NULL) + { + cerr << "invalid file pointer\n"; + } + else + { + openByBlackBox = 0; /* MR21a */ + file = f; + in = new DLGFileInput(f); + scan = new Lexer(in); + pipe = new ANTLRTokenBuffer(scan); + tok = new Token; + scan->setToken(tok); + _parser = new Parser(pipe); + _parser->init(); + } + } + ParserBlackBox(char *fname) + : in(0) + , scan(0) + , tok(0) + , pipe(0) + , _parser(0) + , file(0) + , openByBlackBox(0) + { + FILE *f = fopen(fname, "r"); + if ( f==NULL ) { + openByBlackBox = 0; + cerr << "cannot open " << fname << "\n"; return; + } + else { + openByBlackBox = 1; + file = f; + in = new DLGFileInput(f); + scan = new Lexer(in); + pipe = new ANTLRTokenBuffer(scan); + tok = new Token; + scan->setToken(tok); + _parser = new Parser(pipe); + _parser->init(); + } + } + + ~ParserBlackBox() + { + delete in; delete scan; delete pipe; delete _parser; delete tok; + if (1 == openByBlackBox) { + fclose(file); + } + } + + Parser *parser() { return _parser; } + Lexer *getLexer() { return scan; } +}; + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/PCCTSAST.cpp b/Tools/CodeTools/Source/Pccts/h/PCCTSAST.cpp new file mode 100644 index 0000000000..a8249cdac0 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/PCCTSAST.cpp @@ -0,0 +1,684 @@ +/* + * PCCTSAST.C + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to SORCERER -- SORCERER is in the public + * domain. An individual or company may do whatever they wish with + * source code distributed with SORCERER or the code generated by + * SORCERER, including the incorporation of SORCERER, or its output, into + * commerical software. + * + * We encourage users to develop software with SORCERER. However, we do + * ask that credit is given to us for developing SORCERER. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like SORCERER and have developed a nice tool with the + * output, please mention that you developed it using SORCERER. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * SORCERER 1.00B14 and ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * AHPCRC, University of Minnesota + * 1992-2000 + */ + +#define ANTLR_SUPPORT_CODE + +#include "pcctscfg.h" + +#include "PCCTSAST.h" +#include "pccts_stdarg.h" + +PCCTS_NAMESPACE_STD + +#include + +//#include "SList.h" + + /* String Scanning/Parsing Stuff */ + +const char *PCCTS_AST::scan_token_tbl[] = { /* MR20 const */ + "invalid", /* 0 */ + "LPAREN", /* 1 */ + "RPAREN", /* 2 */ + "PERCENT", /* 3 */ + "INT", /* 4 */ + "COLON", /* 5 */ + "POUND", /* 6 */ + "PERIOD", /* 7 */ +}; + +void PCCTS_AST:: +addChild(PCCTS_AST *t) +{ + if ( t==NULL ) return; + PCCTS_AST *s = down(); + if ( s!=NULL ) + { + while ( s->right()!=NULL ) s = s->right(); + s->setRight(t); + } + else + this->setDown(t); +} + +void PCCTS_AST:: +lisp(FILE *f) +{ + if ( down() != NULL ) /* MR23 */ printMessage(f," ("); + lisp_action(f); + if ( down()!=NULL ) down()->lisp(f); + if ( down() != NULL ) /* MR23 */ printMessage(f," )"); + if ( right()!=NULL ) right()->lisp(f); +} + +/* build a tree (root child1 child2 ... NULL) + * If root is NULL, simply make the children siblings and return ptr + * to 1st sibling (child1). If root is not single node, return NULL. + * + * Siblings that are actually sibling lists themselves are handled + * correctly. For example #( NULL, #( NULL, A, B, C), D) results + * in the tree ( NULL A B C D ). + * + * Requires at least two parameters with the last one being NULL. If + * both are NULL, return NULL. + * + * The down() and right() down/right pointers are used to make the tree. + */ +PCCTS_AST *PCCTS_AST:: +make(PCCTS_AST *rt, ...) +{ + va_list ap; + register PCCTS_AST *child, *sibling=NULL, *tail=NULL /*MR23*/, *w; + PCCTS_AST *root; + + va_start(ap, rt); + root = rt; + + if ( root != NULL ) + if ( root->down() != NULL ) return NULL; + child = va_arg(ap, PCCTS_AST *); + while ( child != NULL ) + { + /* find end of child */ + for (w=child; w->right()!=NULL; w=w->right()) {;} + if ( sibling == NULL ) {sibling = child; tail = w;} + else {tail->setRight(child); tail = w;} + child = va_arg(ap, PCCTS_AST *); + } + if ( root==NULL ) root = sibling; + else root->setDown(sibling); + va_end(ap); + return root; +} + +/* The following push and pop routines are only used by ast_find_all() */ + +void PCCTS_AST:: +_push(PCCTS_AST **st, int *sp, PCCTS_AST *e) +{ + (*sp)--; + require((*sp)>=0, "stack overflow"); + st[(*sp)] = e; +} + +PCCTS_AST *PCCTS_AST:: +_pop(PCCTS_AST **st, int *sp) +{ + PCCTS_AST *e = st[*sp]; + (*sp)++; + require((*sp)<=MaxTreeStackDepth, "stack underflow"); + return e; +} + +/* Find all occurrences of u in t. + * 'cursor' must be initialized to 't'. It eventually + * returns NULL when no more occurrences of 'u' are found. + */ +PCCTS_AST *PCCTS_AST:: +ast_find_all(PCCTS_AST *u, PCCTS_AST **cursor) +{ + PCCTS_AST *sib; + /*** static ***/ PCCTS_AST *template_stack[MaxTreeStackDepth]; /* MR23 Remove "static" */ + /*** static ***/ int tsp = MaxTreeStackDepth; /* MR23 Remove "static" */ + +////static int nesting = 0; /* MR23 Not referenced */ + + if ( *cursor == NULL ) return NULL; + if ( *cursor!=this ) sib = *cursor; + else { + /* else, first time--start at top of template 't' */ + tsp = MaxTreeStackDepth; + sib = this; + /* bottom of stack is always a NULL--"cookie" indicates "done" */ + _push(template_stack, &tsp, NULL); + } + +keep_looking: + if ( sib==NULL ) /* hit end of sibling list */ + { + sib = _pop(template_stack, &tsp); + if ( sib == NULL ) { *cursor = NULL; return NULL; } + } + + if ( sib->type() != u->type() ) + { + /* look for another match */ + if ( sib->down()!=NULL ) + { + if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right()); + sib=sib->down(); + goto keep_looking; + } + /* nothing below to try, try next sibling */ + sib=sib->right(); + goto keep_looking; + } + + /* found a matching root node, try to match what's below */ + if ( match_partial(sib, u) ) + { + /* record sibling cursor so we can pick up next from there */ + if ( sib->down()!=NULL ) + { + if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right()); + *cursor = sib->down(); + } + else if ( sib->right()!=NULL ) *cursor = sib->right(); + else *cursor = _pop(template_stack, &tsp); + return sib; + } + + /* no match, keep searching */ + if ( sib->down()!=NULL ) + { + if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right()); + sib=sib->down(); + } + else sib = sib->right(); /* else, try to right if zip below */ + goto keep_looking; +} + +/* are two trees exactly alike? */ +int PCCTS_AST:: +match(PCCTS_AST *u) +{ + PCCTS_AST *t = this; + PCCTS_AST *sib; + + if ( u==NULL ) return 0; + + for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right()) + { + if ( sib->type() != u->type() ) return 0; + if ( sib->down()!=NULL ) + if ( !sib->down()->match(u->down()) ) return 0; + } + return 1; +} + +/* Is 'u' a subtree of 't' beginning at the root? */ +int PCCTS_AST:: +match_partial(PCCTS_AST *t, PCCTS_AST *u) +{ + PCCTS_AST *sib; + + if ( u==NULL ) return 1; + if ( t==NULL ) return 0; /* MR23 removed unreachable code */ + + for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right()) + { + if ( sib->type() != u->type() ) return 0; + if ( sib->down()!=NULL ) + if ( !match_partial(sib->down(), u->down()) ) return 0; + } + return 1; +} + +#ifdef _MSC_VER // MR23 +//Turn off "unreachable code" warning +#pragma warning(disable : 4702) +#endif +/* Walk the template tree 't' (matching against 'this'), filling in the + * 'labels' array, and setting 'n' according to how many labels were matched. + */ +int PCCTS_AST:: +scanmatch(ScanAST *t, PCCTS_AST **labels[], int *n) +{ + ScanAST *sib; + PCCTS_AST *u = this; + + if ( u==NULL ) return 0; + + for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right()) + { + /* make sure tokens match; token of '0' means wildcard match */ + if ( sib->type() != u->type() && sib->type()!=0 ) return 0; + /* we have a matched token here; set label pointers if exists */ + if ( sib->label_num>0 ) + { + require(labels!=NULL, "label found in template, but no array of labels"); + (*n)++; + *(labels[sib->label_num-1]) = u; + } + /* match what's below if something there and current node is not wildcard */ + if ( sib->down()!=NULL && sib->type()!=0 ) + { + if ( sib->down()==NULL ) + { + if ( u->down()!=NULL ) + return 0; + else + return 1; + } + if ( !u->down()->scanmatch(sib->down(), labels, n) ) return 0; + } + } + return 1; +} +#ifdef _MSC_VER // MR23 +#pragma warning(default : 4702) +#endif + +void PCCTS_AST:: +insert_after(PCCTS_AST *b) +{ + PCCTS_AST *end; + if ( b==NULL ) return; + /* find end of b's child list */ + for (end=b; end->right()!=NULL; end=end->right()) {;} + end->setRight(this->right()); + this->setRight(b); +} + +void PCCTS_AST:: +append(PCCTS_AST *b) +{ + PCCTS_AST *end; + require(b!=NULL, "append: NULL input tree"); + /* find end of child list */ + for (end=this; end->right()!=NULL; end=end->right()) {;} + end->setRight(b); +} + +PCCTS_AST *PCCTS_AST:: +tail() +{ + PCCTS_AST *end; + /* find end of child list */ + for (end=this; end->right()!=NULL; end=end->right()) {;} + return end; +} + +PCCTS_AST *PCCTS_AST:: +bottom() +{ + PCCTS_AST *end; + /* find end of child list */ + for (end=this; end->down()!=NULL; end=end->down()) {;} + return end; +} + +PCCTS_AST *PCCTS_AST:: +cut_between(PCCTS_AST *a, PCCTS_AST *b) +{ + PCCTS_AST *end, *ret; + if (a==NULL||b==NULL) return NULL; + /* find node pointing to b */ + for (end=a; end->right()!=NULL&&end->right()!=b; end=end->right()) + {;} + if (end->right()==NULL) return NULL; //ast_cut_between: a,b not connected + end->setRight(NULL); /* don't want it point to 'b' anymore */ + ret = a->right(); + a->setRight(b); + return ret; +} + +#ifdef NOT_YET +SList *PCCTS_AST:: +to_slist() +{ + SList *list = new SList; + PCCTS_AST *p; + + for (p=this; p!=NULL; p=p->right()) + { + list->add(p); + } + return list; +} +#endif + +void PCCTS_AST:: +tfree() +{ + PCCTS_AST *t = this; + if ( t->down()!=NULL ) t->down()->tfree(); + if ( t->right()!=NULL ) t->right()->tfree(); + delete t; +} + +int PCCTS_AST:: +nsiblings() +{ + PCCTS_AST *t = this; + int n=0; + + while ( t!=NULL ) + { + n++; + t = t->right(); + } + return n; +} + +PCCTS_AST *PCCTS_AST:: +sibling_index(int i) +{ + PCCTS_AST *t = this; + int j=1; + require(i>0, "sibling_index: i<=0"); + + while ( t!=NULL ) + { + if ( j==i ) return t; + j++; + t = t->right(); + } + return NULL; +} + +/* Assume this is a root node of a tree-- + * duplicate that node and what's below; ignore siblings of root node. + */ + +// MR9 23-Sep-97 RJV +// MR9 +// MR9 RJV: Original version only duplicated the node and down elements. +// MR9 Made copies of the pointers to sibling. +// MR9 Changed call "down()->deepCopy()" to "down()->deepCopyBushy()" +// MR9 + +PCCTS_AST *PCCTS_AST:: +deepCopy() +{ + PCCTS_AST *u = this->shallowCopy(); + if ( down()!=NULL ) u->setDown(down()->deepCopyBushy()); + u->setRight(NULL); + return u; +} + +/* Copy all nodes including siblings of root. */ +PCCTS_AST *PCCTS_AST:: +deepCopyBushy() +{ + PCCTS_AST *u = this->shallowCopy(); + /* copy the rest of the tree */ + if ( down()!=NULL ) u->setDown(down()->deepCopyBushy()); + if ( right()!=NULL ) u->setRight(right()->deepCopyBushy()); + return u; +} + +void PCCTS_AST:: +scanast_free(ScanAST *t) +{ + if ( t == NULL ) return; + scanast_free( t->down() ); + scanast_free( t->right() ); + free( (char *) t ); // MR1 +} + +/* + * scan + * + * This function is like scanf(): it attempts to match a template + * against an input tree. A variable number of tree pointers + * may be set according to the '%i' labels in the template string. + * For example: + * + * t->ast_scan("#( 6 #(5 %1:4 %2:3) #(1 %3:3 %4:3) )", + * &w, &x, &y, &z); + * + * Naturally, you'd want this converted from + * + * t->ast_scan("#( RangeOp #(Minus %1:IConst %2:Var) #(Plus %3:Var %4Var) )", + * &w, &x, &y, &z); + * + * by SORCERER. + * + * This function call must be done withing a SORCERER file because SORCERER + * must convert the token references to the associated token number. + * + * This functions parses the template and creates trees which are then + * matched against the input tree. The labels are set as they are + * encountered; hence, partial matches may leave some pointers set + * and some NULL. This routines initializes all argument pointers to NULL + * at the beginning. + * + * This function returns the number of labels matched. + */ +int PCCTS_AST:: +ast_scan(char *templ, ...) +{ + va_list ap; + ScanAST *tmpl; + int n, i, found=0; + PCCTS_AST ***label_ptrs=NULL; + + va_start(ap, templ); + + /* make a ScanAST tree out of the template */ + tmpl = stringparser_parse_scanast(templ, &n); + + /* make an array out of the labels */ + if ( n>0 ) + { + label_ptrs = (PCCTS_AST ***) calloc(n, sizeof(PCCTS_AST **)); + require(label_ptrs!=NULL, "scan: out of memory"); + for (i=1; i<=n; i++) + { + label_ptrs[i-1] = va_arg(ap, PCCTS_AST **); + *(label_ptrs[i-1]) = NULL; + } + } + + /* match the input tree against the template */ + scanmatch(tmpl, label_ptrs, &found); + + scanast_free(tmpl); + free( (char *) label_ptrs); // MR1 + + return found; +} + +ScanAST *PCCTS_AST:: +new_scanast(int tok) +{ + ScanAST *p = (ScanAST *) calloc(1, sizeof(ScanAST)); +// +// 7-Apr-97 133MR1 +// + if ( p == NULL ) + panic("out of memory\n"); // MR23 + p->_token = tok; + return p; +} + +ScanAST *PCCTS_AST:: +stringparser_parse_scanast(char *templ, int *num_labels) +{ + StringLexer lex; + StringParser parser; + ScanAST *t; + + stringlexer_init(&lex, templ); + stringparser_init(&parser, &lex); + t = stringparser_parse_tree(&parser); + *num_labels = parser.num_labels; + return t; +} + +void PCCTS_AST:: +stringparser_match(StringParser *parser, int token) +{ + if ( parser->token != token ) panic("bad tree in scan()"); +} + +/* + * Match a tree of the form: + * (root child1 child2 ... childn) + * or, + * node + * + * where the elements are integers or labeled integers. + */ +ScanAST *PCCTS_AST:: +stringparser_parse_tree(StringParser *parser) +{ + ScanAST *t=NULL, *root, *child, *last=NULL /*MR23*/; + + if ( parser->token != __POUND ) + { + return stringparser_parse_element(parser); + } + stringparser_match(parser,__POUND); + parser->token = stringscan_gettok(parser->lexer); + stringparser_match(parser,__LPAREN); + parser->token = stringscan_gettok(parser->lexer); + root = stringparser_parse_element(parser); + while ( parser->token != __RPAREN ) + { + child = stringparser_parse_element(parser); + if ( t==NULL ) { t = child; last = t; } + else { last->_right = child; last = child; } + } + stringparser_match(parser,__RPAREN); + parser->token = stringscan_gettok(parser->lexer); + root->_down = t; + return root; +} + +ScanAST *PCCTS_AST:: +stringparser_parse_element(StringParser *parser) +{ + char ebuf[100]; + int label = 0; + + if ( parser->token == __POUND ) + { + return stringparser_parse_tree(parser); + } + if ( parser->token == __PERCENT ) + { + parser->token = stringscan_gettok(parser->lexer); + stringparser_match(parser,__INT); + label = atoi(parser->lexer->text); + parser->num_labels++; + if ( label==0 ) panic("%%0 is an invalid label"); + parser->token = stringscan_gettok(parser->lexer); + stringparser_match(parser,__COLON); + parser->token = stringscan_gettok(parser->lexer); + /* can label tokens and wildcards */ + if ( parser->token != __INT && parser->token != __PERIOD ) + panic("can only label tokens"); + } + if ( parser->token == __INT ) + { + ScanAST *p = new_scanast(atoi(parser->lexer->text)); + parser->token = stringscan_gettok(parser->lexer); + p->label_num = label; + return p; + } + if ( parser->token == __PERIOD ) + { + ScanAST *p = new_scanast(0); /* token of 0 is wildcard */ + parser->token = stringscan_gettok(parser->lexer); + p->label_num = label; + return p; + } + sprintf(ebuf, "mismatch token in scan(): %s", scan_token_str(parser->token)); + panic(ebuf); + return NULL; +} + +void PCCTS_AST:: +stringparser_init(StringParser *parser, StringLexer *input) +{ + parser->lexer = input; + parser->token = stringscan_gettok(parser->lexer); + parser->num_labels = 0; +} + +void PCCTS_AST:: +stringlexer_init(StringLexer *scanner, char *input) +{ + scanner->text[0]='\0'; + scanner->input = input; + scanner->p = input; + stringscan_advance(scanner); +} + +void PCCTS_AST:: +stringscan_advance(StringLexer *scanner) +{ + if ( *(scanner->p) == '\0' ) scanner->c = __StringScanEOF; + scanner->c = *(scanner->p)++; +} + +int PCCTS_AST:: +stringscan_gettok(StringLexer *scanner) +{ + char *index = &scanner->text[0]; + char ebuf[100]; /* MR23 Remove static */ + + while ( isspace(scanner->c) ) { stringscan_advance(scanner); } + if ( isdigit(scanner->c) ) + { + int tok = __INT; + while ( isdigit(scanner->c) ) { + *index++ = (char) /* static_cast */ (scanner->c); // MR23 + stringscan_advance(scanner); + } + *index = '\0'; + return tok; + } + switch ( scanner->c ) + { + case '#' : stringscan_advance(scanner); return __POUND; + case '(' : stringscan_advance(scanner); return __LPAREN; + case ')' : stringscan_advance(scanner); return __RPAREN; + case '%' : stringscan_advance(scanner); return __PERCENT; + case ':' : stringscan_advance(scanner); return __COLON; + case '.' : stringscan_advance(scanner); return __PERIOD; + case '\0' : return __StringScanEOF; + case __StringScanEOF : return __StringScanEOF; + default : + sprintf(ebuf, "invalid char in scan: '%c'", scanner->c); + panic(ebuf); + } + return __StringScanEOF; // never reached +} + +const char *PCCTS_AST:: /* MR20 const */ +scan_token_str(int t) +{ + if ( VALID_SCAN_TOKEN(t) ) return scan_token_tbl[t]; + else if ( t==__StringScanEOF ) return ""; + else return ""; +} + +//MR23 +int PCCTS_AST::printMessage(FILE* pFile, const char* pFormat, ...) +{ + va_list marker; + va_start( marker, pFormat ); + int iRet = vfprintf(pFile, pFormat, marker); + va_end( marker ); + return iRet; +} diff --git a/Tools/CodeTools/Source/Pccts/h/PCCTSAST.h b/Tools/CodeTools/Source/Pccts/h/PCCTSAST.h new file mode 100644 index 0000000000..3485da7d1b --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/PCCTSAST.h @@ -0,0 +1,143 @@ +/* Abstract syntax tree + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +#ifndef PCCTSAST_H +#define PCCTSAST_H + +#include "pcctscfg.h" + +#include "pccts_stdio.h" +#include "pccts_stdlib.h" + +PCCTS_NAMESPACE_STD + +//class SList; + +#define StringScanMaxText 50 +#define MaxTreeStackDepth 400 + +// +// 7-Apr-97 133MR1 signed int not accepted by AT&T cfront +// +typedef struct stringlexer { + int c; // MR1 + char *input; + char *p; + char text[StringScanMaxText]; + } StringLexer; + +/* Define the structures needed for ast_scan() */ +typedef struct stringparser { + int token; + StringLexer *lexer; + int num_labels; + } StringParser; + +typedef struct _scanast { + struct _scanast *_right, *_down; + int _token; + int label_num; + int type() { return _token; } + struct _scanast *right() { return _right; } + struct _scanast *down() { return _down; } + } ScanAST; + +#define VALID_SCAN_TOKEN(t) (t>=__LPAREN && t<=__PERIOD) + +class DllExportPCCTS PCCTS_AST { +protected: + static const char *scan_token_tbl[]; /* MR20 const */ + enum { + __LPAREN=1, + __RPAREN=2, + __PERCENT=3, + __INT=4, + __COLON=5, + __POUND=6, + __PERIOD=7, + __StringScanEOF=-1}; + +protected: + const char *scan_token_str(int t); /* MR20 const */ + void stringlexer_init(StringLexer *scanner, char *input); + void stringparser_init(StringParser *, StringLexer *); + ScanAST *stringparser_parse_scanast(char *templ, int *n); + ScanAST *stringparser_parse_tree(StringParser *parser); + ScanAST *stringparser_parse_element(StringParser *parser); + void stringscan_advance(StringLexer *scanner); + int stringscan_gettok(StringLexer *scanner); + void _push(PCCTS_AST **st, int *sp, PCCTS_AST *e); + PCCTS_AST *_pop(PCCTS_AST **st, int *sp); + int match_partial(PCCTS_AST *t, PCCTS_AST *u); + int scanmatch(ScanAST *t, PCCTS_AST **labels[], int *n); + void scanast_free(ScanAST *t); + ScanAST *new_scanast(int tok); + void stringparser_match(StringParser *parser, int type); + virtual PCCTS_AST *deepCopyBushy(); + +public: + PCCTS_AST() {;} + virtual ~PCCTS_AST() {;} + + /* This group must be defined for SORCERER to work correctly */ + virtual PCCTS_AST *right() = 0; + virtual PCCTS_AST *down() = 0; + virtual void setRight(PCCTS_AST *t) = 0; + virtual void setDown(PCCTS_AST *t) = 0; +// we define these so ANTLR doesn't have to + virtual int type() { return 0; } + virtual void setType(int /*t MR23 */) {;} + virtual PCCTS_AST *shallowCopy() {panic("no shallowCopy() defined"); return NULL;} + + /* These are not needed by ANTLR, but are support functions */ + virtual PCCTS_AST *deepCopy(); // used by SORCERER in transform mode + virtual void addChild(PCCTS_AST *t); + virtual void lisp_action(FILE * /*f MR23 */) {;} + virtual void lisp(FILE *f); + static PCCTS_AST *make(PCCTS_AST *rt, ...); + virtual PCCTS_AST *ast_find_all(PCCTS_AST *u, PCCTS_AST **cursor); + virtual int match(PCCTS_AST *u); + virtual void insert_after(PCCTS_AST *b); + virtual void append(PCCTS_AST *b); + virtual PCCTS_AST *tail(); + virtual PCCTS_AST *bottom(); + static PCCTS_AST *cut_between(PCCTS_AST *a, PCCTS_AST *b); +// virtual SList *to_slist(); + virtual void tfree(); + int ast_scan(char *templ, ...); + virtual int nsiblings(); + virtual PCCTS_AST *sibling_index(int i); + + void require(int e,const char *err){ if ( !e ) panic(err); } /* MR20 const */ + virtual void panic(const char *err) // MR20 const + { /* MR23 */ printMessage(stderr, "PCCTS_AST: %s\n", err); exit(PCCTS_EXIT_FAILURE); } + virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23 +}; + +#endif /* PCCTSAST_H */ diff --git a/Tools/CodeTools/Source/Pccts/h/SList.h b/Tools/CodeTools/Source/Pccts/h/SList.h new file mode 100644 index 0000000000..5b8bf97427 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/SList.h @@ -0,0 +1,72 @@ +#ifndef SList_h +#define SList_h + +/* + * SList.h + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to SORCERER -- SORCERER is in the public + * domain. An individual or company may do whatever they wish with + * source code distributed with SORCERER or the code generated by + * SORCERER, including the incorporation of SORCERER, or its output, into + * commerical software. + * + * We encourage users to develop software with SORCERER. However, we do + * ask that credit is given to us for developing SORCERER. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like SORCERER and have developed a nice tool with the + * output, please mention that you developed it using SORCERER. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * PCCTS 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1992-2000 + */ + +#include "pcctscfg.h" + +#include "pccts_stdio.h" +#include "pccts_stdlib.h" + +PCCTS_NAMESPACE_STD + +#include "PCCTSAST.h" + +class PCCTS_AST; + +class SListNode { +protected: + void *_elem; /* pointer to any kind of element */ + SListNode *_next; +public: + SListNode() {_elem=_next=NULL;} + virtual ~SListNode() {_elem=_next=NULL;} + void *elem() { return _elem; } + void setElem(void *e) { _elem = e; } + void setNext(SListNode *t) { _next = t; } + SListNode *next() { return _next; } +}; + +class SList { + SListNode *head, *tail; +public: + SList() {head=tail=NULL;} + virtual ~SList() {head=tail=NULL;} + virtual void *iterate(SListNode **); + virtual void add(void *e); + virtual void lfree(); + virtual PCCTS_AST *to_ast(SList list); + virtual void require(int e,char *err){ if ( !e ) panic(err); } + virtual void panic(char *err){ /* MR23 */ printMessage(stderr, "SList panic: %s\n", err); exit(PCCTS_EXIT_FAILURE); } + virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23 +}; + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/antlr.h b/Tools/CodeTools/Source/Pccts/h/antlr.h new file mode 100644 index 0000000000..80664535d3 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/antlr.h @@ -0,0 +1,807 @@ +/* antlr.h + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +#ifndef ANTLR_H +#define ANTLR_H + +#include "pcctscfg.h" + +#include "pccts_stdio.h" + +/* turn off warnings for unreferenced labels */ + +#ifdef _MSC_VER +#pragma warning(disable:4102) +#endif + +/* + * Define all of the stack setup and manipulation of $i, #i variables. + * + * Notes: + * The type 'Attrib' must be defined before entry into this .h file. + */ + + +#ifdef __USE_PROTOS +#include "pccts_stdlib.h" +#else +#ifdef VAXC +#include +#else +#include +#endif +#endif +#include "pccts_string.h" + +#if 0 +#include "set.h" +#endif + + +typedef int ANTLRTokenType; +typedef unsigned char SetWordType; + +typedef char ANTLRChar; + + /* G u e s s S t u f f */ + +#ifdef ZZCAN_GUESS +#ifndef ZZINF_LOOK +#define ZZINF_LOOK +#endif +#endif + +#ifdef ZZCAN_GUESS +typedef struct _zzjmp_buf { + jmp_buf state; + } zzjmp_buf; +#endif + + +/* can make this a power of 2 for more efficient lookup */ + +#ifndef ZZLEXBUFSIZE +#define ZZLEXBUFSIZE 8000 /* MR22 raise from 2k to 8k */ +#endif + +#define zzOvfChk \ + if ( zzasp <= 0 ) \ + { \ + fprintf(stderr, zzStackOvfMsg, __FILE__, __LINE__); \ + exit(PCCTS_EXIT_FAILURE); \ + } + +#ifndef ZZA_STACKSIZE +#define ZZA_STACKSIZE 400 +#endif +#ifndef ZZAST_STACKSIZE +#define ZZAST_STACKSIZE 400 +#endif + +#ifndef zzfailed_pred +#ifdef ZZCAN_GUESS +#define zzfailed_pred(_p,_hasuseraction,_useraction) \ + if (zzguessing) { \ + zzGUESS_FAIL; \ + } else { \ + zzfailed_pred_action(_p,_hasuseraction,_useraction); \ + } +#else +#define zzfailed_pred(_p,_hasuseraction,_useraction) \ + zzfailed_pred_action(_p,_hasuseraction,_useraction); +#endif +#endif + +/* MR23 Provide more control over failed predicate action + without any need for user to worry about guessing internals. + _hasuseraction == 0 => no user specified error action + _hasuseraction == 1 => user specified error action +*/ + +#ifndef zzfailed_pred_action +#define zzfailed_pred_action(_p,_hasuseraction,_useraction) \ + if (_hasuseraction) { _useraction } \ + else { fprintf(stderr, "semantic error; failed predicate: '%s'\n",_p); } +#endif + +/* MR19 zzchar_t additions */ + +#ifdef LL_K +#define LOOKAHEAD \ + int zztokenLA[LL_K]; \ + zzchar_t zztextLA[LL_K][ZZLEXBUFSIZE]; \ + int zzlap = 0, zzlabase=0; /* labase only used for DEMAND_LOOK */ +#else +#define LOOKAHEAD \ + int zztoken; +#endif + +#ifndef zzcr_ast +#define zzcr_ast(ast,attr,tok,text) +#endif + +#ifdef DEMAND_LOOK +#define DemandLookData int zzdirty=1; +#else +#define DemandLookData +#endif + +#ifndef zzUSER_GUESS_HOOK +#define zzUSER_GUESS_HOOK(seqFrozen,zzrv) +#endif + +#ifndef zzUSER_GUESS_DONE_HOOK +#define zzUSER_GUESS_DONE_HOOK(seqFrozen) +#endif + + /* S t a t e S t u f f */ + +#ifdef ZZCAN_GUESS +#define zzGUESS_BLOCK zzantlr_state zzst; int zzrv; int zzGuessSeqFrozen; + +/* MR10 change zzGUESS: do zzGUESS_DONE when zzrv==1 after longjmp as in C++ mode */ + +#define zzGUESS zzsave_antlr_state(&zzst); \ + zzguessing = 1; \ + zzGuessSeqFrozen=++zzGuessSeq; \ + zzrv = setjmp(zzguess_start.state); \ + zzUSER_GUESS_HOOK(zzGuessSeqFrozen,zzrv) \ + if (zzrv) zzGUESS_DONE; +#ifdef zzTRACE_RULES +#define zzGUESS_FAIL { zzTraceGuessFail(); longjmp(zzguess_start.state, 1); } +#else +#define zzGUESS_FAIL longjmp(zzguess_start.state, 1) +#endif + +/* MR10 change zzGUESS_DONE: zzrv=1 to simulate longjmp() return value as in C++ mode */ + +#define zzGUESS_DONE { zzrestore_antlr_state(&zzst); zzrv=1; zzUSER_GUESS_DONE_HOOK(zzGuessSeqFrozen) } +#define zzNON_GUESS_MODE if ( !zzguessing ) +#define zzGuessData \ + zzjmp_buf zzguess_start; \ + int zzguessing; +#else +#define zzGUESS_BLOCK +#define zzGUESS +#define zzGUESS_FAIL +#define zzGUESS_DONE +#define zzNON_GUESS_MODE +#define zzGuessData +#endif + +typedef struct _zzantlr_state { +#ifdef ZZCAN_GUESS + zzjmp_buf guess_start; + int guessing; +#endif + int asp; + int ast_sp; +#ifdef ZZINF_LOOK + int inf_lap; /* not sure we need to save this one */ + int inf_labase; + int inf_last; + +/* MR6 Gunnar Rxnning (gunnar@candleweb.no) */ +/* MR6 Additional state needs to be saved/restored */ +/* MR6 Matching changes in err.h */ + + int *inf_tokens; /* MR6 */ + char **inf_text; /* MR6 */ + char *inf_text_buffer; /* MR6 */ + int *inf_line; /* MR6 */ +#endif +#ifdef DEMAND_LOOK + int dirty; +#endif + +#ifdef LL_K + int tokenLA[LL_K]; + char textLA[LL_K][ZZLEXBUFSIZE]; + int lap; + int labase; +#else + int token; + char text[ZZLEXBUFSIZE]; +#endif +#ifdef zzTRACE_RULES + int traceOptionValue; /* MR10 */ + int traceGuessOptionValue; /* MR10 */ + char *traceCurrentRuleName; /* MR10 */ + int traceDepth; /* MR10 */ +#endif + + } zzantlr_state; + +#ifdef zzTRACE_RULES +extern int zzTraceOptionValueDefault; +extern int zzTraceOptionValue; +extern int zzTraceGuessOptionValue; +extern char *zzTraceCurrentRuleName; +extern int zzTraceDepth; +#endif + +extern int zzGuessSeq; /* MR10 */ +extern int zzSyntaxErrCount; /* MR11 */ +extern int zzLexErrCount; /* MR11 */ + + /* I n f i n i t e L o o k a h e a d */ + + +#ifdef ZZINF_LOOK +#define InfLookData \ + int *zzinf_tokens; \ + char **zzinf_text; \ + char *zzinf_text_buffer; \ + int *zzinf_line; \ + int zzinf_labase; \ + int zzinf_last; +#else +#define InfLookData +#endif + +#ifdef ZZINF_LOOK + +#ifndef ZZINF_DEF_TEXT_BUFFER_SIZE +#define ZZINF_DEF_TEXT_BUFFER_SIZE 20000 +#endif +#ifndef ZZINF_DEF_TOKEN_BUFFER_SIZE +#define ZZINF_DEF_TOKEN_BUFFER_SIZE 2000 +#endif +/* WARNING!!!!!! + * ZZINF_BUFFER_TEXT_CHUNK_SIZE must be > sizeof(text) largest possible token. + */ +#ifndef ZZINF_BUFFER_TEXT_CHUNK_SIZE +#define ZZINF_BUFFER_TEXT_CHUNK_SIZE 5000 +#endif +#ifndef ZZINF_BUFFER_TOKEN_CHUNK_SIZE +#define ZZINF_BUFFER_TOKEN_CHUNK_SIZE 1000 +#endif + +#if ZZLEXBUFSIZE > ZZINF_BUFFER_TEXT_CHUNK_SIZE +#define ZZINF_BUFFER_TEXT_CHUNK_SIZE ZZLEXBUFSIZE+5 +#endif + +/* make inf_look user-access macros */ +#ifdef LL_K +#define ZZINF_LA_VALID(i) (((zzinf_labase+i-1)-LL_K+1) <= zzinf_last) +#define ZZINF_LA(i) zzinf_tokens[(zzinf_labase+i-1)-LL_K+1] +#define ZZINF_LATEXT(i) zzinf_text[(zzinf_labase+i-1)-LL_K+1] +/* MR6 In 1.33 vanilla the #define ZZINF_LINE(i) is was commented out */ +#define ZZINF_LINE(i) zzinf_line[(zzinf_labase+i-1)-LL_K+1] +#else +#define ZZINF_LA_VALID(i) (((zzinf_labase+i-1)) <= zzinf_last) +#define ZZINF_LA(i) zzinf_tokens[(zzinf_labase+i-1)] +#define ZZINF_LATEXT(i) zzinf_text[(zzinf_labase+i-1)] +#endif + +#define inf_zzgettok _inf_zzgettok() +extern void _inf_zzgettok(); + +#endif /* ZZINF_LOOK */ + + +#ifdef LL_K + +#ifdef __USE_PROTOS +#define ANTLR_INFO \ + Attrib zzempty_attr(void) {static Attrib a; return a;} \ + Attrib zzconstr_attr(int _tok, char *_text) \ + {Attrib a; zzcr_attr((&a),_tok,_text); return a;} \ + int zzasp=ZZA_STACKSIZE; \ + char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n"; \ + Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData \ + InfLookData \ + zzGuessData +#else +#define ANTLR_INFO \ + Attrib zzempty_attr() {static Attrib a; return a;} \ + Attrib zzconstr_attr(_tok, _text) int _tok; char *_text; \ + {Attrib a; zzcr_attr((&a),_tok,_text); return a;} \ + int zzasp=ZZA_STACKSIZE; \ + char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n"; \ + Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData \ + InfLookData \ + zzGuessData +#endif + +#else + +#ifdef __USE_PROTOS +#define ANTLR_INFO \ + Attrib zzempty_attr(void) {static Attrib a; return a;} \ + Attrib zzconstr_attr(int _tok, char *_text) \ + {Attrib a; zzcr_attr((&a),_tok,_text); return a;} \ + int zzasp=ZZA_STACKSIZE; \ + char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n"; \ + Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData \ + InfLookData \ + zzGuessData +#else +#define ANTLR_INFO \ + Attrib zzempty_attr() {static Attrib a; return a;} \ + Attrib zzconstr_attr(_tok, _text) int _tok; char *_text; \ + {Attrib a; zzcr_attr((&a),_tok,_text); return a;} \ + int zzasp=ZZA_STACKSIZE; \ + char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n"; \ + Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData \ + InfLookData \ + zzGuessData +#endif + +#endif /* LL_k */ + + +#ifdef ZZINF_LOOK + +#ifdef LL_K +#ifdef DEMAND_LOOK +#define zzPrimeLookAhead {zzdirty=LL_K; zzlap = zzlabase = 0;} +#else +#define zzPrimeLookAhead {zzlap = zzlabase = 0; zzfill_inf_look();\ + {int _i; for(_i=1;_i<=LL_K; _i++) \ + {zzCONSUME;} zzlap = zzlabase = 0;}} +#endif + +#else /* LL_K */ + +#ifdef DEMAND_LOOK +#define zzPrimeLookAhead zzfill_inf_look(); zzdirty=1 +#else +#define zzPrimeLookAhead zzfill_inf_look(); inf_zzgettok + +#endif +#endif /* LL_K */ + +#else /* ZZINF_LOOK */ + +#ifdef LL_K +#ifdef DEMAND_LOOK +#define zzPrimeLookAhead {zzdirty=LL_K; zzlap = zzlabase = 0;} +#else +#define zzPrimeLookAhead {int _i; zzlap = 0; for(_i=1;_i<=LL_K; _i++) \ + {zzCONSUME;} zzlap = 0;} +#endif + +#else + +#ifdef DEMAND_LOOK +#define zzPrimeLookAhead zzdirty=1 +#else +#define zzPrimeLookAhead zzgettok() +#endif +#endif /* LL_K */ + +#endif /* ZZINF_LOOK */ + + +#ifdef LL_K +#define zzenterANTLRs(s) \ + zzlextext = &(zztextLA[0][0]); zzrdstr( s ); zzPrimeLookAhead; +#define zzenterANTLRf(f) \ + zzlextext = &(zztextLA[0][0]); zzrdfunc( f ); zzPrimeLookAhead; +#define zzenterANTLR(f) \ + zzlextext = &(zztextLA[0][0]); zzrdstream( f ); zzPrimeLookAhead; +#ifdef ZZINF_LOOK +#define zzleaveANTLR(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line); +#define zzleaveANTLRf(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line); +#define zzleaveANTLRs(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line); +#else +#define zzleaveANTLR(f) +#define zzleaveANTLRf(f) +#define zzleaveANTLRs(f) +#endif + +#else + +#define zzenterANTLRs(s) \ + {static char zztoktext[ZZLEXBUFSIZE]; \ + zzlextext = zztoktext; zzrdstr( s ); zzPrimeLookAhead;} +#define zzenterANTLRf(f) \ + {static char zztoktext[ZZLEXBUFSIZE]; \ + zzlextext = zztoktext; zzrdfunc( f ); zzPrimeLookAhead;} +#define zzenterANTLR(f) \ + {static char zztoktext[ZZLEXBUFSIZE]; \ + zzlextext = zztoktext; zzrdstream( f ); zzPrimeLookAhead;} +#ifdef ZZINF_LOOK +#define zzleaveANTLR(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line); +#define zzleaveANTLRf(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line); +#define zzleaveANTLRs(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line); +#else +#define zzleaveANTLR(f) +#define zzleaveANTLRf(f) +#define zzleaveANTLRs(f) +#endif + +#endif + +/* MR19 Paul D. Smith (psmith@baynetworks.com) + Need to adjust AST stack pointer at exit. + Referenced in ANTLRx macros. +*/ + +#ifdef GENAST +#define ZZAST_ADJUST ++zzast_sp; +#else +#define ZZAST_ADJUST +#endif + +#define ANTLR(st, f) zzbufsize = ZZLEXBUFSIZE; \ + zzenterANTLR(f); \ + { \ + zzBLOCK(zztasp1); \ + st; /* ++zzasp; Removed MR20 G. Hobbelt */ \ + /* ZZAST_ADJUST Removed MR20 G. Hobbelt */ \ + /* MR20 G. Hobbelt. Kill the top' attribute (+AST stack corr.) */ \ + zzEXIT_ANTLR(zztasp1 + 1); \ + } \ + zzleaveANTLR(f); + +#define ANTLRm(st, f, _m) zzbufsize = ZZLEXBUFSIZE; \ + zzmode(_m); \ + zzenterANTLR(f); \ + { \ + zzBLOCK(zztasp1); \ + st; /* ++zzasp; Removed MR20 G. Hobbelt */ \ + /* ZZAST_ADJUST Removed MR20 G. Hobbelt */ \ + /* MR20 G. Hobbelt. Kill the top' attribute (+AST stack corr.) */ \ + zzEXIT_ANTLR(zztasp1 + 1); \ + } \ + zzleaveANTLR(f); + +#define ANTLRf(st, f) zzbufsize = ZZLEXBUFSIZE; \ + zzenterANTLRf(f); \ + { \ + zzBLOCK(zztasp1); \ + st; /* ++zzasp; Removed MR20 G. Hobbelt */ \ + /* ZZAST_ADJUST Removed MR20 G. Hobbelt */ \ + /* MR20 G. Hobbelt. Kill the top' attribute (+AST stack corr.) */ \ + zzEXIT_ANTLR(zztasp1 + 1); \ + } \ + zzleaveANTLRf(f); + +#define ANTLRs(st, s) zzbufsize = ZZLEXBUFSIZE; \ + zzenterANTLRs(s); \ + { \ + zzBLOCK(zztasp1); \ + st; /* ++zzasp; Removed MR20 G. Hobbelt */ \ + /* ZZAST_ADJUST Removed MR20 G. Hobbelt */ \ + /* MR20 G. Hobbelt. Kill the top' attribute (+AST stack corr.) */ \ + zzEXIT_ANTLR(zztasp1 + 1); \ + } \ + zzleaveANTLRs(s); + +#ifdef LL_K +#define zztext (&(zztextLA[zzlap][0])) +#else +#define zztext zzlextext +#endif + + + /* A r g u m e n t A c c e s s */ + +#define zzaCur (zzaStack[zzasp]) +#define zzaRet (*zzaRetPtr) +#define zzaArg(v,n) zzaStack[v-n] +#define zzMakeAttr { zzNON_GUESS_MODE {zzOvfChk; --zzasp; zzcr_attr(&(zzaStack[zzasp]),LA(1),LATEXT(1));}} +#ifdef zzdef0 +#define zzMake0 { zzOvfChk; --zzasp; zzdef0(&(zzaStack[zzasp]));} +#else +#define zzMake0 { zzOvfChk; --zzasp;} +#endif +#define zzaPush(_v) { zzOvfChk; zzaStack[--zzasp] = _v;} +#ifndef zzd_attr +#define zzREL(t) zzasp=(t); /* Restore state of stack */ +#else +#define zzREL(t) for (; zzasp<(t); zzasp++) \ + { zzd_attr(&(zzaStack[zzasp])); } +#endif + + +#define zzsetmatch(_es,_tokclassErrset) \ + if ( !_zzsetmatch(_es, &zzBadText, &zzMissText, &zzMissTok, &zzBadTok, &zzMissSet, _tokclassErrset) ) goto fail; /* MR23 */ + +#ifdef ZZCAN_GUESS +#define zzsetmatch_wsig(_es, handler) \ + if ( !_zzsetmatch_wsig(_es) ) if (zzguessing) { zzGUESS_FAIL; } else {_signal=MismatchedToken; goto handler;} +#else +#define zzsetmatch_wsig(_es, handler) \ + if ( !_zzsetmatch_wsig(_es) ) {_signal=MismatchedToken; goto handler;} +#endif + +#ifdef __USE_PROTOS +extern int _zzsetmatch(SetWordType *, char **, char **, int *, int *, SetWordType **, SetWordType * /* MR23 */); +extern int _zzsetmatch_wsig(SetWordType *); +#else +extern int _zzsetmatch(); +extern int _zzsetmatch_wsig(); +#endif + +#define zzmatch(_t) \ + if ( !_zzmatch(_t, &zzBadText, &zzMissText, &zzMissTok, &zzBadTok, &zzMissSet) ) goto fail; + +#ifdef ZZCAN_GUESS +#define zzmatch_wsig(_t,handler) \ + if ( !_zzmatch_wsig(_t) ) if (zzguessing) { zzGUESS_FAIL; } else {_signal=MismatchedToken; goto handler;} +#else +#define zzmatch_wsig(_t,handler) \ + if ( !_zzmatch_wsig(_t) ) {_signal=MismatchedToken; goto handler;} +#endif + +#ifdef __USE_PROTOS +extern int _zzmatch(int, char **, char **, int *, int *, SetWordType **); +extern int _zzmatch_wsig(int); +#else +extern int _zzmatch(); +extern int _zzmatch_wsig(); +#endif + +#define zzmatch_wdfltsig(_t,_f) \ + if ( !_zzmatch_wdfltsig(_t,_f) ) _signal=MismatchedToken; +#define zzsetmatch_wdfltsig(tw,tt,wf) \ + if ( !_zzsetmatch_wdfltsig(tw,tt,wf) ) _signal=MismatchedToken; + +#ifdef __USE_PROTOS +extern int _zzmatch_wdfltsig(int, SetWordType *); +extern int _zzsetmatch_wdfltsig(SetWordType *tokensWanted, + int tokenTypeOfSet, + SetWordType *whatFollows); +#else +extern int _zzmatch_wdfltsig(); +extern int _zzsetmatch_wdfltsig(); +#endif + +#ifdef GENAST +#define zzRULE Attrib *zzaRetPtr = &(zzaStack[zzasp-1]); \ + SetWordType *zzMissSet=NULL; int zzMissTok=0; \ + int zzBadTok=0; char *zzBadText=""; \ + int zzErrk=1,zzpf=0; \ + zzTRACEdata \ + char *zzMissText=""; zzASTVars +#else +#define zzRULE Attrib *zzaRetPtr = &(zzaStack[zzasp-1]); \ + int zzBadTok=0; char *zzBadText=""; \ + int zzErrk=1,zzpf=0; \ + zzTRACEdata \ + SetWordType *zzMissSet=NULL; int zzMissTok=0; char *zzMissText="" +#endif + +#ifdef GENAST +#define zzBLOCK(i) int i = zzasp - 1; int zztsp = zzast_sp +#define zzEXIT(i) zzREL(i); zzastREL; zzNON_GUESS_MODE { zzastPush(*_root); } +#define zzEXIT_ANTLR(i) zzREL(i); zzastREL /* [i_a] added as we want this for the ANTLRx() macros */ +#define zzLOOP(i) zzREL(i); zzastREL +#else +#define zzBLOCK(i) int i = zzasp - 1 +#define zzEXIT(i) zzREL(i) +#define zzEXIT_ANTLR(i) zzREL(i) /* [i_a] added as we want this for the ANTLRx() macros */ +#define zzLOOP(i) zzREL(i) +#endif + +#ifdef LL_K + +#ifdef DEMAND_LOOK +#define LOOK(_k) {int i,stop=_k-(LL_K-zzdirty); for (i=1; i<=stop; i++) \ + zzCONSUME;} +#define zzCONSUME {zzgettok(); zzdirty--; \ + zzlap = (zzlap+1)&(LL_K-1); \ + zzlextext = &(zztextLA[zzlap][0]);} +#else +#ifdef ZZINF_LOOK +#define zzCONSUME {inf_zzgettok; \ + zzlap = (zzlap+1)&(LL_K-1); \ + zzlextext = &(zztextLA[zzlap][0]); \ + } +#else +#define zzCONSUME {zzgettok(); \ + zzlap = (zzlap+1)&(LL_K-1); \ + zzlextext = &(zztextLA[zzlap][0]);} +#endif /* ZZINF_LOOK */ +#endif /* DEMAND_LOOK */ + +#else /* LL_K */ + +#ifdef DEMAND_LOOK +#define LOOK(_k) if ( zzdirty) zzCONSUME; +#ifdef ZZINF_LOOK +#define zzCONSUME inf_zzgettok; zzdirty=0; +#else +#define zzCONSUME zzgettok(); zzdirty=0; +#endif /* ZZINF_LOOK */ + +#else /* DEMAND_LOOK */ + +#ifdef ZZINF_LOOK +#define zzCONSUME inf_zzgettok +#else +#define zzCONSUME zzgettok(); +#endif + +#endif /* DEMAND_LOOK */ + +#endif /* LL_K */ + +#ifdef LL_K +#define NLA zztokenLA[zzlap&(LL_K-1)] /* --> next LA */ +#define NLATEXT zztextLA[zzlap&(LL_K-1)] /* --> next text of LA */ +#ifdef DEMAND_LOOK +#define LA(i) zztokenLA[(zzlabase+(i)-1)&(LL_K-1)] +#define LATEXT(i) (&(zztextLA[(zzlabase+(i)-1)&(LL_K-1)][0])) +#else +#define LA(i) zztokenLA[(zzlap+(i)-1)&(LL_K-1)] +#define LATEXT(i) (&(zztextLA[(zzlap+(i)-1)&(LL_K-1)][0])) +#endif +#else +#define NLA zztoken +#define NLATEXT zztext +#define LA(i) zztoken +#define LATEXT(i) zztext +#endif + + + /* S t a n d a r d S i g n a l s */ + +#define NoSignal 0 +#define MismatchedToken 1 +#define NoViableAlt 2 +#define NoSemViableAlt 3 + +/* MR7 Allow more control over signalling */ +/* by adding "Unwind" and "zzsetSignal" */ + +#define Unwind 4 +#define zzsetSignal(newValue) *_retsignal=_signal=(newValue) +#define zzsuppressSignal *_retsignal=_signal=0 +#define zzexportSignal *_retsignal=_signal + + /* F u n c t i o n T r a c i n g */ + +#ifndef zzTRACE_RULES +#define zzTRACEdata +#else +#ifndef zzTRACEdata +#define zzTRACEdata ANTLRChar *zzTracePrevRuleName = NULL; +#endif +#endif + +#ifndef zzTRACEIN +#define zzTRACEIN(r) zzTracePrevRuleName=zzTraceCurrentRuleName;zzTraceIn(r); +#endif +#ifndef zzTRACEOUT +#define zzTRACEOUT(r) zzTraceOut(r);zzTraceCurrentRuleName=zzTracePrevRuleName; +#endif + +/* MR19 zzchar_t additions */ + +#ifndef zzchar_t +#ifdef ZZWCHAR_T +#define zzchar_t wchar_t +#else +#define zzchar_t char +#endif +#endif + + +/* MR26 */ + +#ifdef PCCTS_USE_STDARG +extern void zzFAIL(int k, ...); +#else +extern void zzFAIL(); +#endif + /* E x t e r n D e f s */ + +#ifdef __USE_PROTOS +extern Attrib zzempty_attr(void); +extern Attrib zzconstr_attr(int, char *); +extern void zzsyn(char *, int, char *, SetWordType *, int, int, char *); +extern int zzset_el(unsigned, SetWordType *); +extern int zzset_deg(SetWordType *); +extern void zzedecode(SetWordType *); + +extern void zzresynch(SetWordType *, SetWordType); +extern void zzsave_antlr_state(zzantlr_state *); +extern void zzrestore_antlr_state(zzantlr_state *); +extern void zzfill_inf_look(void); +extern void zzconsumeUntil(SetWordType *st); /* MR7 */ +extern void zzconsumeUntilToken(int t); /* MR7 */ +extern void zzTraceIn(char * ruleName); /* MR10 */ +extern void zzTraceOut(char * ruleName); /* MR10 */ +extern int zzTraceOption(int delta); /* MR10 */ +extern int zzTraceGuessOption(int delta); /* MR10 */ +extern void zzTraceReset(void); /* MR10 */ +extern void zzTraceGuessFail(void); /* MR10 */ +#ifdef EXCEPTION_HANDLING +extern void zzdflthandlers(int, int *); +#endif +#else +extern Attrib zzempty_attr(); +extern Attrib zzconstr_attr(); +extern void zzsyn(); +extern int zzset_el(); +extern int zzset_deg(); +extern void zzedecode(); +extern void zzresynch(); +extern void zzsave_antlr_state(); +extern void zzrestore_antlr_state(); +extern void zzfill_inf_look(); +extern void zzconsumeUntil(); /* MR7 */ +extern void zzconsumeUntilToken(); /* MR7 */ +extern void zzTraceIn(); /* MR10 */ +extern void zzTraceOut(); /* MR10 */ +extern int zzTraceOption(); /* MR10 */ +extern int zzTraceGuessOption(); /* MR10 */ +extern void zzTraceReset(); /* MR10 */ +extern void zzTraceGuessFail(); /* MR10 */ +#ifdef EXCEPTION_HANDLING +extern void zzdflthandlers(); +#endif +#endif + + /* G l o b a l V a r i a b l e s */ + +/* Define a parser; user should do a "#parser myname" in their grammar file */ +/*extern struct pccts_parser zzparser;*/ + +extern char *zztokens[]; +#ifdef LL_K +extern int zztokenLA[]; +extern zzchar_t zztextLA[][ZZLEXBUFSIZE]; +extern int zzlap; +extern int zzlabase; +#else +extern int zztoken; +#endif + +extern char zzStackOvfMsg[]; +extern int zzasp; +extern Attrib zzaStack[]; +#ifdef ZZINF_LOOK +extern int *zzinf_tokens; +extern char **zzinf_text; +extern char *zzinf_text_buffer; +extern int *zzinf_line; +extern int zzinf_labase; +extern int zzinf_last; +#endif +#ifdef DEMAND_LOOK +extern int zzdirty; +#endif +#ifdef ZZCAN_GUESS +extern int zzguessing; +extern zzjmp_buf zzguess_start; +#endif + +/* Define global veriables that refer to values exported by the scanner. + * These declarations duplicate those in dlgdef.h, but are needed + * if ANTLR is not to generate a .dlg file (-gx); PS, this is a hack. + */ +extern zzchar_t *zzlextext; /* text of most recently matched token */ +extern int zzbufsize; /* how long zzlextext is */ + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/ast.c b/Tools/CodeTools/Source/Pccts/h/ast.c new file mode 100644 index 0000000000..9326ae16ae --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/ast.c @@ -0,0 +1,345 @@ +/* Abstract syntax tree manipulation functions + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +#include "pcctscfg.h" + +#ifdef PCCTS_USE_STDARG +#include "pccts_stdarg.h" +#else +#include +#endif + +/* ensure that tree manipulation variables are current after a rule + * reference + */ + +void +#ifdef __USE_PROTOS +zzlink(AST **_root, AST **_sibling, AST **_tail) +#else +zzlink(_root, _sibling, _tail) +AST **_root, **_sibling, **_tail; +#endif +{ + if ( *_sibling == NULL ) return; + if ( *_root == NULL ) *_root = *_sibling; + else if ( *_root != *_sibling ) (*_root)->down = *_sibling; + if ( *_tail==NULL ) *_tail = *_sibling; + while ( (*_tail)->right != NULL ) *_tail = (*_tail)->right; +} + +AST * +#ifdef __USE_PROTOS +zzastnew(void) +#else +zzastnew() +#endif +{ + AST *p = (AST *) calloc(1, sizeof(AST)); + if ( p == NULL ) fprintf(stderr,"%s(%d): cannot allocate AST node\n",__FILE__,__LINE__); + return p; +} + +/* add a child node to the current sibling list */ +void +#ifdef __USE_PROTOS +zzsubchild(AST **_root, AST **_sibling, AST **_tail) +#else +zzsubchild(_root, _sibling, _tail) +AST **_root, **_sibling, **_tail; +#endif +{ + AST *n; + zzNON_GUESS_MODE { + n = zzastnew(); +#ifdef DEMAND_LOOK + zzcr_ast(n, &(zzaCur), LA(0), LATEXT(0)); +#else + zzcr_ast(n, &(zzaCur), LA(1), LATEXT(1)); +#endif + zzastPush( n ); + if ( *_tail != NULL ) (*_tail)->right = n; + else { + *_sibling = n; + if ( *_root != NULL ) (*_root)->down = *_sibling; + } + *_tail = n; + if ( *_root == NULL ) *_root = *_sibling; + } +} + +/* make a new AST node. Make the newly-created + * node the root for the current sibling list. If a root node already + * exists, make the newly-created node the root of the current root. + */ +void +#ifdef __USE_PROTOS +zzsubroot(AST **_root, AST **_sibling, AST **_tail) +#else +zzsubroot(_root, _sibling, _tail) +AST **_root, **_sibling, **_tail; +#endif +{ + AST *n; + zzNON_GUESS_MODE { + n = zzastnew(); +#ifdef DEMAND_LOOK + zzcr_ast(n, &(zzaCur), LA(0), LATEXT(0)); +#else + zzcr_ast(n, &(zzaCur), LA(1), LATEXT(1)); +#endif + zzastPush( n ); + if ( *_root != NULL ) + if ( (*_root)->down == *_sibling ) *_sibling = *_tail = *_root; + *_root = n; + (*_root)->down = *_sibling; + } +} + +/* Apply function to root then each sibling + * example: print tree in child-sibling LISP-format (AST has token field) + * + * void show(tree) + * AST *tree; + * { + * if ( tree == NULL ) return; + * printf(" %s", zztokens[tree->token]); + * } + * + * void before() { printf(" ("); } + * void after() { printf(" )"); } + * + * LISPdump() { zzpre_ast(tree, show, before, after); } + * + */ +void +#ifdef __USE_PROTOS +zzpre_ast( + AST *tree, + void (*func)(AST *), /* apply this to each tree node */ + void (*before)(AST *), /* apply this to root of subtree before preordering it */ + void (*after)(AST *)) /* apply this to root of subtree after preordering it */ +#else +zzpre_ast(tree, func, before, after) +AST *tree; +void (*func)(), /* apply this to each tree node */ + (*before)(), /* apply this to root of subtree before preordering it */ + (*after)(); /* apply this to root of subtree after preordering it */ +#endif +{ + while ( tree!= NULL ) + { + if ( tree->down != NULL ) (*before)(tree); + (*func)(tree); + zzpre_ast(tree->down, func, before, after); + if ( tree->down != NULL ) (*after)(tree); + tree = tree->right; + } +} + +/* free all AST nodes in tree; apply func to each before freeing */ + +#if 0 +////void +////#ifdef __USE_PROTOS +////zzfree_ast(AST *tree) +////#else +////zzfree_ast(tree) +////AST *tree; +////#endif +////{ +//// if ( tree == NULL ) return; +//// zzfree_ast( tree->down ); +//// zzfree_ast( tree->right ); +//// zztfree( tree ); +////} +#endif + +/* + MR19 Optimize freeing of the following structure to limit recursion + SAKAI Kiyotaka (ksakai@isr.co.jp) +*/ + +/* + NULL o + / \ + NULL o + / \ + NULL NULL +*/ + +/* + MR21 Another refinement to replace recursion with iteration + NAKAJIMA Mutsuki (muc@isr.co.jp). +*/ + +void +#ifdef __USE_PROTOS +zzfree_ast(AST *tree) +#else +zzfree_ast(tree) +AST *tree; +#endif +{ + + AST *otree; + + if (tree == NULL) return; + + while (tree->down == NULL || tree->right == NULL) { + + if (tree->down == NULL && tree->right == NULL) { + zztfree(tree); + return; + } + + otree = tree; + if (tree->down == NULL) { + tree = tree->right; + } else { + tree = tree->down; + } + zztfree( otree ); + } + + while (tree != NULL) { + zzfree_ast(tree->down); + otree = tree; + tree = otree->right; + zztfree(otree); + } +} + +/* build a tree (root child1 child2 ... NULL) + * If root is NULL, simply make the children siblings and return ptr + * to 1st sibling (child1). If root is not single node, return NULL. + * + * Siblings that are actually siblins lists themselves are handled + * correctly. For example #( NULL, #( NULL, A, B, C), D) results + * in the tree ( NULL A B C D ). + * + * Requires at least two parameters with the last one being NULL. If + * both are NULL, return NULL. + */ +#ifdef PCCTS_USE_STDARG +AST *zztmake(AST *rt, ...) +#else +AST *zztmake(va_alist) +va_dcl +#endif +{ + va_list ap; + register AST *child, *sibling=NULL, *tail=NULL /* MR20 */, *w; + AST *root; + +#ifdef PCCTS_USE_STDARG + va_start(ap, rt); + root = rt; +#else + va_start(ap); + root = va_arg(ap, AST *); +#endif + + if ( root != NULL ) + if ( root->down != NULL ) return NULL; + child = va_arg(ap, AST *); + while ( child != NULL ) + { + for (w=child; w->right!=NULL; w=w->right) {;} /* find end of child */ + if ( sibling == NULL ) {sibling = child; tail = w;} + else {tail->right = child; tail = w;} + child = va_arg(ap, AST *); + } + if ( root==NULL ) root = sibling; + else root->down = sibling; + va_end(ap); + return root; +} + +/* tree duplicate */ +AST * +#ifdef __USE_PROTOS +zzdup_ast(AST *t) +#else +zzdup_ast(t) +AST *t; +#endif +{ + AST *u; + + if ( t == NULL ) return NULL; + u = zzastnew(); + *u = *t; +#ifdef zzAST_DOUBLE + u->up = NULL; /* set by calling invocation */ + u->left = NULL; +#endif + u->right = zzdup_ast(t->right); + u->down = zzdup_ast(t->down); +#ifdef zzAST_DOUBLE + if ( u->right!=NULL ) u->right->left = u; + if ( u->down!=NULL ) u->down->up = u; +#endif + return u; +} + +void +#ifdef __USE_PROTOS +zztfree(AST *t) +#else +zztfree(t) +AST *t; +#endif +{ +#ifdef zzd_ast + zzd_ast( t ); +#endif + free( t ); +} + +#ifdef zzAST_DOUBLE +/* + * Set the 'up', and 'left' pointers of all nodes in 't'. + * Initial call is double_link(your_tree, NULL, NULL). + */ +void +#ifdef __USE_PROTOS +zzdouble_link(AST *t, AST *left, AST *up) +#else +zzdouble_link(t, left, up) +AST *t, *left, *up; +#endif +{ + if ( t==NULL ) return; + t->left = left; + t->up = up; + zzdouble_link(t->down, NULL, t); + zzdouble_link(t->right, t, up); +} +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/ast.h b/Tools/CodeTools/Source/Pccts/h/ast.h new file mode 100644 index 0000000000..5ff84bd76c --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/ast.h @@ -0,0 +1,121 @@ +/* Abstract syntax tree + * + * Macros, definitions + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +#ifndef ZZAST_H +#define ZZAST_H + +#define zzastOvfChk \ + if ( zzast_sp <= 0 ) \ + { \ + fprintf(stderr, zzStackOvfMsg, __FILE__, __LINE__); \ + exit(PCCTS_EXIT_FAILURE); \ + } + +#ifndef USER_DEFINED_AST +#ifndef AST_FIELDS +#define AST_FIELDS +#endif + +typedef struct _ast { + struct _ast *right, *down; +#ifdef zzAST_DOUBLE + struct _ast *left, *up; +#endif + AST_FIELDS +} AST; + +#else + +#ifdef zzAST_DOUBLE +#define AST_REQUIRED_FIELDS struct _ast *right, *down, *left, *up; +#else +#define AST_REQUIRED_FIELDS struct _ast *right, *down; +#endif + +#endif + + +/* N o d e a c c e s s m a c r o s */ +#define zzchild(t) (((t)==NULL)? (AST *) NULL:(t->down)) /* MR19 */ +#define zzsibling(t) (((t)==NULL)? (AST *) NULL:(t->right)) /* MR19 */ + + +/* define global variables needed by #i stack */ +#define zzASTgvars \ + AST *zzastStack[ZZAST_STACKSIZE]; \ + int zzast_sp = ZZAST_STACKSIZE; + +#define zzASTVars AST *_ast = NULL, *_sibling = NULL, *_tail = NULL +#define zzSTR ( (_tail==NULL)?(&_sibling):(&(_tail->right)) ) +#define zzastCur (zzastStack[zzast_sp]) +#define zzastArg(i) (zzastStack[zztsp-i]) +#define zzastPush(p) zzastOvfChk; zzastStack[--zzast_sp] = p; +#define zzastDPush --zzast_sp +#define zzastMARK zztsp=zzast_sp; /* Save state of stack */ +#define zzastREL zzast_sp=zztsp; /* Return state of stack */ +#define zzrm_ast {zzfree_ast(*_root); _tail = _sibling = (*_root)=NULL;} + +extern int zzast_sp; +extern AST *zzastStack[]; + +/* MR26 */ + +#ifdef PCCTS_USE_STDARG +AST *zztmake(AST *, ...); +#else +AST *zztmake(); +#endif + +#ifdef __USE_PROTOS +void zzlink(AST **, AST **, AST **); +void zzsubchild(AST **, AST **, AST **); +void zzsubroot(AST **, AST **, AST **); +void zzpre_ast(AST *, void (*)(AST *), void (*)(AST *), void (*)(AST *)); +void zzfree_ast(AST *); +AST *zzdup_ast(AST *); +void zztfree(AST *); +void zzdouble_link(AST *, AST *, AST *); +AST *zzastnew(void); + +#else + +void zzlink(); +AST *zzastnew(); +void zzsubchild(); +void zzsubroot(); +void zzpre_ast(); +void zzfree_ast(); +AST *zzdup_ast(); +void zztfree(); +void zzdouble_link(); +#endif + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/charbuf.h b/Tools/CodeTools/Source/Pccts/h/charbuf.h new file mode 100644 index 0000000000..5f01c8ba35 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/charbuf.h @@ -0,0 +1,46 @@ +/* ANTLR attribute definition -- constant width text + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +#ifndef ZZCHARBUF_H +#define ZZCHARBUF_H + +#include "pcctscfg.h" + +#include "pccts_string.h" + +#ifndef D_TextSize +#define D_TextSize 30 +#endif + +typedef struct { char text[D_TextSize]; } Attrib; + +#define zzcr_attr(a,tok,t) strncpy((a)->text, t, D_TextSize-1); \ + (a)->text[D_TextSize-1] = '\0'; + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/charptr.c b/Tools/CodeTools/Source/Pccts/h/charptr.c new file mode 100644 index 0000000000..d3f80e60ba --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/charptr.c @@ -0,0 +1,58 @@ +/* + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +#include "pcctscfg.h" + +#ifdef __STDC__ +#include "pccts_stdlib.h" +#else +#include +#endif +#include "pccts_string.h" + +/* 133MR1 include stdio.h for fprintf in charptr.c */ + +#include "pccts_stdio.h" + +/* 133MR1 include charptr.h for Attrib in charptr.c */ + +#include "charptr.h" + +#ifdef __USE_PROTOS +zzcr_attr(Attrib *a,int token,char *text) +#else +zzcr_attr(a,token,text) +Attrib *a; +int token; +char *text; +#endif +{ + *a = (char *) malloc(strlen(text)+1); /* MR6 */ + if ( *a == NULL ) {fprintf(stderr, "zzcr_attr: out of memory!\n"); exit(-1);} + strcpy(*a, text); +} diff --git a/Tools/CodeTools/Source/Pccts/h/charptr.h b/Tools/CodeTools/Source/Pccts/h/charptr.h new file mode 100644 index 0000000000..e73da681a4 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/charptr.h @@ -0,0 +1,48 @@ +/* + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +/* + * WARNING!!!!: charptr.h does NOT make copies and the + * memory is freed after the attribute scope exits. + */ + +#ifndef ZZCHARPTR_H +#define ZZCHARPTR_H + +typedef char *Attrib; +#define zzdef0(a) {*(a)=NULL;} +/* MR8 Jens Tingleff (jensting@imaginet.fr) */ +/* Set memory pointer to null after free() */ +#define zzd_attr(a) {if ( *(a)!=NULL ) {free(*(a)); *(a)=NULL; }; } + +#ifdef __STDC__ +extern zzcr_attr(Attrib *,int,char *); +#endif + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/config.h b/Tools/CodeTools/Source/Pccts/h/config.h new file mode 100644 index 0000000000..8aa50ad618 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/config.h @@ -0,0 +1 @@ +#include "pcctscfg.h" diff --git a/Tools/CodeTools/Source/Pccts/h/dlgauto.h b/Tools/CodeTools/Source/Pccts/h/dlgauto.h new file mode 100644 index 0000000000..db94cefaca --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/dlgauto.h @@ -0,0 +1,504 @@ +/* dlgauto.h automaton + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Will Cohen and Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +#ifndef ZZDEFAUTO_H +#define ZZDEFAUTO_H + +/* 10-Apr-97 133MR1 Uses __USE_PROTOS show should #include pcctscfg.h */ + +#include "pcctscfg.h" + +zzchar_t *zzlextext; /* text of most recently matched token */ +zzchar_t *zzbegexpr; /* beginning of last reg expr recogn. */ +zzchar_t *zzendexpr; /* beginning of last reg expr recogn. */ +int zzbufsize = 0; /* number of characters in zzlextext */ /* MR7 */ +int zzbegcol = 0; /* column that first character of token is in*/ +int zzendcol = 0; /* column that last character of token is in */ +int zzline = 1; /* line current token is on */ +int zzreal_line=1; /* line of 1st portion of token that is not skipped */ +int zzchar; /* character to determine next state */ +int zzbufovf; /* indicates that buffer too small for text */ +int zzcharfull = 0; +static zzchar_t *zznextpos;/* points to next available position in zzlextext*/ +static int zzclass; + +#ifdef __USE_PROTOS +void zzerrstd(const char *); +void (*zzerr)(const char *)=zzerrstd;/* pointer to error reporting function */ +extern int zzerr_in(void); +static int (*zzfunc_in)(void) = zzerr_in; /* MR20 */ +#else +void zzerrstd(); +void (*zzerr)()=zzerrstd; /* pointer to error reporting function */ +extern int zzerr_in(); +static int (*zzfunc_in)() = zzerr_in; /* MR20 */ +#endif + +static FILE *zzstream_in=0; +static zzchar_t *zzstr_in=0; + +#ifdef USER_ZZMODE_STACK +int zzauto = 0; +#else +static int zzauto = 0; +#endif +static int zzadd_erase; +static char zzebuf[70]; + +#ifdef ZZCOL +#define ZZINC (++zzendcol) +#else +#define ZZINC +#endif + + +#define ZZGETC_STREAM {zzchar = getc(zzstream_in); zzclass = ZZSHIFT(zzchar);} +#define ZZGETC_FUNC {zzchar = (*zzfunc_in)(); zzclass = ZZSHIFT(zzchar);} +#define ZZGETC_STR { \ + if (*zzstr_in){ \ + zzchar = *zzstr_in; \ + ++zzstr_in; \ + }else{ \ + zzchar = EOF; \ + } \ + zzclass = ZZSHIFT(zzchar); \ +} + +#define ZZNEWSTATE (newstate = dfa[state][zzclass]) + +#ifndef ZZCOPY +#define ZZCOPY \ + /* Truncate matching buffer to size (not an error) */ \ + if (zznextpos < lastpos){ \ + *(zznextpos++) = zzchar; \ + }else{ \ + zzbufovf = 1; \ + } +#endif + +void +#ifdef __USE_PROTOS +zzrdstream( FILE *f ) +#else +zzrdstream( f ) +FILE *f; +#endif +{ + /* make sure that it is really set to something, otherwise just + leave it be. + */ + if (f){ + /* make sure that there is always someplace to get input + before closing zzstream_in + */ +#if 0 + if (zzstream_in && zzstream_in!=stdin) fclose( zzstream_in ); +#endif + zzline = 1; + zzstream_in = f; + zzfunc_in = NULL; + zzstr_in = 0; + zzcharfull = 0; + } +} + +void +#ifdef __USE_PROTOS +zzrdfunc( int (*f)(void) ) +#else +zzrdfunc( f ) +int (*f)(); +#endif +{ + /* make sure that it is really set to something, otherwise just + leave it be. + */ + if (f){ + /* make sure that there is always someplace to get input + before closing zzstream_in + */ +#if 0 + if (zzstream_in && zzstream_in!=stdin) fclose( zzstream_in ); +#endif + zzline = 1; + zzstream_in = NULL; + zzfunc_in = f; + zzstr_in = 0; + zzcharfull = 0; + } +} + + +void +#ifdef __USE_PROTOS +zzrdstr( zzchar_t *s ) +#else +zzrdstr( s ) +zzchar_t *s; +#endif +{ + /* make sure that it is really set to something, otherwise just + leave it be. + */ + if (s){ + /* make sure that there is always someplace to get input + before closing zzstream_in + */ +#if 0 + if (zzstream_in && zzstream_in!=stdin) fclose( zzstream_in ); +#endif + zzline = 1; + zzstream_in = NULL; + zzfunc_in = 0; + zzstr_in = s; + zzcharfull = 0; + } +} + + +#ifdef __USE_PROTOS +void zzclose_stream(void) +#else +void zzclose_stream() +#endif +{ +#if 0 + fclose( zzstream_in ); + zzstream_in = NULL; + zzfunc_in = NULL; +#endif +} + +/* saves dlg state, but not what feeds dlg (such as file position) */ +void +#ifdef __USE_PROTOS +zzsave_dlg_state(struct zzdlg_state *state) +#else +zzsave_dlg_state(state) +struct zzdlg_state *state; +#endif +{ + state->stream = zzstream_in; + state->func_ptr = zzfunc_in; + state->str = zzstr_in; + state->auto_num = zzauto; + state->add_erase = zzadd_erase; + state->lookc = zzchar; + state->char_full = zzcharfull; + state->begcol = zzbegcol; + state->endcol = zzendcol; + state->line = zzline; + state->lextext = zzlextext; + state->begexpr = zzbegexpr; + state->endexpr = zzendexpr; + state->bufsize = zzbufsize; + state->bufovf = zzbufovf; + state->nextpos = zznextpos; + state->class_num = zzclass; +} + +void +#ifdef __USE_PROTOS +zzrestore_dlg_state(struct zzdlg_state *state) +#else +zzrestore_dlg_state(state) +struct zzdlg_state *state; +#endif +{ + zzstream_in = state->stream; + zzfunc_in = state->func_ptr; + zzstr_in = state->str; + zzauto = state->auto_num; + zzadd_erase = state->add_erase; + zzchar = state->lookc; + zzcharfull = state->char_full; + zzbegcol = state->begcol; + zzendcol = state->endcol; + zzline = state->line; + zzlextext = state->lextext; + zzbegexpr = state->begexpr; + zzendexpr = state->endexpr; + zzbufsize = state->bufsize; + zzbufovf = state->bufovf; + zznextpos = state->nextpos; + zzclass = state->class_num; +} + +void +#ifdef __USE_PROTOS +zzmode( int m ) +#else +zzmode( m ) +int m; +#endif +{ + /* points to base of dfa table */ + if (m +#include + +/* */ +/* 7-Apr-97 133MR1 */ +/* Proper choice of STDC and cplusplus pre-processor symbols (?) */ +/* */ +#include "pccts_string.h" + +#ifdef PCCTS_USE_STDARG +#include "pccts_stdarg.h" +#else +#include +#endif + +#ifdef DUM +/* Define usable bits per unsigned int word (used for set stuff) */ +#ifdef PC +#define BSETWORDSIZE 16 +#define BSETLOGWORDSIZE 4 +#else +#define BSETWORDSIZE 32 +#define BSETLOGWORDSIZE 5 +#endif +#endif + +#define BSETWORDSIZE 8 +#define BSETLOGWORDSIZE 3 /* SetWordType is 8bits */ + +#define BSETMODWORD(x) ((x) & (BSETWORDSIZE-1)) /* x % BSETWORDSIZE */ +#define BSETDIVWORD(x) ((x) >> BSETLOGWORDSIZE) /* x / BSETWORDSIZE */ + +/* This is not put into the global pccts_parser structure because it is + * hidden and does not need to be saved during a "save state" operation + */ +/* maximum of 32 bits/unsigned int and must be 8 bits/byte */ +static SetWordType bitmask[] = { + 0x00000001, 0x00000002, 0x00000004, 0x00000008, + 0x00000010, 0x00000020, 0x00000040, 0x00000080 +}; + +#ifdef zzTRACE_RULES +int zzTraceOptionValueDefault=1; +int zzTraceOptionValue=1; +int zzTraceGuessOptionValue=1; +char *zzTraceCurrentRuleName=NULL; +int zzTraceDepth=0; +#endif + +int zzGuessSeq=0; /* MR10 */ +int zzSyntaxErrCount=0; /* MR11 */ +int zzLexErrCount=0; /* MR11 */ + +void +#ifdef __USE_PROTOS +zzresynch(SetWordType *wd,SetWordType mask) +#else +zzresynch(wd,mask) +SetWordType *wd, mask; +#endif +{ + static int consumed = 1; + + /* if you enter here without having consumed a token from last resynch + * force a token consumption. + */ + if ( !consumed ) {zzCONSUME; consumed=1; return;} /* MR10 */ + + /* if current token is in resynch set, we've got what we wanted */ + if ( wd[LA(1)]&mask || LA(1) == zzEOF_TOKEN ) {consumed=0; return;} + + /* scan until we find something in the resynch set */ + while ( !(wd[LA(1)]&mask) && LA(1) != zzEOF_TOKEN ) {zzCONSUME;} + consumed=1; +} + +/* */ +/* 7-Apr-97 133MR1 for C++ and MR7 for C */ +/* Change suggested by Eli Sternheim (eli@interhdl.com) */ +/* */ + +void +#ifdef __USE_PROTOS +zzconsumeUntil(SetWordType *st) +#else +zzconsumeUntil(st) +SetWordType *st; +#endif +{ + int tmp; /* MR7 */ + while ( !zzset_el( (tmp=LA(1)), st) && tmp!=1 /* Eof */) { /* MR7 */ + zzCONSUME; } /* MR7 */ +} + +/* */ +/* 7-Apr-97 133MR1 for C++ and MR7 for C */ +/* Change suggested by Eli Sternheim (eli@interhdl.com) */ +/* */ + +void +#ifdef __USE_PROTOS +zzconsumeUntilToken(int t) +#else +zzconsumeUntilToken(t) +int t; +#endif +{ + int tmp; /* MR7 */ + while ( (tmp=LA(1)) !=t && tmp!=1 /* Eof */) { zzCONSUME; } /* MR7 */ +} + +/* input looks like: + * zzFAIL(k, e1, e2, ...,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText) + * where the zzMiss stuff is set here to the token that did not match + * (and which set wasn't it a member of). + */ + +#ifdef PCCTS_USE_STDARG +void zzFAIL(int k, ...) +#else +void zzFAIL(va_alist) +va_dcl +#endif +{ +#ifdef LL_K + static char text[LL_K*ZZLEXBUFSIZE+1]; + SetWordType *f[LL_K]; +#else + static char text[ZZLEXBUFSIZE+1]; + SetWordType *f[1]; +#endif + SetWordType **miss_set; + char **miss_text; + int *bad_tok; + char **bad_text; + int *err_k; + int i; + va_list ap; +#ifndef PCCTS_USE_STDARG /* MR20 */ + int k; +#endif +#ifdef PCCTS_USE_STDARG /* MR20 */ + va_start(ap, k); +#else + va_start(ap); + k = va_arg(ap, int); /* how many lookahead sets? */ +#endif + assert(k <= sizeof(f)/sizeof(f[0])); /* MR20 G. Hobbelt */ + text[0] = '\0'; + for (i=1; i<=k; i++) /* collect all lookahead sets */ + { + f[i-1] = va_arg(ap, SetWordType *); + } + for (i=1; i<=k; i++) /* look for offending token */ + { + if ( i>1 ) strcat(text, " "); + strcat(text, LATEXT(i)); + if ( !zzset_el((unsigned)LA(i), f[i-1]) ) break; + } + miss_set = va_arg(ap, SetWordType **); + miss_text = va_arg(ap, char **); + bad_tok = va_arg(ap, int *); + bad_text = va_arg(ap, char **); + err_k = va_arg(ap, int *); + if ( i>k ) + { + /* bad; lookahead is permutation that cannot be matched, + * but, the ith token of lookahead is valid at the ith position + * (The old LL sub 1 (k) versus LL(k) parsing technique) + */ + *miss_set = NULL; + *miss_text = zzlextext; + *bad_tok = LA(1); + *bad_text = LATEXT(1); + *err_k = k; + return; + } +/* fprintf(stderr, "%s not in %dth set\n", zztokens[LA(i)], i);*/ + *miss_set = f[i-1]; + *miss_text = text; + *bad_tok = LA(i); + *bad_text = LATEXT(i); + if ( i==1 ) *err_k = 1; + else *err_k = k; +} + +#ifdef __USE_PROTOS +void zzTraceGuessDone(zzantlr_state *state) +#else +void zzTraceGuessDone(state) + zzantlr_state *state; +#endif +{ +#ifdef zzTRACE_RULES +#ifdef ZZCAN_GUESS + + int doIt=0; + + if (zzTraceCurrentRuleName == NULL) return; + + if (zzTraceOptionValue <= 0) { + doIt=0; + } else if (zzTraceGuessOptionValue <= 0) { + doIt=0; + } else { + doIt=1; + }; + + if (doIt) { + fprintf(stderr,"guess done - returning to rule %s {\"%s\"} at depth %d", + state->traceCurrentRuleName, + LATEXT(1), + state->traceDepth); + if (state->guessing != 0) { + fprintf(stderr," (guess mode continues - an enclosing guess is still active)"); + } else { + fprintf(stderr," (guess mode ends)"); + }; + fprintf(stderr,"\n"); + }; +#endif +#endif +} + +void +#ifdef __USE_PROTOS +zzsave_antlr_state(zzantlr_state *buf) +#else +zzsave_antlr_state(buf) +zzantlr_state *buf; +#endif +{ +#ifdef LL_K + int i; +#endif + +#ifdef ZZCAN_GUESS + buf->guess_start = zzguess_start; + buf->guessing = zzguessing; +#endif + buf->asp = zzasp; +#ifdef GENAST + buf->ast_sp = zzast_sp; +#endif +#ifdef ZZINF_LOOK + buf->inf_labase = zzinf_labase; + buf->inf_last = zzinf_last; + +/* MR6 Gunnar Rxnning (gunnar@candleweb.no) */ +/* MR6 Additional state needs to be saved/restored */ + + buf->inf_tokens = zzinf_tokens; /* MR6 */ + buf->inf_text = zzinf_text; /* MR6 */ + buf->inf_text_buffer = zzinf_text_buffer; /* MR6 */ + buf->inf_line = zzinf_line; /* MR6 */ + +#endif +#ifdef DEMAND_LOOK + buf->dirty = zzdirty; +#endif +#ifdef LL_K + for (i=0; itokenLA[i] = zztokenLA[i]; + for (i=0; itextLA[i], zztextLA[i]); + buf->lap = zzlap; + buf->labase = zzlabase; +#else + buf->token = zztoken; + strcpy(buf->text, zzlextext); +#endif +#ifdef zzTRACE_RULES + + /* MR10 */ + + buf->traceOptionValue=zzTraceOptionValue; + buf->traceGuessOptionValue=zzTraceGuessOptionValue; + buf->traceCurrentRuleName=zzTraceCurrentRuleName; + buf->traceDepth=zzTraceDepth; +#endif +} + +void +#ifdef __USE_PROTOS +zzrestore_antlr_state(zzantlr_state *buf) +#else +zzrestore_antlr_state(buf) +zzantlr_state *buf; +#endif +{ + +#ifdef zzTRACE_RULES + int prevTraceOptionValue; +#endif + +#ifdef LL_K + int i; +#endif + +#ifdef ZZCAN_GUESS + zzguess_start = buf->guess_start; + zzguessing = buf->guessing; +#endif + zzasp = buf->asp; +#ifdef GENAST + zzast_sp = buf->ast_sp; +#endif +#ifdef ZZINF_LOOK + zzinf_labase = buf->inf_labase; + zzinf_last = buf->inf_last; + +/* MR6 Gunnar Rxnning (gunnar@candleweb.no) */ +/* MR6 Additional state needs to be saved/restored */ + + zzinf_tokens = buf->inf_tokens; /* MR6 */ + zzinf_text = buf->inf_text; /* MR6 */ + zzinf_text_buffer = buf->inf_text_buffer; /* MR6 */ + zzinf_line = buf->inf_line; /* MR6 */ +#endif +#ifdef DEMAND_LOOK + zzdirty = buf->dirty; +#endif +#ifdef LL_K + for (i=0; itokenLA[i]; + for (i=0; itextLA[i]); + zzlap = buf->lap; + zzlabase = buf->labase; +#else + zztoken = buf->token; + strcpy(zzlextext, buf->text); +#endif +#ifdef zzTRACE_RULES + + prevTraceOptionValue=zzTraceOptionValue; + zzTraceOptionValue=buf->traceOptionValue; + if ( (prevTraceOptionValue > 0) != + (zzTraceOptionValue > 0)) { + if (zzTraceOptionValue > 0) { + fprintf(stderr,"trace enable restored in rule %s depth %d\n", + zzTraceCurrentRuleName,zzTraceDepth); + }; + if (zzTraceOptionValue <= 0) { + fprintf(stderr,"trace disable restored in rule %s depth %d\n", + zzTraceCurrentRuleName,zzTraceDepth); + }; + }; + + zzTraceOptionValue=buf->traceOptionValue; /* MR10 */ + zzTraceGuessOptionValue=buf->traceGuessOptionValue; /* MR10 */ + zzTraceCurrentRuleName=buf->traceCurrentRuleName; /* MR10 */ + zzTraceDepth=buf->traceDepth; /* MR10 */ + zzTraceGuessDone(buf); /* MR10 */ +#endif +} + +void +#ifdef __USE_PROTOS +zzedecode(SetWordType *a) +#else +zzedecode(a) +SetWordType *a; +#endif +{ + register SetWordType *p = a; + register SetWordType *endp = &(p[zzSET_SIZE]); + register unsigned e = 0; + + if ( zzset_deg(a)>1 ) fprintf(stderr, " {"); + do { + register SetWordType t = *p; + register SetWordType *b = &(bitmask[0]); + do { + if ( t & *b ) fprintf(stderr, " %s", zztokens[e]); + e++; + } while (++b < &(bitmask[sizeof(SetWordType)*8])); + } while (++p < endp); + if ( zzset_deg(a)>1 ) fprintf(stderr, " }"); +} + +#ifndef USER_ZZSYN +/* standard error reporting function */ +void +#ifdef __USE_PROTOS +zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, int k, char *bad_text) +#else +zzsyn(text, tok, egroup, eset, etok, k, bad_text) +char *text, *egroup, *bad_text; +int tok; +int etok; +int k; +SetWordType *eset; +#endif +{ + + zzSyntaxErrCount++; /* MR11 */ + fprintf(stderr, "line %d: syntax error at \"%s\"", zzline, (tok==zzEOF_TOKEN)?"EOF":bad_text); + if ( !etok && !eset ) {fprintf(stderr, "\n"); return;} + if ( k==1 ) fprintf(stderr, " missing"); + else + { + fprintf(stderr, "; \"%s\" not", bad_text); + if ( zzset_deg(eset)>1 ) fprintf(stderr, " in"); + } + if ( zzset_deg(eset)>0 ) zzedecode(eset); + else fprintf(stderr, " %s", zztokens[etok]); + if ( strlen(egroup) > 0 ) fprintf(stderr, " in %s", egroup); + fprintf(stderr, "\n"); +} +#endif + +/* is b an element of set p? */ +int +#ifdef __USE_PROTOS +zzset_el(unsigned b, SetWordType *p) +#else +zzset_el(b,p) +unsigned b; +SetWordType *p; +#endif +{ + return( p[BSETDIVWORD(b)] & bitmask[BSETMODWORD(b)] ); +} + +int +#ifdef __USE_PROTOS +zzset_deg(SetWordType *a) +#else +zzset_deg(a) +SetWordType *a; +#endif +{ + /* Fast compute degree of a set... the number + of elements present in the set. Assumes + that all word bits are used in the set + */ + register SetWordType *p = a; + register SetWordType *endp = &(a[zzSET_SIZE]); + register int degree = 0; + + if ( a == NULL ) return 0; + while ( p < endp ) + { + register SetWordType t = *p; + register SetWordType *b = &(bitmask[0]); + do { + if (t & *b) ++degree; + } while (++b < &(bitmask[sizeof(SetWordType)*8])); + p++; + } + + return(degree); +} + +#ifdef DEMAND_LOOK + +#ifdef LL_K +int +#ifdef __USE_PROTOS +_zzmatch(int _t, char **zzBadText, char **zzMissText, + int *zzMissTok, int *zzBadTok, + SetWordType **zzMissSet) +#else +_zzmatch(_t, zzBadText, zzMissText, zzMissTok, zzBadTok, zzMissSet) +int _t; +char **zzBadText; +char **zzMissText; +int *zzMissTok, *zzBadTok; +SetWordType **zzMissSet; +#endif +{ + if ( zzdirty==LL_K ) { + zzCONSUME; + } + if ( LA(1)!=_t ) { + *zzBadText = *zzMissText=LATEXT(1); + *zzMissTok= _t; *zzBadTok=LA(1); + *zzMissSet=NULL; + return 0; + } + zzMakeAttr + zzdirty++; + zzlabase++; + return 1; +} + +int +#ifdef __USE_PROTOS +_zzmatch_wsig(int _t) +#else +_zzmatch_wsig(_t) +int _t; +#endif +{ + if ( zzdirty==LL_K ) { + zzCONSUME; + } + if ( LA(1)!=_t ) { + return 0; + } + zzMakeAttr + zzdirty++; + zzlabase++; + return 1; +} + +#else + +int +#ifdef __USE_PROTOS +_zzmatch(int _t, char **zzBadText, char **zzMissText, + int *zzMissTok, int *zzBadTok, SetWordType **zzMissSet) +#else +_zzmatch(_t, zzBadText, zzMissText, zzMissTok, zzBadTok, zzMissSet) +int _t; +char **zzBadText; +char **zzMissText; +int *zzMissTok, *zzBadTok; +SetWordType **zzMissSet; +#endif +{ + if ( zzdirty ) {zzCONSUME;} + if ( LA(1)!=_t ) { + *zzBadText = *zzMissText=LATEXT(1); + *zzMissTok= _t; *zzBadTok=LA(1); + *zzMissSet=NULL; + return 0; + } + zzdirty = 1; + zzMakeAttr + return 1; +} + +int +#ifdef __USE_PROTOS +_zzmatch_wsig(int _t) +#else +_zzmatch_wsig(_t) +int _t; +#endif +{ + if ( zzdirty ) {zzCONSUME;} + if ( LA(1)!=_t ) { + return 0; + } + zzdirty = 1; + zzMakeAttr + return 1; +} + +#endif /*LL_K*/ + +#else + +int +#ifdef __USE_PROTOS +_zzmatch(int _t, char **zzBadText, char **zzMissText, + int *zzMissTok, int *zzBadTok, + SetWordType **zzMissSet) +#else +_zzmatch(_t, zzBadText, zzMissText, zzMissTok, zzBadTok, zzMissSet) +int _t; +char **zzBadText; +char **zzMissText; +int *zzMissTok, *zzBadTok; +SetWordType **zzMissSet; +#endif +{ + if ( LA(1)!=_t ) { + *zzBadText = *zzMissText=LATEXT(1); + *zzMissTok= _t; *zzBadTok=LA(1); + *zzMissSet=NULL; + return 0; + } + zzMakeAttr + return 1; +} + +int +#ifdef __USE_PROTOS +_zzmatch_wsig(int _t) +#else +_zzmatch_wsig(_t) +int _t; +#endif +{ + if ( LA(1)!=_t ) return 0; + zzMakeAttr + return 1; +} + +#endif /*DEMAND_LOOK*/ + +#ifdef ZZINF_LOOK +void +#ifdef __USE_PROTOS +_inf_zzgettok(void) +#else +_inf_zzgettok() +#endif +{ + if ( zzinf_labase >= zzinf_last ) + {NLA = zzEOF_TOKEN; strcpy(NLATEXT, "");} + else { + NLA = zzinf_tokens[zzinf_labase]; + zzline = zzinf_line[zzinf_labase]; /* wrong in 1.21 */ + strcpy(NLATEXT, zzinf_text[zzinf_labase]); + zzinf_labase++; + } +} +#endif + +#ifdef ZZINF_LOOK +/* allocate default size text,token and line arrays; + * then, read all of the input reallocing the arrays as needed. + * Once the number of total tokens is known, the LATEXT(i) array (zzinf_text) + * is allocated and it's pointers are set to the tokens in zzinf_text_buffer. + */ +void +#ifdef __USE_PROTOS +zzfill_inf_look(void) +#else +zzfill_inf_look() +#endif +{ + int tok, line; + int zzinf_token_buffer_size = ZZINF_DEF_TOKEN_BUFFER_SIZE; + int zzinf_text_buffer_size = ZZINF_DEF_TEXT_BUFFER_SIZE; + int zzinf_text_buffer_index = 0; + int zzinf_lap = 0; + + /* allocate text/token buffers */ + zzinf_text_buffer = (char *) malloc(zzinf_text_buffer_size); + if ( zzinf_text_buffer == NULL ) + { + fprintf(stderr, "cannot allocate lookahead text buffer (%d bytes)\n", + zzinf_text_buffer_size); + exit(PCCTS_EXIT_FAILURE); + } + zzinf_tokens = (int *) calloc(zzinf_token_buffer_size,sizeof(int)); + if ( zzinf_tokens == NULL ) + { + fprintf(stderr, "cannot allocate token buffer (%d tokens)\n", + zzinf_token_buffer_size); + exit(PCCTS_EXIT_FAILURE); + } + zzinf_line = (int *) calloc(zzinf_token_buffer_size,sizeof(int)); + if ( zzinf_line == NULL ) + { + fprintf(stderr, "cannot allocate line buffer (%d ints)\n", + zzinf_token_buffer_size); + exit(PCCTS_EXIT_FAILURE); + } + + /* get tokens, copying text to text buffer */ + zzinf_text_buffer_index = 0; + do { + zzgettok(); + line = zzreal_line; + while ( zzinf_lap>=zzinf_token_buffer_size ) + { + zzinf_token_buffer_size += ZZINF_BUFFER_TOKEN_CHUNK_SIZE; + zzinf_tokens = (int *) realloc(zzinf_tokens, + zzinf_token_buffer_size*sizeof(int)); + if ( zzinf_tokens == NULL ) + { + fprintf(stderr, "cannot allocate lookahead token buffer (%d tokens)\n", + zzinf_token_buffer_size); + exit(PCCTS_EXIT_FAILURE); + } + zzinf_line = (int *) realloc(zzinf_line, + zzinf_token_buffer_size*sizeof(int)); + if ( zzinf_line == NULL ) + { + fprintf(stderr, "cannot allocate lookahead line buffer (%d ints)\n", + zzinf_token_buffer_size); + exit(PCCTS_EXIT_FAILURE); + } + + } + while ( (zzinf_text_buffer_index+strlen(NLATEXT)+1) >= zzinf_text_buffer_size ) + { + zzinf_text_buffer_size += ZZINF_BUFFER_TEXT_CHUNK_SIZE; + zzinf_text_buffer = (char *) realloc(zzinf_text_buffer, + zzinf_text_buffer_size); + if ( zzinf_text_buffer == NULL ) + { + fprintf(stderr, "cannot allocate lookahead text buffer (%d bytes)\n", + zzinf_text_buffer_size); + exit(PCCTS_EXIT_FAILURE); + } + } + /* record token and text and line of input symbol */ + tok = zzinf_tokens[zzinf_lap] = NLA; + strcpy(&zzinf_text_buffer[zzinf_text_buffer_index], NLATEXT); + zzinf_text_buffer_index += strlen(NLATEXT)+1; + zzinf_line[zzinf_lap] = line; + zzinf_lap++; + } while (tok!=zzEOF_TOKEN); + zzinf_labase = 0; + zzinf_last = zzinf_lap-1; + + /* allocate ptrs to text of ith token */ + zzinf_text = (char **) calloc(zzinf_last+1,sizeof(char *)); + if ( zzinf_text == NULL ) + { + fprintf(stderr, "cannot allocate lookahead text buffer (%d)\n", + zzinf_text_buffer_size); + exit(PCCTS_EXIT_FAILURE); + } + zzinf_text_buffer_index = 0; + zzinf_lap = 0; + /* set ptrs so that zzinf_text[i] is the text of the ith token found on input */ + while (zzinf_lap<=zzinf_last) + { + zzinf_text[zzinf_lap++] = &zzinf_text_buffer[zzinf_text_buffer_index]; + zzinf_text_buffer_index += strlen(&zzinf_text_buffer[zzinf_text_buffer_index])+1; + } +} +#endif + +int +#ifdef __USE_PROTOS +_zzsetmatch(SetWordType *e, char **zzBadText, char **zzMissText, + int *zzMissTok, int *zzBadTok, + SetWordType **zzMissSet, + SetWordType *zzTokclassErrset /* MR23 */) +#else +_zzsetmatch(e, zzBadText, zzMissText, zzMissTok, zzBadTok, zzMissSet, zzTokclassErrset /* MR23 */) +SetWordType *e; +char **zzBadText; +char **zzMissText; +int *zzMissTok, *zzBadTok; +SetWordType **zzMissSet; +SetWordType *zzTokclassErrset; +#endif +{ +#ifdef DEMAND_LOOK +#ifdef LL_K + if ( zzdirty==LL_K ) {zzCONSUME;} +#else + if ( zzdirty ) {zzCONSUME;} +#endif +#endif + if ( !zzset_el((unsigned)LA(1), e) ) { + *zzBadText = LATEXT(1); *zzMissText=NULL; + *zzMissTok= 0; *zzBadTok=LA(1); + *zzMissSet=zzTokclassErrset; /* MR23 */ + return 0; + } + zzMakeAttr /* MR14 Ger Hobbelt (hobbelt@axa.nl) */ +#ifdef DEMAND_LOOK +#ifdef LL_K + zzdirty++; + zzlabase++; /* MR14 Ger Hobbelt (hobbelt@axa.nl) */ +#else + zzdirty = 1; +#endif +#endif + return 1; +} + +int +#ifdef __USE_PROTOS +_zzmatch_wdfltsig(int tokenWanted, SetWordType *whatFollows) +#else +_zzmatch_wdfltsig(tokenWanted, whatFollows) +int tokenWanted; +SetWordType *whatFollows; +#endif +{ +#ifdef DEMAND_LOOK +#ifdef LL_K + if ( zzdirty==LL_K ) { + zzCONSUME; + } +#else + if ( zzdirty ) {zzCONSUME;} +#endif +#endif + + if ( LA(1)!=tokenWanted ) + { + zzSyntaxErrCount++; /* MR11 */ + fprintf(stderr, + "line %d: syntax error at \"%s\" missing %s\n", + zzline, + (LA(1)==zzEOF_TOKEN)?"":(char *)LATEXT(1), + zztokens[tokenWanted]); + zzconsumeUntil( whatFollows ); + return 0; + } + else { + zzMakeAttr +#ifdef DEMAND_LOOK +#ifdef LL_K + zzdirty++; + zzlabase++; +#else + zzdirty = 1; +#endif +#else +/* zzCONSUME; consume if not demand lookahead */ +#endif + return 1; + } +} + +int +#ifdef __USE_PROTOS +_zzsetmatch_wdfltsig(SetWordType *tokensWanted, + int tokenTypeOfSet, + SetWordType *whatFollows) +#else +_zzsetmatch_wdfltsig(tokensWanted, tokenTypeOfSet, whatFollows) +SetWordType *tokensWanted; +int tokenTypeOfSet; +SetWordType *whatFollows; +#endif +{ +#ifdef DEMAND_LOOK +#ifdef LL_K + if ( zzdirty==LL_K ) {zzCONSUME;} +#else + if ( zzdirty ) {zzCONSUME;} +#endif +#endif + if ( !zzset_el((unsigned)LA(1), tokensWanted) ) + { + zzSyntaxErrCount++; /* MR11 */ + fprintf(stderr, + "line %d: syntax error at \"%s\" missing %s\n", + zzline, + (LA(1)==zzEOF_TOKEN)?"":(char *)LATEXT(1), + zztokens[tokenTypeOfSet]); + zzconsumeUntil( whatFollows ); + return 0; + } + else { + zzMakeAttr +#ifdef DEMAND_LOOK +#ifdef LL_K + zzdirty++; + zzlabase++; +#else + zzdirty = 1; +#endif +#else +/* zzCONSUME; consume if not demand lookahead */ +#endif + return 1; + } +} + +int +#ifdef __USE_PROTOS +_zzsetmatch_wsig(SetWordType *e) +#else +_zzsetmatch_wsig(e) +SetWordType *e; +#endif +{ +#ifdef DEMAND_LOOK +#ifdef LL_K + if ( zzdirty==LL_K ) {zzCONSUME;} +#else + if ( zzdirty ) {zzCONSUME;} +#endif +#endif + if ( !zzset_el((unsigned)LA(1), e) ) return 0; + zzMakeAttr /* MR14 Ger Hobbelt (hobbelt@axa.nl) */ +#ifdef DEMAND_LOOK +#ifdef LL_K + zzdirty++; + zzlabase++; /* MR14 Ger Hobbelt (hobbelt@axa.nl) */ +#else + zzdirty = 1; +#endif +#endif + return 1; +} + +#ifdef USER_ZZMODE_STACK +static int zzmstk[ZZMAXSTK] = { -1 }; +static int zzmdep = 0; +static char zzmbuf[70]; + +void +#ifdef __USE_PROTOS +zzmpush( int m ) +#else +zzmpush( m ) +int m; +#endif +{ + if(zzmdep == ZZMAXSTK - 1) { + sprintf(zzmbuf, "Mode stack overflow "); + zzerr(zzmbuf); + } else { + zzmstk[zzmdep++] = zzauto; + zzmode(m); + } +} + +void +#ifdef __USE_PROTOS +zzmpop( void ) +#else +zzmpop( ) +#endif +{ + if(zzmdep == 0) + { sprintf(zzmbuf, "Mode stack underflow "); + zzerr(zzmbuf); + } + else + { zzmdep--; + zzmode(zzmstk[zzmdep]); + } +} + +void +#ifdef __USE_PROTOS +zzsave_mode_stack( int modeStack[], int *modeLevel ) +#else +zzsave_mode_stack( modeStack, modeLevel ) +int modeStack[]; +int *modeLevel; +#endif +{ + int i; + memcpy(modeStack, zzmstk, sizeof(zzmstk)); + *modeLevel = zzmdep; + zzmdep = 0; + + return; +} + +void +#ifdef __USE_PROTOS +zzrestore_mode_stack( int modeStack[], int *modeLevel ) +#else +zzrestore_mode_stack( modeStack, modeLevel ) +int modeStack[]; +int *modeLevel; +#endif +{ + int i; + + memcpy(zzmstk, modeStack, sizeof(zzmstk)); + zzmdep = *modeLevel; + + return; +} +#endif /* USER_ZZMODE_STACK */ + +#ifdef __USE_PROTOS +void zzTraceReset(void) +#else +void zzTraceReset() +#endif +{ +#ifdef zzTRACE_RULES + zzTraceOptionValue=zzTraceOptionValueDefault; + zzTraceGuessOptionValue=1; + zzTraceCurrentRuleName=NULL; + zzTraceDepth=0; +#endif +} + +#ifdef __USE_PROTOS +void zzTraceGuessFail(void) +#else +void zzTraceGuessFail() +#endif +{ + +#ifdef zzTRACE_RULES +#ifdef ZZCAN_GUESS + + int doIt=0; + + if (zzTraceOptionValue <= 0) { + doIt=0; + } else if (zzguessing && zzTraceGuessOptionValue <= 0) { + doIt=0; + } else { + doIt=1; + }; + + if (doIt) { + fprintf(stderr,"guess failed\n"); + }; +#endif +#endif +} + +/* zzTraceOption: + zero value turns off trace +*/ + +#ifdef __USE_PROTOS +void zzTraceIn(char * rule) +#else +void zzTraceIn(rule) + char *rule; +#endif +{ +#ifdef zzTRACE_RULES + + int doIt=0; + + zzTraceDepth++; + zzTraceCurrentRuleName=rule; + + if (zzTraceOptionValue <= 0) { + doIt=0; +#ifdef ZZCAN_GUESS + } else if (zzguessing && zzTraceGuessOptionValue <= 0) { + doIt=0; +#endif + } else { + doIt=1; + }; + + if (doIt) { + fprintf(stderr,"enter rule %s {\"%s\"} depth %d", + rule, + LA(1)==1 ? "@" : (char *) LATEXT(1), /* MR19 */ + zzTraceDepth); +#ifdef ZZCAN_GUESS + if (zzguessing) fprintf(stderr," guessing"); +#endif + fprintf(stderr,"\n"); + }; +#endif + return; +} + +#ifdef __USE_PROTOS +void zzTraceOut(char * rule) +#else +void zzTraceOut(rule) + char *rule; +#endif +{ +#ifdef zzTRACE_RULES + int doIt=0; + + zzTraceDepth--; + + if (zzTraceOptionValue <= 0) { + doIt=0; +#ifdef ZZCAN_GUESS + } else if (zzguessing && zzTraceGuessOptionValue <= 0) { + doIt=0; +#endif + } else { + doIt=1; + }; + + if (doIt) { + fprintf(stderr,"exit rule %s {\"%s\"} depth %d", + rule, + LA(1)==1 ? "@" : (char *) LATEXT(1), /* MR19 */ + zzTraceDepth+1); +#ifdef ZZCAN_GUESS + if (zzguessing) fprintf(stderr," guessing"); +#endif + fprintf(stderr,"\n"); + }; +#endif +} + +#ifdef __USE_PROTOS +int zzTraceOption(int delta) +#else +int zzTraceOption(delta) + int delta; +#endif +{ +#ifdef zzTRACE_RULES + int prevValue=zzTraceOptionValue; + + zzTraceOptionValue=zzTraceOptionValue+delta; + + if (zzTraceCurrentRuleName != NULL) { + if (prevValue <= 0 && zzTraceOptionValue > 0) { + fprintf(stderr,"trace enabled in rule %s depth %d\n", + zzTraceCurrentRuleName,zzTraceDepth); + }; + if (prevValue > 0 && zzTraceOptionValue <= 0) { + fprintf(stderr,"trace disabled in rule %s depth %d\n", + zzTraceCurrentRuleName,zzTraceDepth); + }; + }; + return prevValue; +#else + return 0; +#endif +} + +#ifdef __USE_PROTOS +int zzTraceGuessOption(int delta) +#else +int zzTraceGuessOption(delta) + int delta; +#endif +{ +#ifdef zzTRACE_RULES +#ifdef ZZCAN_GUESS + int prevValue=zzTraceGuessOptionValue; + + zzTraceGuessOptionValue=zzTraceGuessOptionValue+delta; + + if (zzTraceCurrentRuleName != NULL) { + if (prevValue <= 0 && zzTraceGuessOptionValue > 0) { + fprintf(stderr,"guess trace enabled in rule %s depth %d\n", + zzTraceCurrentRuleName,zzTraceDepth); + }; + if (prevValue > 0 && zzTraceGuessOptionValue <= 0) { + fprintf(stderr,"guess trace disabled in rule %s depth %d\n", + zzTraceCurrentRuleName,zzTraceDepth); + }; + }; + return prevValue; +#else + return 0; +#endif +#else + return 0; +#endif +} + +#endif /* ERR_H */ diff --git a/Tools/CodeTools/Source/Pccts/h/int.h b/Tools/CodeTools/Source/Pccts/h/int.h new file mode 100644 index 0000000000..cdcaa92426 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/int.h @@ -0,0 +1,37 @@ +/* ANTLR attribute definition -- long integers + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * ANTLR 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +#ifndef ZZINT_H +#define ZZINT_H + +typedef long Attrib; + +#define zzcr_attr(a,tok,t) *(a) = atol(t); + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/pccts_assert.h b/Tools/CodeTools/Source/Pccts/h/pccts_assert.h new file mode 100644 index 0000000000..ff0dfb5126 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/pccts_assert.h @@ -0,0 +1,10 @@ +#ifndef __PCCTS_ASSERT_H__ +#define __PCCTS_ASSERT_H__ + +#ifdef PCCTS_USE_NAMESPACE_STD +#include +#else +#include +#endif + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/pccts_iostream.h b/Tools/CodeTools/Source/Pccts/h/pccts_iostream.h new file mode 100644 index 0000000000..972b32cbd1 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/pccts_iostream.h @@ -0,0 +1,10 @@ +#ifndef __PCCTS_IOSTREAM_H__ +#define __PCCTS_IOSTREAM_H__ + +#ifdef PCCTS_USE_NAMESPACE_STD +#include +#else +#include +#endif + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/pccts_istream.h b/Tools/CodeTools/Source/Pccts/h/pccts_istream.h new file mode 100644 index 0000000000..e25cb8c483 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/pccts_istream.h @@ -0,0 +1,10 @@ +#ifndef __PCCTS_ISTREAM_H__ +#define __PCCTS_ISTREAM_H__ + +#ifdef PCCTS_USE_NAMESPACE_STD +#include +#else +#include +#endif + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/pccts_setjmp.h b/Tools/CodeTools/Source/Pccts/h/pccts_setjmp.h new file mode 100644 index 0000000000..9ea185ca73 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/pccts_setjmp.h @@ -0,0 +1,10 @@ +#ifndef __PCCTS_SETJMP_H__ +#define __PCCTS_SETJMP_H__ + +#ifdef PCCTS_USE_NAMESPACE_STD +#include +#else +#include +#endif + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/pccts_stdarg.h b/Tools/CodeTools/Source/Pccts/h/pccts_stdarg.h new file mode 100644 index 0000000000..e957430c32 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/pccts_stdarg.h @@ -0,0 +1,10 @@ +#ifndef __PCCTS_STDARG_H__ +#define __PCCTS_STDARG_H__ + +#ifdef PCCTS_USE_NAMESPACE_STD +#include +#else +#include +#endif + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/pccts_stdio.h b/Tools/CodeTools/Source/Pccts/h/pccts_stdio.h new file mode 100644 index 0000000000..ac34d1086d --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/pccts_stdio.h @@ -0,0 +1,10 @@ +#ifndef __PCCTS_STDIO_H__ +#define __PCCTS_STDIO_H__ + +#ifdef PCCTS_USE_NAMESPACE_STD +#include +#else +#include +#endif + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/pccts_stdlib.h b/Tools/CodeTools/Source/Pccts/h/pccts_stdlib.h new file mode 100644 index 0000000000..f0b344e8dc --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/pccts_stdlib.h @@ -0,0 +1,10 @@ +#ifndef __PCCTS_STDLIB_H__ +#define __PCCTS_STDLIB_H__ + +#ifdef PCCTS_USE_NAMESPACE_STD +#include +#else +#include +#endif + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/pccts_string.h b/Tools/CodeTools/Source/Pccts/h/pccts_string.h new file mode 100644 index 0000000000..458a08a94b --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/pccts_string.h @@ -0,0 +1,10 @@ +#ifndef __PCCTS_STRING_H__ +#define __PCCTS_STRING_H__ + +#ifdef PCCTS_USE_NAMESPACE_STD +#include +#else +#include +#endif + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/pcctscfg.h b/Tools/CodeTools/Source/Pccts/h/pcctscfg.h new file mode 100644 index 0000000000..0c3c5ba6fd --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/pcctscfg.h @@ -0,0 +1,359 @@ +#ifndef PCCTS_CONFIG_H +#define PCCTS_CONFIG_H +/* + * pcctscfg.h (formerly config.h) (for ANTLR, DLG, and SORCERER) + * + * This is a simple configuration file that doesn't have config stuff + * in it, but it's a start. + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to the Purdue Compiler Construction Tool + * Set (PCCTS) -- PCCTS is in the public domain. An individual or + * company may do whatever they wish with source code distributed with + * PCCTS or the code generated by PCCTS, including the incorporation of + * PCCTS, or its output, into commerical software. + * + * We encourage users to develop software with PCCTS. However, we do ask + * that credit is given to us for developing PCCTS. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like PCCTS and have developed a nice tool with the + * output, please mention that you developed it using PCCTS. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * Used by PCCTS 1.33 (SORCERER 1.00B11 and up) + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1989-2000 + */ + +/* This file knows about the following ``environments'' + UNIX (default) + DOS (use #define PC) + MAC (use #define MPW; has a few things for THINK C, Metrowerks) + MS/C++ (MR14 Microsoft Visual C++ environment uses symbol _MSC_VER) + + */ + +/* should test __STDC__ for 1, but some compilers don't set value, just def */ + +#ifndef __USE_PROTOS +#ifdef __STDC__ +#define __USE_PROTOS +#endif +#ifdef __cplusplus +#define __USE_PROTOS +#endif +#endif + +#ifdef PCCTS_USE_NAMESPACE_STD +#define PCCTS_NAMESPACE_STD namespace std {}; using namespace std; +#else +#define PCCTS_NAMESPACE_STD +#endif + +#include "pccts_stdio.h" +#include "pccts_stdlib.h" + +/* largest file name size */ + +#ifdef _MAX_PATH +#define MaxFileName _MAX_PATH /* MR9 RJV: MAX_PATH defined in stdlib.h (MSVC++ 5.0) */ +#else +#define MaxFileName 300 +#endif + +/* +* Define PC32 if in a 32-bit PC environment (e.g. extended DOS or Win32). +* The macros tested here are defined by Watcom, Microsoft, Borland, +* and djgpp, respectively, when they are used as 32-bit compilers. +* Users of these compilers *must* be sure to define PC in their +* makefiles for this to work correctly. +*/ +#ifdef PC +# if (defined(__WATCOMC__) || defined(_WIN32) || defined(__WIN32__) || \ + defined(__GNUC__) || defined(__GNUG__)) +# ifndef PC32 +# define PC32 +# endif +# endif +#endif + +/* MR1 10-Apr-97 Default for PC is short file names */ +/* MR1 Default for non-PC is long file names */ +/* MR1 Can override via command line option LONGFILENAMES */ + +#ifndef LONGFILENAMES +#ifndef PC +#define LONGFILENAMES +#endif +#endif + +#ifndef LONGFILENAMES +#define ATOKEN_H "AToken.h" +#define ATOKPTR_H "ATokPtr.h" +#define ATOKPTR_IMPL_H "ATokPtrIm.h" +#define ATOKENBUFFER_H "ATokBuf.h" +#define ATOKENBUFFER_C "ATokBuf.cpp" +#define ATOKENSTREAM_H "ATokStr.h" +#define APARSER_H "AParser.h" +#define APARSER_C "AParser.cpp" +#define ASTBASE_H "ASTBase.h" +#define ASTBASE_C "ASTBase.cpp" +#define PCCTSAST_C "PCCTSAST.cpp" +#define LIST_C "List.cpp" +#define DLEXERBASE_H "DLexBase.h" +#define DLEXERBASE_C "DLexBase.cpp" +#define DLEXER_H "DLexer.h" +#define STREESUPPORT_C "STreeSup.C" +#else +#define ATOKEN_H "AToken.h" +#define ATOKPTR_H "ATokPtr.h" +#define ATOKPTR_IMPL_H "ATokPtrImpl.h" +#define ATOKENBUFFER_H "ATokenBuffer.h" +#define ATOKENBUFFER_C "ATokenBuffer.cpp" +#define ATOKENSTREAM_H "ATokenStream.h" +#define APARSER_H "AParser.h" +#define APARSER_C "AParser.cpp" +#define ASTBASE_H "ASTBase.h" +#define ASTBASE_C "ASTBase.cpp" +#define PCCTSAST_C "PCCTSAST.cpp" +#define LIST_C "List.cpp" +#define DLEXERBASE_H "DLexerBase.h" +#define DLEXERBASE_C "DLexerBase.cpp" +#define DLEXER_H "DLexer.h" +#define STREESUPPORT_C "STreeSupport.cpp" +#endif + +/* SORCERER Stuff */ + +/* MR8 6-Aug-97 Change from ifdef PC to ifndef LONGFILENAMES */ + +#ifndef LONGFILENAMES +#define STPARSER_H "STreePar.h" +#define STPARSER_C "STreePar.C" +#else +#define STPARSER_H "STreeParser.h" +#define STPARSER_C "STreeParser.cpp" +#endif + +#ifdef MPW +#define CPP_FILE_SUFFIX ".cp" +#define CPP_FILE_SUFFIX_NO_DOT "cp" +#define OBJ_FILE_SUFFIX ".o" +#else +#ifdef PC +#define CPP_FILE_SUFFIX ".cpp" +#define CPP_FILE_SUFFIX_NO_DOT "cpp" +#define OBJ_FILE_SUFFIX ".obj" +#else +#ifdef __VMS +#define CPP_FILE_SUFFIX ".cpp" +#define CPP_FILE_SUFFIX_NO_DOT "cpp" +#define OBJ_FILE_SUFFIX ".obj" +#else +#define CPP_FILE_SUFFIX ".cpp" +#define CPP_FILE_SUFFIX_NO_DOT "cpp" +#define OBJ_FILE_SUFFIX ".o" +#endif +#endif +#endif + +/* User may redefine how line information looks */ /* make it #line MR7 */ +/* MR21 Use #ifndef */ + +#ifndef LineInfoFormatStr +#define LineInfoFormatStr "#line %d \"%s\"\n" +#endif + +#ifdef MPW /* Macintosh Programmer's Workshop */ +#define ErrHdr "File \"%s\"; Line %d #" +#else +#ifdef _MSC_VER /* MR14 Microsoft Visual C++ environment */ +#define ErrHdr "%s(%d) :" +#else +#define ErrHdr "%s, line %d:" /* default */ +#endif +#endif + +/* must assume old K&R cpp here, can't use #if defined(..)... */ + +#ifdef MPW +#define TopDirectory ":" +#define DirectorySymbol ":" +#define OutputDirectoryOption "Directory where all output files should go (default=\":\")" +#else +#ifdef PC +#define TopDirectory "." +#define DirectorySymbol "\\" +#define OutputDirectoryOption "Directory where all output files should go (default=\".\")" +#else +#ifdef __VMS +#define TopDirectory "[000000]" +#define DirectorySymbol "]" +#define OutputDirectoryOption "Directory where all output files should go (default=\"[]\")" +#else +#define TopDirectory "." +#define DirectorySymbol "/" +#define OutputDirectoryOption "Directory where all output files should go (default=\".\")" +#endif +#endif +#endif + +#ifdef MPW + +/* Make sure we have prototypes for all functions under MPW */ + +#include "pccts_string.h" +#include "pccts_stdlib.h" + +/* MR6 2-Jun-97 Fixes false dependency caused by VC++ #include scanner */ +/* MR6 Reported by Brad Schick (schick@interaccess.com) */ +#define MPW_CursorCtl_Header +#include MPW_CursorCtl_Header +#ifdef __cplusplus +extern "C" { +#endif +extern void fsetfileinfo (const char *filename, unsigned long newcreator, unsigned long newtype); +#ifdef __cplusplus +} +#endif + +/* File creators for various popular development environments */ + +#define MAC_FILE_CREATOR 'MPS ' /* MPW Text files */ +#if 0 +#define MAC_FILE_CREATOR 'KAHL' /* THINK C/Symantec C++ Text files */ +#endif +#if 0 +#define MAC_FILE_CREATOR 'CWIE' /* Metrowerks C/C++ Text files */ +#endif + +#endif + +#ifdef MPW +#define DAWDLE SpinCursor(1) +#else +#define DAWDLE +#endif + +#ifdef MPW +#define SPECIAL_INITS +#define SPECIAL_FOPEN +#endif + +#ifdef MPW +#ifdef __cplusplus +inline +#else +static +#endif +void special_inits() +{ + InitCursorCtl((acurHandle) 0); +} +#endif + +#ifdef MPW +#ifdef __cplusplus +inline +#else +static +#endif +void special_fopen_actions(char * s) +{ + fsetfileinfo (s, MAC_FILE_CREATOR, 'TEXT'); +} +#endif + +/* Define usable bits for set.c stuff */ +#define BytesPerWord sizeof(unsigned) +#define WORDSIZE (sizeof(unsigned)*8) +#define LogWordSize (WORDSIZE==16?4:5) + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#if defined(VAXC) || defined(__VMS) +#include +#define PCCTS_EXIT_SUCCESS 1 +#define PCCTS_EXIT_FAILURE SS$_ABORT +#define zzDIE return SS$_ABORT; +#define zzDONE return 1; + +#else /* !VAXC and !__VMS */ + +#define PCCTS_EXIT_SUCCESS 0 +#define PCCTS_EXIT_FAILURE 1 +#define zzDIE return 1; +#define zzDONE return 0; + +#endif + +#ifdef USER_ZZMODE_STACK +# ifndef ZZSTACK_MAX_MODE +# define ZZSTACK_MAX_MODE 32 +# endif +# define ZZMAXSTK (ZZSTACK_MAX_MODE * 2) +#endif + +#ifndef DllExportPCCTS +#define DllExportPCCTS +#endif + +#ifdef PC +#ifndef PCCTS_CASE_INSENSITIVE_FILE_NAME +#define PCCTS_CASE_INSENSITIVE_FILE_NAME +#endif +#endif + +#ifdef PC32 +#ifndef PCCTS_CASE_INSENSITIVE_FILE_NAME +#define PCCTS_CASE_INSENSITIVE_FILE_NAME +#endif +#endif + +#ifdef __VMS +#ifndef PCCTS_CASE_INSENSITIVE_FILE_NAME +#define PCCTS_CASE_INSENSITIVE_FILE_NAME +#endif +#endif + +#ifdef __USE_PROTOS +#ifndef PCCTS_USE_STDARG +#define PCCTS_USE_STDARG +#endif +#endif + +#ifdef __STDC__ +#ifndef PCCTS_USE_STDARG +#define PCCTS_USE_STDARG +#endif +#endif + +#ifdef __cplusplus +#ifndef PCCTS_USE_STDARG +#define PCCTS_USE_STDARG +#endif +#endif + +#ifdef _MSC_VER +/*Turn off the warnings for: + unreferenced inline/local function has been removed +*/ +#pragma warning(disable : 4514) +/* function not expanded */ +#pragma warning(disable : 4710) +#endif + +#endif diff --git a/Tools/CodeTools/Source/Pccts/h/pcnames.bat b/Tools/CodeTools/Source/Pccts/h/pcnames.bat new file mode 100644 index 0000000000..8784aee9ab --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/pcnames.bat @@ -0,0 +1,11 @@ +ren aparser.c aparser.cpp +ren astbase.c astbase.cpp +ren atokenbu.c atokbuf.cpp +ren atokenbu.h atokbuf.h +ren atokenst.h atokstr.h +ren dlexerba.c dlexbase.cpp +ren dlexerba.h dlexbase.h +ren dlexer.c dlexer.cpp +ren list.c list.cpp +ren pblackbo.h pblckbox.h +ren pcctsast.c pcctsast.cpp diff --git a/Tools/CodeTools/Source/Pccts/h/slist.cpp b/Tools/CodeTools/Source/Pccts/h/slist.cpp new file mode 100644 index 0000000000..faf2fe4967 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/h/slist.cpp @@ -0,0 +1,116 @@ +/* + * SList.C + * + * SOFTWARE RIGHTS + * + * We reserve no LEGAL rights to SORCERER -- SORCERER is in the public + * domain. An individual or company may do whatever they wish with + * source code distributed with SORCERER or the code generated by + * SORCERER, including the incorporation of SORCERER, or its output, into + * commerical software. + * + * We encourage users to develop software with SORCERER. However, we do + * ask that credit is given to us for developing SORCERER. By "credit", + * we mean that if you incorporate our source code into one of your + * programs (commercial product, research project, or otherwise) that you + * acknowledge this fact somewhere in the documentation, research report, + * etc... If you like SORCERER and have developed a nice tool with the + * output, please mention that you developed it using SORCERER. In + * addition, we ask that this header remain intact in our source code. + * As long as these guidelines are kept, we expect to continue enhancing + * this system and expect to make other tools available as they are + * completed. + * + * PCCTS 1.33 + * Terence Parr + * Parr Research Corporation + * with Purdue University and AHPCRC, University of Minnesota + * 1992-2000 + */ + +#define ANTLR_SUPPORT_CODE + +#include "SList.h" +#include "pccts_stdarg.h" // MR23 + +/* Iterate over a list of elements; returns ptr to a new element + * in list upon every call and NULL when no more are left. + * Very useful like this: + * + * cursor = mylist; + * while ( (p=mylist->iterate(&cursor)) ) { + * // place with element p + * } + * + * The cursor must be initialized to point to the list to iterate over. + */ +void *SList:: +iterate(SListNode **cursor) +{ + void *e; + + if ( cursor == NULL || *cursor==NULL ) return NULL; + if ( head == *cursor ) { *cursor = (*cursor)->next(); } + e = (*cursor)->elem(); + (*cursor) = (*cursor)->next(); + return e; +} + +/* add an element to end of list. */ +void SList:: +add(void *e) +{ + SListNode *p, *tail=NULL; + require(e!=NULL, "slist_add: attempting to add NULL list element"); + + p = new SListNode; + require(p!=NULL, "add: cannot alloc new list node"); + p->setElem(e); + if ( head == NULL ) + { + head = tail = p; + } + else /* find end of list */ + { + tail->setNext(p); + tail = p; + } +} + +void SList:: +lfree() +{ + SListNode *p,*q; + + if ( head==NULL ) return; /* empty list */ + for (p = head; p!=NULL; p=q) + { + q = p->next(); + free(p); + } +} + +PCCTS_AST *SList:: +to_ast(SList list) +{ + PCCTS_AST *t=NULL, *last=NULL; + SListNode *p; + + for (p = head; p!=NULL; p=p->next()) + { + PCCTS_AST *u = (PCCTS_AST *)p->elem(); + if ( last==NULL ) last = t = u; + else { last->setRight(u); last = u; } + } + return t; +} + +// MR23 +int SList::printMessage(FILE* pFile, const char* pFormat, ...) +{ + va_list marker; + va_start( marker, pFormat ); + int iRet = vfprintf(pFile, pFormat, marker); + va_end( marker ); + return iRet; +} diff --git a/Tools/CodeTools/Source/Pccts/history.ps b/Tools/CodeTools/Source/Pccts/history.ps new file mode 100644 index 0000000000..e2600d5129 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/history.ps @@ -0,0 +1,473 @@ +%!PS-Adobe-3.0 +%%Creator: groff version 1.06 +%%DocumentNeededResources: font Times-Roman +%%+ font Times-Italic +%%+ font Courier +%%DocumentSuppliedResources: procset grops 1.06 0 +%%Pages: 3 +%%PageOrder: Ascend +%%Orientation: Portrait +%%EndComments +%%BeginProlog +%%BeginResource: procset grops 1.06 0 + +/setpacking where { + pop + currentpacking + true setpacking +} if + +/grops 120 dict dup begin + +% The ASCII code of the space character. +/SC 32 def + +/A /show load def +/B { 0 SC 3 -1 roll widthshow } bind def +/C { 0 exch ashow } bind def +/D { 0 exch 0 SC 5 2 roll awidthshow } bind def +/E { 0 rmoveto show } bind def +/F { 0 rmoveto 0 SC 3 -1 roll widthshow } bind def +/G { 0 rmoveto 0 exch ashow } bind def +/H { 0 rmoveto 0 exch 0 SC 5 2 roll awidthshow } bind def +/I { 0 exch rmoveto show } bind def +/J { 0 exch rmoveto 0 SC 3 -1 roll widthshow } bind def +/K { 0 exch rmoveto 0 exch ashow } bind def +/L { 0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow } bind def +/M { rmoveto show } bind def +/N { rmoveto 0 SC 3 -1 roll widthshow } bind def +/O { rmoveto 0 exch ashow } bind def +/P { rmoveto 0 exch 0 SC 5 2 roll awidthshow } bind def +/Q { moveto show } bind def +/R { moveto 0 SC 3 -1 roll widthshow } bind def +/S { moveto 0 exch ashow } bind def +/T { moveto 0 exch 0 SC 5 2 roll awidthshow } bind def + +% name size font SF - + +/SF { + findfont exch + [ exch dup 0 exch 0 exch neg 0 0 ] makefont + dup setfont + [ exch /setfont cvx ] cvx bind def +} bind def + +% name a c d font MF - + +/MF { + findfont + [ 5 2 roll + 0 3 1 roll % b + neg 0 0 ] makefont + dup setfont + [ exch /setfont cvx ] cvx bind def +} bind def + +/level0 0 def +/RES 0 def +/PL 0 def +/LS 0 def + +% Guess the page length. +% This assumes that the imageable area is vertically centered on the page. +% PLG - length + +/PLG { + gsave newpath clippath pathbbox grestore + exch pop add exch pop +} bind def + +% BP - + +/BP { + /level0 save def + 1 setlinecap + 1 setlinejoin + 72 RES div dup scale + LS { + 90 rotate + } { + 0 PL translate + } ifelse + 1 -1 scale +} bind def + +/EP { + level0 restore + showpage +} bind def + + +% centerx centery radius startangle endangle DA - + +/DA { + newpath arcn stroke +} bind def + +% x y SN - x' y' +% round a position to nearest (pixel + (.25,.25)) + +/SN { + transform + .25 sub exch .25 sub exch + round .25 add exch round .25 add exch + itransform +} bind def + +% endx endy startx starty DL - +% we round the endpoints of the line, so that parallel horizontal +% and vertical lines will appear even + +/DL { + SN + moveto + SN + lineto stroke +} bind def + +% centerx centery radius DC - + +/DC { + newpath 0 360 arc closepath +} bind def + + +/TM matrix def + +% width height centerx centery DE - + +/DE { + TM currentmatrix pop + translate scale newpath 0 0 .5 0 360 arc closepath + TM setmatrix +} bind def + +% these are for splines + +/RC /rcurveto load def +/RL /rlineto load def +/ST /stroke load def +/MT /moveto load def +/CL /closepath load def + +% fill the last path + +% amount FL - + +/FL { + currentgray exch setgray fill setgray +} bind def + +% fill with the ``current color'' + +/BL /fill load def + +/LW /setlinewidth load def +% new_font_name encoding_vector old_font_name RE - + +/RE { + findfont + dup maxlength dict begin + { + 1 index /FID ne { def } { pop pop } ifelse + } forall + /Encoding exch def + dup /FontName exch def + currentdict end definefont pop +} bind def + +/DEFS 0 def + +% hpos vpos EBEGIN - + +/EBEGIN { + moveto + DEFS begin +} bind def + +/EEND /end load def + +/CNT 0 def +/level1 0 def + +% llx lly newwid wid newht ht newllx newlly PBEGIN - + +/PBEGIN { + /level1 save def + translate + div 3 1 roll div exch scale + neg exch neg exch translate + % set the graphics state to default values + 0 setgray + 0 setlinecap + 1 setlinewidth + 0 setlinejoin + 10 setmiterlimit + [] 0 setdash + /setstrokeadjust where { + pop + false setstrokeadjust + } if + /setoverprint where { + pop + false setoverprint + } if + newpath + /CNT countdictstack def + userdict begin + /showpage {} def +} bind def + +/PEND { + clear + countdictstack CNT sub { end } repeat + level1 restore +} bind def + +end def + +/setpacking where { + pop + setpacking +} if +%%EndResource +%%IncludeResource: font Times-Roman +%%IncludeResource: font Times-Italic +%%IncludeResource: font Courier +grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL +792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron +/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space +/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft +/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four +/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C +/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash +/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q +/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase +/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger +/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut +/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash +/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar +/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus +/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu +/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright +/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde +/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute +/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis +/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls +/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute +/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve +/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex +/udieresis/yacute/thorn/ydieresis]def/Courier@0 ENC0/Courier RE/Times-Italic@0 +ENC0/Times-Italic RE/Times-Roman@0 ENC0/Times-Roman RE +%%EndProlog +%%Page: 1 1 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 13/Times-Roman@0 SF(The History of PCCTS)228.232 84 Q/F1 11/Times-Roman@0 +SF(The Purdue Compiler)190.468 108 Q(-Construction T)-.22 E(ool Set)-.88 E/F2 +10/Times-Italic@0 SF -.92(Te)262.245 144 S -.37(re).92 G(nce P).37 E(arr)-.8 E +/F3 10/Times-Roman@0 SF -.15(Pa)234.755 156 S(rr Research Corporation).15 E +(Minneapolis, Minnesota)239.39 168 Q(and)280.78 180 Q(Uni)239.315 192 Q -.15 +(ve)-.25 G(rsity of Minnesota).15 E +(Army High Performance Computing Research Center)180.38 204 Q F2 +([Updated 8-7-94])252.31 228 Q F1 .084(The PCCTS project be)97 259.6 R -.055 +(ga)-.165 G 2.834(na).055 G 2.833(sap)220.547 259.6 S(arser)240.876 259.6 Q +.083(-generator project for a graduate course at Purdue Uni-)-.22 F -.165(ve)72 +275.6 S 1.085(rsity in the F).165 F 1.086 +(all of 1988 taught by Hank Dietz\212 translator)-.165 F 1.086 +(-writing systems.)-.22 F 1.086(Under the guid-)6.586 F .627 +(ance of Professor Dietz, the parser generator)72 291.6 R 3.377(,A)-.44 G .626 +(NTLR \(originally called YUCC\), continued after)285.18 291.6 R .253 +(the termination of the course and e)72 307.6 R -.165(ve)-.275 G .254 +(ntually became the subject of T).165 F .254(erence P)-.77 F(arr')-.165 E 3.004 +(sM)-.605 G(aster')445.083 307.6 Q 3.004(st)-.605 G(hesis.)479.25 307.6 Q +(Originally)72 323.6 Q 4.092(,l)-.715 G -.165(ex)126.406 323.6 S 1.342 +(ical analysis w).165 F 1.342(as performed via ALX which w)-.11 F 1.342 +(as soon replaced by W)-.11 F 1.341(ill Cohen')-.44 F(s)-.605 E .594 +(DLG in the F)72 339.6 R .594(all of 1989 \(DF)-.165 F .595(A-based le)-.814 F +.595(xical-analyzer generator)-.165 F 3.345(,a)-.44 G .595(lso an of)367.188 +339.6 R .595(fshoot of the graduate)-.275 F(translation course\).)72 355.6 Q +.877(The alpha v)97 375.2 R .877(ersion of ANTLR w)-.165 F .877(as totally re) +-.11 F .876(written resulting in 1.00B.)-.275 F -1.221(Ve)6.376 G .876 +(rsion 1.00B w)1.221 F(as)-.11 E 1.577(released via an internet ne)72 391.2 R +1.577(wsgroup \(comp.compilers\) posting in February of 1990 and quickly)-.275 +F -.055(ga)72 407.2 S .356(thered a lar).055 F .356(ge follo)-.198 F 3.106 +(wing. 1.00B)-.275 F .356(generated only LL\(1\) parsers, b)3.106 F .356 +(ut allo)-.22 F .356(wed the mer)-.275 F .356(ged descrip-)-.198 F 1.859 +(tion of le)72 423.2 R 1.859(xical and syntactic analysis.)-.165 F 1.86 +(It had rudimentary attrib)7.359 F 1.86(ute handling similar to that of)-.22 F +-.55 -1.32(YA C)72 439.2 T 3.549(Ca)1.32 G .799 +(nd did not incorporate rule parameters or return v)109.231 439.2 R .798 +(alues; do)-.275 F(wnw)-.275 E .798(ard inheritance w)-.11 F .798(as v)-.11 F +(ery)-.165 E -.165(aw)72 455.2 S(kw).165 E 6.433(ard. 1.00B-generated)-.11 F +3.684(parsers terminated upon the \214rst syntax error)6.433 F 9.184(.L)-.605 G +-.165(ex)440.916 455.2 S 3.684(ical classes).165 F(\(modes\) were not allo)72 +471.2 Q(wed and DLG did not ha)-.275 E .33 -.165(ve a)-.22 H 2.75(ni).165 G +(nteracti)305.959 471.2 Q .33 -.165(ve m)-.275 H(ode.).165 E .831 +(Upon starting his Ph.D. at Purdue in the F)97 490.8 R .83(all of 1990, T)-.165 +F .83(erence P)-.77 F .83(arr be)-.165 F -.055(ga)-.165 G 3.58(nt).055 G .83 +(he second total)436.351 490.8 R(re)72 506.8 Q 1.646(write of ANTLR.)-.275 F +1.646(The method by which grammars may be practically analyzed to generate) +7.146 F/F4 11/Times-Italic@0 SF(LL)72.638 522.8 Q F1(\().583 E F4(k).396 E F1 +3.849(\)l).737 G 1.099(ookahead information w)105.703 522.8 R 1.099(as disco) +-.11 F -.165(ve)-.165 G 1.099(red in August of 1990 just before his return.) +.165 F -1.221(Ve)6.598 G(rsion)1.221 E .626 +(1.00 incorporated this algorithm and included the AST mechanism, le)72 538.8 R +.626(xical classes, error classes,)-.165 F .354(and automatic error reco)72 +554.8 R -.165(ve)-.165 G .353(ry; code quality and portability were higher).165 +F 5.853(.I)-.605 G 3.103(nF)395.965 554.8 S .353(ebruary of 1992 1.00)410.684 +554.8 R -.11(wa)72 570.8 S 2.76(sr).11 G .01 +(eleased via an article in SIGPLAN Notices.)95.418 570.8 R .01 +(Peter Dahl, Ph.D. candidate, and Professor Matt)5.51 F(O'K)72 586.8 Q 2.074 +(eefe \(both at the Uni)-.275 F -.165(ve)-.275 G 2.073 +(rsity of Minnesota\) tested this v).165 F 2.073(ersion e)-.165 F(xtensi)-.165 +E -.165(ve)-.275 G(ly).165 E 7.573(.D)-.715 G 2.073(ana Hogg)448.522 586.8 R +(att)-.055 E .078(\(Micro Data Base Systems, Inc.\) came up with the idea of e\ +rror grouping \(strings attached to non-)72 602.8 R +(terminals\) and tested 1.00 hea)72 618.8 Q(vily)-.22 E(.)-.715 E -1.221(Ve)97 +638.4 S .878(rsion 1.06 w)1.221 F .877 +(as released in December 1992 and represented a lar)-.11 F .877 +(ge feature enhancement)-.198 F -.165(ove)72 654.4 S 3.648(r1).165 G 3.648 +(.00. F)100.365 654.4 R .898(or e)-.165 F .899 +(xample, rudimentary semantic predicates were introduced, error messages were) +-.165 F 2.281(signi\214cantly impro)72 670.4 R -.165(ve)-.165 G 5.031(df).165 G +(or)181.953 670.4 Q F4(k)5.427 E F1 2.281 +(>1 lookahead and ANTLR parsers could indicate that lookahead).737 F 1.381 +(fetches were to occur only when necessary for the parse \(normally)72 686.4 R +4.131(,t)-.715 G 1.381(he lookahead `)387.051 686.4 R(`pipe')-.814 E 4.132('w) +-.814 G(as)494.837 686.4 Q 1.182(constantly full\).)72 702.4 R 1.182 +(Russell Quong joined the project in the Spring of 1992 to aid in the semantic) +6.682 F .681(predicate design.)72 718.4 R(Be)6.181 E .681(ginning and adv)-.165 +F .682(anced tutorials were created and released as well.)-.275 F 3.432(Am) +6.182 G(ak)485.179 718.4 Q(e-)-.11 E .993(\214le generator w)72 734.4 R .993 +(as included that sets up dependencies and such correctly for ANTLR and DLG.) +-.11 F EP +%%Page: 2 2 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 11/Times-Roman@0 SF 2.75(-2-)278.837 52 S -1.221(Ve)72 88 S 1.414(ry fe) +1.221 F 4.164(w1)-.275 G 1.414(.00 incompatibilities were introduced \(1.00 w) +122.81 88 R 1.415(as quite dif)-.11 F 1.415(ferent from 1.00B in some)-.275 F +(areas\).)72 104 Q 1.089(1.10 w)97 123.6 R 1.088 +(as released on August 31, 1993 and incorporated b)-.11 F 1.088(ug \214x)-.22 F +1.088(es, a fe)-.165 F 3.838(wf)-.275 G 1.088(eature enhance-)433.59 123.6 R +3.112(ments and a major ne)72 139.6 R 5.863(wc)-.275 G(apability \212)196.957 +139.6 Q 3.113(an arbitrary lookahead operator \(syntactic predicate\),)5.863 F +/F1 11/Courier@0 SF(\(alpha\)?beta)72 155.6 Q F0 6.754(.T)C 1.254 +(his feature w)167.425 155.6 R 1.254 +(as co-designed with Professor Russell Quong also at Purdue.)-.11 F 3.297 -.88 +(To s)72 171.6 T 1.537 +(upport in\214nite lookahead, a preprocessor \215ag, ZZINF_LOOK, w).88 F 1.537 +(as created that forced the)-.11 F .21(ANTLR\(\) macro to tok)72 187.6 R .21 +(enize all input prior to parsing.)-.11 F .209(Hence, at an)5.709 F 2.959(ym) +-.165 G .209(oment, an action or predi-)389.215 187.6 R .936 +(cate can see the entire input sentence.)72 203.6 R .936 +(The predicate mechanism of 1.06 w)6.436 F .937(as e)-.11 F .937 +(xtended to allo)-.165 F(w)-.275 E .55 +(multiple predicates to be hoisted; the syntactic conte)72 219.6 R .55 +(xt of a predicate w)-.165 F .55(as also mo)-.11 F -.165(ve)-.165 G 3.299(da) +.165 G .549(long with)461.585 219.6 R(the predicate.)72 235.6 Q .754 +(In February of 1994, SORCERER \(a simple tree-parser generator\) w)97 255.2 R +.755(as released.)-.11 F .755(This tool)6.255 F(allo)72 271.2 Q .6(ws the user\ + to parse child-sibling trees by specifying a grammar rather than b)-.275 F +.599(uilding a recur)-.22 F(-)-.22 E(si)72 287.2 Q -.165(ve)-.275 G 1.39 +(-descent tree w).165 F(alk)-.11 E 1.391(er by hand.)-.11 F -.88(Wo)6.891 G +1.391(rk to).88 F -.11(wa)-.275 G 1.391 +(rds a library of tree transformations is underw).11 F(ay)-.11 E(.)-.715 E .581 +(Aaron Sa)72 303.2 R(wde)-.165 E 3.331(ya)-.165 G 3.331(tT)145.531 303.2 S .581 +(he Uni)158.641 303.2 R -.165(ve)-.275 G .58 +(rsity of Minnesota became a second author of SORCERER after the).165 F +(initial release.)72 319.2 Q .627(On April 1, 1994, PCCTS 1.20 w)97 338.8 R +.627(as released.)-.11 F .627(This w)6.127 F .627(as the \214rst v)-.11 F .627 +(ersion to acti)-.165 F -.165(ve)-.275 G .627(ly support).165 F 1.664 +(C++ output.)72 354.8 R 1.664(It also included important \214x)7.164 F 1.663 +(es re)-.165 F -.055(ga)-.165 G 1.663 +(rding semantic predicates and \(..\)+ subrules.).055 F(This v)72 370.8 Q +(ersion also introduced tok)-.165 E(en classes, the `)-.11 E(`)-.814 E/F2 11 +/Times-Italic@0 SF(not)A F0 1.628 -.814('' o)D(perator).814 E 2.75(,a)-.44 G +(nd tok)355.294 370.8 Q(en ranges.)-.11 E .764 +(On June 19, 1994, SORCERER 1.00B9 w)97 390.4 R .765(as released.)-.11 F .765 +(Gary Funck of Intrepid T)6.265 F(echnology)-.77 E .807 +(joined the SORCERER team and pro)72 406.4 R .807(vided v)-.165 F .807(ery v) +-.165 F .807(aluable suggestions re)-.275 F -.055(ga)-.165 G .806(rding the `) +.055 F(`transform')-.814 E(')-.814 E(mode of SORCERER.)72 422.4 Q 1.137 +(On August 8, 1994, PCCTS 1.21 w)97 442 R 1.137(as released.)-.11 F 1.138 +(It mainly cleaned up the C++ output and)6.637 F(included a number of b)72 458 +Q(ug \214x)-.22 E(es.)-.165 E .316(From the 1.21 release forw)97 477.6 R .316 +(ard, the maintenance and support of all PCCTS tools will be pri-)-.11 F 1.557 +(marily pro)72 493.6 R 1.557(vided by P)-.165 F 1.557 +(arr Research Corporation, Minneapolis MN---an or)-.165 F -.055(ga)-.198 G +1.558(nization founded on).055 F 1.616(the principles of e)72 509.6 R 1.616 +(xcellence in research and inte)-.165 F 1.616(grity in b)-.165 F 1.616 +(usiness; we are de)-.22 F -.22(vo)-.275 G 1.616(ted to pro).22 F(viding)-.165 +E 1.202(really cool softw)72 525.6 R 1.202(are tools.)-.11 F 1.202 +(Please see \214le PCCTS.FUTURE for more information.)6.702 F 1.203(All PCCTS) +6.703 F(tools currently in the public domain will continue to be in the public\ + domain.)72 541.6 Q 1.198(Looking to)97 561.2 R -.11(wa)-.275 G 1.198 +(rds the future, a graphical user).11 F(-interf)-.22 E 1.197 +(ace is in the design phase.)-.11 F 1.197(This w)6.697 F(ould)-.11 E(allo)72 +577.2 Q 2.753(wu)-.275 G .003(sers to vie)104.42 577.2 R 2.753(wt)-.275 G .004 +(he syntax diagram representation of their grammars and w)162.509 577.2 R .004 +(ould highlight non-)-.11 F 1.181(deterministic productions.)72 593.2 R -.165 +(Pa)6.681 G 1.18(rsing can be traced graphically as well.).165 F 1.18 +(This system will be b)6.68 F(uilt)-.22 E .167(using a multiplatform windo)72 +609.2 R 2.917(wl)-.275 G(ibrary)211.73 609.2 Q 5.667(.W)-.715 G 2.917(ea) +255.204 609.2 S .168(lso anticipate the introduction of a sophisticated error) +267.889 609.2 R(handling mechanism called `)72 625.2 Q(`parser e)-.814 E +(xception handling')-.165 E 2.75('i)-.814 G 2.75(nan)327.431 625.2 S +(ear future release.)348.815 625.2 Q(Currently)97 644.8 Q 3.019(,P)-.715 G .269 +(CCTS is used at o)150.333 644.8 R -.165(ve)-.165 G 3.019(r1).165 G .269 +(000 kno)253.098 644.8 R .268(wn academic, go)-.275 F -.165(ve)-.165 G .268 +(rnment, and commercial sites).165 F .859(in 37 countries.)72 660.8 R .859 +(Of course, the true number of users is unkno)6.359 F .859(wn due to the lar) +-.275 F .859(ge number of ftp)-.198 F(sites.)72 676.8 Q EP +%%Page: 3 3 +%%BeginPageSetup +BP +%%EndPageSetup +/F0 11/Times-Roman@0 SF 2.75(-3-)278.837 52 S(Credits)272.11 88 Q .44 LW +472.162 103.75 103.838 103.75 DL(Idea/T)134.236 117 Q 52.987(ool Coder)-.88 F +(Co-designer\(s\))345.436 117 Q 281.334 103.75 281.334 124.75 DL 209.273 103.75 +209.273 124.75 DL 209.273 124.75 103.838 124.75 DL 103.838 126.75 209.273 +126.75 DL 281.334 124.75 209.273 124.75 DL 209.273 126.75 281.334 126.75 DL +472.162 124.75 281.334 124.75 DL 281.334 126.75 472.162 126.75 DL(ANTLR 1.00A) +109.338 140 Q -.77(Te)217.523 140 S(rence P).77 E 13.75(arr Hank)-.165 F(Dietz) +2.75 E 82.83(ALX T)109.338 156 R(erence P)-.77 E 13.75(arr Hank)-.165 F(Dietz) +2.75 E(ANTLR 1.00B)109.338 172 Q -.77(Te)217.523 172 S(rence P).77 E 13.75 +(arr Hank)-.165 F(Dietz, W)2.75 E(ill Cohen)-.44 E(DLG 1.00B)109.338 188 Q -.44 +(Wi)217.523 188 S(ll Cohen).44 E -.77(Te)289.584 188 S(rence P).77 E(arr)-.165 +E 2.75(,H)-.44 G(ank Dietz)358.147 188 Q(NF)109.338 204 Q 2.75(AR)-.814 G +30.778(elabelling W)140.611 204 R(ill Cohen)-.44 E/F1 11/Times-Italic@0 SF(LL) +109.976 220 Q F0(\().583 E F1(k).396 E F0 2.75(\)a).737 G 40.447(nalysis T) +143.768 220 R(erence P)-.77 E 13.75(arr Hank)-.165 F(Dietz)2.75 E(ANTLR 1.00) +109.338 236 Q -.77(Te)217.523 236 S(rence P).77 E 13.75(arr Hank)-.165 F +(Dietz, W)2.75 E(ill Cohen)-.44 E(DLG 1.00)109.338 252 Q -.44(Wi)217.523 252 S +(ll Cohen).44 E -.77(Te)289.584 252 S(rence P).77 E(arr)-.165 E 2.75(,H)-.44 G +(ank Dietz)358.147 252 Q(ANTLR 1.06)109.338 268 Q -.77(Te)217.523 268 S +(rence P).77 E 13.75(arr W)-.165 F(ill Cohen, Russell Quong, Hank Dietz)-.44 E +(DLG 1.06)109.338 284 Q -.44(Wi)217.523 284 S(ll Cohen).44 E -.77(Te)289.584 +284 S(rence P).77 E(arr)-.165 E 2.75(,H)-.44 G(ank Dietz)358.147 284 Q +(ANTLR 1.10)109.338 300 Q -.77(Te)217.523 300 S(rence P).77 E 13.75(arr W)-.165 +F(ill Cohen, Russell Quong)-.44 E(ANTLR 1.20)109.338 316 Q -.77(Te)217.523 316 +S(rence P).77 E 13.75(arr W)-.165 F(ill Cohen, Russell Quong)-.44 E(ANTLR 1.21) +109.338 332 Q -.77(Te)217.523 332 S(rence P).77 E 13.75(arr Russell)-.165 F +(Quong)2.75 E(DLG 1.10)109.338 348 Q -.44(Wi)217.523 348 S(ll Cohen).44 E -.77 +(Te)289.584 348 S(rence P).77 E(arr)-.165 E(DLG 1.20)109.338 364 Q -.44(Wi) +217.523 364 S(ll Cohen).44 E -.77(Te)289.584 364 S(rence P).77 E(arr)-.165 E +(DLG 1.21)109.338 380 Q -.77(Te)217.523 380 S(rence P).77 E(arr)-.165 E +(Semantic predicates)109.338 396 Q -.77(Te)217.523 396 S(rence P).77 E 13.75 +(arr Russell)-.165 F(Quonq)2.75 E(Syntactic predicates)109.338 412 Q -.77(Te) +217.523 412 S(rence P).77 E 13.75(arr Russell)-.165 F(Quonq)2.75 E +(SORCERER 1.00A)109.338 428 Q -.77(Te)217.523 428 S(rence P).77 E(arr)-.165 E +(SORCERER 1.00B)109.338 444 Q -.77(Te)217.523 444 S(rence P).77 E 13.75 +(arr Aaron)-.165 F(Sa)2.75 E(wde)-.165 E(y)-.165 E(SORCERER 1.00B9)109.338 460 +Q -.77(Te)217.523 460 S(rence P).77 E 13.75(arr Aaron)-.165 F(Sa)2.75 E(wde) +-.165 E 1.43 -.715(y, G)-.165 H(ary Funck).715 E 472.162 467.75 103.838 467.75 +DL 472.162 103.75 472.162 467.75 DL 103.838 103.75 103.838 467.75 DL EP +%%Trailer +end +%%EOF diff --git a/Tools/CodeTools/Source/Pccts/history.txt b/Tools/CodeTools/Source/Pccts/history.txt new file mode 100644 index 0000000000..89ad8408c9 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/history.txt @@ -0,0 +1,186 @@ + + + + The History of PCCTS + + The Purdue Compiler-Construction Tool Set + + + Terence Parr + Parr Research Corporation + Minneapolis, Minnesota + and + University of Minnesota + Army High Performance Computing Research Center + + [Updated 8-7-94] + + + The PCCTS project began as a parser-generator project for a gra- +duate course at Purdue University in the Fall of 1988 taught by Hank +Dietz- translator-writing systems. Under the guidance of Professor +Dietz, the parser generator, ANTLR (originally called YUCC), continued +after the termination of the course and eventually became the subject +of Terence Parr's Master's thesis. Originally, lexical analysis was +performed via ALX which was soon replaced by Will Cohen's DLG in the +Fall of 1989 (DFA-based lexical-analyzer generator, also an offshoot +of the graduate translation course). + + The alpha version of ANTLR was totally rewritten resulting in +1.00B. Version 1.00B was released via an internet newsgroup +(comp.compilers) posting in February of 1990 and quickly gathered a +large following. 1.00B generated only LL(1) parsers, but allowed the +merged description of lexical and syntactic analysis. It had rudimen- +tary attribute handling similar to that of YACC and did not incor- +porate rule parameters or return values; downward inheritance was very +awkward. 1.00B-generated parsers terminated upon the first syntax +error. Lexical classes (modes) were not allowed and DLG did not have +an interactive mode. + + Upon starting his Ph.D. at Purdue in the Fall of 1990, Terence +Parr began the second total rewrite of ANTLR. The method by which +grammars may be practically analyzed to generate LL(k) lookahead +information was discovered in August of 1990 just before his return. +Version 1.00 incorporated this algorithm and included the AST mechan- +ism, lexical classes, error classes, and automatic error recovery; +code quality and portability were higher. In February of 1992 1.00 +was released via an article in SIGPLAN Notices. Peter Dahl, Ph.D. +candidate, and Professor Matt O'Keefe (both at the University of Min- +nesota) tested this version extensively. Dana Hoggatt (Micro Data +Base Systems, Inc.) came up with the idea of error grouping (strings +attached to non-terminals) and tested 1.00 heavily. + + Version 1.06 was released in December 1992 and represented a +large feature enhancement over 1.00. For example, rudimentary seman- +tic predicates were introduced, error messages were significantly +improved for k>1 lookahead and ANTLR parsers could indicate that loo- +kahead fetches were to occur only when necessary for the parse + + + + Page 1 + + PCCTS + + +(normally, the lookahead "pipe" was constantly full). Russell Quong +joined the project in the Spring of 1992 to aid in the semantic predi- +cate design. Beginning and advanced tutorials were created and +released as well. A makefile generator was included that sets up +dependencies and such correctly for ANTLR and DLG. Very few 1.00 +incompatibilities were introduced (1.00 was quite different from 1.00B +in some areas). + + 1.10 was released on August 31, 1993 and incorporated bug fixes, +a few feature enhancements and a major new capability - an arbitrary +lookahead operator (syntactic predicate), (alpha)?beta. This feature +was co-designed with Professor Russell Quong also at Purdue. To sup- +port infinite lookahead, a preprocessor flag, ZZINF_LOOK, was created +that forced the ANTLR() macro to tokenize all input prior to parsing. +Hence, at any moment, an action or predicate can see the entire input +sentence. The predicate mechanism of 1.06 was extended to allow mul- +tiple predicates to be hoisted; the syntactic context of a predicate +was also moved along with the predicate. + + In February of 1994, SORCERER (a simple tree-parser generator) +was released. This tool allows the user to parse child-sibling trees +by specifying a grammar rather than building a recursive-descent tree +walker by hand. Work towards a library of tree transformations is +underway. Aaron Sawdey at The University of Minnesota became a second +author of SORCERER after the initial release. + + On April 1, 1994, PCCTS 1.20 was released. This was the first +version to actively support C++ output. It also included important +fixes regarding semantic predicates and (..)+ subrules. This version +also introduced token classes, the "not" operator, and token ranges. + + On June 19, 1994, SORCERER 1.00B9 was released. Gary Funck of +Intrepid Technology joined the SORCERER team and provided very valu- +able suggestions regarding the "transform" mode of SORCERER. + + On August 8, 1994, PCCTS 1.21 was released. It mainly cleaned up +the C++ output and included a number of bug fixes. + + From the 1.21 release forward, the maintenance and support of all +PCCTS tools will be primarily provided by Parr Research Corporation, +Minneapolis MN---an organization founded on the principles of excel- +lence in research and integrity in business; we are devoted to provid- +ing really cool software tools. Please see file PCCTS.FUTURE for more +information. All PCCTS tools currently in the public domain will con- +tinue to be in the public domain. + + Looking towards the future, a graphical user-interface is in the +design phase. This would allow users to view the syntax diagram +representation of their grammars and would highlight nondeterministic +productions. Parsing can be traced graphically as well. This system +will be built using a multiplatform window library. We also antici- +pate the introduction of a sophisticated error handling mechanism +called "parser exception handling" in a near future release. + + + + + Page 2 + + PCCTS + + + Currently, PCCTS is used at over 1000 known academic, government, +and commercial sites in 37 countries. Of course, the true number of +users is unknown due to the large number of ftp sites. + Credits + +_____________________________________________________________________________ +_____________________________________________________________________________ +|ANTLR 1.00A Terence Parr Hank Dietz | +|ALX Terence Parr Hank Dietz | +|ANTLR 1.00B Terence Parr Hank Dietz, Will Cohen | +|DLG 1.00B Will Cohen Terence Parr, Hank Dietz | +|NFA Relabelling Will Cohen | +|LL(k) analysis Terence Parr Hank Dietz | +|ANTLR 1.00 Terence Parr Hank Dietz, Will Cohen | +|DLG 1.00 Will Cohen Terence Parr, Hank Dietz | +|ANTLR 1.06 Terence Parr Will Cohen, Russell Quong, Hank Dietz| +|DLG 1.06 Will Cohen Terence Parr, Hank Dietz | +|ANTLR 1.10 Terence Parr Will Cohen, Russell Quong | +|ANTLR 1.20 Terence Parr Will Cohen, Russell Quong | +|ANTLR 1.21 Terence Parr Russell Quong | +|DLG 1.10 Will Cohen Terence Parr | +|DLG 1.20 Will Cohen Terence Parr | +|DLG 1.21 Terence Parr | +|Semantic predicates Terence Parr Russell Quonq | +|Syntactic predicates Terence Parr Russell Quonq | +|SORCERER 1.00A Terence Parr | +|SORCERER 1.00B Terence Parr Aaron Sawdey | +|SORCERER 1.00B9 Terence Parr Aaron Sawdey, Gary Funck | +|___________________________________________________________________________| + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Page 3 + diff --git a/Tools/CodeTools/Source/Pccts/makefile b/Tools/CodeTools/Source/Pccts/makefile new file mode 100644 index 0000000000..f9b2dd2b9b --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/makefile @@ -0,0 +1,66 @@ +# +# Main makefile for PCCTS 1.33MR33 /* MRXXX */ +# +# Terence Parr +# Parr Research Corporation +# +# verbosity versus silence... +PSss= +# +# this can be set to /user/local/bin etc... +BINDIR=bin +# This part added by Thomas Herter, M"unchen, Germany. See also manpages +# target. +MANDIR=$(HOME)/man +MANEXT=1 +MANFILES=dlg/dlg.1 antlr/antlr.1 + +#CC=cc +#CC=gcc +#COPT=-O2 + +pccts: + @echo " " + @echo " Welcome to PCCTS 1.33MR33 installation" + @echo " " + @echo " (Version 1.33 Maintenance Release #33)" # mrxxx + @echo " " + @echo " Released 19 April 2002" + @echo " " + @echo " Featuring" + @echo " ANTLR -- ANother Tool for Language Recognition" + @echo " DLG -- DFA-based Lexical Analyzer Generator" + @echo " SORCERER -- Source-to-source translator (tree walker)" + @echo " " + @echo " http://www.antlr.org" + @echo " " + @echo " Trouble reports to tmoog@polhode.com" + @echo " Additional PCCTS 1.33 information at" + @echo " http://www.polhode.com" + @echo + @echo + @echo "To substitute gcc for CC to invoke compiler: make CC=gcc" + @echo "If there are problems with cr and lf try: unzip -a ..." + @echo +# + @if [ ! -d $(BINDIR) ] ; then mkdir $(BINDIR) ; fi + @echo Making executables... + (cd ./antlr; $(MAKE) CC="$(CC)" COPT="$(COPT)") + @echo antlr executable now in $(BINDIR) + (cd ./dlg; $(MAKE) CC="$(CC)" COPT="$(COPT)") + @echo dlg executable now in $(BINDIR) + @echo + @echo " PCCTS 1.33MR33 installation complete" # MRXXX + +clean: + (cd ./antlr; $(MAKE) -s clean) + (cd ./dlg; $(MAKE) -s clean) + + +manpages: + # mkdir -p $(MANDIR)/man$(MANEXT) + if [ ! -d $(MANDIR) ] ; then \ + mkdir $(MANDIR) ; fi + if [ ! -d $(MANDIR)/man$(MANEXT) ] ; then \ + mkdir $(MANDIR)/man$(MANEXT); fi + cp -p $(MANFILES) $(MANDIR)/man$(MANEXT) diff --git a/Tools/CodeTools/Source/Pccts/support/genmk/genmk.c b/Tools/CodeTools/Source/Pccts/support/genmk/genmk.c new file mode 100644 index 0000000000..4952a30b38 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/support/genmk/genmk.c @@ -0,0 +1,1063 @@ +/* + * genmk -- a program to make makefiles for PCCTS + * + * ANTLR 1.33MR23 + * Terence John Parr 1989 - 2000 + * Purdue University + * U of MN + */ + +#include +#include +#include "pcctscfg.h" /* be sensitive to what ANTLR/DLG call the files */ + +#ifdef VAXC +#define DIE return 0; +#define DONE return 1; +#else +#define DIE return 1; +#define DONE return 0; +#endif + +#ifndef require +#define require(expr, err) {if ( !(expr) ) fatal(err);} +#endif + +#define MAX_FILES 50 +#define MAX_CFILES 1600 +#define MAX_SFILES 50 +#define MAX_SORS 50 +#define MAX_CLASSES 50 + +char *RENAME_OBJ_FLAG="-o", + *RENAME_EXE_FLAG="-o"; + +char *dlg = "parser.dlg"; +char *err = "err.c"; +char *hdr = "stdpccts.h"; +char *tok = "tokens.h"; +char *mode = "mode.h"; +char *scan = "scan"; + +char ATOKENBUFFER_O[100]; +char APARSER_O[100]; +char ASTBASE_O[100]; +char PCCTSAST_O[100]; +char LIST_O[100]; +char DLEXERBASE_O[100]; + +/* Option flags */ +static char *project="t", *files[MAX_FILES], *classes[MAX_CLASSES]; +static char *cfiles[MAX_CFILES]; +static char *sfiles[MAX_SORS][MAX_SFILES],*sclasses[MAX_SORS]; +static int num_sfiles[MAX_SORS]; /*sorcerer files in group */ +static int num_sors = 0; /*sorcerer groups */ +static int num_files = 0; /* grammar files */ +static int num_cfiles = 0; /* additional C/C++ files */ +static int num_classes = 0; /* ANTLR classes */ +static int user_lexer = 0; +static char *user_token_types = NULL; +static int gen_CPP = 0; +static char *outdir="."; +static char *dlg_class = "DLGLexer"; +static int gen_trees = 0; +static int gen_hoist = 0; +static int nondef_comp = 0; /* 1=compiler is non default */ +static char *compilerCCC="CC"; +static char *compilerCC="cc"; +static char *pccts_path="/usr/local/pccts"; + +#ifdef __STDC__ +void help(void); +void mk(char *project, char **files, int n, int argc, char **argv); +void pfiles(char **files, int n, char *suffix); +void fatal(char *msg); +void warn(char *msg); +#else +void help(); +void mk(); +void pfiles(); +void fatal(); +void warn(); +#endif + +typedef struct _Opt { + char *option; + int arg; +#ifdef __cplusplus + void (*process)(...); +#else + void (*process)(); +#endif + char *descr; + } Opt; + +#ifdef __STDC__ +static void ProcessArgs(int, char **, Opt *); +#else +static void ProcessArgs(); +#endif + +static void +#ifdef __STDC__ +pProj(char *s, char *t ) +#else +pProj( s, t ) +char *s; +char *t; +#endif +{ + project = t; +} + +static void +#ifdef __STDC__ +pUL( char *s ) +#else +pUL( s ) +char *s; +#endif +{ + user_lexer = 1; +} + +static void +#ifdef __STDC__ +pCPP( char *s ) +#else +pCPP( s ) +char *s; +#endif +{ + gen_CPP = 1; +} + +static void +#ifdef __STDC__ +pUT( char *s, char *t ) +#else +pUT( s, t ) +char *s; +char *t; +#endif +{ + user_token_types = t; +} + +static void +#ifdef __STDC__ +pTrees( char *s ) +#else +pTrees( s ) +char *s; +#endif +{ + gen_trees = 1; +} + +static void +#ifdef __STDC__ +pHoist( char *s ) +#else +pHoist( s ) +char *s; +#endif +{ + gen_hoist = 1; +} + +static void +#ifdef __STDC__ +pSor( char *s ) +#else +pSor( s ) +char *s; +#endif +{ + require(num_sors0 ) { + warn("can't define classes w/o C++ mode; turning on C++ mode...\n"); + gen_CPP=1; + } + if (!gen_CPP && num_sors) { + warn("can't define sorcerer group in C mode (yet); turning on C++ mode...\n"); + gen_CPP=1; + } + if ( gen_CPP && num_classes==0 ) { + fatal("must define classes >0 grammar classes in C++ mode\n"); + } + + mk(project, files, num_files, argc, argv); + DONE; +} + +#ifdef __STDC__ +void help(void) +#else +void help() +#endif +{ + Opt *p = options; + static char buf[1000+1]; + + fprintf(stderr, "genmk [options] f1.g ... fn.g\n"); + while ( p->option!=NULL && *(p->option) != '*' ) + { + buf[0]='\0'; + if ( p->arg ) sprintf(buf, "%s ___", p->option); + else strcpy(buf, p->option); + fprintf(stderr, "\t%-16s %s\n", buf, p->descr); + p++; + } +} + +#ifdef __STDC__ +void mk(char *project, char **files, int n, int argc, char **argv) +#else +void mk(project, files, n, argc, argv) +char *project; +char **files; +int n; +int argc; +char **argv; +#endif +{ + int i,j; + + printf("#\n"); + printf("# PCCTS makefile for: "); + pfiles(files, n, NULL); + printf("\n"); + printf("#\n"); + printf("# Created from:"); + for (i=0; i0) { + printf("SOR_H = $(PCCTS)%ssorcerer%sh\n", DirectorySymbol, DirectorySymbol); + printf("SOR_LIB = $(PCCTS)%ssorcerer%slib\n", + DirectorySymbol, DirectorySymbol); + } + printf("BIN = $(PCCTS)%sbin\n", DirectorySymbol); + printf("ANTLR = $(BIN)%santlr\n", DirectorySymbol); + printf("DLG = $(BIN)%sdlg\n", DirectorySymbol); + if (num_sors>0) printf("SOR = $(BIN)%ssor\n", DirectorySymbol); + printf("CFLAGS = -I. -I$(ANTLR_H)"); + if (num_sors>0) printf(" -I$(SOR_H)"); + if ( strcmp(outdir, ".")!=0 ) printf(" -I%s", outdir); + printf(" $(COTHER)"); + printf("\n"); + printf("AFLAGS ="); + if ( strcmp(outdir,".")!=0 ) printf(" -o %s", outdir); + if ( user_lexer ) printf(" -gx"); + if ( gen_CPP ) printf(" -CC"); + if ( strcmp(hdr,"stdpccts.h")!=0 ) printf(" -gh %s", hdr); + if ( gen_trees ) printf(" -gt"); + if ( gen_hoist ) { + printf(" -mrhoist on") ; + } else { + printf(" -mrhoist off"); + }; + printf(" $(AOTHER)"); + printf("\n"); + printf("DFLAGS = -C2 -i"); + if ( gen_CPP ) printf(" -CC"); + if ( strcmp(dlg_class,"DLGLexer")!=0 ) printf(" -cl %s", dlg_class); + if ( strcmp(outdir,".")!=0 ) printf(" -o %s", outdir); + printf(" $(DOTHER)"); + printf("\n"); + if (num_sors>0) + { + printf("SFLAGS = -CPP"); + if ( strcmp(outdir,".")!=0 ) printf(" -out-dir %s", outdir); + printf(" $(SOTHER)\n"); + } + printf("GRM = "); + pfiles(files, n, NULL); + printf("\n"); + printf("SRC = "); + if ( gen_CPP ) pfiles(files, n, CPP_FILE_SUFFIX_NO_DOT); + else pfiles(files, n, "c"); + if ( gen_CPP ) { + printf(" \\\n\t"); + pclasses(classes, num_classes, CPP_FILE_SUFFIX_NO_DOT); + printf(" \\\n\t"); + printf("$(ANTLR_H)%s%s", DirectorySymbol, APARSER_C); + if ( !user_lexer ) printf(" $(ANTLR_H)%s%s", DirectorySymbol, DLEXERBASE_C); + if ( gen_trees ) { + printf(" \\\n\t"); + printf("$(ANTLR_H)%s%s", DirectorySymbol, ASTBASE_C); + printf(" $(ANTLR_H)%s%s", DirectorySymbol, PCCTSAST_C); +/* printf(" $(ANTLR_H)%s%s", DirectorySymbol, LIST_C); */ + printf(" \\\n\t"); + } + printf(" $(ANTLR_H)%s%s", DirectorySymbol, ATOKENBUFFER_C); + } + if ( !user_lexer ) { + if ( gen_CPP ) printf(" $(SCAN)%s", CPP_FILE_SUFFIX); + else printf(" %s$(SCAN).c", DIR()); + } + if ( !gen_CPP ) printf(" $(ERR).c"); + for (i=0;i0) + printf(" \\\n\t$(SOR_LIB)%sSTreeParser.cpp", DirectorySymbol); + if (num_cfiles>0) + { + printf(" \\\n\t"); + pfiles(cfiles,num_cfiles,NULL); + } + printf("\n\n"); + printf("OBJ = "); + pfiles(files, n, "o"); + if ( gen_CPP ) { + printf(" \\\n\t"); + pclasses(classes, num_classes, "o"); + printf(" \\\n\t"); + printf("%s%s", DIR(), APARSER_O); + if ( !user_lexer ) { + printf(" %s%s", DIR(), DLEXERBASE_O); + } + if ( gen_trees ) { + printf(" \\\n\t"); + printf("%s%s", DIR(), ASTBASE_O); + printf(" %s%s", DIR(), PCCTSAST_O); +/* printf(" %s%s", DIR(), LIST_O); */ + printf(" \\\n\t"); + } + printf(" %s%s", DIR(), ATOKENBUFFER_O); + } + if ( !user_lexer ) { + if ( gen_CPP ) printf(" $(SCAN)%s", OBJ_FILE_SUFFIX); + else printf(" %s$(SCAN)%s", DIR(), OBJ_FILE_SUFFIX); + } + if ( !gen_CPP ) printf(" $(ERR)%s", OBJ_FILE_SUFFIX); + for (i=0;i0) printf(" \\\n\tSTreeParser.o"); + if (num_cfiles>0) + { + printf(" \\\n\t"); + pfiles(cfiles,num_cfiles,"o"); + } + printf("\n\n"); + + printf("ANTLR_SPAWN = "); + if ( gen_CPP ) pfiles(files, n, CPP_FILE_SUFFIX_NO_DOT); + else pfiles(files, n, "c"); + if ( gen_CPP ) { + printf(" "); + pclasses(classes, num_classes, CPP_FILE_SUFFIX_NO_DOT); + printf(" \\\n\t\t"); + pclasses(classes, num_classes, "h"); + if ( strcmp(hdr,"stdpccts.h")!=0 ) { + printf(" \\\n\t\t"); + printf("$(HDR_FILE) stdpccts.h"); + } + } + if ( user_lexer ) { + if ( !user_token_types ) printf(" $(TOKENS)"); + } + else { + printf(" $(DLG_FILE)"); + if ( !user_token_types ) printf(" $(TOKENS)"); + } + if ( !gen_CPP ) printf(" $(ERR).c"); + printf("\n"); + + if ( !user_lexer ) { + if ( gen_CPP ) printf("DLG_SPAWN = $(SCAN)%s", CPP_FILE_SUFFIX); + else printf("DLG_SPAWN = %s$(SCAN).c", DIR()); + if ( gen_CPP ) printf(" $(SCAN).h"); + if ( !gen_CPP ) printf(" $(MOD_FILE)"); + printf("\n"); + } + + if ( gen_CPP ) { + if ( !nondef_comp ) + printf("ifdef CXX\nCCC = $(CXX)\nendif\n\nifndef CCC\n"); + printf("CCC = %s\n",compilerCCC); + if ( !nondef_comp ) printf("endif\n\n"); + } + else + { + if ( !nondef_comp ) printf("ifndef CC\n"); + printf("CC = %s\n",compilerCC); + if ( !nondef_comp ) printf("endif\n\n"); + } + + /* set up dependencies */ + printf("\n%s : $(SRC) $(OBJ)\n", project); + printf("\t%s %s %s $(CFLAGS) $(OBJ)\n", + gen_CPP?"$(CCC)":"$(CC)", + RENAME_EXE_FLAG, + project); + printf("\n"); + + /* implicit rules */ + +/* if(gen_CPP) + printf("%%.o : %%.cpp\n\t$(CCC) -c $(CFLAGS) $<\n\n"); + + printf("%%.o : %%.c\n\t%s -c $(CFLAGS) $<\n\n", + gen_CPP?"$(CCC)":"$(CC)"); +*/ + /* how to compile parser files */ + + for (i=0; i0) + { + printf("STreeParser%s : $(SOR_LIB)%sSTreeParser.cpp\n", + OBJ_FILE_SUFFIX,DirectorySymbol); + printf("\t%s -c $(CFLAGS) %s ", + gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG); + printf("STreeParser%s ",OBJ_FILE_SUFFIX); + printf("$(SOR_LIB)%sSTreeParser.cpp\n\n",DirectorySymbol); + } + + printf("$(ANTLR_SPAWN) : $(GRM)\n"); + printf("\t$(ANTLR) $(AFLAGS) $(GRM)\n"); + + if ( !user_lexer ) + { + printf("\n"); + printf("$(DLG_SPAWN) : $(DLG_FILE)\n"); + if ( gen_CPP ) printf("\t$(DLG) $(DFLAGS) $(DLG_FILE)\n"); + else printf("\t$(DLG) $(DFLAGS) $(DLG_FILE) $(SCAN).c\n"); + } + + /* do the makes for ANTLR/DLG support */ + if ( gen_CPP ) { + printf("\n"); + printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), APARSER_O, DirectorySymbol, APARSER_C); + printf("\t%s -c $(CFLAGS) %s ", + gen_CPP?"$(CCC)":"$(CC)", + RENAME_OBJ_FLAG); + printf("%s%s $(ANTLR_H)%s%s\n", DIR(), APARSER_O, DirectorySymbol, APARSER_C); + printf("\n"); + printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), ATOKENBUFFER_O, DirectorySymbol, ATOKENBUFFER_C); + printf("\t%s -c $(CFLAGS) %s ", + gen_CPP?"$(CCC)":"$(CC)", + RENAME_OBJ_FLAG); + printf("%s%s $(ANTLR_H)%s%s\n", DIR(), ATOKENBUFFER_O, DirectorySymbol, ATOKENBUFFER_C); + if ( !user_lexer ) { + printf("\n"); + printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), DLEXERBASE_O, DirectorySymbol, DLEXERBASE_C); + printf("\t%s -c $(CFLAGS) %s ", + gen_CPP?"$(CCC)":"$(CC)", + RENAME_OBJ_FLAG); + printf("%s%s $(ANTLR_H)%s%s\n", DIR(), DLEXERBASE_O, DirectorySymbol, DLEXERBASE_C); + } + if ( gen_trees ) { + printf("\n"); + printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), ASTBASE_O, DirectorySymbol, ASTBASE_C); + printf("\t%s -c $(CFLAGS) %s ", + gen_CPP?"$(CCC)":"$(CC)", + RENAME_OBJ_FLAG); + printf("%s%s $(ANTLR_H)%s%s\n", DIR(), ASTBASE_O, DirectorySymbol, ASTBASE_C); + printf("\n"); + printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), PCCTSAST_O, DirectorySymbol, PCCTSAST_C); + printf("\t%s -c $(CFLAGS) %s ", + gen_CPP?"$(CCC)":"$(CC)", + RENAME_OBJ_FLAG); + printf("%s%s $(ANTLR_H)%s%s\n", DIR(), PCCTSAST_O, DirectorySymbol, PCCTSAST_C); + printf("\n"); +/* + printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), LIST_O, DirectorySymbol, LIST_C); + printf("\t%s -c $(CFLAGS) %s ", + gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG); + printf("%s%s $(ANTLR_H)%s%s\n", DIR(), LIST_O, DirectorySymbol, LIST_C); +*/ + } + } + + /* clean and scrub targets */ + + printf("\nclean:\n"); + printf("\trm -f *%s core %s", OBJ_FILE_SUFFIX, project); + if ( strcmp(outdir, ".")!=0 ) printf(" %s*%s", DIR(), OBJ_FILE_SUFFIX); + printf("\n"); + + printf("\nscrub: clean\n"); +/* printf("\trm -f *%s core %s", OBJ_FILE_SUFFIX, project); */ +/* if ( strcmp(outdir, ".")!=0 ) printf(" %s*%s", DIR(), OBJ_FILE_SUFFIX); */ + printf("\trm -f $(ANTLR_SPAWN)"); + if ( !user_lexer ) printf(" $(DLG_SPAWN)"); + for (i=0;i0 ) + { + char *p = &(*files)[strlen(*files)-1]; + if ( !first ) putchar(' '); + first=0; + while ( p > *files && *p != '.' ) --p; + if ( p == *files ) + { + fprintf(stderr, + "genmk: filenames must be file.suffix format: %s\n", + *files); + exit(-1); + } + if ( suffix == NULL ) printf("%s", *files); + else + { + *p = '\0'; + printf("%s", DIR()); + if ( strcmp(suffix, "o")==0 ) printf("%s%s", *files, OBJ_FILE_SUFFIX); + else printf("%s.%s", *files, suffix); + *p = '.'; + } + files++; + --n; + } +} + +#ifdef __STDC__ +pclasses(char **classes, int n, char *suffix) +#else +pclasses(classes, n, suffix) +char **classes; +int n; +char *suffix; +#endif +{ + int first=1; + + while ( n>0 ) + { + if ( !first ) putchar(' '); + first=0; + if ( suffix == NULL ) printf("%s", *classes); + else { + printf("%s", DIR()); + if ( strcmp(suffix, "o")==0 ) printf("%s%s", *classes, OBJ_FILE_SUFFIX); + else printf("%s.%s", *classes, suffix); + } + classes++; + --n; + } +} + +static void +#ifdef __STDC__ +ProcessArgs( int argc, char **argv, Opt *options ) +#else +ProcessArgs( argc, argv, options ) +int argc; +char **argv; +Opt *options; +#endif +{ + Opt *p; + require(argv!=NULL, "ProcessArgs: command line NULL"); + + while ( argc-- > 0 ) + { + p = options; + while ( p->option != NULL ) + { + if ( strcmp(p->option, "*") == 0 || + strcmp(p->option, *argv) == 0 ) + { + if ( p->arg ) + { + (*p->process)( *argv, *(argv+1) ); + argv++; + argc--; + } + else + (*p->process)( *argv ); + break; + } + p++; + } + argv++; + } +} + +#ifdef __STDC__ +void fatal( char *err_) +#else +void fatal( err_) +char *err_; +#endif +{ + fprintf(stderr, "genmk: %s\n", err_); + exit(1); +} + +#ifdef __STDC__ +void warn( char *err_) +#else +void warn( err_) +char *err_; +#endif +{ + fprintf(stderr, "genmk: %s\n", err_); +} + +#ifdef __STDC__ +char *DIR(void) +#else +char *DIR() +#endif +{ + static char buf[200+1]; + + if ( strcmp(outdir,TopDirectory)==0 ) return ""; + sprintf(buf, "%s%s", outdir, DirectorySymbol); + return buf; +} diff --git a/Tools/CodeTools/Source/Pccts/support/genmk/genmk_old.c b/Tools/CodeTools/Source/Pccts/support/genmk/genmk_old.c new file mode 100644 index 0000000000..2cf9fad727 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/support/genmk/genmk_old.c @@ -0,0 +1,762 @@ +/* + * genmk -- a program to make makefiles for PCCTS + * + * ANTLR 1.33MR10 + * Terence John Parr 1989 - 1998 + * Purdue University + * U of MN + */ + +#include +#include "pcctscfg.h" /* be sensitive to what ANTLR/DLG call the files */ + +#ifdef VAXC +#define DIE return 0; +#define DONE return 1; +#else +#define DIE return 1; +#define DONE return 0; +#endif + +#ifndef require +#define require(expr, err) {if ( !(expr) ) fatal(err);} +#endif + +#define MAX_FILES 50 +#define MAX_CLASSES 50 + +char *RENAME_OBJ_FLAG="-o", + *RENAME_EXE_FLAG="-o"; + +char *dlg = "parser.dlg"; +char *err = "err.c"; +char *hdr = "stdpccts.h"; +char *tok = "tokens.h"; +char *mode = "mode.h"; +char *scan = "scan"; + +char ATOKENBUFFER_O[100]; +char APARSER_O[100]; +char ASTBASE_O[100]; +char PCCTSAST_O[100]; +char LIST_O[100]; +char DLEXERBASE_O[100]; + +/* Option flags */ +static char *project="t", *files[MAX_FILES], *classes[MAX_CLASSES]; +static int num_files = 0; +static int num_classes = 0; +static int user_lexer = 0; +static char *user_token_types = NULL; +static int gen_CPP = 0; +static char *outdir="."; +static char *dlg_class = "DLGLexer"; +static int gen_trees = 0; +static int gen_hoist = 0; +static char cfiles[1600]=""; +static char *compilerCCC="CC"; +static char *compilerCC="cc"; +static char *pccts_path="/usr/local/pccts"; + +void help(); +void mk(); +void pfiles(); +void pclasses(); +void fatal(); +void warn(); + +typedef struct _Opt { + char *option; + int arg; +#ifdef __cplusplus + void (*process)(...); +#else + void (*process)(); +#endif + char *descr; + } Opt; + +#ifdef __STDC__ +static void ProcessArgs(int, char **, Opt *); +#else +static void ProcessArgs(); +#endif + +static void +pProj( s, t ) +char *s; +char *t; +{ + project = t; +} + +static void +pUL( s ) +char *s; +{ + user_lexer = 1; +} + +static void +pCPP( s ) +char *s; +{ + gen_CPP = 1; +} + +static void +pUT( s, t ) +char *s; +char *t; +{ + user_token_types = t; +} + +static void +pTrees( s ) +char *s; +{ + gen_trees = 1; +} + +static void +pHoist( s ) +char *s; +{ + gen_hoist = 1; +} + +static void +#ifdef __STDC__ +pFile( char *s ) +#else +pFile( s ) +char *s; +#endif +{ + if ( *s=='-' ) + { + fprintf(stderr, "invalid option: '%s'; ignored...",s); + return; + } + + require(num_files0 ) { + warn("can't define classes w/o C++ mode; turning on C++ mode...\n"); + gen_CPP=1; + } + if ( gen_CPP && num_classes==0 ) { + fatal("must define classes >0 grammar classes in C++ mode\n"); + } + + mk(project, files, num_files, argc, argv); + DONE; +} + +void help() +{ + Opt *p = options; + static char buf[1000+1]; + + fprintf(stderr, "genmk [options] f1.g ... fn.g\n"); + while ( p->option!=NULL && *(p->option) != '*' ) + { + buf[0]='\0'; + if ( p->arg ) sprintf(buf, "%s ___", p->option); + else strcpy(buf, p->option); + fprintf(stderr, "\t%-16s %s\n", buf, p->descr); + p++; + } +} + +void mk(project, files, n, argc, argv) +char *project; +char **files; +int n; +int argc; +char **argv; +{ + int i; + + printf("#\n"); + printf("# PCCTS makefile for: "); + pfiles(files, n, NULL); + printf("\n"); + printf("#\n"); + printf("# Created from:"); + for (i=0; i0 ) + { + char *p = &(*files)[strlen(*files)-1]; + if ( !first ) putchar(' '); + first=0; + while ( p > *files && *p != '.' ) --p; + if ( p == *files ) + { + fprintf(stderr, + "genmk: filenames must be file.suffix format: %s\n", + *files); + exit(-1); + } + if ( suffix == NULL ) printf("%s", *files); + else + { + *p = '\0'; + printf("%s", DIR()); + if ( strcmp(suffix, "o")==0 ) printf("%s%s", *files, OBJ_FILE_SUFFIX); + else printf("%s.%s", *files, suffix); + *p = '.'; + } + files++; + --n; + } +} + +void pclasses(classes, n, suffix) +char **classes; +int n; +char *suffix; +{ + int first=1; + + while ( n>0 ) + { + if ( !first ) putchar(' '); + first=0; + if ( suffix == NULL ) printf("%s", *classes); + else { + printf("%s", DIR()); + if ( strcmp(suffix, "o")==0 ) printf("%s%s", *classes, OBJ_FILE_SUFFIX); + else printf("%s.%s", *classes, suffix); + } + classes++; + --n; + } +} + +static void +#ifdef __STDC__ +ProcessArgs( int argc, char **argv, Opt *options ) +#else +ProcessArgs( argc, argv, options ) +int argc; +char **argv; +Opt *options; +#endif +{ + Opt *p; + require(argv!=NULL, "ProcessArgs: command line NULL"); + + while ( argc-- > 0 ) + { + p = options; + while ( p->option != NULL ) + { + if ( strcmp(p->option, "*") == 0 || + strcmp(p->option, *argv) == 0 ) + { + if ( p->arg ) + { + (*p->process)( *argv, *(argv+1) ); + argv++; + argc--; + } + else + (*p->process)( *argv ); + break; + } + p++; + } + argv++; + } +} + +void fatal( err_) +char *err_; +{ + fprintf(stderr, "genmk: %s\n", err_); + exit(1); +} + +void warn( err_) +char *err_; +{ + fprintf(stderr, "genmk: %s\n", err_); +} + +char *DIR() +{ + static char buf[200+1]; + + if ( strcmp(outdir,TopDirectory)==0 ) return ""; + sprintf(buf, "%s%s", outdir, DirectorySymbol); + return buf; +} diff --git a/Tools/CodeTools/Source/Pccts/support/genmk/makefile b/Tools/CodeTools/Source/Pccts/support/genmk/makefile new file mode 100644 index 0000000000..a003c2f321 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/support/genmk/makefile @@ -0,0 +1,29 @@ +## +## 7-Apr-97 +## added support/genmk/makefile to pccts 1.33MR1 distribution kit +## (support/genmk/makefile" omitted from 1.33 distribution kit) +## +SRC=genmk.c +OBJ=genmk.o +# Define PC if you use a PC OS (changes directory symbol and object file extension) +# see pccts/h/pcctscfg.h +CC=cc +COPT=-O +#CFLAGS=-I../../h -DPC +CFLAGS=$(COPT) -I../../h +BAG=../../bin/bag + +genmk: $(OBJ) $(SRC) ../../h/pcctscfg.h + $(CC) -o genmk $(OBJ) + +clean: + rm -rf core *.o + +scrub: + rm -rf genmk core *.o + +shar: + shar genmk.c makefile > genmk.shar + +archive: + $(BAG) genmk.c makefile > genmk.bag diff --git a/Tools/CodeTools/Source/Pccts/support/rexpr/makefile b/Tools/CodeTools/Source/Pccts/support/rexpr/makefile new file mode 100644 index 0000000000..44caef1aa5 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/support/rexpr/makefile @@ -0,0 +1,19 @@ +BAG=../../bin/bag +SRC=test.c rexpr.c +OBJ=test.o rexpr.o +CFLAGS = -g + +test: $(OBJ) $(SRC) + cc -g -o texpr $(OBJ) + +shar: + shar makefile test.c rexpr.c rexpr.h > rexpr.shar + +archive: + $(BAG) makefile test.c rexpr.c rexpr.h > rexpr.bag + +clean: + rm -rf *.o core texpr + +scrub: + rm -rf *.o core texpr diff --git a/Tools/CodeTools/Source/Pccts/support/rexpr/rexpr.c b/Tools/CodeTools/Source/Pccts/support/rexpr/rexpr.c new file mode 100644 index 0000000000..805bf65533 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/support/rexpr/rexpr.c @@ -0,0 +1,586 @@ +/* + * This file contains code for + * + * int rexpr(char *expr, char *s); + * + * which answers + * + * 1 if 's' is in the language described by the regular expression 'expr' + * 0 if it is not + * -1 if the regular expression is invalid + * + * Language membership is determined by constructing a non-deterministic + * finite automata (NFA) from the regular expression. A depth- + * first-search is performed on the NFA (graph) to check for a match of 's'. + * Each non-epsilon arc consumes one character from 's'. Backtracking is + * performed to check all possible paths through the NFA. + * + * Regular expressions follow the meta-language: + * + * ::= ( '|' )* + * + * ::= ( )* + * + * ::= {'~'} '[' ']' + * | '(' ')' + * | '{' '}' + * | + * + * ::= { '*' | '+' } + * + * ::= ( )* + * | { } '-' { } + * + * ::= Token[Atom] + * + * Notes: + * ~ means complement the set in [..]. i.e. all characters not listed + * * means match 0 or more times (can be on expression or atom) + * + means match 1 or more times (can be on expression or atom) + * {} optional + * () grouping + * [] set of atoms + * x-y all characters from x to y (found only in [..]) + * \xx the character with value xx + * + * Examples: + * [a-z]+ + * match 1 or more lower-case letters (e.g. variable) + * + * 0x[0-9A-Fa-f]+ + * match a hex number with 0x on front (e.g. 0xA1FF) + * + * [0-9]+.[0-9]+{e[0-9]+} + * match a floating point number (e.g. 3.14e21) + * + * Code example: + * if ( rexpr("[a-zA-Z][a-zA-Z0-9]+", str) ) then str is keyword + * + * Terence Parr + * Purdue University + * April 1991 + */ + +#include +#include +#ifdef __STDC__ +#include +#else +#include +#endif +#include "rexpr.h" + +#ifdef __USE_PROTOS +static int regExpr( GraphPtr g ); +static int andExpr( GraphPtr g ); +static int expr( GraphPtr g ); +static int repeatSymbol( GraphPtr g ); +static int atomList( char *p, int complement ); +static void next( void ); +static ArcPtr newGraphArc( void ); +static NodePtr newNode( void ); +static int ArcBetweenGraphNode( NodePtr i, NodePtr j, int label ); +static Graph BuildNFA_atom( int label ); +static Graph BuildNFA_AB( Graph A, Graph B ); +static Graph BuildNFA_AorB( Graph A, Graph B ); +static Graph BuildNFA_set( char *s ); +static Graph BuildNFA_Astar( Graph A ); +static Graph BuildNFA_Aplus( Graph A ); +static Graph BuildNFA_Aoptional( Graph A ); +#else +static int regExpr(); +static int andExpr(); +static int expr(); +static int repeatSymbol(); +static int atomList(); +static void next(); +static ArcPtr newGraphArc(); +static NodePtr newNode(); +static int ArcBetweenGraphNode(); +static Graph BuildNFA_atom(); +static Graph BuildNFA_AB(); +static Graph BuildNFA_AorB(); +static Graph BuildNFA_set(); +static Graph BuildNFA_Astar(); +static Graph BuildNFA_Aplus(); +static Graph BuildNFA_Aoptional(); +#endif + +static char *_c; +static int token, tokchar; +static NodePtr accept; +static NodePtr freelist = NULL; + +/* + * return 1 if s in language described by expr + * 0 if s is not + * -1 if expr is an invalid regular expression + */ +#ifdef __USE_PROTOS +static int rexpr(char *expr,char *s) +#else +static int rexpr(expr, s) +char *expr, *s; +#endif +{ + NodePtr p,q; + Graph nfa; + int result; + + fprintf(stderr, "rexpr(%s,%s);\n", expr,s); + freelist = NULL; + _c = expr; + next(); + if ( regExpr(&nfa) == -1 ) return -1; + accept = nfa.right; + result = match(nfa.left, s); + /* free all your memory */ + p = q = freelist; + while ( p!=NULL ) { q = p->track; free(p); p = q; } + return result; +} + +/* + * do a depth-first-search on the NFA looking for a path from start to + * accept state labelled with the characters of 's'. + */ + +#ifdef __USE_PROTOS +static int match(NodePtr automaton,char *s) +#else +static int match(automaton, s) +NodePtr automaton; +char *s; +#endif +{ + ArcPtr p; + + if ( automaton == accept && *s == '\0' ) return 1; /* match */ + + for (p=automaton->arcs; p!=NULL; p=p->next) /* try all arcs */ + { + if ( p->label == Epsilon ) + { + if ( match(p->target, s) ) return 1; + } + else if ( p->label == *s ) + if ( match(p->target, s+1) ) return 1; + } + return 0; +} + +/* + * ::= ( '|' {} )* + * + * Return -1 if syntax error + * Return 0 if none found + * Return 1 if a regExrp was found + */ + +#ifdef __USE_PROTOS +static int regExpr(GraphPtr g) +#else +static int regExpr(g) +GraphPtr g; +#endif +{ + Graph g1, g2; + + if ( andExpr(&g1) == -1 ) + { + return -1; + } + + while ( token == '|' ) + { + int a; + next(); + a = andExpr(&g2); + if ( a == -1 ) return -1; /* syntax error below */ + else if ( !a ) return 1; /* empty alternative */ + g1 = BuildNFA_AorB(g1, g2); + } + + if ( token!='\0' ) return -1; + + *g = g1; + return 1; +} + +/* + * ::= ( )* + */ + +#ifdef __USE_PROTOS +static int andExpr(GraphPtr g) +#else +static int andExpr(g) +GraphPtr g; +#endif +{ + Graph g1, g2; + + if ( expr(&g1) == -1 ) + { + return -1; + } + + while ( token==Atom || token=='{' || token=='(' || token=='~' || token=='[' ) + { + if (expr(&g2) == -1) return -1; + g1 = BuildNFA_AB(g1, g2); + } + + *g = g1; + return 1; +} + +/* + * ::= {'~'} '[' ']' + * | '(' ')' + * | '{' '}' + * | + */ + +#ifdef __USE_PROTOS +static int expr(GraphPtr g) +#else +static int expr(g) +GraphPtr g; +#endif +{ + int complement = 0; + char s[257]; /* alloc space for string of char in [] */ + + if ( token == '~' || token == '[' ) + { + if ( token == '~' ) {complement = 1; next();} + if ( token != '[' ) return -1; + next(); + if ( atomList( s, complement ) == -1 ) return -1; + *g = BuildNFA_set( s ); + if ( token != ']' ) return -1; + next(); + repeatSymbol( g ); + return 1; + } + if ( token == '(' ) + { + next(); + if ( regExpr( g ) == -1 ) return -1; + if ( token != ')' ) return -1; + next(); + repeatSymbol( g ); + return 1; + } + if ( token == '{' ) + { + next(); + if ( regExpr( g ) == -1 ) return -1; + if ( token != '}' ) return -1; + next(); + /* S p e c i a l C a s e O p t i o n a l { } */ + if ( token != '*' && token != '+' ) + { + *g = BuildNFA_Aoptional( *g ); + } + repeatSymbol( g ); + return 1; + } + if ( token == Atom ) + { + *g = BuildNFA_atom( tokchar ); + next(); + repeatSymbol( g ); + return 1; + } + + return -1; +} + +/* + * ::= { '*' | '+' } + */ +#ifdef __USE_PROTOS +static int repeatSymbol(GraphPtr g) +#else +static int repeatSymbol(g) +GraphPtr g; +#endif +{ + switch ( token ) + { + case '*' : *g = BuildNFA_Astar( *g ); next(); break; + case '+' : *g = BuildNFA_Aplus( *g ); next(); break; + } + return 1; +} + +/* + * ::= { }* + * { } '-' { } + * + * a-b is same as ab + * q-a is same as q + */ + +#ifdef __USE_PROTOS +static int atomList(char *p, int complement) +#else +static int atomList(p, complement) +char *p; +int complement; +#endif +{ + static unsigned char set[256]; /* no duplicates */ + int first, last, i; + char *s = p; + + if ( token != Atom ) return -1; + + for (i=0; i<256; i++) set[i] = 0; + while ( token == Atom ) + { + if ( !set[tokchar] ) *s++ = tokchar; + set[tokchar] = 1; /* Add atom to set */ + next(); + if ( token == '-' ) /* have we found '-' */ + { + first = *(s-1); /* Get last char */ + next(); + if ( token != Atom ) return -1; + else + { + last = tokchar; + } + for (i = first+1; i <= last; i++) + { + if ( !set[tokchar] ) *s++ = i; + set[i] = 1; /* Add atom to set */ + } + next(); + } + } + *s = '\0'; + if ( complement ) + { + for (i=0; i<256; i++) set[i] = !set[i]; + for (i=1,s=p; i<256; i++) if ( set[i] ) *s++ = i; + *s = '\0'; + } + return 1; +} + +/* a somewhat stupid lexical analyzer */ + +#ifdef __USE_PROTOS +static void next(void) +#else +static void next() +#endif +{ + while ( *_c==' ' || *_c=='\t' || *_c=='\n' ) _c++; + if ( *_c=='\\' ) + { + _c++; + if ( isdigit(*_c) ) + { + int n=0; + while ( isdigit(*_c) ) + { + n = n*10 + (*_c++ - '0'); + } + if ( n>255 ) n=255; + tokchar = n; + } + else + { + switch (*_c) + { + case 'n' : tokchar = '\n'; break; + case 't' : tokchar = '\t'; break; + case 'r' : tokchar = '\r'; break; + default : tokchar = *_c; + } + _c++; + } + token = Atom; + } + else if ( isgraph(*_c) && *_c!='[' && *_c!='(' && *_c!='{' && + *_c!='-' && *_c!='}' && *_c!=')' && *_c!=']' && + *_c!='+' && *_c!='*' && *_c!='~' && *_c!='|' ) + { + token = Atom; + tokchar = *_c++; + } + else + { + token = tokchar = *_c++; + } +} + +/* N F A B u i l d i n g R o u t i n e s */ + +#ifdef __USE_PROTOS +static ArcPtr newGraphArc(void) +#else +static ArcPtr newGraphArc() +#endif +{ + ArcPtr p; + p = (ArcPtr) calloc(1, sizeof(Arc)); + if ( p==NULL ) {fprintf(stderr,"rexpr: out of memory\n"); exit(-1);} + if ( freelist != NULL ) p->track = (ArcPtr) freelist; + freelist = (NodePtr) p; + return p; +} + +#ifdef __USE_PROTOS +static NodePtr newNode(void) +#else +static NodePtr newNode() +#endif +{ + NodePtr p; + p = (NodePtr) calloc(1, sizeof(Node)); + if ( p==NULL ) {fprintf(stderr,"rexpr: out of memory\n"); exit(-1);} + if ( freelist != NULL ) p->track = freelist; + freelist = p; + return p; +} + +#ifdef __USE_PROTOS +static void ArcBetweenGraphNodes(NodePtr i,NodePtr j,int label) +#else +static void ArcBetweenGraphNodes(i, j, label) +NodePtr i, j; +int label; +#endif +{ + ArcPtr a; + + a = newGraphArc(); + if ( i->arcs == NULL ) i->arctail = i->arcs = a; + else {(i->arctail)->next = a; i->arctail = a;} + a->label = label; + a->target = j; +} + +#ifdef __USE_PROTOS +static Graph BuildNFA_atom(int label) +#else +static Graph BuildNFA_atom(label) +int label; +#endif +{ + Graph g; + + g.left = newNode(); + g.right = newNode(); + ArcBetweenGraphNodes(g.left, g.right, label); + return( g ); +} + +#ifdef __USE_PROTOS +static Graph BuildNFA_AB(Graph A,Graph B) +#else +static Graph BuildNFA_AB(A, B) +Graph A, B; +#endif +{ + Graph g; + + ArcBetweenGraphNodes(A.right, B.left, Epsilon); + g.left = A.left; + g.right = B.right; + return( g ); +} + +#ifdef __USE_PROTOS +static Graph BuildNFA_AorB(Graph A,Graph B) +#else +static Graph BuildNFA_AorB(A, B) +Graph A, B; +#endif +{ + Graph g; + + g.left = newNode(); + ArcBetweenGraphNodes(g.left, A.left, Epsilon); + ArcBetweenGraphNodes(g.left, B.left, Epsilon); + g.right = newNode(); + ArcBetweenGraphNodes(A.right, g.right, Epsilon); + ArcBetweenGraphNodes(B.right, g.right, Epsilon); + return( g ); +} + +#ifdef __USE_PROTOS +static Graph BuildNFA_set(char *s) +#else +static Graph BuildNFA_set( s ) +char *s; +#endif +{ + Graph g; + + if ( s == NULL ) return g; + + g.left = newNode(); + g.right = newNode(); + while ( *s != '\0' ) + { + ArcBetweenGraphNodes(g.left, g.right, *s++); + } + return g; +} + +#ifdef __USE_PROTOS +static Graph BuildNFA_Astar(Graph A) +#else +static Graph BuildNFA_Astar( A ) +Graph A; +#endif +{ + Graph g; + + g.left = newNode(); + g.right = newNode(); + + ArcBetweenGraphNodes(g.left, A.left, Epsilon); + ArcBetweenGraphNodes(g.left, g.right, Epsilon); + ArcBetweenGraphNodes(A.right, g.right, Epsilon); + ArcBetweenGraphNodes(A.right, A.left, Epsilon); + + return( g ); +} + +#ifdef __USE_PROTOS +static Graph BuildNFA_Aplus(Graph A) +#else +static Graph BuildNFA_Aplus( A ) +Graph A; +#endif +{ + ArcBetweenGraphNodes(A.right, A.left, Epsilon); + + return( A ); +} + +#ifdef __USE_PROTOS +static Graph BuildNFA_Aoptional(Graph A) +#else +static Graph BuildNFA_Aoptional( A ) +Graph A; +#endif +{ + Graph g; + + g.left = newNode(); + g.right = newNode(); + + ArcBetweenGraphNodes(g.left, A.left, Epsilon); + ArcBetweenGraphNodes(g.left, g.right, Epsilon); + ArcBetweenGraphNodes(A.right, g.right, Epsilon); + + return( g ); +} diff --git a/Tools/CodeTools/Source/Pccts/support/rexpr/rexpr.h b/Tools/CodeTools/Source/Pccts/support/rexpr/rexpr.h new file mode 100644 index 0000000000..e67a9652fb --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/support/rexpr/rexpr.h @@ -0,0 +1,30 @@ +#define Atom 256 /* token Atom (an impossible char value) */ +#define Epsilon 257 /* epsilon arc (an impossible char value) */ + +/* track field must be same for all node types */ +typedef struct _a { + struct _a *track; /* track mem allocation */ + int label; + struct _a *next; + struct _n *target; + } Arc, *ArcPtr; + +typedef struct _n { + struct _n *track; + ArcPtr arcs, arctail; + } Node, *NodePtr; + +typedef struct { + NodePtr left, + right; + } Graph, *GraphPtr; + +#ifdef __USE_PROTOS +int rexpr( char *expr, char *s ); +int match( NodePtr automaton, char *s ); +#else +int rexpr(); +int match(); +#endif + + diff --git a/Tools/CodeTools/Source/Pccts/support/rexpr/test.c b/Tools/CodeTools/Source/Pccts/support/rexpr/test.c new file mode 100644 index 0000000000..2619539e4b --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/support/rexpr/test.c @@ -0,0 +1,19 @@ +#include +#include "rexpr.h" + +/* + * test for rexpr(). + * To make this test: + * cc -o rexpr test.c rexpr.c + * Then from command line type: + * rexpr r string + * where r is the regular expression that decribes a language + * and string is the string to verify. + */ +main(argc,argv) +int argc; +char *argv[]; +{ + if ( argc!=3 ) fprintf(stderr,"rexpr: expr s\n"); + else printf("%d\n", rexpr(argv[1], argv[2])); +} diff --git a/Tools/CodeTools/Source/Pccts/support/set/set.c b/Tools/CodeTools/Source/Pccts/support/set/set.c new file mode 100644 index 0000000000..eb6fba7393 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/support/set/set.c @@ -0,0 +1,816 @@ +/* set.c + + The following is a general-purpose set library originally developed + by Hank Dietz and enhanced by Terence Parr to allow dynamic sets. + + Sets are now structs containing the #words in the set and + a pointer to the actual set words. + + Generally, sets need not be explicitly allocated. They are + created/extended/shrunk when appropriate (e.g. in set_of()). + HOWEVER, sets need to be destroyed (free()ed) when they go out of scope + or are otherwise no longer needed. A routine is provided to + free a set. + + Sets can be explicitly created with set_new(s, max_elem). + + Sets can be declared to have minimum size to reduce realloc traffic. + Default minimum size = 1. + + Sets can be explicitly initialized to have no elements (set.n == 0) + by using the 'empty' initializer: + + Examples: + set a = empty; -- set_deg(a) == 0 + + return( empty ); + + Example set creation and destruction: + + set + set_of2(e,g) + unsigned e,g; + { + set a,b,c; + + b = set_of(e); -- Creates space for b and sticks in e + set_new(c, g); -- set_new(); set_orel() ==> set_of() + set_orel(g, &c); + a = set_or(b, c); + . + . + . + set_free(b); + set_free(c); + return( a ); + } + + 1987 by Hank Dietz + + Modified by: + Terence Parr + Purdue University + October 1989 + + Made it smell less bad to C++ 7/31/93 -- TJP +*/ + +#include +#include "pcctscfg.h" +#ifdef __STDC__ +#include +#else +#include +#endif +#include + +#include "set.h" + +#define MIN(i,j) ( (i) > (j) ? (j) : (i)) +#define MAX(i,j) ( (i) < (j) ? (j) : (i)) + +/* elems can be a maximum of 32 bits */ +static unsigned bitmask[] = { + 0x00000001, 0x00000002, 0x00000004, 0x00000008, + 0x00000010, 0x00000020, 0x00000040, 0x00000080, + 0x00000100, 0x00000200, 0x00000400, 0x00000800, + 0x00001000, 0x00002000, 0x00004000, 0x00008000, +#if !defined(PC) || defined(PC32) + 0x00010000, 0x00020000, 0x00040000, 0x00080000, + 0x00100000, 0x00200000, 0x00400000, 0x00800000, + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000 +#endif +}; + +set empty = set_init; +static unsigned min=1; + +#define StrSize 200 + +#ifdef MEMCHK +#define CHK(a) \ + if ( a.setword != NULL ) \ + if ( !valid(a.setword) ) \ + {fprintf(stderr, "%s(%d): invalid set\n",__FILE__,__LINE__); exit(-1);} +#else +#define CHK(a) +#endif + +/* + * Set the minimum size (in words) of a set to reduce realloc calls + */ +void +#ifdef __USE_PROTOS +set_size( unsigned n ) +#else +set_size( n ) +unsigned n; +#endif +{ + min = n; +} + +unsigned int +#ifdef __USE_PROTOS +set_deg( set a ) +#else +set_deg( a ) +set a; +#endif +{ + /* Fast compute degree of a set... the number + of elements present in the set. Assumes + that all word bits are used in the set + and that SETSIZE(a) is a multiple of WORDSIZE. + */ + register unsigned *p = &(a.setword[0]); + register unsigned *endp = NULL; /* MR27 Avoid false memory check report */ + register unsigned degree = 0; + + CHK(a); + if ( a.n == 0 ) return(0); + endp = &(a.setword[a.n]); + while ( p < endp ) + { + register unsigned t = *p; + register unsigned *b = &(bitmask[0]); + do { + if (t & *b) ++degree; + } while (++b < &(bitmask[WORDSIZE])); + p++; + } + + return(degree); +} + +set +#ifdef __USE_PROTOS +set_or( set b, set c ) +#else +set_or( b, c ) +set b; +set c; +#endif +{ + /* Fast set union operation */ + /* resultant set size is max(b, c); */ + set *big; + set t; + unsigned int m,n; + register unsigned *r, *p, *q, *endp; + + CHK(b); CHK(c); + t = empty; + if (b.n > c.n) {big= &b; m=b.n; n=c.n;} else {big= &c; m=c.n; n=b.n;} + set_ext(&t, m); + r = t.setword; + + /* Or b,c until max of smaller set */ + q = c.setword; + p = b.setword; + endp = &(b.setword[n]); + while ( p < endp ) *r++ = *p++ | *q++; + + /* Copy rest of bigger set into result */ + p = &(big->setword[n]); + endp = &(big->setword[m]); + while ( p < endp ) *r++ = *p++; + + return(t); +} + +set +#ifdef __USE_PROTOS +set_and( set b, set c ) +#else +set_and( b, c ) +set b; +set c; +#endif +{ + /* Fast set intersection operation */ + /* resultant set size is min(b, c); */ + set t; + unsigned int n; + register unsigned *r, *p, *q, *endp; + + CHK(b); CHK(c); + t = empty; + n = (b.n > c.n) ? c.n : b.n; + if ( n == 0 ) return t; /* TJP 4-27-92 fixed for empty set */ + set_ext(&t, n); + r = t.setword; + + /* & b,c until max of smaller set */ + q = c.setword; + p = b.setword; + endp = &(b.setword[n]); + while ( p < endp ) *r++ = *p++ & *q++; + + return(t); +} + +set +#ifdef __USE_PROTOS +set_dif( set b, set c ) +#else +set_dif( b, c ) +set b; +set c; +#endif +{ + /* Fast set difference operation b - c */ + /* resultant set size is size(b) */ + set t; + unsigned int n; + register unsigned *r, *p, *q, *endp; + + CHK(b); CHK(c); + t = empty; + n = (b.n <= c.n) ? b.n : c.n ; + if ( b.n == 0 ) return t; /* TJP 4-27-92 fixed for empty set */ + /* WEC 12-1-92 fixed for c.n = 0 */ + set_ext(&t, b.n); + r = t.setword; + + /* Dif b,c until smaller set size */ + q = c.setword; + p = b.setword; + endp = &(b.setword[n]); + while ( p < endp ) *r++ = *p++ & (~ *q++); + + /* Copy rest of b into result if size(b) > c */ + if ( b.n > n ) + { + p = &(b.setword[n]); + endp = &(b.setword[b.n]); + while ( p < endp ) *r++ = *p++; + } + + return(t); +} + +set +#ifdef __USE_PROTOS +set_of( unsigned b ) +#else +set_of( b ) +unsigned b; +#endif +{ + /* Fast singleton set constructor operation */ + static set a; + + if ( b == nil ) return( empty ); + set_new(a, b); + a.setword[DIVWORD(b)] = bitmask[MODWORD(b)]; + + return(a); +} + +/* + * Extend (or shrink) the set passed in to have n words. + * + * if n is smaller than the minimum, boost n to have the minimum. + * if the new set size is the same as the old one, do nothing. + * + * TJP 4-27-92 Fixed so won't try to alloc 0 bytes + */ +void +#ifdef __USE_PROTOS +set_ext( set *a, unsigned int n ) +#else +set_ext( a, n ) +set *a; +unsigned int n; +#endif +{ + register unsigned *p; + register unsigned *endp; + unsigned int size; + + CHK((*a)); + if ( a->n == 0 ) + { + if ( n == 0 ) return; + if (a->setword != NULL) { + free (a->setword); /* MR20 */ + } + a->setword = (unsigned *) calloc(n, BytesPerWord); + if ( a->setword == NULL ) + { + fprintf(stderr, "set_ext(%d words): cannot allocate set\n", n); + exit(-1); + } + a->n = n; + return; + } + if ( n < min ) n = min; + if ( a->n == n || n == 0 ) return; + size = a->n; + a->n = n; + a->setword = (unsigned *) realloc( (char *)a->setword, (n*BytesPerWord) ); + if ( a->setword == NULL ) + { + fprintf(stderr, "set_ext(%d words): cannot allocate set\n", n); + exit(-1); + } + + p = &(a->setword[size]); /* clear from old size to new size */ + endp = &(a->setword[a->n]); + do { + *p++ = 0; + } while ( p < endp ); +} + +set +#ifdef __USE_PROTOS +set_not( set a ) +#else +set_not( a ) +set a; +#endif +{ + /* Fast not of set a (assumes all bits used) */ + /* size of resultant set is size(a) */ + /* ~empty = empty cause we don't know how bit to make set */ + set t; + register unsigned *r; + register unsigned *p = a.setword; + register unsigned *endp = &(a.setword[a.n]); + + CHK(a); + t = empty; + if ( a.n == 0 ) return( empty ); + set_ext(&t, a.n); + r = t.setword; + + do { + *r++ = (~ *p++); + } while ( p < endp ); + + return(t); +} + +int +#ifdef __USE_PROTOS +set_equ( set a, set b ) +#else +set_equ( a, b ) +set a; +set b; +#endif +{ +/* 8-Nov-97 Make it work with sets of different sizes */ +/* Easy to understand, too. Probably faster. */ +/* Check for a equal to b */ + + unsigned int count; /* MR11 */ + unsigned int i; /* MR11 */ + + CHK(a); CHK(b); + + count=MIN(a.n,b.n); + if (count == 0) return 1; + for (i=0; i < count; i++) { + if (a.setword[i] != b.setword[i]) return 0; + }; + if (a.n < b.n) { + for (i=count; i < b.n; i++) { + if (b.setword[i] != 0) return 0; + } + return 1; + } else if (a.n > b.n) { + for (i=count; i < a.n; i++) { + if (a.setword[i] != 0) return 0; + } + return 1; + } else { + return 1; + }; +} + +int +#ifdef __USE_PROTOS +set_sub( set a, set b ) +#else +set_sub( a, b ) +set a; +set b; +#endif +{ + +/* 8-Nov-97 Make it work with sets of different sizes */ +/* Easy to understand, too. Probably faster. */ +/* Check for a is a PROPER subset of b */ + + unsigned int count; + unsigned int i; + + CHK(a); CHK(b); + + if (a.n == 0) return 1; + count=MIN(a.n,b.n); + for (i=0; i < count; i++) { + if (a.setword[i] & ~b.setword[i]) return 0; + }; + if (a.n <= b.n) { + return 1; + } else { + for (i=count; i a.n ) return(0); + + /* Otherwise, we have to check */ + return( a.setword[DIVWORD(b)] & bitmask[MODWORD(b)] ); +} + +int +#ifdef __USE_PROTOS +set_nil( set a ) +#else +set_nil( a ) +set a; +#endif +{ + /* Fast check for nil set */ + register unsigned *p = a.setword; + register unsigned *endp; + + CHK(a); + if ( a.n == 0 ) return(1); + endp = &(a.setword[a.n]); + + /* The set is not empty if any word used to store + the set is non-zero. This means one must be a + bit careful about doing things like negation. + */ + do { + if (*p) return(0); + } while (++p < endp); + + return(1); +} + +char * +#ifdef __USE_PROTOS +set_str( set a ) +#else +set_str( a ) +set a; +#endif +{ + /* Fast convert set a into ASCII char string... + assumes that all word bits are used in the set + and that SETSIZE is a multiple of WORDSIZE. + Trailing 0 bits are removed from the string. + if no bits are on or set is empty, "" is returned. + */ + register unsigned *p = a.setword; + register unsigned *endp = &(a.setword[a.n]); + static char str_tmp[StrSize+1]; + register char *q = &(str_tmp[0]); + + CHK(a); + if ( a.n==0 ) {*q=0; return( &(str_tmp[0]) );} + do { + register unsigned t = *p; + register unsigned *b = &(bitmask[0]); + do { + *(q++) = (char) ((t & *b) ? '1' : '0'); + } while (++b < &(bitmask[WORDSIZE])); + } while (++p < endp); + + /* Trim trailing 0s & NULL terminate the string */ + while ((q > &(str_tmp[0])) && (*(q-1) != '1')) --q; + *q = 0; + + return(&(str_tmp[0])); +} + +set +#ifdef __USE_PROTOS +set_val( register char *s ) +#else +set_val( s ) +register char *s; +#endif +{ + /* Fast convert set ASCII char string into a set. + If the string ends early, the remaining set bits + are all made zero. + The resulting set size is just big enough to hold all elements. + */ + static set a; + register unsigned *p, *endp; + + set_new(a, strlen(s)); + p = a.setword; + endp = &(a.setword[a.n]); + do { + register unsigned *b = &(bitmask[0]); + /* Start with a word with no bits on */ + *p = 0; + do { + if (*s) { + if (*s == '1') { + /* Turn-on this bit */ + *p |= *b; + } + ++s; + } + } while (++b < &(bitmask[WORDSIZE])); + } while (++p < endp); + + return(a); +} + +/* + * Or element e into set a. a can be empty. + */ +void +#ifdef __USE_PROTOS +set_orel( unsigned e, set *a ) +#else +set_orel( e, a ) +unsigned e; +set *a; +#endif +{ + CHK((*a)); + if ( e == nil ) return; + if ( NumWords(e) > a->n ) set_ext(a, NumWords(e)); + a->setword[DIVWORD(e)] |= bitmask[MODWORD(e)]; +} + +/* + * Or set b into set a. a can be empty. does nothing if b empty. + */ +void +#ifdef __USE_PROTOS +set_orin( set *a, set b ) +#else +set_orin( a, b ) +set *a; +set b; +#endif +{ + /* Fast set union operation */ + /* size(a) is max(a, b); */ + unsigned int m; + register unsigned *p, + *q = b.setword, + *endq; /* MR20 */ + + CHK((*a)); CHK(b); + if ( b.n == 0 ) return; + endq = &(b.setword[b.n]); /* MR20 */ + m = (a->n > b.n) ? a->n : b.n; + set_ext(a, m); + p = a->setword; + do { + *p++ |= *q++; + } while ( q < endq ); +} + +/* + * And set b into set a. a can be empty. does nothing if b empty. + */ +void +#ifdef __USE_PROTOS +set_andin( set *a, set b ) +#else +set_andin( a, b ) +set *a; +set b; +#endif +{ + /* Fast set intersection operation */ + /* size(a) is max(a, b); */ + unsigned int m; + register unsigned *p, + *q = b.setword, + *endq = &(b.setword[b.n]); + + CHK((*a)); CHK(b); + if ( b.n == 0 ) return; + m = (a->n > b.n) ? a->n : b.n; + set_ext(a, m); + p = a->setword; + do { + *p++ &= *q++; + } while ( q < endq ); +} + +void +#ifdef __USE_PROTOS +set_rm( unsigned e, set a ) +#else +set_rm( e, a ) +unsigned e; +set a; +#endif +{ + /* Does not effect size of set */ + CHK(a); + if ( (e == nil) || (NumWords(e) > a.n) ) return; + a.setword[DIVWORD(e)] ^= (a.setword[DIVWORD(e)]&bitmask[MODWORD(e)]); +} + +void +#ifdef __USE_PROTOS +set_clr( set a ) +#else +set_clr( a ) +set a; +#endif +{ + /* Does not effect size of set */ + register unsigned *p = a.setword; + register unsigned *endp; + + CHK(a); + if ( a.n == 0 ) return; + endp = &(a.setword[a.n]); + do { + *p++ = 0; + } while ( p < endp ); +} + +set +#ifdef __USE_PROTOS +set_dup( set a ) +#else +set_dup( a ) +set a; +#endif +{ + set b; + register unsigned *p, + *q = a.setword, + *endq; /* MR20 */ + + CHK(a); + b = empty; + if ( a.n == 0 ) return( empty ); + endq = &(a.setword[a.n]); /* MR20 */ + set_ext(&b, a.n); + p = b.setword; + do { + *p++ = *q++; + } while ( q < endq ); + + return(b); +} + +/* + * Return a nil terminated list of unsigned ints that represents all + * "on" bits in the bit set. + * + * e.g. {011011} --> {1, 2, 4, 5, nil} + * + * _set_pdq and set_pdq are useful when an operation is required on each element + * of a set. Normally, the sequence is: + * + * while ( set_deg(a) > 0 ) { + * e = set_int(a); + * set_rm(e, a); + * ...process e... + * } + * Now, + * + * t = e = set_pdq(a); + * while ( *e != nil ) { + * ...process *e... + * e++; + * } + * free( t ); + * + * We have saved many set calls and have not destroyed set a. + */ +void +#ifdef __USE_PROTOS +_set_pdq( set a, register unsigned *q ) +#else +_set_pdq( a, q ) +set a; +register unsigned *q; +#endif +{ + register unsigned *p = a.setword, + *endp = &(a.setword[a.n]); + register unsigned e=0; + + CHK(a); + /* are there any space (possibility of elements)? */ + if ( a.n == 0 ) return; + do { + register unsigned t = *p; + register unsigned *b = &(bitmask[0]); + do { + if ( t & *b ) *q++ = e; + ++e; + } while (++b < &(bitmask[WORDSIZE])); + } while (++p < endp); + *q = nil; +} + +/* + * Same as _set_pdq except allocate memory. set_pdq is the natural function + * to use. + */ +unsigned * +#ifdef __USE_PROTOS +set_pdq( set a ) +#else +set_pdq( a ) +set a; +#endif +{ + unsigned *q; + int max_deg; + + CHK(a); + max_deg = WORDSIZE*a.n; + /* assume a.n!=0 & no elements is rare, but still ok */ + if ( a.n == 0 ) return(NULL); + q = (unsigned *) malloc((max_deg+1)*BytesPerWord); + if ( q == NULL ) return( NULL ); + _set_pdq(a, q); + return( q ); +} + +/* a function that produces a hash number for the set + */ +unsigned int +#ifdef __USE_PROTOS +set_hash( set a, register unsigned int mod ) +#else +set_hash( a, mod ) +set a; +register unsigned int mod; +#endif +{ + /* Fast hash of set a (assumes all bits used) */ + register unsigned *p = &(a.setword[0]); + register unsigned *endp = &(a.setword[a.n]); + register unsigned i = 0; + + CHK(a); + while (p> LogWordSize) /* x / WORDSIZE */ +#define nil (~((unsigned) 0)) /* An impossible set member all bits on (big!) */ + +typedef struct _set { + unsigned int n; /* Number of words in set */ + unsigned *setword; + } set; + +#define set_init {0, NULL} +#define set_null(a) ((a).setword==NULL) + +#define NumBytes(x) (((x)>>3)+1) /* Num bytes to hold x */ +#define NumWords(x) ((((unsigned)(x))>>LogWordSize)+1) /* Num words to hold x */ + + +/* M a c r o s */ + +/* make arg1 a set big enough to hold max elem # of arg2 */ +#define set_new(a,_max) \ +if (((a).setword=(unsigned *)calloc(NumWords(_max),BytesPerWord))==NULL) \ + fprintf(stderr, "set_new: Cannot allocate set with max of %d\n", _max); \ + (a).n = NumWords(_max); + +#define set_free(a) \ + {if ( (a).setword != NULL ) free((char *)((a).setword)); \ + (a) = empty;} + +#ifdef __USE_PROTOS +extern void set_size( unsigned ); +extern unsigned int set_deg( set ); +extern set set_or( set, set ); +extern set set_and( set, set ); +extern set set_dif( set, set ); +extern set set_of( unsigned ); +extern void set_ext( set *, unsigned int ); +extern set set_not( set ); +extern int set_equ( set, set ); +extern int set_sub( set, set ); +extern unsigned set_int( set ); +extern int set_el( unsigned, set ); +extern int set_nil( set ); +extern char * set_str( set ); +extern set set_val( register char * ); +extern void set_orel( unsigned, set * ); +extern void set_orin( set *, set ); +extern void set_andin( set *, set ); +extern void set_rm( unsigned, set ); +extern void set_clr( set ); +extern set set_dup( set ); +extern void set_PDQ( set, register unsigned * ); +extern unsigned *set_pdq( set ); +extern void _set_pdq( set a, register unsigned *q ); +extern unsigned int set_hash( set, register unsigned int ); +#else +extern void set_size(); +extern unsigned int set_deg(); +extern set set_or(); +extern set set_and(); +extern set set_dif(); +extern set set_of(); +extern void set_ext(); +extern set set_not(); +extern int set_equ(); +extern int set_sub(); +extern unsigned set_int(); +extern int set_el(); +extern int set_nil(); +extern char * set_str(); +extern set set_val(); +extern void set_orel(); +extern void set_orin(); +extern void set_andin(); +extern void set_rm(); +extern void set_clr(); +extern set set_dup(); +extern void set_PDQ(); +extern unsigned *set_pdq(); +extern void _set_pdq(); +extern unsigned int set_hash(); +#endif + +extern set empty; + +#endif diff --git a/Tools/CodeTools/Source/Pccts/support/sym/sym.c b/Tools/CodeTools/Source/Pccts/support/sym/sym.c new file mode 100644 index 0000000000..eccce059bb --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/support/sym/sym.c @@ -0,0 +1,402 @@ +/* + * Simple symbol table manager using coalesced chaining to resolve collisions + * + * Doubly-linked lists are used for fast removal of entries. + * + * 'sym.h' must have a definition for typedef "Sym". Sym must include at + * minimum the following fields: + * + * ... + * char *symbol; + * struct ... *next, *prev, **head, *scope; + * unsigned int hash; + * ... + * + * 'template.h' can be used as a template to create a 'sym.h'. + * + * 'head' is &(table[hash(itself)]). + * The hash table is not resizable at run-time. + * The scope field is used to link all symbols of a current scope together. + * Scope() sets the current scope (linked list) to add symbols to. + * Any number of scopes can be handled. The user passes the address of + * a pointer to a symbol table + * entry (INITIALIZED TO NULL first time). + * + * Available Functions: + * + * zzs_init(s1,s2) -- Create hash table with size s1, string table size s2. + * zzs_done() -- Free hash and string table created with zzs_init(). + * zzs_add(key,rec)-- Add 'rec' with key 'key' to the symbol table. + * zzs_newadd(key) -- create entry; add using 'key' to the symbol table. + * zzs_get(key) -- Return pointer to last record entered under 'key' + * Else return NULL + * zzs_del(p) -- Unlink the entry associated with p. This does + * NOT free 'p' and DOES NOT remove it from a scope + * list. If it was a part of your intermediate code + * tree or another structure. It will still be there. + * It is only removed from further consideration + * by the symbol table. + * zzs_keydel(s) -- Unlink the entry associated with key s. + * Calls zzs_del(p) to unlink. + * zzs_scope(sc) -- Specifies that everything added to the symbol + * table with zzs_add() is added to the list (scope) + * 'sc'. 'sc' is of 'Sym **sc' type and must be + * initialized to NULL before trying to add anything + * to it (passing it to zzs_scope()). Scopes can be + * switched at any time and merely links a set of + * symbol table entries. If a NULL pointer is + * passed, the current scope is returned. + * zzs_rmscope(sc) -- Remove (zzs_del()) all elements of scope 'sc' + * from the symbol table. The entries are NOT + * free()'d. A pointer to the first + * element in the "scope" is returned. The user + * can then manipulate the list as he/she chooses + * (such as freeing them all). NOTE that this + * function sets your scope pointer to NULL, + * but returns a pointer to the list for you to use. + * zzs_stat() -- Print out the symbol table and some relevant stats. + * zzs_new(key) -- Create a new record with calloc() of type Sym. + * Add 'key' to the string table and make the new + * records 'symbol' pointer point to it. + * zzs_strdup(s) -- Add s to the string table and return a pointer + * to it. Very fast allocation routine + * and does not require strlen() nor calloc(). + * + * Example: + * + * #include + * #include "sym.h" + * + * main() + * { + * Sym *scope1=NULL, *scope2=NULL, *a, *p; + * + * zzs_init(101, 100); + * + * a = zzs_new("Apple"); zzs_add(a->symbol, a); -- No scope + * zzs_scope( &scope1 ); -- enter scope 1 + * a = zzs_new("Plum"); zzs_add(a->symbol, a); + * zzs_scope( &scope2 ); -- enter scope 2 + * a = zzs_new("Truck"); zzs_add(a->symbol, a); + * + * p = zzs_get("Plum"); + * if ( p == NULL ) fprintf(stderr, "Hmmm...Can't find 'Plum'\n"); + * + * p = zzs_rmscope(&scope1) + * for (; p!=NULL; p=p->scope) {printf("Scope1: %s\n", p->symbol);} + * p = zzs_rmscope(&scope2) + * for (; p!=NULL; p=p->scope) {printf("Scope2: %s\n", p->symbol);} + * } + * + * Terence Parr + * Purdue University + * February 1990 + * + * CHANGES + * + * Terence Parr + * May 1991 + * Renamed functions to be consistent with ANTLR + * Made HASH macro + * Added zzs_keydel() + * Added zzs_newadd() + * Fixed up zzs_stat() + * + * July 1991 + * Made symbol table entry save its hash code for fast comparison + * during searching etc... + */ + +#include +#if defined(__STDC__) || defined(__USE_PROTOS) +#include +#include +#else +#include +#endif +#include "sym.h" + +#define StrSame 0 + +static Sym **CurScope = NULL; +static unsigned size = 0; +static Sym **table=NULL; +static char *strings; +static char *strp; +static int strsize = 0; + +#ifdef __USE_PROTOS +void zzs_init(int sz,int strs) +#else +void zzs_init(sz, strs) +int sz, strs; +#endif +{ + if ( sz <= 0 || strs <= 0 ) return; + table = (Sym **) calloc(sz, sizeof(Sym *)); + if ( table == NULL ) + { + fprintf(stderr, "Cannot allocate table of size %d\n", sz); + exit(1); + } + strings = (char *) calloc(strs, sizeof(char)); + if ( strings == NULL ) + { + fprintf(stderr, "Cannot allocate string table of size %d\n", strs); + exit(1); + } + size = sz; + strsize = strs; + strp = strings; +} + +#ifdef __USE_PROTOS +void zzs_done(void) +#else +void zzs_done() +#endif +{ + if ( table != NULL ) free( table ); + if ( strings != NULL ) free( strings ); +} + +#ifdef __USE_PROTOS +void zzs_add(char *key,Sym rec) +#else +void zzs_add(key, rec) +char *key; +register Sym *rec; +#endif +{ + register unsigned int h=0; + register char *p=key; + + HASH(p, h); + rec->hash = h; /* save hash code for fast comp later */ + h %= size; + + if ( CurScope != NULL ) {rec->scope = *CurScope; *CurScope = rec;} + rec->next = table[h]; /* Add to doubly-linked list */ + rec->prev = NULL; + if ( rec->next != NULL ) (rec->next)->prev = rec; + table[h] = rec; + rec->head = &(table[h]); +} + +#ifdef __USE_PROTOS +Sym * zzs_get(char *key) +#else +Sym * zzs_get(key) +char *key; +#endif +{ + register unsigned int h=0; + register char *p=key; + register Sym *q; + + HASH(p, h); + + for (q = table[h%size]; q != NULL; q = q->next) + { + if ( q->hash == h ) /* do we even have a chance of matching? */ + if ( strcmp(key, q->symbol) == StrSame ) return( q ); + } + return( NULL ); +} + +/* + * Unlink p from the symbol table. Hopefully, it's actually in the + * symbol table. + * + * If p is not part of a bucket chain of the symbol table, bad things + * will happen. + * + * Will do nothing if all list pointers are NULL + */ +#ifdef __USE_PROTOS +void zzs_del(Sym *p) +#else +void zzs_del(p) +register Sym *p; +#endif +{ + if ( p == NULL ) {fprintf(stderr, "zzs_del(NULL)\n"); exit(1);} + if ( p->prev == NULL ) /* Head of list */ + { + register Sym **t = p->head; + + if ( t == NULL ) return; /* not part of symbol table */ + (*t) = p->next; + if ( (*t) != NULL ) (*t)->prev = NULL; + } + else + { + (p->prev)->next = p->next; + if ( p->next != NULL ) (p->next)->prev = p->prev; + } + p->next = p->prev = NULL; /* not part of symbol table anymore */ + p->head = NULL; +} + +#ifdef __USE_PROTOS +void zzs_keydel(char *key) +#else +void zzs_keydel(key) +char *key; +#endif +{ + Sym *p = zzs_get(key); + + if ( p != NULL ) zzs_del( p ); +} + +/* S c o p e S t u f f */ + +/* Set current scope to 'scope'; return current scope if 'scope' == NULL */ + +#ifdef __USE_PROTOS +Sym ** zzs_scope(Sym **scope) +#else +Sym ** zzs_scope(scope) +Sym **scope; +#endif +{ + if ( scope == NULL ) return( CurScope ); + CurScope = scope; + return( scope ); +} + +/* Remove a scope described by 'scope'. Return pointer to 1st element in scope */ + +#ifdef __USE_PROTOS +Sym * zzs_rmscope(Sym **scope) +#else +Sym * zzs_rmscope(scope) +register Sym **scope; +#endif +{ + register Sym *p; + Sym *start; + + if ( scope == NULL ) return(NULL); + start = p = *scope; + for (; p != NULL; p=p->scope) { zzs_del( p ); } + *scope = NULL; + return( start ); +} + +#ifdef __USE_PROTOS +void zzs_stat(void) +#else +void zzs_stat() +#endif +{ + static unsigned short count[20]; + unsigned int i,n=0,low=0, hi=0; + register Sym **p; + float avg=0.0; + + for (i=0; i<20; i++) count[i] = 0; + for (p=table; p<&(table[size]); p++) + { + register Sym *q = *p; + unsigned int len; + + if ( q != NULL && low==0 ) low = p-table; + len = 0; + if ( q != NULL ) printf("[%d]", p-table); + while ( q != NULL ) + { + len++; + n++; + printf(" %s", q->symbol); + q = q->next; + if ( q == NULL ) printf("\n"); + } + if ( len>=20 ) printf("zzs_stat: count table too small\n"); + else count[len]++; + if ( *p != NULL ) hi = p-table; + } + + printf("Storing %d recs used %d hash positions out of %d\n", + n, size-count[0], size); + printf("%f %% utilization\n", + ((float)(size-count[0]))/((float)size)); + for (i=0; i<20; i++) + { + if ( count[i] != 0 ) + { + avg += (((float)(i*count[i]))/((float)n)) * i; + printf("Buckets of len %d == %d (%f %% of recs)\n", + i, count[i], 100.0*((float)(i*count[i]))/((float)n)); + } + } + printf("Avg bucket length %f\n", avg); + printf("Range of hash function: %d..%d\n", low, hi); +} + +/* + * Given a string, this function allocates and returns a pointer to a + * symbol table record whose "symbol" pointer is reset to a position + * in the string table. + */ + +#ifdef __USE_PROTOS +Sym * zzs_new(char *text) +#else +Sym * zzs_new(text) +char *text; +#endif +{ + Sym *p; + + if ( (p = (Sym *) calloc(1,sizeof(Sym))) == 0 ) + { + fprintf(stderr,"Out of memory\n"); + exit(1); + } + p->symbol = zzs_strdup(text); + + return p; +} + +/* create a new symbol table entry and add it to the symbol table */ + +#ifdef __USE_PROTOS +Sym * zzs_newadd(char *text) +#else +Sym * zzs_newadd(text) +char *text; +#endif +{ + Sym *p = zzs_new(text); + if ( p != NULL ) zzs_add(text, p); + return p; +} + +/* Add a string to the string table and return a pointer to it. + * Bump the pointer into the string table to next avail position. + */ + +#ifdef __USE_PROTOS +char * zzs_strdup(char *s) +#else +char * zzs_strdup(s) +register char *s; +#endif +{ + register char *start=strp; + + while ( *s != '\0' ) + { + if ( strp >= &(strings[strsize-2]) ) + { + fprintf(stderr, "sym: string table overflow (%d chars)\n", strsize); + exit(-1); + } + *strp++ = *s++; + } + *strp++ = '\0'; + + return( start ); +} diff --git a/Tools/CodeTools/Source/Pccts/support/sym/template.h b/Tools/CodeTools/Source/Pccts/support/sym/template.h new file mode 100644 index 0000000000..ee6e665e34 --- /dev/null +++ b/Tools/CodeTools/Source/Pccts/support/sym/template.h @@ -0,0 +1,41 @@ +/* T e m p l a t e F o r S y m b o l T a b l e M a n a g e r */ + +/* define some hash function */ +#ifndef HASH +#define HASH(p, h) while ( *p != '\0' ) h = (h<<1) + *p++; +#endif + +/* minimum symbol table record */ +typedef struct _sym { + char *symbol; + struct _sym *next, *prev, **head, *scope; + unsigned int hash; + } Sym, *SymPtr; + +#ifdef __USE_PROTOS +void zzs_init(int, int); +void zzs_done(void); +void zzs_add(char *, Sym *); +Sym *zzs_get(char *); +void zzs_del(Sym *); +void zzs_keydel(char *); +Sym **zzs_scope(Sym **); +Sym *zzs_rmscope(Sym **); +void zzs_stat(void); +Sym *zzs_new(char *); +Sym *zzs_newadd(char *); +char *zzs_strdup(char *); +#else +void zzs_init(); +void zzs_done(); +void zzs_add(); +Sym *zzs_get(); +void zzs_del(); +void zzs_keydel(); +Sym **zzs_scope(); +Sym *zzs_rmscope(); +void zzs_stat(); +Sym *zzs_new(); +Sym *zzs_newadd(); +char *zzs_strdup(); +#endif diff --git a/Tools/CodeTools/Source/PeCoffLoader/BasePeCoff.c b/Tools/CodeTools/Source/PeCoffLoader/BasePeCoff.c new file mode 100644 index 0000000000..9c25e1f4b8 --- /dev/null +++ b/Tools/CodeTools/Source/PeCoffLoader/BasePeCoff.c @@ -0,0 +1,1060 @@ +/*++ + +Copyright (c) 2004 - 2005, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PeCoffLoader.c + +Abstract: + + Tiano PE/COFF loader + +Revision History + +--*/ + + +#include +#include +#include + +STATIC +RETURN_STATUS +PeCoffLoaderGetPeHeader ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, + OUT EFI_IMAGE_NT_HEADERS *PeHdr, + OUT EFI_TE_IMAGE_HEADER *TeHdr + ); + +STATIC +RETURN_STATUS +PeCoffLoaderCheckImageType ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, + IN EFI_IMAGE_NT_HEADERS *PeHdr, + IN EFI_TE_IMAGE_HEADER *TeHdr + ); + +STATIC +VOID * +PeCoffLoaderImageAddress ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, + IN UINTN Address + ); + + +STATIC +RETURN_STATUS +PeCoffLoaderGetPeHeader ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, + OUT EFI_IMAGE_NT_HEADERS *PeHdr, + OUT EFI_TE_IMAGE_HEADER *TeHdr + ) +/*++ + +Routine Description: + + Retrieves the PE or TE Header from a PE/COFF or TE image + +Arguments: + + ImageContext - The context of the image being loaded + + PeHdr - The buffer in which to return the PE header + + TeHdr - The buffer in which to return the TE header + +Returns: + + RETURN_SUCCESS if the PE or TE Header is read, + Otherwise, the error status from reading the PE/COFF or TE image using the ImageRead function. + +--*/ +{ + RETURN_STATUS Status; + EFI_IMAGE_DOS_HEADER DosHdr; + UINTN Size; + + ImageContext->IsTeImage = FALSE; + // + // Read the DOS image headers + // + Size = sizeof (EFI_IMAGE_DOS_HEADER); + Status = ImageContext->ImageRead ( + ImageContext->Handle, + 0, + &Size, + &DosHdr + ); + if (RETURN_ERROR (Status)) { + ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; + return Status; + } + + ImageContext->PeCoffHeaderOffset = 0; + if (DosHdr.e_magic == EFI_IMAGE_DOS_SIGNATURE) { + // + // DOS image header is present, so read the PE header after the DOS image header + // + ImageContext->PeCoffHeaderOffset = DosHdr.e_lfanew; + } + // + // Read the PE/COFF Header + // + Size = sizeof (EFI_IMAGE_NT_HEADERS); + Status = ImageContext->ImageRead ( + ImageContext->Handle, + ImageContext->PeCoffHeaderOffset, + &Size, + PeHdr + ); + if (RETURN_ERROR (Status)) { + ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; + return Status; + } + // + // Check the PE/COFF Header Signature. If not, then try to read a TE header + // + if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) { + Size = sizeof (EFI_TE_IMAGE_HEADER); + Status = ImageContext->ImageRead ( + ImageContext->Handle, + 0, + &Size, + TeHdr + ); + if (TeHdr->Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) { + return RETURN_UNSUPPORTED; + } + + ImageContext->IsTeImage = TRUE; + } + + return RETURN_SUCCESS; +} + +STATIC +RETURN_STATUS +PeCoffLoaderCheckImageType ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, + IN EFI_IMAGE_NT_HEADERS *PeHdr, + IN EFI_TE_IMAGE_HEADER *TeHdr + ) +/*++ + +Routine Description: + + Checks the PE or TE header of a PE/COFF or TE image to determine if it supported + +Arguments: + + ImageContext - The context of the image being loaded + + PeHdr - The buffer in which to return the PE header + + TeHdr - The buffer in which to return the TE header + +Returns: + + RETURN_SUCCESS if the PE/COFF or TE image is supported + RETURN_UNSUPPORTED of the PE/COFF or TE image is not supported. + +--*/ +{ + // + // See if the machine type is supported. We support a native machine type (IA-32/Itanium-based) + // and the machine type for the Virtual Machine. + // + if (ImageContext->IsTeImage == FALSE) { + ImageContext->Machine = PeHdr->FileHeader.Machine; + } else { + ImageContext->Machine = TeHdr->Machine; + } + + if (!(EFI_IMAGE_MACHINE_TYPE_SUPPORTED (ImageContext->Machine))) { + ImageContext->ImageError = IMAGE_ERROR_INVALID_MACHINE_TYPE; + return RETURN_UNSUPPORTED; + } + + // + // See if the image type is supported. We support EFI Applications, + // EFI Boot Service Drivers, and EFI Runtime Drivers. + // + if (ImageContext->IsTeImage == FALSE) { + ImageContext->ImageType = PeHdr->OptionalHeader.Subsystem; + } else { + ImageContext->ImageType = (UINT16) (TeHdr->Subsystem); + } + + + return RETURN_SUCCESS; +} + +RETURN_STATUS +EFIAPI +PeCoffLoaderGetImageInfo ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +/*++ + +Routine Description: + + Retrieves information on a PE/COFF image + +Arguments: + + This - Calling context + ImageContext - The context of the image being loaded + +Returns: + + RETURN_SUCCESS - The information on the PE/COFF image was collected. + RETURN_INVALID_PARAMETER - ImageContext is NULL. + RETURN_UNSUPPORTED - The PE/COFF image is not supported. + Otherwise - The error status from reading the PE/COFF image using the + ImageContext->ImageRead() function + +--*/ +{ + RETURN_STATUS Status; + EFI_IMAGE_NT_HEADERS PeHdr; + EFI_TE_IMAGE_HEADER TeHdr; + EFI_IMAGE_DATA_DIRECTORY *DebugDirectoryEntry; + UINTN Size; + UINTN Index; + UINTN DebugDirectoryEntryRva; + UINTN DebugDirectoryEntryFileOffset; + UINTN SectionHeaderOffset; + EFI_IMAGE_SECTION_HEADER SectionHeader; + EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry; + + if (NULL == ImageContext) { + return RETURN_INVALID_PARAMETER; + } + // + // Assume success + // + ImageContext->ImageError = IMAGE_ERROR_SUCCESS; + + Status = PeCoffLoaderGetPeHeader (ImageContext, &PeHdr, &TeHdr); + if (RETURN_ERROR (Status)) { + return Status; + } + // + // Verify machine type + // + Status = PeCoffLoaderCheckImageType (ImageContext, &PeHdr, &TeHdr); + if (RETURN_ERROR (Status)) { + return Status; + } + // + // Retrieve the base address of the image + // + if (!(ImageContext->IsTeImage)) { + ImageContext->ImageAddress = PeHdr.OptionalHeader.ImageBase; + } else { + ImageContext->ImageAddress = (PHYSICAL_ADDRESS) (TeHdr.ImageBase); + } + // + // Initialize the alternate destination address to 0 indicating that it + // should not be used. + // + ImageContext->DestinationAddress = 0; + + // + // Initialize the codeview pointer. + // + ImageContext->CodeView = NULL; + ImageContext->PdbPointer = NULL; + + // + // Three cases with regards to relocations: + // - Image has base relocs, RELOCS_STRIPPED==0 => image is relocatable + // - Image has no base relocs, RELOCS_STRIPPED==1 => Image is not relocatable + // - Image has no base relocs, RELOCS_STRIPPED==0 => Image is relocatable but + // has no base relocs to apply + // Obviously having base relocations with RELOCS_STRIPPED==1 is invalid. + // + // Look at the file header to determine if relocations have been stripped, and + // save this info in the image context for later use. + // + if ((!(ImageContext->IsTeImage)) && ((PeHdr.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0)) { + ImageContext->RelocationsStripped = TRUE; + } else { + ImageContext->RelocationsStripped = FALSE; + } + + if (!(ImageContext->IsTeImage)) { + ImageContext->ImageSize = (UINT64) PeHdr.OptionalHeader.SizeOfImage; + ImageContext->SectionAlignment = PeHdr.OptionalHeader.SectionAlignment; + ImageContext->SizeOfHeaders = PeHdr.OptionalHeader.SizeOfHeaders; + + // + // Modify ImageSize to contain .PDB file name if required and initialize + // PdbRVA field... + // + if (PeHdr.OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { + DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); + + DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress; + + // + // Determine the file offset of the debug directory... This means we walk + // the sections to find which section contains the RVA of the debug + // directory + // + DebugDirectoryEntryFileOffset = 0; + + SectionHeaderOffset = (UINTN)( + ImageContext->PeCoffHeaderOffset + + sizeof (UINT32) + + sizeof (EFI_IMAGE_FILE_HEADER) + + PeHdr.FileHeader.SizeOfOptionalHeader + ); + + for (Index = 0; Index < PeHdr.FileHeader.NumberOfSections; Index++) { + // + // Read section header from file + // + Size = sizeof (EFI_IMAGE_SECTION_HEADER); + Status = ImageContext->ImageRead ( + ImageContext->Handle, + SectionHeaderOffset, + &Size, + &SectionHeader + ); + if (RETURN_ERROR (Status)) { + ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; + return Status; + } + + if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress && + DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) { + DebugDirectoryEntryFileOffset = + DebugDirectoryEntryRva - SectionHeader.VirtualAddress + SectionHeader.PointerToRawData; + break; + } + + SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER); + } + + if (DebugDirectoryEntryFileOffset != 0) { + for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) { + // + // Read next debug directory entry + // + Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); + Status = ImageContext->ImageRead ( + ImageContext->Handle, + DebugDirectoryEntryFileOffset, + &Size, + &DebugEntry + ); + if (RETURN_ERROR (Status)) { + ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; + return Status; + } + + if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { + ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)); + if (DebugEntry.RVA == 0 && DebugEntry.FileOffset != 0) { + ImageContext->ImageSize += DebugEntry.SizeOfData; + } + + return RETURN_SUCCESS; + } + } + } + } + } else { + ImageContext->ImageSize = 0; + ImageContext->SectionAlignment = 4096; + ImageContext->SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN) TeHdr.BaseOfCode - (UINTN) TeHdr.StrippedSize; + + DebugDirectoryEntry = &TeHdr.DataDirectory[1]; + DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress; + SectionHeaderOffset = (UINTN) (sizeof (EFI_TE_IMAGE_HEADER)); + + DebugDirectoryEntryFileOffset = 0; + + for (Index = 0; Index < TeHdr.NumberOfSections;) { + // + // Read section header from file + // + Size = sizeof (EFI_IMAGE_SECTION_HEADER); + Status = ImageContext->ImageRead ( + ImageContext->Handle, + SectionHeaderOffset, + &Size, + &SectionHeader + ); + if (RETURN_ERROR (Status)) { + ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; + return Status; + } + + if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress && + DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) { + DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva - + SectionHeader.VirtualAddress + + SectionHeader.PointerToRawData + + sizeof (EFI_TE_IMAGE_HEADER) - + TeHdr.StrippedSize; + + // + // File offset of the debug directory was found, if this is not the last + // section, then skip to the last section for calculating the image size. + // + if (Index < (UINTN) TeHdr.NumberOfSections - 1) { + SectionHeaderOffset += (TeHdr.NumberOfSections - 1 - Index) * sizeof (EFI_IMAGE_SECTION_HEADER); + Index = TeHdr.NumberOfSections - 1; + continue; + } + } + + // + // In Te image header there is not a field to describe the ImageSize. + // Actually, the ImageSize equals the RVA plus the VirtualSize of + // the last section mapped into memory (Must be rounded up to + // a mulitple of Section Alignment). Per the PE/COFF specification, the + // section headers in the Section Table must appear in order of the RVA + // values for the corresponding sections. So the ImageSize can be determined + // by the RVA and the VirtualSize of the last section header in the + // Section Table. + // + if ((++Index) == (UINTN) TeHdr.NumberOfSections) { + ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize + + ImageContext->SectionAlignment - 1) & ~(ImageContext->SectionAlignment - 1); + } + + SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER); + } + + if (DebugDirectoryEntryFileOffset != 0) { + for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) { + // + // Read next debug directory entry + // + Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); + Status = ImageContext->ImageRead ( + ImageContext->Handle, + DebugDirectoryEntryFileOffset, + &Size, + &DebugEntry + ); + if (RETURN_ERROR (Status)) { + ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; + return Status; + } + + if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { + ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)); + return RETURN_SUCCESS; + } + } + } + } + + return RETURN_SUCCESS; +} + +STATIC +VOID * +PeCoffLoaderImageAddress ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, + IN UINTN Address + ) +/*++ + +Routine Description: + + Converts an image address to the loaded address + +Arguments: + + ImageContext - The context of the image being loaded + + Address - The address to be converted to the loaded address + +Returns: + + NULL if the address can not be converted, otherwise, the converted address + +--*/ +{ + if (Address >= ImageContext->ImageSize) { + ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS; + return NULL; + } + + return (CHAR8 *) ((UINTN) ImageContext->ImageAddress + Address); +} + +RETURN_STATUS +EFIAPI +PeCoffLoaderRelocateImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +/*++ + +Routine Description: + + Relocates a PE/COFF image in memory + +Arguments: + + This - Calling context + + ImageContext - Contains information on the loaded image to relocate + +Returns: + + RETURN_SUCCESS if the PE/COFF image was relocated + RETURN_LOAD_ERROR if the image is not a valid PE/COFF image + RETURN_UNSUPPORTED not support + +--*/ +{ + RETURN_STATUS Status; + EFI_IMAGE_NT_HEADERS *PeHdr; + EFI_TE_IMAGE_HEADER *TeHdr; + EFI_IMAGE_DATA_DIRECTORY *RelocDir; + UINT64 Adjust; + EFI_IMAGE_BASE_RELOCATION *RelocBase; + EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd; + UINT16 *Reloc; + UINT16 *RelocEnd; + CHAR8 *Fixup; + CHAR8 *FixupBase; + UINT16 *F16; + UINT32 *F32; + CHAR8 *FixupData; + PHYSICAL_ADDRESS BaseAddress; + + PeHdr = NULL; + TeHdr = NULL; + // + // Assume success + // + ImageContext->ImageError = IMAGE_ERROR_SUCCESS; + + // + // If there are no relocation entries, then we are done + // + if (ImageContext->RelocationsStripped) { + return RETURN_SUCCESS; + } + + // + // If the destination address is not 0, use that rather than the + // image address as the relocation target. + // + if (ImageContext->DestinationAddress) { + BaseAddress = ImageContext->DestinationAddress; + } else { + BaseAddress = ImageContext->ImageAddress; + } + + if (!(ImageContext->IsTeImage)) { + PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN)ImageContext->ImageAddress + + ImageContext->PeCoffHeaderOffset); + Adjust = (UINT64) BaseAddress - PeHdr->OptionalHeader.ImageBase; + PeHdr->OptionalHeader.ImageBase = (UINTN) BaseAddress; + + // + // Find the relocation block + // + // Per the PE/COFF spec, you can't assume that a given data directory + // is present in the image. You have to check the NumberOfRvaAndSizes in + // the optional header to verify a desired directory entry is there. + // + if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { + RelocDir = &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]; + RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress); + RelocBaseEnd = PeCoffLoaderImageAddress ( + ImageContext, + RelocDir->VirtualAddress + RelocDir->Size - 1 + ); + } else { + // + // Set base and end to bypass processing below. + // + RelocBase = RelocBaseEnd = 0; + } + } else { + TeHdr = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress); + Adjust = (UINT64) (BaseAddress - TeHdr->ImageBase); + TeHdr->ImageBase = (UINT64) (BaseAddress); + + // + // Find the relocation block + // + RelocDir = &TeHdr->DataDirectory[0]; + RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)( + ImageContext->ImageAddress + + RelocDir->VirtualAddress + + sizeof(EFI_TE_IMAGE_HEADER) - + TeHdr->StrippedSize + ); + RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1); + } + + // + // Run the relocation information and apply the fixups + // + FixupData = ImageContext->FixupData; + while (RelocBase < RelocBaseEnd) { + + Reloc = (UINT16 *) ((CHAR8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION)); + RelocEnd = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock); + if (!(ImageContext->IsTeImage)) { + FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress); + } else { + FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress + + RelocBase->VirtualAddress + + sizeof(EFI_TE_IMAGE_HEADER) - + TeHdr->StrippedSize + ); + } + + if ((CHAR8 *) RelocEnd < (CHAR8 *) ((UINTN) ImageContext->ImageAddress) || + (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress + + (UINTN)ImageContext->ImageSize)) { + ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; + return RETURN_LOAD_ERROR; + } + + // + // Run this relocation record + // + while (Reloc < RelocEnd) { + + Fixup = FixupBase + (*Reloc & 0xFFF); + switch ((*Reloc) >> 12) { + case EFI_IMAGE_REL_BASED_ABSOLUTE: + break; + + case EFI_IMAGE_REL_BASED_HIGH: + F16 = (UINT16 *) Fixup; + *F16 = (UINT16) (*F16 + ((UINT16) ((UINT32) Adjust >> 16))); + if (FixupData != NULL) { + *(UINT16 *) FixupData = *F16; + FixupData = FixupData + sizeof (UINT16); + } + break; + + case EFI_IMAGE_REL_BASED_LOW: + F16 = (UINT16 *) Fixup; + *F16 = (UINT16) (*F16 + (UINT16) Adjust); + if (FixupData != NULL) { + *(UINT16 *) FixupData = *F16; + FixupData = FixupData + sizeof (UINT16); + } + break; + + case EFI_IMAGE_REL_BASED_HIGHLOW: + F32 = (UINT32 *) Fixup; + *F32 = *F32 + (UINT32) Adjust; + if (FixupData != NULL) { + FixupData = ALIGN_POINTER (FixupData, sizeof (UINT32)); + *(UINT32 *) FixupData = *F32; + FixupData = FixupData + sizeof (UINT32); + } + break; + + case EFI_IMAGE_REL_BASED_HIGHADJ: + // + // Return the same EFI_UNSUPPORTED return code as + // PeCoffLoaderRelocateImageEx() returns if it does not recognize + // the relocation type. + // + ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; + return RETURN_UNSUPPORTED; + + default: + Status = PeCoffLoaderRelocateImageEx (Reloc, Fixup, &FixupData, Adjust); + if (RETURN_ERROR (Status)) { + ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; + return Status; + } + } + + // + // Next relocation record + // + Reloc += 1; + } + + // + // Next reloc block + // + RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd; + } + + return RETURN_SUCCESS; +} + +RETURN_STATUS +EFIAPI +PeCoffLoaderLoadImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +/*++ + +Routine Description: + + Loads a PE/COFF image into memory + +Arguments: + + This - Calling context + + ImageContext - Contains information on image to load into memory + +Returns: + + RETURN_SUCCESS if the PE/COFF image was loaded + RETURN_BUFFER_TOO_SMALL if the caller did not provide a large enough buffer + RETURN_LOAD_ERROR if the image is a runtime driver with no relocations + RETURN_INVALID_PARAMETER if the image address is invalid + +--*/ +{ + RETURN_STATUS Status; + EFI_IMAGE_NT_HEADERS *PeHdr; + EFI_TE_IMAGE_HEADER *TeHdr; + PE_COFF_LOADER_IMAGE_CONTEXT CheckContext; + EFI_IMAGE_SECTION_HEADER *FirstSection; + EFI_IMAGE_SECTION_HEADER *Section; + UINTN NumberOfSections; + UINTN Index; + CHAR8 *Base; + CHAR8 *End; + CHAR8 *MaxEnd; + EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry; + EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry; + UINTN Size; + UINT32 TempDebugEntryRva; + + PeHdr = NULL; + TeHdr = NULL; + // + // Assume success + // + ImageContext->ImageError = IMAGE_ERROR_SUCCESS; + + // + // Copy the provided context info into our local version, get what we + // can from the original image, and then use that to make sure everything + // is legit. + // + CopyMem (&CheckContext, ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)); + + Status = PeCoffLoaderGetImageInfo (&CheckContext); + if (RETURN_ERROR (Status)) { + return Status; + } + + // + // Make sure there is enough allocated space for the image being loaded + // + if (ImageContext->ImageSize < CheckContext.ImageSize) { + ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_SIZE; + return RETURN_BUFFER_TOO_SMALL; + } + + // + // If there's no relocations, then make sure it's not a runtime driver, + // and that it's being loaded at the linked address. + // + if (CheckContext.RelocationsStripped) { + // + // If the image does not contain relocations and it is a runtime driver + // then return an error. + // + if (CheckContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) { + ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM; + return RETURN_LOAD_ERROR; + } + // + // If the image does not contain relocations, and the requested load address + // is not the linked address, then return an error. + // + if (CheckContext.ImageAddress != ImageContext->ImageAddress) { + ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS; + return RETURN_INVALID_PARAMETER; + } + } + // + // Make sure the allocated space has the proper section alignment + // + if (!(ImageContext->IsTeImage)) { + if ((ImageContext->ImageAddress & (CheckContext.SectionAlignment - 1)) != 0) { + ImageContext->ImageError = IMAGE_ERROR_INVALID_SECTION_ALIGNMENT; + return RETURN_INVALID_PARAMETER; + } + } + // + // Read the entire PE/COFF or TE header into memory + // + if (!(ImageContext->IsTeImage)) { + Status = ImageContext->ImageRead ( + ImageContext->Handle, + 0, + &ImageContext->SizeOfHeaders, + (VOID *) (UINTN) ImageContext->ImageAddress + ); + + PeHdr = (EFI_IMAGE_NT_HEADERS *) + ((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset); + + FirstSection = (EFI_IMAGE_SECTION_HEADER *) ( + (UINTN)ImageContext->ImageAddress + + ImageContext->PeCoffHeaderOffset + + sizeof(UINT32) + + sizeof(EFI_IMAGE_FILE_HEADER) + + PeHdr->FileHeader.SizeOfOptionalHeader + ); + NumberOfSections = (UINTN) (PeHdr->FileHeader.NumberOfSections); + } else { + Status = ImageContext->ImageRead ( + ImageContext->Handle, + 0, + &ImageContext->SizeOfHeaders, + (void *) (UINTN) ImageContext->ImageAddress + ); + + TeHdr = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress); + + FirstSection = (EFI_IMAGE_SECTION_HEADER *) ( + (UINTN)ImageContext->ImageAddress + + sizeof(EFI_TE_IMAGE_HEADER) + ); + NumberOfSections = (UINTN) (TeHdr->NumberOfSections); + + } + + if (RETURN_ERROR (Status)) { + ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; + return RETURN_LOAD_ERROR; + } + + // + // Load each section of the image + // + Section = FirstSection; + for (Index = 0, MaxEnd = NULL; Index < NumberOfSections; Index++) { + + // + // Compute sections address + // + Base = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress); + End = PeCoffLoaderImageAddress ( + ImageContext, + Section->VirtualAddress + Section->Misc.VirtualSize - 1 + ); + if (ImageContext->IsTeImage) { + Base = (CHAR8 *) ((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize); + End = (CHAR8 *) ((UINTN) End + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize); + } + + if (End > MaxEnd) { + MaxEnd = End; + } + // + // If the base start or end address resolved to 0, then fail. + // + if ((Base == NULL) || (End == NULL)) { + ImageContext->ImageError = IMAGE_ERROR_SECTION_NOT_LOADED; + return RETURN_LOAD_ERROR; + } + + // + // Read the section + // + Size = (UINTN) Section->Misc.VirtualSize; + if ((Size == 0) || (Size > Section->SizeOfRawData)) { + Size = (UINTN) Section->SizeOfRawData; + } + + if (Section->SizeOfRawData) { + if (!(ImageContext->IsTeImage)) { + Status = ImageContext->ImageRead ( + ImageContext->Handle, + Section->PointerToRawData, + &Size, + Base + ); + } else { + Status = ImageContext->ImageRead ( + ImageContext->Handle, + Section->PointerToRawData + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize, + &Size, + Base + ); + } + + if (RETURN_ERROR (Status)) { + ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; + return Status; + } + } + + // + // If raw size is less then virt size, zero fill the remaining + // + + if (Size < Section->Misc.VirtualSize) { + ZeroMem (Base + Size, Section->Misc.VirtualSize - Size); + } + + // + // Next Section + // + Section += 1; + } + + // + // Get image's entry point + // + if (!(ImageContext->IsTeImage)) { + ImageContext->EntryPoint = (PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress ( + ImageContext, + PeHdr->OptionalHeader.AddressOfEntryPoint + ); + } else { + ImageContext->EntryPoint = (PHYSICAL_ADDRESS) ( + (UINTN)ImageContext->ImageAddress + + (UINTN)TeHdr->AddressOfEntryPoint + + (UINTN)sizeof(EFI_TE_IMAGE_HEADER) - + (UINTN) TeHdr->StrippedSize + ); + } + + // + // Determine the size of the fixup data + // + // Per the PE/COFF spec, you can't assume that a given data directory + // is present in the image. You have to check the NumberOfRvaAndSizes in + // the optional header to verify a desired directory entry is there. + // + if (!(ImageContext->IsTeImage)) { + if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { + DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) + &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]; + ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN); + } else { + ImageContext->FixupDataSize = 0; + } + } else { + DirectoryEntry = &TeHdr->DataDirectory[0]; + ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN); + } + // + // Consumer must allocate a buffer for the relocation fixup log. + // Only used for runtime drivers. + // + ImageContext->FixupData = NULL; + + // + // Load the Codeview info if present + // + if (ImageContext->DebugDirectoryEntryRva != 0) { + if (!(ImageContext->IsTeImage)) { + DebugEntry = PeCoffLoaderImageAddress ( + ImageContext, + ImageContext->DebugDirectoryEntryRva + ); + } else { + DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)( + ImageContext->ImageAddress + + ImageContext->DebugDirectoryEntryRva + + sizeof(EFI_TE_IMAGE_HEADER) - + TeHdr->StrippedSize + ); + } + + if (DebugEntry != NULL) { + TempDebugEntryRva = DebugEntry->RVA; + if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) { + Section--; + if ((UINTN) Section->SizeOfRawData < Section->Misc.VirtualSize) { + TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize; + } else { + TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData; + } + } + + if (TempDebugEntryRva != 0) { + if (!(ImageContext->IsTeImage)) { + ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva); + } else { + ImageContext->CodeView = (VOID *)( + (UINTN)ImageContext->ImageAddress + + (UINTN)TempDebugEntryRva + + (UINTN)sizeof(EFI_TE_IMAGE_HEADER) - + (UINTN) TeHdr->StrippedSize + ); + } + + if (ImageContext->CodeView == NULL) { + ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; + return RETURN_LOAD_ERROR; + } + + if (DebugEntry->RVA == 0) { + Size = DebugEntry->SizeOfData; + if (!(ImageContext->IsTeImage)) { + Status = ImageContext->ImageRead ( + ImageContext->Handle, + DebugEntry->FileOffset, + &Size, + ImageContext->CodeView + ); + } else { + Status = ImageContext->ImageRead ( + ImageContext->Handle, + DebugEntry->FileOffset + sizeof (EFI_TE_IMAGE_HEADER) - TeHdr->StrippedSize, + &Size, + ImageContext->CodeView + ); + // + // Should we apply fix up to this field according to the size difference between PE and TE? + // Because now we maintain TE header fields unfixed, this field will also remain as they are + // in original PE image. + // + } + + if (RETURN_ERROR (Status)) { + ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; + return RETURN_LOAD_ERROR; + } + + DebugEntry->RVA = TempDebugEntryRva; + } + + switch (*(UINT32 *) ImageContext->CodeView) { + case CODEVIEW_SIGNATURE_NB10: + ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY); + break; + + case CODEVIEW_SIGNATURE_RSDS: + ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY); + break; + + default: + break; + } + } + } + } + + return Status; +} diff --git a/Tools/CodeTools/Source/PeCoffLoader/Common/EfiImage.h b/Tools/CodeTools/Source/PeCoffLoader/Common/EfiImage.h new file mode 100644 index 0000000000..9528e6bff5 --- /dev/null +++ b/Tools/CodeTools/Source/PeCoffLoader/Common/EfiImage.h @@ -0,0 +1,701 @@ +/** @file + EFI image format for PE32+. Please note some data structures are different + for IA-32 and Itanium-based images, look for UINTN and the #ifdef EFI_IA64 + + @bug Fix text - doc as defined in MSFT EFI specification. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Module Name: EfiImage.h + +**/ + +#ifndef __EFI_IMAGE_H__ +#define __EFI_IMAGE_H__ + +// +// PE32+ Subsystem type for EFI images +// +#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION 10 +#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 +#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 +#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13 + +// +// BugBug: Need to get a real answer for this problem. This is not in the +// PE specification. +// +// A SAL runtime driver does not get fixed up when a transition to +// virtual mode is made. In all other cases it should be treated +// like a EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER image +// +#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13 + +// +// PE32+ Machine type for EFI images +// +#define IMAGE_FILE_MACHINE_I386 0x014c +#define IMAGE_FILE_MACHINE_IA64 0x0200 +#define IMAGE_FILE_MACHINE_EBC 0x0EBC +#define IMAGE_FILE_MACHINE_X64 0x8664 +// +// Support old names for backward compatible +// +#define EFI_IMAGE_MACHINE_IA32 IMAGE_FILE_MACHINE_I386 +#define EFI_IMAGE_MACHINE_IA64 IMAGE_FILE_MACHINE_IA64 +#define EFI_IMAGE_MACHINE_IPF IMAGE_FILE_MACHINE_IA64 +#define EFI_IMAGE_MACHINE_EBC IMAGE_FILE_MACHINE_EBC +#define EFI_IMAGE_MACHINE_X64 IMAGE_FILE_MACHINE_X64 + +#define EFI_IMAGE_DOS_SIGNATURE 0x5A4D // MZ +#define EFI_IMAGE_OS2_SIGNATURE 0x454E // NE +#define EFI_IMAGE_OS2_SIGNATURE_LE 0x454C // LE +#define EFI_IMAGE_NT_SIGNATURE 0x00004550 // PE00 +#define EFI_IMAGE_EDOS_SIGNATURE 0x44454550 // PEED + +/// +/// PE images can start with an optional DOS header, so if an image is run +/// under DOS it can print an error message. +/// +typedef struct { + UINT16 e_magic; // Magic number + UINT16 e_cblp; // Bytes on last page of file + UINT16 e_cp; // Pages in file + UINT16 e_crlc; // Relocations + UINT16 e_cparhdr; // Size of header in paragraphs + UINT16 e_minalloc; // Minimum extra paragraphs needed + UINT16 e_maxalloc; // Maximum extra paragraphs needed + UINT16 e_ss; // Initial (relative) SS value + UINT16 e_sp; // Initial SP value + UINT16 e_csum; // Checksum + UINT16 e_ip; // Initial IP value + UINT16 e_cs; // Initial (relative) CS value + UINT16 e_lfarlc; // File address of relocation table + UINT16 e_ovno; // Overlay number + UINT16 e_res[4]; // Reserved words + UINT16 e_oemid; // OEM identifier (for e_oeminfo) + UINT16 e_oeminfo; // OEM information; e_oemid specific + UINT16 e_res2[10]; // Reserved words + UINT32 e_lfanew; // File address of new exe header +} EFI_IMAGE_DOS_HEADER; + +/// +/// File header format. +/// +typedef struct { + UINT16 Machine; + UINT16 NumberOfSections; + UINT32 TimeDateStamp; + UINT32 PointerToSymbolTable; + UINT32 NumberOfSymbols; + UINT16 SizeOfOptionalHeader; + UINT16 Characteristics; +} EFI_IMAGE_FILE_HEADER; + +#define EFI_IMAGE_SIZEOF_FILE_HEADER 20 + +#define EFI_IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file. +#define EFI_IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references). +#define EFI_IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file. +#define EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file. +#define EFI_IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed. +#define EFI_IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine. +#define EFI_IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file +#define EFI_IMAGE_FILE_SYSTEM 0x1000 // System File. +#define EFI_IMAGE_FILE_DLL 0x2000 // File is a DLL. +#define EFI_IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed. +#define EFI_IMAGE_FILE_MACHINE_UNKNOWN 0 +#define EFI_IMAGE_FILE_MACHINE_I386 0x14c // Intel 386. +#define EFI_IMAGE_FILE_MACHINE_R3000 0x162 // MIPS* little-endian, 0540 big-endian +#define EFI_IMAGE_FILE_MACHINE_R4000 0x166 // MIPS* little-endian +#define EFI_IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP* +#define EFI_IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM* PowerPC Little-Endian +#define EFI_IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine +// +// * Other names and brands may be claimed as the property of others. +// + +/// +/// Directory format. +/// +typedef struct { + UINT32 VirtualAddress; + UINT32 Size; +} EFI_IMAGE_DATA_DIRECTORY; + +#define EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16 + +typedef struct { + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + UINT32 BaseOfData; + UINT32 BaseOfBss; + UINT32 GprMask; + UINT32 CprMask[4]; + UINT32 GpValue; +} EFI_IMAGE_ROM_OPTIONAL_HEADER; + +#define EFI_IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 +#define EFI_IMAGE_SIZEOF_ROM_OPTIONAL_HEADER sizeof (EFI_IMAGE_ROM_OPTIONAL_HEADER) + +typedef struct { + EFI_IMAGE_FILE_HEADER FileHeader; + EFI_IMAGE_ROM_OPTIONAL_HEADER OptionalHeader; +} EFI_IMAGE_ROM_HEADERS; + +/// +/// @attention +/// EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64 +/// are for use ONLY by tools. All proper EFI code MUST use +/// EFI_IMAGE_OPTIONAL_HEADER ONLY!!! +/// +#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b + +typedef struct { + // + // Standard fields. + // + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + UINT32 BaseOfData; + // + // NT additional fields. + // + UINT32 ImageBase; + UINT32 SectionAlignment; + UINT32 FileAlignment; + UINT16 MajorOperatingSystemVersion; + UINT16 MinorOperatingSystemVersion; + UINT16 MajorImageVersion; + UINT16 MinorImageVersion; + UINT16 MajorSubsystemVersion; + UINT16 MinorSubsystemVersion; + UINT32 Win32VersionValue; + UINT32 SizeOfImage; + UINT32 SizeOfHeaders; + UINT32 CheckSum; + UINT16 Subsystem; + UINT16 DllCharacteristics; + UINT32 SizeOfStackReserve; + UINT32 SizeOfStackCommit; + UINT32 SizeOfHeapReserve; + UINT32 SizeOfHeapCommit; + UINT32 LoaderFlags; + UINT32 NumberOfRvaAndSizes; + EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES]; +} EFI_IMAGE_OPTIONAL_HEADER32; + +/// +/// @attention +/// EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64 +/// are for use ONLY by tools. All proper EFI code MUST use +/// EFI_IMAGE_OPTIONAL_HEADER ONLY!!! +/// +#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b + +typedef struct { + // + // Standard fields. + // + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + // + // NT additional fields. + // + UINT64 ImageBase; + UINT32 SectionAlignment; + UINT32 FileAlignment; + UINT16 MajorOperatingSystemVersion; + UINT16 MinorOperatingSystemVersion; + UINT16 MajorImageVersion; + UINT16 MinorImageVersion; + UINT16 MajorSubsystemVersion; + UINT16 MinorSubsystemVersion; + UINT32 Win32VersionValue; + UINT32 SizeOfImage; + UINT32 SizeOfHeaders; + UINT32 CheckSum; + UINT16 Subsystem; + UINT16 DllCharacteristics; + UINT64 SizeOfStackReserve; + UINT64 SizeOfStackCommit; + UINT64 SizeOfHeapReserve; + UINT64 SizeOfHeapCommit; + UINT32 LoaderFlags; + UINT32 NumberOfRvaAndSizes; + EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES]; +} EFI_IMAGE_OPTIONAL_HEADER64; + +/// +/// @attention +/// EFI_IMAGE_NT_HEADERS32 and EFI_IMAGE_HEADERS64 are for use ONLY +/// by tools. All proper EFI code MUST use EFI_IMAGE_NT_HEADERS ONLY!!! +/// +typedef struct { + UINT32 Signature; + EFI_IMAGE_FILE_HEADER FileHeader; + EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader; +} EFI_IMAGE_NT_HEADERS32; + +#define EFI_IMAGE_SIZEOF_NT_OPTIONAL32_HEADER sizeof (EFI_IMAGE_NT_HEADERS32) + +typedef struct { + UINT32 Signature; + EFI_IMAGE_FILE_HEADER FileHeader; + EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader; +} EFI_IMAGE_NT_HEADERS64; + +#define EFI_IMAGE_SIZEOF_NT_OPTIONAL64_HEADER sizeof (EFI_IMAGE_NT_HEADERS64) + +// +// Processor specific definition of EFI_IMAGE_OPTIONAL_HEADER so the +// type name EFI_IMAGE_OPTIONAL_HEADER is appropriate to the build. Same for +// EFI_IMAGE_NT_HEADERS. These definitions MUST be used by ALL EFI code. +// +#if defined (MDE_CPU_IA32) && !defined (BUILDING_TOOLS) || \ + defined (BUILDING_TOOLS) && defined (TOOL_BUILD_IA32_TARGET) + +// typedef EFI_IMAGE_OPTIONAL_HEADER32 EFI_IMAGE_OPTIONAL_HEADER; +typedef EFI_IMAGE_NT_HEADERS32 EFI_IMAGE_NT_HEADERS; + +#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC +#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \ + (((Machine) == EFI_IMAGE_MACHINE_IA32) || ((Machine) == EFI_IMAGE_MACHINE_EBC)) + +#elif defined (MDE_CPU_IPF) && !defined (BUILDING_TOOLS) || \ + defined (BUILDING_TOOLS) && defined (TOOL_BUILD_IPF_TARGET) + +typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER; +typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS; + +#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC +#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \ + (((Machine) == EFI_IMAGE_MACHINE_IPF) || ((Machine) == EFI_IMAGE_MACHINE_EBC)) + +#elif defined (MDE_CPU_X64) && !defined (BUILDING_TOOLS) || \ + defined (BUILDING_TOOLS) && defined (TOOL_BUILD_X64_TARGET) + +typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER; +typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS; + +#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC +#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \ + (((Machine) == EFI_IMAGE_MACHINE_X64) || ((Machine) == EFI_IMAGE_MACHINE_EBC)) + +#elif defined (MDE_CPU_EBC) + +// +// This is just to make sure you can cross compile with the EBC compiiler. +// It does not make sense to have a PE loader coded in EBC. You need to +// understand the basic +// +typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER; +typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS; + +#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC +#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_EBC) + +#else +#error Unknown Processor Type +#endif + + +#define EFI_IMAGE_FIRST_SECTION(ntheader) \ + ( \ + (EFI_IMAGE_SECTION_HEADER *) \ + ( \ + (UINT32) ntheader + \ + FIELD_OFFSET (EFI_IMAGE_NT_HEADERS, OptionalHeader) + \ + ((EFI_IMAGE_NT_HEADERS *) (ntheader))->FileHeader.SizeOfOptionalHeader \ + ) \ + ) + +// +// Subsystem Values +// +#define EFI_IMAGE_SUBSYSTEM_UNKNOWN 0 +#define EFI_IMAGE_SUBSYSTEM_NATIVE 1 +#define EFI_IMAGE_SUBSYSTEM_WINDOWS_GUI 2 +#define EFI_IMAGE_SUBSYSTEM_WINDOWS_CUI 3. +#define EFI_IMAGE_SUBSYSTEM_OS2_CUI 5 +#define EFI_IMAGE_SUBSYSTEM_POSIX_CUI 7 + +// +// Directory Entries +// +#define EFI_IMAGE_DIRECTORY_ENTRY_EXPORT 0 +#define EFI_IMAGE_DIRECTORY_ENTRY_IMPORT 1 +#define EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE 2 +#define EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 +#define EFI_IMAGE_DIRECTORY_ENTRY_SECURITY 4 +#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC 5 +#define EFI_IMAGE_DIRECTORY_ENTRY_DEBUG 6 +#define EFI_IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 +#define EFI_IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 +#define EFI_IMAGE_DIRECTORY_ENTRY_TLS 9 +#define EFI_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 + +// +// Section header format. +// +#define EFI_IMAGE_SIZEOF_SHORT_NAME 8 + +typedef struct { + UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME]; + union { + UINT32 PhysicalAddress; + UINT32 VirtualSize; + } Misc; + UINT32 VirtualAddress; + UINT32 SizeOfRawData; + UINT32 PointerToRawData; + UINT32 PointerToRelocations; + UINT32 PointerToLinenumbers; + UINT16 NumberOfRelocations; + UINT16 NumberOfLinenumbers; + UINT32 Characteristics; +} EFI_IMAGE_SECTION_HEADER; + +#define EFI_IMAGE_SIZEOF_SECTION_HEADER 40 + +#define EFI_IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved. +#define EFI_IMAGE_SCN_CNT_CODE 0x00000020 +#define EFI_IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 +#define EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 + +#define EFI_IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved. +#define EFI_IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information. +#define EFI_IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image. +#define EFI_IMAGE_SCN_LNK_COMDAT 0x00001000 + +#define EFI_IMAGE_SCN_ALIGN_1BYTES 0x00100000 +#define EFI_IMAGE_SCN_ALIGN_2BYTES 0x00200000 +#define EFI_IMAGE_SCN_ALIGN_4BYTES 0x00300000 +#define EFI_IMAGE_SCN_ALIGN_8BYTES 0x00400000 +#define EFI_IMAGE_SCN_ALIGN_16BYTES 0x00500000 +#define EFI_IMAGE_SCN_ALIGN_32BYTES 0x00600000 +#define EFI_IMAGE_SCN_ALIGN_64BYTES 0x00700000 + +#define EFI_IMAGE_SCN_MEM_DISCARDABLE 0x02000000 +#define EFI_IMAGE_SCN_MEM_NOT_CACHED 0x04000000 +#define EFI_IMAGE_SCN_MEM_NOT_PAGED 0x08000000 +#define EFI_IMAGE_SCN_MEM_SHARED 0x10000000 +#define EFI_IMAGE_SCN_MEM_EXECUTE 0x20000000 +#define EFI_IMAGE_SCN_MEM_READ 0x40000000 +#define EFI_IMAGE_SCN_MEM_WRITE 0x80000000 + +/// +/// Symbol format. +/// +#define EFI_IMAGE_SIZEOF_SYMBOL 18 + +// +// Section values. +// +// Symbols have a section number of the section in which they are +// defined. Otherwise, section numbers have the following meanings: +// +#define EFI_IMAGE_SYM_UNDEFINED (UINT16) 0 // Symbol is undefined or is common. +#define EFI_IMAGE_SYM_ABSOLUTE (UINT16) -1 // Symbol is an absolute value. +#define EFI_IMAGE_SYM_DEBUG (UINT16) -2 // Symbol is a special debug item. +// +// Type (fundamental) values. +// +#define EFI_IMAGE_SYM_TYPE_NULL 0 // no type. +#define EFI_IMAGE_SYM_TYPE_VOID 1 // +#define EFI_IMAGE_SYM_TYPE_CHAR 2 // type character. +#define EFI_IMAGE_SYM_TYPE_SHORT 3 // type short integer. +#define EFI_IMAGE_SYM_TYPE_INT 4 +#define EFI_IMAGE_SYM_TYPE_LONG 5 +#define EFI_IMAGE_SYM_TYPE_FLOAT 6 +#define EFI_IMAGE_SYM_TYPE_DOUBLE 7 +#define EFI_IMAGE_SYM_TYPE_STRUCT 8 +#define EFI_IMAGE_SYM_TYPE_UNION 9 +#define EFI_IMAGE_SYM_TYPE_ENUM 10 // enumeration. +#define EFI_IMAGE_SYM_TYPE_MOE 11 // member of enumeration. +#define EFI_IMAGE_SYM_TYPE_BYTE 12 +#define EFI_IMAGE_SYM_TYPE_WORD 13 +#define EFI_IMAGE_SYM_TYPE_UINT 14 +#define EFI_IMAGE_SYM_TYPE_DWORD 15 + +// +// Type (derived) values. +// +#define EFI_IMAGE_SYM_DTYPE_NULL 0 // no derived type. +#define EFI_IMAGE_SYM_DTYPE_POINTER 1 +#define EFI_IMAGE_SYM_DTYPE_FUNCTION 2 +#define EFI_IMAGE_SYM_DTYPE_ARRAY 3 + +// +// Storage classes. +// +#define EFI_IMAGE_SYM_CLASS_END_OF_FUNCTION (UINT8) -1 +#define EFI_IMAGE_SYM_CLASS_NULL 0 +#define EFI_IMAGE_SYM_CLASS_AUTOMATIC 1 +#define EFI_IMAGE_SYM_CLASS_EXTERNAL 2 +#define EFI_IMAGE_SYM_CLASS_STATIC 3 +#define EFI_IMAGE_SYM_CLASS_REGISTER 4 +#define EFI_IMAGE_SYM_CLASS_EXTERNAL_DEF 5 +#define EFI_IMAGE_SYM_CLASS_LABEL 6 +#define EFI_IMAGE_SYM_CLASS_UNDEFINED_LABEL 7 +#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8 +#define EFI_IMAGE_SYM_CLASS_ARGUMENT 9 +#define EFI_IMAGE_SYM_CLASS_STRUCT_TAG 10 +#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_UNION 11 +#define EFI_IMAGE_SYM_CLASS_UNION_TAG 12 +#define EFI_IMAGE_SYM_CLASS_TYPE_DEFINITION 13 +#define EFI_IMAGE_SYM_CLASS_UNDEFINED_STATIC 14 +#define EFI_IMAGE_SYM_CLASS_ENUM_TAG 15 +#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16 +#define EFI_IMAGE_SYM_CLASS_REGISTER_PARAM 17 +#define EFI_IMAGE_SYM_CLASS_BIT_FIELD 18 +#define EFI_IMAGE_SYM_CLASS_BLOCK 100 +#define EFI_IMAGE_SYM_CLASS_FUNCTION 101 +#define EFI_IMAGE_SYM_CLASS_END_OF_STRUCT 102 +#define EFI_IMAGE_SYM_CLASS_FILE 103 +#define EFI_IMAGE_SYM_CLASS_SECTION 104 +#define EFI_IMAGE_SYM_CLASS_WEAK_EXTERNAL 105 + +// +// type packing constants +// +#define EFI_IMAGE_N_BTMASK 017 +#define EFI_IMAGE_N_TMASK 060 +#define EFI_IMAGE_N_TMASK1 0300 +#define EFI_IMAGE_N_TMASK2 0360 +#define EFI_IMAGE_N_BTSHFT 4 +#define EFI_IMAGE_N_TSHIFT 2 + +// +// Communal selection types. +// +#define EFI_IMAGE_COMDAT_SELECT_NODUPLICATES 1 +#define EFI_IMAGE_COMDAT_SELECT_ANY 2 +#define EFI_IMAGE_COMDAT_SELECT_SAME_SIZE 3 +#define EFI_IMAGE_COMDAT_SELECT_EXACT_MATCH 4 +#define EFI_IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 + +#define EFI_IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 +#define EFI_IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 +#define EFI_IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 + +/// +/// Relocation format. +/// +typedef struct { + UINT32 VirtualAddress; + UINT32 SymbolTableIndex; + UINT16 Type; +} EFI_IMAGE_RELOCATION; + +#define EFI_IMAGE_SIZEOF_RELOCATION 10 + +// +// I386 relocation types. +// +#define EFI_IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary +#define EFI_IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address +#define EFI_IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address +#define EFI_IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address +#define EFI_IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included +#define EFI_IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address +#define EFI_IMAGE_REL_I386_SECTION 012 +#define EFI_IMAGE_REL_I386_SECREL 013 +#define EFI_IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address + +/// +/// Based relocation format. +/// +typedef struct { + UINT32 VirtualAddress; + UINT32 SizeOfBlock; +} EFI_IMAGE_BASE_RELOCATION; + +#define EFI_IMAGE_SIZEOF_BASE_RELOCATION 8 + +// +// Based relocation types. +// +#define EFI_IMAGE_REL_BASED_ABSOLUTE 0 +#define EFI_IMAGE_REL_BASED_HIGH 1 +#define EFI_IMAGE_REL_BASED_LOW 2 +#define EFI_IMAGE_REL_BASED_HIGHLOW 3 +#define EFI_IMAGE_REL_BASED_HIGHADJ 4 +#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5 +#define EFI_IMAGE_REL_BASED_IA64_IMM64 9 +#define EFI_IMAGE_REL_BASED_DIR64 10 + +/// +/// Line number format. +/// +typedef struct { + union { + UINT32 SymbolTableIndex; // Symbol table index of function name if Linenumber is 0. + UINT32 VirtualAddress; // Virtual address of line number. + } Type; + UINT16 Linenumber; // Line number. +} EFI_IMAGE_LINENUMBER; + +#define EFI_IMAGE_SIZEOF_LINENUMBER 6 + +// +// Archive format. +// +#define EFI_IMAGE_ARCHIVE_START_SIZE 8 +#define EFI_IMAGE_ARCHIVE_START "!\n" +#define EFI_IMAGE_ARCHIVE_END "`\n" +#define EFI_IMAGE_ARCHIVE_PAD "\n" +#define EFI_IMAGE_ARCHIVE_LINKER_MEMBER "/ " +#define EFI_IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " + +typedef struct { + UINT8 Name[16]; // File member name - `/' terminated. + UINT8 Date[12]; // File member date - decimal. + UINT8 UserID[6]; // File member user id - decimal. + UINT8 GroupID[6]; // File member group id - decimal. + UINT8 Mode[8]; // File member mode - octal. + UINT8 Size[10]; // File member size - decimal. + UINT8 EndHeader[2]; // String to end header. +} EFI_IMAGE_ARCHIVE_MEMBER_HEADER; + +#define EFI_IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 + +// +// DLL support. +// + +/// +/// DLL Export Format +/// +typedef struct { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT16 MajorVersion; + UINT16 MinorVersion; + UINT32 Name; + UINT32 Base; + UINT32 NumberOfFunctions; + UINT32 NumberOfNames; + UINT32 AddressOfFunctions; + UINT32 AddressOfNames; + UINT32 AddressOfNameOrdinals; +} EFI_IMAGE_EXPORT_DIRECTORY; + +/// +/// DLL support. +/// Import Format +/// +typedef struct { + UINT16 Hint; + UINT8 Name[1]; +} EFI_IMAGE_IMPORT_BY_NAME; + +typedef struct { + union { + UINT32 Function; + UINT32 Ordinal; + EFI_IMAGE_IMPORT_BY_NAME *AddressOfData; + } u1; +} EFI_IMAGE_THUNK_DATA; + +#define EFI_IMAGE_ORDINAL_FLAG 0x80000000 +#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0) +#define EFI_IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) + +typedef struct { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT32 ForwarderChain; + UINT32 Name; + EFI_IMAGE_THUNK_DATA *FirstThunk; +} EFI_IMAGE_IMPORT_DESCRIPTOR; + +/// +/// Debug Format +/// +#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2 + +typedef struct { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT16 MajorVersion; + UINT16 MinorVersion; + UINT32 Type; + UINT32 SizeOfData; + UINT32 RVA; + UINT32 FileOffset; +} EFI_IMAGE_DEBUG_DIRECTORY_ENTRY; + +#define CODEVIEW_SIGNATURE_NB10 0x3031424E // "NB10" +typedef struct { + UINT32 Signature; // "NB10" + UINT32 Unknown; + UINT32 Unknown2; + UINT32 Unknown3; + // + // Filename of .PDB goes here + // +} EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY; + +#define CODEVIEW_SIGNATURE_RSDS 0x53445352 // "RSDS" +typedef struct { + UINT32 Signature; // "RSDS" + UINT32 Unknown; + UINT32 Unknown2; + UINT32 Unknown3; + UINT32 Unknown4; + UINT32 Unknown5; + // + // Filename of .PDB goes here + // +} EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY; + +/// +/// Header format for TE images +/// +typedef struct { + UINT16 Signature; // signature for TE format = "VZ" + UINT16 Machine; // from the original file header + UINT8 NumberOfSections; // from the original file header + UINT8 Subsystem; // from original optional header + UINT16 StrippedSize; // how many bytes we removed from the header + UINT32 AddressOfEntryPoint; // offset to entry point -- from original optional header + UINT32 BaseOfCode; // from original image -- required for ITP debug + UINT64 ImageBase; // from original file header + EFI_IMAGE_DATA_DIRECTORY DataDirectory[2]; // only base relocation and debug directory +} EFI_TE_IMAGE_HEADER; + +#define EFI_TE_IMAGE_HEADER_SIGNATURE 0x5A56 // "VZ" + +// +// Data directory indexes in our TE image header +// +#define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC 0 +#define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG 1 + +#endif diff --git a/Tools/CodeTools/Source/PeCoffLoader/Ia32/PeCoffLoaderEx.c b/Tools/CodeTools/Source/PeCoffLoader/Ia32/PeCoffLoaderEx.c new file mode 100644 index 0000000000..f58e8d0364 --- /dev/null +++ b/Tools/CodeTools/Source/PeCoffLoader/Ia32/PeCoffLoaderEx.c @@ -0,0 +1,56 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PeCoffLoaderEx.c + +Abstract: + + IA-32 Specific relocation fixups + +Revision History + +--*/ + +#include + +RETURN_STATUS +PeCoffLoaderRelocateImageEx ( + IN UINT16 *Reloc, + IN OUT CHAR8 *Fixup, + IN OUT CHAR8 **FixupData, + IN UINT64 Adjust + ) +/*++ + +Routine Description: + + Performs an IA-32 specific relocation fixup + +Arguments: + + Reloc - Pointer to the relocation record + + Fixup - Pointer to the address to fix up + + FixupData - Pointer to a buffer to log the fixups + + Adjust - The offset to adjust the fixup + +Returns: + + EFI_UNSUPPORTED - Unsupported now + +--*/ +{ + return RETURN_UNSUPPORTED; +} diff --git a/Tools/CodeTools/Source/PeCoffLoader/Ipf/PeCoffLoaderEx.c b/Tools/CodeTools/Source/PeCoffLoader/Ipf/PeCoffLoaderEx.c new file mode 100644 index 0000000000..3f3989908d --- /dev/null +++ b/Tools/CodeTools/Source/PeCoffLoader/Ipf/PeCoffLoaderEx.c @@ -0,0 +1,249 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PeCoffLoaderEx.c + +Abstract: + + Fixes Intel Itanium(TM) specific relocation types + + +Revision History + +--*/ + +#include +#include +#include + + + + + +#define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \ + Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos) + +#define INS_IMM64(Value, Address, Size, InstPos, ValPos) \ + *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \ + ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos) + +#define IMM64_IMM7B_INST_WORD_X 3 +#define IMM64_IMM7B_SIZE_X 7 +#define IMM64_IMM7B_INST_WORD_POS_X 4 +#define IMM64_IMM7B_VAL_POS_X 0 + +#define IMM64_IMM9D_INST_WORD_X 3 +#define IMM64_IMM9D_SIZE_X 9 +#define IMM64_IMM9D_INST_WORD_POS_X 18 +#define IMM64_IMM9D_VAL_POS_X 7 + +#define IMM64_IMM5C_INST_WORD_X 3 +#define IMM64_IMM5C_SIZE_X 5 +#define IMM64_IMM5C_INST_WORD_POS_X 13 +#define IMM64_IMM5C_VAL_POS_X 16 + +#define IMM64_IC_INST_WORD_X 3 +#define IMM64_IC_SIZE_X 1 +#define IMM64_IC_INST_WORD_POS_X 12 +#define IMM64_IC_VAL_POS_X 21 + +#define IMM64_IMM41a_INST_WORD_X 1 +#define IMM64_IMM41a_SIZE_X 10 +#define IMM64_IMM41a_INST_WORD_POS_X 14 +#define IMM64_IMM41a_VAL_POS_X 22 + +#define IMM64_IMM41b_INST_WORD_X 1 +#define IMM64_IMM41b_SIZE_X 8 +#define IMM64_IMM41b_INST_WORD_POS_X 24 +#define IMM64_IMM41b_VAL_POS_X 32 + +#define IMM64_IMM41c_INST_WORD_X 2 +#define IMM64_IMM41c_SIZE_X 23 +#define IMM64_IMM41c_INST_WORD_POS_X 0 +#define IMM64_IMM41c_VAL_POS_X 40 + +#define IMM64_SIGN_INST_WORD_X 3 +#define IMM64_SIGN_SIZE_X 1 +#define IMM64_SIGN_INST_WORD_POS_X 27 +#define IMM64_SIGN_VAL_POS_X 63 + +RETURN_STATUS +PeCoffLoaderRelocateImageEx ( + IN UINT16 *Reloc, + IN OUT CHAR8 *Fixup, + IN OUT CHAR8 **FixupData, + IN UINT64 Adjust + ) +/*++ + +Routine Description: + + Performs an Itanium-based specific relocation fixup + +Arguments: + + Reloc - Pointer to the relocation record + + Fixup - Pointer to the address to fix up + + FixupData - Pointer to a buffer to log the fixups + + Adjust - The offset to adjust the fixup + +Returns: + + Status code + +--*/ +{ + UINT64 *F64; + UINT64 FixupVal; + + switch ((*Reloc) >> 12) { + + case EFI_IMAGE_REL_BASED_DIR64: + F64 = (UINT64 *) Fixup; + *F64 = *F64 + (UINT64) Adjust; + if (*FixupData != NULL) { + *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64)); + *(UINT64 *)(*FixupData) = *F64; + *FixupData = *FixupData + sizeof(UINT64); + } + break; + + case EFI_IMAGE_REL_BASED_IA64_IMM64: + + // + // Align it to bundle address before fixing up the + // 64-bit immediate value of the movl instruction. + // + + Fixup = (CHAR8 *)((UINTN) Fixup & (UINTN) ~(15)); + FixupVal = (UINT64)0; + + // + // Extract the lower 32 bits of IMM64 from bundle + // + EXT_IMM64(FixupVal, + (UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X, + IMM64_IMM7B_SIZE_X, + IMM64_IMM7B_INST_WORD_POS_X, + IMM64_IMM7B_VAL_POS_X + ); + + EXT_IMM64(FixupVal, + (UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X, + IMM64_IMM9D_SIZE_X, + IMM64_IMM9D_INST_WORD_POS_X, + IMM64_IMM9D_VAL_POS_X + ); + + EXT_IMM64(FixupVal, + (UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X, + IMM64_IMM5C_SIZE_X, + IMM64_IMM5C_INST_WORD_POS_X, + IMM64_IMM5C_VAL_POS_X + ); + + EXT_IMM64(FixupVal, + (UINT32 *)Fixup + IMM64_IC_INST_WORD_X, + IMM64_IC_SIZE_X, + IMM64_IC_INST_WORD_POS_X, + IMM64_IC_VAL_POS_X + ); + + EXT_IMM64(FixupVal, + (UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X, + IMM64_IMM41a_SIZE_X, + IMM64_IMM41a_INST_WORD_POS_X, + IMM64_IMM41a_VAL_POS_X + ); + + // + // Update 64-bit address + // + FixupVal += Adjust; + + // + // Insert IMM64 into bundle + // + INS_IMM64(FixupVal, + ((UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X), + IMM64_IMM7B_SIZE_X, + IMM64_IMM7B_INST_WORD_POS_X, + IMM64_IMM7B_VAL_POS_X + ); + + INS_IMM64(FixupVal, + ((UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X), + IMM64_IMM9D_SIZE_X, + IMM64_IMM9D_INST_WORD_POS_X, + IMM64_IMM9D_VAL_POS_X + ); + + INS_IMM64(FixupVal, + ((UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X), + IMM64_IMM5C_SIZE_X, + IMM64_IMM5C_INST_WORD_POS_X, + IMM64_IMM5C_VAL_POS_X + ); + + INS_IMM64(FixupVal, + ((UINT32 *)Fixup + IMM64_IC_INST_WORD_X), + IMM64_IC_SIZE_X, + IMM64_IC_INST_WORD_POS_X, + IMM64_IC_VAL_POS_X + ); + + INS_IMM64(FixupVal, + ((UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X), + IMM64_IMM41a_SIZE_X, + IMM64_IMM41a_INST_WORD_POS_X, + IMM64_IMM41a_VAL_POS_X + ); + + INS_IMM64(FixupVal, + ((UINT32 *)Fixup + IMM64_IMM41b_INST_WORD_X), + IMM64_IMM41b_SIZE_X, + IMM64_IMM41b_INST_WORD_POS_X, + IMM64_IMM41b_VAL_POS_X + ); + + INS_IMM64(FixupVal, + ((UINT32 *)Fixup + IMM64_IMM41c_INST_WORD_X), + IMM64_IMM41c_SIZE_X, + IMM64_IMM41c_INST_WORD_POS_X, + IMM64_IMM41c_VAL_POS_X + ); + + INS_IMM64(FixupVal, + ((UINT32 *)Fixup + IMM64_SIGN_INST_WORD_X), + IMM64_SIGN_SIZE_X, + IMM64_SIGN_INST_WORD_POS_X, + IMM64_SIGN_VAL_POS_X + ); + + F64 = (UINT64 *) Fixup; + if (*FixupData != NULL) { + *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64)); + *(UINT64 *)(*FixupData) = *F64; + *FixupData = *FixupData + sizeof(UINT64); + } + break; + + default: + return RETURN_UNSUPPORTED; + } + + return RETURN_SUCCESS; +} diff --git a/Tools/CodeTools/Source/PeCoffLoader/X64/PeCoffLoaderEx.c b/Tools/CodeTools/Source/PeCoffLoader/X64/PeCoffLoaderEx.c new file mode 100644 index 0000000000..1e6cc34745 --- /dev/null +++ b/Tools/CodeTools/Source/PeCoffLoader/X64/PeCoffLoaderEx.c @@ -0,0 +1,74 @@ +/*++ + +Copyright 2005, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +Module Name: + + PeCoffLoaderEx.c + +Abstract: + + x64 Specific relocation fixups + +Revision History + +--*/ + +#include +#include +#include + + + + +RETURN_STATUS +PeCoffLoaderRelocateImageEx ( + IN UINT16 *Reloc, + IN OUT CHAR8 *Fixup, + IN OUT CHAR8 **FixupData, + IN UINT64 Adjust + ) +/*++ + +Routine Description: + Performs an x64 specific relocation fixup + +Arguments: + Reloc - Pointer to the relocation record + Fixup - Pointer to the address to fix up + FixupData - Pointer to a buffer to log the fixups + Adjust - The offset to adjust the fixup + +Returns: + None + +--*/ +{ + UINT64 *F64; + + switch ((*Reloc) >> 12) { + + case EFI_IMAGE_REL_BASED_DIR64: + F64 = (UINT64 *) Fixup; + *F64 = *F64 + (UINT64) Adjust; + if (*FixupData != NULL) { + *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64)); + *(UINT64 *)(*FixupData) = *F64; + *FixupData = *FixupData + sizeof(UINT64); + } + break; + + default: + return RETURN_UNSUPPORTED; + } + + return RETURN_SUCCESS; +} diff --git a/Tools/CodeTools/Source/PeCoffLoader/build.xml b/Tools/CodeTools/Source/PeCoffLoader/build.xml new file mode 100644 index 0000000000..db37829840 --- /dev/null +++ b/Tools/CodeTools/Source/PeCoffLoader/build.xml @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/PeiRebase/PeiRebaseExe.c b/Tools/CodeTools/Source/PeiRebase/PeiRebaseExe.c new file mode 100644 index 0000000000..27c646e486 --- /dev/null +++ b/Tools/CodeTools/Source/PeiRebase/PeiRebaseExe.c @@ -0,0 +1,1059 @@ +/*++ + +Copyright (c) 1999-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +Module Name: + + PeiRebaseExe.c + +Abstract: + + This contains all code necessary to build the PeiRebase.exe utility. + This utility relies heavily on the PeiRebase DLL. Definitions for both + can be found in the PEI Rebase Utility Specification, review draft. + +--*/ + +#include +#include +#include + +#include +#include +#include +#include + +#include "CommonLib.h" +#include "ParseInf.h" +#include "FvLib.h" +#include "EfiUtilityMsgs.h" +#include "PeiRebaseExe.h" + +EFI_STATUS +ReadHeader ( + IN FILE *InputFile, + OUT UINT32 *FvSize, + OUT BOOLEAN *ErasePolarity + ); + +int +main ( + int argc, + char **argv + ) +/*++ + +Routine Description: + + This utility relocates PEI XIP PE32s in a FV. + +Arguments: + + argc - Number of command line arguments + argv[]: + BaseAddress The base address to use for rebasing the FV. The correct + format is a hex number preceded by 0x. + InputFileName The name of the input FV file. + OutputFileName The name of the output FV file. + MapFileName The name of the map file of relocation info. + + Arguments come in pair in any order. + -I InputFileName + -O OutputFileName + -B BaseAddress + -M MapFileName + +Returns: + + 0 No error conditions detected. + 1 One or more of the input parameters is invalid. + 2 A resource required by the utility was unavailable. + Most commonly this will be memory allocation or file creation. + 3 PeiRebase.dll could not be loaded. + 4 Error executing the PEI rebase. + +--*/ +{ + UINT8 Index; + CHAR8 InputFileName[_MAX_PATH]; + CHAR8 OutputFileName[_MAX_PATH]; + CHAR8 MapFileName[_MAX_PATH]; + EFI_PHYSICAL_ADDRESS BaseAddress; + BOOLEAN BaseAddressSet; + EFI_STATUS Status; + FILE *InputFile; + FILE *OutputFile; + FILE *MapFile; + UINT64 FvOffset; + UINT32 FileCount; + int BytesRead; + EFI_FIRMWARE_VOLUME_HEADER *FvImage; + UINT32 FvSize; + EFI_FFS_FILE_HEADER *CurrentFile; + BOOLEAN ErasePolarity; + EFI_PHYSICAL_ADDRESS CurrentFileBaseAddress; + + ErasePolarity = FALSE; + // + // Set utility name for error/warning reporting purposes. + // + SetUtilityName (UTILITY_NAME); + // + // Verify the correct number of arguments + // + if (argc != MAX_ARGS) { + PrintUsage (); + return STATUS_ERROR; + } + + // + // Initialize variables + // + InputFileName[0] = 0; + OutputFileName[0] = 0; + MapFileName[0] = 0; + BaseAddress = 0; + BaseAddressSet = FALSE; + FvOffset = 0; + FileCount = 0; + ErasePolarity = FALSE; + InputFile = NULL; + OutputFile = NULL; + MapFile = NULL; + FvImage = NULL; + + // + // Parse the command line arguments + // + for (Index = 1; Index < MAX_ARGS; Index += 2) { + // + // Make sure argument pair begin with - or / + // + if (argv[Index][0] != '-' && argv[Index][0] != '/') { + PrintUsage (); + Error (NULL, 0, 0, argv[Index], "unrecognized option"); + return STATUS_ERROR; + } + // + // Make sure argument specifier is only one letter + // + if (argv[Index][2] != 0) { + PrintUsage (); + Error (NULL, 0, 0, argv[Index], "unrecognized option"); + return STATUS_ERROR; + } + // + // Determine argument to read + // + switch (argv[Index][1]) { + case 'I': + case 'i': + if (strlen (InputFileName) == 0) { + strcpy (InputFileName, argv[Index + 1]); + } else { + PrintUsage (); + Error (NULL, 0, 0, argv[Index + 1], "only one -i InputFileName may be specified"); + return STATUS_ERROR; + } + break; + + case 'O': + case 'o': + if (strlen (OutputFileName) == 0) { + strcpy (OutputFileName, argv[Index + 1]); + } else { + PrintUsage (); + Error (NULL, 0, 0, argv[Index + 1], "only one -o OutputFileName may be specified"); + return STATUS_ERROR; + } + break; + + case 'B': + case 'b': + if (!BaseAddressSet) { + Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &BaseAddress); + if (EFI_ERROR (Status)) { + PrintUsage (); + Error (NULL, 0, 0, argv[Index + 1], "invalid hex digit given for the base address"); + return STATUS_ERROR; + } + + BaseAddressSet = TRUE; + } else { + PrintUsage (); + Error (NULL, 0, 0, argv[Index + 1], "-b BaseAddress may only be specified once"); + return STATUS_ERROR; + } + break; + + case 'M': + case 'm': + if (strlen (MapFileName) == 0) { + strcpy (MapFileName, argv[Index + 1]); + } else { + PrintUsage (); + Error (NULL, 0, 0, argv[Index + 1], "only one -m MapFileName may be specified"); + return STATUS_ERROR; + } + break; + + default: + PrintUsage (); + Error (NULL, 0, 0, argv[Index], "unrecognized argument"); + return STATUS_ERROR; + break; + } + } + + // + // Create the Map file if we need it + // + if (strlen (MapFileName) != 0) { + MapFile = fopen (MapFileName, "w"); + if (MapFile == NULL) { + Error (NULL, 0, 0, MapFileName, "failed to open map file"); + goto Finish; + } + } + + // + // Open the file containing the FV + // + InputFile = fopen (InputFileName, "rb"); + if (InputFile == NULL) { + Error (NULL, 0, 0, InputFileName, "could not open input file for reading"); + return STATUS_ERROR; + } + // + // Determine size of FV + // + Status = ReadHeader (InputFile, &FvSize, &ErasePolarity); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "could not parse the FV header", NULL); + goto Finish; + } + // + // Allocate a buffer for the FV image + // + FvImage = malloc (FvSize); + if (FvImage == NULL) { + Error (NULL, 0, 0, "application error", "memory allocation failed"); + goto Finish; + } + // + // Read the entire FV to the buffer + // + BytesRead = fread (FvImage, 1, FvSize, InputFile); + fclose (InputFile); + InputFile = NULL; + if ((unsigned int) BytesRead != FvSize) { + Error (NULL, 0, 0, InputFileName, "failed to read from file"); + goto Finish; + } + // + // Prepare to walk the FV image + // + InitializeFvLib (FvImage, FvSize); + // + // Get the first file + // + Status = GetNextFile (NULL, &CurrentFile); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "cannot find the first file in the FV image", NULL); + goto Finish; + } + // + // Check if each file should be rebased + // + while (CurrentFile != NULL) { + // + // Rebase this file + // + CurrentFileBaseAddress = BaseAddress + ((UINTN) CurrentFile - (UINTN) FvImage); + Status = FfsRebase (CurrentFile, CurrentFileBaseAddress, MapFile); + + if (EFI_ERROR (Status)) { + switch (Status) { + + case EFI_INVALID_PARAMETER: + Error (NULL, 0, 0, "invalid parameter passed to FfsRebase", NULL); + break; + + case EFI_ABORTED: + Error (NULL, 0, 0, "error detected while rebasing -- aborted", NULL); + break; + + case EFI_OUT_OF_RESOURCES: + Error (NULL, 0, 0, "FfsRebase could not allocate required resources", NULL); + break; + + case EFI_NOT_FOUND: + Error (NULL, 0, 0, "FfsRebase could not locate a PE32 section", NULL); + break; + + default: + Error (NULL, 0, 0, "FfsRebase returned unknown status", "status=0x%08X", Status); + break; + } + + goto Finish; + } + + // + // Get the next file + // + Status = GetNextFile (CurrentFile, &CurrentFile); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "cannot find the next file in the FV image", NULL); + goto Finish; + } + } + // + // Open the output file + // + OutputFile = fopen (OutputFileName, "wb"); + if (OutputFile == NULL) { + Error (NULL, 0, 0, OutputFileName, "failed to open output file"); + goto Finish; + } + + if (fwrite (FvImage, 1, FvSize, OutputFile) != FvSize) { + Error (NULL, 0, 0, "failed to write to output file", 0); + goto Finish; + } + +Finish: + if (InputFile != NULL) { + fclose (InputFile); + } + // + // If we created an output file, and there was an error, remove it so + // subsequent builds will rebuild it. + // + if (OutputFile != NULL) { + if (GetUtilityStatus () == STATUS_ERROR) { + remove (OutputFileName); + } + + fclose (OutputFile); + } + + if (MapFile != NULL) { + fclose (MapFile); + } + + if (FvImage != NULL) { + free (FvImage); + } + + return GetUtilityStatus (); +} + +EFI_STATUS +ReadHeader ( + IN FILE *InputFile, + OUT UINT32 *FvSize, + OUT BOOLEAN *ErasePolarity + ) +/*++ + +Routine Description: + + This function determines the size of the FV and the erase polarity. The + erase polarity is the FALSE value for file state. + +Arguments: + + InputFile The file that contains the FV image. + FvSize The size of the FV. + ErasePolarity The FV erase polarity. + +Returns: + + EFI_SUCCESS Function completed successfully. + EFI_INVALID_PARAMETER A required parameter was NULL or is out of range. + EFI_ABORTED The function encountered an error. + +--*/ +{ + EFI_FIRMWARE_VOLUME_HEADER VolumeHeader; + EFI_FV_BLOCK_MAP_ENTRY BlockMap; + UINTN Signature[2]; + UINTN BytesRead; + UINT32 Size; + + BytesRead = 0; + Size = 0; + // + // Check input parameters + // + if ((InputFile == NULL) || (FvSize == NULL) || (ErasePolarity == NULL)) { + Error (NULL, 0, 0, "ReadHeader()", "invalid input parameter"); + return EFI_INVALID_PARAMETER; + } + // + // Read the header + // + fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile); + BytesRead = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY); + Signature[0] = VolumeHeader.Signature; + Signature[1] = 0; + + // + // Get erase polarity + // + if (VolumeHeader.Attributes & EFI_FVB_ERASE_POLARITY) { + *ErasePolarity = TRUE; + } + + do { + fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile); + BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY); + + if (BlockMap.NumBlocks != 0) { + Size += BlockMap.NumBlocks * BlockMap.BlockLength; + } + + } while (!(BlockMap.NumBlocks == 0 && BlockMap.BlockLength == 0)); + + if (VolumeHeader.FvLength != Size) { + Error (NULL, 0, 0, "volume size not consistant with block maps", NULL); + return EFI_ABORTED; + } + + *FvSize = Size; + + rewind (InputFile); + + return EFI_SUCCESS; +} + +VOID +PrintUtilityInfo ( + VOID + ) +/*++ + +Routine Description: + + Displays the standard utility information to SDTOUT + +Arguments: + + None + +Returns: + + None + +--*/ +{ + printf ( + "%s, PEI Rebase Utility. Version %i.%i, %s.\n\n", + UTILITY_NAME, + UTILITY_MAJOR_VERSION, + UTILITY_MINOR_VERSION, + UTILITY_DATE + ); +} + +VOID +PrintUsage ( + VOID + ) +/*++ + +Routine Description: + + Displays the utility usage syntax to STDOUT + +Arguments: + + None + +Returns: + + None + +--*/ +{ + printf ( + "Usage: %s -I InputFileName -O OutputFileName -B BaseAddress [-M MapFile]\n", + UTILITY_NAME + ); + printf (" Where:\n"); + printf (" InputFileName is the name of the EFI FV file to rebase.\n"); + printf (" OutputFileName is the desired output file name.\n"); + printf (" BaseAddress is the FV base address to rebase agains.\n"); + printf (" MapFileName is an optional map file of the relocations\n"); + printf (" Argument pair may be in any order.\n\n"); +} + +EFI_STATUS +FfsRebase ( + IN OUT EFI_FFS_FILE_HEADER *FfsFile, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN FILE *MapFile OPTIONAL + ) +/*++ + +Routine Description: + + This function determines if a file is XIP and should be rebased. It will + rebase any PE32 sections found in the file using the base address. + +Arguments: + + FfsFile A pointer to Ffs file image. + BaseAddress The base address to use for rebasing the file image. + MapFile Optional file to dump relocation information into + +Returns: + + EFI_SUCCESS The image was properly rebased. + EFI_INVALID_PARAMETER An input parameter is invalid. + EFI_ABORTED An error occurred while rebasing the input file image. + EFI_OUT_OF_RESOURCES Could not allocate a required resource. + EFI_NOT_FOUND No compressed sections could be found. + +--*/ +{ + EFI_STATUS Status; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + UINTN MemoryImagePointer; + UINTN MemoryImagePointerAligned; + EFI_PHYSICAL_ADDRESS ImageAddress; + UINT64 ImageSize; + EFI_PHYSICAL_ADDRESS EntryPoint; + UINT32 Pe32ImageSize; + UINT32 NewPe32BaseAddress; + UINTN Index; + EFI_FILE_SECTION_POINTER CurrentPe32Section; + EFI_FFS_FILE_STATE SavedState; + EFI_IMAGE_NT_HEADERS *PeHdr; + UINT32 *PeHdrSizeOfImage; + UINT32 *PeHdrChecksum; + UINT32 FoundCount; + EFI_TE_IMAGE_HEADER *TEImageHeader; + UINT8 *TEBuffer; + EFI_IMAGE_DOS_HEADER *DosHeader; + UINT8 FileGuidString[80]; + UINT32 TailSize; + EFI_FFS_FILE_TAIL TailValue; + + // + // Verify input parameters + // + if (FfsFile == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Convert the GUID to a string so we can at least report which file + // if we find an error. + // + PrintGuidToBuffer (&FfsFile->Name, FileGuidString, sizeof (FileGuidString), TRUE); + if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) { + TailSize = sizeof (EFI_FFS_FILE_TAIL); + } else { + TailSize = 0; + } + + // + // Do some cursory checks on the FFS file contents + // + Status = VerifyFfsFile (FfsFile); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "file does not appear to be a valid FFS file, cannot be rebased", FileGuidString); + return EFI_INVALID_PARAMETER; + } + + memset (&ImageContext, 0, sizeof (ImageContext)); + + // + // Check if XIP file type. If not XIP, don't rebase. + // + if (FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE && + FfsFile->Type != EFI_FV_FILETYPE_PEIM && + FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE && + FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER + ) { + return EFI_SUCCESS; + } + + // + // Rebase each PE32 section + // + Status = EFI_SUCCESS; + FoundCount = 0; + for (Index = 1;; Index++) { + Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section); + if (EFI_ERROR (Status)) { + break; + } + + FoundCount++; + + // + // Calculate the PE32 base address, the FFS file base plus the offset of the PE32 section + // + NewPe32BaseAddress = ((UINT32) BaseAddress) + ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER) - (UINTN) FfsFile); + + // + // Initialize context + // + memset (&ImageContext, 0, sizeof (ImageContext)); + ImageContext.Handle = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION)); + ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead; + + Status = PeCoffLoaderGetImageInfo (&ImageContext); + + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "GetImageInfo() call failed on rebase", FileGuidString); + return Status; + } + // + // Allocate a buffer for the image to be loaded into. + // + Pe32ImageSize = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION); + MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x1000)); + if (MemoryImagePointer == 0) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + return EFI_OUT_OF_RESOURCES; + } + memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000); + MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12); + + + ImageContext.ImageAddress = MemoryImagePointerAligned; + + Status = PeCoffLoaderLoadImage (&ImageContext); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "LoadImage() call failed on rebase", FileGuidString); + free ((VOID *) MemoryImagePointer); + return Status; + } + + ImageContext.DestinationAddress = NewPe32BaseAddress; + Status = PeCoffLoaderRelocateImage (&ImageContext); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "RelocateImage() call failed on rebase", FileGuidString); + free ((VOID *) MemoryImagePointer); + return Status; + } + + ImageAddress = ImageContext.ImageAddress; + ImageSize = ImageContext.ImageSize; + EntryPoint = ImageContext.EntryPoint; + + if (ImageSize > Pe32ImageSize) { + Error ( + NULL, + 0, + 0, + "rebased image is larger than original PE32 image", + "0x%X > 0x%X, file %s", + ImageSize, + Pe32ImageSize, + FileGuidString + ); + free ((VOID *) MemoryImagePointer); + return EFI_ABORTED; + } + // + // Since we may have updated the Codeview RVA, we need to insure the PE + // header indicates the image is large enough to contain the Codeview data + // so it will be loaded properly later if the PEIM is reloaded into memory... + // + PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset); + if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) { + PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage); + PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum); + } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) { + PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage); + PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum); + } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) { + PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage); + PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum); + } else { + Error ( + NULL, + 0, + 0, + "unknown machine type in PE32 image", + "machine type=0x%X, file=%s", + (UINT32) PeHdr->FileHeader.Machine, + FileGuidString + ); + free ((VOID *) MemoryImagePointer); + return EFI_ABORTED; + } + + if (*PeHdrSizeOfImage != ImageContext.ImageSize) { + *PeHdrSizeOfImage = (UINT32) ImageContext.ImageSize; + if (*PeHdrChecksum) { + *PeHdrChecksum = 0; + } + } + + memcpy (CurrentPe32Section.Pe32Section + 1, (VOID *) MemoryImagePointerAligned, (UINT32) ImageSize); + + // + // Get EntryPoint in Flash Region. + // + EntryPoint = NewPe32BaseAddress + EntryPoint - ImageAddress; + + // + // If a map file was selected output mapping information for any file that + // was rebased. + // + if (MapFile != NULL) { + fprintf (MapFile, "PE32 File: %s Base:%08lx", FileGuidString, BaseAddress); + fprintf (MapFile, " EntryPoint:%08lx", EntryPoint); + if (ImageContext.PdbPointer != NULL) { + fprintf (MapFile, " FileName: %s", ImageContext.PdbPointer); + } + fprintf (MapFile, "\n"); + } + + free ((VOID *) MemoryImagePointer); + + // + // Now update file checksum + // + if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) { + TailSize = sizeof (EFI_FFS_FILE_TAIL); + } else { + TailSize = 0; + } + + if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) { + SavedState = FfsFile->State; + FfsFile->IntegrityCheck.Checksum.File = 0; + FfsFile->State = 0; + if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) { + FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ( + (UINT8 *) FfsFile, + GetLength (FfsFile->Size) - TailSize + ); + } else { + FfsFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; + } + + FfsFile->State = SavedState; + } + // + // Update tail if present + // + if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) { + TailValue = (EFI_FFS_FILE_TAIL) (~(FfsFile->IntegrityCheck.TailReference)); + *(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue; + } + } + // + // Now process TE sections + // + for (Index = 1;; Index++) { + Status = GetSectionByType (FfsFile, EFI_SECTION_TE, Index, &CurrentPe32Section); + if (EFI_ERROR (Status)) { + break; + } + + FoundCount++; + + // + // Calculate the TE base address, the FFS file base plus the offset of the TE section less the size stripped off + // by GenTEImage + // + TEImageHeader = (EFI_TE_IMAGE_HEADER *) ((UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER)); + + NewPe32BaseAddress = ((UINT32) BaseAddress) + + ( + (UINTN) CurrentPe32Section.Pe32Section + + sizeof (EFI_COMMON_SECTION_HEADER) + + sizeof (EFI_TE_IMAGE_HEADER) - + TEImageHeader->StrippedSize - + (UINTN) FfsFile + ); + + // + // Allocate a buffer to unshrink the image into. + // + Pe32ImageSize = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) - + sizeof (EFI_TE_IMAGE_HEADER); + Pe32ImageSize += TEImageHeader->StrippedSize; + TEBuffer = (UINT8 *) malloc (Pe32ImageSize); + if (TEBuffer == NULL) { + Error (NULL, 0, 0, "failed to allocate memory", NULL); + return EFI_OUT_OF_RESOURCES; + } + // + // Expand the image into our buffer and fill in critical fields in the DOS header + // Fill in fields required by the loader. + // At offset 0x3C is the offset to the PE signature. We'll put it immediately following the offset value + // itself. + // + memset (TEBuffer, 0, Pe32ImageSize); + DosHeader = (EFI_IMAGE_DOS_HEADER *) TEBuffer; + DosHeader->e_magic = EFI_IMAGE_DOS_SIGNATURE; + *(UINT32 *) (TEBuffer + 0x3C) = 0x40; + PeHdr = (EFI_IMAGE_NT_HEADERS *) (TEBuffer + 0x40); + PeHdr->Signature = EFI_IMAGE_NT_SIGNATURE; + PeHdr->FileHeader.Machine = TEImageHeader->Machine; + PeHdr->FileHeader.NumberOfSections = TEImageHeader->NumberOfSections; + + // + // Say the size of the optional header is the total we stripped off less the size of a PE file header and PE signature and + // the 0x40 bytes for our DOS header. + // + PeHdr->FileHeader.SizeOfOptionalHeader = (UINT16) (TEImageHeader->StrippedSize - 0x40 - sizeof (UINT32) - sizeof (EFI_IMAGE_FILE_HEADER)); + PeHdr->OptionalHeader.ImageBase = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER)); + PeHdr->OptionalHeader.AddressOfEntryPoint = TEImageHeader->AddressOfEntryPoint; + PeHdr->OptionalHeader.BaseOfCode = TEImageHeader->BaseOfCode; + PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize; + PeHdr->OptionalHeader.Subsystem = TEImageHeader->Subsystem; + PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize; + PeHdr->OptionalHeader.SizeOfHeaders = TEImageHeader->StrippedSize + TEImageHeader->NumberOfSections * + sizeof (EFI_IMAGE_SECTION_HEADER) - 12; + + // + // Set NumberOfRvaAndSizes in the optional header to what we had available in the original image + // + if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) || + (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0) + ) { + PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC + 1; + PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; + PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; + } + + if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) || + (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0) + ) { + PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; + PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size; + if (PeHdr->OptionalHeader.NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1) { + PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1; + } + } + // + // NOTE: These values are defaults, and should be verified to be correct in the GenTE utility + // + PeHdr->OptionalHeader.SectionAlignment = 0x10; + + // + // Copy the rest of the image to its original offset + // + memcpy ( + TEBuffer + TEImageHeader->StrippedSize, + (UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) + sizeof (EFI_TE_IMAGE_HEADER), + GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) - + sizeof (EFI_TE_IMAGE_HEADER) + ); + + // + // Initialize context + // + memset (&ImageContext, 0, sizeof (ImageContext)); + ImageContext.Handle = (VOID *) TEBuffer; + ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead; + + Status = PeCoffLoaderGetImageInfo (&ImageContext); + + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "GetImageInfo() call failed on rebase of TE image", FileGuidString); + free (TEBuffer); + return Status; + } + // + // Allocate a buffer for the image to be loaded into. + // + MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x1000)); + if (MemoryImagePointer == 0) { + Error (NULL, 0, 0, "memory allocation error on rebase of TE image", FileGuidString); + free (TEBuffer); + return EFI_OUT_OF_RESOURCES; + } + memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000); + MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12); + + + ImageContext.ImageAddress = MemoryImagePointerAligned; + Status = PeCoffLoaderLoadImage (&ImageContext); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "LoadImage() call failed on rebase of TE image", FileGuidString); + free (TEBuffer); + free ((VOID *) MemoryImagePointer); + return Status; + } + + ImageContext.DestinationAddress = NewPe32BaseAddress; + Status = PeCoffLoaderRelocateImage (&ImageContext); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "RelocateImage() call failed on rebase of TE image", FileGuidString); + free ((VOID *) MemoryImagePointer); + free (TEBuffer); + return Status; + } + + ImageAddress = ImageContext.ImageAddress; + ImageSize = ImageContext.ImageSize; + EntryPoint = ImageContext.EntryPoint; + + // + // Since we may have updated the Codeview RVA, we need to insure the PE + // header indicates the image is large enough to contain the Codeview data + // so it will be loaded properly later if the PEIM is reloaded into memory... + // + PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset); + if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) { + PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage); + PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum); + } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) { + PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage); + PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum); + } else { + Error ( + NULL, + 0, + 0, + "unknown machine type in TE image", + "machine type=0x%X, file=%s", + (UINT32) PeHdr->FileHeader.Machine, + FileGuidString + ); + free ((VOID *) MemoryImagePointer); + free (TEBuffer); + return EFI_ABORTED; + } + + if (*PeHdrSizeOfImage != ImageContext.ImageSize) { + *PeHdrSizeOfImage = (UINT32) ImageContext.ImageSize; + if (*PeHdrChecksum) { + *PeHdrChecksum = 0; + } + } + + TEImageHeader->ImageBase = (UINT64) (NewPe32BaseAddress + TEImageHeader->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER)); + memcpy ( + (UINT8 *) (CurrentPe32Section.Pe32Section + 1) + sizeof (EFI_TE_IMAGE_HEADER), + (VOID *) ((UINT8 *) MemoryImagePointerAligned + TEImageHeader->StrippedSize), + GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) - + sizeof (EFI_TE_IMAGE_HEADER) + ); + + // + // Get EntryPoint in Flash Region. + // + EntryPoint = NewPe32BaseAddress + EntryPoint - ImageAddress; + + // + // If a map file was selected output mapping information for any file that + // was rebased. + // + if (MapFile != NULL) { + fprintf (MapFile, "TE File: %s Base:%08lx", FileGuidString, BaseAddress); + fprintf (MapFile, " EntryPoint:%08lx", EntryPoint); + if (ImageContext.PdbPointer != NULL) { + fprintf (MapFile, " FileName: %s", ImageContext.PdbPointer); + } + fprintf (MapFile, "\n"); + } + + free ((VOID *) MemoryImagePointer); + free (TEBuffer); + if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) { + TailSize = sizeof (EFI_FFS_FILE_TAIL); + } else { + TailSize = 0; + } + // + // Now update file checksum + // + if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) { + SavedState = FfsFile->State; + FfsFile->IntegrityCheck.Checksum.File = 0; + FfsFile->State = 0; + if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) { + FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ( + (UINT8 *) FfsFile, + GetLength (FfsFile->Size) - TailSize + ); + } else { + FfsFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; + } + + FfsFile->State = SavedState; + } + // + // Update tail if present + // + if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) { + TailValue = (EFI_FFS_FILE_TAIL) (~(FfsFile->IntegrityCheck.TailReference)); + *(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue; + } + } + // + // If we found no files, then emit an error if no compressed sections either + // + if (FoundCount == 0) { + Status = GetSectionByType (FfsFile, EFI_SECTION_COMPRESSION, Index, &CurrentPe32Section); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 0, "no PE32, TE, nor compressed section found in FV file", FileGuidString); + return EFI_NOT_FOUND; + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +FfsRebaseImageRead ( + IN VOID *FileHandle, + IN UINTN FileOffset, + IN OUT UINT32 *ReadSize, + OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file + +Arguments: + + FileHandle - The handle to the PE/COFF file + + FileOffset - The offset, in bytes, into the file to read + + ReadSize - The number of bytes to read from the file starting at FileOffset + + Buffer - A pointer to the buffer to read the data into. + +Returns: + + EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset + +--*/ +{ + CHAR8 *Destination8; + CHAR8 *Source8; + UINT32 Length; + + Destination8 = Buffer; + Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset); + Length = *ReadSize; + while (Length--) { + *(Destination8++) = *(Source8++); + } + + return EFI_SUCCESS; +} diff --git a/Tools/CodeTools/Source/PeiRebase/PeiRebaseExe.h b/Tools/CodeTools/Source/PeiRebase/PeiRebaseExe.h new file mode 100644 index 0000000000..b05baefb59 --- /dev/null +++ b/Tools/CodeTools/Source/PeiRebase/PeiRebaseExe.h @@ -0,0 +1,155 @@ +/*++ + +Copyright (c) 1999-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +Module Name: + + PeiRebaseExe.h + +Abstract: + + Definitions for the PeiRebase exe utility. + +--*/ + +#ifndef _EFI_PEIM_FIXUP_EXE_H +#define _EFI_PEIM_FIXUP_EXE_H + +#include +#include +#include +#include + +// +// Utility Name +// +#define UTILITY_NAME "PeiRebase" + +// +// Utility version information +// +#define UTILITY_MAJOR_VERSION 0 +#define UTILITY_MINOR_VERSION 1 +#define UTILITY_DATE __DATE__ + +// +// The maximum number of arguments accepted from the command line. +// +#define MAX_ARGS 9 + +// +// The file copy buffer size +// +#define FILE_COPY_BUFFER_SIZE 512 + +// +// The function that displays general utility information +// +VOID +PrintUtilityInfo ( + VOID + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + None + +Returns: + + GC_TODO: add return values + +--*/ +; + +// +// The function that displays the utility usage message. +// +VOID +PrintUsage ( + VOID + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + None + +Returns: + + GC_TODO: add return values + +--*/ +; + +// +// Internal function declarations +// +EFI_STATUS +FfsRebaseImageRead ( + IN VOID *FileHandle, + IN UINTN FileOffset, + IN OUT UINT32 *ReadSize, + OUT VOID *Buffer + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FileHandle - GC_TODO: add argument description + FileOffset - GC_TODO: add argument description + ReadSize - GC_TODO: add argument description + Buffer - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +EFI_STATUS +FfsRebase ( + IN OUT EFI_FFS_FILE_HEADER *FfsFile, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN FILE *MapFile OPTIONAL + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FfsFile - GC_TODO: add argument description + BaseAddress - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +#endif diff --git a/Tools/CodeTools/Source/PeiRebase/build.xml b/Tools/CodeTools/Source/PeiRebase/build.xml new file mode 100644 index 0000000000..7174441f3f --- /dev/null +++ b/Tools/CodeTools/Source/PeiRebase/build.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/SecApResetVectorFixup/SecApResetVectorFixup.c b/Tools/CodeTools/Source/SecApResetVectorFixup/SecApResetVectorFixup.c new file mode 100644 index 0000000000..442645720e --- /dev/null +++ b/Tools/CodeTools/Source/SecApResetVectorFixup/SecApResetVectorFixup.c @@ -0,0 +1,363 @@ +/*++ + +Copyright (c) 2004-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +Module Name: + + SecApResetVectorFixup.c + +Abstract: + + This utility is part of build process for IA32 Fvrecovery.fv whose total size + is larger than 128kB so that we cannot use GenFvImage utility to put Ap reset + vector at the zero vector of Fv header. + + PEI FV after using the tool + + ------------------------- + |zzz | + | | + | | + | FFS | + | | + | | + | | + |---------------------- | + | PAD | + | | + |.......................| --- + | | | + |xxx | | 128K + |---------------------- | | + | VTF (SEC) | | + ------------------------- --- + + 1. zzz --> Zero vector, which is beyond the 128K limited address space + 2. xxx --> AP reset vector at 4K alignment below 128K and it is in the PAD + file area. + 3. After the build process ,the PAD guid is changed to a new GUID to avoid + the PAD definition confusing. If there is some problem, try to disable + UpdatePadFileGuid + + + +--*/ + +#include "SecApResetVectorFixup.h" + + +EFI_GUID DefaultFvPadFileNameGuid = { 0x78f54d4, 0xcc22, 0x4048, 0x9e, 0x94, 0x87, 0x9c, 0x21, 0x4d, 0x56, 0x2f }; +EFI_GUID NewFvPadFileNameGuid = { 0x145372bc, 0x66b9, 0x476d, 0x81, 0xbc, 0x21, 0x27, 0xc3, 0x76, 0xbb, 0x66 }; + +// +// jmp 0xf000:0xffd0 (0xFFFFFFD0) +// +UINT8 ApResetVector[5] = {0xEA, 0xD0, 0xFF, 0x00, 0xF0}; + +VOID +PrintUtilityInfo ( + VOID + ) +/*++ + +Routine Description: + + Displays the standard utility information to SDTOUT + +Arguments: + + None + +Returns: + + None + +--*/ +{ + printf ( + "%s - Tiano IA32 SEC Ap Reset Vector Fixup Utility."" Version %i.%i\n\n", + UTILITY_NAME, + UTILITY_MAJOR_VERSION, + UTILITY_MINOR_VERSION + ); +} + +VOID +PrintUsage ( + VOID + ) +/*++ + +Routine Description: + + Displays the utility usage syntax to STDOUT + +Arguments: + + None + +Returns: + + None + +--*/ +{ + printf ("Usage: %s InputFvrecoveryFile OutputFvrecoveryFile\n", UTILITY_NAME); + printf (" Where:\n"); + printf ("\tInputFvrecoveryFile - Name of the IA32 input Fvrecovery.fv file.\n"); + printf ("\tOutputFvrecoveryFile - Name of the IA32 output Fvrecovery.fv file.\n"); +} + + +VOID +UpdatePadFileGuid ( + IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader, + IN EFI_FFS_FILE_HEADER *FileHeader, + IN UINT32 FileLength, + IN OUT EFI_GUID *Guid + ) +/*++ + +Routine Description: + + Update the Pad File Guid to change it to other guid and update + the checksum + +Arguments: + FvHeader - EFI_FIRMWARE_VOLUME_HEADER + FileHeader - The FFS PAD file header. + FileLength - The FFS PAD file length. + Guid - The Guid to compare and if it is PAD Guid, update it to new Guid +Returns: + VOID +--*/ + +{ + if ((CompareGuid (Guid, (EFI_GUID *)&DefaultFvPadFileNameGuid)) == 0) { + // + // Set new Pad file guid + // + memcpy (Guid, &NewFvPadFileNameGuid, sizeof (EFI_GUID)); + + + + FileHeader->Type = EFI_FV_FILETYPE_FFS_PAD; + FileHeader->Attributes = 0; + // + // Fill in checksums and state, must be zero during checksum calculation. + // + FileHeader->IntegrityCheck.Checksum.Header = 0; + FileHeader->IntegrityCheck.Checksum.File = 0; + FileHeader->State = 0; + FileHeader->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER)); + if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) { + FileHeader->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) FileHeader, FileLength); + } else { + FileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; + } + + FileHeader->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID; + + if (FvHeader->Attributes & EFI_FVB_ERASE_POLARITY) { + FileHeader->State = (UINT8)~(FileHeader->State); + } + } + +} + + +STATUS +main ( + IN INTN argc, + IN CHAR8 **argv + ) +/*++ + +Routine Description: + + Main function. + +Arguments: + + argc - Number of command line parameters. + argv - Array of pointers to parameter strings. + +Returns: + STATUS_SUCCESS - Utility exits successfully. + STATUS_ERROR - Some error occurred during execution. + +--*/ +{ + FILE *FpIn; + FILE *FpOut; + UINT32 FvrecoveryFileSize; + UINT8 *FileBuffer; + UINT8 *FileBufferRaw; + UINT64 FvLength; + UINT32 Offset; + UINT32 FileLength; + UINT32 FileOccupiedSize; + EFI_FIRMWARE_VOLUME_HEADER *FvHeader; + EFI_FFS_FILE_HEADER *FileHeader; + EFI_GUID *TempGuid; + UINT8 *FixPoint; + UINT32 TempResult; + UINT32 Index; + UINT32 IpiVector; + + TempGuid = NULL; + SetUtilityName (UTILITY_NAME); + + // + // Display utility information + // + PrintUtilityInfo (); + + // + // Verify the correct number of arguments + // + if (argc != MAX_ARGS) { + Error (NULL, 0, 0, "invalid number of input parameters specified", NULL); + PrintUsage (); + return STATUS_ERROR; + } + // + // Open the Input Fvrecovery.fv file + // + if ((FpIn = fopen (argv[1], "rb")) == NULL) { + Error (NULL, 0, 0, "Unable to open file", argv[1]); + return STATUS_ERROR; + } + // + // Get the Input Fvrecovery.fv file size + // + fseek (FpIn, 0, SEEK_END); + FvrecoveryFileSize = ftell (FpIn); + // + // Read the contents of input file to memory buffer + // + FileBuffer = NULL; + FileBufferRaw = NULL; + FileBufferRaw = (UINT8 *) malloc (FvrecoveryFileSize + 0x10000); + if (NULL == FileBufferRaw) { + Error (NULL, 0, 0, "No sufficient memory to allocate!", NULL); + fclose (FpIn); + return STATUS_ERROR; + } + TempResult = 0x10000 - ((UINT32)FileBufferRaw & 0x0FFFF); + FileBuffer = (UINT8 *)((UINT32)FileBufferRaw + TempResult); + fseek (FpIn, 0, SEEK_SET); + TempResult = fread (FileBuffer, 1, FvrecoveryFileSize, FpIn); + if (TempResult != FvrecoveryFileSize) { + Error (NULL, 0, 0, "Read input file error!", NULL); + free ((VOID *)FileBufferRaw); + fclose (FpIn); + return STATUS_ERROR; + } + // + // Close the input Fvrecovery.fv file + // + fclose (FpIn); + // + // Find the pad FFS file + // + FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FileBuffer; + FvLength = FvHeader->FvLength; + FileHeader = (EFI_FFS_FILE_HEADER *)(FileBuffer + FvHeader->HeaderLength); + FileLength = (*(UINT32 *)(FileHeader->Size)) & 0x00FFFFFF; + FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8); + Offset = (UINT32)FileHeader - (UINT32)FileBuffer; + + while (Offset < FvLength) { + TempGuid = (EFI_GUID *)&(FileHeader->Name); + FileLength = (*(UINT32 *)(FileHeader->Size)) & 0x00FFFFFF; + FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8); + if ((CompareGuid (TempGuid, (EFI_GUID *)&DefaultFvPadFileNameGuid)) == 0) { + break; + } + FileHeader = (EFI_FFS_FILE_HEADER *)((UINT32)FileHeader + FileOccupiedSize); + Offset = (UINT32)FileHeader - (UINT32)FileBuffer; + } + + if (Offset >= FvLength) { + Error (NULL, 0, 0, "No pad file found!", NULL); + free ((VOID *)FileBufferRaw); + return STATUS_ERROR; + } + // + // Find the position to place Ap reset vector, the offset + // between the position and the end of Fvrecovery.fv file + // should not exceed 128kB to prevent Ap reset vector from + // outside legacy E and F segment + // + FixPoint = (UINT8 *)(FileHeader + sizeof(EFI_FFS_FILE_HEADER)); + TempResult = 0x1000 - ((UINT32)FixPoint & 0x0FFF); + FixPoint +=TempResult; + if (((UINT32)FixPoint - (UINT32)FileHeader + 5) > FileOccupiedSize) { + Error (NULL, 0, 0, "No appropriate space in pad file to add Ap reset vector!", NULL); + free ((VOID *)FileBufferRaw); + return STATUS_ERROR; + } + while (((UINT32)FixPoint - (UINT32)FileHeader + 5) <= FileOccupiedSize) { + FixPoint += 0x1000; + } + FixPoint -= 0x1000; + if ((UINT32)FvHeader + FvLength - (UINT32)FixPoint > 0x20000) { + Error (NULL, 0, 0, "The position to place Ap reset vector is not in E and F segment!", NULL); + free ((VOID *)FileBufferRaw); + return STATUS_ERROR; + } + // + // Fix up Ap reset vector and calculate the IPI vector + // + for (Index = 0; Index < 5; Index++) { + FixPoint[Index] = ApResetVector[Index]; + } + TempResult = 0x0FFFFFFFF - ((UINT32)FvHeader + (UINT32)FvLength - 1 - (UINT32)FixPoint); + TempResult >>= 12; + IpiVector = TempResult & 0x0FF; + + + UpdatePadFileGuid (FvHeader, FileHeader, FileLength, TempGuid); + + // + // Open the output Fvrecovery.fv file + // + if ((FpOut = fopen (argv[2], "w+b")) == NULL) { + Error (NULL, 0, 0, "Unable to open file", argv[2]); + free ((VOID *)FileBufferRaw); + return STATUS_ERROR; + } + // + // Write the output Fvrecovery.fv file + // + if ((fwrite (FileBuffer, 1, FvrecoveryFileSize, FpOut)) != FvrecoveryFileSize) { + Error (NULL, 0, 0, "Write output file error!", NULL); + free ((VOID *)FileBufferRaw); + return STATUS_ERROR; + } + // + // + // + fseek (FpOut, -8, SEEK_END); + if ((fwrite (&IpiVector, 1, sizeof(UINT32), FpOut)) != sizeof(UINT32)) { + Error (NULL, 0, 0, "Write output file error!", NULL); + free ((VOID *)FileBufferRaw); + return STATUS_ERROR; + } + // + // Close the output Fvrecovery.fv file + // + fclose (FpOut); + free ((VOID *)FileBufferRaw); + return STATUS_SUCCESS; +} + diff --git a/Tools/CodeTools/Source/SecApResetVectorFixup/SecApResetVectorFixup.h b/Tools/CodeTools/Source/SecApResetVectorFixup/SecApResetVectorFixup.h new file mode 100644 index 0000000000..6d234e3a18 --- /dev/null +++ b/Tools/CodeTools/Source/SecApResetVectorFixup/SecApResetVectorFixup.h @@ -0,0 +1,104 @@ +/*++ + +Copyright (c) 1999-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +Module Name: + + SecApResetVectorFixup.h + +Abstract: + + Definitions for the SecApResetVectorFixup utility. + +--*/ + +#ifndef _SEC_AP_RESET_VECTOR_FIXUP_H +#define _SEC_AP_RESET_VECTOR_FIXUP_H + +#include +#include + +#include +#include +#include +#include +#include + +#include "EfiUtilityMsgs.c" +#include "CommonLib.h" + + +// +// Utility Name +// +#define UTILITY_NAME "SecApResetVectorFixup" + +// +// Utility version information +// +#define UTILITY_MAJOR_VERSION 0 +#define UTILITY_MINOR_VERSION 1 +#define UTILITY_DATE __DATE__ + +// +// The maximum number of arguments accepted from the command line. +// +#define MAX_ARGS 3 +#define BUF_SIZE (8 * 1024) + +#define GETOCCUPIEDSIZE(ActualSize, Alignment) \ + (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1)) + + +VOID +PrintUtilityInfo ( + VOID + ) +/*++ + +Routine Description: + + Displays the standard utility information to SDTOUT + +Arguments: + + None + +Returns: + + None + +--*/ +; + +VOID +PrintUsage ( + VOID + ) +/*++ + +Routine Description: + + Displays the utility usage syntax to STDOUT + +Arguments: + + None + +Returns: + + None + +--*/ +; + + +#endif diff --git a/Tools/CodeTools/Source/SecApResetVectorFixup/build.xml b/Tools/CodeTools/Source/SecApResetVectorFixup/build.xml new file mode 100644 index 0000000000..f615b2a602 --- /dev/null +++ b/Tools/CodeTools/Source/SecApResetVectorFixup/build.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/SecFixup/SecFixup.c b/Tools/CodeTools/Source/SecFixup/SecFixup.c new file mode 100644 index 0000000000..c2d46a1d5c --- /dev/null +++ b/Tools/CodeTools/Source/SecFixup/SecFixup.c @@ -0,0 +1,362 @@ +/*++ + +Copyright (c) 1999-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +Module Name: + + SecFixup.c + +Abstract: + + This utility is part of build process for IA32 SEC FFS file. + + It fixup the reset vector data. The reset vector data binary file + will be wrapped as a RAW section and be located immediately after + the PE/TE section. + + The SEC EXE file can be either PE or TE file. + +--*/ + +#include + +#include +#include +#include + +#include "EfiUtilityMsgs.c" +#include "SecFixup.h" + +VOID +PrintUtilityInfo ( + VOID + ) +/*++ + +Routine Description: + + Displays the standard utility information to SDTOUT + +Arguments: + + None + +Returns: + + None + +--*/ +{ + printf ( + "%s - Tiano IA32 SEC Fixup Utility."" Version %i.%i\n\n", + UTILITY_NAME, + UTILITY_MAJOR_VERSION, + UTILITY_MINOR_VERSION + ); +} + +VOID +PrintUsage ( + VOID + ) +/*++ + +Routine Description: + + Displays the utility usage syntax to STDOUT + +Arguments: + + None + +Returns: + + None + +--*/ +{ + printf ("Usage: %s SecExeFile ResetVectorDataFile OutputFile\n", UTILITY_NAME); + printf (" Where:\n"); + printf ("\tSecExeFile - Name of the IA32 SEC EXE file.\n"); + printf ("\tResetVectorDataFile - Name of the reset vector data binary file.\n"); + printf ("\tOutputFileName - Name of the output file.\n\n"); +} + +STATUS +main ( + IN INTN argc, + IN CHAR8 **argv + ) +/*++ + +Routine Description: + + Main function. + +Arguments: + + argc - Number of command line parameters. + argv - Array of pointers to parameter strings. + +Returns: + STATUS_SUCCESS - Utility exits successfully. + STATUS_ERROR - Some error occurred during execution. + +--*/ +{ + FILE *FpIn; + + FILE *FpOut; + UINT32 AddressOfEntryPoint; + INT32 DestRel; + STATUS Status; + UINT32 SecFileSize; + + SetUtilityName (UTILITY_NAME); + + // + // Display utility information + // + PrintUtilityInfo (); + + // + // Verify the correct number of arguments + // + if (argc != MAX_ARGS) { + Error (NULL, 0, 0, "invalid number of input parameters specified", NULL); + PrintUsage (); + return STATUS_ERROR; + } + // + // Open the SEC exe file + // + if ((FpIn = fopen (argv[1], "rb")) == NULL) { + Error (NULL, 0, 0, "Unable to open file", argv[1]); + return STATUS_ERROR; + } + // + // Get the entry point of the EXE file + // + Status = GetEntryPoint (FpIn, &AddressOfEntryPoint); + if (Status != STATUS_SUCCESS) { + fclose (FpIn); + return STATUS_ERROR; + } + // + // Get the SEC file size + // + fseek (FpIn, 0, SEEK_END); + SecFileSize = ftell (FpIn); + + // + // Close the SEC file + // + fclose (FpIn); + + // + // Open the reset vector data file + // + if ((FpIn = fopen (argv[2], "rb")) == NULL) { + Error (NULL, 0, 0, "Unable to open file", argv[2]); + return STATUS_ERROR; + } + // + // Open the output file + // + if ((FpOut = fopen (argv[3], "w+b")) == NULL) { + Error (NULL, 0, 0, "Unable to open file", argv[3]); + fclose (FpIn); + return STATUS_ERROR; + } + // + // Copy the input file to the output file + // + if (CopyFile (FpIn, FpOut) != STATUS_SUCCESS) { + fclose (FpIn); + fclose (FpOut); + return STATUS_ERROR; + } + // + // Close the reset vector data file + // + fclose (FpIn); + + // + // Fix the destination relative in the jmp instruction + // in the reset vector data structure + // + fseek (FpOut, -DEST_REL_OFFSET, SEEK_END); + DestRel = AddressOfEntryPoint - (SecFileSize + sizeof (EFI_COMMON_SECTION_HEADER) + (UINT32) (ftell (FpOut)) + 2); + if (DestRel <= -65536) { + Error (NULL, 0, 0, "The SEC EXE file size is too big", NULL); + fclose (FpOut); + return STATUS_ERROR; + } + + if (fwrite (&DestRel, sizeof (UINT16), 1, FpOut) != 1) { + Error (NULL, 0, 0, "Failed to write to the output file", NULL); + fclose (FpOut); + return STATUS_ERROR; + } + // + // Close the output file + // + fclose (FpOut); + + return STATUS_SUCCESS; +} + +STATUS +GetEntryPoint ( + IN FILE *ExeFile, + OUT UINT32 *EntryPoint + ) +/*++ + +Routine Description: + + Get the address of the entry point of a PE/TE file. + +Arguments: + + PeFile - File pointer to the specified PE/TE file. + EntryPoint - Buffer for the address of the entry point to be returned. + +Returns: + STATUS_SUCCESS - Function completed successfully. + STATUS_ERROR - Error occured. + +--*/ +// GC_TODO: ExeFile - add argument and description to function comment +{ + EFI_IMAGE_DOS_HEADER DosHeader; + EFI_IMAGE_NT_HEADERS32 NtHeader; + EFI_TE_IMAGE_HEADER TeHeader; + + // + // Check if it is a TE file + // + fseek (ExeFile, 0, SEEK_SET); + // + // Attempt to read the TE header + // + if (fread (&TeHeader, sizeof (TeHeader), 1, ExeFile) == 1) { + if (TeHeader.Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { + if (TeHeader.Machine != EFI_IMAGE_MACHINE_IA32) { + Error (NULL, 0, 0, "The SEC file is PE but is not PE32 for IA32", NULL); + return STATUS_ERROR; + } + + *EntryPoint = TeHeader.AddressOfEntryPoint + sizeof (EFI_TE_IMAGE_HEADER) - TeHeader.StrippedSize; + return STATUS_SUCCESS; + } + } + // + // Check if it is a PE file + // + fseek (ExeFile, 0, SEEK_SET); + // + // Attempt to read the DOS header + // + if (fread (&DosHeader, sizeof (DosHeader), 1, ExeFile) != 1) { + goto InvalidFile; + } + // + // Check the magic number + // + if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) { + goto InvalidFile; + } + // + // Position into the file and read the NT PE header + // + fseek (ExeFile, (long) DosHeader.e_lfanew, SEEK_SET); + if (fread (&NtHeader, sizeof (NtHeader), 1, ExeFile) != 1) { + goto InvalidFile; + } + // + // Check the PE signature in the header + // + if (NtHeader.Signature != EFI_IMAGE_NT_SIGNATURE) { + goto InvalidFile; + } + // + // Make sure the PE file is PE32 for IA32 + // + if (NtHeader.FileHeader.Machine != EFI_IMAGE_MACHINE_IA32 || + NtHeader.OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC + ) { + Error (NULL, 0, 0, "The SEC file is PE but is not PE32 for IA32", NULL); + return STATUS_ERROR; + } + // + // Get the entry point from the optional header + // + *EntryPoint = NtHeader.OptionalHeader.AddressOfEntryPoint; + return STATUS_SUCCESS; + +InvalidFile: + Error (NULL, 0, 0, "The SEC file is neither PE nor TE file", NULL); + return STATUS_ERROR; +} + +STATUS +CopyFile ( + FILE *FpIn, + FILE *FpOut + ) +/*++ + +Routine Description: + + Copy file. + +Arguments: + + FpIn - File pointer to the source file. + FpOut - File pointer to the destination file. + +Returns: + STATUS_SUCCESS - Function completed successfully. + STATUS_ERROR - Error occured. + +--*/ +{ + INTN FileSize; + + INTN Offset; + + INTN Length; + UINT8 Buffer[BUF_SIZE]; + + fseek (FpIn, 0, SEEK_END); + FileSize = ftell (FpIn); + + fseek (FpIn, 0, SEEK_SET); + fseek (FpOut, 0, SEEK_SET); + + Offset = 0; + while (Offset < FileSize) { + Length = sizeof (Buffer); + if (FileSize - Offset < Length) { + Length = FileSize - Offset; + } + + if (fread (Buffer, Length, 1, FpIn) != 1 || fwrite (Buffer, Length, 1, FpOut) != 1) { + Error (NULL, 0, 0, "Copy file error", NULL); + return STATUS_ERROR; + } + + Offset += Length; + } + + return STATUS_SUCCESS; +} diff --git a/Tools/CodeTools/Source/SecFixup/SecFixup.h b/Tools/CodeTools/Source/SecFixup/SecFixup.h new file mode 100644 index 0000000000..3694b1516a --- /dev/null +++ b/Tools/CodeTools/Source/SecFixup/SecFixup.h @@ -0,0 +1,146 @@ +/*++ + +Copyright (c) 1999-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +Module Name: + + SecFixup.h + +Abstract: + + Definitions for the SecFixup utility. + +--*/ + +#ifndef _SEC_FIXUP_H +#define _SEC_FIXUP_H + +// +// Utility Name +// +#define UTILITY_NAME "SecFixup" + +// +// Utility version information +// +#define UTILITY_MAJOR_VERSION 0 +#define UTILITY_MINOR_VERSION 1 +#define UTILITY_DATE __DATE__ + +// +// The maximum number of arguments accepted from the command line. +// +#define MAX_ARGS 4 + +#define DEST_REL_OFFSET 13 +#define BUF_SIZE (8 * 1024) + +// +// The function that displays general utility information +// +VOID +PrintUtilityInfo ( + VOID + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + None + +Returns: + + GC_TODO: add return values + +--*/ +; + +// +// The function that displays the utility usage message. +// +VOID +PrintUsage ( + VOID + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + None + +Returns: + + GC_TODO: add return values + +--*/ +; + +// +// The function that gets the entry point of a PE/TE file. +// +STATUS +GetEntryPoint ( + IN FILE *ExeFile, + OUT UINT32 *EntryPoint + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + ExeFile - GC_TODO: add argument description + EntryPoint - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +// +// The function that copies a file. +// +STATUS +CopyFile ( + FILE *FpIn, + FILE *FpOut + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + FpIn - GC_TODO: add argument description + FpOut - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +; + +#endif diff --git a/Tools/CodeTools/Source/SecFixup/build.xml b/Tools/CodeTools/Source/SecFixup/build.xml new file mode 100644 index 0000000000..ebc408ba26 --- /dev/null +++ b/Tools/CodeTools/Source/SecFixup/build.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/SetStamp/SetStamp.c b/Tools/CodeTools/Source/SetStamp/SetStamp.c new file mode 100644 index 0000000000..539aced1d9 --- /dev/null +++ b/Tools/CodeTools/Source/SetStamp/SetStamp.c @@ -0,0 +1,475 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + SetStamp.c + +Abstract: + Set Date/Time Stamp of Portable Executable (PE) format file + +--*/ + +#include +#include +#include + +#define LINE_MAXLEN 80 + +void +PrintUsage ( + void + ) +/*++ +Routine Description: + print usage of setstamp command + +Arguments: + void + +Returns: + None +--*/ +{ + // + // print usage of command + // + printf ("Usage: SetStamp \n"); +} + +int +GetDateTime ( + FILE *fp, + time_t *ltime + ) +/*++ +Routine Description: + Read the date and time from TIME file. If the date/time string is +"NOW NOW", write the current date and time to TIME file and set it to +ltime. Else, set the date and time of TIME file to ltime. + +Arguments: + fp - The pointer of TIME file + ltime - Date and time + +Returns: + = 0 - Success + = -1 - Failed +--*/ +{ + char buffer[LINE_MAXLEN]; + struct tm stime; + struct tm *now; + + if (fgets (buffer, LINE_MAXLEN, fp) == NULL) { + printf ("Error: Cannot read TIME file.\n"); + return -1; + } + // + // compare the value with "NOW NOW", write TIME file if equal + // + if (strncmp (buffer, "NOW NOW", 7) == 0) { + // + // get system current time and date + // + time (ltime); + + now = localtime (ltime); + if (now == NULL) { + printf ("Error: Cannot get local time.\n"); + return -1; + } + + if (strftime (buffer, LINE_MAXLEN, "%Y-%m-%d %H:%M:%S", now) == 0) { + printf ("Error: Cannot format time string.\n"); + return -1; + } + // + // write TIME file + // + if (fseek (fp, 0, SEEK_SET) != 0) { + printf ("Error: Cannot move location of TIME file.\n"); + return -1; + } + + if (fputs (buffer, fp) == EOF) { + printf ("Error: Cannot write time string to TIME file.\n"); + return -1; + } + // + // ltime has been set as current time and date, return + // + return 0; + } + // + // get the date and time from buffer + // + if (6 != sscanf ( + buffer, + "%d-%d-%d %d:%d:%d", + &stime.tm_year, + &stime.tm_mon, + &stime.tm_mday, + &stime.tm_hour, + &stime.tm_min, + &stime.tm_sec + )) { + printf ("Error: Invaild date or time!\n"); + return -1; + } + // + // in struct, Month (0 - 11; Jan = 0). So decrease 1 from it + // + stime.tm_mon -= 1; + + // + // in struct, Year (current year minus 1900) + // and only the dates can be handled from Jan 1, 1970 to Jan 18, 2038 + // + // + // convert 0 -> 100 (2000), 1 -> 101 (2001), ..., 38 -> 138 (2038) + // + if (stime.tm_year <= 38) { + stime.tm_year += 100; + } + // + // convert 1970 -> 70, 2000 -> 100, ... + // + else if (stime.tm_year >= 1970) { + stime.tm_year -= 1900; + } + // + // convert the date and time to time_t format + // + *ltime = mktime (&stime); + if (*ltime == (time_t) - 1) { + printf ("Error: Invalid date or time!\n"); + return -1; + } + + return 0; +} + +int +ReadFromFile ( + FILE *fp, + long offset, + void *buffer, + int size + ) +/*++ +Routine Description: + read data from a specified location of file + +Arguments: + fp - file pointer + offset - number of bytes from beginning of file + buffer - buffer used to store data + size - size of buffer + +Returns: + = 0 - Success + = -1 - Failed +--*/ +{ + // + // set file pointer to the specified location of file + // + if (fseek (fp, offset, SEEK_SET) != 0) { + printf ("Error: Cannot move the current location of the file.\n"); + return -1; + } + // + // read data from the file + // + if (fread (buffer, size, 1, fp) != 1) { + printf ("Error: Cannot read data from the file.\n"); + return -1; + } + + return 0; +} + +int +WriteToFile ( + FILE *fp, + long offset, + void *buffer, + int size + ) +/*++ +Routine Description: + write data to a specified location of file + +Arguments: + fp - file pointer + offset - number of bytes from beginning of file + buffer - buffer used to store data + size - size of buffer + +Returns: + = 0 - Success + = -1 - Failed +--*/ +{ + // + // set file pointer to the specified location of file + // + if (fseek (fp, offset, SEEK_SET) != 0) { + printf ("Error: Cannot move the current location of the file.\n"); + return -1; + } + // + // write data to the file + // + if (fwrite (buffer, size, 1, fp) != 1) { + perror ("Error: Cannot write data to the file.\n"); + return -1; + } + + return 0; +} + +int +SetStamp ( + FILE *fp, + time_t ltime + ) +/*++ +Routine Description: + set Date/Time Stamp of the file + +Arguments: + fp - file pointer + ltime - time and date + +Returns: + = 0 - Success + = -1 - Failed +--*/ +{ + unsigned char header[4]; + unsigned long offset; + unsigned long NumberOfRvaAndSizes; + unsigned int nvalue; + unsigned long lvalue; + + // + // read the header of file + // + if (ReadFromFile (fp, 0, header, 2) != 0) { + return -1; + } + // + // "MZ" -- the header of image file (PE) + // + if (strncmp ((char *) header, "MZ", 2) != 0) { + printf ("Error: Invalid Image file.\n"); + return -1; + } + // + // At location 0x3C, the stub has the file offset to the + // PE signature. + // + if (ReadFromFile (fp, 0x3C, &offset, 4) != 0) { + return -1; + } + // + // read the header of optional + // + if (ReadFromFile (fp, offset, header, 4) != 0) { + return -1; + } + // + // "PE\0\0" -- the signature of optional header + // + if (strncmp ((char *) header, "PE\0\0", 4) != 0) { + printf ("Error: Invalid PE format file.\n"); + return -1; + } + // + // Add 8 to skip PE signature (4-byte), Machine (2-byte) and + // NumberOfSection (2-byte) + // + offset += 8; + + if (WriteToFile (fp, offset, <ime, 4) != 0) { + return -1; + } + // + // Add 16 to skip COFF file header, and get to optional header. + // + offset += 16; + + // + // Check the magic field, 0x10B for PE32 and 0x20B for PE32+ + // + if (ReadFromFile (fp, offset, &nvalue, 2) != 0) { + return -1; + } + // + // If this is PE32 image file, offset of NumberOfRvaAndSizes is 92. + // Else it is 108. + // + switch (nvalue & 0xFFFF) { + case 0x10B: + offset += 92; + break; + + case 0x20B: + offset += 108; + break; + + default: + printf ("Error: Sorry! The Magic value is unknown.\n"); + return -1; + } + // + // get the value of NumberOfRvaAndSizes + // + if (ReadFromFile (fp, offset, &NumberOfRvaAndSizes, 4) != 0) { + return -1; + } + // + // Date/time stamp exists in Export Table, Import Table, Resource Table, + // Debug Table and Delay Import Table. And in Import Table and Delay Import + // Table, it will be set when bound. So here only set the date/time stamp + // of Export Table, Resource Table and Debug Table. + // + // + // change date/time stamp of Export Table, the offset of Export Table + // is 4 + 0 * 8 = 4. And the offset of stamp is 4. + // + if (NumberOfRvaAndSizes >= 1) { + if (ReadFromFile (fp, offset + 4, &lvalue, 4) != 0) { + return -1; + } + + if (lvalue != 0) { + if (WriteToFile (fp, lvalue + 4, <ime, 4) != 0) { + return -1; + } + } + } + // + // change date/time stamp of Resource Table, the offset of Resource Table + // is 4 + 2 * 8 = 20. And the offset of stamp is 4. + // + if (NumberOfRvaAndSizes >= 3) { + if (ReadFromFile (fp, offset + 20, &lvalue, 4) != 0) { + return -1; + } + + if (lvalue != 0) { + if (WriteToFile (fp, lvalue + 4, <ime, 4) != 0) { + return -1; + } + } + } + // + // change date/time stamp of Debug Table, offset of Debug Table + // is 4 + 6 * 8 = 52. And the offset of stamp is 4. + // + if (NumberOfRvaAndSizes >= 7) { + if (ReadFromFile (fp, offset + 52, &lvalue, 4) != 0) { + return -1; + } + + if (lvalue != 0) { + if (WriteToFile (fp, lvalue + 4, <ime, 4) != 0) { + return -1; + } + } + // + // change the date/time stamp of Debug Data + // + if (ReadFromFile (fp, lvalue + 24, &lvalue, 4) != 0) { + return -1; + } + // + // get the signature of debug data + // + if (ReadFromFile (fp, lvalue, header, 2) != 0) { + return -1; + } + // + // "NB" - the signature of Debug Data + // Need Review: (From Spec. is "NB05", From .dll is "NB10") + // + if (strncmp ((char *) header, "NB", 2) == 0) { + if (WriteToFile (fp, lvalue + 8, <ime, 4) != 0) { + return -1; + } + } + } + + return 0; +} + +int +main ( + int argc, + char *argv[] + ) +{ + FILE *fp; + time_t ltime; + + // + // check the number of parameters + // + if (argc != 3) { + PrintUsage (); + return -1; + } + // + // open the TIME file, if not exists, return + // + fp = fopen (argv[2], "r+"); + if (fp == NULL) { + return 0; + } + // + // get time and date from file + // + if (GetDateTime (fp, <ime) != 0) { + fclose (fp); + return -1; + } + // + // close the TIME file + // + fclose (fp); + + // + // open the PE file + // + fp = fopen (argv[1], "r+b"); + if (fp == NULL) { + printf ("Error: Cannot open the PE file!\n"); + return -1; + } + // + // set time and date stamp to the PE file + // + if (SetStamp (fp, ltime) != 0) { + fclose (fp); + return -1; + } + + printf ("Set Date/Time Stamp to %s", ctime (<ime)); + + // + // close the PE file + // + fclose (fp); + + return 0; +} diff --git a/Tools/CodeTools/Source/SetStamp/build.xml b/Tools/CodeTools/Source/SetStamp/build.xml new file mode 100644 index 0000000000..9425797c45 --- /dev/null +++ b/Tools/CodeTools/Source/SetStamp/build.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/SplitFile/SplitFile.c b/Tools/CodeTools/Source/SplitFile/SplitFile.c new file mode 100644 index 0000000000..a1bda7dc31 --- /dev/null +++ b/Tools/CodeTools/Source/SplitFile/SplitFile.c @@ -0,0 +1,131 @@ +/* + +Copyright (c) 1999-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +*/ + +// GC_TODO: fix comment to start with /*++ +#include "stdio.h" +#include "string.h" +#include "stdlib.h" + +void +helpmsg ( + void + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + +Returns: + + GC_TODO: add return values + +--*/ +{ + printf ( + "SplitFile Filename Offset\n"" Filename = Input file to split\n"" Offset = offset at which to split file\n" + "\n\n""SplitFile will break a file in two pieces at the requested offset\n" + " outputting Filename1 and Filename2\n" + ); +} + +int +main ( + int argc, + char*argv[] + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + argc - GC_TODO: add argument description + ] - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + FILE *In; + + FILE *Out1; + + FILE *Out2; + char OutName1[512]; + char OutName2[512]; + unsigned long Index; + unsigned long splitpoint; + char CharC; + + if (argc != 3) { + helpmsg (); + return -1; + } + + In = fopen (argv[1], "rb"); + if (In == NULL) { + printf ("Unable to open file \"%s\"\n", argv[1]); + return -1; + } + + strncpy (OutName1, argv[1], 510); + strncpy (OutName2, argv[1], 510); + strcat (OutName1, "1"); + strcat (OutName2, "2"); + + Out1 = fopen (OutName1, "wb"); + if (Out1 == NULL) { + printf ("Unable to open file \"%s\"\n", OutName1); + return -1; + } + + Out2 = fopen (OutName2, "wb"); + if (Out2 == NULL) { + printf ("Unable to open file \"%s\"\n", OutName2); + return -1; + } + + splitpoint = atoi (argv[2]); + + for (Index = 0; Index < splitpoint; Index++) { + CharC = (char) fgetc (In); + if (feof (In)) { + break; + } + + fputc (CharC, Out1); + } + + for (;;) { + CharC = (char) fgetc (In); + if (feof (In)) { + break; + } + + fputc (CharC, Out2); + } + + fclose (In); + fclose (Out1); + fclose (Out2); + + return 0; +} diff --git a/Tools/CodeTools/Source/SplitFile/build.xml b/Tools/CodeTools/Source/SplitFile/build.xml new file mode 100644 index 0000000000..6fa9b573c3 --- /dev/null +++ b/Tools/CodeTools/Source/SplitFile/build.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/StrGather/StrGather.c b/Tools/CodeTools/Source/StrGather/StrGather.c new file mode 100644 index 0000000000..9eb5c5a19e --- /dev/null +++ b/Tools/CodeTools/Source/StrGather/StrGather.c @@ -0,0 +1,2531 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + StrGather.c + +Abstract: + + Parse a strings file and create or add to a string database file. + +--*/ + +#include +#include +#include +#include + +#include + +#include "CommonLib.h" +#include "EfiUtilityMsgs.h" +#include "StrGather.h" +#include "StringDB.h" + +#define TOOL_VERSION "0.31" + +#ifndef MAX_PATH +#define MAX_PATH 255 +#endif +#define MAX_NEST_DEPTH 20 // just in case we get in an endless loop. +#define MAX_STRING_IDENTIFIER_NAME 100 // number of wchars +#define MAX_LINE_LEN 200 +#define STRING_TOKEN "STRING_TOKEN" +#define DEFAULT_BASE_NAME "BaseName" +// +// Operational modes for this utility +// +#define MODE_UNKNOWN 0 +#define MODE_PARSE 1 +#define MODE_SCAN 2 +#define MODE_DUMP 3 + +// +// We keep a linked list of these for the source files we process +// +typedef struct _SOURCE_FILE { + FILE *Fptr; + WCHAR *FileBuffer; + WCHAR *FileBufferPtr; + UINT32 FileSize; + CHAR8 FileName[MAX_PATH]; + UINT32 LineNum; + BOOLEAN EndOfFile; + BOOLEAN SkipToHash; + struct _SOURCE_FILE *Previous; + struct _SOURCE_FILE *Next; + WCHAR ControlCharacter; +} SOURCE_FILE; + +#define DEFAULT_CONTROL_CHARACTER UNICODE_SLASH + +// +// Here's all our globals. We need a linked list of include paths, a linked +// list of source files, a linked list of subdirectories (appended to each +// include path when searching), and a couple other fields. +// +static struct { + SOURCE_FILE SourceFiles; + TEXT_STRING_LIST *IncludePaths; // all include paths to search + TEXT_STRING_LIST *LastIncludePath; + TEXT_STRING_LIST *ScanFileName; + TEXT_STRING_LIST *LastScanFileName; + TEXT_STRING_LIST *SkipExt; // if -skipext .uni + TEXT_STRING_LIST *LastSkipExt; + TEXT_STRING_LIST *IndirectionFileName; + TEXT_STRING_LIST *LastIndirectionFileName; + TEXT_STRING_LIST *DatabaseFileName; + TEXT_STRING_LIST *LastDatabaseFileName; + WCHAR_STRING_LIST *Language; + WCHAR_STRING_LIST *LastLanguage; + WCHAR_MATCHING_STRING_LIST *IndirectionList; // from indirection file(s) + WCHAR_MATCHING_STRING_LIST *LastIndirectionList; + BOOLEAN Verbose; // for more detailed output + BOOLEAN VerboseDatabaseWrite; // for more detailed output when writing database + BOOLEAN VerboseDatabaseRead; // for more detailed output when reading database + BOOLEAN NewDatabase; // to start from scratch + BOOLEAN IgnoreNotFound; // when scanning + BOOLEAN VerboseScan; + BOOLEAN UnquotedStrings; // -uqs option + CHAR8 OutputDatabaseFileName[MAX_PATH]; + CHAR8 StringHFileName[MAX_PATH]; + CHAR8 StringCFileName[MAX_PATH]; // output .C filename + CHAR8 DumpUFileName[MAX_PATH]; // output unicode dump file name + CHAR8 HiiExportPackFileName[MAX_PATH]; // HII export pack file name + CHAR8 BaseName[MAX_PATH]; // base filename of the strings file + UINT32 Mode; +} mGlobals; + +static +BOOLEAN +IsValidIdentifierChar ( + CHAR8 Char, + BOOLEAN FirstChar + ); + +static +void +RewindFile ( + SOURCE_FILE *SourceFile + ); + +static +BOOLEAN +SkipTo ( + SOURCE_FILE *SourceFile, + WCHAR WChar, + BOOLEAN StopAfterNewline + ); + +static +UINT32 +SkipWhiteSpace ( + SOURCE_FILE *SourceFile + ); + +static +BOOLEAN +IsWhiteSpace ( + SOURCE_FILE *SourceFile + ); + +static +BOOLEAN +EndOfFile ( + SOURCE_FILE *SourceFile + ); + +static +void +PreprocessFile ( + SOURCE_FILE *SourceFile + ); + +static +UINT32 +GetStringIdentifierName ( + IN SOURCE_FILE *SourceFile, + IN OUT WCHAR *StringIdentifierName, + IN UINT32 StringIdentifierNameLen + ); + +static +UINT32 +GetLanguageIdentifierName ( + IN SOURCE_FILE *SourceFile, + IN OUT WCHAR *LanguageIdentifierName, + IN UINT32 LanguageIdentifierNameLen, + IN BOOLEAN Optional + ); + +static +WCHAR * +GetPrintableLanguageName ( + IN SOURCE_FILE *SourceFile + ); + +static +STATUS +AddCommandLineLanguage ( + IN CHAR8 *Language + ); + +static +WCHAR * +GetQuotedString ( + SOURCE_FILE *SourceFile, + BOOLEAN Optional + ); + +static +STATUS +ProcessIncludeFile ( + SOURCE_FILE *SourceFile, + SOURCE_FILE *ParentSourceFile + ); + +static +STATUS +ParseFile ( + SOURCE_FILE *SourceFile + ); + +static +FILE * +FindFile ( + IN CHAR8 *FileName, + OUT CHAR8 *FoundFileName, + IN UINT32 FoundFileNameLen + ); + +static +STATUS +ProcessArgs ( + int Argc, + char *Argv[] + ); + +static +STATUS +ProcessFile ( + SOURCE_FILE *SourceFile + ); + +static +UINT32 +wstrcmp ( + WCHAR *Buffer, + WCHAR *Str + ); + +static +void +Usage ( + VOID + ); + +static +void +FreeLists ( + VOID + ); + +static +void +ProcessTokenString ( + SOURCE_FILE *SourceFile + ); + +static +void +ProcessTokenInclude ( + SOURCE_FILE *SourceFile + ); + +static +void +ProcessTokenScope ( + SOURCE_FILE *SourceFile + ); + +static +void +ProcessTokenLanguage ( + SOURCE_FILE *SourceFile + ); + +static +void +ProcessTokenLangDef ( + SOURCE_FILE *SourceFile + ); + +static +STATUS +ScanFiles ( + TEXT_STRING_LIST *ScanFiles + ); + +static +STATUS +ParseIndirectionFiles ( + TEXT_STRING_LIST *Files + ); + +STATUS +StringDBCreateHiiExportPack ( + CHAR8 *OutputFileName + ); + +int +main ( + int Argc, + char *Argv[] + ) +/*++ + +Routine Description: + + Call the routine to parse the command-line options, then process the file. + +Arguments: + + Argc - Standard C main() argc and argv. + Argv - Standard C main() argc and argv. + +Returns: + + 0 if successful + nonzero otherwise + +--*/ +{ + STATUS Status; + + SetUtilityName (PROGRAM_NAME); + // + // Process the command-line arguments + // + Status = ProcessArgs (Argc, Argv); + if (Status != STATUS_SUCCESS) { + return Status; + } + // + // Initialize the database manager + // + StringDBConstructor (); + // + // We always try to read in an existing database file. It may not + // exist, which is ok usually. + // + if (mGlobals.NewDatabase == 0) { + // + // Read all databases specified. + // + for (mGlobals.LastDatabaseFileName = mGlobals.DatabaseFileName; + mGlobals.LastDatabaseFileName != NULL; + mGlobals.LastDatabaseFileName = mGlobals.LastDatabaseFileName->Next + ) { + Status = StringDBReadDatabase (mGlobals.LastDatabaseFileName->Str, TRUE, mGlobals.VerboseDatabaseRead); + if (Status != STATUS_SUCCESS) { + return Status; + } + } + } + // + // Read indirection file(s) if specified + // + if (ParseIndirectionFiles (mGlobals.IndirectionFileName) != STATUS_SUCCESS) { + goto Finish; + } + // + // If scanning source files, do that now + // + if (mGlobals.Mode == MODE_SCAN) { + ScanFiles (mGlobals.ScanFileName); + } else if (mGlobals.Mode == MODE_PARSE) { + // + // Parsing a unicode strings file + // + mGlobals.SourceFiles.ControlCharacter = DEFAULT_CONTROL_CHARACTER; + Status = ProcessIncludeFile (&mGlobals.SourceFiles, NULL); + if (Status != STATUS_SUCCESS) { + goto Finish; + } + } + // + // Create the string defines header file if there have been no errors. + // + ParserSetPosition (NULL, 0); + if ((mGlobals.StringHFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) { + Status = StringDBDumpStringDefines (mGlobals.StringHFileName, mGlobals.BaseName); + if (Status != EFI_SUCCESS) { + goto Finish; + } + } + // + // Dump the strings to a .c file if there have still been no errors. + // + if ((mGlobals.StringCFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) { + Status = StringDBDumpCStrings ( + mGlobals.StringCFileName, + mGlobals.BaseName, + mGlobals.Language, + mGlobals.IndirectionList + ); + if (Status != EFI_SUCCESS) { + goto Finish; + } + } + // + // Dump the database if requested + // + if ((mGlobals.DumpUFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) { + StringDBDumpDatabase (NULL, mGlobals.DumpUFileName, FALSE); + } + // + // Dump the string data as HII binary string pack if requested + // + if ((mGlobals.HiiExportPackFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) { + StringDBCreateHiiExportPack (mGlobals.HiiExportPackFileName); + } + // + // Always update the database if no errors and not in dump mode. If they specified -od + // for an output database file name, then use that name. Otherwise use the name of + // the first database file specified with -db + // + if ((mGlobals.Mode != MODE_DUMP) && (GetUtilityStatus () < STATUS_ERROR)) { + if (mGlobals.OutputDatabaseFileName[0]) { + Status = StringDBWriteDatabase (mGlobals.OutputDatabaseFileName, mGlobals.VerboseDatabaseWrite); + } else { + Status = StringDBWriteDatabase (mGlobals.DatabaseFileName->Str, mGlobals.VerboseDatabaseWrite); + } + + if (Status != EFI_SUCCESS) { + goto Finish; + } + } + +Finish: + // + // Free up memory + // + FreeLists (); + StringDBDestructor (); + return GetUtilityStatus (); +} + +static +STATUS +ProcessIncludeFile ( + SOURCE_FILE *SourceFile, + SOURCE_FILE *ParentSourceFile + ) +/*++ + +Routine Description: + + Given a source file, open the file and parse it + +Arguments: + + SourceFile - name of file to parse + ParentSourceFile - for error reporting purposes, the file that #included SourceFile. + +Returns: + + Standard status. + +--*/ +{ + static UINT32 NestDepth = 0; + CHAR8 FoundFileName[MAX_PATH]; + STATUS Status; + + Status = STATUS_SUCCESS; + NestDepth++; + // + // Print the file being processed. Indent so you can tell the include nesting + // depth. + // + if (mGlobals.Verbose) { + fprintf (stdout, "%*cProcessing file '%s'\n", NestDepth * 2, ' ', SourceFile->FileName); + } + + // + // Make sure we didn't exceed our maximum nesting depth + // + if (NestDepth > MAX_NEST_DEPTH) { + Error (NULL, 0, 0, SourceFile->FileName, "max nesting depth (%d) exceeded", NestDepth); + Status = STATUS_ERROR; + goto Finish; + } + // + // Try to open the file locally, and if that fails try along our include paths. + // + strcpy (FoundFileName, SourceFile->FileName); + if ((SourceFile->Fptr = fopen (FoundFileName, "rb")) == NULL) { + // + // Try to find it among the paths if it has a parent (that is, it is included + // by someone else). + // + if (ParentSourceFile == NULL) { + Error (NULL, 0, 0, SourceFile->FileName, "file not found"); + return STATUS_ERROR; + } + + SourceFile->Fptr = FindFile (SourceFile->FileName, FoundFileName, sizeof (FoundFileName)); + if (SourceFile->Fptr == NULL) { + Error (ParentSourceFile->FileName, ParentSourceFile->LineNum, 0, SourceFile->FileName, "include file not found"); + return STATUS_ERROR; + } + } + // + // Process the file found + // + ProcessFile (SourceFile); +Finish: + // + // Close open files and return status + // + if (SourceFile->Fptr != NULL) { + fclose (SourceFile->Fptr); + } + + return Status; +} + +static +STATUS +ProcessFile ( + SOURCE_FILE *SourceFile + ) +{ + // + // Get the file size, and then read the entire thing into memory. + // Allocate space for a terminator character. + // + fseek (SourceFile->Fptr, 0, SEEK_END); + SourceFile->FileSize = ftell (SourceFile->Fptr); + fseek (SourceFile->Fptr, 0, SEEK_SET); + SourceFile->FileBuffer = (WCHAR *) malloc (SourceFile->FileSize + sizeof (WCHAR)); + if (SourceFile->FileBuffer == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + fread ((VOID *) SourceFile->FileBuffer, SourceFile->FileSize, 1, SourceFile->Fptr); + SourceFile->FileBuffer[(SourceFile->FileSize / sizeof (WCHAR))] = UNICODE_NULL; + // + // Pre-process the file to replace comments with spaces + // + PreprocessFile (SourceFile); + // + // Parse the file + // + ParseFile (SourceFile); + free (SourceFile->FileBuffer); + return STATUS_SUCCESS; +} + +static +STATUS +ParseFile ( + SOURCE_FILE *SourceFile + ) +{ + BOOLEAN InComment; + UINT32 Len; + + // + // First character of a unicode file is special. Make sure + // + if (SourceFile->FileBufferPtr[0] != UNICODE_FILE_START) { + Error (SourceFile->FileName, 1, 0, SourceFile->FileName, "file does not appear to be a unicode file"); + return STATUS_ERROR; + } + + SourceFile->FileBufferPtr++; + InComment = FALSE; + // + // Print the first line if in verbose mode + // + if (mGlobals.Verbose) { + printf ("%d: %S\n", SourceFile->LineNum, SourceFile->FileBufferPtr); + } + // + // Since the syntax is relatively straightforward, just switch on the next char + // + while (!EndOfFile (SourceFile)) { + // + // Check for whitespace + // + if (SourceFile->FileBufferPtr[0] == UNICODE_SPACE) { + SourceFile->FileBufferPtr++; + } else if (SourceFile->FileBufferPtr[0] == UNICODE_TAB) { + SourceFile->FileBufferPtr++; + } else if (SourceFile->FileBufferPtr[0] == UNICODE_CR) { + SourceFile->FileBufferPtr++; + } else if (SourceFile->FileBufferPtr[0] == UNICODE_LF) { + SourceFile->FileBufferPtr++; + SourceFile->LineNum++; + if (mGlobals.Verbose) { + printf ("%d: %S\n", SourceFile->LineNum, SourceFile->FileBufferPtr); + } + + InComment = FALSE; + } else if (SourceFile->FileBufferPtr[0] == 0) { + SourceFile->FileBufferPtr++; + } else if (InComment) { + SourceFile->FileBufferPtr++; + } else if ((SourceFile->FileBufferPtr[0] == UNICODE_SLASH) && (SourceFile->FileBufferPtr[1] == UNICODE_SLASH)) { + SourceFile->FileBufferPtr += 2; + InComment = TRUE; + } else if (SourceFile->SkipToHash && (SourceFile->FileBufferPtr[0] != SourceFile->ControlCharacter)) { + SourceFile->FileBufferPtr++; + } else { + SourceFile->SkipToHash = FALSE; + if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && + ((Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"include")) > 0) + ) { + SourceFile->FileBufferPtr += Len + 1; + ProcessTokenInclude (SourceFile); + } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && + (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"scope")) > 0 + ) { + SourceFile->FileBufferPtr += Len + 1; + ProcessTokenScope (SourceFile); + } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && + (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"language")) > 0 + ) { + SourceFile->FileBufferPtr += Len + 1; + ProcessTokenLanguage (SourceFile); + } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && + (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"langdef")) > 0 + ) { + SourceFile->FileBufferPtr += Len + 1; + ProcessTokenLangDef (SourceFile); + } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && + (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"string")) > 0 + ) { + SourceFile->FileBufferPtr += Len + 1; + ProcessTokenString (SourceFile); + } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && + (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"EFI_BREAKPOINT()")) > 0 + ) { + SourceFile->FileBufferPtr += Len; + // + // BUGBUG: Caling EFI_BREAKOINT() is breaking the link. What is the proper action for this tool + // in this condition? + // +// EFI_BREAKPOINT (); + } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && + (SourceFile->FileBufferPtr[1] == UNICODE_EQUAL_SIGN) + ) { + SourceFile->ControlCharacter = SourceFile->FileBufferPtr[2]; + SourceFile->FileBufferPtr += 3; + } else { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "unrecognized token", "%S", SourceFile->FileBufferPtr); + // + // Treat rest of line as a comment. + // + InComment = TRUE; + } + } + } + + return STATUS_SUCCESS; +} + +static +void +PreprocessFile ( + SOURCE_FILE *SourceFile + ) +/*++ + +Routine Description: + Preprocess a file to replace all carriage returns with NULLs so + we can print lines from the file to the screen. + +Arguments: + SourceFile - structure that we use to keep track of an input file. + +Returns: + Nothing. + +--*/ +{ + BOOLEAN InComment; + + RewindFile (SourceFile); + InComment = FALSE; + while (!EndOfFile (SourceFile)) { + // + // If a line-feed, then no longer in a comment + // + if (SourceFile->FileBufferPtr[0] == UNICODE_LF) { + SourceFile->FileBufferPtr++; + SourceFile->LineNum++; + InComment = 0; + } else if (SourceFile->FileBufferPtr[0] == UNICODE_CR) { + // + // Replace all carriage returns with a NULL so we can print stuff + // + SourceFile->FileBufferPtr[0] = 0; + SourceFile->FileBufferPtr++; + } else if (InComment) { + SourceFile->FileBufferPtr[0] = UNICODE_SPACE; + SourceFile->FileBufferPtr++; + } else if ((SourceFile->FileBufferPtr[0] == UNICODE_SLASH) && (SourceFile->FileBufferPtr[1] == UNICODE_SLASH)) { + SourceFile->FileBufferPtr += 2; + InComment = TRUE; + } else { + SourceFile->FileBufferPtr++; + } + } + // + // Could check for end-of-file and still in a comment, but + // should not be necessary. So just restore the file pointers. + // + RewindFile (SourceFile); +} + +static +WCHAR * +GetPrintableLanguageName ( + IN SOURCE_FILE *SourceFile + ) +{ + WCHAR *String; + WCHAR *Start; + WCHAR *Ptr; + UINT32 Len; + + SkipWhiteSpace (SourceFile); + if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + "expected quoted printable language name", + "%S", + SourceFile->FileBufferPtr + ); + SourceFile->SkipToHash = TRUE; + return NULL; + } + + Len = 0; + SourceFile->FileBufferPtr++; + Start = Ptr = SourceFile->FileBufferPtr; + while (!EndOfFile (SourceFile)) { + if (SourceFile->FileBufferPtr[0] == UNICODE_CR) { + Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start); + break; + } else if (SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) { + break; + } + + SourceFile->FileBufferPtr++; + Len++; + } + + if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) { + Warning ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + "missing closing quote on printable language name string", + "%S", + Start + ); + } else { + SourceFile->FileBufferPtr++; + } + // + // Now allocate memory for the string and save it off + // + String = (WCHAR *) malloc ((Len + 1) * sizeof (WCHAR)); + if (String == NULL) { + Error (NULL, 0, 0, "memory allocation failed", NULL); + return NULL; + } + // + // Copy the string from the file buffer to the local copy. + // We do no reformatting of it whatsoever at this point. + // + Ptr = String; + while (Len > 0) { + *Ptr = *Start; + Start++; + Ptr++; + Len--; + } + + *Ptr = 0; + // + // Now format the string to convert \wide and \narrow controls + // + StringDBFormatString (String); + return String; +} + +static +WCHAR * +GetQuotedString ( + SOURCE_FILE *SourceFile, + BOOLEAN Optional + ) +{ + WCHAR *String; + WCHAR *Start; + WCHAR *Ptr; + UINT32 Len; + BOOLEAN PreviousBackslash; + + if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) { + if (!Optional) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted string", "%S", SourceFile->FileBufferPtr); + } + + return NULL; + } + + Len = 0; + SourceFile->FileBufferPtr++; + Start = Ptr = SourceFile->FileBufferPtr; + PreviousBackslash = FALSE; + while (!EndOfFile (SourceFile)) { + if ((SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) && (!PreviousBackslash)) { + break; + } else if (SourceFile->FileBufferPtr[0] == UNICODE_CR) { + Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start); + PreviousBackslash = FALSE; + } else if (SourceFile->FileBufferPtr[0] == UNICODE_BACKSLASH) { + PreviousBackslash = TRUE; + } else { + PreviousBackslash = FALSE; + } + + SourceFile->FileBufferPtr++; + Len++; + } + + if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) { + Warning (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing quote on string", "%S", Start); + } else { + SourceFile->FileBufferPtr++; + } + // + // Now allocate memory for the string and save it off + // + String = (WCHAR *) malloc ((Len + 1) * sizeof (WCHAR)); + if (String == NULL) { + Error (NULL, 0, 0, "memory allocation failed", NULL); + return NULL; + } + // + // Copy the string from the file buffer to the local copy. + // We do no reformatting of it whatsoever at this point. + // + Ptr = String; + while (Len > 0) { + *Ptr = *Start; + Start++; + Ptr++; + Len--; + } + + *Ptr = 0; + return String; +} +// +// Parse: +// #string STR_ID_NAME +// +// All we can do is call the string database to add the string identifier. Unfortunately +// he'll have to keep track of the last identifier we added. +// +static +void +ProcessTokenString ( + SOURCE_FILE *SourceFile + ) +{ + WCHAR StringIdentifier[MAX_STRING_IDENTIFIER_NAME]; + UINT16 StringId; + // + // Extract the string identifier name and add it to the database. + // + if (GetStringIdentifierName (SourceFile, StringIdentifier, sizeof (StringIdentifier)) > 0) { + StringId = STRING_ID_INVALID; + StringDBAddStringIdentifier (StringIdentifier, &StringId, 0); + } else { + // + // Error recovery -- skip to the next # + // + SourceFile->SkipToHash = TRUE; + } +} + +static +BOOLEAN +EndOfFile ( + SOURCE_FILE *SourceFile + ) +{ + // + // The file buffer pointer will typically get updated before the End-of-file flag in the + // source file structure, so check it first. + // + if (SourceFile->FileBufferPtr >= SourceFile->FileBuffer + SourceFile->FileSize / sizeof (WCHAR)) { + SourceFile->EndOfFile = TRUE; + return TRUE; + } + + if (SourceFile->EndOfFile) { + return TRUE; + } + + return FALSE; +} + +static +UINT32 +GetStringIdentifierName ( + IN SOURCE_FILE *SourceFile, + IN OUT WCHAR *StringIdentifierName, + IN UINT32 StringIdentifierNameLen + ) +{ + UINT32 Len; + WCHAR *From; + WCHAR *Start; + + // + // Skip whitespace + // + SkipWhiteSpace (SourceFile); + if (SourceFile->EndOfFile) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-file encountered", "expected string identifier"); + return 0; + } + // + // Verify first character of name is [A-Za-z] + // + Len = 0; + StringIdentifierNameLen /= 2; + From = SourceFile->FileBufferPtr; + Start = SourceFile->FileBufferPtr; + if (((SourceFile->FileBufferPtr[0] >= UNICODE_A) && (SourceFile->FileBufferPtr[0] <= UNICODE_Z)) || + ((SourceFile->FileBufferPtr[0] >= UNICODE_z) && (SourceFile->FileBufferPtr[0] <= UNICODE_z)) + ) { + // + // Do nothing + // + } else { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid character in string identifier name", "%S", Start); + return 0; + } + + while (!EndOfFile (SourceFile)) { + if (((SourceFile->FileBufferPtr[0] >= UNICODE_A) && (SourceFile->FileBufferPtr[0] <= UNICODE_Z)) || + ((SourceFile->FileBufferPtr[0] >= UNICODE_z) && (SourceFile->FileBufferPtr[0] <= UNICODE_z)) || + ((SourceFile->FileBufferPtr[0] >= UNICODE_0) && (SourceFile->FileBufferPtr[0] <= UNICODE_9)) || + (SourceFile->FileBufferPtr[0] == UNICODE_UNDERSCORE) + ) { + Len++; + if (Len >= StringIdentifierNameLen) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "string identifier name too long", "%S", Start); + return 0; + } + + *StringIdentifierName = SourceFile->FileBufferPtr[0]; + StringIdentifierName++; + SourceFile->FileBufferPtr++; + } else if (SkipWhiteSpace (SourceFile) == 0) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid string identifier name", "%S", Start); + return 0; + } else { + break; + } + } + // + // Terminate the copy of the string. + // + *StringIdentifierName = 0; + return Len; +} + +static +UINT32 +GetLanguageIdentifierName ( + IN SOURCE_FILE *SourceFile, + IN OUT WCHAR *LanguageIdentifierName, + IN UINT32 LanguageIdentifierNameLen, + IN BOOLEAN Optional + ) +{ + UINT32 Len; + WCHAR *From; + WCHAR *Start; + // + // Skip whitespace + // + SkipWhiteSpace (SourceFile); + if (SourceFile->EndOfFile) { + if (!Optional) { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + "end-of-file encountered", + "expected language identifier" + ); + } + + return 0; + } + // + // This function is called to optionally get a language identifier name in: + // #string STR_ID eng "the string" + // If it's optional, and we find a double-quote, then return now. + // + if (Optional) { + if (*SourceFile->FileBufferPtr == UNICODE_DOUBLE_QUOTE) { + return 0; + } + } + + Len = 0; + LanguageIdentifierNameLen /= 2; + // + // Internal error if we weren't given at least 4 WCHAR's to work with. + // + if (LanguageIdentifierNameLen < LANGUAGE_IDENTIFIER_NAME_LEN + 1) { + Error ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + "app error -- language identifier name length is invalid", + NULL + ); + } + + From = SourceFile->FileBufferPtr; + Start = SourceFile->FileBufferPtr; + while (!EndOfFile (SourceFile)) { + if (((SourceFile->FileBufferPtr[0] >= UNICODE_a) && (SourceFile->FileBufferPtr[0] <= UNICODE_z))) { + Len++; + if (Len > LANGUAGE_IDENTIFIER_NAME_LEN) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "language identifier name too long", "%S", Start); + return 0; + } + + *LanguageIdentifierName = SourceFile->FileBufferPtr[0]; + SourceFile->FileBufferPtr++; + LanguageIdentifierName++; + } else if (!IsWhiteSpace (SourceFile)) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid language identifier name", "%S", Start); + return 0; + } else { + break; + } + } + // + // Terminate the copy of the string. + // + *LanguageIdentifierName = 0; + return Len; +} + +static +void +ProcessTokenInclude ( + SOURCE_FILE *SourceFile + ) +{ + CHAR8 IncludeFileName[MAX_PATH]; + CHAR8 *To; + UINT32 Len; + BOOLEAN ReportedError; + SOURCE_FILE IncludedSourceFile; + + ReportedError = FALSE; + if (SkipWhiteSpace (SourceFile) == 0) { + Warning (SourceFile->FileName, SourceFile->LineNum, 0, "expected whitespace following #include keyword", NULL); + } + // + // Should be quoted file name + // + if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted include file name", NULL); + goto FailDone; + } + + SourceFile->FileBufferPtr++; + // + // Copy the filename as ascii to our local string + // + To = IncludeFileName; + Len = 0; + while (!EndOfFile (SourceFile)) { + if ((SourceFile->FileBufferPtr[0] == UNICODE_CR) || (SourceFile->FileBufferPtr[0] == UNICODE_LF)) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-line found in quoted include file name", NULL); + goto FailDone; + } + + if (SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) { + SourceFile->FileBufferPtr++; + break; + } + // + // If too long, then report the error once and process until the closing quote + // + Len++; + if (!ReportedError && (Len >= sizeof (IncludeFileName))) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "length of include file name exceeds limit", NULL); + ReportedError = TRUE; + } + + if (!ReportedError) { + *To = UNICODE_TO_ASCII (SourceFile->FileBufferPtr[0]); + To++; + } + + SourceFile->FileBufferPtr++; + } + + if (!ReportedError) { + *To = 0; + memset ((char *) &IncludedSourceFile, 0, sizeof (SOURCE_FILE)); + strcpy (IncludedSourceFile.FileName, IncludeFileName); + IncludedSourceFile.ControlCharacter = DEFAULT_CONTROL_CHARACTER; + ProcessIncludeFile (&IncludedSourceFile, SourceFile); + // + // printf ("including file '%s'\n", IncludeFileName); + // + } + + return ; +FailDone: + // + // Error recovery -- skip to next # + // + SourceFile->SkipToHash = TRUE; +} + +static +void +ProcessTokenScope ( + SOURCE_FILE *SourceFile + ) +{ + WCHAR StringIdentifier[MAX_STRING_IDENTIFIER_NAME]; + // + // Extract the scope name + // + if (GetStringIdentifierName (SourceFile, StringIdentifier, sizeof (StringIdentifier)) > 0) { + StringDBSetScope (StringIdentifier); + } +} +// +// Parse: #langdef eng "English" +// #langdef chn "\wideChinese" +// +static +void +ProcessTokenLangDef ( + SOURCE_FILE *SourceFile + ) +{ + WCHAR LanguageIdentifier[MAX_STRING_IDENTIFIER_NAME]; + UINT32 Len; + WCHAR *PrintableName; + // + // Extract the 3-character language identifier + // + Len = GetLanguageIdentifierName (SourceFile, LanguageIdentifier, sizeof (LanguageIdentifier), FALSE); + if (Len != LANGUAGE_IDENTIFIER_NAME_LEN) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid or missing language identifier", NULL); + } else { + // + // Extract the printable name + // + PrintableName = GetPrintableLanguageName (SourceFile); + if (PrintableName != NULL) { + ParserSetPosition (SourceFile->FileName, SourceFile->LineNum); + StringDBAddLanguage (LanguageIdentifier, PrintableName); + free (PrintableName); + return ; + } + } + // + // Error recovery -- skip to next # + // + SourceFile->SkipToHash = TRUE; +} + +static +BOOLEAN +ApparentQuotedString ( + SOURCE_FILE *SourceFile + ) +{ + WCHAR *Ptr; + // + // See if the first and last nonblank characters on the line are double quotes + // + for (Ptr = SourceFile->FileBufferPtr; *Ptr && (*Ptr == UNICODE_SPACE); Ptr++) + ; + if (*Ptr != UNICODE_DOUBLE_QUOTE) { + return FALSE; + } + + while (*Ptr) { + Ptr++; + } + + Ptr--; + for (; *Ptr && (*Ptr == UNICODE_SPACE); Ptr--) + ; + if (*Ptr != UNICODE_DOUBLE_QUOTE) { + return FALSE; + } + + return TRUE; +} +// +// Parse: +// #language eng "some string " "more string" +// +static +void +ProcessTokenLanguage ( + SOURCE_FILE *SourceFile + ) +{ + WCHAR *String; + WCHAR *SecondString; + WCHAR *TempString; + WCHAR *From; + WCHAR *To; + WCHAR Language[LANGUAGE_IDENTIFIER_NAME_LEN + 1]; + UINT32 Len; + BOOLEAN PreviousNewline; + // + // Get the language identifier + // + Language[0] = 0; + Len = GetLanguageIdentifierName (SourceFile, Language, sizeof (Language), TRUE); + if (Len != LANGUAGE_IDENTIFIER_NAME_LEN) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid or missing language identifier", "%S", Language); + SourceFile->SkipToHash = TRUE; + return ; + } + // + // Extract the string value. It's either a quoted string that starts on the current line, or + // an unquoted string that starts on the following line and continues until the next control + // character in column 1. + // Look ahead to find a quote or a newline + // + if (SkipTo (SourceFile, UNICODE_DOUBLE_QUOTE, TRUE)) { + String = GetQuotedString (SourceFile, FALSE); + if (String != NULL) { + // + // Set the position in the file of where we are parsing for error + // reporting purposes. Then start looking ahead for additional + // quoted strings, and concatenate them until we get a failure + // back from the string parser. + // + Len = StrLen (String) + 1; + ParserSetPosition (SourceFile->FileName, SourceFile->LineNum); + do { + SkipWhiteSpace (SourceFile); + SecondString = GetQuotedString (SourceFile, TRUE); + if (SecondString != NULL) { + Len += StrLen (SecondString); + TempString = (WCHAR *) malloc (Len * sizeof (WCHAR)); + if (TempString == NULL) { + Error (NULL, 0, 0, "application error", "failed to allocate memory"); + return ; + } + + StrCpy (TempString, String); + StrCat (TempString, SecondString); + free (String); + free (SecondString); + String = TempString; + } + } while (SecondString != NULL); + StringDBAddString (Language, NULL, NULL, String, TRUE, 0); + free (String); + } else { + // + // Error was reported at lower level. Error recovery mode. + // + SourceFile->SkipToHash = TRUE; + } + } else { + if (!mGlobals.UnquotedStrings) { + // + // They're using unquoted strings. If the next non-blank character is a double quote, and the + // last non-blank character on the line is a double quote, then more than likely they're using + // quotes, so they need to put the quoted string on the end of the previous line + // + if (ApparentQuotedString (SourceFile)) { + Warning ( + SourceFile->FileName, + SourceFile->LineNum, + 0, + "unexpected quoted string on line", + "specify -uqs option if necessary" + ); + } + } + // + // Found end-of-line (hopefully). Skip over it and start taking in characters + // until we find a control character at the start of a line. + // + Len = 0; + From = SourceFile->FileBufferPtr; + PreviousNewline = FALSE; + while (!EndOfFile (SourceFile)) { + if (SourceFile->FileBufferPtr[0] == UNICODE_LF) { + PreviousNewline = TRUE; + SourceFile->LineNum++; + } else { + Len++; + if (PreviousNewline && (SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter)) { + break; + } + + PreviousNewline = FALSE; + } + + SourceFile->FileBufferPtr++; + } + + if ((Len == 0) && EndOfFile (SourceFile)) { + Error (SourceFile->FileName, SourceFile->LineNum, 0, "unexpected end of file", NULL); + SourceFile->SkipToHash = TRUE; + return ; + } + // + // Now allocate a buffer, copy the characters, and add the string. + // + String = (WCHAR *) malloc ((Len + 1) * sizeof (WCHAR)); + if (String == NULL) { + Error (NULL, 0, 0, "application error", "failed to allocate memory"); + return ; + } + + To = String; + while (From < SourceFile->FileBufferPtr) { + switch (*From) { + case UNICODE_LF: + case 0: + break; + + default: + *To = *From; + To++; + break; + } + + From++; + } + + // + // String[Len] = 0; + // + *To = 0; + StringDBAddString (Language, NULL, NULL, String, TRUE, 0); + } +} + +static +BOOLEAN +IsWhiteSpace ( + SOURCE_FILE *SourceFile + ) +{ + switch (SourceFile->FileBufferPtr[0]) { + case UNICODE_NULL: + case UNICODE_CR: + case UNICODE_SPACE: + case UNICODE_TAB: + case UNICODE_LF: + return TRUE; + + default: + return FALSE; + } +} + +static +UINT32 +SkipWhiteSpace ( + SOURCE_FILE *SourceFile + ) +{ + UINT32 Count; + + Count = 0; + while (!EndOfFile (SourceFile)) { + Count++; + switch (*SourceFile->FileBufferPtr) { + case UNICODE_NULL: + case UNICODE_CR: + case UNICODE_SPACE: + case UNICODE_TAB: + SourceFile->FileBufferPtr++; + break; + + case UNICODE_LF: + SourceFile->FileBufferPtr++; + SourceFile->LineNum++; + if (mGlobals.Verbose) { + printf ("%d: %S\n", SourceFile->LineNum, SourceFile->FileBufferPtr); + } + break; + + default: + return Count - 1; + } + } + // + // Some tokens require trailing whitespace. If we're at the end of the + // file, then we count that as well. + // + if ((Count == 0) && (EndOfFile (SourceFile))) { + Count++; + } + + return Count; +} + +static +UINT32 +wstrcmp ( + WCHAR *Buffer, + WCHAR *Str + ) +{ + UINT32 Len; + + Len = 0; + while (*Str == *Buffer) { + Buffer++; + Str++; + Len++; + } + + if (*Str) { + return 0; + } + + return Len; +} +// +// Given a filename, try to find it along the include paths. +// +static +FILE * +FindFile ( + IN CHAR8 *FileName, + OUT CHAR8 *FoundFileName, + IN UINT32 FoundFileNameLen + ) +{ + FILE *Fptr; + TEXT_STRING_LIST *List; + + // + // Traverse the list of paths and try to find the file + // + List = mGlobals.IncludePaths; + while (List != NULL) { + // + // Put the path and filename together + // + if (strlen (List->Str) + strlen (FileName) + 1 > FoundFileNameLen) { + Error (PROGRAM_NAME, 0, 0, NULL, "internal error - cannot concatenate path+filename"); + return NULL; + } + // + // Append the filename to this include path and try to open the file. + // + strcpy (FoundFileName, List->Str); + strcat (FoundFileName, FileName); + if ((Fptr = fopen (FoundFileName, "rb")) != NULL) { + // + // Return the file pointer + // + return Fptr; + } + + List = List->Next; + } + // + // Not found + // + FoundFileName[0] = 0; + return NULL; +} +// +// Process the command-line arguments +// +static +STATUS +ProcessArgs ( + int Argc, + char *Argv[] + ) +{ + TEXT_STRING_LIST *NewList; + // + // Clear our globals + // + memset ((char *) &mGlobals, 0, sizeof (mGlobals)); + strcpy (mGlobals.BaseName, DEFAULT_BASE_NAME); + // + // Skip program name + // + Argc--; + Argv++; + + if (Argc == 0) { + Usage (); + return STATUS_ERROR; + } + + mGlobals.Mode = MODE_UNKNOWN; + // + // Process until no more -args. + // + while ((Argc > 0) && (Argv[0][0] == '-')) { + // + // -parse option + // + if (stricmp (Argv[0], "-parse") == 0) { + if (mGlobals.Mode != MODE_UNKNOWN) { + Error (NULL, 0, 0, "only one of -parse/-scan/-dump allowed", NULL); + return STATUS_ERROR; + } + + mGlobals.Mode = MODE_PARSE; + // + // -scan option + // + } else if (stricmp (Argv[0], "-scan") == 0) { + if (mGlobals.Mode != MODE_UNKNOWN) { + Error (NULL, 0, 0, "only one of -parse/-scan/-dump allowed", NULL); + return STATUS_ERROR; + } + + mGlobals.Mode = MODE_SCAN; + // + // -vscan verbose scanning option + // + } else if (stricmp (Argv[0], "-vscan") == 0) { + mGlobals.VerboseScan = TRUE; + // + // -dump option + // + } else if (stricmp (Argv[0], "-dump") == 0) { + if (mGlobals.Mode != MODE_UNKNOWN) { + Error (NULL, 0, 0, "only one of -parse/-scan/-dump allowed", NULL); + return STATUS_ERROR; + } + + mGlobals.Mode = MODE_DUMP; + } else if (stricmp (Argv[0], "-uqs") == 0) { + mGlobals.UnquotedStrings = TRUE; + // + // -i path add include search path when parsing + // + } else if (stricmp (Argv[0], "-i") == 0) { + // + // check for one more arg + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing include path"); + return STATUS_ERROR; + } + // + // Allocate memory for a new list element, fill it in, and + // add it to our list of include paths. Always make sure it + // has a "\" on the end of it. + // + NewList = malloc (sizeof (TEXT_STRING_LIST)); + if (NewList == NULL) { + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + + memset ((char *) NewList, 0, sizeof (TEXT_STRING_LIST)); + NewList->Str = malloc (strlen (Argv[1]) + 2); + if (NewList->Str == NULL) { + free (NewList); + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + + strcpy (NewList->Str, Argv[1]); + if (NewList->Str[strlen (NewList->Str) - 1] != '\\') { + strcat (NewList->Str, "\\"); + } + // + // Add it to our linked list + // + if (mGlobals.IncludePaths == NULL) { + mGlobals.IncludePaths = NewList; + } else { + mGlobals.LastIncludePath->Next = NewList; + } + + mGlobals.LastIncludePath = NewList; + Argc--; + Argv++; + } else if (stricmp (Argv[0], "-if") == 0) { + // + // Indirection file -- check for one more arg + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing indirection file name"); + return STATUS_ERROR; + } + // + // Allocate memory for a new list element, fill it in, and + // add it to our list of include paths. Always make sure it + // has a "\" on the end of it. + // + NewList = malloc (sizeof (TEXT_STRING_LIST)); + if (NewList == NULL) { + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + + memset ((char *) NewList, 0, sizeof (TEXT_STRING_LIST)); + NewList->Str = malloc (strlen (Argv[1]) + 1); + if (NewList->Str == NULL) { + free (NewList); + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + + strcpy (NewList->Str, Argv[1]); + // + // Add it to our linked list + // + if (mGlobals.IndirectionFileName == NULL) { + mGlobals.IndirectionFileName = NewList; + } else { + mGlobals.LastIndirectionFileName->Next = NewList; + } + + mGlobals.LastIndirectionFileName = NewList; + Argc--; + Argv++; + } else if (stricmp (Argv[0], "-db") == 0) { + // + // -db option to specify a database file. + // Check for one more arg (the database file name) + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing database file name"); + return STATUS_ERROR; + } + + NewList = malloc (sizeof (TEXT_STRING_LIST)); + if (NewList == NULL) { + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + + memset ((char *) NewList, 0, sizeof (TEXT_STRING_LIST)); + NewList->Str = malloc (strlen (Argv[1]) + 1); + if (NewList->Str == NULL) { + free (NewList); + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + + strcpy (NewList->Str, Argv[1]); + // + // Add it to our linked list + // + if (mGlobals.DatabaseFileName == NULL) { + mGlobals.DatabaseFileName = NewList; + } else { + mGlobals.LastDatabaseFileName->Next = NewList; + } + + mGlobals.LastDatabaseFileName = NewList; + Argc--; + Argv++; + } else if (stricmp (Argv[0], "-ou") == 0) { + // + // -ou option to specify an output unicode file to + // which we can dump our database. + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing database dump output file name"); + return STATUS_ERROR; + } + + if (mGlobals.DumpUFileName[0] == 0) { + strcpy (mGlobals.DumpUFileName, Argv[1]); + } else { + Error (PROGRAM_NAME, 0, 0, Argv[1], "-ou option already specified with '%s'", mGlobals.DumpUFileName); + return STATUS_ERROR; + } + + Argc--; + Argv++; + } else if (stricmp (Argv[0], "-hpk") == 0) { + // + // -hpk option to create an HII export pack of the input database file + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing raw string data dump output file name"); + return STATUS_ERROR; + } + + if (mGlobals.HiiExportPackFileName[0] == 0) { + strcpy (mGlobals.HiiExportPackFileName, Argv[1]); + } else { + Error (PROGRAM_NAME, 0, 0, Argv[1], "-or option already specified with '%s'", mGlobals.HiiExportPackFileName); + return STATUS_ERROR; + } + + Argc--; + Argv++; + } else if ((stricmp (Argv[0], "-?") == 0) || (stricmp (Argv[0], "-h") == 0)) { + Usage (); + return STATUS_ERROR; + } else if (stricmp (Argv[0], "-v") == 0) { + mGlobals.Verbose = 1; + } else if (stricmp (Argv[0], "-vdbw") == 0) { + mGlobals.VerboseDatabaseWrite = 1; + } else if (stricmp (Argv[0], "-vdbr") == 0) { + mGlobals.VerboseDatabaseRead = 1; + } else if (stricmp (Argv[0], "-newdb") == 0) { + mGlobals.NewDatabase = 1; + } else if (stricmp (Argv[0], "-ignorenotfound") == 0) { + mGlobals.IgnoreNotFound = 1; + } else if (stricmp (Argv[0], "-oc") == 0) { + // + // check for one more arg + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing output C filename"); + return STATUS_ERROR; + } + + strcpy (mGlobals.StringCFileName, Argv[1]); + Argc--; + Argv++; + } else if (stricmp (Argv[0], "-bn") == 0) { + // + // check for one more arg + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing base name"); + Usage (); + return STATUS_ERROR; + } + + strcpy (mGlobals.BaseName, Argv[1]); + Argc--; + Argv++; + } else if (stricmp (Argv[0], "-oh") == 0) { + // + // -oh to specify output .h defines file name + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing output .h filename"); + return STATUS_ERROR; + } + + strcpy (mGlobals.StringHFileName, Argv[1]); + Argc--; + Argv++; + } else if (stricmp (Argv[0], "-skipext") == 0) { + // + // -skipext to skip scanning of files with certain filename extensions + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing filename extension"); + return STATUS_ERROR; + } + // + // Allocate memory for a new list element, fill it in, and + // add it to our list of excluded extensions. Always make sure it + // has a "." as the first character. + // + NewList = malloc (sizeof (TEXT_STRING_LIST)); + if (NewList == NULL) { + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + + memset ((char *) NewList, 0, sizeof (TEXT_STRING_LIST)); + NewList->Str = malloc (strlen (Argv[1]) + 2); + if (NewList->Str == NULL) { + free (NewList); + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + + if (Argv[1][0] == '.') { + strcpy (NewList->Str, Argv[1]); + } else { + NewList->Str[0] = '.'; + strcpy (NewList->Str + 1, Argv[1]); + } + // + // Add it to our linked list + // + if (mGlobals.SkipExt == NULL) { + mGlobals.SkipExt = NewList; + } else { + mGlobals.LastSkipExt->Next = NewList; + } + + mGlobals.LastSkipExt = NewList; + Argc--; + Argv++; + } else if (stricmp (Argv[0], "-lang") == 0) { + // + // "-lang eng" or "-lang spa+cat" to only output certain languages + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing language name"); + Usage (); + return STATUS_ERROR; + } + + if (AddCommandLineLanguage (Argv[1]) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + Argc--; + Argv++; + } else if (stricmp (Argv[0], "-od") == 0) { + // + // Output database file name -- check for another arg + // + if ((Argc <= 1) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing output database file name"); + return STATUS_ERROR; + } + + strcpy (mGlobals.OutputDatabaseFileName, Argv[1]); + Argv++; + Argc--; + } else { + // + // Unrecognized arg + // + Error (PROGRAM_NAME, 0, 0, Argv[0], "unrecognized option"); + Usage (); + return STATUS_ERROR; + } + + Argv++; + Argc--; + } + // + // Make sure they specified the mode parse/scan/dump + // + if (mGlobals.Mode == MODE_UNKNOWN) { + Error (NULL, 0, 0, "must specify one of -parse/-scan/-dump", NULL); + return STATUS_ERROR; + } + // + // All modes require a database filename + // + if (mGlobals.DatabaseFileName == 0) { + Error (NULL, 0, 0, "must specify a database filename using -db DbFileName", NULL); + Usage (); + return STATUS_ERROR; + } + // + // If dumping the database file, then return immediately if all + // parameters check out. + // + if (mGlobals.Mode == MODE_DUMP) { + // + // Not much use if they didn't specify -oh or -oc or -ou or -hpk + // + if ((mGlobals.DumpUFileName[0] == 0) && + (mGlobals.StringHFileName[0] == 0) && + (mGlobals.StringCFileName[0] == 0) && + (mGlobals.HiiExportPackFileName[0] == 0) + ) { + Error (NULL, 0, 0, "-dump without -oc/-oh/-ou/-hpk is a NOP", NULL); + return STATUS_ERROR; + } + + return STATUS_SUCCESS; + } + // + // Had to specify source string file and output string defines header filename. + // + if (mGlobals.Mode == MODE_SCAN) { + if (Argc < 1) { + Error (PROGRAM_NAME, 0, 0, NULL, "must specify at least one source file to scan with -scan"); + Usage (); + return STATUS_ERROR; + } + // + // Get the list of filenames + // + while (Argc > 0) { + NewList = malloc (sizeof (TEXT_STRING_LIST)); + if (NewList == NULL) { + Error (PROGRAM_NAME, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + memset (NewList, 0, sizeof (TEXT_STRING_LIST)); + NewList->Str = (CHAR8 *) malloc (strlen (Argv[0]) + 1); + if (NewList->Str == NULL) { + Error (PROGRAM_NAME, 0, 0, "memory allocation failure", NULL); + return STATUS_ERROR; + } + + strcpy (NewList->Str, Argv[0]); + if (mGlobals.ScanFileName == NULL) { + mGlobals.ScanFileName = NewList; + } else { + mGlobals.LastScanFileName->Next = NewList; + } + + mGlobals.LastScanFileName = NewList; + Argc--; + Argv++; + } + } else { + // + // Parse mode -- must specify an input unicode file name + // + if (Argc < 1) { + Error (PROGRAM_NAME, 0, 0, NULL, "must specify input unicode string file name with -parse"); + Usage (); + return STATUS_ERROR; + } + + strcpy (mGlobals.SourceFiles.FileName, Argv[0]); + } + + return STATUS_SUCCESS; +} +// +// Found "-lang eng,spa+cat" on the command line. Parse the +// language list and save the setting for later processing. +// +static +STATUS +AddCommandLineLanguage ( + IN CHAR8 *Language + ) +{ + WCHAR_STRING_LIST *WNewList; + WCHAR *From; + WCHAR *To; + // + // Keep processing the input string until we find the end. + // + while (*Language) { + // + // Allocate memory for a new list element, fill it in, and + // add it to our list. + // + WNewList = MALLOC (sizeof (WCHAR_STRING_LIST)); + if (WNewList == NULL) { + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + + memset ((char *) WNewList, 0, sizeof (WCHAR_STRING_LIST)); + WNewList->Str = malloc ((strlen (Language) + 1) * sizeof (WCHAR)); + if (WNewList->Str == NULL) { + free (WNewList); + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + // + // Copy it as unicode to our new structure. Then remove the + // plus signs in it, and verify each language name is 3 characters + // long. If we find a comma, then we're done with this group, so + // break out. + // + UnicodeSPrint (WNewList->Str, (strlen (Language) + 1) * sizeof (WCHAR), L"%a", Language); + From = To = WNewList->Str; + while (*From) { + if (*From == L',') { + break; + } + + if ((StrLen (From) < LANGUAGE_IDENTIFIER_NAME_LEN) || + ( + (From[LANGUAGE_IDENTIFIER_NAME_LEN] != 0) && + (From[LANGUAGE_IDENTIFIER_NAME_LEN] != UNICODE_PLUS_SIGN) && + (From[LANGUAGE_IDENTIFIER_NAME_LEN] != L',') + ) + ) { + Error (PROGRAM_NAME, 0, 0, Language, "invalid format for language name on command line"); + FREE (WNewList->Str); + FREE (WNewList); + return STATUS_ERROR; + } + + StrnCpy (To, From, LANGUAGE_IDENTIFIER_NAME_LEN); + To += LANGUAGE_IDENTIFIER_NAME_LEN; + From += LANGUAGE_IDENTIFIER_NAME_LEN; + if (*From == L'+') { + From++; + } + } + + *To = 0; + // + // Add it to our linked list + // + if (mGlobals.Language == NULL) { + mGlobals.Language = WNewList; + } else { + mGlobals.LastLanguage->Next = WNewList; + } + + mGlobals.LastLanguage = WNewList; + // + // Skip to next entry (comma-separated list) + // + while (*Language) { + if (*Language == L',') { + Language++; + break; + } + + Language++; + } + } + + return STATUS_SUCCESS; +} +// +// The contents of the text file are expected to be (one per line) +// STRING_IDENTIFIER_NAME ScopeName +// For example: +// STR_ID_MY_FAVORITE_STRING IBM +// +static +STATUS +ParseIndirectionFiles ( + TEXT_STRING_LIST *Files + ) +{ + FILE *Fptr; + CHAR8 Line[200]; + CHAR8 *StringName; + CHAR8 *ScopeName; + CHAR8 *End; + UINT32 LineCount; + WCHAR_MATCHING_STRING_LIST *NewList; + + Line[sizeof (Line) - 1] = 0; + Fptr = NULL; + while (Files != NULL) { + Fptr = fopen (Files->Str, "r"); + LineCount = 0; + if (Fptr == NULL) { + Error (NULL, 0, 0, Files->Str, "failed to open input indirection file for reading"); + return STATUS_ERROR; + } + + while (fgets (Line, sizeof (Line), Fptr) != NULL) { + // + // remove terminating newline for error printing purposes. + // + if (Line[strlen (Line) - 1] == '\n') { + Line[strlen (Line) - 1] = 0; + } + + LineCount++; + if (Line[sizeof (Line) - 1] != 0) { + Error (Files->Str, LineCount, 0, "line length exceeds maximum supported", NULL); + goto Done; + } + + StringName = Line; + while (*StringName && (isspace (*StringName))) { + StringName++; + } + + if (*StringName) { + if ((*StringName == '_') || isalpha (*StringName)) { + End = StringName; + while ((*End) && (*End == '_') || (isalnum (*End))) { + End++; + } + + if (isspace (*End)) { + *End = 0; + End++; + while (isspace (*End)) { + End++; + } + + if (*End) { + ScopeName = End; + while (*End && !isspace (*End)) { + End++; + } + + *End = 0; + // + // Add the string name/scope pair + // + NewList = malloc (sizeof (WCHAR_MATCHING_STRING_LIST)); + if (NewList == NULL) { + Error (NULL, 0, 0, "memory allocation error", NULL); + goto Done; + } + + memset (NewList, 0, sizeof (WCHAR_MATCHING_STRING_LIST)); + NewList->Str1 = (WCHAR *) malloc ((strlen (StringName) + 1) * sizeof (WCHAR)); + NewList->Str2 = (WCHAR *) malloc ((strlen (ScopeName) + 1) * sizeof (WCHAR)); + if ((NewList->Str1 == NULL) || (NewList->Str2 == NULL)) { + Error (NULL, 0, 0, "memory allocation error", NULL); + goto Done; + } + + UnicodeSPrint (NewList->Str1, strlen (StringName) + 1, L"%a", StringName); + UnicodeSPrint (NewList->Str2, strlen (ScopeName) + 1, L"%a", ScopeName); + if (mGlobals.IndirectionList == NULL) { + mGlobals.IndirectionList = NewList; + } else { + mGlobals.LastIndirectionList->Next = NewList; + } + + mGlobals.LastIndirectionList = NewList; + } else { + Error (Files->Str, LineCount, 0, StringName, "invalid line : expected 'StringIdentifier Scope'"); + goto Done; + } + } else { + Error (Files->Str, LineCount, 0, StringName, "invalid line : expected 'StringIdentifier Scope'"); + goto Done; + } + } else { + Error (Files->Str, LineCount, 0, StringName, "invalid string identifier"); + goto Done; + } + } + } + + fclose (Fptr); + Fptr = NULL; + Files = Files->Next; + } + +Done: + if (Fptr != NULL) { + fclose (Fptr); + return STATUS_ERROR; + } + + return STATUS_SUCCESS; +} + +static +STATUS +ScanFiles ( + TEXT_STRING_LIST *ScanFiles + ) +{ + char Line[MAX_LINE_LEN]; + FILE *Fptr; + UINT32 LineNum; + char *Cptr; + char *SavePtr; + char *TermPtr; + char *StringTokenPos; + TEXT_STRING_LIST *SList; + BOOLEAN SkipIt; + + // + // Put a null-terminator at the end of the line. If we read in + // a line longer than we support, then we can catch it. + // + Line[MAX_LINE_LEN - 1] = 0; + // + // Process each file. If they gave us a skip extension list, then + // skip it if the extension matches. + // + while (ScanFiles != NULL) { + SkipIt = FALSE; + for (SList = mGlobals.SkipExt; SList != NULL; SList = SList->Next) { + if ((strlen (ScanFiles->Str) > strlen (SList->Str)) && + (strcmp (ScanFiles->Str + strlen (ScanFiles->Str) - strlen (SList->Str), SList->Str) == 0) + ) { + SkipIt = TRUE; + // + // printf ("Match: %s : %s\n", ScanFiles->Str, SList->Str); + // + break; + } + } + + if (!SkipIt) { + if (mGlobals.VerboseScan) { + printf ("Scanning %s\n", ScanFiles->Str); + } + + Fptr = fopen (ScanFiles->Str, "r"); + if (Fptr == NULL) { + Error (NULL, 0, 0, ScanFiles->Str, "failed to open input file for scanning"); + return STATUS_ERROR; + } + + LineNum = 0; + while (fgets (Line, sizeof (Line), Fptr) != NULL) { + LineNum++; + if (Line[MAX_LINE_LEN - 1] != 0) { + Error (ScanFiles->Str, LineNum, 0, "line length exceeds maximum supported by tool", NULL); + fclose (Fptr); + return STATUS_ERROR; + } + // + // Remove the newline from the input line so we can print a warning message + // + if (Line[strlen (Line) - 1] == '\n') { + Line[strlen (Line) - 1] = 0; + } + // + // Terminate the line at // comments + // + Cptr = strstr (Line, "//"); + if (Cptr != NULL) { + *Cptr = 0; + } + + Cptr = Line; + while ((Cptr = strstr (Cptr, STRING_TOKEN)) != NULL) { + // + // Found "STRING_TOKEN". Make sure we don't have NUM_STRING_TOKENS or + // something like that. Then make sure it's followed by + // an open parenthesis, a string identifier, and then a closing + // parenthesis. + // + if (mGlobals.VerboseScan) { + printf (" %d: %s", LineNum, Cptr); + } + + if (((Cptr == Line) || (!IsValidIdentifierChar (*(Cptr - 1), FALSE))) && + (!IsValidIdentifierChar (*(Cptr + sizeof (STRING_TOKEN) - 1), FALSE)) + ) { + StringTokenPos = Cptr; + SavePtr = Cptr; + Cptr += strlen (STRING_TOKEN); + while (*Cptr && isspace (*Cptr) && (*Cptr != '(')) { + Cptr++; + } + + if (*Cptr != '(') { + Warning (ScanFiles->Str, LineNum, 0, StringTokenPos, "expected "STRING_TOKEN "(identifier)"); + } else { + // + // Skip over the open-parenthesis and find the next non-blank character + // + Cptr++; + while (isspace (*Cptr)) { + Cptr++; + } + + SavePtr = Cptr; + if ((*Cptr == '_') || isalpha (*Cptr)) { + while ((*Cptr == '_') || (isalnum (*Cptr))) { + Cptr++; + } + + TermPtr = Cptr; + while (*Cptr && isspace (*Cptr)) { + Cptr++; + } + + if (*Cptr != ')') { + Warning (ScanFiles->Str, LineNum, 0, StringTokenPos, "expected "STRING_TOKEN "(identifier)"); + } + + if (*TermPtr) { + *TermPtr = 0; + Cptr = TermPtr + 1; + } else { + Cptr = TermPtr; + } + // + // Add the string identifier to the list of used strings + // + ParserSetPosition (ScanFiles->Str, LineNum); + StringDBSetStringReferenced (SavePtr, mGlobals.IgnoreNotFound); + if (mGlobals.VerboseScan) { + printf ("...referenced %s", SavePtr); + } + } else { + Warning (ScanFiles->Str, LineNum, 0, StringTokenPos, "expected valid string identifier name"); + } + } + } else { + // + // Found it, but it's a substring of something else. Advance our pointer. + // + Cptr++; + } + + if (mGlobals.VerboseScan) { + printf ("\n"); + } + } + } + + fclose (Fptr); + } else { + // + // Skipping this file type + // + if (mGlobals.VerboseScan) { + printf ("Skip scanning of %s\n", ScanFiles->Str); + } + } + + ScanFiles = ScanFiles->Next; + } + + return STATUS_SUCCESS; +} +// +// Free the global string lists we allocated memory for +// +static +void +FreeLists ( + VOID + ) +{ + TEXT_STRING_LIST *Temp; + WCHAR_STRING_LIST *WTemp; + + // + // Traverse the include paths, freeing each + // + while (mGlobals.IncludePaths != NULL) { + Temp = mGlobals.IncludePaths->Next; + free (mGlobals.IncludePaths->Str); + free (mGlobals.IncludePaths); + mGlobals.IncludePaths = Temp; + } + // + // If we did a scan, then free up our + // list of files to scan. + // + while (mGlobals.ScanFileName != NULL) { + Temp = mGlobals.ScanFileName->Next; + free (mGlobals.ScanFileName->Str); + free (mGlobals.ScanFileName); + mGlobals.ScanFileName = Temp; + } + // + // If they gave us a list of filename extensions to + // skip on scan, then free them up. + // + while (mGlobals.SkipExt != NULL) { + Temp = mGlobals.SkipExt->Next; + free (mGlobals.SkipExt->Str); + free (mGlobals.SkipExt); + mGlobals.SkipExt = Temp; + } + // + // Free up any languages specified + // + while (mGlobals.Language != NULL) { + WTemp = mGlobals.Language->Next; + free (mGlobals.Language->Str); + free (mGlobals.Language); + mGlobals.Language = WTemp; + } + // + // Free up our indirection list + // + while (mGlobals.IndirectionList != NULL) { + mGlobals.LastIndirectionList = mGlobals.IndirectionList->Next; + free (mGlobals.IndirectionList->Str1); + free (mGlobals.IndirectionList->Str2); + free (mGlobals.IndirectionList); + mGlobals.IndirectionList = mGlobals.LastIndirectionList; + } + + while (mGlobals.IndirectionFileName != NULL) { + mGlobals.LastIndirectionFileName = mGlobals.IndirectionFileName->Next; + free (mGlobals.IndirectionFileName->Str); + free (mGlobals.IndirectionFileName); + mGlobals.IndirectionFileName = mGlobals.LastIndirectionFileName; + } +} + +static +BOOLEAN +IsValidIdentifierChar ( + CHAR8 Char, + BOOLEAN FirstChar + ) +{ + // + // If it's the first character of an identifier, then + // it must be one of [A-Za-z_]. + // + if (FirstChar) { + if (isalpha (Char) || (Char == '_')) { + return TRUE; + } + } else { + // + // If it's not the first character, then it can + // be one of [A-Za-z_0-9] + // + if (isalnum (Char) || (Char == '_')) { + return TRUE; + } + } + + return FALSE; +} + +static +void +RewindFile ( + SOURCE_FILE *SourceFile + ) +{ + SourceFile->LineNum = 1; + SourceFile->FileBufferPtr = SourceFile->FileBuffer; + SourceFile->EndOfFile = 0; +} + +static +BOOLEAN +SkipTo ( + SOURCE_FILE *SourceFile, + WCHAR WChar, + BOOLEAN StopAfterNewline + ) +{ + while (!EndOfFile (SourceFile)) { + // + // Check for the character of interest + // + if (SourceFile->FileBufferPtr[0] == WChar) { + return TRUE; + } else { + if (SourceFile->FileBufferPtr[0] == UNICODE_LF) { + SourceFile->LineNum++; + if (StopAfterNewline) { + SourceFile->FileBufferPtr++; + if (SourceFile->FileBufferPtr[0] == 0) { + SourceFile->FileBufferPtr++; + } + + return FALSE; + } + } + + SourceFile->FileBufferPtr++; + } + } + + return FALSE; +} + +static +void +Usage ( + VOID + ) +/*++ + +Routine Description: + + Print usage information for this utility. + +Arguments: + + None. + +Returns: + + Nothing. + +--*/ +{ + int Index; + static const char *Str[] = { + "", + PROGRAM_NAME " version "TOOL_VERSION " -- process unicode strings file", + " Usage: "PROGRAM_NAME " -parse {parse options} [FileNames]", + " "PROGRAM_NAME " -scan {scan options} [FileName]", + " "PROGRAM_NAME " -dump {dump options}", + " Common options include:", + " -h or -? for this help information", + " -db Database required name of output/input database file", + " -bn BaseName for use in the .h and .c output files", + " Default = "DEFAULT_BASE_NAME, + " -v for verbose output", + " -vdbw for verbose output when writing database", + " -vdbr for verbose output when reading database", + " -od FileName to specify an output database file name", + " Parse options include:", + " -i IncludePath add IncludePath to list of search paths", + " -newdb to not read in existing database file", + " -uqs to indicate that unquoted strings are used", + " FileNames name of one or more unicode files to parse", + " Scan options include:", + " -scan scan text file(s) for STRING_TOKEN() usage", + " -skipext .ext to skip scan of files with .ext filename extension", + " -ignorenotfound ignore if a given STRING_TOKEN(STR) is not ", + " found in the database", + " FileNames one or more files to scan", + " Dump options include:", + " -oc FileName write string data to FileName", + " -oh FileName write string defines to FileName", + " -ou FileName dump database to unicode file FileName", + " -lang Lang only dump for the language 'Lang'", + " -if FileName to specify an indirection file", + " -hpk FileName to create an HII export pack of the strings", + "", + " The expected process is to parse a unicode string file to create an initial", + " database of string identifier names and string definitions. Then text files", + " should be scanned for STRING_TOKEN() usages, and the referenced", + " strings will be tagged as used in the database. After all files have been", + " scanned, then the database should be dumped to create the necessary output", + " files.", + "", + NULL + }; + for (Index = 0; Str[Index] != NULL; Index++) { + fprintf (stdout, "%s\n", Str[Index]); + } +} diff --git a/Tools/CodeTools/Source/StrGather/StrGather.h b/Tools/CodeTools/Source/StrGather/StrGather.h new file mode 100644 index 0000000000..65dc15cbe8 --- /dev/null +++ b/Tools/CodeTools/Source/StrGather/StrGather.h @@ -0,0 +1,84 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + StrGather.h + +Abstract: + + Common defines and prototypes for StrGather. + +--*/ + +#ifndef _STR_GATHER_H_ +#define _STR_GATHER_H_ + +#define MALLOC(size) malloc (size) +#define FREE(ptr) free (ptr) + +#define PROGRAM_NAME "StrGather" + +typedef CHAR16 WCHAR; + +#define UNICODE_TO_ASCII(w) (INT8) ((w) & 0xFF) +#define ASCII_TO_UNICODE(a) (WCHAR) ((UINT8) (a)) + +#define UNICODE_HASH L'#' +#define UNICODE_BACKSLASH L'\\' +#define UNICODE_SLASH L'/' +#define UNICODE_EQUAL_SIGN L'=' +#define UNICODE_PLUS_SIGN L'+' + +#define UNICODE_FILE_START 0xFEFF +#define UNICODE_CR 0x000D +#define UNICODE_LF 0x000A +#define UNICODE_NULL 0x0000 +#define UNICODE_SPACE L' ' +#define UNICODE_SLASH L'/' +#define UNICODE_DOUBLE_QUOTE L'"' +#define UNICODE_Z L'Z' +#define UNICODE_z L'z' +#define UNICODE_A L'A' +#define UNICODE_a L'a' +#define UNICODE_F L'F' +#define UNICODE_f L'f' +#define UNICODE_UNDERSCORE L'_' +#define UNICODE_0 L'0' +#define UNICODE_9 L'9' +#define UNICODE_TAB L'\t' +#define UNICODE_NBR_STRING L"\\nbr" +#define UNICODE_BR_STRING L"\\br" +#define UNICODE_WIDE_STRING L"\\wide" +#define UNICODE_NARROW_STRING L"\\narrow" + +// +// This is the length of a valid string identifier +// +#define LANGUAGE_IDENTIFIER_NAME_LEN 3 + +typedef struct _TEXT_STRING_LIST { + struct _TEXT_STRING_LIST *Next; + CHAR8 *Str; +} TEXT_STRING_LIST; + +typedef struct _WCHAR_STRING_LIST { + struct _WCHAR_STRING_LIST *Next; + WCHAR *Str; +} WCHAR_STRING_LIST; + +typedef struct _WCHAR_MATCHING_STRING_LIST { + struct _WCHAR_MATCHING_STRING_LIST *Next; + WCHAR *Str1; + WCHAR *Str2; +} WCHAR_MATCHING_STRING_LIST; + +#endif // #ifndef _STR_GATHER_H_ diff --git a/Tools/CodeTools/Source/StrGather/StringDB.c b/Tools/CodeTools/Source/StrGather/StringDB.c new file mode 100644 index 0000000000..16ef0526d7 --- /dev/null +++ b/Tools/CodeTools/Source/StrGather/StringDB.c @@ -0,0 +1,2759 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + StringDB.c + +Abstract: + + String database implementation + +--*/ + +#include +#include +#include +#include // for tolower() + +#include +#include +#include +#include // for EFI_UGA_PIXEL definition +#include + +#include "EfiUtilityMsgs.h" +#include "StrGather.h" +#include "StringDB.h" + + +#define STRING_OFFSET RELOFST + +#define STRING_DB_KEY (('S' << 24) | ('D' << 16) | ('B' << 8) | 'K') +// +// Version supported by this tool +// +#define STRING_DB_VERSION 0x00010000 + +#define STRING_DB_MAJOR_VERSION_MASK 0xFFFF0000 +#define STRING_DB_MINOR_VERSION_MASK 0x0000FFFF + +#define DEFINE_STR L"// #define" + +#define LANGUAGE_CODE_WIDTH 4 +// +// This is the header that gets written to the top of the +// output binary database file. +// +typedef struct { + UINT32 Key; + UINT32 HeaderSize; + UINT32 Version; + UINT32 NumStringIdenfiers; + UINT32 StringIdentifiersSize; + UINT32 NumLanguages; +} STRING_DB_HEADER; + +// +// When we write out data to the database, we have a UINT16 identifier, which +// indicates what follows, followed by the data. Here's the structure. +// +typedef struct { + UINT16 DataType; + UINT16 Reserved; +} DB_DATA_ITEM_HEADER; + +#define DB_DATA_TYPE_INVALID 0x0000 +#define DB_DATA_TYPE_STRING_IDENTIFIER 0x0001 +#define DB_DATA_TYPE_LANGUAGE_DEFINITION 0x0002 +#define DB_DATA_TYPE_STRING_DEFINITION 0x0003 +#define DB_DATA_TYPE_LAST DB_DATA_TYPE_STRING_DEFINITION + +// +// We have to keep track of a list of languages, each of which has its own +// list of strings. Define a structure to keep track of all languages and +// their list of strings. +// +typedef struct _STRING_LIST { + struct _STRING_LIST *Next; + UINT32 Size; // number of bytes in string, including null terminator + WCHAR *LanguageName; + WCHAR *StringName; // for example STR_ID_TEXT1 + WCHAR *Scope; // + WCHAR *Str; // the actual string + UINT16 Flags; // properties of this string (used, undefined) +} STRING_LIST; + +typedef struct _LANGUAGE_LIST { + struct _LANGUAGE_LIST *Next; + WCHAR LanguageName[4]; + WCHAR *PrintableLanguageName; + STRING_LIST *String; + STRING_LIST *LastString; +} LANGUAGE_LIST; + +// +// We also keep track of all the string identifier names, which we assign unique +// values to. Create a structure to keep track of them all. +// +typedef struct _STRING_IDENTIFIER { + struct _STRING_IDENTIFIER *Next; + UINT32 Index; // only need 16 bits, but makes it easier with UINT32 + WCHAR *StringName; + UINT16 Flags; // if someone referenced it via STRING_TOKEN() +} STRING_IDENTIFIER; +// +// Keep our globals in this structure to be as modular as possible. +// +typedef struct { + FILE *StringDBFptr; + LANGUAGE_LIST *LanguageList; + LANGUAGE_LIST *LastLanguageList; + LANGUAGE_LIST *CurrentLanguage; // keep track of the last language they used + STRING_IDENTIFIER *StringIdentifier; + STRING_IDENTIFIER *LastStringIdentifier; + UINT8 *StringDBFileName; + UINT32 NumStringIdentifiers; + UINT32 NumStringIdentifiersReferenced; + STRING_IDENTIFIER *CurrentStringIdentifier; // keep track of the last string identifier they added + WCHAR *CurrentScope; +} STRING_DB_DATA; + +static STRING_DB_DATA mDBData; + +static const char *mSourceFileHeader[] = { + "//", + "// DO NOT EDIT -- auto-generated file", + "//", + "// This file is generated by the string gather utility", + "//", + NULL +}; + +static +STRING_LIST * +StringDBFindString ( + WCHAR *LanguageName, + WCHAR *StringName, + WCHAR *Scope, + WCHAR_STRING_LIST *LanguagesOfInterest, + WCHAR_MATCHING_STRING_LIST *IndirectionList + ); + +static +STRING_IDENTIFIER * +StringDBFindStringIdentifierByName ( + WCHAR *Name + ); + +static +STRING_IDENTIFIER * +StringDBFindStringIdentifierByIndex ( + UINT32 Index + ); + +static +LANGUAGE_LIST * +StringDBFindLanguageList ( + WCHAR *LanguageName + ); + +static +void +StringDBWriteStandardFileHeader ( + FILE *OutFptr + ); + +static +WCHAR * +AsciiToWchar ( + CHAR8 *Str + ); + +static +WCHAR * +DuplicateString ( + WCHAR *Str + ); + +static +STATUS +StringDBWriteStringIdentifier ( + FILE *DBFptr, + UINT16 StringId, + UINT16 Flags, + WCHAR *IdentifierName + ); + +static +STATUS +StringDBReadStringIdentifier ( + FILE *DBFptr + ); + +static +STATUS +StringDBWriteLanguageDefinition ( + FILE *DBFptr, + WCHAR *LanguageName, + WCHAR *PrintableLanguageName + ); + +static +STATUS +StringDBReadLanguageDefinition ( + FILE *DBFptr + ); + +static +STATUS +StringDBWriteString ( + FILE *DBFptr, + UINT16 Flags, + WCHAR *Language, + WCHAR *StringName, + WCHAR *Scope, + WCHAR *Str + ); + +static +STATUS +StringDBReadString ( + FILE *DBFptr + ); + +static +STATUS +StringDBReadGenericString ( + FILE *DBFptr, + UINT16 *Size, + WCHAR **Str + ); + +static +STATUS +StringDBWriteGenericString ( + FILE *DBFptr, + WCHAR *Str + ); + +static +void +StringDBAssignStringIndexes ( + VOID + ); + +/*****************************************************************************/ + +/*++ + +Routine Description: + Constructor function for the string database handler. + +Arguments: + None. + +Returns: + None. + +--*/ +void +StringDBConstructor ( + VOID + ) +{ + memset ((char *) &mDBData, 0, sizeof (STRING_DB_DATA)); + mDBData.CurrentScope = DuplicateString (L"NULL"); +} + +/*****************************************************************************/ + +/*++ + +Routine Description: + Destructor function for the string database handler. + +Arguments: + None. + +Returns: + None. + +--*/ +void +StringDBDestructor ( + VOID + ) +{ + LANGUAGE_LIST *NextLang; + STRING_LIST *NextStr; + STRING_IDENTIFIER *NextIdentifier; + // + // Close the database file if it's open + // + if (mDBData.StringDBFptr != NULL) { + fclose (mDBData.StringDBFptr); + mDBData.StringDBFptr = NULL; + } + // + // If we've allocated any strings/languages, free them up + // + while (mDBData.LanguageList != NULL) { + NextLang = mDBData.LanguageList->Next; + // + // Free up all strings for this language + // + while (mDBData.LanguageList->String != NULL) { + NextStr = mDBData.LanguageList->String->Next; + FREE (mDBData.LanguageList->String->Str); + FREE (mDBData.LanguageList->String); + mDBData.LanguageList->String = NextStr; + } + + FREE (mDBData.LanguageList->PrintableLanguageName); + FREE (mDBData.LanguageList); + mDBData.LanguageList = NextLang; + } + // + // Free up string identifiers + // + while (mDBData.StringIdentifier != NULL) { + NextIdentifier = mDBData.StringIdentifier->Next; + FREE (mDBData.StringIdentifier->StringName); + FREE (mDBData.StringIdentifier); + mDBData.StringIdentifier = NextIdentifier; + } + // + // Free the filename + // + if (mDBData.StringDBFileName != NULL) { + FREE (mDBData.StringDBFileName); + mDBData.StringDBFileName = NULL; + } + // + // We save a copy of the scope, so free it up if we + // have one. + // + if (mDBData.CurrentScope != NULL) { + FREE (mDBData.CurrentScope); + mDBData.CurrentScope = NULL; + } +} + +/*****************************************************************************/ + +/*++ + +Routine Description: + + Dump the contents of a database to an output C file. + +Arguments: + + FileName - name of the output file to write + BaseName - used for the name of the C array defined + Languages - list of languages of interest + +Returns: + + STATUS + +Notes: + + Languages is a pointer to a linked list of languages specified on + the command line. Format is "eng" and "spa+cat". For this, print + the strings for eng. Print the strings for spa too, but if one is + missing look for a cat string and print if it it exists. + +--*/ +STATUS +StringDBDumpCStrings ( + CHAR8 *FileName, + CHAR8 *BaseName, + WCHAR_STRING_LIST *LanguagesOfInterest, + WCHAR_MATCHING_STRING_LIST *IndirectionList + ) +{ + FILE *Fptr; + LANGUAGE_LIST *Lang; + STRING_LIST *CurrString; + STRING_LIST EmptyString; + UINT32 Offset; + UINT32 StringIndex; + UINT32 TempIndex; + UINT32 BytesThisLine; + EFI_HII_STRING_PACK StringPack; + UINT8 *Ptr; + UINT32 Len; + WCHAR ZeroString[1]; + WCHAR_STRING_LIST *LOIPtr; + BOOLEAN LanguageOk; + WCHAR *TempStringPtr; + WCHAR *LangName; + STRING_IDENTIFIER *StringIdentifier; + WCHAR Line[200]; + + if ((Fptr = fopen (FileName, "w")) == NULL) { + Error (NULL, 0, 0, FileName, "failed to open output C string file"); + return STATUS_ERROR; + } + // + // Assign index values to the string identifiers + // + StringDBAssignStringIndexes (); + // + // Write the standard header to the output file, then the structure + // definition header. + // + StringDBWriteStandardFileHeader (Fptr); + fprintf (Fptr, "\nunsigned char %s[] = {\n", BaseName); + // + // If a given string is not defined, then we'll use this one. + // + memset (&EmptyString, 0, sizeof (EmptyString)); + EmptyString.Size = sizeof (ZeroString); + EmptyString.Str = ZeroString; + // + // Process each language, then each string for each langage + // + ZeroString[0] = 0; + for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) { + // + // If we have a language list, then make sure this language is in that + // list. + // + LanguageOk = TRUE; + LangName = Lang->LanguageName; + if (LanguagesOfInterest != NULL) { + LanguageOk = FALSE; + for (LOIPtr = LanguagesOfInterest; LOIPtr != NULL; LOIPtr = LOIPtr->Next) { + if (StrnCmp (LOIPtr->Str, Lang->LanguageName, LANGUAGE_IDENTIFIER_NAME_LEN) == 0) { + LangName = LOIPtr->Str; + LanguageOk = TRUE; + break; + } + } + } + + if (!LanguageOk) { + continue; + } + // + // Process each string for this language. We have to make 3 passes on the strings: + // Pass1: computes sizes and fill in the string pack header + // Pass2: write the array of offsets + // Pass3: write the strings + // + // + // PASS 1: Fill in and print the HII string pack header + // + // Compute the size for this language package and write + // the header out. Each string package contains: + // Header + // Offset[] -- an array of offsets to strings, of type RELOFST each + // String[] -- the actual strings themselves + // + AsciiSPrint ( Line, sizeof(Line), + "\n//******************************************************************************" + "\n// Start of string definitions for %s/%s", + Lang->LanguageName, + Lang->PrintableLanguageName + ); + fprintf (Fptr, "%s", Line); + memset ((char *) &StringPack, 0, sizeof (EFI_HII_STRING_PACK)); + StringPack.Header.Type = EFI_HII_STRING; + StringPack.NumStringPointers = (UINT16) mDBData.NumStringIdentifiersReferenced; + // + // First string is the language name. If we're printing all languages, then + // it's just the "spa". If we were given a list of languages to print, then it's + // the "spacat" string. Compute its offset and fill in + // the info in the header. Since we know the language name string's length, + // and the printable language name follows it, use that info to fill in the + // entry for the printable language name as well. + // + StringPack.LanguageNameString = (STRING_OFFSET) (sizeof (EFI_HII_STRING_PACK) + (mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET))); + StringPack.PrintableLanguageName = (STRING_OFFSET) (StringPack.LanguageNameString + (StrLen (LangName) + 1) * sizeof (WCHAR)); + // + // Add up the size of all strings so we can fill in our header. + // + Len = 0; + for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) { + // + // For the first string (language name), we print out the "spacat" if they + // requested it. We set LangName to point to the proper language name string above. + // + if (StringIndex == STRING_ID_LANGUAGE_NAME) { + Len += (StrLen (LangName) + 1) * sizeof (WCHAR); + } else { + // + // Find a string with this language.stringname + // + StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex); + if (StringIdentifier == NULL) { + Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex); + return STATUS_ERROR; + } + // + // Find a matching string if this string identifier was referenced + // + EmptyString.Flags = STRING_FLAGS_UNDEFINED; + CurrString = NULL; + if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) { + CurrString = StringDBFindString ( + Lang->LanguageName, + StringIdentifier->StringName, + NULL, + LanguagesOfInterest, + IndirectionList + ); + if (NULL == CurrString) { + // + // If string for Lang->LanguageName is not found, try to get an English version + // + CurrString = StringDBFindString ( + L"eng", + StringIdentifier->StringName, + NULL, + LanguagesOfInterest, + IndirectionList + ); + } + } + + if (CurrString == NULL) { + CurrString = &EmptyString; + EmptyString.Flags |= StringIdentifier->Flags; + } + + Len += CurrString->Size; + } + } + StringPack.Header.Length = sizeof (EFI_HII_STRING_PACK) + + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET) + + Len; + // + // Write out the header one byte at a time + // + Ptr = (UINT8 *) &StringPack; + for (TempIndex = 0; TempIndex < sizeof (EFI_HII_STRING_PACK); TempIndex++, Ptr++) { + if ((TempIndex & 0x07) == 0) { + fprintf (Fptr, "\n "); + } + + fprintf (Fptr, "0x%02X, ", (UINT32) *Ptr); + } + + fprintf (Fptr, "\n // offset 0x%X\n", sizeof (StringPack)); + // + // PASS2 : write the offsets + // + // Traverse the list of strings again and write the array of offsets. The + // offset to the first string is the size of the string pack header + // plus the size of the offsets array. The other strings follow it. + // + StringIndex = 0; + Offset = sizeof (StringPack) + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET); + for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) { + // + // Write the offset, followed by a useful comment + // + fprintf (Fptr, " "); + Ptr = (UINT8 *) &Offset; + for (TempIndex = 0; TempIndex < sizeof (STRING_OFFSET); TempIndex++) { + fprintf (Fptr, "0x%02X, ", (UINT32) Ptr[TempIndex]); + } + // + // Find the string name + // + StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex); + if (StringIdentifier == NULL) { + Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex); + return STATUS_ERROR; + } + + AsciiSPrint (Line, sizeof(Line) , " // offset to string %s (0x%04X)", StringIdentifier->StringName, StringIndex); + fprintf (Fptr, "%s", Line); + // + // For the first string (language name), we print out the "spacat" if they + // requested it. We set LangName to point to the proper language name string above. + // + if (StringIndex == STRING_ID_LANGUAGE_NAME) { + Offset += (StrLen (LangName) + 1) * sizeof (WCHAR); + CurrString = StringDBFindString ( + Lang->LanguageName, + StringIdentifier->StringName, + NULL, // scope + NULL, + NULL + ); + } else { + // + // Find a matching string + // + CurrString = StringDBFindString ( + Lang->LanguageName, + StringIdentifier->StringName, + NULL, // scope + LanguagesOfInterest, + IndirectionList + ); + + if (NULL == CurrString) { + CurrString = StringDBFindString ( + L"eng", + StringIdentifier->StringName, + NULL, // scope + LanguagesOfInterest, + IndirectionList + ); + } + + EmptyString.LanguageName = Lang->LanguageName; + if (CurrString == NULL) { + CurrString = &EmptyString; + EmptyString.Flags = STRING_FLAGS_UNDEFINED; + } else if ((StringIdentifier->Flags & STRING_FLAGS_REFERENCED) == 0) { + CurrString = &EmptyString; + EmptyString.Flags = 0; + } + + Offset += CurrString->Size; + } + // + // Print useful info about this string + // + if ((StringIdentifier->Flags & STRING_FLAGS_REFERENCED) == 0) { + fprintf (Fptr, " - not referenced"); + } + + if (CurrString->Flags & STRING_FLAGS_UNDEFINED) { + fprintf (Fptr, " - not defined for this language"); + } else if (StrCmp (CurrString->LanguageName, Lang->LanguageName) != 0) { + AsciiSPrint ( + Line, sizeof(Line), + " - not defined for this language -- using secondary language %s definition", + CurrString->LanguageName + ); + fprintf ( Fptr, "%s", Line); + } + + fprintf (Fptr, "\n"); + } + // + // For unreferenced string identifiers, print a message that they are not referenced anywhere + // + while (StringIndex < mDBData.NumStringIdentifiers) { + StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex); + if (StringIdentifier != NULL) { + AsciiSPrint (Line, sizeof(Line), " // %s not referenced\n", StringIdentifier->StringName); + fprintf (Fptr, "%s", Line); + } + + StringIndex++; + } + + // + // PASS 3: write the strings themselves. + // Keep track of how many bytes we write per line because some editors + // (Visual Studio for instance) can't handle too long of lines. + // + Offset = sizeof (StringPack) + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET); + for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) { + StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex); + if (StringIdentifier == NULL) { + Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex); + return STATUS_ERROR; + } + + AsciiSPrint (Line, sizeof(Line), " // string %s offset 0x%08X\n ", StringIdentifier->StringName, Offset); + fprintf (Fptr, "%s", Line); + // + // For the first string (language name), we print out the "spacat" if they + // requested it. We set LangName to point to the proper language name string above. + // + if (StringIndex == STRING_ID_LANGUAGE_NAME) { + TempStringPtr = LangName; + } else { + // + // Find a matching string if this string identifier was referenced + // + CurrString = NULL; + if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) { + CurrString = StringDBFindString ( + Lang->LanguageName, + StringIdentifier->StringName, + NULL, // scope + LanguagesOfInterest, + IndirectionList + ); + if (NULL == CurrString) { + CurrString = StringDBFindString ( + L"eng", + StringIdentifier->StringName, + NULL, // scope + LanguagesOfInterest, + IndirectionList + ); + } + } + + if (CurrString == NULL) { + CurrString = &EmptyString; + } + + TempStringPtr = CurrString->Str; + } + + BytesThisLine = 0; + for (TempIndex = 0; TempStringPtr[TempIndex] != 0; TempIndex++) { + fprintf ( + Fptr, + "0x%02X, 0x%02X, ", + (UINT32) TempStringPtr[TempIndex] & 0xFF, + (UINT32) ((TempStringPtr[TempIndex] >> 8) & 0xFF) + ); + BytesThisLine += 2; + Offset += 2; + // + // Let's say we only allow 14 per line + // + if (BytesThisLine > 14) { + fprintf (Fptr, "\n "); + BytesThisLine = 0; + } + } + // + // Print NULL WCHAR at the end of this string. + // + fprintf (Fptr, "0x00, 0x00,\n"); + Offset += 2; + } + // + // Sanity check the offset. Make sure our running offset is what we put in the + // string pack header. + // + if (StringPack.Header.Length != Offset) { + Error ( + __FILE__, + __LINE__, + 0, + "application error", + "stringpack size 0x%X does not match final size 0x%X", + StringPack.Header.Length, + Offset + ); + } + } + // + // Print terminator string pack, closing brace and close the file. + // The size of 0 triggers to the consumer that this is the end. + // + memset ((char *) &StringPack, 0, sizeof (EFI_HII_STRING_PACK)); + StringPack.Header.Type = EFI_HII_STRING; + Ptr = (UINT8 *) &StringPack; + fprintf (Fptr, "\n // strings terminator pack"); + for (TempIndex = 0; TempIndex < sizeof (StringPack); TempIndex++, Ptr++) { + if ((TempIndex & 0x0F) == 0) { + fprintf (Fptr, "\n "); + } + + fprintf (Fptr, "0x%02X, ", (UINT32) *Ptr); + } + + fprintf (Fptr, "\n};\n"); + fclose (Fptr); + return STATUS_SUCCESS; +} + +/*****************************************************************************/ + +/*++ + +Routine Description: + + Dump the #define string names + +Arguments: + + FileName - name of the output file to write + BaseName - used for the protection #ifndef/#endif + +Returns: + + STATUS + +--*/ +STATUS +StringDBDumpStringDefines ( + CHAR8 *FileName, + CHAR8 *BaseName + ) +{ + FILE *Fptr; + STRING_IDENTIFIER *Identifier; + CHAR8 CopyBaseName[100]; + WCHAR Line[200]; + UINT32 Index; + const CHAR8 *StrDefHeader[] = { + "#ifndef _%s_STRINGS_DEFINE_H_\n", + "#define _%s_STRINGS_DEFINE_H_\n\n", + NULL + }; + + if ((Fptr = fopen (FileName, "w")) == NULL) { + Error (NULL, 0, 0, FileName, "failed to open output string defines file"); + return STATUS_ERROR; + } + // + // Get the base source filename and convert to uppercase. + // + if (sizeof (CopyBaseName) <= strlen (BaseName) + 1) { + Error (NULL, 0, 0, "application error", "StringDBDumpStringDefines() string length insufficient"); + return STATUS_ERROR; + } + + strcpy (CopyBaseName, BaseName); + for (Index = 0; CopyBaseName[Index] != 0; Index++) { + if (islower (CopyBaseName[Index])) { + CopyBaseName[Index] = (INT8) toupper (CopyBaseName[Index]); + } + } + // + // Assign index values to the string identifiers + // + StringDBAssignStringIndexes (); + // + // Write the standard header to the output file, and then the + // protective #ifndef. + // + StringDBWriteStandardFileHeader (Fptr); + for (Index = 0; StrDefHeader[Index] != NULL; Index++) { + fprintf (Fptr, StrDefHeader[Index], CopyBaseName); + } + // + // Print all the #defines for the string identifiers. Print identifiers + // whose names start with '$' as comments. Add comments for string + // identifiers not used as well. + // + Identifier = mDBData.StringIdentifier; + while (Identifier != NULL) { + if (Identifier->StringName[0] == L'$') { + fprintf (Fptr, "// "); + } + + if (Identifier->Flags & STRING_FLAGS_REFERENCED) { + AsciiSPrint (Line, sizeof(Line), "#define %-40s 0x%04X\n", Identifier->StringName, Identifier->Index); + fprintf (Fptr, "%s", Line); + } else { + AsciiSPrint (Line, sizeof(Line), "//#define %-40s 0x%04X // not referenced\n", Identifier->StringName, Identifier->Index); + fprintf (Fptr, "%s", Line); + } + + Identifier = Identifier->Next; + } + + fprintf (Fptr, "\n#endif\n"); + fclose (Fptr); + return STATUS_SUCCESS; +} + +/*****************************************************************************/ + +/*++ + +Routine Description: + + Add a string identifier to the database. + +Arguments: + + StringName - name of the string identifier. For example "STR_MY_STRING" + NewId - if an ID has been assigned + Flags - characteristics for the identifier + +Returns: + + STATUS + +--*/ +STATUS +StringDBAddStringIdentifier ( + WCHAR *StringName, + UINT16 *NewId, + UINT16 Flags + ) +{ + STRING_IDENTIFIER *StringIdentifier; + STATUS Status; + // + // If it was already used for some other language, then we don't + // need to add it. But set it to the current string identifier. + // The referenced bit is sticky. + // + Status = STATUS_SUCCESS; + StringIdentifier = StringDBFindStringIdentifierByName (StringName); + if (StringIdentifier != NULL) { + if (Flags & STRING_FLAGS_REFERENCED) { + StringIdentifier->Flags |= STRING_FLAGS_REFERENCED; + } + + mDBData.CurrentStringIdentifier = StringIdentifier; + *NewId = (UINT16) StringIdentifier->Index; + return Status; + } + + StringIdentifier = (STRING_IDENTIFIER *) MALLOC (sizeof (STRING_IDENTIFIER)); + if (StringIdentifier == NULL) { + Error (NULL, 0, 0, NULL, "memory allocation error"); + return STATUS_ERROR; + } + + memset ((char *) StringIdentifier, 0, sizeof (STRING_IDENTIFIER)); + StringIdentifier->StringName = (WCHAR *) malloc ((StrLen (StringName) + 1) * sizeof (WCHAR)); + if (StringIdentifier->StringName == NULL) { + Error (NULL, 0, 0, NULL, "memory allocation error"); + return STATUS_ERROR; + } + + StrCpy (StringIdentifier->StringName, StringName); + if (*NewId != STRING_ID_INVALID) { + StringIdentifier->Index = *NewId; + StringIdentifier->Flags |= STRING_FLAGS_INDEX_ASSIGNED; + if (mDBData.NumStringIdentifiers <= StringIdentifier->Index) { + mDBData.NumStringIdentifiers = StringIdentifier->Index + 1; + } + } else { + StringIdentifier->Index = mDBData.NumStringIdentifiers++; + } + + StringIdentifier->Flags |= Flags; + // + // Add it to our list of string identifiers + // + if (mDBData.StringIdentifier == NULL) { + mDBData.StringIdentifier = StringIdentifier; + } else { + mDBData.LastStringIdentifier->Next = StringIdentifier; + } + + mDBData.LastStringIdentifier = StringIdentifier; + mDBData.CurrentStringIdentifier = StringIdentifier; + *NewId = (UINT16) StringIdentifier->Index; + return Status; +} + +/*****************************************************************************/ + +/*++ + +Routine Description: + + Add a new string to the database. + +Arguments: + + LanguageName - "eng" or "spa" language name + StringName - "STR_MY_TEXT" string name + Scope - from the #scope statements in the string file + Format - if we should format the string + Flags - characteristic flags for the string + +Returns: + + STATUS + +Notes: + + Several of the fields can be "inherited" from the previous calls to + our database functions. For example, if scope is NULL here, then + we'll use the previous setting. + +--*/ +STATUS +StringDBAddString ( + WCHAR *LanguageName, + WCHAR *StringName, + WCHAR *Scope, + WCHAR *String, + BOOLEAN Format, + UINT16 Flags + ) +{ + LANGUAGE_LIST *Lang; + UINT32 Size; + STRING_LIST *Str; + UINT16 StringIndex; + WCHAR TempLangName[4]; + STRING_IDENTIFIER *StringIdentifier; + + // + // Check that language name is exactly 3 characters, or emit an error. + // Truncate at 3 if it's longer, or make it 3 if it's shorter. + // + if (LanguageName != NULL) { + Size = StrLen (LanguageName); + if (Size != 3) { + ParserError (0, "invalid length for language name", "%S", LanguageName); + if (Size > 3) { + LanguageName[3] = 0; + } else { + // + // Make a local copy of the language name string, and extend to + // 3 characters since we make assumptions elsewhere in this program + // on the length. + // + StrCpy (TempLangName, LanguageName); + for (; Size < 3; Size++) { + TempLangName[Size] = L'?'; + } + + TempLangName[4] = 0; + LanguageName = TempLangName; + } + } + } + // + // If they specified a language, make sure they've defined it already + // via a #langdef statement. Otherwise use the current default language. + // + if (LanguageName != NULL) { + Lang = StringDBFindLanguageList (LanguageName); + if (Lang == NULL) { + ParserError (0, "language not defined", "%S", LanguageName); + return STATUS_ERROR; + } else { + StringDBSetCurrentLanguage (LanguageName); + } + } else { + Lang = mDBData.CurrentLanguage; + if (Lang == NULL) { + // + // Have to call SetLanguage() first + // + ParserError (0, "no language defined", "%S", StringName); + return STATUS_ERROR; + } + } + // + // If they didn't define a string identifier, use the last string identifier + // added. + // + if (StringName == NULL) { + StringName = mDBData.CurrentStringIdentifier->StringName; + if (StringName == NULL) { + ParserError (0, "no string identifier previously specified", NULL); + return STATUS_ERROR; + } + } + // + // If scope was not specified, use the default setting + // + if (Scope != NULL) { + Scope = DuplicateString (Scope); + } else { + Scope = DuplicateString (mDBData.CurrentScope); + } + // + // printf ("Adding string: %S.%S.%S\n", Lang->LanguageName, StringName, Scope); + // + // Check for duplicates for this Language.StringName.Scope. Allow multiple + // definitions of the language name and printable language name, since the + // user does not specifically define them. + // + if (StringDBFindString (Lang->LanguageName, StringName, Scope, NULL, NULL) != NULL) { + if ((StrCmp (StringName, LANGUAGE_NAME_STRING_NAME) == 0) && + (StrCmp (StringName, PRINTABLE_LANGUAGE_NAME_STRING_NAME) == 0) + ) { + ParserError ( + 0, + "string multiply defined", + "Language.Name.Scope = %S.%S.%S", + Lang->LanguageName, + StringName, + Scope + ); + return STATUS_ERROR; + } + } + + StringIndex = STRING_ID_INVALID; + if (StringDBAddStringIdentifier (StringName, &StringIndex, Flags) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + StringIdentifier = StringDBFindStringIdentifierByName (StringName); + // + // Add this string to the end of the strings for this language. + // + Str = (STRING_LIST *) malloc (sizeof (STRING_LIST)); + if (Str == NULL) { + Error (NULL, 0, 0, NULL, "memory allocation error"); + return STATUS_ERROR; + } + + memset ((char *) Str, 0, sizeof (STRING_LIST)); + Size = (StrLen (String) + 1) * sizeof (WCHAR); + Str->Flags = Flags; + Str->Scope = Scope; + Str->StringName = StringIdentifier->StringName; + Str->LanguageName = DuplicateString (LanguageName); + Str->Str = (WCHAR *) MALLOC (Size); + if (Str->Str == NULL) { + Error (NULL, 0, 0, NULL, "memory allocation error"); + return STATUS_ERROR; + } + // + // If not formatting, just copy the string. + // + StrCpy (Str->Str, String); + if (Format) { + StringDBFormatString (Str->Str); + } + // + // Size may change after formatting. We set the size to + // the actual size of the string, including the null for + // easier processing later. + // + Str->Size = (StrLen (Str->Str) + 1) * sizeof (WCHAR); + if (Lang->String == NULL) { + Lang->String = Str; + } else { + Lang->LastString->Next = Str; + } + + Lang->LastString = Str; + return STATUS_SUCCESS; +} + +/*****************************************************************************/ + +/*++ + +Routine Description: + + Given a language name, see if a language list for it has been defined + +Arguments: + + LanguageName - like "eng" + +Returns: + + A pointer to the language list + +--*/ +static +LANGUAGE_LIST * +StringDBFindLanguageList ( + WCHAR *LanguageName + ) +{ + LANGUAGE_LIST *Lang; + + Lang = mDBData.LanguageList; + while (Lang != NULL) { + if (StrCmp (LanguageName, Lang->LanguageName) == 0) { + break; + } + + Lang = Lang->Next; + } + + return Lang; +} + +/*****************************************************************************/ +STATUS +StringDBSetCurrentLanguage ( + WCHAR *LanguageName + ) +{ + LANGUAGE_LIST *Lang; + + Lang = StringDBFindLanguageList (LanguageName); + if (Lang == NULL) { + ParserError (0, "language not previously defined", "%S", LanguageName); + return STATUS_ERROR; + } + + mDBData.CurrentLanguage = Lang; + return STATUS_SUCCESS; +} + +/*****************************************************************************/ +STATUS +StringDBAddLanguage ( + WCHAR *LanguageName, + WCHAR *PrintableLanguageName + ) +{ + LANGUAGE_LIST *Lang; + // + // Check for redefinitions + // + Lang = StringDBFindLanguageList (LanguageName); + if (Lang != NULL) { + // + // Better be the same printable name + // + if (StrCmp (PrintableLanguageName, Lang->PrintableLanguageName) != 0) { + ParserError ( + 0, + "language redefinition", + "%S:%S != %S:%S", + Lang->LanguageName, + Lang->PrintableLanguageName, + LanguageName, + PrintableLanguageName + ); + return STATUS_ERROR; + // + // } else { + // ParserWarning (0, "benign language redefinition", "%S", PrintableLanguageName); + // return STATUS_WARNING; + // + } + } else { + // + // Allocate memory to keep track of this new language + // + Lang = (LANGUAGE_LIST *) malloc (sizeof (LANGUAGE_LIST)); + if (Lang == NULL) { + Error (NULL, 0, 0, NULL, "memory allocation error"); + return STATUS_ERROR; + } + + memset ((char *) Lang, 0, sizeof (LANGUAGE_LIST)); + // + // Save the language name, then allocate memory to save the + // printable language name + // + StrCpy (Lang->LanguageName, LanguageName); + Lang->PrintableLanguageName = (WCHAR *) malloc ((StrLen (PrintableLanguageName) + 1) * sizeof (WCHAR)); + if (Lang->PrintableLanguageName == NULL) { + Error (NULL, 0, 0, NULL, "memory allocation error"); + return STATUS_ERROR; + } + + StrCpy (Lang->PrintableLanguageName, PrintableLanguageName); + + if (mDBData.LanguageList == NULL) { + mDBData.LanguageList = Lang; + } else { + mDBData.LastLanguageList->Next = Lang; + } + + mDBData.LastLanguageList = Lang; + } + // + // Default is to make our active language this new one + // + StringDBSetCurrentLanguage (LanguageName); + // + // The first two strings for any language are the language name, + // followed by the printable language name. Add them and set them + // to referenced so they never get stripped out. + // + StringDBAddString ( + LanguageName, + LANGUAGE_NAME_STRING_NAME, + NULL, + LanguageName, + FALSE, + STRING_FLAGS_REFERENCED + ); + StringDBAddString ( + LanguageName, + PRINTABLE_LANGUAGE_NAME_STRING_NAME, + NULL, + PrintableLanguageName, + FALSE, + STRING_FLAGS_REFERENCED + ); + return STATUS_SUCCESS; +} + +/*****************************************************************************/ +static +STRING_IDENTIFIER * +StringDBFindStringIdentifierByName ( + WCHAR *StringName + ) +{ + STRING_IDENTIFIER *Identifier; + + Identifier = mDBData.StringIdentifier; + while (Identifier != NULL) { + if (StrCmp (StringName, Identifier->StringName) == 0) { + return Identifier; + } + + Identifier = Identifier->Next; + } + + return NULL; +} + +static +STRING_IDENTIFIER * +StringDBFindStringIdentifierByIndex ( + UINT32 StringIndex + ) +{ + STRING_IDENTIFIER *Identifier; + + Identifier = mDBData.StringIdentifier; + while (Identifier != NULL) { + if (Identifier->Index == StringIndex) { + return Identifier; + } + + Identifier = Identifier->Next; + } + + return NULL; +} + +/*****************************************************************************/ +static +void +StringDBWriteStandardFileHeader ( + FILE *OutFptr + ) +{ + UINT32 TempIndex; + for (TempIndex = 0; mSourceFileHeader[TempIndex] != NULL; TempIndex++) { + fprintf (OutFptr, "%s\n", mSourceFileHeader[TempIndex]); + } +} + +/*****************************************************************************/ + +/*++ + +Routine Description: + + Given a Unicode string from an input file, reformat the string to replace + backslash control sequences with the appropriate encoding. + +Arguments: + + String - pointer to string to reformat + +Returns: + + Nothing + +--*/ +void +StringDBFormatString ( + WCHAR *String + ) +{ + WCHAR *From; + WCHAR *To; + int HexNibbles; + WCHAR HexValue; + // + // Go through the string and process any formatting characters + // + From = String; + To = String; + while (*From) { + if (*From == UNICODE_BACKSLASH) { + // + // First look for \wide and replace with the appropriate control character. Note that + // when you have "define STR L"ABC"", then sizeof(ABC) is 8 because the null char is + // counted. Make adjustments for this. We advance From below, so subtract 2 each time. + // + if (StrnCmp (From, UNICODE_WIDE_STRING, sizeof (UNICODE_WIDE_STRING) / sizeof (WCHAR) - 1) == 0) { + *To = WIDE_CHAR; + From += sizeof (UNICODE_WIDE_STRING) / sizeof (WCHAR) - 2; + } else if (StrnCmp (From, UNICODE_NARROW_STRING, sizeof (UNICODE_NARROW_STRING) / sizeof (WCHAR) - 1) == 0) { + // + // Found: \narrow + // + *To = NARROW_CHAR; + From += sizeof (UNICODE_NARROW_STRING) / sizeof (WCHAR) - 2; + } else if (StrnCmp (From, UNICODE_NBR_STRING, sizeof (UNICODE_NBR_STRING) / sizeof (WCHAR) - 1) == 0) { + // + // Found: \nbr + // + *To = NON_BREAKING_CHAR; + From += sizeof (UNICODE_NBR_STRING) / sizeof (WCHAR) - 2; + } else if (StrnCmp (From, UNICODE_BR_STRING, sizeof (UNICODE_BR_STRING) / sizeof (WCHAR) - 1) == 0) { + // + // Found: \br -- pass through untouched + // + *To = *From; + } else { + // + // Standard one-character control sequences such as \n, \r, \\, or \x + // + From++; + switch (*From) { + case ASCII_TO_UNICODE ('n'): + *To = UNICODE_CR; + To++; + *To = UNICODE_LF; + break; + + // + // carriage return + // + case ASCII_TO_UNICODE ('r'): + *To = UNICODE_CR; + break; + + // + // backslash + // + case UNICODE_BACKSLASH: + *To = UNICODE_BACKSLASH; + break; + + // + // Tab + // + case ASCII_TO_UNICODE ('t'): + *To = UNICODE_TAB; + break; + + // + // embedded double-quote + // + case UNICODE_DOUBLE_QUOTE: + *To = UNICODE_DOUBLE_QUOTE; + break; + + // + // Hex Unicode character \x1234. We'll process up to 4 hex characters + // + case ASCII_TO_UNICODE ('x'): + HexValue = 0; + for (HexNibbles = 0; HexNibbles < 4; HexNibbles++) { + if ((From[1] >= UNICODE_0) && (From[1] <= UNICODE_9)) { + HexValue = (HexValue << 4) | (From[1] - UNICODE_0); + } else if ((From[1] >= UNICODE_a) && (From[1] <= UNICODE_f)) { + HexValue = (HexValue << 4) | (10 + From[1] - UNICODE_a); + } else if ((From[1] >= UNICODE_A) && (From[1] <= UNICODE_F)) { + HexValue = (HexValue << 4) | (10 + From[1] - UNICODE_A); + } else { + break; + } + + From++; + } + + if (HexNibbles == 0) { + ParserWarning ( + 0, + "expected at least one valid hex digit with \\x escaped character in string", + "\\%C", + *From + ); + } else { + *To = HexValue; + } + break; + + default: + *To = UNICODE_SPACE; + ParserWarning (0, "invalid escaped character in string", "\\%C", *From); + break; + } + } + } else { + *To = *From; + } + + From++; + To++; + } + + *To = 0; +} + +/*****************************************************************************/ +STATUS +StringDBReadDatabase ( + CHAR8 *DBFileName, + BOOLEAN IgnoreIfNotExist, + BOOLEAN Verbose + ) +{ + STRING_DB_HEADER DbHeader; + STATUS Status; + FILE *DBFptr; + DB_DATA_ITEM_HEADER DataItemHeader; + + Status = STATUS_SUCCESS; + DBFptr = NULL; + // + // if (Verbose) { + // fprintf (stdout, "Reading database file %s\n", DBFileName); + // } + // + // Try to open the input file + // + if ((DBFptr = fopen (DBFileName, "rb")) == NULL) { + if (IgnoreIfNotExist) { + return STATUS_SUCCESS; + } + + Error (NULL, 0, 0, DBFileName, "failed to open input database file for reading"); + return STATUS_ERROR; + } + // + // Read and verify the database header + // + if (fread ((void *) &DbHeader, sizeof (STRING_DB_HEADER), 1, DBFptr) != 1) { + Error (NULL, 0, 0, DBFileName, "failed to read header from database file"); + Status = STATUS_ERROR; + goto Finish; + } + + if (DbHeader.Key != STRING_DB_KEY) { + Error (NULL, 0, 0, DBFileName, "invalid header in database file"); + Status = STATUS_ERROR; + goto Finish; + } + + if ((DbHeader.Version & STRING_DB_MAJOR_VERSION_MASK) != (STRING_DB_VERSION & STRING_DB_MAJOR_VERSION_MASK)) { + Error (NULL, 0, 0, DBFileName, "incompatible database file version -- rebuild clean"); + Status = STATUS_ERROR; + goto Finish; + } + // + // Read remaining items + // + while (fread (&DataItemHeader, sizeof (DataItemHeader), 1, DBFptr) == 1) { + switch (DataItemHeader.DataType) { + case DB_DATA_TYPE_STRING_IDENTIFIER: + StringDBReadStringIdentifier (DBFptr); + break; + + case DB_DATA_TYPE_LANGUAGE_DEFINITION: + StringDBReadLanguageDefinition (DBFptr); + break; + + case DB_DATA_TYPE_STRING_DEFINITION: + StringDBReadString (DBFptr); + break; + + default: + Error ( + NULL, + 0, + 0, + "database corrupted", + "invalid data item type 0x%X at offset 0x%X", + (UINT32) DataItemHeader.DataType, + ftell (DBFptr) - sizeof (DataItemHeader) + ); + Status = STATUS_ERROR; + goto Finish; + } + } + +Finish: + if (DBFptr != NULL) { + fclose (DBFptr); + } + + return Status; +} + +/*****************************************************************************/ + +/*++ + +Routine Description: + + Write everything we know to the output database file. Write: + + Database header + String identifiers[] + StringPacks[] + +Arguments: + + DBFileName - name of the file to write to + Verbose - for debug purposes, print info messages along the way. + +Returns: + + STATUS + +--*/ +STATUS +StringDBWriteDatabase ( + CHAR8 *DBFileName, + BOOLEAN Verbose + ) +{ + STRING_DB_HEADER DbHeader; + UINT32 Counter; + UINT32 StrLength; + LANGUAGE_LIST *Lang; + STRING_IDENTIFIER *StringIdentifier; + STRING_LIST *StrList; + FILE *DBFptr; + + if (Verbose) { + fprintf (stdout, "Writing database %s\n", DBFileName); + } + + if ((DBFptr = fopen (DBFileName, "wb")) == NULL) { + Error (NULL, 0, 0, DBFileName, "failed to open output database file for writing"); + return STATUS_ERROR; + } + // + // Fill in and write the database header + // + memset (&DbHeader, 0, sizeof (STRING_DB_HEADER)); + DbHeader.HeaderSize = sizeof (STRING_DB_HEADER); + DbHeader.Key = STRING_DB_KEY; + DbHeader.Version = STRING_DB_VERSION; + // + // Count the number of languages we have + // + for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) { + DbHeader.NumLanguages++; + } + // + // Count up how many string identifiers we have, and total up the + // size of the names plus the size of the flags field we will + // write out too. + // + DbHeader.NumStringIdenfiers = mDBData.NumStringIdentifiers; + StringIdentifier = mDBData.StringIdentifier; + for (Counter = 0; Counter < mDBData.NumStringIdentifiers; Counter++) { + StrLength = StrLen (StringIdentifier->StringName) + 1; + DbHeader.StringIdentifiersSize += StrLength * sizeof (WCHAR) + sizeof (StringIdentifier->Flags); + StringIdentifier = StringIdentifier->Next; + } + + // + // Write the header + // + fwrite (&DbHeader, sizeof (STRING_DB_HEADER), 1, DBFptr); + if (Verbose) { + fprintf (stdout, " Number of string identifiers 0x%04X\n", DbHeader.NumStringIdenfiers); + fprintf (stdout, " Number of languages %d\n", DbHeader.NumLanguages); + } + // + // Write the string identifiers + // + for (StringIdentifier = mDBData.StringIdentifier; StringIdentifier != NULL; StringIdentifier = StringIdentifier->Next) { + StringDBWriteStringIdentifier ( + DBFptr, + (UINT16) StringIdentifier->Index, + StringIdentifier->Flags, + StringIdentifier->StringName + ); + } + // + // Now write all the strings for each language + // + for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) { + StringDBWriteLanguageDefinition (DBFptr, Lang->LanguageName, Lang->PrintableLanguageName); + for (StrList = Lang->String; StrList != NULL; StrList = StrList->Next) { + StringDBWriteString ( + DBFptr, + StrList->Flags, + Lang->LanguageName, + StrList->StringName, + StrList->Scope, + StrList->Str + ); + } + } + + fclose (DBFptr); + return STATUS_SUCCESS; +} + +STATUS +StringDBSetStringReferenced ( + CHAR8 *StringIdentifierName, + BOOLEAN IgnoreNotFound + ) +{ + STRING_IDENTIFIER *Id; + WCHAR *WName; + STATUS Status; + // + // See if it's already been defined. + // + Status = STATUS_SUCCESS; + WName = (WCHAR *) malloc ((strlen (StringIdentifierName) + 1) * sizeof (WCHAR)); + UnicodeSPrint (WName, (strlen (StringIdentifierName) + 1) * sizeof (WCHAR), L"%a", StringIdentifierName); + Id = StringDBFindStringIdentifierByName (WName); + if (Id != NULL) { + Id->Flags |= STRING_FLAGS_REFERENCED; + } else { + if (IgnoreNotFound == 0) { + ParserWarning (0, StringIdentifierName, "string identifier not found in database"); + Status = STATUS_WARNING; + } + } + + free (WName); + return Status; +} + +/*****************************************************************************/ + +/*++ + +Routine Description: + + Dump the contents of a database to an output unicode file. + +Arguments: + + DBFileName - name of the pre-existing database file to read + OutputFileName - name of the file to dump the database contents to + Verbose - for printing of additional info useful for debugging + +Returns: + + STATUS + +Notes: + + There's some issue with the unicode printing routines. Therefore to + write to the output file properly, open it as binary and use fwrite. + Ideally we could open it with just L"w" and use fwprintf(). + +--*/ +STATUS +StringDBDumpDatabase ( + CHAR8 *DBFileName, + CHAR8 *OutputFileName, + BOOLEAN Verbose + ) +{ + LANGUAGE_LIST *Lang; + STRING_IDENTIFIER *StringIdentifier; + STRING_LIST *StrList; + FILE *OutFptr; + WCHAR WChar; + WCHAR CrLf[2]; + WCHAR Line[200]; + WCHAR *Scope; + // + // This function assumes the database has already been read, and + // we're just dumping our internal data structures to a unicode file. + // + if (Verbose) { + fprintf (stdout, "Dumping database file %s\n", DBFileName); + } + + OutFptr = fopen (OutputFileName, "wb"); + if (OutFptr == NULL) { + Error (NULL, 0, 0, OutputFileName, "failed to open output file for writing"); + return STATUS_ERROR; + } + + WChar = UNICODE_FILE_START; + fwrite (&WChar, sizeof (WCHAR), 1, OutFptr); + CrLf[1] = UNICODE_LF; + CrLf[0] = UNICODE_CR; + // + // The default control character is '/'. Make it '#' by writing + // "/=#" to the output file. + // + UnicodeSPrint (Line, sizeof(Line), L"/=#"); + fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr); + fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); + fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); + // + // Dump all the string identifiers and their values + // + StringDBAssignStringIndexes (); + for (StringIdentifier = mDBData.StringIdentifier; StringIdentifier != NULL; StringIdentifier = StringIdentifier->Next) { + // + // Write the "#define " string + // + if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) { + UnicodeSPrint ( + Line, + sizeof(Line), L"%s %-60.60s 0x%04X", + DEFINE_STR, + StringIdentifier->StringName, + StringIdentifier->Index + ); + } else { + UnicodeSPrint ( + Line, + sizeof(Line), L"%s %-60.60s 0x%04X // NOT REFERENCED", + DEFINE_STR, + StringIdentifier->StringName, + StringIdentifier->Index + ); + } + + fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr); + fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); + } + + fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); + // + // Now write all the strings for each language. + // + WChar = UNICODE_DOUBLE_QUOTE; + Scope = NULL; + for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) { + fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); + UnicodeSPrint (Line, sizeof(Line), L"#langdef %s \"%s\"", Lang->LanguageName, Lang->PrintableLanguageName); + fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr); + fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); + fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); + // + // Now the strings (in double-quotes) for this language. Write + // #string STR_NAME #language eng "string" + // + for (StrList = Lang->String; StrList != NULL; StrList = StrList->Next) { + // + // Print the internal flags for debug + // + UnicodeSPrint (Line, sizeof(Line), L"// flags=0x%02X", (UINT32) StrList->Flags); + fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr); + fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); + // + // Print the scope if changed + // + if ((Scope == NULL) || (StrCmp (Scope, StrList->Scope) != 0)) { + UnicodeSPrint (Line, sizeof(Line), L"#scope %s", StrList->Scope); + fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr); + fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); + Scope = StrList->Scope; + } + + UnicodeSPrint ( + Line, + sizeof(Line), L"#string %-50.50s #language %s \"", + StrList->StringName, + Lang->LanguageName + ); + fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr); + fwrite (StrList->Str, StrList->Size - sizeof (WCHAR), 1, OutFptr); + UnicodeSPrint (Line, sizeof(Line), L"\""); + fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr); + fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); + } + } + + fclose (OutFptr); + return STATUS_SUCCESS; +} + +/*****************************************************************************/ + +/*++ + +Routine Description: + + Given a primary language, a string identifier number, and a list of + languages, find a secondary string. + +Arguments: + + LanguageName - primary language, like "spa" + StringId - string index value + LanguageList - linked list of "eng", "spa+cat",... + +Returns: + + Pointer to a secondary string if found. NULL otherwise. + +Notes: + + Given: LanguageName "spa" and LanguageList "spa+cat", match the + "spa" and extract the "cat" and see if there is a string defined + for "cat".StringId. + +--*/ +static +STATUS +StringDBWriteStringIdentifier ( + FILE *DBFptr, + UINT16 StringId, + UINT16 Flags, + WCHAR *IdentifierName + ) +{ + DB_DATA_ITEM_HEADER Hdr; + memset (&Hdr, 0, sizeof (DB_DATA_ITEM_HEADER)); + Hdr.DataType = DB_DATA_TYPE_STRING_IDENTIFIER; + if (fwrite (&Hdr, sizeof (DB_DATA_ITEM_HEADER), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to write string to output database file", NULL); + return STATUS_ERROR; + } + + if (fwrite (&StringId, sizeof (StringId), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to write StringId to output database", NULL); + return STATUS_ERROR; + } + + if (fwrite (&Flags, sizeof (Flags), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to write StringId flags to output database", NULL); + return STATUS_ERROR; + } + + if (StringDBWriteGenericString (DBFptr, IdentifierName) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + return STATUS_SUCCESS; +} + +static +STATUS +StringDBReadStringIdentifier ( + FILE *DBFptr + ) +{ + WCHAR *IdentifierName; + UINT16 Flags; + UINT16 StringId; + UINT16 Size; + + if (fread (&StringId, sizeof (StringId), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to read StringId from database", NULL); + return STATUS_ERROR; + } + + if (fread (&Flags, sizeof (Flags), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to read StringId flags from database", NULL); + return STATUS_ERROR; + } + + if (StringDBReadGenericString (DBFptr, &Size, &IdentifierName) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + StringDBAddStringIdentifier (IdentifierName, &StringId, Flags); + // + // printf ("STRID: 0x%04X %S\n", (UINT32)StringId, IdentifierName); + // + FREE (IdentifierName); + return STATUS_SUCCESS; +} + +static +STATUS +StringDBWriteString ( + FILE *DBFptr, + UINT16 Flags, + WCHAR *Language, + WCHAR *StringName, + WCHAR *Scope, + WCHAR *Str + ) +{ + DB_DATA_ITEM_HEADER Hdr; + memset (&Hdr, 0, sizeof (DB_DATA_ITEM_HEADER)); + Hdr.DataType = DB_DATA_TYPE_STRING_DEFINITION; + if (fwrite (&Hdr, sizeof (DB_DATA_ITEM_HEADER), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to write string header to output database file", NULL); + return STATUS_ERROR; + } + + if (fwrite (&Flags, sizeof (Flags), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to write string flags to output database", NULL); + return STATUS_ERROR; + } + + if (StringDBWriteGenericString (DBFptr, Language) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + if (StringDBWriteGenericString (DBFptr, StringName) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + if (StringDBWriteGenericString (DBFptr, Scope) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + if (StringDBWriteGenericString (DBFptr, Str) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + // + // printf ("DBWriteString: %S.%S.%S\n", Language, StringName, Scope); + // + return STATUS_SUCCESS; +} + +static +STATUS +StringDBReadString ( + FILE *DBFptr + ) +{ + UINT16 Flags; + UINT16 Size; + WCHAR *Language; + WCHAR *StringName; + WCHAR *Scope; + WCHAR *Str; + + if (fread (&Flags, sizeof (Flags), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to read string flags from database", NULL); + return STATUS_ERROR; + } + + if (StringDBReadGenericString (DBFptr, &Size, &Language) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + if (StringDBReadGenericString (DBFptr, &Size, &StringName) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + if (StringDBReadGenericString (DBFptr, &Size, &Scope) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + if (StringDBReadGenericString (DBFptr, &Size, &Str) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + // + // If the first or second string (language name and printable language name), + // then skip them. They're added via language definitions data items in + // the database. + // + if (StringName[0] != L'$') { + StringDBAddString (Language, StringName, Scope, Str, FALSE, Flags); + } + // + // printf ("DBReadString: %S.%S.%S\n", Language, StringName, Scope); + // + FREE (Language); + FREE (StringName); + if (Str != NULL) { + FREE (Str); + } + + if (Scope != NULL) { + FREE (Scope); + } + + return STATUS_SUCCESS; +} + +static +STATUS +StringDBWriteLanguageDefinition ( + FILE *DBFptr, + WCHAR *LanguageName, + WCHAR *PrintableLanguageName + ) +{ + DB_DATA_ITEM_HEADER Hdr; + memset (&Hdr, 0, sizeof (DB_DATA_ITEM_HEADER)); + Hdr.DataType = DB_DATA_TYPE_LANGUAGE_DEFINITION; + if (fwrite (&Hdr, sizeof (DB_DATA_ITEM_HEADER), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to write string to output database file", NULL); + return STATUS_ERROR; + } + + if (StringDBWriteGenericString (DBFptr, LanguageName) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + if (StringDBWriteGenericString (DBFptr, PrintableLanguageName) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + return STATUS_SUCCESS; +} + +static +STATUS +StringDBReadLanguageDefinition ( + FILE *DBFptr + ) +{ + WCHAR *LanguageName; + WCHAR *PrintableLanguageName; + UINT16 Size; + STATUS Status; + + if (StringDBReadGenericString (DBFptr, &Size, &LanguageName) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + + if (StringDBReadGenericString (DBFptr, &Size, &PrintableLanguageName) != STATUS_SUCCESS) { + return STATUS_ERROR; + } + // + // printf("LANG: %S %S\n", LanguageName, PrintableLanguageName); + // + Status = StringDBAddLanguage (LanguageName, PrintableLanguageName); + FREE (LanguageName); + FREE (PrintableLanguageName); + return Status; +} +// +// All unicode strings in the database consist of a UINT16 length +// field, followed by the string itself. This routine reads one +// of those and returns the info. +// +static +STATUS +StringDBReadGenericString ( + FILE *DBFptr, + UINT16 *Size, + WCHAR **Str + ) +{ + UINT16 LSize; + UINT16 Flags; + WCHAR *LStr; + + if (fread (&LSize, sizeof (UINT16), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to read a string length field from the database", NULL); + return STATUS_ERROR; + } + + if (fread (&Flags, sizeof (UINT16), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to read a string flags field from the database", NULL); + return STATUS_ERROR; + } + + LStr = MALLOC (LSize); + if (LStr == NULL) { + Error (__FILE__, __LINE__, 0, "memory allocation failed reading the database", NULL); + return STATUS_ERROR; + } + + if (fread (LStr, sizeof (WCHAR), (UINT32) LSize / sizeof (WCHAR), DBFptr) != (UINT32) LSize / sizeof (WCHAR)) { + Error (NULL, 0, 0, "failed to read string from database", NULL); + Error (NULL, 0, 0, "database read failure", "offset 0x%X", ftell (DBFptr)); + free (LStr); + return STATUS_ERROR; + } + // + // printf ("DBR: %S\n", LStr); + // + // If the flags field indicated we were asked to write a NULL string, then + // return them a NULL pointer. + // + if (Flags & STRING_FLAGS_UNDEFINED) { + *Size = 0; + *Str = NULL; + } else { + *Size = LSize; + *Str = LStr; + } + + return STATUS_SUCCESS; +} + +static +STATUS +StringDBWriteGenericString ( + FILE *DBFptr, + WCHAR *Str + ) +{ + UINT16 Size; + UINT16 Flags; + WCHAR ZeroString[1]; + // + // Strings in the database consist of a size UINT16 followed + // by the string itself. + // + if (Str == NULL) { + ZeroString[0] = 0; + Str = ZeroString; + Size = sizeof (ZeroString); + Flags = STRING_FLAGS_UNDEFINED; + } else { + Flags = 0; + Size = (UINT16) ((StrLen (Str) + 1) * sizeof (WCHAR)); + } + + if (fwrite (&Size, sizeof (UINT16), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to write string size to database", NULL); + return STATUS_ERROR; + } + + if (fwrite (&Flags, sizeof (UINT16), 1, DBFptr) != 1) { + Error (NULL, 0, 0, "failed to write string flags to database", NULL); + return STATUS_ERROR; + } + + if (fwrite (Str, sizeof (WCHAR), Size / sizeof (WCHAR), DBFptr) != Size / sizeof (WCHAR)) { + Error (NULL, 0, 0, "failed to write string to database", NULL); + return STATUS_ERROR; + } + + return STATUS_SUCCESS; +} + +static +STRING_LIST * +StringDBFindString ( + WCHAR *LanguageName, + WCHAR *StringName, + WCHAR *Scope, + WCHAR_STRING_LIST *LanguagesOfInterest, + WCHAR_MATCHING_STRING_LIST *IndirectionList + ) +{ + LANGUAGE_LIST *Lang; + STRING_LIST *CurrString; + WCHAR_MATCHING_STRING_LIST *IndListPtr; + WCHAR TempLangName[LANGUAGE_IDENTIFIER_NAME_LEN + 1]; + WCHAR *WCharPtr; + + // + // If we were given an indirection list, then see if one was specified for this + // string identifier. That is to say, if the indirection says "STR_ID_MY_FAVORITE MyScope", + // then if this string name matches one in the list, then do a lookup with the + // specified scope and return that value. + // + if (IndirectionList != NULL) { + for (IndListPtr = IndirectionList; IndListPtr != NULL; IndListPtr = IndListPtr->Next) { + if (StrCmp (StringName, IndListPtr->Str1) == 0) { + CurrString = StringDBFindString (LanguageName, StringName, IndListPtr->Str2, LanguagesOfInterest, NULL); + if (CurrString != NULL) { + return CurrString; + } + } + } + } + // + // First look for exact match language.stringname + // + for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) { + if (StrCmp (LanguageName, Lang->LanguageName) == 0) { + // + // Found language match. Try to find string name match + // + for (CurrString = Lang->String; CurrString != NULL; CurrString = CurrString->Next) { + if (StrCmp (StringName, CurrString->StringName) == 0) { + // + // Found a string name match. See if we're supposed to find + // a scope match. + // + if (Scope != NULL) { + if (StrCmp (CurrString->Scope, Scope) == 0) { + return CurrString; + } + } else { + return CurrString; + } + } + } + } + } + // + // If we got here, then we didn't find a match. Look for secondary string + // matches. That is to say, if we're processing "spa", and they requested + // "spa+cat", then recursively call with "cat" + // + while (LanguagesOfInterest != NULL) { + // + // If this is the language we're looking for, then process the + // languages of interest list for it. + // + if (StrnCmp (LanguageName, LanguagesOfInterest->Str, LANGUAGE_IDENTIFIER_NAME_LEN) == 0) { + WCharPtr = LanguagesOfInterest->Str + LANGUAGE_IDENTIFIER_NAME_LEN; + while (*WCharPtr) { + // + // Double-check the length, though it should have been checked on the + // command line. + // + if (StrLen (WCharPtr) < LANGUAGE_IDENTIFIER_NAME_LEN) { + Error (NULL, 0, 0, "malformed alternate language list", "%S", LanguagesOfInterest->Str); + return NULL; + } + + StrnCpy (TempLangName, WCharPtr, LANGUAGE_IDENTIFIER_NAME_LEN); + TempLangName[LANGUAGE_IDENTIFIER_NAME_LEN] = 0; + CurrString = StringDBFindString (TempLangName, StringName, NULL, NULL, IndirectionList); + if (CurrString != NULL) { + return CurrString; + } + + WCharPtr += LANGUAGE_IDENTIFIER_NAME_LEN; + } + } + + LanguagesOfInterest = LanguagesOfInterest->Next; + } + + return NULL; +} + +STATUS +StringDBSetScope ( + WCHAR *Scope + ) +{ + // + // Free up existing scope memory. + // + if (mDBData.CurrentScope != NULL) { + FREE (mDBData.CurrentScope); + } + + mDBData.CurrentScope = DuplicateString (Scope); + return STATUS_SUCCESS; +} +// +// We typically don't assign index values to string identifiers +// until we're ready to write out files. To reduce the size of +// the output file, re-order the string identifiers to move any +// unreferenced ones to the end. Then we'll walk the list +// again to assign string indexes, keeping track of the last +// one referenced. +// +static +void +StringDBAssignStringIndexes ( + VOID + ) +{ + STRING_IDENTIFIER *StrId; + STRING_IDENTIFIER *FirstUsed; + STRING_IDENTIFIER *LastUsed; + STRING_IDENTIFIER *FirstUnused; + STRING_IDENTIFIER *LastUnused; + UINT32 Index; + UINT32 MaxReferenced; + + // + // Create two lists -- used and unused. Then put them together with + // the unused ones on the end. + // + FirstUsed = NULL; + LastUsed = NULL; + FirstUnused = NULL; + LastUnused = NULL; + StrId = mDBData.StringIdentifier; + while (StrId != NULL) { + if ((StrId->Flags & STRING_FLAGS_REFERENCED) == 0) { + // + // Put it on the unused list + // + if (FirstUnused == NULL) { + FirstUnused = StrId; + } else { + LastUnused->Next = StrId; + } + + LastUnused = StrId; + StrId = StrId->Next; + LastUnused->Next = NULL; + } else { + // + // Put it on the used list + // + if (FirstUsed == NULL) { + FirstUsed = StrId; + } else { + LastUsed->Next = StrId; + } + + LastUsed = StrId; + StrId = StrId->Next; + LastUsed->Next = NULL; + } + } + // + // Join the lists + // + if (FirstUsed != NULL) { + mDBData.StringIdentifier = FirstUsed; + LastUsed->Next = FirstUnused; + } else { + mDBData.StringIdentifier = FirstUnused; + } + + MaxReferenced = 0; + Index = 0; + for (StrId = mDBData.StringIdentifier; StrId != NULL; StrId = StrId->Next) { + StrId->Index = Index; + Index++; + if (StrId->Flags & STRING_FLAGS_REFERENCED) { + mDBData.NumStringIdentifiersReferenced = Index; + } + } + + mDBData.NumStringIdentifiers = Index; +} + +static +WCHAR * +DuplicateString ( + WCHAR *Str + ) +{ + WCHAR *NewStr; + if (Str == NULL) { + return NULL; + } + + NewStr = MALLOC ((StrLen (Str) + 1) * sizeof (WCHAR)); + if (NewStr == NULL) { + Error (NULL, 0, 0, "memory allocation failure", NULL); + return NULL; + } + + StrCpy (NewStr, Str); + return NewStr; +} + +static +WCHAR * +AsciiToWchar ( + CHAR8 *Str + ) +{ + UINT32 Len; + WCHAR *NewStr; + WCHAR *Ptr; + + Len = strlen (Str) + 1; + NewStr = (WCHAR *) malloc (Len * sizeof (WCHAR)); + for (Ptr = NewStr; *Str != 0; Str++, Ptr++) { + *Ptr = (UINT16) (UINT8) *Str; + } + + *Ptr = 0; + return NewStr; +} + +/*****************************************************************************/ + +/*++ + +Routine Description: + + Create an HII export string pack for the strings in our database. + +Arguments: + + FileName - name of the output file to write + +Returns: + + STATUS + + +--*/ +STATUS +StringDBCreateHiiExportPack ( + CHAR8 *FileName + ) +{ + FILE *Fptr; + LANGUAGE_LIST *Lang; + STRING_LIST *CurrString; + STRING_LIST EmptyString; + UINT32 Offset; + UINT32 StringIndex; + UINT32 TempIndex; + EFI_HII_STRING_PACK StringPack; + UINT32 Len; + WCHAR ZeroString[1]; + WCHAR *TempStringPtr; + WCHAR *LangName; + STRING_IDENTIFIER *StringIdentifier; + + if ((Fptr = fopen (FileName, "wb")) == NULL) { + Error (NULL, 0, 0, FileName, "failed to open output HII export file"); + return STATUS_ERROR; + } + // + // Assign index values to the string identifiers + // + StringDBAssignStringIndexes (); + // + // If a given string is not defined, then we'll use this one. + // + memset (&EmptyString, 0, sizeof (EmptyString)); + EmptyString.Size = sizeof (ZeroString); + EmptyString.Str = ZeroString; + // + // Process each language, then each string for each langage + // + ZeroString[0] = 0; + for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) { + // + // Process each string for this language. We have to make 3 passes on the strings: + // Pass1: computes sizes and fill in the string pack header + // Pass2: write the array of offsets + // Pass3: write the strings + // + // + // PASS 1: Fill in and print the HII string pack header + // + // Compute the size for this language package and write + // the header out. Each string package contains: + // Header + // Offset[] -- an array of offsets to strings, of type RELOFST each + // String[] -- the actual strings themselves + // + memset ((char *) &StringPack, 0, sizeof (EFI_HII_STRING_PACK)); + StringPack.Header.Type = EFI_HII_STRING; + StringPack.NumStringPointers = (UINT16) mDBData.NumStringIdentifiersReferenced; + LangName = Lang->LanguageName; + // + // First string is the language name. If we're printing all languages, then + // it's just the "spa". If we were given a list of languages to print, then it's + // the "spacat" string. Compute its offset and fill in + // the info in the header. Since we know the language name string's length, + // and the printable language name follows it, use that info to fill in the + // entry for the printable language name as well. + // + StringPack.LanguageNameString = (STRING_OFFSET) (sizeof (EFI_HII_STRING_PACK) + (mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET))); + StringPack.PrintableLanguageName = (STRING_OFFSET) (StringPack.LanguageNameString + (StrLen (LangName) + 1) * sizeof (WCHAR)); + // + // Add up the size of all strings so we can fill in our header. + // + Len = 0; + for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) { + // + // For the first string (language name), we print out the "spacat" if they + // requested it. We set LangName to point to the proper language name string above. + // + if (StringIndex == STRING_ID_LANGUAGE_NAME) { + Len += (StrLen (LangName) + 1) * sizeof (WCHAR); + } else { + // + // Find a string with this language.stringname + // + StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex); + if (StringIdentifier == NULL) { + Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex); + return STATUS_ERROR; + } + // + // Find a matching string if this string identifier was referenced + // + EmptyString.Flags = STRING_FLAGS_UNDEFINED; + CurrString = NULL; + if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) { + CurrString = StringDBFindString ( + Lang->LanguageName, + StringIdentifier->StringName, + NULL, + NULL, // LanguagesOfInterest, + NULL + ); + // + // IndirectionList); + // + if (NULL == CurrString) { + // + // If string for Lang->LanguageName is not found, try to get an English version + // + CurrString = StringDBFindString ( + L"eng", + StringIdentifier->StringName, + NULL, + NULL, // LanguagesOfInterest, + NULL + ); + // + // IndirectionList); + // + } + } + + if (CurrString == NULL) { + CurrString = &EmptyString; + EmptyString.Flags |= StringIdentifier->Flags; + } + + Len += CurrString->Size; + } + } + StringPack.Header.Length = sizeof (EFI_HII_STRING_PACK) + + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET) + + Len; + // + // Write out the string pack header + // + fwrite ((void *) &StringPack, sizeof (StringPack), 1, Fptr); + // + // PASS2 : write the offsets + // + // Traverse the list of strings again and write the array of offsets. The + // offset to the first string is the size of the string pack header + // plus the size of the offsets array. The other strings follow it. + // + StringIndex = 0; + Offset = sizeof (StringPack) + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET); + for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) { + // + // Write the offset + // + fwrite (&Offset, sizeof (STRING_OFFSET), 1, Fptr); + // + // Find the string name + // + StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex); + if (StringIdentifier == NULL) { + Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex); + return STATUS_ERROR; + } + // + // For the first string (language name), we print out the "spacat" if they + // requested it. We set LangName to point to the proper language name string above. + // + if (StringIndex == STRING_ID_LANGUAGE_NAME) { + Offset += (StrLen (LangName) + 1) * sizeof (WCHAR); + CurrString = StringDBFindString ( + Lang->LanguageName, + StringIdentifier->StringName, + NULL, // scope + NULL, + NULL + ); + } else { + // + // Find a matching string + // + CurrString = StringDBFindString ( + Lang->LanguageName, + StringIdentifier->StringName, + NULL, // scope + NULL, // LanguagesOfInterest, + NULL + ); + // + // IndirectionList); + // + if (NULL == CurrString) { + CurrString = StringDBFindString ( + L"eng", + StringIdentifier->StringName, + NULL, // scope + NULL, // LanguagesOfInterest, + NULL + ); + // + // IndirectionList); + // + } + + EmptyString.LanguageName = Lang->LanguageName; + if (CurrString == NULL) { + CurrString = &EmptyString; + EmptyString.Flags = STRING_FLAGS_UNDEFINED; + } else if ((StringIdentifier->Flags & STRING_FLAGS_REFERENCED) == 0) { + CurrString = &EmptyString; + EmptyString.Flags = 0; + } + + Offset += CurrString->Size; + } + } + + // + // PASS 3: write the strings themselves. + // + Offset = sizeof (StringPack) + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET); + for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) { + StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex); + if (StringIdentifier == NULL) { + Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex); + return STATUS_ERROR; + } + // + // For the first string (language name), we print out the "spacat" if they + // requested it. We set LangName to point to the proper language name string above. + // + if (StringIndex == STRING_ID_LANGUAGE_NAME) { + TempStringPtr = LangName; + } else { + // + // Find a matching string if this string identifier was referenced + // + CurrString = NULL; + if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) { + CurrString = StringDBFindString ( + Lang->LanguageName, + StringIdentifier->StringName, + NULL, // scope + NULL, // LanguagesOfInterest, + NULL + ); + // + // IndirectionList); + // + if (NULL == CurrString) { + CurrString = StringDBFindString ( + L"eng", + StringIdentifier->StringName, + NULL, // scope + NULL, // LanguagesOfInterest, + NULL + ); + // + // IndirectionList); + // + } + } + + if (CurrString == NULL) { + CurrString = &EmptyString; + } + + TempStringPtr = CurrString->Str; + } + + for (TempIndex = 0; TempStringPtr[TempIndex] != 0; TempIndex++) { + fwrite (&TempStringPtr[TempIndex], sizeof (CHAR16), 1, Fptr); + Offset += 2; + } + // + // Print NULL WCHAR at the end of this string. + // + TempIndex = 0; + fwrite (&TempIndex, sizeof (CHAR16), 1, Fptr); + Offset += 2; + } + // + // Sanity check the offset. Make sure our running offset is what we put in the + // string pack header. + // + if (StringPack.Header.Length != Offset) { + Error ( + __FILE__, + __LINE__, + 0, + "application error", + "stringpack size 0x%X does not match final size 0x%X", + StringPack.Header.Length, + Offset + ); + } + } + // + // Print terminator string pack, closing brace and close the file. + // The size of 0 triggers to the consumer that this is the end. + // + memset ((char *) &StringPack, 0, sizeof (EFI_HII_STRING_PACK)); + StringPack.Header.Type = EFI_HII_STRING; + fwrite ((void *) &StringPack, sizeof (StringPack), 1, Fptr); + fclose (Fptr); + return STATUS_SUCCESS; +} diff --git a/Tools/CodeTools/Source/StrGather/StringDB.h b/Tools/CodeTools/Source/StrGather/StringDB.h new file mode 100644 index 0000000000..c52573151f --- /dev/null +++ b/Tools/CodeTools/Source/StrGather/StringDB.h @@ -0,0 +1,136 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + StringDB.h + +Abstract: + + Common defines and prototypes for string database management + +--*/ + +#ifndef _STRING_DB_H_ +#define _STRING_DB_H_ + +#define LANGUAGE_NAME_STRING_NAME L"$LANGUAGE_NAME" +#define PRINTABLE_LANGUAGE_NAME_STRING_NAME L"$PRINTABLE_LANGUAGE_NAME" + +void +StringDBConstructor ( + void + ) +; +void +StringDBDestructor ( + void + ) +; + +STATUS +StringDBAddString ( + WCHAR *LanguageName, + WCHAR *StringIdentifier, + WCHAR *Scope, + WCHAR *String, + BOOLEAN Format, + UINT16 Flags + ) +; + +STATUS +StringDBSetScope ( + WCHAR *Scope + ) +; + +#define STRING_FLAGS_REFERENCED 0x0001 // if referenced somewhere +#define STRING_FLAGS_UNDEFINED 0x0002 // if we added it for padding purposes +#define STRING_FLAGS_INDEX_ASSIGNED 0x0004 // so don't change the index value +#define STRING_ID_INVALID 0xFFFF +#define STRING_ID_LANGUAGE_NAME 0x0000 +#define STRING_ID_PRINTABLE_LANGUAGE_NAME 0x0001 + +STATUS +StringDBAddStringIdentifier ( + WCHAR *StringIdentifier, + UINT16 *NewId, + UINT16 Flags + ) +; + +STATUS +StringDBReadDatabase ( + CHAR8 *DBFileName, + BOOLEAN IgnoreIfNotExist, + BOOLEAN Verbose + ) +; + +STATUS +StringDBWriteDatabase ( + CHAR8 *DBFileName, + BOOLEAN Verbose + ) +; + +STATUS +StringDBDumpDatabase ( + CHAR8 *DBFileName, + CHAR8 *OutputFileName, + BOOLEAN Verbose + ) +; + +STATUS +StringDBAddLanguage ( + WCHAR *LanguageName, + WCHAR *PrintableLanguageName + ) +; + +STATUS +StringDBDumpCStrings ( + CHAR8 *FileName, + CHAR8 *BaseName, + WCHAR_STRING_LIST *LanguagesOfInterest, + WCHAR_MATCHING_STRING_LIST *IndirectionList + ) +; + +STATUS +StringDBDumpStringDefines ( + CHAR8 *FileName, + CHAR8 *BaseName + ) +; + +STATUS +StringDBSetCurrentLanguage ( + WCHAR *LanguageName + ) +; + +STATUS +StringDBSetStringReferenced ( + CHAR8 *StringIdentifierName, + BOOLEAN IgnoreNotFound + ) +; + +void +StringDBFormatString ( + WCHAR *String + ) +; + +#endif // #ifndef _STRING_DB_H_ diff --git a/Tools/CodeTools/Source/StrGather/build.xml b/Tools/CodeTools/Source/StrGather/build.xml new file mode 100644 index 0000000000..f01117777a --- /dev/null +++ b/Tools/CodeTools/Source/StrGather/build.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/String/PrintLib.c b/Tools/CodeTools/Source/String/PrintLib.c new file mode 100644 index 0000000000..eef3f4d083 --- /dev/null +++ b/Tools/CodeTools/Source/String/PrintLib.c @@ -0,0 +1,674 @@ +/*++ + +Copyright (c) 2004-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +Module Name: + + PrintLib.c + +Abstract: + + Print Library. + +--*/ + +#include +#include + +#include "CommonLib.h" +#include "PrintLibInternal.h" + +typedef struct { + RETURN_STATUS Status; + CHAR8 *String; +} STATUS_LOOKUP_TABLE_ENTRY; + +static CONST STATUS_LOOKUP_TABLE_ENTRY StatusString[] = { + { RETURN_SUCCESS, "Success" }, + { RETURN_LOAD_ERROR, "Load Error" }, + { RETURN_INVALID_PARAMETER, "Invalid Parameter" }, + { RETURN_UNSUPPORTED, "Unsupported" }, + { RETURN_BAD_BUFFER_SIZE, "Bad Buffer Size" }, + { RETURN_BUFFER_TOO_SMALL, "Buffer Too Small" }, + { RETURN_NOT_READY, "Not Ready" }, + { RETURN_DEVICE_ERROR, "Device Error" }, + { RETURN_WRITE_PROTECTED, "Write Protected" }, + { RETURN_OUT_OF_RESOURCES, "Out of Resources" }, + { RETURN_VOLUME_CORRUPTED, "Volume Corrupt" }, + { RETURN_VOLUME_FULL, "Volume Full" }, + { RETURN_NO_MEDIA, "No Media" }, + { RETURN_MEDIA_CHANGED, "Media changed" }, + { RETURN_NOT_FOUND, "Not Found" }, + { RETURN_ACCESS_DENIED, "Access Denied" }, + { RETURN_NO_RESPONSE, "No Response" }, + { RETURN_NO_MAPPING, "No mapping" }, + { RETURN_TIMEOUT, "Time out" }, + { RETURN_NOT_STARTED, "Not started" }, + { RETURN_ALREADY_STARTED, "Already started" }, + { RETURN_ABORTED, "Aborted" }, + { RETURN_ICMP_ERROR, "ICMP Error" }, + { RETURN_TFTP_ERROR, "TFTP Error" }, + { RETURN_PROTOCOL_ERROR, "Protocol Error" }, + { RETURN_WARN_UNKNOWN_GLYPH, "Warning Unknown Glyph" }, + { RETURN_WARN_DELETE_FAILURE, "Warning Delete Failure" }, + { RETURN_WARN_WRITE_FAILURE, "Warning Write Failure" }, + { RETURN_WARN_BUFFER_TOO_SMALL, "Warning Buffer Too Small" }, + { 0, NULL } +}; + + +/** + VSPrint function to process format and place the results in Buffer. Since a + VA_LIST is used this rountine allows the nesting of Vararg routines. Thus + this is the main print working routine + + @param StartOfBuffer Unicode buffer to print the results of the parsing of Format into. + + @param BufferSize Maximum number of characters to put into buffer. Zero means + no limit. + + @param Flags Intial flags value. Can only have FORMAT_UNICODE and OUTPUT_UNICODE set + + @param FormatString Unicode format string see file header for more details. + + @param Marker Vararg list consumed by processing Format. + + @return Number of characters printed. + +**/ +UINTN +BasePrintLibVSPrint ( + OUT CHAR8 *Buffer, + IN UINTN BufferSize, + IN UINTN Flags, + IN CONST CHAR8 *Format, + IN VA_LIST Marker + ) +{ + CHAR8 *OriginalBuffer; + CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS]; + UINTN BytesPerOutputCharacter; + UINTN BytesPerFormatCharacter; + UINTN FormatMask; + UINTN FormatCharacter; + UINTN Width; + UINTN Precision; + INT64 Value; + CHAR8 *ArgumentString; + UINTN Character; + GUID *TmpGuid; + TIME *TmpTime; + UINTN Count; + UINTN ArgumentMask; + INTN BytesPerArgumentCharacter; + UINTN ArgumentCharacter; + BOOLEAN Done; + UINTN Index; + CHAR8 Prefix; + BOOLEAN ZeroPad; + BOOLEAN Comma; + UINTN Digits; + UINTN Radix; + RETURN_STATUS Status; + + OriginalBuffer = Buffer; + + if ((Flags & OUTPUT_UNICODE) != 0) { + BytesPerOutputCharacter = 2; + } else { + BytesPerOutputCharacter = 1; + } + if ((Flags & FORMAT_UNICODE) != 0) { + BytesPerFormatCharacter = 2; + FormatMask = 0xffff; + } else { + BytesPerFormatCharacter = 1; + FormatMask = 0xff; + } + + // + // Reserve space for the Null terminator. + // If BufferSize is 0, this will set BufferSize to the max unsigned value + // + BufferSize--; + + // + // Get the first character from the format string + // + FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask; + + // + // Loop until the end of the format string is reached or the output buffer is full + // + while (FormatCharacter != 0 && BufferSize > 0) { + // + // Clear all the flag bits except those that may have been passed in + // + Flags &= (OUTPUT_UNICODE | FORMAT_UNICODE); + + // + // Set the default width to zero, and the default precision to 1 + // + Width = 0; + Precision = 1; + Prefix = 0; + Comma = FALSE; + ZeroPad = FALSE; + Count = 0; + Digits = 0; + + switch (FormatCharacter) { + case '%': + // + // Parse Flags and Width + // + for (Done = FALSE; !Done; ) { + Format += BytesPerFormatCharacter; + FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask; + switch (FormatCharacter) { + case '.': + Flags |= PRECISION; + break; + case '-': + Flags |= LEFT_JUSTIFY; + break; + case '+': + Flags |= PREFIX_SIGN; + break; + case ' ': + Flags |= PREFIX_BLANK; + break; + case ',': + Flags |= COMMA_TYPE; + break; + case 'L': + case 'l': + Flags |= LONG_TYPE; + break; + case '*': + if ((Flags & PRECISION) == 0) { + Flags |= PAD_TO_WIDTH; + Width = VA_ARG (Marker, UINTN); + } else { + Precision = VA_ARG (Marker, UINTN); + } + break; + case '0': + if ((Flags & PRECISION) == 0) { + Flags |= PREFIX_ZERO; + } + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + for (Count = 0; ((FormatCharacter >= '0') && (FormatCharacter <= '9')); ){ + Count = (Count * 10) + FormatCharacter - '0'; + Format += BytesPerFormatCharacter; + FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask; + } + Format -= BytesPerFormatCharacter; + if ((Flags & PRECISION) == 0) { + Flags |= PAD_TO_WIDTH; + Width = Count; + } else { + Precision = Count; + } + break; + default: + Done = TRUE; + break; + } + } + + // + // Limit the maximum field width to the remaining characters in the output buffer + // + if (Width > BufferSize) { + Width = BufferSize; + } + + // + // Handle each argument type + // + switch (FormatCharacter) { + case 'X': + Flags |= PREFIX_ZERO; + // + // break skiped on purpose + // + case 'x': + Flags |= RADIX_HEX; + // + // break skiped on purpose + // + case 'd': + if ((Flags & LONG_TYPE) == 0) { + Value = (VA_ARG (Marker, INTN)); + } else { + Value = VA_ARG (Marker, INT64); + } + if ((Flags & PREFIX_BLANK) != 0) { + Prefix = ' '; + } + if ((Flags & PREFIX_SIGN) != 0) { + Prefix = '+'; + } + if ((Flags & COMMA_TYPE) != 0) { + Comma = TRUE; + } + if ((Flags & RADIX_HEX) == 0) { + Radix = 10; + if (Comma) { + Flags &= (~PREFIX_ZERO); + Precision = 1; + } + if (Value < 0) { + Flags |= PREFIX_SIGN; + Prefix = '-'; + Value = -Value; + } + } else { + Radix = 16; + Comma = FALSE; + if ((Flags & LONG_TYPE) == 0 && Value < 0) { + Value = (UINTN)Value; + } + } + // + // Convert Value to a reversed string + // + Count = BasePrintLibValueToString (ValueBuffer, Value, Radix); + if (Value == 0 && Precision == 0) { + Count = 0; + } + ArgumentString = (CHAR8 *)ValueBuffer + Count; + Digits = 3 - (Count % 3); + if (Comma && Count != 0) { + Count += ((Count - 1) / 3); + } + if (Prefix != 0) { + Count++; + } + Flags |= ARGUMENT_REVERSED; + ZeroPad = TRUE; + if ((Flags & PREFIX_ZERO) != 0) { + if ((Flags & PAD_TO_WIDTH) != 0) { + if ((Flags & PRECISION) == 0) { + Precision = Width; + } + } + } + break; + + case 's': + case 'S': + Flags |= ARGUMENT_UNICODE; + // + // break skipped on purpose + // + case 'a': + ArgumentString = (CHAR8 *)VA_ARG (Marker, CHAR8 *); + if (ArgumentString == NULL) { + Flags &= (~ARGUMENT_UNICODE); + ArgumentString = ""; + } + break; + + case 'c': + Character = VA_ARG (Marker, UINTN) & 0xffff; + ArgumentString = (CHAR8 *)&Character; + Flags |= ARGUMENT_UNICODE; + break; + + case 'g': + TmpGuid = VA_ARG (Marker, GUID *); + if (TmpGuid == NULL) { + ArgumentString = ""; + } else { + BasePrintLibSPrint ( + ValueBuffer, + 0, + 0, + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + TmpGuid->Data1, + TmpGuid->Data2, + TmpGuid->Data3, + TmpGuid->Data4[0], + TmpGuid->Data4[1], + TmpGuid->Data4[2], + TmpGuid->Data4[3], + TmpGuid->Data4[4], + TmpGuid->Data4[5], + TmpGuid->Data4[6], + TmpGuid->Data4[7] + ); + ArgumentString = ValueBuffer; + } + break; + + case 't': + TmpTime = VA_ARG (Marker, TIME *); + if (TmpTime == NULL) { + ArgumentString = ""; + } else { + BasePrintLibSPrint ( + ValueBuffer, + 0, + 0, + "%02d/%02d/%04d %02d:%02d", + TmpTime->Month, + TmpTime->Day, + TmpTime->Year, + TmpTime->Hour, + TmpTime->Minute + ); + ArgumentString = ValueBuffer; + } + break; + + case 'r': + Status = VA_ARG (Marker, RETURN_STATUS); + ArgumentString = ValueBuffer; + for (Index = 0; StatusString[Index].String != NULL; Index++) { + if (Status == StatusString[Index].Status) { + ArgumentString = StatusString[Index].String; + } + } + if (ArgumentString == ValueBuffer) { + BasePrintLibSPrint ((CHAR8 *) ValueBuffer, 0, 0, "%08X", Status); + } + break; + + case '%': + default: + // + // if the type is '%' or unknown, then print it to the screen + // + ArgumentString = (CHAR8 *)&FormatCharacter; + Flags |= ARGUMENT_UNICODE; + break; + } + break; + case '\n': + ArgumentString = "\n"; + + break; + default: + ArgumentString = (CHAR8 *)&FormatCharacter; + Flags |= ARGUMENT_UNICODE; + break; + } + + // + // Retrieve the ArgumentString attriubutes + // + if ((Flags & ARGUMENT_UNICODE) != 0) { + ArgumentMask = 0xffff; + BytesPerArgumentCharacter = 2; + } else { + ArgumentMask = 0xff; + BytesPerArgumentCharacter = 1; + } + if ((Flags & ARGUMENT_REVERSED) != 0) { + BytesPerArgumentCharacter = -BytesPerArgumentCharacter; + } else { + // + // Compute the number of characters in ArgumentString and store it in Count + // ArgumentString is either null-terminated, or it contains Precision characters + // + for (Count = 0; Count < Precision || ((Flags & PRECISION) == 0); Count++) { + ArgumentCharacter = ((ArgumentString[Count * BytesPerArgumentCharacter] & 0xff) | ((ArgumentString[Count * BytesPerArgumentCharacter + 1]) << 8)) & ArgumentMask; + if (ArgumentCharacter == 0) { + break; + } + } + } + + // + // Limit the length of the string to append to the remaining characters in the output buffer + // + if (Count > BufferSize) { + Count = BufferSize; + } + if (Precision < Count) { + Precision = Count; + } + + // + // Pad before the string + // + if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH)) { + Buffer = BasePrintLibFillBuffer (Buffer, Width - Precision, ' ', BytesPerOutputCharacter); + } + + if (ZeroPad) { + if (Prefix != 0) { + Buffer = BasePrintLibFillBuffer (Buffer, 1, Prefix, BytesPerOutputCharacter); + } + Buffer = BasePrintLibFillBuffer (Buffer, Precision - Count, '0', BytesPerOutputCharacter); + } else { + Buffer = BasePrintLibFillBuffer (Buffer, Precision - Count, ' ', BytesPerOutputCharacter); + if (Prefix != 0) { + Buffer = BasePrintLibFillBuffer (Buffer, 1, Prefix, BytesPerOutputCharacter); + } + } + + // + // Output the Prefix character if it is present + // + Index = 0; + if (Prefix) { + Index++; + } + + // + // Copy the string into the output buffer performing the required type conversions + // + while (Index < Count) { + ArgumentCharacter = ((*ArgumentString & 0xff) | (*(ArgumentString + 1) << 8)) & ArgumentMask; + + Buffer = BasePrintLibFillBuffer (Buffer, 1, ArgumentCharacter, BytesPerOutputCharacter); + ArgumentString += BytesPerArgumentCharacter; + Index++; + if (Comma) { + Digits++; + if (Digits == 3) { + Digits = 0; + Index++; + if (Index < Count) { + Buffer = BasePrintLibFillBuffer (Buffer, 1, ',', BytesPerOutputCharacter); + } + } + } + } + + // + // Pad after the string + // + if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH | LEFT_JUSTIFY)) { + Buffer = BasePrintLibFillBuffer (Buffer, Width - Precision, ' ', BytesPerOutputCharacter); + } + + // + // Reduce the number of characters + // + BufferSize -= Count; + + // + // Get the next character from the format string + // + Format += BytesPerFormatCharacter; + + // + // Get the next character from the format string + // + FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask; + } + + // + // Null terminate the Unicode or ASCII string + // + Buffer = BasePrintLibFillBuffer (Buffer, 1, 0, BytesPerOutputCharacter); + + return ((Buffer - OriginalBuffer) / BytesPerOutputCharacter); +} + +UINTN +BasePrintLibSPrint ( + OUT CHAR8 *StartOfBuffer, + IN UINTN BufferSize, + IN UINTN Flags, + IN CONST CHAR8 *FormatString, + ... + ) +{ + VA_LIST Marker; + + VA_START (Marker, FormatString); + return BasePrintLibVSPrint (StartOfBuffer, BufferSize, Flags, FormatString, Marker); +} + +UINTN +EFIAPI +UnicodeVSPrint ( + OUT CHAR16 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR16 *FormatString, + IN VA_LIST Marker + ) +{ + return BasePrintLibVSPrint ((CHAR8 *)StartOfBuffer, BufferSize >> 1, FORMAT_UNICODE | OUTPUT_UNICODE, (CHAR8 *)FormatString, Marker); +} + +UINTN +EFIAPI +UnicodeSPrint ( + OUT CHAR16 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR16 *FormatString, + ... + ) +{ + VA_LIST Marker; + + VA_START (Marker, FormatString); + return UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker); +} + +UINTN +EFIAPI +UnicodeVSPrintAsciiFormat ( + OUT CHAR16 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR8 *FormatString, + IN VA_LIST Marker + ) +{ + return BasePrintLibVSPrint ((CHAR8 *)StartOfBuffer, BufferSize >> 1, OUTPUT_UNICODE,FormatString, Marker); +} + +UINTN +EFIAPI +UnicodeSPrintAsciiFormat ( + OUT CHAR16 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR8 *FormatString, + ... + ) +{ + VA_LIST Marker; + + VA_START (Marker, FormatString); + return UnicodeVSPrintAsciiFormat (StartOfBuffer, BufferSize >> 1, FormatString, Marker); +} + +UINTN +EFIAPI +AsciiVSPrint ( + OUT CHAR8 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR8 *FormatString, + IN VA_LIST Marker + ) +{ + return BasePrintLibVSPrint (StartOfBuffer, BufferSize, 0, FormatString, Marker); +} + +UINTN +EFIAPI +AsciiSPrint ( + OUT CHAR8 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR8 *FormatString, + ... + ) +{ + VA_LIST Marker; + + VA_START (Marker, FormatString); + return AsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker); +} + +UINTN +EFIAPI +AsciiVSPrintUnicodeFormat ( + OUT CHAR8 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR16 *FormatString, + IN VA_LIST Marker + ) +{ + return BasePrintLibVSPrint (StartOfBuffer, BufferSize, FORMAT_UNICODE, (CHAR8 *)FormatString, Marker); +} + +UINTN +EFIAPI +AsciiSPrintUnicodeFormat ( + OUT CHAR8 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR16 *FormatString, + ... + ) +{ + VA_LIST Marker; + + VA_START (Marker, FormatString); + return AsciiVSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker); +} + +UINTN +EFIAPI +UnicodeValueToString ( + IN OUT CHAR16 *Buffer, + IN UINTN Flags, + IN INT64 Value, + IN UINTN Width + ) +{ + return BasePrintLibConvertValueToString ((CHAR8 *)Buffer, Flags, Value, Width, 2); +} + +UINTN +EFIAPI +AsciiValueToString ( + IN OUT CHAR8 *Buffer, + IN UINTN Flags, + IN INT64 Value, + IN UINTN Width + ) +{ + return BasePrintLibConvertValueToString ((CHAR8 *)Buffer, Flags, Value, Width, 1); +} diff --git a/Tools/CodeTools/Source/String/PrintLibInternal.c b/Tools/CodeTools/Source/String/PrintLibInternal.c new file mode 100644 index 0000000000..63d0c7196f --- /dev/null +++ b/Tools/CodeTools/Source/String/PrintLibInternal.c @@ -0,0 +1,142 @@ +/*++ + +Copyright (c) 2004-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +Module Name: + + PrintLibInternal.c + +Abstract: + + Print Library worker functions. + +--*/ + +#include +#include + +#include "CommonLib.h" +#include "PrintLibInternal.h" + +static CONST CHAR8 mHexStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; + +CHAR8 * +BasePrintLibFillBuffer ( + CHAR8 *Buffer, + INTN Length, + UINTN Character, + INTN Increment + ) +{ + INTN Index; + + for (Index = 0; Index < Length; Index++) { + *Buffer = (CHAR8) Character; + *(Buffer + 1) = (CHAR8) (Character >> 8); + Buffer += Increment; + } + return Buffer; +} + +/** + Print worker function that prints a Value as a decimal number in Buffer. + + @param Buffer Location to place the Unicode or ASCII string of Value. + + @param Value Value to convert to a Decimal or Hexidecimal string in Buffer. + + @param Flags Flags to use in printing string, see file header for details. + + @param Precision Minimum number of digits to return in the ASCII string + + @return Number of characters printed. + +**/ +UINTN +EFIAPI +BasePrintLibValueToString ( + IN OUT CHAR8 *Buffer, + IN INT64 Value, + IN UINTN Radix + ) +{ + UINTN Digits; + UINT32 Remainder; + + // + // Loop to convert one digit at a time in reverse order + // + *(Buffer++) = 0; + Digits = 0; + do { + // Value = (INT64)DivU64x32Remainder ((UINT64)Value, (UINT32)Radix, &Remainder); + Remainder = (UINT64)Value % (UINT32)Radix; + Value = (UINT64)Value / (UINT32)Radix; + *(Buffer++) = mHexStr[Remainder]; + Digits++; + } while (Value != 0); + return Digits; +} + +UINTN +BasePrintLibConvertValueToString ( + IN OUT CHAR8 *Buffer, + IN UINTN Flags, + IN INT64 Value, + IN UINTN Width, + IN UINTN Increment + ) +{ + CHAR8 *OriginalBuffer; + CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS]; + UINTN Count; + UINTN Digits; + UINTN Index; + + OriginalBuffer = Buffer; + + if (Width == 0 || (Flags & COMMA_TYPE) != 0) { + Flags &= (~PREFIX_ZERO); + } + + if (Width == 0 || Width > (MAXIMUM_VALUE_CHARACTERS - 1)) { + Width = MAXIMUM_VALUE_CHARACTERS - 1; + } + + if (Value < 0) { + Value = -Value; + Buffer = BasePrintLibFillBuffer (Buffer, 1, '-', Increment); + } + + Count = BasePrintLibValueToString (ValueBuffer, Value, 10); + + if ((Flags & PREFIX_ZERO) != 0) { + Buffer = BasePrintLibFillBuffer (Buffer, Width - Count, '0', Increment); + } + + Digits = 3 - (Count % 3); + for (Index = 0; Index < Count; Index++) { + Buffer = BasePrintLibFillBuffer (Buffer, 1, ValueBuffer[Count - Index], Increment); + if ((Flags & COMMA_TYPE) != 0) { + Digits++; + if (Digits == 3) { + Digits = 0; + if ((Index + 1) < Count) { + Buffer = BasePrintLibFillBuffer (Buffer, 1, ',', Increment); + } + } + } + } + + Buffer = BasePrintLibFillBuffer (Buffer, 1, 0, Increment); + + return ((Buffer - OriginalBuffer) / Increment); +} diff --git a/Tools/CodeTools/Source/String/PrintLibInternal.h b/Tools/CodeTools/Source/String/PrintLibInternal.h new file mode 100644 index 0000000000..87f0955e05 --- /dev/null +++ b/Tools/CodeTools/Source/String/PrintLibInternal.h @@ -0,0 +1,101 @@ +/*++ + +Copyright (c) 2004-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +Module Name: + + PrintLibInternal.h + +Abstract: + + Print Library. + +--*/ + + + +// +// Print primitives +// +//#define LEFT_JUSTIFY 0x01 +#define PREFIX_SIGN 0x02 +#define PREFIX_BLANK 0x04 +//#define COMMA_TYPE 0x08 +#define LONG_TYPE 0x10 +//#define PREFIX_ZERO 0x20 +#define OUTPUT_UNICODE 0x40 +#define RADIX_HEX 0x80 +#define FORMAT_UNICODE 0x100 +#define PAD_TO_WIDTH 0x200 +#define ARGUMENT_UNICODE 0x400 +#define PRECISION 0x800 +#define ARGUMENT_REVERSED 0x1000 + +/// +/// Define the maximum number of characters that are required to encode +/// a decimal, hexidecimal, GUID, or TIME value with a Nll terminator. +/// Maximum Length Decimal String = 28 "-9,223,372,036,854,775,808" +/// Maximum Length Hexidecimal String = 17 "FFFFFFFFFFFFFFFF" +/// Maximum Length GUID = 37 "00000000-0000-0000-0000-000000000000" +/// Maximum Length TIME = 18 "12/12/2006 12:12" +/// +#define MAXIMUM_VALUE_CHARACTERS 38 + +// +// +// +typedef struct { + UINT16 Year; + UINT8 Month; + UINT8 Day; + UINT8 Hour; + UINT8 Minute; + UINT8 Second; + UINT8 Pad1; + UINT32 Nanosecond; + INT16 TimeZone; + UINT8 Daylight; + UINT8 Pad2; +} TIME; + +UINTN +BasePrintLibSPrint ( + OUT CHAR8 *Buffer, + IN UINTN BufferSize, + IN UINTN Flags, + IN CONST CHAR8 *FormatString, + ... + ); + +CHAR8 * +BasePrintLibFillBuffer ( + CHAR8 *Buffer, + INTN Length, + UINTN Character, + INTN Increment + ); + +UINTN +EFIAPI +BasePrintLibValueToString ( + IN OUT CHAR8 *Buffer, + IN INT64 Value, + IN UINTN Radix + ); + +UINTN +BasePrintLibConvertValueToString ( + IN OUT CHAR8 *Buffer, + IN UINTN Flags, + IN INT64 Value, + IN UINTN Width, + IN UINTN Increment + ); diff --git a/Tools/CodeTools/Source/String/String.c b/Tools/CodeTools/Source/String/String.c new file mode 100644 index 0000000000..78d0a59fca --- /dev/null +++ b/Tools/CodeTools/Source/String/String.c @@ -0,0 +1,732 @@ +/*++ + +Copyright (c) 2004-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +Module Name: + + String.c + +Abstract: + + Unicode and ASCII string primatives. + +--*/ + +#include + +#include + +#include + +#include "CommonLib.h" + +/** + Returns the length of a Null-terminated Unicode string. + + This function returns the number of Unicode characters in the Null-terminated + Unicode string specified by String. + + If String is NULL, then ASSERT(). + + @param String Pointer to a Null-terminated Unicode string. + + @return The length of String. + +**/ +UINTN +EFIAPI +StrLen ( + IN CONST CHAR16 *String + ) +{ + UINTN Length; + + ASSERT (String != NULL); + + for (Length = 0; *String != L'\0'; String++, Length++) { + ; + } + return Length; +} + +/** + Returns the length of a Null-terminated ASCII string. + + This function returns the number of ASCII characters in the Null-terminated + ASCII string specified by String. + + If String is NULL, then ASSERT(). + + @param String Pointer to a Null-terminated ASCII string. + + @return The length of String. + +**/ +UINTN +EFIAPI +AsciiStrLen ( + IN CONST CHAR8 *String + ) +{ + UINTN Length; + + ASSERT (String != NULL); + + for (Length = 0; *String != '\0'; String++, Length++) { + ; + } + return Length; +} + +/** + Copies one Null-terminated Unicode string to another Null-terminated Unicode + string and returns the new Unicode string. + + This function copies the contents of the Unicode string Source to the Unicode + string Destination, and returns Destination. If Source and Destination + overlap, then the results are undefined. + + If Destination is NULL, then ASSERT(). + If Source is NULL, then ASSERT(). + If Source and Destination overlap, then ASSERT(). + + @param Destination Pointer to a Null-terminated Unicode string. + @param Source Pointer to a Null-terminated Unicode string. + + @return Destiantion + +**/ +CHAR16 * +EFIAPI +StrCpy ( + OUT CHAR16 *Destination, + IN CONST CHAR16 *Source + ) +{ + CHAR16 *ReturnValue; + + // + // Destination cannot be NULL + // + ASSERT (Destination != NULL); + + // + // Destination and source cannot overlap + // + ASSERT ((UINTN)(Destination - Source) > StrLen (Source)); + ASSERT ((UINTN)(Source - Destination) > StrLen (Source)); + + ReturnValue = Destination; + while (*Source) { + *(Destination++) = *(Source++); + } + *Destination = 0; + return ReturnValue; +} + +/** + Copies one Null-terminated Unicode string with a maximum length to another + Null-terminated Unicode string with a maximum length and returns the new + Unicode string. + + This function copies the contents of the Unicode string Source to the Unicode + string Destination, and returns Destination. At most, Length Unicode + characters are copied from Source to Destination. If Length is 0, then + Destination is returned unmodified. If Length is greater that the number of + Unicode characters in Source, then Destination is padded with Null Unicode + characters. If Source and Destination overlap, then the results are + undefined. + + If Destination is NULL, then ASSERT(). + If Source is NULL, then ASSERT(). + If Source and Destination overlap, then ASSERT(). + + @param Destination Pointer to a Null-terminated Unicode string. + @param Source Pointer to a Null-terminated Unicode string. + @param Length Maximum number of Unicode characters to copy. + + @return Destination + +**/ +CHAR16 * +EFIAPI +StrnCpy ( + OUT CHAR16 *Destination, + IN CONST CHAR16 *Source, + IN UINTN Length + ) +{ + CHAR16 *ReturnValue; + + if (Length == 0) { + return Destination; + } + + // + // Destination cannot be NULL if Length is not zero + // + ASSERT (Destination != NULL); + + // + // Destination and source cannot overlap + // Q: Does Source have to be NULL-terminated? + // + ASSERT ((UINTN)(Destination - Source) > StrLen (Source)); + ASSERT ((UINTN)(Source - Destination) >= Length); + + ReturnValue = Destination; + + while ((*Source != L'\0') && (Length > 0)) { + *(Destination++) = *(Source++); + Length--; + } + + memset (Destination, 0, Length * sizeof (*Destination)); + return ReturnValue; +} + +/** + Returns the size of a Null-terminated Unicode string in bytes, including the + Null terminator. + + This function returns the size, in bytes, of the Null-terminated Unicode + string specified by String. + + If String is NULL, then ASSERT(). + + @param String Pointer to a Null-terminated Unicode string. + + @return The size of String. + +**/ +UINTN +EFIAPI +StrSize ( + IN CONST CHAR16 *String + ) +{ + return (StrLen (String) + 1) * sizeof (*String); +} + +/** + Compares two Null-terminated Unicode strings, and returns the difference + between the first mismatched Unicode characters. + + This function compares the Null-terminated Unicode string FirstString to the + Null-terminated Unicode string SecondString. If FirstString is identical to + SecondString, then 0 is returned. Otherwise, the value returned is the first + mismatched Unicode character in SecondString subtracted from the first + mismatched Unicode character in FirstString. + + If FirstString is NULL, then ASSERT(). + If SecondString is NULL, then ASSERT(). + + @param FirstString Pointer to a Null-terminated Unicode string. + @param SecondString Pointer to a Null-terminated Unicode string. + + @retval 0 FirstString is identical to SecondString. + @retval !=0 FirstString is not identical to SecondString. + +**/ +INTN +EFIAPI +StrCmp ( + IN CONST CHAR16 *FirstString, + IN CONST CHAR16 *SecondString + ) +{ + // + // ASSERT both strings should never be zero + // + ASSERT (StrSize (FirstString) != 0); + ASSERT (StrSize (SecondString) != 0); + + while ((*FirstString != L'\0') && (*FirstString == *SecondString)) { + FirstString++; + SecondString++; + } + return *FirstString - *SecondString; +} + +/** + Compares two Null-terminated Unicode strings with maximum lengths, and + returns the difference between the first mismatched Unicode characters. + + This function compares the Null-terminated Unicode string FirstString to the + Null-terminated Unicode string SecondString. At most, Length Unicode + characters will be compared. If Length is 0, then 0 is returned. If + FirstString is identical to SecondString, then 0 is returned. Otherwise, the + value returned is the first mismatched Unicode character in SecondString + subtracted from the first mismatched Unicode character in FirstString. + + If FirstString is NULL, then ASSERT(). + If SecondString is NULL, then ASSERT(). + + @param FirstString Pointer to a Null-terminated Unicode string. + @param SecondString Pointer to a Null-terminated Unicode string. + @param Length Maximum number of Unicode characters to compare. + + @retval 0 FirstString is identical to SecondString. + @retval !=0 FirstString is not identical to SecondString. + +**/ +INTN +EFIAPI +StrnCmp ( + IN CONST CHAR16 *FirstString, + IN CONST CHAR16 *SecondString, + IN UINTN Length + ) +{ + if (Length == 0) { + return 0; + } + + // + // ASSERT both strings should never be zero + // + ASSERT (StrSize (FirstString) != 0); + ASSERT (StrSize (SecondString) != 0); + + while ((*FirstString != L'\0') && + (*FirstString == *SecondString) && + (Length > 1)) { + FirstString++; + SecondString++; + Length--; + } + + return *FirstString - *SecondString; +} + +/** + Concatenates one Null-terminated Unicode string to another Null-terminated + Unicode string, and returns the concatenated Unicode string. + + This function concatenates two Null-terminated Unicode strings. The contents + of Null-terminated Unicode string Source are concatenated to the end of + Null-terminated Unicode string Destination. The Null-terminated concatenated + Unicode String is returned. If Source and Destination overlap, then the + results are undefined. + + If Destination is NULL, then ASSERT(). + If Source is NULL, then ASSERT(). + If Source and Destination overlap, then ASSERT(). + + @param Destination Pointer to a Null-terminated Unicode string. + @param Source Pointer to a Null-terminated Unicode string. + + @return Destination + +**/ +CHAR16 * +EFIAPI +StrCat ( + IN OUT CHAR16 *Destination, + IN CONST CHAR16 *Source + ) +{ + StrCpy (Destination + StrLen (Destination), Source); + + // + // Size of the resulting string should never be zero. + // + ASSERT (StrSize (Destination) != 0); + return Destination; +} + +/** + Concatenates one Null-terminated Unicode string with a maximum length to the + end of another Null-terminated Unicode string, and returns the concatenated + Unicode string. + + This function concatenates two Null-terminated Unicode strings. The contents + of Null-terminated Unicode string Source are concatenated to the end of + Null-terminated Unicode string Destination, and Destination is returned. At + most, Length Unicode characters are concatenated from Source to the end of + Destination, and Destination is always Null-terminated. If Length is 0, then + Destination is returned unmodified. If Source and Destination overlap, then + the results are undefined. + + If Destination is NULL, then ASSERT(). + If Source is NULL, then ASSERT(). + If Source and Destination overlap, then ASSERT(). + + @param Destination Pointer to a Null-terminated Unicode string. + @param Source Pointer to a Null-terminated Unicode string. + @param Length Maximum number of Unicode characters to concatenate from + Source. + + @return Destination + +**/ +CHAR16 * +EFIAPI +StrnCat ( + IN OUT CHAR16 *Destination, + IN CONST CHAR16 *Source, + IN UINTN Length + ) +{ + StrnCpy (Destination + StrLen (Destination), Source, Length); + + // + // Size of the resulting string should never be zero. + // + ASSERT (StrSize (Destination) != 0); + return Destination; +} + +/** + Copies one Null-terminated ASCII string to another Null-terminated ASCII + string and returns the new ASCII string. + + This function copies the contents of the ASCII string Source to the ASCII + string Destination, and returns Destination. If Source and Destination + overlap, then the results are undefined. + + If Destination is NULL, then ASSERT(). + If Source is NULL, then ASSERT(). + If Source and Destination overlap, then ASSERT(). + + @param Destination Pointer to a Null-terminated ASCII string. + @param Source Pointer to a Null-terminated ASCII string. + + @return Destination + +**/ +CHAR8 * +EFIAPI +AsciiStrCpy ( + OUT CHAR8 *Destination, + IN CONST CHAR8 *Source + ) +{ + CHAR8 *ReturnValue; + + // + // Destination cannot be NULL + // + ASSERT (Destination != NULL); + + // + // Destination and source cannot overlap + // + ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source)); + ASSERT ((UINTN)(Source - Destination) > AsciiStrLen (Source)); + + ReturnValue = Destination; + while (*Source) { + *(Destination++) = *(Source++); + } + *Destination = 0; + return ReturnValue; +} + +/** + Copies one Null-terminated ASCII string with a maximum length to another + Null-terminated ASCII string with a maximum length and returns the new ASCII + string. + + This function copies the contents of the ASCII string Source to the ASCII + string Destination, and returns Destination. At most, Length ASCII characters + are copied from Source to Destination. If Length is 0, then Destination is + returned unmodified. If Length is greater that the number of ASCII characters + in Source, then Destination is padded with Null ASCII characters. If Source + and Destination overlap, then the results are undefined. + + If Destination is NULL, then ASSERT(). + If Source is NULL, then ASSERT(). + If Source and Destination overlap, then ASSERT(). + + @param Destination Pointer to a Null-terminated ASCII string. + @param Source Pointer to a Null-terminated ASCII string. + @param Length Maximum number of ASCII characters to copy. + + @return Destination + +**/ +CHAR8 * +EFIAPI +AsciiStrnCpy ( + OUT CHAR8 *Destination, + IN CONST CHAR8 *Source, + IN UINTN Length + ) +{ + CHAR8 *ReturnValue; + + if (Length == 0) { + return Destination; + } + + // + // Destination cannot be NULL + // + ASSERT (Destination != NULL); + + // + // Destination and source cannot overlap + // + ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source)); + ASSERT ((UINTN)(Source - Destination) >= Length); + + ReturnValue = Destination; + + while (*Source && Length > 0) { + *(Destination++) = *(Source++); + Length--; + } + + // ZeroMem (Destination, Length * sizeof (*Destination)); + memset (Destination, 0, Length * sizeof (*Destination)); + return ReturnValue; +} + +/** + Returns the size of a Null-terminated ASCII string in bytes, including the + Null terminator. + + This function returns the size, in bytes, of the Null-terminated ASCII string + specified by String. + + If String is NULL, then ASSERT(). + + @param String Pointer to a Null-terminated ASCII string. + + @return The size of String. + +**/ +UINTN +EFIAPI +AsciiStrSize ( + IN CONST CHAR8 *String + ) +{ + return (AsciiStrLen (String) + 1) * sizeof (*String); +} + +/** + Compares two Null-terminated ASCII strings, and returns the difference + between the first mismatched ASCII characters. + + This function compares the Null-terminated ASCII string FirstString to the + Null-terminated ASCII string SecondString. If FirstString is identical to + SecondString, then 0 is returned. Otherwise, the value returned is the first + mismatched ASCII character in SecondString subtracted from the first + mismatched ASCII character in FirstString. + + If FirstString is NULL, then ASSERT(). + If SecondString is NULL, then ASSERT(). + + @param FirstString Pointer to a Null-terminated ASCII string. + @param SecondString Pointer to a Null-terminated ASCII string. + + @retval 0 FirstString is identical to SecondString. + @retval !=0 FirstString is not identical to SecondString. + +**/ +INTN +EFIAPI +AsciiStrCmp ( + IN CONST CHAR8 *FirstString, + IN CONST CHAR8 *SecondString + ) +{ + // + // ASSERT both strings should never be zero + // + ASSERT (AsciiStrSize (FirstString)); + ASSERT (AsciiStrSize (SecondString)); + + while ((*FirstString != '\0') && (*FirstString == *SecondString)) { + FirstString++; + SecondString++; + } + + return *FirstString - *SecondString; +} + +STATIC +CHAR8 +EFIAPI +AsciiToUpper ( + IN CHAR8 Chr + ) +{ + return (Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr; +} + +/** + Performs a case insensitive comparison of two Null-terminated ASCII strings, + and returns the difference between the first mismatched ASCII characters. + + This function performs a case insensitive comparison of the Null-terminated + ASCII string FirstString to the Null-terminated ASCII string SecondString. If + FirstString is identical to SecondString, then 0 is returned. Otherwise, the + value returned is the first mismatched lower case ASCII character in + SecondString subtracted from the first mismatched lower case ASCII character + in FirstString. + + If FirstString is NULL, then ASSERT(). + If SecondString is NULL, then ASSERT(). + + @param FirstString Pointer to a Null-terminated ASCII string. + @param SecondString Pointer to a Null-terminated ASCII string. + + @retval 0 FirstString is identical to SecondString using case insensitive + comparisons. + @retval !=0 FirstString is not identical to SecondString using case + insensitive comparisons. + +**/ +INTN +EFIAPI +AsciiStriCmp ( + IN CONST CHAR8 *FirstString, + IN CONST CHAR8 *SecondString + ) +{ + // + // ASSERT both strings should never be zero + // + ASSERT (AsciiStrSize (FirstString)); + ASSERT (AsciiStrSize (SecondString)); + + while ((*FirstString != '\0') && + (AsciiToUpper (*FirstString) == AsciiToUpper (*SecondString))) { + FirstString++; + SecondString++; + } + + return AsciiToUpper (*FirstString) - AsciiToUpper (*SecondString); +} + +/** + Compares two Null-terminated ASCII strings with maximum lengths, and returns + the difference between the first mismatched ASCII characters. + + This function compares the Null-terminated ASCII string FirstString to the + Null-terminated ASCII string SecondString. At most, Length ASCII characters + will be compared. If Length is 0, then 0 is returned. If FirstString is + identical to SecondString, then 0 is returned. Otherwise, the value returned + is the first mismatched ASCII character in SecondString subtracted from the + first mismatched ASCII character in FirstString. + + If FirstString is NULL, then ASSERT(). + If SecondString is NULL, then ASSERT(). + + @param FirstString Pointer to a Null-terminated ASCII string. + @param SecondString Pointer to a Null-terminated ASCII string. + + @retval 0 FirstString is identical to SecondString. + @retval !=0 FirstString is not identical to SecondString. + +**/ +INTN +EFIAPI +AsciiStrnCmp ( + IN CONST CHAR8 *FirstString, + IN CONST CHAR8 *SecondString, + IN UINTN Length + ) +{ + // + // ASSERT both strings should never be zero + // + ASSERT (AsciiStrSize (FirstString)); + ASSERT (AsciiStrSize (SecondString)); + + while ((*FirstString != '\0') && + (*FirstString == *SecondString) && + (Length > 1)) { + FirstString++; + SecondString++; + Length--; + } + return *FirstString - *SecondString; +} + +/** + Concatenates one Null-terminated ASCII string to another Null-terminated + ASCII string, and returns the concatenated ASCII string. + + This function concatenates two Null-terminated ASCII strings. The contents of + Null-terminated ASCII string Source are concatenated to the end of Null- + terminated ASCII string Destination. The Null-terminated concatenated ASCII + String is returned. + + If Destination is NULL, then ASSERT(). + If Source is NULL, then ASSERT(). + + @param Destination Pointer to a Null-terminated ASCII string. + @param Source Pointer to a Null-terminated ASCII string. + + @return Destination + +**/ +CHAR8 * +EFIAPI +AsciiStrCat ( + IN OUT CHAR8 *Destination, + IN CONST CHAR8 *Source + ) +{ + AsciiStrCpy (Destination + AsciiStrLen (Destination), Source); + + // + // Size of the resulting string should never be zero. + // + ASSERT (AsciiStrSize (Destination) != 0); + return Destination; +} + +/** + Concatenates one Null-terminated ASCII string with a maximum length to the + end of another Null-terminated ASCII string, and returns the concatenated + ASCII string. + + This function concatenates two Null-terminated ASCII strings. The contents + of Null-terminated ASCII string Source are concatenated to the end of Null- + terminated ASCII string Destination, and Destination is returned. At most, + Length ASCII characters are concatenated from Source to the end of + Destination, and Destination is always Null-terminated. If Length is 0, then + Destination is returned unmodified. If Source and Destination overlap, then + the results are undefined. + + If Destination is NULL, then ASSERT(). + If Source is NULL, then ASSERT(). + If Source and Destination overlap, then ASSERT(). + + @param Destination Pointer to a Null-terminated ASCII string. + @param Source Pointer to a Null-terminated ASCII string. + @param Length Maximum number of ASCII characters to concatenate from + Source. + + @return Destination + +**/ +CHAR8 * +EFIAPI +AsciiStrnCat ( + IN OUT CHAR8 *Destination, + IN CONST CHAR8 *Source, + IN UINTN Length + ) +{ + AsciiStrnCpy (Destination + AsciiStrLen (Destination), Source, Length); + + // + // Size of the resulting string should never be zero. + // + ASSERT (AsciiStrSize (Destination) != 0); + return Destination; +} diff --git a/Tools/CodeTools/Source/String/build.xml b/Tools/CodeTools/Source/String/build.xml new file mode 100644 index 0000000000..933cb5c1e4 --- /dev/null +++ b/Tools/CodeTools/Source/String/build.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/Strip/Strip.c b/Tools/CodeTools/Source/Strip/Strip.c new file mode 100644 index 0000000000..bccdffb55a --- /dev/null +++ b/Tools/CodeTools/Source/Strip/Strip.c @@ -0,0 +1,105 @@ +/*++ + +Copyright (c) 2004-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +Module Name: + + Strip.c + +Abstract: + + Quick Exe2Bin equivalent. + +--*/ + +#include +#include +#include +#include + +int +main ( + int argc, + char *argv[] + ) +/*++ + +Routine Description: + + Converts executable files to binary files. + +Arguments: + + argc - Number of command line arguments + argv[] - Array of pointers to the command line arguments + +Returns: + + Zero - Function completed successfully. + Non-zero - Function exited with errors. + +--*/ +{ + FILE *InFile; + FILE *OutFile; + int Index; + int FileSize; + char *Buffer; + char *Ptrx; + + if (argc < 3) { + printf ("Need more args, such as file name to convert and output name\n"); + return -1; + } + + InFile = fopen (argv[1], "rb"); + OutFile = fopen (argv[2], "wb"); + + if (!InFile) { + printf ("no file, exit\n"); + return -1; + } + + if (OutFile == NULL) { + printf ("Unable to open output file.\n"); + return -1; + } + + fseek (InFile, 0, SEEK_END); + FileSize = ftell (InFile); + + if (FileSize < 0x200) { + printf ("%d is not a legal size, exit\n", FileSize); + return -1; + } + + fseek (InFile, 0, SEEK_SET); + + Buffer = (char *) malloc (FileSize); + if (Buffer == NULL) { + printf ("Error: Out of resources.\n"); + return -1; + } + + fread (Buffer, 1, FileSize, InFile); + + Ptrx = Buffer + 0x200; + + Index = FileSize - 0x200; + + fwrite (Ptrx, Index, 1, OutFile); + + fclose (InFile); + fclose (OutFile); + free (Buffer); + + return 0; +} diff --git a/Tools/CodeTools/Source/Strip/build.xml b/Tools/CodeTools/Source/Strip/build.xml new file mode 100644 index 0000000000..9ead28d16f --- /dev/null +++ b/Tools/CodeTools/Source/Strip/build.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/TianoTools.msa b/Tools/CodeTools/Source/TianoTools.msa new file mode 100644 index 0000000000..2e4b27c19d --- /dev/null +++ b/Tools/CodeTools/Source/TianoTools.msa @@ -0,0 +1,316 @@ + + + + Tiano C Tools + TOOL + A169C678-3F55-4b6a-80BF-FD8B8DCAB883 + 2.0 + This is the TianoTools Module + This Module provides the EFI/Tiano Tools that are used to create EFI/Tiano + Modules and Platform Binary Files (PBF) + These tools require compilation only once if the Developer Workstation and + the Developer's choice of HOST tool chain are stable. If the developer + updates either the OS or the HOST tool chain, these tools should be rebuilt. + Copyright 2006, Intel Corporation + All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the +BSD License which accompanies this distribution. The full text of the +license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + EBC IA32 X64 IPF + false + NULL + + + build.xml + Common/build.xml + Common/CommonLib.c + Common/CommonLib.h + Common/Crc32.c + Common/Crc32.h + Common/EfiCompress.c + Common/EfiCompress.h + Common/EfiCustomizedCompress.h + Common/EfiDecompress.c + Common/EfiDecompress.h + Common/EfiUtilityMsgs.c + Common/EfiUtilityMsgs.h + Common/FvLib.c + Common/FvLib.h + Common/MyAlloc.c + Common/MyAlloc.h + Common/ParseInf.c + Common/ParseInf.h + Common/SimpleFileParsing.c + Common/SimpleFileParsing.h + Common/WinNtInclude.h + CompressDll/build.xml + CompressDll/CompressDll.c + CompressDll/CompressDll.h + CreateMtFile/build.xml + CreateMtFile/CreateMtFile.c + CustomizedCompress/build.xml + CustomizedCompress/CustomizedCompress.c + EfiCompress/build.xml + EfiCompress/EfiCompressMain.c + EfiCompress/makefile + EfiRom/build.xml + EfiRom/EfiRom.c + FlashMap/build.xml + FlashMap/FlashDefFile.c + FlashMap/FlashDefFile.h + FlashMap/FlashMap.c + FlashMap/Microcode.c + FlashMap/Microcode.h + FlashMap/Symbols.c + FlashMap/Symbols.h + FwImage/build.xml + FwImage/fwimage.c + GenAcpiTable/build.xml + GenAcpiTable/GenAcpiTable.c + GenCapsuleHdr/build.xml + GenCapsuleHdr/CreateGuid.c + GenCapsuleHdr/GenCapsuleHdr.c + GenCRC32Section/build.xml + GenCRC32Section/GenCRC32Section.c + GenCRC32Section/GenCRC32Section.h + GenDepex/build.xml + GenDepex/DepexParser.c + GenDepex/DepexParser.h + GenDepex/GenDepex.c + GenDepex/GenDepex.h + GenFfsFile/build.xml + GenFfsFile/GenFfsFile.c + GenFfsFile/GenFfsFile.h + GenFfsFile/SimpleFileParsing.c + GenFvImage/build.xml + GenFvImage/Ebc/PeCoffLoaderEx.c + GenFvImage/GenFvImageExe.c + GenFvImage/GenFvImageExe.h + GenFvImage/GenFvImageLib.c + GenFvImage/GenFvImageLib.h + GenFvImage/GenFvImageLibInternal.h + GenSection/build.xml + GenSection/GenSection.c + GenSection/GenSection.h + GenTEImage/build.xml + GenTEImage/GenTEImage.c + GuidChk/build.xml + GuidChk/CommonUtils.h + GuidChk/FileSearch.c + GuidChk/FileSearch.h + GuidChk/GuidChk.c + GuidChk/GuidList.c + GuidChk/UtilsMsgs.c + GuidChk/UtilsMsgs.h + Include/Common/BaseTypes.h + Include/Common/Capsule.h + Include/Common/Dependency.h + Include/Common/EfiImage.h + Include/Common/FirmwareFileSystem.h + Include/Common/FirmwareVolumeHeader.h + Include/Common/FirmwareVolumeImageFormat.h + Include/Common/InternalFormRepresentation.h + Include/Common/MultiPhase.h + Include/Common/UefiBaseTypes.h + Include/Common/Variable.h + Include/Common/WorkingBlockHeader.h + Include/Guid/AcpiTableStorage.h + Include/Guid/Apriori.h + Include/Guid/Capsule.h + Include/Guid/FirmwareFileSystem.h + Include/Ia32/ProcessorBind.h + Include/IndustryStandard/pci22.h + Include/Library/PeCoffLib.h + Include/Library/PrintLib.h + Include/Protocol/DevicePath.h + Include/Protocol/GuidedSectionExtraction.h + Include/Protocol/Hii.h + Include/Protocol/UgaDraw.h + MakeDeps/build.xml + MakeDeps/MakeDeps.c + ModifyInf/build.xml + ModifyInf/ModifyInf.c + Pccts/antlr/antlr.1 + Pccts/antlr/antlr.c + Pccts/antlr/antlr.g + Pccts/antlr/antlr.ilk + Pccts/antlr/antlr.pdb + Pccts/antlr/antlr.r + Pccts/antlr/antlr1.txt + Pccts/antlr/AntlrMS.mak + Pccts/antlr/AntlrPPC.mak + Pccts/antlr/bits.c + Pccts/antlr/build.c + Pccts/antlr/build.xml + Pccts/antlr/dumpcycles.c + Pccts/antlr/dumpnode.c + Pccts/antlr/egman.c + Pccts/antlr/err.c + Pccts/antlr/fcache.c + Pccts/antlr/fset.c + Pccts/antlr/fset2.c + Pccts/antlr/gen.c + Pccts/antlr/generic.h + Pccts/antlr/globals.c + Pccts/antlr/hash.c + Pccts/antlr/hash.h + Pccts/antlr/lex.c + Pccts/antlr/main.c + Pccts/antlr/makefile + Pccts/antlr/makefile1 + Pccts/antlr/misc.c + Pccts/antlr/mode.h + Pccts/antlr/mrhoist.c + Pccts/antlr/parser.dlg + Pccts/antlr/pred.c + Pccts/antlr/proto.h + Pccts/antlr/README + Pccts/antlr/scan.c + Pccts/antlr/stdpccts.h + Pccts/antlr/syn.h + Pccts/antlr/tokens.h + Pccts/antlr/vc70.pdb + Pccts/build.xml + Pccts/CHANGES_FROM_131.txt + Pccts/CHANGES_FROM_133.txt + Pccts/CHANGES_FROM_133_BEFORE_MR13.txt + Pccts/CHANGES_SUMMARY.txt + Pccts/dlg/automata.c + Pccts/dlg/build.xml + Pccts/dlg/dlg.1 + Pccts/dlg/dlg.h + Pccts/dlg/dlg.r + Pccts/dlg/dlg1.txt + Pccts/dlg/dlg_a.c + Pccts/dlg/dlg_p.c + Pccts/dlg/dlg_p.g + Pccts/dlg/DlgMS.mak + Pccts/dlg/DlgPPC.mak + Pccts/dlg/err.c + Pccts/dlg/main.c + Pccts/dlg/makefile + Pccts/dlg/makefile1 + Pccts/dlg/mode.h + Pccts/dlg/output.c + Pccts/dlg/parser.dlg + Pccts/dlg/relabel.c + Pccts/dlg/stdpccts.h + Pccts/dlg/support.c + Pccts/dlg/tokens.h + Pccts/h/antlr.h + Pccts/h/AParser.cpp + Pccts/h/AParser.h + Pccts/h/ast.c + Pccts/h/ast.h + Pccts/h/ASTBase.cpp + Pccts/h/ASTBase.h + Pccts/h/AToken.h + Pccts/h/ATokenBuffer.cpp + Pccts/h/ATokenBuffer.h + Pccts/h/ATokenStream.h + Pccts/h/ATokPtr.h + Pccts/h/ATokPtrImpl.h + Pccts/h/BufFileInput.cpp + Pccts/h/BufFileInput.h + Pccts/h/charbuf.h + Pccts/h/charptr.c + Pccts/h/charptr.h + Pccts/h/config.h + Pccts/h/DLexer.h + Pccts/h/DLexerBase.cpp + Pccts/h/DLexerBase.h + Pccts/h/DLG_stream_input.h + Pccts/h/dlgauto.h + Pccts/h/dlgdef.h + Pccts/h/err.h + Pccts/h/int.h + Pccts/h/PBlackBox.h + Pccts/h/pccts_assert.h + Pccts/h/pccts_iostream.h + Pccts/h/pccts_istream.h + Pccts/h/pccts_setjmp.h + Pccts/h/pccts_stdarg.h + Pccts/h/pccts_stdio.h + Pccts/h/pccts_stdlib.h + Pccts/h/pccts_string.h + Pccts/h/PCCTSAST.cpp + Pccts/h/PCCTSAST.h + Pccts/h/pcctscfg.h + Pccts/h/pcnames.bat + Pccts/h/slist.cpp + Pccts/h/SList.h + Pccts/history.ps + Pccts/history.txt + Pccts/KNOWN_PROBLEMS.txt + Pccts/makefile + Pccts/MPW_Read_Me + Pccts/NOTES.bcc + Pccts/NOTES.msvc + Pccts/README + Pccts/RIGHTS + Pccts/support/genmk/genmk.c + Pccts/support/genmk/genmk_old.c + Pccts/support/genmk/makefile + Pccts/support/rexpr/makefile + Pccts/support/rexpr/rexpr.c + Pccts/support/rexpr/rexpr.h + Pccts/support/rexpr/test.c + Pccts/support/set/set.c + Pccts/support/set/set.h + Pccts/support/sym/sym.c + Pccts/support/sym/template.h + PeCoffLoader/BasePeCoff.c + PeCoffLoader/build.xml + PeCoffLoader/Common/EfiImage.h + PeCoffLoader/Ia32/PeCoffLoaderEx.c + PeCoffLoader/Ipf/PeCoffLoaderEx.c + PeCoffLoader/X64/PeCoffLoaderEx.c + PeiRebase/build.xml + PeiRebase/makefile + PeiRebase/PeiRebaseExe.c + PeiRebase/PeiRebaseExe.h + SecApResetVectorFixup/build.xml + SecApResetVectorFixup/SecApResetVectorFixup.c + SecApResetVectorFixup/SecApResetVectorFixup.h + SecFixup/build.xml + SecFixup/SecFixup.c + SecFixup/SecFixup.h + SetStamp/build.xml + SetStamp/SetStamp.c + SplitFile/build.xml + SplitFile/SplitFile.c + StrGather/build.xml + StrGather/StrGather.c + StrGather/StrGather.h + StrGather/StringDB.c + StrGather/StringDB.h + String/build.xml + String/PrintLib.c + String/PrintLibInternal.c + String/PrintLibInternal.h + String/String.c + Strip/build.xml + Strip/Strip.c + VfrCompile/build.xml + VfrCompile/DLGLexer.cpp + VfrCompile/DLGLexer.h + VfrCompile/EfiVfr.h + VfrCompile/EfiVfrParser.cpp + VfrCompile/EfiVfrParser.h + VfrCompile/parser.dlg + VfrCompile/tokens.h + VfrCompile/VfrCompile.cpp + VfrCompile/VfrCompile.g + VfrCompile/VfrServices.cpp + VfrCompile/VfrServices.h + ZeroDebugData/build.xml + ZeroDebugData/ZeroDebugData.c + + \ No newline at end of file diff --git a/Tools/CodeTools/Source/VfrCompile/EfiVfr.h b/Tools/CodeTools/Source/VfrCompile/EfiVfr.h new file mode 100644 index 0000000000..6419ad7e71 --- /dev/null +++ b/Tools/CodeTools/Source/VfrCompile/EfiVfr.h @@ -0,0 +1,181 @@ +/*++ + +Copyright (c) 2004 - 2005, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + EfiVfr.h + +Abstract: + + Defines and prototypes for the EFI internal forms representation + setup protocol and drivers + +--*/ + +#ifndef _EFI_VFR_H_ +#define _EFI_VFR_H_ + +#include + +#include +#include + +// +// This number should be incremented with each change to the VFR compiler. +// We write the version to the output list file for debug purposes. +// +#define VFR_COMPILER_VERSION "1.88" + +// +// Maximum file path for filenames +// +#ifndef MAX_PATH +#define MAX_PATH 255 +#endif +#define MAX_QUEUE_COUNT 255 +#define MAX_LINE_LEN 1024 +#define PROGRAM_NAME "VfrCompile" + +// +// We parse C-style structure definitions which can then be referenced +// in VFR statements. +// We need to define an internal structure that can be used to +// track the fields in a structure definition, and another structure +// to keep track of the structure name and subfields. +// +typedef struct _STRUCT_FIELD_DEFINITION { + struct _STRUCT_FIELD_DEFINITION *Next; + int DataSize; + int Offset; // from the start of the structure + int ArrayLength; + char IsArray; + char *Name; +} STRUCT_FIELD_DEFINITION; + +typedef struct _STRUCT_DEFINITION { + struct _STRUCT_DEFINITION *Next; + int Size; + int LineNum; // line number where the structure was defined + int IsNonNV; // if this is the non-NV data structure definition + int Referenced; // if it's referenced anywhere in the VFR + int VarStoreIdValid; // found a 'varstore' statement for it in the VFR + unsigned short VarStoreId; // key from a varstore IFR statement + int VarStoreLineNum; // line number where VARSTORE was defined + char *Name; + STRUCT_FIELD_DEFINITION *Field; + STRUCT_FIELD_DEFINITION *LastField; +} STRUCT_DEFINITION; + +// +// For the IdEqValList variable list of UINT16's, keep track of them using +// a linked list until we know how many there are. +// We also use a linked list of these to keep track of labels used in +// the VFR script so we can catch duplicates. +// We'll also use it to keep track of defined varstore id's so we can +// detect duplicate definitions. +// +typedef struct _UINT16_LIST { + struct _UINT16_LIST *Next; + UINT16 Value; + UINT32 LineNum; +} UINT16_LIST; + +typedef struct _GOTO_REFERENCE { + struct _GOTO_REFERENCE *Next; + UINT32 RefLineNum; // line number of source file where referenced + UINT16 Value; +} GOTO_REFERENCE; + +typedef struct _FORM_ID_VALUE { + struct _FORM_ID_VALUE *Next; + UINT32 LineNum; + UINT16 Value; +} FORM_ID_VALUE; + +// +// We keep track in the parser of all "#line 4 "x.y"" strings so we +// can cross-reference the line numbers in the preprocessor output .i file +// to the original input files. +// +typedef struct _PARSER_LINE_DEFINITION { + struct _PARSER_LINE_DEFINITION *Next; + UINT32 HashLineNum; // from the #line stmt + UINT32 TokenLineNum; // line number in the .i file + CHAR8 *FileName; // from the #line stmt +} PARSER_LINE_DEFINITION; + +extern PARSER_LINE_DEFINITION *gLineDefinition; +extern PARSER_LINE_DEFINITION *gLastLineDefinition; + +extern +char * +ConvertLineNumber ( + UINT32 *LineNum + ) +/*++ + +Routine Description: + Given the line number in the preprocessor-output file, use the line number + information we've saved to determine the source file name and line number + where the code originally came from. This is required for error reporting. + +Arguments: + LineNum - the line number in the preprocessor-output file. + +Returns: + Returns a pointer to the source file name. Also returns the line number + in the provided LineNum argument + +--*/ +; + +typedef struct _IFR_BYTE { + struct _IFR_BYTE *Next; + UINT32 LineNum; + UINT8 OpcodeByte; + UINT8 KeyByte; +} IFR_BYTE; + +typedef struct { + CHAR8 VfrFileName[MAX_PATH]; + CHAR8 VfrListFileName[MAX_PATH]; + INT8 CreateListFile; + INT8 CreateIfrBinFile; + CHAR8 IfrOutputFileName[MAX_PATH]; + CHAR8 OutputDirectory[MAX_PATH]; + CHAR8 PreprocessorOutputFileName[MAX_PATH]; + CHAR8 VfrBaseFileName[MAX_PATH]; // name of input VFR file with no path or extension + CHAR8 *IncludePaths; + CHAR8 *CPreprocessorOptions; +} OPTIONS; + +extern OPTIONS gOptions; + +VOID +WriteStandardFileHeader ( + FILE *OutFptr + ) +/*++ + +Routine Description: + This function is invoked to emit a standard header to an + output text file. + +Arguments: + OutFptr - file to write the header to + +Returns: + None + +--*/ +; + +#endif // #ifndef _EFI_VFR_H_ diff --git a/Tools/CodeTools/Source/VfrCompile/VfrCompile.g b/Tools/CodeTools/Source/VfrCompile/VfrCompile.g new file mode 100644 index 0000000000..44820bc31b --- /dev/null +++ b/Tools/CodeTools/Source/VfrCompile/VfrCompile.g @@ -0,0 +1,3529 @@ +/*++ + +Copyright (c) 2004 - 2005, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + VfrCompile.g + +Abstract: + + PCCTS parser and lexer definitions for the EFI VFR forms compiler + +--*/ + +#header<< + +#include +#include +#include +#include +#include + +#include "CommonLib.h" +#include "EfiUtilityMsgs.h" +#include "EfiVfr.h" +#include "VfrServices.h" + +#include +#ifndef __GNUC__ +#include +#include // for spawn functions +#else +#include +#endif + +>> + +<< + +// +// Base info for DLG-generated scanner +// +#include "DLexerBase.h" + +// +// Include the scanner file generated by DLG +// +#include "DLGLexer.h" + +class DLGLexerVfr : public DLGLexer +{ +public: + DLGLexerVfr (DLGFileInput *F) : DLGLexer (F) {}; + INT32 errstd (char *Text) + { + printf ("unrecognized input '%s'\n", Text); + } + +}; + +// +// Base token definitions for ANTLR +// +#include "AToken.h" + +// +// This is how we invoke the C preprocessor on the VFR source file +// to resolve #defines, #includes, etc. To make C source files +// shareable between VFR and drivers, define VFRCOMPILE so that +// #ifdefs can be used in shared .h files. +// +#ifdef __GNUC__ +#define PREPROCESSOR_COMMAND "gcc " +#define PREPROCESSOR_OPTIONS "-x c -E -P -DVFRCOMPILE " +#define FILE_SEP_CHAR '/' +#define FILE_SEP_STRING "/" +#else +#define PREPROCESSOR_COMMAND "cl.exe " +#define PREPROCESSOR_OPTIONS "/nologo /P /TC /DVFRCOMPILE " +#define FILE_SEP_CHAR '/' +#define FILE_SEP_STRING "/" +#endif + +typedef ANTLRCommonToken ANTLRToken; + +// +// Specify the filename extensions for the files we generate. +// +#define VFR_BINARY_FILENAME_EXTENSION ".c" +#define VFR_LIST_FILENAME_EXTENSION ".lst" + +static +VOID +Usage (); + +static +STATUS +ProcessArgs ( + int Argc, + char *Argv[] + ); + +static +VOID +Cleanup (); + +// +// Globals +// +OPTIONS gOptions; + +int +main ( + int argc, + char **argv + ) +/*++ + +Routine Description: + Application entry point function. Parse command-line arguments, + invoke the parser, clean up, and return. + +Arguments: + argc - standard argc passed to main() per C conventions + argv - standard argv passed to main() per C conventions + +Returns: + STATUS_SUCCESS - program executed with no errors or warnings + STATUS_WARNING - program executed with warnings + STATUS_ERROR - non-recoverable errors encountered while processing + +--*/ +{ + FILE *VfrFptr; + char *Cmd; + char *Cptr; + int Len; + STATUS Status; + + // + // Set our program name for the error printing routines. + // Then set printing limits. + // + SetUtilityName (PROGRAM_NAME); + SetPrintLimits (20, 20, 30); + // + // Process the command-line arguments + // + if (ProcessArgs (argc, argv) != STATUS_SUCCESS) { + Usage (); + Cleanup(); + return STATUS_ERROR; + } + VfrFptr = NULL; + // + // Verify the VFR script file exists + // + if ((VfrFptr = fopen (gOptions.VfrFileName, "r")) == NULL) { + Error (PROGRAM_NAME, 0, 0, gOptions.VfrFileName, "could not open input VFR file"); + Cleanup(); + return STATUS_ERROR; + } + // + // Now close the file and make a system call to run the preprocessor + // on it. + // + fclose (VfrFptr); + Len = strlen (PREPROCESSOR_OPTIONS) + strlen (gOptions.VfrFileName) + 10; + if (gOptions.CPreprocessorOptions != NULL) { + Len += strlen (gOptions.CPreprocessorOptions) + 1; + } + if (gOptions.IncludePaths != NULL) { + Len += strlen (gOptions.IncludePaths) + 1; + } + Cmd = (char *)malloc (Len); + if (Cmd == NULL) { + Error (PROGRAM_NAME, 0, 0, NULL, "could not allocate memory"); + Cleanup(); + return STATUS_ERROR; + } + strcpy (Cmd, PREPROCESSOR_OPTIONS); + if (gOptions.IncludePaths != NULL) { + strcat (Cmd, gOptions.IncludePaths); + strcat (Cmd, " "); + } + if (gOptions.CPreprocessorOptions != NULL) { + strcat (Cmd, gOptions.CPreprocessorOptions); + strcat (Cmd, " "); + } + strcat (Cmd, gOptions.VfrFileName); +#ifndef __GNUC__ + Status = _spawnlp (_P_WAIT, PREPROCESSOR_COMMAND, Cmd, NULL); +#else + { + char CommandLine[1000]; + char *p; + + // + // Lean the slashes forward. + // + for (p = gOptions.PreprocessorOutputFileName; *p; p++) { + if (*p=='\\') { + *p=FILE_SEP_CHAR; + } + } + + // + // Lean the slashes forward. + // + for (p = Cmd; *p; p++) { + if (*p=='\\') { + *p=FILE_SEP_CHAR; + } + } + + sprintf(CommandLine, "%s %s > %s", PREPROCESSOR_COMMAND, Cmd, gOptions.PreprocessorOutputFileName); + Status = system (CommandLine); + } +#endif + if (Status != 0) { + Error (PROGRAM_NAME, 0, 0, gOptions.VfrFileName, "failed to spawn C preprocessor on VFR file"); + printf ("Command: '%s %s'\n", PREPROCESSOR_COMMAND, Cmd); + Cleanup(); + return STATUS_ERROR; + } + free (Cmd); + // + // Open the preprocessor output file + // + if ((VfrFptr = fopen (gOptions.PreprocessorOutputFileName, "r")) == NULL) { + Error (PROGRAM_NAME, 0, 0, "failed to open input VFR preprocessor output file", + gOptions.PreprocessorOutputFileName); + Cleanup(); + return STATUS_ERROR; + } + // + // Define input VFR file + // + DLGFileInput InputFile (VfrFptr); + // + // Define an instance of the scanner + // + DLGLexerVfr Scanner (&InputFile); + // + // Define token buffer between scanner and parser + // + ANTLRTokenBuffer Pipe (&Scanner); + // + // Create a token to use as a model + // + ANTLRToken Tok; + // + // Tell the scanner what type the token is + // + Scanner.setToken (&Tok); + // + // Create an instance of our parser + // + EfiVfrParser Parser (&Pipe); + // + // Initialize the parser + // + Parser.init (); + Status = GetUtilityStatus (); + if (Status != STATUS_SUCCESS) { + Cleanup(); + return Status; + } + // + // Start the first rule + // + Parser.program (); + // + // Close the input script file + // + fclose (VfrFptr); + Parser.WriteIfrBytes (); + // + // Call cleanup, which does some extra checking of the script + // + Parser.Cleanup (); + Cleanup(); + // + // If we had an error somewhere, delete our output files so that + // a subsequent build will rebuild them. + // + Status = GetUtilityStatus (); + if (Status == STATUS_ERROR) { + remove (gOptions.IfrOutputFileName); + } + return Status; +} +static +VOID +Cleanup () +/*++ + +Routine Description: + Free up memory allocated during parsing. + +Arguments: + None + +Returns: + None + +--*/ +{ + // + // Free up our string we allocated to track the include paths + // + if (gOptions.IncludePaths != NULL) { + free (gOptions.IncludePaths); + gOptions.IncludePaths = NULL; + } + // + // Free up our string we allocated to track preprocessor options + // + if (gOptions.CPreprocessorOptions != NULL) { + free (gOptions.CPreprocessorOptions); + gOptions.CPreprocessorOptions = NULL; + } +} + +static +STATUS +ProcessArgs ( + int Argc, + char *Argv[] + ) +/*++ + +Routine Description: + Process the command-line arguments. + +Arguments: + Argc - standard argc passed to main() + Argv - standard argv passed to main() + +Returns: + STATUS_SUCCESS - program should continue (all args ok) + +--*/ +{ + char *IncludePaths; + char *CPreprocessorOptions; + int Len; + char CopyStr[MAX_PATH]; + char *Cptr; + + // + // Put options in known state. + // + memset ((char *)&gOptions, 0, sizeof (OPTIONS)); + // + // Go through all the arguments that start with '-' + // + Argc--; + Argv++; + while ((Argc > 0) && (Argv[0][0] == '-')) { + // + // -? or -h help option -- return an error for printing usage + // + if ((stricmp (Argv[0], "-?") == 0) || (stricmp (Argv[0], "-h") == 0)) { + return STATUS_ERROR; + break; + // + // -l to create a listing output file + // + } else if (stricmp (Argv[0], "-l") == 0) { + gOptions.CreateListFile = 1; + // + // -I include_path option for finding include files. We'll pass this + // to the preprocessor. Turn them all into a single include string. + // + } else if (stricmp (Argv[0], "-i") == 0) { + if ((Argc < 2) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing path argument"); + return STATUS_ERROR; + } + Argc--; + Argv++; + Len = strlen (" -I "); + Len += strlen (Argv[0]) + 2; + if (gOptions.IncludePaths != NULL) { + Len += strlen (gOptions.IncludePaths); + } + IncludePaths = (CHAR8 *)malloc (Len); + if (IncludePaths == NULL) { + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + IncludePaths[0] = 0; + if (gOptions.IncludePaths != NULL) { + strcpy (IncludePaths, gOptions.IncludePaths); + free (gOptions.IncludePaths); + } + strcat (IncludePaths, " -I "); + strcat (IncludePaths, Argv[0]); + gOptions.IncludePaths = IncludePaths; + // + // -od OutputDirectory to define a common directory for output files + // + } else if (stricmp (Argv[0], "-od") == 0) { + if ((Argc < 2) || (Argv[1][0] == '-')) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing output directory name"); + return STATUS_ERROR; + } + Argc--; + Argv++; + strcpy (gOptions.OutputDirectory, Argv[0]); + } else if (stricmp (Argv[0], "-ibin") == 0) { + gOptions.CreateIfrBinFile = 1; + } else if (stricmp (Argv[0], "-nostrings") == 0) { + // deprecated option + // + // -ppflag C-preprocessor-flag option for passing options to the C preprocessor. + // Turn them all into a single string. + // + } else if (stricmp (Argv[0], "-ppflag") == 0) { + if (Argc < 2) { + Error (PROGRAM_NAME, 0, 0, Argv[0], "missing C-preprocessor argument"); + return STATUS_ERROR; + } + Argc--; + Argv++; + Len = strlen (Argv[0]) + 2; + if (gOptions.CPreprocessorOptions != NULL) { + Len += strlen (gOptions.CPreprocessorOptions); + } + CPreprocessorOptions = (CHAR8 *)malloc (Len); + if (CPreprocessorOptions == NULL) { + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return STATUS_ERROR; + } + CPreprocessorOptions[0] = 0; + if (gOptions.CPreprocessorOptions != NULL) { + strcpy (CPreprocessorOptions, gOptions.CPreprocessorOptions); + free (gOptions.CPreprocessorOptions); + } + strcat (CPreprocessorOptions, " "); + strcat (CPreprocessorOptions, Argv[0]); + gOptions.CPreprocessorOptions = CPreprocessorOptions; + } else { + Error (PROGRAM_NAME, 0, 0, Argv[0], "unrecognized option"); + return STATUS_ERROR; + } + Argc--; + Argv++; + } + // + // Must specify at least the vfr file name + // + if (Argc > 1) { + Error (PROGRAM_NAME, 0, 0, Argv[1], "unrecognized argument after VFR file name"); + return STATUS_ERROR; + } else if (Argc < 1) { + Error (PROGRAM_NAME, 0, 0, NULL, "must specify VFR file name"); + return STATUS_ERROR; + } + strcpy (gOptions.VfrFileName, Argv[0]); + // + // We run the preprocessor on the VFR file to manage #include statements. + // Unfortunately the preprocessor does not allow you to specify the + // output name or path of the resultant .i file, so we have to do + // some work. Here we'll extract the basename of the VFR file, then + // append .i on the end. + // + strcpy (CopyStr, gOptions.VfrFileName); + Cptr = CopyStr + strlen (CopyStr) - 1; + for (;(Cptr > CopyStr) && (*Cptr != '\\') && (*Cptr != ':') && (*Cptr != '/'); Cptr--); + if (Cptr == CopyStr) { + strcpy (gOptions.PreprocessorOutputFileName, Cptr); + strcpy (gOptions.VfrBaseFileName, Cptr); + } else { + strcpy (gOptions.PreprocessorOutputFileName, Cptr+1); + strcpy (gOptions.VfrBaseFileName, Cptr+1); + } + for (Cptr = gOptions.PreprocessorOutputFileName; *Cptr && (*Cptr != '.'); Cptr++); + strcpy (Cptr, ".i"); + // + // Terminate the vfr file basename at the extension + // + for (Cptr = gOptions.VfrBaseFileName; *Cptr && (*Cptr != '.'); Cptr++) { + } + *Cptr = 0; + // + // If they defined an output directory, prepend all output files + // with the working directory. Output files of interest: + // VfrListFileName -- list file + // IfrOutputFileName -- IFR bytes + // StringOutputFileName -- string bytes + // StringListFileName -- not used + // StringDefineFileName -- #defines of string identifiers + // + // We have two cases: + // 1. Output directory (-od) not specified, in which case output files + // go to the current working directory. + // 2. Output directory specified, in which case the output files + // go directly to the specified directory. + // + if (gOptions.OutputDirectory[0] == 0) { + CopyStr[0] = 0; +#ifndef __GNUC__ + _getcwd (CopyStr, sizeof (CopyStr)); +#else + getcwd (CopyStr, sizeof (CopyStr)); +#endif + strcpy (gOptions.OutputDirectory, CopyStr); + } + // + // Make sure output directory has a trailing backslash + // + if (gOptions.OutputDirectory[strlen (gOptions.OutputDirectory) - 1] != '\\' || + gOptions.OutputDirectory[strlen (gOptions.OutputDirectory) - 1] != '/') { + strcat (gOptions.OutputDirectory, FILE_SEP_STRING); + } + // + // Create the base output file name as: path\base, copy it to all the output + // filenames, and then add the appropriate extension to each. + // + strcpy (gOptions.VfrListFileName, gOptions.OutputDirectory); + strcat (gOptions.VfrListFileName, gOptions.VfrBaseFileName); + strcpy (gOptions.IfrOutputFileName, gOptions.VfrListFileName); + strcat (gOptions.VfrListFileName, VFR_LIST_FILENAME_EXTENSION); + strcat (gOptions.IfrOutputFileName, VFR_BINARY_FILENAME_EXTENSION); + // + // We set a default list file name, so if they do not + // want a list file, null out the name now. + // + if (gOptions.CreateListFile == 0) { + gOptions.VfrListFileName[0] = 0; + } + return STATUS_SUCCESS; +} +static +VOID +Usage () +/*++ + +Routine Description: + Print utility usage instructions + +Arguments: + None + +Returns: + None + +--*/ +{ + int Index; + const char *Help[] = { + " ", + "VfrCompile version " VFR_COMPILER_VERSION, + " ", + " Usage: VfrCompile {options} [VfrFile]", + " ", + " where options include:", + " -? or -h prints this help", + " -l create an output IFR listing file", + " -i IncPath add IncPath to the search path for VFR included files", + " -od OutputDir deposit all output files to directory OutputDir (default=cwd)", + " -ibin create an IFR HII pack file", + " where parameters include:", + " VfrFile name of the input VFR script file", + " ", + NULL + }; + for (Index = 0; Help[Index] != NULL; Index++) { + fprintf (stdout, "%s\n", Help[Index]); + } +} + +>> + + +#lexaction +<< + +#include "EfiVfr.h" + +PARSER_LINE_DEFINITION *gLineDefinition = NULL; +PARSER_LINE_DEFINITION *gLastLineDefinition = NULL; + +VOID +AddFileLine ( + char *TokenString, + UINT32 TokenLine + ) +/*++ + +Routine Description: + During the lexer phase, if we encounter a #line statement output by + the preprocessor, this function gets called. We'll save off the info + for error reporting purposes. The preprocessor line information has the + form: + + #line 3 "FileName.c" + +Arguments: + TokenString - the parsed string as shown above + TokenLine - the line number in the preprocessed output file + +Returns: + NA + +--*/ +{ + PARSER_LINE_DEFINITION *LineDef; + CHAR8 *Cptr; + + // + // Allocate a structure in which we can keep track of this line information. + // + LineDef = (PARSER_LINE_DEFINITION *)malloc (sizeof (PARSER_LINE_DEFINITION)); + memset ((char *)LineDef, 0, sizeof (PARSER_LINE_DEFINITION)); + LineDef->TokenLineNum = TokenLine; + LineDef->HashLineNum = atoi (TokenString + 6); + // + // Find the quotes in the filename, then allocate space in the line + // def structure for a copy of the filename. Finally, copy it without + // quotes to the line def. + // + for (Cptr = TokenString + 7; *Cptr && (*Cptr != '"'); Cptr++); + if (*Cptr == '"') { + LineDef->FileName = (CHAR8 *)malloc (strlen (Cptr)); + Cptr++; + strcpy (LineDef->FileName, Cptr); + for (Cptr = LineDef->FileName; *Cptr && (*Cptr != '"'); Cptr++); + *Cptr = 0; + // + // Now add this new one to the list + // + if (gLineDefinition == NULL) { + gLineDefinition = LineDef; + } else { + gLastLineDefinition->Next = LineDef; + } + gLastLineDefinition = LineDef; + } else { + Error (PROGRAM_NAME, 0, 0, "invalid line definition in preprocessor output file", TokenString); + free (LineDef); + return; + } +} +char * +ConvertLineNumber ( + UINT32 *LineNum + ) +/*++ + +Routine Description: + Given the line number in the preprocessor-output file, use the line number + information we've saved to determine the source file name and line number + where the code originally came from. This is required for error reporting. + +Arguments: + LineNum - the line number in the preprocessor-output file. + +Returns: + Returns a pointer to the source file name. Also returns the line number + in the provided LineNum argument + +--*/ +{ + PARSER_LINE_DEFINITION *LineDef; + // + // Step through our linked list of #line information we saved off. + // For each one, look at its line number, and the line number of the + // next record, and see if the passed-in line number is in the range. + // If it is, then convert the line number to the appropriate line number + // of the original source file. + // + for (LineDef = gLineDefinition; LineDef != NULL; LineDef = LineDef->Next) { + // + // The given LineNum is the line number from the .i file. + // Find a line definition whose range includes this line number, + // convert the line number, and return the filename. + // + if (LineDef->TokenLineNum <= *LineNum) { + if (LineDef->Next != NULL) { + if (LineDef->Next->TokenLineNum > *LineNum) { + *LineNum = *LineNum - LineDef->TokenLineNum + LineDef->HashLineNum; + return LineDef->FileName; + } + } else { + // + // Last one in the list of line definitions, so has to be right + // + *LineNum = *LineNum - LineDef->TokenLineNum + LineDef->HashLineNum; + return LineDef->FileName; + } + } + } + return NULL; +} + +>> + +// +// Define a lexical class for parsing quoted strings. Basically +// starts with a double quote, and ends with a double quote that +// is not preceeded with a backslash. +// +#lexclass QUOTED_STRING +#token TheString "~[\"]*\"" << mode (START); >> + +// +// Define a lexical class for parsing "#pragma pack" statements. +// We do this just for convenience (since we skip them here) so +// that users can include some minimal .h files. +// +#lexclass PRAGMA_PACK +#token "pack" << skip (); >> +#token "[\ \t]" << skip (); >> +#token "\(" << skip (); >> +#token "[0-9]*" << skip (); >> +#token "\)" << skip (); mode (START); >> + +// +// Define a lexclass for skipping over C++ style comments +// +#lexclass CPP_COMMENT +#token "~[\n]*" << skip (); >> +#token "\n" << skip (); mode (START); newline (); >> + +// +// Standard lexclass is START +// +#lexclass START + +// +// Find start of C++ style comments +// +#token "//" << skip (); mode (CPP_COMMENT); >> + +// +// Skip whitespace +// +#token "[\ \t]" << skip (); >> + +// +// Skip over newlines, but count them +// +#token "\n" << skip (); newline (); >> + +// +// Skip pragma pack statements +// +#token "\#pragma" << skip (); mode(PRAGMA_PACK); >> + +// +// Skip over 'extern' in any included .H file +// +#token "extern" << skip (); >> + +// +// Tokens for the different keywords. Syntax is: +// TokenName("ErrorMessageText") "TokenString" +// where: +// TokenName is the token name (must be capitalized) that is used in the rules +// ErrorMessageText is the string the compiler emits when it detects a syntax error +// TokenString is the actual matching string used in the user script +// +#token LineDefinition "#line\ [0-9]+\ \"~[\"]+\"[\ \t]*\n" << AddFileLine (begexpr (), line ()); skip (); >> +#token FormSet("formset") "formset" +#token EndFormSet("endformset") "endformset" +#token Title("title") "title" +#token FormId("formid") "formid" +#token OneOf("oneof") "oneof" +#token Prompt("prompt") "prompt" +#token OrderedList("orderedlist") "orderedlist" +#token EndList("endlist") "endlist" +#token EndForm("endform") "endform" +#token EndOneOf("endoneof") "endoneof" +#token Form("form") "form" +#token Subtitle("subtitle") "subtitle" +#token Help("help") "help" +#token VarId("varid") "varid" +#token Text("text") "text" +#token Option("option") "option" +#token Value("value") "value" +#token Flags("flags") "flags" +#token Date("date") "date" +#token EndDate("enddate") "enddate" +#token Year("year") "year" +#token Month("month") "month" +#token Day("day") "day" +#token Time("time") "time" +#token EndTime("endtime") "endtime" +#token Hour("hour") "hour" +#token Minute("minute") "minute" +#token Second("second") "second" +#token AND("AND") "AND" +#token OR("OR") "OR" +#token GrayOutIf("grayoutif") "grayoutif" +#token NOT("NOT") "NOT" +#token Label("label") "label" +#token Timeout("timeout") "timeout" +#token Inventory("inventory") "inventory" +#token StringToken("STRING_TOKEN") "STRING_TOKEN" +#token NonNvDataMap("_NON_NV_DATA_MAP") "_NON_NV_DATA_MAP" +#token Struct("struct") "struct" +#token Uint64("UINT64") "UINT64" +#token Uint32("UINT32") "UINT32" +#token Uint16("UINT16") "UINT16" +#token Char16("CHAR16") "CHAR16" +#token Uint8("UINT8") "UINT8" +#token Guid("guid") "guid" +#token CheckBox("checkbox") "checkbox" +#token EndCheckBox("endcheckbox") "endcheckbox" +#token Numeric("numeric") "numeric" +#token EndNumeric("endnumeric") "endnumeric" +#token Minimum("minimum") "minimum" +#token Maximum("maximum") "maximum" +#token Step("step") "step" +#token Default("default") "default" +#token Password("password") "password" +#token EndPassword("endpassword") "endpassword" +#token String("string") "string" +#token EndString("endstring") "endstring" +#token MinSize("minsize") "minsize" +#token MaxSize("maxsize") "maxsize" +#token Encoding("encoding") "encoding" +#token SuppressIf("suppressif") "suppressif" +#token Hidden("hidden") "hidden" +#token Goto("goto") "goto" +#token InconsistentIf "inconsistentif" +#token EndIf("endif") "endif" +#token IdEqId("ideqid") "ideqid" +#token IdEqVal("ideqval") "ideqval" +#token VarEqVal("vareqval") "vareqval" +#token Var("var") "var" +#token IdEqValList("ideqvallist") "ideqvallist" +#token Length("length") "length" +#token Values("values") "values" +#token Key("key") "key" +#token DefaultFlag("DEFAULT") "DEFAULT" +#token ManufacturingFlag("MANUFACTURING") "MANUFACTURING" +#token InteractiveFlag("INTERACTIVE") "INTERACTIVE" +#token NVAccessFlag("NV_ACCESS") "NV_ACCESS" +#token ResetRequiredFlag("RESET_REQUIRED") "RESET_REQUIRED" +#token LateCheckFlag("LATE_CHECK") "LATE_CHECK" +#token Class("class") "class" +#token Subclass("subclass") "subclass" +#token TypeDef("typedef") "typedef" +#token Restore("restore") "restore" +#token Save("save") "save" +#token Defaults("defaults") "defaults" +#token Banner("banner") "banner" +#token Align("align") "align" +#token Left("left") "left" +#token Right("right") "right" +#token Center("center") "center" +#token Line("line") "line" +#token VarStore("varstore") "varstore" +#token Name("name") "name" +#token Oem("oem") "oem" +#token True("TRUE") "TRUE" +#token False("FALSE") "FALSE" +#token GreaterThan(">") ">" +#token GreaterEqual(">=") ">=" +#token LessThan("<") "<" +#token LessEqual("<=") "<=" + +// +// Define the class and subclass tokens +// +#token ClassNonDevice("NONDEVICE") "NON_DEVICE" +#token ClassDiskDevice("DISK_DEVICE") "DISK_DEVICE" +#token ClassVideoDevice("VIDEO_DEVICE") "VIDEO_DEVICE" +#token ClassNetworkDevice("NETWORK_DEVICE") "NETWORK_DEVICE" +#token ClassInputDevice("INPUT_DEVICE") "INPUT_DEVICE" +#token ClassOnBoardDevice("ONBOARD_DEVICE") "ONBOARD_DEVICE" +#token ClassOtherDevice("OTHER_DEVICE") "OTHER_DEVICE" + +#token SubclassSetupApplication("SETUP_APPLICATION") "SETUP_APPLICATION" +#token SubclassGeneralApplication("GENERAL_APPLICATION") "GENERAL_APPLICATION" +#token SubclassFrontPage("FRONT_PAGE") "FRONT_PAGE" +#token SubclassSingleUse("SINGLE_USE") "SINGLE_USE" + +#token LanguageIdentifier("language identifier") "[a-z][a-z][a-z]" // 3 lowercase characters +#token StringIdentifier("string identifier") "[A-Za-z_][A-Za-z_0-9]*" +#token Number("numeric value") "(0x[0-9A-Fa-f]+) | [0-9]+" +#token OpenBrace("{") "\{" +#token CloseBrace("}") "\}" +#token OpenParen("(") "\(" +#token CloseParen(")") "\)" +#token OpenBracket("[") "\[" +#token CloseBracket("]") "\]" + +// +// Define all other invalid characters so that they get through the lexical phase +// and we can catch them during the parse phase. We get much better error +// messages then. +// +#token InvalidCharacters("invalid characters") "~[;:=,\.\|]" + +// +// This is the overall definition of a VFR form definition script. +// +program : + ( dataStructDefinition )* + formSetStatement + ( vfrStatementVarStore )* + ( formDefinition )* + EFS:EndFormSet ";" << WriteOpByte (EFS->getLine(), EFI_IFR_END_FORM_SET_OP); >> + "@" // end of file + ; + +formSetStatement : + FS:FormSet << WriteOpByte (FS->getLine(), EFI_IFR_FORM_SET_OP); >> + Guid "=" + OpenBrace + G1:Number "," + G2:Number "," + G3:Number "," + OpenBrace + G4:Number "," + G5:Number "," + G6:Number "," + G7:Number "," + G8:Number "," + G9:Number "," + G10:Number "," + G11:Number + CloseBrace + CloseBrace << WriteGuidValue (G1->getLine (), G1->getText (), G2->getText (), G3->getText (), + G4->getText (), G5->getText (), G6->getText (), G7->getText (), + G8->getText (), G9->getText (), G10->getText (), G11->getText () + ); + >> + "," + Title "=" getStringId "," + Help "=" getStringId "," + // + // insert padding for an EFI_PHYSICAL_ADDRESS (UINT64) + // + << WriteDWord (0, 0); WriteDWord (0, 0); >> + Class "=" CVAL:classDefinition "," << WriteClass (); >> + Subclass "=" SVAL:subclassDefinition "," << WriteSubclass (); >> + << WriteWord (mNvDataStructSize); >> + ; + +// +// A form can be of multiple classes, thus allow CLASS_A | CLASS_B | CLASS_C +// +classDefinition : + validClassNames ( "\|" validClassNames )* + ; + +validClassNames : + CND:ClassNonDevice << SetClass (CND->getLine(), EFI_NON_DEVICE_CLASS); >> + | CDD:ClassDiskDevice << SetClass (CDD->getLine(), EFI_DISK_DEVICE_CLASS); >> + | CVD:ClassVideoDevice << SetClass (CVD->getLine(), EFI_VIDEO_DEVICE_CLASS); >> + | CNW:ClassNetworkDevice << SetClass (CNW->getLine(), EFI_NETWORK_DEVICE_CLASS); >> + | CID:ClassInputDevice << SetClass (CID->getLine(), EFI_INPUT_DEVICE_CLASS); >> + | COB:ClassOnBoardDevice << SetClass (COB->getLine(), EFI_ON_BOARD_DEVICE_CLASS); >> + | COD:ClassOtherDevice << SetClass (COD->getLine(), EFI_OTHER_DEVICE_CLASS); >> + | CNUM:Number << SetClass (CNUM->getLine(), GetNumber (CNUM->getText(), CNUM->getLine(), 4)); >> + ; << PrintErrorMessage (LT(1)->getLine(), LT(1)->getText(), "invalid class"); >> + +// +// A form can only be of one subclass type. +// +subclassDefinition : + SSA:SubclassSetupApplication << SetSubclass (SSA->getLine(), EFI_SETUP_APPLICATION_SUBCLASS); >> + | SGA:SubclassGeneralApplication << SetSubclass (SGA->getLine(), EFI_GENERAL_APPLICATION_SUBCLASS); >> + | SFP:SubclassFrontPage << SetSubclass (SFP->getLine(), EFI_FRONT_PAGE_SUBCLASS); >> + | SSU:SubclassSingleUse << SetSubclass (SSU->getLine(), EFI_SINGLE_USE_SUBCLASS); >> + | SNUM:Number << SetSubclass (SNUM->getLine(), GetNumber (SNUM->getText(), SNUM->getLine(), 4)); >> + ; << PrintErrorMessage (LT(1)->getLine(), LT(1)->getText(), "invalid subclass"); >> + +// +// Parse a C type data structure for storing VFR setup data. Allow: +// typedef struct _XXX_ { +// (fields) +// } MY_NV_DATA; +// +dataStructDefinition : + << int IsNonNV = 0; >> + { TypeDef } + S:Struct + ( + NonNvDataMap << IsNonNV = 1; >> + | + { StringIdentifier } + ) << StartStructDefinition (IsNonNV, S->getLine()); >> + OpenBrace + dataStructFields + CloseBrace NAME:StringIdentifier << EndStructDefinition (NAME->getText(), NAME->getLine()); >> + ";" + ; + +// +// Parse a C type data structure for defining data that is not stored in NV. +// typedef struct _NON_NV_DATA_MAP { +// (fields) +// } NON_NV_DATA_MAP; +// +nonNvDataStructDefinition : + { TypeDef } + Struct NonNvDataMap + { StringIdentifier } + OpenBrace + dataStructFields + CloseBrace NAME:StringIdentifier << AddStructField (NAME->getText(), NAME->getLine(), 0, 0, 0); >> + ";" + ; + +dataStructFields : + ( dataStructField64 | dataStructField32 | dataStructField16 | dataStructField8 ) * + ; + +//***************************************************************************** +// +// PARSE: +// UINT64 Name[4]; +// UINT64 Name; +// +// Used while parsing the NV data map structures. +// +dataStructField64 : + << int ArrayLength = 1; char IsArray = 0; >> + "UINT64" + NAME:StringIdentifier + ( ";" | OpenBracket IVal:Number CloseBracket ";" << ArrayLength = GetNumber (IVal->getText(), IVal->getLine(), 4); IsArray = 1; >> ) + << AddStructField (NAME->getText(), NAME->getLine(), 8, ArrayLength, IsArray); >> + ; + +//***************************************************************************** +// +// PARSE: +// UINT32 Name[4]; +// UINT32 Name; +// +// Used while parsing the NV data map structures. +// +dataStructField32 : + << int ArrayLength = 1; char IsArray = 0; >> + "UINT32" + NAME:StringIdentifier + ( ";" | OpenBracket IVal:Number CloseBracket ";" << ArrayLength = GetNumber (IVal->getText(), IVal->getLine(), 4); IsArray = 1; >> ) + << AddStructField (NAME->getText(), NAME->getLine(), 4, ArrayLength, IsArray); >> + ; + +//***************************************************************************** +// +// PARSE: +// UINT16 Name[4]; +// UINT16 Name; +// +// Used while parsing the NV data map structures. +// +dataStructField16 : + << int ArrayLength = 1; char IsArray = 0; >> + ( "UINT16" | "CHAR16" ) + NAME:StringIdentifier + ( ";" | OpenBracket IVal:Number CloseBracket ";" << ArrayLength = GetNumber (IVal->getText(), IVal->getLine(), 4); IsArray = 1; >> ) + << AddStructField (NAME->getText(), NAME->getLine(), 2, ArrayLength, IsArray); >> + ; + +//***************************************************************************** +// +// PARSE: +// UINT8 Name[4]; +// UINT8 Name; +// +// Used while parsing the NV data map structures. +// +dataStructField8 : + << int ArrayLength = 1; char IsArray = 0; >> + "UINT8" + NAME:StringIdentifier + ( ";" | OpenBracket IVal:Number CloseBracket ";" << ArrayLength = GetNumber (IVal->getText(), IVal->getLine(), 4); IsArray = 1; >> ) + << AddStructField (NAME->getText(), NAME->getLine(), 1, ArrayLength, IsArray); >> + ; + +//***************************************************************************** +// +// PARSE: +// form formid = 1, +// title = STRING_TOKEN(STR_FORM_TITLE); +// -- form statements -- +// endform; +// +// The Form ID cannot be 0 +// +formDefinition : + FRM:Form FormId << WriteOpByte (FRM->getLine(), EFI_IFR_FORM_OP); >> + "=" + VAL:Number << WriteWord (GetNumber (VAL->getText(), VAL->getLine(), 2)); AddFormId (GetNumber (VAL->getText(), VAL->getLine(), 2), VAL->getLine()); >> + "," + Title "=" getStringId ";" // writes string identifier + ( vfrStatements )* + ENDF:EndForm ";" << WriteOpByte (ENDF->getLine(), EFI_IFR_END_FORM_OP); >> + ; + +// +// VFR statements in a formset +// +vfrStatements : + vfrStatementSubTitle | + vfrStatementOneOf | + vfrStatementTextText | + vfrStatementCheckBox | + vfrStatementNumeric | + vfrStatementDate | + vfrStatementTime | + vfrStatementPassword | + vfrStatementString | + vfrStatementSuppressIf | + vfrStatementHidden | + vfrStatementGoto | + vfrStatementGrayOutIf | + vfrStatementInconsistentIf | + vfrStatementLabel | + vfrStatementBanner | + vfrStatementInventory | + vfrStatementOrderedList | + vfrStatementOem | + vfrStatementSaveRestoreDefaults + ; + +//***************************************************************************** +// +// PARSE: +// label 100; +// +vfrStatementLabel : + OPID:Label << WriteOpByte (OPID->getLine(), EFI_IFR_LABEL_OP); >> + VAL:Number << + WriteWord (GetNumber (VAL->getText(), VAL->getLine(), 2)); + AddLabel (GetNumber (VAL->getText(), VAL->getLine(), 2), VAL->getLine()); + >> + ";" + ; + +//***************************************************************************** +// +// PARSE: +// oem 0x12, 0x34, 0x56; +// +vfrStatementOem : + OPID:Oem << WriteOpByte (OPID->getLine(), EFI_IFR_OEM_DEFINED_OP); >> + ( VAL1:Number << WriteByte (GetNumber (VAL1->getText(), VAL1->getLine(), 1), 0); >> ) + ( "," VAL2:Number << WriteByte (GetNumber (VAL2->getText(), VAL2->getLine(), 1), 0); >> )* + ";" + ; + +//***************************************************************************** +// +// PARSE: +// inconsistentif NOT .... AND NOT .... OR ... endif; +// +vfrStatementInconsistentIf : + << ResetFlags (); >> + IIFOP:InconsistentIf << WriteOpByte (IIFOP->getLine(), EFI_IFR_INCONSISTENT_IF_OP); >> + Prompt "=" getStringId "," + { + FF:Flags "=" flagsField ( "\|" flagsField )* "," + } + << WriteFlags (); >> // write the flags field + vfrBooleanExpression + EOP:EndIf ";" << WriteOpByte (EOP->getLine(), EFI_IFR_END_IF_OP); >> + ; + +//***************************************************************************** +// +// PARSE: +// TRUE AND (ideqval SomeStruct.SomeMember >= 0x10 OR +// ideqid SomeStruct.SomeMember < SomeStruct.SomeOtherMember) AND +// (ideqlist SomeStruct.SomeOtherMember == 0x10, 0x20, 0x30 OR +// vareqval var(VAR_EQ_TEST_NAME) == 0x1) +// +// For supporting complex express, divide the vfrBooleanExpression to two parts +// so that pred-LL(k) parser can parse incrementally. +// +vfrBooleanExpression : + leftPartVfrBooleanExp { rightPartVfrBooleanExp } + ; + +leftPartVfrBooleanExp : + OpenParen vfrBooleanExpression CloseParen | + (ideqval | ideqid | ideqvallist | vareqval | truefalse) | + NOPID:NOT leftPartVfrBooleanExp << WriteOpByte (NOPID->getLine(), EFI_IFR_NOT_OP); >> + ; + +rightPartVfrBooleanExp : + AOPID:AND vfrBooleanExpression << WriteOpByte (AOPID->getLine(), EFI_IFR_AND_OP); >> | + OOPID:OR vfrBooleanExpression << WriteOpByte (OOPID->getLine(), EFI_IFR_OR_OP); >> + ; + +//***************************************************************************** +// +// PARSE: +// TRUE +// +truefalse : + TOPID:True << WriteOpByte (TOPID->getLine(), EFI_IFR_TRUE_OP); >> | + FOPID:False << WriteOpByte (FOPID->getLine(), EFI_IFR_FALSE_OP); >> + ; + +//***************************************************************************** +// +// PARSE: +// varstore MY_STRUCT_NAME, key = 0x1234, name = "MyVariableName", guid = {...}; +// +vfrStatementVarStore : + OP:VarStore << WriteOpByte (OP->getLine(), EFI_IFR_VARSTORE_OP); >> + STRUCT_NAME:StringIdentifier "," + Key "=" KNUM:Number "," + Name "=" VAR_NAME:StringIdentifier "," + Guid "=" + OpenBrace + G1:Number "," + G2:Number "," + G3:Number "," + OpenBrace + G4:Number "," + G5:Number "," + G6:Number "," + G7:Number "," + G8:Number "," + G9:Number "," + G10:Number "," + G11:Number + CloseBrace + CloseBrace << WriteGuidValue (G1->getLine (), G1->getText (), G2->getText (), G3->getText (), + G4->getText (), G5->getText (), G6->getText (), G7->getText (), + G8->getText (), G9->getText (), G10->getText (), G11->getText () + ); + WriteWord (GetNumber (KNUM->getText(), KNUM->getLine(), 2)); + AddVarStore (STRUCT_NAME->getText(), VAR_NAME->getText(), GetNumber (KNUM->getText(), KNUM->getLine(), 2), STRUCT_NAME->getLine()); + >> + + ";" + ; + +//***************************************************************************** +// +// PARSE: +// vareqval var(0x100) == 0x20 +// +vareqval : + OPID:VarEqVal << WriteOpByte (OPID->getLine(), EFI_IFR_EQ_VAR_VAL_OP); >> + Var OpenParen + VAR:Number << WriteWord (GetNumber (VAR->getText(), VAR->getLine(), 2)); >> + CloseParen + compareNumber + ; + +ideqval : + OPID:IdEqVal << WriteOpByte (OPID->getLine(), EFI_IFR_EQ_ID_VAL_OP); >> + vfrStructFieldName[0] + compareNumber + ; + +//***************************************************************************** +// +// PARSE: +// ideqid MyNVData3.Field16A == MyNVData3.Field16B +// +// NOTE: Before processing the second variable store in the ideqid statement, set a global flag +// so that when we parse the second variable we set the secondary variable store id. +// +ideqid : + OPID:IdEqId << WriteOpByte (OPID->getLine(), EFI_IFR_EQ_ID_ID_OP); >> + vfrStructFieldName[0] + compareVfrStructFieldNameNL0 + ; + +//***************************************************************************** +// +// compareNumber is the combination of compare operation and Number +// +compareNumber : + ( + "==" + VAL1:Number << WriteWord (GetNumber (VAL1->getText(), VAL1->getLine(), 2)); >> + ) | + ( + GTOPID:GreaterThan + VAL2:Number << WriteWord (GetNumber (VAL2->getText(), VAL2->getLine(), 2)); + WriteOpByte (GTOPID->getLine(), EFI_IFR_GT_OP); >> + ) | + ( + GEOPID:GreaterEqual + VAL3:Number << WriteWord (GetNumber (VAL3->getText(), VAL3->getLine(), 2)); + WriteOpByte (GEOPID->getLine(), EFI_IFR_GE_OP); >> + ) | + ( + LTOPID:LessThan + VAL4:Number << WriteWord (GetNumber (VAL4->getText(), VAL4->getLine(), 2)); + WriteOpByte (LTOPID->getLine(), EFI_IFR_GE_OP); + WriteOpByte (LTOPID->getLine(), EFI_IFR_NOT_OP); >> + ) | + ( + LEOPID:LessEqual + VAL5:Number << WriteWord (GetNumber (VAL5->getText(), VAL5->getLine(), 2)); + WriteOpByte (LEOPID->getLine(), EFI_IFR_GT_OP); + WriteOpByte (LEOPID->getLine(), EFI_IFR_NOT_OP); >> + ) + ; + +//***************************************************************************** +// +// compareVfrStructFieldNameNL0 is the combination of compare operation and vfrStructFieldNameNL[0] +// +compareVfrStructFieldNameNL0 : + ( + "==" << mIdEqIdStmt = 1; >> + vfrStructFieldNameNL[0] << mIdEqIdStmt = 0; >> + ) | + ( + GTOPID:GreaterThan << mIdEqIdStmt = 1; >> + vfrStructFieldNameNL[0] << mIdEqIdStmt = 0; + WriteOpByte (GTOPID->getLine(), EFI_IFR_GT_OP); >> + ) | + ( + GEOPID:GreaterEqual << mIdEqIdStmt = 1; >> + vfrStructFieldNameNL[0] << mIdEqIdStmt = 0; + WriteOpByte (GEOPID->getLine(), EFI_IFR_GE_OP); >> + ) | + ( + LTOPID:LessThan << mIdEqIdStmt = 1; >> + vfrStructFieldNameNL[0] << mIdEqIdStmt = 0; + WriteOpByte (LTOPID->getLine(), EFI_IFR_GE_OP); + WriteOpByte (LTOPID->getLine(), EFI_IFR_NOT_OP); >> + ) | + ( + LEOPID:LessEqual << mIdEqIdStmt = 1; >> + vfrStructFieldNameNL[0] << mIdEqIdStmt = 0; + WriteOpByte (LEOPID->getLine(), EFI_IFR_GT_OP); + WriteOpByte (LEOPID->getLine(), EFI_IFR_NOT_OP); >> + ) + ; + + +ideqvallist : + OPID:IdEqValList << WriteOpByte (OPID->getLine(), EFI_IFR_EQ_ID_LIST_OP); >> + vfrStructFieldName[0] + "==" + ( VAL:Number << QueueIdEqValList (GetNumber (VAL->getText(), VAL->getLine(), 2)); >> ) + + << FlushQueueIdEqValList(); >> + ; + +vfrStatementGoto : + << UINT32 LineNum, KeyValue = 0; ResetFlags (); >> + IDG:Goto << WriteOpByte (IDG->getLine(), EFI_IFR_REF_OP); >> + VAL:Number "," << WriteWord (GetNumber (VAL->getText(), VAL->getLine(), 2)); + AddGotoReference (GetNumber (VAL->getText(), VAL->getLine(), 2), VAL->getLine()); + >> + KP:Prompt "=" getStringId "," << LineNum = KP->getLine(); >> + Help "=" getStringId + { + "," + FF:Flags "=" flagsField ( "\|" flagsField )* << LineNum = FF->getLine(); >> + } + { + "," Key "=" KNUM:Number << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >> + } + << WriteFlagsKey (KeyValue, LineNum); >> + ";" + ; + +vfrStatementHidden : + IDH:Hidden << WriteOpByte (IDH->getLine(), EFI_IFR_HIDDEN_OP); >> + Value "=" + VAL:Number "," << WriteWord (GetNumber (VAL->getText(), VAL->getLine(), 2)); >> + Key "=" + KVAL:Number << WriteWord (GetNumber (KVAL->getText(), KVAL->getLine(), 2)); >> + ";" + ; + +//***************************************************************************** +// +// PARSE: +// suppressif { grayoutif } + endif; +// Note: +// You can have: suppressif:grayoutif:statements:endif +// suppressif:grayoutif:endif -- serves no purpose +// suppressif:statements:endif +// suppressif:endif -- serves no purpose +// +vfrStatementSuppressIf : + << ResetFlags (); >> + OPID:SuppressIf << WriteOpByte (OPID->getLine(), EFI_IFR_SUPPRESS_IF_OP); SetIfStart (OPID->getLine()); >> + { + FF:Flags "=" flagsField ( "\|" flagsField )* "," + } + << WriteFlags (); >> // write the flags field + vfrBooleanExpression + ";" + { suppressIfGrayOutIf } ( suppressIfAndGrayoutIfSubstatements )+ + ENDOP:EndIf ";" << WriteOpByte (ENDOP->getLine(), EFI_IFR_END_IF_OP); SetIfStart (0); >> + ; + +// +// This is the form for a grayoutif nested in a suppressif statement +// +suppressIfGrayOutIf : + << ResetFlags (); >> + OPID:GrayOutIf << WriteOpByte (OPID->getLine(), EFI_IFR_GRAYOUT_IF_OP); >> + { + FF:Flags "=" flagsField ( "\|" flagsField )* "," + } + << WriteFlags (); >> // write the flags field + vfrBooleanExpression + ";" + ; + +//***************************************************************************** +// +// PARSE: +// grayoutif { flags = n, } endif; +// Note: +// You can have: grayoutif:suppressif:statements:endif +// grayoutif:statements:endif +// +// +vfrStatementGrayOutIf : + << ResetFlags (); >> + OPID:GrayOutIf << WriteOpByte (OPID->getLine(), EFI_IFR_GRAYOUT_IF_OP); SetIfStart (OPID->getLine()); >> + { + FF:Flags "=" flagsField ( "\|" flagsField )* "," + } + << WriteFlags (); >> // write the flags field + vfrBooleanExpression + ";" + { grayoutIfSuppressIf } ( suppressIfAndGrayoutIfSubstatements )+ + ENDOP:EndIf ";" << WriteOpByte (ENDOP->getLine(), EFI_IFR_END_IF_OP); SetIfStart (0); >> + ; + +// +// This is the format for a suppressif nested in a grayoutif +// +grayoutIfSuppressIf : + << ResetFlags (); >> + OPID:SuppressIf << WriteOpByte (OPID->getLine(), EFI_IFR_SUPPRESS_IF_OP); >> + { + FF:Flags "=" flagsField ( "\|" flagsField )* "," + } + << WriteFlags (); >> // write the flags field + vfrBooleanExpression + ";" + ; + +// +// These are the VFR statements that are valid inside a suppressif or grayoutif statement. +// +suppressIfAndGrayoutIfSubstatements : + vfrStatementOneOf | + vfrStatementTextText | + vfrStatementCheckBox | + vfrStatementNumeric | + vfrStatementDate | + vfrStatementTime | + vfrStatementPassword | + vfrStatementString | + vfrStatementHidden | + vfrStatementGoto | + vfrStatementLabel | + vfrStatementInventory | + vfrStatementOrderedList | + vfrStatementSaveRestoreDefaults + ; + +//***************************************************************************** +// +// PARSE: +// +// password varid = MyNvData.Password, +// prompt = STRING_TOKEN(STR_PASSWORD_PROMPT), +// help = STRING_TOKEN(STR_PASSWORD_HELP), +// minsize = 6, +// maxsize = 20, +// encoding = 1, +// endpassword; + +vfrStatementPassword : + << UINT32 KeyValue = 0; UINT32 LineNum; ResetFlags (); >> + IDPW:Password << WriteOpByte (IDPW->getLine(), EFI_IFR_PASSWORD_OP); >> + VarId "=" vfrStructFieldNameArray[0] "," + Prompt "=" getStringId "," + KH:Help "=" getStringId "," << LineNum = KH->getLine(); >> + { + FF:Flags "=" flagsField ( "\|" flagsField )* "," << LineNum = FF->getLine(); >> + } + { + Key "=" KNUM:Number "," << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >> + } + << WriteFlagsKey (KeyValue, LineNum); >> + MinSize "=" MIN:Number "," << WriteByte (GetNumber (MIN->getText(), MIN->getLine(), 1), 0); >> + MaxSize "=" MAX:Number "," << WriteByte (GetNumber (MAX->getText(), MAX->getLine(), 1), 0); >> + Encoding "=" ENC:Number "," << WriteWord (GetNumber (ENC->getText(), ENC->getLine(), 2)); >> + EndPassword ";" + ; + +//***************************************************************************** +// +// PARSE: +// +// string varid = MyNv.String, +// prompt = STRING_TOKEN(STR_STRING_PROMPT), +// help = STRING_TOKEN(STR_STRING_HELP), +// flags = INTERACTIVE, +// key = 0x1234, +// minsize = 6, +// maxsize = 0x14, +// endstring; +// +// Since flags and key are optional, we can't use Flags->getLine(). Therefore for error +// reporting we save the line number of the "help" keyword. +// +vfrStatementString : + << unsigned int KeyValue = 0; UINT32 LineNum; ResetFlags (); >> + IDS:String << WriteOpByte (IDS->getLine(), EFI_IFR_STRING_OP); >> + VarId "=" vfrStructFieldNameArray[0] "," + Prompt "=" getStringId "," + KH:Help "=" getStringId "," << LineNum = KH->getLine(); >> + { + FF:Flags "=" + flagsField ( "\|" flagsField )* << LineNum = FF->getLine(); >> + "," + } + { + Key "=" KNUM:Number "," << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >> + } + << WriteFlagsKey (KeyValue, LineNum); >> + MinSize "=" MIN:Number "," << WriteByte (GetNumber (MIN->getText(), MIN->getLine(), 1), 0); >> + MaxSize "=" MAX:Number "," << WriteByte (GetNumber (MAX->getText(), MAX->getLine(), 1), 0); >> + EndString ";" + ; + +//***************************************************************************** +// +// PARSE: +// numeric varid = MyIfrNVData.HowOldAreYouInYears, +// prompt = STRING_TOKEN(STR_NUMERIC_PROMPT), +// help = STRING_TOKEN(STR_NUMERIC_HELP), +// flags = INTERACTIVE, // flags is optional +// key = 0x1234, // key is optional if (flags & INTERACTIVE = 0) +// minimum = 0x0, +// maximum = 0xf0, +// step = 1, // step is option, and step=1 if not specified +// default = 0; // default is optional, and default=minimum if not specified +// endnumeric; +// +// Make flags and key optional. However if flags includes INTERACTIVE, then a key is required. +// That check is done in WriteFlagsKey() function. +// +vfrStatementNumeric : + << UINT32 LineNum, KeyValue = 0; ResetFlags (); >> + IDN:Numeric << WriteOpByte (IDN->getLine(), EFI_IFR_NUMERIC_OP); >> + VarId "=" vfrStructFieldName[2] "," + Prompt "=" getStringId "," + KH:Help "=" getStringId "," << LineNum = KH->getLine(); >> + { + FF:Flags "=" flagsField ( "\|" flagsField )* "," << LineNum = FF->getLine (); >> + } + { + Key "=" KNUM:Number "," << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >> + } + << WriteFlagsKey (KeyValue, LineNum); >> + minMaxStepDefault + EndNumeric ";" << WriteMinMaxStepDefault (); >> + ; + +// +// Parse minimum/maximum/step/default statements. Special cases: +// - if step not specified, then the value is 1 +// - if default not specified, then the value is the min value specified +// - if max < min, print a warning and swap the values (changes default too) +// +minMaxStepDefault : + << InitMinMaxStepDefault (); >> + Minimum "=" MIN:Number "," << SetMinMaxStepDefault (GetNumber (MIN->getText(), MIN->getLine(), 2), 0, MIN->getLine()); >> + Maximum "=" MAX:Number "," << SetMinMaxStepDefault (GetNumber (MAX->getText(), MAX->getLine(), 2), 1, MAX->getLine()); >> + { Step "=" STEP:Number "," << SetMinMaxStepDefault (GetNumber (STEP->getText(), STEP->getLine(), 2), 2, STEP->getLine()); >> } + { Default "=" DEF:Number "," << SetMinMaxStepDefault (GetNumber (DEF->getText(), DEF->getLine(), 2), 3, DEF->getLine()); >> } + ; + + +//***************************************************************************** +// +// PARSE: +// +// date year varid = Date.Year, // "Date.Year" is a special case we recognize +// prompt = STRING_TOKEN(STR_DATE_PROMPT), +// help = STRING_TOKEN(STR_DATE_YEAR_HELP), +// minimum = 1939, +// maximum = 2101, +// step = 1, +// default = 1964, +// +// month varid = Date.Month, +// prompt = STRING_TOKEN(STR_DATE_PROMPT), +// help = STRING_TOKEN(STR_DATE_MONTH_HELP), +// minimum = 1, +// maximum = 12, +// step = 1, +// default = 1, +// +// day varid = Date.Day, +// prompt = STRING_TOKEN(STR_DATE_PROMPT), +// help = STRING_TOKEN(STR_DATE_DAY_HELP), +// minimum = 1, +// maximum = 31, +// step = 0x1, +// default = 1, +// +// enddate; +// +vfrStatementDate : + Date + IDY:Year VarId "=" << WriteOpByte (IDY->getLine(), EFI_IFR_DATE_OP); >> + vfrStructFieldName[2] "," + dateTimeSubStatement + IDM:Month VarId "=" << WriteOpByte (IDM->getLine(), EFI_IFR_DATE_OP); >> + vfrStructFieldName[2] "," + dateTimeSubStatement + IDD:Day VarId "=" << WriteOpByte (IDD->getLine(), EFI_IFR_DATE_OP); >> + vfrStructFieldName[2] "," + dateTimeSubStatement + EndDate ";" + ; + +vfrStatementTime : + Time + IDH:Hour VarId "=" << WriteOpByte (IDH->getLine(), EFI_IFR_TIME_OP); >> + vfrStructFieldName[2] "," + dateTimeSubStatement + IDM:Minute VarId "=" << WriteOpByte (IDM->getLine(), EFI_IFR_TIME_OP); >> + vfrStructFieldName[2] "," + dateTimeSubStatement + IDS:Second VarId "=" << WriteOpByte (IDS->getLine(), EFI_IFR_TIME_OP); >> + vfrStructFieldName[2] "," + dateTimeSubStatement + EndTime ";" + ; + +//***************************************************************************** +// +// PARSE: +// +// text text = STRING_ID; +// text text = STRING_ID, text = STRING_ID; +// text text = STRING_ID, text = STRING_ID, flags = x, key = y; +// +vfrStatementTextText : + << ResetFlags (); >> + IDT:Text << WriteOpByte (IDT->getLine(), EFI_IFR_TEXT_OP); >> + Help "=" getStringId "," + Text "=" + getStringId // writes string identifier + { "," Text "=" getStringId + "," Flags "=" flagsField ( "\|" flagsField )* << WriteFlags (); >> + "," + Key "=" KNUM:Number << WriteWord (GetNumber(KNUM->getText(), KNUM->getLine(), 2)); >> + } + ";" + ; + +//***************************************************************************** +// +// PARSE: +// +// inventory help = ID, text = ID; +// inventory help = ID, text = id, text = ID; +// +vfrStatementInventory : + IDI:Inventory << WriteOpByte (IDI->getLine(), EFI_IFR_INVENTORY_OP); >> + Help "=" getStringId "," + Text "=" getStringId // writes string identifier + { "," Text "=" getStringId + } + ";" + ; + +//***************************************************************************** +// +// PARSE: +// +// restore defaults, +// formid = 4, +// prompt = STRING_TOKEN(STR_RESTORE_DEFAULTS_PROMPT), +// help = STRING_TOKEN(STR_RESTORE_DEFAULTS_HELP), +// flags = 0, +// key = 0; +// +// save defaults, +// formid = 4, +// prompt = STRING_TOKEN(STR_SAVE_DEFAULTS_PROMPT), +// help = STRING_TOKEN(STR_SAVE_DEFAULTS_HELP), +// flags = 0, +// key = 0; +// +vfrStatementSaveRestoreDefaults : + << unsigned int KeyValue = 0; UINT32 LineNum; ResetFlags (); >> + ( IDS:Save << WriteOpByte (IDS->getLine(), EFI_IFR_SAVE_DEFAULTS_OP); >> + | IDR:Restore << WriteOpByte (IDR->getLine(), EFI_IFR_RESTORE_DEFAULTS_OP); >> + ) + Defaults "," + FormId "=" FRMID:Number "," << WriteWord (GetNumber (FRMID->getText(), FRMID->getLine(), 2)); + AddGotoReference (GetNumber (FRMID->getText(), FRMID->getLine(), 2), FRMID->getLine()); + >> + Prompt "=" getStringId "," + KH:Help "=" getStringId << LineNum = KH->getLine(); >> + { + "," FF:Flags "=" flagsField ( "\|" flagsField )* << LineNum = FF->getLine(); >> + } + { + "," Key "=" KNUM:Number << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >> + } + << WriteFlagsKey (KeyValue, LineNum); >> + ";" + ; + +//***************************************************************************** +// +// PARSE: +// +// flags = 0x10 | DEFAULT | MANUFACTURING | INTERACTIVE | NV_ACCESS | RESET_REQUIRED | LATE_CHECK +// +// +flagsField : + VAL:Number << SetFlags (GetNumber(VAL->getText(), VAL->getLine(), 4), VAL->getLine()); >> + | IF:InteractiveFlag << SetFlags (EFI_IFR_FLAG_INTERACTIVE, IF->getLine()); >> + | MF:ManufacturingFlag << SetFlags (EFI_IFR_FLAG_MANUFACTURING, MF->getLine()); >> + | DF:DefaultFlag << SetFlags (EFI_IFR_FLAG_DEFAULT, DF->getLine()); >> + | NV:NVAccessFlag << SetFlags (EFI_IFR_FLAG_NV_ACCESS, NV->getLine()); >> + | RR:ResetRequiredFlag << SetFlags (EFI_IFR_FLAG_RESET_REQUIRED, RR->getLine()); >> + | LC:LateCheckFlag << SetFlags (EFI_IFR_FLAG_LATE_CHECK, LC->getLine()); >> + ; + +dateTimeSubStatement : + Prompt "=" getStringId "," + Help "=" getStringId "," + << WriteByte (0, 0); WriteWord (0); >> // bogus flags and key + minMaxStepDefault << WriteMinMaxStepDefault (); >> + ; + +vfrStatementCheckBox : + << UINT32 LineNum, KeyValue = 0; ResetFlags (); >> + IDCB:CheckBox << WriteOpByte (IDCB->getLine(), EFI_IFR_CHECKBOX_OP); >> + VarId "=" vfrStructFieldName[1] "," + Prompt "=" getStringId "," + Help "=" getStringId "," + FF:Flags "=" flagsField ( "\|" flagsField )* "," << LineNum = FF->getLine(); >> + { + Key "=" KV:Number "," << LineNum = KV->getLine(); KeyValue = GetNumber(KV->getText(), LineNum, 2); >> + } + << WriteFlagsKey (KeyValue, LineNum); >> + EndCheckBox ";" + ; + +vfrStatementSubTitle : + IDS:Subtitle Text "=" << WriteOpByte (IDS->getLine(), EFI_IFR_SUBTITLE_OP); >> + getStringId // writes string indentifier + ";" + ; + +//***************************************************************************** +// +// PARSE: +// banner +// title = STRING_TOKEN(STR_BANNER_TITLE), +// line 1, +// align center; // or left or right +// +// banner, +// title = STRING_TOKEN(STR_BANNER_TITLE), timeout = 100; +// +vfrStatementBanner : + IDB:Banner { "," } << WriteOpByte (IDB->getLine(), EFI_IFR_BANNER_OP); >> + Title "=" getStringId "," + ( + Line VAL:Number "," << WriteWord (GetNumber(VAL->getText(), VAL->getLine(), 2)); >> + Align + ( Left << WriteByte (EFI_IFR_BANNER_ALIGN_LEFT, 0); >> + | Center << WriteByte (EFI_IFR_BANNER_ALIGN_CENTER, 0); >> + | Right << WriteByte (EFI_IFR_BANNER_ALIGN_RIGHT, 0); >> + ) ";" + | + Timeout "=" TO:Number ";" << WriteWord (GetNumber(TO->getText(), TO->getLine(), 2)); >> + << WriteByte (EFI_IFR_BANNER_TIMEOUT, 0); >> + ) + ; + +//***************************************************************************** +// +// PARSE: +// oneof varid = MyNv.OneOfData, +// prompt = STRING_TOKEN(STR_ONE_OF_PROMPT), +// help = STRING_TOKEN(STR_ONE_OF_HELP), +// option text = STRING_TOKEN(STR_ONE_OF_TEXT), +// value = 0, +// flags = DEFAULT | INTERACTIVE; +// +// supressif/grayoutif are supported inside oneof stmt. +// We do not restrict the number of oneOfOptionText to >=2, but >=1. +// The situation that all oneOfOptionText are suppressed is also possiable. +// +vfrStatementOneOf : + << ResetFlags (); >> + IDOO:OneOf << WriteOpByte (IDOO->getLine(), EFI_IFR_ONE_OF_OP); >> + VarId "=" vfrStructFieldName[2] "," + Prompt "=" getStringId "," // writes string identifier + Help "=" getStringId "," // writes string identifier + ( oneOfOptionText )+ // there must be at least 1 option to be choosed, not 2. + IDEOO:EndOneOf ";" << TestOneOfFlags (IDEOO->getLine()); WriteOpByte (IDEOO->getLine(), EFI_IFR_END_ONE_OF_OP); >> + ; + +//***************************************************************************** +// +// PARSE: +// +// orderedlist varid = MyNv.OrderedListData, +// prompt = STRING_TOKEN(STR_ORDERED_LIST_PROMPT), +// help = STRING_TOKEN(STR_ORDERED_LIST_HELP), +// option text = STRING_TOKEN(STR_ORDERED_LIST_TEXT), value = 0, flags = INTERACTIVE; +// -- additional option text -- +// endlist; +// +vfrStatementOrderedList : + << ResetFlags (); InitOrderedList(); >> + IDOL:OrderedList << WriteOpByte (IDOL->getLine(), EFI_IFR_ORDERED_LIST_OP); >> + VarId "=" vfrStructFieldNameArray[1] "," + Prompt "=" getStringId "," // writes string identifier + Help "=" getStringId "," // writes string identifier + orderedListOptionText ( orderedListOptionText )+ + IDEOL:EndList ";" << WriteOpByte (IDEOL->getLine(), EFI_IFR_END_OP); EndOrderedList(IDEOL->getLine()); >> + ; + +//***************************************************************************** +// +// PARSE: +// +// option text = STRING_TOKEN(STRING_ID), value = 0 flags = 99; +// +// Differs from the oneOfOptionText in that we don't allow the DEFAULT flag to +// be set, and value cannot be 0. +// +orderedListOptionText : + << UINT32 KeyValue = 0; >> + IDO:Option << WriteOpByte (IDO->getLine(), EFI_IFR_ONE_OF_OPTION_OP); >> + Text "=" getStringId "," // writes string identifier + Value "=" WVAL:Number "," << + if (GetNumber(WVAL->getText(), WVAL->getLine(), 2) == 0) { + PrintErrorMessage (WVAL->getLine(), "value=0 is invalid for ordered lists", NULL); + } else { + WriteWord (GetNumber(WVAL->getText(), WVAL->getLine(), 2)); + } + >> + FF:Flags "=" orderedListFlagsField + ("\|" orderedListFlagsField )* + { + "," Key "=" KV:Number << KeyValue = GetNumber (KV->getText(), KV->getLine(), 2); >> + } + << WriteFlagsKey (KeyValue, FF->getLine()); >> + ";" << mOptionCount++; >> + ; + +//***************************************************************************** +// +// PARSE: +// +// flags = 0x10 | DEFAULT | MANUFACTURING | INTERACTIVE | NV_ACCESS | RESET_REQUIRED | LATE_CHECK +// +// The ordered list flags field cannot have a default. +// +orderedListFlagsField : + VAL:Number << SetFlags (GetNumber(VAL->getText(), VAL->getLine(), 4), VAL->getLine()); >> + | IF:InteractiveFlag << SetFlags (EFI_IFR_FLAG_INTERACTIVE, IF->getLine()); >> + | MF:ManufacturingFlag << SetFlags (EFI_IFR_FLAG_MANUFACTURING, MF->getLine()); >> + | NV:NVAccessFlag << SetFlags (EFI_IFR_FLAG_NV_ACCESS, NV->getLine()); >> + | RR:ResetRequiredFlag << SetFlags (EFI_IFR_FLAG_RESET_REQUIRED, RR->getLine()); >> + | LC:LateCheckFlag << SetFlags (EFI_IFR_FLAG_LATE_CHECK, LC->getLine()); >> + | DF:DefaultFlag << PrintWarningMessage (DF->getLine(), "DEFAULT flag not valid for ordered lists", NULL); >> + ; + +// +// Parse references to VFR structure field names of form "MyNvStructure.Field". +// This implementation is specific to strings, passwords, and references in an +// ordered list statement because we want to specify the size of the entire +// field, rather than just one element. Then call a function to write out its +// offset and length. +// +vfrStructFieldNameArray[int FieldWidth] : + << int ArrayIndex = 1; char IsArrayIndex = 0; >> + SName:StringIdentifier + "." + SFieldName:StringIdentifier + { OpenBracket AIndex:Number CloseBracket << ArrayIndex = GetNumber(AIndex->getText(), AIndex->getLine(), 4); IsArrayIndex = 1; >> } + << + WriteFieldOffset (1, + SName->getText(), + SName->getLine(), + SFieldName->getText(), + SFieldName->getLine(), + ArrayIndex, + IsArrayIndex, + FieldWidth, + 1 + ); + >> + ; + +// +// Parse references to VFR structure field names of form "MyNvStructure.Field", +// then call a function to write out its offset and length. +// +vfrStructFieldName[int FieldWidth] : + << int ArrayIndex = 1; char IsArrayIndex = 0; >> + SName:StringIdentifier + "." + SFieldName:StringIdentifier + { OpenBracket AIndex:Number CloseBracket << ArrayIndex = GetNumber(AIndex->getText(), AIndex->getLine(), 4); IsArrayIndex = 1; >> } + << + WriteFieldOffset (1, + SName->getText(), + SName->getLine(), + SFieldName->getText(), + SFieldName->getLine(), + ArrayIndex, + IsArrayIndex, + FieldWidth, + 0 + ); + >> + ; + +//***************************************************************************** +// +// PARSE: +// +// MyNvStructure.FieldName[4] +// +// Parse references to VFR structure field names of form "MyNvStructure.Field", +// then call a function to write out the offset with no length. +// +vfrStructFieldNameNL[int FieldWidth] : + << int ArrayIndex = 1; char IsArrayIndex = 0; >> + SName:StringIdentifier + "." + SFieldName:StringIdentifier + { OpenBracket AIndex:Number CloseBracket << ArrayIndex = GetNumber(AIndex->getText(), AIndex->getLine(), 4); IsArrayIndex = 1; >> } + << + WriteFieldOffset (0, + SName->getText(), + SName->getLine(), + SFieldName->getText(), + SFieldName->getLine(), + ArrayIndex, + IsArrayIndex, + FieldWidth, + 0 + ); + >> + ; + +//***************************************************************************** +// +// PARSE: +// suppressif TRUE OR FALSE; +// grayoutif FALSE OR TRUE; +// option text = STRING_TOKEN(STRING_ID), value = 0 flags = 99; +// option text = STRING_TOKEN(STRING_ID2), value = 1 flags = 98; +// endif; +// +oneOfOptionText : + suppressIfOptionText | + grayOutIfOptionText | + commonOptionText + ; + +suppressIfOptionText : + << ResetFlags (); >> + OPID:SuppressIf << WriteOpByte (OPID->getLine(), EFI_IFR_SUPPRESS_IF_OP); SetIfStart (OPID->getLine()); >> + { + FF:Flags "=" flagsField ( "\|" flagsField )* "," + } + << WriteFlags (); >> // write the flags field + vfrBooleanExpression + ";" + { suppressIfGrayOutIf } ( commonOptionText )+ + ENDOP:EndIf ";" << WriteOpByte (ENDOP->getLine(), EFI_IFR_END_IF_OP); SetIfStart (0); >> + ; + +grayOutIfOptionText : + << ResetFlags (); >> + OPID:GrayOutIf << WriteOpByte (OPID->getLine(), EFI_IFR_GRAYOUT_IF_OP); SetIfStart (OPID->getLine()); >> + { + FF:Flags "=" flagsField ( "\|" flagsField )* "," + } + << WriteFlags (); >> // write the flags field + vfrBooleanExpression + ";" + { grayoutIfSuppressIf } ( commonOptionText )+ + ENDOP:EndIf ";" << WriteOpByte (ENDOP->getLine(), EFI_IFR_END_IF_OP); SetIfStart (0); >> + ; + +commonOptionText : + << UINT32 KeyValue = 0; >> + IDO:Option << WriteOpByte (IDO->getLine(), EFI_IFR_ONE_OF_OPTION_OP); >> + Text "=" getStringId "," // writes string identifier + Value "=" WVal:Number "," << WriteWord (GetNumber(WVal->getText(), WVal->getLine(), 2)); >> + FF:Flags "=" flagsField ("\|" flagsField )* + { + "," Key "=" KV:Number << KeyValue = GetNumber (KV->getText(), KV->getLine(), 2); >> + } + << WriteFlagsKey (KeyValue, FF->getLine()); >> + ";" << mOptionCount++; >> + ; + +// +// Gets a string identifier. It must be a numeric value of form: +// +// STRING_TOKEN(100) +// +getStringId : + << unsigned short StrId; >> + StringToken OpenParen + IdVal:Number << StrId = GetNumber (IdVal->getText(), IdVal->getLine(), 2); WriteStringIdWord (StrId); >> + CloseParen + ; + +//****************************************************************************** +// +// Parser class definition. +// +class EfiVfrParser { +<< +// +// Parser definitions go here +// +private: + STRUCT_DEFINITION *mFirstStructDefinition; + STRUCT_DEFINITION *mLastStructDefinition; + INT32 mNvDataStructSize; + INT32 mNonNvDataStructSize; + // + // Flag to indicate that we're processing a ideqid VFR statement so that + // we can do late checks on the statement. + // + INT32 mIdEqIdStmt; + INT32 mLastNVVariableDataSize; + GOTO_REFERENCE *mGotoReferences; + FORM_ID_VALUE *mFormIdValues; + VfrOpcodeHandler mOpcodeHandler; + UINT16_LIST *mUint16List; + UINT16_LIST *mLastUint16; + UINT16_LIST *mDefinedLabels; + UINT16_LIST *mDefinedVarStoreId; + UINT16_LIST *mLastDefinedVarStoreId; + UINT32 mMinimumValue, mMaximumValue, mStepValue, mDefaultValue; + UINT32 mStmtFlags; + UINT32 mSubStmtFlags; + UINT32 mSubStmtFlagsLineNum; + EFI_GUID mFormSetGuid; + UINT8 mNvDataStructDefined; + UINT16 mClass, mSubclass; + UINT32 mIfStart; + UINT32 mOptionCount; // how many "option" fields in a given statement + UINT32 mLastVarIdSize; + UINT8 mOutput; +public: + +VOID +EfiVfrParser::SetIfStart ( + UINT32 LineNum + ) +/*++ + +Routine Description: + Invoked during VFR parsing when an "if" is encountered. Save the + source line number so we can point to it if we don't find a + corresponding endif later. + +Arguments: + LineNum - source line number where the "if" was parsed. + +Returns: + None + +--*/ +{ + mIfStart = LineNum; +} +VOID +EfiVfrParser::SetClass ( + UINT32 LineNum, + UINT32 Value + ) +/*++ + +Routine Description: + Invoked during VFR parsing when a "class" statement is found. Check the + range on the class value and save it for later. + +Arguments: + LineNum - source line number where the class statement was parsed. + Value - the class value + +Returns: + None + +--*/ +{ + if (Value & 0xFFFF0000) { + PrintWarningMessage (LineNum, NULL, "class value exceeds maximum allowed"); + } + mClass |= (UINT16)Value; +} +VOID +EfiVfrParser::SetSubclass ( + UINT32 LineNum, + UINT32 Value + ) +/*++ + +Routine Description: + Invoked during VFR parsing when a subclass statement is found. Check the + range on the value and save it for later. + +Arguments: + LineNum - source line number where the class statement was parsed. + Value - the subclass value from the VFR statement + +Returns: + None + +--*/ +{ + if (Value & 0xFFFF0000) { + PrintWarningMessage (LineNum, NULL, "subclass value exceeds maximum allowed"); + } + mSubclass |= (UINT16)Value; +} +VOID EfiVfrParser::WriteClass () +{ + WriteWord (mClass); + mClass = 0; +} +VOID EfiVfrParser::WriteSubclass () +{ + WriteWord (mSubclass); + mSubclass = 0; +} +VOID EfiVfrParser::WriteIfrBytes () +{ + mOpcodeHandler.WriteIfrBytes (); +} +VOID +EfiVfrParser::WriteFlagsKey ( + UINT32 KeyValue, + UINT32 LineNum + ) +/*++ + +Routine Description: + Write out the flags and key values from the previous VFR statement. + Many statements take a flags/key pair. If not specified, then 0 + values are written out. However do not allow an interactive flags field + to be specified if no key value is specified. Also, if NV_ACCESS flag + is set but INTERACTIVE is not, then set interactive and issue a warning. + +Arguments: + KeyValue - the key value from the VFR statement + LineNum - source line number where the statement was parsed + +Returns: + None + +--*/ +{ + if ((mSubStmtFlags & EFI_IFR_FLAG_INTERACTIVE) && (KeyValue == 0)) { + PrintErrorMessage (LineNum, NULL, "invalid or missing key value - required with INTERACTIVE"); + } + if ((mSubStmtFlags & EFI_IFR_FLAG_NV_ACCESS) && !(mSubStmtFlags & EFI_IFR_FLAG_INTERACTIVE)) { + PrintWarningMessage (LineNum, NULL, "NV_ACCESS without INTERACTIVE has no effect -- setting INTERACTIVE"); + mSubStmtFlags |= EFI_IFR_FLAG_INTERACTIVE; + } + WriteFlags (); + WriteWord (KeyValue); +} +VOID +EfiVfrParser::InitOrderedList () +{ + mOptionCount = 0; +} +VOID +EfiVfrParser::EndOrderedList ( + UINT32 LineNum + ) +{ + if (mLastVarIdSize < mOptionCount) { + PrintErrorMessage (LineNum, NULL, "number of options exceeds the variable store size"); + } +} +VOID +EfiVfrParser::ResetFlags () +/*++ + +Routine Description: + + Flags are set for each substatement in a given one-of statement. + To make sure there are no conflicts, for example setting DEFAULT on + more than one substatement, we keep track of the flags at a statement + level and a substatement level. This function resets the flags so + we get a fresh start. + +Arguments: + None + +Returns: + None + +--*/ +{ + mStmtFlags = 0; + mSubStmtFlagsLineNum = 0; + mSubStmtFlags = 0; +} +// +// Test validity of flags value for a one-of statement. +// +VOID +EfiVfrParser::TestOneOfFlags ( + UINT32 LineNum + ) +{ + // + // One of the fields must have had the default bit set + // + if ((mStmtFlags & EFI_IFR_FLAG_DEFAULT) == 0) { + PrintWarningMessage (LineNum, "default value must be specified", NULL); + } +} +VOID +EfiVfrParser::SetFlags ( + UINT32 Flags, + UINT32 LineNum + ) +{ + // + // Check for redefinitions and invalid combinations + // + if (mStmtFlags & Flags & EFI_IFR_FLAG_MANUFACTURING) { + PrintErrorMessage (LineNum, "MANUFACTURING", "a field with this flag already defined"); + } + if (mStmtFlags & Flags & EFI_IFR_FLAG_DEFAULT) { + PrintErrorMessage (LineNum, "DEFAULT", "a field with this flag already defined"); + } + mSubStmtFlags |= Flags; + mSubStmtFlagsLineNum = LineNum; +} +VOID +EfiVfrParser::WriteFlags () +{ + // + // Check value for validity + // + if (mSubStmtFlags & ~(EFI_IFR_FLAG_DEFAULT | + EFI_IFR_FLAG_MANUFACTURING | + EFI_IFR_FLAG_INTERACTIVE | + EFI_IFR_FLAG_NV_ACCESS | + EFI_IFR_FLAG_RESET_REQUIRED | + EFI_IFR_FLAG_LATE_CHECK )) { + PrintWarningMessage (mSubStmtFlagsLineNum, "invalid bits defined in flag", NULL); + } + WriteByte ((UINT8)mSubStmtFlags, 'F'); + // + // We can now clear the substatement flags + // + mStmtFlags |= mSubStmtFlags; + mSubStmtFlags = 0; +} +// +// When we parse a min/max/step/default sequence, save off the values for +// later use. Call this first to init the values. +// +VOID +EfiVfrParser::InitMinMaxStepDefault () +{ + mMinimumValue = 0; + mMaximumValue = 0; + mStepValue = 1; + mDefaultValue = 0; +} +VOID +EfiVfrParser::WriteMinMaxStepDefault () +{ + WriteWord (mMinimumValue); + WriteWord (mMaximumValue); + WriteWord (mStepValue); + WriteWord (mDefaultValue); +} +VOID +EfiVfrParser::SetMinMaxStepDefault ( + UINT16 Value, + INT32 MMSD, + INT32 LineNum + ) +{ + UINT16 TempValue; + // + // Min specified + // + if (MMSD == 0) { + mMinimumValue = Value; + mDefaultValue = Value; + // + // Max specified + // + } else if (MMSD == 1) { + mMaximumValue = Value; + // + // If min > max, then swap the values. That includes resetting the default + // value as well. + // + if (mMinimumValue > mMaximumValue) { + PrintWarningMessage (LineNum, NULL, "maximum < minimum"); + TempValue = Value; + mMaximumValue = mMinimumValue; + mMinimumValue = TempValue; + mDefaultValue = mMinimumValue; + } + // + // Step specified + // + } else if (MMSD == 2) { + mStepValue = Value; + // + // Default specified. Make sure min <= default <= max. + // + } else if (MMSD == 3) { + mDefaultValue = Value; + if (mMinimumValue > Value) { + PrintErrorMessage (LineNum, NULL, "default value < minimum value"); + } else if (Value > mMaximumValue) { + PrintErrorMessage (LineNum, NULL, "default value > maximum value"); + } + } else { + PrintErrorMessage (LineNum, "application error", "internal MMSD error"); + } +} +VOID +EfiVfrParser::AddLabel ( + UINT32 LabelNumber, + UINT32 LineNum + ) +{ + UINT16_LIST *Label; + + // + // Added a label from the user VFR script. Make sure they haven't already + // defined the same label elsewhere + // + for (Label = mDefinedLabels; Label != NULL; Label = Label->Next) { + if (Label->Value == LabelNumber) { + PrintErrorMessage (LineNum, NULL, "label already defined"); + PrintErrorMessage (Label->LineNum, NULL, "previous definition of redefined label"); + break; + } + } + Label = (UINT16_LIST *)malloc (sizeof (UINT16_LIST)); + if (Label == NULL) { + PrintErrorMessage (0, NULL, "memory allocation error"); + return; + } + memset ((char *)Label, 0, sizeof (UINT16_LIST)); + Label->Value = LabelNumber; + Label->LineNum = LineNum; + Label->Next = mDefinedLabels; + mDefinedLabels = Label; +} +VOID +EfiVfrParser::QueueIdEqValList ( + UINT16 Value + ) +{ + UINT16_LIST *U16; + + U16 = (UINT16_LIST *)malloc (sizeof (UINT16_LIST)); + if (U16 == NULL) { + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failed"); + } else { + memset ((char *)U16, 0, sizeof (UINT16_LIST)); + U16->Value = Value; + if (mUint16List == NULL) { + mUint16List = U16; + } else { + mLastUint16->Next = U16; + } + mLastUint16 = U16; + } +} +VOID +EfiVfrParser::FlushQueueIdEqValList () +{ + UINT32 Count; + + // + // We queued up a list of IdEqValList items. The IFR requires a count + // followed by the actual values. Do it. + // + Count = 0; + mLastUint16 = mUint16List; + while (mLastUint16 != NULL) { + Count++; + mLastUint16 = mLastUint16->Next; + } + // BUGBUG -- check for more than 16K items? + WriteWord (Count); + // + // Now write the values. + // + mLastUint16 = mUint16List; + while (mLastUint16 != NULL) { + WriteWord ((UINT32)mLastUint16->Value); + mLastUint16 = mLastUint16->Next; + } + // + // Free up the list + // + mLastUint16 = mUint16List; + while (mUint16List != NULL) { + mLastUint16 = mUint16List->Next; + free (mUint16List); + mUint16List = mLastUint16; + } +} +VOID +EfiVfrParser::PrintErrorMessage ( + UINT32 LineNum, + CHAR8 *Msg1, + CHAR8 *Msg2 + ) +{ + char *FileName; + + if (LineNum != 0) { + FileName = ConvertLineNumber ((UINT32 *)&LineNum); + Error (FileName, LineNum, 0, Msg1, Msg2); + } else { + Error (PROGRAM_NAME, 0, 0, Msg1, Msg2); + } +} +VOID +EfiVfrParser::PrintWarningMessage ( + UINT32 LineNum, + CHAR8 *Msg1, + CHAR8 *Msg2 + ) +{ + char *FileName; + + if (LineNum != 0) { + FileName = ConvertLineNumber ((UINT32 *)&LineNum); + Warning (FileName, LineNum, 0, Msg1, Msg2); + } else { + Warning (PROGRAM_NAME, 0, 0, Msg1, Msg2); + } +} +VOID +EfiVfrParser::syn ( + ANTLRAbstractToken *Tok, + ANTLRChar *Egroup, + SetWordType *Eset, + ANTLRTokenType ETok, + INT32 Huh + ) +/*++ + +Routine Description: + Called by the parser base class as a result of parse syntax errors. + +Arguments: + Tok - token that caused the error + Egroup - not sure + Eset - index in token table of the expected token + Huh - not sure + +Returns: + NA + +--*/ +{ + char *FileName; + UINT32 LineNum; + + LineNum = Tok->getLine (); + FileName = ConvertLineNumber ((UINT32 *)&LineNum); + // + // Sometimes the token number is 0, in which case I don't know what to + // print. + // + if (ETok == 0) { + Error (FileName, LineNum, 0, Tok->getText (), "unexpected token"); + } else { + // + // If we were expecting an endif, then report the line where the corresponding + // IF began. + // + if ((strcmp (_token_tbl[ETok], "endif") == 0) && (mIfStart != 0)) { + LineNum = mIfStart; + FileName = ConvertLineNumber (&LineNum); + Error (FileName, LineNum, 0, "statement missing corresponding endif", NULL); + } else { + Error (FileName, LineNum, 0, Tok->getText (), "expected %s", _token_tbl[ETok]); + } + } +} + +VOID +EfiVfrParser::init() +/*++ + +Routine Description: + Initializations function for our parser. + +Arguments: + None. + +Returns: + None. + +--*/ +{ + ANTLRParser::init(); + + // + // Used for queuing a variable list of UINT16's + // + mUint16List = NULL; + mLastUint16 = NULL; + mFirstStructDefinition = NULL; + mLastStructDefinition = NULL; + mNvDataStructSize = 0; + mNonNvDataStructSize = 0; + mNvDataStructDefined = 0; + mGotoReferences = NULL; + mFormIdValues = NULL; + mDefinedLabels = NULL; + mClass = 0; + mSubclass = 0; + mIfStart = 0; + mDefinedVarStoreId = NULL; + mLastDefinedVarStoreId = NULL; + mIdEqIdStmt = 0; + mLastNVVariableDataSize = 0; + + memset ((char *)&mFormSetGuid, 0, sizeof (EFI_GUID)); +} +// +// Destructor for the parser. +// +EfiVfrParser::~EfiVfrParser(VOID) +{ + Cleanup(); +} +VOID +EfiVfrParser::Cleanup (VOID) +/*++ + +Routine Description: + Free memory allocated during parsing + +Arguments: + None. + +Returns: + None. + +--*/ +{ + STRUCT_DEFINITION *NextStruct; + STRUCT_FIELD_DEFINITION *NextField; + UINT8 Buff[6]; + UINT16_LIST *NextU16List; + + // + // Free up the structure definitions if any + // + while (mFirstStructDefinition != NULL) { + // + // Free up all the fields for this struct + // + while (mFirstStructDefinition->Field != NULL) { + NextField = mFirstStructDefinition->Field->Next; + free (mFirstStructDefinition->Field->Name); + free (mFirstStructDefinition->Field); + mFirstStructDefinition->Field = NextField; + } + NextStruct = mFirstStructDefinition->Next; + free (mFirstStructDefinition->Name); + free (mFirstStructDefinition); + mFirstStructDefinition = NextStruct; + } + // + // Free up the goto references and form id defines + // + FreeGotoReferences (); + // + // Free up label list + // + while (mDefinedLabels != NULL) { + NextU16List = mDefinedLabels->Next; + delete (mDefinedLabels); + mDefinedLabels = NextU16List; + } + // + // Free up the list of defined variable storage IDs + // + while (mDefinedVarStoreId != NULL) { + NextU16List = mDefinedVarStoreId->Next; + delete (mDefinedVarStoreId); + mDefinedVarStoreId = NextU16List; + } +} + +INT32 +EfiVfrParser::AtoX ( + CHAR8 *HexString, + INT32 NumBytes, + UINT32 *HexValue + ) +/*++ + +Routine Description: + Given a pointer to a ascii hex string, convert to a number with the given + number of bytes. + +Arguments: + HexString - pointer to a string of format 30BCA + Size - number of bytes to convert + HexValue - return result + +Returns: + The number of bytes converted. + +--*/ +{ + INT32 Count; + INT32 Value; + + *HexValue = 0; + Count = 0; + while (Count < NumBytes) { + if ((*HexString >= '0') && (*HexString <= '9')) { + Value = *HexString - '0'; + } else if ((*HexString >= 'a') && (*HexString <= 'f')) { + Value = *HexString - 'a' + 10; + } else if ((*HexString >= 'A') && (*HexString <= 'F')) { + Value = *HexString - 'A' + 10; + } else { + return Count; + } + HexString++; + *HexValue = (*HexValue << 4) | Value; + if ((*HexString >= '0') && (*HexString <= '9')) { + Value = *HexString - '0'; + } else if ((*HexString >= 'a') && (*HexString <= 'f')) { + Value = *HexString - 'a' + 10; + } else if ((*HexString >= 'A') && (*HexString <= 'F')) { + Value = *HexString - 'A' + 10; + } else { + return Count; + } + *HexValue = (*HexValue << 4) | Value; + HexString++; + Count++; + } + return Count; +} +VOID +EfiVfrParser::WriteGuidValue ( + UINT32 TokenLineNum, + CHAR8 *G1, + CHAR8 *G2, + CHAR8 *G3, + CHAR8 *G4, + CHAR8 *G5, + CHAR8 *G6, + CHAR8 *G7, + CHAR8 *G8, + CHAR8 *G9, + CHAR8 *G10, + CHAR8 *G11 + ) +/*++ + +Routine Description: + A Guid was parsed, likely of format: + #define MY_GUID { 0x12345678, 0xAABB, 0xCCDD, 0xEE, 0xFF, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 } + + Write out the value. + +Arguments: + TokenLineNum - line number where the guid was used + G1-G11 - the 11 fields of the guid value + +Returns: + None. + +--*/ +{ + UINT32 Value; + INT32 Loop; + + mFormSetGuid.Data1 = GetNumber (G1, TokenLineNum, 4); + mFormSetGuid.Data2 = (UINT16)GetNumber (G2, TokenLineNum, 2); + mFormSetGuid.Data3 = (UINT16)GetNumber (G3, TokenLineNum, 2); + mFormSetGuid.Data4[0] = (UINT8)GetNumber (G4, TokenLineNum, 1); + mFormSetGuid.Data4[1] = (UINT8)GetNumber (G5, TokenLineNum, 1); + mFormSetGuid.Data4[2] = (UINT8)GetNumber (G6, TokenLineNum, 1); + mFormSetGuid.Data4[3] = (UINT8)GetNumber (G7, TokenLineNum, 1); + mFormSetGuid.Data4[4] = (UINT8)GetNumber (G8, TokenLineNum, 1); + mFormSetGuid.Data4[5] = (UINT8)GetNumber (G9, TokenLineNum, 1); + mFormSetGuid.Data4[6] = (UINT8)GetNumber (G10, TokenLineNum, 1); + mFormSetGuid.Data4[7] = (UINT8)GetNumber (G11, TokenLineNum, 1); + + WriteDWord (mFormSetGuid.Data1, 'G'); + WriteWord (mFormSetGuid.Data2); + WriteWord (mFormSetGuid.Data3); + WriteByte (mFormSetGuid.Data4[0], 0); + WriteByte (mFormSetGuid.Data4[1], 0); + WriteByte (mFormSetGuid.Data4[2], 0); + WriteByte (mFormSetGuid.Data4[3], 0); + WriteByte (mFormSetGuid.Data4[4], 0); + WriteByte (mFormSetGuid.Data4[5], 0); + WriteByte (mFormSetGuid.Data4[6], 0); + WriteByte (mFormSetGuid.Data4[7], 0); +} +VOID +EfiVfrParser::WriteFieldOffset ( + INT8 WriteLength, + CHAR8 *StructName, + INT32 LineNum1, + CHAR8 *FieldName, + INT32 LineNum2, + INT32 ArrayIndex, + INT8 IsArrayIndex, + INT32 FieldWidth, + INT8 WriteArraySize + ) +/*++ + +Routine Description: + A VFR script referenced the NV store structure. Given the structure's name + and the field's name, write the offset of the field to the output file. + +Arguments: + WriteLength - write the field length byte out + StructName - name of the NV store structure + LineNum1 - line number in the VFR where we are (for error printing) + FieldName - the name of the field within the NV store structure + LineNum2 - line number in the VFR where FieldName is referenced + ArrayIndex - the index specified, for example NV_DATA.Field[ArrayIndex] + IsArrayIndex - non-zero if an array index was specified + FieldWidth - expected size for the Field (1 byte? 2 bytes?) + WriteArraySize - write the size of the entire field, not the size of a single element + +Returns: + None. + +--*/ +{ + STRUCT_DEFINITION *StructDef; + STRUCT_FIELD_DEFINITION *FieldDef; + UINT32 Offset; + UINT32 VarSize; + CHAR8 Msg[100]; + // + // If we're writing an array size, then they better have referenced the field without an + // index. + // + if (WriteArraySize && IsArrayIndex) { + sprintf (Msg, "array index specified where an array is required"); + PrintErrorMessage (LineNum2, FieldName, Msg); + return; + } + // + // Look through our list of known structures for a match + // + for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) { + // + // Check for matching structure name + // + if (strcmp (StructDef->Name, StructName) == 0) { + // + // Mark it as referenced (for debug purposes only). Check the + // flag that indicates that we have already found a varstore VFR + // statement for it. + // + StructDef->Referenced++; + if (StructDef->VarStoreIdValid == 0) { + // + // Set it valid so we don't flag it multiple times, then emit the error + // + StructDef->VarStoreIdValid = 1; + PrintErrorMessage (LineNum1, StructName, "varstore statement missing for this variable store"); + } + // + // Let the opcode-handler know which variable storage we're now using + // + if (mIdEqIdStmt) { + mOpcodeHandler.SetSecondaryVarStoreId (StructDef->VarStoreId); + } else { + mOpcodeHandler.SetVarStoreId (StructDef->VarStoreId); + } + // + // Found matching structure name. Now find the matching field name + // + for (FieldDef = StructDef->Field; FieldDef != NULL; FieldDef = FieldDef->Next) { + if (strcmp (FieldDef->Name, FieldName) == 0) { + // + // Make sure the variable size is valid + // + if ((FieldWidth != 0) && (FieldDef->DataSize > FieldWidth)) { + sprintf (Msg, "field width exceeds %d byte%c", FieldWidth, FieldWidth == 1 ? ' ' : 's'); + PrintErrorMessage (LineNum2, FieldName, Msg); + } + // + // If they specified an index (MyVfrData.FieldX[10]), then make sure that the + // data structure was declared as an array, and that the index is in bounds. + // If they did not specify an index, then we'll assume 0. This is required for + // strings. + // + if (IsArrayIndex) { + VarSize = FieldDef->DataSize; + if (FieldDef->IsArray == 0) { + PrintErrorMessage (LineNum2, FieldName, "field is not declared as an array"); + return; + } + if (FieldDef->ArrayLength < ArrayIndex) { + PrintErrorMessage (LineNum2, FieldName, "array index exceeds declared size of field"); + return; + } + } else { + if (FieldDef->IsArray) { + VarSize = FieldDef->DataSize * FieldDef->ArrayLength; + } else { + VarSize = FieldDef->DataSize; + } + } + // + // If we're in the middle of a ideqid VFR statement, then this is the second + // variable ID that we're now processing. Make sure that its size is the same + // as the first variable. + // + if (mIdEqIdStmt) { + if (mLastVarIdSize != VarSize) { + PrintErrorMessage (LineNum2, FieldName, "variables must have the same size"); + return; + } + } + mLastVarIdSize = VarSize; + // + // If we're supposed to write an array size, then require it to be an array + // + if (WriteArraySize && !FieldDef->IsArray) { + PrintErrorMessage (LineNum2, FieldName, "array required"); + return; + } + // + // Write the variable offset and size. If we're in the non-NV structure, then + // set the offset beyond the NV data structure size. + // + Offset = FieldDef->Offset + FieldDef->DataSize * (ArrayIndex - 1); + if (StructDef->IsNonNV) Offset += mNvDataStructSize; + WriteWord (Offset); + if (WriteLength) { + if (WriteArraySize) { + if (FieldDef->DataSize * FieldDef->ArrayLength > 255) { + PrintErrorMessage (LineNum2, FieldName, "array size exceeds 255 maximum encoding limit"); + return; + } + WriteByte (FieldDef->DataSize * FieldDef->ArrayLength, 0); + } else { + WriteByte (FieldDef->DataSize, 0); + } + } + return; + } + } + sprintf (Msg, "structure %s does not have a field named '%s'", StructName, FieldName); + PrintErrorMessage (LineNum2, Msg, NULL); + PrintErrorMessage (StructDef->LineNum, "see structure definition", NULL); + return; + } + } + // + // The structure was not found in the defined list. See if it's the "Date" structure + // + if (strcmp (StructName, "Date") == 0) { + // + // BUGBUG -- remove support for Date and Time as valid structure + // names. They should use the NON_NV_DATA_MAP structure for this. + // + // Someone specified Date.Years|Months|Days + // BUGBUG -- define some constants for the IDs used here + // Length == 0 implies that this is not user NV data storage. + // + if (strcmp (FieldName, "Year") == 0) { + // + // Write ID (offset), ID, and size + // + WriteWord (mNvDataStructSize + mNonNvDataStructSize + 0); + if (WriteLength) { + WriteByte (0, 0); + } + } else if (strcmp (FieldName, "Month") == 0) { + // + // Write ID (offset), ID, and size + // + WriteWord (mNvDataStructSize + mNonNvDataStructSize + 2); + if (WriteLength) { + WriteByte (0, 0); + } + } else if (strcmp (FieldName, "Day") == 0) { + // + // Write ID (offset), ID, and size + // + WriteWord (mNvDataStructSize + mNonNvDataStructSize + 4); + if (WriteLength) { + WriteByte (0, 0); + } + } else { + PrintErrorMessage (LineNum1, FieldName, "expected valid field name TheYear/TheMonth/TheDay"); + } + return; + } else if (strcmp (StructName, "Time") == 0) { + // + // Someone specified Time.Hours|Minutes|Seconds + // BUGBUG -- define some constants for the IDs used here + // + if (strcmp (FieldName, "Hours") == 0) { + // + // Write ID (offset), ID, and size + // + WriteWord (mNvDataStructSize + mNonNvDataStructSize + 6); + if (WriteLength) { + WriteByte (0, 0); + } + } else if (strcmp (FieldName, "Minutes") == 0) { + // + // Write ID (offset), ID, and size + // + WriteWord (mNvDataStructSize + mNonNvDataStructSize + 8); + if (WriteLength) { + WriteByte (0, 0); + } + } else if (strcmp (FieldName, "Seconds") == 0) { + // + // Write ID (offset), ID, and size + // + WriteWord (mNvDataStructSize + mNonNvDataStructSize + 10); + if (WriteLength) { + WriteByte (0, 0); + } + } else { + PrintErrorMessage (LineNum1, FieldName, "expected valid field name Hours/Minutes/Seconds"); + } + return; + } else { + PrintErrorMessage (LineNum1, StructName, "undefined structure"); + return; + } +} +VOID +EfiVfrParser::StartStructDefinition ( + INT32 IsNonNV, + INT32 LineNum + ) +/*++ + +Routine Description: + Called when we encounter a new "struct _MY_STRUCT..." statement while parsing. + Initialize internal data and structures for parsing the fields of the structure. + +Arguments: + LineNum - line number in the source file (for error reporting purposes) + IsNonNv - flag indicating (if nonzero) that the variable referred to is not in + the standard NV store. +Returns: + None + +--*/ +{ + STRUCT_DEFINITION *StructDef; + // + // Allocate memory for the structure record + // + StructDef = (STRUCT_DEFINITION *)malloc (sizeof (STRUCT_DEFINITION)); + memset (StructDef, 0, sizeof (STRUCT_DEFINITION)); + StructDef->LineNum = LineNum; + // + // Set flag indicating non-NV data structure or not + // + StructDef->IsNonNV = IsNonNV; + // + // Add it to the end of our linked list. If it's the first one + // defined, then it's the default varstore ID, so set it valid. + // + if (mFirstStructDefinition == NULL) { + mFirstStructDefinition = StructDef; + StructDef->VarStoreIdValid = 1; + } else { + mLastStructDefinition->Next = StructDef; + } + mLastStructDefinition = StructDef; +} +VOID +EfiVfrParser::EndStructDefinition ( + CHAR8 *StructName, + INT32 LineNum + ) +{ + STRUCT_DEFINITION *StructDef; + STRUCT_FIELD_DEFINITION *FieldDef; + UINT32 Offset; + // + // Make sure they have not already defined a structure with this name + // + for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) { + if ((StructDef->Name != NULL) && (strcmp (StructDef->Name, StructName) == 0)) { + PrintErrorMessage (LineNum, StructName, "structure with this name already defined"); + // + // Fall through and fill in the rest of the structure information. We do + // this because the structure has already been added to our global list, + // so will be used elsewhere, so we want it to contain valid fields. + // + } + } + // + // Allocate memory for the structure name + // + mLastStructDefinition->Name = (char *)malloc (strlen (StructName) + 1); + strcpy (mLastStructDefinition->Name, StructName); + // + // Compute the structure size, and the offsets to each field + // + Offset = 0; + for (FieldDef = mLastStructDefinition->Field; FieldDef != NULL; FieldDef = FieldDef->Next) { + FieldDef->Offset = Offset; + Offset += FieldDef->ArrayLength * FieldDef->DataSize; + } + mLastStructDefinition->Size = Offset; + // + // Go through all the structure we have so far and figure out (if we can) + // the size of the non-NV storage. We also assume that the first structure + // definition is the primary/default storage for the VFR form. + // + if (mNonNvDataStructSize == 0) { + for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) { + if (StructDef->IsNonNV) { + mNonNvDataStructSize = StructDef->Size; + break; + } + } + } + if (mNvDataStructSize == 0) { + for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) { + if (StructDef->IsNonNV == 0) { + mNvDataStructSize = StructDef->Size; + break; + } + } + } +} +VOID +EfiVfrParser::AddStructField ( + CHAR8 *FieldName, + INT32 LineNum, + INT32 DataSize, + INT32 ArrayLength, + INT8 IsArray + ) +/*++ + +Routine Description: + We're parsing the VFR structure definition. Add another defined field to + our definition. + +Arguments: + FieldName - name of the field in the structure. + LineNum - the line number from the input (preprocessor output) file + DataSize - the size of the field (1, 2, or 4 bytes) + ArrayLength - the number of elements (for array) + IsArray - non-zero if the field is an array + +Returns: + None. + +--*/ +{ + STRUCT_FIELD_DEFINITION *FieldDef; + STRUCT_FIELD_DEFINITION *Temp; + // + // Make sure we don't already have a field of this name in our structure + // + for (FieldDef = mLastStructDefinition->Field; FieldDef != NULL; FieldDef = FieldDef->Next) { + if (strcmp (FieldDef->Name, FieldName) == 0) { + PrintErrorMessage (LineNum, FieldName, "field with this name already defined"); + return; + } + } + // + // If it's an array, then they better not have a size of 0. For example: + // UINT8 MyBytes[0]; + // + if (IsArray && (ArrayLength <= 0)) { + PrintErrorMessage (LineNum, FieldName, "invalid array size"); + return; + } + // + // Allocate memory for a new structure field definition + // + FieldDef = (STRUCT_FIELD_DEFINITION *)malloc (sizeof (STRUCT_FIELD_DEFINITION)); + memset ((char *)FieldDef, 0, sizeof (STRUCT_FIELD_DEFINITION)); + FieldDef->ArrayLength = ArrayLength; + FieldDef->DataSize = DataSize; + FieldDef->IsArray = IsArray; + FieldDef->Name = (char *)malloc (strlen (FieldName) + 1); + strcpy (FieldDef->Name, FieldName); + // + // Add it to the end of the field list for the currently active structure + // + if (mLastStructDefinition->Field == NULL) { + mLastStructDefinition->Field = FieldDef; + } else { + mLastStructDefinition->LastField->Next = FieldDef; + } + mLastStructDefinition->LastField = FieldDef; +} +VOID +EfiVfrParser::AddVarStore ( + CHAR8 *StructName, // actual name of the structure + CHAR8 *VarName, // actual NV variable name + UINT16 VarStoreId, // key value + INT32 LineNum // parse line number (for error reporting) + ) +/*++ + +Routine Description: + Called while parsing a varstore statement. Add the variable store + to our linked list. + +Arguments: + StructName - the name of the typedef'ed structure to use + VarName - the NV variable name as specified in the varstore statement + VarStoreId - the variable store ID as specified in the varstore statememt + LineNum - the line number from the input (preprocessor output) file + +Returns: + None. + +--*/ +{ + STRUCT_DEFINITION *StructDef; + UINT16_LIST *L16Ptr; + // + // Go through our list of previously-defined variable store IDs and + // make sure this one is not a duplicate in name or key value. + // + for (L16Ptr = mDefinedVarStoreId; L16Ptr != NULL; L16Ptr = L16Ptr->Next) { + if (L16Ptr->Value == VarStoreId) { + PrintErrorMessage (LineNum, "variable storage key already used", NULL); + PrintErrorMessage (L16Ptr->LineNum, "previous usage of storage key", NULL); + } + } + // + // Key value of 0 is invalid since that's assigned by default to the default + // variable store (the first structure parsed). + // + if (VarStoreId == 0) { + PrintErrorMessage (LineNum, "variable storage key of 0 is invalid", NULL); + } + // + // Create a new element to add to the list + // + L16Ptr = (UINT16_LIST *)malloc(sizeof (UINT16_LIST)); + memset (L16Ptr, 0, sizeof (UINT16_LIST)); + L16Ptr->LineNum = LineNum; + L16Ptr->Value = VarStoreId; + if (mDefinedVarStoreId == NULL) { + mDefinedVarStoreId = L16Ptr; + } else { + mLastDefinedVarStoreId->Next = L16Ptr; + } + mLastDefinedVarStoreId = L16Ptr; + // + // Find the structure definition with this name + // + for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) { + if (strcmp (StructDef->Name, StructName) == 0) { + // + // Make sure they did not already define a variable storage ID + // for this structure. + // + if (StructDef->VarStoreId != 0) { + PrintErrorMessage (LineNum, StructName, "variable storage already defined for this structure"); + PrintErrorMessage (StructDef->VarStoreLineNum, StructName, "previous definition for variable storage"); + } + StructDef->VarStoreId = VarStoreId; + StructDef->VarStoreIdValid = 1; + StructDef->VarStoreLineNum = LineNum; + WriteWord (StructDef->Size); + while (*VarName) { + WriteByte(*VarName, 0); + VarName++; + } + WriteByte(0,0); + return; + } + } + PrintErrorMessage (LineNum, StructName, "structure with this name not defined"); +} +VOID +EfiVfrParser::WriteDWord ( + UINT32 Value, + UINT8 KeyByte + ) +/*++ + +Routine Description: + During parsing, we came upon some code that requires a 32-bit value be + written to the VFR binary file. Queue up the 4 bytes. + +Arguments: + Value - the 32-bit value to write + KeyByte - a single character which gets written out beside the first byte. + This is used to tag the data in the output file so that during + debug you have an idea what the value is. + +Returns: + None. + +--*/ +{ + // + // Write 4 bytes, little endian. Specify a key byte only on the first one + // + mOpcodeHandler.AddByte ((UINT8)Value, KeyByte); + Value \>>= 8; + mOpcodeHandler.AddByte ((UINT8)Value, 0); + Value \>>= 8; + mOpcodeHandler.AddByte ((UINT8)Value, 0); + Value \>>= 8; + mOpcodeHandler.AddByte ((UINT8)Value, 0); +} +VOID +EfiVfrParser::WriteOpByte ( + UINT32 LineNum, + UINT8 ByteValue + ) +/*++ + +Routine Description: + + During parsing, we came upon a new VFR opcode. At this point we flush + the output queue and then queue up this byte (with 'O' for opcode tag). + +Arguments: + + ByteValue - opcode value + +Returns: + + None. + +--*/ +{ + mOpcodeHandler.AddOpcodeByte (ByteValue, LineNum); +} +VOID +EfiVfrParser::WriteByte ( + UINT8 ByteValue, + UINT8 Key + ) +/*++ + +Routine Description: + + During parsing of the VFR we spoonfeed this function with bytes to write to + the output VFR binary file. This function simply queues up the bytes, and + the queue gets flushed each time a new VFR opcode is encountered. + +Arguments: + + ByteValue - raw byte to write + Key - character to tag the byte with when we write ByteValue to the + output file. + +Returns: + + None. + +--*/ +{ + mOpcodeHandler.AddByte (ByteValue, Key); +} +VOID +EfiVfrParser::WriteWord ( + UINT32 Value + ) +/*++ + +Routine Description: + During VFR parsing we came upon a case where we need to write out a + 16-bit value. Queue it up. + +Arguments: + Value - value to write. + +Returns: + None. + +--*/ +{ + mOpcodeHandler.AddByte ((UINT8)Value, 0); + mOpcodeHandler.AddByte ((UINT8)((Value \>> 8) & 0xFF), 0); +} +VOID +EfiVfrParser::WriteStringIdWord ( + UINT16 WordValue + ) +{ + mOpcodeHandler.AddByte ((UINT8)WordValue, 'S'); + mOpcodeHandler.AddByte ((UINT8)((WordValue \>> 8) & 0xFF), 0); +} +VOID +EfiVfrParser::FreeGotoReferences () +/*++ + +Routine Description: + Called during cleanup to free up the memory we allocated when + keeping track of VFR goto statements. + +Arguments: + None + +Returns: + None + +--*/ +{ + GOTO_REFERENCE *CurrRef; + GOTO_REFERENCE *NextRef; + FORM_ID_VALUE *CurrFormId; + FORM_ID_VALUE *NextFormId; + UINT8 Found; + CHAR8 Name[20]; + + // + // Go through all the "goto" references and make sure there was a + // form ID of that value defined. + // + for (CurrRef = mGotoReferences; CurrRef != NULL; CurrRef = CurrRef->Next) { + Found = 0; + for (CurrFormId = mFormIdValues; CurrFormId != NULL; CurrFormId = CurrFormId->Next) { + if (CurrRef->Value == CurrFormId->Value) { + Found = 1; + break; + } + } + if (!Found) { + sprintf (Name, "%d", (UINT32)CurrRef->Value); + PrintErrorMessage (CurrRef->RefLineNum, Name, "undefined form ID"); + } + } + // + // Now free up the form id and goto references + // + CurrFormId = mFormIdValues; + while (CurrFormId != NULL) { + NextFormId = CurrFormId->Next; + free (CurrFormId); + CurrFormId = NextFormId; + } + mFormIdValues = NULL; + CurrRef = mGotoReferences; + while (CurrRef != NULL) { + NextRef = CurrRef->Next; + free (CurrRef); + CurrRef = NextRef; + } + mGotoReferences = NULL; +} +VOID +EfiVfrParser::AddGotoReference ( + UINT32 GotoNumber, + UINT32 LineNum + ) +/*++ + +Routine Description: + During VFR parsing we came upon a goto statement. Since we support + forward references, save the referenced label and at the end of parsing + we'll check that the label was actually defined somewhere. + +Arguments: + GotoNumber - the label number referenced + LineNum - the line number where the reference was made (used for + error reporting) + +Returns: + None + +--*/ +{ + GOTO_REFERENCE *NewRef; + + NewRef = (GOTO_REFERENCE *)malloc (sizeof (GOTO_REFERENCE)); + if (NewRef == NULL) { + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return; + } + memset ((char *)NewRef, 0, sizeof (GOTO_REFERENCE)); + NewRef->Value = (UINT16)GotoNumber; + NewRef->RefLineNum = LineNum; + NewRef->Next = mGotoReferences; + mGotoReferences = NewRef; +} +VOID +EfiVfrParser::AddFormId ( + INT32 FormIdValue, + UINT32 LineNum + ) +/*++ + +Routine Description: + This function is called when we parse "form formid = 3" statements. + We save the form ID valud so we can verify that duplicates are not + defined. Also, these are the targets of goto statements, so when we're + done parsing the script we also go through all the goto statements to + check that there was a target FormId defined as referenced by each + goto statement. + + Note that formid = 0 is invalid. + +Arguments: + FormIdValue - the parsed value for the Form ID + LineNum - line number of the source file we're parsing + +Returns: + NA + +--*/ +{ + FORM_ID_VALUE *NewFormId; + char *FileName; + char *FileName2; + UINT32 LineNum2; + // + // Verify that FormId != 0 + // + if (FormIdValue == 0) { + FileName = ConvertLineNumber (&LineNum); + Error (FileName, LineNum, 0, "form ID cannot be 0", NULL); + return; + } + // + // First go through all previously defined form IDs and make sure they have not defined + // duplicates. + // + for (NewFormId = mFormIdValues; NewFormId != NULL; NewFormId = NewFormId->Next) { + if ((UINT16)FormIdValue == NewFormId->Value) { + FileName = ConvertLineNumber (&LineNum); + LineNum2 = NewFormId->LineNum; + FileName2 = ConvertLineNumber (&LineNum2); + Error (FileName, LineNum, 0, NULL, "form ID %d already defined", FormIdValue); + Error (FileName2, LineNum2, 0, NULL, "form ID %d previous definition", FormIdValue); + return; + } + } + // + // Allocate memory for a new one + // + NewFormId = (FORM_ID_VALUE *)malloc (sizeof (FORM_ID_VALUE)); + if (NewFormId == NULL) { + Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); + return; + } + memset ((char *)NewFormId, 0, sizeof (FORM_ID_VALUE)); + NewFormId->LineNum = LineNum; + NewFormId->Next = mFormIdValues; + NewFormId->Value = (UINT16)FormIdValue; + mFormIdValues = NewFormId; +} +UINT32 +EfiVfrParser::GetNumber ( + CHAR8 *NumStr, + UINT32 LineNum, + UINT32 NumBytes + ) +{ + UINT32 Value; + + if ((NumStr[0] == '0') && (NumStr[1] == 'x')) { + AtoX (NumStr + 2, 4, &Value); + } else { + Value = (UINT32)atoi (NumStr); + } + // + // Check range + // + if ((NumBytes < 4) && (Value & ((UINT32)0xFFFFFFFF << (NumBytes * 8)))) { + PrintErrorMessage (LineNum, NumStr, "value out of range"); + return 0; + } + return Value; +} + +>> + +} // end grammar class + diff --git a/Tools/CodeTools/Source/VfrCompile/VfrServices.cpp b/Tools/CodeTools/Source/VfrCompile/VfrServices.cpp new file mode 100644 index 0000000000..359256a358 --- /dev/null +++ b/Tools/CodeTools/Source/VfrCompile/VfrServices.cpp @@ -0,0 +1,758 @@ +/*++ + +Copyright (c) 2004 - 2005, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + VfrServices.cpp + +Abstract: + + Support routines for the VFR compiler + +--*/ + +#include // for FILE routines +#include // for malloc() and free() + +#include +#include +#include +#include // for EFI_UGA_PIXEL definition +#include + +#include "EfiUtilityMsgs.h" +#include "EfiVfr.h" +#include "VfrServices.h" + + +static const char *mSourceFileHeader[] = { + "//", + "// DO NOT EDIT -- auto-generated file", + "//", + "// This file is generated by the VFR compiler.", + "//", + NULL +}; + +typedef struct { + CHAR8 *Name; + INT32 Size; +} IFR_OPCODE_SIZES; + +// +// Create a table that can be used to do internal checking on the IFR +// bytes we emit. +// +static const IFR_OPCODE_SIZES mOpcodeSizes[] = { + { 0, 0 }, // invalid + { "EFI_IFR_FORM", sizeof (EFI_IFR_FORM) }, + { "EFI_IFR_SUBTITLE", sizeof (EFI_IFR_SUBTITLE) }, + { "EFI_IFR_TEXT", -6 }, //sizeof (EFI_IFR_TEXT) }, + { "unused 0x04 opcode", 0 }, // EFI_IFR_GRAPHIC_OP + { "EFI_IFR_ONE_OF", sizeof (EFI_IFR_ONE_OF) }, + { "EFI_IFR_CHECKBOX", sizeof (EFI_IFR_CHECKBOX) }, + { "EFI_IFR_NUMERIC", sizeof (EFI_IFR_NUMERIC) }, + { "EFI_IFR_PASSWORD", sizeof (EFI_IFR_PASSWORD) }, + { "EFI_IFR_ONE_OF_OPTION", sizeof (EFI_IFR_ONE_OF_OPTION) }, + { "EFI_IFR_SUPPRESS", sizeof (EFI_IFR_SUPPRESS) }, + { "EFI_IFR_END_FORM", sizeof (EFI_IFR_END_FORM) }, + { "EFI_IFR_HIDDEN", sizeof (EFI_IFR_HIDDEN) }, + { "EFI_IFR_END_FORM_SET", sizeof (EFI_IFR_END_FORM_SET) }, + { "EFI_IFR_FORM_SET", sizeof (EFI_IFR_FORM_SET) }, + { "EFI_IFR_REF", sizeof (EFI_IFR_REF) }, + { "EFI_IFR_END_ONE_OF", sizeof (EFI_IFR_END_ONE_OF) }, + { "EFI_IFR_INCONSISTENT", sizeof (EFI_IFR_INCONSISTENT) }, + { "EFI_IFR_EQ_ID_VAL", sizeof (EFI_IFR_EQ_ID_VAL) }, + { "EFI_IFR_EQ_ID_ID", sizeof (EFI_IFR_EQ_ID_ID) }, + { "EFI_IFR_EQ_ID_LIST", -sizeof (EFI_IFR_EQ_ID_LIST) }, + { "EFI_IFR_AND", sizeof (EFI_IFR_AND) }, + { "EFI_IFR_OR", sizeof (EFI_IFR_OR) }, + { "EFI_IFR_NOT", sizeof (EFI_IFR_NOT) }, + { "EFI_IFR_END_EXPR", sizeof (EFI_IFR_END_EXPR) }, + { "EFI_IFR_GRAY_OUT", sizeof (EFI_IFR_GRAY_OUT) }, + { "EFI_IFR_DATE", sizeof (EFI_IFR_DATE) / 3 }, + { "EFI_IFR_TIME", sizeof (EFI_IFR_TIME) / 3 }, + { "EFI_IFR_STRING", sizeof (EFI_IFR_STRING) }, + { "EFI_IFR_LABEL", sizeof (EFI_IFR_LABEL) }, + { "EFI_IFR_SAVE_DEFAULTS", sizeof (EFI_IFR_SAVE_DEFAULTS) }, + { "EFI_IFR_RESTORE_DEFAULTS", sizeof (EFI_IFR_RESTORE_DEFAULTS) }, + { "EFI_IFR_BANNER", sizeof (EFI_IFR_BANNER) }, + { "EFI_IFR_INVENTORY", sizeof (EFI_IFR_INVENTORY) }, + { "EFI_IFR_EQ_VAR_VAL_OP", sizeof (EFI_IFR_EQ_VAR_VAL) }, + { "EFI_IFR_ORDERED_LIST_OP", sizeof (EFI_IFR_ORDERED_LIST) }, + { "EFI_IFR_VARSTORE_OP", -sizeof (EFI_IFR_VARSTORE) }, + { "EFI_IFR_VARSTORE_SELECT_OP", sizeof (EFI_IFR_VARSTORE_SELECT) }, + { "EFI_IFR_VARSTORE_SELECT_PAIR_OP", sizeof (EFI_IFR_VARSTORE_SELECT_PAIR) }, + { "EFI_IFR_TRUE", sizeof (EFI_IFR_TRUE)}, + { "EFI_IFR_FALSE", sizeof (EFI_IFR_FALSE)}, + { "EFI_IFR_GT", sizeof (EFI_IFR_GT)}, + { "EFI_IFR_GE", sizeof (EFI_IFR_GE)}, + { "EFI_IFR_OEM_DEFINED_OP", -2 }, +}; + + +VfrOpcodeHandler::VfrOpcodeHandler ( + ) +/*++ + +Routine Description: + Constructor for the VFR opcode handling class. + +Arguments: + None + +Returns: + None + +--*/ +{ + mIfrBytes = NULL; + mLastIfrByte = NULL; + mBytesWritten = 0; + mQueuedByteCount = 0; + mQueuedOpcodeByteValid = 0; + mPrimaryVarStoreId = 0; + mSecondaryVarStoreId = 0; + mSecondaryVarStoreIdSet = 0; + mPrimaryVarStoreIdSet = 0; + mDefaultVarStoreId = 0; +} + +VOID +VfrOpcodeHandler::SetVarStoreId ( + UINT16 VarStoreId + ) +/*++ + +Routine Description: + This function is invoked by the parser when a variable is referenced in the + VFR. Save the variable store (and set a flag) so that we can later determine + if we need to emit a varstore-select or varstore-select-pair opcode. + +Arguments: + VarStoreId - ID of the variable store referenced in the VFR + +Returns: + None + +--*/ +{ + mPrimaryVarStoreId = VarStoreId; + mPrimaryVarStoreIdSet = 1; +} + +VOID +VfrOpcodeHandler::SetSecondaryVarStoreId ( + UINT16 VarStoreId + ) +/*++ + +Routine Description: + This function is invoked by the parser when a secondary variable is + referenced in the VFR. Save the variable store (and set a flag) so + that we can later determine if we need to emit a varstore-select or + varstore-pair opcode. + +Arguments: + VarStoreId - ID of the variable store referenced in the VFR + +Returns: + None + +--*/ +{ + mSecondaryVarStoreId = VarStoreId; + mSecondaryVarStoreIdSet = 1; +} + +VOID +VfrOpcodeHandler::WriteIfrBytes ( + ) +/*++ + +Routine Description: + This function is invoked at the end of parsing. Its purpose + is to write out all the IFR bytes that were queued up while + parsing. + +Arguments: + None + +Returns: + None + +--*/ +{ + IFR_BYTE *Curr; + IFR_BYTE *Next; + UINT32 Count; + UINT32 LineCount; + UINT32 PoundLines; + UINT32 ByteCount; + CHAR8 Line[MAX_LINE_LEN]; + CHAR8 *Cptr; + FILE *InFptr; + FILE *OutFptr; + UINT32 ListFile; + EFI_HII_IFR_PACK_HEADER IfrHeader; + UINT8 *Ptr; + FILE *IfrBinFptr; + UINT32 BytesLeftThisOpcode; + // + // If someone added a new opcode and didn't update our opcode sizes structure, error out. + // + if (sizeof(mOpcodeSizes) / sizeof (mOpcodeSizes[0]) != EFI_IFR_LAST_OPCODE + 1) { + Error (__FILE__, __LINE__, 0, "application error", "internal IFR binary table size is incorrect"); + return; + } + // + // Flush the queue + // + FlushQueue (); + // + // If there have been any errors to this point, then skip dumping the IFR + // binary data. This way doing an nmake again will try to build it again, and + // the build will fail if they did not fix the problem. + // + if (GetUtilityStatus () != STATUS_ERROR) { + if ((IfrBinFptr = fopen (gOptions.IfrOutputFileName, "w")) == NULL) { + Error (PROGRAM_NAME, 0, 0, gOptions.IfrOutputFileName, "could not open file for writing"); + return; + } + // + // Write the standard file header to the output file + // + WriteStandardFileHeader (IfrBinFptr); + // + // Write the structure header + // + fprintf (IfrBinFptr, "\nunsigned char %sBin[] = {", gOptions.VfrBaseFileName); + // + // Write the header + // + memset ((char *)&IfrHeader, 0, sizeof (IfrHeader)); + IfrHeader.Header.Type = EFI_HII_IFR; + IfrHeader.Header.Length = mBytesWritten + sizeof (IfrHeader); + Ptr = (UINT8 *)&IfrHeader; + for (Count = 0; Count < sizeof (IfrHeader); Count++, Ptr++) { + if ((Count & 0x03) == 0) { + fprintf (IfrBinFptr, "\n "); + } + fprintf (IfrBinFptr, "0x%02X, ", *Ptr); + } + // + // + // Write all the IFR bytes + // + fprintf (IfrBinFptr, "\n // start of IFR data"); + Curr = mIfrBytes; + Count = 0; + while (Curr != NULL) { + if ((Count & 0x0F) == 0) { + fprintf (IfrBinFptr, "\n "); + } + if (Curr->KeyByte != 0) { + fprintf (IfrBinFptr, "/*%c*/ ", Curr->KeyByte); + } + fprintf (IfrBinFptr, "0x%02X, ", Curr->OpcodeByte); + Count++; + Curr = Curr->Next; + } + fprintf (IfrBinFptr, "\n};\n\n"); + // + // + // Close the file + // + fclose (IfrBinFptr); + IfrBinFptr = NULL; + } + // + // Write the bytes as binary data if the user specified to do so + // + if ((GetUtilityStatus () != STATUS_ERROR) && (gOptions.CreateIfrBinFile != 0)) { + // + // Use the Ifr output file name with a ".hpk" extension. + // + for (Cptr = gOptions.IfrOutputFileName + strlen (gOptions.IfrOutputFileName) - 1; + (*Cptr != '.') && (Cptr > gOptions.IfrOutputFileName) && (*Cptr != '\\'); + Cptr--) { + // + // do nothing + // + } + if (*Cptr == '.') { + strcpy (Cptr, ".hpk"); + } else { + strcat (gOptions.IfrOutputFileName, ".hpk"); + } + if ((IfrBinFptr = fopen (gOptions.IfrOutputFileName, "wb")) == NULL) { + Error (PROGRAM_NAME, 0, 0, gOptions.IfrOutputFileName, "could not open file for writing"); + return; + } + // + // Write the structure header + // + memset ((char *)&IfrHeader, 0, sizeof (IfrHeader)); + IfrHeader.Header.Type = EFI_HII_IFR; + IfrHeader.Header.Length = mBytesWritten + sizeof (IfrHeader); + Ptr = (UINT8 *)&IfrHeader; + for (Count = 0; Count < sizeof (IfrHeader); Count++, Ptr++) { + fwrite (Ptr, 1, 1, IfrBinFptr); + } + // + // + // Write all the IFR bytes + // + Curr = mIfrBytes; + Count = 0; + while (Curr != NULL) { + fwrite (&Curr->OpcodeByte, 1, 1, IfrBinFptr); + Curr = Curr->Next; + } + // + // + // Close the file + // + fclose (IfrBinFptr); + IfrBinFptr = NULL; + } + // + // If creating a listing file, then open the input and output files + // + ListFile = 0; + if (gOptions.CreateListFile) { + // + // Open the input VFR file and the output list file + // + if ((InFptr = fopen (gOptions.PreprocessorOutputFileName, "r")) == NULL) { + Warning (PROGRAM_NAME, 0, 0, gOptions.PreprocessorOutputFileName, "could not open file for creating a list file"); + } else { + if ((OutFptr = fopen (gOptions.VfrListFileName, "w")) == NULL) { + Warning (PROGRAM_NAME, 0, 0, gOptions.VfrListFileName, "could not open output list file for writing"); + fclose (InFptr); + InFptr = NULL; + } else { + LineCount = 0; + ListFile = 1; + PoundLines = 0; + ByteCount = 0; + } + } + } + // + // Write the list file + // + if (ListFile) { + // + // Write out the VFR compiler version + // + fprintf (OutFptr, "//\n// VFR compiler version " VFR_COMPILER_VERSION "\n//\n"); + Curr = mIfrBytes; + while (Curr != NULL) { + // + // Print lines until we reach the line of the current opcode + // + while (LineCount < PoundLines + Curr->LineNum) { + if (fgets (Line, sizeof (Line), InFptr) != NULL) { + // + // We should check for line length exceeded on the fgets(). Otherwise it + // throws the listing file output off. Future enhancement perhaps. + // + fprintf (OutFptr, "%s", Line); + if (strncmp (Line, "#line", 5) == 0) { + PoundLines++; + } + } + LineCount++; + } + // + // Print all opcodes with line numbers less than where we are now + // + BytesLeftThisOpcode = 0; + while ((Curr != NULL) && ((Curr->LineNum == 0) || (LineCount >= PoundLines + Curr->LineNum))) { + if (BytesLeftThisOpcode == 0) { + fprintf (OutFptr, ">%08X: ", ByteCount); + if (Curr->Next != NULL) { + BytesLeftThisOpcode = (UINT32)Curr->Next->OpcodeByte; + } + } + fprintf (OutFptr, "%02X ", (UINT32)Curr->OpcodeByte); + ByteCount++; + BytesLeftThisOpcode--; + if (BytesLeftThisOpcode == 0) { + fprintf (OutFptr, "\n"); + } + Curr = Curr->Next; + } + } + // + // Dump any remaining lines from the input file + // + while (fgets (Line, sizeof (Line), InFptr) != NULL) { + fprintf (OutFptr, "%s", Line); + } + fclose (InFptr); + fclose (OutFptr); + } + // + // Debug code to make sure that each opcode we write out has as many + // bytes as the IFR structure requires. If there were errors, then + // don't do this step. + // + if (GetUtilityStatus () != STATUS_ERROR) { + Curr = mIfrBytes; + ByteCount = 0; + while (Curr != NULL) { + // + // First byte is the opcode, second byte is the length + // + if (Curr->Next == NULL) { + Error (__FILE__, __LINE__, 0, "application error", "last opcode written does not contain a length byte"); + break; + } + Count = (UINT32)Curr->Next->OpcodeByte; + if (Count == 0) { + Error ( + __FILE__, + __LINE__, + 0, + "application error", + "opcode with 0 length specified in output at offset 0x%X", + ByteCount + ); + break; + } + // + // Check the length + // + if ((Curr->OpcodeByte > EFI_IFR_LAST_OPCODE) || (Curr->OpcodeByte == 0)) { + Error ( + __FILE__, + __LINE__, + 0, + "application error", + "invalid opcode 0x%X in output at offset 0x%X", + (UINT32) Curr->OpcodeByte, ByteCount + ); + } else if (mOpcodeSizes[Curr->OpcodeByte].Size < 0) { + // + // For those cases where the length is variable, the size is negative, and indicates + // the miniumum size. + // + if ((mOpcodeSizes[Curr->OpcodeByte].Size * -1) > Count) { + Error ( + __FILE__, + __LINE__, + 0, + "application error", + "insufficient number of bytes written for %s at offset 0x%X", + mOpcodeSizes[Curr->OpcodeByte].Name, + ByteCount + ); + } + } else { + // + // Check for gaps + // + if (mOpcodeSizes[Curr->OpcodeByte].Size == 0) { + Error ( + __FILE__, + __LINE__, + 0, + "application error", + "invalid opcode 0x%X in output at offset 0x%X", + (UINT32)Curr->OpcodeByte, + ByteCount + ); + } else { + // + // Check size + // + if (mOpcodeSizes[Curr->OpcodeByte].Size != Count) { + Error ( + __FILE__, + __LINE__, + 0, + "application error", + "invalid number of bytes (%d written s/b %d) written for %s at offset 0x%X", + Count, + mOpcodeSizes[Curr->OpcodeByte].Size, + mOpcodeSizes[Curr->OpcodeByte].Name, + ByteCount + ); + } + } + } + // + // Skip to next opcode + // + while (Count > 0) { + ByteCount++; + if (Curr == NULL) { + Error (__FILE__, __LINE__, 0, "application error", "last opcode written has invalid length"); + break; + } + Curr = Curr->Next; + Count--; + } + } + } +} + +VfrOpcodeHandler::~VfrOpcodeHandler( + ) +/*++ + +Routine Description: + Destructor for the VFR opcode handler. Free up memory allocated + while parsing the VFR script. + +Arguments: + None + +Returns: + None + +--*/ +{ + IFR_BYTE *Curr; + IFR_BYTE *Next; + // + // Free up the IFR bytes + // + Curr = mIfrBytes; + while (Curr != NULL) { + Next = Curr->Next; + free (Curr); + Curr = Next; + } +} + +int +VfrOpcodeHandler::AddOpcodeByte ( + UINT8 OpcodeByte, + UINT32 LineNum + ) +/*++ + +Routine Description: + This function is invoked by the parser when a new IFR + opcode should be emitted. + +Arguments: + OpcodeByte - the IFR opcode + LineNum - the line number from the source file that resulted + in the opcode being emitted. + +Returns: + 0 always + +--*/ +{ + UINT32 Count; + + FlushQueue(); + // + // Now add this new byte + // + mQueuedOpcodeByte = OpcodeByte; + mQueuedLineNum = LineNum; + mQueuedOpcodeByteValid = 1; + return 0; +} + +VOID +VfrOpcodeHandler::AddByte ( + UINT8 ByteVal, + UINT8 KeyByte + ) +/*++ + +Routine Description: + This function is invoked by the parser when it determines + that more raw IFR bytes should be emitted to the output stream. + Here we just queue them up into an output buffer. + +Arguments: + ByteVal - the raw byte to emit to the output IFR stream + KeyByte - a value that can be used for debug. + +Returns: + None + +--*/ +{ + // + // Check for buffer overflow + // + if (mQueuedByteCount > MAX_QUEUE_COUNT) { + Error (PROGRAM_NAME, 0, 0, NULL, "opcode queue overflow"); + } else { + mQueuedBytes[mQueuedByteCount] = ByteVal; + mQueuedKeyBytes[mQueuedByteCount] = KeyByte; + mQueuedByteCount++; + } +} + +int +VfrOpcodeHandler::FlushQueue ( + ) +/*++ + +Routine Description: + This function is invoked to flush the internal IFR buffer. + +Arguments: + None + +Returns: + 0 always + +--*/ +{ + UINT32 Count; + UINT32 EmitNoneOnePair; + + EmitNoneOnePair = 0; + // + // If the secondary varstore was specified, then we have to emit + // a varstore-select-pair opcode, which only applies to the following + // statement. + // + if (mSecondaryVarStoreIdSet) { + mSecondaryVarStoreIdSet = 0; + // + // If primary and secondary are the same as the current default + // varstore, then we don't have to do anything. + // Note that the varstore-select-pair only applies to the following + // opcode. + // + if ((mPrimaryVarStoreId != mSecondaryVarStoreId) || (mPrimaryVarStoreId != mDefaultVarStoreId)) { + IAddByte (EFI_IFR_VARSTORE_SELECT_PAIR_OP, 'O', mQueuedLineNum); + IAddByte ((UINT8)sizeof (EFI_IFR_VARSTORE_SELECT_PAIR), 'L', 0); + IAddByte ((UINT8)mPrimaryVarStoreId, 0, 0); + IAddByte ((UINT8)(mPrimaryVarStoreId >> 8), 0, 0); + IAddByte ((UINT8)mSecondaryVarStoreId, 0, 0); + IAddByte ((UINT8)(mSecondaryVarStoreId >> 8), 0, 0); + } + } else if (mPrimaryVarStoreIdSet != 0) { + mPrimaryVarStoreIdSet = 0; + if (mDefaultVarStoreId != mPrimaryVarStoreId) { + // + // The VFR statement referenced a different variable store + // than the last one we reported. Insert a new varstore select + // statement. + // + IAddByte (EFI_IFR_VARSTORE_SELECT_OP, 'O', mQueuedLineNum); + IAddByte ((UINT8)sizeof (EFI_IFR_VARSTORE_SELECT), 'L', 0); + IAddByte ((UINT8)mPrimaryVarStoreId, 0, 0); + IAddByte ((UINT8)(mPrimaryVarStoreId >> 8), 0, 0); + mDefaultVarStoreId = mPrimaryVarStoreId; + } + } + // + // Likely a new opcode is being added. Since each opcode item in the IFR has + // a header that specifies the size of the opcode item (which we don't + // know until we find the next opcode in the VFR), we queue up bytes + // until we know the size. Then we write them out. So flush the queue + // now. + // + if (mQueuedOpcodeByteValid != 0) { + // + // Add the previous opcode byte, the length byte, and the binary + // data. + // + IAddByte (mQueuedOpcodeByte, 'O', mQueuedLineNum); + IAddByte ((UINT8)(mQueuedByteCount + 2), 'L', 0); + for (Count = 0; Count < mQueuedByteCount; Count++) { + IAddByte (mQueuedBytes[Count], mQueuedKeyBytes[Count], 0); + } + mQueuedByteCount = 0; + mQueuedOpcodeByteValid = 0; + } + return 0; +} + +int +VfrOpcodeHandler::IAddByte ( + UINT8 ByteVal, + UINT8 KeyByte, + UINT32 LineNum + ) +/*++ + +Routine Description: + This internal function is used to add actual IFR bytes to + the output stream. Most other functions queue up the bytes + in an internal buffer. Once they come here, there's no + going back. + + +Arguments: + ByteVal - value to write to output + KeyByte - key value tied to the byte -- useful for debug + LineNum - line number from source file the byte resulted from + +Returns: + 0 - if successful + 1 - failed due to memory allocation failure + +--*/ +{ + IFR_BYTE *NewByte; + NewByte = (IFR_BYTE *)malloc (sizeof (IFR_BYTE)); + if (NewByte == NULL) { + return 1; + } + memset ((char *)NewByte, 0, sizeof (IFR_BYTE)); + NewByte->OpcodeByte = ByteVal; + NewByte->KeyByte = KeyByte; + NewByte->LineNum = LineNum; + // + // Add to the list + // + if (mIfrBytes == NULL) { + mIfrBytes = NewByte; + } else { + mLastIfrByte->Next = NewByte; + } + mLastIfrByte = NewByte; + mBytesWritten++; + return 0; +} + +VOID +WriteStandardFileHeader ( + FILE *OutFptr + ) +/*++ + +Routine Description: + This function is invoked to emit a standard header to an + output text file. + +Arguments: + OutFptr - file to write the header to + +Returns: + None + +--*/ +{ + UINT32 TempIndex; + for (TempIndex = 0; mSourceFileHeader[TempIndex] != NULL; TempIndex++) { + fprintf (OutFptr, "%s\n", mSourceFileHeader[TempIndex]); + } + // + // Write out the VFR compiler version + // + fprintf (OutFptr, "// VFR compiler version " VFR_COMPILER_VERSION "\n//\n"); +} diff --git a/Tools/CodeTools/Source/VfrCompile/VfrServices.h b/Tools/CodeTools/Source/VfrCompile/VfrServices.h new file mode 100644 index 0000000000..6b8c560d63 --- /dev/null +++ b/Tools/CodeTools/Source/VfrCompile/VfrServices.h @@ -0,0 +1,227 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + VfrServices.h + +Abstract: + + Prototypes and defines for routines and classes used by the + EFI VFR compiler. + +--*/ + +#ifndef _VFR_SERVICES_H_ +#define _VFR_SERVICES_H_ + +class VfrOpcodeHandler +{ +public: + VfrOpcodeHandler ( + VOID + ) + /*++ + +Routine Description: + Constructor for the VFR opcode handling class. + +Arguments: + None + +Returns: + None + +--*/ + ; + ~VfrOpcodeHandler ( + VOID + ) + /*++ + +Routine Description: + Destructor for the VFR opcode handler. Free up memory allocated + while parsing the VFR script. + +Arguments: + None + +Returns: + None + +--*/ + ; + void + WriteIfrBytes ( + VOID + ) + /*++ + +Routine Description: + This function is invoked at the end of parsing. Its purpose + is to write out all the IFR bytes that were queued up while + parsing. + +Arguments: + None + +Returns: + None + +--*/ + ; + int + AddOpcodeByte ( + UINT8 OpcodeByte, + UINT32 LineNum + ) + /*++ + +Routine Description: + This function is invoked by the parser when a new IFR + opcode should be emitted. + +Arguments: + OpcodeByte - the IFR opcode + LineNum - the line number from the source file that resulted + in the opcode being emitted. + +Returns: + 0 always + +--*/ + ; + void + AddByte ( + UINT8 ByteVal, + UINT8 KeyByte + ) + /*++ + +Routine Description: + This function is invoked by the parser when it determines + that more raw IFR bytes should be emitted to the output stream. + Here we just queue them up into an output buffer. + +Arguments: + ByteVal - the raw byte to emit to the output IFR stream + KeyByte - a value that can be used for debug. + +Returns: + None + +--*/ + ; + void + SetVarStoreId ( + UINT16 VarStoreId + ) + /*++ + +Routine Description: + This function is invoked by the parser when a variable is referenced in the + VFR. Save the variable store (and set a flag) so that we can later determine + if we need to emit a varstore-select or varstore-select-pair opcode. + +Arguments: + VarStoreId - ID of the variable store referenced in the VFR + +Returns: + None + +--*/ + ; + void + SetSecondaryVarStoreId ( + UINT16 VarStoreId + ) + /*++ + +Routine Description: + This function is invoked by the parser when a secondary variable is + referenced in the VFR. Save the variable store (and set a flag) so + that we can later determine if we need to emit a varstore-select or + varstore-pair opcode. + +Arguments: + VarStoreId - ID of the variable store referenced in the VFR + +Returns: + None + +--*/ + ; + +/* */ +private: + int + FlushQueue ( + VOID + ) + /*++ + +Routine Description: + This function is invoked to flush the internal IFR buffer. + +Arguments: + None + +Returns: + 0 always + +--*/ + ; + int + IAddByte ( + UINT8 ByteVal, + UINT8 KeyByte, + UINT32 LineNum + ) + /*++ + +Routine Description: + This internal function is used to add actual IFR bytes to + the output stream. Most other functions queue up the bytes + in an internal buffer. Once they come here, there's no + going back. + + +Arguments: + ByteVal - value to write to output + KeyByte - key value tied to the byte -- useful for debug + LineNum - line number from source file the byte resulted from + +Returns: + 0 - if successful + 1 - failed due to memory allocation failure + +--*/ + ; + +/* */ +private: + IFR_BYTE *mIfrBytes; + IFR_BYTE *mLastIfrByte; + UINT32 mQueuedByteCount; + UINT32 mBytesWritten; + UINT32 mQueuedLineNum; + UINT8 mQueuedBytes[MAX_QUEUE_COUNT]; + UINT8 mQueuedKeyBytes[MAX_QUEUE_COUNT]; + UINT8 mQueuedOpcodeByte; + UINT32 mQueuedOpcodeByteValid; + UINT16 mPrimaryVarStoreId; + UINT8 mPrimaryVarStoreIdSet; + UINT16 mSecondaryVarStoreId; + UINT8 mSecondaryVarStoreIdSet; + UINT16 mDefaultVarStoreId; +}; + +#endif // #ifndef _VFR_SERVICES_H_ diff --git a/Tools/CodeTools/Source/VfrCompile/build.xml b/Tools/CodeTools/Source/VfrCompile/build.xml new file mode 100644 index 0000000000..247f0d2315 --- /dev/null +++ b/Tools/CodeTools/Source/VfrCompile/build.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/ZeroDebugData/ZeroDebugData.c b/Tools/CodeTools/Source/ZeroDebugData/ZeroDebugData.c new file mode 100644 index 0000000000..caf129b429 --- /dev/null +++ b/Tools/CodeTools/Source/ZeroDebugData/ZeroDebugData.c @@ -0,0 +1,391 @@ +/*++ + +Copyright (c) 2004-2006 Intel Corporation. All rights reserved +This program and the accompanying materials are licensed and made available +under the terms and conditions of the BSD License which accompanies this +distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + +Module Name: + + ZeroDebugData.c + +Abstract: + + Zero the Debug Data Fields of Portable Executable (PE) format file. + +--*/ + +#include +#include +#include + +void +PrintUsage ( + void + ) +/*++ +Routine Description: + print usage of ZeroDebugData command + +Arguments: + None + +Returns: + None +--*/ +// GC_TODO: void - add argument and description to function comment +{ + // + // print usage of command + // + printf ("\nUsage: ZeroDebugData [DebugData-File]\n"); +} + +int +ReadFromFile ( + FILE *fp, + long offset, + void *buffer, + int size + ) +/*++ +Routine Description: + read data from a specified location of file + +Arguments: + fp - file pointer + offset - number of bytes from beginning of file + buffer - buffer used to store data + size - size of buffer + +Returns: + = 0 - Success + = -1 - Failed +--*/ +{ + // + // set file pointer to the specified location of file + // + if (fseek (fp, offset, SEEK_SET) != 0) { + printf ("Error: Cannot move the current location of the file.\n"); + return -1; + } + // + // read data from the file + // + if (fread (buffer, size, 1, fp) != 1) { + printf ("Error: Cannot read data from the file.\n"); + return -1; + } + + return 0; +} + +int +ZeroDebugData ( + FILE *fp, + FILE *fpData + ) +/*++ + +Routine Description: + + Zero the debug data fields of the file + +Arguments: + + fp - file pointer + fpData - pointer to output file that ZeroDebugData progress is written to + +Returns: + + = 0 - Success + = -1 - Failed + +--*/ +{ + unsigned char header[4]; + unsigned long offset; + unsigned long NumberOfRvaAndSizes; + unsigned int nvalue; + unsigned long lvalue; + unsigned long Size; + unsigned long Pointer; + unsigned char *Buffer; + unsigned long Index; + + // + // read the header of file + // + if (ReadFromFile (fp, 0, header, 2) != 0) { + printf ("Error: open image file\n"); + return -1; + } + // + // "MZ" -- the header of image file (PE) + // + if (strncmp ((char *) header, "MZ", 2) != 0) { + printf ("Error: Invalid Image file.\n"); + return -1; + } + // + // At location 0x3C, the stub has the file offset to the + // PE signature. + // + if (ReadFromFile (fp, 0x3C, &offset, 4) != 0) { + return -1; + } + // + // read the header of optional + // + if (ReadFromFile (fp, offset, header, 4) != 0) { + return -1; + } + // + // "PE\0\0" -- the signature of optional header + // + if (strncmp ((char *) header, "PE\0\0", 4) != 0) { + printf ("Error: Invalid PE format file.\n"); + return -1; + } + // + // Add 16 to skip COFF file header, and get to optional header. + // + offset += 24; + + // + // Check the magic field, 0x10B for PE32 and 0x20B for PE32+ + // + if (ReadFromFile (fp, offset, &nvalue, 2) != 0) { + return -1; + } + // + // If this is PE32 image file, offset of NumberOfRvaAndSizes is 92. + // Else it is 108. + // + switch (nvalue & 0xFFFF) { + case 0x10B: + offset += 92; + printf ("Info: Image is PE32. "); + break; + + case 0x20B: + offset += 108; + printf ("Info: Image is PE32+. "); + break; + + default: + printf ("Error: Magic value is unknown.\n"); + return -1; + } + // + // get the value of NumberOfRvaAndSizes + // + if (ReadFromFile (fp, offset, &NumberOfRvaAndSizes, 4) != 0) { + printf ("Error: read NumberOfRvaAndSizes error.\n"); + return -1; + } + // + // printf ("Info: NumberOfRvaAndSizes = %d\n", NumberOfRvaAndSizes); + // + // + // Finding Debug Table, offset of Debug Table + // is 4 + 6 * 8 = 52. + // + if (NumberOfRvaAndSizes >= 7) { + if (ReadFromFile (fp, offset + 52, &lvalue, 4) != 0) { + return -1; + } + // + // Read the SizeOfData(16) and PointerToRawData(24) + // + if (ReadFromFile (fp, lvalue + 16, &Size, 4) != 0) { + printf ("error: Size = %d\n", Size); + return -1; + } + + printf ("Debug data: size = %xh, ", Size); + fprintf (fpData, "Debug data: size = %xh, ", Size); + + if (ReadFromFile (fp, lvalue + 20, &Pointer, 4) != 0) { + printf ("error: LoadOffset = %xh\n", Pointer); + return -1; + } + // + // printf ("LoadOffset = %xh, ", Pointer); + // + fprintf (fpData, "LoadOffset = %xh, ", Pointer); + + if (ReadFromFile (fp, lvalue + 24, &Pointer, 4) != 0) { + printf ("error: FileOffset = %xh\n", Pointer); + return -1; + } + + printf ("FileOffset = %xh, ", Pointer); + fprintf (fpData, "FileOffset = %xh, \n", Pointer); + + if ((lvalue != 0) && (Pointer != 0)) { + // + // prepare buffer + // + Buffer = malloc (Size + 1); + if (Buffer == NULL) { + printf ("Error: Cannot allocate memory.\n"); + return -1; + } + // + // set file pointer to the specified location of file + // + if (fseek (fp, Pointer, SEEK_SET) != 0) { + printf ("Error: Cannot move the current location of the file.\n"); + free (Buffer); + return -1; + } + // + // read data from PE file + // + if (fread (Buffer, Size, 1, fp) != 1) { + printf ("Error: Cannot read data from the file.\n"); + free (Buffer); + return -1; + } + // + // write to data file + // + for (Index = 0; Index < Size;) { + fprintf (fpData, "%02x ", Buffer[Index]); + + Index++; + if (Index % 8 == 0) { + fprintf (fpData, "\n"); + } + } + + fprintf (fpData, "\n"); + + // + // zero buffer and write back to PE file + // + if (fseek (fp, Pointer, SEEK_SET) != 0) { + printf ("Error: Cannot move the current location of the file.\n"); + free (Buffer); + return -1; + } + + memset (Buffer, 0, Size); + if (fwrite (Buffer, Size, 1, fp) != 1) { + perror ("Error: Cannot write zero to the file.\n"); + free (Buffer); + return -1; + } + // + // set file pointer to the specified location of file + // + if (fseek (fp, lvalue + 4, SEEK_SET) != 0) { + printf ("Error: Cannot move the current location of the file.\n"); + free (Buffer); + return -1; + } + + if (fwrite (Buffer, 4, 1, fp) != 1) { + perror ("Error: Cannot write zero to the file.\n"); + free (Buffer); + return -1; + } + + free (Buffer); + } + } + + return 0; +} + +int +main ( + int argc, + char *argv[] + ) +/*++ + +Routine Description: + + Prints the zero debug data of the PE file to the DebugData file. + Executes the ZeroDebugData function. + +Arguments: + + argc - Standard C argument, number of command line arguments. + argv[] - Standard C argument, array of pointers to the input files, + such as the PE and DebugData files. + +Returns: + + zero - success + nonzero - failure + +--*/ +{ + FILE *fp; + FILE *fpData; + char DataFile[1024] = ""; + + // + // check the number of parameters + // + if (argc < 2) { + printf ("\nUsage: ZeroDebugData [DebugData-File]\n"); + return -1; + } + // + // open the DebugData file, if not exists, return + // + if (argc >= 3) { + strcpy (DataFile, argv[2]); + } else { + strcpy (DataFile, "DebugData.dat"); + } + + fpData = fopen (DataFile, "a+"); + if (fpData == NULL) { + fpData = fopen (DataFile, "w"); + if (fpData == NULL) { + printf ("Error: Cannot open the data file!\n"); + return -1; + } + } + // + // open the PE file + // + fp = fopen (argv[1], "r+b"); + if (fp == NULL) { + printf ("Error: Cannot open the PE file!\n"); + return -1; + } + // + // Zero the Debug Data to the PE file + // + printf ("Zero Debug Data to file %s:\n", argv[1]); + fprintf (fpData, "\nZero Debug Data to file %s:\n", argv[1]); + if ((int *) ZeroDebugData (fp, fpData) != 0) { + printf ("Error: Zero Debug Data PE file\n"); + fclose (fp); + return -1; + } + + printf (" success\n"); + + // + // close the PE file + // + fflush (fpData); + fflush (fp); + fclose (fpData); + fclose (fp); + + return 0; +} diff --git a/Tools/CodeTools/Source/ZeroDebugData/build.xml b/Tools/CodeTools/Source/ZeroDebugData/build.xml new file mode 100644 index 0000000000..2a85fc1af2 --- /dev/null +++ b/Tools/CodeTools/Source/ZeroDebugData/build.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/Source/build.xml b/Tools/CodeTools/Source/build.xml new file mode 100644 index 0000000000..3d59c9c2c2 --- /dev/null +++ b/Tools/CodeTools/Source/build.xml @@ -0,0 +1,269 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/CodeTools/TianoTools/Common/CommonLib.c b/Tools/CodeTools/TianoTools/Common/CommonLib.c deleted file mode 100644 index 4d1663a55a..0000000000 --- a/Tools/CodeTools/TianoTools/Common/CommonLib.c +++ /dev/null @@ -1,508 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - CommonLib.c - -Abstract: - - Common Library Functions - ---*/ - -#include -#include -#include -#include "CommonLib.h" - -VOID -PeiZeroMem ( - IN VOID *Buffer, - IN UINTN Size - ) -/*++ - -Routine Description: - - Set Buffer to zero for Size bytes. - -Arguments: - - Buffer - Memory to set. - - Size - Number of bytes to set - -Returns: - - None - ---*/ -{ - INT8 *Ptr; - - Ptr = Buffer; - while (Size--) { - *(Ptr++) = 0; - } -} - -VOID -PeiCopyMem ( - IN VOID *Destination, - IN VOID *Source, - IN UINTN Length - ) -/*++ - -Routine Description: - - Copy Length bytes from Source to Destination. - -Arguments: - - Destination - Target of copy - - Source - Place to copy from - - Length - Number of bytes to copy - -Returns: - - None - ---*/ -{ - CHAR8 *Destination8; - CHAR8 *Source8; - - Destination8 = Destination; - Source8 = Source; - while (Length--) { - *(Destination8++) = *(Source8++); - } -} - -VOID -ZeroMem ( - IN VOID *Buffer, - IN UINTN Size - ) -{ - PeiZeroMem (Buffer, Size); -} - -VOID -CopyMem ( - IN VOID *Destination, - IN VOID *Source, - IN UINTN Length - ) -{ - PeiCopyMem (Destination, Source, Length); -} - -INTN -CompareGuid ( - IN EFI_GUID *Guid1, - IN EFI_GUID *Guid2 - ) -/*++ - -Routine Description: - - Compares to GUIDs - -Arguments: - - Guid1 - guid to compare - Guid2 - guid to compare - -Returns: - = 0 if Guid1 == Guid2 - != 0 if Guid1 != Guid2 - ---*/ -{ - INT32 *g1; - INT32 *g2; - INT32 r; - - // - // Compare 32 bits at a time - // - g1 = (INT32 *) Guid1; - g2 = (INT32 *) Guid2; - - r = g1[0] - g2[0]; - r |= g1[1] - g2[1]; - r |= g1[2] - g2[2]; - r |= g1[3] - g2[3]; - - return r; -} - -EFI_STATUS -GetFileImage ( - IN CHAR8 *InputFileName, - OUT CHAR8 **InputFileImage, - OUT UINT32 *BytesRead - ) -/*++ - -Routine Description: - - This function opens a file and reads it into a memory buffer. The function - will allocate the memory buffer and returns the size of the buffer. - -Arguments: - - InputFileName The name of the file to read. - InputFileImage A pointer to the memory buffer. - BytesRead The size of the memory buffer. - -Returns: - - EFI_SUCCESS The function completed successfully. - EFI_INVALID_PARAMETER One of the input parameters was invalid. - EFI_ABORTED An error occurred. - EFI_OUT_OF_RESOURCES No resource to complete operations. - ---*/ -{ - FILE *InputFile; - UINT32 FileSize; - - // - // Verify input parameters. - // - if (InputFileName == NULL || strlen (InputFileName) == 0 || InputFileImage == NULL) { - return EFI_INVALID_PARAMETER; - } - // - // Open the file and copy contents into a memory buffer. - // - // - // Open the file - // - InputFile = fopen (InputFileName, "rb"); - if (InputFile == NULL) { - printf ("ERROR: Could not open input file \"%s\".\n", InputFileName); - return EFI_ABORTED; - } - // - // Go to the end so that we can determine the file size - // - if (fseek (InputFile, 0, SEEK_END)) { - printf ("ERROR: System error reading input file \"%s\".\n", InputFileName); - fclose (InputFile); - return EFI_ABORTED; - } - // - // Get the file size - // - FileSize = ftell (InputFile); - if (FileSize == -1) { - printf ("ERROR: System error parsing input file \"%s\".\n", InputFileName); - fclose (InputFile); - return EFI_ABORTED; - } - // - // Allocate a buffer - // - *InputFileImage = malloc (FileSize); - if (*InputFileImage == NULL) { - fclose (InputFile); - return EFI_OUT_OF_RESOURCES; - } - // - // Reset to the beginning of the file - // - if (fseek (InputFile, 0, SEEK_SET)) { - printf ("ERROR: System error reading input file \"%s\".\n", InputFileName); - fclose (InputFile); - free (*InputFileImage); - *InputFileImage = NULL; - return EFI_ABORTED; - } - // - // Read all of the file contents. - // - *BytesRead = fread (*InputFileImage, sizeof (UINT8), FileSize, InputFile); - if (*BytesRead != sizeof (UINT8) * FileSize) { - printf ("ERROR: Reading file \"%s\"%i.\n", InputFileName); - fclose (InputFile); - free (*InputFileImage); - *InputFileImage = NULL; - return EFI_ABORTED; - } - // - // Close the file - // - fclose (InputFile); - - return EFI_SUCCESS; -} - -UINT8 -CalculateChecksum8 ( - IN UINT8 *Buffer, - IN UINTN Size - ) -/*++ - -Routine Description: - - This function calculates the value needed for a valid UINT8 checksum - -Arguments: - - Buffer Pointer to buffer containing byte data of component. - Size Size of the buffer - -Returns: - - The 8 bit checksum value needed. - ---*/ -{ - return (UINT8) (0x100 - CalculateSum8 (Buffer, Size)); -} - -UINT8 -CalculateSum8 ( - IN UINT8 *Buffer, - IN UINTN Size - ) -/*++ - -Routine Description:: - - This function calculates the UINT8 sum for the requested region. - -Arguments: - - Buffer Pointer to buffer containing byte data of component. - Size Size of the buffer - -Returns: - - The 8 bit checksum value needed. - ---*/ -{ - UINTN Index; - UINT8 Sum; - - Sum = 0; - - // - // Perform the byte sum for buffer - // - for (Index = 0; Index < Size; Index++) { - Sum = (UINT8) (Sum + Buffer[Index]); - } - - return Sum; -} - -UINT16 -CalculateChecksum16 ( - IN UINT16 *Buffer, - IN UINTN Size - ) -/*++ - -Routine Description:: - - This function calculates the value needed for a valid UINT16 checksum - -Arguments: - - Buffer Pointer to buffer containing byte data of component. - Size Size of the buffer - -Returns: - - The 16 bit checksum value needed. - ---*/ -{ - return (UINT16) (0x10000 - CalculateSum16 (Buffer, Size)); -} - -UINT16 -CalculateSum16 ( - IN UINT16 *Buffer, - IN UINTN Size - ) -/*++ - -Routine Description: - - This function calculates the UINT16 sum for the requested region. - -Arguments: - - Buffer Pointer to buffer containing byte data of component. - Size Size of the buffer - -Returns: - - The 16 bit checksum - ---*/ -{ - UINTN Index; - UINT16 Sum; - - Sum = 0; - - // - // Perform the word sum for buffer - // - for (Index = 0; Index < Size; Index++) { - Sum = (UINT16) (Sum + Buffer[Index]); - } - - return (UINT16) Sum; -} - -EFI_STATUS -PrintGuid ( - IN EFI_GUID *Guid - ) -/*++ - -Routine Description: - - This function prints a GUID to STDOUT. - -Arguments: - - Guid Pointer to a GUID to print. - -Returns: - - EFI_SUCCESS The GUID was printed. - EFI_INVALID_PARAMETER The input was NULL. - ---*/ -{ - if (Guid == NULL) { - printf ("ERROR: PrintGuid called with a NULL value.\n"); - return EFI_INVALID_PARAMETER; - } - - printf ( - "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", - Guid->Data1, - Guid->Data2, - Guid->Data3, - Guid->Data4[0], - Guid->Data4[1], - Guid->Data4[2], - Guid->Data4[3], - Guid->Data4[4], - Guid->Data4[5], - Guid->Data4[6], - Guid->Data4[7] - ); - return EFI_SUCCESS; -} - -EFI_STATUS -PrintGuidToBuffer ( - IN EFI_GUID *Guid, - IN OUT UINT8 *Buffer, - IN UINT32 BufferLen, - IN BOOLEAN Uppercase - ) -/*++ - -Routine Description: - - This function prints a GUID to a buffer - -Arguments: - - Guid - Pointer to a GUID to print. - Buffer - Pointer to a user-provided buffer to print to - BufferLen - Size of the Buffer - Uppercase - If use upper case. - -Returns: - - EFI_SUCCESS The GUID was printed. - EFI_INVALID_PARAMETER The input was NULL. - EFI_BUFFER_TOO_SMALL The input buffer was not big enough - ---*/ -{ - if (Guid == NULL) { - printf ("ERROR: PrintGuidToBuffer() called with a NULL value\n"); - return EFI_INVALID_PARAMETER; - } - - if (BufferLen < PRINTED_GUID_BUFFER_SIZE) { - printf ("ERORR: PrintGuidToBuffer() called with invalid buffer size\n"); - return EFI_BUFFER_TOO_SMALL; - } - - if (Uppercase) { - sprintf ( - Buffer, - "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", - Guid->Data1, - Guid->Data2, - Guid->Data3, - Guid->Data4[0], - Guid->Data4[1], - Guid->Data4[2], - Guid->Data4[3], - Guid->Data4[4], - Guid->Data4[5], - Guid->Data4[6], - Guid->Data4[7] - ); - } else { - sprintf ( - Buffer, - "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", - Guid->Data1, - Guid->Data2, - Guid->Data3, - Guid->Data4[0], - Guid->Data4[1], - Guid->Data4[2], - Guid->Data4[3], - Guid->Data4[4], - Guid->Data4[5], - Guid->Data4[6], - Guid->Data4[7] - ); - } - - return EFI_SUCCESS; -} - -#ifdef __GNUC__ -#ifndef __CYGWIN__ -char *strlwr(char *s) -{ - char *p = s; - for(;*s;s++) { - *s = tolower(*s); - } - return p; -} -#endif -#endif diff --git a/Tools/CodeTools/TianoTools/Common/CommonLib.h b/Tools/CodeTools/TianoTools/Common/CommonLib.h deleted file mode 100644 index 46f0cbace5..0000000000 --- a/Tools/CodeTools/TianoTools/Common/CommonLib.h +++ /dev/null @@ -1,135 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - CommonLib.h - -Abstract: - - Common library assistance routines. - ---*/ - -#ifndef _EFI_COMMON_LIB_H -#define _EFI_COMMON_LIB_H - -#include - -#ifndef _MAX_PATH -#define _MAX_PATH 500 -#endif - -#define PRINTED_GUID_BUFFER_SIZE 37 // including null-termination -// -// Function declarations -// -VOID -PeiZeroMem ( - IN VOID *Buffer, - IN UINTN Size - ) -; - -VOID -PeiCopyMem ( - IN VOID *Destination, - IN VOID *Source, - IN UINTN Length - ) -; - -VOID -ZeroMem ( - IN VOID *Buffer, - IN UINTN Size - ) -; - -VOID -CopyMem ( - IN VOID *Destination, - IN VOID *Source, - IN UINTN Length - ) -; - -INTN -CompareGuid ( - IN EFI_GUID *Guid1, - IN EFI_GUID *Guid2 - ) -; - -EFI_STATUS -GetFileImage ( - IN CHAR8 *InputFileName, - OUT CHAR8 **InputFileImage, - OUT UINT32 *BytesRead - ) -; - -UINT8 -CalculateChecksum8 ( - IN UINT8 *Buffer, - IN UINTN Size - ) -; - -UINT8 -CalculateSum8 ( - IN UINT8 *Buffer, - IN UINTN Size - ) -; - -UINT16 -CalculateChecksum16 ( - IN UINT16 *Buffer, - IN UINTN Size - ) -; - -UINT16 -CalculateSum16 ( - IN UINT16 *Buffer, - IN UINTN Size - ) -; - -EFI_STATUS -PrintGuid ( - IN EFI_GUID *Guid - ) -; - -#define PRINTED_GUID_BUFFER_SIZE 37 // including null-termination -EFI_STATUS -PrintGuidToBuffer ( - IN EFI_GUID *Guid, - IN OUT UINT8 *Buffer, - IN UINT32 BufferLen, - IN BOOLEAN Uppercase - ) -; - -#define ASSERT(x) assert(x) - -#ifdef __GNUC__ -#define stricmp strcasecmp -#define strnicmp strncasecmp -#define strcmpi strcasecmp -#ifndef __CYGWIN__ -char *strlwr(char *s); -#endif -#endif - -#endif diff --git a/Tools/CodeTools/TianoTools/Common/Crc32.c b/Tools/CodeTools/TianoTools/Common/Crc32.c deleted file mode 100644 index 4ae5eb486b..0000000000 --- a/Tools/CodeTools/TianoTools/Common/Crc32.c +++ /dev/null @@ -1,326 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - crc32.c - -Abstract: - - CalcuateCrc32 routine. - ---*/ - -#include -#include "Crc32.h" - -UINT32 mCrcTable[256] = { - 0x00000000, - 0x77073096, - 0xEE0E612C, - 0x990951BA, - 0x076DC419, - 0x706AF48F, - 0xE963A535, - 0x9E6495A3, - 0x0EDB8832, - 0x79DCB8A4, - 0xE0D5E91E, - 0x97D2D988, - 0x09B64C2B, - 0x7EB17CBD, - 0xE7B82D07, - 0x90BF1D91, - 0x1DB71064, - 0x6AB020F2, - 0xF3B97148, - 0x84BE41DE, - 0x1ADAD47D, - 0x6DDDE4EB, - 0xF4D4B551, - 0x83D385C7, - 0x136C9856, - 0x646BA8C0, - 0xFD62F97A, - 0x8A65C9EC, - 0x14015C4F, - 0x63066CD9, - 0xFA0F3D63, - 0x8D080DF5, - 0x3B6E20C8, - 0x4C69105E, - 0xD56041E4, - 0xA2677172, - 0x3C03E4D1, - 0x4B04D447, - 0xD20D85FD, - 0xA50AB56B, - 0x35B5A8FA, - 0x42B2986C, - 0xDBBBC9D6, - 0xACBCF940, - 0x32D86CE3, - 0x45DF5C75, - 0xDCD60DCF, - 0xABD13D59, - 0x26D930AC, - 0x51DE003A, - 0xC8D75180, - 0xBFD06116, - 0x21B4F4B5, - 0x56B3C423, - 0xCFBA9599, - 0xB8BDA50F, - 0x2802B89E, - 0x5F058808, - 0xC60CD9B2, - 0xB10BE924, - 0x2F6F7C87, - 0x58684C11, - 0xC1611DAB, - 0xB6662D3D, - 0x76DC4190, - 0x01DB7106, - 0x98D220BC, - 0xEFD5102A, - 0x71B18589, - 0x06B6B51F, - 0x9FBFE4A5, - 0xE8B8D433, - 0x7807C9A2, - 0x0F00F934, - 0x9609A88E, - 0xE10E9818, - 0x7F6A0DBB, - 0x086D3D2D, - 0x91646C97, - 0xE6635C01, - 0x6B6B51F4, - 0x1C6C6162, - 0x856530D8, - 0xF262004E, - 0x6C0695ED, - 0x1B01A57B, - 0x8208F4C1, - 0xF50FC457, - 0x65B0D9C6, - 0x12B7E950, - 0x8BBEB8EA, - 0xFCB9887C, - 0x62DD1DDF, - 0x15DA2D49, - 0x8CD37CF3, - 0xFBD44C65, - 0x4DB26158, - 0x3AB551CE, - 0xA3BC0074, - 0xD4BB30E2, - 0x4ADFA541, - 0x3DD895D7, - 0xA4D1C46D, - 0xD3D6F4FB, - 0x4369E96A, - 0x346ED9FC, - 0xAD678846, - 0xDA60B8D0, - 0x44042D73, - 0x33031DE5, - 0xAA0A4C5F, - 0xDD0D7CC9, - 0x5005713C, - 0x270241AA, - 0xBE0B1010, - 0xC90C2086, - 0x5768B525, - 0x206F85B3, - 0xB966D409, - 0xCE61E49F, - 0x5EDEF90E, - 0x29D9C998, - 0xB0D09822, - 0xC7D7A8B4, - 0x59B33D17, - 0x2EB40D81, - 0xB7BD5C3B, - 0xC0BA6CAD, - 0xEDB88320, - 0x9ABFB3B6, - 0x03B6E20C, - 0x74B1D29A, - 0xEAD54739, - 0x9DD277AF, - 0x04DB2615, - 0x73DC1683, - 0xE3630B12, - 0x94643B84, - 0x0D6D6A3E, - 0x7A6A5AA8, - 0xE40ECF0B, - 0x9309FF9D, - 0x0A00AE27, - 0x7D079EB1, - 0xF00F9344, - 0x8708A3D2, - 0x1E01F268, - 0x6906C2FE, - 0xF762575D, - 0x806567CB, - 0x196C3671, - 0x6E6B06E7, - 0xFED41B76, - 0x89D32BE0, - 0x10DA7A5A, - 0x67DD4ACC, - 0xF9B9DF6F, - 0x8EBEEFF9, - 0x17B7BE43, - 0x60B08ED5, - 0xD6D6A3E8, - 0xA1D1937E, - 0x38D8C2C4, - 0x4FDFF252, - 0xD1BB67F1, - 0xA6BC5767, - 0x3FB506DD, - 0x48B2364B, - 0xD80D2BDA, - 0xAF0A1B4C, - 0x36034AF6, - 0x41047A60, - 0xDF60EFC3, - 0xA867DF55, - 0x316E8EEF, - 0x4669BE79, - 0xCB61B38C, - 0xBC66831A, - 0x256FD2A0, - 0x5268E236, - 0xCC0C7795, - 0xBB0B4703, - 0x220216B9, - 0x5505262F, - 0xC5BA3BBE, - 0xB2BD0B28, - 0x2BB45A92, - 0x5CB36A04, - 0xC2D7FFA7, - 0xB5D0CF31, - 0x2CD99E8B, - 0x5BDEAE1D, - 0x9B64C2B0, - 0xEC63F226, - 0x756AA39C, - 0x026D930A, - 0x9C0906A9, - 0xEB0E363F, - 0x72076785, - 0x05005713, - 0x95BF4A82, - 0xE2B87A14, - 0x7BB12BAE, - 0x0CB61B38, - 0x92D28E9B, - 0xE5D5BE0D, - 0x7CDCEFB7, - 0x0BDBDF21, - 0x86D3D2D4, - 0xF1D4E242, - 0x68DDB3F8, - 0x1FDA836E, - 0x81BE16CD, - 0xF6B9265B, - 0x6FB077E1, - 0x18B74777, - 0x88085AE6, - 0xFF0F6A70, - 0x66063BCA, - 0x11010B5C, - 0x8F659EFF, - 0xF862AE69, - 0x616BFFD3, - 0x166CCF45, - 0xA00AE278, - 0xD70DD2EE, - 0x4E048354, - 0x3903B3C2, - 0xA7672661, - 0xD06016F7, - 0x4969474D, - 0x3E6E77DB, - 0xAED16A4A, - 0xD9D65ADC, - 0x40DF0B66, - 0x37D83BF0, - 0xA9BCAE53, - 0xDEBB9EC5, - 0x47B2CF7F, - 0x30B5FFE9, - 0xBDBDF21C, - 0xCABAC28A, - 0x53B39330, - 0x24B4A3A6, - 0xBAD03605, - 0xCDD70693, - 0x54DE5729, - 0x23D967BF, - 0xB3667A2E, - 0xC4614AB8, - 0x5D681B02, - 0x2A6F2B94, - 0xB40BBE37, - 0xC30C8EA1, - 0x5A05DF1B, - 0x2D02EF8D -}; - -EFI_STATUS -CalculateCrc32 ( - IN UINT8 *Data, - IN UINTN DataSize, - IN OUT UINT32 *CrcOut - ) -/*++ - -Routine Description: - - The CalculateCrc32 routine. - -Arguments: - - Data - The buffer contaning the data to be processed - DataSize - The size of data to be processed - CrcOut - A pointer to the caller allocated UINT32 that on - contains the CRC32 checksum of Data - -Returns: - - EFI_SUCCESS - Calculation is successful. - EFI_INVALID_PARAMETER - Data / CrcOut = NULL, or DataSize = 0 - ---*/ -{ - UINT32 Crc; - UINTN Index; - UINT8 *Ptr; - - if ((DataSize == 0) || (Data == NULL) || (CrcOut == NULL)) { - return EFI_INVALID_PARAMETER; - } - - Crc = 0xffffffff; - for (Index = 0, Ptr = Data; Index < DataSize; Index++, Ptr++) { - Crc = (Crc >> 8) ^ mCrcTable[(UINT8) Crc ^ *Ptr]; - } - - *CrcOut = Crc ^ 0xffffffff; - - return EFI_SUCCESS; -} diff --git a/Tools/CodeTools/TianoTools/Common/Crc32.h b/Tools/CodeTools/TianoTools/Common/Crc32.h deleted file mode 100644 index ec48cdd478..0000000000 --- a/Tools/CodeTools/TianoTools/Common/Crc32.h +++ /dev/null @@ -1,54 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - Crc32.h - -Abstract: - - Header file for CalcuateCrc32 routine - ---*/ - -#ifndef _CRC32_H -#define _CRC32_H - -#include - -EFI_STATUS -CalculateCrc32 ( - IN UINT8 *Data, - IN UINTN DataSize, - IN OUT UINT32 *CrcOut - ) -/*++ - -Routine Description: - - The CalculateCrc32 routine. - -Arguments: - - Data - The buffer contaning the data to be processed - DataSize - The size of data to be processed - CrcOut - A pointer to the caller allocated UINT32 that on - contains the CRC32 checksum of Data - -Returns: - - EFI_SUCCESS - Calculation is successful. - EFI_INVALID_PARAMETER - Data / CrcOut = NULL, or DataSize = 0 - ---*/ -; - -#endif diff --git a/Tools/CodeTools/TianoTools/Common/EfiCompress.c b/Tools/CodeTools/TianoTools/Common/EfiCompress.c deleted file mode 100644 index 5b91b1d216..0000000000 --- a/Tools/CodeTools/TianoTools/Common/EfiCompress.c +++ /dev/null @@ -1,1742 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - EfiCompress.c - -Abstract: - - Compression routine. The compression algorithm is a mixture of - LZ77 and Huffman coding. LZ77 transforms the source data into a - sequence of Original Characters and Pointers to repeated strings. - This sequence is further divided into Blocks and Huffman codings - are applied to each Block. - ---*/ - -#include "EfiCompress.h" - -// -// Macro Definitions -// -typedef INT32 NODE; -#define UINT8_BIT 8 -#define THRESHOLD 3 -#define INIT_CRC 0 -#define WNDBIT 19 -#define WNDSIZ (1U << WNDBIT) -#define MAXMATCH 256 -#define BLKSIZ (1U << 14) // 16 * 1024U -#define PERC_FLAG 0x80000000U -#define CODE_BIT 16 -#define NIL 0 -#define MAX_HASH_VAL (3 * WNDSIZ + (WNDSIZ / 512 + 1) * UINT8_MAX) -#define HASH(p, c) ((p) + ((c) << (WNDBIT - 9)) + WNDSIZ * 2) -#define CRCPOLY 0xA001 -#define UPDATE_CRC(c) mCrc = mCrcTable[(mCrc ^ (c)) & 0xFF] ^ (mCrc >> UINT8_BIT) - -// -// C: the Char&Len Set; P: the Position Set; T: the exTra Set -// -#define NC (UINT8_MAX + MAXMATCH + 2 - THRESHOLD) -#define CBIT 9 -#define NP (WNDBIT + 1) -#define PBIT 5 -#define NT (CODE_BIT + 3) -#define TBIT 5 -#if NT > NP -#define NPT NT -#else -#define NPT NP -#endif -// -// Function Prototypes -// -STATIC VOID PutDword(IN UINT32 Data); - -STATIC -EFI_STATUS -AllocateMemory ( - VOID - ); - -STATIC -VOID -FreeMemory ( - VOID - ); - -STATIC -VOID -InitSlide ( - VOID - ); - -STATIC -NODE -Child ( - IN NODE NodeQ, - IN UINT8 CharC - ); - -STATIC -VOID -MakeChild ( - IN NODE NodeQ, - IN UINT8 CharC, - IN NODE NodeR - ); - -STATIC -VOID -Split ( - IN NODE Old - ); - -STATIC -VOID -InsertNode ( - VOID - ); - -STATIC -VOID -DeleteNode ( - VOID - ); - -STATIC -VOID -GetNextMatch ( - VOID - ); - -STATIC -EFI_STATUS -Encode ( - VOID - ); - -STATIC -VOID -CountTFreq ( - VOID - ); - -STATIC -VOID -WritePTLen ( - IN INT32 Number, - IN INT32 nbit, - IN INT32 Special - ); - -STATIC -VOID -WriteCLen ( - VOID - ); - -STATIC -VOID -EncodeC ( - IN INT32 Value - ); - -STATIC -VOID -EncodeP ( - IN UINT32 Value - ); - -STATIC -VOID -SendBlock ( - VOID - ); - -STATIC -VOID -Output ( - IN UINT32 c, - IN UINT32 p - ); - -STATIC -VOID -HufEncodeStart ( - VOID - ); - -STATIC -VOID -HufEncodeEnd ( - VOID - ); - -STATIC -VOID -MakeCrcTable ( - VOID - ); - -STATIC -VOID -PutBits ( - IN INT32 Number, - IN UINT32 Value - ); - -STATIC -INT32 -FreadCrc ( - OUT UINT8 *Pointer, - IN INT32 Number - ); - -STATIC -VOID -InitPutBits ( - VOID - ); - -STATIC -VOID -CountLen ( - IN INT32 Index - ); - -STATIC -VOID -MakeLen ( - IN INT32 Root - ); - -STATIC -VOID -DownHeap ( - IN INT32 Index - ); - -STATIC -VOID -MakeCode ( - IN INT32 Number, - IN UINT8 Len[ ], - OUT UINT16 Code[] - ); - -STATIC -INT32 -MakeTree ( - IN INT32 NParm, - IN UINT16 FreqParm[], - OUT UINT8 LenParm[ ], - OUT UINT16 CodeParm[] - ); - -// -// Global Variables -// -static UINT8 *mSrc, *mDst, *mSrcUpperLimit, *mDstUpperLimit; - -static UINT8 *mLevel, *mText, *mChildCount, *mBuf, mCLen[NC], mPTLen[NPT], *mLen; -static INT16 mHeap[NC + 1]; -static INT32 mRemainder, mMatchLen, mBitCount, mHeapSize, mN; -static UINT32 mBufSiz = 0, mOutputPos, mOutputMask, mSubBitBuf, mCrc; -static UINT32 mCompSize, mOrigSize; - -static UINT16 *mFreq, *mSortPtr, mLenCnt[17], mLeft[2 * NC - 1], mRight[2 * NC - 1], mCrcTable[UINT8_MAX + 1], - mCFreq[2 * NC - 1], mCTable[4096], mCCode[NC], mPFreq[2 * NP - 1], mPTCode[NPT], mTFreq[2 * NT - 1]; - -static NODE mPos, mMatchPos, mAvail, *mPosition, *mParent, *mPrev, *mNext = NULL; - -// -// functions -// -EFI_STATUS -Compress ( - IN UINT8 *SrcBuffer, - IN UINT32 SrcSize, - IN UINT8 *DstBuffer, - IN OUT UINT32 *DstSize - ) -/*++ - -Routine Description: - - The main compression routine. - -Arguments: - - SrcBuffer - The buffer storing the source data - SrcSize - The size of source data - DstBuffer - The buffer to store the compressed data - DstSize - On input, the size of DstBuffer; On output, - the size of the actual compressed data. - -Returns: - - EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. In this case, - DstSize contains the size needed. - EFI_SUCCESS - Compression is successful. - EFI_OUT_OF_RESOURCES - No resource to complete function. - ---*/ -{ - EFI_STATUS Status; - - // - // Initializations - // - mBufSiz = 0; - mBuf = NULL; - mText = NULL; - mLevel = NULL; - mChildCount = NULL; - mPosition = NULL; - mParent = NULL; - mPrev = NULL; - mNext = NULL; - - mSrc = SrcBuffer; - mSrcUpperLimit = mSrc + SrcSize; - mDst = DstBuffer; - mDstUpperLimit = mDst +*DstSize; - - PutDword (0L); - PutDword (0L); - - MakeCrcTable (); - - mOrigSize = mCompSize = 0; - mCrc = INIT_CRC; - - // - // Compress it - // - Status = Encode (); - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - // - // Null terminate the compressed data - // - if (mDst < mDstUpperLimit) { - *mDst++ = 0; - } - // - // Fill in compressed size and original size - // - mDst = DstBuffer; - PutDword (mCompSize + 1); - PutDword (mOrigSize); - - // - // Return - // - if (mCompSize + 1 + 8 > *DstSize) { - *DstSize = mCompSize + 1 + 8; - return EFI_BUFFER_TOO_SMALL; - } else { - *DstSize = mCompSize + 1 + 8; - return EFI_SUCCESS; - } - -} - -STATIC -VOID -PutDword ( - IN UINT32 Data - ) -/*++ - -Routine Description: - - Put a dword to output stream - -Arguments: - - Data - the dword to put - -Returns: (VOID) - ---*/ -{ - if (mDst < mDstUpperLimit) { - *mDst++ = (UINT8) (((UINT8) (Data)) & 0xff); - } - - if (mDst < mDstUpperLimit) { - *mDst++ = (UINT8) (((UINT8) (Data >> 0x08)) & 0xff); - } - - if (mDst < mDstUpperLimit) { - *mDst++ = (UINT8) (((UINT8) (Data >> 0x10)) & 0xff); - } - - if (mDst < mDstUpperLimit) { - *mDst++ = (UINT8) (((UINT8) (Data >> 0x18)) & 0xff); - } -} - -STATIC -EFI_STATUS -AllocateMemory ( - VOID - ) -/*++ - -Routine Description: - - Allocate memory spaces for data structures used in compression process - -Argements: - VOID - -Returns: - - EFI_SUCCESS - Memory is allocated successfully - EFI_OUT_OF_RESOURCES - Allocation fails - ---*/ -{ - UINT32 Index; - - mText = malloc (WNDSIZ * 2 + MAXMATCH); - for (Index = 0; Index < WNDSIZ * 2 + MAXMATCH; Index++) { - mText[Index] = 0; - } - - mLevel = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mLevel)); - mChildCount = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mChildCount)); - mPosition = malloc ((WNDSIZ + UINT8_MAX + 1) * sizeof (*mPosition)); - mParent = malloc (WNDSIZ * 2 * sizeof (*mParent)); - mPrev = malloc (WNDSIZ * 2 * sizeof (*mPrev)); - mNext = malloc ((MAX_HASH_VAL + 1) * sizeof (*mNext)); - - mBufSiz = BLKSIZ; - mBuf = malloc (mBufSiz); - while (mBuf == NULL) { - mBufSiz = (mBufSiz / 10U) * 9U; - if (mBufSiz < 4 * 1024U) { - return EFI_OUT_OF_RESOURCES; - } - - mBuf = malloc (mBufSiz); - } - - mBuf[0] = 0; - - return EFI_SUCCESS; -} - -VOID -FreeMemory ( - VOID - ) -/*++ - -Routine Description: - - Called when compression is completed to free memory previously allocated. - -Arguments: (VOID) - -Returns: (VOID) - ---*/ -{ - if (mText != NULL) { - free (mText); - } - - if (mLevel != NULL) { - free (mLevel); - } - - if (mChildCount != NULL) { - free (mChildCount); - } - - if (mPosition != NULL) { - free (mPosition); - } - - if (mParent != NULL) { - free (mParent); - } - - if (mPrev != NULL) { - free (mPrev); - } - - if (mNext != NULL) { - free (mNext); - } - - if (mBuf != NULL) { - free (mBuf); - } - - return ; -} - -STATIC -VOID -InitSlide ( - VOID - ) -/*++ - -Routine Description: - - Initialize String Info Log data structures - -Arguments: (VOID) - -Returns: (VOID) - ---*/ -{ - NODE Index; - - for (Index = WNDSIZ; Index <= WNDSIZ + UINT8_MAX; Index++) { - mLevel[Index] = 1; - mPosition[Index] = NIL; /* sentinel */ - } - - for (Index = WNDSIZ; Index < WNDSIZ * 2; Index++) { - mParent[Index] = NIL; - } - - mAvail = 1; - for (Index = 1; Index < WNDSIZ - 1; Index++) { - mNext[Index] = (NODE) (Index + 1); - } - - mNext[WNDSIZ - 1] = NIL; - for (Index = WNDSIZ * 2; Index <= MAX_HASH_VAL; Index++) { - mNext[Index] = NIL; - } -} - -STATIC -NODE -Child ( - IN NODE NodeQ, - IN UINT8 CharC - ) -/*++ - -Routine Description: - - Find child node given the parent node and the edge character - -Arguments: - - NodeQ - the parent node - CharC - the edge character - -Returns: - - The child node (NIL if not found) - ---*/ -{ - NODE NodeR; - - NodeR = mNext[HASH (NodeQ, CharC)]; - // - // sentinel - // - mParent[NIL] = NodeQ; - while (mParent[NodeR] != NodeQ) { - NodeR = mNext[NodeR]; - } - - return NodeR; -} - -STATIC -VOID -MakeChild ( - IN NODE Parent, - IN UINT8 CharC, - IN NODE Child - ) -/*++ - -Routine Description: - - Create a new child for a given parent node. - -Arguments: - - Parent - the parent node - CharC - the edge character - Child - the child node - -Returns: (VOID) - ---*/ -{ - NODE Node1; - NODE Node2; - - Node1 = (NODE) HASH (Parent, CharC); - Node2 = mNext[Node1]; - mNext[Node1] = Child; - mNext[Child] = Node2; - mPrev[Node2] = Child; - mPrev[Child] = Node1; - mParent[Child] = Parent; - mChildCount[Parent]++; -} - -STATIC -VOID -Split ( - NODE Old - ) -/*++ - -Routine Description: - - Split a node. - -Arguments: - - Old - the node to split - -Returns: (VOID) - ---*/ -{ - NODE New; - NODE TempNode; - - New = mAvail; - mAvail = mNext[New]; - mChildCount[New] = 0; - TempNode = mPrev[Old]; - mPrev[New] = TempNode; - mNext[TempNode] = New; - TempNode = mNext[Old]; - mNext[New] = TempNode; - mPrev[TempNode] = New; - mParent[New] = mParent[Old]; - mLevel[New] = (UINT8) mMatchLen; - mPosition[New] = mPos; - MakeChild (New, mText[mMatchPos + mMatchLen], Old); - MakeChild (New, mText[mPos + mMatchLen], mPos); -} - -STATIC -VOID -InsertNode ( - VOID - ) -/*++ - -Routine Description: - - Insert string info for current position into the String Info Log - -Arguments: (VOID) - -Returns: (VOID) - ---*/ -{ - NODE NodeQ; - NODE NodeR; - NODE Index2; - NODE NodeT; - UINT8 CharC; - UINT8 *t1; - UINT8 *t2; - - if (mMatchLen >= 4) { - // - // We have just got a long match, the target tree - // can be located by MatchPos + 1. Travese the tree - // from bottom up to get to a proper starting point. - // The usage of PERC_FLAG ensures proper node deletion - // in DeleteNode() later. - // - mMatchLen--; - NodeR = (NODE) ((mMatchPos + 1) | WNDSIZ); - NodeQ = mParent[NodeR]; - while (NodeQ == NIL) { - NodeR = mNext[NodeR]; - NodeQ = mParent[NodeR]; - } - - while (mLevel[NodeQ] >= mMatchLen) { - NodeR = NodeQ; - NodeQ = mParent[NodeQ]; - } - - NodeT = NodeQ; - while (mPosition[NodeT] < 0) { - mPosition[NodeT] = mPos; - NodeT = mParent[NodeT]; - } - - if (NodeT < WNDSIZ) { - mPosition[NodeT] = (NODE) (mPos | (UINT32) PERC_FLAG); - } - } else { - // - // Locate the target tree - // - NodeQ = (NODE) (mText[mPos] + WNDSIZ); - CharC = mText[mPos + 1]; - NodeR = Child (NodeQ, CharC); - if (NodeR == NIL) { - MakeChild (NodeQ, CharC, mPos); - mMatchLen = 1; - return ; - } - - mMatchLen = 2; - } - // - // Traverse down the tree to find a match. - // Update Position value along the route. - // Node split or creation is involved. - // - for (;;) { - if (NodeR >= WNDSIZ) { - Index2 = MAXMATCH; - mMatchPos = NodeR; - } else { - Index2 = mLevel[NodeR]; - mMatchPos = (NODE) (mPosition[NodeR] & (UINT32)~PERC_FLAG); - } - - if (mMatchPos >= mPos) { - mMatchPos -= WNDSIZ; - } - - t1 = &mText[mPos + mMatchLen]; - t2 = &mText[mMatchPos + mMatchLen]; - while (mMatchLen < Index2) { - if (*t1 != *t2) { - Split (NodeR); - return ; - } - - mMatchLen++; - t1++; - t2++; - } - - if (mMatchLen >= MAXMATCH) { - break; - } - - mPosition[NodeR] = mPos; - NodeQ = NodeR; - NodeR = Child (NodeQ, *t1); - if (NodeR == NIL) { - MakeChild (NodeQ, *t1, mPos); - return ; - } - - mMatchLen++; - } - - NodeT = mPrev[NodeR]; - mPrev[mPos] = NodeT; - mNext[NodeT] = mPos; - NodeT = mNext[NodeR]; - mNext[mPos] = NodeT; - mPrev[NodeT] = mPos; - mParent[mPos] = NodeQ; - mParent[NodeR] = NIL; - - // - // Special usage of 'next' - // - mNext[NodeR] = mPos; - -} - -STATIC -VOID -DeleteNode ( - VOID - ) -/*++ - -Routine Description: - - Delete outdated string info. (The Usage of PERC_FLAG - ensures a clean deletion) - -Arguments: (VOID) - -Returns: (VOID) - ---*/ -{ - NODE NodeQ; - NODE NodeR; - NODE NodeS; - NODE NodeT; - NODE NodeU; - - if (mParent[mPos] == NIL) { - return ; - } - - NodeR = mPrev[mPos]; - NodeS = mNext[mPos]; - mNext[NodeR] = NodeS; - mPrev[NodeS] = NodeR; - NodeR = mParent[mPos]; - mParent[mPos] = NIL; - if (NodeR >= WNDSIZ) { - return ; - } - - mChildCount[NodeR]--; - if (mChildCount[NodeR] > 1) { - return ; - } - - NodeT = (NODE) (mPosition[NodeR] & (UINT32)~PERC_FLAG); - if (NodeT >= mPos) { - NodeT -= WNDSIZ; - } - - NodeS = NodeT; - NodeQ = mParent[NodeR]; - NodeU = mPosition[NodeQ]; - while (NodeU & (UINT32) PERC_FLAG) { - NodeU &= (UINT32)~PERC_FLAG; - if (NodeU >= mPos) { - NodeU -= WNDSIZ; - } - - if (NodeU > NodeS) { - NodeS = NodeU; - } - - mPosition[NodeQ] = (NODE) (NodeS | WNDSIZ); - NodeQ = mParent[NodeQ]; - NodeU = mPosition[NodeQ]; - } - - if (NodeQ < WNDSIZ) { - if (NodeU >= mPos) { - NodeU -= WNDSIZ; - } - - if (NodeU > NodeS) { - NodeS = NodeU; - } - - mPosition[NodeQ] = (NODE) (NodeS | WNDSIZ | (UINT32) PERC_FLAG); - } - - NodeS = Child (NodeR, mText[NodeT + mLevel[NodeR]]); - NodeT = mPrev[NodeS]; - NodeU = mNext[NodeS]; - mNext[NodeT] = NodeU; - mPrev[NodeU] = NodeT; - NodeT = mPrev[NodeR]; - mNext[NodeT] = NodeS; - mPrev[NodeS] = NodeT; - NodeT = mNext[NodeR]; - mPrev[NodeT] = NodeS; - mNext[NodeS] = NodeT; - mParent[NodeS] = mParent[NodeR]; - mParent[NodeR] = NIL; - mNext[NodeR] = mAvail; - mAvail = NodeR; -} - -STATIC -VOID -GetNextMatch ( - VOID - ) -/*++ - -Routine Description: - - Advance the current position (read in new data if needed). - Delete outdated string info. Find a match string for current position. - -Arguments: (VOID) - -Returns: (VOID) - ---*/ -{ - INT32 Number; - - mRemainder--; - mPos++; - if (mPos == WNDSIZ * 2) { - memmove (&mText[0], &mText[WNDSIZ], WNDSIZ + MAXMATCH); - Number = FreadCrc (&mText[WNDSIZ + MAXMATCH], WNDSIZ); - mRemainder += Number; - mPos = WNDSIZ; - } - - DeleteNode (); - InsertNode (); -} - -STATIC -EFI_STATUS -Encode ( - VOID - ) -/*++ - -Routine Description: - - The main controlling routine for compression process. - -Arguments: (VOID) - -Returns: - - EFI_SUCCESS - The compression is successful - EFI_OUT_0F_RESOURCES - Not enough memory for compression process - ---*/ -{ - EFI_STATUS Status; - INT32 LastMatchLen; - NODE LastMatchPos; - - Status = AllocateMemory (); - if (EFI_ERROR (Status)) { - FreeMemory (); - return Status; - } - - InitSlide (); - - HufEncodeStart (); - - mRemainder = FreadCrc (&mText[WNDSIZ], WNDSIZ + MAXMATCH); - - mMatchLen = 0; - mPos = WNDSIZ; - InsertNode (); - if (mMatchLen > mRemainder) { - mMatchLen = mRemainder; - } - - while (mRemainder > 0) { - LastMatchLen = mMatchLen; - LastMatchPos = mMatchPos; - GetNextMatch (); - if (mMatchLen > mRemainder) { - mMatchLen = mRemainder; - } - - if (mMatchLen > LastMatchLen || LastMatchLen < THRESHOLD) { - // - // Not enough benefits are gained by outputting a pointer, - // so just output the original character - // - Output (mText[mPos - 1], 0); - - } else { - - if (LastMatchLen == THRESHOLD) { - if (((mPos - LastMatchPos - 2) & (WNDSIZ - 1)) > (1U << 11)) { - Output (mText[mPos - 1], 0); - continue; - } - } - // - // Outputting a pointer is beneficial enough, do it. - // - Output ( - LastMatchLen + (UINT8_MAX + 1 - THRESHOLD), - (mPos - LastMatchPos - 2) & (WNDSIZ - 1) - ); - LastMatchLen--; - while (LastMatchLen > 0) { - GetNextMatch (); - LastMatchLen--; - } - - if (mMatchLen > mRemainder) { - mMatchLen = mRemainder; - } - } - } - - HufEncodeEnd (); - FreeMemory (); - return EFI_SUCCESS; -} - -STATIC -VOID -CountTFreq ( - VOID - ) -/*++ - -Routine Description: - - Count the frequencies for the Extra Set - -Arguments: (VOID) - -Returns: (VOID) - ---*/ -{ - INT32 Index; - INT32 Index3; - INT32 Number; - INT32 Count; - - for (Index = 0; Index < NT; Index++) { - mTFreq[Index] = 0; - } - - Number = NC; - while (Number > 0 && mCLen[Number - 1] == 0) { - Number--; - } - - Index = 0; - while (Index < Number) { - Index3 = mCLen[Index++]; - if (Index3 == 0) { - Count = 1; - while (Index < Number && mCLen[Index] == 0) { - Index++; - Count++; - } - - if (Count <= 2) { - mTFreq[0] = (UINT16) (mTFreq[0] + Count); - } else if (Count <= 18) { - mTFreq[1]++; - } else if (Count == 19) { - mTFreq[0]++; - mTFreq[1]++; - } else { - mTFreq[2]++; - } - } else { - mTFreq[Index3 + 2]++; - } - } -} - -STATIC -VOID -WritePTLen ( - IN INT32 Number, - IN INT32 nbit, - IN INT32 Special - ) -/*++ - -Routine Description: - - Outputs the code length array for the Extra Set or the Position Set. - -Arguments: - - Number - the number of symbols - nbit - the number of bits needed to represent 'n' - Special - the special symbol that needs to be take care of - -Returns: (VOID) - ---*/ -{ - INT32 Index; - INT32 Index3; - - while (Number > 0 && mPTLen[Number - 1] == 0) { - Number--; - } - - PutBits (nbit, Number); - Index = 0; - while (Index < Number) { - Index3 = mPTLen[Index++]; - if (Index3 <= 6) { - PutBits (3, Index3); - } else { - PutBits (Index3 - 3, (1U << (Index3 - 3)) - 2); - } - - if (Index == Special) { - while (Index < 6 && mPTLen[Index] == 0) { - Index++; - } - - PutBits (2, (Index - 3) & 3); - } - } -} - -STATIC -VOID -WriteCLen ( - VOID - ) -/*++ - -Routine Description: - - Outputs the code length array for Char&Length Set - -Arguments: (VOID) - -Returns: (VOID) - ---*/ -{ - INT32 Index; - INT32 Index3; - INT32 Number; - INT32 Count; - - Number = NC; - while (Number > 0 && mCLen[Number - 1] == 0) { - Number--; - } - - PutBits (CBIT, Number); - Index = 0; - while (Index < Number) { - Index3 = mCLen[Index++]; - if (Index3 == 0) { - Count = 1; - while (Index < Number && mCLen[Index] == 0) { - Index++; - Count++; - } - - if (Count <= 2) { - for (Index3 = 0; Index3 < Count; Index3++) { - PutBits (mPTLen[0], mPTCode[0]); - } - } else if (Count <= 18) { - PutBits (mPTLen[1], mPTCode[1]); - PutBits (4, Count - 3); - } else if (Count == 19) { - PutBits (mPTLen[0], mPTCode[0]); - PutBits (mPTLen[1], mPTCode[1]); - PutBits (4, 15); - } else { - PutBits (mPTLen[2], mPTCode[2]); - PutBits (CBIT, Count - 20); - } - } else { - PutBits (mPTLen[Index3 + 2], mPTCode[Index3 + 2]); - } - } -} - -STATIC -VOID -EncodeC ( - IN INT32 Value - ) -{ - PutBits (mCLen[Value], mCCode[Value]); -} - -STATIC -VOID -EncodeP ( - IN UINT32 Value - ) -{ - UINT32 Index; - UINT32 NodeQ; - - Index = 0; - NodeQ = Value; - while (NodeQ) { - NodeQ >>= 1; - Index++; - } - - PutBits (mPTLen[Index], mPTCode[Index]); - if (Index > 1) { - PutBits (Index - 1, Value & (0xFFFFFFFFU >> (32 - Index + 1))); - } -} - -STATIC -VOID -SendBlock ( - VOID - ) -/*++ - -Routine Description: - - Huffman code the block and output it. - -Arguments: - (VOID) - -Returns: - (VOID) - ---*/ -{ - UINT32 Index; - UINT32 Index2; - UINT32 Index3; - UINT32 Flags; - UINT32 Root; - UINT32 Pos; - UINT32 Size; - Flags = 0; - - Root = MakeTree (NC, mCFreq, mCLen, mCCode); - Size = mCFreq[Root]; - PutBits (16, Size); - if (Root >= NC) { - CountTFreq (); - Root = MakeTree (NT, mTFreq, mPTLen, mPTCode); - if (Root >= NT) { - WritePTLen (NT, TBIT, 3); - } else { - PutBits (TBIT, 0); - PutBits (TBIT, Root); - } - - WriteCLen (); - } else { - PutBits (TBIT, 0); - PutBits (TBIT, 0); - PutBits (CBIT, 0); - PutBits (CBIT, Root); - } - - Root = MakeTree (NP, mPFreq, mPTLen, mPTCode); - if (Root >= NP) { - WritePTLen (NP, PBIT, -1); - } else { - PutBits (PBIT, 0); - PutBits (PBIT, Root); - } - - Pos = 0; - for (Index = 0; Index < Size; Index++) { - if (Index % UINT8_BIT == 0) { - Flags = mBuf[Pos++]; - } else { - Flags <<= 1; - } - - if (Flags & (1U << (UINT8_BIT - 1))) { - EncodeC (mBuf[Pos++] + (1U << UINT8_BIT)); - Index3 = mBuf[Pos++]; - for (Index2 = 0; Index2 < 3; Index2++) { - Index3 <<= UINT8_BIT; - Index3 += mBuf[Pos++]; - } - - EncodeP (Index3); - } else { - EncodeC (mBuf[Pos++]); - } - } - - for (Index = 0; Index < NC; Index++) { - mCFreq[Index] = 0; - } - - for (Index = 0; Index < NP; Index++) { - mPFreq[Index] = 0; - } -} - -STATIC -VOID -Output ( - IN UINT32 CharC, - IN UINT32 Pos - ) -/*++ - -Routine Description: - - Outputs an Original Character or a Pointer - -Arguments: - - CharC - The original character or the 'String Length' element of a Pointer - Pos - The 'Position' field of a Pointer - -Returns: (VOID) - ---*/ -{ - static UINT32 CPos; - - if ((mOutputMask >>= 1) == 0) { - mOutputMask = 1U << (UINT8_BIT - 1); - // - // Check the buffer overflow per outputing UINT8_BIT symbols - // which is an Original Character or a Pointer. The biggest - // symbol is a Pointer which occupies 5 bytes. - // - if (mOutputPos >= mBufSiz - 5 * UINT8_BIT) { - SendBlock (); - mOutputPos = 0; - } - - CPos = mOutputPos++; - mBuf[CPos] = 0; - } - - mBuf[mOutputPos++] = (UINT8) CharC; - mCFreq[CharC]++; - if (CharC >= (1U << UINT8_BIT)) { - mBuf[CPos] |= mOutputMask; - mBuf[mOutputPos++] = (UINT8) (Pos >> 24); - mBuf[mOutputPos++] = (UINT8) (Pos >> 16); - mBuf[mOutputPos++] = (UINT8) (Pos >> (UINT8_BIT)); - mBuf[mOutputPos++] = (UINT8) Pos; - CharC = 0; - while (Pos) { - Pos >>= 1; - CharC++; - } - - mPFreq[CharC]++; - } -} - -STATIC -VOID -HufEncodeStart ( - VOID - ) -{ - INT32 Index; - - for (Index = 0; Index < NC; Index++) { - mCFreq[Index] = 0; - } - - for (Index = 0; Index < NP; Index++) { - mPFreq[Index] = 0; - } - - mOutputPos = mOutputMask = 0; - InitPutBits (); - return ; -} - -STATIC -VOID -HufEncodeEnd ( - VOID - ) -{ - SendBlock (); - - // - // Flush remaining bits - // - PutBits (UINT8_BIT - 1, 0); - - return ; -} - -STATIC -VOID -MakeCrcTable ( - VOID - ) -{ - UINT32 Index; - UINT32 Index2; - UINT32 Temp; - - for (Index = 0; Index <= UINT8_MAX; Index++) { - Temp = Index; - for (Index2 = 0; Index2 < UINT8_BIT; Index2++) { - if (Temp & 1) { - Temp = (Temp >> 1) ^ CRCPOLY; - } else { - Temp >>= 1; - } - } - - mCrcTable[Index] = (UINT16) Temp; - } -} - -STATIC -VOID -PutBits ( - IN INT32 Number, - IN UINT32 Value - ) -/*++ - -Routine Description: - - Outputs rightmost n bits of x - -Arguments: - - Number - the rightmost n bits of the data is used - x - the data - -Returns: (VOID) - ---*/ -{ - UINT8 Temp; - - while (Number >= mBitCount) { - // - // Number -= mBitCount should never equal to 32 - // - Temp = (UINT8) (mSubBitBuf | (Value >> (Number -= mBitCount))); - if (mDst < mDstUpperLimit) { - *mDst++ = Temp; - } - - mCompSize++; - mSubBitBuf = 0; - mBitCount = UINT8_BIT; - } - - mSubBitBuf |= Value << (mBitCount -= Number); -} - -STATIC -INT32 -FreadCrc ( - OUT UINT8 *Pointer, - IN INT32 Number - ) -/*++ - -Routine Description: - - Read in source data - -Arguments: - - Pointer - the buffer to hold the data - Number - number of bytes to read - -Returns: - - number of bytes actually read - ---*/ -{ - INT32 Index; - - for (Index = 0; mSrc < mSrcUpperLimit && Index < Number; Index++) { - *Pointer++ = *mSrc++; - } - - Number = Index; - - Pointer -= Number; - mOrigSize += Number; - Index--; - while (Index >= 0) { - UPDATE_CRC (*Pointer++); - Index--; - } - - return Number; -} - -STATIC -VOID -InitPutBits ( - VOID - ) -{ - mBitCount = UINT8_BIT; - mSubBitBuf = 0; -} - -STATIC -VOID -CountLen ( - IN INT32 Index - ) -/*++ - -Routine Description: - - Count the number of each code length for a Huffman tree. - -Arguments: - - Index - the top node - -Returns: (VOID) - ---*/ -{ - static INT32 Depth = 0; - - if (Index < mN) { - mLenCnt[(Depth < 16) ? Depth : 16]++; - } else { - Depth++; - CountLen (mLeft[Index]); - CountLen (mRight[Index]); - Depth--; - } -} - -STATIC -VOID -MakeLen ( - IN INT32 Root - ) -/*++ - -Routine Description: - - Create code length array for a Huffman tree - -Arguments: - - Root - the root of the tree - -Returns: - - VOID - ---*/ -{ - INT32 Index; - INT32 Index3; - UINT32 Cum; - - for (Index = 0; Index <= 16; Index++) { - mLenCnt[Index] = 0; - } - - CountLen (Root); - - // - // Adjust the length count array so that - // no code will be generated longer than its designated length - // - Cum = 0; - for (Index = 16; Index > 0; Index--) { - Cum += mLenCnt[Index] << (16 - Index); - } - - while (Cum != (1U << 16)) { - mLenCnt[16]--; - for (Index = 15; Index > 0; Index--) { - if (mLenCnt[Index] != 0) { - mLenCnt[Index]--; - mLenCnt[Index + 1] += 2; - break; - } - } - - Cum--; - } - - for (Index = 16; Index > 0; Index--) { - Index3 = mLenCnt[Index]; - Index3--; - while (Index3 >= 0) { - mLen[*mSortPtr++] = (UINT8) Index; - Index3--; - } - } -} - -STATIC -VOID -DownHeap ( - IN INT32 Index - ) -{ - INT32 Index2; - INT32 Index3; - - // - // priority queue: send Index-th entry down heap - // - Index3 = mHeap[Index]; - Index2 = 2 * Index; - while (Index2 <= mHeapSize) { - if (Index2 < mHeapSize && mFreq[mHeap[Index2]] > mFreq[mHeap[Index2 + 1]]) { - Index2++; - } - - if (mFreq[Index3] <= mFreq[mHeap[Index2]]) { - break; - } - - mHeap[Index] = mHeap[Index2]; - Index = Index2; - Index2 = 2 * Index; - } - - mHeap[Index] = (INT16) Index3; -} - -STATIC -VOID -MakeCode ( - IN INT32 Number, - IN UINT8 Len[ ], - OUT UINT16 Code[] - ) -/*++ - -Routine Description: - - Assign code to each symbol based on the code length array - -Arguments: - - Number - number of symbols - Len - the code length array - Code - stores codes for each symbol - -Returns: (VOID) - ---*/ -{ - INT32 Index; - UINT16 Start[18]; - - Start[1] = 0; - for (Index = 1; Index <= 16; Index++) { - Start[Index + 1] = (UINT16) ((Start[Index] + mLenCnt[Index]) << 1); - } - - for (Index = 0; Index < Number; Index++) { - Code[Index] = Start[Len[Index]]++; - } -} - -STATIC -INT32 -MakeTree ( - IN INT32 NParm, - IN UINT16 FreqParm[], - OUT UINT8 LenParm[ ], - OUT UINT16 CodeParm[] - ) -/*++ - -Routine Description: - - Generates Huffman codes given a frequency distribution of symbols - -Arguments: - - NParm - number of symbols - FreqParm - frequency of each symbol - LenParm - code length for each symbol - CodeParm - code for each symbol - -Returns: - - Root of the Huffman tree. - ---*/ -{ - INT32 Index; - INT32 Index2; - INT32 Index3; - INT32 Avail; - - // - // make tree, calculate len[], return root - // - mN = NParm; - mFreq = FreqParm; - mLen = LenParm; - Avail = mN; - mHeapSize = 0; - mHeap[1] = 0; - for (Index = 0; Index < mN; Index++) { - mLen[Index] = 0; - if (mFreq[Index]) { - mHeapSize++; - mHeap[mHeapSize] = (INT16) Index; - } - } - - if (mHeapSize < 2) { - CodeParm[mHeap[1]] = 0; - return mHeap[1]; - } - - for (Index = mHeapSize / 2; Index >= 1; Index--) { - // - // make priority queue - // - DownHeap (Index); - } - - mSortPtr = CodeParm; - do { - Index = mHeap[1]; - if (Index < mN) { - *mSortPtr++ = (UINT16) Index; - } - - mHeap[1] = mHeap[mHeapSize--]; - DownHeap (1); - Index2 = mHeap[1]; - if (Index2 < mN) { - *mSortPtr++ = (UINT16) Index2; - } - - Index3 = Avail++; - mFreq[Index3] = (UINT16) (mFreq[Index] + mFreq[Index2]); - mHeap[1] = (INT16) Index3; - DownHeap (1); - mLeft[Index3] = (UINT16) Index; - mRight[Index3] = (UINT16) Index2; - } while (mHeapSize > 1); - - mSortPtr = CodeParm; - MakeLen (Index3); - MakeCode (NParm, LenParm, CodeParm); - - // - // return root - // - return Index3; -} diff --git a/Tools/CodeTools/TianoTools/Common/EfiCompress.h b/Tools/CodeTools/TianoTools/Common/EfiCompress.h deleted file mode 100644 index 6ad80e4742..0000000000 --- a/Tools/CodeTools/TianoTools/Common/EfiCompress.h +++ /dev/null @@ -1,69 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - EfiCompress.h - -Abstract: - - Header file for compression routine - ---*/ - -#ifndef _EFICOMPRESS_H -#define _EFICOMPRESS_H - -#include -#include - -#include - -EFI_STATUS -Compress ( - IN UINT8 *SrcBuffer, - IN UINT32 SrcSize, - IN UINT8 *DstBuffer, - IN OUT UINT32 *DstSize - ) -; - -/*++ - -Routine Description: - - The compression routine. - -Arguments: - - SrcBuffer - The buffer storing the source data - SrcSize - The size of source data - DstBuffer - The buffer to store the compressed data - DstSize - On input, the size of DstBuffer; On output, - the size of the actual compressed data. - -Returns: - - EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. In this case, - DstSize contains the size needed. - EFI_SUCCESS - Compression is successful. - ---*/ -typedef -EFI_STATUS -(*COMPRESS_FUNCTION) ( - IN UINT8 *SrcBuffer, - IN UINT32 SrcSize, - IN UINT8 *DstBuffer, - IN OUT UINT32 *DstSize - ); - -#endif diff --git a/Tools/CodeTools/TianoTools/Common/EfiCustomizedCompress.h b/Tools/CodeTools/TianoTools/Common/EfiCustomizedCompress.h deleted file mode 100644 index af26b6f12a..0000000000 --- a/Tools/CodeTools/TianoTools/Common/EfiCustomizedCompress.h +++ /dev/null @@ -1,141 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - EfiCustomizedCompress.h - -Abstract: - - Header file for Customized compression routine - ---*/ - -#ifndef _EFICUSTOMIZEDCOMPRESS_H -#define _EFICUSTOMIZEDCOMPRESS_H - -#include - -EFI_STATUS -SetCustomizedCompressionType ( - IN CHAR8 *Type - ) -; - -/*++ - -Routine Description: - -The implementation of Customized SetCompressionType(). - -Arguments: - Type - The type if compression. - -Returns: - - EFI_SUCCESS - The type has been set. - EFI_UNSUPPORTED - This type is unsupported. - - ---*/ -EFI_STATUS -CustomizedGetInfo ( - IN VOID *Source, - IN UINT32 SrcSize, - OUT UINT32 *DstSize, - OUT UINT32 *ScratchSize - ) -; - -/*++ - -Routine Description: - - The implementation of Customized GetInfo(). - -Arguments: - - Source - The source buffer containing the compressed data. - SrcSize - The size of source buffer - DstSize - The size of destination buffer. - ScratchSize - The size of scratch buffer. - -Returns: - - EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved. - EFI_INVALID_PARAMETER - The source data is corrupted - ---*/ -EFI_STATUS -CustomizedDecompress ( - IN VOID *Source, - IN UINT32 SrcSize, - IN OUT VOID *Destination, - IN UINT32 DstSize, - IN OUT VOID *Scratch, - IN UINT32 ScratchSize - ) -; - -/*++ - -Routine Description: - - The implementation of Customized Decompress(). - -Arguments: - - This - The protocol instance pointer - Source - The source buffer containing the compressed data. - SrcSize - The size of source buffer - Destination - The destination buffer to store the decompressed data - DstSize - The size of destination buffer. - Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data. - ScratchSize - The size of scratch buffer. - -Returns: - - EFI_SUCCESS - Decompression is successfull - EFI_INVALID_PARAMETER - The source data is corrupted - ---*/ -EFI_STATUS -CustomizedCompress ( - IN UINT8 *SrcBuffer, - IN UINT32 SrcSize, - IN UINT8 *DstBuffer, - IN OUT UINT32 *DstSize - ) -; - -/*++ - -Routine Description: - - The Customized compression routine. - -Arguments: - - SrcBuffer - The buffer storing the source data - SrcSize - The size of source data - DstBuffer - The buffer to store the compressed data - DstSize - On input, the size of DstBuffer; On output, - the size of the actual compressed data. - -Returns: - - EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. In this case, - DstSize contains the size needed. - EFI_SUCCESS - Compression is successful. - ---*/ - -#endif diff --git a/Tools/CodeTools/TianoTools/Common/EfiDecompress.c b/Tools/CodeTools/TianoTools/Common/EfiDecompress.c deleted file mode 100644 index 288c42579e..0000000000 --- a/Tools/CodeTools/TianoTools/Common/EfiDecompress.c +++ /dev/null @@ -1,790 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - EfiDecompress.c - -Abstract: - - Decompressor. Algorithm Ported from OPSD code (Decomp.asm) - ---*/ - -#include "EfiDecompress.h" - -// -// Decompression algorithm begins here -// -#define BITBUFSIZ 32 -#define MAXMATCH 256 -#define THRESHOLD 3 -#define CODE_BIT 16 -#define BAD_TABLE - 1 - -// -// C: Char&Len Set; P: Position Set; T: exTra Set -// -#define NC (0xff + MAXMATCH + 2 - THRESHOLD) -#define CBIT 9 -#define PBIT 5 -#define TBIT 5 -#define MAXNP ((1U << PBIT) - 1) -#define NT (CODE_BIT + 3) -#if NT > MAXNP -#define NPT NT -#else -#define NPT MAXNP -#endif - -typedef struct { - UINT8 *mSrcBase; // Starting address of compressed data - UINT8 *mDstBase; // Starting address of decompressed data - UINT32 mOutBuf; - UINT32 mInBuf; - - UINT16 mBitCount; - UINT32 mBitBuf; - UINT32 mSubBitBuf; - UINT16 mBlockSize; - UINT32 mCompSize; - UINT32 mOrigSize; - - UINT16 mBadTableFlag; - - UINT16 mLeft[2 * NC - 1]; - UINT16 mRight[2 * NC - 1]; - UINT8 mCLen[NC]; - UINT8 mPTLen[NPT]; - UINT16 mCTable[4096]; - UINT16 mPTTable[256]; -} SCRATCH_DATA; - -STATIC -VOID -FillBuf ( - IN SCRATCH_DATA *Sd, - IN UINT16 NumOfBits - ) -/*++ - -Routine Description: - - Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source. - -Arguments: - - Sd - The global scratch data - NumOfBit - The number of bits to shift and read. - -Returns: (VOID) - ---*/ -{ - Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits); - - while (NumOfBits > Sd->mBitCount) { - - Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount))); - - if (Sd->mCompSize > 0) { - // - // Get 1 byte into SubBitBuf - // - Sd->mCompSize--; - Sd->mSubBitBuf = 0; - Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++]; - Sd->mBitCount = 8; - - } else { - // - // No more bits from the source, just pad zero bit. - // - Sd->mSubBitBuf = 0; - Sd->mBitCount = 8; - - } - } - - Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits); - Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount; -} - -STATIC -UINT32 -GetBits ( - IN SCRATCH_DATA *Sd, - IN UINT16 NumOfBits - ) -/*++ - -Routine Description: - - Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent - NumOfBits of bits from source. Returns NumOfBits of bits that are - popped out. - -Arguments: - - Sd - The global scratch data. - NumOfBits - The number of bits to pop and read. - -Returns: - - The bits that are popped out. - ---*/ -{ - UINT32 OutBits; - - OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits)); - - FillBuf (Sd, NumOfBits); - - return OutBits; -} - -STATIC -UINT16 -MakeTable ( - IN SCRATCH_DATA *Sd, - IN UINT16 NumOfChar, - IN UINT8 *BitLen, - IN UINT16 TableBits, - OUT UINT16 *Table - ) -/*++ - -Routine Description: - - Creates Huffman Code mapping table according to code length array. - -Arguments: - - Sd - The global scratch data - NumOfChar - Number of symbols in the symbol set - BitLen - Code length array - TableBits - The width of the mapping table - Table - The table - -Returns: - - 0 - OK. - BAD_TABLE - The table is corrupted. - ---*/ -{ - UINT16 Count[17]; - UINT16 Weight[17]; - UINT16 Start[18]; - UINT16 *Pointer; - UINT16 Index3; - UINT16 Index; - UINT16 Len; - UINT16 Char; - UINT16 JuBits; - UINT16 Avail; - UINT16 NextCode; - UINT16 Mask; - - for (Index = 1; Index <= 16; Index++) { - Count[Index] = 0; - } - - for (Index = 0; Index < NumOfChar; Index++) { - Count[BitLen[Index]]++; - } - - Start[1] = 0; - - for (Index = 1; Index <= 16; Index++) { - Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index))); - } - - if (Start[17] != 0) { - /*(1U << 16)*/ - return (UINT16) BAD_TABLE; - } - - JuBits = (UINT16) (16 - TableBits); - - for (Index = 1; Index <= TableBits; Index++) { - Start[Index] >>= JuBits; - Weight[Index] = (UINT16) (1U << (TableBits - Index)); - } - - while (Index <= 16) { - Weight[Index++] = (UINT16) (1U << (16 - Index)); - } - - Index = (UINT16) (Start[TableBits + 1] >> JuBits); - - if (Index != 0) { - Index3 = (UINT16) (1U << TableBits); - while (Index != Index3) { - Table[Index++] = 0; - } - } - - Avail = NumOfChar; - Mask = (UINT16) (1U << (15 - TableBits)); - - for (Char = 0; Char < NumOfChar; Char++) { - - Len = BitLen[Char]; - if (Len == 0) { - continue; - } - - NextCode = (UINT16) (Start[Len] + Weight[Len]); - - if (Len <= TableBits) { - - for (Index = Start[Len]; Index < NextCode; Index++) { - Table[Index] = Char; - } - - } else { - - Index3 = Start[Len]; - Pointer = &Table[Index3 >> JuBits]; - Index = (UINT16) (Len - TableBits); - - while (Index != 0) { - if (*Pointer == 0) { - Sd->mRight[Avail] = Sd->mLeft[Avail] = 0; - *Pointer = Avail++; - } - - if (Index3 & Mask) { - Pointer = &Sd->mRight[*Pointer]; - } else { - Pointer = &Sd->mLeft[*Pointer]; - } - - Index3 <<= 1; - Index--; - } - - *Pointer = Char; - - } - - Start[Len] = NextCode; - } - // - // Succeeds - // - return 0; -} - -STATIC -UINT32 -DecodeP ( - IN SCRATCH_DATA *Sd - ) -/*++ - -Routine Description: - - Decodes a position value. - -Arguments: - - Sd - the global scratch data - -Returns: - - The position value decoded. - ---*/ -{ - UINT16 Val; - UINT32 Mask; - UINT32 Pos; - - Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)]; - - if (Val >= MAXNP) { - Mask = 1U << (BITBUFSIZ - 1 - 8); - - do { - - if (Sd->mBitBuf & Mask) { - Val = Sd->mRight[Val]; - } else { - Val = Sd->mLeft[Val]; - } - - Mask >>= 1; - } while (Val >= MAXNP); - } - // - // Advance what we have read - // - FillBuf (Sd, Sd->mPTLen[Val]); - - Pos = Val; - if (Val > 1) { - Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1))); - } - - return Pos; -} - -STATIC -UINT16 -ReadPTLen ( - IN SCRATCH_DATA *Sd, - IN UINT16 nn, - IN UINT16 nbit, - IN UINT16 Special - ) -/*++ - -Routine Description: - - Reads code lengths for the Extra Set or the Position Set - -Arguments: - - Sd - The global scratch data - nn - Number of symbols - nbit - Number of bits needed to represent nn - Special - The special symbol that needs to be taken care of - -Returns: - - 0 - OK. - BAD_TABLE - Table is corrupted. - ---*/ -{ - UINT16 Number; - UINT16 CharC; - UINT16 Index; - UINT32 Mask; - - Number = (UINT16) GetBits (Sd, nbit); - - if (Number == 0) { - CharC = (UINT16) GetBits (Sd, nbit); - - for (Index = 0; Index < 256; Index++) { - Sd->mPTTable[Index] = CharC; - } - - for (Index = 0; Index < nn; Index++) { - Sd->mPTLen[Index] = 0; - } - - return 0; - } - - Index = 0; - - while (Index < Number) { - - CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3)); - - if (CharC == 7) { - Mask = 1U << (BITBUFSIZ - 1 - 3); - while (Mask & Sd->mBitBuf) { - Mask >>= 1; - CharC += 1; - } - } - - FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3)); - - Sd->mPTLen[Index++] = (UINT8) CharC; - - if (Index == Special) { - CharC = (UINT16) GetBits (Sd, 2); - CharC--; - while ((INT16) (CharC) >= 0) { - Sd->mPTLen[Index++] = 0; - CharC--; - } - } - } - - while (Index < nn) { - Sd->mPTLen[Index++] = 0; - } - - return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable); -} - -STATIC -VOID -ReadCLen ( - SCRATCH_DATA *Sd - ) -/*++ - -Routine Description: - - Reads code lengths for Char&Len Set. - -Arguments: - - Sd - the global scratch data - -Returns: (VOID) - ---*/ -{ - UINT16 Number; - UINT16 CharC; - UINT16 Index; - UINT32 Mask; - - Number = (UINT16) GetBits (Sd, CBIT); - - if (Number == 0) { - CharC = (UINT16) GetBits (Sd, CBIT); - - for (Index = 0; Index < NC; Index++) { - Sd->mCLen[Index] = 0; - } - - for (Index = 0; Index < 4096; Index++) { - Sd->mCTable[Index] = CharC; - } - - return ; - } - - Index = 0; - while (Index < Number) { - - CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)]; - if (CharC >= NT) { - Mask = 1U << (BITBUFSIZ - 1 - 8); - - do { - - if (Mask & Sd->mBitBuf) { - CharC = Sd->mRight[CharC]; - } else { - CharC = Sd->mLeft[CharC]; - } - - Mask >>= 1; - - } while (CharC >= NT); - } - // - // Advance what we have read - // - FillBuf (Sd, Sd->mPTLen[CharC]); - - if (CharC <= 2) { - - if (CharC == 0) { - CharC = 1; - } else if (CharC == 1) { - CharC = (UINT16) (GetBits (Sd, 4) + 3); - } else if (CharC == 2) { - CharC = (UINT16) (GetBits (Sd, CBIT) + 20); - } - - CharC--; - while ((INT16) (CharC) >= 0) { - Sd->mCLen[Index++] = 0; - CharC--; - } - - } else { - - Sd->mCLen[Index++] = (UINT8) (CharC - 2); - - } - } - - while (Index < NC) { - Sd->mCLen[Index++] = 0; - } - - MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable); - - return ; -} - -STATIC -UINT16 -DecodeC ( - SCRATCH_DATA *Sd - ) -/*++ - -Routine Description: - - Decode a character/length value. - -Arguments: - - Sd - The global scratch data. - -Returns: - - The value decoded. - ---*/ -{ - UINT16 Index2; - UINT32 Mask; - - if (Sd->mBlockSize == 0) { - // - // Starting a new block - // - Sd->mBlockSize = (UINT16) GetBits (Sd, 16); - Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3); - if (Sd->mBadTableFlag != 0) { - return 0; - } - - ReadCLen (Sd); - - Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, PBIT, (UINT16) (-1)); - if (Sd->mBadTableFlag != 0) { - return 0; - } - } - - Sd->mBlockSize--; - Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)]; - - if (Index2 >= NC) { - Mask = 1U << (BITBUFSIZ - 1 - 12); - - do { - if (Sd->mBitBuf & Mask) { - Index2 = Sd->mRight[Index2]; - } else { - Index2 = Sd->mLeft[Index2]; - } - - Mask >>= 1; - } while (Index2 >= NC); - } - // - // Advance what we have read - // - FillBuf (Sd, Sd->mCLen[Index2]); - - return Index2; -} - -STATIC -VOID -Decode ( - SCRATCH_DATA *Sd - ) -/*++ - -Routine Description: - - Decode the source data and put the resulting data into the destination buffer. - -Arguments: - - Sd - The global scratch data - -Returns: (VOID) - - --*/ -{ - UINT16 BytesRemain; - UINT32 DataIdx; - UINT16 CharC; - - BytesRemain = (UINT16) (-1); - - DataIdx = 0; - - for (;;) { - CharC = DecodeC (Sd); - if (Sd->mBadTableFlag != 0) { - return ; - } - - if (CharC < 256) { - // - // Process an Original character - // - Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC; - if (Sd->mOutBuf >= Sd->mOrigSize) { - return ; - } - - } else { - // - // Process a Pointer - // - CharC = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD)); - - BytesRemain = CharC; - - DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1; - - BytesRemain--; - while ((INT16) (BytesRemain) >= 0) { - Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++]; - if (Sd->mOutBuf >= Sd->mOrigSize) { - return ; - } - - BytesRemain--; - } - } - } - - return ; -} - -EFI_STATUS -GetInfo ( - IN VOID *Source, - IN UINT32 SrcSize, - OUT UINT32 *DstSize, - OUT UINT32 *ScratchSize - ) -/*++ - -Routine Description: - - The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo(). - -Arguments: - - Source - The source buffer containing the compressed data. - SrcSize - The size of source buffer - DstSize - The size of destination buffer. - ScratchSize - The size of scratch buffer. - -Returns: - - EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved. - EFI_INVALID_PARAMETER - The source data is corrupted - ---*/ -{ - UINT8 *Src; - - *ScratchSize = sizeof (SCRATCH_DATA); - - Src = Source; - if (SrcSize < 8) { - return EFI_INVALID_PARAMETER; - } - - *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24); - return EFI_SUCCESS; -} - -EFI_STATUS -Decompress ( - IN VOID *Source, - IN UINT32 SrcSize, - IN OUT VOID *Destination, - IN UINT32 DstSize, - IN OUT VOID *Scratch, - IN UINT32 ScratchSize - ) -/*++ - -Routine Description: - - The implementation of EFI_DECOMPRESS_PROTOCOL.Decompress(). - -Arguments: - - This - The protocol instance pointer - Source - The source buffer containing the compressed data. - SrcSize - The size of source buffer - Destination - The destination buffer to store the decompressed data - DstSize - The size of destination buffer. - Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data. - ScratchSize - The size of scratch buffer. - -Returns: - - EFI_SUCCESS - Decompression is successfull - EFI_INVALID_PARAMETER - The source data is corrupted - ---*/ -{ - UINT32 Index; - UINT32 CompSize; - UINT32 OrigSize; - EFI_STATUS Status; - SCRATCH_DATA *Sd; - UINT8 *Src; - UINT8 *Dst; - - Status = EFI_SUCCESS; - Src = Source; - Dst = Destination; - - if (ScratchSize < sizeof (SCRATCH_DATA)) { - return EFI_INVALID_PARAMETER; - } - - Sd = (SCRATCH_DATA *) Scratch; - - if (SrcSize < 8) { - return EFI_INVALID_PARAMETER; - } - - CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24); - OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24); - - if (SrcSize < CompSize + 8) { - return EFI_INVALID_PARAMETER; - } - - if (DstSize != OrigSize) { - return EFI_INVALID_PARAMETER; - } - - Src = Src + 8; - - for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) { - ((UINT8 *) Sd)[Index] = 0; - } - - Sd->mSrcBase = Src; - Sd->mDstBase = Dst; - Sd->mCompSize = CompSize; - Sd->mOrigSize = OrigSize; - - // - // Fill the first BITBUFSIZ bits - // - FillBuf (Sd, BITBUFSIZ); - - // - // Decompress it - // - Decode (Sd); - - if (Sd->mBadTableFlag != 0) { - // - // Something wrong with the source - // - Status = EFI_INVALID_PARAMETER; - } - - return Status; -} diff --git a/Tools/CodeTools/TianoTools/Common/EfiDecompress.h b/Tools/CodeTools/TianoTools/Common/EfiDecompress.h deleted file mode 100644 index 3f82ac6872..0000000000 --- a/Tools/CodeTools/TianoTools/Common/EfiDecompress.h +++ /dev/null @@ -1,106 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - EfiDecompress.h - -Abstract: - - Header file for compression routine - ---*/ - -#ifndef _EFI_DECOMPRESS_H -#define _EFI_DECOMPRESS_H - -#include - -EFI_STATUS -GetInfo ( - IN VOID *Source, - IN UINT32 SrcSize, - OUT UINT32 *DstSize, - OUT UINT32 *ScratchSize - ); - -/*++ - -Routine Description: - - The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo(). - -Arguments: - - Source - The source buffer containing the compressed data. - SrcSize - The size of source buffer - DstSize - The size of destination buffer. - ScratchSize - The size of scratch buffer. - -Returns: - - EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved. - EFI_INVALID_PARAMETER - The source data is corrupted - ---*/ -EFI_STATUS -Decompress ( - IN VOID *Source, - IN UINT32 SrcSize, - IN OUT VOID *Destination, - IN UINT32 DstSize, - IN OUT VOID *Scratch, - IN UINT32 ScratchSize - ) -; - -/*++ - -Routine Description: - - The implementation of EFI_DECOMPRESS_PROTOCOL.Decompress(). - -Arguments: - - This - The protocol instance pointer - Source - The source buffer containing the compressed data. - SrcSize - The size of source buffer - Destination - The destination buffer to store the decompressed data - DstSize - The size of destination buffer. - Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data. - ScratchSize - The size of scratch buffer. - -Returns: - - EFI_SUCCESS - Decompression is successfull - EFI_INVALID_PARAMETER - The source data is corrupted - ---*/ -typedef -EFI_STATUS -(*GETINFO_FUNCTION) ( - IN VOID *Source, - IN UINT32 SrcSize, - OUT UINT32 *DstSize, - OUT UINT32 *ScratchSize - ); - -typedef -EFI_STATUS -(*DECOMPRESS_FUNCTION) ( - IN VOID *Source, - IN UINT32 SrcSize, - IN OUT VOID *Destination, - IN UINT32 DstSize, - IN OUT VOID *Scratch, - IN UINT32 ScratchSize - ); -#endif diff --git a/Tools/CodeTools/TianoTools/Common/EfiUtilityMsgs.c b/Tools/CodeTools/TianoTools/Common/EfiUtilityMsgs.c deleted file mode 100644 index 566d214cab..0000000000 --- a/Tools/CodeTools/TianoTools/Common/EfiUtilityMsgs.c +++ /dev/null @@ -1,755 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - EfiUtilityMsgs.c - -Abstract: - - EFI tools utility functions to display warning, error, and informational - messages. - ---*/ - -#include -#include -#include -#include - -#include "EfiUtilityMsgs.h" - -#define MAX_LINE_LEN 200 - -// -// Declare module globals for keeping track of the the utility's -// name and other settings. -// -static STATUS mStatus = STATUS_SUCCESS; -static CHAR8 mUtilityName[50] = { 0 }; -static UINT32 mDebugMsgMask = 0; -static CHAR8 *mSourceFileName = NULL; -static UINT32 mSourceFileLineNum = 0; -static UINT32 mErrorCount = 0; -static UINT32 mWarningCount = 0; -static UINT32 mMaxErrors = 0; -static UINT32 mMaxWarnings = 0; -static UINT32 mMaxWarningsPlusErrors = 0; -static INT8 mPrintLimitsSet = 0; - -static -void -PrintMessage ( - CHAR8 *Type, - CHAR8 *FileName, - UINT32 LineNumber, - UINT32 MessageCode, - CHAR8 *Text, - CHAR8 *MsgFmt, - va_list List - ); - -static -void -PrintLimitExceeded ( - VOID - ); - -void -Error ( - CHAR8 *FileName, - UINT32 LineNumber, - UINT32 MessageCode, - CHAR8 *Text, - CHAR8 *MsgFmt, - ... - ) -/*++ - -Routine Description: - Prints an error message. - -Arguments: - All arguments are optional, though the printed message may be useless if - at least something valid is not specified. - - FileName - name of the file or application. If not specified, then the - utilty name (as set by the utility calling SetUtilityName() - earlier) is used. Otherwise "Unknown utility" is used. - - LineNumber - the line number of error, typically used by parsers. If the - utility is not a parser, then 0 should be specified. Otherwise - the FileName and LineNumber info can be used to cause - MS Visual Studio to jump to the error. - - MessageCode - an application-specific error code that can be referenced in - other documentation. - - Text - the text in question, typically used by parsers. - - MsgFmt - the format string for the error message. Can contain formatting - controls for use with the varargs. - -Returns: - None. - -Notes: - We print the following (similar to the Warn() and Debug() - W - Typical error/warning message format: - - bin\VfrCompile.cpp(330) : error C2660: 'AddVfrDataStructField' : function does not take 2 parameters - - BUGBUG -- these three utility functions are almost identical, and - should be modified to share code. - - Visual Studio does not find error messages with: - - " error :" - " error 1:" - " error c1:" - " error 1000:" - " error c100:" - - It does find: - " error c1000:" ---*/ -{ - va_list List; - // - // If limits have been set, then check that we have not exceeded them - // - if (mPrintLimitsSet) { - // - // See if we've exceeded our total count - // - if (mMaxWarningsPlusErrors != 0) { - if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) { - PrintLimitExceeded (); - return ; - } - } - // - // See if we've exceeded our error count - // - if (mMaxErrors != 0) { - if (mErrorCount > mMaxErrors) { - PrintLimitExceeded (); - return ; - } - } - } - - mErrorCount++; - va_start (List, MsgFmt); - PrintMessage ("error", FileName, LineNumber, MessageCode, Text, MsgFmt, List); - va_end (List); - // - // Set status accordingly - // - if (mStatus < STATUS_ERROR) { - mStatus = STATUS_ERROR; - } -} - -void -ParserError ( - UINT32 MessageCode, - CHAR8 *Text, - CHAR8 *MsgFmt, - ... - ) -/*++ - -Routine Description: - Print a parser error, using the source file name and line number - set by a previous call to SetParserPosition(). - -Arguments: - MessageCode - application-specific error code - Text - text to print in the error message - MsgFmt - format string to print at the end of the error message - -Returns: - NA - ---*/ -{ - va_list List; - // - // If limits have been set, then check them - // - if (mPrintLimitsSet) { - // - // See if we've exceeded our total count - // - if (mMaxWarningsPlusErrors != 0) { - if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) { - PrintLimitExceeded (); - return ; - } - } - // - // See if we've exceeded our error count - // - if (mMaxErrors != 0) { - if (mErrorCount > mMaxErrors) { - PrintLimitExceeded (); - return ; - } - } - } - - mErrorCount++; - va_start (List, MsgFmt); - PrintMessage ("error", mSourceFileName, mSourceFileLineNum, MessageCode, Text, MsgFmt, List); - va_end (List); - // - // Set status accordingly - // - if (mStatus < STATUS_ERROR) { - mStatus = STATUS_ERROR; - } -} - -void -ParserWarning ( - UINT32 ErrorCode, - CHAR8 *OffendingText, - CHAR8 *MsgFmt, - ... - ) -/*++ - -Routine Description: - Print a parser warning, using the source file name and line number - set by a previous call to SetParserPosition(). - -Arguments: - ErrorCode - application-specific error code - OffendingText - text to print in the warning message - MsgFmt - format string to print at the end of the warning message - -Returns: - NA - ---*/ -{ - va_list List; - // - // If limits have been set, then check them - // - if (mPrintLimitsSet) { - // - // See if we've exceeded our total count - // - if (mMaxWarningsPlusErrors != 0) { - if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) { - PrintLimitExceeded (); - return ; - } - } - // - // See if we've exceeded our warning count - // - if (mMaxWarnings != 0) { - if (mWarningCount > mMaxWarnings) { - PrintLimitExceeded (); - return ; - } - } - } - - mWarningCount++; - va_start (List, MsgFmt); - PrintMessage ("warning", mSourceFileName, mSourceFileLineNum, ErrorCode, OffendingText, MsgFmt, List); - va_end (List); - // - // Set status accordingly - // - if (mStatus < STATUS_WARNING) { - mStatus = STATUS_WARNING; - } -} - -void -Warning ( - CHAR8 *FileName, - UINT32 LineNumber, - UINT32 MessageCode, - CHAR8 *Text, - CHAR8 *MsgFmt, - ... - ) -/*++ - -Routine Description: - Print a warning message. - -Arguments: - FileName - name of the file where the warning was detected, or the name - of the application that detected the warning - - LineNumber - the line number where the warning was detected (parsers). - 0 should be specified if the utility is not a parser. - - MessageCode - an application-specific warning code that can be referenced in - other documentation. - - Text - the text in question (parsers) - - MsgFmt - the format string for the warning message. Can contain formatting - controls for use with varargs. - -Returns: - None. - ---*/ -{ - va_list List; - // - // If limits have been set, then check them - // - if (mPrintLimitsSet) { - // - // See if we've exceeded our total count - // - if (mMaxWarningsPlusErrors != 0) { - if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) { - PrintLimitExceeded (); - return ; - } - } - // - // See if we've exceeded our warning count - // - if (mMaxWarnings != 0) { - if (mWarningCount > mMaxWarnings) { - PrintLimitExceeded (); - return ; - } - } - } - - mWarningCount++; - va_start (List, MsgFmt); - PrintMessage ("warning", FileName, LineNumber, MessageCode, Text, MsgFmt, List); - va_end (List); - // - // Set status accordingly - // - if (mStatus < STATUS_WARNING) { - mStatus = STATUS_WARNING; - } -} - -void -DebugMsg ( - CHAR8 *FileName, - UINT32 LineNumber, - UINT32 MsgMask, - CHAR8 *Text, - CHAR8 *MsgFmt, - ... - ) -/*++ - -Routine Description: - Print a warning message. - -Arguments: - FileName - typically the name of the utility printing the debug message, but - can be the name of a file being parsed. - - LineNumber - the line number in FileName (parsers) - - MsgMask - an application-specific bitmask that, in combination with mDebugMsgMask, - determines if the debug message gets printed. - - Text - the text in question (parsers) - - MsgFmt - the format string for the debug message. Can contain formatting - controls for use with varargs. - -Returns: - None. - ---*/ -{ - va_list List; - // - // If the debug mask is not applicable, then do nothing. - // - if ((MsgMask != 0) && ((mDebugMsgMask & MsgMask) == 0)) { - return ; - } - - va_start (List, MsgFmt); - PrintMessage ("debug", FileName, LineNumber, 0, Text, MsgFmt, List); - va_end (List); -} - -static -void -PrintMessage ( - CHAR8 *Type, - CHAR8 *FileName, - UINT32 LineNumber, - UINT32 MessageCode, - CHAR8 *Text, - CHAR8 *MsgFmt, - va_list List - ) -/*++ - -Routine Description: - Worker routine for all the utility printing services. Prints the message in - a format that Visual Studio will find when scanning build outputs for - errors or warnings. - -Arguments: - Type - "warning" or "error" string to insert into the message to be - printed. The first character of this string (converted to uppercase) - is used to preceed the MessageCode value in the output string. - - FileName - name of the file where the warning was detected, or the name - of the application that detected the warning - - LineNumber - the line number where the warning was detected (parsers). - 0 should be specified if the utility is not a parser. - - MessageCode - an application-specific warning code that can be referenced in - other documentation. - - Text - part of the message to print - - MsgFmt - the format string for the message. Can contain formatting - controls for use with varargs. - List - the variable list. - -Returns: - None. - -Notes: - If FileName == NULL then this utility will use the string passed into SetUtilityName(). - - LineNumber is only used if the caller is a parser, in which case FileName refers to the - file being parsed. - - Text and MsgFmt are both optional, though it would be of little use calling this function with - them both NULL. - - Output will typically be of the form: - () : : : - - Parser (LineNumber != 0) - VfrCompile.cpp(330) : error E2660: AddVfrDataStructField : function does not take 2 parameters - Generic utility (LineNumber == 0) - UtilityName : error E1234 : Text string : MsgFmt string and args - ---*/ -{ - CHAR8 Line[MAX_LINE_LEN]; - CHAR8 Line2[MAX_LINE_LEN]; - CHAR8 *Cptr; - // - // If given a filename, then add it (and the line number) to the string. - // If there's no filename, then use the program name if provided. - // - if (FileName != NULL) { - Cptr = FileName; - } else if (mUtilityName[0] != 0) { - Cptr = mUtilityName; - } else { - Cptr = "Unknown utility"; - } - - strcpy (Line, Cptr); - if (LineNumber != 0) { - sprintf (Line2, "(%d)", LineNumber); - strcat (Line, Line2); - } - // - // Have to print an error code or Visual Studio won't find the - // message for you. It has to be decimal digits too. - // - sprintf (Line2, " : %s %c%04d", Type, toupper (Type[0]), MessageCode); - strcat (Line, Line2); - fprintf (stdout, "%s", Line); - // - // If offending text was provided, then print it - // - if (Text != NULL) { - fprintf (stdout, ": %s ", Text); - } - // - // Print formatted message if provided - // - if (MsgFmt != NULL) { - vsprintf (Line2, MsgFmt, List); - fprintf (stdout, ": %s", Line2); - } - - fprintf (stdout, "\n"); -} - -void -ParserSetPosition ( - CHAR8 *SourceFileName, - UINT32 LineNum - ) -/*++ - -Routine Description: - Set the position in a file being parsed. This can be used to - print error messages deeper down in a parser. - -Arguments: - SourceFileName - name of the source file being parsed - LineNum - line number of the source file being parsed - -Returns: - NA - ---*/ -{ - mSourceFileName = SourceFileName; - mSourceFileLineNum = LineNum; -} - -void -SetUtilityName ( - CHAR8 *UtilityName - ) -/*++ - -Routine Description: - All printed error/warning/debug messages follow the same format, and - typically will print a filename or utility name followed by the error - text. However if a filename is not passed to the print routines, then - they'll print the utility name if you call this function early in your - app to set the utility name. - -Arguments: - UtilityName - name of the utility, which will be printed with all - error/warning/debug messags. - -Returns: - NA - ---*/ -{ - // - // Save the name of the utility in our local variable. Make sure its - // length does not exceed our buffer. - // - if (UtilityName != NULL) { - if (strlen (UtilityName) >= sizeof (mUtilityName)) { - Error (UtilityName, 0, 0, "application error", "utility name length exceeds internal buffer size"); - strncpy (mUtilityName, UtilityName, sizeof (mUtilityName) - 1); - mUtilityName[sizeof (mUtilityName) - 1] = 0; - return ; - } else { - strcpy (mUtilityName, UtilityName); - } - } else { - Error (NULL, 0, 0, "application error", "SetUtilityName() called with NULL utility name"); - } -} - -STATUS -GetUtilityStatus ( - VOID - ) -/*++ - -Routine Description: - When you call Error() or Warning(), this module keeps track of it and - sets a local mStatus to STATUS_ERROR or STATUS_WARNING. When the utility - exits, it can call this function to get the status and use it as a return - value. - -Arguments: - None. - -Returns: - Worst-case status reported, as defined by which print function was called. - ---*/ -{ - return mStatus; -} - -void -SetDebugMsgMask ( - UINT32 DebugMask - ) -/*++ - -Routine Description: - Set the debug printing mask. This is used by the DebugMsg() function - to determine when/if a debug message should be printed. - -Arguments: - DebugMask - bitmask, specific to the calling application - -Returns: - NA - ---*/ -{ - mDebugMsgMask = DebugMask; -} - -void -SetPrintLimits ( - UINT32 MaxErrors, - UINT32 MaxWarnings, - UINT32 MaxWarningsPlusErrors - ) -/*++ - -Routine Description: - Set the limits of how many errors, warnings, and errors+warnings - we will print. - -Arguments: - MaxErrors - maximum number of error messages to print - MaxWarnings - maximum number of warning messages to print - MaxWarningsPlusErrors - - maximum number of errors+warnings to print - -Returns: - NA - ---*/ -{ - mMaxErrors = MaxErrors; - mMaxWarnings = MaxWarnings; - mMaxWarningsPlusErrors = MaxWarningsPlusErrors; - mPrintLimitsSet = 1; -} - -static -void -PrintLimitExceeded ( - VOID - ) -{ - static INT8 mPrintLimitExceeded = 0; - // - // If we've already printed the message, do nothing. Otherwise - // temporarily increase our print limits so we can pass one - // more message through. - // - if (mPrintLimitExceeded == 0) { - mPrintLimitExceeded++; - mMaxErrors++; - mMaxWarnings++; - mMaxWarningsPlusErrors++; - Error (NULL, 0, 0, "error/warning print limit exceeded", NULL); - mMaxErrors--; - mMaxWarnings--; - mMaxWarningsPlusErrors--; - } -} - -#if 0 -void -TestUtilityMessages ( - VOID - ) -{ - char *ArgStr = "ArgString"; - int ArgInt; - - ArgInt = 0x12345678; - // - // Test without setting utility name - // - fprintf (stdout, "* Testing without setting utility name\n"); - fprintf (stdout, "** Test debug message not printed\n"); - DebugMsg (NULL, 0, 0x00000001, NULL, NULL); - fprintf (stdout, "** Test warning with two strings and two args\n"); - Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); - fprintf (stdout, "** Test error with two strings and two args\n"); - Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); - fprintf (stdout, "** Test parser warning with nothing\n"); - ParserWarning (0, NULL, NULL); - fprintf (stdout, "** Test parser error with nothing\n"); - ParserError (0, NULL, NULL); - // - // Test with utility name set now - // - fprintf (stdout, "** Testingin with utility name set\n"); - SetUtilityName ("MyUtilityName"); - // - // Test debug prints - // - SetDebugMsgMask (2); - fprintf (stdout, "** Test debug message with one string\n"); - DebugMsg (NULL, 0, 0x00000002, "Text1", NULL); - fprintf (stdout, "** Test debug message with one string\n"); - DebugMsg (NULL, 0, 0x00000002, NULL, "Text2"); - fprintf (stdout, "** Test debug message with two strings\n"); - DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2"); - fprintf (stdout, "** Test debug message with two strings and two args\n"); - DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); - // - // Test warning prints - // - fprintf (stdout, "** Test warning with no strings\n"); - Warning (NULL, 0, 1234, NULL, NULL); - fprintf (stdout, "** Test warning with one string\n"); - Warning (NULL, 0, 1234, "Text1", NULL); - fprintf (stdout, "** Test warning with one string\n"); - Warning (NULL, 0, 1234, NULL, "Text2"); - fprintf (stdout, "** Test warning with two strings and two args\n"); - Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); - // - // Test error prints - // - fprintf (stdout, "** Test error with no strings\n"); - Error (NULL, 0, 1234, NULL, NULL); - fprintf (stdout, "** Test error with one string\n"); - Error (NULL, 0, 1234, "Text1", NULL); - fprintf (stdout, "** Test error with one string\n"); - Error (NULL, 0, 1234, NULL, "Text2"); - fprintf (stdout, "** Test error with two strings and two args\n"); - Error (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); - // - // Test parser prints - // - fprintf (stdout, "** Test parser errors\n"); - ParserSetPosition (__FILE__, __LINE__ + 1); - ParserError (1234, NULL, NULL); - ParserSetPosition (__FILE__, __LINE__ + 1); - ParserError (1234, "Text1", NULL); - ParserSetPosition (__FILE__, __LINE__ + 1); - ParserError (1234, NULL, "Text2"); - ParserSetPosition (__FILE__, __LINE__ + 1); - ParserError (1234, "Text1", "Text2"); - ParserSetPosition (__FILE__, __LINE__ + 1); - ParserError (1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); - - fprintf (stdout, "** Test parser warnings\n"); - ParserSetPosition (__FILE__, __LINE__ + 1); - ParserWarning (4321, NULL, NULL); - ParserSetPosition (__FILE__, __LINE__ + 1); - ParserWarning (4321, "Text1", NULL); - ParserSetPosition (__FILE__, __LINE__ + 1); - ParserWarning (4321, NULL, "Text2"); - ParserSetPosition (__FILE__, __LINE__ + 1); - ParserWarning (4321, "Text1", "Text2"); - ParserSetPosition (__FILE__, __LINE__ + 1); - ParserWarning (4321, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); -} -#endif diff --git a/Tools/CodeTools/TianoTools/Common/EfiUtilityMsgs.h b/Tools/CodeTools/TianoTools/Common/EfiUtilityMsgs.h deleted file mode 100644 index a76b822675..0000000000 --- a/Tools/CodeTools/TianoTools/Common/EfiUtilityMsgs.h +++ /dev/null @@ -1,137 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - EfiUtilityMsgs.h - -Abstract: - - Defines and prototypes for common EFI utility error and debug messages. - ---*/ - -#ifndef _EFI_UTILITY_MSGS_H_ -#define _EFI_UTILITY_MSGS_H_ - -#include - -// -// Status codes returned by EFI utility programs and functions -// -#define STATUS_SUCCESS 0 -#define STATUS_WARNING 1 -#define STATUS_ERROR 2 -#define VOID void - -typedef int STATUS; - -#ifdef __cplusplus -extern "C" { -#endif -// -// When we call Error() or Warning(), the module keeps track of the worst -// case reported. GetUtilityStatus() will get the worst-case results, which -// can be used as the return value from the app. -// -STATUS -GetUtilityStatus ( - void - ); - -// -// If someone prints an error message and didn't specify a source file name, -// then we print the utility name instead. However they must tell us the -// utility name early on via this function. -// -void -SetUtilityName ( - CHAR8 *ProgramName - ) -; - -void -Error ( - CHAR8 *FileName, - UINT32 LineNumber, - UINT32 ErrorCode, - CHAR8 *OffendingText, - CHAR8 *MsgFmt, - ... - ) -; - -void -Warning ( - CHAR8 *FileName, - UINT32 LineNumber, - UINT32 ErrorCode, - CHAR8 *OffendingText, - CHAR8 *MsgFmt, - ... - ) -; - -void -DebugMsg ( - CHAR8 *FileName, - UINT32 LineNumber, - UINT32 MsgLevel, - CHAR8 *OffendingText, - CHAR8 *MsgFmt, - ... - ) -; - -void -SetDebugMsgMask ( - UINT32 MsgMask - ) -; - -void -ParserSetPosition ( - CHAR8 *SourceFileName, - UINT32 LineNum - ) -; - -void -ParserError ( - UINT32 ErrorCode, - CHAR8 *OffendingText, - CHAR8 *MsgFmt, - ... - ) -; - -void -ParserWarning ( - UINT32 ErrorCode, - CHAR8 *OffendingText, - CHAR8 *MsgFmt, - ... - ) -; - -void -SetPrintLimits ( - UINT32 NumErrors, - UINT32 NumWarnings, - UINT32 NumWarningsPlusErrors - ) -; - -#ifdef __cplusplus -} -#endif - -#endif // #ifndef _EFI_UTILITY_MSGS_H_ diff --git a/Tools/CodeTools/TianoTools/Common/FvLib.c b/Tools/CodeTools/TianoTools/Common/FvLib.c deleted file mode 100644 index e8d62791f3..0000000000 --- a/Tools/CodeTools/TianoTools/Common/FvLib.c +++ /dev/null @@ -1,780 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - FvLib.c - -Abstract: - - These functions assist in parsing and manipulating a Firmware Volume. - ---*/ - -// -// Include files -// -#include "FvLib.h" -#include "CommonLib.h" -#include "EfiUtilityMsgs.h" - -// -// Module global variables -// -EFI_FIRMWARE_VOLUME_HEADER *mFvHeader = NULL; -UINT32 mFvLength = 0; - -// -// External function implementations -// -EFI_STATUS -InitializeFvLib ( - IN VOID *Fv, - IN UINT32 FvLength - ) -/*++ - -Routine Description: - - This initializes the FV lib with a pointer to the FV and length. It does not - verify the FV in any way. - -Arguments: - - Fv Buffer containing the FV. - FvLength Length of the FV - -Returns: - - EFI_SUCCESS Function Completed successfully. - EFI_INVALID_PARAMETER A required parameter was NULL. - ---*/ -{ - // - // Verify input arguments - // - if (Fv == NULL) { - return EFI_INVALID_PARAMETER; - } - - mFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) Fv; - mFvLength = FvLength; - - return EFI_SUCCESS; -} - -EFI_STATUS -GetFvHeader ( - OUT EFI_FIRMWARE_VOLUME_HEADER **FvHeader, - OUT UINT32 *FvLength - ) -/*++ - -Routine Description: - - This function returns a pointer to the current FV and the size. - -Arguments: - - FvHeader Pointer to the FV buffer. - FvLength Length of the FV - -Returns: - - EFI_SUCCESS Function Completed successfully. - EFI_INVALID_PARAMETER A required parameter was NULL. - EFI_ABORTED The library needs to be initialized. - ---*/ -{ - // - // Verify library has been initialized. - // - if (mFvHeader == NULL || mFvLength == 0) { - return EFI_ABORTED; - } - // - // Verify input arguments - // - if (FvHeader == NULL) { - return EFI_INVALID_PARAMETER; - } - - *FvHeader = mFvHeader; - return EFI_SUCCESS; -} - -EFI_STATUS -GetNextFile ( - IN EFI_FFS_FILE_HEADER *CurrentFile, - OUT EFI_FFS_FILE_HEADER **NextFile - ) -/*++ - -Routine Description: - - This function returns the next file. If the current file is NULL, it returns - the first file in the FV. If the function returns EFI_SUCCESS and the file - pointer is NULL, then there are no more files in the FV. - -Arguments: - - CurrentFile Pointer to the current file, must be within the current FV. - NextFile Pointer to the next file in the FV. - -Returns: - - EFI_SUCCESS Function completed successfully. - EFI_INVALID_PARAMETER A required parameter was NULL or is out of range. - EFI_ABORTED The library needs to be initialized. - ---*/ -{ - EFI_STATUS Status; - - // - // Verify library has been initialized. - // - if (mFvHeader == NULL || mFvLength == 0) { - return EFI_ABORTED; - } - // - // Verify input arguments - // - if (NextFile == NULL) { - return EFI_INVALID_PARAMETER; - } - // - // Verify FV header - // - Status = VerifyFv (mFvHeader); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - // - // Get first file - // - if (CurrentFile == NULL) { - CurrentFile = (EFI_FFS_FILE_HEADER *) ((UINTN) mFvHeader + mFvHeader->HeaderLength); - - // - // Verify file is valid - // - Status = VerifyFfsFile (CurrentFile); - if (EFI_ERROR (Status)) { - // - // no files in this FV - // - *NextFile = NULL; - return EFI_SUCCESS; - } else { - // - // Verify file is in this FV. - // - if ((UINTN) CurrentFile >= (UINTN) mFvHeader + mFvLength - sizeof (EFI_FFS_FILE_HEADER)) { - *NextFile = NULL; - return EFI_SUCCESS; - } - - *NextFile = CurrentFile; - return EFI_SUCCESS; - } - } - // - // Verify current file is in range - // - if (((UINTN) CurrentFile < (UINTN) mFvHeader + sizeof (EFI_FIRMWARE_VOLUME_HEADER)) || - ((UINTN) CurrentFile >= (UINTN) mFvHeader + mFvLength - sizeof (EFI_FIRMWARE_VOLUME_HEADER)) - ) { - return EFI_INVALID_PARAMETER; - } - // - // Get next file, compensate for 8 byte alignment if necessary. - // - *NextFile = (EFI_FFS_FILE_HEADER *) (((UINTN) CurrentFile + GetLength (CurrentFile->Size) + 0x07) & (-1 << 3)); - - // - // Verify file is in this FV. - // - if ((UINTN) *NextFile >= (UINTN) mFvHeader + mFvLength - sizeof (EFI_FFS_FILE_HEADER)) { - *NextFile = NULL; - return EFI_SUCCESS; - } - // - // Verify file is valid - // - Status = VerifyFfsFile (*NextFile); - if (EFI_ERROR (Status)) { - // - // no more files in this FV - // - *NextFile = NULL; - return EFI_SUCCESS; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -GetFileByName ( - IN EFI_GUID *FileName, - OUT EFI_FFS_FILE_HEADER **File - ) -/*++ - -Routine Description: - - Find a file by name. The function will return NULL if the file is not found. - -Arguments: - - FileName The GUID file name of the file to search for. - File Return pointer. In the case of an error, contents are undefined. - -Returns: - - EFI_SUCCESS The function completed successfully. - EFI_ABORTED An error was encountered. - EFI_INVALID_PARAMETER One of the parameters was NULL. - ---*/ -{ - EFI_FFS_FILE_HEADER *CurrentFile; - EFI_STATUS Status; - - // - // Verify library has been initialized. - // - if (mFvHeader == NULL || mFvLength == 0) { - return EFI_ABORTED; - } - // - // Verify input parameters - // - if (FileName == NULL || File == NULL) { - return EFI_INVALID_PARAMETER; - } - // - // Verify FV header - // - Status = VerifyFv (mFvHeader); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - // - // Get the first file - // - Status = GetNextFile (NULL, &CurrentFile); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "error parsing the FV", NULL); - return EFI_ABORTED; - } - // - // Loop as long as we have a valid file - // - while (CurrentFile) { - if (!CompareGuid (&CurrentFile->Name, FileName)) { - *File = CurrentFile; - return EFI_SUCCESS; - } - - Status = GetNextFile (CurrentFile, &CurrentFile); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "error parsing the FV", NULL); - return EFI_ABORTED; - } - } - // - // File not found in this FV. - // - *File = NULL; - return EFI_SUCCESS; -} - -EFI_STATUS -GetFileByType ( - IN EFI_FV_FILETYPE FileType, - IN UINTN Instance, - OUT EFI_FFS_FILE_HEADER **File - ) -/*++ - -Routine Description: - - Find a file by type and instance. An instance of 1 is the first instance. - The function will return NULL if a matching file cannot be found. - File type EFI_FV_FILETYPE_ALL means any file type is valid. - -Arguments: - - FileType Type of file to search for. - Instance Instace of the file type to return. - File Return pointer. In the case of an error, contents are undefined. - -Returns: - - EFI_SUCCESS The function completed successfully. - EFI_ABORTED An error was encountered. - EFI_INVALID_PARAMETER One of the parameters was NULL. - ---*/ -{ - EFI_FFS_FILE_HEADER *CurrentFile; - EFI_STATUS Status; - UINTN FileCount; - - // - // Verify library has been initialized. - // - if (mFvHeader == NULL || mFvLength == 0) { - return EFI_ABORTED; - } - // - // Verify input parameters - // - if (File == NULL) { - return EFI_INVALID_PARAMETER; - } - // - // Verify FV header - // - Status = VerifyFv (mFvHeader); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - // - // Initialize the number of matching files found. - // - FileCount = 0; - - // - // Get the first file - // - Status = GetNextFile (NULL, &CurrentFile); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "error parsing FV", NULL); - return EFI_ABORTED; - } - // - // Loop as long as we have a valid file - // - while (CurrentFile) { - if (FileType == EFI_FV_FILETYPE_ALL || CurrentFile->Type == FileType) { - FileCount++; - } - - if (FileCount == Instance) { - *File = CurrentFile; - return EFI_SUCCESS; - } - - Status = GetNextFile (CurrentFile, &CurrentFile); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "error parsing the FV", NULL); - return EFI_ABORTED; - } - } - - *File = NULL; - return EFI_SUCCESS; -} - -EFI_STATUS -GetSectionByType ( - IN EFI_FFS_FILE_HEADER *File, - IN EFI_SECTION_TYPE SectionType, - IN UINTN Instance, - OUT EFI_FILE_SECTION_POINTER *Section - ) -/*++ - -Routine Description: - - Find a section in a file by type and instance. An instance of 1 is the first - instance. The function will return NULL if a matching section cannot be found. - The function will not handle encapsulating sections. - -Arguments: - - File The file to search. - SectionType Type of file to search for. - Instance Instace of the section to return. - Section Return pointer. In the case of an error, contents are undefined. - -Returns: - - EFI_SUCCESS The function completed successfully. - EFI_ABORTED An error was encountered. - EFI_INVALID_PARAMETER One of the parameters was NULL. - EFI_NOT_FOUND No found. ---*/ -{ - EFI_FILE_SECTION_POINTER CurrentSection; - EFI_STATUS Status; - UINTN SectionCount; - - // - // Verify input parameters - // - if (File == NULL || Instance == 0) { - return EFI_INVALID_PARAMETER; - } - // - // Verify FFS header - // - Status = VerifyFfsFile (File); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "invalid FFS file", NULL); - return EFI_ABORTED; - } - // - // Initialize the number of matching sections found. - // - SectionCount = 0; - - // - // Get the first section - // - CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) File + sizeof (EFI_FFS_FILE_HEADER)); - - // - // Loop as long as we have a valid file - // - while ((UINTN) CurrentSection.CommonHeader < (UINTN) File + GetLength (File->Size)) { - if (CurrentSection.CommonHeader->Type == SectionType) { - SectionCount++; - } - - if (SectionCount == Instance) { - *Section = CurrentSection; - return EFI_SUCCESS; - } - // - // Find next section (including compensating for alignment issues. - // - CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetLength (CurrentSection.CommonHeader->Size) + 0x03) & (-1 << 2)); - } - // - // Section not found - // - (*Section).Code16Section = NULL; - return EFI_NOT_FOUND; -} -// -// will not parse compressed sections -// -EFI_STATUS -VerifyFv ( - IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader - ) -/*++ - -Routine Description: - - Verify the current pointer points to a valid FV header. - -Arguments: - - FvHeader Pointer to an alleged FV file. - -Returns: - - EFI_SUCCESS The FV header is valid. - EFI_VOLUME_CORRUPTED The FV header is not valid. - EFI_INVALID_PARAMETER A required parameter was NULL. - EFI_ABORTED Operation aborted. - ---*/ -{ - UINT16 Checksum; - - // - // Verify input parameters - // - if (FvHeader == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (FvHeader->Signature != EFI_FVH_SIGNATURE) { - Error (NULL, 0, 0, "invalid FV header signature", NULL); - return EFI_VOLUME_CORRUPTED; - } - // - // Verify header checksum - // - Checksum = CalculateSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); - - if (Checksum != 0) { - Error (NULL, 0, 0, "invalid FV header checksum", NULL); - return EFI_ABORTED; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -VerifyFfsFile ( - IN EFI_FFS_FILE_HEADER *FfsHeader - ) -/*++ - -Routine Description: - - Verify the current pointer points to a FFS file header. - -Arguments: - - FfsHeader Pointer to an alleged FFS file. - -Returns: - - EFI_SUCCESS The Ffs header is valid. - EFI_NOT_FOUND This "file" is the beginning of free space. - EFI_VOLUME_CORRUPTED The Ffs header is not valid. - EFI_ABORTED The erase polarity is not known. - ---*/ -{ - BOOLEAN ErasePolarity; - EFI_STATUS Status; - EFI_FFS_FILE_HEADER BlankHeader; - UINT8 Checksum; - UINT32 FileLength; - UINT32 OccupiedFileLength; - EFI_FFS_FILE_TAIL *Tail; - UINT8 SavedChecksum; - UINT8 SavedState; - UINT8 FileGuidString[80]; - UINT32 TailSize; - // - // Verify library has been initialized. - // - if (mFvHeader == NULL || mFvLength == 0) { - return EFI_ABORTED; - } - // - // Verify FV header - // - Status = VerifyFv (mFvHeader); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - // - // Get the erase polarity. - // - Status = GetErasePolarity (&ErasePolarity); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - // - // Check if we have free space - // - if (ErasePolarity) { - memset (&BlankHeader, -1, sizeof (EFI_FFS_FILE_HEADER)); - } else { - memset (&BlankHeader, 0, sizeof (EFI_FFS_FILE_HEADER)); - } - - if (memcmp (&BlankHeader, FfsHeader, sizeof (EFI_FFS_FILE_HEADER)) == 0) { - return EFI_NOT_FOUND; - } - // - // Convert the GUID to a string so we can at least report which file - // if we find an error. - // - PrintGuidToBuffer (&FfsHeader->Name, FileGuidString, sizeof (FileGuidString), TRUE); - if (FfsHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) { - TailSize = sizeof (EFI_FFS_FILE_TAIL); - } else { - TailSize = 0; - } - // - // Verify file header checksum - // - SavedState = FfsHeader->State; - FfsHeader->State = 0; - SavedChecksum = FfsHeader->IntegrityCheck.Checksum.File; - FfsHeader->IntegrityCheck.Checksum.File = 0; - Checksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER)); - FfsHeader->State = SavedState; - FfsHeader->IntegrityCheck.Checksum.File = SavedChecksum; - if (Checksum != 0) { - Error (NULL, 0, 0, FileGuidString, "invalid FFS file header checksum"); - return EFI_ABORTED; - } - // - // Verify file checksum - // - if (FfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) { - // - // Verify file data checksum - // - FileLength = GetLength (FfsHeader->Size); - OccupiedFileLength = (FileLength + 0x07) & (-1 << 3); - Checksum = CalculateSum8 ((UINT8 *) FfsHeader, FileLength - TailSize); - Checksum = (UINT8) (Checksum - FfsHeader->State); - if (Checksum != 0) { - Error (NULL, 0, 0, FileGuidString, "invalid FFS file checksum"); - return EFI_ABORTED; - } - } else { - // - // File does not have a checksum - // Verify contents are 0x5A as spec'd - // - if (FfsHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) { - Error (NULL, 0, 0, FileGuidString, "invalid fixed FFS file header checksum"); - return EFI_ABORTED; - } - } - // - // Check if the tail is present and verify it if it is. - // - if (FfsHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) { - // - // Verify tail is complement of integrity check field in the header. - // - Tail = (EFI_FFS_FILE_TAIL *) ((UINTN) FfsHeader + GetLength (FfsHeader->Size) - sizeof (EFI_FFS_FILE_TAIL)); - if (FfsHeader->IntegrityCheck.TailReference != (EFI_FFS_FILE_TAIL)~(*Tail)) { - Error (NULL, 0, 0, FileGuidString, "invalid FFS file tail"); - return EFI_ABORTED; - } - } - - return EFI_SUCCESS; -} - -UINT32 -GetLength ( - UINT8 *ThreeByteLength - ) -/*++ - -Routine Description: - - Converts a three byte length value into a UINT32. - -Arguments: - - ThreeByteLength Pointer to the first of the 3 byte length. - -Returns: - - UINT32 Size of the section - ---*/ -{ - UINT32 Length; - - if (ThreeByteLength == NULL) { - return 0; - } - - Length = *((UINT32 *) ThreeByteLength); - Length = Length & 0x00FFFFFF; - - return Length; -} - -EFI_STATUS -GetErasePolarity ( - OUT BOOLEAN *ErasePolarity - ) -/*++ - -Routine Description: - - This function returns with the FV erase polarity. If the erase polarity - for a bit is 1, the function return TRUE. - -Arguments: - - ErasePolarity A pointer to the erase polarity. - -Returns: - - EFI_SUCCESS The function completed successfully. - EFI_INVALID_PARAMETER One of the input parameters was invalid. - EFI_ABORTED Operation aborted. - ---*/ -{ - EFI_STATUS Status; - - // - // Verify library has been initialized. - // - if (mFvHeader == NULL || mFvLength == 0) { - return EFI_ABORTED; - } - // - // Verify FV header - // - Status = VerifyFv (mFvHeader); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - // - // Verify input parameters. - // - if (ErasePolarity == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (mFvHeader->Attributes & EFI_FVB_ERASE_POLARITY) { - *ErasePolarity = TRUE; - } else { - *ErasePolarity = FALSE; - } - - return EFI_SUCCESS; -} - -UINT8 -GetFileState ( - IN BOOLEAN ErasePolarity, - IN EFI_FFS_FILE_HEADER *FfsHeader - ) -/*++ - -Routine Description: - - This function returns a the highest state bit in the FFS that is set. - It in no way validate the FFS file. - -Arguments: - - ErasePolarity The erase polarity for the file state bits. - FfsHeader Pointer to a FFS file. - -Returns: - - UINT8 The hightest set state of the file. - ---*/ -{ - UINT8 FileState; - UINT8 HighestBit; - - FileState = FfsHeader->State; - - if (ErasePolarity) { - FileState = (UINT8)~FileState; - } - - HighestBit = 0x80; - while (HighestBit != 0 && (HighestBit & FileState) == 0) { - HighestBit >>= 1; - } - - return HighestBit; -} diff --git a/Tools/CodeTools/TianoTools/Common/FvLib.h b/Tools/CodeTools/TianoTools/Common/FvLib.h deleted file mode 100644 index 1ad1e812dd..0000000000 --- a/Tools/CodeTools/TianoTools/Common/FvLib.h +++ /dev/null @@ -1,181 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - FvLib.h - -Abstract: - - These functions assist in parsing and manipulating a Firmware Volume. - ---*/ - -#ifndef _EFI_FV_LIB_H -#define _EFI_FV_LIB_H - -// -// Include files -// -#include - -#include -#include -#include -#include -#include -#include - -EFI_STATUS -InitializeFvLib ( - IN VOID *Fv, - IN UINT32 FvLength - ) -; - -EFI_STATUS -GetFvHeader ( - OUT EFI_FIRMWARE_VOLUME_HEADER **FvHeader, - OUT UINT32 *FvLength - ) -; - -EFI_STATUS -GetNextFile ( - IN EFI_FFS_FILE_HEADER *CurrentFile, - OUT EFI_FFS_FILE_HEADER **NextFile - ) -; - -EFI_STATUS -GetFileByName ( - IN EFI_GUID *FileName, - OUT EFI_FFS_FILE_HEADER **File - ) -; - -EFI_STATUS -GetFileByType ( - IN EFI_FV_FILETYPE FileType, - IN UINTN Instance, - OUT EFI_FFS_FILE_HEADER **File - ) -; - -EFI_STATUS -GetSectionByType ( - IN EFI_FFS_FILE_HEADER *File, - IN EFI_SECTION_TYPE SectionType, - IN UINTN Instance, - OUT EFI_FILE_SECTION_POINTER *Section - ) -; -// -// will not parse compressed sections -// -EFI_STATUS -VerifyFv ( - IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader - ) -; - -EFI_STATUS -VerifyFfsFile ( - IN EFI_FFS_FILE_HEADER *FfsHeader - ) -; - -/*++ - -Routine Description: - - Verify the current pointer points to a FFS file header. - -Arguments: - - FfsHeader Pointer to an alleged FFS file. - -Returns: - - EFI_SUCCESS The Ffs header is valid. - EFI_NOT_FOUND This "file" is the beginning of free space. - EFI_VOLUME_CORRUPTED The Ffs header is not valid. - ---*/ -UINT32 -GetLength ( - UINT8 *ThreeByteLength - ) -; - -/*++ - -Routine Description: - - Converts a three byte length value into a UINT32. - -Arguments: - - ThreeByteLength Pointer to the first of the 3 byte length. - -Returns: - - UINT32 Size of the section - ---*/ -EFI_STATUS -GetErasePolarity ( - OUT BOOLEAN *ErasePolarity - ) -; - -/*++ - -Routine Description: - - This function returns with the FV erase polarity. If the erase polarity - for a bit is 1, the function return TRUE. - -Arguments: - - ErasePolarity A pointer to the erase polarity. - -Returns: - - EFI_SUCCESS The function completed successfully. - EFI_INVALID_PARAMETER One of the input parameters was invalid. - ---*/ -UINT8 -GetFileState ( - IN BOOLEAN ErasePolarity, - IN EFI_FFS_FILE_HEADER *FfsHeader - ) -; - -/*++ - -Routine Description: - - This function returns a the highest state bit in the FFS that is set. - It in no way validate the FFS file. - -Arguments: - - ErasePolarity The erase polarity for the file state bits. - FfsHeader Pointer to a FFS file. - -Returns: - - UINT8 The hightest set state of the file. - ---*/ -#endif diff --git a/Tools/CodeTools/TianoTools/Common/MyAlloc.c b/Tools/CodeTools/TianoTools/Common/MyAlloc.c deleted file mode 100644 index 39fddf7428..0000000000 --- a/Tools/CodeTools/TianoTools/Common/MyAlloc.c +++ /dev/null @@ -1,516 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - MyAlloc.c - -Abstract: - - File for memory allocation tracking functions. - ---*/ - -#include "MyAlloc.h" - -#if USE_MYALLOC -// -// Get back to original alloc/free calls. -// -#undef malloc -#undef calloc -#undef realloc -#undef free -// -// Start of allocation list. -// -static MY_ALLOC_STRUCT *MyAllocData = NULL; - -// -// -// -static UINT32 MyAllocHeadMagik = MYALLOC_HEAD_MAGIK; -static UINT32 MyAllocTailMagik = MYALLOC_TAIL_MAGIK; - -// -// //////////////////////////////////////////////////////////////////////////// -// -// -VOID -MyCheck ( - BOOLEAN Final, - UINT8 File[], - UINTN Line - ) -// *++ -// Description: -// -// Check for corruptions in the allocated memory chain. If a corruption -// is detection program operation stops w/ an exit(1) call. -// -// Parameters: -// -// Final := When FALSE, MyCheck() returns if the allocated memory chain -// has not been corrupted. When TRUE, MyCheck() returns if there -// are no un-freed allocations. If there are un-freed allocations, -// they are displayed and exit(1) is called. -// -// -// File := Set to __FILE__ by macro expansion. -// -// Line := Set to __LINE__ by macro expansion. -// -// Returns: -// -// n/a -// -// --*/ -// -{ - MY_ALLOC_STRUCT *Tmp; - - // - // Check parameters. - // - if (File == NULL || Line == 0) { - printf ( - "\nMyCheck(Final=%u, File=%xh, Line=%u)" - "Invalid parameter(s).\n", - Final, - File, - Line - ); - - exit (1); - } - - if (strlen (File) == 0) { - printf ( - "\nMyCheck(Final=%u, File=%s, Line=%u)" - "Invalid parameter.\n", - Final, - File, - Line - ); - - exit (1); - } - // - // Check structure contents. - // - for (Tmp = MyAllocData; Tmp != NULL; Tmp = Tmp->Next) { - if (memcmp(Tmp->Buffer, &MyAllocHeadMagik, sizeof MyAllocHeadMagik) || - memcmp(&Tmp->Buffer[Tmp->Size + sizeof(UINT32)], &MyAllocTailMagik, sizeof MyAllocTailMagik)) { - break; - } - } - // - // If Tmp is not NULL, the structure is corrupt. - // - if (Tmp != NULL) { - printf ( - "\nMyCheck(Final=%u, File=%s, Line=%u)""\nStructure corrupted!" - "\nFile=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n", - Final, - File, - Line, - Tmp->File, - Tmp->Line, - Tmp->Size, - *(UINT32 *) (Tmp->Buffer), - *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)]) - ); - - exit (1); - } - // - // If Final is TRUE, display the state of the structure chain. - // - if (Final) { - if (MyAllocData != NULL) { - printf ( - "\nMyCheck(Final=%u, File=%s, Line=%u)" - "\nSome allocated items have not been freed.\n", - Final, - File, - Line - ); - - for (Tmp = MyAllocData; Tmp != NULL; Tmp = Tmp->Next) { - printf ( - "File=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n", - Tmp->File, - Tmp->Line, - Tmp->Size, - *(UINT32 *) (Tmp->Buffer), - *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)]) - ); - } - } - } -} -// -// //////////////////////////////////////////////////////////////////////////// -// -// -VOID * -MyAlloc ( - UINTN Size, - UINT8 File[], - UINTN Line - ) -// *++ -// Description: -// -// Allocate a new link in the allocation chain along with enough storage -// for the File[] string, requested Size and alignment overhead. If -// memory cannot be allocated or the allocation chain has been corrupted, -// exit(1) will be called. -// -// Parameters: -// -// Size := Number of bytes (UINT8) requested by the called. -// Size cannot be zero. -// -// File := Set to __FILE__ by macro expansion. -// -// Line := Set to __LINE__ by macro expansion. -// -// Returns: -// -// Pointer to the caller's buffer. -// -// --*/ -// -{ - MY_ALLOC_STRUCT *Tmp; - UINTN Len; - - // - // Check for invalid parameters. - // - if (Size == 0 || File == NULL || Line == 0) { - printf ( - "\nMyAlloc(Size=%u, File=%xh, Line=%u)" - "\nInvalid parameter(s).\n", - Size, - File, - Line - ); - - exit (1); - } - - Len = strlen (File); - if (Len == 0) { - printf ( - "\nMyAlloc(Size=%u, File=%s, Line=%u)" - "\nInvalid parameter.\n", - Size, - File, - Line - ); - - exit (1); - } - // - // Check the allocation list for corruption. - // - MyCheck (0, __FILE__, __LINE__); - - // - // Allocate a new entry. - // - Tmp = calloc ( - 1, - sizeof (MY_ALLOC_STRUCT) + Len + 1 + sizeof (UINT64) + Size + (sizeof MyAllocHeadMagik) + (sizeof MyAllocTailMagik) - ); - - if (Tmp == NULL) { - printf ( - "\nMyAlloc(Size=%u, File=%s, Line=%u)" - "\nOut of memory.\n", - Size, - File, - Line - ); - - exit (1); - } - // - // Fill in the new entry. - // - Tmp->File = ((UINT8 *) Tmp) + sizeof (MY_ALLOC_STRUCT); - strcpy (Tmp->File, File); - Tmp->Line = Line; - Tmp->Size = Size; - Tmp->Buffer = (UINT8 *) (((UINTN) Tmp + Len + 9) &~7); - - memcpy (Tmp->Buffer, &MyAllocHeadMagik, sizeof MyAllocHeadMagik); - - memcpy ( - &Tmp->Buffer[Size + sizeof (UINT32)], - &MyAllocTailMagik, - sizeof MyAllocTailMagik - ); - - Tmp->Next = MyAllocData; - Tmp->Cksum = (UINTN) Tmp + (UINTN) (Tmp->Next) + Tmp->Line + Tmp->Size + (UINTN) (Tmp->File) + (UINTN) (Tmp->Buffer); - - MyAllocData = Tmp; - - return Tmp->Buffer + sizeof (UINT32); -} -// -// //////////////////////////////////////////////////////////////////////////// -// -// -VOID * -MyRealloc ( - VOID *Ptr, - UINTN Size, - UINT8 File[], - UINTN Line - ) -// *++ -// Description: -// -// This does a MyAlloc(), memcpy() and MyFree(). There is no optimization -// for shrinking or expanding buffers. An invalid parameter will cause -// MyRealloc() to fail with a call to exit(1). -// -// Parameters: -// -// Ptr := Pointer to the caller's buffer to be re-allocated. -// -// Size := Size of new buffer. Size cannot be zero. -// -// File := Set to __FILE__ by macro expansion. -// -// Line := Set to __LINE__ by macro expansion. -// -// Returns: -// -// Pointer to new caller's buffer. -// -// --*/ -// -{ - MY_ALLOC_STRUCT *Tmp; - VOID *Buffer; - - // - // Check for invalid parameter(s). - // - if (Size == 0 || File == NULL || Line == 0) { - printf ( - "\nMyRealloc(Ptr=%xh, Size=%u, File=%xh, Line=%u)" - "\nInvalid parameter(s).\n", - Ptr, - Size, - File, - Line - ); - - exit (1); - } - - if (strlen (File) == 0) { - printf ( - "\nMyRealloc(Ptr=%xh, Size=%u, File=%s, Line=%u)" - "\nInvalid parameter.\n", - Ptr, - Size, - File, - Line - ); - - exit (1); - } - // - // Find existing buffer in allocation list. - // - if (Ptr == NULL) { - Tmp = NULL; - } else if (&MyAllocData->Buffer[sizeof (UINT32)] == Ptr) { - Tmp = MyAllocData; - } else { - for (Tmp = MyAllocData;; Tmp = Tmp->Next) { - if (Tmp->Next == NULL) { - printf ( - "\nMyRealloc(Ptr=%xh, Size=%u, File=%s, Line=%u)" - "\nCould not find buffer.\n", - Ptr, - Size, - File, - Line - ); - - exit (1); - } - - Tmp = Tmp->Next; - } - } - // - // Allocate new buffer, copy old data, free old buffer. - // - Buffer = MyAlloc (Size, File, Line); - - if (Buffer != NULL && Tmp != NULL) { - memcpy ( - Buffer, - &Tmp->Buffer[sizeof (UINT32)], - ((Size <= Tmp->Size) ? Size : Tmp->Size) - ); - - MyFree (Ptr, __FILE__, __LINE__); - } - - return Buffer; -} -// -// //////////////////////////////////////////////////////////////////////////// -// -// -VOID -MyFree ( - VOID *Ptr, - UINT8 File[], - UINTN Line - ) -// *++ -// Description: -// -// Release a previously allocated buffer. Invalid parameters will cause -// MyFree() to fail with an exit(1) call. -// -// Parameters: -// -// Ptr := Pointer to the caller's buffer to be freed. -// A NULL pointer will be ignored. -// -// File := Set to __FILE__ by macro expansion. -// -// Line := Set to __LINE__ by macro expansion. -// -// Returns: -// -// n/a -// -// --*/ -// -{ - MY_ALLOC_STRUCT *Tmp; - MY_ALLOC_STRUCT *Tmp2; - - // - // Check for invalid parameter(s). - // - if (File == NULL || Line == 0) { - printf ( - "\nMyFree(Ptr=%xh, File=%xh, Line=%u)" - "\nInvalid parameter(s).\n", - Ptr, - File, - Line - ); - - exit (1); - } - - if (strlen (File) == 0) { - printf ( - "\nMyFree(Ptr=%xh, File=%s, Line=%u)" - "\nInvalid parameter.\n", - Ptr, - File, - Line - ); - - exit (1); - } - // - // Freeing NULL is always valid. - // - if (Ptr == NULL) { - return ; - } - // - // Fail if nothing is allocated. - // - if (MyAllocData == NULL) { - printf ( - "\nMyFree(Ptr=%xh, File=%s, Line=%u)" - "\nCalled before memory allocated.\n", - Ptr, - File, - Line - ); - - exit (1); - } - // - // Check for corrupted allocation list. - // - MyCheck (0, __FILE__, __LINE__); - - // - // Need special check for first item in list. - // - if (&MyAllocData->Buffer[sizeof (UINT32)] == Ptr) { - // - // Unlink first item in list. - // - Tmp = MyAllocData; - MyAllocData = MyAllocData->Next; - } else { - // - // Walk list looking for matching item. - // - for (Tmp = MyAllocData;; Tmp = Tmp->Next) { - // - // Fail if end of list is reached. - // - if (Tmp->Next == NULL) { - printf ( - "\nMyFree(Ptr=%xh, File=%s, Line=%u)\n" - "\nNot found.\n", - Ptr, - File, - Line - ); - - exit (1); - } - // - // Leave loop when match is found. - // - if (&Tmp->Next->Buffer[sizeof (UINT32)] == Ptr) { - break; - } - } - // - // Unlink item from list. - // - Tmp2 = Tmp->Next; - Tmp->Next = Tmp->Next->Next; - Tmp = Tmp2; - } - // - // Release item. - // - free (Tmp); -} - -#endif /* USE_MYALLOC */ - -/* eof - MyAlloc.c */ diff --git a/Tools/CodeTools/TianoTools/Common/MyAlloc.h b/Tools/CodeTools/TianoTools/Common/MyAlloc.h deleted file mode 100644 index 9697012d7d..0000000000 --- a/Tools/CodeTools/TianoTools/Common/MyAlloc.h +++ /dev/null @@ -1,222 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - MyAlloc.h - -Abstract: - - Header file for memory allocation tracking functions. - ---*/ - -#ifndef _MYALLOC_H_ -#define _MYALLOC_H_ - -#include -#include -#include - -#include - -// -// Default operation is to use the memory allocation tracking functions. -// To over-ride add "#define USE_MYALLOC 0" to your program header and/or -// source files as needed. Or, just do not include this header file in -// your project. -// -#ifndef USE_MYALLOC -#define USE_MYALLOC 1 -#endif - -#if USE_MYALLOC -// -// Replace C library allocation routines with MyAlloc routines. -// -#define malloc(size) MyAlloc ((size), __FILE__, __LINE__) -#define calloc(count, size) MyAlloc ((count) * (size), __FILE__, __LINE__) -#define realloc(ptr, size) MyRealloc ((ptr), (size), __FILE__, __LINE__) -#define free(ptr) MyFree ((ptr), __FILE__, __LINE__) -#define alloc_check(final) MyCheck ((final), __FILE__, __LINE__) - -// -// Structure for checking/tracking memory allocations. -// -typedef struct MyAllocStruct { - UINTN Cksum; - struct MyAllocStruct *Next; - UINTN Line; - UINTN Size; - UINT8 *File; - UINT8 *Buffer; -} MY_ALLOC_STRUCT; -// -// Cksum := (UINTN)This + (UINTN)Next + Line + Size + (UINTN)File + -// (UINTN)Buffer; -// -// Next := Pointer to next allocation structure in the list. -// -// Line := __LINE__ -// -// Size := Size of allocation request. -// -// File := Pointer to __FILE__ string stored immediately following -// MY_ALLOC_STRUCT in memory. -// -// Buffer := Pointer to UINT32 aligned storage immediately following -// the NULL terminated __FILE__ string. This is UINT32 -// aligned because the underflow signature is 32-bits and -// this will place the first caller address on a 64-bit -// boundary. -// -// -// Signatures used to check for buffer overflow/underflow conditions. -// -#define MYALLOC_HEAD_MAGIK 0xBADFACED -#define MYALLOC_TAIL_MAGIK 0xDEADBEEF - -VOID -MyCheck ( - BOOLEAN Final, - UINT8 File[], - UINTN Line - ) -; -// -// *++ -// Description: -// -// Check for corruptions in the allocated memory chain. If a corruption -// is detection program operation stops w/ an exit(1) call. -// -// Parameters: -// -// Final := When FALSE, MyCheck() returns if the allocated memory chain -// has not been corrupted. When TRUE, MyCheck() returns if there -// are no un-freed allocations. If there are un-freed allocations, -// they are displayed and exit(1) is called. -// -// -// File := Set to __FILE__ by macro expansion. -// -// Line := Set to __LINE__ by macro expansion. -// -// Returns: -// -// n/a -// -// --*/ -// -VOID * -MyAlloc ( - UINTN Size, - UINT8 File[], - UINTN Line - ) -; -// -// *++ -// Description: -// -// Allocate a new link in the allocation chain along with enough storage -// for the File[] string, requested Size and alignment overhead. If -// memory cannot be allocated or the allocation chain has been corrupted, -// exit(1) will be called. -// -// Parameters: -// -// Size := Number of bytes (UINT8) requested by the called. -// Size cannot be zero. -// -// File := Set to __FILE__ by macro expansion. -// -// Line := Set to __LINE__ by macro expansion. -// -// Returns: -// -// Pointer to the caller's buffer. -// -// --*/ -// -VOID * -MyRealloc ( - VOID *Ptr, - UINTN Size, - UINT8 File[], - UINTN Line - ) -; -// -// *++ -// Description: -// -// This does a MyAlloc(), memcpy() and MyFree(). There is no optimization -// for shrinking or expanding buffers. An invalid parameter will cause -// MyRealloc() to fail with a call to exit(1). -// -// Parameters: -// -// Ptr := Pointer to the caller's buffer to be re-allocated. -// Ptr cannot be NULL. -// -// Size := Size of new buffer. Size cannot be zero. -// -// File := Set to __FILE__ by macro expansion. -// -// Line := Set to __LINE__ by macro expansion. -// -// Returns: -// -// Pointer to new caller's buffer. -// -// --*/ -// -VOID -MyFree ( - VOID *Ptr, - UINT8 File[], - UINTN Line - ) -; -// -// *++ -// Description: -// -// Release a previously allocated buffer. Invalid parameters will cause -// MyFree() to fail with an exit(1) call. -// -// Parameters: -// -// Ptr := Pointer to the caller's buffer to be freed. -// A NULL pointer will be ignored. -// -// File := Set to __FILE__ by macro expansion. -// -// Line := Set to __LINE__ by macro expansion. -// -// Returns: -// -// n/a -// -// --*/ -// -#else /* USE_MYALLOC */ - -// -// Nothing to do when USE_MYALLOC is zero. -// -#define alloc_check(final) - -#endif /* USE_MYALLOC */ -#endif /* _MYALLOC_H_ */ - -/* eof - MyAlloc.h */ diff --git a/Tools/CodeTools/TianoTools/Common/ParseInf.c b/Tools/CodeTools/TianoTools/Common/ParseInf.c deleted file mode 100644 index de0ffd85c7..0000000000 --- a/Tools/CodeTools/TianoTools/Common/ParseInf.c +++ /dev/null @@ -1,630 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - ParseInf.c - -Abstract: - - This contains some useful functions for parsing INF files. - ---*/ - -#include -#include -#include -#include -#include "ParseInf.h" - -#ifndef _MAX_PATH -#define _MAX_PATH 500 -#endif - -CHAR8 * -ReadLine ( - IN MEMORY_FILE *InputFile, - IN OUT CHAR8 *InputBuffer, - IN UINTN MaxLength - ) -/*++ - -Routine Description: - - This function reads a line, stripping any comments. - The function reads a string from the input stream argument and stores it in - the input string. ReadLine reads characters from the current file position - to and including the first newline character, to the end of the stream, or - until the number of characters read is equal to MaxLength - 1, whichever - comes first. The newline character, if read, is replaced with a \0. - -Arguments: - - InputFile Memory file image. - InputBuffer Buffer to read into, must be _MAX_PATH size. - MaxLength The maximum size of the input buffer. - -Returns: - - NULL if error or EOF - InputBuffer otherwise - ---*/ -{ - CHAR8 *CharPtr; - CHAR8 *EndOfLine; - UINTN CharsToCopy; - - // - // Verify input parameters are not null - // - assert (InputBuffer); - assert (InputFile->FileImage); - assert (InputFile->Eof); - assert (InputFile->CurrentFilePointer); - - // - // Check for end of file condition - // - if (InputFile->CurrentFilePointer >= InputFile->Eof) { - return NULL; - } - // - // Find the next newline char - // - EndOfLine = strchr (InputFile->CurrentFilePointer, '\n'); - - // - // Determine the number of characters to copy. - // - if (EndOfLine == 0) { - // - // If no newline found, copy to the end of the file. - // - CharsToCopy = InputFile->Eof - InputFile->CurrentFilePointer; - } else if (EndOfLine >= InputFile->Eof) { - // - // If the newline found was beyond the end of file, copy to the eof. - // - CharsToCopy = InputFile->Eof - InputFile->CurrentFilePointer; - } else { - // - // Newline found in the file. - // - CharsToCopy = EndOfLine - InputFile->CurrentFilePointer; - } - // - // If the end of line is too big for the current buffer, set it to the max - // size of the buffer (leaving room for the \0. - // - if (CharsToCopy > MaxLength - 1) { - CharsToCopy = MaxLength - 1; - } - // - // Copy the line. - // - memcpy (InputBuffer, InputFile->CurrentFilePointer, CharsToCopy); - - // - // Add the null termination over the 0x0D - // - InputBuffer[CharsToCopy - 1] = '\0'; - - // - // Increment the current file pointer (include the 0x0A) - // - InputFile->CurrentFilePointer += CharsToCopy + 1; - - // - // Strip any comments - // - CharPtr = strstr (InputBuffer, "//"); - if (CharPtr != 0) { - CharPtr[0] = 0; - } - // - // Return the string - // - return InputBuffer; -} - -BOOLEAN -FindSection ( - IN MEMORY_FILE *InputFile, - IN CHAR8 *Section - ) -/*++ - -Routine Description: - - This function parses a file from the beginning to find a section. - The section string may be anywhere within a line. - -Arguments: - - InputFile Memory file image. - Section Section to search for - -Returns: - - FALSE if error or EOF - TRUE if section found - ---*/ -{ - CHAR8 InputBuffer[_MAX_PATH]; - CHAR8 *CurrentToken; - - // - // Verify input is not NULL - // - assert (InputFile->FileImage); - assert (InputFile->Eof); - assert (InputFile->CurrentFilePointer); - assert (Section); - - // - // Rewind to beginning of file - // - InputFile->CurrentFilePointer = InputFile->FileImage; - - // - // Read lines until the section is found - // - while (InputFile->CurrentFilePointer < InputFile->Eof) { - // - // Read a line - // - ReadLine (InputFile, InputBuffer, _MAX_PATH); - - // - // Check if the section is found - // - CurrentToken = strstr (InputBuffer, Section); - if (CurrentToken != NULL) { - return TRUE; - } - } - - return FALSE; -} - -EFI_STATUS -FindToken ( - IN MEMORY_FILE *InputFile, - IN CHAR8 *Section, - IN CHAR8 *Token, - IN UINTN Instance, - OUT CHAR8 *Value - ) -/*++ - -Routine Description: - - Finds a token value given the section and token to search for. - -Arguments: - - InputFile Memory file image. - Section The section to search for, a string within []. - Token The token to search for, e.g. EFI_PEIM_RECOVERY, followed by an = in the INF file. - Instance The instance of the token to search for. Zero is the first instance. - Value The string that holds the value following the =. Must be _MAX_PATH in size. - -Returns: - - EFI_SUCCESS Value found. - EFI_ABORTED Format error detected in INF file. - EFI_INVALID_PARAMETER Input argument was null. - EFI_LOAD_ERROR Error reading from the file. - EFI_NOT_FOUND Section/Token/Value not found. - ---*/ -{ - CHAR8 InputBuffer[_MAX_PATH]; - CHAR8 *CurrentToken; - BOOLEAN ParseError; - BOOLEAN ReadError; - UINTN Occurrance; - - // - // Check input parameters - // - if (InputFile->FileImage == NULL || - InputFile->Eof == NULL || - InputFile->CurrentFilePointer == NULL || - Section == NULL || - strlen (Section) == 0 || - Token == NULL || - strlen (Token) == 0 || - Value == NULL - ) { - return EFI_INVALID_PARAMETER; - } - // - // Initialize error codes - // - ParseError = FALSE; - ReadError = FALSE; - - // - // Initialize our instance counter for the search token - // - Occurrance = 0; - - if (FindSection (InputFile, Section)) { - // - // Found the desired section, find and read the desired token - // - do { - // - // Read a line from the file - // - if (ReadLine (InputFile, InputBuffer, _MAX_PATH) == NULL) { - // - // Error reading from input file - // - ReadError = TRUE; - break; - } - // - // Get the first non-whitespace string - // - CurrentToken = strtok (InputBuffer, " \t\n"); - if (CurrentToken == NULL) { - // - // Whitespace line found (or comment) so continue - // - CurrentToken = InputBuffer; - continue; - } - // - // Make sure we have not reached the end of the current section - // - if (CurrentToken[0] == '[') { - break; - } - // - // Compare the current token with the desired token - // - if (strcmp (CurrentToken, Token) == 0) { - // - // Found it - // - // - // Check if it is the correct instance - // - if (Instance == Occurrance) { - // - // Copy the contents following the = - // - CurrentToken = strtok (NULL, "= \t\n"); - if (CurrentToken == NULL) { - // - // Nothing found, parsing error - // - ParseError = TRUE; - } else { - // - // Copy the current token to the output value - // - strcpy (Value, CurrentToken); - return EFI_SUCCESS; - } - } else { - // - // Increment the occurrance found - // - Occurrance++; - } - } - } while ( - !ParseError && - !ReadError && - InputFile->CurrentFilePointer < InputFile->Eof && - CurrentToken[0] != '[' && - Occurrance <= Instance - ); - } - // - // Distinguish between read errors and INF file format errors. - // - if (ReadError) { - return EFI_LOAD_ERROR; - } - - if (ParseError) { - return EFI_ABORTED; - } - - return EFI_NOT_FOUND; -} - -EFI_STATUS -StringToGuid ( - IN CHAR8 *AsciiGuidBuffer, - OUT EFI_GUID *GuidBuffer - ) -/*++ - -Routine Description: - - Converts a string to an EFI_GUID. The string must be in the - xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format. - -Arguments: - - AsciiGuidBuffer - pointer to ascii string - GuidBuffer - pointer to destination Guid - -Returns: - - EFI_ABORTED Could not convert the string - EFI_SUCCESS The string was successfully converted - EFI_INVALID_PARAMETER Input parameter is invalid. - ---*/ -{ - INT32 Index; - UINTN Data1; - UINTN Data2; - UINTN Data3; - UINTN Data4[8]; - - if (AsciiGuidBuffer == NULL || GuidBuffer == NULL) { - return EFI_INVALID_PARAMETER; - } - // - // Scan the guid string into the buffer - // - Index = sscanf ( - AsciiGuidBuffer, - "%08x-%04x-%04x-%02x%02x-%02hx%02hx%02hx%02hx%02hx%02hx", - &Data1, - &Data2, - &Data3, - &Data4[0], - &Data4[1], - &Data4[2], - &Data4[3], - &Data4[4], - &Data4[5], - &Data4[6], - &Data4[7] - ); - - // - // Verify the correct number of items were scanned. - // - if (Index != 11) { - printf ("ERROR: Malformed GUID \"%s\".\n\n", AsciiGuidBuffer); - return EFI_ABORTED; - } - // - // Copy the data into our GUID. - // - GuidBuffer->Data1 = (UINT32) Data1; - GuidBuffer->Data2 = (UINT16) Data2; - GuidBuffer->Data3 = (UINT16) Data3; - GuidBuffer->Data4[0] = (UINT8) Data4[0]; - GuidBuffer->Data4[1] = (UINT8) Data4[1]; - GuidBuffer->Data4[2] = (UINT8) Data4[2]; - GuidBuffer->Data4[3] = (UINT8) Data4[3]; - GuidBuffer->Data4[4] = (UINT8) Data4[4]; - GuidBuffer->Data4[5] = (UINT8) Data4[5]; - GuidBuffer->Data4[6] = (UINT8) Data4[6]; - GuidBuffer->Data4[7] = (UINT8) Data4[7]; - - return EFI_SUCCESS; -} - -EFI_STATUS -AsciiStringToUint64 ( - IN CONST CHAR8 *AsciiString, - IN BOOLEAN IsHex, - OUT UINT64 *ReturnValue - ) -/*++ - -Routine Description: - - Converts a null terminated ascii string that represents a number into a - UINT64 value. A hex number may be preceeded by a 0x, but may not be - succeeded by an h. A number without 0x or 0X is considered to be base 10 - unless the IsHex input is true. - -Arguments: - - AsciiString The string to convert. - IsHex Force the string to be treated as a hex number. - ReturnValue The return value. - -Returns: - - EFI_SUCCESS Number successfully converted. - EFI_ABORTED Invalid character encountered. - ---*/ -{ - UINT8 Index; - UINT64 HexNumber; - CHAR8 CurrentChar; - - // - // Initialize the result - // - HexNumber = 0; - - // - // Add each character to the result - // - if (IsHex || (AsciiString[0] == '0' && (AsciiString[1] == 'x' || AsciiString[1] == 'X'))) { - // - // Verify string is a hex number - // - for (Index = 2; Index < strlen (AsciiString); Index++) { - if (isxdigit (AsciiString[Index]) == 0) { - return EFI_ABORTED; - } - } - // - // Convert the hex string. - // - for (Index = 2; AsciiString[Index] != '\0'; Index++) { - CurrentChar = AsciiString[Index]; - HexNumber *= 16; - if (CurrentChar >= '0' && CurrentChar <= '9') { - HexNumber += CurrentChar - '0'; - } else if (CurrentChar >= 'a' && CurrentChar <= 'f') { - HexNumber += CurrentChar - 'a' + 10; - } else if (CurrentChar >= 'A' && CurrentChar <= 'F') { - HexNumber += CurrentChar - 'A' + 10; - } else { - // - // Unrecognized character - // - return EFI_ABORTED; - } - } - - *ReturnValue = HexNumber; - } else { - // - // Verify string is a number - // - for (Index = 0; Index < strlen (AsciiString); Index++) { - if (isdigit (AsciiString[Index]) == 0) { - return EFI_ABORTED; - } - } - - *ReturnValue = atol (AsciiString); - } - - return EFI_SUCCESS; -}; - -CHAR8 * -ReadLineInStream ( - IN FILE *InputFile, - IN OUT CHAR8 *InputBuffer - ) -/*++ - -Routine Description: - - This function reads a line, stripping any comments. - // BUGBUG: This is obsolete once genmake goes away... - -Arguments: - - InputFile Stream pointer. - InputBuffer Buffer to read into, must be _MAX_PATH size. - -Returns: - - NULL if error or EOF - InputBuffer otherwise - ---*/ -{ - CHAR8 *CharPtr; - - // - // Verify input parameters are not null - // - assert (InputFile); - assert (InputBuffer); - - // - // Read a line - // - if (fgets (InputBuffer, _MAX_PATH, InputFile) == NULL) { - return NULL; - } - // - // Strip any comments - // - CharPtr = strstr (InputBuffer, "//"); - if (CharPtr != 0) { - CharPtr[0] = 0; - } - - CharPtr = strstr (InputBuffer, "#"); - if (CharPtr != 0) { - CharPtr[0] = 0; - } - // - // Return the string - // - return InputBuffer; -} - -BOOLEAN -FindSectionInStream ( - IN FILE *InputFile, - IN CHAR8 *Section - ) -/*++ - -Routine Description: - - This function parses a stream file from the beginning to find a section. - The section string may be anywhere within a line. - // BUGBUG: This is obsolete once genmake goes away... - -Arguments: - - InputFile Stream pointer. - Section Section to search for - -Returns: - - FALSE if error or EOF - TRUE if section found - ---*/ -{ - CHAR8 InputBuffer[_MAX_PATH]; - CHAR8 *CurrentToken; - - // - // Verify input is not NULL - // - assert (InputFile); - assert (Section); - - // - // Rewind to beginning of file - // - if (fseek (InputFile, 0, SEEK_SET) != 0) { - return FALSE; - } - // - // Read lines until the section is found - // - while (feof (InputFile) == 0) { - // - // Read a line - // - ReadLineInStream (InputFile, InputBuffer); - - // - // Check if the section is found - // - CurrentToken = strstr (InputBuffer, Section); - if (CurrentToken != NULL) { - return TRUE; - } - } - - return FALSE; -} diff --git a/Tools/CodeTools/TianoTools/Common/ParseInf.h b/Tools/CodeTools/TianoTools/Common/ParseInf.h deleted file mode 100644 index ff986352c6..0000000000 --- a/Tools/CodeTools/TianoTools/Common/ParseInf.h +++ /dev/null @@ -1,234 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - ParseInf.h - -Abstract: - - Header file for helper functions useful for parsing INF files. - ---*/ - -#ifndef _EFI_PARSE_INF_H -#define _EFI_PARSE_INF_H - -#include -#include - -#include - -// -// Common data structures -// -typedef struct { - CHAR8 *FileImage; - CHAR8 *Eof; - CHAR8 *CurrentFilePointer; -} MEMORY_FILE; - -// -// Functions declarations -// -CHAR8 * -ReadLine ( - IN MEMORY_FILE *InputFile, - IN OUT CHAR8 *InputBuffer, - IN UINTN MaxLength - ) -; - -/*++ - -Routine Description: - - This function reads a line, stripping any comments. - The function reads a string from the input stream argument and stores it in - the input string. ReadLine reads characters from the current file position - to and including the first newline character, to the end of the stream, or - until the number of characters read is equal to MaxLength - 1, whichever - comes first. The newline character, if read, is replaced with a \0. - -Arguments: - - InputFile Memory file image. - InputBuffer Buffer to read into, must be _MAX_PATH size. - MaxLength The maximum size of the input buffer. - -Returns: - - NULL if error or EOF - InputBuffer otherwise - ---*/ -BOOLEAN -FindSection ( - IN MEMORY_FILE *InputFile, - IN CHAR8 *Section - ) -; - -/*++ - -Routine Description: - - This function parses a file from the beginning to find a section. - The section string may be anywhere within a line. - -Arguments: - - InputFile Memory file image. - Section Section to search for - -Returns: - - FALSE if error or EOF - TRUE if section found - ---*/ -EFI_STATUS -FindToken ( - IN MEMORY_FILE *InputFile, - IN CHAR8 *Section, - IN CHAR8 *Token, - IN UINTN Instance, - OUT CHAR8 *Value - ) -; - -/*++ - -Routine Description: - - Finds a token value given the section and token to search for. - -Arguments: - - InputFile Memory file image. - Section The section to search for, a string within []. - Token The token to search for, e.g. EFI_PEIM_RECOVERY, followed by an = in the INF file. - Instance The instance of the token to search for. Zero is the first instance. - Value The string that holds the value following the =. Must be _MAX_PATH in size. - -Returns: - - EFI_SUCCESS Value found. - EFI_ABORTED Format error detected in INF file. - EFI_INVALID_PARAMETER Input argument was null. - EFI_LOAD_ERROR Error reading from the file. - EFI_NOT_FOUND Section/Token/Value not found. - ---*/ -EFI_STATUS -StringToGuid ( - IN CHAR8 *AsciiGuidBuffer, - OUT EFI_GUID *GuidBuffer - ) -; - -/*++ - -Routine Description: - - Converts a string to an EFI_GUID. The string must be in the - xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format. - -Arguments: - - GuidBuffer - pointer to destination Guid - AsciiGuidBuffer - pointer to ascii string - -Returns: - - EFI_ABORTED Could not convert the string - EFI_SUCCESS The string was successfully converted - ---*/ -EFI_STATUS -AsciiStringToUint64 ( - IN CONST CHAR8 *AsciiString, - IN BOOLEAN IsHex, - OUT UINT64 *ReturnValue - ) -; - -/*++ - -Routine Description: - - Converts a null terminated ascii string that represents a number into a - UINT64 value. A hex number may be preceeded by a 0x, but may not be - succeeded by an h. A number without 0x or 0X is considered to be base 10 - unless the IsHex input is true. - -Arguments: - - AsciiString The string to convert. - IsHex Force the string to be treated as a hex number. - ReturnValue The return value. - -Returns: - - EFI_SUCCESS Number successfully converted. - EFI_ABORTED Invalid character encountered. - ---*/ -CHAR8 * -ReadLineInStream ( - IN FILE *InputFile, - IN OUT CHAR8 *InputBuffer - ) -; - -/*++ - -Routine Description: - - This function reads a line, stripping any comments. - -Arguments: - - InputFile Stream pointer. - InputBuffer Buffer to read into, must be _MAX_PATH size. - -Returns: - - NULL if error or EOF - InputBuffer otherwise - ---*/ -BOOLEAN -FindSectionInStream ( - IN FILE *InputFile, - IN CHAR8 *Section - ) -; - -/*++ - -Routine Description: - - This function parses a stream file from the beginning to find a section. - The section string may be anywhere within a line. - -Arguments: - - InputFile Stream pointer. - Section Section to search for - -Returns: - - FALSE if error or EOF - TRUE if section found - ---*/ -#endif diff --git a/Tools/CodeTools/TianoTools/Common/SimpleFileParsing.c b/Tools/CodeTools/TianoTools/Common/SimpleFileParsing.c deleted file mode 100644 index 73b74cd0ff..0000000000 --- a/Tools/CodeTools/TianoTools/Common/SimpleFileParsing.c +++ /dev/null @@ -1,1457 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - SimpleFileParsing.c - -Abstract: - - Generic but simple file parsing routines. - ---*/ - -#include -#include -#include -#include - -#include "EfiUtilityMsgs.h" -#include "SimpleFileParsing.h" - -#ifndef MAX_PATH -#define MAX_PATH 255 -#endif -// -// just in case we get in an endless loop. -// -#define MAX_NEST_DEPTH 20 -// -// number of wchars -// -#define MAX_STRING_IDENTIFIER_NAME 100 - -#define MAX_LINE_LEN 400 - -#define T_CHAR_SPACE ' ' -#define T_CHAR_NULL 0 -#define T_CHAR_CR '\r' -#define T_CHAR_TAB '\t' -#define T_CHAR_LF '\n' -#define T_CHAR_SLASH '/' -#define T_CHAR_BACKSLASH '\\' -#define T_CHAR_DOUBLE_QUOTE '"' -#define T_CHAR_LC_X 'x' -#define T_CHAR_0 '0' -#define T_CHAR_STAR '*' - -// -// We keep a linked list of these for the source files we process -// -typedef struct _SOURCE_FILE { - FILE *Fptr; - T_CHAR *FileBuffer; - T_CHAR *FileBufferPtr; - unsigned int FileSize; - char FileName[MAX_PATH]; - unsigned int LineNum; - BOOLEAN EndOfFile; - BOOLEAN SkipToHash; - struct _SOURCE_FILE *Previous; - struct _SOURCE_FILE *Next; - T_CHAR ControlCharacter; -} SOURCE_FILE; - -typedef struct { - T_CHAR *FileBufferPtr; -} FILE_POSITION; - -// -// Keep all our module globals in this structure -// -static struct { - SOURCE_FILE SourceFile; - BOOLEAN VerboseFile; - BOOLEAN VerboseToken; -} mGlobals; - -static -unsigned int -t_strcmp ( - T_CHAR *Buffer, - T_CHAR *Str - ); - -static -unsigned int -t_strncmp ( - T_CHAR *Str1, - T_CHAR *Str2, - int Len - ); - -static -unsigned int -t_strlen ( - T_CHAR *Str - ); - -static -void -RewindFile ( - SOURCE_FILE *SourceFile - ); - -static -BOOLEAN -IsWhiteSpace ( - SOURCE_FILE *SourceFile - ); - -static -unsigned int -SkipWhiteSpace ( - SOURCE_FILE *SourceFile - ); - -static -BOOLEAN -EndOfFile ( - SOURCE_FILE *SourceFile - ); - -static -void -PreprocessFile ( - SOURCE_FILE *SourceFile - ); - -static -T_CHAR * -t_strcpy ( - T_CHAR *Dest, - T_CHAR *Src - ); - -static -STATUS -ProcessIncludeFile ( - SOURCE_FILE *SourceFile, - SOURCE_FILE *ParentSourceFile - ); - -static -STATUS -ParseFile ( - SOURCE_FILE *SourceFile - ); - -static -FILE * -FindFile ( - char *FileName, - char *FoundFileName, - unsigned int FoundFileNameLen - ); - -static -STATUS -ProcessFile ( - SOURCE_FILE *SourceFile - ); - -static -STATUS -GetFilePosition ( - FILE_POSITION *Fpos - ); - -static -STATUS -SetFilePosition ( - FILE_POSITION *Fpos - ); - -STATUS -SFPInit ( - VOID - ) -/*++ - -Routine Description: - -Arguments: - None. - -Returns: - STATUS_SUCCESS always - ---*/ -{ - memset ((void *) &mGlobals, 0, sizeof (mGlobals)); - return STATUS_SUCCESS; -} - -unsigned -int -SFPGetLineNumber ( - VOID - ) -/*++ - -Routine Description: - Return the line number of the file we're parsing. Used - for error reporting purposes. - -Arguments: - None. - -Returns: - The line number, or 0 if no file is being processed - ---*/ -{ - return mGlobals.SourceFile.LineNum; -} - -T_CHAR * -SFPGetFileName ( - VOID - ) -/*++ - -Routine Description: - Return the name of the file we're parsing. Used - for error reporting purposes. - -Arguments: - None. - -Returns: - A pointer to the file name. Null if no file is being - processed. - ---*/ -{ - if (mGlobals.SourceFile.FileName[0]) { - return mGlobals.SourceFile.FileName; - } - - return NULL; -} - -STATUS -SFPOpenFile ( - char *FileName - ) -/*++ - -Routine Description: - Open a file for parsing. - -Arguments: - FileName - name of the file to parse - -Returns: - - ---*/ -{ - STATUS Status; - t_strcpy (mGlobals.SourceFile.FileName, FileName); - Status = ProcessIncludeFile (&mGlobals.SourceFile, NULL); - return Status; -} - -BOOLEAN -SFPIsToken ( - T_CHAR *Str - ) -/*++ - -Routine Description: - Check to see if the specified token is found at - the current position in the input file. - -Arguments: - Str - the token to look for - -Returns: - TRUE - the token is next - FALSE - the token is not next - -Notes: - We do a simple string comparison on this function. It is - the responsibility of the caller to ensure that the token - is not a subset of some other token. - - The file pointer is advanced past the token in the input file. - ---*/ -{ - unsigned int Len; - SkipWhiteSpace (&mGlobals.SourceFile); - if (EndOfFile (&mGlobals.SourceFile)) { - return FALSE; - } - - if ((Len = t_strcmp (mGlobals.SourceFile.FileBufferPtr, Str)) > 0) { - mGlobals.SourceFile.FileBufferPtr += Len; - if (mGlobals.VerboseToken) { - printf ("Token: '%s'\n", Str); - } - - return TRUE; - } - - return FALSE; -} - -BOOLEAN -SFPIsKeyword ( - T_CHAR *Str - ) -/*++ - -Routine Description: - Check to see if the specified keyword is found at - the current position in the input file. - -Arguments: - Str - keyword to look for - -Returns: - TRUE - the keyword is next - FALSE - the keyword is not next - -Notes: - A keyword is defined as a "special" string that has a non-alphanumeric - character following it. - ---*/ -{ - unsigned int Len; - SkipWhiteSpace (&mGlobals.SourceFile); - if (EndOfFile (&mGlobals.SourceFile)) { - return FALSE; - } - - if ((Len = t_strcmp (mGlobals.SourceFile.FileBufferPtr, Str)) > 0) { - if (isalnum (mGlobals.SourceFile.FileBufferPtr[Len])) { - return FALSE; - } - - mGlobals.SourceFile.FileBufferPtr += Len; - if (mGlobals.VerboseToken) { - printf ("Token: '%s'\n", Str); - } - - return TRUE; - } - - return FALSE; -} - -BOOLEAN -SFPGetNextToken ( - T_CHAR *Str, - unsigned int Len - ) -/*++ - -Routine Description: - Get the next token from the input stream. - -Arguments: - Str - pointer to a copy of the next token - Len - size of buffer pointed to by Str - -Returns: - TRUE - next token successfully returned - FALSE - otherwise - -Notes: - Preceeding white space is ignored. - The parser's buffer pointer is advanced past the end of the - token. - ---*/ -{ - unsigned int Index; - T_CHAR TempChar; - - SkipWhiteSpace (&mGlobals.SourceFile); - if (EndOfFile (&mGlobals.SourceFile)) { - return FALSE; - } - // - // Have to have enough string for at least one char and a null-terminator - // - if (Len < 2) { - return FALSE; - } - // - // Look at the first character. If it's an identifier, then treat it - // as such - // - TempChar = mGlobals.SourceFile.FileBufferPtr[0]; - if (((TempChar >= 'a') && (TempChar <= 'z')) || ((TempChar >= 'A') && (TempChar <= 'Z')) || (TempChar == '_')) { - Str[0] = TempChar; - mGlobals.SourceFile.FileBufferPtr++; - Index = 1; - while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) { - TempChar = mGlobals.SourceFile.FileBufferPtr[0]; - if (((TempChar >= 'a') && (TempChar <= 'z')) || - ((TempChar >= 'A') && (TempChar <= 'Z')) || - ((TempChar >= '0') && (TempChar <= '9')) || - (TempChar == '_') - ) { - Str[Index] = mGlobals.SourceFile.FileBufferPtr[0]; - mGlobals.SourceFile.FileBufferPtr++; - Index++; - } else { - // - // Invalid character for symbol name, so break out - // - break; - } - } - // - // Null terminate and return success - // - Str[Index] = 0; - return TRUE; - } else if ((TempChar == ')') || (TempChar == '(') || (TempChar == '*')) { - Str[0] = mGlobals.SourceFile.FileBufferPtr[0]; - mGlobals.SourceFile.FileBufferPtr++; - Str[1] = 0; - return TRUE; - } else { - // - // Everything else is white-space (or EOF) separated - // - Index = 0; - while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) { - if (IsWhiteSpace (&mGlobals.SourceFile)) { - if (Index > 0) { - Str[Index] = 0; - return TRUE; - } - - return FALSE; - } else { - Str[Index] = mGlobals.SourceFile.FileBufferPtr[0]; - mGlobals.SourceFile.FileBufferPtr++; - Index++; - } - } - // - // See if we just ran out of file contents, but did find a token - // - if ((Index > 0) && EndOfFile (&mGlobals.SourceFile)) { - Str[Index] = 0; - return TRUE; - } - } - - return FALSE; -} - -BOOLEAN -SFPGetGuidToken ( - T_CHAR *Str, - UINT32 Len - ) -/*++ - -Routine Description: - Parse a GUID from the input stream. Stop when you discover white space. - -Arguments: - Str - pointer to a copy of the next token - Len - size of buffer pointed to by Str - -Returns: - TRUE - GUID string returned successfully - FALSE - otherwise - ---*/ -{ - UINT32 Index; - SkipWhiteSpace (&mGlobals.SourceFile); - if (EndOfFile (&mGlobals.SourceFile)) { - return FALSE; - } - - Index = 0; - while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) { - if (IsWhiteSpace (&mGlobals.SourceFile)) { - if (Index > 0) { - Str[Index] = 0; - return TRUE; - } - - return FALSE; - } else { - Str[Index] = mGlobals.SourceFile.FileBufferPtr[0]; - mGlobals.SourceFile.FileBufferPtr++; - Index++; - } - } - - return FALSE; -} - -BOOLEAN -SFPSkipToToken ( - T_CHAR *Str - ) -{ - unsigned int Len; - T_CHAR *SavePos; - Len = t_strlen (Str); - SavePos = mGlobals.SourceFile.FileBufferPtr; - SkipWhiteSpace (&mGlobals.SourceFile); - while (!EndOfFile (&mGlobals.SourceFile)) { - if (t_strncmp (Str, mGlobals.SourceFile.FileBufferPtr, Len) == 0) { - mGlobals.SourceFile.FileBufferPtr += Len; - return TRUE; - } - - mGlobals.SourceFile.FileBufferPtr++; - SkipWhiteSpace (&mGlobals.SourceFile); - } - - mGlobals.SourceFile.FileBufferPtr = SavePos; - return FALSE; -} - -BOOLEAN -SFPGetNumber ( - unsigned int *Value - ) -/*++ - -Routine Description: - Check the token at the current file position for a numeric value. - May be either decimal or hex. - -Arguments: - Value - pointer where to store the value - -Returns: - FALSE - current token is not a number - TRUE - current token is a number - ---*/ -{ - SkipWhiteSpace (&mGlobals.SourceFile); - if (EndOfFile (&mGlobals.SourceFile)) { - return FALSE; - } - - if (isdigit (mGlobals.SourceFile.FileBufferPtr[0])) { - // - // Check for hex value - // - if ((mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_0) && (mGlobals.SourceFile.FileBufferPtr[1] == T_CHAR_LC_X)) { - if (!isxdigit (mGlobals.SourceFile.FileBufferPtr[2])) { - return FALSE; - } - - mGlobals.SourceFile.FileBufferPtr += 2; - sscanf (mGlobals.SourceFile.FileBufferPtr, "%x", Value); - while (isxdigit (mGlobals.SourceFile.FileBufferPtr[0])) { - mGlobals.SourceFile.FileBufferPtr++; - } - - return TRUE; - } else { - *Value = atoi (mGlobals.SourceFile.FileBufferPtr); - while (isdigit (mGlobals.SourceFile.FileBufferPtr[0])) { - mGlobals.SourceFile.FileBufferPtr++; - } - - return TRUE; - } - } else { - return FALSE; - } -} - -STATUS -SFPCloseFile ( - VOID - ) -/*++ - -Routine Description: - Close the file being parsed. - -Arguments: - None. - -Returns: - STATUS_SUCCESS - the file was closed - STATUS_ERROR - no file is currently open - ---*/ -{ - if (mGlobals.SourceFile.FileBuffer != NULL) { - free (mGlobals.SourceFile.FileBuffer); - memset (&mGlobals.SourceFile, 0, sizeof (mGlobals.SourceFile)); - return STATUS_SUCCESS; - } - - return STATUS_ERROR; -} - -static -STATUS -ProcessIncludeFile ( - SOURCE_FILE *SourceFile, - SOURCE_FILE *ParentSourceFile - ) -/*++ - -Routine Description: - - Given a source file, open the file and parse it - -Arguments: - - SourceFile - name of file to parse - ParentSourceFile - for error reporting purposes, the file that #included SourceFile. - -Returns: - - Standard status. - ---*/ -{ - static unsigned int NestDepth = 0; - char FoundFileName[MAX_PATH]; - STATUS Status; - - Status = STATUS_SUCCESS; - NestDepth++; - // - // Print the file being processed. Indent so you can tell the include nesting - // depth. - // - if (mGlobals.VerboseFile) { - fprintf (stdout, "%*cProcessing file '%s'\n", NestDepth * 2, ' ', SourceFile->FileName); - fprintf (stdout, "Parent source file = '%s'\n", ParentSourceFile); - } - - // - // Make sure we didn't exceed our maximum nesting depth - // - if (NestDepth > MAX_NEST_DEPTH) { - Error (NULL, 0, 0, SourceFile->FileName, "max nesting depth (%d) exceeded", NestDepth); - Status = STATUS_ERROR; - goto Finish; - } - // - // Try to open the file locally, and if that fails try along our include paths. - // - strcpy (FoundFileName, SourceFile->FileName); - if ((SourceFile->Fptr = fopen (FoundFileName, "rb")) == NULL) { - return STATUS_ERROR; - } - // - // Process the file found - // - ProcessFile (SourceFile); -Finish: - // - // Close open files and return status - // - if (SourceFile->Fptr != NULL) { - fclose (SourceFile->Fptr); - SourceFile->Fptr = NULL; - } - - return Status; -} - -static -STATUS -ProcessFile ( - SOURCE_FILE *SourceFile - ) -/*++ - -Routine Description: - - Given a source file that's been opened, read the contents into an internal - buffer and pre-process it to remove comments. - -Arguments: - - SourceFile - structure containing info on the file to process - -Returns: - - Standard status. - ---*/ -{ - // - // Get the file size, and then read the entire thing into memory. - // Allocate extra space for a terminator character. - // - fseek (SourceFile->Fptr, 0, SEEK_END); - SourceFile->FileSize = ftell (SourceFile->Fptr); - if (mGlobals.VerboseFile) { - printf ("FileSize = %d (0x%X)\n", SourceFile->FileSize, SourceFile->FileSize); - } - - fseek (SourceFile->Fptr, 0, SEEK_SET); - SourceFile->FileBuffer = (T_CHAR *) malloc (SourceFile->FileSize + sizeof (T_CHAR)); - if (SourceFile->FileBuffer == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - fread ((void *) SourceFile->FileBuffer, SourceFile->FileSize, 1, SourceFile->Fptr); - SourceFile->FileBuffer[(SourceFile->FileSize / sizeof (T_CHAR))] = T_CHAR_NULL; - // - // Pre-process the file to replace comments with spaces - // - PreprocessFile (SourceFile); - SourceFile->LineNum = 1; - return STATUS_SUCCESS; -} - -static -void -PreprocessFile ( - SOURCE_FILE *SourceFile - ) -/*++ - -Routine Description: - Preprocess a file to replace all carriage returns with NULLs so - we can print lines (as part of error messages) from the file to the screen. - -Arguments: - SourceFile - structure that we use to keep track of an input file. - -Returns: - Nothing. - ---*/ -{ - BOOLEAN InComment; - BOOLEAN SlashSlashComment; - int LineNum; - - RewindFile (SourceFile); - InComment = FALSE; - SlashSlashComment = FALSE; - while (!EndOfFile (SourceFile)) { - // - // If a line-feed, then no longer in a comment if we're in a // comment - // - if (SourceFile->FileBufferPtr[0] == T_CHAR_LF) { - SourceFile->FileBufferPtr++; - SourceFile->LineNum++; - if (InComment && SlashSlashComment) { - InComment = FALSE; - SlashSlashComment = FALSE; - } - } else if (SourceFile->FileBufferPtr[0] == T_CHAR_CR) { - // - // Replace all carriage returns with a NULL so we can print stuff - // - SourceFile->FileBufferPtr[0] = 0; - SourceFile->FileBufferPtr++; - // - // Check for */ comment end - // - } else if (InComment && - !SlashSlashComment && - (SourceFile->FileBufferPtr[0] == T_CHAR_STAR) && - (SourceFile->FileBufferPtr[1] == T_CHAR_SLASH) - ) { - SourceFile->FileBufferPtr[0] = T_CHAR_SPACE; - SourceFile->FileBufferPtr++; - SourceFile->FileBufferPtr[0] = T_CHAR_SPACE; - SourceFile->FileBufferPtr++; - InComment = FALSE; - } else if (InComment) { - SourceFile->FileBufferPtr[0] = T_CHAR_SPACE; - SourceFile->FileBufferPtr++; - // - // Check for // comments - // - } else if ((SourceFile->FileBufferPtr[0] == T_CHAR_SLASH) && (SourceFile->FileBufferPtr[1] == T_CHAR_SLASH)) { - InComment = TRUE; - SlashSlashComment = TRUE; - // - // Check for /* comment start - // - } else if ((SourceFile->FileBufferPtr[0] == T_CHAR_SLASH) && (SourceFile->FileBufferPtr[1] == T_CHAR_STAR)) { - SourceFile->FileBufferPtr[0] = T_CHAR_SPACE; - SourceFile->FileBufferPtr++; - SourceFile->FileBufferPtr[0] = T_CHAR_SPACE; - SourceFile->FileBufferPtr++; - SlashSlashComment = FALSE; - InComment = TRUE; - } else { - SourceFile->FileBufferPtr++; - } - } - // - // Could check for end-of-file and still in a comment, but - // should not be necessary. So just restore the file pointers. - // - RewindFile (SourceFile); - // - // Dump the reformatted file if verbose mode - // - if (mGlobals.VerboseFile) { - LineNum = 1; - printf ("%04d: ", LineNum); - while (!EndOfFile (SourceFile)) { - if (SourceFile->FileBufferPtr[0] == T_CHAR_LF) { - printf ("'\n%04d: '", ++LineNum); - } else { - printf ("%c", SourceFile->FileBufferPtr[0]); - } - - SourceFile->FileBufferPtr++; - } - - printf ("'\n"); - printf ("FileSize = %d (0x%X)\n", SourceFile->FileSize, SourceFile->FileSize); - RewindFile (SourceFile); - } -} - -BOOLEAN -SFPGetQuotedString ( - T_CHAR *Str, - int Length - ) -/*++ - -Routine Description: - Retrieve a quoted-string from the input file. - -Arguments: - Str - pointer to a copy of the quoted string parsed - Length - size of buffer pointed to by Str - -Returns: - TRUE - next token in input stream was a quoted string, and - the string value was returned in Str - FALSE - otherwise - ---*/ -{ - SkipWhiteSpace (&mGlobals.SourceFile); - if (EndOfFile (&mGlobals.SourceFile)) { - return FALSE; - } - - if (mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) { - mGlobals.SourceFile.FileBufferPtr++; - while (Length > 0) { - if (EndOfFile (&mGlobals.SourceFile)) { - return FALSE; - } - // - // Check for closing quote - // - if (mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) { - mGlobals.SourceFile.FileBufferPtr++; - *Str = 0; - return TRUE; - } - - *Str = mGlobals.SourceFile.FileBufferPtr[0]; - Str++; - Length--; - mGlobals.SourceFile.FileBufferPtr++; - } - } - // - // First character was not a quote, or the input string length was - // insufficient to contain the quoted string, so return failure code. - // - return FALSE; -} - -BOOLEAN -SFPIsEOF ( - VOID - ) -/*++ - -Routine Description: - Return TRUE of FALSE to indicate whether or not we've reached the end of the - file we're parsing. - -Arguments: - NA - -Returns: - TRUE - EOF reached - FALSE - otherwise - ---*/ -{ - SkipWhiteSpace (&mGlobals.SourceFile); - return EndOfFile (&mGlobals.SourceFile); -} - -#if 0 -static -T_CHAR * -GetQuotedString ( - SOURCE_FILE *SourceFile, - BOOLEAN Optional - ) -{ - T_CHAR *String; - T_CHAR *Start; - T_CHAR *Ptr; - unsigned int Len; - BOOLEAN PreviousBackslash; - - if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) { - if (Optional == FALSE) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted string", "%S", SourceFile->FileBufferPtr); - } - - return NULL; - } - - Len = 0; - SourceFile->FileBufferPtr++; - Start = Ptr = SourceFile->FileBufferPtr; - PreviousBackslash = FALSE; - while (!EndOfFile (SourceFile)) { - if ((SourceFile->FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) && (PreviousBackslash == FALSE)) { - break; - } else if (SourceFile->FileBufferPtr[0] == T_CHAR_CR) { - Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start); - PreviousBackslash = FALSE; - } else if (SourceFile->FileBufferPtr[0] == T_CHAR_BACKSLASH) { - PreviousBackslash = TRUE; - } else { - PreviousBackslash = FALSE; - } - - SourceFile->FileBufferPtr++; - Len++; - } - - if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) { - Warning (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing quote on string", "%S", Start); - } else { - SourceFile->FileBufferPtr++; - } - // - // Now allocate memory for the string and save it off - // - String = (T_CHAR *) malloc ((Len + 1) * sizeof (T_CHAR)); - if (String == NULL) { - Error (NULL, 0, 0, "memory allocation failed", NULL); - return NULL; - } - // - // Copy the string from the file buffer to the local copy. - // We do no reformatting of it whatsoever at this point. - // - Ptr = String; - while (Len > 0) { - *Ptr = *Start; - Start++; - Ptr++; - Len--; - } - - *Ptr = 0; - return String; -} -#endif -static -BOOLEAN -EndOfFile ( - SOURCE_FILE *SourceFile - ) -{ - // - // The file buffer pointer will typically get updated before the End-of-file flag in the - // source file structure, so check it first. - // - if (SourceFile->FileBufferPtr >= SourceFile->FileBuffer + SourceFile->FileSize / sizeof (T_CHAR)) { - SourceFile->EndOfFile = TRUE; - return TRUE; - } - - if (SourceFile->EndOfFile) { - return TRUE; - } - - return FALSE; -} - -#if 0 -static -void -ProcessTokenInclude ( - SOURCE_FILE *SourceFile - ) -{ - char IncludeFileName[MAX_PATH]; - char *To; - unsigned int Len; - BOOLEAN ReportedError; - SOURCE_FILE IncludedSourceFile; - - ReportedError = FALSE; - if (SkipWhiteSpace (SourceFile) == 0) { - Warning (SourceFile->FileName, SourceFile->LineNum, 0, "expected whitespace following #include keyword", NULL); - } - // - // Should be quoted file name - // - if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted include file name", NULL); - goto FailDone; - } - - SourceFile->FileBufferPtr++; - // - // Copy the filename as ascii to our local string - // - To = IncludeFileName; - Len = 0; - while (!EndOfFile (SourceFile)) { - if ((SourceFile->FileBufferPtr[0] == T_CHAR_CR) || (SourceFile->FileBufferPtr[0] == T_CHAR_LF)) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-line found in quoted include file name", NULL); - goto FailDone; - } - - if (SourceFile->FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) { - SourceFile->FileBufferPtr++; - break; - } - // - // If too long, then report the error once and process until the closing quote - // - Len++; - if (!ReportedError && (Len >= sizeof (IncludeFileName))) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "length of include file name exceeds limit", NULL); - ReportedError = TRUE; - } - - if (!ReportedError) { - *To = (T_CHAR) SourceFile->FileBufferPtr[0]; - To++; - } - - SourceFile->FileBufferPtr++; - } - - if (!ReportedError) { - *To = 0; - memset ((char *) &IncludedSourceFile, 0, sizeof (SOURCE_FILE)); - strcpy (IncludedSourceFile.FileName, IncludeFileName); - ProcessIncludeFile (&IncludedSourceFile, SourceFile); - } - - return ; -FailDone: - // - // Error recovery -- skip to next # - // - SourceFile->SkipToHash = TRUE; -} -#endif -static -BOOLEAN -IsWhiteSpace ( - SOURCE_FILE *SourceFile - ) -{ - switch (*SourceFile->FileBufferPtr) { - case T_CHAR_NULL: - case T_CHAR_CR: - case T_CHAR_SPACE: - case T_CHAR_TAB: - case T_CHAR_LF: - return TRUE; - - default: - return FALSE; - } -} - -unsigned int -SkipWhiteSpace ( - SOURCE_FILE *SourceFile - ) -{ - unsigned int Count; - - Count = 0; - while (!EndOfFile (SourceFile)) { - Count++; - switch (*SourceFile->FileBufferPtr) { - case T_CHAR_NULL: - case T_CHAR_CR: - case T_CHAR_SPACE: - case T_CHAR_TAB: - SourceFile->FileBufferPtr++; - break; - - case T_CHAR_LF: - SourceFile->FileBufferPtr++; - SourceFile->LineNum++; - break; - - default: - return Count - 1; - } - } - // - // Some tokens require trailing whitespace. If we're at the end of the - // file, then we count that as well. - // - if ((Count == 0) && (EndOfFile (SourceFile))) { - Count++; - } - - return Count; -} - -static -unsigned int -t_strcmp ( - T_CHAR *Buffer, - T_CHAR *Str - ) -/*++ - -Routine Description: - Compare two strings for equality. The string pointed to by 'Buffer' may or may not be null-terminated, - so only compare up to the length of Str. - -Arguments: - Buffer - pointer to first (possibly not null-terminated) string - Str - pointer to null-terminated string to compare to Buffer - -Returns: - Number of bytes matched if exact match - 0 if Buffer does not start with Str - ---*/ -{ - unsigned int Len; - - Len = 0; - while (*Str && (*Str == *Buffer)) { - Buffer++; - Str++; - Len++; - } - - if (*Str) { - return 0; - } - - return Len; -} - -static -unsigned int -t_strlen ( - T_CHAR *Str - ) -{ - unsigned int Len; - Len = 0; - while (*Str) { - Len++; - Str++; - } - - return Len; -} - -static -unsigned int -t_strncmp ( - T_CHAR *Str1, - T_CHAR *Str2, - int Len - ) -{ - while (Len > 0) { - if (*Str1 != *Str2) { - return Len; - } - - Len--; - Str1++; - Str2++; - } - - return 0; -} - -static -T_CHAR * -t_strcpy ( - T_CHAR *Dest, - T_CHAR *Src - ) -{ - T_CHAR *SaveDest; - SaveDest = Dest; - while (*Src) { - *Dest = *Src; - Dest++; - Src++; - } - - *Dest = 0; - return SaveDest; -} - -static -void -RewindFile ( - SOURCE_FILE *SourceFile - ) -{ - SourceFile->LineNum = 1; - SourceFile->FileBufferPtr = SourceFile->FileBuffer; - SourceFile->EndOfFile = 0; -} - -static -UINT32 -GetHexChars ( - T_CHAR *Buffer, - UINT32 BufferLen - ) -{ - UINT32 Len; - Len = 0; - while (!EndOfFile (&mGlobals.SourceFile) && (BufferLen > 0)) { - if (isxdigit (mGlobals.SourceFile.FileBufferPtr[0])) { - *Buffer = mGlobals.SourceFile.FileBufferPtr[0]; - Buffer++; - Len++; - BufferLen--; - mGlobals.SourceFile.FileBufferPtr++; - } else { - break; - } - } - // - // Null terminate if we can - // - if ((Len > 0) && (BufferLen > 0)) { - *Buffer = 0; - } - - return Len; -} - -BOOLEAN -SFPGetGuid ( - int GuidStyle, - EFI_GUID *Value - ) -/*++ - -Routine Description: - Parse a GUID from the input stream. Stop when you discover white space. - -Arguments: - GuidStyle - Style of the following GUID token - Value - pointer to EFI_GUID struct for output - -Returns: - TRUE - GUID string parsed successfully - FALSE - otherwise - - GUID styles - Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD - ---*/ -{ - UINT32 Value32; - UINT32 Index; - FILE_POSITION FPos; - T_CHAR TempString[20]; - T_CHAR TempString2[3]; - T_CHAR *From; - T_CHAR *To; - UINT32 Len; - BOOLEAN Status; - - Status = FALSE; - // - // Skip white space, then start parsing - // - SkipWhiteSpace (&mGlobals.SourceFile); - GetFilePosition (&FPos); - if (EndOfFile (&mGlobals.SourceFile)) { - return FALSE; - } - - if (GuidStyle == PARSE_GUID_STYLE_5_FIELDS) { - // - // Style[0] 12345678-1234-5678-AAAA-BBBBCCCCDDDD - // - Len = GetHexChars (TempString, sizeof (TempString)); - if ((Len == 0) || (Len > 8)) { - goto Done; - } - - sscanf (TempString, "%x", &Value32); - Value->Data1 = Value32; - // - // Next two UINT16 fields - // - if (mGlobals.SourceFile.FileBufferPtr[0] != '-') { - goto Done; - } - - mGlobals.SourceFile.FileBufferPtr++; - Len = GetHexChars (TempString, sizeof (TempString)); - if ((Len == 0) || (Len > 4)) { - goto Done; - } - - sscanf (TempString, "%x", &Value32); - Value->Data2 = (UINT16) Value32; - - if (mGlobals.SourceFile.FileBufferPtr[0] != '-') { - goto Done; - } - - mGlobals.SourceFile.FileBufferPtr++; - Len = GetHexChars (TempString, sizeof (TempString)); - if ((Len == 0) || (Len > 4)) { - goto Done; - } - - sscanf (TempString, "%x", &Value32); - Value->Data3 = (UINT16) Value32; - // - // Parse the "AAAA" as two bytes - // - if (mGlobals.SourceFile.FileBufferPtr[0] != '-') { - goto Done; - } - - mGlobals.SourceFile.FileBufferPtr++; - Len = GetHexChars (TempString, sizeof (TempString)); - if ((Len == 0) || (Len > 4)) { - goto Done; - } - - sscanf (TempString, "%x", &Value32); - Value->Data4[0] = (UINT8) (Value32 >> 8); - Value->Data4[1] = (UINT8) Value32; - if (mGlobals.SourceFile.FileBufferPtr[0] != '-') { - goto Done; - } - - mGlobals.SourceFile.FileBufferPtr++; - // - // Read the last 6 bytes of the GUID - // - // - Len = GetHexChars (TempString, sizeof (TempString)); - if ((Len == 0) || (Len > 12)) { - goto Done; - } - // - // Insert leading 0's to make life easier - // - if (Len != 12) { - From = TempString + Len - 1; - To = TempString + 11; - TempString[12] = 0; - while (From >= TempString) { - *To = *From; - To--; - From--; - } - - while (To >= TempString) { - *To = '0'; - To--; - } - } - // - // Now parse each byte - // - TempString2[2] = 0; - for (Index = 0; Index < 6; Index++) { - // - // Copy the two characters from the input string to something - // we can parse. - // - TempString2[0] = TempString[Index * 2]; - TempString2[1] = TempString[Index * 2 + 1]; - sscanf (TempString2, "%x", &Value32); - Value->Data4[Index + 2] = (UINT8) Value32; - } - - Status = TRUE; - } else { - // - // Unsupported GUID style - // - return FALSE; - } - -Done: - if (Status == FALSE) { - SetFilePosition (&FPos); - } - - return Status; -} - -static -STATUS -GetFilePosition ( - FILE_POSITION *Fpos - ) -{ - Fpos->FileBufferPtr = mGlobals.SourceFile.FileBufferPtr; - return STATUS_SUCCESS; -} - -static -STATUS -SetFilePosition ( - FILE_POSITION *Fpos - ) -{ - // - // Should check range of pointer - // - mGlobals.SourceFile.FileBufferPtr = Fpos->FileBufferPtr; - return STATUS_SUCCESS; -} diff --git a/Tools/CodeTools/TianoTools/Common/SimpleFileParsing.h b/Tools/CodeTools/TianoTools/Common/SimpleFileParsing.h deleted file mode 100644 index 7cf25a6bf8..0000000000 --- a/Tools/CodeTools/TianoTools/Common/SimpleFileParsing.h +++ /dev/null @@ -1,120 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - SimpleFileParsing.h - -Abstract: - - Function prototypes and defines for the simple file parsing routines. - ---*/ - -#ifndef _SIMPLE_FILE_PARSING_H_ -#define _SIMPLE_FILE_PARSING_H_ - -#include - -#define T_CHAR char - -STATUS -SFPInit ( - VOID - ) -; - -STATUS -SFPOpenFile ( - char *FileName - ) -; - -BOOLEAN -SFPIsKeyword ( - T_CHAR *Str - ) -; - -BOOLEAN -SFPIsToken ( - T_CHAR *Str - ) -; - -BOOLEAN -SFPGetNextToken ( - T_CHAR *Str, - unsigned int Len - ) -; - -BOOLEAN -SFPGetGuidToken ( - T_CHAR *Str, - UINT32 Len - ) -; - -#define PARSE_GUID_STYLE_5_FIELDS 0 - -BOOLEAN -SFPGetGuid ( - int GuidStyle, - EFI_GUID *Value - ) -; - -BOOLEAN -SFPSkipToToken ( - T_CHAR *Str - ) -; - -BOOLEAN -SFPGetNumber ( - unsigned int *Value - ) -; - -BOOLEAN -SFPGetQuotedString ( - T_CHAR *Str, - int Length - ) -; - -BOOLEAN -SFPIsEOF ( - VOID - ) -; - -STATUS -SFPCloseFile ( - VOID - ) -; - -unsigned -int -SFPGetLineNumber ( - VOID - ) -; - -T_CHAR * -SFPGetFileName ( - VOID - ) -; - -#endif // #ifndef _SIMPLE_FILE_PARSING_H_ diff --git a/Tools/CodeTools/TianoTools/Common/WinNtInclude.h b/Tools/CodeTools/TianoTools/Common/WinNtInclude.h deleted file mode 100644 index 80e45b4ad6..0000000000 --- a/Tools/CodeTools/TianoTools/Common/WinNtInclude.h +++ /dev/null @@ -1,73 +0,0 @@ -/*-- - -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - WinNtInclude.h - -Abstract: - Include file for the WinNt Library - ---*/ - -#ifndef __WIN_NT_INCLUDE_H__ -#define __WIN_NT_INCLUDE_H__ - -// -// Win32 include files do not compile clean with /W4, so we use the warning -// pragma to suppress the warnings for Win32 only. This way our code can stil -// compile at /W4 (highest warning level) with /WX (warnings cause build -// errors). -// -#pragma warning(disable : 4115) -#pragma warning(disable : 4201) -#pragma warning(disable : 4214) -#pragma warning(disable : 4028) -#pragma warning(disable : 4133) - -#define GUID _WINNT_DUP_GUID_____ -#define _LIST_ENTRY _WINNT_DUP_LIST_ENTRY_FORWARD -#define LIST_ENTRY _WINNT_DUP_LIST_ENTRY -#define InterlockedIncrement _WINNT_DUP_InterlockedIncrement -#define InterlockedDecrement _WINNT_DUP_InterlockedDecrement -#define InterlockedCompareExchange64 _WINNT_DUP_InterlockedCompareExchange64 -#undef UNALIGNED -#undef CONST -#undef VOID - -#ifndef __GNUC__ -#include "windows.h" -#endif - -#undef GUID -#undef _LIST_ENTRY -#undef LIST_ENTRY -#undef InterlockedIncrement -#undef InterlockedDecrement -#undef InterlockedCompareExchange64 -#undef InterlockedCompareExchangePointer - -#define VOID void - -// -// Prevent collisions with Windows API name macros that deal with Unicode/Not issues -// -#undef LoadImage -#undef CreateEvent - -// -// Set the warnings back on as the EFI code must be /W4. -// -#pragma warning(default : 4115) -#pragma warning(default : 4201) -#pragma warning(default : 4214) - - -#endif diff --git a/Tools/CodeTools/TianoTools/Common/build.xml b/Tools/CodeTools/TianoTools/Common/build.xml deleted file mode 100644 index 902f677d1d..0000000000 --- a/Tools/CodeTools/TianoTools/Common/build.xml +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/CompressDll/CompressDll.c b/Tools/CodeTools/TianoTools/CompressDll/CompressDll.c deleted file mode 100644 index cc06f26c05..0000000000 --- a/Tools/CodeTools/TianoTools/CompressDll/CompressDll.c +++ /dev/null @@ -1,105 +0,0 @@ -/** @file - Compression DLL used by PCD Tools - - Copyright (c) 2006, Intel Corporation All rights reserved. - This program and the accompanying materials are licensed and made available - under the terms and conditions of the BSD License which accompanies this - distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ -#if defined(__GNUC__) -typedef long long __int64;/*For cygwin build*/ -#endif -#include "CompressDll.h" -#include "EfiCompress.h" - -extern -EFI_STATUS -Compress ( - IN UINT8 *SrcBuffer, - IN UINT32 SrcSize, - IN UINT8 *DstBuffer, - IN OUT UINT32 *DstSize - ); - -JNIEXPORT jbyteArray JNICALL Java_org_tianocore_framework_tasks_Compress_CallCompress -(JNIEnv *env, jobject obj, jbyteArray SourceBuffer, jint SourceSize, jstring path) -{ - char* DestBuffer; - int DestSize; - int Result; - char *InputBuffer; - jbyteArray OutputBuffer; - jbyte *TempByte; - - DestSize = 0; - DestBuffer = NULL; - - TempByte = (*env)->GetByteArrayElements(env, SourceBuffer, 0); - InputBuffer = (char*) TempByte; - - - // - // First call compress function and get need buffer size - // - - Result = Compress ( - (char*) InputBuffer, - SourceSize, - DestBuffer, - &DestSize - ); - - if (Result = EFI_BUFFER_TOO_SMALL) { - DestBuffer = malloc (DestSize); - } - - // - // Second call compress and get the DestBuffer value - // - Result = Compress( - (char*) InputBuffer, - SourceSize, - DestBuffer, - &DestSize - ); - - // - // new a MV array to store the return compressed buffer - // - OutputBuffer = (*env)->NewByteArray(env, DestSize); - (*env)->SetByteArrayRegion(env, OutputBuffer,0, DestSize, (jbyte*) DestBuffer); - - // - // Free Ouputbuffer. - // - free (DestBuffer); - - - if (Result != 0) { - return NULL; - } else { - return OutputBuffer; - } -} - -#ifdef _MSC_VER -BOOLEAN -__stdcall -DllMainCRTStartup( - unsigned int hDllHandle, - unsigned int nReason, - void* Reserved -) -{ - return TRUE; -} -#else -#ifdef __GNUC__ -#endif -#endif - diff --git a/Tools/CodeTools/TianoTools/CompressDll/CompressDll.h b/Tools/CodeTools/TianoTools/CompressDll/CompressDll.h deleted file mode 100644 index fa3b83cd10..0000000000 --- a/Tools/CodeTools/TianoTools/CompressDll/CompressDll.h +++ /dev/null @@ -1,22 +0,0 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ - -#include -/* Header for class org_tianocore_frameworktasks_Compress */ - -#ifndef _Included_org_tianocore_framework_tasks_Compress -#define _Included_org_tianocore_framework_tasks_Compress -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: org_tianocore_frameworktasks_Compress - * Method: CallCompress - * Signature: ([BILjava/lang/String;)[B - */ -JNIEXPORT jbyteArray JNICALL Java_org_tianocore_framework_tasks_Compress_CallCompress - (JNIEnv *, jobject, jbyteArray, jint, jstring); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Tools/CodeTools/TianoTools/CompressDll/build.xml b/Tools/CodeTools/TianoTools/CompressDll/build.xml deleted file mode 100644 index 5043d127d5..0000000000 --- a/Tools/CodeTools/TianoTools/CompressDll/build.xml +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/CreateMtFile/CreateMtFile.c b/Tools/CodeTools/TianoTools/CreateMtFile/CreateMtFile.c deleted file mode 100644 index 1c17b3de23..0000000000 --- a/Tools/CodeTools/TianoTools/CreateMtFile/CreateMtFile.c +++ /dev/null @@ -1,247 +0,0 @@ -/*++ - -Copyright (c) 1999-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -Module Name: - - CreateMtFile.c - -Abstract: - - Simple utility to create a pad file containing fixed data. - ---*/ - -#include -#include -#include - -#include - -#define PROGRAM_NAME "CreateMtFile" - -typedef struct { - INT8 *OutFileName; - INT8 ByteValue; - UINT32 FileSize; -} OPTIONS; - -static -EFI_STATUS -ProcessArgs ( - IN INT32 Argc, - IN INT8 *Argv[], - IN OUT OPTIONS *Options - ); - -static -void -Usage ( - VOID - ); - -int -main ( - IN INT32 Argc, - IN INT8 *Argv[] - ) -/*++ - -Routine Description: - - Main entry point for this utility. - -Arguments: - - Standard C entry point args Argc and Argv - -Returns: - - EFI_SUCCESS if good to go - ---*/ -// GC_TODO: ] - add argument and description to function comment -// GC_TODO: EFI_INVALID_PARAMETER - add return value to function comment -// GC_TODO: EFI_DEVICE_ERROR - add return value to function comment -// GC_TODO: EFI_DEVICE_ERROR - add return value to function comment -{ - FILE *OutFptr; - OPTIONS Options; - - // - // Process the command-line arguments. - // - if (ProcessArgs (Argc, Argv, &Options) != EFI_SUCCESS) { - return EFI_INVALID_PARAMETER; - } - // - // Open the output file - // - if ((OutFptr = fopen (Options.OutFileName, "wb")) == NULL) { - fprintf ( - stdout, - PROGRAM_NAME " ERROR: Could not open output file '%s' for writing\n", - Options.OutFileName - ); - return EFI_DEVICE_ERROR; - } - // - // Write the pad bytes. Do it the slow way (one at a time) for now. - // - while (Options.FileSize > 0) { - if (fwrite (&Options.ByteValue, 1, 1, OutFptr) != 1) { - fclose (OutFptr); - fprintf (stdout, PROGRAM_NAME " ERROR: Failed to write to output file\n"); - return EFI_DEVICE_ERROR; - } - - Options.FileSize--; - } - // - // Close the file - // - fclose (OutFptr); - return EFI_SUCCESS; -} - -static -EFI_STATUS -ProcessArgs ( - IN INT32 Argc, - IN INT8 *Argv[], - IN OUT OPTIONS *Options - ) -/*++ - -Routine Description: - - Process the command line arguments. - -Arguments: - - Argc - argument count as passed in to the entry point function - Argv - array of arguments as passed in to the entry point function - Options - stucture of where to put the values of the parsed arguments - -Returns: - - EFI_SUCCESS if everything looks good - EFI_INVALID_PARAMETER otherwise - ---*/ -// GC_TODO: ] - add argument and description to function comment -{ - UINT32 Multiplier; - - // - // Clear the options - // - memset ((char *) Options, 0, sizeof (OPTIONS)); - - // - // Skip program name - // - Argv++; - Argc--; - if (Argc < 2) { - Usage (); - return EFI_INVALID_PARAMETER; - } - // - // If first arg is dash-option, then print usage. - // - if (Argv[0][0] == '-') { - Usage (); - return EFI_INVALID_PARAMETER; - } - // - // First arg is file name - // - Options->OutFileName = Argv[0]; - Argc--; - Argv++; - - // - // Second arg is file size. Allow 0x1000, 0x100K, 1024, 1K - // - Multiplier = 1; - if ((Argv[0][strlen (Argv[0]) - 1] == 'k') || (Argv[0][strlen (Argv[0]) - 1] == 'K')) { - Multiplier = 1024; - } - // - // Look for 0x prefix on file size - // - if ((Argv[0][0] == '0') && ((Argv[0][1] == 'x') || (Argv[0][1] == 'X'))) { - if (sscanf (Argv[0], "%x", &Options->FileSize) != 1) { - fprintf (stdout, PROGRAM_NAME " ERROR: Invalid file size '%s'\n", Argv[0]); - Usage (); - return EFI_INVALID_PARAMETER; - } - // - // Otherwise must be a decimal number - // - } else { - if (sscanf (Argv[0], "%d", &Options->FileSize) != 1) { - fprintf (stdout, PROGRAM_NAME " ERROR: Invalid file size '%s'\n", Argv[0]); - Usage (); - return EFI_INVALID_PARAMETER; - } - } - - Options->FileSize *= Multiplier; - // - // Assume byte value of 0xff - // - Options->ByteValue = (INT8) (UINT8) 0xFF; - return EFI_SUCCESS; -} -// -// Print utility usage info -// -static -void -Usage ( - VOID - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - None - -Returns: - - GC_TODO: add return values - ---*/ -{ - UINT32 Index; - static const INT8 *Text[] = { - " ", - "Usage: "PROGRAM_NAME " OutFileName FileSize", - " where:", - " OutFileName is the name of the output file to generate", - " FileSize is the size of the file to create", - " Examples:", - " "PROGRAM_NAME " OutFile.bin 32K", - " "PROGRAM_NAME " OutFile.bin 0x1000", - " ", - NULL - }; - - for (Index = 0; Text[Index] != NULL; Index++) { - fprintf (stdout, "%s\n", Text[Index]); - } -} diff --git a/Tools/CodeTools/TianoTools/CreateMtFile/build.xml b/Tools/CodeTools/TianoTools/CreateMtFile/build.xml deleted file mode 100644 index b2272244cd..0000000000 --- a/Tools/CodeTools/TianoTools/CreateMtFile/build.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/CustomizedCompress/CustomizedCompress.c b/Tools/CodeTools/TianoTools/CustomizedCompress/CustomizedCompress.c deleted file mode 100644 index 0dc66128c9..0000000000 --- a/Tools/CodeTools/TianoTools/CustomizedCompress/CustomizedCompress.c +++ /dev/null @@ -1,146 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - CustomizedCompress.c - -Abstract: - - Header file for Customized compression routine - ---*/ - -#include - -EFI_STATUS -SetCustomizedCompressionType ( - IN CHAR8 *Type - ) -/*++ - -Routine Description: - -The implementation of Customized SetCompressionType(). - -Arguments: - Type - The type if compression. - -Returns: - - EFI_SUCCESS - The type has been set. - EFI_UNSUPPORTED - This type is unsupported. - - ---*/ -{ - return EFI_UNSUPPORTED; -} - -EFI_STATUS -CustomizedGetInfo ( - IN VOID *Source, - IN UINT32 SrcSize, - OUT UINT32 *DstSize, - OUT UINT32 *ScratchSize - ) -/*++ - -Routine Description: - -The implementation of Customized GetInfo(). - -Arguments: - Source - The source buffer containing the compressed data. - SrcSize - The size of source buffer - DstSize - The size of destination buffer. - ScratchSize - The size of scratch buffer. - -Returns: - - EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved. - EFI_INVALID_PARAMETER - The source data is corrupted - EFI_UNSUPPORTED - The operation is unsupported. - - ---*/ -{ - return EFI_UNSUPPORTED; -} - -EFI_STATUS -CustomizedDecompress ( - IN VOID *Source, - IN UINT32 SrcSize, - IN OUT VOID *Destination, - IN UINT32 DstSize, - IN OUT VOID *Scratch, - IN UINT32 ScratchSize - ) -/*++ - -Routine Description: - - The implementation of Customized Decompress(). - -Arguments: - - This - The protocol instance pointer - Source - The source buffer containing the compressed data. - SrcSize - The size of source buffer - Destination - The destination buffer to store the decompressed data - DstSize - The size of destination buffer. - Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data. - ScratchSize - The size of scratch buffer. - -Returns: - - EFI_SUCCESS - Decompression is successfull - EFI_INVALID_PARAMETER - The source data is corrupted - EFI_UNSUPPORTED - The operation is unsupported. - ---*/ -{ - return EFI_UNSUPPORTED; -} - -EFI_STATUS -CustomizedCompress ( - IN UINT8 *SrcBuffer, - IN UINT32 SrcSize, - IN UINT8 *DstBuffer, - IN OUT UINT32 *DstSize - ) -/*++ - -Routine Description: - - The Customized compression routine. - -Arguments: - - SrcBuffer - The buffer storing the source data - SrcSize - The size of source data - DstBuffer - The buffer to store the compressed data - DstSize - On input, the size of DstBuffer; On output, - the size of the actual compressed data. - -Returns: - - EFI_BUFFER_TOO_SMALL - The DstBuffer is too small. In this case, - DstSize contains the size needed. - EFI_SUCCESS - Compression is successful. - - EFI_UNSUPPORTED - The operation is unsupported. ---*/ -{ - return EFI_UNSUPPORTED; -} diff --git a/Tools/CodeTools/TianoTools/CustomizedCompress/build.xml b/Tools/CodeTools/TianoTools/CustomizedCompress/build.xml deleted file mode 100644 index 4664a957f0..0000000000 --- a/Tools/CodeTools/TianoTools/CustomizedCompress/build.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/EfiCompress/EfiCompressMain.c b/Tools/CodeTools/TianoTools/EfiCompress/EfiCompressMain.c deleted file mode 100644 index 492210f67c..0000000000 --- a/Tools/CodeTools/TianoTools/EfiCompress/EfiCompressMain.c +++ /dev/null @@ -1,165 +0,0 @@ -/*++ - -Copyright (c) 1999-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -Module Name: - - EfiCompressMain.c - -Abstract: - - The main function for the compression utility. - ---*/ - -#include -#include -#include -#include -#include - -#include - -#include "EfiCompress.h" - -int -main ( - INT32 argc, - CHAR8 *argv[] - ) -/*++ - -Routine Description: - - Compresses the input files - -Arguments: - - argc - number of arguments passed into the command line. - argv[] - files to compress and files to output compressed data to. - -Returns: - - int: 0 for successful execution of the function. - ---*/ -{ - EFI_STATUS Status; - FILE *infile; - FILE *outfile; - UINT32 SrcSize; - UINT32 DstSize; - UINT8 *SrcBuffer; - UINT8 *DstBuffer; - UINT8 Buffer[8]; - - // - // Added for makefile debug - KCE - // - INT32 arg_counter; - printf ("\n\n"); - for (arg_counter = 0; arg_counter < argc; arg_counter++) { - printf ("%s ", argv[arg_counter]); - } - - printf ("\n\n"); - - SrcBuffer = DstBuffer = NULL; - - infile = outfile = NULL; - - if (argc != 3) { - printf ("Usage: EFICOMPRESS \n"); - goto Done; - } - - if ((outfile = fopen (argv[2], "wb")) == NULL) { - printf ("Can't open output file\n"); - goto Done; - } - - if ((infile = fopen (argv[1], "rb")) == NULL) { - printf ("Can't open input file\n"); - goto Done; - } - // - // Get the size of source file - // - SrcSize = 0; - while (fread (Buffer, 1, 1, infile)) { - SrcSize++; - - } - // - // Read in the source data - // - if ((SrcBuffer = malloc (SrcSize)) == NULL) { - printf ("Can't allocate memory\n"); - goto Done; - } - - rewind (infile); - if (fread (SrcBuffer, 1, SrcSize, infile) != SrcSize) { - printf ("Can't read from source\n"); - goto Done; - } - // - // Get destination data size and do the compression - // - DstSize = 0; - Status = Compress (SrcBuffer, SrcSize, DstBuffer, &DstSize); - if (Status == EFI_BUFFER_TOO_SMALL) { - if ((DstBuffer = malloc (DstSize)) == NULL) { - printf ("Can't allocate memory\n"); - goto Done; - } - - Status = Compress (SrcBuffer, SrcSize, DstBuffer, &DstSize); - } - - if (EFI_ERROR (Status)) { - printf ("Compress Error\n"); - goto Done; - } - - printf ("\nOrig Size = %ld\n", SrcSize); - printf ("Comp Size = %ld\n", DstSize); - - if (DstBuffer == NULL) { - printf ("No destination to write to.\n"); - goto Done; - } - // - // Write out the result - // - if (fwrite (DstBuffer, 1, DstSize, outfile) != DstSize) { - printf ("Can't write to destination file\n"); - } - -Done: - if (SrcBuffer) { - free (SrcBuffer); - } - - if (DstBuffer) { - free (DstBuffer); - } - - if (infile) { - fclose (infile); - } - - if (outfile) { - fclose (outfile); - } - - return 0; -} diff --git a/Tools/CodeTools/TianoTools/EfiCompress/build.xml b/Tools/CodeTools/TianoTools/EfiCompress/build.xml deleted file mode 100644 index 94f60558cc..0000000000 --- a/Tools/CodeTools/TianoTools/EfiCompress/build.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/EfiRom/EfiRom.c b/Tools/CodeTools/TianoTools/EfiRom/EfiRom.c deleted file mode 100644 index 2cc478b119..0000000000 --- a/Tools/CodeTools/TianoTools/EfiRom/EfiRom.c +++ /dev/null @@ -1,1536 +0,0 @@ -/*++ - -Copyright (c) 1999-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - EfiRom.c - -Abstract: - - Utility program to create an EFI option ROM image from binary and - EFI PE32 files. - - ---*/ - -#include -#include -#include - -#include -#include // for PE32 structure definitions -#include - -#include // for option ROM header structures - -#include "EfiCompress.h" -#include "CommonLib.h" - -// -// Version of this utility -// -#define UTILITY_VERSION "v2.5" - -// -// Define some status return values -// -#define STATUS_SUCCESS 0 -#define STATUS_WARNING 1 -#define STATUS_ERROR 2 - -// -// Define the max length of a filename -// -#define MAX_PATH 200 - -#define DEFAULT_OUTPUT_EXTENSION ".rom" - -// -// Max size for an option ROM image -// -#define MAX_OPTION_ROM_SIZE (1024 * 1024 * 16) // 16MB -// -// Values for the indicator field in the PCI data structure -// -#define INDICATOR_LAST 0x80 // last file in series of files -// -// Masks for the FILE_LIST.FileFlags field -// -#define FILE_FLAG_BINARY 0x01 -#define FILE_FLAG_EFI 0x02 -#define FILE_FLAG_COMPRESS 0x04 - -// -// Use this linked list structure to keep track of all the filenames -// specified on the command line. -// -typedef struct _FILE_LIST { - struct _FILE_LIST *Next; - INT8 *FileName; - UINT32 FileFlags; - UINT32 ClassCode; - UINT16 CodeRevision; -} FILE_LIST; - -// -// Use this to track our command-line options -// -typedef struct { - INT8 OutFileName[MAX_PATH]; - INT8 NoLast; - INT8 Verbose; - INT8 DumpOption; - UINT8 DevIdValid; - UINT8 VendIdValid; - UINT16 VendId; - UINT16 DevId; - FILE_LIST *FileList; -} OPTIONS; - -// -// Make a global structure to keep track of command-line options -// -static OPTIONS mOptions; - -// -// Use these to convert from machine type value to a named type -// -typedef struct { - UINT16 Value; - char *Name; -} STRING_LOOKUP; - -static STRING_LOOKUP mMachineTypes[] = { - EFI_IMAGE_MACHINE_IA32, - "IA32", - EFI_IMAGE_MACHINE_IA64, - "IA64", - EFI_IMAGE_MACHINE_EBC, - "EBC", - 0, - NULL -}; - -static STRING_LOOKUP mSubsystemTypes[] = { - EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION, - "EFI application", - EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, - "EFI boot service driver", - EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER, - "EFI runtime driver", - 0, - NULL -}; -// -// Function prototypes -// -static -void -Usage ( - VOID - ); - -static -int -ParseCommandLine ( - int Argc, - char *Argv[], - OPTIONS *Options - ); - -static -int -CheckPE32File ( - FILE *Fptr, - UINT16 *MachineType, - UINT16 *SubSystem - ); - -static -int -ProcessEfiFile ( - FILE *OutFptr, - FILE_LIST *InFile, - UINT16 VendId, - UINT16 DevId, - UINT32 *Size - ); - -static -int -ProcessBinFile ( - FILE *OutFptr, - FILE_LIST *InFile, - UINT32 *Size - ); - -static -void -DumpImage ( - FILE_LIST *InFile - ); - -char * -GetMachineTypeStr ( - UINT16 MachineType - ); - -static -char * -GetSubsystemTypeStr ( - UINT16 SubsystemType - ); - -main ( - int Argc, - char *Argv[] - ) -/*++ - -Routine Description: - - Given an EFI image filename, create a ROM-able image by creating an option - ROM header and PCI data structure, filling them in, and then writing the - option ROM header + PCI data structure + EFI image out to the output file. - -Arguments: - - Argc - standard C main() argument count - - Argv - standard C main() argument list - -Returns: - - 0 success - non-zero otherwise - ---*/ -// GC_TODO: ] - add argument and description to function comment -{ - INT8 *Ext; - FILE *FptrOut; - UINT32 Status; - FILE_LIST *FList; - UINT32 TotalSize; - UINT32 Size; - - Status = STATUS_SUCCESS; - FptrOut = NULL; - - // - // Parse the command line arguments - // - if (ParseCommandLine (Argc, Argv, &mOptions)) { - return STATUS_ERROR; - } - // - // If dumping an image, then do that and quit - // - if (mOptions.DumpOption) { - DumpImage (mOptions.FileList); - goto BailOut; - } - // - // Determine the output filename. Either what they specified on - // the command line, or the first input filename with a different extension. - // - if (!mOptions.OutFileName[0]) { - strcpy (mOptions.OutFileName, mOptions.FileList->FileName); - // - // Find the last . on the line and replace the filename extension with - // the default - // - for (Ext = mOptions.OutFileName + strlen (mOptions.OutFileName) - 1; - (Ext >= mOptions.OutFileName) && (*Ext != '.') && (*Ext != '\\'); - Ext-- - ) - ; - // - // If dot here, then insert extension here, otherwise append - // - if (*Ext != '.') { - Ext = mOptions.OutFileName + strlen (mOptions.OutFileName); - } - - strcpy (Ext, DEFAULT_OUTPUT_EXTENSION); - } - // - // Make sure we don't have the same filename for input and output files - // - for (FList = mOptions.FileList; FList != NULL; FList = FList->Next) { - if (stricmp (mOptions.OutFileName, FList->FileName) == 0) { - Status = STATUS_ERROR; - fprintf ( - stdout, - "ERROR: Input and output file names must be different - %s = %s\n", - FList->FileName, - mOptions.OutFileName - ); - goto BailOut; - } - } - // - // Now open our output file - // - if ((FptrOut = fopen (mOptions.OutFileName, "w+b")) == NULL) { - fprintf (stdout, "ERROR: Failed to open output file %s\n", mOptions.OutFileName); - goto BailOut; - } - // - // Process all our files - // - TotalSize = 0; - for (FList = mOptions.FileList; FList != NULL; FList = FList->Next) { - Size = 0; - if (FList->FileFlags & FILE_FLAG_EFI) { - if (mOptions.Verbose) { - fprintf (stdout, "Processing EFI file %s\n", FList->FileName); - } - - Status = ProcessEfiFile (FptrOut, FList, mOptions.VendId, mOptions.DevId, &Size); - } else if (FList->FileFlags & FILE_FLAG_BINARY) { - if (mOptions.Verbose) { - fprintf (stdout, "Processing binary file %s\n", FList->FileName); - } - - Status = ProcessBinFile (FptrOut, FList, &Size); - } else { - fprintf (stdout, "ERROR: File not specified as EFI or binary: %s\n", FList->FileName); - Status = STATUS_ERROR; - } - - if (mOptions.Verbose) { - fprintf (stdout, " Output size = 0x%X\n", Size); - } - - if (Status != STATUS_SUCCESS) { - break; - } - - TotalSize += Size; - } - // - // Check total size - // - if (TotalSize > MAX_OPTION_ROM_SIZE) { - fprintf ( - stdout, - "ERROR: Option ROM image size exceeds limit 0x%X bytes\n", - MAX_OPTION_ROM_SIZE - ); - Status = STATUS_ERROR; - } - -BailOut: - if (FptrOut != NULL) { - fclose (FptrOut); - } - // - // Clean up our file list - // - while (mOptions.FileList != NULL) { - FList = mOptions.FileList->Next; - free (mOptions.FileList); - mOptions.FileList = FList; - } - - return Status; -} - -static -int -ProcessBinFile ( - FILE *OutFptr, - FILE_LIST *InFile, - UINT32 *Size - ) -/*++ - -Routine Description: - - Process a binary input file. - -Arguments: - - OutFptr - file pointer to output binary ROM image file we're creating - InFile - structure contains information on the binary file to process - Size - pointer to where to return the size added to the output file - -Returns: - - 0 - successful - ---*/ -{ - FILE *InFptr; - UINT32 TotalSize; - UINT32 FileSize; - UINT8 *Buffer; - UINT32 Status; - PCI_EXPANSION_ROM_HEADER *RomHdr; - PCI_DATA_STRUCTURE *PciDs; - UINT32 Index; - UINT8 ByteCheckSum; - - Status = STATUS_SUCCESS; - - // - // Try to open the input file - // - if ((InFptr = fopen (InFile->FileName, "rb")) == NULL) { - fprintf (stdout, "ERROR: Failed to open input file %s\n", InFile->FileName); - return STATUS_ERROR; - } - // - // Seek to the end of the input file and get the file size. Then allocate - // a buffer to read it in to. - // - fseek (InFptr, 0, SEEK_END); - FileSize = ftell (InFptr); - if (mOptions.Verbose) { - fprintf (stdout, " File size = 0x%X\n", FileSize); - } - - fseek (InFptr, 0, SEEK_SET); - Buffer = (INT8 *) malloc (FileSize); - if (Buffer == NULL) { - fprintf (stdout, "ERROR: Memory allocation failed\n"); - Status = STATUS_ERROR; - goto BailOut; - } - - if (fread (Buffer, FileSize, 1, InFptr) != 1) { - fprintf (stdout, "ERROR: Failed to read all bytes from input file\n"); - Status = STATUS_ERROR; - goto BailOut; - } - // - // Total size must be an even multiple of 512 bytes, and can't exceed - // the option ROM image size. - // - TotalSize = FileSize; - if (TotalSize & 0x1FF) { - TotalSize = (TotalSize + 0x200) &~0x1ff; - } - - if (TotalSize > MAX_OPTION_ROM_SIZE) { - fprintf ( - stdout, - "ERROR: Option ROM image %s size exceeds limit 0x%X bytes\n", - InFile->FileName, - MAX_OPTION_ROM_SIZE - ); - Status = STATUS_ERROR; - goto BailOut; - } - // - // Return the size to the caller so they can keep track of the running total. - // - *Size = TotalSize; - - // - // Crude check to make sure it's a legitimate ROM image - // - RomHdr = (PCI_EXPANSION_ROM_HEADER *) Buffer; - if (RomHdr->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) { - fprintf (stdout, "ERROR: ROM image file has invalid ROM signature\n"); - Status = STATUS_ERROR; - goto BailOut; - } - // - // Make sure the pointer to the PCI data structure is within the size of the image. - // Then check it for valid signature. - // - if ((RomHdr->PcirOffset > FileSize) || (RomHdr->PcirOffset == 0)) { - fprintf (stdout, "ERROR: Invalid PCI data structure offset\n"); - Status = STATUS_ERROR; - goto BailOut; - } - - PciDs = (PCI_DATA_STRUCTURE *) (Buffer + RomHdr->PcirOffset); - if (PciDs->Signature != PCI_DATA_STRUCTURE_SIGNATURE) { - fprintf (stdout, "ERROR: PCI data structure has invalid signature\n"); - Status = STATUS_ERROR; - goto BailOut; - } - // - // If this is the last image, then set the LAST bit unless requested not - // to via the command-line -l argument. Otherwise, make sure you clear it. - // - if ((InFile->Next == NULL) && (mOptions.NoLast == 0)) { - PciDs->Indicator = INDICATOR_LAST; - } else { - PciDs->Indicator = 0; - } - - ByteCheckSum = 0; - for (Index = 0; Index < FileSize - 1; Index++) { - ByteCheckSum = (UINT8) (ByteCheckSum + Buffer[Index]); - } - - Buffer[FileSize - 1] = (UINT8) ((~ByteCheckSum) + 1); - fprintf (stdout, "CheckSUm = %02x\n", (UINT32) Buffer[FileSize - 1]); - - // - // Now copy the input file contents out to the output file - // - if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) { - fprintf (stdout, "ERROR: Failed to write all file bytes to output file\n"); - Status = STATUS_ERROR; - goto BailOut; - } - - TotalSize -= FileSize; - // - // Pad the rest of the image to make it a multiple of 512 bytes - // - while (TotalSize > 0) { - putc (~0, OutFptr); - TotalSize--; - } - -BailOut: - if (InFptr != NULL) { - fclose (InFptr); - } - - if (Buffer != NULL) { - free (Buffer); - } - // - // Print the file name if errors occurred - // - if (Status != STATUS_SUCCESS) { - fprintf (stdout, "Error processing binary file %s\n", InFile->FileName); - } - - return Status; -} - -static -int -ProcessEfiFile ( - FILE *OutFptr, - FILE_LIST *InFile, - UINT16 VendId, - UINT16 DevId, - UINT32 *Size - ) -/*++ - -Routine Description: - - Process a PE32 EFI file. - -Arguments: - - OutFptr - file pointer to output binary ROM image file we're creating - InFile - structure contains information on the PE32 file to process - VendId - vendor ID as required in the option ROM header - DevId - device ID as required in the option ROM header - Size - pointer to where to return the size added to the output file - -Returns: - - 0 - successful - ---*/ -{ - UINT32 Status; - FILE *InFptr; - EFI_PCI_EXPANSION_ROM_HEADER RomHdr; - PCI_DATA_STRUCTURE PciDs; - UINT32 FileSize; - UINT32 CompressedFileSize; - UINT8 *Buffer; - UINT8 *CompressedBuffer; - UINT8 *TempBufferPtr; - UINT32 TotalSize; - UINT32 HeaderSize; - UINT16 MachineType; - UINT16 SubSystem; - UINT32 HeaderPadBytes; - - // - // Try to open the input file - // - if ((InFptr = fopen (InFile->FileName, "rb")) == NULL) { - fprintf (stdout, "ERROR: Failed to open input file %s\n", InFile->FileName); - return STATUS_ERROR; - } - // - // Initialize our buffer pointers to null. - // - Buffer = NULL; - CompressedBuffer = NULL; - - // - // Double-check the file to make sure it's what we expect it to be - // - Status = CheckPE32File (InFptr, &MachineType, &SubSystem); - if (Status != STATUS_SUCCESS) { - goto BailOut; - } - // - // Seek to the end of the input file and get the file size - // - fseek (InFptr, 0, SEEK_END); - FileSize = ftell (InFptr); - - // - // Get the size of the headers we're going to put in front of the image. The - // EFI header must be aligned on a 4-byte boundary, so pad accordingly. - // - if (sizeof (RomHdr) & 0x03) { - HeaderPadBytes = 4 - (sizeof (RomHdr) & 0x03); - } else { - HeaderPadBytes = 0; - } - - HeaderSize = sizeof (PCI_DATA_STRUCTURE) + HeaderPadBytes + sizeof (EFI_PCI_EXPANSION_ROM_HEADER); - if (mOptions.Verbose) { - fprintf (stdout, " File size = 0x%X\n", FileSize); - } - // - // Allocate memory for the entire file (in case we have to compress), then - // seek back to the beginning of the file and read it into our buffer. - // - Buffer = (INT8 *) malloc (FileSize); - if (Buffer == NULL) { - fprintf (stdout, "ERROR: Memory allocation failed\n"); - Status = STATUS_ERROR; - goto BailOut; - } - - fseek (InFptr, 0, SEEK_SET); - if (fread (Buffer, FileSize, 1, InFptr) != 1) { - fprintf (stdout, "ERROR: Failed to read all bytes from input file\n"); - Status = STATUS_ERROR; - goto BailOut; - } - // - // Now determine the size of the final output file. It's either the header size - // plus the file's size, or the header size plus the compressed file size. - // - if (InFile->FileFlags & FILE_FLAG_COMPRESS) { - // - // Allocate a buffer into which we can compress the image, compress it, - // and use that size as the new size. - // - CompressedBuffer = (INT8 *) malloc (FileSize); - if (CompressedBuffer == NULL) { - fprintf (stdout, "ERROR: Memory allocation failed\n"); - Status = STATUS_ERROR; - goto BailOut; - } - - CompressedFileSize = FileSize; - Status = Compress (Buffer, FileSize, CompressedBuffer, &CompressedFileSize); - if (Status != STATUS_SUCCESS) { - fprintf (stdout, "ERROR: Compression failed\n"); - goto BailOut; - } - // - // Now compute the size, then swap buffer pointers. - // - if (mOptions.Verbose) { - fprintf (stdout, " Comp size = 0x%X\n", CompressedFileSize); - } - - TotalSize = CompressedFileSize + HeaderSize; - FileSize = CompressedFileSize; - TempBufferPtr = Buffer; - Buffer = CompressedBuffer; - CompressedBuffer = TempBufferPtr; - } else { - TotalSize = FileSize + HeaderSize; - } - // - // Total size must be an even multiple of 512 bytes - // - if (TotalSize & 0x1FF) { - TotalSize = (TotalSize + 0x200) &~0x1ff; - } - // - // Check size - // - if (TotalSize > MAX_OPTION_ROM_SIZE) { - fprintf ( - stdout, - "ERROR: Option ROM image %s size exceeds limit 0x%X bytes\n", - InFile->FileName, - MAX_OPTION_ROM_SIZE - ); - Status = STATUS_ERROR; - goto BailOut; - } - // - // Return the size to the caller so they can keep track of the running total. - // - *Size = TotalSize; - - // - // Now fill in the ROM header. These values come from chapter 18 of the - // EFI 1.02 specification. - // - memset (&RomHdr, 0, sizeof (RomHdr)); - RomHdr.Signature = PCI_EXPANSION_ROM_HEADER_SIGNATURE; - RomHdr.InitializationSize = (UINT16) (TotalSize / 512); - RomHdr.EfiSignature = EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE; - RomHdr.EfiSubsystem = SubSystem; - RomHdr.EfiMachineType = MachineType; - RomHdr.EfiImageHeaderOffset = (UINT16) HeaderSize; - RomHdr.PcirOffset = (UINT16) (sizeof (RomHdr) + HeaderPadBytes); - // - // Set image as compressed or not - // - if (InFile->FileFlags & FILE_FLAG_COMPRESS) { - RomHdr.CompressionType = EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED; - } - // - // Fill in the PCI data structure - // - memset (&PciDs, 0, sizeof (PCI_DATA_STRUCTURE)); - - PciDs.Signature = PCI_DATA_STRUCTURE_SIGNATURE; - PciDs.VendorId = VendId; - PciDs.DeviceId = DevId; - PciDs.Length = (UINT16) sizeof (PCI_DATA_STRUCTURE); - PciDs.Revision = 0; - // - // Class code and code revision from the command line (optional) - // - PciDs.ClassCode[0] = (UINT8) InFile->ClassCode; - PciDs.ClassCode[1] = (UINT8) (InFile->ClassCode >> 8); - PciDs.ClassCode[2] = (UINT8) (InFile->ClassCode >> 16); - PciDs.ImageLength = RomHdr.InitializationSize; - PciDs.CodeRevision = InFile->CodeRevision; - PciDs.CodeType = PCI_CODE_TYPE_EFI_IMAGE; - - // - // If this is the last image, then set the LAST bit unless requested not - // to via the command-line -l argument. - // - if ((InFile->Next == NULL) && (mOptions.NoLast == 0)) { - PciDs.Indicator = INDICATOR_LAST; - } - // - // Write the ROM header to the output file - // - if (fwrite (&RomHdr, sizeof (RomHdr), 1, OutFptr) != 1) { - fprintf (stdout, "ERROR: Failed to write ROM header to output file\n"); - Status = STATUS_ERROR; - goto BailOut; - } - - // - // Write pad bytes to align the PciDs - // - while (HeaderPadBytes > 0) { - if (putc (0, OutFptr) == EOF) { - fprintf (stdout, "ERROR: Failed to write ROM header pad bytes to output file\n"); - Status = STATUS_ERROR; - goto BailOut; - } - - HeaderPadBytes--; - } - // - // Write the PCI data structure header to the output file - // - if (fwrite (&PciDs, sizeof (PciDs), 1, OutFptr) != 1) { - fprintf (stdout, "ERROR: Failed to write PCI ROM header to output file\n"); - Status = STATUS_ERROR; - goto BailOut; - } - // - // Keep track of how many bytes left to write - // - TotalSize -= HeaderSize; - - // - // Now dump the input file's contents to the output file - // - if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) { - fprintf (stdout, "ERROR: Failed to write all file bytes to output file\n"); - Status = STATUS_ERROR; - goto BailOut; - } - - TotalSize -= FileSize; - // - // Pad the rest of the image to make it a multiple of 512 bytes - // - while (TotalSize > 0) { - if (putc (~0, OutFptr) == EOF) { - fprintf (stdout, "ERROR: Failed to write trailing pad bytes output file\n"); - Status = STATUS_ERROR; - goto BailOut; - } - - TotalSize--; - } - -BailOut: - if (InFptr != NULL) { - fclose (InFptr); - } - - // - // Free up our buffers - // - if (Buffer != NULL) { - free (Buffer); - } - - if (CompressedBuffer != NULL) { - free (CompressedBuffer); - } - // - // Print the file name if errors occurred - // - if (Status != STATUS_SUCCESS) { - fprintf (stdout, "Error processing EFI file %s\n", InFile->FileName); - } - - return Status; -} - -static -int -CheckPE32File ( - FILE *Fptr, - UINT16 *MachineType, - UINT16 *SubSystem - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - Fptr - GC_TODO: add argument description - MachineType - GC_TODO: add argument description - SubSystem - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - /*++ - -Routine Description: - - Given a file pointer to a supposed PE32 image file, verify that it is indeed a - PE32 image file, and then return the machine type in the supplied pointer. - -Arguments: - - Fptr File pointer to the already-opened PE32 file - MachineType Location to stuff the machine type of the PE32 file. This is needed - because the image may be Itanium-based, IA32, or EBC. - -Returns: - - 0 success - non-zero otherwise - ---*/ - EFI_IMAGE_DOS_HEADER DosHeader; - EFI_IMAGE_FILE_HEADER FileHdr; - EFI_IMAGE_OPTIONAL_HEADER OptionalHdr; - UINT32 PESig; - - // - // Position to the start of the file - // - fseek (Fptr, 0, SEEK_SET); - - // - // Read the DOS header - // - if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) { - fprintf (stdout, "ERROR: Failed to read the DOS stub from the input file\n"); - return STATUS_ERROR; - } - // - // Check the magic number (0x5A4D) - // - if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) { - fprintf (stdout, "ERROR: Input file does not appear to be a PE32 image (magic number)\n"); - return STATUS_ERROR; - } - // - // Position into the file and check the PE signature - // - fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET); - if (fread (&PESig, sizeof (PESig), 1, Fptr) != 1) { - fprintf (stdout, "ERROR: Failed to read PE signature bytes from input file\n"); - return STATUS_ERROR; - } - // - // Check the PE signature in the header "PE\0\0" - // - if (PESig != EFI_IMAGE_NT_SIGNATURE) { - fprintf (stdout, "ERROR: Input file does not appear to be a PE32 image (signature)\n"); - return STATUS_ERROR; - } - // - // Read the file header and stuff their MachineType - // - if (fread (&FileHdr, sizeof (FileHdr), 1, Fptr) != 1) { - fprintf (stdout, "ERROR: Failed to read PE file header from input file\n"); - return STATUS_ERROR; - } - - memcpy ((char *) MachineType, &FileHdr.Machine, 2); - - // - // Read the optional header so we can get the subsystem - // - if (fread (&OptionalHdr, sizeof (OptionalHdr), 1, Fptr) != 1) { - fprintf (stdout, "ERROR: Failed to read COFF optional header from input file\n"); - return STATUS_ERROR; - } - - *SubSystem = OptionalHdr.Subsystem; - if (mOptions.Verbose) { - fprintf (stdout, " Got subsystem = 0x%X from image\n", (int) *SubSystem); - } - // - // Good to go - // - return STATUS_SUCCESS; -} - -static -int -ParseCommandLine ( - int Argc, - char *Argv[], - OPTIONS *Options - ) -/*++ - -Routine Description: - - Given the Argc/Argv program arguments, and a pointer to an options structure, - parse the command-line options and check their validity. - - -Arguments: - - Argc - standard C main() argument count - Argv[] - standard C main() argument list - Options - pointer to a structure to store the options in - -Returns: - - STATUS_SUCCESS success - non-zero otherwise - ---*/ -// -{ - FILE_LIST *FileList; - - FILE_LIST *PrevFileList; - UINT32 FileFlags; - UINT32 ClassCode; - UINT32 CodeRevision; - - FileFlags = 0; - - // - // Clear out the options - // - memset ((char *) Options, 0, sizeof (OPTIONS)); - - // - // To avoid compile warnings - // - FileList = PrevFileList = NULL; - - ClassCode = 0; - CodeRevision = 0; - // - // Skip over the program name - // - Argc--; - Argv++; - - // - // If no arguments, assume they want usage info - // - if (Argc == 0) { - Usage (); - return STATUS_ERROR; - } - // - // Process until no more arguments - // - while (Argc > 0) { - if ((Argv[0][0] == '-') || (Argv[0][0] == '/')) { - // - // To simplify string comparisons, replace slashes with dashes - // - Argv[0][0] = '-'; - - // - // Vendor ID specified with -v - // - if (stricmp (Argv[0], "-v") == 0) { - // - // Make sure there's another parameter - // - if (Argc > 1) { - Options->VendId = (UINT16) strtol (Argv[1], NULL, 16); - Options->VendIdValid = 1; - } else { - fprintf ( - stdout, - "ERROR: Missing Vendor ID with %s\n\n", - Argv[0] - ); - Usage (); - return STATUS_ERROR; - } - - Argv++; - Argc--; - } else if (stricmp (Argv[0], "-d") == 0) { - // - // Device ID specified with -d - // Make sure there's another parameter - // - if (Argc > 1) { - Options->DevId = (UINT16) strtol (Argv[1], NULL, 16); - Options->DevIdValid = 1; - } else { - fprintf ( - stdout, - "ERROR: Missing Device ID with %s\n\n", - Argv[0] - ); - Usage (); - return STATUS_ERROR; - } - - Argv++; - Argc--; - } else if (stricmp (Argv[0], "-o") == 0) { - // - // Output filename specified with -o - // Make sure there's another parameter - // - if (Argc > 1) { - strcpy (Options->OutFileName, Argv[1]); - } else { - fprintf ( - stdout, - "ERROR: Missing output file name with %s\n\n", - Argv[0] - ); - Usage (); - return STATUS_ERROR; - } - - Argv++; - Argc--; - } else if ((stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) { - // - // Help option - // - Usage (); - return STATUS_ERROR; - } else if (stricmp (Argv[0], "-b") == 0) { - // - // Specify binary files with -b - // - FileFlags = (FileFlags &~FILE_FLAG_EFI) | FILE_FLAG_BINARY; - } else if ((stricmp (Argv[0], "-e") == 0) || (stricmp (Argv[0], "-ec") == 0)) { - // - // Specify EFI files with -e. Specify EFI-compressed with -ec. - // - FileFlags = (FileFlags &~FILE_FLAG_BINARY) | FILE_FLAG_EFI; - if ((Argv[0][2] == 'c') || (Argv[0][2] == 'C')) { - FileFlags |= FILE_FLAG_COMPRESS; - } - // - // Specify not to set the LAST bit in the last file with -l - // - } else if (stricmp (Argv[0], "-l") == 0) { - Options->NoLast = 1; - } else if (stricmp (Argv[0], "-p") == 0) { - // - // -v for verbose would have been nicer, but it's already used. Let's use - // -p for prolix (wordy) output - // - Options->Verbose = 1; - } else if (stricmp (Argv[0], "-dump") == 0) { - // - // -dump for dumping a ROM image. In this case, say that the device id - // and vendor id are valid so we don't have to specify bogus ones on the - // command line. - // - Options->DumpOption = 1; - - Options->VendIdValid = 1; - Options->DevIdValid = 1; - FileFlags = FILE_FLAG_BINARY; - } else if (stricmp (Argv[0], "-cc") == 0) { - // - // Class code value for the next file in the list. - // Make sure there's another parameter - // - if (Argc > 1) { - // - // No error checking on the return value. Could check for LONG_MAX, - // LONG_MIN, or 0 class code value if desired. Check range (3 bytes) - // at least. - // - ClassCode = (UINT32) strtol (Argv[1], NULL, 16); - if (ClassCode & 0xFF000000) { - fprintf (stdout, "ERROR: Class code %s out of range\n", Argv[1]); - return STATUS_ERROR; - } - } else { - fprintf ( - stdout, - "ERROR: Missing class code value with %s\n\n", - Argv[0] - ); - Usage (); - return STATUS_ERROR; - } - - Argv++; - Argc--; - } else if (stricmp (Argv[0], "-rev") == 0) { - // - // Code revision in the PCI data structure. The value is for the next - // file in the list. - // Make sure there's another parameter - // - if (Argc > 1) { - // - // No error checking on the return value. Could check for LONG_MAX, - // LONG_MIN, or 0 value if desired. Check range (2 bytes) - // at least. - // - CodeRevision = (UINT32) strtol (Argv[1], NULL, 16); - if (CodeRevision & 0xFFFF0000) { - fprintf (stdout, "ERROR: Code revision %s out of range\n", Argv[1]); - return STATUS_ERROR; - } - } else { - fprintf ( - stdout, - "ERROR: Missing code revision value with %s\n\n", - Argv[0] - ); - Usage (); - return STATUS_ERROR; - } - - Argv++; - Argc--; - } else { - fprintf (stdout, "ERROR: Invalid option specified: %s\n\n", Argv[0]); - Usage (); - return STATUS_ERROR; - } - } else { - // - // Not a slash-option argument. Must be a file name. Make sure they've specified - // -e or -b already. - // - if ((FileFlags & (FILE_FLAG_BINARY | FILE_FLAG_EFI)) == 0) { - fprintf (stdout, "ERROR: Missing -e or -b with input file %s\n", Argv[0]); - return STATUS_ERROR; - } - // - // Create a new file structure - // - FileList = (FILE_LIST *) malloc (sizeof (FILE_LIST)); - if (FileList == NULL) { - fprintf (stdout, "ERROR: Memory allocation failure\n"); - return STATUS_ERROR; - } - - memset ((char *) FileList, 0, sizeof (FILE_LIST)); - FileList->FileName = Argv[0]; - FileList->FileFlags = FileFlags; - if (Options->FileList == NULL) { - Options->FileList = FileList; - } else { - if (PrevFileList == NULL) { - PrevFileList = FileList; - } else { - PrevFileList->Next = FileList; - } - } - - PrevFileList = FileList; - // - // Set the class code and code revision for this file, then reset the values. - // - FileList->ClassCode = ClassCode; - FileList->CodeRevision = (UINT16) CodeRevision; - ClassCode = 0; - CodeRevision = 0; - } - // - // Next argument - // - Argv++; - Argc--; - } - // - // Make sure they specified a device ID and vendor ID - // - if (!Options->VendIdValid) { - fprintf (stdout, "ERROR: Missing Vendor ID on command line\n\n"); - Usage (); - return STATUS_ERROR; - } - - if (!Options->DevIdValid) { - fprintf (stdout, "ERROR: Missing Device ID on command line\n\n"); - Usage (); - return STATUS_ERROR; - } - // - // Must have specified some files - // - if (Options->FileList == NULL) { - fprintf (stdout, "ERROR: Missing input file name\n"); - Usage (); - return STATUS_ERROR; - } - - return 0; -} - -static -void -Usage ( - VOID - ) -/*++ - -Routine Description: - - Print usage information for this utility. - -Arguments: - - None. - -Returns: - - Nothing. - ---*/ -{ - int Index; - static const char *Msg[] = { - "EfiRom "UTILITY_VERSION " - Intel EFI Make Option ROM utility", - " Copyright (C), 1999-2002 Intel Coproration\n", - " Create an option ROM image from a list of input files", - " Usage: efirom {-p} [-v VendorId] [-d DeviceId] {-o OutFileName} ", - " [-e|-b] [FileName(s)]", - " where:", - " VendorId - required hex PCI Vendor ID for the device", - " DeviceId - required hex PCI Device ID for the device", - " OutFileName - optional output file name. Default is the first input", - " file name with a "DEFAULT_OUTPUT_EXTENSION " file extension", - " FileNames - input PE32 or binary file name(s)", - " BinFileName - input binary file name(s)", - " -p - for verbose output", - " -l - to not automatically set the LAST bit on the last file", - " -b - following FileNames are binary files", - " -e - following FileNames are EFI PE32 image files", - " -ec - following FileNames are EFI PE32 image files, and should", - " be compressed by this utility", - " -cc ClassCode - to use hex ClassCode in the PCI data structure header for", - " the following FileName", - " -rev Revision - to use hex Revision in the PCI data structure header for", - " the following FileName", - " -dump - to dump the headers of an existing option ROM image", - "", - "Example usage: EfiRom -v 0xABCD -d 0x1234 -b File1.bin File2.bin -e File1.efi File2.efi ", - "", - NULL - }; - - for (Index = 0; Msg[Index] != NULL; Index++) { - fprintf (stdout, "%s\n", Msg[Index]); - } -} - -static -void -DumpImage ( - FILE_LIST *InFile - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - InFile - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - PCI_EXPANSION_ROM_HEADER PciRomHdr; - FILE *InFptr; - UINT32 ImageStart; - UINT32 ImageCount; - EFI_PCI_EXPANSION_ROM_HEADER EfiRomHdr; - PCI_DATA_STRUCTURE PciDs; - - // - // Open the input file - // - if ((InFptr = fopen (InFile->FileName, "rb")) == NULL) { - fprintf ( - stdout, - "ERROR: Could not open input file %s\n", - InFile->FileName - ); - return ; - } - // - // Go through the image and dump the header stuff for each - // - ImageCount = 0; - for (;;) { - // - // Save our postition in the file, since offsets in the headers - // are relative to the particular image. - // - ImageStart = ftell (InFptr); - ImageCount++; - - // - // Read the option ROM header. Have to assume a raw binary image for now. - // - if (fread (&PciRomHdr, sizeof (PciRomHdr), 1, InFptr) != 1) { - fprintf (stdout, "ERROR: Failed to read PCI ROM header from file\n"); - goto BailOut; - } - - // - // Dump the contents of the header - // - fprintf (stdout, "Image %d -- Offset 0x%X\n", ImageCount, ImageStart); - fprintf (stdout, " ROM header contents\n"); - fprintf (stdout, " Signature 0x%04X\n", (UINT32) PciRomHdr.Signature); - fprintf (stdout, " PCIR offset 0x%04X\n", (UINT32) PciRomHdr.PcirOffset); - // - // Find PCI data structure - // - if (fseek (InFptr, ImageStart + PciRomHdr.PcirOffset, SEEK_SET)) { - fprintf (stdout, "ERROR: Failed to seek to PCI data structure\n"); - goto BailOut; - } - // - // Read and dump the PCI data structure - // - if (fread (&PciDs, sizeof (PciDs), 1, InFptr) != 1) { - fprintf (stdout, "ERROR: Failed to read PCI data structure from file\n"); - goto BailOut; - } - - fprintf (stdout, " PCI Data Structure\n"); - fprintf ( - stdout, - " Signature %c%c%c%c\n", - (char) PciDs.Signature, - (char) (PciDs.Signature >> 8), - (char) (PciDs.Signature >> 16), - (char) (PciDs.Signature >> 24) - ); - fprintf (stdout, " Vendor ID 0x%04X\n", PciDs.VendorId); - fprintf (stdout, " Device ID 0x%04X\n", PciDs.DeviceId); - fprintf ( - stdout, - " Class Code 0x%06X\n", - (UINT32) (PciDs.ClassCode[0] | (PciDs.ClassCode[1] << 8) | (PciDs.ClassCode[2] << 16)) - ); - fprintf (stdout, " Image size 0x%X\n", PciDs.ImageLength * 512); - fprintf (stdout, " Code revision: 0x%04X\n", PciDs.CodeRevision); - fprintf (stdout, " Indicator 0x%02X", (UINT32) PciDs.Indicator); - // - // Print the indicator, used to flag the last image - // - if (PciDs.Indicator == INDICATOR_LAST) { - fprintf (stdout, " (last image)\n"); - } else { - fprintf (stdout, "\n"); - } - // - // Print the code type. If EFI code, then we can provide more info. - // - fprintf (stdout, " Code type 0x%02X", (UINT32) PciDs.CodeType); - if (PciDs.CodeType == PCI_CODE_TYPE_EFI_IMAGE) { - fprintf (stdout, " (EFI image)\n"); - // - // Re-read the header as an EFI ROM header, then dump more info - // - fprintf (stdout, " EFI ROM header contents\n"); - if (fseek (InFptr, ImageStart, SEEK_SET)) { - fprintf (stdout, "ERROR: Failed to re-seek to ROM header structure\n"); - goto BailOut; - } - - if (fread (&EfiRomHdr, sizeof (EfiRomHdr), 1, InFptr) != 1) { - fprintf (stdout, "ERROR: Failed to read EFI PCI ROM header from file\n"); - goto BailOut; - } - // - // Now dump more info - // - fprintf (stdout, " EFI Signature 0x%04X\n", EfiRomHdr.EfiSignature); - fprintf ( - stdout, - " Compression Type 0x%04X ", - (UINT32) EfiRomHdr.CompressionType - ); - if (EfiRomHdr.CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) { - fprintf (stdout, "(compressed)\n"); - } else { - fprintf (stdout, "(not compressed)\n"); - } - - fprintf ( - stdout, - " Machine type 0x%04X (%s)\n", - EfiRomHdr.EfiMachineType, - GetMachineTypeStr (EfiRomHdr.EfiMachineType) - ); - fprintf ( - stdout, - " Subsystem 0x%04X (%s)\n", - EfiRomHdr.EfiSubsystem, - GetSubsystemTypeStr (EfiRomHdr.EfiSubsystem) - ); - fprintf ( - stdout, - " EFI image offset 0x%04X (@0x%X)\n", - (UINT32) EfiRomHdr.EfiImageHeaderOffset, - (UINT32) (EfiRomHdr.EfiImageHeaderOffset + ImageStart) - ); - - } else { - // - // Not an EFI image - // - fprintf (stdout, "\n"); - } - // - // If code type is EFI image, then dump it as well? - // - // if (PciDs.CodeType == PCI_CODE_TYPE_EFI_IMAGE) { - // } - // - // If last image, then we're done - // - if (PciDs.Indicator == INDICATOR_LAST) { - goto BailOut; - } - // - // Seek to the start of the next image - // - if (fseek (InFptr, ImageStart + (PciDs.ImageLength * 512), SEEK_SET)) { - fprintf (stdout, "ERROR: Failed to seek to next image\n"); - goto BailOut; - } - } - -BailOut: - fclose (InFptr); -} - -char * -GetMachineTypeStr ( - UINT16 MachineType - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - MachineType - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - int Index; - - for (Index = 0; mMachineTypes[Index].Name != NULL; Index++) { - if (mMachineTypes[Index].Value == MachineType) { - return mMachineTypes[Index].Name; - } - } - - return "unknown"; -} - -static -char * -GetSubsystemTypeStr ( - UINT16 SubsystemType - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - SubsystemType - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - int Index; - - for (Index = 0; mSubsystemTypes[Index].Name != NULL; Index++) { - if (mSubsystemTypes[Index].Value == SubsystemType) { - return mSubsystemTypes[Index].Name; - } - } - - return "unknown"; -} diff --git a/Tools/CodeTools/TianoTools/EfiRom/build.xml b/Tools/CodeTools/TianoTools/EfiRom/build.xml deleted file mode 100644 index acb94a4835..0000000000 --- a/Tools/CodeTools/TianoTools/EfiRom/build.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/FlashMap/FlashDefFile.c b/Tools/CodeTools/TianoTools/FlashMap/FlashDefFile.c deleted file mode 100644 index cdbf7886ec..0000000000 --- a/Tools/CodeTools/TianoTools/FlashMap/FlashDefFile.c +++ /dev/null @@ -1,2788 +0,0 @@ -/*++ - -Copyright (c) 2004-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - FlashDefFile.c - -Abstract: - - Utility for flash management in the Intel Platform Innovation Framework - for EFI build environment. - ---*/ - -#include -#include -#include - -#include -#include -#include - -#include "EfiUtilityMsgs.h" -#include "FlashDefFile.h" -#include "SimpleFileParsing.h" -#include "Symbols.h" - -// -// #include "TrackMallocFree.h" -// -#define WCHAR_T char -#define MAX_STRING_LEN 256 -#define MAX_NAME_LEN 128 -#define BUFFER_SIZE 1024 -#define MAX_ATTR_LEN 128 -#define MAX_AREATYPE_LEN 128 -#define COLUMN2_START 60 -#define COLUMN3_START 70 -// -// Information for each subregions defined in the fdf file will be saved in these -// -typedef struct _FLASH_SUBREGION_DESCRIPTION { - struct _FLASH_SUBREGION_DESCRIPTION *Next; - int CreateHob; // to add to the auto-created HOB array - WCHAR_T Name[MAX_NAME_LEN]; // each subregion within a region must have a unique name - unsigned int Size; // size, in bytes, of this subregion - unsigned int SizeLeft; // used when creating the image - WCHAR_T Attributes[MAX_ATTR_LEN]; // subregion attributes used in the output HOB - WCHAR_T AreaType[MAX_AREATYPE_LEN]; // subregion area type used in the output HOB - EFI_GUID NameGuid; // used in the output HOB - WCHAR_T NameGuidString[MAX_NAME_LEN]; - EFI_GUID AreaTypeGuid; // used in the output HOB - WCHAR_T AreaTypeGuidString[MAX_NAME_LEN]; - EFI_GUID FileSystemGuid; // used in the output HOB - WCHAR_T FileSystemGuidString[MAX_NAME_LEN]; -} FLASH_SUBREGION_DESCRIPTION; - -// -// Information for each block in a flash device will be saved in one of these. -// We'll also use it for region definitions. -// -typedef struct _FLASH_BLOCK_DESCRIPTION { - struct _FLASH_BLOCK_DESCRIPTION *Next; // next block in the linked list - WCHAR_T Name[MAX_NAME_LEN]; // each block must have a unique name - unsigned int Size; // size, in bytes, of this block - unsigned int SizeLeft; // for use when creating image - unsigned int Flags; // user-defined flags for the block - unsigned int Alignment; // power of 2 alignment - WCHAR_T Attributes[MAX_ATTR_LEN]; // only used for Region definitions - WCHAR_T AreaType[MAX_AREATYPE_LEN]; // only used for Region definitions - FLASH_SUBREGION_DESCRIPTION *Subregions; - FLASH_SUBREGION_DESCRIPTION *LastSubregion; -} FLASH_BLOCK_DESCRIPTION; - -// -// Information for each flash device will be saved in one of these -// -typedef struct _FLASH_DEVICE_DESCRIPTION { - struct _FLASH_DEVICE_DESCRIPTION *Next; // next flash device in our linked list - int ErasePolarity; // erase polarity of the flash device - unsigned int BaseAddress; // base address of the flash device - unsigned int Size; // total size, in bytes, of the flash device - WCHAR_T Name[MAX_NAME_LEN]; // name of the flash device - FLASH_BLOCK_DESCRIPTION *PBlocks; // linked list of physical block descriptors - FLASH_BLOCK_DESCRIPTION *LastPBlock; // last block in the linked list - FLASH_BLOCK_DESCRIPTION *Regions; // linked list of flash region descriptors - FLASH_BLOCK_DESCRIPTION *LastRegion; // last region in the linked list -} FLASH_DEVICE_DESCRIPTION; - -// -// For image definitions, they can specify a file name or raw data bytes. Keep a linked list. -// -typedef struct _IMAGE_DEFINITION_ENTRY { - struct _IMAGE_DEFINITION_ENTRY *Next; - WCHAR_T RegionName[MAX_NAME_LEN]; - WCHAR_T SubregionName[MAX_NAME_LEN]; - WCHAR_T Name[MAX_NAME_LEN]; // file or data name - int IsRawData; // non-zero if raw data bytes - unsigned int RawDataSize; - char *RawData; - int Optional; // optional file (don't include if it doesn't exist) -} IMAGE_DEFINITION_ENTRY; - -// -// When we parse an image definition, save all the data for each in one of these -// -typedef struct _IMAGE_DEFINITION { - struct _IMAGE_DEFINITION *Next; - WCHAR_T Name[MAX_NAME_LEN]; - IMAGE_DEFINITION_ENTRY *Entries; - IMAGE_DEFINITION_ENTRY *LastEntry; -} IMAGE_DEFINITION; - -typedef struct { - char *BufferStart; - char *BufferEnd; - char *BufferPos; -} BUFFER_DATA; - -static const char *CIncludeHeader = "/*++\n\n" -" DO NOT EDIT -- file auto-generated by FlashMap utility\n\n""--*/\n""\n""#ifndef _FLASH_MAP_H_\n" -"#define _FLASH_MAP_H_\n\n"; -// -// "#include \"EfiFlashMap.h\"\n\n"; -// -static const char *CIncludeFooter = "#endif // #ifndef _FLASH_MAP_H_\n\n"; - -static const char *CFlashMapDataFileHeader = "/*++\n\n" -" DO NOT EDIT -- file auto-generated by FlashMap utility\n\n""--*/\n""\n"; - -static FLASH_DEVICE_DESCRIPTION *mFlashDevices = NULL; -static IMAGE_DEFINITION *mImageDefinitions = NULL; - -// -// Local function prototypes -// -static -BUFFER_DATA * -CreateBufferData ( - VOID - ); - -static -BOOLEAN -AddBufferDataByte ( - BUFFER_DATA *Buffer, - char Data - ); - -static -void -FreeBufferData ( - BUFFER_DATA *Buffer, - BOOLEAN FreeData - ); - -static -char * -GetBufferData ( - BUFFER_DATA *Buffer, - int *BufferSize - ); - -static -FLASH_SUBREGION_DESCRIPTION * -ParseSubregionDefinition ( - unsigned int SizeLeft - ); - -void -FDFConstructor ( - VOID - ) -/*++ - -Routine Description: - Initialization routine for the services that operate on a flash - definition file. - -Arguments: - None. - -Returns: - NA - ---*/ -{ - mFlashDevices = NULL; - mImageDefinitions = NULL; -} - -void -FDFDestructor ( - VOID - ) -/*++ - -Routine Description: - Finalization/cleanup routine for the services that operate on a flash - definition file. - -Arguments: - None. - -Returns: - NA - ---*/ -{ - FLASH_BLOCK_DESCRIPTION *FBNext; - FLASH_DEVICE_DESCRIPTION *FDNext; - IMAGE_DEFINITION *IDNext; - IMAGE_DEFINITION_ENTRY *IDENext; - FLASH_SUBREGION_DESCRIPTION *SubNext; - // - // Go through all our flash devices and free the memory - // - while (mFlashDevices != NULL) { - // - // Free the physical block definitions - // - while (mFlashDevices->PBlocks != NULL) { - FBNext = mFlashDevices->PBlocks->Next; - _free (mFlashDevices->PBlocks); - mFlashDevices->PBlocks = FBNext; - } - // - // Free the region definitions - // - while (mFlashDevices->Regions != NULL) { - FBNext = mFlashDevices->Regions->Next; - // - // First free the subregion definitions - // - while (mFlashDevices->Regions->Subregions != NULL) { - SubNext = mFlashDevices->Regions->Subregions->Next; - _free (mFlashDevices->Regions->Subregions); - mFlashDevices->Regions->Subregions = SubNext; - } - - _free (mFlashDevices->Regions); - mFlashDevices->Regions = FBNext; - } - - FDNext = mFlashDevices->Next; - _free (mFlashDevices); - mFlashDevices = FDNext; - } - // - // Free up the image definitions, and the data - // - while (mImageDefinitions != NULL) { - // - // Free the entries - // - while (mImageDefinitions->Entries != NULL) { - IDENext = mImageDefinitions->Entries->Next; - if (mImageDefinitions->Entries->RawData != NULL) { - _free (mImageDefinitions->Entries->RawData); - } - - _free (mImageDefinitions->Entries); - mImageDefinitions->Entries = IDENext; - } - - IDNext = mImageDefinitions->Next; - _free (mImageDefinitions); - mImageDefinitions = IDNext; - } -} - -STATUS -FDFParseFile ( - char *FileName - ) -/*++ - -Routine Description: - Parse the specified flash definition file, saving the definitions in - file-static variables for use by other functions. - -Arguments: - FileName - name of the input flash definition text file. - -Returns: - STATUS_SUCCESS - file parsed with no errors or warnings - STATUS_WARNING - warnings, but no errors, were encountered while parsing - STATUS_ERROR - errors were encountered while parsing - ---*/ -{ - FILE *Fptr; - STATUS Status; - unsigned int Num; - FLASH_DEVICE_DESCRIPTION *FDDesc; - FLASH_BLOCK_DESCRIPTION *FBlockDesc; - FLASH_BLOCK_DESCRIPTION *TempBlockDesc; - FLASH_SUBREGION_DESCRIPTION *Subregion; - FLASH_SUBREGION_DESCRIPTION *TempSubregion; - unsigned int BlockSizeLeft; - unsigned int RegionSizeLeft; - unsigned int SubregionSizeLeft; - int ErrorCount; - int WarningCount; - IMAGE_DEFINITION *ImageDef; - IMAGE_DEFINITION_ENTRY *ImageDefEntry; - IMAGE_DEFINITION_ENTRY *TempImageDefEntry; - BUFFER_DATA *BufferData; - char Str[100]; - BOOLEAN PreviousComma; - - if ((Fptr = fopen (FileName, "r")) == NULL) { - Error (NULL, 0, 0, FileName, "failed to open input flash definition file for reading"); - return STATUS_ERROR; - } - - fclose (Fptr); - Status = STATUS_SUCCESS; - ErrorCount = 0; - WarningCount = 0; - // - // Initialize the simple-file-parsing routines - // - SFPInit (); - // - // Open the file - // - if ((Status = SFPOpenFile (FileName)) != STATUS_SUCCESS) { - return Status; - } - // - // Parse the file. Should start with a series of these: - // FlashDevice { - // Name = "FLASH_1234", Size = 0x2004, BaseAddress = 0xFFF0000, ErasePolarity = 1, - // Block { Name = "BLOCK1", Size = 0x1000, Flags = 0x0001 } - // Block { Name = "BLOCK2", Size = 0x1004, Flags = 0x0002 } - // Region { Name = "REGION_NAME", Size = 0x2004, Align= 4 } - // } - // - while (SFPIsKeyword ("FlashDevice")) { - // - // Allocate memory for new flash device description block - // - FDDesc = (FLASH_DEVICE_DESCRIPTION *) _malloc (sizeof (FLASH_DEVICE_DESCRIPTION)); - if (FDDesc == NULL) { - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - ErrorCount++; - goto Done; - } - - memset (FDDesc, 0, sizeof (FLASH_DEVICE_DESCRIPTION)); - // - // Open brace -- warning if not there - // - if (!SFPIsToken ("{")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL); - WarningCount++; - } - // - // Parse: Name = "DeviceName", - // - if (!SFPIsKeyword ("Name")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetQuotedString (FDDesc->Name, sizeof (FDDesc->Name))) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of flash device", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following flash device name", NULL); - WarningCount++; - } - // - // Parse: Size = 0x20000, - // - if (!SFPIsKeyword ("Size")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetNumber (&FDDesc->Size)) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL); - ErrorCount++; - goto Done; - } - // - // Check for 0 size - // - if (FDDesc->Size == 0) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, FDDesc->Name, "Size field cannot be 0", NULL); - ErrorCount++; - goto Done; - } - - SFPIsToken (","); - // - // Parse: BaseAddress = 0xFFF0000, - // - if (!SFPIsKeyword ("BaseAddress")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'BaseAddress'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetNumber (&FDDesc->BaseAddress)) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for BaseAddress", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following BaseAddress value", NULL); - WarningCount++; - } - // - // Parse: ErasePolarity = 1, - // - if (!SFPIsKeyword ("ErasePolarity")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'ErasePolarity'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetNumber (&Num) || ((Num != 0) && (Num != 1))) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric erase polarity value 1 or 0", NULL); - ErrorCount++; - goto Done; - } - - FDDesc->ErasePolarity = Num; - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following erase polarity value", NULL); - WarningCount++; - } - // - // Parse array of: - // Block { Name = "BLOCK1", Size = 0x1000, Flags = 0x0001 } - // - // Keep track of size to make sure the sum of the physical blocks and region sizes do not - // exceed the size of the flash device. - // - BlockSizeLeft = FDDesc->Size; - RegionSizeLeft = FDDesc->Size; - while (SFPIsKeyword ("Block")) { - // - // Allocate memory for a new physical block descriptor - // - FBlockDesc = (FLASH_BLOCK_DESCRIPTION *) _malloc (sizeof (FLASH_BLOCK_DESCRIPTION)); - if (FBlockDesc == NULL) { - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - ErrorCount++; - goto Done; - } - - memset (FBlockDesc, 0, sizeof (FLASH_BLOCK_DESCRIPTION)); - // - // Open brace -- warning if not there - // - if (!SFPIsToken ("{")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL); - WarningCount++; - } - // - // Parse: Name = "BlockName", - // - if (!SFPIsKeyword ("Name")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetQuotedString (FBlockDesc->Name, sizeof (FBlockDesc->Name))) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of physical block", NULL); - ErrorCount++; - goto Done; - } - // - // Make sure there are no other physical block names with this same name - // - for (TempBlockDesc = FDDesc->PBlocks; TempBlockDesc != NULL; TempBlockDesc = TempBlockDesc->Next) { - if (strcmp (TempBlockDesc->Name, FBlockDesc->Name) == 0) { - Error ( - SFPGetFileName (), - SFPGetLineNumber (), - 0, - TempBlockDesc->Name, - "physical block with this name already defined" - ); - ErrorCount++; - } - } - - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following physical block name", NULL); - WarningCount++; - } - // - // Parse: Size = 0x2000, - // - if (!SFPIsKeyword ("Size")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetNumber (&FBlockDesc->Size)) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL); - ErrorCount++; - goto Done; - } - // - // Make sure the sum of physical blocks so far does not exceed flash device size - // - if (BlockSizeLeft < FBlockDesc->Size) { - Error ( - SFPGetFileName (), - SFPGetLineNumber (), - 0, - "sum of physical block sizes exceeds flash device size", - NULL - ); - ErrorCount++; - } - - BlockSizeLeft -= FBlockDesc->Size; - SFPIsToken (","); - // - // Optional parse: Flags = 0xFFF0000, - // - if (SFPIsKeyword ("Flags")) { - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetNumber (&FBlockDesc->Flags)) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for Flags", NULL); - ErrorCount++; - goto Done; - } - } - - if (!SFPIsToken ("}")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected PhysicalBlock closing brace '}'", NULL); - WarningCount++; - } - // - // Add the physical block descriptor to the end of the linked list - // - if (FDDesc->LastPBlock != NULL) { - FDDesc->LastPBlock->Next = FBlockDesc; - } else { - FDDesc->PBlocks = FBlockDesc; - } - - FDDesc->LastPBlock = FBlockDesc; - } - // - // Make sure sum of sizes of physical blocks added up to size of flash device - // - if (BlockSizeLeft != 0) { - Error ( - SFPGetFileName (), - SFPGetLineNumber (), - 0, - NULL, - "sum of sizes of physical blocks (0x%08X) != flash device size (0x%08X) : delta = 0x%08X", - FDDesc->Size - BlockSizeLeft, - FDDesc->Size, - BlockSizeLeft - ); - ErrorCount++; - } - // - // Parse array of: - // Region { Name = "REGION_1", Size = 0x2000, Flags = 0x1234, Alignment = 4, Attributes = "str", AreaType = "str" } - // - while (SFPIsKeyword ("Region")) { - // - // Allocate memory for a new physical block descriptor - // - FBlockDesc = (FLASH_BLOCK_DESCRIPTION *) _malloc (sizeof (FLASH_BLOCK_DESCRIPTION)); - if (FBlockDesc == NULL) { - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - ErrorCount++; - goto Done; - } - - memset (FBlockDesc, 0, sizeof (FLASH_BLOCK_DESCRIPTION)); - // - // Open brace -- warning if not there - // - if (!SFPIsToken ("{")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL); - WarningCount++; - } - // - // Parse: Name = "BlockName", - // - if (!SFPIsKeyword ("Name")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetQuotedString (FBlockDesc->Name, sizeof (FBlockDesc->Name))) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL); - ErrorCount++; - goto Done; - } - // - // Make sure there are no other region names with this same name - // - for (TempBlockDesc = FDDesc->Regions; TempBlockDesc != NULL; TempBlockDesc = TempBlockDesc->Next) { - if (strcmp (TempBlockDesc->Name, FBlockDesc->Name) == 0) { - Error ( - SFPGetFileName (), - SFPGetLineNumber (), - 0, - TempBlockDesc->Name, - "Region with this name already defined" - ); - ErrorCount++; - } - } - - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL); - WarningCount++; - } - // - // Parse: Size = 0x2000, - // - if (!SFPIsKeyword ("Size")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetNumber (&FBlockDesc->Size)) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL); - } - // - // Make sure the sum of regions so far does not exceed flash device size - // - if (RegionSizeLeft < FBlockDesc->Size) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "sum of Region sizes exceeds flash device size", NULL); - ErrorCount++; - } - - RegionSizeLeft -= FBlockDesc->Size; - // - // Optional parse: Flags = 0xFFF0000, - // - if (SFPIsKeyword ("Flags")) { - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetNumber (&FBlockDesc->Flags)) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric value for Flags", NULL); - ErrorCount++; - goto Done; - } - // - // comma - // - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL); - } - } - // - // Optional parse: Alignment = 4 - // - if (SFPIsKeyword ("Alignment")) { - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetNumber (&FBlockDesc->Alignment)) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Alignment value", NULL); - ErrorCount++; - goto Done; - } - // - // comma - // - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL); - } - } - // - // Parse: Attributes = "String", - // - if (!SFPIsKeyword ("Attributes")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Attributes'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetQuotedString (FBlockDesc->Attributes, sizeof (FBlockDesc->Attributes))) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Attributes string", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL); - } - // - // Parse: AreaType = "String", - // - if (!SFPIsKeyword ("AreaType")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'AreaType'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetQuotedString (FBlockDesc->AreaType, sizeof (FBlockDesc->AreaType))) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted AreaType string", NULL); - ErrorCount++; - goto Done; - } - - PreviousComma = SFPIsToken (","); - // - // Parse optional Subregion definitions - // - SubregionSizeLeft = FBlockDesc->Size; - while (SFPIsToken ("Subregion")) { - if (!PreviousComma) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'Subregion'", NULL); - WarningCount++; - PreviousComma = TRUE; - } - - Subregion = ParseSubregionDefinition (SubregionSizeLeft); - if (Subregion == NULL) { - ErrorCount++; - goto Done; - } - - SubregionSizeLeft -= Subregion->Size; - // - // Add it to the end of our list - // - if (FBlockDesc->Subregions == NULL) { - FBlockDesc->Subregions = Subregion; - } else { - FBlockDesc->LastSubregion->Next = Subregion; - } - - FBlockDesc->LastSubregion = Subregion; - // - // Make sure all subregion names are unique. We do this each time - // through so that we catch the error immediately after it happens, in - // which case the reported line number is at least close to where the - // problem lies. We don't exit on the error because we can continue parsing - // the script to perhaps catch other errors or warnings. - // - for (Subregion = FBlockDesc->Subregions; Subregion != NULL; Subregion = Subregion->Next) { - for (TempSubregion = Subregion->Next; TempSubregion != NULL; TempSubregion = TempSubregion->Next) { - if (strcmp (Subregion->Name, TempSubregion->Name) == 0) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, Subregion->Name, "duplicate Subregion name"); - ErrorCount++; - } - } - } - } - - if (!SFPIsToken ("}")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Region closing brace '}'", NULL); - WarningCount++; - } - // - // Add the region descriptor to the end of the linked list - // - if (FDDesc->LastRegion != NULL) { - FDDesc->LastRegion->Next = FBlockDesc; - } else { - FDDesc->Regions = FBlockDesc; - } - - FDDesc->LastRegion = FBlockDesc; - } - // - // Make sure sum of sizes of regions adds up to size of flash device - // - if (RegionSizeLeft != 0) { - Error ( - SFPGetFileName (), - SFPGetLineNumber (), - 0, - NULL, - "sum of sizes of Regions (0x%08X) != flash device size (0x%08X) : delta = 0x%08X", - FDDesc->Size - RegionSizeLeft, - FDDesc->Size, - RegionSizeLeft - ); - ErrorCount++; - } - // - // Look for closing brace - // - if (!SFPIsToken ("}")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected FlashDevice closing brace '}'", NULL); - WarningCount++; - } - // - // Add this flash description to the list - // - FDDesc->Next = mFlashDevices; - mFlashDevices = FDDesc; - } - - while (SFPIsKeyword ("FlashDeviceImage")) { - // - // Allocate memory for a new FD image definition - // - ImageDef = (IMAGE_DEFINITION *) _malloc (sizeof (IMAGE_DEFINITION)); - if (ImageDef == NULL) { - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - ErrorCount++; - goto Done; - } - - memset (ImageDef, 0, sizeof (IMAGE_DEFINITION)); - // - // Open brace -- warning if not there - // - if (!SFPIsToken ("{")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL); - WarningCount++; - } - // - // Parse: Name = "ImageName", - // - if (!SFPIsKeyword ("Name")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetQuotedString (ImageDef->Name, sizeof (ImageDef->Name))) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of image", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following image name", NULL); - WarningCount++; - } - - while (1) { - // - // Parse: File { Name = "FV\FvOem.fv", Region = "REGION_OEM", Optional = TRUE } - // - if (SFPIsKeyword ("File")) { - ImageDefEntry = (IMAGE_DEFINITION_ENTRY *) _malloc (sizeof (IMAGE_DEFINITION_ENTRY)); - if (ImageDefEntry == NULL) { - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - ErrorCount++; - goto Done; - } - - memset (ImageDefEntry, 0, sizeof (IMAGE_DEFINITION_ENTRY)); - // - // Open brace -- warning if not there - // - if (!SFPIsToken ("{")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL); - WarningCount++; - } - // - // Parse: Name = "FileName.txt" - // - if (!SFPIsKeyword ("Name")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetQuotedString (ImageDefEntry->Name, sizeof (ImageDefEntry->Name))) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of file", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following file name", NULL); - WarningCount++; - } - // - // Parse: Region = "REGION_NAME" - // - if (!SFPIsKeyword ("Region")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Region'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetQuotedString (ImageDefEntry->RegionName, sizeof (ImageDefEntry->RegionName))) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL); - WarningCount++; - } - // - // Parse optional: Subregion = "SUBREGION_NAME" - // - if (SFPIsKeyword ("Subregion")) { - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetQuotedString (ImageDefEntry->SubregionName, sizeof (ImageDefEntry->SubregionName))) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Subegion name", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Subregion name", NULL); - WarningCount++; - } - // - // For a given region, you can only place data using the region name, or the subregion names. - // In other words, you can't say File1->Region1 and File2->Region1.Subregion1. Enforce that - // here by checking that any previous entries with the same Region name had a Subregion specified - // as well. - // - for (TempImageDefEntry = ImageDef->Entries; - TempImageDefEntry != NULL; - TempImageDefEntry = TempImageDefEntry->Next - ) { - if (strcmp (TempImageDefEntry->Name, ImageDefEntry->Name) == 0) { - if (TempImageDefEntry->SubregionName[0] == 0) { - Error ( - SFPGetFileName (), - SFPGetLineNumber (), - 0, - TempImageDefEntry->RegionName, - "data already placed on a region-basis in the region, can't place data using subregions" - ); - ErrorCount++; - } - } - } - } - // - // Optional parse: Optional = TRUE | FALSE - // - if (SFPIsKeyword ("Optional")) { - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPIsKeyword ("TRUE")) { - ImageDefEntry->Optional = 1; - } else if (SFPIsKeyword ("FALSE")) { - // - // Already set to 0 - // - } else { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL); - ErrorCount++; - goto Done; - } - - SFPIsToken (","); - } - // - // Closing brace - // - if (!SFPIsToken ("}")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '}' closing brace to File entry", NULL); - ErrorCount++; - goto Done; - } - // - // Add the entry to the end of the list - // - if (ImageDef->LastEntry != NULL) { - ImageDef->LastEntry->Next = ImageDefEntry; - } else { - ImageDef->Entries = ImageDefEntry; - } - - ImageDef->LastEntry = ImageDefEntry; - } else if (SFPIsKeyword ("RawData")) { - // - // Parse: RawData { Name = "PadBytes", Region = "REGION_1", Data = { 0x78, 0x56, 0x34, 0x12 }} - // - ImageDefEntry = (IMAGE_DEFINITION_ENTRY *) _malloc (sizeof (IMAGE_DEFINITION_ENTRY)); - if (ImageDefEntry == NULL) { - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - ErrorCount++; - goto Done; - } - - memset (ImageDefEntry, 0, sizeof (IMAGE_DEFINITION_ENTRY)); - ImageDefEntry->IsRawData = 1; - // - // Open brace -- warning if not there - // - if (!SFPIsToken ("{")) { - Warning ( - SFPGetFileName (), - SFPGetLineNumber (), - 0, - "expected '{' opening brace for RawData definition", - NULL - ); - WarningCount++; - } - // - // Parse: Name = "PadBytes" - // - if (!SFPIsKeyword ("Name")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetQuotedString (ImageDefEntry->Name, sizeof (ImageDefEntry->Name))) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted name of raw data", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following raw data name", NULL); - WarningCount++; - } - // - // Parse: Region = "REGION_NAME" - // - if (!SFPIsKeyword ("Region")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Region'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetQuotedString (ImageDefEntry->RegionName, sizeof (ImageDefEntry->RegionName))) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Region name", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL); - WarningCount++; - } - // - // Parse optional: Subregion = "SUBREGION_NAME" - // - if (SFPIsKeyword ("Subregion")) { - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetQuotedString (ImageDefEntry->SubregionName, sizeof (ImageDefEntry->SubregionName))) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Subegion name", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Subregion name", NULL); - WarningCount++; - } - // - // For a given region, you can only place data using the region name, or the subregion names. - // In other words, you can't say File1->Region1 and File2->Region1.Subregion1. Enforce that - // here by checking that any previous entries with the same Region name had a Subregion specified - // as well. - // - for (TempImageDefEntry = ImageDef->Entries; - TempImageDefEntry != NULL; - TempImageDefEntry = TempImageDefEntry->Next - ) { - if (strcmp (TempImageDefEntry->Name, ImageDefEntry->Name) == 0) { - if (TempImageDefEntry->SubregionName[0] == 0) { - Error ( - SFPGetFileName (), - SFPGetLineNumber (), - 0, - TempImageDefEntry->RegionName, - "data already placed on a region-basis in the region, can't place data using subregions" - ); - ErrorCount++; - } - } - } - } - // - // Parse: Data = { 0x78, 0x56, 0x34, 0x12 } - // - if (!SFPIsKeyword ("Data")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Data'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPIsToken ("{")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '{' preceeding data list", NULL); - WarningCount++; - } - - if ((BufferData = CreateBufferData ()) == NULL) { - ErrorCount++; - goto Done; - } - // - // Read bytes from input file until closing brace - // - while (!SFPIsToken ("}")) { - if (!SFPGetNumber (&Num)) { - SFPGetNextToken (Str, sizeof (Str)); - Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "expected data value", Str); - ErrorCount++; - FreeBufferData (BufferData, TRUE); - goto Done; - } else { - // - // Only allow bytes - // - if (Num > 0xFF) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "only values 0-255 (0x00-0xFF) allowed", NULL); - ErrorCount++; - FreeBufferData (BufferData, TRUE); - goto Done; - } - - AddBufferDataByte (BufferData, (char) Num); - SFPIsToken (","); - } - } - // - // Now get the data and save it in our image entry - // - ImageDefEntry->RawData = GetBufferData (BufferData, &ImageDefEntry->RawDataSize); - FreeBufferData (BufferData, 0); - // - // Closing brace for RawData {} - // - if (!SFPIsToken ("}")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '}' closing brace for RawData", NULL); - ErrorCount++; - goto Done; - } - // - // Add the entry to the end of the list - // - if (ImageDef->LastEntry != NULL) { - ImageDef->LastEntry->Next = ImageDefEntry; - } else { - ImageDef->Entries = ImageDefEntry; - } - - ImageDef->LastEntry = ImageDefEntry; - } else if (SFPIsToken ("}")) { - // - // Closing brace for FDImage {} - // - break; - } else { - SFPGetNextToken (Str, sizeof (Str)); - Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "unrecognized token", Str); - ErrorCount++; - goto Done; - } - } - // - // Add this image definition to our global list - // - ImageDef->Next = mImageDefinitions; - mImageDefinitions = ImageDef; - } - // - // Check for end-of-file - // - if (!SFPIsEOF ()) { - SFPGetNextToken (Str, sizeof (Str)); - Error (SFPGetFileName (), SFPGetLineNumber (), 0, Str, "expected end-of-file", Str); - ErrorCount++; - } - -Done: - SFPCloseFile (); - if (ErrorCount != 0) { - return STATUS_ERROR; - } else if (WarningCount != 0) { - return STATUS_WARNING; - } - - return STATUS_SUCCESS; -} - -static -FLASH_SUBREGION_DESCRIPTION * -ParseSubregionDefinition ( - unsigned int SizeLeft - ) -/*++ - -Routine Description: - - Parse Subregion definitions from the input flash definition file. Format: - - Subregion { - CreateHob = TRUE, - Name = "FOO", - Size = 0xA000, - Attributes = "EFI_FLASH_AREA_SUBFV | EFI_FLASH_AREA_MEMMAPPED_FV", - AreaType = "EFI_FLASH_AREA_EFI_VARIABLES", - NameGuid = 12345678-1234-5678-AAAA-BBBBCCCCDDDD (or "EFI_SOME_GUID"), - AreaTypeGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID") (optional) - FileSystemGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID") (optional) - } - - NOTE: The caller has already parsed the "Subregion" token, so start with the opening brace. - -Arguments: - - SizeLeft - in the flash definition file, a Region can be broken up into - one or more subregions. As we parse the subregion definitions, - the caller keeps track of how much space is left in the region - that we're parsing subregions for. SizeLeft is that size, and - so the size of the subregion we're now parsing better not - exceed the size left. - Returns: - - NULL - unrecoverable errors detected while parsing the subregion definition - - pointer to a subregion definition created from the parsed subregion - ---*/ -{ - FLASH_SUBREGION_DESCRIPTION *Subregion; - int ErrorCount; - int WarningCount; - unsigned int Number; - BOOLEAN PreviousComma; - // - // Allocate memory for the new subregion descriptor - // - ErrorCount = 0; - WarningCount = 0; - Subregion = (FLASH_SUBREGION_DESCRIPTION *) _malloc (sizeof (FLASH_SUBREGION_DESCRIPTION)); - if (Subregion == NULL) { - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - ErrorCount++; - goto Done; - } - - memset (Subregion, 0, sizeof (FLASH_SUBREGION_DESCRIPTION)); - // - // Open brace -- warning if not there - // - if (!SFPIsToken ("{")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected {", NULL); - WarningCount++; - } - // - // Parse: CreateHob = TRUE | FALSE, - // - if (!SFPIsKeyword ("CreateHob")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'CreateHob'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (SFPIsToken ("TRUE")) { - Subregion->CreateHob = 1; - } else if (SFPIsToken ("FALSE")) { - // - // Subregion->CreateHob = 0; -- not required since we did a memset earlier - // - } else { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following CreateHob value", NULL); - WarningCount++; - } - // - // Parse: Name = "Name", - // - if (!SFPIsKeyword ("Name")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Name'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetQuotedString (Subregion->Name, sizeof (Subregion->Name))) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Subregion name", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected comma following Region name", NULL); - WarningCount++; - } - // - // Parse: Size = 0x2000, - // - if (!SFPIsKeyword ("Size")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Size'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (!SFPGetNumber (&Subregion->Size)) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected numeric Size value", NULL); - ErrorCount++; - goto Done; - } - - // - // Check that the size does not exceed the size left passed in - // - if (Subregion->Size > SizeLeft) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "sum of Subregion sizes exceeds Region size", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following Size value", NULL); - } - // - // Parse: Attributes = Number | "String", - // - if (!SFPIsKeyword ("Attributes")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'Attributes'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (SFPGetNumber (&Number)) { - sprintf (Subregion->Attributes, "0x%X", Number); - } else if (!SFPGetQuotedString (Subregion->Attributes, sizeof (Subregion->Attributes))) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted Attributes string", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ','", NULL); - } - // - // Parse: AreaType = Number | "String", - // AreaType is a UINT8, so error if it exceeds the size - // - if (!SFPIsKeyword ("AreaType")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'AreaType'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (SFPGetNumber (&Number)) { - if (Number > 0xFF) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "AreaType value exceeds 255", NULL); - ErrorCount++; - } - - sprintf (Subregion->AreaType, "0x%X", Number & 0x00FF); - } else if (!SFPGetQuotedString (Subregion->AreaType, sizeof (Subregion->AreaType))) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected quoted AreaType string", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken (",")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' following AreaType value", NULL); - } - // - // Parse the three GUIDs (last two are optional) - // - // NameGuid = 12345678-1234-5678-AAAA-BBBBCCCCDDDD, (or "EFI_SOME_GUID") - // AreaTypeGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID") - // FileSysteGuid = 11111111-2222-3333-4444-1, (or "EFI_SOME_GUID") - // - if (!SFPIsKeyword ("NameGuid")) { - Error (SFPGetFileName (), SFPGetLineNumber (), 0, "expected 'NameGuid'", NULL); - ErrorCount++; - goto Done; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - // - // Allow a GUID or a quoted string identifier, which we'll just copy as a string - // - if (SFPGetQuotedString (Subregion->NameGuidString, sizeof (Subregion->NameGuidString))) { - // - // Nothing else to do - // - } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->NameGuid)) { - Error ( - SFPGetFileName (), - SFPGetLineNumber (), - 0, - "expected NameGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC", - NULL - ); - ErrorCount++; - goto Done; - } - // - // Comma following NameGuid is optional if they don't specify AreaTypeGuid or FileSystemGuid - // - PreviousComma = SFPIsToken (","); - if (SFPIsKeyword ("AreaTypeGuid")) { - // - // Check for preceeding comma now - // - if (!PreviousComma) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'AreaTypeGuid'", NULL); - WarningCount++; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - - if (SFPGetQuotedString (Subregion->AreaTypeGuidString, sizeof (Subregion->AreaTypeGuidString))) { - // - // Nothing else to do - // - } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->AreaTypeGuid)) { - Error ( - SFPGetFileName (), - SFPGetLineNumber (), - 0, - "expected AreaTypeGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC", - NULL - ); - ErrorCount++; - goto Done; - } - - PreviousComma = SFPIsToken (","); - } - - if (SFPIsKeyword ("FileSystemGuid")) { - // - // Check for preceeding comma now - // - if (!PreviousComma) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected ',' before 'FileSystemGuid'", NULL); - WarningCount++; - } - - if (!SFPIsToken ("=")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected '='", NULL); - WarningCount++; - } - // - // Allow a GUID or a quoted string identifier, which we'll just copy as a string - // - if (SFPGetQuotedString (Subregion->FileSystemGuidString, sizeof (Subregion->FileSystemGuidString))) { - // - // Nothing else to do - // - } else if (!SFPGetGuid (PARSE_GUID_STYLE_5_FIELDS, &Subregion->FileSystemGuid)) { - Error ( - SFPGetFileName (), - SFPGetLineNumber (), - 0, - "expected FileSystemGuid quoted string or GUID of form 12345678-1234-1234-1234-123456789ABC", - NULL - ); - ErrorCount++; - goto Done; - } - - SFPIsToken (","); - } - // - // Look for subregion closing brace - // - if (!SFPIsToken ("}")) { - Warning (SFPGetFileName (), SFPGetLineNumber (), 0, "expected Subregion closing brace '}'", NULL); - WarningCount++; - } - -Done: - // - // If any errors were encountered, then delete the subregion definition - // - if (ErrorCount != 0) { - _free (Subregion); - Subregion = NULL; - } - - return Subregion; -} - -STATUS -FDFCreateCIncludeFile ( - char *FlashDeviceName, - char *FileName - ) -/*++ - -Routine Description: - Create a header file with #define definitions per an already-parsed - flash definition file. - -Arguments: - FlashDeviceName - name of flash device (from the flash definition file) - to use - FileName - name of output file to create - -Returns: - STATUS_SUCCESS - no errors or warnings - STATUS_WARNING - warnings, but no errors, were encountered - STATUS_ERROR - errors were encountered - ---*/ -{ - FILE *OutFptr; - FLASH_BLOCK_DESCRIPTION *FBlock; - FLASH_DEVICE_DESCRIPTION *FDev; - FLASH_SUBREGION_DESCRIPTION *Subregion; - unsigned int Offset; - unsigned int SubregionOffset; - int CreateHobs; - // - // Find the definition we're supposed to use - // - for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) { - if (strcmp (FDev->Name, FlashDeviceName) == 0) { - break; - } - } - - if (FDev == NULL) { - Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions"); - return STATUS_ERROR; - } - - if ((OutFptr = fopen (FileName, "w")) == NULL) { - Error (NULL, 0, 0, FileName, "failed to open output file for writing"); - return STATUS_ERROR; - } - // - // Write a header - // - fprintf (OutFptr, CIncludeHeader); - // - // Write flash block base and size defines - // - fprintf (OutFptr, "#define FLASH_BASE 0x%08X\n", FDev->BaseAddress); - fprintf (OutFptr, "#define FLASH_SIZE 0x%08X\n\n", FDev->Size); - // - // Write flash regions base, size and offset defines - // - Offset = 0; - CreateHobs = 0; - for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) { - fprintf ( - OutFptr, - "#define FLASH_REGION_%s_BASE %*c0x%08X\n", - FBlock->Name, - COLUMN2_START - 40 - strlen (FBlock->Name), - ' ', - Offset + FDev->BaseAddress - ); - fprintf ( - OutFptr, - "#define FLASH_REGION_%s_SIZE %*c0x%08X\n", - FBlock->Name, - COLUMN2_START - 40 - strlen (FBlock->Name), - ' ', - FBlock->Size - ); - fprintf ( - OutFptr, - "#define FLASH_REGION_%s_OFFSET %*c0x%08X\n", - FBlock->Name, - COLUMN2_START - 40 - strlen (FBlock->Name), - ' ', - Offset - ); - // - // Create defines for any subregions - // - SubregionOffset = 0; - for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) { - fprintf ( - OutFptr, - "#define FLASH_REGION_%s_SUBREGION_%s_BASE %*c0x%08X\n", - FBlock->Name, - Subregion->Name, - COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name), - ' ', - FDev->BaseAddress + Offset + SubregionOffset - ); - fprintf ( - OutFptr, - "#define FLASH_REGION_%s_SUBREGION_%s_SIZE %*c0x%08X\n", - FBlock->Name, - Subregion->Name, - COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name), - ' ', - Subregion->Size - ); - fprintf ( - OutFptr, - "#define FLASH_REGION_%s_SUBREGION_%s_OFFSET %*c0x%08X\n", - FBlock->Name, - Subregion->Name, - COLUMN3_START - 43 - strlen (FBlock->Name) - strlen (Subregion->Name), - ' ', - Offset + SubregionOffset - ); - SubregionOffset += Subregion->Size; - if (Subregion->CreateHob != 0) { - CreateHobs = 1; - } - } - - Offset += FBlock->Size; - } - // - // Now create a #define for the flash map data definition - // - fprintf (OutFptr, "\n\n#define EFI_FLASH_AREA_DATA_DEFINITION \\\n"); - // - // Emit entry for each region - // - Offset = 0; - for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) { - fprintf (OutFptr, " /* %s region */\\\n", FBlock->Name); - fprintf (OutFptr, " {\\\n"); - fprintf (OutFptr, " FLASH_REGION_%s_BASE,\\\n", FBlock->Name); - fprintf (OutFptr, " FLASH_REGION_%s_SIZE,\\\n", FBlock->Name); - fprintf (OutFptr, " %s,\\\n", FBlock->Attributes); - fprintf (OutFptr, " %s,\\\n },\\\n", FBlock->AreaType); - } - - fprintf (OutFptr, "\n\n"); - // - // Now walk the list again to create the EFI_HOB_FLASH_MAP_ENTRY_TYPE definition - // - if (CreateHobs != 0) { - fprintf (OutFptr, "//\n// EFI_HOB_FLASH_MAP_ENTRY_TYPE definition\n//\n"); - fprintf (OutFptr, "#define EFI_HOB_FLASH_MAP_ENTRY_TYPE_DATA_DEFINITION"); - for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) { - // - // See if the block has subregions, and that the CreateHobs flag is set - // for any of them. - // - CreateHobs = 0; - for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) { - if (Subregion->CreateHob != 0) { - CreateHobs = 1; - break; - } - } - // - // If any of the subregions had the CreateHobs flag set, then create the entries in the - // output file - // - if (CreateHobs != 0) { - for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) { - if (Subregion->CreateHob != 0) { - fprintf (OutFptr, " \\\n"); - fprintf (OutFptr, " /* %s.%s Subregion */\\\n", FBlock->Name, Subregion->Name); - fprintf (OutFptr, " {\\\n"); - fprintf (OutFptr, " EFI_HOB_TYPE_GUID_EXTENSION,\\\n"); - fprintf (OutFptr, " sizeof (EFI_HOB_FLASH_MAP_ENTRY_TYPE ),\\\n"); - fprintf (OutFptr, " 0,\\\n"); - // - // The NameGuid may have been specified in the input flash definition file as a GUID, or - // as a quoted string. Do the right one. - // - if (Subregion->NameGuidString[0] != 0) { - fprintf (OutFptr, " %s, \\\n", Subregion->NameGuidString); - } else { - fprintf ( - OutFptr, - " { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n", - Subregion->NameGuid.Data1, - (unsigned int) Subregion->NameGuid.Data2, - (unsigned int) Subregion->NameGuid.Data3, - (unsigned int) Subregion->NameGuid.Data4[0], - (unsigned int) Subregion->NameGuid.Data4[1], - (unsigned int) Subregion->NameGuid.Data4[2], - (unsigned int) Subregion->NameGuid.Data4[3], - (unsigned int) Subregion->NameGuid.Data4[4], - (unsigned int) Subregion->NameGuid.Data4[5], - (unsigned int) Subregion->NameGuid.Data4[6], - (unsigned int) Subregion->NameGuid.Data4[7] - ); - } - - fprintf (OutFptr, " 0, 0, 0,\\\n"); - fprintf (OutFptr, " %s,\\\n", Subregion->AreaType); - // - // The AreaTypeGuid may have been specified in the input flash definition file as a GUID, or - // as a quoted string. Do the right one. - // - if (Subregion->AreaTypeGuidString[0] != 0) { - fprintf (OutFptr, " %s, \\\n", Subregion->AreaTypeGuidString); - } else { - fprintf ( - OutFptr, - " { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n", - Subregion->AreaTypeGuid.Data1, - (unsigned int) Subregion->AreaTypeGuid.Data2, - (unsigned int) Subregion->AreaTypeGuid.Data3, - (unsigned int) Subregion->AreaTypeGuid.Data4[0], - (unsigned int) Subregion->AreaTypeGuid.Data4[1], - (unsigned int) Subregion->AreaTypeGuid.Data4[2], - (unsigned int) Subregion->AreaTypeGuid.Data4[3], - (unsigned int) Subregion->AreaTypeGuid.Data4[4], - (unsigned int) Subregion->AreaTypeGuid.Data4[5], - (unsigned int) Subregion->AreaTypeGuid.Data4[6], - (unsigned int) Subregion->AreaTypeGuid.Data4[7] - ); - } - - fprintf (OutFptr, " 1,\\\n"); - fprintf (OutFptr, " {\\\n"); - fprintf (OutFptr, " %s,\\\n", Subregion->Attributes); - fprintf (OutFptr, " 0,\\\n"); - fprintf (OutFptr, " FLASH_REGION_%s_SUBREGION_%s_BASE,\\\n", FBlock->Name, Subregion->Name); - fprintf (OutFptr, " FLASH_REGION_%s_SUBREGION_%s_SIZE,\\\n", FBlock->Name, Subregion->Name); - // - // The FileSystemGuid may have been specified in the input flash definition file as a GUID, or - // as a quoted string. Do the right one. - // - if (Subregion->FileSystemGuidString[0] != 0) { - fprintf (OutFptr, " %s, \\\n", Subregion->FileSystemGuidString); - } else { - fprintf ( - OutFptr, - " { 0x%08X, 0x%04X, 0x%04X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X },\\\n", - Subregion->FileSystemGuid.Data1, - (unsigned int) Subregion->FileSystemGuid.Data2, - (unsigned int) Subregion->FileSystemGuid.Data3, - (unsigned int) Subregion->FileSystemGuid.Data4[0], - (unsigned int) Subregion->FileSystemGuid.Data4[1], - (unsigned int) Subregion->FileSystemGuid.Data4[2], - (unsigned int) Subregion->FileSystemGuid.Data4[3], - (unsigned int) Subregion->FileSystemGuid.Data4[4], - (unsigned int) Subregion->FileSystemGuid.Data4[5], - (unsigned int) Subregion->FileSystemGuid.Data4[6], - (unsigned int) Subregion->FileSystemGuid.Data4[7] - ); - } - - fprintf (OutFptr, " },\\\n"); - fprintf (OutFptr, " },"); - } - } - } - } - - fprintf (OutFptr, "\n\n"); - } - - // - // Write the file's closing #endif - // - fprintf (OutFptr, CIncludeFooter); - fclose (OutFptr); - return STATUS_SUCCESS; -} - -STATUS -FDFCreateAsmIncludeFile ( - char *FlashDeviceName, - char *FileName - ) -/*++ - -Routine Description: - Create an assembly header file with equate definitions per an already-parsed - flash definition file. - -Arguments: - FlashDeviceName - name of flash device (from the flash definition file) - to use - FileName - name of output file to create - -Returns: - STATUS_SUCCESS - no errors or warnings - STATUS_WARNING - warnings, but no errors, were encountered - STATUS_ERROR - errors were encountered - ---*/ -{ - FILE *OutFptr; - FLASH_BLOCK_DESCRIPTION *FBlock; - FLASH_DEVICE_DESCRIPTION *FDev; - unsigned int Offset; - FLASH_SUBREGION_DESCRIPTION *Subregion; - unsigned int SubregionOffset; - // - // Find the definition we're supposed to use - // - for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) { - if (strcmp (FDev->Name, FlashDeviceName) == 0) { - break; - } - } - - if (FDev == NULL) { - Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions"); - return STATUS_ERROR; - } - - if ((OutFptr = fopen (FileName, "w")) == NULL) { - Error (NULL, 0, 0, FileName, "failed to open output file for writing"); - return STATUS_ERROR; - } - // - // Write a header - // - fprintf (OutFptr, "\n\n"); - // - // Write flash block size and offset defines - // - fprintf ( - OutFptr, - "FLASH_BASE %*cequ 0%08Xh\n", - COLUMN2_START - 40, - ' ', - FDev->BaseAddress - ); - fprintf (OutFptr, "FLASH_SIZE %*cequ 0%08Xh\n", COLUMN2_START - 40, ' ', FDev->Size); - // - // Write flash region size and offset defines - // - fprintf (OutFptr, "\n"); - Offset = 0; - for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) { - fprintf ( - OutFptr, - "FLASH_REGION_%s_BASE %*cequ 0%08Xh\n", - FBlock->Name, - COLUMN2_START - 20 - strlen (FBlock->Name), - ' ', - FDev->BaseAddress + Offset - ); - fprintf ( - OutFptr, - "FLASH_REGION_%s_SIZE %*cequ 0%08Xh\n", - FBlock->Name, - COLUMN2_START - 20 - strlen (FBlock->Name), - ' ', - FBlock->Size - ); - fprintf ( - OutFptr, - "FLASH_REGION_%s_OFFSET %*cequ 0%08Xh\n", - FBlock->Name, - COLUMN2_START - 20 - strlen (FBlock->Name), - ' ', - Offset - ); - // - // Create defines for any subregions - // - SubregionOffset = 0; - for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) { - fprintf ( - OutFptr, - "FLASH_REGION_%s_SUBREGION_%s_BASE %*cequ 0%08Xh\n", - FBlock->Name, - Subregion->Name, - COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name), - ' ', - FDev->BaseAddress + Offset + SubregionOffset - ); - fprintf ( - OutFptr, - "FLASH_REGION_%s_SUBREGION_%s_SIZE %*cequ 0%08Xh\n", - FBlock->Name, - Subregion->Name, - COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name), - ' ', - Subregion->Size - ); - fprintf ( - OutFptr, - "FLASH_REGION_%s_SUBREGION_%s_OFFSET %*cequ 0%08Xh\n", - FBlock->Name, - Subregion->Name, - COLUMN3_START - 39 - strlen (FBlock->Name) - strlen (Subregion->Name), - ' ', - Offset + SubregionOffset - ); - SubregionOffset += Subregion->Size; - } - - Offset += FBlock->Size; - } - - // - // Write closing \n - // - fprintf (OutFptr, "\n\n"); - fclose (OutFptr); - return STATUS_SUCCESS; -} - -STATUS -FDFCreateSymbols ( - char *FlashDeviceName - ) -/*++ - -Routine Description: - Using the given flash device name, add symbols to the global symbol table. This - allows other functions to use the symbol definitions for other purposes. - -Arguments: - FlashDeviceName - name of flash device (from the flash definition file) - to use - -Returns: - STATUS_SUCCESS - no errors or warnings - STATUS_WARNING - warnings, but no errors, were encountered - STATUS_ERROR - errors were encountered - ---*/ -{ - FLASH_BLOCK_DESCRIPTION *FBlock; - FLASH_DEVICE_DESCRIPTION *FDev; - unsigned int Offset; - char SymName[120]; - char SymValue[120]; - FLASH_SUBREGION_DESCRIPTION *Subregion; - unsigned int SubregionOffset; - // - // Find the definition we're supposed to use - // - for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) { - if (strcmp (FDev->Name, FlashDeviceName) == 0) { - break; - } - } - - if (FDev == NULL) { - Error (NULL, 0, 0, NULL, FlashDeviceName, "flash device not found in flash definitions"); - return STATUS_ERROR; - } - - sprintf (SymValue, "0x%08X", FDev->BaseAddress); - SymbolAdd ("FLASH_BASE", SymValue, 0); - sprintf (SymValue, "0x%08X", FDev->Size); - SymbolAdd ("FLASH_SIZE", SymValue, 0); - // - // Add flash block size and offset defines - // - // Offset = 0; - // for (FBlock = FDev->PBlocks; FBlock != NULL; FBlock = FBlock->Next) { - // sprintf (SymName, "FLASH_BLOCK_%s_BASE", FBlock->Name); - // sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset); - // SymbolAdd (SymName, SymValue, 0); - // sprintf (SymName, "FLASH_BLOCK_%s_SIZE", FBlock->Name); - // sprintf (SymValue, "0x%08X", FBlock->Size); - // SymbolAdd (SymName, SymValue, 0); - // sprintf (SymName, "FLASH_BLOCK_%s_OFFSET", FBlock->Name); - // sprintf (SymValue, "0x%08X", Offset); - // SymbolAdd (SymName, SymValue, 0); - // Offset += FBlock->Size; - // } - // - // Add flash region block base, size, and offset defines - // - Offset = 0; - for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) { - sprintf (SymName, "FLASH_REGION_%s_BASE", FBlock->Name); - sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset); - SymbolAdd (SymName, SymValue, 0); - sprintf (SymName, "FLASH_REGION_%s_SIZE", FBlock->Name); - sprintf (SymValue, "0x%08X", FBlock->Size); - SymbolAdd (SymName, SymValue, 0); - sprintf (SymName, "FLASH_REGION_%s_OFFSET", FBlock->Name); - sprintf (SymValue, "0x%08X", Offset); - SymbolAdd (SymName, SymValue, 0); - // - // Add subregion symbols - // - if (FBlock->Subregions != NULL) { - SubregionOffset = 0; - for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) { - sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_BASE", FBlock->Name, Subregion->Name); - sprintf (SymValue, "0x%08X", FDev->BaseAddress + Offset + SubregionOffset); - SymbolAdd (SymName, SymValue, 0); - sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_SIZE", FBlock->Name, Subregion->Name); - sprintf (SymValue, "0x%08X", Subregion->Size); - SymbolAdd (SymName, SymValue, 0); - sprintf (SymName, "FLASH_REGION_%s_SUBREGION_%s_OFFSET", FBlock->Name, Subregion->Name); - sprintf (SymValue, "0x%08X", Offset + SubregionOffset); - SymbolAdd (SymName, SymValue, 0); - SubregionOffset += Subregion->Size; - } - } - - Offset += FBlock->Size; - } - - return STATUS_SUCCESS; -} - -STATUS -FDFCreateImage ( - char *FlashDeviceName, - char *ImageName, - char *FileName - ) -/*++ - -Routine Description: - Create a flash image using the given device and image names. - -Arguments: - FlashDeviceName - name of flash device (from the flash definition file) - to use - ImageName - name of image (from the flash definition file) to create - FileName - name of output file to create - -Returns: - STATUS_SUCCESS - no errors or warnings - STATUS_WARNING - warnings, but no errors, were encountered - STATUS_ERROR - errors were encountered - ---*/ -{ - STATUS Status; - FILE *OutFptr; - FLASH_BLOCK_DESCRIPTION *RegionDef; - FLASH_DEVICE_DESCRIPTION *FDev; - IMAGE_DEFINITION *ImageDef; - unsigned int Offset; - char *Buffer; - FILE *InFptr; - long FileSize; - IMAGE_DEFINITION_ENTRY *IDefEntry; - FLASH_SUBREGION_DESCRIPTION *SubregionDef; - // - // Find the flash definition we're supposed to use - // - InFptr = NULL; - Status = STATUS_ERROR; - for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) { - if (strcmp (FDev->Name, FlashDeviceName) == 0) { - break; - } - } - - if (FDev == NULL) { - Error (NULL, 0, 0, FlashDeviceName, "flash device not found in flash definitions"); - return STATUS_ERROR; - } - // - // Find the image name we're supposed to create - // - for (ImageDef = mImageDefinitions; ImageDef != NULL; ImageDef = ImageDef->Next) { - if (strcmp (ImageDef->Name, ImageName) == 0) { - break; - } - } - - if (ImageDef == NULL) { - Error (NULL, 0, 0, ImageName, "image definition not found in image definitions"); - return STATUS_ERROR; - } - // - // Open the output file - // - if ((OutFptr = fopen (FileName, "wb")) == NULL) { - Error (NULL, 0, 0, FileName, "failed to open output file for writing"); - return STATUS_ERROR; - } - // - // Allocate a buffer to copy the input data to - // - Buffer = (char *) _malloc (FDev->Size); - if (Buffer == NULL) { - Error (NULL, 0, 0, (INT8 *) "failed to allocate memory", NULL); - goto Done; - } - // - // Set contents of buffer to the erased value - // - if (FDev->ErasePolarity) { - memset (Buffer, 0xFF, FDev->Size); - } else { - memset (Buffer, 0, FDev->Size); - } - // - // Set all region and subregion size-left fields to the size of the region/subregion - // - for (RegionDef = FDev->Regions; RegionDef != NULL; RegionDef = RegionDef->Next) { - RegionDef->SizeLeft = RegionDef->Size; - for (SubregionDef = RegionDef->Subregions; SubregionDef != NULL; SubregionDef = SubregionDef->Next) { - SubregionDef->SizeLeft = SubregionDef->Size; - } - } - // - // Now go through the image list, read files into the buffer. - // - for (IDefEntry = ImageDef->Entries; IDefEntry != NULL; IDefEntry = IDefEntry->Next) { - // - // If it's a file name, open the file, get the size, find the corresponding - // flash region it's in, and copy the data. - // - if (IDefEntry->IsRawData == 0) { - if ((InFptr = fopen (IDefEntry->Name, "rb")) == NULL) { - Error (NULL, 0, 0, IDefEntry->Name, "failed to open input file for reading"); - goto Done; - } - - fseek (InFptr, 0, SEEK_END); - FileSize = ftell (InFptr); - fseek (InFptr, 0, SEEK_SET); - } else { - FileSize = IDefEntry->RawDataSize; - } - // - // Find the region/subregion it's in, see if we have space left - // - Offset = 0; - for (RegionDef = FDev->Regions; RegionDef != NULL; RegionDef = RegionDef->Next) { - if (strcmp (RegionDef->Name, IDefEntry->RegionName) == 0) { - break; - } - - Offset += RegionDef->Size; - } - - if (RegionDef == NULL) { - Error (NULL, 0, 0, IDefEntry->RegionName, "Region name not found in FlashDevice %s definition", FDev->Name); - goto Done; - } - - // - // Check for subregion - // - if (IDefEntry->SubregionName[0] != 0) { - for (SubregionDef = RegionDef->Subregions; SubregionDef != NULL; SubregionDef = SubregionDef->Next) { - if (strcmp (SubregionDef->Name, IDefEntry->SubregionName) == 0) { - break; - } - - Offset += SubregionDef->Size; - } - - if (SubregionDef == NULL) { - Error ( - NULL, - 0, - 0, - IDefEntry->SubregionName, - "Subregion name not found in FlashDevice %s.%s Region definition", - FDev->Name, - RegionDef->Name - ); - goto Done; - } - // - // Enough space in the subregion? - // - if (SubregionDef->SizeLeft < (unsigned int) FileSize) { - Error ( - NULL, - 0, - 0, - IDefEntry->Name, - "insufficient space in Subregion (at least 0x%X additional bytes required)", - FileSize - SubregionDef->SizeLeft - ); - goto Done; - } - - // - // Read the file into the buffer if it's a file. Otherwise copy the raw data - // - if (IDefEntry->IsRawData == 0) { - if (fread (Buffer + Offset + (SubregionDef->Size - SubregionDef->SizeLeft), FileSize, 1, InFptr) != 1) { - Error (NULL, 0, 0, IDefEntry->Name, "failed to read file contents"); - goto Done; - } - - fclose (InFptr); - InFptr = NULL; - } else { - memcpy ( - Buffer + Offset + (SubregionDef->Size - SubregionDef->SizeLeft), - IDefEntry->RawData, - IDefEntry->RawDataSize - ); - } - - SubregionDef->SizeLeft -= FileSize; - // - // Align based on the Region alignment requirements. - // - if (RegionDef->Alignment != 0) { - while (((unsigned int) (SubregionDef->Size - SubregionDef->SizeLeft) &~RegionDef->Alignment) != 0) { - if (SubregionDef->SizeLeft == 0) { - break; - } - - SubregionDef->SizeLeft--; - } - } - } else { - // - // Placing data in a region. Check for enough space in the region left. - // - if (RegionDef->SizeLeft < (unsigned int) FileSize) { - Error ( - NULL, - 0, - 0, - IDefEntry->Name, - "insufficient space in Region (at least 0x%X additional bytes required)", - FileSize - RegionDef->SizeLeft - ); - goto Done; - } - - // - // Read the file into the buffer if it's a file. Otherwise copy the raw data - // - if (IDefEntry->IsRawData == 0) { - if (fread (Buffer + Offset + (RegionDef->Size - RegionDef->SizeLeft), FileSize, 1, InFptr) != 1) { - Error (NULL, 0, 0, IDefEntry->Name, "failed to read file contents"); - goto Done; - } - - fclose (InFptr); - InFptr = NULL; - } else { - memcpy (Buffer + Offset + (RegionDef->Size - RegionDef->SizeLeft), IDefEntry->RawData, IDefEntry->RawDataSize); - } - - RegionDef->SizeLeft -= FileSize; - // - // Align - // - if (RegionDef->Alignment != 0) { - while (((unsigned int) (RegionDef->Size - RegionDef->SizeLeft) &~RegionDef->Alignment) != 0) { - if (RegionDef->SizeLeft == 0) { - break; - } - - RegionDef->SizeLeft--; - } - } - } - } - - if (fwrite (Buffer, FDev->Size, 1, OutFptr) != 1) { - Error (NULL, 0, 0, "failed to write buffer contents to output file", NULL); - goto Done; - } - - Status = STATUS_SUCCESS; -Done: - if (InFptr != NULL) { - fclose (InFptr); - } - - if (Buffer != NULL) { - _free (Buffer); - } - - if (OutFptr != NULL) { - fclose (OutFptr); - if (Status == STATUS_ERROR) { - remove (FileName); - } - } - - return Status; -} - -STATUS -FDFCreateDscFile ( - char *FlashDeviceName, - char *FileName - ) -/*++ - -Routine Description: - Create a DSC-style output file with equates for flash management. - -Arguments: - FlashDeviceName - name of flash device (from the flash definition file) - to use - FileName - name of output file to create - -Returns: - STATUS_SUCCESS - no errors or warnings - STATUS_WARNING - warnings, but no errors, were encountered - STATUS_ERROR - errors were encountered - ---*/ -{ - FILE *OutFptr; - FLASH_BLOCK_DESCRIPTION *FBlock; - FLASH_DEVICE_DESCRIPTION *FDev; - unsigned int Offset; - FLASH_SUBREGION_DESCRIPTION *Subregion; - unsigned int SubregionOffset; - // - // Find the definition we're supposed to use - // - for (FDev = mFlashDevices; FDev != NULL; FDev = FDev->Next) { - if (strcmp (FDev->Name, FlashDeviceName) == 0) { - break; - } - } - - if (FDev == NULL) { - Error (NULL, 0, 0, FlashDeviceName, "flash device not found in flash definitions"); - return STATUS_ERROR; - } - - if ((OutFptr = fopen (FileName, "w")) == NULL) { - Error (NULL, 0, 0, FileName, "failed to open output file for writing"); - return STATUS_ERROR; - } - // - // Write the flash base address and size - // - fprintf (OutFptr, "\n"); - fprintf (OutFptr, "FLASH_BASE = 0x%08X\n", FDev->BaseAddress); - fprintf (OutFptr, "FLASH_SIZE = 0x%08X\n\n", FDev->Size); - // - // Write flash block size and offset defines - // - Offset = 0; - for (FBlock = FDev->Regions; FBlock != NULL; FBlock = FBlock->Next) { - fprintf ( - OutFptr, - "FLASH_REGION_%s_BASE %*c= 0x%08X\n", - FBlock->Name, - COLUMN2_START - 40 - strlen (FBlock->Name), - ' ', - Offset + FDev->BaseAddress - ); - fprintf ( - OutFptr, - "FLASH_REGION_%s_SIZE %*c= 0x%08X\n", - FBlock->Name, - COLUMN2_START - 40 - strlen (FBlock->Name), - ' ', - FBlock->Size - ); - fprintf ( - OutFptr, - "FLASH_REGION_%s_SIZE_BLOCKS %*c= 0x%x\n", - FBlock->Name, - COLUMN2_START - 40 - strlen (FBlock->Name), - ' ', - (FBlock->Size)/(FDev->PBlocks->Size) - ); - // - // Create defines for any subregions - // - SubregionOffset = 0; - for (Subregion = FBlock->Subregions; Subregion != NULL; Subregion = Subregion->Next) { - fprintf ( - OutFptr, - "FLASH_REGION_%s_SUBREGION_%s_BASE %*c= 0x%08X\n", - FBlock->Name, - Subregion->Name, - COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name), - ' ', - FDev->BaseAddress + Offset + SubregionOffset - ); - fprintf ( - OutFptr, - "FLASH_REGION_%s_SUBREGION_%s_SIZE %*c= 0x%08X\n", - FBlock->Name, - Subregion->Name, - COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name), - ' ', - Subregion->Size - ); - fprintf ( - OutFptr, - "FLASH_REGION_%s_SUBREGION_%s_OFFSET %*c= 0x%08X\n", - FBlock->Name, - Subregion->Name, - COLUMN3_START - 48 - strlen (FBlock->Name) - strlen (Subregion->Name), - ' ', - Offset + SubregionOffset - ); - - SubregionOffset += Subregion->Size; - } - - Offset += FBlock->Size; - } - // - // Close file - // - fprintf (OutFptr, "\n"); - fclose (OutFptr); - return STATUS_SUCCESS; -} - - -/*++ - -Routine Description: - The following buffer management routines are used to encapsulate functionality - for managing a growable data buffer. - -Arguments: - BUFFER_DATA - structure that is used to maintain a data buffer - -Returns: - NA - ---*/ -static -BUFFER_DATA * -CreateBufferData ( - VOID - ) -/*++ - -Routine Description: - - Create a growable data buffer with default buffer length. - -Arguments: - - None - -Returns: - - NULL - error occured during data buffer creation - Not NULL - the pointer to the newly created data buffer - ---*/ -{ - BUFFER_DATA *BD; - BD = (BUFFER_DATA *) _malloc (sizeof (BUFFER_DATA)); - if (BD == NULL) { - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - return NULL; - } - - memset (BD, 0, sizeof (BUFFER_DATA)); - BD->BufferStart = (char *) _malloc (BUFFER_SIZE); - if (BD->BufferStart == NULL) { - _free (BD); - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - return NULL; - } - - BD->BufferEnd = BD->BufferStart + BUFFER_SIZE; - BD->BufferPos = BD->BufferStart; - return BD; -} - -static -BOOLEAN -AddBufferDataByte ( - BUFFER_DATA *Buffer, - char Data - ) -/*++ - -Routine Description: - - Add a single byte to a growable data buffer, growing the buffer if required. - -Arguments: - - Buffer - pointer to the growable data buffer to add a single byte to - Data - value of the single byte data to be added - -Returns: - - TRUE - the single byte data was successfully added - FALSE - error occurred, the single byte data was not added - ---*/ -{ - int Size; - char *NewBuffer; - // - // See if we have to grow the buffer - // - if (Buffer->BufferPos >= Buffer->BufferEnd) { - Size = (int) Buffer->BufferEnd - (int) Buffer->BufferStart; - NewBuffer = (char *) _malloc (Size + BUFFER_SIZE); - if (NewBuffer == NULL) { - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - return FALSE; - } - - memcpy (NewBuffer, Buffer->BufferStart, Size); - _free (Buffer->BufferStart); - Buffer->BufferStart = NewBuffer; - Buffer->BufferPos = Buffer->BufferStart + Size; - Buffer->BufferEnd = Buffer->BufferStart + Size + BUFFER_SIZE; - } - - *Buffer->BufferPos = Data; - Buffer->BufferPos++; - return TRUE; -} - -static -void -FreeBufferData ( - BUFFER_DATA *Buffer, - BOOLEAN FreeData - ) -/*++ - -Routine Description: - - Free memory used to manage a growable data buffer. - -Arguments: - - Buffer - pointer to the growable data buffer to be destructed - FreeData - TRUE, free memory containing the buffered data - FALSE, do not free the buffered data memory - -Returns: - - None - ---*/ -{ - if (Buffer != NULL) { - if (FreeData && (Buffer->BufferStart != NULL)) { - _free (Buffer->BufferStart); - } - - _free (Buffer); - } -} - -static -char * -GetBufferData ( - BUFFER_DATA *Buffer, - int *BufferSize - ) -/*++ - -Routine Description: - - Return a pointer and size of the data in a growable data buffer. - -Arguments: - - Buffer - pointer to the growable data buffer - BufferSize - size of the data in the growable data buffer - -Returns: - - pointer of the data in the growable data buffer - ---*/ -{ - *BufferSize = (int) Buffer->BufferPos - (int) Buffer->BufferStart; - return Buffer->BufferStart; -} - -STATUS -FDDiscover ( - char *FDFileName, - unsigned int BaseAddr - ) -/*++ - -Routine Description: - Walk a binary image and see if you find anything that looks like a - firmware volume. - -Arguments: - FDFileName - name of input FD image to parse - BaseAddr - base address of input FD image - -Returns: - STATUS_SUCCESS - no errors or warnings - STATUS_WARNING - warnings, but no errors, were encountered - STATUS_ERROR - errors were encountered - -NOTE: - This routine is used for debug purposes only. - ---*/ -{ - FILE *InFptr; - long FileSize; - long Offset; - EFI_FIRMWARE_VOLUME_HEADER FVHeader; - EFI_GUID - FileSystemGuid = { 0x7A9354D9, 0x0468, 0x444a, 0x81, 0xCE, 0x0B, 0xF6, 0x17, 0xD8, 0x90, 0xDF }; - - if ((InFptr = fopen (FDFileName, "rb")) == NULL) { - Error (NULL, 0, 0, FDFileName, "failed to open file for reading"); - return STATUS_ERROR; - } - - fseek (InFptr, 0, SEEK_END); - FileSize = ftell (InFptr); - fseek (InFptr, 0, SEEK_SET); - Offset = 0; - while (Offset < FileSize) { - fseek (InFptr, Offset, SEEK_SET); - // - // Read the contents of the file, see if it's an FV header - // - if (fread (&FVHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER), 1, InFptr) == 1) { - // - // Check version and GUID - // - if ((FVHeader.Revision == EFI_FVH_REVISION) && (FVHeader.Signature == EFI_FVH_SIGNATURE)) { - fprintf (stdout, "FV header at 0x%08X FVSize=0x%08X ", Offset + BaseAddr, (UINT32) FVHeader.FvLength); - if (memcmp (&FVHeader.FileSystemGuid, &FileSystemGuid, sizeof (EFI_GUID)) == 0) { - fprintf (stdout, "standard FFS file system\n"); - } else { - fprintf (stdout, "non-standard FFS file system\n"); - } - } - } - - Offset += 16 * 1024; - } - - fclose (InFptr); - return STATUS_SUCCESS; -} diff --git a/Tools/CodeTools/TianoTools/FlashMap/FlashDefFile.h b/Tools/CodeTools/TianoTools/FlashMap/FlashDefFile.h deleted file mode 100644 index 0e2ea2c920..0000000000 --- a/Tools/CodeTools/TianoTools/FlashMap/FlashDefFile.h +++ /dev/null @@ -1,281 +0,0 @@ -/*++ - -Copyright (c) 2004-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -Module Name: - - FlashDefFile.h - -Abstract: - - Header file for flash management utility in the Intel Platform - Innovation Framework for EFI build environment. - ---*/ - -#ifndef _FLASH_DEF_FILE_H_ -#define _FLASH_DEF_FILE_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - -void -FDFConstructor ( - VOID - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - None - -Returns: - - GC_TODO: add return values - ---*/ -; - -void -FDFDestructor ( - VOID - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - None - -Returns: - - GC_TODO: add return values - ---*/ -; - -STATUS -FDFParseFile ( - char *FileName - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - FileName - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -; - -STATUS -FDFCreateCIncludeFile ( - char *FlashDeviceName, - char *FileName - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - FlashDeviceName - GC_TODO: add argument description - FileName - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -; - -STATUS -FDFCreateCFlashMapDataFile ( - char *FlashDeviceName, - char *FileName - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - FlashDeviceName - GC_TODO: add argument description - FileName - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -; - -STATUS -FDFCreateAsmIncludeFile ( - char *FlashDeviceName, - char *FileName - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - FlashDeviceName - GC_TODO: add argument description - FileName - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -; - -STATUS -FDFParseFile ( - char *FileName - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - FileName - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -; - -STATUS -FDFCreateImage ( - char *FlashDeviceName, - char *ImageName, - char *FileName - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - FlashDeviceName - GC_TODO: add argument description - ImageName - GC_TODO: add argument description - FileName - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -; - -STATUS -FDFCreateDscFile ( - char *FlashDeviceName, - char *FileName - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - FlashDeviceName - GC_TODO: add argument description - FileName - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -; - -STATUS -FDFCreateSymbols ( - char *FlashDeviceName - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - FlashDeviceName - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -; - -STATUS -FDDiscover ( - char *FDFileName, - unsigned int BaseAddr - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - FDFileName - GC_TODO: add argument description - BaseAddr - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -; - -#ifdef __cplusplus -} -#endif - -#endif // #ifndef _FLASH_DEF_FILE_H_ diff --git a/Tools/CodeTools/TianoTools/FlashMap/FlashMap.c b/Tools/CodeTools/TianoTools/FlashMap/FlashMap.c deleted file mode 100644 index 88f5003d2d..0000000000 --- a/Tools/CodeTools/TianoTools/FlashMap/FlashMap.c +++ /dev/null @@ -1,769 +0,0 @@ -/*++ - -Copyright (c) 2004-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - FlashMap.c - -Abstract: - - Utility for flash management in the Intel Platform Innovation Framework - for EFI build environment. - ---*/ - -#include -#include -#include -#include - -#include - -#include "EfiUtilityMsgs.h" -#include "Microcode.h" -#include "FlashDefFile.h" -#include "Symbols.h" - -#define UTILITY_NAME "FlashMap" - -typedef struct _STRING_LIST { - struct _STRING_LIST *Next; - char *Str; -} STRING_LIST; - -// -// Keep our globals in one of these structures -// -static struct { - char *CIncludeFileName; - char *FlashDevice; - char *FlashDeviceImage; - char *MCIFileName; - char *MCOFileName; - char *ImageOutFileName; - char *DscFileName; - char *AsmIncludeFileName; - char *FlashDefinitionFileName; - char *StringReplaceInFileName; - char *StringReplaceOutFileName; - char *DiscoverFDImageName; - char MicrocodePadByteValue; - unsigned int MicrocodeAlignment; - STRING_LIST *MCIFileNames; - STRING_LIST *LastMCIFileNames; - unsigned int BaseAddress; -} mGlobals; - -#define DEFAULT_MC_PAD_BYTE_VALUE 0xFF -#define DEFAULT_MC_ALIGNMENT 16 - -static -STATUS -ProcessCommandLine ( - int argc, - char *argv[] - ); - -static -STATUS -MergeMicrocodeFiles ( - char *OutFileName, - STRING_LIST *FileNames, - unsigned int Alignment, - char PadByteValue - ); - -static -void -Usage ( - VOID - ); - -char* -NormalizePath ( - char* OldPathName - ); - -int -main ( - int argc, - char *argv[] - ) -/*++ - -Routine Description: - Parse the command line arguments and then call worker functions to do the work - -Arguments: - argc - number of elements in argv - argv - array of command-line arguments - -Returns: - STATUS_SUCCESS - no problems encountered while processing - STATUS_WARNING - warnings, but no errors, were encountered while processing - STATUS_ERROR - errors were encountered while processing - ---*/ -{ - STATUS Status; - - SetUtilityName (UTILITY_NAME); - Status = ProcessCommandLine (argc, argv); - if (Status != STATUS_SUCCESS) { - return Status; - } - // - // Check for discovery of an FD (command line option) - // - if (mGlobals.DiscoverFDImageName != NULL) { - Status = FDDiscover (mGlobals.DiscoverFDImageName, mGlobals.BaseAddress); - goto Done; - } - // - // If they're doing microcode file parsing, then do that - // - if (mGlobals.MCIFileName != NULL) { - MicrocodeConstructor (); - MicrocodeParseFile (mGlobals.MCIFileName, mGlobals.MCOFileName); - MicrocodeDestructor (); - } - // - // If they're doing microcode file merging, then do that now - // - if (mGlobals.MCIFileNames != NULL) { - MergeMicrocodeFiles ( - mGlobals.MCOFileName, - mGlobals.MCIFileNames, - mGlobals.MicrocodeAlignment, - mGlobals.MicrocodePadByteValue - ); - } - // - // If using a flash definition file, then process that and return - // - if (mGlobals.FlashDefinitionFileName != NULL) { - FDFConstructor (); - SymbolsConstructor (); - Status = FDFParseFile (mGlobals.FlashDefinitionFileName); - if (GetUtilityStatus () != STATUS_ERROR) { - // - // If they want us to do a string-replace on a file, then add the symbol definitions to - // the symbol table, and then do the string replace. - // - if (mGlobals.StringReplaceInFileName != NULL) { - Status = FDFCreateSymbols (mGlobals.FlashDevice); - Status = SymbolsFileStringsReplace (mGlobals.StringReplaceInFileName, mGlobals.StringReplaceOutFileName); - } - // - // If they want us to create a .h defines file or .c flashmap data file, then do so now - // - if (mGlobals.CIncludeFileName != NULL) { - Status = FDFCreateCIncludeFile (mGlobals.FlashDevice, mGlobals.CIncludeFileName); - } - if (mGlobals.AsmIncludeFileName != NULL) { - Status = FDFCreateAsmIncludeFile (mGlobals.FlashDevice, mGlobals.AsmIncludeFileName); - } - // - // If they want us to create an image, do that now - // - if (mGlobals.ImageOutFileName != NULL) { - Status = FDFCreateImage (mGlobals.FlashDevice, mGlobals.FlashDeviceImage, mGlobals.ImageOutFileName); - } - // - // If they want to create an output DSC file, do that now - // - if (mGlobals.DscFileName != NULL) { - Status = FDFCreateDscFile (mGlobals.FlashDevice, mGlobals.DscFileName); - } - } - SymbolsDestructor (); - FDFDestructor (); - } -Done: - // - // Free up memory - // - while (mGlobals.MCIFileNames != NULL) { - mGlobals.LastMCIFileNames = mGlobals.MCIFileNames->Next; - _free (mGlobals.MCIFileNames); - mGlobals.MCIFileNames = mGlobals.LastMCIFileNames; - } - return GetUtilityStatus (); -} - -static -STATUS -MergeMicrocodeFiles ( - char *OutFileName, - STRING_LIST *FileNames, - unsigned int Alignment, - char PadByteValue - ) -/*++ - -Routine Description: - - Merge binary microcode files into a single file, taking into consideration - the alignment and pad value. - -Arguments: - - OutFileName - name of the output file to create - FileNames - linked list of input microcode files to merge - Alignment - alignment for each microcode file in the output image - PadByteValue - value to use when padding to meet alignment requirements - -Returns: - - STATUS_SUCCESS - merge completed successfully or with acceptable warnings - STATUS_ERROR - merge failed, output file not created - ---*/ -{ - long FileSize; - long TotalFileSize; - FILE *InFptr; - FILE *OutFptr; - char *Buffer; - STATUS Status; - - // - // Open the output file - // - if ((OutFptr = fopen (OutFileName, "wb")) == NULL) { - Error (NULL, 0, 0, OutFileName, "failed to open output file for writing"); - return STATUS_ERROR; - } - // - // Walk the list of files - // - Status = STATUS_ERROR; - Buffer = NULL; - InFptr = NULL; - TotalFileSize = 0; - while (FileNames != NULL) { - // - // Open the file, determine the size, then read it in and write - // it back out. - // - if ((InFptr = fopen (NormalizePath(FileNames->Str), "rb")) == NULL) { - Error (NULL, 0, 0, NormalizePath(FileNames->Str), "failed to open input file for reading"); - goto Done; - } - fseek (InFptr, 0, SEEK_END); - FileSize = ftell (InFptr); - fseek (InFptr, 0, SEEK_SET); - if (FileSize != 0) { - Buffer = (char *) _malloc (FileSize); - if (Buffer == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - goto Done; - } - if (fread (Buffer, FileSize, 1, InFptr) != 1) { - Error (NULL, 0, 0, FileNames->Str, "failed to read file contents"); - goto Done; - } - // - // Align - // - if (Alignment != 0) { - while ((TotalFileSize % Alignment) != 0) { - if (fwrite (&PadByteValue, 1, 1, OutFptr) != 1) { - Error (NULL, 0, 0, OutFileName, "failed to write pad bytes to output file"); - goto Done; - } - TotalFileSize++; - } - } - TotalFileSize += FileSize; - if (fwrite (Buffer, FileSize, 1, OutFptr) != 1) { - Error (NULL, 0, 0, OutFileName, "failed to write to output file"); - goto Done; - } - _free (Buffer); - Buffer = NULL; - } else { - Warning (NULL, 0, 0, FileNames->Str, "0-size file encountered"); - } - fclose (InFptr); - InFptr = NULL; - FileNames = FileNames->Next; - } - Status = STATUS_SUCCESS; -Done: - fclose (OutFptr); - if (InFptr != NULL) { - fclose (InFptr); - } - if (Buffer != NULL) { - _free (Buffer); - } - if (Status == STATUS_ERROR) { - remove (OutFileName); - } - return Status; -} - -static -STATUS -ProcessCommandLine ( - int argc, - char *argv[] - ) -/*++ - -Routine Description: - Process the command line arguments - -Arguments: - argc - Standard C entry point arguments - argv[] - Standard C entry point arguments - -Returns: - STATUS_SUCCESS - no problems encountered while processing - STATUS_WARNING - warnings, but no errors, were encountered while processing - STATUS_ERROR - errors were encountered while processing - ---*/ -{ - int ThingsToDo; - unsigned int Temp; - STRING_LIST *Str; - // - // Skip program name arg, process others - // - argc--; - argv++; - if (argc == 0) { - Usage (); - return STATUS_ERROR; - } - // - // Clear out our globals, then start walking the arguments - // - memset ((void *) &mGlobals, 0, sizeof (mGlobals)); - mGlobals.MicrocodePadByteValue = DEFAULT_MC_PAD_BYTE_VALUE; - mGlobals.MicrocodeAlignment = DEFAULT_MC_ALIGNMENT; - ThingsToDo = 0; - while (argc > 0) { - if (strcmp (argv[0], "-?") == 0) { - Usage (); - return STATUS_ERROR; - } else if (strcmp (argv[0], "-hfile") == 0) { - // - // -hfile FileName - // - // Used to specify an output C #include file to create that contains - // #define statements for all the flashmap region offsets and sizes. - // Check for additional argument. - // - if (argc < 2) { - Error (NULL, 0, 0, argv[0], "option requires an output file name"); - return STATUS_ERROR; - } - argc--; - argv++; - mGlobals.CIncludeFileName = argv[0]; - ThingsToDo++; - } else if (strcmp (argv[0], "-flashdevice") == 0) { - // - // -flashdevice FLASH_DEVICE_NAME - // - // Used to select which flash device definition to operate on. - // Check for additional argument - // - if (argc < 2) { - Error (NULL, 0, 0, argv[0], "option requires a flash device name to use"); - return STATUS_ERROR; - } - argc--; - argv++; - mGlobals.FlashDevice = argv[0]; - } else if (strcmp (argv[0], "-mco") == 0) { - // - // -mco OutFileName - // - // Used to specify a microcode output binary file to create. - // Check for additional argument. - // - if (argc < 2) { - Error (NULL, 0, 0, (INT8 *) argv[0], (INT8 *) "option requires an output microcode file name to create"); - return STATUS_ERROR; - } - argc--; - argv++; - mGlobals.MCOFileName = argv[0]; - ThingsToDo++; - } else if (strcmp (argv[0], "-asmincfile") == 0) { - // - // -asmincfile FileName - // - // Used to specify the name of the output assembly include file that contains - // equates for the flash region addresses and sizes. - // Check for additional argument. - // - if (argc < 2) { - Error (NULL, 0, 0, argv[0], "option requires an output ASM include file name to create"); - return STATUS_ERROR; - } - argc--; - argv++; - mGlobals.AsmIncludeFileName = argv[0]; - ThingsToDo++; - } else if (strcmp (argv[0], "-mci") == 0) { - // - // -mci FileName - // - // Used to specify an input microcode text file to parse. - // Check for additional argument - // - if (argc < 2) { - Error (NULL, 0, 0, (INT8 *) argv[0], (INT8 *) "option requires an input microcode text file name to parse"); - return STATUS_ERROR; - } - argc--; - argv++; - mGlobals.MCIFileName = argv[0]; - } else if (strcmp (argv[0], "-flashdeviceimage") == 0) { - // - // -flashdeviceimage FlashDeviceImage - // - // Used to specify which flash device image definition from the input flash definition file - // to create. - // Check for additional argument. - // - if (argc < 2) { - Error (NULL, 0, 0, argv[0], "option requires the name of a flash definition image to use"); - return STATUS_ERROR; - } - argc--; - argv++; - mGlobals.FlashDeviceImage = argv[0]; - } else if (strcmp (argv[0], "-imageout") == 0) { - // - // -imageout FileName - // - // Used to specify the name of the output FD image file to create. - // Check for additional argument. - // - if (argc < 2) { - Error (NULL, 0, 0, argv[0], "option requires an output image filename to create"); - return STATUS_ERROR; - } - argc--; - argv++; - mGlobals.ImageOutFileName = argv[0]; - ThingsToDo++; - } else if (strcmp (argv[0], "-dsc") == 0) { - // - // -dsc FileName - // - // Used to specify the name of the output DSC file to create. - // Check for additional argument. - // - if (argc < 2) { - Error (NULL, 0, 0, argv[0], "option requires an output DSC filename to create"); - return STATUS_ERROR; - } - argc--; - argv++; - mGlobals.DscFileName = argv[0]; - ThingsToDo++; - } else if (strcmp (argv[0], "-fdf") == 0) { - // - // -fdf FileName - // - // Used to specify the name of the input flash definition file. - // Check for additional argument. - // - if (argc < 2) { - Error (NULL, 0, 0, argv[0], "option requires an input flash definition file name"); - return STATUS_ERROR; - } - argc--; - argv++; - mGlobals.FlashDefinitionFileName = argv[0]; - } else if (strcmp (argv[0], "-discover") == 0) { - // - // -discover FDFileName - // - // Debug functionality used to scan an existing FD image, trying to find - // firmware volumes at 64K boundaries. - // Check for additional argument. - // - if (argc < 2) { - Error (NULL, 0, 0, argv[0], "option requires an input FD image file name"); - return STATUS_ERROR; - } - argc--; - argv++; - mGlobals.DiscoverFDImageName = argv[0]; - ThingsToDo++; - } else if (strcmp (argv[0], "-baseaddr") == 0) { - // - // -baseaddr Addr - // - // Used to specify a base address when doing a discover of an FD image. - // Check for additional argument. - // - if (argc < 2) { - Error (NULL, 0, 0, argv[0], "option requires a base address"); - return STATUS_ERROR; - } - argc--; - argv++; - if (tolower (argv[0][1]) == 'x') { - sscanf (argv[0] + 2, "%x", &mGlobals.BaseAddress); - } else { - sscanf (argv[0], "%d", &mGlobals.BaseAddress); - } - } else if (strcmp (argv[0], "-padvalue") == 0) { - // - // -padvalue Value - // - // Used to specify the value to pad with when aligning data while - // creating an FD image. Check for additional argument. - // - if (argc < 2) { - Error (NULL, 0, 0, argv[0], "option requires a byte value"); - return STATUS_ERROR; - } - argc--; - argv++; - if (tolower (argv[0][1]) == 'x') { - sscanf (argv[0] + 2, "%x", &Temp); - mGlobals.MicrocodePadByteValue = (char) Temp; - } else { - sscanf (argv[0], "%d", &Temp); - mGlobals.MicrocodePadByteValue = (char) Temp; - } - } else if (strcmp (argv[0], "-align") == 0) { - // - // -align Alignment - // - // Used to specify how each data file is aligned in the region - // when creating an FD image. Check for additional argument. - // - if (argc < 2) { - Error (NULL, 0, 0, argv[0], "option requires an alignment"); - return STATUS_ERROR; - } - argc--; - argv++; - if (tolower (argv[0][1]) == 'x') { - sscanf (argv[0] + 2, "%x", &mGlobals.MicrocodeAlignment); - } else { - sscanf (argv[0], "%d", &mGlobals.MicrocodeAlignment); - } - } else if (strcmp (argv[0], "-mcmerge") == 0) { - // - // -mcmerge FileName(s) - // - // Used to concatenate multiple microde binary files. Can specify - // multiple file names with the one -mcmerge flag. Check for additional argument. - // - if ((argc < 2) || (argv[1][0] == '-')) { - Error (NULL, 0, 0, argv[0], "option requires one or more input file names"); - return STATUS_ERROR; - } - // - // Take input files until another option or end of list - // - ThingsToDo++; - while ((argc > 1) && (argv[1][0] != '-')) { - Str = (STRING_LIST *) _malloc (sizeof (STRING_LIST)); - if (Str == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - memset (Str, 0, sizeof (STRING_LIST)); - Str->Str = argv[1]; - if (mGlobals.MCIFileNames == NULL) { - mGlobals.MCIFileNames = Str; - } else { - mGlobals.LastMCIFileNames->Next = Str; - } - mGlobals.LastMCIFileNames = Str; - argc--; - argv++; - } - } else if (strcmp (argv[0], "-strsub") == 0) { - // - // -strsub SrcFile DestFile - // - // Used to perform string substitutions on a file, writing the result to a new - // file. Check for two additional arguments. - // - if (argc < 3) { - Error (NULL, 0, 0, argv[0], "option requires input and output file names for string substitution"); - return STATUS_ERROR; - } - argc--; - argv++; - mGlobals.StringReplaceInFileName = argv[0]; - argc--; - argv++; - mGlobals.StringReplaceOutFileName = argv[0]; - ThingsToDo++; - } else { - Error (NULL, 0, 0, argv[0], "invalid option"); - return STATUS_ERROR; - } - argc--; - argv++; - } - // - // If no outputs requested, then report an error - // - if (ThingsToDo == 0) { - Error (NULL, 0, 0, "nothing to do", NULL); - return STATUS_ERROR; - } - // - // If they want an asm file, #include file, or C file to be created, then they have to specify a - // flash device name and flash definition file name. - // - if ((mGlobals.CIncludeFileName != NULL) && - ((mGlobals.FlashDevice == NULL) || (mGlobals.FlashDefinitionFileName == NULL))) { - Error (NULL, 0, 0, "must specify -flashdevice and -fdf with -hfile", NULL); - return STATUS_ERROR; - } - if ((mGlobals.AsmIncludeFileName != NULL) && - ((mGlobals.FlashDevice == NULL) || (mGlobals.FlashDefinitionFileName == NULL))) { - Error (NULL, 0, 0, "must specify -flashdevice and -fdf with -asmincfile", NULL); - return STATUS_ERROR; - } - // - // If they want a dsc file to be created, then they have to specify a - // flash device name and a flash definition file name - // - if (mGlobals.DscFileName != NULL) { - if (mGlobals.FlashDevice == NULL) { - Error (NULL, 0, 0, "must specify -flashdevice with -dsc", NULL); - return STATUS_ERROR; - } - if (mGlobals.FlashDefinitionFileName == NULL) { - Error (NULL, 0, 0, "must specify -fdf with -dsc", NULL); - return STATUS_ERROR; - } - } - // - // If they specified an output microcode file name, then they have to specify an input - // file name, and vice versa. - // - if ((mGlobals.MCIFileName != NULL) && (mGlobals.MCOFileName == NULL)) { - Error (NULL, 0, 0, "must specify output microcode file name", NULL); - return STATUS_ERROR; - } - if ((mGlobals.MCOFileName != NULL) && (mGlobals.MCIFileName == NULL) && (mGlobals.MCIFileNames == NULL)) { - Error (NULL, 0, 0, "must specify input microcode file name", NULL); - return STATUS_ERROR; - } - // - // If doing merge, then have to specify output file name - // - if ((mGlobals.MCIFileNames != NULL) && (mGlobals.MCOFileName == NULL)) { - Error (NULL, 0, 0, "must specify output microcode file name", NULL); - return STATUS_ERROR; - } - // - // If they want an output image to be created, then they have to specify - // the flash device and the flash device image to use. - // - if (mGlobals.ImageOutFileName != NULL) { - if (mGlobals.FlashDevice == NULL) { - Error (NULL, 0, 0, "must specify -flashdevice with -imageout", NULL); - return STATUS_ERROR; - } - if (mGlobals.FlashDeviceImage == NULL) { - Error (NULL, 0, 0, "must specify -flashdeviceimage with -imageout", NULL); - return STATUS_ERROR; - } - if (mGlobals.FlashDefinitionFileName == NULL) { - Error (NULL, 0, 0, "must specify -c or -fdf with -imageout", NULL); - return STATUS_ERROR; - } - } - return STATUS_SUCCESS; -} - -static -void -Usage ( - VOID - ) -/*++ - -Routine Description: - Print utility command line help - -Arguments: - None - -Returns: - NA - ---*/ -{ - int i; - char *Msg[] = { - "Usage: FlashTool -fdf FlashDefFile -flashdevice FlashDevice", - " -flashdeviceimage FlashDeviceImage -mci MCIFile -mco MCOFile", - " -discover FDImage -dsc DscFile -asmincfile AsmIncFile", - " -imageOut ImageOutFile -hfile HFile -strsub InStrFile OutStrFile", - " -baseaddr BaseAddr -align Alignment -padvalue PadValue", - " -mcmerge MCIFile(s)", - " where", - " FlashDefFile - input Flash Definition File", - " FlashDevice - flash device to use (from flash definition file)", - " FlashDeviceImage - flash device image to use (from flash definition file)", - " MCIFile - input microcode file to parse", - " MCOFile - output binary microcode image to create from MCIFile", - " HFile - output #include file to create", - " FDImage - name of input FDImage file to scan", - " ImageOutFile - output image file to create", - " DscFile - output DSC file to create", - " AsmIncFile - output ASM include file to create", - " InStrFile - input file to replace symbol names, writing result to OutStrFile", - " BaseAddr - base address of FDImage (used with -discover)", - " Alignment - alignment to use when merging microcode binaries", - " PadValue - byte value to use as pad value when aligning microcode binaries", - " MCIFile(s) - one or more microcode binary files to merge/concatenate", - "", - NULL - }; - for (i = 0; Msg[i] != NULL; i++) { - fprintf (stdout, "%s\n", Msg[i]); - } -} - -char* -NormalizePath ( - char* OldPathName - ) -{ - char* Visitor; - - if (OldPathName == NULL) { - return NULL; - } - - Visitor = OldPathName; - while (*Visitor != '\0') { - if (*Visitor == '\\') { - *Visitor = '/'; - } - Visitor++; - } - - return OldPathName; -} - diff --git a/Tools/CodeTools/TianoTools/FlashMap/Microcode.c b/Tools/CodeTools/TianoTools/FlashMap/Microcode.c deleted file mode 100644 index 23353254a4..0000000000 --- a/Tools/CodeTools/TianoTools/FlashMap/Microcode.c +++ /dev/null @@ -1,304 +0,0 @@ -/*++ - -Copyright (c) 2004-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - Microcode.c - -Abstract: - - Utility for working with microcode patch files in the Intel - Platform Innovation Framework for EFI build environment. - ---*/ - -#include -#include // for memset() -#include -#include // for malloc() - -#include "EfiUtilityMsgs.h" -#include "Microcode.h" - -#define MAX_LINE_LEN 256 - -// -// Structure definition for a microcode header -// -typedef struct { - unsigned int HeaderVersion; - unsigned int PatchId; - unsigned int Date; - unsigned int CpuId; - unsigned int Checksum; - unsigned int LoaderVersion; - unsigned int PlatformId; - unsigned int DataSize; // if 0, then TotalSize = 2048, and TotalSize field is invalid - unsigned int TotalSize; // number of bytes - unsigned int Reserved[3]; -} MICROCODE_IMAGE_HEADER; - -static -STATUS -MicrocodeReadData ( - FILE *InFptr, - unsigned int *Data - ); - -void -MicrocodeConstructor ( - void - ) -/*++ - -Routine Description: - - Constructor of module Microcode - -Arguments: - - None - -Returns: - - None - ---*/ -{ -} - -void -MicrocodeDestructor ( - void - ) -/*++ - -Routine Description: - - Destructor of module Microcode - -Arguments: - - None - -Returns: - - None - ---*/ -{ -} - -static -STATUS -MicrocodeReadData ( - FILE *InFptr, - unsigned int *Data - ) -/*++ - -Routine Description: - Read a 32-bit microcode data value from a text file and convert to raw binary form. - -Arguments: - InFptr - file pointer to input text file - Data - pointer to where to return the data parsed - -Returns: - STATUS_SUCCESS - no errors or warnings, Data contains valid information - STATUS_ERROR - errors were encountered - ---*/ -{ - char Line[MAX_LINE_LEN]; - char *cptr; - - Line[MAX_LINE_LEN - 1] = 0; - *Data = 0; - if (fgets (Line, MAX_LINE_LEN, InFptr) == NULL) { - return STATUS_ERROR; - } - // - // If it was a binary file, then it may have overwritten our null terminator - // - if (Line[MAX_LINE_LEN - 1] != 0) { - return STATUS_ERROR; - } - // - // Look for - // dd 000000001h ; comment - // dd XXXXXXXX - // DD XXXXXXXXX - // DD XXXXXXXXX - // - for (cptr = Line; *cptr && isspace(*cptr); cptr++) { - } - if ((tolower(cptr[0]) == 'd') && (tolower(cptr[1]) == 'd') && isspace (cptr[2])) { - // - // Skip blanks and look for a hex digit - // - cptr += 3; - for (; *cptr && isspace(*cptr); cptr++) { - } - if (isxdigit (*cptr)) { - if (sscanf (cptr, "%X", Data) != 1) { - return STATUS_ERROR; - } - } - return STATUS_SUCCESS; - } - return STATUS_ERROR; -} - -STATUS -MicrocodeParseFile ( - char *InFileName, - char *OutFileName - ) -/*++ - -Routine Description: - Parse a microcode text file, and write the binary results to an output file. - -Arguments: - InFileName - input text file to parse - OutFileName - output file to write raw binary data from parsed input file - -Returns: - STATUS_SUCCESS - no errors or warnings - STATUS_ERROR - errors were encountered - ---*/ -{ - FILE *InFptr; - FILE *OutFptr; - STATUS Status; - MICROCODE_IMAGE_HEADER *Header; - unsigned int Size; - unsigned int Size2; - unsigned int Data; - unsigned int Checksum; - char *Buffer; - char *Ptr; - unsigned int TotalSize; - - Status = STATUS_ERROR; - InFptr = NULL; - OutFptr = NULL; - Buffer = NULL; - // - // Open the input text file - // - if ((InFptr = fopen (InFileName, "r")) == NULL) { - Error (NULL, 0, 0, InFileName, "failed to open input microcode file for reading"); - return STATUS_ERROR; - } - // - // Make two passes on the input file. The first pass is to determine how - // much data is in the file so we can allocate a working buffer. Then - // we'll allocate a buffer and re-read the file into the buffer for processing. - // - Size = 0; - do { - Status = MicrocodeReadData (InFptr, &Data); - if (Status == STATUS_SUCCESS) { - Size += sizeof (Data); - } - } while (Status == STATUS_SUCCESS); - // - // Error if no data. - // - if (Size == 0) { - Error (NULL, 0, 0, InFileName, "no parse-able data found in file"); - goto Done; - } - if (Size < sizeof (MICROCODE_IMAGE_HEADER)) { - Error (NULL, 0, 0, InFileName, "amount of parse-able data is insufficient to contain a microcode header"); - goto Done; - } - // - // Allocate a buffer for the data - // - Buffer = (char *) _malloc (Size); - if (Buffer == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - goto Done; - } - // - // Re-read the file, storing the data into our buffer - // - fseek (InFptr, 0, SEEK_SET); - Ptr = Buffer; - do { - Status = MicrocodeReadData (InFptr, &Data); - if (Status == STATUS_SUCCESS) { - *(unsigned int *) Ptr = Data; - Ptr += sizeof (Data); - } - } while (Status == STATUS_SUCCESS); - // - // Can't do much checking on the header because, per the spec, the - // DataSize field may be 0, which means DataSize = 2000 and TotalSize = 2K, - // and the TotalSize field is invalid (actually missing). Thus we can't - // even verify the Reserved fields are 0. - // - Header = (MICROCODE_IMAGE_HEADER *) Buffer; - if (Header->DataSize == 0) { - TotalSize = 2048; - } else { - TotalSize = Header->TotalSize; - } - if (TotalSize != Size) { - Error (NULL, 0, 0, InFileName, "file contents do not contain expected TotalSize 0x%04X", TotalSize); - goto Done; - } - // - // Checksum the contents - // - Ptr = Buffer; - Checksum = 0; - Size2 = 0; - while (Size2 < Size) { - Checksum += *(unsigned int *) Ptr; - Ptr += 4; - Size2 += 4; - } - if (Checksum != 0) { - Error (NULL, 0, 0, InFileName, "checksum failed on file contents"); - goto Done; - } - // - // Open the output file and write the buffer contents - // - if ((OutFptr = fopen (OutFileName, "wb")) == NULL) { - Error (NULL, 0, 0, OutFileName, "failed to open output microcode file for writing"); - goto Done; - } - if (fwrite (Buffer, Size, 1, OutFptr) != 1) { - Error (NULL, 0, 0, OutFileName, "failed to write microcode data to output file"); - goto Done; - } - Status = STATUS_SUCCESS; -Done: - if (Buffer != NULL) { - free (Buffer); - } - if (InFptr != NULL) { - fclose (InFptr); - } - if (OutFptr != NULL) { - fclose (OutFptr); - if (Status == STATUS_ERROR) { - remove (OutFileName); - } - } - return Status; -} diff --git a/Tools/CodeTools/TianoTools/FlashMap/Microcode.h b/Tools/CodeTools/TianoTools/FlashMap/Microcode.h deleted file mode 100644 index f85313e978..0000000000 --- a/Tools/CodeTools/TianoTools/FlashMap/Microcode.h +++ /dev/null @@ -1,87 +0,0 @@ -/*++ - -Copyright (c) 2004-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - Microcode.h - -Abstract: - - Header file for flash management utility in the Intel Platform - Innovation Framework for EFI build environment. - ---*/ - -#ifndef _MICROCODE_H_ -#define _MICROCODE_H_ - -void -MicrocodeConstructor ( - void - ); -/*++ - -Routine Description: - - Constructor of module Microcode - -Arguments: - - None - -Returns: - - None - ---*/ - -void -MicrocodeDestructor ( - void - ); -/*++ - -Routine Description: - - Destructor of module Microcode - -Arguments: - - None - -Returns: - - None - ---*/ - -STATUS -MicrocodeParseFile ( - char *InFileName, - char *OutFileName - ); -/*++ - -Routine Description: - Parse a microcode text file, and write the binary results to an output file. - -Arguments: - InFileName - input text file to parse - OutFileName - output file to write raw binary data from parsed input file - -Returns: - STATUS_SUCCESS - no errors or warnings - STATUS_ERROR - errors were encountered - ---*/ - - -#endif // #ifndef _MICROCODE_H_ diff --git a/Tools/CodeTools/TianoTools/FlashMap/Symbols.c b/Tools/CodeTools/TianoTools/FlashMap/Symbols.c deleted file mode 100644 index 8e408144db..0000000000 --- a/Tools/CodeTools/TianoTools/FlashMap/Symbols.c +++ /dev/null @@ -1,648 +0,0 @@ -/*++ - -Copyright (c) 2004-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - Symbol.c - -Abstract: - - Class-like implementation for a symbol table. - ---*/ - -// GC_TODO: fix comment to set correct module name: Symbols.c -#include -#include -#include -// -// for isspace() -// -#include - -#include - -#include "CommonLib.h" -#include "EfiUtilityMsgs.h" -#include "Symbols.h" - -#define MAX_LINE_LEN 512 - -// -// Linked list to keep track of all symbols -// -typedef struct _SYMBOL { - struct _SYMBOL *Next; - int Type; - char *Name; - char *Value; -} SYMBOL; - -static -SYMBOL * -FreeSymbols ( - SYMBOL *Syms - ); - -static -int -ExpandMacros ( - char *SourceLine, - char *DestLine, - int LineLen - ); - -static SYMBOL *mSymbolTable = NULL; - -void -SymbolsConstructor ( - VOID - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - None - -Returns: - - GC_TODO: add return values - ---*/ -{ - SymbolsDestructor (); -} - -void -SymbolsDestructor ( - VOID - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - None - -Returns: - - GC_TODO: add return values - ---*/ -{ - mSymbolTable = FreeSymbols (mSymbolTable); -} - -char * -GetSymbolValue ( - char *SymbolName - ) -/*++ - -Routine Description: - - Look up a symbol in our symbol table. - -Arguments: - - SymbolName - -Returns: - - Pointer to the value of the symbol if found - NULL if the symbol is not found - ---*/ -// GC_TODO: SymbolName - add argument and description to function comment -{ - SYMBOL *Symbol; - // - // Walk the symbol table - // - Symbol = mSymbolTable; - while (Symbol) { - if (stricmp (SymbolName, Symbol->Name) == 0) { - return Symbol->Value; - } - - Symbol = Symbol->Next; - } - - return NULL; -} - -int -SymbolAdd ( - char *Name, - char *Value, - int Mode - ) -/*++ - -Routine Description: - - Add a symbol name/value to the symbol table - -Arguments: - - Name - name of symbol to add - Value - value of symbol to add - Mode - currrently unused - -Returns: - - Length of symbol added. - -Notes: - If Value == NULL, then this routine will assume that the Name field - looks something like "MySymName = MySymValue", and will try to parse - it that way and add the symbol name/pair from the string. - ---*/ -{ - SYMBOL *Symbol; - - SYMBOL *NewSymbol; - int Len; - char *Start; - char *Cptr; - char CSave; - char *SaveCptr; - - Len = 0; - SaveCptr = NULL; - CSave = 0; - // - // If value pointer is null, then they passed us a line something like: - // varname = value, or simply var = - // - if (Value == NULL) { - Start = Name; - while (*Name && isspace (*Name)) { - Name++; - } - - if (Name == NULL) { - return -1; - } - // - // Find the end of the name. Either space or a '='. - // - for (Value = Name; *Value && !isspace (*Value) && (*Value != '='); Value++) - ; - if (Value == NULL) { - return -1; - } - // - // Look for the '=' - // - Cptr = Value; - while (*Value && (*Value != '=')) { - Value++; - } - - if (Value == NULL) { - return -1; - } - // - // Now truncate the name - // - *Cptr = 0; - // - // Skip over the = and then any spaces - // - Value++; - while (*Value && isspace (*Value)) { - Value++; - - } - // - // Find end of string, checking for quoted string - // - if (*Value == '\"') { - Value++; - for (Cptr = Value; *Cptr && *Cptr != '\"'; Cptr++) - ; - } else { - for (Cptr = Value; *Cptr && !isspace (*Cptr); Cptr++) - ; - } - // - // Null terminate the value string - // - CSave = *Cptr; - SaveCptr = Cptr; - *Cptr = 0; - Len = (int) (Cptr - Start); - } - // - // We now have a symbol name and a value. Look for an existing variable - // and overwrite it. - // - Symbol = mSymbolTable; - while (Symbol) { - // - // Check for symbol name match - // - if (stricmp (Name, Symbol->Name) == 0) { - _free (Symbol->Value); - Symbol->Value = (char *) _malloc (strlen (Value) + 1); - if (Symbol->Value == NULL) { - Error (NULL, 0, 0, NULL, "failed to allocate memory"); - return -1; - } - - strcpy (Symbol->Value, Value); - // - // If value == "NULL", then make it a 0-length string - // - if (stricmp (Symbol->Value, "NULL") == 0) { - Symbol->Value[0] = 0; - } - - return Len; - } - - Symbol = Symbol->Next; - } - // - // Does not exist, create a new one - // - NewSymbol = (SYMBOL *) _malloc (sizeof (SYMBOL)); - if (NewSymbol == NULL) { - Error (NULL, 0, 0, NULL, "memory allocation failure"); - return -1; - } - - memset ((char *) NewSymbol, 0, sizeof (SYMBOL)); - NewSymbol->Name = (char *) _malloc (strlen (Name) + 1); - if (NewSymbol->Name == NULL) { - Error (NULL, 0, 0, NULL, "memory allocation failure"); - _free (NewSymbol); - return -1; - } - - NewSymbol->Value = (char *) _malloc (strlen (Value) + 1); - if (NewSymbol->Value == NULL) { - Error (NULL, 0, 0, NULL, "memory allocation failure"); - _free (NewSymbol->Name); - _free (NewSymbol); - return -1; - } - - strcpy (NewSymbol->Name, Name); - strcpy (NewSymbol->Value, Value); - // - // Remove trailing spaces - // - Cptr = NewSymbol->Value + strlen (NewSymbol->Value) - 1; - while (Cptr > NewSymbol->Value) { - if (isspace (*Cptr)) { - *Cptr = 0; - Cptr--; - } else { - break; - } - } - // - // Add it to the head of the list. - // - NewSymbol->Next = mSymbolTable; - mSymbolTable = NewSymbol; - // - // If value == "NULL", then make it a 0-length string - // - if (stricmp (NewSymbol->Value, "NULL") == 0) { - NewSymbol->Value[0] = 0; - } - // - // Restore the terminator we inserted if they passed in var=value - // - if (SaveCptr != NULL) { - *SaveCptr = CSave; - } - _free (NewSymbol->Value); - _free (NewSymbol->Name); - _free (NewSymbol); - return Len; -} - -static -STATUS -RemoveSymbol ( - char *Name, - char SymbolType - ) -/*++ - -Routine Description: - - Remove a symbol name/value from the symbol table - -Arguments: - - Name - name of symbol to remove - SymbolType - type of symbol to remove - -Returns: - - STATUS_SUCCESS - matching symbol found and removed - STATUS_ERROR - matching symbol not found in symbol table - ---*/ -{ - SYMBOL *Symbol; - - SYMBOL *PrevSymbol; - - PrevSymbol = NULL; - Symbol = mSymbolTable; - // - // Walk the linked list of symbols in the symbol table looking - // for a match of both symbol name and type. - // - while (Symbol) { - if ((stricmp (Name, Symbol->Name) == 0) && (Symbol->Type & SymbolType)) { - // - // If the symbol has a value associated with it, free the memory - // allocated for the value. - // Then free the memory allocated for the symbols string name. - // - if (Symbol->Value) { - _free (Symbol->Value); - } - - _free (Symbol->Name); - // - // Link the previous symbol to the next symbol to effectively - // remove this symbol from the linked list. - // - if (PrevSymbol) { - PrevSymbol->Next = Symbol->Next; - } else { - mSymbolTable = Symbol->Next; - } - - _free (Symbol); - return STATUS_SUCCESS; - } - - PrevSymbol = Symbol; - Symbol = Symbol->Next; - } - - return STATUS_WARNING; -} - -static -SYMBOL * -FreeSymbols ( - SYMBOL *Syms - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - Syms - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - SYMBOL *Next; - while (Syms) { - if (Syms->Name != NULL) { - _free (Syms->Name); - } - - if (Syms->Value != NULL) { - _free (Syms->Value); - } - - Next = Syms->Next; - _free (Syms); - Syms = Next; - } - - return Syms; -} - -static -int -ExpandMacros ( - char *SourceLine, - char *DestLine, - int LineLen - ) -/*++ - -Routine Description: - - Given a line of text, replace all variables of format $(NAME) with values - from our symbol table. - -Arguments: - - SourceLine - input line of text to do symbol replacements on - DestLine - on output, SourceLine with symbols replaced - LineLen - length of DestLine, so we don't exceed its allocated length - -Returns: - - STATUS_SUCCESS - no problems encountered - STATUS_WARNING - missing closing parenthesis on a symbol reference in SourceLine - STATUS_ERROR - memory allocation failure - ---*/ -{ - static int NestDepth = 0; - char *FromPtr; - char *ToPtr; - char *SaveStart; - char *Cptr; - char *value; - int Expanded; - int ExpandedCount; - INT8 *LocalDestLine; - STATUS Status; - int LocalLineLen; - - NestDepth++; - Status = STATUS_SUCCESS; - LocalDestLine = (char *) _malloc (LineLen); - if (LocalDestLine == NULL) { - Error (__FILE__, __LINE__, 0, "memory allocation failed", NULL); - return STATUS_ERROR; - } - - FromPtr = SourceLine; - ToPtr = LocalDestLine; - // - // Walk the entire line, replacing $(MACRO_NAME). - // - LocalLineLen = LineLen; - ExpandedCount = 0; - while (*FromPtr && (LocalLineLen > 0)) { - if ((*FromPtr == '$') && (*(FromPtr + 1) == '(')) { - // - // Save the start in case it's undefined, in which case we copy it as-is. - // - SaveStart = FromPtr; - Expanded = 0; - // - // Macro expansion time. Find the end (no spaces allowed) - // - FromPtr += 2; - for (Cptr = FromPtr; *Cptr && (*Cptr != ')'); Cptr++) - ; - if (*Cptr) { - // - // Truncate the string at the closing parenthesis for ease-of-use. - // Then copy the string directly to the destination line in case we don't find - // a definition for it. - // - *Cptr = 0; - strcpy (ToPtr, SaveStart); - if ((value = GetSymbolValue (FromPtr)) != NULL) { - strcpy (ToPtr, value); - LocalLineLen -= strlen (value); - ToPtr += strlen (value); - Expanded = 1; - ExpandedCount++; - } - - if (!Expanded) { - // - // Restore closing parenthesis, and advance to next character - // - *Cptr = ')'; - FromPtr = SaveStart + 1; - ToPtr++; - } else { - FromPtr = Cptr + 1; - } - } else { - Error (NULL, 0, 0, SourceLine, "missing closing parenthesis on macro"); - strcpy (ToPtr, FromPtr); - Status = STATUS_WARNING; - goto Done; - } - } else { - *ToPtr = *FromPtr; - FromPtr++; - ToPtr++; - LocalLineLen--; - } - } - - if (*FromPtr == 0) { - *ToPtr = 0; - } - - // - // If we expanded at least one string successfully, then make a recursive call to try again. - // - if ((ExpandedCount != 0) && (Status == STATUS_SUCCESS) && (NestDepth < 10)) { - Status = ExpandMacros (LocalDestLine, DestLine, LineLen); - _free (LocalDestLine); - NestDepth = 0; - return Status; - } - -Done: - if (Status != STATUS_ERROR) { - strcpy (DestLine, LocalDestLine); - } - - NestDepth = 0; - _free (LocalDestLine); - return Status; -} - -STATUS -SymbolsFileStringsReplace ( - char *InFileName, - char *OutFileName - ) -/*++ - -Routine Description: - - Given input and output file names, read in the input file, replace variable - references of format $(NAME) with appropriate values from our symbol table, - and write the result out to the output file. - -Arguments: - - InFileName - name of input text file to replace variable references - OutFileName - name of output text file to write results to - -Returns: - - STATUS_SUCCESS - no problems encountered - STATUS_ERROR - failed to open input or output file - ---*/ -{ - STATUS Status; - FILE *InFptr; - FILE *OutFptr; - char Line[MAX_LINE_LEN]; - char OutLine[MAX_LINE_LEN]; - - Status = STATUS_ERROR; - // - // Open input and output files - // - InFptr = NULL; - OutFptr = NULL; - if ((InFptr = fopen (InFileName, "r")) == NULL) { - Error (NULL, 0, 0, InFileName, "failed to open input file for reading"); - goto Done; - } - - if ((OutFptr = fopen (OutFileName, "w")) == NULL) { - Error (NULL, 0, 0, OutFileName, "failed to open output file for writing"); - goto Done; - } - // - // Read lines from input file until done - // - while (fgets (Line, sizeof (Line), InFptr) != NULL) { - ExpandMacros (Line, OutLine, sizeof (OutLine)); - fprintf (OutFptr, OutLine); - } - - Status = STATUS_SUCCESS; -Done: - if (InFptr != NULL) { - fclose (InFptr); - } - - if (OutFptr != NULL) { - fclose (OutFptr); - } - - return Status; -} diff --git a/Tools/CodeTools/TianoTools/FlashMap/Symbols.h b/Tools/CodeTools/TianoTools/FlashMap/Symbols.h deleted file mode 100644 index a3cadff268..0000000000 --- a/Tools/CodeTools/TianoTools/FlashMap/Symbols.h +++ /dev/null @@ -1,124 +0,0 @@ -/*++ - -Copyright (c) 2004-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - Symbols.h - -Abstract: - - Defines and prototypes for a class-like symbol table service. - ---*/ - -#ifndef _SYMBOLS_H_ -#define _SYMBOLS_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - -int -SymbolAdd ( - char *Name, - char *Value, - int Mode - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - Name - GC_TODO: add argument description - Value - GC_TODO: add argument description - Mode - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -; - -STATUS -SymbolsFileStringsReplace ( - char *InFileName, - char *OutFileName - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - InFileName - GC_TODO: add argument description - OutFileName - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -; - -void -SymbolsConstructor ( - VOID - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - None - -Returns: - - GC_TODO: add return values - ---*/ -; - -void -SymbolsDestructor ( - VOID - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - None - -Returns: - - GC_TODO: add return values - ---*/ -; - -#ifdef __cplusplus -} -#endif - -#endif // #ifndef _SYMBOLS_H_ diff --git a/Tools/CodeTools/TianoTools/FlashMap/build.xml b/Tools/CodeTools/TianoTools/FlashMap/build.xml deleted file mode 100644 index 680c1820b0..0000000000 --- a/Tools/CodeTools/TianoTools/FlashMap/build.xml +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/FwImage/build.xml b/Tools/CodeTools/TianoTools/FwImage/build.xml deleted file mode 100644 index b52c576c34..0000000000 --- a/Tools/CodeTools/TianoTools/FwImage/build.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/FwImage/fwimage.c b/Tools/CodeTools/TianoTools/FwImage/fwimage.c deleted file mode 100644 index 5dd1634b99..0000000000 --- a/Tools/CodeTools/TianoTools/FwImage/fwimage.c +++ /dev/null @@ -1,510 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - fwimage.c - -Abstract: - - Converts a pe32+ image to an FW image type - ---*/ - -#include "WinNtInclude.h" - -#ifndef __GNUC__ -#include -#endif -#include -#include -#include -#include - -#include -#include - -#include "CommonLib.h" -#include "EfiUtilityMsgs.c" - -#define UTILITY_NAME "FwImage" - -#ifdef __GNUC__ -typedef unsigned long ULONG; -typedef unsigned char UCHAR; -typedef unsigned char *PUCHAR; -typedef unsigned short USHORT; -#endif - -VOID -Usage ( - VOID - ) -{ - printf ("Usage: " UTILITY_NAME " {-t time-date} [BASE|SEC|PEI_CORE|PEIM|DXE_CORE|DXE_DRIVER|DXE_RUNTIME_DRIVER|DXE_SAL_DRIVER|DXE_SMM_DRIVER|TOOL|UEFI_DRIVER|UEFI_APPLICATION|USER_DEFINED] peimage [outimage]"); -} - -static -STATUS -FCopyFile ( - FILE *in, - FILE *out - ) -{ - ULONG filesize; - ULONG offset; - ULONG length; - UCHAR Buffer[8 * 1024]; - - fseek (in, 0, SEEK_END); - filesize = ftell (in); - - fseek (in, 0, SEEK_SET); - fseek (out, 0, SEEK_SET); - - offset = 0; - while (offset < filesize) { - length = sizeof (Buffer); - if (filesize - offset < length) { - length = filesize - offset; - } - - fread (Buffer, length, 1, in); - fwrite (Buffer, length, 1, out); - offset += length; - } - - if ((ULONG) ftell (out) != filesize) { - Error (NULL, 0, 0, "write error", NULL); - return STATUS_ERROR; - } - - return STATUS_SUCCESS; -} - -static -STATUS -FReadFile ( - FILE *in, - VOID **Buffer, - UINTN *Length - ) -{ - fseek (in, 0, SEEK_END); - *Length = ftell (in); - *Buffer = malloc (*Length); - fseek (in, 0, SEEK_SET); - fread (*Buffer, *Length, 1, in); - return STATUS_SUCCESS; -} - -static -STATUS -FWriteFile ( - FILE *out, - VOID *Buffer, - UINTN Length - ) -{ - fseek (out, 0, SEEK_SET); - fwrite (Buffer, Length, 1, out); - if ((ULONG) ftell (out) != Length) { - Error (NULL, 0, 0, "write error", NULL); - return STATUS_ERROR; - } - free (Buffer); - return STATUS_SUCCESS; -} - -int -main ( - int argc, - char *argv[] - ) -/*++ - -Routine Description: - - Main function. - -Arguments: - - argc - Number of command line parameters. - argv - Array of pointers to command line parameter strings. - -Returns: - STATUS_SUCCESS - Utility exits successfully. - STATUS_ERROR - Some error occurred during execution. - ---*/ -{ - ULONG Type; - PUCHAR Ext; - PUCHAR p; - PUCHAR pe; - PUCHAR OutImageName; - UCHAR outname[500]; - FILE *fpIn; - FILE *fpOut; - VOID *ZeroBuffer; - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_NT_HEADERS *PeHdr; - EFI_IMAGE_OPTIONAL_HEADER32 *Optional32; - EFI_IMAGE_OPTIONAL_HEADER64 *Optional64; - time_t TimeStamp; - struct tm TimeStruct; - EFI_IMAGE_DOS_HEADER BackupDosHdr; - ULONG Index; - ULONG Index1; - ULONG Index2; - ULONG Index3; - BOOLEAN TimeStampPresent; - UINTN AllignedRelocSize; - UINTN Delta; - EFI_IMAGE_SECTION_HEADER *SectionHeader; - UINT8 *FileBuffer; - UINTN FileLength; - RUNTIME_FUNCTION *RuntimeFunction; - UNWIND_INFO *UnwindInfo; - - SetUtilityName (UTILITY_NAME); - // - // Assign to fix compile warning - // - OutImageName = NULL; - Type = 0; - Ext = 0; - TimeStamp = 0; - TimeStampPresent = FALSE; - - // - // Look for -t time-date option first. If the time is "0", then - // skip it. - // - if ((argc > 2) && !strcmp (argv[1], "-t")) { - TimeStampPresent = TRUE; - if (strcmp (argv[2], "0") != 0) { - // - // Convert the string to a value - // - memset ((char *) &TimeStruct, 0, sizeof (TimeStruct)); - if (sscanf( - argv[2], "%d/%d/%d,%d:%d:%d", - &TimeStruct.tm_mon, /* months since January - [0,11] */ - &TimeStruct.tm_mday, /* day of the month - [1,31] */ - &TimeStruct.tm_year, /* years since 1900 */ - &TimeStruct.tm_hour, /* hours since midnight - [0,23] */ - &TimeStruct.tm_min, /* minutes after the hour - [0,59] */ - &TimeStruct.tm_sec /* seconds after the minute - [0,59] */ - ) != 6) { - Error (NULL, 0, 0, argv[2], "failed to convert to mm/dd/yyyy,hh:mm:ss format"); - return STATUS_ERROR; - } - // - // Now fixup some of the fields - // - TimeStruct.tm_mon--; - TimeStruct.tm_year -= 1900; - // - // Sanity-check values? - // Convert - // - TimeStamp = mktime (&TimeStruct); - if (TimeStamp == (time_t) - 1) { - Error (NULL, 0, 0, argv[2], "failed to convert time"); - return STATUS_ERROR; - } - } - // - // Skip over the args - // - argc -= 2; - argv += 2; - } - // - // Check for enough args - // - if (argc < 3) { - Usage (); - return STATUS_ERROR; - } - - if (argc == 4) { - OutImageName = argv[3]; - } - // - // Get new image type - // - p = argv[1]; - if (*p == '/' || *p == '\\') { - p += 1; - } - - if (stricmp (p, "app") == 0 || stricmp (p, "UEFI_APPLICATION") == 0) { - Type = EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION; - Ext = ".efi"; - - } else if (stricmp (p, "bsdrv") == 0 || stricmp (p, "DXE_DRIVER") == 0) { - Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER; - Ext = ".efi"; - - } else if (stricmp (p, "rtdrv") == 0 || stricmp (p, "DXE_RUNTIME_DRIVER") == 0) { - Type = EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER; - Ext = ".efi"; - - } else if (stricmp (p, "rtdrv") == 0 || stricmp (p, "DXE_SAL_DRIVER") == 0) { - Type = EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER; - Ext = ".efi"; - } else if (stricmp (p, "SEC") == 0) { - Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER; - Ext = ".sec"; - } else if (stricmp (p, "peim") == 0 || - stricmp (p, "BASE") == 0 || - stricmp (p, "PEI_CORE") == 0 || - stricmp (p, "PEIM") == 0 || - stricmp (p, "DXE_SMM_DRIVER") == 0 || - stricmp (p, "TOOL") == 0 || - stricmp (p, "UEFI_APPLICATION") == 0 || - stricmp (p, "USER_DEFINED") == 0 || - stricmp (p, "UEFI_DRIVER") == 0 || - stricmp (p, "DXE_CORE") == 0 - ) { - Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER; - Ext = ".pei"; - } else { - printf ("%s", p); - Usage (); - return STATUS_ERROR; - } - // - // open source file - // - fpIn = fopen (argv[2], "rb"); - if (!fpIn) { - Error (NULL, 0, 0, argv[2], "failed to open input file for reading"); - return STATUS_ERROR; - } - - FReadFile (fpIn, (VOID **)&FileBuffer, &FileLength); - - // - // Read the dos & pe hdrs of the image - // - DosHdr = (EFI_IMAGE_DOS_HEADER *)FileBuffer; - if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) { - Error (NULL, 0, 0, argv[2], "DOS header signature not found in source image"); - fclose (fpIn); - return STATUS_ERROR; - } - - PeHdr = (EFI_IMAGE_NT_HEADERS *)(FileBuffer + DosHdr->e_lfanew); - if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) { - Error (NULL, 0, 0, argv[2], "PE header signature not found in source image"); - fclose (fpIn); - return STATUS_ERROR; - } - - // - // open output file - // - strcpy (outname, argv[2]); - pe = NULL; - for (p = outname; *p; p++) { - if (*p == '.') { - pe = p; - } - } - - if (!pe) { - pe = p; - } - - strcpy (pe, Ext); - - if (!OutImageName) { - OutImageName = outname; - } - - fpOut = fopen (OutImageName, "w+b"); - if (!fpOut) { - Error (NULL, 0, 0, OutImageName, "could not open output file for writing"); - fclose (fpIn); - return STATUS_ERROR; - } - - // - // Zero all unused fields of the DOS header - // - memcpy (&BackupDosHdr, DosHdr, sizeof (EFI_IMAGE_DOS_HEADER)); - memset (DosHdr, 0, sizeof (EFI_IMAGE_DOS_HEADER)); - DosHdr->e_magic = BackupDosHdr.e_magic; - DosHdr->e_lfanew = BackupDosHdr.e_lfanew; - - for (Index = sizeof (EFI_IMAGE_DOS_HEADER); Index < (ULONG) DosHdr->e_lfanew; Index++) { - FileBuffer[Index] = DosHdr->e_cp; - } - - // - // Path the PE header - // - PeHdr->OptionalHeader.Subsystem = (USHORT) Type; - if (TimeStampPresent) { - PeHdr->FileHeader.TimeDateStamp = (UINT32) TimeStamp; - } - - if (PeHdr->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->OptionalHeader; - Optional32->MajorLinkerVersion = 0; - Optional32->MinorLinkerVersion = 0; - Optional32->MajorOperatingSystemVersion = 0; - Optional32->MinorOperatingSystemVersion = 0; - Optional32->MajorImageVersion = 0; - Optional32->MinorImageVersion = 0; - Optional32->MajorSubsystemVersion = 0; - Optional32->MinorSubsystemVersion = 0; - Optional32->Win32VersionValue = 0; - Optional32->CheckSum = 0; - Optional32->SizeOfStackReserve = 0; - Optional32->SizeOfStackCommit = 0; - Optional32->SizeOfHeapReserve = 0; - Optional32->SizeOfHeapCommit = 0; - - // - // Strip zero padding at the end of the .reloc section - // - if (Optional32->NumberOfRvaAndSizes >= 6) { - if (Optional32->DataDirectory[5].Size != 0) { - SectionHeader = (EFI_IMAGE_SECTION_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof(UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + PeHdr->FileHeader.SizeOfOptionalHeader); - for (Index = 0; Index < PeHdr->FileHeader.NumberOfSections; Index++, SectionHeader++) { - // - // Look for the Section Header that starts as the same virtual address as the Base Relocation Data Directory - // - if (SectionHeader->VirtualAddress == Optional32->DataDirectory[5].VirtualAddress) { - SectionHeader->Misc.VirtualSize = Optional32->DataDirectory[5].Size; - AllignedRelocSize = (Optional32->DataDirectory[5].Size + Optional32->FileAlignment - 1) & (~(Optional32->FileAlignment - 1)); - // - // Check to see if there is zero padding at the end of the base relocations - // - if (AllignedRelocSize < SectionHeader->SizeOfRawData) { - // - // Check to see if the base relocations are at the end of the file - // - if (SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData == Optional32->SizeOfImage) { - // - // All the required conditions are met to strip the zero padding of the end of the base relocations section - // - Optional32->SizeOfImage -= (SectionHeader->SizeOfRawData - AllignedRelocSize); - Optional32->SizeOfInitializedData -= (SectionHeader->SizeOfRawData - AllignedRelocSize); - SectionHeader->SizeOfRawData = AllignedRelocSize; - FileLength = Optional32->SizeOfImage; - } - } - } - } - } - } - } - if (PeHdr->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->OptionalHeader; - Optional64->MajorLinkerVersion = 0; - Optional64->MinorLinkerVersion = 0; - Optional64->MajorOperatingSystemVersion = 0; - Optional64->MinorOperatingSystemVersion = 0; - Optional64->MajorImageVersion = 0; - Optional64->MinorImageVersion = 0; - Optional64->MajorSubsystemVersion = 0; - Optional64->MinorSubsystemVersion = 0; - Optional64->Win32VersionValue = 0; - Optional64->CheckSum = 0; - Optional64->SizeOfStackReserve = 0; - Optional64->SizeOfStackCommit = 0; - Optional64->SizeOfHeapReserve = 0; - Optional64->SizeOfHeapCommit = 0; - - // - // Zero the .pdata section if the machine type is X64 and the Debug Directory is empty - // - if (PeHdr->FileHeader.Machine == 0x8664) { // X64 - if (Optional64->NumberOfRvaAndSizes >= 4) { - if (Optional64->NumberOfRvaAndSizes < 7 || (Optional64->NumberOfRvaAndSizes >= 7 && Optional64->DataDirectory[6].Size == 0)) { - SectionHeader = (EFI_IMAGE_SECTION_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof(UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + PeHdr->FileHeader.SizeOfOptionalHeader); - for (Index = 0; Index < PeHdr->FileHeader.NumberOfSections; Index++, SectionHeader++) { - if (SectionHeader->VirtualAddress == Optional64->DataDirectory[3].VirtualAddress) { - RuntimeFunction = (RUNTIME_FUNCTION *)(FileBuffer + SectionHeader->PointerToRawData); - for (Index1 = 0; Index1 < Optional64->DataDirectory[3].Size / sizeof (RUNTIME_FUNCTION); Index1++, RuntimeFunction++) { - SectionHeader = (EFI_IMAGE_SECTION_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof(UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + PeHdr->FileHeader.SizeOfOptionalHeader); - for (Index2 = 0; Index2 < PeHdr->FileHeader.NumberOfSections; Index2++, SectionHeader++) { - if (RuntimeFunction->UnwindInfoAddress > SectionHeader->VirtualAddress && RuntimeFunction->UnwindInfoAddress < (SectionHeader->VirtualAddress + SectionHeader->SizeOfRawData)) { - UnwindInfo = (UNWIND_INFO *)(FileBuffer + SectionHeader->PointerToRawData + (RuntimeFunction->UnwindInfoAddress - SectionHeader->VirtualAddress)); - if (UnwindInfo->Version == 1) { - memset (UnwindInfo + 1, 0, UnwindInfo->CountOfUnwindCodes * sizeof (UINT16)); - memset (UnwindInfo, 0, sizeof (UNWIND_INFO)); - } - } - } - memset (RuntimeFunction, 0, sizeof (RUNTIME_FUNCTION)); - } - } - } - Optional64->DataDirectory[3].Size = 0; - Optional64->DataDirectory[3].VirtualAddress = 0; - } - } - } - - // - // Strip zero padding at the end of the .reloc section - // - if (Optional64->NumberOfRvaAndSizes >= 6) { - if (Optional64->DataDirectory[5].Size != 0) { - SectionHeader = (EFI_IMAGE_SECTION_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof(UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + PeHdr->FileHeader.SizeOfOptionalHeader); - for (Index = 0; Index < PeHdr->FileHeader.NumberOfSections; Index++, SectionHeader++) { - // - // Look for the Section Header that starts as the same virtual address as the Base Relocation Data Directory - // - if (SectionHeader->VirtualAddress == Optional64->DataDirectory[5].VirtualAddress) { - SectionHeader->Misc.VirtualSize = Optional64->DataDirectory[5].Size; - AllignedRelocSize = (Optional64->DataDirectory[5].Size + Optional64->FileAlignment - 1) & (~(Optional64->FileAlignment - 1)); - // - // Check to see if there is zero padding at the end of the base relocations - // - if (AllignedRelocSize < SectionHeader->SizeOfRawData) { - // - // Check to see if the base relocations are at the end of the file - // - if (SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData == Optional64->SizeOfImage) { - // - // All the required conditions are met to strip the zero padding of the end of the base relocations section - // - Optional64->SizeOfImage -= (SectionHeader->SizeOfRawData - AllignedRelocSize); - Optional64->SizeOfInitializedData -= (SectionHeader->SizeOfRawData - AllignedRelocSize); - SectionHeader->SizeOfRawData = AllignedRelocSize; - FileLength = Optional64->SizeOfImage; - } - } - } - } - } - } - } - - FWriteFile (fpOut, FileBuffer, FileLength); - - // - // Done - // - fclose (fpIn); - fclose (fpOut); - // - // printf ("Created %s\n", OutImageName); - // - return STATUS_SUCCESS; -} diff --git a/Tools/CodeTools/TianoTools/GenAcpiTable/GenAcpiTable.c b/Tools/CodeTools/TianoTools/GenAcpiTable/GenAcpiTable.c deleted file mode 100644 index 7a413eacb0..0000000000 --- a/Tools/CodeTools/TianoTools/GenAcpiTable/GenAcpiTable.c +++ /dev/null @@ -1,544 +0,0 @@ -/*++ - -Copyright (c) 2004-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - GenAcpiTable.c - -Abstract: - - A utility that extracts the .DATA section from a PE/COFF image. - ---*/ - -#include -#include -#include - -#include -#include // for PE32 structure definitions - -#include "CommonLib.h" -#include "EfiUtilityMsgs.h" - -// -// Version of this utility -// -#define UTILITY_NAME "GenAcpiTable" -#define UTILITY_VERSION "v0.11" - -// -// Define the max length of a filename -// -#define MAX_PATH 256 -#define DEFAULT_OUTPUT_EXTENSION ".acpi" - -// -// Use this to track our command-line options and globals -// -struct { - INT8 OutFileName[MAX_PATH]; - INT8 InFileName[MAX_PATH]; -} mOptions; - -// -// Use these to convert from machine type value to a named type -// -typedef struct { - UINT16 Value; - INT8 *Name; -} STRING_LOOKUP; - -static STRING_LOOKUP mMachineTypes[] = { - EFI_IMAGE_MACHINE_IA32, - "IA32", - EFI_IMAGE_MACHINE_IA64, - "IA64", - EFI_IMAGE_MACHINE_EBC, - "EBC", - 0, - NULL -}; - -static STRING_LOOKUP mSubsystemTypes[] = { - EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION, - "EFI application", - EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, - "EFI boot service driver", - EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER, - "EFI runtime driver", - 0, - NULL -}; -// -// Function prototypes -// -static -void -Usage ( - VOID - ); - -static -STATUS -ParseCommandLine ( - int Argc, - char *Argv[] - ); - -static -STATUS -CheckPE32File ( - INT8 *FileName, - FILE *Fptr, - UINT16 *MachineType, - UINT16 *SubSystem - ); - -static -STATUS -ProcessFile ( - INT8 *InFileName, - INT8 *OutFileName - ); - -static -void -DumpImage ( - INT8 *FileName - ); - -main ( - int Argc, - char *Argv[] - ) -/*++ - -Routine Description: - - -Arguments: - - Argc - standard C main() argument count - - Argv - standard C main() argument list - -Returns: - - 0 success - non-zero otherwise - ---*/ -// GC_TODO: ] - add argument and description to function comment -{ - UINT32 Status; - - SetUtilityName (UTILITY_NAME); - // - // Parse the command line arguments - // - if (ParseCommandLine (Argc, Argv)) { - return STATUS_ERROR; - } - // - // Make sure we don't have the same filename for input and output files - // - if (stricmp (mOptions.OutFileName, mOptions.InFileName) == 0) { - Error (NULL, 0, 0, mOptions.OutFileName, "input and output file names must be different"); - goto Finish; - } - // - // Process the file - // - ProcessFile (mOptions.InFileName, mOptions.OutFileName); -Finish: - Status = GetUtilityStatus (); - return Status; -} - -static -STATUS -ProcessFile ( - INT8 *InFileName, - INT8 *OutFileName - ) -/*++ - -Routine Description: - - Process a PE32 EFI file. - -Arguments: - - InFileName - Name of the PE32 EFI file to process. - OutFileName - Name of the output file for the processed data. - -Returns: - - 0 - successful - ---*/ -{ - STATUS Status; - UINTN Index; - FILE *InFptr; - FILE *OutFptr; - UINT16 MachineType; - UINT16 SubSystem; - UINT32 PESigOffset; - EFI_IMAGE_FILE_HEADER FileHeader; - EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader32; - EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader64; - EFI_IMAGE_SECTION_HEADER SectionHeader; - UINT8 *Buffer; - long SaveFilePosition; - - InFptr = NULL; - OutFptr = NULL; - Buffer = NULL; - Status = STATUS_ERROR; - // - // Try to open the input file - // - if ((InFptr = fopen (InFileName, "rb")) == NULL) { - Error (NULL, 0, 0, InFileName, "failed to open input file for reading"); - return STATUS_ERROR; - } - // - // Double-check the file to make sure it's what we expect it to be - // - if (CheckPE32File (InFileName, InFptr, &MachineType, &SubSystem) != STATUS_SUCCESS) { - goto Finish; - } - // - // Per the PE/COFF specification, at offset 0x3C in the file is a 32-bit - // offset (from the start of the file) to the PE signature, which always - // follows the MSDOS stub. The PE signature is immediately followed by the - // COFF file header. - // - // - if (fseek (InFptr, 0x3C, SEEK_SET) != 0) { - Error (NULL, 0, 0, InFileName, "failed to seek to PE signature in file", NULL); - goto Finish; - } - - if (fread (&PESigOffset, sizeof (PESigOffset), 1, InFptr) != 1) { - Error (NULL, 0, 0, InFileName, "failed to read PE signature offset from file"); - goto Finish; - } - - if (fseek (InFptr, PESigOffset + 4, SEEK_SET) != 0) { - Error (NULL, 0, 0, InFileName, "failed to seek to PE signature"); - goto Finish; - } - // - // We should now be at the COFF file header. Read it in and verify it's - // of an image type we support. - // - if (fread (&FileHeader, sizeof (EFI_IMAGE_FILE_HEADER), 1, InFptr) != 1) { - Error (NULL, 0, 0, InFileName, "failed to read file header from image"); - goto Finish; - } - - if ((FileHeader.Machine != EFI_IMAGE_MACHINE_IA32) && (FileHeader.Machine != EFI_IMAGE_MACHINE_IA64) && (FileHeader.Machine != EFI_IMAGE_MACHINE_X64)) { - Error (NULL, 0, 0, InFileName, "image is of an unsupported machine type 0x%X", (UINT32) FileHeader.Machine); - goto Finish; - } - // - // Read in the optional header. Assume PE32, and if not, then re-read as PE32+ - // - SaveFilePosition = ftell (InFptr); - if (fread (&OptionalHeader32, sizeof (EFI_IMAGE_OPTIONAL_HEADER32), 1, InFptr) != 1) { - Error (NULL, 0, 0, InFileName, "failed to read optional header from input file"); - goto Finish; - } - - if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - if (fseek (InFptr, SaveFilePosition, SEEK_SET) != 0) { - Error (NULL, 0, 0, InFileName, "failed to seek to .data section"); - goto Finish; - } - - if (fread (&OptionalHeader64, sizeof (EFI_IMAGE_OPTIONAL_HEADER64), 1, InFptr) != 1) { - Error (NULL, 0, 0, InFileName, "failed to read optional header from input file"); - goto Finish; - } - } - // - // Search for the ".data" section - // - for (Index = 0; Index < FileHeader.NumberOfSections; Index++) { - if (fread (&SectionHeader, sizeof (EFI_IMAGE_SECTION_HEADER), 1, InFptr) != 1) { - Error (NULL, 0, 0, InFileName, "failed to read optional header from input file"); - goto Finish; - } - - if (strcmp (SectionHeader.Name, ".data") == 0) { - if (fseek (InFptr, SectionHeader.PointerToRawData, SEEK_SET) != 0) { - Error (NULL, 0, 0, InFileName, "failed to seek to .data section"); - goto Finish; - } - - Buffer = (UINT8 *) malloc (SectionHeader.Misc.VirtualSize); - if (Buffer == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Finish; - } - if (fread (Buffer, SectionHeader.Misc.VirtualSize, 1, InFptr) != 1) { - Error (NULL, 0, 0, InFileName, "failed to .data section"); - goto Finish; - } - // - // Now open our output file - // - if ((OutFptr = fopen (OutFileName, "wb")) == NULL) { - Error (NULL, 0, 0, OutFileName, "failed to open output file for writing"); - goto Finish; - } - - if (fwrite (Buffer, SectionHeader.Misc.VirtualSize, 1, OutFptr) != 1) { - Error (NULL, 0, 0, OutFileName, "failed to write .data section"); - goto Finish; - } - - Status = STATUS_SUCCESS; - goto Finish; - } - } - - Status = STATUS_ERROR; - -Finish: - if (InFptr != NULL) { - fclose (InFptr); - } - // - // Close the output file. If there was an error, delete the output file so - // that a subsequent build will rebuild it. - // - if (OutFptr != NULL) { - fclose (OutFptr); - if (GetUtilityStatus () == STATUS_ERROR) { - remove (OutFileName); - } - } - - // - // Free up our buffer - // - if (Buffer != NULL) { - free (Buffer); - } - - return Status; -} - -static -STATUS -CheckPE32File ( - INT8 *FileName, - FILE *Fptr, - UINT16 *MachineType, - UINT16 *SubSystem - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - FileName - GC_TODO: add argument description - Fptr - GC_TODO: add argument description - MachineType - GC_TODO: add argument description - SubSystem - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - /*++ - -Routine Description: - - Given a file pointer to a supposed PE32 image file, verify that it is indeed a - PE32 image file, and then return the machine type in the supplied pointer. - -Arguments: - - Fptr File pointer to the already-opened PE32 file - MachineType Location to stuff the machine type of the PE32 file. This is needed - because the image may be Itanium-based, IA32, or EBC. - -Returns: - - 0 success - non-zero otherwise - ---*/ - EFI_IMAGE_DOS_HEADER DosHeader; - EFI_IMAGE_FILE_HEADER FileHdr; - EFI_IMAGE_OPTIONAL_HEADER OptionalHdr; - UINT32 PESig; - STATUS Status; - - Status = STATUS_ERROR; - // - // Position to the start of the file - // - fseek (Fptr, 0, SEEK_SET); - // - // Read the DOS header - // - if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) { - Error (NULL, 0, 0, FileName, "failed to read the DOS stub from the input file"); - goto Finish; - } - // - // Check the magic number (0x5A4D) - // - if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) { - Error (NULL, 0, 0, FileName, "input file does not appear to be a PE32 image (magic number)"); - goto Finish; - } - // - // Position into the file and check the PE signature - // - fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET); - if (fread (&PESig, sizeof (PESig), 1, Fptr) != 1) { - Error (NULL, 0, 0, FileName, "failed to read PE signature bytes"); - goto Finish; - } - // - // Check the PE signature in the header "PE\0\0" - // - if (PESig != EFI_IMAGE_NT_SIGNATURE) { - Error (NULL, 0, 0, FileName, "file does not appear to be a PE32 image (signature)"); - goto Finish; - } - // - // Read the file header - // - if (fread (&FileHdr, sizeof (FileHdr), 1, Fptr) != 1) { - Error (NULL, 0, 0, FileName, "failed to read PE file header from input file"); - goto Finish; - } - // - // Read the optional header so we can get the subsystem - // - if (fread (&OptionalHdr, sizeof (OptionalHdr), 1, Fptr) != 1) { - Error (NULL, 0, 0, FileName, "failed to read COFF optional header from input file"); - goto Finish; - } - - *SubSystem = OptionalHdr.Subsystem; - // - // Good to go - // - Status = STATUS_SUCCESS; -Finish: - fseek (Fptr, 0, SEEK_SET); - return Status; -} - -static -int -ParseCommandLine ( - int Argc, - char *Argv[] - ) -/*++ - -Routine Description: - - Given the Argc/Argv program arguments, and a pointer to an options structure, - parse the command-line options and check their validity. - - -Arguments: - - Argc - standard C main() argument count - Argv - standard C main() argument list - -Returns: - - STATUS_SUCCESS success - non-zero otherwise - ---*/ -// GC_TODO: ] - add argument and description to function comment -{ - // - // Clear out the options - // - memset ((char *) &mOptions, 0, sizeof (mOptions)); - // - // Skip over the program name - // - Argc--; - Argv++; - - if (Argc != 2) { - Usage (); - return STATUS_ERROR; - } - - strcpy (mOptions.InFileName, Argv[0]); - // - // Next argument - // - Argv++; - Argc--; - - strcpy (mOptions.OutFileName, Argv[0]); - - return STATUS_SUCCESS; -} - -static -void -Usage ( - VOID - ) -/*++ - -Routine Description: - - Print usage information for this utility. - -Arguments: - - None. - -Returns: - - Nothing. - ---*/ -{ - int Index; - static const char *Msg[] = { - UTILITY_NAME " version "UTILITY_VERSION " - Generate ACPI Table image utility", - " Generate an ACPI Table image from an EFI PE32 image", - " Usage: "UTILITY_NAME " InFileName OutFileName", - " where:", - " InFileName - name of the input PE32 file", - " OutFileName - to write output to OutFileName rather than InFileName"DEFAULT_OUTPUT_EXTENSION, - "", - NULL - }; - for (Index = 0; Msg[Index] != NULL; Index++) { - fprintf (stdout, "%s\n", Msg[Index]); - } -} diff --git a/Tools/CodeTools/TianoTools/GenAcpiTable/build.xml b/Tools/CodeTools/TianoTools/GenAcpiTable/build.xml deleted file mode 100644 index 8c8c5eb81f..0000000000 --- a/Tools/CodeTools/TianoTools/GenAcpiTable/build.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/GenCRC32Section/GenCRC32Section.c b/Tools/CodeTools/TianoTools/GenCRC32Section/GenCRC32Section.c deleted file mode 100644 index b99cf2f816..0000000000 --- a/Tools/CodeTools/TianoTools/GenCRC32Section/GenCRC32Section.c +++ /dev/null @@ -1,286 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - GenCRC32Section.c - -Abstract: - - This file contains functions required to generate a Firmware File System - file. The code is compliant with the Tiano C Coding standards. - ---*/ - -#include "GenCRC32Section.h" - -#define TOOLVERSION "0.2" - -#define UTILITY_NAME "GenCrc32Section" - -EFI_GUID gEfiCrc32SectionGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID; - -EFI_STATUS -SignSectionWithCrc32 ( - IN OUT UINT8 *FileBuffer, - IN OUT UINT32 *BufferSize, - IN UINT32 DataSize - ) -/*++ - -Routine Description: - - Signs the section with CRC32 and add GUIDed section header for the - signed data. data stays in same location (overwrites source data). - -Arguments: - - FileBuffer - Buffer containing data to sign - - BufferSize - On input, the size of FileBuffer. On output, the size of - actual section data (including added section header). - - DataSize - Length of data to Sign - - Key - Key to use when signing. Currently only CRC32 is supported. - -Returns: - - EFI_SUCCESS - Successful - EFI_OUT_OF_RESOURCES - Not enough resource to complete the operation. - ---*/ -{ - - UINT32 Crc32Checksum; - EFI_STATUS Status; - UINT32 TotalSize; - CRC32_SECTION_HEADER Crc32Header; - UINT8 *SwapBuffer; - - Crc32Checksum = 0; - SwapBuffer = NULL; - - if (DataSize == 0) { - *BufferSize = 0; - - return EFI_SUCCESS; - } - - Status = CalculateCrc32 (FileBuffer, DataSize, &Crc32Checksum); - if (EFI_ERROR (Status)) { - return Status; - } - - TotalSize = DataSize + CRC32_SECTION_HEADER_SIZE; - Crc32Header.GuidSectionHeader.CommonHeader.Type = EFI_SECTION_GUID_DEFINED; - Crc32Header.GuidSectionHeader.CommonHeader.Size[0] = (UINT8) (TotalSize & 0xff); - Crc32Header.GuidSectionHeader.CommonHeader.Size[1] = (UINT8) ((TotalSize & 0xff00) >> 8); - Crc32Header.GuidSectionHeader.CommonHeader.Size[2] = (UINT8) ((TotalSize & 0xff0000) >> 16); - memcpy (&(Crc32Header.GuidSectionHeader.SectionDefinitionGuid), &gEfiCrc32SectionGuid, sizeof (EFI_GUID)); - Crc32Header.GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID; - Crc32Header.GuidSectionHeader.DataOffset = CRC32_SECTION_HEADER_SIZE; - Crc32Header.CRC32Checksum = Crc32Checksum; - - SwapBuffer = (UINT8 *) malloc (DataSize); - if (SwapBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - memcpy (SwapBuffer, FileBuffer, DataSize); - memcpy (FileBuffer, &Crc32Header, CRC32_SECTION_HEADER_SIZE); - memcpy (FileBuffer + CRC32_SECTION_HEADER_SIZE, SwapBuffer, DataSize); - - // - // Make sure section ends on a DWORD boundary - // - while ((TotalSize & 0x03) != 0) { - FileBuffer[TotalSize] = 0; - TotalSize++; - } - - *BufferSize = TotalSize; - - if (SwapBuffer != NULL) { - free (SwapBuffer); - } - - return EFI_SUCCESS; -} - -VOID -PrintUsage ( - VOID - ) -{ - printf ("Usage:\n"); - printf (UTILITY_NAME " -i \"inputfile1\" \"inputfile2\" -o \"outputfile\" \n"); - printf (" -i \"inputfile\":\n "); - printf (" specifies the input files that would be signed to CRC32 Guided section.\n"); - printf (" -o \"outputfile\":\n"); - printf (" specifies the output file that is a CRC32 Guided section.\n"); -} - -INT32 -ReadFilesContentsIntoBuffer ( - IN CHAR8 *argv[], - IN INT32 Start, - IN OUT UINT8 **FileBuffer, - IN OUT UINT32 *BufferSize, - OUT UINT32 *ContentSize, - IN INT32 MaximumArguments - ) -{ - INT32 Index; - CHAR8 *FileName; - FILE *InputFile; - UINT8 Temp; - UINT32 Size; - - FileName = NULL; - InputFile = NULL; - Size = 0; - Index = 0; - - // - // read all input files into one file buffer - // - while (argv[Start + Index][0] != '-') { - - FileName = argv[Start + Index]; - InputFile = fopen (FileName, "rb"); - if (InputFile == NULL) { - Error (NULL, 0, 0, FileName, "failed to open input binary file"); - return -1; - } - - fread (&Temp, sizeof (UINT8), 1, InputFile); - while (!feof (InputFile)) { - (*FileBuffer)[Size++] = Temp; - fread (&Temp, sizeof (UINT8), 1, InputFile); - } - - fclose (InputFile); - InputFile = NULL; - - // - // Make sure section ends on a DWORD boundary - // - while ((Size & 0x03) != 0) { - (*FileBuffer)[Size] = 0; - Size++; - } - - Index++; - if (Index == MaximumArguments) { - break; - } - } - - *ContentSize = Size; - return Index; -} - -int -main ( - INT32 argc, - CHAR8 *argv[] - ) -{ - FILE *OutputFile; - UINT8 *FileBuffer; - UINT32 BufferSize; - EFI_STATUS Status; - UINT32 ContentSize; - CHAR8 *OutputFileName; - INT32 ReturnValue; - INT32 Index; - - OutputFile = NULL; - FileBuffer = NULL; - ContentSize = 0; - OutputFileName = NULL; - - SetUtilityName (UTILITY_NAME); - - if (argc == 1) { - PrintUsage (); - return -1; - } - - BufferSize = 1024 * 1024 * 16; - FileBuffer = (UINT8 *) malloc (BufferSize * sizeof (UINT8)); - if (FileBuffer == NULL) { - Error (NULL, 0, 0, "memory allocation failed", NULL); - return -1; - } - - ZeroMem (FileBuffer, BufferSize); - - for (Index = 0; Index < argc; Index++) { - if (strcmpi (argv[Index], "-i") == 0) { - ReturnValue = ReadFilesContentsIntoBuffer ( - argv, - (Index + 1), - &FileBuffer, - &BufferSize, - &ContentSize, - (argc - (Index + 1)) - ); - if (ReturnValue == -1) { - Error (NULL, 0, 0, "failed to read file contents", NULL); - return -1; - } - - Index += ReturnValue; - } - - if (strcmpi (argv[Index], "-o") == 0) { - OutputFileName = argv[Index + 1]; - } - } - - OutputFile = fopen (OutputFileName, "wb"); - if (OutputFile == NULL) { - Error (NULL, 0, 0, OutputFileName, "failed to open output binary file"); - free (FileBuffer); - return -1; - } - - /* - // - // make sure section ends on a DWORD boundary ?? - // - while ( (Size & 0x03) != 0 ) { - FileBuffer[Size] = 0; - Size ++; - } -*/ - Status = SignSectionWithCrc32 (FileBuffer, &BufferSize, ContentSize); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "failed to sign section", NULL); - free (FileBuffer); - fclose (OutputFile); - return -1; - } - - ContentSize = fwrite (FileBuffer, sizeof (UINT8), BufferSize, OutputFile); - if (ContentSize != BufferSize) { - Error (NULL, 0, 0, "failed to write output buffer", NULL); - ReturnValue = -1; - } else { - ReturnValue = 0; - } - - free (FileBuffer); - fclose (OutputFile); - return ReturnValue; -} diff --git a/Tools/CodeTools/TianoTools/GenCRC32Section/GenCRC32Section.h b/Tools/CodeTools/TianoTools/GenCRC32Section/GenCRC32Section.h deleted file mode 100644 index 1cf976b065..0000000000 --- a/Tools/CodeTools/TianoTools/GenCRC32Section/GenCRC32Section.h +++ /dev/null @@ -1,63 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - GenCRC32Section.h - -Abstract: - - Header file for GenFfsFile. Mainly defines the header of section - header for CRC32 GUID defined sections. Share with GenSection.c - ---*/ - -// -// External Files Referenced -// - -/* Standard Headers */ -#include -#include -#include -#include - -/* MDE Headers */ -#include -#include -#include -#include -#include -#include - -/* Tool Headers */ -#include "CommonLib.h" -#include "Crc32.h" -#include "EfiCompress.h" -#include "EfiUtilityMsgs.h" -#include "ParseInf.h" - -// -// Module Coded to Tiano Coding Conventions -// -#ifndef _EFI_GEN_CRC32_SECTION_H -#define _EFI_GEN_CRC32_SECTION_H - - -typedef struct { - EFI_GUID_DEFINED_SECTION GuidSectionHeader; - UINT32 CRC32Checksum; -} CRC32_SECTION_HEADER; - -#define EFI_SECTION_CRC32_GUID_DEFINED 0 -#define CRC32_SECTION_HEADER_SIZE (sizeof (CRC32_SECTION_HEADER)) - -#endif diff --git a/Tools/CodeTools/TianoTools/GenCRC32Section/build.xml b/Tools/CodeTools/TianoTools/GenCRC32Section/build.xml deleted file mode 100644 index bbb0f71f5d..0000000000 --- a/Tools/CodeTools/TianoTools/GenCRC32Section/build.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/GenCapsuleHdr/CreateGuid.c b/Tools/CodeTools/TianoTools/GenCapsuleHdr/CreateGuid.c deleted file mode 100644 index 2a984fa70e..0000000000 --- a/Tools/CodeTools/TianoTools/GenCapsuleHdr/CreateGuid.c +++ /dev/null @@ -1,50 +0,0 @@ -/*++ - -Copyright (c) 2004-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -Module Name: - - CreateGuid.c - -Abstract: - - Library routine to create a GUID - ---*/ - -#include -#include -#include -#include -#include - -void -CreateGuid ( - GUID *Guid - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - Guid - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - CoCreateGuid (Guid); -} diff --git a/Tools/CodeTools/TianoTools/GenCapsuleHdr/GenCapsuleHdr.c b/Tools/CodeTools/TianoTools/GenCapsuleHdr/GenCapsuleHdr.c deleted file mode 100644 index d1f55b9abd..0000000000 --- a/Tools/CodeTools/TianoTools/GenCapsuleHdr/GenCapsuleHdr.c +++ /dev/null @@ -1,2674 +0,0 @@ -/*++ - -Copyright (c) 2002-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -Module Name: - - GenCapsuleHdr.c - -Abstract: - - Generate a capsule header for a file, and optionally prepend the - header to a file or list of files. - ---*/ - -#define _UNICODE - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include // for FV header GUID -#include -#include // for FV header GUID - -#include "CommonLib.h" -#include "EfiUtilityMsgs.h" - -#define MAX_PATH 256 -#define PROGRAM_NAME "GenCapsuleHdr" - -#define UNICODE_BACKSLASH L'\\' -#define UNICODE_FILE_START 0xFEFF -#define UNICODE_CR 0x000D -#define UNICODE_LF 0x000A -#define UNICODE_NULL 0x0000 -#define UNICODE_SPACE L' ' -#define UNICODE_SLASH L'/' -#define UNICODE_DOUBLE_QUOTE L'"' -#define UNICODE_A L'A' -#define UNICODE_F L'F' -#define UNICODE_Z L'Z' -#define UNICODE_a L'a' -#define UNICODE_f L'f' -#define UNICODE_z L'z' -#define UNICODE_0 L'0' -#define UNICODE_9 L'9' -#define UNICODE_TAB L'\t' - -#define OEM_HEADER_STRING L"OemHeader" -#define AUTHOR_INFO_STRING L"AuthorInfo" -#define REVISION_INFO_STRING L"RevisionInfo" -#define SHORT_DESCRIPTION_STRING L"ShortDescription" -#define LONG_DESCRIPTION_STRING L"LongDescription" -#define EQUAL_STRING L"=" -#define OPEN_BRACE_STRING L"{" -#define CLOSE_BRACE_STRING L"}" -#define GUID_STRING L"GUID" -#define DATA_STRING L"DATA" - -#if (EFI_SPECIFICATION_VERSION >= 0x00020000) -#define UEFI_CAPSULE_HEADER_NO_FALAGS 0 -#define UEFI_CAPSULE_HEADER_RESET_FALAGS CAPSULE_FLAGS_PERSIST_ACROSS_RESET -#define UEFI_CAPSULE_HEADER_ALL_FALAGS (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) -#endif - -typedef wchar_t WCHAR; - -typedef struct _FILE_LIST { - struct _FILE_LIST *Next; - INT8 FileName[MAX_PATH]; -} FILE_LIST; - -typedef struct _SIZE_LIST { - struct _SIZE_LIST *Next; - UINT32 Size; -} SIZE_LIST; - -typedef struct { - INT8 FileName[MAX_PATH]; - WCHAR *FileBuffer; - WCHAR *FileBufferPtr; - UINT32 FileSize; - FILE *FilePtr; - BOOLEAN EndOfFile; - UINT32 LineNum; -} SOURCE_FILE; - -// -// Here's all our globals. -// -static struct { - BOOLEAN Dump; - BOOLEAN Verbose; - BOOLEAN JoinMode; - INT8 ScriptFileName[MAX_PATH]; - INT8 OutputFileName[MAX_PATH]; - FILE_LIST *FileList; - FILE *OutFptr; - SIZE_LIST *SizeList; - SIZE_LIST *LastSize; - SIZE_LIST *CurrentSize; -} mOptions; - -static EFI_GUID mEfiCapsuleHeaderGuid = EFI_CAPSULE_GUID; - -void -CreateGuid ( - EFI_GUID *Guid - ); - -static -STATUS -ProcessArgs ( - int Argc, - char *Argv[] - ); - -static -void -SkipWhiteSpace ( - SOURCE_FILE *SourceFile - ); - -static -STATUS -GetHexValue ( - SOURCE_FILE *SourceFile, - UINT32 *Value, - UINT32 NumDigits - ); - -static -BOOLEAN -GetSplitFileName ( - INT8 *BaseFileName, - INT8 *NewFileName, - UINT32 SequenceNumber - ); - -static -STATUS -SplitCapsule ( - INT8 *CapsuleFileName - ); - -static -void -Usage ( - VOID - ); - -static -void -DumpCapsule ( - VOID - ); - -static -STATUS -JoinCapsule ( - VOID - ); - -static -STATUS -DumpCapsuleHeaderStrings ( - UINT8 *SectionName, - WCHAR *Buffer - ); - -static -STATUS -CheckFirmwareVolumeHeader ( - INT8 *FileName, - INT8 *Buffer, - UINT32 BufferSize - ); - -static -BOOLEAN -IsToken ( - SOURCE_FILE *File, - WCHAR *Token - ); - -static -BOOLEAN -GetNumber ( - INT8 *Str, - UINT32 *Value - ); - -static -STATUS -ProcessScriptFile ( - INT8 *ScriptFileName, - FILE *OutFptr, - EFI_CAPSULE_HEADER *CapsuleHeader - ); - -static -STATUS -ParseCapsuleInfo ( - SOURCE_FILE *SourceFile, - FILE *OutFptr, - WCHAR *SectionName - ); - -static -STATUS -CreateCapsule ( - VOID - ); - -static -STATUS -ParseOemInfo ( - SOURCE_FILE *SourceFile, - FILE *OutFptr - ); - -static -BOOLEAN -IsWhiteSpace ( - WCHAR Char - ); - -static -BOOLEAN -EndOfFile ( - SOURCE_FILE *File - ); - -int -main ( - int Argc, - char *Argv[] - ) -/*++ - -Routine Description: - Call the routine to process the command-line arguments, then - dispatch to the appropriate function. - -Arguments: - Standard C main() argc and argv. - -Returns: - 0 if successful - nonzero otherwise - ---*/ -// GC_TODO: Argc - add argument and description to function comment -// GC_TODO: ] - add argument and description to function comment -{ - STATUS Status; - FILE_LIST *NextFile; - // - // Specify our program name to the error printing routines. - // - SetUtilityName (PROGRAM_NAME); - // - // Process the command-line arguments - // - Status = ProcessArgs (Argc, Argv); - if (Status == STATUS_SUCCESS) { - if (mOptions.Dump) { - DumpCapsule (); - } else if (mOptions.JoinMode) { - JoinCapsule (); - } else { - CreateCapsule (); - } - } - // - // Cleanup - // - while (mOptions.FileList != NULL) { - NextFile = mOptions.FileList->Next; - free (mOptions.FileList); - mOptions.FileList = NextFile; - } - - while (mOptions.SizeList != NULL) { - mOptions.CurrentSize = mOptions.SizeList->Next; - free (mOptions.SizeList); - mOptions.SizeList = mOptions.CurrentSize; - } - - return GetUtilityStatus (); -} - -static -STATUS -CreateCapsule ( - VOID - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - None - -Returns: - - GC_TODO: add return values - ---*/ -{ - FILE *InFptr; - FILE_LIST *FileList; - INT8 *Buffer; - UINT32 Size; - EFI_CAPSULE_HEADER CapsuleHeader; - UINT8 Zero; - UINT8 FirstFile; - UINT32 CapsuleHeaderSize; - long InsertedBlockMapEntryOffset; - EFI_FV_BLOCK_MAP_ENTRY InsertedBlockMapEntry; - UINT64 FirmwareVolumeSize; - long FileSize; - EFI_FIRMWARE_VOLUME_HEADER FVHeader; - - Buffer = NULL; - InFptr = NULL; - FirmwareVolumeSize = 0; - CapsuleHeaderSize = 0; - InsertedBlockMapEntryOffset = 0; - memset (&InsertedBlockMapEntry, 0, sizeof (EFI_FV_BLOCK_MAP_ENTRY)); - memset (&FVHeader, 0, sizeof (EFI_FIRMWARE_VOLUME_HEADER)); - - if ((mOptions.OutFptr = fopen (mOptions.OutputFileName, "wb")) == NULL) { - Error (NULL, 0, 0, mOptions.OutputFileName, "failed to open output file for writing"); - return STATUS_ERROR; - } - - memset ((char *) &CapsuleHeader, 0, sizeof (CapsuleHeader)); - memcpy ((void *) &CapsuleHeader.CapsuleGuid, (void *) &mEfiCapsuleHeaderGuid, sizeof (EFI_GUID)); - CapsuleHeader.HeaderSize = sizeof (EFI_CAPSULE_HEADER); - CapsuleHeader.CapsuleImageSize = sizeof (EFI_CAPSULE_HEADER); - if (mOptions.ScriptFileName[0] != 0) { - if (ProcessScriptFile (mOptions.ScriptFileName, mOptions.OutFptr, &CapsuleHeader) != STATUS_SUCCESS) { - goto Done; - } - } else { - // - // Insert a default capsule header -#if (EFI_SPECIFICATION_VERSION >= 0x00020000) - CapsuleHeader.HeaderSize = sizeof (EFI_CAPSULE_HEADER); - CapsuleHeader.Flags = UEFI_CAPSULE_HEADER_ALL_FALAGS; -#endif - CapsuleHeader.OffsetToCapsuleBody = sizeof (EFI_CAPSULE_HEADER); - - if (fwrite ((void *) &CapsuleHeader, sizeof (CapsuleHeader), 1, mOptions.OutFptr) != 1) { - Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file"); - goto Done; - } - } - - CapsuleHeaderSize = CapsuleHeader.OffsetToCapsuleBody; - // - // Now copy the contents of any other files specified on the command - // line to the output file. Files must be FFS files, which are aligned - // on 8-byte boundaries. Don't align the first file, since it's the start - // of the image once the capsule header has been removed. - // - FileList = mOptions.FileList; - FirstFile = 1; - Zero = 0; - while (FileList != NULL) { - if ((InFptr = fopen (FileList->FileName, "rb")) == NULL) { - Error (NULL, 0, 0, FileList->FileName, "failed to open file for reading"); - goto Done; - } - // - // Allocate a buffer into which we can read the file. - // - fseek (InFptr, 0, SEEK_END); - Size = ftell (InFptr); - rewind (InFptr); - Buffer = (char *) malloc (Size); - if (Buffer == NULL) { - Error (__FILE__, __LINE__, 0, FileList->FileName, "failed to allocate buffer to read file into"); - goto Done; - } - - if (fread ((void *) Buffer, Size, 1, InFptr) != 1) { - Error (NULL, 0, 0, FileList->FileName, "failed to read file contents"); - goto Done; - } - - if (Size > 0) { - // - // Align the write of the first bytes from the file if not the first file - // - if (FirstFile) { - // - // First file must be a firmware volume. Double-check, and then insert - // an additional block map entry so we can add more files from the command line - // - if (CheckFirmwareVolumeHeader (FileList->FileName, Buffer, Size) != STATUS_SUCCESS) { - goto Done; - } - // - // Save a copy of the firmware volume header for later - // - memcpy (&FVHeader, Buffer, sizeof (EFI_FIRMWARE_VOLUME_HEADER)); - FirmwareVolumeSize = FVHeader.FvLength; - if (FileList->Next != NULL) { - // - // Copy the firmware volume header - // - InsertedBlockMapEntryOffset = CapsuleHeaderSize + FVHeader.HeaderLength; - if (fwrite (Buffer, FVHeader.HeaderLength, 1, mOptions.OutFptr) != 1) { - Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file"); - goto Done; - } - - if (fwrite (&InsertedBlockMapEntry, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, mOptions.OutFptr) != 1) { - Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file"); - goto Done; - } - - if (fwrite ( - Buffer + FVHeader.HeaderLength, - Size - FVHeader.HeaderLength, - 1, - mOptions.OutFptr - ) != 1) { - Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file"); - goto Done; - } - } else { - // - // Copy the file contents as-is - // - if (fwrite ((void *) Buffer, Size, 1, mOptions.OutFptr) != 1) { - Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file"); - goto Done; - } - } - } else { - while ((ftell (mOptions.OutFptr) - CapsuleHeaderSize) & 0x07) { - if (fwrite ((void *) &Zero, 1, 1, mOptions.OutFptr) != 1) { - Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file"); - goto Done; - } - } - - if (fwrite ((void *) Buffer, Size, 1, mOptions.OutFptr) != 1) { - Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file"); - goto Done; - } - } - - FirstFile = 0; - } - - free (Buffer); - Buffer = NULL; - fclose (InFptr); - InFptr = NULL; - FileList = FileList->Next; - } - -Done: - if (Buffer != NULL) { - free (Buffer); - } - - if (InFptr != NULL) { - fclose (InFptr); - } - // - // If we inserted an additional block map entry, then fix it up. Fix up the - // FV header as well to reflect our new size. - // - if (InsertedBlockMapEntryOffset != 0) { - FileSize = ftell (mOptions.OutFptr); - InsertedBlockMapEntry.NumBlocks = 1; - InsertedBlockMapEntry.BlockLength = (UINT32) ((UINT64) FileSize - (UINT64) CapsuleHeaderSize - FirmwareVolumeSize - sizeof (EFI_FV_BLOCK_MAP_ENTRY)); - fseek (mOptions.OutFptr, InsertedBlockMapEntryOffset, SEEK_SET); - fwrite (&InsertedBlockMapEntry, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, mOptions.OutFptr); - // - // Fix up the firmware volume header and write it out - // - fseek (mOptions.OutFptr, CapsuleHeaderSize, SEEK_SET); - FVHeader.FvLength = FileSize - CapsuleHeaderSize; - FVHeader.HeaderLength += sizeof (EFI_FV_BLOCK_MAP_ENTRY); - fwrite (&FVHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, mOptions.OutFptr); - // - // Reposition to the end of the file - // - } - // - // Close files and free the global string lists we allocated memory for - // - if (mOptions.OutFptr != NULL) { - // - // We should now know the full capsule image size. Update the header and write it again. - // - fseek (mOptions.OutFptr, 0, SEEK_END); - Size = ftell (mOptions.OutFptr); - CapsuleHeader.CapsuleImageSize = Size; - fseek (mOptions.OutFptr, 0, SEEK_SET); - if (fwrite ((void *) &CapsuleHeader, sizeof (CapsuleHeader), 1, mOptions.OutFptr) != 1) { - Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file"); - } - - fseek (mOptions.OutFptr, 0, SEEK_END); - fclose (mOptions.OutFptr); - mOptions.OutFptr = NULL; - } - // - // If they are doing split capsule output, then split it up now. - // - if ((mOptions.Dump == 0) && (GetUtilityStatus () == STATUS_SUCCESS) && (mOptions.SizeList != NULL)) { - SplitCapsule (mOptions.OutputFileName); - } - - return STATUS_SUCCESS; -} - -static -STATUS -ProcessScriptFile ( - INT8 *ScriptFileName, - FILE *OutFptr, - EFI_CAPSULE_HEADER *CapsuleHeader - ) -/*++ - -Routine Description: - Parse a capsule header script file. - -Arguments: - ScriptFileName - name of script file to parse - OutFptr - output to dump binary data - CapsuleHeader - capsule header to update with size info - of parsed fields in the script file - -Returns: - STATUS_SUCCESS - if all went well - ---*/ -{ -#if 0 - STATUS Status; - SOURCE_FILE SourceFile; - WCHAR *WScriptFileName; - BOOLEAN InComment; - - if (fwrite (CapsuleHeader, sizeof (EFI_CAPSULE_HEADER), 1, OutFptr) != 1) { - Error (NULL, 0, 0, "failed to write capsule header to output file", NULL); - return STATUS_ERROR; - } - - memset (&SourceFile, 0, sizeof (SOURCE_FILE)); - strcpy (SourceFile.FileName, ScriptFileName); - - Status = STATUS_ERROR; - // - // Open the input unicode script file and read it into a buffer - // - WScriptFileName = (WCHAR *) malloc ((strlen (ScriptFileName) + 1) * sizeof (WCHAR)); - if (WScriptFileName == NULL) { - Error (__FILE__, __LINE__, 0, "failed to allocate memory", NULL); - return STATUS_ERROR; - } - - swprintf (WScriptFileName, L"%S", ScriptFileName); - if ((SourceFile.FilePtr = _wfopen (WScriptFileName, L"r")) == NULL) { - free (WScriptFileName); - Error (NULL, 0, 0, ScriptFileName, "failed to open script file for reading"); - goto Done; - } - - free (WScriptFileName); - fseek (SourceFile.FilePtr, 0, SEEK_END); - SourceFile.FileSize = ftell (SourceFile.FilePtr); - rewind (SourceFile.FilePtr); - SourceFile.FileBuffer = (WCHAR *) malloc (SourceFile.FileSize + sizeof (WCHAR)); - if (SourceFile.FileBuffer == NULL) { - Error (__FILE__, __LINE__, 0, ScriptFileName, "failed to allocate memory to read in file contents"); - goto Done; - } - - if (fread (SourceFile.FileBuffer, SourceFile.FileSize, 1, SourceFile.FilePtr) != 1) { - Error (NULL, 0, 0, ScriptFileName, "failed to read file contents"); - goto Done; - } - - SourceFile.FileBufferPtr = SourceFile.FileBuffer; - SourceFile.LineNum = 1; - if (SourceFile.FileBuffer[0] != UNICODE_FILE_START) { - Error (ScriptFileName, 1, 0, "file does not appear to be a unicode file", NULL); - goto Done; - } - - SourceFile.FileBufferPtr++; - SourceFile.FileBuffer[SourceFile.FileSize / sizeof (WCHAR)] = 0; - // - // Walk the source file buffer and replace all carriage returns with 0 so - // we can print from the file contents on parse errors. - // - InComment = 0; - while (!EndOfFile (&SourceFile)) { - if (SourceFile.FileBufferPtr[0] == UNICODE_CR) { - SourceFile.FileBufferPtr[0] = 0; - InComment = 0; - } else if (SourceFile.FileBufferPtr[0] == UNICODE_LF) { - InComment = 0; - } else if (InComment) { - SourceFile.FileBufferPtr[0] = UNICODE_SPACE; - } else if ((SourceFile.FileBufferPtr[0] == UNICODE_SLASH) && (SourceFile.FileBufferPtr[1] == UNICODE_SLASH)) { - InComment = 1; - SourceFile.FileBufferPtr[0] = UNICODE_SPACE; - } - - SourceFile.FileBufferPtr++; - } - // - // Reposition to the start of the file, but skip over the unicode file start - // - SourceFile.FileBufferPtr = SourceFile.FileBuffer; - SourceFile.FileBufferPtr++; - SourceFile.EndOfFile = 0; - CapsuleHeader->OffsetToOemDefinedHeader = ftell (OutFptr); - // - // Parse the OEM bytes - // - if (ParseOemInfo (&SourceFile, OutFptr) != STATUS_SUCCESS) { - goto Done; - } - // - // Parse the author information - // - CapsuleHeader->OffsetToAuthorInformation = ftell (OutFptr); - if (ParseCapsuleInfo (&SourceFile, OutFptr, AUTHOR_INFO_STRING) != STATUS_SUCCESS) { - goto Done; - } - // - // Parse the revision information - // - CapsuleHeader->OffsetToRevisionInformation = ftell (OutFptr); - if (ParseCapsuleInfo (&SourceFile, OutFptr, REVISION_INFO_STRING) != STATUS_SUCCESS) { - goto Done; - } - // - // Parse the short description - // - CapsuleHeader->OffsetToShortDescription = ftell (OutFptr); - if (ParseCapsuleInfo (&SourceFile, OutFptr, SHORT_DESCRIPTION_STRING) != STATUS_SUCCESS) { - goto Done; - } - // - // Parse the long description - // - CapsuleHeader->OffsetToLongDescription = ftell (OutFptr); - if (ParseCapsuleInfo (&SourceFile, OutFptr, LONG_DESCRIPTION_STRING) != STATUS_SUCCESS) { - goto Done; - } - // - // Better be end of contents - // - SkipWhiteSpace (&SourceFile); - if (!EndOfFile (&SourceFile)) { - Error (ScriptFileName, SourceFile.LineNum, 0, NULL, "expected end-of-file, not %.20S", SourceFile.FileBufferPtr); - goto Done; - } - - CapsuleHeader->OffsetToCapsuleBody = ftell (OutFptr); - rewind (OutFptr); - fwrite (CapsuleHeader, sizeof (EFI_CAPSULE_HEADER), 1, OutFptr); - fseek (OutFptr, 0, SEEK_END); - Status = STATUS_SUCCESS; -Done: - if (SourceFile.FilePtr != NULL) { - fclose (SourceFile.FilePtr); - } - - if (SourceFile.FileBuffer != NULL) { - free (SourceFile.FileBuffer); - } - - return Status; - -#endif - return STATUS_SUCCESS; -} -// -// Parse the OEM data of format: -// OemInfo { -// GUID = 12345676-1234-1234-123456789ABC -// DATA = 0x01, 0x02, 0x03... -// } -// -static -STATUS -ParseOemInfo ( - SOURCE_FILE *SourceFile, - FILE *OutFptr - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - SourceFile - GC_TODO: add argument description - OutFptr - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - long OemHeaderOffset; - UINT32 Data; - EFI_CAPSULE_OEM_HEADER OemHeader; - STATUS Status; - UINT32 DigitCount; - WCHAR *SaveFilePos; - UINT8 ByteData; - - Status = STATUS_ERROR; - memset (&OemHeader, 0, sizeof (EFI_CAPSULE_OEM_HEADER)); - OemHeaderOffset = ftell (OutFptr); - OemHeader.HeaderSize = sizeof (EFI_CAPSULE_OEM_HEADER); - if (fwrite (&OemHeader, sizeof (EFI_CAPSULE_OEM_HEADER), 1, OutFptr) != 1) { - Error (NULL, 0, 0, "failed to write OEM header to output file", NULL); - goto Done; - } - - if (!IsToken (SourceFile, OEM_HEADER_STRING)) { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - NULL, - "expected %S, not %.20S", - OEM_HEADER_STRING, - SourceFile->FileBufferPtr - ); - goto Done; - } - - if (!IsToken (SourceFile, EQUAL_STRING)) { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - NULL, - "expected %S, not %.20S", - EQUAL_STRING, - SourceFile->FileBufferPtr - ); - goto Done; - } - - if (!IsToken (SourceFile, OPEN_BRACE_STRING)) { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - NULL, - "expected %S, not %.20S", - OPEN_BRACE_STRING, - SourceFile->FileBufferPtr - ); - goto Done; - } - // - // Look for: GUID = xxxxxxx-xxxx-xxxx-xxxxxxxxxxxxx - // - if (!IsToken (SourceFile, GUID_STRING)) { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - NULL, - "expected %S, not %.20S", - GUID_STRING, - SourceFile->FileBufferPtr - ); - goto Done; - } - - if (!IsToken (SourceFile, EQUAL_STRING)) { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - NULL, - "expected %S, not %.20S", - EQUAL_STRING, - SourceFile->FileBufferPtr - ); - goto Done; - } - // - // Parse the xxxxxxxx-xxxx-xxxx-xxxx portion of the GUID - // - SkipWhiteSpace (SourceFile); - if (GetHexValue (SourceFile, &Data, 8) != STATUS_SUCCESS) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid GUID", NULL); - goto Done; - } - - OemHeader.OemGuid.Data1 = Data; - if (!IsToken (SourceFile, L"-")) { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - NULL, - "expected dash in GUID, not %S", - SourceFile->FileBufferPtr - ); - goto Done; - } - // - // Get 3 word values - // - for (DigitCount = 0; DigitCount < 3; DigitCount++) { - if (GetHexValue (SourceFile, &Data, 4) != STATUS_SUCCESS) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid GUID", NULL); - goto Done; - } - - switch (DigitCount) { - case 0: - OemHeader.OemGuid.Data2 = (UINT16) Data; - break; - - case 1: - OemHeader.OemGuid.Data3 = (UINT16) Data; - break; - - case 2: - OemHeader.OemGuid.Data4[1] = (UINT8) Data; - OemHeader.OemGuid.Data4[0] = (UINT8) (Data >> 8); - break; - } - - if (!IsToken (SourceFile, L"-")) { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - NULL, - "expected dash in GUID, not %S", - SourceFile->FileBufferPtr - ); - goto Done; - } - } - // - // Pick up the last 6 bytes of the GUID - // - SaveFilePos = SourceFile->FileBufferPtr; - for (DigitCount = 0; DigitCount < 6; DigitCount++) { - if (GetHexValue (SourceFile, &Data, 2) != STATUS_SUCCESS) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid GUID", NULL); - goto Done; - } - - OemHeader.OemGuid.Data4[DigitCount + 2] = (UINT8) Data; - } - // - // Now read raw OEM data bytes. May or may not be present. - // DATA = 0x01, 0x02, 0x02... - // - if (IsToken (SourceFile, CLOSE_BRACE_STRING)) { - Status = STATUS_SUCCESS; - goto Done; - } - - if (!IsToken (SourceFile, DATA_STRING)) { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - NULL, - "expected %S, not %.20S", - DATA_STRING, - SourceFile->FileBufferPtr - ); - goto Done; - } - - if (!IsToken (SourceFile, EQUAL_STRING)) { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - NULL, - "expected %S, not %.20S", - EQUAL_STRING, - SourceFile->FileBufferPtr - ); - goto Done; - } - - while (!EndOfFile (SourceFile)) { - if (IsToken (SourceFile, CLOSE_BRACE_STRING)) { - Status = STATUS_SUCCESS; - goto Done; - } - - if (IsToken (SourceFile, L"0x")) { - if (swscanf (SourceFile->FileBufferPtr, L"%x", &Data) != 1) { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - NULL, - "expected hex byte value, not %.20S", - SourceFile->FileBufferPtr - ); - goto Done; - } - - if (Data &~0xFF) { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - NULL, - "expected byte hex byte value at %.20S", - SourceFile->FileBufferPtr - ); - goto Done; - } - // - // Skip over the hex digits, then write the data - // - while (iswxdigit (SourceFile->FileBufferPtr[0])) { - SourceFile->FileBufferPtr++; - } - - ByteData = (UINT8) Data; - if (fwrite (&ByteData, 1, 1, OutFptr) != 1) { - Error (NULL, 0, 0, "failed to write OEM data to output file", NULL); - goto Done; - } - - OemHeader.HeaderSize++; - // - // Optional comma - // - IsToken (SourceFile, L","); - } else { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - NULL, - "expected hex OEM data, not %.20S", - SourceFile->FileBufferPtr - ); - goto Done; - } - } - - if (EndOfFile (SourceFile)) { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - NULL, - "expected %S close to OEM header data", - CLOSE_BRACE_STRING - ); - goto Done; - } - - Status = STATUS_SUCCESS; -Done: - // - // re-write the oem header if no errors - // - if (Status == STATUS_SUCCESS) { - fseek (OutFptr, OemHeaderOffset, SEEK_SET); - if (fwrite (&OemHeader, sizeof (EFI_CAPSULE_OEM_HEADER), 1, OutFptr) != 1) { - Error (NULL, 0, 0, "failed to write OEM header to output file", NULL); - goto Done; - } - - fseek (OutFptr, 0, SEEK_END); - } - - return Status; -} - -static -STATUS -ParseCapsuleInfo ( - SOURCE_FILE *SourceFile, - FILE *OutFptr, - WCHAR *SectionName - ) -// GC_TODO: function comment should start with '/*++' -// -// GC_TODO: function comment is missing 'Routine Description:' -// GC_TODO: function comment is missing 'Arguments:' -// GC_TODO: function comment is missing 'Returns:' -// GC_TODO: SourceFile - add argument and description to function comment -// GC_TODO: OutFptr - add argument and description to function comment -// GC_TODO: SectionName - add argument and description to function comment -// Parse: eng "string " "parts" -// spa "string " "parts" -// Write out: "eng string parts\0spa string parts\0\0 -// -{ - STATUS Status; - int StringCount; - WCHAR Zero; - WCHAR Spacebar; - - Status = STATUS_ERROR; - Zero = 0; - Spacebar = UNICODE_SPACE; - - if (!IsToken (SourceFile, SectionName)) { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - NULL, - "expected %S, not %.20S", - SectionName, - SourceFile->FileBufferPtr - ); - goto Done; - } - - if (!IsToken (SourceFile, EQUAL_STRING)) { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - NULL, - "expected %S, not %.20S", - EQUAL_STRING, - SourceFile->FileBufferPtr - ); - goto Done; - } - - if (!IsToken (SourceFile, OPEN_BRACE_STRING)) { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - NULL, - "expected %S, not %.20S", - OPEN_BRACE_STRING, - SourceFile->FileBufferPtr - ); - goto Done; - } - - while (!EndOfFile (SourceFile)) { - if (IsToken (SourceFile, CLOSE_BRACE_STRING)) { - break; - } - // - // Look for language identifier (3 lowercase chars) - // - if ((SourceFile->FileBufferPtr[0] >= UNICODE_a) && - (SourceFile->FileBufferPtr[0] <= UNICODE_z) && - (SourceFile->FileBufferPtr[1] >= UNICODE_a) && - (SourceFile->FileBufferPtr[1] <= UNICODE_z) && - (SourceFile->FileBufferPtr[2] >= UNICODE_a) && - (SourceFile->FileBufferPtr[2] <= UNICODE_z) && - IsWhiteSpace (SourceFile->FileBufferPtr[3]) - ) { - // - // Write the 3 chars followed by a spacebar, and then look for opening quote - // - fwrite (SourceFile->FileBufferPtr, sizeof (WCHAR), 1, OutFptr); - SourceFile->FileBufferPtr++; - fwrite (SourceFile->FileBufferPtr, sizeof (WCHAR), 1, OutFptr); - SourceFile->FileBufferPtr++; - fwrite (SourceFile->FileBufferPtr, sizeof (WCHAR), 1, OutFptr); - SourceFile->FileBufferPtr++; - fwrite (&Spacebar, sizeof (WCHAR), 1, OutFptr); - StringCount = 0; - while (IsToken (SourceFile, L"\"")) { - StringCount++; - while (!EndOfFile (SourceFile)) { - if (SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) { - SourceFile->FileBufferPtr++; - break; - } else if ((SourceFile->FileBufferPtr[0] == UNICODE_LF) || (SourceFile->FileBufferPtr[0] == 0)) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing quote on string", NULL); - goto Done; - } else { - fwrite (SourceFile->FileBufferPtr, sizeof (WCHAR), 1, OutFptr); - SourceFile->FileBufferPtr++; - } - } - } - - if (StringCount == 0) { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - NULL, - "expected quoted string, not %.20S", - SourceFile->FileBufferPtr - ); - goto Done; - } - // - // This string's null terminator - // - fwrite (&Zero, sizeof (WCHAR), 1, OutFptr); - } else { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - NULL, - "expected valid language identifer, not %.20S", - SourceFile->FileBufferPtr - ); - goto Done; - } - } - // - // Double null terminator - // - fwrite (&Zero, sizeof (WCHAR), 1, OutFptr); - Status = STATUS_SUCCESS; -Done: - return Status; -} - -static -STATUS -SplitCapsule ( - INT8 *CapsuleFileName - ) -/*++ - -Routine Description: - We've created an entire capsule image. Now split it up into the - size pieces they requested. - -Arguments: - CapsuleFileName - name of an existing capsule file on disk - -Returns: - STATUS_SUCCESS - if no problems - -Notes: - This implementation reads in the entire capsule image from - disk, then overwrites the original file with the first - in the series. - ---*/ -{ -#if 0 - EFI_CAPSULE_HEADER *CapHdr; - - EFI_CAPSULE_HEADER Hdr; - FILE *CapFptr; - FILE *OutFptr; - UINT32 SizeLeft; - UINT32 CurrentSize; - UINT32 DataSize; - UINT32 SequenceNumber; - INT8 *Buffer; - INT8 FileName[MAX_PATH]; - STATUS Status; - UINT32 FileSize; - // - // Figure out the total size, then rewind the input file and - // read the entire thing in - // - if ((CapFptr = fopen (CapsuleFileName, "rb")) == NULL) { - Error (NULL, 0, 0, CapsuleFileName, "failed to open capsule image for reading"); - return STATUS_ERROR; - } - - OutFptr = NULL; - Status = STATUS_SUCCESS; - fseek (CapFptr, 0, SEEK_END); - SizeLeft = ftell (CapFptr); - fseek (CapFptr, 0, SEEK_SET); - CapHdr = (EFI_CAPSULE_HEADER *) malloc (SizeLeft); - if (CapHdr == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - goto FailDone; - } - - if (fread (CapHdr, SizeLeft, 1, CapFptr) != 1) { - Error (NULL, 0, 0, "failed to read capsule contents", "split failed"); - goto FailDone; - } - - fclose (CapFptr); - CapFptr = NULL; - // - // Get a GUID to fill in the InstanceId GUID in the header - // - CreateGuid (&CapHdr->InstanceId); - SequenceNumber = 0; - // - // If the split size is larger than the original capsule image, then - // we're done. - // - if (mOptions.SizeList->Size >= SizeLeft) { - mOptions.SizeList->Size = SizeLeft; - goto Done; - } - // - // First size has to be big enough for the original header - // - if (mOptions.SizeList->Size < CapHdr->OffsetToCapsuleBody) { - Error (NULL, 0, 0, "first split size is insufficient for the original capsule header", NULL); - goto FailDone; - } - // - // Initialize the header we'll use on all but the first part - // - memset (&Hdr, 0, sizeof (Hdr)); - Hdr.CapsuleGuid = CapHdr->CapsuleGuid; - Hdr.HeaderSize = sizeof (Hdr); - Hdr.Flags = CapHdr->Flags; - Hdr.InstanceId = CapHdr->InstanceId; - Hdr.CapsuleImageSize = CapHdr->CapsuleImageSize; - Hdr.OffsetToCapsuleBody = Hdr.HeaderSize; - Hdr.SequenceNumber = 1; - // - // printf ("Created %s - 0x%X bytes\n", CapsuleFileName, mOptions.SizeList->Size); - // - Buffer = (UINT8 *) CapHdr; - // - // Walk the list of sizes and write out a capsule header, and - // then the raw capsule data. - // - // SizeLeft -= mOptions.SizeList->Size; - // - mOptions.CurrentSize = mOptions.SizeList; - while (SizeLeft) { - CurrentSize = mOptions.CurrentSize->Size; - GetSplitFileName (mOptions.OutputFileName, FileName, SequenceNumber); - if ((OutFptr = fopen (FileName, "wb")) == NULL) { - Error (NULL, 0, 0, FileName, "failed to open split file for writing"); - goto FailDone; - } - - if (Buffer == (UINT8 *) CapHdr) { - // - // First part -- write out original header and data - // - if (fwrite (Buffer, CurrentSize, 1, OutFptr) != 1) { - Error (NULL, 0, 0, FileName, "failed to write to split image file"); - goto FailDone; - } - - SizeLeft -= CurrentSize; - Buffer += CurrentSize; - DataSize = CurrentSize; - FileSize = CurrentSize; - } else { - // - // Not the first part. Write the default header, and then the raw bytes from the - // original image. - // - if (CurrentSize <= sizeof (Hdr)) { - Error (NULL, 0, 0, "split size too small for capsule header + data", "0x%X", CurrentSize); - goto FailDone; - } - - DataSize = CurrentSize - sizeof (Hdr); - if (DataSize > SizeLeft) { - DataSize = SizeLeft; - } - - if (fwrite (&Hdr, sizeof (Hdr), 1, OutFptr) != 1) { - Error (NULL, 0, 0, FileName, "failed to write capsule header to output file"); - fclose (OutFptr); - goto FailDone; - } - - if (fwrite (Buffer, DataSize, 1, OutFptr) != 1) { - Error (NULL, 0, 0, FileName, "failed to write capsule data to output file"); - fclose (OutFptr); - goto FailDone; - } - - Hdr.SequenceNumber++; - Buffer += DataSize; - SizeLeft -= DataSize; - FileSize = DataSize + sizeof (Hdr); - } - // - // Next size in list if there is one - // - if (mOptions.CurrentSize->Next != NULL) { - mOptions.CurrentSize = mOptions.CurrentSize->Next; - } - - SequenceNumber++; - fclose (OutFptr); - OutFptr = NULL; - printf ("Created %s - 0x%X bytes (0x%X bytes of data)\n", FileName, FileSize, DataSize); - } - - goto Done; -FailDone: - Status = STATUS_ERROR; -Done: - if (CapHdr != NULL) { - free (CapHdr); - } - - if (CapFptr != NULL) { - fclose (CapFptr); - } - - if (OutFptr != NULL) { - fclose (OutFptr); - } - - return Status; - -#endif - return STATUS_SUCCESS; -} - -static -BOOLEAN -GetSplitFileName ( - INT8 *BaseFileName, - INT8 *NewFileName, - UINT32 SequenceNumber - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - BaseFileName - GC_TODO: add argument description - NewFileName - GC_TODO: add argument description - SequenceNumber - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - /*++ - -Routine Description: - Given an initial split capsule file name and a sequence number, - create an appropriate file name for this split of a capsule image. - -Arguments: - BaseFileName - name of of the first split file in the series - NewFileName - output name of the split file - SequenceNumber - 0-based sequence number of split images - -Returns: - TRUE - name created successfully - FALSE - otherwise - ---*/ - INT8 *Ptr; - INT8 *Part2Start; - UINT32 Digits; - UINT32 Len; - UINT32 BaseOffset; - // - // Work back from the end of the file name and see if there is a number somewhere - // - for (Ptr = BaseFileName + strlen (BaseFileName) - 1; (Ptr > BaseFileName) && !isdigit (*Ptr); Ptr--) - ; - if ((Ptr == BaseFileName) && (!isdigit (*Ptr))) { - // - // Found no number, so just add it to the end - // - sprintf (NewFileName, "%s%d", BaseFileName, SequenceNumber); - return TRUE; - } else { - // - // Found a number. Look back to find the first digit. - // - Part2Start = Ptr + 1; - for (Digits = 1; isdigit (*Ptr) && (Ptr > BaseFileName); Ptr--, Digits++) - ; - if (!isdigit (*Ptr)) { - Ptr++; - Digits--; - } - - BaseOffset = atoi (Ptr); - SequenceNumber = SequenceNumber + BaseOffset; - if (Digits > 1) { - // - // Copy the first part of the original file name to the new filename - // This is the path for filenames with format path\name001.cap - // - Len = (UINT32) Ptr - (UINT32) BaseFileName; - strncpy (NewFileName, BaseFileName, Len); - sprintf (NewFileName + Len, "%0*d", Digits, SequenceNumber); - strcat (NewFileName, Part2Start); - return TRUE; - } else { - // - // Only one digit found. This is the path for filenames with - // format path\name1.cap - // - Len = (UINT32) Ptr - (UINT32) BaseFileName + 1; - strncpy (NewFileName, BaseFileName, Len); - sprintf (NewFileName + Len - 1, "%d", SequenceNumber); - strcat (NewFileName, Part2Start); - return TRUE; - } - } -} - -static -BOOLEAN -IsWhiteSpace ( - WCHAR Char - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - Char - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - switch (Char) { - case UNICODE_SPACE: - case UNICODE_TAB: - case UNICODE_NULL: - case UNICODE_CR: - case UNICODE_LF: - return TRUE; - - default: - return FALSE; - } -} - -static -BOOLEAN -IsToken ( - SOURCE_FILE *File, - WCHAR *Token - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - File - GC_TODO: add argument description - Token - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - SkipWhiteSpace (File); - if (EndOfFile (File)) { - return FALSE; - } - - if (wcsncmp (Token, File->FileBufferPtr, wcslen (Token)) == 0) { - File->FileBufferPtr += wcslen (Token); - return TRUE; - } - - return FALSE; -} - -static -STATUS -CheckFirmwareVolumeHeader ( - INT8 *FileName, - INT8 *Buffer, - UINT32 BufferSize - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - FileName - GC_TODO: add argument description - Buffer - GC_TODO: add argument description - BufferSize - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - EFI_FIRMWARE_VOLUME_HEADER *Hdr; - EFI_GUID FVHeaderGuid = EFI_FIRMWARE_FILE_SYSTEM_GUID; - - Hdr = (EFI_FIRMWARE_VOLUME_HEADER *) Buffer; - if (Hdr->Signature != EFI_FVH_SIGNATURE) { - Error (NULL, 0, 0, FileName, "file does not appear to be a firmware volume (bad signature)"); - return STATUS_ERROR; - } - - if (Hdr->Revision != EFI_FVH_REVISION) { - Error (NULL, 0, 0, FileName, "unsupported firmware volume header version"); - return STATUS_ERROR; - } - - if (Hdr->FvLength > BufferSize) { - Error (NULL, 0, 0, FileName, "malformed firmware volume -- FvLength > file size"); - return STATUS_ERROR; - } - - if (memcmp (&Hdr->FileSystemGuid, &FVHeaderGuid, sizeof (EFI_GUID)) != 0) { - Error (NULL, 0, 0, FileName, "invalid FFS GUID in firmware volume header"); - return STATUS_ERROR; - } - - return STATUS_SUCCESS; -} - -static -void -DumpCapsule ( - VOID - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - None - -Returns: - - GC_TODO: add return values - ---*/ -{ -#if 0 - FILE *InFptr; - FILE_LIST *FileList; - EFI_CAPSULE_HEADER CapsuleHeader; - EFI_FIRMWARE_VOLUME_HEADER FVHeader; - EFI_CAPSULE_OEM_HEADER *OemHeader; - UINT8 *BPtr; - UINT32 FileSize; - UINT32 CapsuleHeaderDataSize; - UINT8 ByteCount; - UINT8 *CapsuleHeaderData; - BOOLEAN SplitImage; - - InFptr = NULL; - CapsuleHeaderData = NULL; - FileList = mOptions.FileList; - while (FileList != NULL) { - if ((InFptr = fopen (FileList->FileName, "rb")) == NULL) { - Error (NULL, 0, 0, FileList->FileName, "failed to open file for reading"); - goto Done; - } - - if (fread (&CapsuleHeader, sizeof (EFI_CAPSULE_HEADER), 1, InFptr) != 1) { - Error (NULL, 0, 0, FileList->FileName, "failed to read capsule header"); - goto Done; - } - - fseek (InFptr, 0, SEEK_END); - FileSize = ftell (InFptr); - if (CapsuleHeader.CapsuleImageSize > FileSize) { - SplitImage = TRUE; - } else { - SplitImage = FALSE; - } - - printf ( - "Capsule %s Size=0x%X CargoSize=0x%X\n", - FileList->FileName, - FileSize, - FileSize - CapsuleHeader.OffsetToCapsuleBody - ); - printf ( - " GUID %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", - CapsuleHeader.CapsuleGuid.Data1, - (UINT32) CapsuleHeader.CapsuleGuid.Data2, - (UINT32) CapsuleHeader.CapsuleGuid.Data3, - (UINT32) CapsuleHeader.CapsuleGuid.Data4[0], - (UINT32) CapsuleHeader.CapsuleGuid.Data4[1], - (UINT32) CapsuleHeader.CapsuleGuid.Data4[2], - (UINT32) CapsuleHeader.CapsuleGuid.Data4[3], - (UINT32) CapsuleHeader.CapsuleGuid.Data4[4], - (UINT32) CapsuleHeader.CapsuleGuid.Data4[5], - (UINT32) CapsuleHeader.CapsuleGuid.Data4[6], - (UINT32) CapsuleHeader.CapsuleGuid.Data4[7] - ); - if (memcmp (&CapsuleHeader.CapsuleGuid, &mEfiCapsuleHeaderGuid, sizeof (EFI_GUID)) != 0) { - printf (" INVALID GUID"); - } - - printf ("\n"); - printf (" Header size 0x%08X\n", CapsuleHeader.HeaderSize); - printf (" Flags 0x%08X\n", CapsuleHeader.Flags); - if (!SplitImage) { - printf (" Capsule image size 0x%08X\n", CapsuleHeader.CapsuleImageSize); - } else { - printf (" Capsule image size 0x%08X (split)\n", CapsuleHeader.CapsuleImageSize); - } - - printf (" Sequence number %d\n", CapsuleHeader.SequenceNumber); - printf ( - " InstanceId %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n", - CapsuleHeader.InstanceId.Data1, - (UINT32) CapsuleHeader.InstanceId.Data2, - (UINT32) CapsuleHeader.InstanceId.Data3, - (UINT32) CapsuleHeader.InstanceId.Data4[0], - (UINT32) CapsuleHeader.InstanceId.Data4[1], - (UINT32) CapsuleHeader.InstanceId.Data4[2], - (UINT32) CapsuleHeader.InstanceId.Data4[3], - (UINT32) CapsuleHeader.InstanceId.Data4[4], - (UINT32) CapsuleHeader.InstanceId.Data4[5], - (UINT32) CapsuleHeader.InstanceId.Data4[6], - (UINT32) CapsuleHeader.InstanceId.Data4[7] - ); - printf (" Offset to capsule 0x%X\n", CapsuleHeader.OffsetToCapsuleBody); - // - // Dump header data if there - // - CapsuleHeaderDataSize = CapsuleHeader.OffsetToCapsuleBody - CapsuleHeader.HeaderSize; - if (CapsuleHeaderDataSize != 0) { - CapsuleHeaderData = (UINT8 *) malloc (CapsuleHeaderDataSize); - if (CapsuleHeaderData == NULL) { - Error ( - NULL, - 0, - 0, - "failed to allocate memory to read in capsule header data", - "0x%X bytes", - CapsuleHeaderDataSize - ); - goto Done; - } - - fseek (InFptr, CapsuleHeader.HeaderSize, SEEK_SET); - if (fread (CapsuleHeaderData, CapsuleHeaderDataSize, 1, InFptr) != 1) { - Error ( - NULL, - 0, - 0, - "failed to read capsule header data contents from file", - "0x%X bytes", - CapsuleHeaderDataSize - ); - goto Done; - } - // - // ************************************************************************ - // - // OEM HEADER - // - // ************************************************************************ - // - if (CapsuleHeader.OffsetToOemDefinedHeader != 0) { - OemHeader = (EFI_CAPSULE_OEM_HEADER *) (CapsuleHeaderData + CapsuleHeader.OffsetToOemDefinedHeader - CapsuleHeader.HeaderSize); - printf (" OEM Header\n"); - printf ( - " GUID %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n", - OemHeader->OemGuid.Data1, - (UINT32) OemHeader->OemGuid.Data2, - (UINT32) OemHeader->OemGuid.Data3, - (UINT32) OemHeader->OemGuid.Data4[0], - (UINT32) OemHeader->OemGuid.Data4[1], - (UINT32) OemHeader->OemGuid.Data4[2], - (UINT32) OemHeader->OemGuid.Data4[3], - (UINT32) OemHeader->OemGuid.Data4[4], - (UINT32) OemHeader->OemGuid.Data4[5], - (UINT32) OemHeader->OemGuid.Data4[6], - (UINT32) OemHeader->OemGuid.Data4[7] - ); - printf (" Header size: 0x%X\n", OemHeader->HeaderSize); - printf (" OEM data"); - BPtr = (UINT8 *) (OemHeader + 1); - for (ByteCount = 0; ByteCount < OemHeader->HeaderSize - sizeof (EFI_CAPSULE_OEM_HEADER); ByteCount++) { - if ((ByteCount & 0x7) == 0) { - printf ("\n "); - } - - printf ("%02X ", (UINT32) *BPtr); - BPtr++; - } - - printf ("\n"); - } - // - // ************************************************************************ - // - // Author, revision, short description, and long description information - // - // ************************************************************************ - // - if (CapsuleHeader.OffsetToAuthorInformation != 0) { - if (DumpCapsuleHeaderStrings ( - "Author information", - (WCHAR *) (CapsuleHeaderData + CapsuleHeader.OffsetToAuthorInformation - CapsuleHeader.HeaderSize) - ) != STATUS_SUCCESS) { - goto Done; - } - } - - if (CapsuleHeader.OffsetToRevisionInformation != 0) { - if (DumpCapsuleHeaderStrings ( - "Revision information", - (WCHAR *) (CapsuleHeaderData + CapsuleHeader.OffsetToRevisionInformation - CapsuleHeader.HeaderSize) - ) != STATUS_SUCCESS) { - goto Done; - } - } - - if (CapsuleHeader.OffsetToShortDescription != 0) { - if (DumpCapsuleHeaderStrings ( - "Short description", - (WCHAR *) (CapsuleHeaderData + CapsuleHeader.OffsetToShortDescription - CapsuleHeader.HeaderSize) - ) != STATUS_SUCCESS) { - goto Done; - } - } - - if (CapsuleHeader.OffsetToLongDescription != 0) { - if (DumpCapsuleHeaderStrings ( - "Long description", - (WCHAR *) (CapsuleHeaderData + CapsuleHeader.OffsetToLongDescription - CapsuleHeader.HeaderSize) - ) != STATUS_SUCCESS) { - goto Done; - } - } - } - // - // If it's not a split image, or it is a split image and this is the first in the series, then - // dump the cargo volume. - // - if ((!SplitImage) || (CapsuleHeader.SequenceNumber == 0)) { - printf (" Cargo FV dump\n"); - fseek (InFptr, CapsuleHeader.OffsetToCapsuleBody, SEEK_SET); - if (fread (&FVHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER), 1, InFptr) != 1) { - Error (NULL, 0, 0, FileList->FileName, "failed to read cargo FV header"); - goto Done; - } - - printf (" FV length 0x%X", FVHeader.FvLength); - if (FileSize - CapsuleHeader.OffsetToCapsuleBody != FVHeader.FvLength) { - if (!SplitImage) { - printf (" ERROR: expected 0x%X to jive with file size on disk", FileSize - CapsuleHeader.OffsetToCapsuleBody); - } - } - - printf ("\n"); - printf (" Signature 0x%X ", FVHeader.Signature); - if (FVHeader.Signature == EFI_FVH_SIGNATURE) { - printf ("_FVH\n"); - } else { - printf ("INVALID\n"); - } - - printf (" FV header length 0x%X\n", (UINT32) FVHeader.HeaderLength); - printf (" Revision 0x%X\n", (UINT32) FVHeader.Revision); - printf ("\n"); - } - - FileList = FileList->Next; - } - -Done: - if (InFptr != NULL) { - fclose (InFptr); - } - - if (CapsuleHeaderData != NULL) { - free (CapsuleHeaderData); - } -#endif -} - -static -STATUS -JoinCapsule ( - VOID - ) -/*++ - -Routine Description: - Join split capsule images into a single image. This is the - support function for the -j command-line option. - -Arguments: - None. - -Returns: - STATUS_SUCCESS - no problems encountered - ---*/ -{ -#if 0 - UINT32 Size; - FILE *InFptr; - FILE *OutFptr; - INT8 *Buffer; - FILE_LIST *FileList; - STATUS Status; - EFI_CAPSULE_HEADER CapHdr; - EFI_CAPSULE_HEADER *CapHdrPtr; - UINT32 SizeLeft; - UINT32 SequenceNumber; - // - // Must have at least two files for join mode - // - if ((mOptions.FileList == NULL) || (mOptions.FileList->Next == NULL)) { - Error (NULL, 0, 0, "must specify at least two file names to join", NULL); - return STATUS_ERROR; - } - // - // Open the output file - // - if ((OutFptr = fopen (mOptions.OutputFileName, "wb")) == NULL) { - Error (NULL, 0, 0, mOptions.OutputFileName, "failed to open output file for writing"); - return STATUS_ERROR; - } - - FileList = mOptions.FileList; - Buffer = NULL; - SequenceNumber = 0; - InFptr = NULL; - SizeLeft = 0; - while (FileList != NULL) { - if ((InFptr = fopen (FileList->FileName, "rb")) == NULL) { - Error (NULL, 0, 0, FileList->FileName, "failed to open file for reading"); - goto FailDone; - } - // - // Allocate a buffer into which we can read the file. - // - fseek (InFptr, 0, SEEK_END); - Size = ftell (InFptr); - rewind (InFptr); - Buffer = (char *) malloc (Size); - if (Buffer == NULL) { - Error (__FILE__, __LINE__, 0, FileList->FileName, "failed to allocate buffer to read file into"); - goto FailDone; - } - - CapHdrPtr = (EFI_CAPSULE_HEADER *) Buffer; - if (fread ((void *) Buffer, Size, 1, InFptr) != 1) { - Error (NULL, 0, 0, FileList->FileName, "failed to read file contents"); - goto FailDone; - } - // - // Check the header for validity. Check size first. - // - if (Size < sizeof (EFI_CAPSULE_HEADER)) { - Error (NULL, 0, 0, FileList->FileName, "file size is insufficient for a capsule header"); - goto FailDone; - } - // - // Check GUID - // - if (memcmp (&CapHdrPtr->CapsuleGuid, &mEfiCapsuleHeaderGuid, sizeof (EFI_GUID)) != 0) { - Error (NULL, 0, 0, FileList->FileName, "invalid capsule GUID"); - goto FailDone; - } - // - // Check sequence number - // - if (CapHdrPtr->SequenceNumber != SequenceNumber) { - Error ( - NULL, - 0, - 0, - FileList->FileName, - "invalid sequence number %d (expected %d)", - CapHdrPtr->SequenceNumber, - SequenceNumber - ); - goto FailDone; - } - // - // If the first file, read save the capsule header - // - if (SequenceNumber == 0) { - memcpy (&CapHdr, CapHdrPtr, sizeof (EFI_CAPSULE_HEADER)); - // - // Erase the InstanceId GUID - // - memset (&CapHdrPtr->InstanceId, 0, sizeof (EFI_GUID)); - if (fwrite (Buffer, Size, 1, OutFptr) != 1) { - Error (NULL, 0, 0, FileList->FileName, "failed to write contents to output file"); - goto FailDone; - } - - if (CapHdr.CapsuleImageSize < Size) { - Error (NULL, 0, 0, FileList->FileName, "capsule image size in capsule header < image size"); - goto FailDone; - } - - SizeLeft = CapHdr.CapsuleImageSize - Size; - } else { - // - // Check the GUID against the first file's GUID - // - if (memcmp (&CapHdr.CapsuleGuid, &CapHdrPtr->CapsuleGuid, sizeof (EFI_GUID)) != 0) { - Error (NULL, 0, 0, FileList->FileName, "GUID does not match first file's GUID"); - goto FailDone; - } - // - // Make sure we're not throwing out any header info - // - if (CapHdrPtr->OffsetToCapsuleBody > sizeof (EFI_CAPSULE_HEADER)) { - // - // Could be the split information, so just emit a warning - // - Warning ( - NULL, - 0, - 0, - FileList->FileName, - "image appears to have additional capsule header information -- ignoring" - ); - } else if (CapHdrPtr->OffsetToCapsuleBody < sizeof (EFI_CAPSULE_HEADER)) { - Error (NULL, 0, 0, FileList->FileName, "offset to capsule body in capsule header is insufficient"); - goto FailDone; - } - - if (fwrite (Buffer + CapHdrPtr->OffsetToCapsuleBody, Size - CapHdrPtr->OffsetToCapsuleBody, 1, OutFptr) != 1) { - Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file"); - goto FailDone; - } - - if (SizeLeft < (Size - CapHdrPtr->OffsetToCapsuleBody)) { - Error (NULL, 0, 0, "sum of image sizes exceeds size specified in initial capsule header", NULL); - goto FailDone; - } - // - // printf ("FILE: %s OffsetToCapsuleBody=0x%X\n", FileList->FileName, CapHdrPtr->OffsetToCapsuleBody); - // - SizeLeft = SizeLeft - (Size - CapHdrPtr->OffsetToCapsuleBody); - } - // - // printf ("FILE: %s sizeleft=0x%X\n", FileList->FileName, SizeLeft); - // - fclose (InFptr); - InFptr = NULL; - free (Buffer); - Buffer = NULL; - FileList = FileList->Next; - SequenceNumber++; - } - - if (SizeLeft) { - Error (NULL, 0, 0, "sum of capsule images is insufficient", "0x%X bytes missing", SizeLeft); - goto FailDone; - } - - Status = STATUS_SUCCESS; - goto Done; -FailDone: - Status = STATUS_ERROR; -Done: - if (InFptr != NULL) { - fclose (InFptr); - } - - if (OutFptr != NULL) { - fclose (OutFptr); - } - - if (Buffer != NULL) { - free (Buffer); - } - - return Status; - -#endif -return STATUS_SUCCESS; -} - -static -STATUS -DumpCapsuleHeaderStrings ( - UINT8 *SectionName, - WCHAR *Buffer - ) -/*++ - -Routine Description: - Given a pointer to string data from a capsule header, dump - the strings. - -Arguments: - SectionName - name of the capsule header section to which - the string data pertains - Buffer - pointer to string data from a capsule header - -Returns: - STATUS_SUCCESS - all went well - ---*/ -{ - printf (" %s\n", SectionName); - while (*Buffer) { - printf (" Language: %S\n", Buffer); - while (*Buffer) { - Buffer++; - } - - Buffer++; - while (*Buffer) { - if (wcslen (Buffer) > 60) { - printf (" %.60S\n", Buffer); - Buffer += 60; - } else { - printf (" %S\n", Buffer); - Buffer += wcslen (Buffer); - } - } - - Buffer++; - } - - return STATUS_SUCCESS; -} - -static -STATUS -GetHexValue ( - SOURCE_FILE *SourceFile, - UINT32 *Value, - UINT32 NumDigits - ) -/*++ - -Routine Description: - Scan a hex value from the input stream. - -Arguments: - SourceFile - input file contents - Value - returned value - NumDigits - number of digits to read - -Returns: - STATUS_SUCCESS - if NumDigits were read from the file - STATUS_ERROR - otherwise - - ---*/ -{ - WCHAR *SaveFilePos; - UINT32 Digits; - WCHAR Nibble; - - SaveFilePos = SourceFile->FileBufferPtr; - *Value = 0; - Digits = NumDigits; - while (Digits > 0) { - Nibble = SourceFile->FileBufferPtr[0]; - if ((Nibble >= UNICODE_0) && (Nibble <= UNICODE_9)) { - *Value = (*Value << 4) | (Nibble - UNICODE_0); - } else if ((Nibble >= UNICODE_A) && (Nibble <= UNICODE_F)) { - *Value = (*Value << 4) | (Nibble - UNICODE_A + 0x10); - } else if ((Nibble >= UNICODE_a) && (Nibble <= UNICODE_f)) { - *Value = (*Value << 4) | (Nibble - UNICODE_a + 0x10); - } else { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - NULL, - "expected %d valid hex nibbles at %.20S", - NumDigits, - SaveFilePos - ); - return STATUS_ERROR; - } - - SourceFile->FileBufferPtr++; - Digits--; - } - - return STATUS_SUCCESS; -} - -static -BOOLEAN -EndOfFile ( - SOURCE_FILE *File - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - File - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - if ((UINT32) File->FileBufferPtr - (UINT32) File->FileBuffer >= File->FileSize) { - File->EndOfFile = TRUE; - } - // - // Reposition to the end of the file if we went beyond - // - if (File->EndOfFile) { - File->FileBufferPtr = File->FileBuffer + File->FileSize / sizeof (WCHAR); - } - - return File->EndOfFile; -} - -static -void -SkipWhiteSpace ( - SOURCE_FILE *SourceFile - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - SourceFile - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - while (!EndOfFile (SourceFile)) { - switch (*SourceFile->FileBufferPtr) { - case UNICODE_NULL: - case UNICODE_CR: - case UNICODE_SPACE: - case UNICODE_TAB: - SourceFile->FileBufferPtr++; - break; - - case UNICODE_LF: - SourceFile->FileBufferPtr++; - SourceFile->LineNum++; - break; - - default: - return ; - } - } -} -// -// Parse a number. Possible format: -// 1234 -// 1234k -// 1234K -// 1M -// 1m -// 0x100 -// -static -BOOLEAN -GetNumber ( - INT8 *Str, - UINT32 *Value - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - Str - GC_TODO: add argument description - Value - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - UINT32 LValue; - - *Value = 0; - LValue = 0; - if (!isdigit (Str[0])) { - return FALSE; - } - // - // Look for hex number - // - if ((Str[0] == '0') && (tolower (Str[1]) == 'x')) { - Str += 2; - if (Str[0] == 0) { - return FALSE; - } - - while (Str[0]) { - if ((Str[0] >= '0') && (Str[0] <= '9')) { - LValue = (LValue << 4) | (Str[0] - '0'); - } else if ((Str[0] >= 'A') && (Str[0] <= 'F')) { - LValue = (LValue << 4) | (Str[0] - 'A' + 0x10); - } else if ((Str[0] >= 'a') && (Str[0] <= 'f')) { - LValue = (LValue << 4) | (Str[0] - 'a' + 0x10); - } else { - break; - } - - Str++; - } - } else { - LValue = atoi (Str); - while (isdigit (*Str)) { - Str++; - } - } - // - // If string left over, better be one character we recognize - // - if (Str[0]) { - if (Str[1]) { - return FALSE; - } - - switch (Str[0]) { - case 'k': - case 'K': - LValue *= 1024; - break; - - case 'm': - case 'M': - LValue *= 1024 * 1024; - break; - - default: - return FALSE; - } - } - - *Value = LValue; - return TRUE; -} -// -// Process the command-line arguments -// -static -STATUS -ProcessArgs ( - int Argc, - char *Argv[] - ) -/*++ - -Routine Description: - - Processes command line arguments. - -Arguments: - - Argc - Number of command line arguments - Argv[] - Array of files input on command line - -Returns: - - STATUS_ERROR - Function exited with an error - STATUS_SUCCESS - Function executed successfully - ---*/ -{ - FILE_LIST *NewFile; - - FILE_LIST *LastFile; - SIZE_LIST *NewSize; - - NewFile = NULL; - NewSize = NULL; - - // - // Clear our globals - // - memset ((char *) &mOptions, 0, sizeof (mOptions)); - - // - // Skip program name - // - Argc--; - Argv++; - - if (Argc == 0) { - Usage (); - return STATUS_ERROR; - } - // - // Process until no more options - // - while ((Argc > 0) && (Argv[0][0] == '-')) { - if (stricmp (Argv[0], "-script") == 0) { - // - // Check for one more arg - // - if (Argc > 1) { - // - // Save the file name - // - if (strlen (Argv[1]) >= sizeof (mOptions.ScriptFileName)) { - Error (NULL, 0, 0, NULL, "input script file name length exceeds internal buffer size"); - - if (NewFile != NULL) { - free (NewFile); - } - if (NewSize != NULL) { - free (NewSize); - } - - return STATUS_ERROR; - } - - strcpy (mOptions.ScriptFileName, Argv[1]); - } else { - Error (NULL, 0, 0, Argv[0], "missing script file name with option"); - Usage (); - - if (NewFile != NULL) { - free (NewFile); - } - if (NewSize != NULL) { - free (NewSize); - } - - return STATUS_ERROR; - } - - Argc--; - Argv++; - // - // -o outfilename -- specify output file name (required) - // - } else if (stricmp (Argv[0], "-o") == 0) { - // - // check for one more arg - // - if (Argc > 1) { - // - // Try to open the file - // - // if ((mOptions.OutFptr = fopen (Argv[1], "wb")) == NULL) { - // Error (NULL, 0, 0, Argv[1], "failed to open output file for writing"); - // return STATUS_ERROR; - // } - // - strcpy (mOptions.OutputFileName, Argv[1]); - } else { - Error (NULL, 0, 0, Argv[0], "missing output filename with option"); - Usage (); - - if (NewFile != NULL) { - free (NewFile); - } - if (NewSize != NULL) { - free (NewSize); - } - - return STATUS_ERROR; - } - - Argc--; - Argv++; - } else if (stricmp (Argv[0], "-j") == 0) { - mOptions.JoinMode = TRUE; - // - // -split option (multiple allowed) - // - } else if (stricmp (Argv[0], "-split") == 0) { - if (Argc > 1) { - NewSize = (SIZE_LIST *) malloc (sizeof (SIZE_LIST)); - if (NewSize == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - - if (NewFile != NULL) { - free (NewFile); - } - if (NewSize != NULL) { - free (NewSize); - } - - return STATUS_ERROR; - } - - memset (NewSize, 0, sizeof (SIZE_LIST)); - // - // Get the size from the next arg, and then add this size - // to our size list - // - if (!GetNumber (Argv[1], &NewSize->Size)) { - Error (NULL, 0, 0, Argv[1], "invalid split size argument"); - - if (NewFile != NULL) { - free (NewFile); - } - if (NewSize != NULL) { - free (NewSize); - } - - return STATUS_ERROR; - } - - if (mOptions.SizeList == NULL) { - mOptions.SizeList = NewSize; - mOptions.CurrentSize = NewSize; - } else { - mOptions.LastSize->Next = NewSize; - } - - mOptions.LastSize = NewSize; - free (NewSize); - } else { - Error (NULL, 0, 0, Argv[0], "missing size parameter with option"); - Usage (); - - if (NewFile != NULL) { - free (NewFile); - } - if (NewSize != NULL) { - free (NewSize); - } - - return STATUS_ERROR; - } - - Argc--; - Argv++; - } else if ((stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) { - Usage (); - - if (NewFile != NULL) { - free (NewFile); - } - if (NewSize != NULL) { - free (NewSize); - } - - return STATUS_ERROR; - // - // Default minimum header - // - } else if (stricmp (Argv[0], "-dump") == 0) { - mOptions.Dump = TRUE; - } else if (stricmp (Argv[0], "-v") == 0) { - mOptions.Verbose = TRUE; - } else { - Error (NULL, 0, 0, Argv[0], "unrecognized option"); - Usage (); - - if (NewFile != NULL) { - free (NewFile); - } - if (NewSize != NULL) { - free (NewSize); - } - - return STATUS_ERROR; - } - - Argc--; - Argv++; - } - // - // Can't -j join files and -s split output capsule - // - if ((mOptions.SizeList != NULL) && (mOptions.JoinMode)) { - Error (NULL, 0, 0, "cannot specify both -j and -size", NULL); - - if (NewFile != NULL) { - free (NewFile); - } - if (NewSize != NULL) { - free (NewSize); - } - - return STATUS_ERROR; - } - // - // Must have specified an output file name if not -dump - // - if ((mOptions.Dump == 0) && (mOptions.OutputFileName[0] == 0)) { - Error (NULL, 0, 0, NULL, "-o OutputFileName must be specified"); - Usage (); - - if (NewFile != NULL) { - free (NewFile); - } - if (NewSize != NULL) { - free (NewSize); - } - - return STATUS_ERROR; - } - // - // Rest of arguments are input files. The first one is a firmware - // volume image, and the rest are FFS files that are to be inserted - // into the firmware volume. - // - LastFile = NULL; - while (Argc > 0) { - NewFile = (FILE_LIST *) malloc (sizeof (FILE_LIST)); - if (NewFile == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - - if (NewFile != NULL) { - free (NewFile); - } - if (NewSize != NULL) { - free (NewSize); - } - - return STATUS_ERROR; - } - - memset ((char *) NewFile, 0, sizeof (FILE_LIST)); - strcpy (NewFile->FileName, Argv[0]); - if (mOptions.FileList == NULL) { - mOptions.FileList = NewFile; - } else { - if (LastFile == NULL) { - LastFile = NewFile; - } else { - LastFile->Next = NewFile; - } - } - - LastFile = NewFile; - Argc--; - Argv++; - } - - // - // Must have provided at least one file name - // - if (mOptions.FileList == NULL) { - Error (NULL, 0, 0, "must specify at least one file name", NULL); - Usage (); - - if (NewFile != NULL) { - free (NewFile); - } - if (NewSize != NULL) { - free (NewSize); - } - - return STATUS_ERROR; - } - - return STATUS_SUCCESS; -} - -static -void -Usage ( - VOID - ) -/*++ - -Routine Description: - - Print usage information for this utility. - -Arguments: - - None. - -Returns: - - Nothing. - ---*/ -{ - int Index; - static const char *Str[] = { - PROGRAM_NAME " -- create a capsule header", - " Usage: "PROGRAM_NAME " {options} [CapsuleFV]", - // - // {FfsFileNames}", - // - " Options include:", - " -h or -? for this help information", - " -script fname to take capsule header info from unicode script", - " file fname", - " -o fname write output to file fname (required)", - " -split size split capsule image into multiple output files", - " -dump to dump a capsule header", - " -v for verbose output\n", - " -j to join split capsule images into a single image", - "", - " CapsuleFV is the name of an existing well-formed Tiano firmware", - " volume file.", - // - // FfsFileNames are the names of one or more Tiano FFS files to", - // " insert into the output capsule image.", - // - NULL - }; - for (Index = 0; Str[Index] != NULL; Index++) { - fprintf (stdout, "%s\n", Str[Index]); - } -} diff --git a/Tools/CodeTools/TianoTools/GenCapsuleHdr/build.xml b/Tools/CodeTools/TianoTools/GenCapsuleHdr/build.xml deleted file mode 100644 index 7c43d0a347..0000000000 --- a/Tools/CodeTools/TianoTools/GenCapsuleHdr/build.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/GenDepex/DepexParser.c b/Tools/CodeTools/TianoTools/GenDepex/DepexParser.c deleted file mode 100644 index 9f0a0cbbab..0000000000 --- a/Tools/CodeTools/TianoTools/GenDepex/DepexParser.c +++ /dev/null @@ -1,903 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - DepexParser.c - -Abstract: - - Validate Dependency Expression syntax - recursive descent Algorithm - - The original BNF grammar(taken from "Pre EFI Initialization Core Interface Specification - draft review 0.9") is thus: - ::= BEFORE END - | AFTER END - | SOR END - | END - ::= AND - | OR - | - ::= NOT - | - ::= - | TRUE - | FALSE - | GUID - - ::= '{' ',' ',' ',' - ',' ',' ',' ',' - ',' ',' ',' '}' - ::= - ::= - ::= - ::= '0' 'x' - | '0' 'X' - ::= - | - ::= [0-9] - | [a-f] - | [A-F] - - After cleaning left recursive and parentheses supported, the BNF grammar used in this module is thus: - ::= BEFORE - | AFTER - | SOR - | - ::= - ::= AND - | OR - | '' - ::= NOT - | - ::= '('')' - | NOT - | TRUE - | FALSE - | END - | - ::=AND - | OR - | '' - ::= '{' ',' ',' ',' - ',' ',' ',' ',' - ',' ',' ',' '}' - ::= - ::= - ::= - ::= '0' 'x' - | '0' 'X' - ::= - | - ::= [0-9] - | [a-f] - | [A-F] - - Note: 1. There's no precedence in operators except parentheses; - 2. For hex32, less and equal than 8 bits is valid, more than 8 bits is invalid. - Same constraint for hex16 is 4, hex8 is 2. All hex should contains at least 1 bit. - 3. " ::= '('')'" is added to support parentheses; - 4. " ::= GUID" is changed to " ::= "; - 5. "DEPENDENCY_END" is the terminal of the expression. But it has been filtered by caller. - During parsing, "DEPENDENCY_END" will be treated as illegal factor; - - This code should build in any environment that supports a standard C-library w/ string - operations and File I/O services. - - As an example of usage, consider the following: - - The input string could be something like: - - NOT ({ 0xce345171, 0xba0b, 0x11d2, 0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72, - 0x3b } AND { 0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, - 0x72, 0x3b }) OR { 0x03c4e603, 0xac28, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27, - 0x3f, 0xc1, 0x4d } AND - - It's invalid for an extra "AND" in the end. - - Complies with Tiano C Coding Standards Document, version 0.33, 16 Aug 2001. - ---*/ - -#include "DepexParser.h" - -BOOLEAN -ParseBool ( - IN INT8 *Pbegin, - IN UINT32 length, - IN OUT INT8 **Pindex - ); - -BOOLEAN -ParseTerm ( - IN INT8 *Pbegin, - IN UINT32 length, - IN OUT INT8 **Pindex - ); - -BOOLEAN -ParseRightBool ( - IN INT8 *Pbegin, - IN UINT32 length, - IN OUT INT8 **Pindex - ); - -BOOLEAN -ParseFactor ( - IN INT8 *Pbegin, - IN UINT32 length, - IN OUT INT8 **Pindex - ); - -VOID -LeftTrim ( - IN INT8 *Pbegin, - IN UINT32 length, - IN OUT INT8 **Pindex - ) -/*++ - -Routine Description: - - Left trim the space, '\n' and '\r' character in string. - The space at the end does not need trim. - - -Arguments: - - Pbegin The pointer to the string - length length of the string - Pindex The pointer of pointer to the next parse character in the string - -Returns: - - None - - ---*/ -{ - while - ( - ((*Pindex) < (Pbegin + length)) && - ((strncmp (*Pindex, " ", 1) == 0) || (strncmp (*Pindex, "\n", 1) == 0) || (strncmp (*Pindex, "\r", 1) == 0)) - ) { - (*Pindex)++; - } -} - -BOOLEAN -ParseHexdigit ( - IN INT8 *Pbegin, - IN UINT32 length, - IN OUT INT8 **Pindex - ) -/*++ - -Routine Description: - - Parse Hex bit in dependency expression. - -Arguments: - - Pbegin The pointer to the string - length Length of the string - Pindex The pointer of pointer to the next parse character in the string - -Returns: - - BOOLEAN If parses a valid hex bit, return TRUE, otherwise FALSE - - ---*/ -{ - // - // ::= [0-9] | [a-f] | [A-F] - // - if (((**Pindex) >= '0' && (**Pindex) <= '9') || - ((**Pindex) >= 'a' && (**Pindex) <= 'f') || - ((**Pindex) >= 'A' && (**Pindex) <= 'F') - ) { - (*Pindex)++; - return TRUE; - } else { - return FALSE; - } -} - -BOOLEAN -ParseHex32 ( - IN INT8 *Pbegin, - IN UINT32 length, - IN OUT INT8 **Pindex - ) -/*++ - -Routine Description: - - Parse Hex32 in dependency expression. - -Arguments: - - Pbegin The pointer to the string - length Length of the string - Pindex The pointer of point to the next parse character in the string - -Returns: - - BOOLEAN If parses a valid hex32, return TRUE, otherwise FALSE - - ---*/ -{ - INT32 Index; - INT8 *Pin; - - Index = 0; - Pin = *Pindex; - LeftTrim (Pbegin, length, Pindex); - - if ((strncmp (*Pindex, "0x", 2) != 0) && (strncmp (*Pindex, "0X", 2) != 0)) { - return FALSE; - } - (*Pindex) += 2; - - while (ParseHexdigit (Pbegin, length, Pindex)) { - Index++; - } - - if (Index > 0 && Index <= 8) { - return TRUE; - } else { - *Pindex = Pin; - return FALSE; - } -} - -BOOLEAN -ParseHex16 ( - IN INT8 *Pbegin, - IN UINT32 length, - IN OUT INT8 **Pindex - ) -/*++ - -Routine Description: - - Parse Hex16 in dependency expression. - -Arguments: - - Pbegin The pointer to the string - length Length of the string - Pindex The pointer of pointer to the next parse character in the string - -Returns: - - BOOLEAN If parses a valid hex16, return TRUE, otherwise FALSE - - ---*/ -{ - int Index; - INT8 *Pin; - - Index = 0; - Pin = *Pindex; - LeftTrim (Pbegin, length, Pindex); - - if ((strncmp (*Pindex, "0x", 2) != 0) && (strncmp (*Pindex, "0X", 2) != 0)) { - return FALSE; - } - (*Pindex) += 2; - - while (ParseHexdigit (Pbegin, length, Pindex)) { - Index++; - } - - if (Index > 0 && Index <= 4) { - return TRUE; - } else { - *Pindex = Pin; - return FALSE; - } -} - -BOOLEAN -ParseHex8 ( - IN INT8 *Pbegin, - IN UINT32 length, - IN OUT INT8 **Pindex - ) -/*++ - -Routine Description: - - Parse Hex8 in dependency expression. - -Arguments: - - Pbegin The pointer to the string - length Length of the string - Pindex The pointer of pointer to the next parse character in the string - -Returns: - - BOOLEAN If parses a valid hex8, return TRUE, otherwise FALSE - - ---*/ -{ - int Index; - INT8 *Pin; - - Index = 0; - Pin = *Pindex; - LeftTrim (Pbegin, length, Pindex); - - if ((strncmp (*Pindex, "0x", 2) != 0) && (strncmp (*Pindex, "0X", 2) != 0)) { - return FALSE; - } - (*Pindex) += 2; - - while (ParseHexdigit (Pbegin, length, Pindex)) { - Index++; - } - - if (Index > 0 && Index <= 2) { - return TRUE; - } else { - *Pindex = Pin; - return FALSE; - } -} - -BOOLEAN -ParseGuid ( - IN INT8 *Pbegin, - IN UINT32 length, - IN OUT INT8 **Pindex - ) -/*++ - -Routine Description: - - Parse guid in dependency expression. - There can be any number of spaces between '{' and hexword, ',' and hexword, - hexword and ',', hexword and '}'. The hexword include hex32, hex16 and hex8. - -Arguments: - - Pbegin The pointer to the string - length length of the string - Pindex The pointer of pointer to the next parse character in the string - -Returns: - - BOOLEAN If parses a valid guid, return TRUE, otherwise FALSE - - ---*/ -{ - INT32 Index; - INT8 *Pin; - Pin = *Pindex; - LeftTrim (Pbegin, length, Pindex); - if (strncmp (*Pindex, "{", 1) != 0) { - return FALSE; - } - (*Pindex)++; - - LeftTrim (Pbegin, length, Pindex); - if (!ParseHex32 (Pbegin, length, Pindex)) { - *Pindex = Pin; - return FALSE; - } - - LeftTrim (Pbegin, length, Pindex); - if (strncmp (*Pindex, ",", 1) != 0) { - return FALSE; - } else { - (*Pindex)++; - } - - for (Index = 0; Index < 2; Index++) { - LeftTrim (Pbegin, length, Pindex); - if (!ParseHex16 (Pbegin, length, Pindex)) { - *Pindex = Pin; - return FALSE; - } - - LeftTrim (Pbegin, length, Pindex); - if (strncmp (*Pindex, ",", 1) != 0) { - return FALSE; - } else { - (*Pindex)++; - } - } - - LeftTrim (Pbegin, length, Pindex); - if (strncmp (*Pindex, "{", 1) != 0) { - return FALSE; - } - (*Pindex)++; - - for (Index = 0; Index < 7; Index++) { - LeftTrim (Pbegin, length, Pindex); - if (!ParseHex8 (Pbegin, length, Pindex)) { - *Pindex = Pin; - return FALSE; - } - - LeftTrim (Pbegin, length, Pindex); - if (strncmp (*Pindex, ",", 1) != 0) { - return FALSE; - } else { - (*Pindex)++; - } - } - - LeftTrim (Pbegin, length, Pindex); - if (!ParseHex8 (Pbegin, length, Pindex)) { - *Pindex = Pin; - return FALSE; - } - - LeftTrim (Pbegin, length, Pindex); - if (strncmp (*Pindex, "}", 1) != 0) { - return FALSE; - } else { - (*Pindex)++; - } - - LeftTrim (Pbegin, length, Pindex); - if (strncmp (*Pindex, "}", 1) != 0) { - return FALSE; - } else { - (*Pindex)++; - } - - return TRUE; -} - -BOOLEAN -ParseRightFactor ( - IN INT8 *Pbegin, - IN UINT32 length, - IN OUT INT8 **Pindex - ) -/*++ - -Routine Description: - - Parse rightfactor in bool expression. - -Arguments: - - Pbegin The pointer to the string - length length of the string - Pindex The pointer of pointer to the next parse character in the string - -Returns: - - BOOLEAN If string is a valid rightfactor expression, return TRUE, otherwise FALSE - - ---*/ -{ - INT8 *Pin; - - Pin = *Pindex; - LeftTrim (Pbegin, length, Pindex); - - // - // ::=AND - // - if (strncmp (*Pindex, OPERATOR_AND, strlen (OPERATOR_AND)) == 0) { - *Pindex += strlen (OPERATOR_AND); - LeftTrim (Pbegin, length, Pindex); - - if (ParseTerm (Pbegin, length, Pindex)) { - LeftTrim (Pbegin, length, Pindex); - - if (ParseRightBool (Pbegin, length, Pindex)) { - LeftTrim (Pbegin, length, Pindex); - if (ParseRightFactor (Pbegin, length, Pindex)) { - return TRUE; - } else { - *Pindex = Pin; - } - } else { - *Pindex = Pin; - } - } else { - *Pindex = Pin; - } - } - // - // ::=OR - // - if (strncmp (*Pindex, OPERATOR_OR, strlen (OPERATOR_OR)) == 0) { - *Pindex += strlen (OPERATOR_OR); - LeftTrim (Pbegin, length, Pindex); - - if (ParseTerm (Pbegin, length, Pindex)) { - LeftTrim (Pbegin, length, Pindex); - - if (ParseRightBool (Pbegin, length, Pindex)) { - LeftTrim (Pbegin, length, Pindex); - if (ParseRightFactor (Pbegin, length, Pindex)) { - return TRUE; - } else { - *Pindex = Pin; - } - } else { - *Pindex = Pin; - } - } else { - *Pindex = Pin; - } - } - // - // ::= '' - // - *Pindex = Pin; - return TRUE; -} - -BOOLEAN -ParseRightBool ( - IN INT8 *Pbegin, - IN UINT32 length, - IN OUT INT8 **Pindex - ) -/*++ - -Routine Description: - - Parse rightbool in bool expression. - -Arguments: - - Pbegin The pointer to the string - length length of the string - Pindex The pointer of pointer to the next parse character in the string - -Returns: - - BOOLEAN If string is a valid rightbool expression, return TRUE, otherwise FALSE - - ---*/ -{ - INT8 *Pin; - - Pin = *Pindex; - LeftTrim (Pbegin, length, Pindex); - - // - // ::= AND - // - if (strncmp (*Pindex, OPERATOR_AND, strlen (OPERATOR_AND)) == 0) { - *Pindex += strlen (OPERATOR_AND); - LeftTrim (Pbegin, length, Pindex); - - if (ParseTerm (Pbegin, length, Pindex)) { - LeftTrim (Pbegin, length, Pindex); - - if (ParseRightBool (Pbegin, length, Pindex)) { - return TRUE; - } else { - *Pindex = Pin; - } - } else { - *Pindex = Pin; - } - } - // - // ::= OR - // - if (strncmp (*Pindex, OPERATOR_OR, strlen (OPERATOR_OR)) == 0) { - *Pindex += strlen (OPERATOR_OR); - LeftTrim (Pbegin, length, Pindex); - - if (ParseTerm (Pbegin, length, Pindex)) { - LeftTrim (Pbegin, length, Pindex); - - if (ParseRightBool (Pbegin, length, Pindex)) { - return TRUE; - } else { - *Pindex = Pin; - } - } else { - *Pindex = Pin; - } - } - // - // ::= '' - // - *Pindex = Pin; - return TRUE; -} - -BOOLEAN -ParseFactor ( - IN INT8 *Pbegin, - IN UINT32 length, - IN OUT INT8 **Pindex - ) -/*++ - -Routine Description: - - Parse factor in bool expression. - -Arguments: - - Pbegin The pointer to the string - length length of the string - Pindex The pointer of pointer to the next parse character in the string - -Returns: - - BOOLEAN If string is a valid factor, return TRUE, otherwise FALSE - - ---*/ -{ - INT8 *Pin; - - Pin = *Pindex; - LeftTrim (Pbegin, length, Pindex); - - // - // ::= '('')' - // - if (strncmp (*Pindex, OPERATOR_LEFT_PARENTHESIS, strlen (OPERATOR_LEFT_PARENTHESIS)) == 0) { - *Pindex += strlen (OPERATOR_LEFT_PARENTHESIS); - LeftTrim (Pbegin, length, Pindex); - - if (!ParseBool (Pbegin, length, Pindex)) { - *Pindex = Pin; - } else { - LeftTrim (Pbegin, length, Pindex); - - if (strncmp (*Pindex, OPERATOR_RIGHT_PARENTHESIS, strlen (OPERATOR_RIGHT_PARENTHESIS)) == 0) { - *Pindex += strlen (OPERATOR_RIGHT_PARENTHESIS); - LeftTrim (Pbegin, length, Pindex); - - if (ParseRightFactor (Pbegin, length, Pindex)) { - return TRUE; - } else { - *Pindex = Pin; - } - } - } - } - // - // ::= NOT - // - if (strncmp (*Pindex, OPERATOR_NOT, strlen (OPERATOR_NOT)) == 0) { - *Pindex += strlen (OPERATOR_NOT); - LeftTrim (Pbegin, length, Pindex); - - if (ParseFactor (Pbegin, length, Pindex)) { - LeftTrim (Pbegin, length, Pindex); - - if (ParseRightBool (Pbegin, length, Pindex)) { - LeftTrim (Pbegin, length, Pindex); - - if (ParseRightFactor (Pbegin, length, Pindex)) { - return TRUE; - } else { - *Pindex = Pin; - } - } else { - *Pindex = Pin; - } - } else { - *Pindex = Pin; - } - } - // - // ::= TRUE - // - if (strncmp (*Pindex, OPERATOR_TRUE, strlen (OPERATOR_TRUE)) == 0) { - *Pindex += strlen (OPERATOR_TRUE); - LeftTrim (Pbegin, length, Pindex); - - if (ParseRightFactor (Pbegin, length, Pindex)) { - return TRUE; - } else { - *Pindex = Pin; - } - } - // - // ::= FALSE - // - if (strncmp (*Pindex, OPERATOR_FALSE, strlen (OPERATOR_FALSE)) == 0) { - *Pindex += strlen (OPERATOR_FALSE); - LeftTrim (Pbegin, length, Pindex); - - if (ParseRightFactor (Pbegin, length, Pindex)) { - return TRUE; - } else { - *Pindex = Pin; - } - } - // - // ::= - // - if (ParseGuid (Pbegin, length, Pindex)) { - LeftTrim (Pbegin, length, Pindex); - - if (ParseRightFactor (Pbegin, length, Pindex)) { - return TRUE; - } else { - *Pindex = Pin; - return FALSE; - } - } else { - *Pindex = Pin; - return FALSE; - } -} - -BOOLEAN -ParseTerm ( - IN INT8 *Pbegin, - IN UINT32 length, - IN OUT INT8 **Pindex - ) -/*++ - -Routine Description: - - Parse term in bool expression. - -Arguments: - - Pbegin The pointer to the string - length length of the string - Pindex The pointer of pointer to the next parse character in the string - -Returns: - - BOOLEAN If string is a valid term, return TRUE, otherwise FALSE - - ---*/ -{ - INT8 *Pin; - - Pin = *Pindex; - LeftTrim (Pbegin, length, Pindex); - - // - // ::= NOT - // - if (strncmp (*Pindex, OPERATOR_NOT, strlen (OPERATOR_NOT)) == 0) { - *Pindex += strlen (OPERATOR_NOT); - LeftTrim (Pbegin, length, Pindex); - - if (!ParseFactor (Pbegin, length, Pindex)) { - *Pindex = Pin; - } else { - return TRUE; - } - } - // - // ::= - // - if (ParseFactor (Pbegin, length, Pindex)) { - return TRUE; - } else { - *Pindex = Pin; - return FALSE; - } -} - -BOOLEAN -ParseBool ( - IN INT8 *Pbegin, - IN UINT32 length, - IN OUT INT8 **Pindex - ) -/*++ - -Routine Description: - - Parse bool expression. - -Arguments: - - Pbegin The pointer to the string - length length of the string - Pindex The pointer of pointer to the next parse character in the string - -Returns: - - BOOLEAN If string is a valid bool expression, return TRUE, otherwise FALSE - - ---*/ -{ - INT8 *Pin; - Pin = *Pindex; - LeftTrim (Pbegin, length, Pindex); - - if (ParseTerm (Pbegin, length, Pindex)) { - LeftTrim (Pbegin, length, Pindex); - - if (!ParseRightBool (Pbegin, length, Pindex)) { - *Pindex = Pin; - return FALSE; - } else { - return TRUE; - } - } else { - *Pindex = Pin; - return FALSE; - } -} - -BOOLEAN -ParseDepex ( - IN INT8 *Pbegin, - IN UINT32 length - ) -/*++ - -Routine Description: - - Parse whole dependency expression. - -Arguments: - - Pbegin The pointer to the string - length length of the string - -Returns: - - BOOLEAN If string is a valid dependency expression, return TRUE, otherwise FALSE - - ---*/ -{ - BOOLEAN Result; - INT8 **Pindex; - INT8 *temp; - - Result = FALSE; - temp = Pbegin; - Pindex = &temp; - - LeftTrim (Pbegin, length, Pindex); - if (strncmp (*Pindex, OPERATOR_BEFORE, strlen (OPERATOR_BEFORE)) == 0) { - (*Pindex) += strlen (OPERATOR_BEFORE); - Result = ParseGuid (Pbegin, length, Pindex); - - } else if (strncmp (*Pindex, OPERATOR_AFTER, strlen (OPERATOR_AFTER)) == 0) { - (*Pindex) += strlen (OPERATOR_AFTER); - Result = ParseGuid (Pbegin, length, Pindex); - - } else if (strncmp (*Pindex, OPERATOR_SOR, strlen (OPERATOR_SOR)) == 0) { - (*Pindex) += strlen (OPERATOR_SOR); - Result = ParseBool (Pbegin, length, Pindex); - - } else { - Result = ParseBool (Pbegin, length, Pindex); - - } - - LeftTrim (Pbegin, length, Pindex); - return (BOOLEAN) (Result && (*Pindex) >= (Pbegin + length)); -} diff --git a/Tools/CodeTools/TianoTools/GenDepex/DepexParser.h b/Tools/CodeTools/TianoTools/GenDepex/DepexParser.h deleted file mode 100644 index 29e0884a3e..0000000000 --- a/Tools/CodeTools/TianoTools/GenDepex/DepexParser.h +++ /dev/null @@ -1,26 +0,0 @@ -/*++ -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: - GenDepex.h - - Abstract: - This file contains the relevant declarations required - to generate a binary Dependency File - - Complies with Tiano C Coding Standards Document, version 0.31, 12 Dec 2000. - ---*/ - -// TODO: fix comment to set correct module name: DepexParser.h -#ifndef _EFI_DEPEX_PARSER_H_ -#define _EFI_DEPEX_PARSER_H_ -#include "GenDepex.h" -#endif diff --git a/Tools/CodeTools/TianoTools/GenDepex/GenDepex.c b/Tools/CodeTools/TianoTools/GenDepex/GenDepex.c deleted file mode 100644 index 3818649330..0000000000 --- a/Tools/CodeTools/TianoTools/GenDepex/GenDepex.c +++ /dev/null @@ -1,919 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - GenDepex.c - -Abstract: - - Generate Dependency Expression ("GenDepex") - - Infix to Postfix Algorithm - - This code has been scrubbed to be free of having any EFI core tree dependencies. - It should build in any environment that supports a standard C-library w/ string - operations and File I/O services. - - As an example of usage, consider the following: - - The input user file could be something like "Sample.DXS" whose contents are - - #include "Tiano.h" - - DEPENDENCY_START - NOT (DISK_IO_PROTOCOL AND SIMPLE_FILE_SYSTEM_PROTOCOL) - OR EFI_PXE_BASE_CODE_PROTOCOL - DEPENDENCY_END - - This file is then washed through the C-preprocessor, viz., - - cl /EP Sample.DXS > Sample.TMP1 - - This yields the following file "Sample.TMP1" whose contents are - - DEPENDENCY_START - NOT ({ 0xce345171, 0xba0b, 0x11d2, 0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72, - 0x3b } AND { 0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, - 0x72, 0x3b }) OR { 0x03c4e603, 0xac28, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27, - 0x3f, 0xc1, 0x4d } - DEPENDENCY_END - - This file, in turn, will be fed into the utility, viz., - - GenDepex Sample.TMP1 Sample.TMP2 - - With a file that is 55 bytes long: - - 55 bytes for the grammar binary - PUSH opcode - 1 byte - GUID Instance - 16 bytes - PUSH opcode - 1 byte - GUID Instance - 16 bytes - AND opcode - 1 byte - NOT opcode - 1 byte - PUSH opcode - 1 byte - GUID Instance - 16 bytes - OR opcode - 1 byte - END opcode - 1 byte - - The file "Sample.TMP2" could be fed via a Section-builder utility - (GenSection) that would be used for the creation of a dependency - section file (.DPX) which in turn would be used by a generate FFS - utility (GenFfsFile) to produce a DXE driver/core (.DXE) or - a DXE application (.APP) file. - - Complies with Tiano C Coding Standards Document, version 0.31, 12 Dec 2000. - ---*/ - -#include "GenDepex.h" - -#define TOOL_NAME "GenDepex" - -extern -ParseDepex ( - IN INT8 *Pbegin, - IN UINT32 length - ); - -VOID -PrintGenDepexUtilityInfo ( - VOID - ) -/*++ - -Routine Description: - - Displays the standard utility information to SDTOUT. - -Arguments: - - None - -Returns: - - None - ---*/ -{ - printf ( - "%s, Tiano Dependency Expression Generation Utility. Version %d.%d.\n", - UTILITY_NAME, - UTILITY_MAJOR_VERSION, - UTILITY_MINOR_VERSION - ); - printf ("Copyright (C) 1996-2002 Intel Corporation. All rights reserved.\n\n"); -} - -VOID -PrintGenDepexUsageInfo ( - VOID - ) -/*++ - -Routine Description: - - Displays the utility usage syntax to STDOUT. - -Arguments: - - None - -Returns: - - None - ---*/ -{ - printf ( - "Usage: %s -I -O [-P ] \n", - UTILITY_NAME - ); - printf (" Where:\n"); - printf (" is the input pre-processed dependency text files name.\n"); - printf (" is the output binary dependency files name.\n"); - printf (" is the padding integer value.\n"); - printf (" This is the boundary to align the output file size to.\n"); -} - -DEPENDENCY_OPCODE -PopOpCode ( - IN OUT VOID **Stack - ) -/*++ - -Routine Description: - - Pop an element from the Opcode stack. - -Arguments: - - Stack Current top of the OpCode stack location - -Returns: - - DEPENDENCY_OPCODE OpCode at the top of the OpCode stack. - Stack New top of the OpCode stack location - - ---*/ -{ - DEPENDENCY_OPCODE *OpCodePtr; - - OpCodePtr = *Stack; - OpCodePtr--; - *Stack = OpCodePtr; - return *OpCodePtr; -} - -VOID -PushOpCode ( - IN OUT VOID **Stack, - IN DEPENDENCY_OPCODE OpCode - ) -/*++ - -Routine Description: - - Push an element onto the Opcode Stack - -Arguments: - - Stack Current top of the OpCode stack location - OpCode OpCode to push onto the stack - -Returns: - - Stack New top of the OpCode stack location - ---*/ -{ - DEPENDENCY_OPCODE *OpCodePtr; - - OpCodePtr = *Stack; - *OpCodePtr = OpCode; - OpCodePtr++; - *Stack = OpCodePtr; -} - -EFI_STATUS -GenerateDependencyExpression ( - IN FILE *InFile, - IN OUT FILE *OutFile, - IN INT8 Padding OPTIONAL - ) -/*++ - -Routine Description: - - This takes the pre-compiled dependency text file and - converts it into a binary dependency file. - - The BNF for the dependency expression is as follows - (from the DXE 1.0 Draft specification). - - The inputted BNF grammar is thus: - ::= sor | - before GUID | - after GUID | - - - ::= | - - ::= and | - or | - - - ::= not | - - - ::= ( ) | - | - GUID | - - - ::= true | - false - - The outputed binary grammer is thus: - ::= sor | - before | - after | - - - ::= | - - ::= and | - or | - - ::= not | - - - ::= ( ) | - | - | - | - - - ::= true | - false - - ::= push GUID - - ::= end - - BugBug: A correct grammer is parsed correctly. A file that violates the - grammer may parse when it should generate an error. There is some - error checking and it covers most of the case when it's an include - of definition issue. An ill formed expresion may not be detected. - -Arguments: - - InFile - Input pre-compiled text file of the dependency expression. - This needs to be in ASCII. - The file pointer can not be NULL. - - OutFile - Binary dependency file. - The file pointer can not be NULL. - - Padding - OPTIONAL integer value to pad the output file to. - - -Returns: - - EFI_SUCCESS The function completed successfully. - EFI_INVALID_PARAMETER One of the parameters in the text file was invalid. - EFI_OUT_OF_RESOURCES Unable to allocate memory. - EFI_ABORTED An misc error occurred. - ---*/ -{ - INT8 *Ptrx; - INT8 *Pend; - INT8 *EvaluationStack; - INT8 *StackPtr; - INT8 *Buffer; - INT8 Line[LINESIZE]; - UINTN Index; - UINTN OutFileSize; - UINTN FileSize; - UINTN Results; - BOOLEAN NotDone; - BOOLEAN Before_Flag; - BOOLEAN After_Flag; - BOOLEAN Dep_Flag; - BOOLEAN SOR_Flag; - EFI_GUID Guid; - UINTN ArgCountParsed; - DEPENDENCY_OPCODE Opcode; - - Before_Flag = FALSE; - After_Flag = FALSE; - Dep_Flag = FALSE; - SOR_Flag = FALSE; - - memset (Line, 0, LINESIZE); - - OutFileSize = 0; - - EvaluationStack = (INT8 *) malloc (EVAL_STACK_SIZE); - - if (EvaluationStack != NULL) { - StackPtr = EvaluationStack; - } else { - printf ("Unable to allocate memory to EvaluationStack - Out of resources\n"); - return EFI_OUT_OF_RESOURCES; - } - - Results = (UINTN) fseek (InFile, 0, SEEK_END); - - if (Results != 0) { - printf ("FSEEK failed - Aborted\n"); - return EFI_ABORTED; - } - - FileSize = ftell (InFile); - - if (FileSize == -1L) { - printf ("FTELL failed - Aborted\n"); - return EFI_ABORTED; - } - - Buffer = (INT8 *) malloc (FileSize + BUFFER_SIZE); - - if (Buffer == NULL) { - printf ("Unable to allocate memory to Buffer - Out of resources\n"); - free (EvaluationStack); - - Results = (UINTN) fclose (InFile); - if (Results != 0) { - printf ("FCLOSE failed\n"); - } - - Results = (UINTN) fclose (OutFile); - if (Results != 0) { - printf ("FCLOSE failed\n"); - } - - return EFI_OUT_OF_RESOURCES; - } - - Results = (UINTN) fseek (InFile, 0, SEEK_SET); - - if (Results != 0) { - printf ("FSEEK failed - Aborted\n"); - return EFI_ABORTED; - } - - memset (Buffer, 0, FileSize + BUFFER_SIZE); - fread (Buffer, FileSize, 1, InFile); - - Ptrx = Buffer; - Pend = Ptrx + FileSize - strlen (DEPENDENCY_END); - Index = FileSize; - - NotDone = TRUE; - while ((Index--) && NotDone) { - - if (strncmp (Pend, DEPENDENCY_END, strlen (DEPENDENCY_END)) == 0) { - NotDone = FALSE; - } else { - Pend--; - } - } - - if (NotDone) { - printf ("Couldn't find end string %s\n", DEPENDENCY_END); - - Results = (UINTN) fclose (InFile); - if (Results != 0) { - printf ("FCLOSE failed\n"); - } - - Results = (UINTN) fclose (OutFile); - if (Results != 0) { - printf ("FCLOSE failed\n"); - } - - free (Buffer); - free (EvaluationStack); - - return EFI_INVALID_PARAMETER; - } - - Index = FileSize; - - NotDone = TRUE; - while ((Index--) && NotDone) { - - if (strncmp (Ptrx, DEPENDENCY_START, strlen (DEPENDENCY_START)) == 0) { - Ptrx += sizeof (DEPENDENCY_START); - NotDone = FALSE; - // - // BUGBUG -- should Index be decremented by sizeof(DEPENDENCY_START)? - // - } else { - Ptrx++; - } - } - - if (NotDone) { - printf ("Couldn't find start string %s\n", DEPENDENCY_START); - - Results = (UINTN) fclose (InFile); - if (Results != 0) { - printf ("FCLOSE failed\n"); - } - - Results = (UINTN) fclose (OutFile); - if (Results != 0) { - printf ("FCLOSE failed\n"); - } - - free (Buffer); - free (EvaluationStack); - - return EFI_INVALID_PARAMETER; - } - // - // validate the syntax of expression - // - if (!ParseDepex (Ptrx, Pend - Ptrx - 1)) { - printf ("The syntax of expression is wrong\n"); - - Results = (UINTN) fclose (InFile); - if (Results != 0) { - printf ("FCLOSE failed\n"); - } - - Results = (UINTN) fclose (OutFile); - if (Results != 0) { - printf ("FCLOSE failed\n"); - } - - free (Buffer); - free (EvaluationStack); - - return EFI_INVALID_PARAMETER; - } - - NotDone = TRUE; - - while ((Index--) && NotDone) { - - if (*Ptrx == ' ') { - Ptrx++; - } else if (*Ptrx == '\n' || *Ptrx == '\r') { - Ptrx++; - } else if (strncmp (Ptrx, OPERATOR_SOR, strlen (OPERATOR_SOR)) == 0) { - // - // Checks for some invalid dependencies - // - if (Before_Flag) { - - printf ("A BEFORE operator was detected.\n"); - printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); - return EFI_INVALID_PARAMETER; - - } else if (After_Flag) { - - printf ("An AFTER operator was detected.\n"); - printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); - return EFI_INVALID_PARAMETER; - - } else if (SOR_Flag) { - - printf ("Another SOR operator was detected.\n"); - printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); - return EFI_INVALID_PARAMETER; - - } else if (Dep_Flag) { - - printf ("The Schedule On Request - SOR operator must be the first operator following DEPENDENCY_START\n"); - return EFI_INVALID_PARAMETER; - - } else { - // - // BUGBUG - This was not in the spec but is in the CORE code - // An OPERATOR_SOR has to be first - following the DEPENDENCY_START - // - fputc (EFI_DEP_SOR, OutFile); - OutFileSize++; - Ptrx += sizeof (OPERATOR_SOR); - SOR_Flag = TRUE; - - } - } else if (strncmp (Ptrx, OPERATOR_BEFORE, strlen (OPERATOR_BEFORE)) == 0) { - // - // Checks for some invalid dependencies - // - if (Before_Flag) { - - printf ("Another BEFORE operator was detected.\n"); - printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); - return EFI_INVALID_PARAMETER; - - } else if (After_Flag) { - - printf ("An AFTER operator was detected.\n"); - printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); - return EFI_INVALID_PARAMETER; - - } else if (SOR_Flag) { - - printf ("A SOR operator was detected.\n"); - printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); - return EFI_INVALID_PARAMETER; - - } else if (Dep_Flag) { - - printf ("The BEFORE operator must be the first operator following DEPENDENCY_START\n"); - return EFI_INVALID_PARAMETER; - - } else { - fputc (EFI_DEP_BEFORE, OutFile); - OutFileSize++; - Ptrx += sizeof (OPERATOR_BEFORE); - Before_Flag = TRUE; - } - } else if (strncmp (Ptrx, OPERATOR_AFTER, strlen (OPERATOR_AFTER)) == 0) { - // - // Checks for some invalid dependencies - // - if (Before_Flag) { - - printf ("A BEFORE operator was detected.\n"); - printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); - return EFI_INVALID_PARAMETER; - - } else if (After_Flag) { - - printf ("Another AFTER operator was detected.\n"); - printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); - return EFI_INVALID_PARAMETER; - - } else if (SOR_Flag) { - - printf ("A SOR operator was detected.\n"); - printf ("There can only be one SOR or one AFTER or one BEFORE operator\n"); - return EFI_INVALID_PARAMETER; - - } else if (Dep_Flag) { - - printf ("The AFTER operator must be the first operator following DEPENDENCY_START\n"); - return EFI_INVALID_PARAMETER; - - } else { - fputc (EFI_DEP_AFTER, OutFile); - OutFileSize++; - Ptrx += sizeof (OPERATOR_AFTER); - Dep_Flag = TRUE; - After_Flag = TRUE; - } - } else if (strncmp (Ptrx, OPERATOR_AND, strlen (OPERATOR_AND)) == 0) { - while (StackPtr != EvaluationStack) { - Opcode = PopOpCode ((VOID **) &StackPtr); - if (Opcode != DXE_DEP_LEFT_PARENTHESIS) { - fputc (Opcode, OutFile); - OutFileSize++; - } else { - PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS); - break; - } - } - - PushOpCode ((VOID **) &StackPtr, EFI_DEP_AND); - Ptrx += sizeof (OPERATOR_AND); - Dep_Flag = TRUE; - - } else if (strncmp (Ptrx, OPERATOR_OR, strlen (OPERATOR_OR)) == 0) { - while (StackPtr != EvaluationStack) { - Opcode = PopOpCode ((VOID **) &StackPtr); - if (Opcode != DXE_DEP_LEFT_PARENTHESIS) { - fputc (Opcode, OutFile); - OutFileSize++; - } else { - PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS); - break; - } - } - - PushOpCode ((VOID **) &StackPtr, EFI_DEP_OR); - Ptrx += sizeof (OPERATOR_OR); - Dep_Flag = TRUE; - - } else if (strncmp (Ptrx, OPERATOR_NOT, strlen (OPERATOR_NOT)) == 0) { - while (StackPtr != EvaluationStack) { - Opcode = PopOpCode ((VOID **) &StackPtr); - if (Opcode != DXE_DEP_LEFT_PARENTHESIS) { - fputc (Opcode, OutFile); - OutFileSize++; - } else { - PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS); - break; - } - } - - PushOpCode ((VOID **) &StackPtr, EFI_DEP_NOT); - Ptrx += sizeof (OPERATOR_NOT); - Dep_Flag = TRUE; - - } else if (*Ptrx == '\t') { - - printf ("File contains tabs. This violates the coding standard\n"); - return EFI_INVALID_PARAMETER; - - } else if (*Ptrx == '\n') { - // - // Skip the newline character in the file - // - Ptrx++; - - } else if (strncmp (Ptrx, OPERATOR_LEFT_PARENTHESIS, strlen (OPERATOR_LEFT_PARENTHESIS)) == 0) { - PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS); - - Ptrx += strlen (OPERATOR_LEFT_PARENTHESIS); - Dep_Flag = TRUE; - - } else if (strncmp (Ptrx, OPERATOR_RIGHT_PARENTHESIS, strlen (OPERATOR_RIGHT_PARENTHESIS)) == 0) { - while (StackPtr != EvaluationStack) { - Opcode = PopOpCode ((VOID **) &StackPtr); - if (Opcode != DXE_DEP_LEFT_PARENTHESIS) { - fputc (Opcode, OutFile); - OutFileSize++; - } else { - break; - } - } - - Ptrx += strlen (OPERATOR_RIGHT_PARENTHESIS); - Dep_Flag = TRUE; - - } else if (strncmp (Ptrx, OPERATOR_TRUE, strlen (OPERATOR_TRUE)) == 0) { - - fputc (EFI_DEP_TRUE, OutFile); - - OutFileSize++; - - // - // OutFileSize += sizeof (EFI_DEP_TRUE); - // - Dep_Flag = TRUE; - - Ptrx += strlen (OPERATOR_TRUE); - - } else if (strncmp (Ptrx, OPERATOR_FALSE, strlen (OPERATOR_FALSE)) == 0) { - - fputc (EFI_DEP_FALSE, OutFile); - - OutFileSize++; - - // - // OutFileSize += sizeof (EFI_DEP_FALSE); - // - Dep_Flag = TRUE; - - Ptrx += strlen (OPERATOR_FALSE); - - } else if (*Ptrx == '{') { - Ptrx++; - - if (*Ptrx == ' ') { - Ptrx++; - } - - { - int byte_index; - // This is an array of UINT32s. sscanf will trash memory - // if you try to read into a UINT8 with a %x formatter. - UINT32 Guid_Data4[8]; - - ArgCountParsed = sscanf ( - Ptrx, - "%x, %x, %x, { %x, %x, %x, %x, %x, %x, %x, %x }", - &Guid.Data1, - &Guid.Data2, - &Guid.Data3, - &Guid_Data4[0], - &Guid_Data4[1], - &Guid_Data4[2], - &Guid_Data4[3], - &Guid_Data4[4], - &Guid_Data4[5], - &Guid_Data4[6], - &Guid_Data4[7] - ); - - // Now we can copy the 32 bit ints into the GUID. - for (byte_index=0; byte_index<8; byte_index++) { - Guid.Data4[byte_index] = (UINT8) Guid_Data4[byte_index]; - } - } - - if (ArgCountParsed != 11) { - printf ("We have found an illegal GUID\n"); - printf ("Fix your depex\n"); - exit (-1); - } - - while (*Ptrx != '}') { - Ptrx++; - } - - Ptrx++; - while (*Ptrx != '}') { - Ptrx++; - } - // - // Absorb the closing } - // - Ptrx++; - - // - // Don't provide a PUSH Opcode for the Before and After case - // - if ((!Before_Flag) && (!After_Flag)) { - fputc (EFI_DEP_PUSH, OutFile); - OutFileSize++; - } - - fwrite (&Guid, sizeof (EFI_GUID), 1, OutFile); - - OutFileSize += sizeof (EFI_GUID); - Dep_Flag = TRUE; - - } else if (strncmp (Ptrx, DEPENDENCY_END, strlen (DEPENDENCY_END)) == 0) { - NotDone = FALSE; - } else { - // - // Not a valid construct. Null terminate somewhere out there and - // print an error message. - // - *(Ptrx + 20) = 0; - printf (TOOL_NAME " ERROR: Unrecognized input at: \"%s\"...\n", Ptrx); - return EFI_INVALID_PARAMETER; - } - } - // - // DRAIN(); - // - while (StackPtr != EvaluationStack) { - fputc (PopOpCode ((VOID **) &StackPtr), OutFile); - OutFileSize++; - } - - if (OutFileSize == 0) { - printf ("Grammer contains no operators or constants\n"); - return EFI_INVALID_PARAMETER; - } - - fputc (EFI_DEP_END, OutFile); - - OutFileSize++; - - // - // Checks for invalid padding values - // - if (Padding < 0) { - - printf ("The inputted padding value was %d\n", Padding); - printf ("The optional padding value can not be less than ZERO\n"); - return EFI_INVALID_PARAMETER; - - } else if (Padding > 0) { - - while ((OutFileSize % Padding) != 0) { - - fputc (' ', OutFile); - OutFileSize++; - } - } - - Results = (UINTN) fclose (InFile); - if (Results != 0) { - printf ("FCLOSE failed\n"); - } - - Results = (UINTN) fclose (OutFile); - if (Results != 0) { - printf ("FCLOSE failed\n"); - } - - free (Buffer); - free (EvaluationStack); - - return EFI_SUCCESS; -} // End GenerateDependencyExpression function - -int -main ( - IN UINTN argc, - IN CHAR8 *argv[] - ) -/*++ - -Routine Description: - - Parse user entries. Print some rudimentary help - -Arguments: - - argc The count of input arguments - argv The input arguments string array - -Returns: - - EFI_SUCCESS The function completed successfully. - EFI_INVALID_PARAMETER One of the input parameters was invalid or one of the parameters in the text file was invalid. - EFI_OUT_OF_RESOURCES Unable to allocate memory. - EFI_ABORTED Unable to open/create a file or a misc error. - ---*/ -// TODO: ] - add argument and description to function comment -{ - FILE *OutFile; - FILE *InFile; - UINT8 Padding; - UINTN Index; - BOOLEAN Input_Flag; - BOOLEAN Output_Flag; - BOOLEAN Pad_Flag; - - InFile = NULL; - OutFile = NULL; - Padding = 0; - Input_Flag = FALSE; - Output_Flag = FALSE; - Pad_Flag = FALSE; - - if (argc < 5) { - printf ("Not enough arguments\n"); - PrintGenDepexUsageInfo (); - return EFI_INVALID_PARAMETER; - } - - for (Index = 1; Index < argc - 1; Index++) { - - if ((strcmp (argv[Index], "-I") == 0) || (strcmp (argv[Index], "-i") == 0)) { - - if (!Input_Flag) { - - InFile = fopen (argv[Index + 1], "rb"); - Input_Flag = TRUE; - - } else { - printf ("GenDepex only allows one INPUT (-I) argument\n"); - return EFI_INVALID_PARAMETER; - } - - } else if ((strcmp (argv[Index], "-O") == 0) || (strcmp (argv[Index], "-o") == 0)) { - - if (!Output_Flag) { - - OutFile = fopen (argv[Index + 1], "wb"); - Output_Flag = TRUE; - - } else { - printf ("GenDepex only allows one OUTPUT (-O) argument\n"); - return EFI_INVALID_PARAMETER; - } - - } else if ((strcmp (argv[Index], "-P") == 0) || (strcmp (argv[Index], "-p") == 0)) { - - if (!Pad_Flag) { - - Padding = (UINT8) atoi (argv[Index + 1]); - Pad_Flag = TRUE; - - } else { - printf ("GenDepex only allows one PADDING (-P) argument\n"); - return EFI_INVALID_PARAMETER; - } - } - } - - PrintGenDepexUtilityInfo (); - - if (InFile == NULL) { - printf ("Can not open for reading.\n"); - PrintGenDepexUsageInfo (); - return EFI_ABORTED; - } - - if (OutFile == NULL) { - printf ("Can not open for writting.\n"); - PrintGenDepexUsageInfo (); - return EFI_ABORTED; - } - - return GenerateDependencyExpression (InFile, OutFile, Padding); -} diff --git a/Tools/CodeTools/TianoTools/GenDepex/GenDepex.h b/Tools/CodeTools/TianoTools/GenDepex/GenDepex.h deleted file mode 100644 index b198156baa..0000000000 --- a/Tools/CodeTools/TianoTools/GenDepex/GenDepex.h +++ /dev/null @@ -1,71 +0,0 @@ -/*++ -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: - GenDepex.h - - Abstract: - This file contains the relevant declarations required - to generate a binary Dependency File - - Complies with Tiano C Coding Standards Document, version 0.31, 12 Dec 2000. - ---*/ - -#ifndef _EFI_GEN_DEPEX_H -#define _EFI_GEN_DEPEX_H - - -#include -#include -#include -#include -#ifndef __GNUC__ -#include -#endif - -#include -#include - -#define DEPENDENCY_START "DEPENDENCY_START" -#define OPERATOR_BEFORE "BEFORE" -#define OPERATOR_AFTER "AFTER" -#define OPERATOR_AND "AND" -#define OPERATOR_OR "OR" -#define OPERATOR_NOT "NOT" -#define OPERATOR_TRUE "TRUE" -#define OPERATOR_FALSE "FALSE" -#define OPERATOR_SOR "SOR" -#define OPERATOR_END "END" -#define OPERATOR_LEFT_PARENTHESIS "(" -#define OPERATOR_RIGHT_PARENTHESIS ")" -#define DEPENDENCY_END "DEPENDENCY_END" - -#define DXE_DEP_LEFT_PARENTHESIS 0x0a -#define DXE_DEP_RIGHT_PARENTHESIS 0x0b - -#define LINESIZE 320 -#define SIZE_A_SYMBOL 60 -#define DEPENDENCY_OPCODE UINT8 -#define EVAL_STACK_SIZE 0x1024 -#define BUFFER_SIZE 0x100 - -// -// Utility Name -// -#define UTILITY_NAME "GenDepex" - -// -// Utility version information -// -#define UTILITY_MAJOR_VERSION 0 -#define UTILITY_MINOR_VERSION 5 - -#endif diff --git a/Tools/CodeTools/TianoTools/GenDepex/build.xml b/Tools/CodeTools/TianoTools/GenDepex/build.xml deleted file mode 100644 index 568177aa03..0000000000 --- a/Tools/CodeTools/TianoTools/GenDepex/build.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/GenFfsFile/GenFfsFile.c b/Tools/CodeTools/TianoTools/GenFfsFile/GenFfsFile.c deleted file mode 100644 index 1eea09f5fb..0000000000 --- a/Tools/CodeTools/TianoTools/GenFfsFile/GenFfsFile.c +++ /dev/null @@ -1,2646 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - GenFfsFile.c - -Abstract: - - This file contains functions required to generate a Firmware File System - file. - ---*/ - -#include -#include // for isalpha() -// -// include file for _spawnv -// -#ifndef __GNUC__ -#include -#endif -#include -#include - -#include -#include -#include -#include -#include - -#include "ParseInf.h" -#include "EfiCompress.h" -#include "EfiCustomizedCompress.h" -#include "Crc32.h" -#include "GenFfsFile.h" -#include "CommonLib.h" -#include "EfiUtilityMsgs.h" -#include "SimpleFileParsing.h" - -#define UTILITY_NAME "GenFfsFile" -#define TOOLVERSION "0.32" -#define MAX_ARRAY_SIZE 100 - -static -INT32 -GetNextLine ( - OUT CHAR8 *Destination, - IN FILE *Package, - IN OUT UINT32 *LineNumber - ); - -static -void -CheckSlash ( - IN OUT CHAR8 *String, - IN FILE *In, - IN OUT UINT32 *LineNumber - ); - -static -INT32 -FindSectionInPackage ( - IN CHAR8 *BuildDirectory, - IN FILE *OverridePackage, - IN OUT UINT32 *LineNumber - ); - -static -STATUS -ProcessCommandLineArgs ( - int Argc, - char *Argv[] - ); - -static -void -PrintUsage ( - void - ); - -// -// Keep globals in this structure -// -static struct { - UINT8 BuildDirectory[_MAX_PATH]; - UINT8 PrimaryPackagePath[_MAX_PATH]; - UINT8 OverridePackagePath[_MAX_PATH]; - BOOLEAN Verbose; -} mGlobals; - -static EFI_GUID mZeroGuid = { 0 }; - -static -void -StripQuotes ( - IN OUT CHAR8 *String - ) -/*++ - -Routine Description: - - Removes quotes and/or whitespace from around a string - -Arguments: - - String - String to remove quotes from - -Returns: - - None - ---*/ -{ - UINTN Index; - UINTN Index2; - UINTN StrLen; - - Index2 = strspn (String, "\" \t\n"); - StrLen = strlen (String); - - for (Index = Index2; String[Index] != '\"', Index < StrLen; Index++) { - String[Index - Index2] = String[Index]; - } - - String[Index - Index2] = 0; -} - -static -void -PrintUsage ( - void - ) -/*++ - -Routine Description: - - Print Error / Help message. - -Arguments: - - void - -Returns: - - None - ---*/ -{ - printf ("Usage:\n"); - printf (UTILITY_NAME " -b \"build directory\" -p1 \"package1.inf\" -p2 \"package2.inf\" -v\n"); - printf (" -b \"build directory\":\n "); - printf (" specifies the full path to the component build directory.\n"); - printf (" -p1 \"P1_path\":\n"); - printf (" specifies fully qualified file name to the primary package file.\n"); - printf (" This file will normally exist in the same directory as the makefile\n"); - printf (" for the component. Required.\n"); - printf (" -p2 \"P2_path\":\n"); - printf (" specifies fully qualified file name to the override package file.\n"); - printf (" This file will normally exist in the build tip. Optional.\n"); -} - -static -INT32 -TestComment ( - IN CHAR8 *String, - IN FILE *In - ) -/*++ - -Routine Description: - - Tests input string to see if it is a comment, and if so goes to the next line in the file that is not a comment - -Arguments: - - String - String to test - - In - Open file to move pointer within - -Returns: - - -1 - End of file reached - 0 - Not a comment - 1 - Comment bypassed - ---*/ -{ - CHAR8 CharBuffer; - - CharBuffer = 0; - if ((String[0] == '/') && (String[1] == '/')) { - while (CharBuffer != '\n') { - fscanf (In, "%c", &CharBuffer); - if (feof (In)) { - return -1; - } - } - } else { - return 0; - } - - return 1; -} - -static -void -BreakString ( - IN CONST CHAR8 *Source, - OUT CHAR8 *Destination, - IN INTN Direction - ) -/*++ - -Routine Description: - - Takes an input string and returns either the part before the =, or the part after the =, depending on direction - -Arguments: - - Source - String to break - - Destination - Buffer to place new string in - - Direction - 0 to return all of source string before = - 1 to return all of source string after = - -Returns: - - None - ---*/ -{ - UINTN Index; - UINTN Index2; - - Index = 0; - Index2 = 0; - - if (strchr (Source, '=') == NULL) { - strcpy (Destination, Source); - - return ; - } - - if (Direction == 0) { - // - // return part of string before = - // - while (Source[Index] != '=') { - Destination[Index] = Source[Index++]; - } - - Destination[Index] = 0; - } else { - // - // return part of string after = - // - strcpy (Destination, strchr (Source, '=') + 1); - } -} - -static -INT32 -GetNextLine ( - OUT CHAR8 *Destination, - IN FILE *Package, - IN OUT UINT32 *LineNumber - ) -/*++ - -Routine Description: - - Gets the next non-commented line from the file - -Arguments: - - Destination - Where to put string - - Package - Package to get string from - - LineNumber - The actual line number. - -Returns: - - -1 - End of file reached - 0 - Success - ---*/ -{ - CHAR8 String[_MAX_PATH]; - fscanf (Package, "%s", &String); - if (feof (Package)) { - return -1; - } - - while (TestComment (String, Package) == 1) { - fscanf (Package, "%s", &String); - if (feof (Package)) { - return -1; - } - } - - strcpy (Destination, String); - return 0; -} - -static -VOID -CheckSlash ( - IN OUT CHAR8 *String, - IN FILE *In, - IN OUT UINT32 *LineNumber - ) -/*++ - -Routine Description: - - Checks to see if string is line continuation character, if so goes to next valid line - -Arguments: - - String - String to test - - In - Open file to move pointer within - - LineNumber - The line number. - -Returns: - - None - ---*/ -{ - CHAR8 ByteBuffer; - ByteBuffer = 0; - - switch (String[0]) { - - case '\\': - while (String[0] == '\\') { - while (ByteBuffer != '\n') { - fscanf (In, "%c", &ByteBuffer); - } - (*LineNumber)++; - if (GetNextLine (String, In, LineNumber) == -1) { - return ; - } - } - break; - - case '\n': - (*LineNumber)++; - while (String[0] == '\n') { - if (GetNextLine (String, In, LineNumber) == -1) { - return ; - } - } - break; - - default: - break; - - } - -} - -static -INT32 -FindSectionInPackage ( - IN CHAR8 *BuildDirectory, - IN FILE *OverridePackage, - IN OUT UINT32 *LineNumber - ) -/*++ - -Routine Description: - - Finds the matching section within the package - -Arguments: - - BuildDirectory - name of section to find - - OverridePackage - Package file to search within - - LineNumber - The line number. - -Returns: - - -1 - End of file reached - 0 - Success - ---*/ -{ - CHAR8 String[_MAX_PATH]; - CHAR8 NewString[_MAX_PATH]; - String[0] = 0; - - while (strcmp (BuildDirectory, String) != 0) { - if (GetNextLine (NewString, OverridePackage, LineNumber) != 0) { - return -1; - } - - if (NewString[0] == '[') { - if (NewString[strlen (NewString) - 1] != ']') { - // - // have to construct string. - // - strcpy (String, NewString + 1); - - while (1) { - fscanf (OverridePackage, "%s", &NewString); - if (feof (OverridePackage)) { - return -1; - } - - if (NewString[0] != ']') { - if (strlen (String) != 0) { - strcat (String, " "); - } - - strcat (String, NewString); - if (String[strlen (String) - 1] == ']') { - String[strlen (String) - 1] = 0; - break; - } - } else { - break; - } - } - } else { - NewString[strlen (NewString) - 1] = 0; - strcpy (String, NewString + 1); - } - } - } - - return 0; -} - -static -EFI_STATUS -GenSimpleGuidSection ( - IN OUT UINT8 *FileBuffer, - IN OUT UINT32 *BufferSize, - IN UINT32 DataSize, - IN EFI_GUID SignGuid, - IN UINT16 GuidedSectionAttributes - ) -/*++ - -Routine Description: - - add GUIDed section header for the data buffer. - data stays in same location (overwrites source data). - -Arguments: - - FileBuffer - Buffer containing data to sign - - BufferSize - On input, the size of FileBuffer. On output, the size of - actual section data (including added section header). - - DataSize - Length of data to Sign - - SignGuid - Guid to be add. - - GuidedSectionAttributes - The section attribute. - -Returns: - - EFI_SUCCESS - Successful - EFI_OUT_OF_RESOURCES - Not enough resource. - ---*/ -{ - UINT32 TotalSize; - - EFI_GUID_DEFINED_SECTION GuidSectionHeader; - UINT8 *SwapBuffer; - - SwapBuffer = NULL; - - if (DataSize == 0) { - *BufferSize = 0; - - return EFI_SUCCESS; - } - - TotalSize = DataSize + sizeof (EFI_GUID_DEFINED_SECTION); - GuidSectionHeader.CommonHeader.Type = EFI_SECTION_GUID_DEFINED; - GuidSectionHeader.CommonHeader.Size[0] = (UINT8) (TotalSize & 0xff); - GuidSectionHeader.CommonHeader.Size[1] = (UINT8) ((TotalSize & 0xff00) >> 8); - GuidSectionHeader.CommonHeader.Size[2] = (UINT8) ((TotalSize & 0xff0000) >> 16); - memcpy (&(GuidSectionHeader.SectionDefinitionGuid), &SignGuid, sizeof (EFI_GUID)); - GuidSectionHeader.Attributes = GuidedSectionAttributes; - GuidSectionHeader.DataOffset = sizeof (EFI_GUID_DEFINED_SECTION); - - SwapBuffer = (UINT8 *) malloc (DataSize); - if (SwapBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - memcpy (SwapBuffer, FileBuffer, DataSize); - memcpy (FileBuffer, &GuidSectionHeader, sizeof (EFI_GUID_DEFINED_SECTION)); - memcpy (FileBuffer + sizeof (EFI_GUID_DEFINED_SECTION), SwapBuffer, DataSize); - - // - // Make sure section ends on a DWORD boundary - // - while ((TotalSize & 0x03) != 0) { - FileBuffer[TotalSize] = 0; - TotalSize++; - } - - *BufferSize = TotalSize; - - if (SwapBuffer != NULL) { - free (SwapBuffer); - } - - return EFI_SUCCESS; -} - -static -EFI_STATUS -CompressSection ( - UINT8 *FileBuffer, - UINT32 *BufferSize, - UINT32 DataSize, - CHAR8 *Type - ) -/*++ - -Routine Description: - - Compress the data and add section header for the compressed data. - Compressed data (with section header) stays in same location as the source - (overwrites source data). - -Arguments: - - FileBuffer - Buffer containing data to Compress - - BufferSize - On input, the size of FileBuffer. On output, the size of - actual compressed data (including added section header). - When buffer is too small, this value indicates the size needed. - - DataSize - The size of data to compress - - Type - The compression type (not used currently). - Assume EFI_HEAVY_COMPRESSION. - -Returns: - - EFI_BUFFER_TOO_SMALL - Buffer size is too small. - EFI_UNSUPPORTED - Compress type can not be supported. - EFI_SUCCESS - Successful - EFI_OUT_OF_RESOURCES - Not enough resource. - ---*/ -{ - EFI_STATUS Status; - UINT8 *CompData; - UINT32 CompSize; - UINT32 TotalSize; - EFI_COMPRESSION_SECTION CompressionSet; - UINT8 CompressionType; - COMPRESS_FUNCTION CompressFunction; - - Status = EFI_SUCCESS; - CompData = NULL; - CompSize = 0; - TotalSize = 0; - CompressFunction = NULL; - - // - // Get the compress type - // - if (strcmpi (Type, "Dummy") == 0) { - // - // Added "Dummy" to keep backward compatibility. - // - CompressionType = EFI_STANDARD_COMPRESSION; - CompressFunction = (COMPRESS_FUNCTION) Compress; - - } else if (strcmpi (Type, "LZH") == 0) { - // - // EFI stardard compression (LZH) - // - CompressionType = EFI_STANDARD_COMPRESSION; - CompressFunction = (COMPRESS_FUNCTION) Compress; - - } else { - // - // Customized compression - // - Status = SetCustomizedCompressionType (Type); - if (EFI_ERROR (Status)) { - return Status; - } - - CompressionType = EFI_CUSTOMIZED_COMPRESSION; - CompressFunction = (COMPRESS_FUNCTION) CustomizedCompress; - } - // - // Compress the raw data - // - Status = CompressFunction (FileBuffer, DataSize, CompData, &CompSize); - if (Status == EFI_BUFFER_TOO_SMALL) { - CompData = malloc (CompSize); - if (!CompData) { - return EFI_OUT_OF_RESOURCES; - } - - Status = CompressFunction (FileBuffer, DataSize, CompData, &CompSize); - } - - if (EFI_ERROR (Status)) { - if (CompData != NULL) { - free (CompData); - } - - return Status; - } - - TotalSize = CompSize + sizeof (EFI_COMPRESSION_SECTION); - - // - // Buffer too small? - // - if (TotalSize > *BufferSize) { - *BufferSize = TotalSize; - if (CompData != NULL) { - free (CompData); - } - - return EFI_BUFFER_TOO_SMALL; - } - // - // Add the section header for the compressed data - // - CompressionSet.CommonHeader.Type = EFI_SECTION_COMPRESSION; - CompressionSet.CommonHeader.Size[0] = (UINT8) (TotalSize & 0xff); - CompressionSet.CommonHeader.Size[1] = (UINT8) ((TotalSize & 0xff00) >> 8); - CompressionSet.CommonHeader.Size[2] = (UINT8) ((TotalSize & 0xff0000) >> 16); - CompressionSet.CompressionType = CompressionType; - CompressionSet.UncompressedLength = DataSize; - - // - // Copy header and data to the buffer - // - memcpy (FileBuffer, &CompressionSet, sizeof (EFI_COMPRESSION_SECTION)); - memcpy (FileBuffer + sizeof (CompressionSet), CompData, CompSize); - - // - // Make sure section ends on a DWORD boundary - // - while ((TotalSize & 0x03) != 0) { - FileBuffer[TotalSize] = 0; - TotalSize++; - } - - *BufferSize = TotalSize; - - if (CompData != NULL) { - free (CompData); - } - - return EFI_SUCCESS; -} - -static -void -StripParens ( - IN OUT CHAR8 *String - ) -/*++ - -Routine Description: - - Removes Parenthesis from around a string - -Arguments: - - String - String to remove parens from - -Returns: - - None - ---*/ -{ - INT32 Index; - - if (String[0] != '(') { - return ; - } - - for (Index = 1; String[Index] != ')'; Index++) { - String[Index - 1] = String[Index]; - if (String[Index] == 0) { - return ; - } - } - - String[Index - 1] = 0; - - return ; -} - -static -void -StripEqualMark ( - IN OUT CHAR8 *String - ) -/*++ - -Routine Description: - - Removes Equal Mark from around a string - -Arguments: - - String - String to remove equal mark from - -Returns: - - None - ---*/ -{ - INT32 Index; - - if (String[0] != '=' && String[strlen (String) - 1] != '=') { - return ; - } - - if (String[0] == '=') { - - for (Index = 1; String[Index] != 0; Index++) { - String[Index - 1] = String[Index]; - } - - String[Index - 1] = 0; - } - - if (String[strlen (String) - 1] == '=') { - String[strlen (String) - 1] = 0; - } - - return ; -} - -static -INT32 -ProcessEnvironmentVariable ( - IN CHAR8 *Buffer, - OUT CHAR8 *NewBuffer - ) -/*++ - -Routine Description: - - Converts environment variables to values - -Arguments: - - Buffer - Buffer containing Environment Variable String - - NewBuffer - Buffer containing value of environment variable - - -Returns: - - Number of characters from Buffer used - ---*/ -{ - INT32 Index; - INT32 Index2; - CHAR8 VariableBuffer[_MAX_PATH]; - - Index = 2; - Index2 = 0; - - while (Buffer[Index] != ')') { - VariableBuffer[Index - 2] = Buffer[Index++]; - } - - VariableBuffer[Index - 2] = 0; - Index++; - - if (getenv (VariableBuffer) != NULL) { - strcpy (NewBuffer, getenv (VariableBuffer)); - } else { - printf ("Environment variable %s not found!\n", VariableBuffer); - } - - return Index; -} - -static -void -SplitAttributesField ( - IN CHAR8 *Buffer, - IN CHAR8 *AttributesArray[], - IN OUT UINT32 *NumberOfAttributes - ) -/* - NumberOfAttributes: on input, it specifies the current number of attributes - stored in AttributeArray. - on output, it is updated to the latest number of attributes - stored in AttributesArray. -*/ -{ - UINT32 Index; - UINT32 Index2; - UINT32 z; - CHAR8 *CharBuffer; - - CharBuffer = NULL; - CharBuffer = (CHAR8 *) malloc (_MAX_PATH); - ZeroMem (CharBuffer, _MAX_PATH); - - for (Index = 0, z = 0, Index2 = 0; Index < strlen (Buffer); Index++) { - - if (Buffer[Index] != '|') { - CharBuffer[z] = Buffer[Index]; - z++; - } else { - - CharBuffer[z] = 0; - AttributesArray[*NumberOfAttributes + Index2] = CharBuffer; - Index2++; - - // - // allocate new char buffer for the next attributes string - // - CharBuffer = (CHAR8 *) malloc (_MAX_PATH); - ZeroMem (CharBuffer, _MAX_PATH); - z = 0; - } - } - - CharBuffer[z] = 0; - // - // record the last attributes string in the Buffer - // - AttributesArray[*NumberOfAttributes + Index2] = CharBuffer; - Index2++; - - *NumberOfAttributes += Index2; - - return ; -} - -static -INT32 -GetToolArguments ( - CHAR8 *ToolArgumentsArray[], - FILE *Package, - CHAR8 **PtrInputFileName, - CHAR8 **PtrOutputFileName, - EFI_GUID *Guid, - UINT16 *GuidedSectionAttributes - ) -{ - CHAR8 Buffer[_MAX_PATH]; - BOOLEAN ArgumentsFlag; - BOOLEAN InputFlag; - BOOLEAN OutputFlag; - BOOLEAN GuidFlag; - BOOLEAN AttributesFlag; - UINT32 argc; - UINT32 Index2; - UINT32 z; - CHAR8 *CharBuffer; - INT32 Index; - INT32 ReturnValue; - EFI_STATUS Status; - - CHAR8 *AttributesArray[MAX_ARRAY_SIZE]; - UINT32 NumberOfAttributes; - CHAR8 *InputFileName; - CHAR8 *OutputFileName; - UINT32 LineNumber; - Buffer[_MAX_PATH]; - - ArgumentsFlag = FALSE; - InputFlag = FALSE; - OutputFlag = FALSE; - GuidFlag = FALSE; - AttributesFlag = FALSE; - // - // Start at 1, since ToolArgumentsArray[0] - // is the program name. - // - argc = 1; - Index2 = 0; - - z = 0; - ReturnValue = 0; - NumberOfAttributes = 0; - InputFileName = NULL; - OutputFileName = NULL; - - ZeroMem (Buffer, _MAX_PATH); - ZeroMem (AttributesArray, sizeof (CHAR8 *) * MAX_ARRAY_SIZE); - LineNumber = 0; - while (Buffer[0] != ')') { - - if (GetNextLine (Buffer, Package, &LineNumber) != -1) { - CheckSlash (Buffer, Package, &LineNumber); - StripEqualMark (Buffer); - } else { - Error (NULL, 0, 0, "failed to get next line from package file", NULL); - return -1; - } - - if (Buffer[0] == ')') { - break; - } else if (strcmpi (Buffer, "ARGS") == 0) { - - ArgumentsFlag = TRUE; - AttributesFlag = FALSE; - continue; - - } else if (strcmpi (Buffer, "INPUT") == 0) { - - InputFlag = TRUE; - ArgumentsFlag = FALSE; - AttributesFlag = FALSE; - continue; - - } else if (strcmpi (Buffer, "OUTPUT") == 0) { - - OutputFlag = TRUE; - ArgumentsFlag = FALSE; - AttributesFlag = FALSE; - continue; - - } else if (strcmpi (Buffer, "GUID") == 0) { - - GuidFlag = TRUE; - ArgumentsFlag = FALSE; - AttributesFlag = FALSE; - // - // fetch the GUID for the section - // - continue; - - } else if (strcmpi (Buffer, "ATTRIBUTES") == 0) { - - AttributesFlag = TRUE; - ArgumentsFlag = FALSE; - // - // fetch the GUIDed Section's Attributes - // - continue; - - } else if (strcmpi (Buffer, "") == 0) { - continue; - } - // - // get all command arguments into ToolArgumentsArray - // - if (ArgumentsFlag) { - - StripEqualMark (Buffer); - - CharBuffer = (CHAR8 *) malloc (_MAX_PATH); - if (CharBuffer == NULL) { - goto ErrorExit; - } - - ZeroMem (CharBuffer, sizeof (_MAX_PATH)); - - ToolArgumentsArray[argc] = CharBuffer; - - if (Buffer[0] == '$') { - Index = ProcessEnvironmentVariable (&Buffer[0], ToolArgumentsArray[argc]); - // - // if there is string after the environment variable, cat it. - // - if ((UINT32) Index < strlen (Buffer)) { - strcat (ToolArgumentsArray[argc], &Buffer[Index]); - } - } else { - strcpy (ToolArgumentsArray[argc], Buffer); - } - - argc += 1; - ToolArgumentsArray[argc] = NULL; - continue; - } - - if (InputFlag) { - - StripEqualMark (Buffer); - - InputFileName = (CHAR8 *) malloc (_MAX_PATH); - if (InputFileName == NULL) { - goto ErrorExit; - } - - ZeroMem (InputFileName, sizeof (_MAX_PATH)); - - if (Buffer[0] == '$') { - Index = ProcessEnvironmentVariable (&Buffer[0], InputFileName); - // - // if there is string after the environment variable, cat it. - // - if ((UINT32) Index < strlen (Buffer)) { - strcat (InputFileName, &Buffer[Index]); - } - } else { - strcpy (InputFileName, Buffer); - } - - InputFlag = FALSE; - continue; - } - - if (OutputFlag) { - - StripEqualMark (Buffer); - - OutputFileName = (CHAR8 *) malloc (_MAX_PATH); - if (OutputFileName == NULL) { - goto ErrorExit; - } - - ZeroMem (OutputFileName, sizeof (_MAX_PATH)); - - if (Buffer[0] == '$') { - Index = ProcessEnvironmentVariable (&Buffer[0], OutputFileName); - // - // if there is string after the environment variable, cat it. - // - if ((UINT32) Index < strlen (Buffer)) { - strcat (OutputFileName, &Buffer[Index]); - } - } else { - strcpy (OutputFileName, Buffer); - } - - OutputFlag = FALSE; - continue; - } - - if (GuidFlag) { - - StripEqualMark (Buffer); - - Status = StringToGuid (Buffer, Guid); - if (EFI_ERROR (Status)) { - ReturnValue = -1; - goto ErrorExit; - } - - GuidFlag = FALSE; - } - - if (AttributesFlag) { - - StripEqualMark (Buffer); - - // - // there might be no space between each attribute in the statement, - // split them aside and return each attribute string - // in the AttributesArray - // - SplitAttributesField (Buffer, AttributesArray, &NumberOfAttributes); - } - } - // - // ReplaceVariableInBuffer (ToolArgumentsArray,&i,"INPUT",InputVariable,j); - // ReplaceVariableInBuffer (ToolArgumentsArray,&i,"OUTPUT",&TargetFileName,1); - // - for (z = 0; z < NumberOfAttributes; z++) { - if (strcmpi (AttributesArray[z], "PROCESSING_REQUIRED") == 0) { - *GuidedSectionAttributes |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED; - } else if (strcmpi (AttributesArray[z], "AUTH_STATUS_VALID") == 0) { - *GuidedSectionAttributes |= EFI_GUIDED_SECTION_AUTH_STATUS_VALID; - } - } - -ErrorExit: - - for (Index2 = 0; Index2 < MAX_ARRAY_SIZE; Index2++) { - if (AttributesArray[Index2] == NULL) { - break; - } - - free (AttributesArray[Index2]); - } - - *PtrInputFileName = InputFileName; - *PtrOutputFileName = OutputFileName; - - return ReturnValue; -} - -static -INT32 -ProcessScript ( - IN OUT UINT8 *FileBuffer, - IN FILE *Package, - IN CHAR8 *BuildDirectory, - IN BOOLEAN ForceUncompress - ) -/*++ - -Routine Description: - - Signs the section, data stays in same location - -Arguments: - - FileBuffer - Data Buffer - - Package - Points to curly brace in Image Script - - BuildDirectory - Name of the source directory parameter - - ForceUncompress - Whether to force uncompress. - -Returns: - - Number of bytes added to file buffer - -1 on error - ---*/ -{ - EFI_STATUS Status; - UINT32 Size; - CHAR8 Buffer[_MAX_PATH]; - CHAR8 Type[_MAX_PATH]; - CHAR8 FileName[_MAX_PATH]; - CHAR8 NewBuffer[_MAX_PATH]; - INT32 Index3; - INT32 Index2; - UINT32 ReturnValue; - UINT8 ByteBuffer; - FILE *InFile; - UINT32 SourceDataSize; - CHAR8 *ToolArgumentsArray[MAX_ARRAY_SIZE]; - CHAR8 *OutputFileName; - CHAR8 *InputFileName; - CHAR8 ToolName[_MAX_PATH]; - FILE *OutputFile; - FILE *InputFile; - UINT8 Temp; - int returnint; - INT32 Index; - UINT32 LineNumber; - BOOLEAN IsError; - EFI_GUID SignGuid; - UINT16 GuidedSectionAttributes; - UINT8 *TargetFileBuffer; - - OutputFileName = NULL; - InputFileName = NULL; - OutputFile = NULL; - InputFile = NULL; - IsError = FALSE; - GuidedSectionAttributes = 0; - TargetFileBuffer = NULL; - - Size = 0; - LineNumber = 0; - Buffer[0] = 0; - for (Index3 = 0; Index3 < MAX_ARRAY_SIZE; ++Index3) { - ToolArgumentsArray[Index3] = NULL; - } - - while (Buffer[0] != '}') { - if (GetNextLine (Buffer, Package, &LineNumber) != -1) { - CheckSlash (Buffer, Package, &LineNumber); - } else { - printf ("ERROR in IMAGE SCRIPT!\n"); - IsError = TRUE; - goto Done; - } - - if (strcmpi (Buffer, "Compress") == 0) { - // - // Handle compress - // - // - // read compression type - // - if (GetNextLine (Buffer, Package, &LineNumber) != -1) { - CheckSlash (Buffer, Package, &LineNumber); - } - - StripParens (Buffer); - if (Buffer[0] == '$') { - ProcessEnvironmentVariable (&Buffer[0], Type); - } else { - strcpy (Type, Buffer); - } - // - // build buffer - // - while (Buffer[0] != '{') { - if (GetNextLine (Buffer, Package, &LineNumber) != -1) { - CheckSlash (Buffer, Package, &LineNumber); - } - } - - ReturnValue = ProcessScript (&FileBuffer[Size], Package, BuildDirectory, ForceUncompress); - if (ReturnValue == -1) { - IsError = TRUE; - goto Done; - } - // - // Call compress routine on buffer. - // Occasionally, compressed data + section header would - // be largere than the source and EFI_BUFFER_TOO_SMALL is - // returned from CompressSection() - // - SourceDataSize = ReturnValue; - - if (!ForceUncompress) { - - Status = CompressSection ( - &FileBuffer[Size], - &ReturnValue, - SourceDataSize, - Type - ); - - if (Status == EFI_BUFFER_TOO_SMALL) { - Status = CompressSection ( - &FileBuffer[Size], - &ReturnValue, - SourceDataSize, - Type - ); - } - - if (EFI_ERROR (Status)) { - IsError = TRUE; - goto Done; - } - } - - Size += ReturnValue; - - } else if (strcmpi (Buffer, "Tool") == 0) { - - ZeroMem (ToolName, _MAX_PATH); - ZeroMem (ToolArgumentsArray, sizeof (CHAR8 *) * MAX_ARRAY_SIZE); - ZeroMem (&SignGuid, sizeof (EFI_GUID)); - - // - // handle signing Tool - // - while (Buffer[0] != '(') { - if (GetNextLine (Buffer, Package, &LineNumber) != -1) { - CheckSlash (Buffer, Package, &LineNumber); - } - } - - if (strcmpi (Buffer, "(") == 0) { - if (GetNextLine (Buffer, Package, &LineNumber) != -1) { - CheckSlash (Buffer, Package, &LineNumber); - } - } - - StripParens (Buffer); - - if (Buffer[0] == '$') { - Index = ProcessEnvironmentVariable (&Buffer[0], ToolName); - // - // if there is string after the environment variable, cat it. - // - if ((UINT32) Index < strlen (Buffer)) { - strcat (ToolName, &Buffer[Index]); - } - } else { - strcpy (ToolName, Buffer); - } - - ToolArgumentsArray[0] = ToolName; - - // - // read ARGS - // - if (GetToolArguments ( - ToolArgumentsArray, - Package, - &InputFileName, - &OutputFileName, - &SignGuid, - &GuidedSectionAttributes - ) == -1) { - IsError = TRUE; - goto Done; - } - // - // if the tool need input file, - // dump the file buffer to the specified input file. - // - if (InputFileName != NULL) { - InputFile = fopen (InputFileName, "wb"); - if (InputFile == NULL) { - Error (NULL, 0, 0, InputFileName, "failed to open output file for writing"); - IsError = TRUE; - goto Done; - } - - fwrite (FileBuffer, sizeof (UINT8), Size, InputFile); - fclose (InputFile); - InputFile = NULL; - free (InputFileName); - InputFileName = NULL; - } - // - // dispatch signing tool - // -#ifdef __GNUC__ - { - char CommandLine[1000]; - sprintf(CommandLine, "%s %s", ToolName, ToolArgumentsArray); - returnint = system(CommandLine); - } -#else - returnint = _spawnv (_P_WAIT, ToolName, ToolArgumentsArray); -#endif - if (returnint != 0) { - Error (NULL, 0, 0, ToolName, "external tool failed"); - IsError = TRUE; - goto Done; - } - // - // if the tool has output file, - // dump the output file to the file buffer - // - if (OutputFileName != NULL) { - - OutputFile = fopen (OutputFileName, "rb"); - if (OutputFile == NULL) { - Error (NULL, 0, 0, OutputFileName, "failed to open output file for writing"); - IsError = TRUE; - goto Done; - } - - TargetFileBuffer = &FileBuffer[Size]; - SourceDataSize = Size; - - fread (&Temp, sizeof (UINT8), 1, OutputFile); - while (!feof (OutputFile)) { - FileBuffer[Size++] = Temp; - fread (&Temp, sizeof (UINT8), 1, OutputFile); - } - - while ((Size & 0x03) != 0) { - FileBuffer[Size] = 0; - Size++; - } - - SourceDataSize = Size - SourceDataSize; - - fclose (OutputFile); - OutputFile = NULL; - free (OutputFileName); - OutputFileName = NULL; - - if (CompareGuid (&SignGuid, &mZeroGuid) != 0) { - ReturnValue = SourceDataSize; - Status = GenSimpleGuidSection ( - TargetFileBuffer, - &ReturnValue, - SourceDataSize, - SignGuid, - GuidedSectionAttributes - ); - if (EFI_ERROR (Status)) { - IsError = TRUE; - goto Done; - } - - Size = ReturnValue; - } - } - - } else if (Buffer[0] != '}') { - // - // if we are here, we should see either a file name, - // or a }. - // - Index3 = 0; - FileName[0] = 0; - // - // Prepend the build directory to the file name if the - // file name does not already contain a full path. - // - if (!isalpha (Buffer[0]) || (Buffer[1] != ':')) { - sprintf (FileName, "%s\\", BuildDirectory); - } - - while (Buffer[Index3] != '\n') { - if (Buffer[Index3] == '$') { - Index3 += ProcessEnvironmentVariable (&Buffer[Index3], NewBuffer); - strcat (FileName, NewBuffer); - } - - if (Buffer[Index3] == 0) { - break; - } else { - Index2 = strlen (FileName); - FileName[Index2++] = Buffer[Index3++]; - FileName[Index2] = 0; - } - } - - InFile = fopen (FileName, "rb"); - if (InFile == NULL) { - Error (NULL, 0, 0, FileName, "failed to open file for reading"); - IsError = TRUE; - goto Done; - } - - fread (&ByteBuffer, sizeof (UINT8), 1, InFile); - while (!feof (InFile)) { - FileBuffer[Size++] = ByteBuffer; - fread (&ByteBuffer, sizeof (UINT8), 1, InFile); - } - - fclose (InFile); - InFile = NULL; - - // - // Make sure section ends on a DWORD boundary - // - while ((Size & 0x03) != 0) { - FileBuffer[Size] = 0; - Size++; - } - - } - } - -Done: - for (Index3 = 1; Index3 < MAX_ARRAY_SIZE; Index3++) { - if (ToolArgumentsArray[Index3] == NULL) { - break; - } - - free (ToolArgumentsArray[Index3]); - } - - if (IsError) { - return -1; - } - - return Size; - -} - -static -UINT8 -StringToType ( - IN CHAR8 *String - ) -/*++ - -Routine Description: - - Converts File Type String to value. EFI_FV_FILETYPE_ALL indicates that an - unrecognized file type was specified. - -Arguments: - - String - File type string - -Returns: - - File Type Value - ---*/ -{ - if (strcmpi (String, "EFI_FV_FILETYPE_RAW") == 0) { - return EFI_FV_FILETYPE_RAW; - } - - if (strcmpi (String, "EFI_FV_FILETYPE_FREEFORM") == 0) { - return EFI_FV_FILETYPE_FREEFORM; - } - - if (strcmpi (String, "EFI_FV_FILETYPE_SECURITY_CORE") == 0) { - return EFI_FV_FILETYPE_SECURITY_CORE; - } - - if (strcmpi (String, "EFI_FV_FILETYPE_PEI_CORE") == 0) { - return EFI_FV_FILETYPE_PEI_CORE; - } - - if (strcmpi (String, "EFI_FV_FILETYPE_DXE_CORE") == 0) { - return EFI_FV_FILETYPE_DXE_CORE; - } - - if (strcmpi (String, "EFI_FV_FILETYPE_PEIM") == 0) { - return EFI_FV_FILETYPE_PEIM; - } - - if (strcmpi (String, "EFI_FV_FILETYPE_DRIVER") == 0) { - return EFI_FV_FILETYPE_DRIVER; - } - - if (strcmpi (String, "EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER") == 0) { - return EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER; - } - - if (strcmpi (String, "EFI_FV_FILETYPE_APPLICATION") == 0) { - return EFI_FV_FILETYPE_APPLICATION; - } - - if (strcmpi (String, "EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE") == 0) { - return EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE; - } - - return EFI_FV_FILETYPE_ALL; -} - -static -UINT32 -AdjustFileSize ( - IN UINT8 *FileBuffer, - IN UINT32 FileSize - ) -/*++ - -Routine Description: - Adjusts file size to insure sectioned file is exactly the right length such - that it ends on exactly the last byte of the last section. ProcessScript() - may have padded beyond the end of the last section out to a 4 byte boundary. - This padding is stripped. - -Arguments: - FileBuffer - Data Buffer - contains a section stream - FileSize - Size of FileBuffer as returned from ProcessScript() - -Returns: - Corrected size of file. - ---*/ -{ - UINT32 TotalLength; - UINT32 CurrentLength; - UINT32 SectionLength; - UINT32 SectionStreamLength; - EFI_COMMON_SECTION_HEADER *SectionHeader; - EFI_COMMON_SECTION_HEADER *NextSectionHeader; - - TotalLength = 0; - CurrentLength = 0; - SectionStreamLength = FileSize; - - SectionHeader = (EFI_COMMON_SECTION_HEADER *) FileBuffer; - - while (TotalLength < SectionStreamLength) { - SectionLength = *((UINT32 *) SectionHeader->Size) & 0x00ffffff; - TotalLength += SectionLength; - - if (TotalLength == SectionStreamLength) { - return TotalLength; - } - // - // Move to the next byte following the section... - // - SectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) SectionHeader + SectionLength); - CurrentLength = (UINTN) SectionHeader - (UINTN) FileBuffer; - - // - // Figure out where the next section begins - // - NextSectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) SectionHeader + 3); - NextSectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) NextSectionHeader &~ (UINTN) 3); - TotalLength += (UINTN) NextSectionHeader - (UINTN) SectionHeader; - SectionHeader = NextSectionHeader; - } - - return CurrentLength; -} - -static -INT32 -MainEntry ( - INT32 argc, - CHAR8 *argv[], - BOOLEAN ForceUncompress - ) -/*++ - -Routine Description: - - MainEntry function. - -Arguments: - - argc - Number of command line parameters. - argv - Array of pointers to command line parameter strings. - ForceUncompress - If TRUE, force to do not compress the sections even if compression - is specified in the script. Otherwise, FALSE. - -Returns: - STATUS_SUCCESS - Function exits successfully. - STATUS_ERROR - Some error occurred during execution. - ---*/ -{ - FILE *PrimaryPackage; - FILE *OverridePackage; - FILE *Out; - CHAR8 BaseName[_MAX_PATH]; - EFI_GUID FfsGuid; - CHAR8 GuidString[_MAX_PATH]; - EFI_FFS_FILE_HEADER FileHeader; - CHAR8 FileType[_MAX_PATH]; - EFI_FFS_FILE_ATTRIBUTES FfsAttrib; - EFI_FFS_FILE_ATTRIBUTES FfsAttribDefined; - UINT64 FfsAlignment; - UINT32 FfsAlignment32; - CHAR8 InputString[_MAX_PATH]; - BOOLEAN ImageScriptInOveride; - UINT32 FileSize; - UINT8 *FileBuffer; - EFI_STATUS Status; - UINT32 LineNumber; - EFI_FFS_FILE_TAIL TailValue; - - BaseName[0] = 0; - FileType[0] = 0; - FfsAttrib = 0; - FfsAttribDefined = 0; - FfsAlignment = 0; - FfsAlignment32 = 0; - PrimaryPackage = NULL; - Out = NULL; - OverridePackage = NULL; - FileBuffer = NULL; - - strcpy (GuidString, "00000000-0000-0000-0000-000000000000"); - Status = StringToGuid (GuidString, &FfsGuid); - if (Status != 0) { - Error (NULL, 0, 0, GuidString, "error parsing GUID string"); - return STATUS_ERROR; - } - - GuidString[0] = 0; - ImageScriptInOveride = FALSE; - // - // Initialize the simple file parsing routines. Then open - // the primary package file for parsing. - // - SFPInit (); - if (SFPOpenFile (mGlobals.PrimaryPackagePath) != STATUS_SUCCESS) { - Error (NULL, 0, 0, mGlobals.PrimaryPackagePath, "unable to open primary package file"); - goto Done; - } - // - // First token in the file must be "PACKAGE.INF" - // - if (!SFPIsToken ("PACKAGE.INF")) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'PACKAGE.INF'", NULL); - goto Done; - } - // - // Find the [.] section - // - if (!SFPSkipToToken ("[.]")) { - Error (mGlobals.PrimaryPackagePath, 1, 0, "could not locate [.] section in package file", NULL); - goto Done; - } - // - // Start parsing the data. The algorithm is essentially the same for each keyword: - // 1. Identify the keyword - // 2. Verify that the keyword/value pair has not already been defined - // 3. Set some flag indicating that the keyword/value pair has been defined - // 4. Skip over the "=" - // 5. Get the value, which may be a number, TRUE, FALSE, or a string. - // - while (1) { - if (SFPIsToken ("BASE_NAME")) { - // - // Found BASE_NAME, format: - // BASE_NAME = MyBaseName - // - if (BaseName[0] != 0) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "BASE_NAME already defined", NULL); - goto Done; - } - - if (!SFPIsToken ("=")) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL); - goto Done; - } - - if (!SFPGetNextToken (BaseName, sizeof (BaseName))) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected valid base name", NULL); - goto Done; - } - } else if (SFPIsToken ("IMAGE_SCRIPT")) { - // - // Found IMAGE_SCRIPT. Break out and process below. - // - break; - } else if (SFPIsToken ("FFS_FILEGUID")) { - // - // found FILEGUID, format: - // FFS_FILEGUID = F7845C4F-EDF5-42C5-BD8F-A02AF63DD93A - // - if (GuidString[0] != 0) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_FILEGUID already defined", NULL); - goto Done; - } - - if (!SFPIsToken ("=")) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL); - goto Done; - } - - if (SFPGetGuidToken (GuidString, sizeof (GuidString)) != TRUE) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected file GUID", NULL); - goto Done; - } - - Status = StringToGuid (GuidString, &FfsGuid); - if (Status != 0) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected valid file GUID", NULL); - goto Done; - } - } else if (SFPIsToken ("FFS_FILETYPE")) { - // - // *********************************************************************** - // - // Found FFS_FILETYPE, format: - // FFS_FILETYPE = EFI_FV_FILETYPE_APPLICATION - // - if (FileType[0] != 0) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_FILETYPE previously defined", NULL); - goto Done; - } - - if (!SFPIsToken ("=")) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL); - goto Done; - } - - if (!SFPGetNextToken (FileType, sizeof (FileType))) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected valid FFS_FILETYPE", NULL); - goto Done; - } - } else if (SFPIsToken ("FFS_ATTRIB_HEADER_EXTENSION")) { - // - // *********************************************************************** - // - // Found: FFS_ATTRIB_HEADER_EXTENSION = FALSE - // Spec says the bit is for future expansion, and must be false. - // - if (FfsAttribDefined & FFS_ATTRIB_HEADER_EXTENSION) { - Error ( - mGlobals.PrimaryPackagePath, - SFPGetLineNumber (), - 0, - "FFS_ATTRIB_HEADER_EXTENSION previously defined", - NULL - ); - goto Done; - } - - FfsAttribDefined |= FFS_ATTRIB_HEADER_EXTENSION; - if (!SFPIsToken ("=")) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL); - goto Done; - } - - if (SFPIsToken ("TRUE")) { - Error ( - mGlobals.PrimaryPackagePath, - SFPGetLineNumber (), - 0, - "only FFS_ATTRIB_HEADER_EXTENSION = FALSE is supported", - NULL - ); - goto Done; - } else if (SFPIsToken ("FALSE")) { - // - // Default is FALSE - // - } else { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'FALSE'", NULL); - goto Done; - } - } else if (SFPIsToken ("FFS_ATTRIB_TAIL_PRESENT")) { - // - // *********************************************************************** - // - // Found: FFS_ATTRIB_TAIL_PRESENT = TRUE | FALSE - // - if (FfsAttribDefined & FFS_ATTRIB_TAIL_PRESENT) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_ATTRIB_TAIL_PRESENT previously defined", NULL); - goto Done; - } - - FfsAttribDefined |= FFS_ATTRIB_TAIL_PRESENT; - if (!SFPIsToken ("=")) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL); - goto Done; - } - - if (SFPIsToken ("TRUE")) { - FfsAttrib |= FFS_ATTRIB_TAIL_PRESENT; - } else if (SFPIsToken ("FALSE")) { - // - // Default is FALSE - // - } else { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL); - goto Done; - } - } else if (SFPIsToken ("FFS_ATTRIB_RECOVERY")) { - // - // *********************************************************************** - // - // Found: FFS_ATTRIB_RECOVERY = TRUE | FALSE - // - if (FfsAttribDefined & FFS_ATTRIB_RECOVERY) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_ATTRIB_RECOVERY previously defined", NULL); - goto Done; - } - - FfsAttribDefined |= FFS_ATTRIB_RECOVERY; - if (!SFPIsToken ("=")) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL); - goto Done; - } - - if (SFPIsToken ("TRUE")) { - FfsAttrib |= FFS_ATTRIB_RECOVERY; - } else if (SFPIsToken ("FALSE")) { - // - // Default is FALSE - // - } else { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL); - goto Done; - } - } else if (SFPIsToken ("FFS_ATTRIB_CHECKSUM")) { - // - // *********************************************************************** - // - // Found: FFS_ATTRIB_CHECKSUM = TRUE | FALSE - // - if (FfsAttribDefined & FFS_ATTRIB_CHECKSUM) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "FFS_ATTRIB_CHECKSUM previously defined", NULL); - goto Done; - } - - FfsAttribDefined |= FFS_ATTRIB_CHECKSUM; - if (!SFPIsToken ("=")) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL); - goto Done; - } - - if (SFPIsToken ("TRUE")) { - FfsAttrib |= FFS_ATTRIB_CHECKSUM; - } else if (SFPIsToken ("FALSE")) { - // - // Default is FALSE - // - } else { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 'TRUE' or 'FALSE'", NULL); - goto Done; - } - } else if (SFPIsToken ("FFS_ALIGNMENT") || SFPIsToken ("FFS_ATTRIB_DATA_ALIGNMENT")) { - // - // *********************************************************************** - // - // Found FFS_ALIGNMENT, formats: - // FFS_ALIGNMENT = 0-7 - // FFS_ATTRIB_DATA_ALIGNMENT = 0-7 - // - if (FfsAttribDefined & FFS_ATTRIB_DATA_ALIGNMENT) { - Error ( - mGlobals.PrimaryPackagePath, - SFPGetLineNumber (), - 0, - "FFS_ALIGNMENT/FFS_ATTRIB_DATA_ALIGNMENT previously defined", - NULL - ); - goto Done; - } - - FfsAttribDefined |= FFS_ATTRIB_DATA_ALIGNMENT; - if (!SFPIsToken ("=")) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected '='", NULL); - goto Done; - } - - if (!SFPGetNumber (&FfsAlignment32)) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected numeric value for alignment", NULL); - goto Done; - } - - if (FfsAlignment32 > 7) { - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, "expected 0 <= alignment <= 7", NULL); - goto Done; - } - - FfsAttrib |= (((EFI_FFS_FILE_ATTRIBUTES) FfsAlignment32) << 3); - } else { - SFPGetNextToken (InputString, sizeof (InputString)); - Error (mGlobals.PrimaryPackagePath, SFPGetLineNumber (), 0, InputString, "unrecognized/unexpected token"); - goto Done; - } - } - // - // Close the primary package file - // - SFPCloseFile (); - // - // TODO: replace code below with basically a copy of the code above. Don't - // forget to reset the FfsAttribDefined variable first. Also, you'll need - // to somehow keep track of whether or not the basename is defined multiple - // times in the override package. Ditto on the file GUID. - // - if (mGlobals.OverridePackagePath[0] != 0) { - OverridePackage = fopen (mGlobals.OverridePackagePath, "r"); - // - // NOTE: For package override to work correctly, the code below must be modified to - // SET or CLEAR bits properly. For example, if the primary package set - // FFS_ATTRIB_CHECKSUM = TRUE, and the override set FFS_ATTRIB_CHECKSUM = FALSE, then - // we'd need to clear the bit below. Since this is not happening, I'm guessing that - // the override functionality is not being used, so should be made obsolete. If I'm - // wrong, and it is being used, then it needs to be fixed. Thus emit an error if it is - // used, and we'll address it then. 4/10/2003 - // - Error (__FILE__, __LINE__, 0, "package override functionality is not implemented correctly", NULL); - goto Done; - } else { - OverridePackage = NULL; - } - -#ifdef OVERRIDE_SUPPORTED - if (OverridePackage != NULL) { - // - // Parse override package file - // - fscanf (OverridePackage, "%s", &InputString); - if (strcmpi (InputString, "PACKAGE.INF") != 0) { - Error (mGlobals.OverridePackagePath, 1, 0, "invalid package file", "expected 'PACKAGE.INF'"); - goto Done; - } - // - // Match [dir] to Build Directory - // - if (FindSectionInPackage (mGlobals.BuildDirectory, OverridePackage, &LineNumber) != 0) { - Error (mGlobals.OverridePackagePath, 1, 0, mGlobals.BuildDirectory, "section not found in package file"); - goto Done; - } - - InputString[0] = 0; - while ((InputString[0] != '[') && (!feof (OverridePackage))) { - if (GetNextLine (InputString, OverridePackage, &LineNumber) != -1) { - if (InputString[0] != '[') { -here: - if (strcmpi (InputString, "BASE_NAME") == 0) { - // - // found BASE_NAME, next is = and string. - // - fscanf (OverridePackage, "%s", &InputString); - CheckSlash (InputString, OverridePackage, &LineNumber); - if (strlen (InputString) == 1) { - // - // string is just = - // - fscanf (OverridePackage, "%s", &InputString); - CheckSlash (InputString, OverridePackage, &LineNumber); - strcpy (BaseName, InputString); - } else { - BreakString (InputString, InputString, 1); - strcpy (BaseName, InputString); - } - } else if (strcmpi (InputString, "IMAGE_SCRIPT") == 0) { - // - // found IMAGE_SCRIPT, come back later to process it - // - ImageScriptInOveride = TRUE; - fscanf (OverridePackage, "%s", &InputString); - } else if (strcmpi (InputString, "FFS_FILEGUID") == 0) { - // - // found FILEGUID, next is = and string. - // - fscanf (OverridePackage, "%s", &InputString); - CheckSlash (InputString, OverridePackage, &LineNumber); - if (strlen (InputString) == 1) { - // - // string is just = - // - fscanf (OverridePackage, "%s", &InputString); - CheckSlash (InputString, OverridePackage, &LineNumber); - Status = StringToGuid (InputString, &FfsGuid); - if (Status != 0) { - Error (mGlobals.OverridePackagePath, 1, 0, InputString, "bad FFS_FILEGUID format"); - goto Done; - } - } else { - BreakString (InputString, InputString, 1); - Status = StringToGuid (InputString, &FfsGuid); - if (Status != 0) { - Error (mGlobals.OverridePackagePath, 1, 0, InputString, "bad FFS_FILEGUID format"); - goto Done; - } - } - } else if (strcmpi (InputString, "FFS_FILETYPE") == 0) { - // - // found FILETYPE, next is = and string. - // - fscanf (OverridePackage, "%s", &InputString); - CheckSlash (InputString, OverridePackage, &LineNumber); - if (strlen (InputString) == 1) { - // - // string is just = - // - fscanf (OverridePackage, "%s", &InputString); - CheckSlash (InputString, OverridePackage, &LineNumber); - strcpy (FileType, InputString); - } else { - BreakString (InputString, InputString, 1); - strcpy (FileType, InputString); - } - - } else if (strcmpi (InputString, "FFS_ATTRIB_RECOVERY") == 0) { - // - // found FFS_ATTRIB_RECOVERY, next is = and string. - // - fscanf (OverridePackage, "%s", &InputString); - CheckSlash (InputString, OverridePackage, &LineNumber); - if (strlen (InputString) == 1) { - // - // string is just = - // - fscanf (OverridePackage, "%s", &InputString); - CheckSlash (InputString, OverridePackage, &LineNumber); - if (strcmpi (InputString, "TRUE") == 0) { - FfsAttrib |= FFS_ATTRIB_RECOVERY; - } - } else { - BreakString (InputString, InputString, 1); - if (strcmpi (InputString, "TRUE") == 0) { - FfsAttrib |= FFS_ATTRIB_RECOVERY; - } - } - } else if (strcmpi (InputString, "FFS_ATTRIB_CHECKSUM") == 0) { - // - // found FFS_ATTRIB_CHECKSUM, next is = and string. - // - fscanf (OverridePackage, "%s", &InputString); - CheckSlash (InputString, OverridePackage, &LineNumber); - if (strlen (InputString) == 1) { - // - // string is just = - // - fscanf (OverridePackage, "%s", &InputString); - CheckSlash (InputString, OverridePackage, &LineNumber); - if (strcmpi (InputString, "TRUE") == 0) { - FfsAttrib |= FFS_ATTRIB_CHECKSUM; - } - } else { - BreakString (InputString, InputString, 1); - if (strcmpi (InputString, "TRUE") == 0) { - FfsAttrib |= FFS_ATTRIB_CHECKSUM; - } - } - } else if (strcmpi (InputString, "FFS_ALIGNMENT") == 0) { - // - // found FFS_ALIGNMENT, next is = and string. - // - fscanf (OverridePackage, "%s", &InputString); - CheckSlash (InputString, OverridePackage, &LineNumber); - if (strlen (InputString) == 1) { - // - // string is just = - // - fscanf (OverridePackage, "%s", &InputString); - CheckSlash (InputString, OverridePackage, &LineNumber); - } else { - BreakString (InputString, InputString, 1); - } - - AsciiStringToUint64 (InputString, FALSE, &FfsAlignment); - if (FfsAlignment > 7) { - Error (mGlobals.OverridePackagePath, 1, 0, InputString, "invalid FFS_ALIGNMENT value"); - goto Done; - } - - FfsAttrib |= (((EFI_FFS_FILE_ATTRIBUTES) FfsAlignment) << 3); - } else if (strchr (InputString, '=') != NULL) { - BreakString (InputString, String, 1); - fseek (OverridePackage, (-1 * (strlen (String) + 1)), SEEK_CUR); - BreakString (InputString, InputString, 0); - goto here; - } - } - } - } - } -#endif // #ifdef OVERRIDE_SUPPORTED - // - // Require that they specified a file GUID at least, since that's how we're - // naming the file. - // - if (GuidString[0] == 0) { - Error (mGlobals.PrimaryPackagePath, 1, 0, "FFS_FILEGUID must be specified", NULL); - return STATUS_ERROR; - } - // - // Build Header and process image script - // - FileBuffer = (UINT8 *) malloc ((1024 * 1024 * 16) * sizeof (UINT8)); - if (FileBuffer == NULL) { - Error (__FILE__, __LINE__, 0, "memory allocation failed", NULL); - goto Done; - } - - FileSize = 0; - if (ImageScriptInOveride) { -#ifdef OVERRIDE_SUPORTED - rewind (OverridePackage); - LineNumber = 0; - FindSectionInPackage (mGlobals.BuildDirectory, OverridePackage, &LineNumber); - while (strcmpi (InputString, "IMAGE_SCRIPT") != 0) { - GetNextLine (InputString, OverridePackage, &LineNumber); - CheckSlash (InputString, OverridePackage, &LineNumber); - if (strchr (InputString, '=') != NULL) { - BreakString (InputString, InputString, 0); - } - } - - while (InputString[0] != '{') { - GetNextLine (InputString, OverridePackage, &LineNumber); - CheckSlash (InputString, OverridePackage, &LineNumber); - } - // - // Found start of image script, process it - // - FileSize += ProcessScript (FileBuffer, OverridePackage, mGlobals.BuildDirectory, ForceUncompress); - if (FileSize == -1) { - return -1; - } - - if (StringToType (FileType) != EFI_FV_FILETYPE_RAW) { - FileSize = AdjustFileSize (FileBuffer, FileSize); - } - - if (BaseName[0] == '\"') { - StripQuotes (BaseName); - } - - if (BaseName[0] != 0) { - sprintf (InputString, "%s-%s", GuidString, BaseName); - } else { - strcpy (InputString, GuidString); - } - - switch (StringToType (FileType)) { - - case EFI_FV_FILETYPE_SECURITY_CORE: - strcat (InputString, ".SEC"); - break; - - case EFI_FV_FILETYPE_PEIM: - case EFI_FV_FILETYPE_PEI_CORE: - case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER: - strcat (InputString, ".PEI"); - break; - - case EFI_FV_FILETYPE_DRIVER: - case EFI_FV_FILETYPE_DXE_CORE: - strcat (InputString, ".DXE"); - break; - - case EFI_FV_FILETYPE_APPLICATION: - strcat (InputString, ".APP"); - break; - - case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE: - strcat (InputString, ".FVI"); - break; - - case EFI_FV_FILETYPE_ALL: - Error (mGlobals.OverridePackagePath, 1, 0, "invalid FFS file type for this utility", NULL); - goto Done; - - default: - strcat (InputString, ".FFS"); - break; - } - - if (ForceUncompress) { - strcat (InputString, ".ORG"); - } - - Out = fopen (InputString, "wb"); - if (Out == NULL) { - Error (NULL, 0, 0, InputString, "could not open output file for writing"); - goto Done; - } - // - // create ffs header - // - memset (&FileHeader, 0, sizeof (EFI_FFS_FILE_HEADER)); - memcpy (&FileHeader.Name, &FfsGuid, sizeof (EFI_GUID)); - FileHeader.Type = StringToType (FileType); - FileHeader.Attributes = FfsAttrib; - // - // Now FileSize includes the EFI_FFS_FILE_HEADER - // - FileSize += sizeof (EFI_FFS_FILE_HEADER); - FileHeader.Size[0] = (UINT8) (FileSize & 0xFF); - FileHeader.Size[1] = (UINT8) ((FileSize & 0xFF00) >> 8); - FileHeader.Size[2] = (UINT8) ((FileSize & 0xFF0000) >> 16); - // - // Fill in checksums and state, these must be zero for checksumming - // - // FileHeader.IntegrityCheck.Checksum.Header = 0; - // FileHeader.IntegrityCheck.Checksum.File = 0; - // FileHeader.State = 0; - // - FileHeader.IntegrityCheck.Checksum.Header = CalculateChecksum8 ( - (UINT8 *) &FileHeader, - sizeof (EFI_FFS_FILE_HEADER) - ); - if (FileHeader.Attributes & FFS_ATTRIB_CHECKSUM) { - FileHeader.IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) &FileHeader, FileSize); - } else { - FileHeader.IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; - } - - FileHeader.State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID; - // - // write header - // - if (fwrite (&FileHeader, sizeof (FileHeader), 1, Out) != 1) { - Error (NULL, 0, 0, "failed to write file header to output file", NULL); - goto Done; - } - // - // write data - // - if (fwrite (FileBuffer, FileSize - sizeof (EFI_FFS_FILE_HEADER), 1, Out) != 1) { - Error (NULL, 0, 0, "failed to write all bytes to output file", NULL); - goto Done; - } - - fclose (Out); - Out = NULL; -#endif // #ifdef OVERRIDE_SUPPORTED - } else { - // - // Open primary package file and process the IMAGE_SCRIPT section - // - PrimaryPackage = fopen (mGlobals.PrimaryPackagePath, "r"); - if (PrimaryPackage == NULL) { - Error (NULL, 0, 0, mGlobals.PrimaryPackagePath, "unable to open primary package file"); - goto Done; - } - - LineNumber = 1; - FindSectionInPackage (".", PrimaryPackage, &LineNumber); - while (strcmpi (InputString, "IMAGE_SCRIPT") != 0) { - GetNextLine (InputString, PrimaryPackage, &LineNumber); - CheckSlash (InputString, PrimaryPackage, &LineNumber); - if (strchr (InputString, '=') != NULL) { - BreakString (InputString, InputString, 0); - } - } - - while (InputString[0] != '{') { - GetNextLine (InputString, PrimaryPackage, &LineNumber); - CheckSlash (InputString, PrimaryPackage, &LineNumber); - } - // - // Found start of image script, process it - // - FileSize += ProcessScript (FileBuffer, PrimaryPackage, mGlobals.BuildDirectory, ForceUncompress); - if (FileSize == -1) { - goto Done; - } - - if (StringToType (FileType) != EFI_FV_FILETYPE_RAW) { - FileSize = AdjustFileSize (FileBuffer, FileSize); - } - - if (BaseName[0] == '\"') { - StripQuotes (BaseName); - } - - if (BaseName[0] != 0) { - sprintf (InputString, "%s-%s", GuidString, BaseName); - } else { - strcpy (InputString, GuidString); - } - - switch (StringToType (FileType)) { - - case EFI_FV_FILETYPE_SECURITY_CORE: - strcat (InputString, ".SEC"); - break; - - case EFI_FV_FILETYPE_PEIM: - case EFI_FV_FILETYPE_PEI_CORE: - case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER: - strcat (InputString, ".PEI"); - break; - - case EFI_FV_FILETYPE_DRIVER: - case EFI_FV_FILETYPE_DXE_CORE: - strcat (InputString, ".DXE"); - break; - - case EFI_FV_FILETYPE_APPLICATION: - strcat (InputString, ".APP"); - break; - - case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE: - strcat (InputString, ".FVI"); - break; - - case EFI_FV_FILETYPE_ALL: - Error (mGlobals.PrimaryPackagePath, 1, 0, "invalid FFS file type for this utility", NULL); - goto Done; - - default: - strcat (InputString, ".FFS"); - break; - } - - if (ForceUncompress) { - strcat (InputString, ".ORG"); - } - - Out = fopen (InputString, "wb"); - if (Out == NULL) { - Error (NULL, 0, 0, InputString, "failed to open output file for writing"); - goto Done; - } - // - // Initialize the FFS file header - // - memset (&FileHeader, 0, sizeof (EFI_FFS_FILE_HEADER)); - memcpy (&FileHeader.Name, &FfsGuid, sizeof (EFI_GUID)); - FileHeader.Type = StringToType (FileType); - FileHeader.Attributes = FfsAttrib; - // - // From this point on FileSize includes the size of the EFI_FFS_FILE_HEADER - // - FileSize += sizeof (EFI_FFS_FILE_HEADER); - // - // If using a tail, then it adds two bytes - // - if (FileHeader.Attributes & FFS_ATTRIB_TAIL_PRESENT) { - // - // Tail is not allowed for pad and 0-length files - // - if ((FileHeader.Type == EFI_FV_FILETYPE_FFS_PAD) || (FileSize == sizeof (EFI_FFS_FILE_HEADER))) { - Error ( - mGlobals.PrimaryPackagePath, - 1, - 0, - "FFS_ATTRIB_TAIL_PRESENT=TRUE is invalid for PAD or 0-length files", - NULL - ); - goto Done; - } - - FileSize += sizeof (EFI_FFS_FILE_TAIL); - } - - FileHeader.Size[0] = (UINT8) (FileSize & 0xFF); - FileHeader.Size[1] = (UINT8) ((FileSize & 0xFF00) >> 8); - FileHeader.Size[2] = (UINT8) ((FileSize & 0xFF0000) >> 16); - // - // Fill in checksums and state, they must be 0 for checksumming. - // - // FileHeader.IntegrityCheck.Checksum.Header = 0; - // FileHeader.IntegrityCheck.Checksum.File = 0; - // FileHeader.State = 0; - // - FileHeader.IntegrityCheck.Checksum.Header = CalculateChecksum8 ( - (UINT8 *) &FileHeader, - sizeof (EFI_FFS_FILE_HEADER) - ); - if (FileHeader.Attributes & FFS_ATTRIB_CHECKSUM) { - // - // Cheating here. Since the header checksums, just calculate the checksum of the body. - // Checksum does not include the tail - // - if (FileHeader.Attributes & FFS_ATTRIB_TAIL_PRESENT) { - FileHeader.IntegrityCheck.Checksum.File = CalculateChecksum8 ( - FileBuffer, - FileSize - sizeof (EFI_FFS_FILE_HEADER) - sizeof (EFI_FFS_FILE_TAIL) - ); - } else { - FileHeader.IntegrityCheck.Checksum.File = CalculateChecksum8 ( - FileBuffer, - FileSize - sizeof (EFI_FFS_FILE_HEADER) - ); - } - } else { - FileHeader.IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; - } - // - // Set the state now. Spec says the checksum assumes the state is 0 - // - FileHeader.State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID; - // - // If there is a tail, then set it - // - if (FileHeader.Attributes & FFS_ATTRIB_TAIL_PRESENT) { - TailValue = FileHeader.IntegrityCheck.TailReference; - TailValue = (UINT16) (~TailValue); - memcpy ( - (UINT8 *) FileBuffer + FileSize - sizeof (EFI_FFS_FILE_HEADER) - sizeof (EFI_FFS_FILE_TAIL), - &TailValue, - sizeof (TailValue) - ); - } - // - // Write the FFS file header - // - if (fwrite (&FileHeader, sizeof (FileHeader), 1, Out) != 1) { - Error (NULL, 0, 0, "failed to write file header contents", NULL); - goto Done; - } - // - // Write data - // - if (fwrite (FileBuffer, FileSize - sizeof (EFI_FFS_FILE_HEADER), 1, Out) != 1) { - Error (NULL, 0, 0, "failed to write file contents", NULL); - goto Done; - } - } - -Done: - SFPCloseFile (); - if (Out != NULL) { - fclose (Out); - } - - if (PrimaryPackage != NULL) { - fclose (PrimaryPackage); - } - - if (FileBuffer != NULL) { - free (FileBuffer); - } - - if (OverridePackage != NULL) { - fclose (OverridePackage); - } - - return GetUtilityStatus (); -} - -int -main ( - INT32 argc, - CHAR8 *argv[] - ) -/*++ - -Routine Description: - - Main function. - -Arguments: - - argc - Number of command line parameters. - argv - Array of pointers to parameter strings. - -Returns: - STATUS_SUCCESS - Utility exits successfully. - STATUS_ERROR - Some error occurred during execution. - ---*/ -{ - STATUS Status; - // - // Set the name of our utility for error reporting purposes. - // - SetUtilityName (UTILITY_NAME); - Status = ProcessCommandLineArgs (argc, argv); - if (Status != STATUS_SUCCESS) { - return Status; - } - - Status = MainEntry (argc, argv, TRUE); - if (Status == STATUS_SUCCESS) { - MainEntry (argc, argv, FALSE); - } - // - // If any errors were reported via the standard error reporting - // routines, then the status has been saved. Get the value and - // return it to the caller. - // - return GetUtilityStatus (); -} - -static -STATUS -ProcessCommandLineArgs ( - int Argc, - char *Argv[] - ) -/*++ - -Routine Description: - Process the command line arguments. - -Arguments: - Argc - as passed in to main() - Argv - as passed in to main() - -Returns: - STATUS_SUCCESS - arguments all ok - STATUS_ERROR - problem with args, so caller should exit - ---*/ -{ - // - // If no args, then print usage instructions and return an error - // - if (Argc == 1) { - PrintUsage (); - return STATUS_ERROR; - } - - memset (&mGlobals, 0, sizeof (mGlobals)); - Argc--; - Argv++; - while (Argc > 0) { - if (strcmpi (Argv[0], "-b") == 0) { - // - // OPTION: -b BuildDirectory - // Make sure there is another argument, then save it to our globals. - // - if (Argc < 2) { - Error (NULL, 0, 0, "-b option requires the build directory name", NULL); - return STATUS_ERROR; - } - - if (mGlobals.BuildDirectory[0]) { - Error (NULL, 0, 0, Argv[0], "option can only be specified once"); - return STATUS_ERROR; - } - - strcpy (mGlobals.BuildDirectory, Argv[1]); - Argc--; - Argv++; - } else if (strcmpi (Argv[0], "-p1") == 0) { - // - // OPTION: -p1 PrimaryPackageFile - // Make sure there is another argument, then save it to our globals. - // - if (Argc < 2) { - Error (NULL, 0, 0, Argv[0], "option requires the primary package file name"); - return STATUS_ERROR; - } - - if (mGlobals.PrimaryPackagePath[0]) { - Error (NULL, 0, 0, Argv[0], "option can only be specified once"); - return STATUS_ERROR; - } - - strcpy (mGlobals.PrimaryPackagePath, Argv[1]); - Argc--; - Argv++; - } else if (strcmpi (Argv[0], "-p2") == 0) { - // - // OPTION: -p2 OverridePackageFile - // Make sure there is another argument, then save it to our globals. - // - if (Argc < 2) { - Error (NULL, 0, 0, Argv[0], "option requires the override package file name"); - return STATUS_ERROR; - } - - if (mGlobals.OverridePackagePath[0]) { - Error (NULL, 0, 0, Argv[0], "option can only be specified once"); - return STATUS_ERROR; - } - - strcpy (mGlobals.OverridePackagePath, Argv[1]); - Argc--; - Argv++; - } else if (strcmpi (Argv[0], "-v") == 0) { - // - // OPTION: -v verbose - // - mGlobals.Verbose = TRUE; - } else if (strcmpi (Argv[0], "-h") == 0) { - // - // OPTION: -h help - // - PrintUsage (); - return STATUS_ERROR; - } else if (strcmpi (Argv[0], "-?") == 0) { - // - // OPTION: -? help - // - PrintUsage (); - return STATUS_ERROR; - } else { - Error (NULL, 0, 0, Argv[0], "unrecognized option"); - PrintUsage (); - return STATUS_ERROR; - } - - Argv++; - Argc--; - } - // - // Must have at least specified the package file name - // - if (mGlobals.PrimaryPackagePath[0] == 0) { - Error (NULL, 0, 0, "must specify primary package file", NULL); - return STATUS_ERROR; - } - - return STATUS_SUCCESS; -} diff --git a/Tools/CodeTools/TianoTools/GenFfsFile/GenFfsFile.h b/Tools/CodeTools/TianoTools/GenFfsFile/GenFfsFile.h deleted file mode 100644 index f5bc718716..0000000000 --- a/Tools/CodeTools/TianoTools/GenFfsFile/GenFfsFile.h +++ /dev/null @@ -1,36 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - GenFfsFile.h - -Abstract: - - Header file for GenFfsFile. - ---*/ - -// -// Module Coded to Tiano Coding Conventions -// -#ifndef _EFI_GEN_FFSFILE_H -#define _EFI_GEN_FFSFILE_H - -// -// External Files Referenced -// -#include -#include - -#include "MyAlloc.h" - -#endif diff --git a/Tools/CodeTools/TianoTools/GenFfsFile/SimpleFileParsing.c b/Tools/CodeTools/TianoTools/GenFfsFile/SimpleFileParsing.c deleted file mode 100644 index 5fa5a22096..0000000000 --- a/Tools/CodeTools/TianoTools/GenFfsFile/SimpleFileParsing.c +++ /dev/null @@ -1,969 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - SimpleFileParsing.c - -Abstract: - - Generic but simple file parsing routines. - ---*/ - -#include -#include -#include -#include - -#include - -#include "EfiUtilityMsgs.h" -#include "SimpleFileParsing.h" - -#define MAX_PATH 255 -#define MAX_NEST_DEPTH 20 // just in case we get in an endless loop. -#define MAX_STRING_IDENTIFIER_NAME 100 // number of wchars -#define MAX_LINE_LEN 400 - -#define T_CHAR_SPACE ' ' -#define T_CHAR_NULL 0 -#define T_CHAR_CR '\r' -#define T_CHAR_TAB '\t' -#define T_CHAR_LF '\n' -#define T_CHAR_SLASH '/' -#define T_CHAR_BACKSLASH '\\' -#define T_CHAR_DOUBLE_QUOTE '"' -#define T_CHAR_LC_X 'x' -#define T_CHAR_0 '0' - -// -// We keep a linked list of these for the source files we process -// -typedef struct _SOURCE_FILE { - FILE *Fptr; - T_CHAR *FileBuffer; - T_CHAR *FileBufferPtr; - UINT32 FileSize; - INT8 FileName[MAX_PATH]; - UINT32 LineNum; - BOOLEAN EndOfFile; - BOOLEAN SkipToHash; - struct _SOURCE_FILE *Previous; - struct _SOURCE_FILE *Next; - T_CHAR ControlCharacter; -} SOURCE_FILE; - -// -// Here's all our module globals. -// -static struct { - SOURCE_FILE SourceFile; - BOOLEAN Verbose; -} mGlobals; - -static -UINT32 -t_strcmp ( - T_CHAR *Buffer, - T_CHAR *Str - ); - -static -UINT32 -t_strncmp ( - T_CHAR *Str1, - T_CHAR *Str2, - UINT32 Len - ); - -static -UINT32 -t_strlen ( - T_CHAR *Str - ); - -static -void -RewindFile ( - SOURCE_FILE *SourceFile - ); - -static -BOOLEAN -SkipTo ( - SOURCE_FILE *SourceFile, - T_CHAR TChar, - BOOLEAN StopAfterNewline - ); - -static -BOOLEAN -IsWhiteSpace ( - SOURCE_FILE *SourceFile - ); - -static -UINT32 -SkipWhiteSpace ( - SOURCE_FILE *SourceFile - ); - -static -BOOLEAN -EndOfFile ( - SOURCE_FILE *SourceFile - ); - -static -void -PreprocessFile ( - SOURCE_FILE *SourceFile - ); - -// -// static -// T_CHAR * -// GetQuotedString ( -// SOURCE_FILE *SourceFile, -// BOOLEAN Optional -// ); -// -static -T_CHAR * -t_strcpy ( - T_CHAR *Dest, - T_CHAR *Src - ); - -static -STATUS -ProcessIncludeFile ( - SOURCE_FILE *SourceFile, - SOURCE_FILE *ParentSourceFile - ); - -static -STATUS -ParseFile ( - SOURCE_FILE *SourceFile - ); - -static -FILE * -FindFile ( - IN INT8 *FileName, - OUT INT8 *FoundFileName, - IN UINT32 FoundFileNameLen - ); - -static -STATUS -ProcessFile ( - SOURCE_FILE *SourceFile - ); - -STATUS -SFPInit ( - VOID - ) -{ - memset ((void *) &mGlobals, 0, sizeof (mGlobals)); - return STATUS_SUCCESS; -} - -UINT32 -SFPGetLineNumber ( - VOID - ) -{ - return mGlobals.SourceFile.LineNum; -} - -/*++ - -Routine Description: - Return the line number of the file we're parsing. Used - for error reporting purposes. - -Arguments: - None. - -Returns: - The line number, or 0 if no file is being processed - ---*/ -T_CHAR * -SFPGetFileName ( - VOID - ) -/*++ - -Routine Description: - Return the name of the file we're parsing. Used - for error reporting purposes. - -Arguments: - None. - -Returns: - A pointer to the file name. Null if no file is being - processed. - ---*/ -{ - if (mGlobals.SourceFile.FileName[0]) { - return mGlobals.SourceFile.FileName; - } - - return NULL; -} - -STATUS -SFPOpenFile ( - IN INT8 *FileName - ) -/*++ - -Routine Description: - Open a file for parsing. - -Arguments: - FileName - name of the file to parse - -Returns: - - ---*/ -{ - STATUS Status; - t_strcpy (mGlobals.SourceFile.FileName, FileName); - Status = ProcessIncludeFile (&mGlobals.SourceFile, NULL); - return Status; -} - -BOOLEAN -SFPIsToken ( - T_CHAR *Str - ) -/*++ - -Routine Description: - Check to see if the specified token is found at - the current position in the input file. - -Arguments: - Str - the token to look for - -Returns: - TRUE - the token is next - FALSE - the token is not next - -Notes: - We do a simple string comparison on this function. It is - the responsibility of the caller to ensure that the token - is not a subset of some other token. - - The file pointer is advanced past the token in the input file. - ---*/ -{ - UINT32 Len; - SkipWhiteSpace (&mGlobals.SourceFile); - - if ((Len = t_strcmp (mGlobals.SourceFile.FileBufferPtr, Str)) > 0) { - mGlobals.SourceFile.FileBufferPtr += Len; - return TRUE; - } - - return FALSE; - -} - -BOOLEAN -SFPGetNextToken ( - T_CHAR *Str, - UINT32 Len - ) -{ - UINT32 Index; - SkipWhiteSpace (&mGlobals.SourceFile); - Index = 0; - while (!EndOfFile (&mGlobals.SourceFile) && (Index < Len)) { - if (IsWhiteSpace (&mGlobals.SourceFile)) { - if (Index > 0) { - Str[Index] = 0; - return TRUE; - } - - return FALSE; - } else { - Str[Index] = mGlobals.SourceFile.FileBufferPtr[0]; - mGlobals.SourceFile.FileBufferPtr++; - Index++; - } - } - - return FALSE; -} - -BOOLEAN -SFPSkipToToken ( - T_CHAR *Str - ) -{ - UINT32 Len; - T_CHAR *SavePos; - Len = t_strlen (Str); - SavePos = mGlobals.SourceFile.FileBufferPtr; - SkipWhiteSpace (&mGlobals.SourceFile); - while (!EndOfFile (&mGlobals.SourceFile)) { - if (t_strncmp (Str, mGlobals.SourceFile.FileBufferPtr, Len) == 0) { - mGlobals.SourceFile.FileBufferPtr += Len; - return TRUE; - } - - mGlobals.SourceFile.FileBufferPtr++; - SkipWhiteSpace (&mGlobals.SourceFile); - } - - mGlobals.SourceFile.FileBufferPtr = SavePos; - return FALSE; -} - -BOOLEAN -SFPGetNumber ( - UINT32 *Value - ) -/*++ - -Routine Description: - Check the token at the current file position for a numeric value. - May be either decimal or hex. - -Arguments: - Value - pointer where to store the value - -Returns: - FALSE - current token is not a number - TRUE - current token is a number - ---*/ -{ - // - // UINT32 Len; - // - SkipWhiteSpace (&mGlobals.SourceFile); - if (EndOfFile (&mGlobals.SourceFile)) { - return FALSE; - } - - if (isdigit (mGlobals.SourceFile.FileBufferPtr[0])) { - // - // Check for hex value - // - if ((mGlobals.SourceFile.FileBufferPtr[0] == T_CHAR_0) && (mGlobals.SourceFile.FileBufferPtr[1] == T_CHAR_LC_X)) { - if (!isxdigit (mGlobals.SourceFile.FileBufferPtr[2])) { - return FALSE; - } - - mGlobals.SourceFile.FileBufferPtr += 2; - sscanf (mGlobals.SourceFile.FileBufferPtr, "%x", Value); - while (isxdigit (mGlobals.SourceFile.FileBufferPtr[0])) { - mGlobals.SourceFile.FileBufferPtr++; - } - - return TRUE; - } else { - *Value = atoi (mGlobals.SourceFile.FileBufferPtr); - while (isdigit (mGlobals.SourceFile.FileBufferPtr[0])) { - mGlobals.SourceFile.FileBufferPtr++; - } - - return TRUE; - } - } else { - return FALSE; - } -} - -STATUS -SFPCloseFile ( - VOID - ) -/*++ - -Routine Description: - Close the file being parsed. - -Arguments: - None. - -Returns: - STATUS_SUCCESS - the file was closed - STATUS_ERROR - no file is currently open - ---*/ -{ - if (mGlobals.SourceFile.FileBuffer != NULL) { - free (mGlobals.SourceFile.FileBuffer); - memset (&mGlobals.SourceFile, 0, sizeof (mGlobals.SourceFile)); - return STATUS_SUCCESS; - } - - return STATUS_ERROR; -} - -static -STATUS -ProcessIncludeFile ( - SOURCE_FILE *SourceFile, - SOURCE_FILE *ParentSourceFile - ) -/*++ - -Routine Description: - - Given a source file, open the file and parse it - -Arguments: - - SourceFile - name of file to parse - ParentSourceFile - for error reporting purposes, the file that #included SourceFile. - -Returns: - - Standard status. - ---*/ -{ - static UINT32 NestDepth = 0; - INT8 FoundFileName[MAX_PATH]; - STATUS Status; - - Status = STATUS_SUCCESS; - NestDepth++; - // - // Print the file being processed. Indent so you can tell the include nesting - // depth. - // - if (mGlobals.Verbose) { - fprintf (stdout, "%*cProcessing file '%s'\n", NestDepth * 2, ' ', SourceFile->FileName); - } - - // - // Make sure we didn't exceed our maximum nesting depth - // - if (NestDepth > MAX_NEST_DEPTH) { - Error (NULL, 0, 0, SourceFile->FileName, "max nesting depth (%d) exceeded", NestDepth); - Status = STATUS_ERROR; - goto Finish; - } - // - // Try to open the file locally, and if that fails try along our include paths. - // - strcpy (FoundFileName, SourceFile->FileName); - if ((SourceFile->Fptr = fopen (FoundFileName, "r")) == NULL) { - // - // Try to find it among the paths if it has a parent (that is, it is included - // by someone else). - // - Error (NULL, 0, 0, SourceFile->FileName, "file not found"); - return STATUS_ERROR; - } - // - // Process the file found - // - ProcessFile (SourceFile); -Finish: - // - // Close open files and return status - // - if (SourceFile->Fptr != NULL) { - fclose (SourceFile->Fptr); - SourceFile->Fptr = NULL; - } - - return Status; -} - -static -STATUS -ProcessFile ( - SOURCE_FILE *SourceFile - ) -{ - // - // Get the file size, and then read the entire thing into memory. - // Allocate space for a terminator character. - // - fseek (SourceFile->Fptr, 0, SEEK_END); - SourceFile->FileSize = ftell (SourceFile->Fptr); - fseek (SourceFile->Fptr, 0, SEEK_SET); - SourceFile->FileBuffer = (T_CHAR *) malloc (SourceFile->FileSize + sizeof (T_CHAR)); - if (SourceFile->FileBuffer == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - fread ((VOID *) SourceFile->FileBuffer, SourceFile->FileSize, 1, SourceFile->Fptr); - SourceFile->FileBuffer[(SourceFile->FileSize / sizeof (T_CHAR))] = T_CHAR_NULL; - // - // Pre-process the file to replace comments with spaces - // - PreprocessFile (SourceFile); - SourceFile->LineNum = 1; - return STATUS_SUCCESS; -} - -static -void -PreprocessFile ( - SOURCE_FILE *SourceFile - ) -/*++ - -Routine Description: - Preprocess a file to replace all carriage returns with NULLs so - we can print lines from the file to the screen. - -Arguments: - SourceFile - structure that we use to keep track of an input file. - -Returns: - Nothing. - ---*/ -{ - BOOLEAN InComment; - - RewindFile (SourceFile); - InComment = FALSE; - while (!EndOfFile (SourceFile)) { - // - // If a line-feed, then no longer in a comment - // - if (SourceFile->FileBufferPtr[0] == T_CHAR_LF) { - SourceFile->FileBufferPtr++; - SourceFile->LineNum++; - InComment = 0; - } else if (SourceFile->FileBufferPtr[0] == T_CHAR_CR) { - // - // Replace all carriage returns with a NULL so we can print stuff - // - SourceFile->FileBufferPtr[0] = 0; - SourceFile->FileBufferPtr++; - } else if (InComment) { - SourceFile->FileBufferPtr[0] = T_CHAR_SPACE; - SourceFile->FileBufferPtr++; - } else if ((SourceFile->FileBufferPtr[0] == T_CHAR_SLASH) && (SourceFile->FileBufferPtr[1] == T_CHAR_SLASH)) { - SourceFile->FileBufferPtr += 2; - InComment = TRUE; - } else { - SourceFile->FileBufferPtr++; - } - } - // - // Could check for end-of-file and still in a comment, but - // should not be necessary. So just restore the file pointers. - // - RewindFile (SourceFile); -} - -#if 0 -static -T_CHAR * -GetQuotedString ( - SOURCE_FILE *SourceFile, - BOOLEAN Optional - ) -{ - T_CHAR *String; - T_CHAR *Start; - T_CHAR *Ptr; - UINT32 Len; - BOOLEAN PreviousBackslash; - - if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) { - if (!Optional) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted string", "%S", SourceFile->FileBufferPtr); - } - - return NULL; - } - - Len = 0; - SourceFile->FileBufferPtr++; - Start = Ptr = SourceFile->FileBufferPtr; - PreviousBackslash = FALSE; - while (!EndOfFile (SourceFile)) { - if ((SourceFile->FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) && (!PreviousBackslash)) { - break; - } else if (SourceFile->FileBufferPtr[0] == T_CHAR_CR) { - Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start); - PreviousBackslash = FALSE; - } else if (SourceFile->FileBufferPtr[0] == T_CHAR_BACKSLASH) { - PreviousBackslash = TRUE; - } else { - PreviousBackslash = FALSE; - } - - SourceFile->FileBufferPtr++; - Len++; - } - - if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) { - Warning (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing quote on string", "%S", Start); - } else { - SourceFile->FileBufferPtr++; - } - // - // Now allocate memory for the string and save it off - // - String = (T_CHAR *) malloc ((Len + 1) * sizeof (T_CHAR)); - if (String == NULL) { - Error (NULL, 0, 0, "memory allocation failed", NULL); - return NULL; - } - // - // Copy the string from the file buffer to the local copy. - // We do no reformatting of it whatsoever at this point. - // - Ptr = String; - while (Len > 0) { - *Ptr = *Start; - Start++; - Ptr++; - Len--; - } - - *Ptr = 0; - return String; -} -#endif -static -BOOLEAN -EndOfFile ( - SOURCE_FILE *SourceFile - ) -{ - // - // The file buffer pointer will typically get updated before the End-of-file flag in the - // source file structure, so check it first. - // - if (SourceFile->FileBufferPtr >= SourceFile->FileBuffer + SourceFile->FileSize / sizeof (T_CHAR)) { - SourceFile->EndOfFile = TRUE; - return TRUE; - } - - if (SourceFile->EndOfFile) { - return TRUE; - } - - return FALSE; -} - -#if 0 -static -void -ProcessTokenInclude ( - SOURCE_FILE *SourceFile - ) -{ - INT8 IncludeFileName[MAX_PATH]; - INT8 *To; - UINT32 Len; - BOOLEAN ReportedError; - SOURCE_FILE IncludedSourceFile; - - ReportedError = FALSE; - if (SkipWhiteSpace (SourceFile) == 0) { - Warning (SourceFile->FileName, SourceFile->LineNum, 0, "expected whitespace following #include keyword", NULL); - } - // - // Should be quoted file name - // - if (SourceFile->FileBufferPtr[0] != T_CHAR_DOUBLE_QUOTE) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted include file name", NULL); - goto FailDone; - } - - SourceFile->FileBufferPtr++; - // - // Copy the filename as ascii to our local string - // - To = IncludeFileName; - Len = 0; - while (!EndOfFile (SourceFile)) { - if ((SourceFile->FileBufferPtr[0] == T_CHAR_CR) || (SourceFile->FileBufferPtr[0] == T_CHAR_LF)) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-line found in quoted include file name", NULL); - goto FailDone; - } - - if (SourceFile->FileBufferPtr[0] == T_CHAR_DOUBLE_QUOTE) { - SourceFile->FileBufferPtr++; - break; - } - // - // If too long, then report the error once and process until the closing quote - // - Len++; - if (!ReportedError && (Len >= sizeof (IncludeFileName))) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "length of include file name exceeds limit", NULL); - ReportedError = TRUE; - } - - if (!ReportedError) { - // - // *To = UNICODE_TO_ASCII(SourceFile->FileBufferPtr[0]); - // - *To = (T_CHAR) SourceFile->FileBufferPtr[0]; - To++; - } - - SourceFile->FileBufferPtr++; - } - - if (!ReportedError) { - *To = 0; - memset ((char *) &IncludedSourceFile, 0, sizeof (SOURCE_FILE)); - strcpy (IncludedSourceFile.FileName, IncludeFileName); - // - // IncludedSourceFile.ControlCharacter = DEFAULT_CONTROL_CHARACTER; - // - ProcessIncludeFile (&IncludedSourceFile, SourceFile); - // - // printf ("including file '%s'\n", IncludeFileName); - // - } - - return ; -FailDone: - // - // Error recovery -- skip to next # - // - SourceFile->SkipToHash = TRUE; -} -#endif -static -BOOLEAN -IsWhiteSpace ( - SOURCE_FILE *SourceFile - ) -{ - switch (*SourceFile->FileBufferPtr) { - case T_CHAR_NULL: - case T_CHAR_CR: - case T_CHAR_SPACE: - case T_CHAR_TAB: - case T_CHAR_LF: - return TRUE; - - default: - return FALSE; - } -} - -UINT32 -SkipWhiteSpace ( - SOURCE_FILE *SourceFile - ) -{ - UINT32 Count; - - Count = 0; - while (!EndOfFile (SourceFile)) { - Count++; - switch (*SourceFile->FileBufferPtr) { - case T_CHAR_NULL: - case T_CHAR_CR: - case T_CHAR_SPACE: - case T_CHAR_TAB: - SourceFile->FileBufferPtr++; - break; - - case T_CHAR_LF: - SourceFile->FileBufferPtr++; - SourceFile->LineNum++; - if (mGlobals.Verbose) { - printf ("%d: %S\n", SourceFile->LineNum, SourceFile->FileBufferPtr); - } - break; - - default: - return Count - 1; - } - } - // - // Some tokens require trailing whitespace. If we're at the end of the - // file, then we count that as well. - // - if ((Count == 0) && (EndOfFile (SourceFile))) { - Count++; - } - - return Count; -} - -static -UINT32 -t_strcmp ( - T_CHAR *Buffer, - T_CHAR *Str - ) -{ - UINT32 Len; - - Len = 0; - while (*Str == *Buffer) { - Buffer++; - Str++; - Len++; - } - - if (*Str) { - return 0; - } - - return Len; -} - -static -UINT32 -t_strlen ( - T_CHAR *Str - ) -{ - UINT32 Len; - Len = 0; - while (*Str) { - Len++; - Str++; - } - - return Len; -} - -static -UINT32 -t_strncmp ( - T_CHAR *Str1, - T_CHAR *Str2, - UINT32 Len - ) -{ - while (Len > 0) { - if (*Str1 != *Str2) { - return Len; - } - - Len--; - Str1++; - Str2++; - } - - return 0; -} - -static -T_CHAR * -t_strcpy ( - T_CHAR *Dest, - T_CHAR *Src - ) -{ - T_CHAR *SaveDest; - SaveDest = Dest; - while (*Src) { - *Dest = *Src; - Dest++; - Src++; - } - - *Dest = 0; - return SaveDest; -} - -#if 0 -static -BOOLEAN -IsValidIdentifierChar ( - INT8 Char, - BOOLEAN FirstChar - ) -{ - // - // If it's the first character of an identifier, then - // it must be one of [A-Za-z_]. - // - if (FirstChar) { - if (isalpha (Char) || (Char == '_')) { - return TRUE; - } - } else { - // - // If it's not the first character, then it can - // be one of [A-Za-z_0-9] - // - if (isalnum (Char) || (Char == '_')) { - return TRUE; - } - } - - return FALSE; -} -#endif -static -void -RewindFile ( - SOURCE_FILE *SourceFile - ) -{ - SourceFile->LineNum = 1; - SourceFile->FileBufferPtr = SourceFile->FileBuffer; - SourceFile->EndOfFile = 0; -} - -#if 0 -static -BOOLEAN -SkipTo ( - SOURCE_FILE *SourceFile, - T_CHAR TChar, - BOOLEAN StopAfterNewline - ) -{ - while (!EndOfFile (SourceFile)) { - // - // Check for the character of interest - // - if (SourceFile->FileBufferPtr[0] == TChar) { - return TRUE; - } else { - if (SourceFile->FileBufferPtr[0] == T_CHAR_LF) { - SourceFile->LineNum++; - if (StopAfterNewline) { - SourceFile->FileBufferPtr++; - if (SourceFile->FileBufferPtr[0] == 0) { - SourceFile->FileBufferPtr++; - } - - return FALSE; - } - } - - SourceFile->FileBufferPtr++; - } - } - - return FALSE; -} -#endif diff --git a/Tools/CodeTools/TianoTools/GenFfsFile/build.xml b/Tools/CodeTools/TianoTools/GenFfsFile/build.xml deleted file mode 100644 index b7f8681436..0000000000 --- a/Tools/CodeTools/TianoTools/GenFfsFile/build.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/GenFvImage/Ebc/PeCoffLoaderEx.c b/Tools/CodeTools/TianoTools/GenFvImage/Ebc/PeCoffLoaderEx.c deleted file mode 100644 index e8cf8b6457..0000000000 --- a/Tools/CodeTools/TianoTools/GenFvImage/Ebc/PeCoffLoaderEx.c +++ /dev/null @@ -1,57 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PeCoffLoaderEx.c - -Abstract: - - EBC Specific relocation fixups - -Revision History - ---*/ - - - - -RETURN_STATUS -PeCoffLoaderRelocateImageEx ( - IN UINT16 *Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust - ) -/*++ - -Routine Description: - - Performs an IA-32 specific relocation fixup - -Arguments: - - Reloc - Pointer to the relocation record - - Fixup - Pointer to the address to fix up - - FixupData - Pointer to a buffer to log the fixups - - Adjust - The offset to adjust the fixup - -Returns: - - EFI_UNSUPPORTED - Unsupported now - ---*/ -{ - return RETURN_UNSUPPORTED; -} diff --git a/Tools/CodeTools/TianoTools/GenFvImage/GenFvImageExe.c b/Tools/CodeTools/TianoTools/GenFvImage/GenFvImageExe.c deleted file mode 100644 index d0117b8ae9..0000000000 --- a/Tools/CodeTools/TianoTools/GenFvImage/GenFvImageExe.c +++ /dev/null @@ -1,299 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - GenFvImageExe.c - -Abstract: - - This contains all code necessary to build the GenFvImage.exe utility. - This utility relies heavily on the GenFvImage Lib. Definitions for both - can be found in the Tiano Firmware Volume Generation Utility - Specification, review draft. - ---*/ - -// -// File included in build -// -#include "GenFvImageExe.h" -#include "CommonLib.h" -#include "EfiUtilityMsgs.h" - -VOID -PrintUtilityInfo ( - VOID - ) -/*++ - -Routine Description: - - Displays the standard utility information to SDTOUT - -Arguments: - - None - -Returns: - - None - ---*/ -{ - printf ( - "%s - Tiano Firmware Volume Generation Utility."" Version %i.%i\n\n", - UTILITY_NAME, - UTILITY_MAJOR_VERSION, - UTILITY_MINOR_VERSION - ); -} - -VOID -PrintUsage ( - VOID - ) -/*++ - -Routine Description: - - Displays the utility usage syntax to STDOUT - -Arguments: - - None - -Returns: - - None - ---*/ -{ - printf ("Usage: %s -I FvInfFileName\n", UTILITY_NAME); - printf (" Where:\n"); - printf ("\tFvInfFileName is the name of the image description file.\n\n"); -} - -int -main ( - IN INTN argc, - IN CHAR8 **argv - ) -/*++ - -Routine Description: - - This utility uses GenFvImage.Lib to build a firmware volume image. - -Arguments: - - FvInfFileName The name of an FV image description file. - - Arguments come in pair in any order. - -I FvInfFileName - -Returns: - - EFI_SUCCESS No error conditions detected. - EFI_INVALID_PARAMETER One or more of the input parameters is invalid. - EFI_OUT_OF_RESOURCES A resource required by the utility was unavailable. - Most commonly this will be memory allocation - or file creation. - EFI_LOAD_ERROR GenFvImage.lib could not be loaded. - EFI_ABORTED Error executing the GenFvImage lib. - ---*/ -{ - EFI_STATUS Status; - CHAR8 InfFileName[_MAX_PATH]; - CHAR8 *InfFileImage; - UINTN InfFileSize; - UINT8 *FvImage; - UINTN FvImageSize; - UINT8 Index; - CHAR8 FvFileNameBuffer[_MAX_PATH]; - CHAR8 *FvFileName; - FILE *FvFile; - FILE *SymFile; - CHAR8 SymFileNameBuffer[_MAX_PATH]; - CHAR8 *SymFileName; - UINT8 *SymImage; - UINTN SymImageSize; - CHAR8 *CurrentSymString; - - FvFileName = FvFileNameBuffer; - SymFileName = SymFileNameBuffer; - - SetUtilityName (UTILITY_NAME); - // - // Display utility information - // - PrintUtilityInfo (); - - // - // Verify the correct number of arguments - // - if (argc != MAX_ARGS) { - Error (NULL, 0, 0, "invalid number of input parameters specified", NULL); - PrintUsage (); - return GetUtilityStatus (); - } - // - // Initialize variables - // - strcpy (InfFileName, ""); - - // - // Parse the command line arguments - // - for (Index = 1; Index < MAX_ARGS; Index += 2) { - // - // Make sure argument pair begin with - or / - // - if (argv[Index][0] != '-' && argv[Index][0] != '/') { - Error (NULL, 0, 0, argv[Index], "argument pair must begin with \"-\" or \"/\""); - PrintUsage (); - return GetUtilityStatus (); - } - // - // Make sure argument specifier is only one letter - // - if (argv[Index][2] != 0) { - Error (NULL, 0, 0, argv[Index], "unrecognized argument"); - PrintUsage (); - return GetUtilityStatus (); - } - // - // Determine argument to read - // - switch (argv[Index][1]) { - - case 'I': - case 'i': - if (strlen (InfFileName) == 0) { - strcpy (InfFileName, argv[Index + 1]); - } else { - Error (NULL, 0, 0, argv[Index + 1], "FvInfFileName may only be specified once"); - PrintUsage (); - return GetUtilityStatus (); - } - break; - - default: - Error (NULL, 0, 0, argv[Index], "unrecognized argument"); - PrintUsage (); - return GetUtilityStatus (); - break; - } - } - // - // Read the INF file image - // - Status = GetFileImage (InfFileName, &InfFileImage, &InfFileSize); - if (EFI_ERROR (Status)) { - return STATUS_ERROR; - } - // - // Call the GenFvImage lib - // - Status = GenerateFvImage ( - InfFileImage, - InfFileSize, - &FvImage, - &FvImageSize, - &FvFileName, - &SymImage, - &SymImageSize, - &SymFileName - ); - - if (EFI_ERROR (Status)) { - switch (Status) { - - case EFI_INVALID_PARAMETER: - Error (NULL, 0, 0, "invalid parameter passed to GenFvImage Lib", NULL); - return GetUtilityStatus (); - break; - - case EFI_ABORTED: - Error (NULL, 0, 0, "error detected while creating the file image", NULL); - return GetUtilityStatus (); - break; - - case EFI_OUT_OF_RESOURCES: - Error (NULL, 0, 0, "GenFvImage Lib could not allocate required resources", NULL); - return GetUtilityStatus (); - break; - - case EFI_VOLUME_CORRUPTED: - Error (NULL, 0, 0, "no base address was specified, but the FV.INF included a PEI or BSF file", NULL); - return GetUtilityStatus (); - break; - - case EFI_LOAD_ERROR: - Error (NULL, 0, 0, "could not load FV image generation library", NULL); - return GetUtilityStatus (); - break; - - default: - Error (NULL, 0, 0, "GenFvImage Lib returned unknown status", "status returned = 0x%X", Status); - return GetUtilityStatus (); - break; - } - } - // - // Write file - // - FvFile = fopen (FvFileName, "wb"); - if (FvFile == NULL) { - Error (NULL, 0, 0, FvFileName, "could not open output file"); - free (FvImage); - free (SymImage); - return GetUtilityStatus (); - } - - if (fwrite (FvImage, 1, FvImageSize, FvFile) != FvImageSize) { - Error (NULL, 0, 0, FvFileName, "failed to write to output file"); - free (FvImage); - free (SymImage); - fclose (FvFile); - return GetUtilityStatus (); - } - - fclose (FvFile); - free (FvImage); - - // - // Write symbol file - // - if (strcmp (SymFileName, "")) { - SymFile = fopen (SymFileName, "wt"); - if (SymFile == NULL) { - Error (NULL, 0, 0, SymFileName, "could not open output symbol file"); - free (SymImage); - return GetUtilityStatus (); - } - - fprintf (SymFile, "TEXTSYM format | V1.0\n"); - - CurrentSymString = SymImage; - while (((UINTN) CurrentSymString - (UINTN) SymImage) < SymImageSize) { - fprintf (SymFile, "%s", CurrentSymString); - CurrentSymString = (CHAR8 *) (((UINTN) CurrentSymString) + strlen (CurrentSymString) + 1); - } - - fclose (SymFile); - } - - free (SymImage); - - return GetUtilityStatus (); -} diff --git a/Tools/CodeTools/TianoTools/GenFvImage/GenFvImageExe.h b/Tools/CodeTools/TianoTools/GenFvImage/GenFvImageExe.h deleted file mode 100644 index 9b97935656..0000000000 --- a/Tools/CodeTools/TianoTools/GenFvImage/GenFvImageExe.h +++ /dev/null @@ -1,98 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - GenFvImageExe.h - -Abstract: - - Definitions for the PeimFixup exe utility. - ---*/ - -// -// Coded to Tiano Coding Standards -// -#ifndef _EFI_GEN_FV_IMAGE_EXE_H -#define _EFI_GEN_FV_IMAGE_EXE_H - -#include -#include -#include -#include "GenFvImageLib.h" - -// -// Utility Name -// -#define UTILITY_NAME "GenFvImage" - -// -// Utility version information -// -#define UTILITY_MAJOR_VERSION 0 -#define UTILITY_MINOR_VERSION 1 -#define UTILITY_DATE __DATE__ - -// -// The maximum number of arguments accepted from the command line. -// -#define MAX_ARGS 3 - -// -// The function that displays general utility information -// -VOID -PrintUtilityInfo ( - VOID - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - None - -Returns: - - TODO: add return values - ---*/ -; - -// -// The function that displays the utility usage message. -// -VOID -PrintUsage ( - VOID - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - None - -Returns: - - TODO: add return values - ---*/ -; - -#endif diff --git a/Tools/CodeTools/TianoTools/GenFvImage/GenFvImageLib.c b/Tools/CodeTools/TianoTools/GenFvImage/GenFvImageLib.c deleted file mode 100644 index 888656ad5c..0000000000 --- a/Tools/CodeTools/TianoTools/GenFvImage/GenFvImageLib.c +++ /dev/null @@ -1,2727 +0,0 @@ -/*++ -i - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - GenFvImageLib.c - -Abstract: - - This file contains functions required to generate a Firmware Volume. - ---*/ - -// -// Include files -// -#ifdef __GNUC__ -#include -#include -#endif -#include -#ifndef __GNUC__ -#include -#endif -#include - -#include -#include -#include -#include -#include - -#include "GenFvImageLib.h" -#include "GenFvImageLibInternal.h" -#include "CommonLib.h" -#include "Crc32.h" -#include "EfiUtilityMsgs.h" -#include "FvLib.h" -#include "EfiCompress.h" -#include "WinNtInclude.h" - - -// -// Local function prototypes -// -EFI_STATUS -GetPe32Info ( - IN UINT8 *Pe32, - OUT UINT32 *EntryPoint, - OUT UINT32 *BaseOfCode, - OUT UINT16 *MachineType - ); - -// -// Local function implementations. -// -EFI_GUID FfsGuid = EFI_FIRMWARE_FILE_SYSTEM_GUID; -EFI_GUID DefaultFvPadFileNameGuid = { 0x78f54d4, 0xcc22, 0x4048, 0x9e, 0x94, 0x87, 0x9c, 0x21, 0x4d, 0x56, 0x2f }; - -// -// This data array will be located at the base of the Firmware Volume Header (FVH) -// in the boot block. It must not exceed 14 bytes of code. The last 2 bytes -// will be used to keep the FVH checksum consistent. -// This code will be run in response to a starutp IPI for HT-enabled systems. -// -#define SIZEOF_STARTUP_DATA_ARRAY 0x10 - -UINT8 m128kRecoveryStartupApDataArray[SIZEOF_STARTUP_DATA_ARRAY] = { - // - // EA D0 FF 00 F0 ; far jmp F000:FFD0 - // 0, 0, 0, 0, 0, 0, 0, 0, 0, ; Reserved bytes - // 0, 0 ; Checksum Padding - // - 0xEA, - 0xD0, - 0xFF, - 0x0, - 0xF0, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; - -UINT8 m64kRecoveryStartupApDataArray[SIZEOF_STARTUP_DATA_ARRAY] = { - // - // EB CE ; jmp short ($-0x30) - // ; (from offset 0x0 to offset 0xFFD0) - // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ; Reserved bytes - // 0, 0 ; Checksum Padding - // - 0xEB, - 0xCE, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; - -EFI_STATUS -ParseFvInf ( - IN MEMORY_FILE *InfFile, - IN FV_INFO *FvInfo - ) -/*++ - -Routine Description: - - This function parses a FV.INF file and copies info into a FV_INFO structure. - -Arguments: - - InfFile Memory file image. - FvInfo Information read from INF file. - -Returns: - - EFI_SUCCESS INF file information successfully retrieved. - EFI_ABORTED INF file has an invalid format. - EFI_NOT_FOUND A required string was not found in the INF file. ---*/ -{ - CHAR8 Value[_MAX_PATH]; - UINT64 Value64; - UINTN Index; - EFI_STATUS Status; - - // - // Initialize FV info - // - memset (FvInfo, 0, sizeof (FV_INFO)); - - // - // Read the FV base address - // - Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_BASE_ADDRESS_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Get the base address - // - Status = AsciiStringToUint64 (Value, FALSE, &Value64); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, EFI_FV_BASE_ADDRESS_STRING, "invalid value"); - return EFI_ABORTED; - } - - FvInfo->BaseAddress = Value64; - } else { - Error (NULL, 0, 0, EFI_FV_BASE_ADDRESS_STRING, "could not find value"); - return EFI_ABORTED; - } - // - // Read the FV Guid - // - Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_GUID_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Get the guid value - // - Status = StringToGuid (Value, &FvInfo->FvGuid); - if (EFI_ERROR (Status)) { - memcpy (&FvInfo->FvGuid, &FfsGuid, sizeof (EFI_GUID)); - } - } else { - memcpy (&FvInfo->FvGuid, &FfsGuid, sizeof (EFI_GUID)); - } - // - // Read the FV file name - // - Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_FILE_NAME_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // copy the file name - // - strcpy (FvInfo->FvName, Value); - } else { - Error (NULL, 0, 0, EFI_FV_FILE_NAME_STRING, "value not specified"); - return EFI_ABORTED; - } - // - // Read the Sym file name - // - Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_SYM_FILE_NAME_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // copy the file name - // - strcpy (FvInfo->SymName, Value); - } else { - // - // Symbols not required, so init to NULL. - // - strcpy (FvInfo->SymName, ""); - } - // - // Read the read disabled capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_READ_DISABLED_CAP_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the read disabled flag - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_READ_DISABLED_CAP; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_READ_DISABLED_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_READ_DISABLED_CAP_STRING, "value not specified"); - return Status; - } - // - // Read the read enabled capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_READ_ENABLED_CAP_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the read disabled flag - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_READ_ENABLED_CAP; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_READ_ENABLED_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_READ_ENABLED_CAP_STRING, "value not specified"); - return Status; - } - // - // Read the read status attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_READ_STATUS_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the read disabled flag - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_READ_STATUS; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_READ_STATUS_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_READ_STATUS_STRING, "value not specified"); - return Status; - } - // - // Read the write disabled capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_WRITE_DISABLED_CAP_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the write disabled flag - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_WRITE_DISABLED_CAP; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_WRITE_DISABLED_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_WRITE_DISABLED_CAP_STRING, "value not specified"); - return Status; - } - // - // Read the write enabled capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_WRITE_ENABLED_CAP_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the write disabled flag - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_WRITE_ENABLED_CAP; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_WRITE_ENABLED_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_WRITE_ENABLED_CAP_STRING, "value not specified"); - return Status; - } - // - // Read the write status attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_WRITE_STATUS_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the write disabled flag - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_WRITE_STATUS; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_WRITE_STATUS_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_WRITE_STATUS_STRING, "value not specified"); - return Status; - } - // - // Read the lock capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_LOCK_CAP_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the attribute flag - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_LOCK_CAP; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_LOCK_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_LOCK_CAP_STRING, "value not specified"); - return Status; - } - // - // Read the lock status attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_LOCK_STATUS_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the attribute flag - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_LOCK_STATUS; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_LOCK_STATUS_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_LOCK_STATUS_STRING, "value not specified"); - return Status; - } - // - // Read the sticky write attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_STICKY_WRITE_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the attribute flag - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_STICKY_WRITE; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_STICKY_WRITE_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_STICKY_WRITE_STRING, "value not specified"); - return Status; - } - // - // Read the memory mapped attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_MEMORY_MAPPED_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the attribute flag - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_MEMORY_MAPPED; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_MEMORY_MAPPED_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_MEMORY_MAPPED_STRING, "value not specified"); - return Status; - } - // - // Read the erase polarity attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ERASE_POLARITY_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the attribute flag - // - if (strcmp (Value, ONE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ERASE_POLARITY; - } else if (strcmp (Value, ZERO_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ERASE_POLARITY_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ERASE_POLARITY_STRING, "value not specified"); - return Status; - } - // - // Read the alignment capabilities attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_CAP_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_CAP; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_CAP_STRING, "value not specified"); - return Status; - } - // - // Read the word alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_2_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_2; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_2_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_2_STRING, "value not specified"); - return Status; - } - // - // Read the dword alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_4_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_4; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_4_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_4_STRING, "value not specified"); - return Status; - } - // - // Read the word alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_8_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_8; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_8_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_8_STRING, "value not specified"); - return Status; - } - // - // Read the qword alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_16_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_16; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_16_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_16_STRING, "value not specified"); - return Status; - } - // - // Read the 32 byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_32_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_32; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_32_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_32_STRING, "value not specified"); - return Status; - } - // - // Read the 64 byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_64_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_64; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_64_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_64_STRING, "value not specified"); - return Status; - } - // - // Read the 128 byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_128_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_128; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_128_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_128_STRING, "value not specified"); - return Status; - } - // - // Read the 256 byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_256_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_256; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_256_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_256_STRING, "value not specified"); - return Status; - } - // - // Read the 512 byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_512_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_512; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_512_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_512_STRING, "value not specified"); - return Status; - } - // - // Read the 1K byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_1K_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_1K; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_1K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_1K_STRING, "value not specified"); - return Status; - } - // - // Read the 2K byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_2K_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_2K; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_2K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_2K_STRING, "value not specified"); - return Status; - } - // - // Read the 4K byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_4K_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_4K; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_4K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_4K_STRING, "value not specified"); - return Status; - } - // - // Read the 8K byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_8K_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_8K; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_8K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_8K_STRING, "value not specified"); - return Status; - } - // - // Read the 16K byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_16K_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_16K; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_16K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_16K_STRING, "value not specified"); - return Status; - } - // - // Read the 32K byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_32K_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_32K; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_32K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_32K_STRING, "value not specified"); - return Status; - } - // - // Read the 64K byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_64K_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_64K; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_64K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_64K_STRING, "value not specified"); - return Status; - } - - if (!(FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_CAP) && - ( - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_2) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_4) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_8) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_16) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_32) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_64) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_128) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_256) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_512) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_1K) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_2K) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_4K) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_8K) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_16K) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_32K) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_64K) - ) - ) { - Error ( - NULL, - 0, - 0, - "illegal combination of alignment attributes", - "if %s is not %s, no individual alignments can be %s", - EFI_FVB_ALIGNMENT_CAP_STRING, - TRUE_STRING, - TRUE_STRING - ); - return EFI_ABORTED; - } - // - // Read block maps - // - for (Index = 0; Index < MAX_NUMBER_OF_FV_BLOCKS; Index++) { - // - // Read the number of blocks - // - Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_NUM_BLOCKS_STRING, Index, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the number of blocks - // - Status = AsciiStringToUint64 (Value, FALSE, &Value64); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, Value, "invalid value for %s", EFI_NUM_BLOCKS_STRING); - return EFI_ABORTED; - } - - FvInfo->FvBlocks[Index].NumBlocks = (UINT32) Value64; - } else { - // - // If there is no number of blocks, but there is a size, then we have a mismatched pair - // and should return an error. - // - Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_BLOCK_SIZE_STRING, Index, Value); - if (!EFI_ERROR (Status)) { - Error (NULL, 0, 0, "must specify both", "%s and %s", EFI_NUM_BLOCKS_STRING, EFI_BLOCK_SIZE_STRING); - return EFI_ABORTED; - } else { - // - // We are done - // - break; - } - } - // - // Read the size of blocks - // - Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_BLOCK_SIZE_STRING, Index, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the number of blocks - // - Status = AsciiStringToUint64 (Value, FALSE, &Value64); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, Value, "invalid value specified for %s", EFI_BLOCK_SIZE_STRING); - return EFI_ABORTED; - } - - FvInfo->FvBlocks[Index].BlockLength = (UINT32) Value64; - } else { - // - // There is a number of blocks, but there is no size, so we have a mismatched pair - // and should return an error. - // - Error (NULL, 0, 0, "must specify both", "%s and %s", EFI_NUM_BLOCKS_STRING, EFI_BLOCK_SIZE_STRING); - return EFI_ABORTED; - } - } - // - // Read files - // - for (Index = 0; Index < MAX_NUMBER_OF_FILES_IN_FV; Index++) { - // - // Read the number of blocks - // - Status = FindToken (InfFile, FILES_SECTION_STRING, EFI_FILE_NAME_STRING, Index, Value); - - if (Status == EFI_SUCCESS) { - // - // Add the file - // - strcpy (FvInfo->FvFiles[Index], Value); - } else { - break; - } - } - - if (FindSection (InfFile, COMPONENT_SECTION_STRING)) { - Index = 0; - // - // Read component FV_VARIABLE - // - Status = FindToken (InfFile, COMPONENT_SECTION_STRING, EFI_NV_VARIABLE_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Add the component - // - strcpy (FvInfo->FvComponents[Index].ComponentName, EFI_NV_VARIABLE_STRING); - Status = AsciiStringToUint64 (Value, FALSE, &Value64); - if (EFI_ERROR (Status)) { - printf ("ERROR: %s is not a valid integer.\n", EFI_NV_VARIABLE_STRING); - return EFI_ABORTED; - } - - FvInfo->FvComponents[Index].Size = (UINTN) Value64; - } else { - printf ("WARNING: Could not read %s.\n", EFI_NV_VARIABLE_STRING); - } - - Index++; - // - // Read component FV_EVENT_LOG - // - Status = FindToken (InfFile, COMPONENT_SECTION_STRING, EFI_NV_EVENT_LOG_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Add the component - // - strcpy (FvInfo->FvComponents[Index].ComponentName, EFI_NV_EVENT_LOG_STRING); - Status = AsciiStringToUint64 (Value, FALSE, &Value64); - if (EFI_ERROR (Status)) { - printf ("ERROR: %s is not a valid integer.\n", EFI_NV_EVENT_LOG_STRING); - return EFI_ABORTED; - } - - FvInfo->FvComponents[Index].Size = (UINTN) Value64; - } else { - printf ("WARNING: Could not read %s.\n", EFI_NV_EVENT_LOG_STRING); - } - - Index++; - // - // Read component FV_FTW_WORKING - // - Status = FindToken (InfFile, COMPONENT_SECTION_STRING, EFI_NV_FTW_WORKING_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Add the component - // - strcpy (FvInfo->FvComponents[Index].ComponentName, EFI_NV_FTW_WORKING_STRING); - Status = AsciiStringToUint64 (Value, FALSE, &Value64); - if (EFI_ERROR (Status)) { - printf ("ERROR: %s is not a valid integer.\n", EFI_NV_FTW_WORKING_STRING); - return EFI_ABORTED; - } - - FvInfo->FvComponents[Index].Size = (UINTN) Value64; - } else { - printf ("WARNING: Could not read %s.\n", EFI_NV_FTW_WORKING_STRING); - } - - Index++; - // - // Read component FV_FTW_SPARE - // - Status = FindToken (InfFile, COMPONENT_SECTION_STRING, EFI_NV_FTW_SPARE_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Add the component - // - strcpy (FvInfo->FvComponents[Index].ComponentName, EFI_NV_FTW_SPARE_STRING); - Status = AsciiStringToUint64 (Value, FALSE, &Value64); - if (EFI_ERROR (Status)) { - printf ("ERROR: %s is not a valid integer.\n", EFI_NV_FTW_SPARE_STRING); - return EFI_ABORTED; - } - - FvInfo->FvComponents[Index].Size = (UINTN) Value64; - } else { - printf ("WARNING: Could not read %s.\n", EFI_NV_FTW_SPARE_STRING); - } - } - // - // Compute size for easy access later - // - FvInfo->Size = 0; - for (Index = 0; FvInfo->FvBlocks[Index].NumBlocks; Index++) { - FvInfo->Size += FvInfo->FvBlocks[Index].NumBlocks * FvInfo->FvBlocks[Index].BlockLength; - } - - return EFI_SUCCESS; -} - -VOID -UpdateFfsFileState ( - IN EFI_FFS_FILE_HEADER *FfsFile, - IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader - ) -/*++ - -Routine Description: - - This function changes the FFS file attributes based on the erase polarity - of the FV. - -Arguments: - - FfsFile File header. - FvHeader FV header. - -Returns: - - None - ---*/ -{ - if (FvHeader->Attributes & EFI_FVB_ERASE_POLARITY) { - FfsFile->State = (UINT8)~(FfsFile->State); - } -} - -EFI_STATUS -ReadFfsAlignment ( - IN EFI_FFS_FILE_HEADER *FfsFile, - IN OUT UINT32 *Alignment - ) -/*++ - -Routine Description: - - This function determines the alignment of the FFS input file from the file - attributes. - -Arguments: - - FfsFile FFS file to parse - Alignment The minimum required alignment of the FFS file, in bytes - -Returns: - - EFI_SUCCESS The function completed successfully. - EFI_INVALID_PARAMETER One of the input parameters was invalid. - EFI_ABORTED An error occurred. - ---*/ -{ - // - // Verify input parameters. - // - if (FfsFile == NULL || Alignment == NULL) { - return EFI_INVALID_PARAMETER; - } - - switch ((FfsFile->Attributes >> 3) & 0x07) { - - case 0: - // - // 1 byte alignment - // - *Alignment = (1 << 0); - break; - - case 1: - // - // 16 byte alignment - // - *Alignment = (1 << 4); - break; - - case 2: - // - // 128 byte alignment - // - *Alignment = (1 << 7); - break; - - case 3: - // - // 512 byte alignment - // - *Alignment = (1 << 9); - break; - - case 4: - // - // 1K byte alignment - // - *Alignment = (1 << 10); - break; - - case 5: - // - // 4K byte alignment - // - *Alignment = (1 << 12); - break; - - case 6: - // - // 32K byte alignment - // - *Alignment = (1 << 15); - break; - - case 7: - // - // 64K byte alignment - // - *Alignment = (1 << 16); - break; - - default: - Error (NULL, 0, 0, "nvalid file attribute calculated, this is most likely a utility error", NULL); - return EFI_ABORTED; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -AddPadFile ( - IN OUT MEMORY_FILE *FvImage, - IN UINT32 DataAlignment - ) -/*++ - -Routine Description: - - This function adds a pad file to the FV image if it required to align the - data of the next file. - -Arguments: - - FvImage The memory image of the FV to add it to. The current offset - must be valid. - DataAlignment The data alignment of the next FFS file. - -Returns: - - EFI_SUCCESS The function completed successfully. - EFI_INVALID_PARAMETER One of the input parameters was invalid. - EFI_OUT_OF_RESOURCES Insufficient resources exist in the FV to complete - the pad file add. - ---*/ -{ - EFI_FFS_FILE_HEADER *PadFile; - EFI_GUID PadFileGuid; - UINTN PadFileSize; - - // - // Verify input parameters. - // - if (FvImage == NULL) { - return EFI_INVALID_PARAMETER; - } - // - // Basic assumption is we start from an 8 byte aligned address - // and our file header is a multiple of 8 bytes - // - assert ((UINTN) FvImage->CurrentFilePointer % 8 == 0); - assert (sizeof (EFI_FFS_FILE_HEADER) % 8 == 0); - - // - // Check if a pad file is necessary - // - if (((UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + sizeof (EFI_FFS_FILE_HEADER)) % DataAlignment == 0) { - return EFI_SUCCESS; - } - // - // Write pad file header - // - PadFile = (EFI_FFS_FILE_HEADER *) FvImage->CurrentFilePointer; - - // - // Verify that we have enough space for the file header - // - if ((UINTN) (PadFile + sizeof (EFI_FFS_FILE_HEADER)) >= (UINTN) FvImage->Eof) { - return EFI_OUT_OF_RESOURCES; - } - -#ifdef __GNUC__ - { - uuid_t tmp_id; - uuid_generate (tmp_id); - memcpy (&PadFileGuid, tmp_id, sizeof (EFI_GUID)); - } -#else - UuidCreate (&PadFileGuid); -#endif - memset (PadFile, 0, sizeof (EFI_FFS_FILE_HEADER)); - memcpy (&PadFile->Name, &PadFileGuid, sizeof (EFI_GUID)); - PadFile->Type = EFI_FV_FILETYPE_FFS_PAD; - PadFile->Attributes = 0; - - // - // Calculate the pad file size - // - // - // This is the earliest possible valid offset (current plus pad file header - // plus the next file header) - // - PadFileSize = (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + (sizeof (EFI_FFS_FILE_HEADER) * 2); - - // - // Add whatever it takes to get to the next aligned address - // - while ((PadFileSize % DataAlignment) != 0) { - PadFileSize++; - } - // - // Subtract the next file header size - // - PadFileSize -= sizeof (EFI_FFS_FILE_HEADER); - - // - // Subtract the starting offset to get size - // - PadFileSize -= (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage; - - // - // Write pad file size (calculated size minus next file header size) - // - PadFile->Size[0] = (UINT8) (PadFileSize & 0xFF); - PadFile->Size[1] = (UINT8) ((PadFileSize >> 8) & 0xFF); - PadFile->Size[2] = (UINT8) ((PadFileSize >> 16) & 0xFF); - - // - // Fill in checksums and state, they must be 0 for checksumming. - // - PadFile->IntegrityCheck.Checksum.Header = 0; - PadFile->IntegrityCheck.Checksum.File = 0; - PadFile->State = 0; - PadFile->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) PadFile, sizeof (EFI_FFS_FILE_HEADER)); - if (PadFile->Attributes & FFS_ATTRIB_CHECKSUM) { - PadFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) PadFile, PadFileSize); - } else { - PadFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; - } - - PadFile->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID; - UpdateFfsFileState ( - (EFI_FFS_FILE_HEADER *) PadFile, - (EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage - ); - - // - // Verify that we have enough space (including the padding - // - if ((UINTN) (PadFile + sizeof (EFI_FFS_FILE_HEADER)) >= (UINTN) FvImage->Eof) { - return EFI_OUT_OF_RESOURCES; - } - // - // Update the current FV pointer - // - FvImage->CurrentFilePointer += PadFileSize; - - return EFI_SUCCESS; -} - -BOOLEAN -IsVtfFile ( - IN EFI_FFS_FILE_HEADER *FileBuffer - ) -/*++ - -Routine Description: - - This function checks the header to validate if it is a VTF file - -Arguments: - - FileBuffer Buffer in which content of a file has been read. - -Returns: - - TRUE If this is a VTF file - FALSE If this is not a VTF file - ---*/ -{ - EFI_GUID VtfGuid = EFI_FFS_VOLUME_TOP_FILE_GUID; - if (!memcmp (&FileBuffer->Name, &VtfGuid, sizeof (EFI_GUID))) { - return TRUE; - } else { - return FALSE; - } -} - -EFI_STATUS -FfsRebaseImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINT32 *ReadSize, - OUT VOID *Buffer - ) -/*++ - -Routine Description: - - Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file - -Arguments: - - FileHandle - The handle to the PE/COFF file - - FileOffset - The offset, in bytes, into the file to read - - ReadSize - The number of bytes to read from the file starting at FileOffset - - Buffer - A pointer to the buffer to read the data into. - -Returns: - - EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset - ---*/ -{ - CHAR8 *Destination8; - CHAR8 *Source8; - UINT32 Length; - - Destination8 = Buffer; - Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset); - Length = *ReadSize; - while (Length--) { - *(Destination8++) = *(Source8++); - } - - return EFI_SUCCESS; -} - - -EFI_STATUS -AddSymFile ( - IN UINT64 BaseAddress, - IN EFI_FFS_FILE_HEADER *FfsFile, - IN OUT MEMORY_FILE *SymImage, - IN CHAR8 *SourceFileName - ) -/*++ - -Routine Description: - - This function adds the SYM tokens in the source file to the destination file. - The SYM tokens are updated to reflect the base address. - -Arguments: - - BaseAddress The base address for the new SYM tokens. - FfsFile Pointer to the beginning of the FFS file in question. - SymImage The memory file to update with symbol information. - SourceFileName The source file. - -Returns: - - EFI_SUCCESS The function completed successfully. - EFI_INVALID_PARAMETER One of the input parameters was invalid. - EFI_ABORTED An error occurred. - ---*/ -{ - FILE *SourceFile; - - CHAR8 Buffer[_MAX_PATH]; - CHAR8 Type[_MAX_PATH]; - CHAR8 Address[_MAX_PATH]; - CHAR8 Section[_MAX_PATH]; - CHAR8 Token[_MAX_PATH]; - CHAR8 SymFileName[_MAX_PATH]; - CHAR8 CodeModuleName[_MAX_PATH]; - CHAR8 *Ptr; - - UINT64 TokenAddress; - - EFI_STATUS Status; - EFI_FILE_SECTION_POINTER Pe32Section; - UINT32 EntryPoint; - UINT32 BaseOfCode; - UINT16 MachineType; - - // - // Verify input parameters. - // - if (BaseAddress == 0 || FfsFile == NULL || SymImage == NULL || SourceFileName == NULL) { - Error (NULL, 0, 0, "invalid parameter passed to AddSymFile()", NULL); - return EFI_INVALID_PARAMETER; - } - // - // Check if we want to add this file - // - // - // Get the file name - // - strcpy (Buffer, SourceFileName); - - // - // Copy the file name for the path of the sym file and truncate the name portion. - // - strcpy (SymFileName, Buffer); - Ptr = strrchr (SymFileName, '\\'); - assert (Ptr); - Ptr[0] = 0; - - // - // Find the file extension and make it lower case - // - Ptr = strrchr (SymFileName, '.'); - if (Ptr != NULL) { - strlwr (Ptr); - } - // - // Check if it is PEI file - // - if (strstr (Buffer, ".pei") != NULL) { - // - // Find the human readable portion - // - if (!strtok (Buffer, "-") || - !strtok (NULL, "-") || - !strtok (NULL, "-") || - !strtok (NULL, "-") || - !strtok (NULL, "-") || - !strcpy (Buffer, strtok (NULL, ".")) - ) { - Error (NULL, 0, 0, "failed to find human readable portion of the file name in AddSymFile()", NULL); - return EFI_ABORTED; - } - // - // Save code module name - // - strcpy (CodeModuleName, Buffer); - - // - // Add the symbol file name and extension to the file path. - // - strcat (Buffer, ".sym"); - strcat (SymFileName, "\\"); - strcat (SymFileName, Buffer); - } else { - // - // Only handle PEIM files. - // - return EFI_SUCCESS; - } - // - // Find PE32 section - // - Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, 1, &Pe32Section); - - // - // BUGBUG: Assume if no PE32 section it is PIC and hardcode base address - // - if (Status == EFI_NOT_FOUND) { - Status = GetSectionByType (FfsFile, EFI_SECTION_TE, 1, &Pe32Section); - } - - if (Status == EFI_SUCCESS) { - Status = GetPe32Info ( - (VOID *) ((UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32)), - &EntryPoint, - &BaseOfCode, - &MachineType - ); - } else if (Status == EFI_NOT_FOUND) { - // - // For PIC, hardcode. - // - BaseOfCode = 0x60; - Status = EFI_SUCCESS; - } else { - Error (NULL, 0, 0, "could not parse a PE32 section from the PEI file", NULL); - return Status; - } - - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "GetPe32Info() could not get PE32 entry point for PEI file", NULL); - return Status; - } - - // - // Open the source file - // - SourceFile = fopen (SymFileName, "r"); - if (SourceFile == NULL) { - // - // SYM files are not required. - // - return EFI_SUCCESS; - } - // - // Read the first line - // - if (fgets (Buffer, _MAX_PATH, SourceFile) == NULL) { - Buffer[0] = 0; - } - // - // Make sure it matches the expected sym format - // - if (strcmp (Buffer, "TEXTSYM format | V1.0\n")) { - fclose (SourceFile); - Error (NULL, 0, 0, "AddSymFile() found unexpected sym format in input file", NULL); - return EFI_ABORTED; - } - // - // Read in the file - // - while (feof (SourceFile) == 0) { - // - // Read a line - // - if (fscanf ( - SourceFile, - "%s | %s | %s | %s\n", - Type, - Address, - Section, - Token - ) == 4) { - // - // If the token starts with "??" ignore it - // - if (Token[0] == '?' && Token[1] == '?') { - continue; - } - // - // Get the token address - // - AsciiStringToUint64 (Address, TRUE, &TokenAddress); - - // - // Add the base address - // - TokenAddress += BaseAddress; - - // - // If PE32 or TE section then find the start of code. For PIC it is hardcoded. - // - if (Pe32Section.Pe32Section) { - // - // Add the offset of the PE32 section - // - TokenAddress += (UINTN) Pe32Section.Pe32Section - (UINTN) FfsFile; - - // - // Add the size of the PE32 section header - // - TokenAddress += sizeof (EFI_PE32_SECTION); - } else { - // - // For PIC hardcoded. - // - TokenAddress += 0x28; - } - - // - // Add the beginning of the code - // - TokenAddress += BaseOfCode; - - sprintf ( - Buffer, - "%s | %016I64X | %s | _%s%s\n", - Type, - TokenAddress, - Section, - CodeModuleName, - Token - ); - memcpy (SymImage->CurrentFilePointer, Buffer, strlen (Buffer) + 1); - SymImage->CurrentFilePointer = (UINT8 *) (((UINTN) SymImage->CurrentFilePointer) + strlen (Buffer) + 1); - } - } - - fclose (SourceFile); - return EFI_SUCCESS; -} - -EFI_STATUS -AddFile ( - IN OUT MEMORY_FILE *FvImage, - IN FV_INFO *FvInfo, - IN UINTN Index, - IN OUT EFI_FFS_FILE_HEADER **VtfFileImage, - IN OUT MEMORY_FILE *SymImage - ) -/*++ - -Routine Description: - - This function adds a file to the FV image. The file will pad to the - appropriate alignment if required. - -Arguments: - - FvImage The memory image of the FV to add it to. The current offset - must be valid. - FvInfo Pointer to information about the FV. - Index The file in the FvInfo file list to add. - VtfFileImage A pointer to the VTF file within the FvImage. If this is equal - to the end of the FvImage then no VTF previously found. - SymImage The memory image of the Sym file to update if symbols are present. - The current offset must be valid. - -Returns: - - EFI_SUCCESS The function completed successfully. - EFI_INVALID_PARAMETER One of the input parameters was invalid. - EFI_ABORTED An error occurred. - EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the add. - ---*/ -{ - FILE *NewFile; - UINTN FileSize; - UINT8 *FileBuffer; - UINTN NumBytesRead; - UINT32 CurrentFileAlignment; - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS CurrentFileBaseAddress; - UINT8 VtfHeaderChecksum; - UINT8 VtfFileChecksum; - UINT8 FileState; - EFI_FFS_FILE_TAIL TailValue; - UINT32 TailSize; - // - // Verify input parameters. - // - if (FvImage == NULL || FvInfo == NULL || FvInfo->FvFiles[Index][0] == 0 || VtfFileImage == NULL || SymImage == NULL) { - return EFI_INVALID_PARAMETER; - } - // - // Read the file to add - // - NewFile = fopen (FvInfo->FvFiles[Index], "rb"); - - if (NewFile == NULL) { - Error (NULL, 0, 0, FvInfo->FvFiles[Index], "failed to open file for reading"); - return EFI_ABORTED; - } - // - // Get the file size - // -#ifdef __GNUC__ - { - struct stat stat_buf; - fstat(fileno(NewFile), &stat_buf); - FileSize = stat_buf.st_size; - } -#else - FileSize = _filelength (fileno (NewFile)); -#endif - - // - // Read the file into a buffer - // - FileBuffer = malloc (FileSize); - if (FileBuffer == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - return EFI_OUT_OF_RESOURCES; - } - - NumBytesRead = fread (FileBuffer, sizeof (UINT8), FileSize, NewFile); - - // - // Done with the file, from this point on we will just use the buffer read. - // - fclose (NewFile); - - // - // Verify read successful - // - if (NumBytesRead != sizeof (UINT8) * FileSize) { - free (FileBuffer); - Error (NULL, 0, 0, FvInfo->FvFiles[Index], "failed to read input file contents"); - return EFI_ABORTED; - } - // - // Verify space exists to add the file - // - if (FileSize > (UINTN) ((UINTN) *VtfFileImage - (UINTN) FvImage->CurrentFilePointer)) { - Error (NULL, 0, 0, FvInfo->FvFiles[Index], "insufficient space remains to add the file"); - return EFI_OUT_OF_RESOURCES; - } - // - // Update the file state based on polarity of the FV. - // - UpdateFfsFileState ( - (EFI_FFS_FILE_HEADER *) FileBuffer, - (EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage - ); - - // - // If we have a VTF file, add it at the top. - // - if (IsVtfFile ((EFI_FFS_FILE_HEADER *) FileBuffer)) { - if ((UINTN) *VtfFileImage == (UINTN) FvImage->Eof) { - // - // No previous VTF, add this one. - // - *VtfFileImage = (EFI_FFS_FILE_HEADER *) (UINTN) ((UINTN) FvImage->FileImage + FvInfo->Size - FileSize); - // - // Sanity check. The file MUST align appropriately - // - if ((((UINTN) *VtfFileImage) & 0x07) != 0) { - Error (NULL, 0, 0, "VTF file does not align on 8-byte boundary", NULL); - } - // - // copy VTF File Header - // - memcpy (*VtfFileImage, FileBuffer, sizeof (EFI_FFS_FILE_HEADER)); - - // - // Copy VTF body - // - memcpy ( - (UINT8 *) *VtfFileImage + sizeof (EFI_FFS_FILE_HEADER), - FileBuffer + sizeof (EFI_FFS_FILE_HEADER), - FileSize - sizeof (EFI_FFS_FILE_HEADER) - ); - - // - // re-calculate the VTF File Header - // - FileState = (*VtfFileImage)->State; - (*VtfFileImage)->State = 0; - *(UINT32 *) ((*VtfFileImage)->Size) = FileSize; - (*VtfFileImage)->IntegrityCheck.Checksum.Header = 0; - (*VtfFileImage)->IntegrityCheck.Checksum.File = 0; - - VtfHeaderChecksum = CalculateChecksum8 ((UINT8 *) *VtfFileImage, sizeof (EFI_FFS_FILE_HEADER)); - (*VtfFileImage)->IntegrityCheck.Checksum.Header = VtfHeaderChecksum; - // - // Determine if it has a tail - // - if ((*VtfFileImage)->Attributes & FFS_ATTRIB_TAIL_PRESENT) { - TailSize = sizeof (EFI_FFS_FILE_TAIL); - } else { - TailSize = 0; - } - - if ((*VtfFileImage)->Attributes & FFS_ATTRIB_CHECKSUM) { - VtfFileChecksum = CalculateChecksum8 ((UINT8 *) *VtfFileImage, FileSize - TailSize); - (*VtfFileImage)->IntegrityCheck.Checksum.File = VtfFileChecksum; - } else { - (*VtfFileImage)->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; - } - // - // If it has a file tail, update it - // - if ((*VtfFileImage)->Attributes & FFS_ATTRIB_TAIL_PRESENT) { - TailValue = (EFI_FFS_FILE_TAIL) (~((*VtfFileImage)->IntegrityCheck.TailReference)); - *(EFI_FFS_FILE_TAIL *) (((UINTN) (*VtfFileImage) + GetLength ((*VtfFileImage)->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue; - } - (*VtfFileImage)->State = FileState; - free (FileBuffer); - return EFI_SUCCESS; - } else { - // - // Already found a VTF file. - // - Error (NULL, 0, 0, "multiple VTF files are illegal in a single FV", NULL); - free (FileBuffer); - return EFI_ABORTED; - } - } - // - // Check if alignment is required - // - Status = ReadFfsAlignment ((EFI_FFS_FILE_HEADER *) FileBuffer, &CurrentFileAlignment); - if (EFI_ERROR (Status)) { - printf ("ERROR: Could not determine alignment of file %s.\n", FvInfo->FvFiles[Index]); - free (FileBuffer); - return EFI_ABORTED; - } - // - // Add pad file if necessary - // - Status = AddPadFile (FvImage, CurrentFileAlignment); - if (EFI_ERROR (Status)) { - printf ("ERROR: Could not align the file data properly.\n"); - free (FileBuffer); - return EFI_ABORTED; - } - // - // Add file - // - if ((FvImage->CurrentFilePointer + FileSize) < FvImage->Eof) { - // - // Copy the file - // - memcpy (FvImage->CurrentFilePointer, FileBuffer, FileSize); - - // - // If the file is XIP, rebase - // - CurrentFileBaseAddress = FvInfo->BaseAddress + ((UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage); - // - // Status = RebaseFfsFile ((EFI_FFS_FILE_HEADER*) FvImage->CurrentFilePointer, CurrentFileBaseAddress); - // if (EFI_ERROR(Status)) { - // printf ("ERROR: Could not rebase the file %s.\n", FvInfo->FvFiles[Index]); - // return EFI_ABORTED; - // } - // - // Update Symbol file - // - Status = AddSymFile ( - CurrentFileBaseAddress, - (EFI_FFS_FILE_HEADER *) FvImage->CurrentFilePointer, - SymImage, - FvInfo->FvFiles[Index] - ); - assert (!EFI_ERROR (Status)); - - // - // Update the current pointer in the FV image - // - FvImage->CurrentFilePointer += FileSize; - } else { - printf ("ERROR: The firmware volume is out of space, could not add file %s.\n", FvInfo->FvFiles[Index]); - return EFI_ABORTED; - } - // - // Make next file start at QWord Boundry - // - while (((UINTN) FvImage->CurrentFilePointer & 0x07) != 0) { - FvImage->CurrentFilePointer++; - } - // - // Free allocated memory. - // - free (FileBuffer); - - return EFI_SUCCESS; -} - -EFI_STATUS -AddVariableBlock ( - IN UINT8 *FvImage, - IN UINTN Size, - IN FV_INFO *FvInfo - ) -{ - EFI_FIRMWARE_VOLUME_HEADER *FvHeader; - VARIABLE_STORE_HEADER *VarStoreHeader; - // - // Variable block should exclude FvHeader. Since the length of - // FvHeader depends on the block map, which is variable length, - // we could only decide the actual variable block length here. - // - FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FvImage; - FvImage = FvImage + FvHeader->HeaderLength; - - VarStoreHeader = (VARIABLE_STORE_HEADER *) FvImage; - - VarStoreHeader->Signature = VARIABLE_STORE_SIGNATURE; - VarStoreHeader->Size = Size - FvHeader->HeaderLength; - VarStoreHeader->Format = VARIABLE_STORE_FORMATTED; - VarStoreHeader->State = VARIABLE_STORE_HEALTHY; - VarStoreHeader->Reserved = 0; - VarStoreHeader->Reserved1 = 0; - - return EFI_SUCCESS; -} - -EFI_STATUS -AddEventLogBlock ( - IN UINT8 *FvImage, - IN UINTN Size, - IN FV_INFO *FvInfo - ) -{ - return EFI_SUCCESS; -} - -EFI_STATUS -AddFTWWorkingBlock ( - IN UINT8 *FvImage, - IN UINTN Size, - IN FV_INFO *FvInfo - ) -{ - EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *FTWHeader; - UINT32 Crc32; - - Crc32 = 0; - FTWHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) FvImage; - memcpy (&FTWHeader->Signature, &(FvInfo->FvGuid), sizeof (EFI_GUID)); - FTWHeader->WriteQueueSize = Size - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER); - CalculateCrc32 (FvImage, sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER), &Crc32); - FTWHeader->Crc = Crc32; - if (FvInfo->FvAttributes & EFI_FVB_ERASE_POLARITY) { - FTWHeader->WorkingBlockValid = 0; - FTWHeader->WorkingBlockInvalid = 1; - } else { - FTWHeader->WorkingBlockValid = 1; - FTWHeader->WorkingBlockInvalid = 0; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -AddFTWSpareBlock ( - IN UINT8 *FvImage, - IN UINTN Size, - IN FV_INFO *FvInfo - ) -{ - return EFI_SUCCESS; -} - -EFI_STATUS -GenNonFFSFv ( - IN UINT8 *FvImage, - IN FV_INFO *FvInfo - ) -/*++ - -Routine Description: - - This function generate the non FFS FV image, such as the working block - and spare block. How each component of the FV is built is component - specific. - -Arguments: - - FvImage The memory image of the FV to add it to. The current offset - must be valid. - FvInfo Pointer to information about the FV. - -Returns: - - EFI_SUCCESS The function completed successfully. - EFI_INVALID_PARAMETER One of the input parameters was invalid. - EFI_ABORTED An error occurred. - EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the add. - ---*/ -{ - UINTN Index; - EFI_FIRMWARE_VOLUME_HEADER *FvHeader; - UINT64 TotalSize; - - FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FvImage; - TotalSize = 0; - - for (Index = 0; FvInfo->FvComponents[Index].Size != 0; Index++) { - if (stricmp (FvInfo->FvComponents[Index].ComponentName, EFI_NV_VARIABLE_STRING) == 0) { - AddVariableBlock (FvImage, FvInfo->FvComponents[Index].Size, FvInfo); - } else if (stricmp (FvInfo->FvComponents[Index].ComponentName, EFI_NV_EVENT_LOG_STRING) == 0) { - AddEventLogBlock (FvImage, FvInfo->FvComponents[Index].Size, FvInfo); - } else if (stricmp (FvInfo->FvComponents[Index].ComponentName, EFI_NV_FTW_WORKING_STRING) == 0) { - AddFTWWorkingBlock (FvImage, FvInfo->FvComponents[Index].Size, FvInfo); - } else if (stricmp (FvInfo->FvComponents[Index].ComponentName, EFI_NV_FTW_SPARE_STRING) == 0) { - AddFTWSpareBlock (FvImage, FvInfo->FvComponents[Index].Size, FvInfo); - } else { - printf ("Error. Unknown Non-FFS block %s \n", FvInfo->FvComponents[Index].ComponentName); - return EFI_ABORTED; - } - - FvImage = FvImage + FvInfo->FvComponents[Index].Size; - TotalSize = TotalSize + FvInfo->FvComponents[Index].Size; - } - // - // Index and TotalSize is zero mean there's no component, so this is an empty fv - // - if ((Index != 0 || TotalSize != 0) && TotalSize != FvInfo->Size) { - printf ("Error. Component size does not sum up to FV size.\n"); - return EFI_ABORTED; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -PadFvImage ( - IN MEMORY_FILE *FvImage, - IN EFI_FFS_FILE_HEADER *VtfFileImage - ) -/*++ - -Routine Description: - - This function places a pad file between the last file in the FV and the VTF - file if the VTF file exists. - -Arguments: - - FvImage Memory file for the FV memory image - VtfFileImage The address of the VTF file. If this is the end of the FV - image, no VTF exists and no pad file is needed. - -Returns: - - EFI_SUCCESS Completed successfully. - EFI_INVALID_PARAMETER One of the input parameters was NULL. - ---*/ -{ - EFI_FFS_FILE_HEADER *PadFile; - UINTN FileSize; - - // - // If there is no VTF or the VTF naturally follows the previous file without a - // pad file, then there's nothing to do - // - if ((UINTN) VtfFileImage == (UINTN) FvImage->Eof || (void *) FvImage->CurrentFilePointer == (void *) VtfFileImage) { - return EFI_SUCCESS; - } - // - // Pad file starts at beginning of free space - // - PadFile = (EFI_FFS_FILE_HEADER *) FvImage->CurrentFilePointer; - - // - // write header - // - memset (PadFile, 0, sizeof (EFI_FFS_FILE_HEADER)); - memcpy (&PadFile->Name, &DefaultFvPadFileNameGuid, sizeof (EFI_GUID)); - PadFile->Type = EFI_FV_FILETYPE_FFS_PAD; - PadFile->Attributes = 0; - - // - // FileSize includes the EFI_FFS_FILE_HEADER - // - FileSize = (UINTN) VtfFileImage - (UINTN) FvImage->CurrentFilePointer; - PadFile->Size[0] = (UINT8) (FileSize & 0x000000FF); - PadFile->Size[1] = (UINT8) ((FileSize & 0x0000FF00) >> 8); - PadFile->Size[2] = (UINT8) ((FileSize & 0x00FF0000) >> 16); - - // - // Fill in checksums and state, must be zero during checksum calculation. - // - PadFile->IntegrityCheck.Checksum.Header = 0; - PadFile->IntegrityCheck.Checksum.File = 0; - PadFile->State = 0; - PadFile->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) PadFile, sizeof (EFI_FFS_FILE_HEADER)); - if (PadFile->Attributes & FFS_ATTRIB_CHECKSUM) { - PadFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) PadFile, FileSize); - } else { - PadFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; - } - - PadFile->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID; - - UpdateFfsFileState ( - (EFI_FFS_FILE_HEADER *) PadFile, - (EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage - ); - // - // Update the current FV pointer - // - FvImage->CurrentFilePointer = FvImage->Eof; - - return EFI_SUCCESS; -} - -EFI_STATUS -UpdateResetVector ( - IN MEMORY_FILE *FvImage, - IN FV_INFO *FvInfo, - IN EFI_FFS_FILE_HEADER *VtfFile - ) -/*++ - -Routine Description: - - This parses the FV looking for the PEI core and then plugs the address into - the SALE_ENTRY point of the BSF/VTF for IPF and does BUGBUG TBD action to - complete an IA32 Bootstrap FV. - -Arguments: - - FvImage Memory file for the FV memory image - FvInfo Information read from INF file. - VtfFile Pointer to the VTF file in the FV image. - -Returns: - - EFI_SUCCESS Function Completed successfully. - EFI_ABORTED Error encountered. - EFI_INVALID_PARAMETER A required parameter was NULL. - EFI_NOT_FOUND PEI Core file not found. - ---*/ -{ - EFI_FFS_FILE_HEADER *PeiCoreFile; - EFI_FFS_FILE_HEADER *SecCoreFile; - EFI_STATUS Status; - EFI_FILE_SECTION_POINTER Pe32Section; - UINT32 EntryPoint; - UINT32 BaseOfCode; - UINT16 MachineType; - EFI_PHYSICAL_ADDRESS PeiCorePhysicalAddress; - EFI_PHYSICAL_ADDRESS SecCorePhysicalAddress; - EFI_PHYSICAL_ADDRESS *SecCoreEntryAddressPtr; - UINT32 *Ia32ResetAddressPtr; - UINT8 *BytePointer; - UINT8 *BytePointer2; - UINT16 *WordPointer; - UINT16 CheckSum; - UINTN Index; - EFI_FFS_FILE_STATE SavedState; - EFI_FFS_FILE_TAIL TailValue; - UINT32 TailSize; - UINT64 FitAddress; - FIT_TABLE *FitTablePtr; - - // - // Verify input parameters - // - if (FvImage == NULL || FvInfo == NULL || VtfFile == NULL) { - return EFI_INVALID_PARAMETER; - } - // - // Initialize FV library - // - InitializeFvLib (FvImage->FileImage, (UINTN) FvImage->Eof - (UINTN) FvImage->FileImage); - - // - // Verify VTF file - // - Status = VerifyFfsFile (VtfFile); - if (EFI_ERROR (Status)) { - return EFI_INVALID_PARAMETER; - } - // - // Find the PEI Core - // - Status = GetFileByType (EFI_FV_FILETYPE_PEI_CORE, 1, &PeiCoreFile); - if (EFI_ERROR (Status) || PeiCoreFile == NULL) { - Error (NULL, 0, 0, "could not find the PEI core in the FV", NULL); - return EFI_ABORTED; - } - - // - // PEI Core found, now find PE32 or TE section - // - Status = GetSectionByType (PeiCoreFile, EFI_SECTION_PE32, 1, &Pe32Section); - if (Status == EFI_NOT_FOUND) { - Status = GetSectionByType (PeiCoreFile, EFI_SECTION_TE, 1, &Pe32Section); - } - - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "could not find PE32 or TE section in PEI core file", NULL); - return EFI_ABORTED; - } - - Status = GetPe32Info ( - (VOID *) ((UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32)), - &EntryPoint, - &BaseOfCode, - &MachineType - ); - - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "could not get PE32 entry point for PEI core", NULL); - return EFI_ABORTED; - } - // - // Physical address is FV base + offset of PE32 + offset of the entry point - // - PeiCorePhysicalAddress = FvInfo->BaseAddress; - PeiCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32) - (UINTN) FvImage->FileImage; - PeiCorePhysicalAddress += EntryPoint; - - if (MachineType == EFI_IMAGE_MACHINE_IA64) { - // - // Update PEI_CORE address - // - // - // Set the uncached attribute bit in the physical address - // - PeiCorePhysicalAddress |= 0x8000000000000000ULL; - - // - // Check if address is aligned on a 16 byte boundary - // - if (PeiCorePhysicalAddress & 0xF) { - printf ( - "ERROR: PEI_CORE entry point is not aligned on a 16 byte boundary, address specified is %Xh.\n", - PeiCorePhysicalAddress - ); - return EFI_ABORTED; - } - // - // First Get the FIT table address - // - FitAddress = (*(UINT64 *) (FvImage->Eof - IPF_FIT_ADDRESS_OFFSET)) & 0xFFFFFFFF; - - FitTablePtr = (FIT_TABLE *) (FvImage->FileImage + (FitAddress - FvInfo->BaseAddress)); - - Status = UpdatePeiCoreEntryInFit (FitTablePtr, PeiCorePhysicalAddress); - - if (!EFI_ERROR (Status)) { - UpdateFitCheckSum (FitTablePtr); - } - // - // Find the Sec Core - // - Status = GetFileByType (EFI_FV_FILETYPE_SECURITY_CORE, 1, &SecCoreFile); - if (EFI_ERROR (Status) || SecCoreFile == NULL) { - Error (NULL, 0, 0, "could not find the Sec core in the FV", NULL); - return EFI_ABORTED; - } - // - // Sec Core found, now find PE32 section - // - Status = GetSectionByType (SecCoreFile, EFI_SECTION_PE32, 1, &Pe32Section); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "could not find PE32 section in SEC core file", NULL); - return EFI_ABORTED; - } - - Status = GetPe32Info ( - (VOID *) ((UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32)), - &EntryPoint, - &BaseOfCode, - &MachineType - ); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "could not get PE32 entry point for SEC core", NULL); - return EFI_ABORTED; - } - // - // Physical address is FV base + offset of PE32 + offset of the entry point - // - SecCorePhysicalAddress = FvInfo->BaseAddress; - SecCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32) - (UINTN) FvImage->FileImage; - SecCorePhysicalAddress += EntryPoint; - - // - // Update SEC_CORE address - // - // - // Set the uncached attribute bit in the physical address - // - SecCorePhysicalAddress |= 0x8000000000000000ULL; - - // - // Update the address - // - SecCoreEntryAddressPtr = (EFI_PHYSICAL_ADDRESS *) ((UINTN) FvImage->Eof - IPF_SALE_ENTRY_ADDRESS_OFFSET); - *SecCoreEntryAddressPtr = SecCorePhysicalAddress; - - // - // Check if address is aligned on a 16 byte boundary - // - if (SecCorePhysicalAddress & 0xF) { - printf ( - "ERROR: SALE_ENTRY entry point is not aligned on a 16 byte boundary, address specified is %Xh.\n", - SecCorePhysicalAddress - ); - return EFI_ABORTED; - } - } else if (MachineType == EFI_IMAGE_MACHINE_IA32) { - // - // Get the location to update - // - Ia32ResetAddressPtr = (UINT32 *) ((UINTN) FvImage->Eof - IA32_PEI_CORE_ENTRY_OFFSET); - - // - // Write lower 32 bits of physical address - // - *Ia32ResetAddressPtr = (UINT32) PeiCorePhysicalAddress; - - // - // Update the BFV base address - // - Ia32ResetAddressPtr = (UINT32 *) ((UINTN) FvImage->Eof - 4); - *Ia32ResetAddressPtr = (UINT32) (FvInfo->BaseAddress); - - CheckSum = 0x0000; - - // - // Update the Startup AP in the FVH header block ZeroVector region. - // - BytePointer = (UINT8 *) ((UINTN) FvImage->FileImage); - BytePointer2 = (FvInfo->Size == 0x10000) ? m64kRecoveryStartupApDataArray : m128kRecoveryStartupApDataArray; - for (Index = 0; Index < SIZEOF_STARTUP_DATA_ARRAY; Index++) { - *BytePointer++ = *BytePointer2++; - } - // - // Calculate the checksum - // - WordPointer = (UINT16 *) ((UINTN) FvImage->FileImage); - for (Index = 0; Index < SIZEOF_STARTUP_DATA_ARRAY / 2; Index++) { - CheckSum = (UINT16) (CheckSum + ((UINT16) *WordPointer)); - WordPointer++; - } - // - // Update the checksum field - // - BytePointer = (UINT8 *) ((UINTN) FvImage->FileImage); - BytePointer += (SIZEOF_STARTUP_DATA_ARRAY - 2); - WordPointer = (UINT16 *) BytePointer; - *WordPointer = (UINT16) (0x10000 - (UINT32) CheckSum); - } else { - Error (NULL, 0, 0, "invalid machine type in PEI core", "machine type=0x%X", (UINT32) MachineType); - return EFI_ABORTED; - } - // - // Determine if it has an FFS file tail. - // - if (VtfFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) { - TailSize = sizeof (EFI_FFS_FILE_TAIL); - } else { - TailSize = 0; - } - // - // Now update file checksum - // - SavedState = VtfFile->State; - VtfFile->IntegrityCheck.Checksum.File = 0; - VtfFile->State = 0; - if (VtfFile->Attributes & FFS_ATTRIB_CHECKSUM) { - VtfFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ( - (UINT8 *) VtfFile, - GetLength (VtfFile->Size) - TailSize - ); - } else { - VtfFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; - } - - VtfFile->State = SavedState; - - // - // Update tail if present - // - if (VtfFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) { - TailValue = (EFI_FFS_FILE_TAIL) (~(VtfFile->IntegrityCheck.TailReference)); - *(EFI_FFS_FILE_TAIL *) (((UINTN) (VtfFile) + GetLength (VtfFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -GetPe32Info ( - IN UINT8 *Pe32, - OUT UINT32 *EntryPoint, - OUT UINT32 *BaseOfCode, - OUT UINT16 *MachineType - ) -/*++ - -Routine Description: - - Retrieves the PE32 entry point offset and machine type from PE image or TeImage. - See EfiImage.h for machine types. The entry point offset is from the beginning - of the PE32 buffer passed in. - -Arguments: - - Pe32 Beginning of the PE32. - EntryPoint Offset from the beginning of the PE32 to the image entry point. - BaseOfCode Base address of code. - MachineType Magic number for the machine type. - -Returns: - - EFI_SUCCESS Function completed successfully. - EFI_ABORTED Error encountered. - EFI_INVALID_PARAMETER A required parameter was NULL. - EFI_UNSUPPORTED The operation is unsupported. - ---*/ -{ - EFI_IMAGE_DOS_HEADER *DosHeader; - EFI_IMAGE_NT_HEADERS *NtHeader; - EFI_TE_IMAGE_HEADER *TeHeader; - - // - // Verify input parameters - // - if (Pe32 == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // First check whether it is one TE Image. - // - TeHeader = (EFI_TE_IMAGE_HEADER *) Pe32; - if (TeHeader->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - // - // By TeImage Header to get output - // - *EntryPoint = TeHeader->AddressOfEntryPoint + sizeof (EFI_TE_IMAGE_HEADER) - TeHeader->StrippedSize; - *BaseOfCode = TeHeader->BaseOfCode + sizeof (EFI_TE_IMAGE_HEADER) - TeHeader->StrippedSize; - *MachineType = TeHeader->Machine; - } else { - - // - // Then check whether - // First is the DOS header - // - DosHeader = (EFI_IMAGE_DOS_HEADER *) Pe32; - - // - // Verify DOS header is expected - // - if (DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) { - printf ("ERROR: Unknown magic number in the DOS header, 0x%04X.\n", DosHeader->e_magic); - return EFI_UNSUPPORTED; - } - // - // Immediately following is the NT header. - // - NtHeader = (EFI_IMAGE_NT_HEADERS *) ((UINTN) Pe32 + DosHeader->e_lfanew); - - // - // Verify NT header is expected - // - if (NtHeader->Signature != EFI_IMAGE_NT_SIGNATURE) { - printf ("ERROR: Unrecognized image signature 0x%08X.\n", NtHeader->Signature); - return EFI_UNSUPPORTED; - } - // - // Get output - // - *EntryPoint = NtHeader->OptionalHeader.AddressOfEntryPoint; - *BaseOfCode = NtHeader->OptionalHeader.BaseOfCode; - *MachineType = NtHeader->FileHeader.Machine; - } - - // - // Verify machine type is supported - // - if (*MachineType != EFI_IMAGE_MACHINE_IA32 && *MachineType != EFI_IMAGE_MACHINE_IA64 && *MachineType != EFI_IMAGE_MACHINE_X64 && *MachineType != EFI_IMAGE_MACHINE_EBC) { - printf ("ERROR: Unrecognized machine type in the PE32 file.\n"); - return EFI_UNSUPPORTED; - } - - return EFI_SUCCESS; -} -// -// Exposed function implementations (prototypes are defined in GenFvImageLib.h) -// -EFI_STATUS -GenerateFvImage ( - IN CHAR8 *InfFileImage, - IN UINTN InfFileSize, - OUT UINT8 **FvImage, - OUT UINTN *FvImageSize, - OUT CHAR8 **FvFileName, - OUT UINT8 **SymImage, - OUT UINTN *SymImageSize, - OUT CHAR8 **SymFileName - ) -/*++ - -Routine Description: - - This is the main function which will be called from application. - -Arguments: - - InfFileImage Buffer containing the INF file contents. - InfFileSize Size of the contents of the InfFileImage buffer. - FvImage Pointer to the FV image created. - FvImageSize Size of the FV image created and pointed to by FvImage. - FvFileName Requested name for the FV file. - SymImage Pointer to the Sym image created. - SymImageSize Size of the Sym image created and pointed to by SymImage. - SymFileName Requested name for the Sym file. - -Returns: - - EFI_SUCCESS Function completed successfully. - EFI_OUT_OF_RESOURCES Could not allocate required resources. - EFI_ABORTED Error encountered. - EFI_INVALID_PARAMETER A required parameter was NULL. - ---*/ -{ - EFI_STATUS Status; - MEMORY_FILE InfMemoryFile; - MEMORY_FILE FvImageMemoryFile; - MEMORY_FILE SymImageMemoryFile; - FV_INFO FvInfo; - UINTN Index; - EFI_FIRMWARE_VOLUME_HEADER *FvHeader; - EFI_FFS_FILE_HEADER *VtfFileImage; - - // - // Check for invalid parameter - // - if (InfFileImage == NULL || FvImage == NULL || FvImageSize == NULL || FvFileName == NULL) { - return EFI_INVALID_PARAMETER; - } - // - // Initialize file structures - // - InfMemoryFile.FileImage = InfFileImage; - InfMemoryFile.CurrentFilePointer = InfFileImage; - InfMemoryFile.Eof = InfFileImage + InfFileSize; - - // - // Parse the FV inf file for header information - // - Status = ParseFvInf (&InfMemoryFile, &FvInfo); - if (EFI_ERROR (Status)) { - printf ("ERROR: Could not parse the input INF file.\n"); - return EFI_ABORTED; - } - // - // Update the file name return values - // - strcpy (*FvFileName, FvInfo.FvName); - strcpy (*SymFileName, FvInfo.SymName); - - // - // Calculate the FV size - // - *FvImageSize = FvInfo.Size; - - // - // Allocate the FV - // - *FvImage = malloc (*FvImageSize); - if (*FvImage == NULL) { - return EFI_OUT_OF_RESOURCES; - } - // - // Allocate space for symbol file storage - // - *SymImage = malloc (SYMBOL_FILE_SIZE); - if (*SymImage == NULL) { - return EFI_OUT_OF_RESOURCES; - } - // - // Initialize the FV to the erase polarity - // - if (FvInfo.FvAttributes & EFI_FVB_ERASE_POLARITY) { - memset (*FvImage, -1, *FvImageSize); - } else { - memset (*FvImage, 0, *FvImageSize); - } - // - // Initialize FV header - // - FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) *FvImage; - - // - // Initialize the zero vector to all zeros. - // - memset (FvHeader->ZeroVector, 0, 16); - - // - // Copy the FFS GUID - // - memcpy (&FvHeader->FileSystemGuid, &FvInfo.FvGuid, sizeof (EFI_GUID)); - - FvHeader->FvLength = *FvImageSize; - FvHeader->Signature = EFI_FVH_SIGNATURE; - FvHeader->Attributes = FvInfo.FvAttributes; - FvHeader->Revision = EFI_FVH_REVISION; - FvHeader->Reserved[0] = 0; - FvHeader->Reserved[1] = 0; - FvHeader->Reserved[2] = 0; - - // - // Copy firmware block map - // - for (Index = 0; FvInfo.FvBlocks[Index].NumBlocks != 0; Index++) { - FvHeader->FvBlockMap[Index].NumBlocks = FvInfo.FvBlocks[Index].NumBlocks; - FvHeader->FvBlockMap[Index].BlockLength = FvInfo.FvBlocks[Index].BlockLength; - } - // - // Add block map terminator - // - FvHeader->FvBlockMap[Index].NumBlocks = 0; - FvHeader->FvBlockMap[Index].BlockLength = 0; - - // - // Complete the header - // - FvHeader->HeaderLength = (UINT16) (((UINTN) &(FvHeader->FvBlockMap[Index + 1])) - (UINTN) *FvImage); - FvHeader->Checksum = 0; - FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); - - // - // If there is no FFS file, find and generate each components of the FV - // - if (FvInfo.FvFiles[0][0] == 0) { - Status = GenNonFFSFv (*FvImage, &FvInfo); - if (EFI_ERROR (Status)) { - printf ("ERROR: Could not generate NonFFS FV.\n"); - free (*FvImage); - return EFI_ABORTED; - } - - return EFI_SUCCESS; - } - // - // Initialize our "file" view of the buffer - // - FvImageMemoryFile.FileImage = *FvImage; - FvImageMemoryFile.CurrentFilePointer = *FvImage + FvHeader->HeaderLength; - FvImageMemoryFile.Eof = *FvImage +*FvImageSize; - - // - // Initialize our "file" view of the symbol file. - // - SymImageMemoryFile.FileImage = *SymImage; - SymImageMemoryFile.CurrentFilePointer = *SymImage; - SymImageMemoryFile.Eof = *FvImage + SYMBOL_FILE_SIZE; - - // - // Initialize the FV library. - // - InitializeFvLib (FvImageMemoryFile.FileImage, FvInfo.Size); - - // - // Files start on 8 byte alignments, so move to the next 8 byte aligned - // address. For now, just assert if it isn't. Currently FV header is - // always a multiple of 8 bytes. - // BUGBUG: Handle this better - // - assert ((((UINTN) FvImageMemoryFile.CurrentFilePointer) % 8) == 0); - - // - // Initialize the VTF file address. - // - VtfFileImage = (EFI_FFS_FILE_HEADER *) FvImageMemoryFile.Eof; - - // - // Add files to FV - // - for (Index = 0; FvInfo.FvFiles[Index][0] != 0; Index++) { - // - // Add the file - // - Status = AddFile (&FvImageMemoryFile, &FvInfo, Index, &VtfFileImage, &SymImageMemoryFile); - - // - // Exit if error detected while adding the file - // - if (EFI_ERROR (Status)) { - printf ("ERROR: Could not add file %s.\n", FvInfo.FvFiles[Index]); - free (*FvImage); - return EFI_ABORTED; - } - } - // - // If there is a VTF file, some special actions need to occur. - // - if ((UINTN) VtfFileImage != (UINTN) FvImageMemoryFile.Eof) { - // - // Pad from the end of the last file to the beginning of the VTF file. - // - Status = PadFvImage (&FvImageMemoryFile, VtfFileImage); - if (EFI_ERROR (Status)) { - printf ("ERROR: Could not create the pad file between the last file and the VTF file.\n"); - free (*FvImage); - return EFI_ABORTED; - } - // - // Update reset vector (SALE_ENTRY for IPF) - // Now for IA32 and IA64 platform, the fv which has bsf file must have the - // EndAddress of 0xFFFFFFFF. Thus, only this type fv needs to update the - // reset vector. If the PEI Core is found, the VTF file will probably get - // corrupted by updating the entry point. - // - if ((FvInfo.BaseAddress + FvInfo.Size) == FV_IMAGES_TOP_ADDRESS) { - Status = UpdateResetVector (&FvImageMemoryFile, &FvInfo, VtfFileImage); - if (EFI_ERROR(Status)) { - printf ("ERROR: Could not update the reset vector.\n"); - free (*FvImage); - return EFI_ABORTED; - } - } - } - // - // Determine final Sym file size - // - *SymImageSize = SymImageMemoryFile.CurrentFilePointer - SymImageMemoryFile.FileImage; - - return EFI_SUCCESS; -} - -EFI_STATUS -UpdatePeiCoreEntryInFit ( - IN FIT_TABLE *FitTablePtr, - IN UINT64 PeiCorePhysicalAddress - ) -/*++ - -Routine Description: - - This function is used to update the Pei Core address in FIT, this can be used by Sec core to pass control from - Sec to Pei Core - -Arguments: - - FitTablePtr - The pointer of FIT_TABLE. - PeiCorePhysicalAddress - The address of Pei Core entry. - -Returns: - - EFI_SUCCESS - The PEI_CORE FIT entry was updated successfully. - EFI_NOT_FOUND - Not found the PEI_CORE FIT entry. - ---*/ -{ - FIT_TABLE *TmpFitPtr; - UINTN Index; - UINTN NumFitComponents; - - TmpFitPtr = FitTablePtr; - NumFitComponents = TmpFitPtr->CompSize; - - for (Index = 0; Index < NumFitComponents; Index++) { - if ((TmpFitPtr->CvAndType & FIT_TYPE_MASK) == COMP_TYPE_FIT_PEICORE) { - TmpFitPtr->CompAddress = PeiCorePhysicalAddress; - return EFI_SUCCESS; - } - - TmpFitPtr++; - } - - return EFI_NOT_FOUND; -} - -VOID -UpdateFitCheckSum ( - IN FIT_TABLE *FitTablePtr - ) -/*++ - -Routine Description: - - This function is used to update the checksum for FIT. - - -Arguments: - - FitTablePtr - The pointer of FIT_TABLE. - -Returns: - - None. - ---*/ -{ - if ((FitTablePtr->CvAndType & CHECKSUM_BIT_MASK) >> 7) { - FitTablePtr->CheckSum = 0; - FitTablePtr->CheckSum = CalculateChecksum8 ((UINT8 *) FitTablePtr, FitTablePtr->CompSize * 16); - } -} diff --git a/Tools/CodeTools/TianoTools/GenFvImage/GenFvImageLib.h b/Tools/CodeTools/TianoTools/GenFvImage/GenFvImageLib.h deleted file mode 100644 index 47a5a3b1b2..0000000000 --- a/Tools/CodeTools/TianoTools/GenFvImage/GenFvImageLib.h +++ /dev/null @@ -1,142 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - GenFvImageLib.h - -Abstract: - - This file contains describes the public interfaces to the GenFvImage Library. - The basic purpose of the library is to create Firmware Volume images. - ---*/ - -#ifndef _EFI_GEN_FV_IMAGE_LIB_H -#define _EFI_GEN_FV_IMAGE_LIB_H - -// -// Include files -// -#include -#include - -#include "ParseInf.h" - -// -// Following definition is used for FIT in IPF -// -#define COMP_TYPE_FIT_PEICORE 0x10 -#define COMP_TYPE_FIT_UNUSED 0x7F - -#define FIT_TYPE_MASK 0x7F -#define CHECKSUM_BIT_MASK 0x80 - -#pragma pack(1) - -typedef struct { - UINT64 CompAddress; - UINT32 CompSize; - UINT16 CompVersion; - UINT8 CvAndType; - UINT8 CheckSum; -} FIT_TABLE; - -#pragma pack() -// -// Exported function prototypes -// -EFI_STATUS -GenerateFvImage ( - IN CHAR8 *InfFileImage, - IN UINTN InfFileSize, - OUT UINT8 **FvImage, - OUT UINTN *FvImageSize, - OUT CHAR8 **FvFileName, - OUT UINT8 **SymImage, - OUT UINTN *SymImageSize, - OUT CHAR8 **SymFileName - ) -; - -/*++ - -Routine Description: - - This is the main function which will be called from application. - -Arguments: - - InfFileImage Buffer containing the INF file contents. - InfFileSize Size of the contents of the InfFileImage buffer. - FvImage Pointer to the FV image created. - FvImageSize Size of the FV image created and pointed to by FvImage. - FvFileName Requested name for the FV file. - SymImage Pointer to the Sym image created. - SymImageSize Size of the Sym image created and pointed to by SymImage. - SymFileName Requested name for the Sym file. - -Returns: - - EFI_SUCCESS Function completed successfully. - EFI_OUT_OF_RESOURCES Could not allocate required resources. - EFI_ABORTED Error encountered. - EFI_INVALID_PARAMETER A required parameter was NULL. - ---*/ -EFI_STATUS -UpdatePeiCoreEntryInFit ( - IN FIT_TABLE *FitTablePtr, - IN UINT64 PeiCorePhysicalAddress - ) -; - -/*++ - -Routine Description: - - This function is used to update the Pei Core address in FIT, this can be used by Sec core to pass control from - Sec to Pei Core - -Arguments: - - FitTablePtr - The pointer of FIT_TABLE. - PeiCorePhysicalAddress - The address of Pei Core entry. - -Returns: - - EFI_SUCCESS - The PEI_CORE FIT entry was updated successfully. - EFI_NOT_FOUND - Not found the PEI_CORE FIT entry. - ---*/ -VOID -UpdateFitCheckSum ( - IN FIT_TABLE *FitTablePtr - ) -; - -/*++ - -Routine Description: - - This function is used to update the checksum for FIT. - - -Arguments: - - FitTablePtr - The pointer of FIT_TABLE. - -Returns: - - None. - ---*/ -#endif diff --git a/Tools/CodeTools/TianoTools/GenFvImage/GenFvImageLibInternal.h b/Tools/CodeTools/TianoTools/GenFvImage/GenFvImageLibInternal.h deleted file mode 100644 index cff3b1aea4..0000000000 --- a/Tools/CodeTools/TianoTools/GenFvImage/GenFvImageLibInternal.h +++ /dev/null @@ -1,172 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - GenFvImageLibInternal.h - -Abstract: - - This file contains describes the private declarations for the GenFvImage Library. - The basic purpose of the library is to create Firmware Volume images. - ---*/ - -#ifndef _EFI_GEN_FV_IMAGE_LIB_INTERNAL_H -#define _EFI_GEN_FV_IMAGE_LIB_INTERNAL_H - -// -// Include files -// -#include - -#include - -#include "CommonLib.h" -#include "GenFvImageLib.h" - -// -// Private data declarations -// -// -// The maximum number of block map entries supported by the library -// -#define MAX_NUMBER_OF_FV_BLOCKS 100 - -// -// The maximum number of files in the FV supported by the library -// -#define MAX_NUMBER_OF_FILES_IN_FV 1000 -#define MAX_NUMBER_OF_COMPONENTS_IN_FV 10 - -// -// INF file strings -// -#define OPTIONS_SECTION_STRING "[options]" -#define ATTRIBUTES_SECTION_STRING "[attributes]" -#define FILES_SECTION_STRING "[files]" -#define COMPONENT_SECTION_STRING "[components]" - -#define EFI_FV_BASE_ADDRESS_STRING "EFI_BASE_ADDRESS" -#define EFI_FV_FILE_NAME_STRING "EFI_FILE_NAME" -#define EFI_SYM_FILE_NAME_STRING "EFI_SYM_FILE_NAME" -#define EFI_NUM_BLOCKS_STRING "EFI_NUM_BLOCKS" -#define EFI_BLOCK_SIZE_STRING "EFI_BLOCK_SIZE" -#define EFI_FV_GUID_STRING "EFI_FV_GUID" - -#define EFI_FVB_READ_DISABLED_CAP_STRING "EFI_READ_DISABLED_CAP" -#define EFI_FVB_READ_ENABLED_CAP_STRING "EFI_READ_ENABLED_CAP" -#define EFI_FVB_READ_STATUS_STRING "EFI_READ_STATUS" - -#define EFI_FVB_WRITE_DISABLED_CAP_STRING "EFI_WRITE_DISABLED_CAP" -#define EFI_FVB_WRITE_ENABLED_CAP_STRING "EFI_WRITE_ENABLED_CAP" -#define EFI_FVB_WRITE_STATUS_STRING "EFI_WRITE_STATUS" - -#define EFI_FVB_LOCK_CAP_STRING "EFI_LOCK_CAP" -#define EFI_FVB_LOCK_STATUS_STRING "EFI_LOCK_STATUS" - -#define EFI_FVB_STICKY_WRITE_STRING "EFI_STICKY_WRITE" -#define EFI_FVB_MEMORY_MAPPED_STRING "EFI_MEMORY_MAPPED" -#define EFI_FVB_ERASE_POLARITY_STRING "EFI_ERASE_POLARITY" - -#define EFI_FVB_ALIGNMENT_CAP_STRING "EFI_ALIGNMENT_CAP" -#define EFI_FVB_ALIGNMENT_2_STRING "EFI_ALIGNMENT_2" -#define EFI_FVB_ALIGNMENT_4_STRING "EFI_ALIGNMENT_4" -#define EFI_FVB_ALIGNMENT_8_STRING "EFI_ALIGNMENT_8" -#define EFI_FVB_ALIGNMENT_16_STRING "EFI_ALIGNMENT_16" -#define EFI_FVB_ALIGNMENT_32_STRING "EFI_ALIGNMENT_32" -#define EFI_FVB_ALIGNMENT_64_STRING "EFI_ALIGNMENT_64" -#define EFI_FVB_ALIGNMENT_128_STRING "EFI_ALIGNMENT_128" -#define EFI_FVB_ALIGNMENT_256_STRING "EFI_ALIGNMENT_256" -#define EFI_FVB_ALIGNMENT_512_STRING "EFI_ALIGNMENT_512" -#define EFI_FVB_ALIGNMENT_1K_STRING "EFI_ALIGNMENT_1K" -#define EFI_FVB_ALIGNMENT_2K_STRING "EFI_ALIGNMENT_2K" -#define EFI_FVB_ALIGNMENT_4K_STRING "EFI_ALIGNMENT_4K" -#define EFI_FVB_ALIGNMENT_8K_STRING "EFI_ALIGNMENT_8K" -#define EFI_FVB_ALIGNMENT_16K_STRING "EFI_ALIGNMENT_16K" -#define EFI_FVB_ALIGNMENT_32K_STRING "EFI_ALIGNMENT_32K" -#define EFI_FVB_ALIGNMENT_64K_STRING "EFI_ALIGNMENT_64K" - -// -// Component sections -// -#define EFI_NV_VARIABLE_STRING "EFI_NV_VARIABLE" -#define EFI_NV_EVENT_LOG_STRING "EFI_NV_EVENT_LOG" -#define EFI_NV_FTW_WORKING_STRING "EFI_NV_FTW_WORKING" -#define EFI_NV_FTW_SPARE_STRING "EFI_NV_FTW_SPARE" - -#define EFI_FILE_NAME_STRING "EFI_FILE_NAME" - -#define ONE_STRING "1" -#define ZERO_STRING "0" -#define TRUE_STRING "TRUE" -#define FALSE_STRING "FALSE" -#define NULL_STRING "NULL" - -// -// Defines to calculate the offset for PEI CORE entry points -// -#define IA32_PEI_CORE_ENTRY_OFFSET 0x20 - -// -// Defines to calculate the FIT table -// -#define IPF_FIT_ADDRESS_OFFSET 0x20 - -// -// Defines to calculate the offset for SALE_ENTRY -// -#define IPF_SALE_ENTRY_ADDRESS_OFFSET 0x18 - -// -// Symbol file definitions, current max size if 512K -// -#define SYMBOL_FILE_SIZE 0x80000 - -#define FV_IMAGES_TOP_ADDRESS 0x100000000ULL - -// -// Private data types -// -// -// Component information -// -typedef struct { - UINTN Size; - CHAR8 ComponentName[_MAX_PATH]; -} COMPONENT_INFO; - -// -// FV information holder -// -typedef struct { - EFI_PHYSICAL_ADDRESS BaseAddress; - EFI_GUID FvGuid; - UINTN Size; - CHAR8 FvName[_MAX_PATH]; - CHAR8 SymName[_MAX_PATH]; - EFI_FV_BLOCK_MAP_ENTRY FvBlocks[MAX_NUMBER_OF_FV_BLOCKS]; - EFI_FVB_ATTRIBUTES FvAttributes; - CHAR8 FvFiles[MAX_NUMBER_OF_FILES_IN_FV][_MAX_PATH]; - COMPONENT_INFO FvComponents[MAX_NUMBER_OF_COMPONENTS_IN_FV]; -} FV_INFO; - -// -// Private function prototypes -// -EFI_STATUS -ParseFvInf ( - IN MEMORY_FILE *InfFile, - IN FV_INFO *FvInfo - ) -; - -#endif diff --git a/Tools/CodeTools/TianoTools/GenFvImage/build.xml b/Tools/CodeTools/TianoTools/GenFvImage/build.xml deleted file mode 100644 index ae930b053b..0000000000 --- a/Tools/CodeTools/TianoTools/GenFvImage/build.xml +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/GenSection/GenSection.c b/Tools/CodeTools/TianoTools/GenSection/GenSection.c deleted file mode 100644 index 353b1a3985..0000000000 --- a/Tools/CodeTools/TianoTools/GenSection/GenSection.c +++ /dev/null @@ -1,938 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - GenSection.c - -Abstract: - - Creates output file that is a properly formed section per the FV spec. - ---*/ - -#include -#include -#include - -#include -#include -#include - -#include "CommonLib.h" -#include "EfiCompress.h" -#include "EfiCustomizedCompress.h" -#include "Crc32.h" -#include "EfiUtilityMsgs.h" -#include "GenSection.h" - - -#define UTILITY_NAME "GenSection" - -#define PARAMETER_NOT_SPECIFIED "Parameter not specified" -#define MAXIMUM_INPUT_FILE_NUM 10 - -char *SectionTypeName[] = { - NULL, // 0x00 - reserved - "EFI_SECTION_COMPRESSION", // 0x01 - "EFI_SECTION_GUID_DEFINED", // 0x02 - NULL, // 0x03 - reserved - NULL, // 0x04 - reserved - NULL, // 0x05 - reserved - NULL, // 0x06 - reserved - NULL, // 0x07 - reserved - NULL, // 0x08 - reserved - NULL, // 0x09 - reserved - NULL, // 0x0A - reserved - NULL, // 0x0B - reserved - NULL, // 0x0C - reserved - NULL, // 0x0D - reserved - NULL, // 0x0E - reserved - NULL, // 0x0F - reserved - "EFI_SECTION_PE32", // 0x10 - "EFI_SECTION_PIC", // 0x11 - "EFI_SECTION_TE", // 0x12 - "EFI_SECTION_DXE_DEPEX", // 0x13 - "EFI_SECTION_VERSION", // 0x14 - "EFI_SECTION_USER_INTERFACE", // 0x15 - "EFI_SECTION_COMPATIBILITY16", // 0x16 - "EFI_SECTION_FIRMWARE_VOLUME_IMAGE", // 0x17 - "EFI_SECTION_FREEFORM_SUBTYPE_GUID", // 0x18 - "EFI_SECTION_RAW", // 0x19 - NULL, // 0x1A - "EFI_SECTION_PEI_DEPEX" // 0x1B -}; - -char *CompressionTypeName[] = { "NONE", "STANDARD" }; -char *GUIDedSectionTypeName[] = { "CRC32" }; -EFI_GUID gEfiCrc32SectionGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID; - -static -VOID -PrintUsageMessage ( - VOID - ) -{ - UINTN SectionType; - UINTN DisplayCount; - - printf ("Usage: "UTILITY_NAME " -i InputFile -o OutputFile -s SectionType [SectionType params]\n\n"); - printf (" Where SectionType is one of the following section types:\n\n"); - - DisplayCount = 0; - for (SectionType = 0; SectionType <= EFI_SECTION_LAST_SECTION_TYPE; SectionType++) { - if (SectionTypeName[SectionType] != NULL) { - printf (" %s\n", SectionTypeName[SectionType]); - } - } - - printf ("\n and SectionType dependent parameters are as follows:\n\n"); - printf ( - " %s: -t < %s | %s >\n", - SectionTypeName[EFI_SECTION_COMPRESSION], - CompressionTypeName[EFI_NOT_COMPRESSED], - CompressionTypeName[EFI_STANDARD_COMPRESSION] - ); - printf ( - " %s: -t < %s >\n"" // Currently only CRC32 is supported\n\n", - SectionTypeName[EFI_SECTION_GUID_DEFINED], - GUIDedSectionTypeName[EFI_SECTION_CRC32_GUID_DEFINED] - ); - printf ( - " %s: -v VersionNumber\n"" [-a \"Version string\"]\n\n", - SectionTypeName[EFI_SECTION_VERSION] - ); - printf ( - " %s: -a \"Human readable name\"\n\n", - SectionTypeName[EFI_SECTION_USER_INTERFACE] - ); -} - -VOID -Ascii2UnicodeWriteString ( - char *String, - FILE *OutFile, - BOOLEAN WriteLangCode - ) -{ - UINTN Index; - UINT8 AsciiNull; - // - // BUGBUG need to get correct language code... - // - char *EnglishLangCode = "eng"; - AsciiNull = 0; - // - // first write the language code (english only) - // - if (WriteLangCode) { - fwrite (EnglishLangCode, 1, 4, OutFile); - } - // - // Next, write out the string... Convert ASCII to Unicode in the process. - // - Index = 0; - do { - fwrite (&String[Index], 1, 1, OutFile); - fwrite (&AsciiNull, 1, 1, OutFile); - } while (String[Index++] != 0); -} - -STATUS -GenSectionCommonLeafSection ( - char **InputFileName, - int InputFileNum, - UINTN SectionType, - FILE *OutFile - ) -/*++ - -Routine Description: - - Generate a leaf section of type other than EFI_SECTION_VERSION - and EFI_SECTION_USER_INTERFACE. Input file must be well formed. - The function won't validate the input file's contents. For - common leaf sections, the input file may be a binary file. - The utility will add section header to the file. - -Arguments: - - InputFileName - Name of the input file. - - InputFileNum - Number of input files. Should be 1 for leaf section. - - SectionType - A valid section type string - - OutFile - Output file handle - -Returns: - - STATUS_ERROR - can't continue - STATUS_SUCCESS - successful return - ---*/ -{ - UINT64 InputFileLength; - FILE *InFile; - UINT8 *Buffer; - INTN TotalLength; - EFI_COMMON_SECTION_HEADER CommonSect; - STATUS Status; - - if (InputFileNum > 1) { - Error (NULL, 0, 0, "invalid parameter", "more than one input file specified"); - return STATUS_ERROR; - } else if (InputFileNum < 1) { - Error (NULL, 0, 0, "no input file specified", NULL); - return STATUS_ERROR; - } - // - // Open the input file - // - InFile = fopen (InputFileName[0], "rb"); - if (InFile == NULL) { - Error (NULL, 0, 0, InputFileName[0], "failed to open input file"); - return STATUS_ERROR; - } - - Status = STATUS_ERROR; - Buffer = NULL; - // - // Seek to the end of the input file so we can determine its size - // - fseek (InFile, 0, SEEK_END); - fgetpos (InFile, &InputFileLength); - fseek (InFile, 0, SEEK_SET); - // - // Fill in the fields in the local section header structure - // - CommonSect.Type = (EFI_SECTION_TYPE) SectionType; - TotalLength = sizeof (CommonSect) + (INTN) InputFileLength; - // - // Size must fit in 3 bytes - // - if (TotalLength >= 0x1000000) { - Error (NULL, 0, 0, InputFileName[0], "file size (0x%X) exceeds section size limit", TotalLength); - goto Done; - } - // - // Now copy the size into the section header and write out the section header - // - memcpy (&CommonSect.Size, &TotalLength, 3); - fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile); - // - // Allocate a buffer to read in the contents of the input file. Then - // read it in as one block and write it to the output file. - // - if (InputFileLength != 0) { - Buffer = (UINT8 *) malloc ((size_t) InputFileLength); - if (Buffer == NULL) { - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - goto Done; - } - - if (fread (Buffer, (size_t) InputFileLength, 1, InFile) != 1) { - Error (NULL, 0, 0, InputFileName[0], "failed to read contents of file"); - goto Done; - } - - if (fwrite (Buffer, (size_t) InputFileLength, 1, OutFile) != 1) { - Error (NULL, 0, 0, "failed to write to output file", NULL); - goto Done; - } - } - - Status = STATUS_SUCCESS; -Done: - fclose (InFile); - if (Buffer != NULL) { - free (Buffer); - } - - return Status; -} - -EFI_STATUS -GetSectionContents ( - char **InputFileName, - int InputFileNum, - UINT8 *FileBuffer, - UINTN *BufferLength - ) -/*++ - -Routine Description: - - Get the contents of all section files specified in InputFileName - into FileBuffer. - -Arguments: - - InputFileName - Name of the input file. - - InputFileNum - Number of input files. Should be at least 1. - - FileBuffer - Output buffer to contain data - - BufferLength - Actual length of the data - -Returns: - - EFI_SUCCESS on successful return - EFI_INVALID_PARAMETER if InputFileNum is less than 1 - EFI_ABORTED if unable to open input file. - ---*/ -{ - UINTN Size; - UINTN FileSize; - INTN Index; - FILE *InFile; - - if (InputFileNum < 1) { - Error (NULL, 0, 0, "must specify at least one input file", NULL); - return EFI_INVALID_PARAMETER; - } - - Size = 0; - // - // Go through our array of file names and copy their contents - // to the output buffer. - // - for (Index = 0; Index < InputFileNum; Index++) { - InFile = fopen (InputFileName[Index], "rb"); - if (InFile == NULL) { - Error (NULL, 0, 0, InputFileName[Index], "failed to open input file"); - return EFI_ABORTED; - } - - fseek (InFile, 0, SEEK_END); - FileSize = ftell (InFile); - fseek (InFile, 0, SEEK_SET); - // - // Now read the contents of the file into the buffer - // - if (FileSize > 0) { - if (fread (FileBuffer + Size, (size_t) FileSize, 1, InFile) != 1) { - Error (NULL, 0, 0, InputFileName[Index], "failed to read contents of input file"); - fclose (InFile); - return EFI_ABORTED; - } - } - - fclose (InFile); - Size += (UINTN) FileSize; - // - // make sure section ends on a DWORD boundary - // - while ((Size & 0x03) != 0) { - FileBuffer[Size] = 0; - Size++; - } - } - - *BufferLength = Size; - return EFI_SUCCESS; -} - -EFI_STATUS -GenSectionCompressionSection ( - char **InputFileName, - int InputFileNum, - UINTN SectionType, - UINTN SectionSubType, - FILE *OutFile - ) -/*++ - -Routine Description: - - Generate an encapsulating section of type EFI_SECTION_COMPRESSION - Input file must be already sectioned. The function won't validate - the input files' contents. Caller should hand in files already - with section header. - -Arguments: - - InputFileName - Name of the input file. - - InputFileNum - Number of input files. Should be at least 1. - - SectionType - Section type to generate. Should be - EFI_SECTION_COMPRESSION - - SectionSubType - Specify the compression algorithm requested. - - OutFile - Output file handle - -Returns: - - EFI_SUCCESS on successful return - EFI_INVALID_PARAMETER if InputFileNum is less than 1 - EFI_ABORTED if unable to open input file. - EFI_OUT_OF_RESOURCES No resource to complete the operation. ---*/ -{ - UINTN TotalLength; - UINTN InputLength; - UINTN CompressedLength; - UINT8 *FileBuffer; - UINT8 *OutputBuffer; - EFI_STATUS Status; - EFI_COMPRESSION_SECTION CompressionSect; - COMPRESS_FUNCTION CompressFunction; - - if (SectionType != EFI_SECTION_COMPRESSION) { - Error (NULL, 0, 0, "parameter must be EFI_SECTION_COMPRESSION", NULL); - return EFI_INVALID_PARAMETER; - } - - InputLength = 0; - FileBuffer = NULL; - OutputBuffer = NULL; - CompressedLength = 0; - FileBuffer = (UINT8 *) malloc ((1024 * 1024 * 4) * sizeof (UINT8)); - if (FileBuffer == NULL) { - Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory"); - return EFI_OUT_OF_RESOURCES; - } - // - // read all input file contents into a buffer - // - Status = GetSectionContents ( - InputFileName, - InputFileNum, - FileBuffer, - &InputLength - ); - if (EFI_ERROR (Status)) { - free (FileBuffer); - return Status; - } - - CompressFunction = NULL; - - // - // Now data is in FileBuffer, compress the data - // - switch (SectionSubType) { - case EFI_NOT_COMPRESSED: - CompressedLength = InputLength; - break; - - case EFI_STANDARD_COMPRESSION: - CompressFunction = (COMPRESS_FUNCTION) Compress; - break; - - case EFI_CUSTOMIZED_COMPRESSION: - CompressFunction = (COMPRESS_FUNCTION) CustomizedCompress; - break; - - default: - Error (NULL, 0, 0, "unknown compression type", NULL); - free (FileBuffer); - return EFI_ABORTED; - } - - if (CompressFunction != NULL) { - - Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength); - if (Status == EFI_BUFFER_TOO_SMALL) { - OutputBuffer = malloc (CompressedLength); - if (!OutputBuffer) { - free (FileBuffer); - return EFI_OUT_OF_RESOURCES; - } - - Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength); - } - - free (FileBuffer); - FileBuffer = OutputBuffer; - - if (EFI_ERROR (Status)) { - if (FileBuffer != NULL) { - free (FileBuffer); - } - - return Status; - } - } - - TotalLength = CompressedLength + sizeof (EFI_COMPRESSION_SECTION); - // - // Add the section header for the compressed data - // - CompressionSect.CommonHeader.Type = (EFI_SECTION_TYPE) SectionType; - CompressionSect.CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff); - CompressionSect.CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8); - CompressionSect.CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16); - CompressionSect.CompressionType = (UINT8) SectionSubType; - CompressionSect.UncompressedLength = InputLength; - - fwrite (&CompressionSect, sizeof (CompressionSect), 1, OutFile); - fwrite (FileBuffer, CompressedLength, 1, OutFile); - free (FileBuffer); - return EFI_SUCCESS; -} - -EFI_STATUS -GenSectionGuidDefinedSection ( - char **InputFileName, - int InputFileNum, - UINTN SectionType, - UINTN SectionSubType, - FILE *OutFile - ) -/*++ - -Routine Description: - - Generate an encapsulating section of type EFI_SECTION_GUID_DEFINED - Input file must be already sectioned. The function won't validate - the input files' contents. Caller should hand in files already - with section header. - -Arguments: - - InputFileName - Name of the input file. - - InputFileNum - Number of input files. Should be at least 1. - - SectionType - Section type to generate. Should be - EFI_SECTION_GUID_DEFINED - - SectionSubType - Specify the authentication algorithm requested. - - OutFile - Output file handle - -Returns: - - EFI_SUCCESS on successful return - EFI_INVALID_PARAMETER if InputFileNum is less than 1 - EFI_ABORTED if unable to open input file. - EFI_OUT_OF_RESOURCES No resource to complete the operation. - ---*/ -{ - INTN TotalLength; - INTN InputLength; - UINT8 *FileBuffer; - UINT32 Crc32Checksum; - EFI_STATUS Status; - CRC32_SECTION_HEADER Crc32GuidSect; - - if (SectionType != EFI_SECTION_GUID_DEFINED) { - Error (NULL, 0, 0, "parameter must be EFI_SECTION_GUID_DEFINED", NULL); - return EFI_INVALID_PARAMETER; - } - - InputLength = 0; - FileBuffer = NULL; - FileBuffer = (UINT8 *) malloc ((1024 * 1024 * 4) * sizeof (UINT8)); - if (FileBuffer == NULL) { - Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory"); - return EFI_OUT_OF_RESOURCES; - } - // - // read all input file contents into a buffer - // - Status = GetSectionContents ( - InputFileName, - InputFileNum, - FileBuffer, - &InputLength - ); - if (EFI_ERROR (Status)) { - free (FileBuffer); - return Status; - } - // - // Now data is in FileBuffer, compress the data - // - switch (SectionSubType) { - case EFI_SECTION_CRC32_GUID_DEFINED: - Crc32Checksum = 0; - CalculateCrc32 (FileBuffer, InputLength, &Crc32Checksum); - if (EFI_ERROR (Status)) { - free (FileBuffer); - return Status; - } - - TotalLength = InputLength + CRC32_SECTION_HEADER_SIZE; - Crc32GuidSect.GuidSectionHeader.CommonHeader.Type = (EFI_SECTION_TYPE) SectionType; - Crc32GuidSect.GuidSectionHeader.CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff); - Crc32GuidSect.GuidSectionHeader.CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8); - Crc32GuidSect.GuidSectionHeader.CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16); - memcpy (&(Crc32GuidSect.GuidSectionHeader.SectionDefinitionGuid), &gEfiCrc32SectionGuid, sizeof (EFI_GUID)); - Crc32GuidSect.GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID; - Crc32GuidSect.GuidSectionHeader.DataOffset = CRC32_SECTION_HEADER_SIZE; - Crc32GuidSect.CRC32Checksum = Crc32Checksum; - - break; - - default: - Error (NULL, 0, 0, "invalid parameter", "unknown GUID defined type"); - free (FileBuffer); - return EFI_ABORTED; - } - - fwrite (&Crc32GuidSect, sizeof (Crc32GuidSect), 1, OutFile); - fwrite (FileBuffer, InputLength, 1, OutFile); - - free (FileBuffer); - - return EFI_SUCCESS; -} - -int -main ( - int argc, - char *argv[] - ) -/*++ - -Routine Description: - - Main - -Arguments: - - command line parameters - -Returns: - - EFI_SUCCESS Section header successfully generated and section concatenated. - EFI_ABORTED Could not generate the section - EFI_OUT_OF_RESOURCES No resource to complete the operation. - ---*/ -{ - INTN Index; - INTN VersionNumber; - UINTN SectionType; - UINTN SectionSubType; - BOOLEAN InputFileRequired; - BOOLEAN SubTypeRequired; - FILE *InFile; - FILE *OutFile; - INTN InputFileNum; - - char **InputFileName; - char *OutputFileName; - char AuxString[500] = { 0 }; - - char *ParamSectionType; - char *ParamSectionSubType; - char *ParamLength; - char *ParamVersion; - char *ParamDigitalSignature; - - EFI_STATUS Status; - EFI_COMMON_SECTION_HEADER CommonSect; - - InputFileName = NULL; - OutputFileName = PARAMETER_NOT_SPECIFIED; - ParamSectionType = PARAMETER_NOT_SPECIFIED; - ParamSectionSubType = PARAMETER_NOT_SPECIFIED; - ParamLength = PARAMETER_NOT_SPECIFIED; - ParamVersion = PARAMETER_NOT_SPECIFIED; - ParamDigitalSignature = PARAMETER_NOT_SPECIFIED; - Status = EFI_SUCCESS; - - VersionNumber = 0; - SectionType = 0; - SectionSubType = 0; - InputFileRequired = TRUE; - SubTypeRequired = FALSE; - InFile = NULL; - OutFile = NULL; - InputFileNum = 0; - Status = EFI_SUCCESS; - - SetUtilityName (UTILITY_NAME); - if (argc == 1) { - PrintUsageMessage (); - return STATUS_ERROR; - } - // - // Parse command line - // - Index = 1; - while (Index < argc) { - if (strcmpi (argv[Index], "-i") == 0) { - // - // Input File found - // - Index++; - InputFileName = (char **) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (char *)); - if (InputFileName == NULL) { - Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory"); - return EFI_OUT_OF_RESOURCES; - } - - memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (char *))); - InputFileName[InputFileNum] = argv[Index]; - InputFileNum++; - Index++; - // - // Parse subsequent parameters until another switch is encountered - // - while ((Index < argc) && (argv[Index][0] != '-')) { - if ((InputFileNum % MAXIMUM_INPUT_FILE_NUM) == 0) { - // - // InputFileName buffer too small, need to realloc - // - InputFileName = (char **) realloc ( - InputFileName, - (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (char *) - ); - if (InputFileName == NULL) { - Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory"); - return EFI_OUT_OF_RESOURCES; - } - - memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (char *))); - } - - InputFileName[InputFileNum] = argv[Index]; - InputFileNum++; - Index++; - } - - } - - if (strcmpi (argv[Index], "-o") == 0) { - // - // Output file found - // - Index++; - OutputFileName = argv[Index]; - } else if (strcmpi (argv[Index], "-s") == 0) { - // - // Section Type found - // - Index++; - ParamSectionType = argv[Index]; - } else if (strcmpi (argv[Index], "-t") == 0) { - // - // Compression or Authentication type - // - Index++; - ParamSectionSubType = argv[Index]; - } else if (strcmpi (argv[Index], "-l") == 0) { - // - // Length - // - Index++; - ParamLength = argv[Index]; - } else if (strcmpi (argv[Index], "-v") == 0) { - // - // VersionNumber - // - Index++; - ParamVersion = argv[Index]; - } else if (strcmpi (argv[Index], "-a") == 0) { - // - // Aux string - // - Index++; - // - // Note, the MSVC C-Start parses out and consolidates quoted strings from the command - // line. Quote characters are stripped. If this tool is ported to other environments - // this will need to be taken into account - // - strncpy (AuxString, argv[Index], 499); - } else if (strcmpi (argv[Index], "-d") == 0) { - // - // Digital signature for EFI_TEST_AUTHENTICAION (must be 0 or 1) - // - Index++; - ParamDigitalSignature = argv[Index]; - } else if (strcmpi (argv[Index], "-?") == 0) { - PrintUsageMessage (); - return STATUS_ERROR; - } else { - Error (NULL, 0, 0, argv[Index], "unknown option"); - return GetUtilityStatus (); - } - - Index++; - } - // - // At this point, all command line parameters are verified as not being totally - // bogus. Next verify the command line parameters are complete and make - // sense... - // - if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_COMPRESSION]) == 0) { - SectionType = EFI_SECTION_COMPRESSION; - SubTypeRequired = TRUE; - if (stricmp (ParamSectionSubType, CompressionTypeName[EFI_NOT_COMPRESSED]) == 0) { - SectionSubType = EFI_NOT_COMPRESSED; - } else if (stricmp (ParamSectionSubType, CompressionTypeName[EFI_STANDARD_COMPRESSION]) == 0) { - SectionSubType = EFI_STANDARD_COMPRESSION; - } else { - Error (NULL, 0, 0, ParamSectionSubType, "unknown compression type"); - PrintUsageMessage (); - return GetUtilityStatus (); - } - } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_GUID_DEFINED]) == 0) { - SectionType = EFI_SECTION_GUID_DEFINED; - SubTypeRequired = TRUE; - if (stricmp (ParamSectionSubType, GUIDedSectionTypeName[EFI_SECTION_CRC32_GUID_DEFINED]) == 0) { - SectionSubType = EFI_SECTION_CRC32_GUID_DEFINED; - } else { - Error (NULL, 0, 0, ParamSectionSubType, "unknown GUID defined section type", ParamSectionSubType); - PrintUsageMessage (); - return GetUtilityStatus (); - } - } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_PE32]) == 0) { - SectionType = EFI_SECTION_PE32; - } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_PIC]) == 0) { - SectionType = EFI_SECTION_PIC; - } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_TE]) == 0) { - SectionType = EFI_SECTION_TE; - } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_DXE_DEPEX]) == 0) { - SectionType = EFI_SECTION_DXE_DEPEX; - } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_VERSION]) == 0) { - SectionType = EFI_SECTION_VERSION; - InputFileRequired = FALSE; - Index = sscanf (ParamVersion, "%d", &VersionNumber); - if (Index != 1 || VersionNumber < 0 || VersionNumber > 65565) { - Error (NULL, 0, 0, ParamVersion, "illegal version number"); - PrintUsageMessage (); - return GetUtilityStatus (); - } - - if (strcmp (AuxString, PARAMETER_NOT_SPECIFIED) == 0) { - AuxString[0] = 0; - } - } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_USER_INTERFACE]) == 0) { - SectionType = EFI_SECTION_USER_INTERFACE; - InputFileRequired = FALSE; - if (strcmp (AuxString, PARAMETER_NOT_SPECIFIED) == 0) { - Error (NULL, 0, 0, "user interface string not specified", NULL); - PrintUsageMessage (); - return GetUtilityStatus (); - } - } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_COMPATIBILITY16]) == 0) { - SectionType = EFI_SECTION_COMPATIBILITY16; - } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_FIRMWARE_VOLUME_IMAGE]) == 0) { - SectionType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE; - } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_FREEFORM_SUBTYPE_GUID]) == 0) { - SectionType = EFI_SECTION_FREEFORM_SUBTYPE_GUID; - } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_RAW]) == 0) { - SectionType = EFI_SECTION_RAW; - } else if (stricmp (ParamSectionType, SectionTypeName[EFI_SECTION_PEI_DEPEX]) == 0) { - SectionType = EFI_SECTION_PEI_DEPEX; - } else { - Error (NULL, 0, 0, ParamSectionType, "unknown section type"); - PrintUsageMessage (); - return GetUtilityStatus (); - } - // - // Open output file - // - OutFile = fopen (OutputFileName, "wb"); - if (OutFile == NULL) { - Error (NULL, 0, 0, OutputFileName, "failed to open output file for writing"); - if (InFile != NULL) { - fclose (InFile); - } - - return GetUtilityStatus (); - } - // - // At this point, we've fully validated the command line, and opened appropriate - // files, so let's go and do what we've been asked to do... - // - // - // Within this switch, build and write out the section header including any - // section type specific pieces. If there's an input file, it's tacked on later - // - switch (SectionType) { - case EFI_SECTION_COMPRESSION: - Status = GenSectionCompressionSection ( - InputFileName, - InputFileNum, - SectionType, - SectionSubType, - OutFile - ); - break; - - case EFI_SECTION_GUID_DEFINED: - Status = GenSectionGuidDefinedSection ( - InputFileName, - InputFileNum, - SectionType, - SectionSubType, - OutFile - ); - break; - - case EFI_SECTION_VERSION: - CommonSect.Type = (EFI_SECTION_TYPE) SectionType; - - Index = sizeof (CommonSect); - // - // 2 characters for the build number - // - Index += 2; - // - // Aux string is ascii.. unicode is 2X + 2 bytes for terminating unicode null. - // - Index += (strlen (AuxString) * 2) + 2; - memcpy (&CommonSect.Size, &Index, 3); - fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile); - fwrite (&VersionNumber, 2, 1, OutFile); - Ascii2UnicodeWriteString (AuxString, OutFile, FALSE); - break; - - case EFI_SECTION_USER_INTERFACE: - CommonSect.Type = (EFI_SECTION_TYPE) SectionType; - Index = sizeof (CommonSect); - // - // Aux string is ascii.. unicode is 2X + 2 bytes for terminating unicode null. - // - Index += (strlen (AuxString) * 2) + 2; - memcpy (&CommonSect.Size, &Index, 3); - fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile); - Ascii2UnicodeWriteString (AuxString, OutFile, FALSE); - break; - - default: - // - // All other section types are caught by default (they're all the same) - // - Status = GenSectionCommonLeafSection ( - InputFileName, - InputFileNum, - SectionType, - OutFile - ); - break; - } - - if (InputFileName != NULL) { - free (InputFileName); - } - - fclose (OutFile); - // - // If we had errors, then delete the output file - // - if (GetUtilityStatus () == STATUS_ERROR) { - remove (OutputFileName); - } - - return GetUtilityStatus (); -} diff --git a/Tools/CodeTools/TianoTools/GenSection/GenSection.h b/Tools/CodeTools/TianoTools/GenSection/GenSection.h deleted file mode 100644 index 36064632db..0000000000 --- a/Tools/CodeTools/TianoTools/GenSection/GenSection.h +++ /dev/null @@ -1,42 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - GenSection.h - -Abstract: - - Header file for GenSection. - ---*/ - -// -// Module Coded to Tiano Coding Conventions -// -#ifndef _EFI_GEN_SECTION_H -#define _EFI_GEN_SECTION_H - -// -// External Files Referenced -// -#include -#include - -typedef struct { - EFI_GUID_DEFINED_SECTION GuidSectionHeader; - UINT32 CRC32Checksum; -} CRC32_SECTION_HEADER; - -#define EFI_SECTION_CRC32_GUID_DEFINED 0 -#define CRC32_SECTION_HEADER_SIZE (sizeof (CRC32_SECTION_HEADER)) - -#endif diff --git a/Tools/CodeTools/TianoTools/GenSection/build.xml b/Tools/CodeTools/TianoTools/GenSection/build.xml deleted file mode 100644 index 63ffccdf74..0000000000 --- a/Tools/CodeTools/TianoTools/GenSection/build.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/GenTEImage/GenTEImage.c b/Tools/CodeTools/TianoTools/GenTEImage/GenTEImage.c deleted file mode 100644 index 90f3b3919a..0000000000 --- a/Tools/CodeTools/TianoTools/GenTEImage/GenTEImage.c +++ /dev/null @@ -1,916 +0,0 @@ -/*++ - -Copyright (c) 1999-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - GenTEImage.c - -Abstract: - - Utility program to shrink a PE32 image down by replacing - the DOS, PE, and optional headers with a minimal header. - ---*/ - -#include -#include -#include - -#include -#include // for PE32 structure definitions - -#include "CommonLib.h" -#include "EfiUtilityMsgs.h" - -// -// Version of this utility -// -#define UTILITY_NAME "GenTEImage" -#define UTILITY_VERSION "v0.11" - -// -// Define the max length of a filename -// -#define MAX_PATH 256 -#define DEFAULT_OUTPUT_EXTENSION ".te" - -// -// Use this to track our command-line options and globals -// -struct { - INT8 OutFileName[MAX_PATH]; - INT8 InFileName[MAX_PATH]; - INT8 Verbose; - INT8 Dump; -} mOptions; - -// -// Use these to convert from machine type value to a named type -// -typedef struct { - UINT16 Value; - INT8 *Name; -} STRING_LOOKUP; - -static STRING_LOOKUP mMachineTypes[] = { - EFI_IMAGE_MACHINE_IA32, - "IA32", - EFI_IMAGE_MACHINE_IA64, - "IA64", - EFI_IMAGE_MACHINE_EBC, - "EBC", - 0, - NULL -}; - -static STRING_LOOKUP mSubsystemTypes[] = { - EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION, - "EFI application", - EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, - "EFI boot service driver", - EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER, - "EFI runtime driver", - 0, - NULL -}; -// -// Function prototypes -// -static -void -Usage ( - VOID - ); - -static -STATUS -ParseCommandLine ( - int Argc, - char *Argv[] - ); - -static -STATUS -CheckPE32File ( - INT8 *FileName, - FILE *Fptr, - UINT16 *MachineType, - UINT16 *SubSystem - ); - -static -STATUS -ProcessFile ( - INT8 *InFileName, - INT8 *OutFileName - ); - -static -void -DumpImage ( - INT8 *FileName - ); - -static -INT8 * -GetMachineTypeStr ( - UINT16 MachineType - ); - -static -INT8 * -GetSubsystemTypeStr ( - UINT16 SubsystemType - ); - -main ( - int Argc, - char *Argv[] - ) -/*++ - -Routine Description: - - -Arguments: - - Argc - standard C main() argument count - - Argv - standard C main() argument list - -Returns: - - 0 success - non-zero otherwise - ---*/ -// GC_TODO: ] - add argument and description to function comment -{ - INT8 *Ext; - UINT32 Status; - - SetUtilityName (UTILITY_NAME); - // - // Parse the command line arguments - // - if (ParseCommandLine (Argc, Argv)) { - return STATUS_ERROR; - } - // - // If dumping an image, then do that and quit - // - if (mOptions.Dump) { - DumpImage (mOptions.InFileName); - goto Finish; - } - // - // Determine the output filename. Either what they specified on - // the command line, or the first input filename with a different extension. - // - if (!mOptions.OutFileName[0]) { - strcpy (mOptions.OutFileName, mOptions.InFileName); - // - // Find the last . on the line and replace the filename extension with - // the default - // - for (Ext = mOptions.OutFileName + strlen (mOptions.OutFileName) - 1; - (Ext >= mOptions.OutFileName) && (*Ext != '.') && (*Ext != '\\'); - Ext-- - ) - ; - // - // If dot here, then insert extension here, otherwise append - // - if (*Ext != '.') { - Ext = mOptions.OutFileName + strlen (mOptions.OutFileName); - } - - strcpy (Ext, DEFAULT_OUTPUT_EXTENSION); - } - // - // Make sure we don't have the same filename for input and output files - // - if (stricmp (mOptions.OutFileName, mOptions.InFileName) == 0) { - Error (NULL, 0, 0, mOptions.OutFileName, "input and output file names must be different"); - goto Finish; - } - // - // Process the file - // - ProcessFile (mOptions.InFileName, mOptions.OutFileName); -Finish: - Status = GetUtilityStatus (); - return Status; -} - -static -STATUS -ProcessFile ( - INT8 *InFileName, - INT8 *OutFileName - ) -/*++ - -Routine Description: - - Process a PE32 EFI file. - -Arguments: - - InFileName - the file name pointer to the input file - OutFileName - the file name pointer to the output file - -Returns: - - STATUS_SUCCESS - the process has been finished successfully - STATUS_ERROR - error occured during the processing - ---*/ -{ - STATUS Status; - FILE *InFptr; - FILE *OutFptr; - UINT16 MachineType; - UINT16 SubSystem; - EFI_TE_IMAGE_HEADER TEImageHeader; - UINT32 PESigOffset; - EFI_IMAGE_FILE_HEADER FileHeader; - EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader32; - EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader64; - UINT32 BytesStripped; - UINT32 FileSize; - UINT8 *Buffer; - long SaveFilePosition; - - InFptr = NULL; - OutFptr = NULL; - Buffer = NULL; - Status = STATUS_ERROR; - - // - // Try to open the input file - // - if ((InFptr = fopen (InFileName, "rb")) == NULL) { - Error (NULL, 0, 0, InFileName, "failed to open input file for reading"); - return STATUS_ERROR; - } - // - // Double-check the file to make sure it's what we expect it to be - // - if (CheckPE32File (InFileName, InFptr, &MachineType, &SubSystem) != STATUS_SUCCESS) { - goto Finish; - } - // - // Initialize our new header - // - memset (&TEImageHeader, 0, sizeof (EFI_TE_IMAGE_HEADER)); - - // - // Seek to the end to get the file size - // - fseek (InFptr, 0, SEEK_END); - FileSize = ftell (InFptr); - fseek (InFptr, 0, SEEK_SET); - - // - // Per the PE/COFF specification, at offset 0x3C in the file is a 32-bit - // offset (from the start of the file) to the PE signature, which always - // follows the MSDOS stub. The PE signature is immediately followed by the - // COFF file header. - // - // - if (fseek (InFptr, 0x3C, SEEK_SET) != 0) { - Error (NULL, 0, 0, InFileName, "failed to seek to PE signature in file", NULL); - goto Finish; - } - - if (fread (&PESigOffset, sizeof (PESigOffset), 1, InFptr) != 1) { - Error (NULL, 0, 0, InFileName, "failed to read PE signature offset from file"); - goto Finish; - } - - if (fseek (InFptr, PESigOffset + 4, SEEK_SET) != 0) { - Error (NULL, 0, 0, InFileName, "failed to seek to PE signature"); - goto Finish; - } - // - // We should now be at the COFF file header. Read it in and verify it's - // of an image type we support. - // - if (fread (&FileHeader, sizeof (EFI_IMAGE_FILE_HEADER), 1, InFptr) != 1) { - Error (NULL, 0, 0, InFileName, "failed to read file header from image"); - goto Finish; - } - - if ((FileHeader.Machine != EFI_IMAGE_MACHINE_IA32) && (FileHeader.Machine != EFI_IMAGE_MACHINE_IA64)) { - Error (NULL, 0, 0, InFileName, "image is of an unsupported machine type 0x%X", (UINT32) FileHeader.Machine); - goto Finish; - } - // - // Calculate the total number of bytes we're going to strip off. The '4' is for the - // PE signature PE\0\0. Then sanity check the size. - // - BytesStripped = PESigOffset + 4 + sizeof (EFI_IMAGE_FILE_HEADER) + FileHeader.SizeOfOptionalHeader; - if (BytesStripped >= FileSize) { - Error (NULL, 0, 0, InFileName, "attempt to strip more bytes than the total file size"); - goto Finish; - } - - if (BytesStripped &~0xFFFF) { - Error (NULL, 0, 0, InFileName, "attempt to strip more than 64K bytes", NULL); - goto Finish; - } - - TEImageHeader.StrippedSize = (UINT16) BytesStripped; - - // - // Read in the optional header. Assume PE32, and if not, then re-read as PE32+ - // - SaveFilePosition = ftell (InFptr); - if (fread (&OptionalHeader32, sizeof (EFI_IMAGE_OPTIONAL_HEADER32), 1, InFptr) != 1) { - Error (NULL, 0, 0, InFileName, "failed to read optional header from input file"); - goto Finish; - } - - if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Fill in our new header with required data directory entries - // - TEImageHeader.AddressOfEntryPoint = OptionalHeader32.AddressOfEntryPoint; - // - // - BytesStripped + sizeof (EFI_TE_IMAGE_HEADER); - // - // We're going to pack the subsystem into 1 byte. Make sure it fits - // - if (OptionalHeader32.Subsystem &~0xFF) { - Error ( - NULL, - 0, - 0, - InFileName, - NULL, - "image subsystem 0x%X cannot be packed into 1 byte", - (UINT32) OptionalHeader32.Subsystem - ); - goto Finish; - } - - TEImageHeader.Subsystem = (UINT8) OptionalHeader32.Subsystem; - TEImageHeader.BaseOfCode = OptionalHeader32.BaseOfCode; - TEImageHeader.ImageBase = (UINT64) (OptionalHeader32.ImageBase + TEImageHeader.StrippedSize - sizeof (EFI_TE_IMAGE_HEADER)); - if (OptionalHeader32.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; - } - - if (OptionalHeader32.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = OptionalHeader32.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size; - } - } else if (OptionalHeader32.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - // - // Rewind and re-read the optional header - // - fseek (InFptr, SaveFilePosition, SEEK_SET); - if (fread (&OptionalHeader64, sizeof (EFI_IMAGE_OPTIONAL_HEADER64), 1, InFptr) != 1) { - Error (NULL, 0, 0, InFileName, "failed to re-read optional header from input file"); - goto Finish; - } - - TEImageHeader.AddressOfEntryPoint = OptionalHeader64.AddressOfEntryPoint; - // - // - BytesStripped + sizeof (EFI_TE_IMAGE_HEADER); - // - // We're going to pack the subsystem into 1 byte. Make sure it fits - // - if (OptionalHeader64.Subsystem &~0xFF) { - Error ( - NULL, - 0, - 0, - InFileName, - NULL, - "image subsystem 0x%X cannot be packed into 1 byte", - (UINT32) OptionalHeader64.Subsystem - ); - goto Finish; - } - - TEImageHeader.Subsystem = (UINT8) OptionalHeader64.Subsystem; - TEImageHeader.BaseOfCode = OptionalHeader32.BaseOfCode; - TEImageHeader.ImageBase = (UINT64) (OptionalHeader64.ImageBase + TEImageHeader.StrippedSize - sizeof (EFI_TE_IMAGE_HEADER)); - if (OptionalHeader64.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; - } - - if (OptionalHeader64.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = OptionalHeader64.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size; - } - } else { - Error ( - NULL, - 0, - 0, - InFileName, - "unsupported magic number 0x%X found in optional header", - (UINT32) OptionalHeader32.Magic - ); - goto Finish; - } - // - // Fill in the remainder of our new image header - // - TEImageHeader.Signature = EFI_TE_IMAGE_HEADER_SIGNATURE; - TEImageHeader.Machine = FileHeader.Machine; - // - // We're going to pack the number of sections into a single byte. Make sure it fits. - // - if (FileHeader.NumberOfSections &~0xFF) { - Error ( - NULL, - 0, - 0, - InFileName, - NULL, - "image's number of sections 0x%X cannot be packed into 1 byte", - (UINT32) FileHeader.NumberOfSections - ); - goto Finish; - } - - TEImageHeader.NumberOfSections = (UINT8) FileHeader.NumberOfSections; - - // - // Now open our output file - // - if ((OutFptr = fopen (OutFileName, "wb")) == NULL) { - Error (NULL, 0, 0, OutFileName, "failed to open output file for writing"); - goto Finish; - } - // - // Write the TE header - // - if (fwrite (&TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER), 1, OutFptr) != 1) { - Error (NULL, 0, 0, "failed to write image header to output file", NULL); - goto Finish; - } - // - // Position into the input file, read the part we're not stripping, and - // write it out. - // - fseek (InFptr, BytesStripped, SEEK_SET); - Buffer = (UINT8 *) malloc (FileSize - BytesStripped); - if (Buffer == NULL) { - Error (NULL, 0, 0, "application error", "failed to allocate memory"); - goto Finish; - } - - if (fread (Buffer, FileSize - BytesStripped, 1, InFptr) != 1) { - Error (NULL, 0, 0, InFileName, "failed to read remaining contents of input file"); - goto Finish; - } - - if (fwrite (Buffer, FileSize - BytesStripped, 1, OutFptr) != 1) { - Error (NULL, 0, 0, OutFileName, "failed to write all bytes to output file"); - goto Finish; - } - - Status = STATUS_SUCCESS; - -Finish: - if (InFptr != NULL) { - fclose (InFptr); - } - // - // Close the output file. If there was an error, delete the output file so - // that a subsequent build will rebuild it. - // - if (OutFptr != NULL) { - fclose (OutFptr); - if (GetUtilityStatus () == STATUS_ERROR) { - remove (OutFileName); - } - } - - // - // Free up our buffer - // - if (Buffer != NULL) { - free (Buffer); - } - - return Status; -} - -static -STATUS -CheckPE32File ( - INT8 *FileName, - FILE *Fptr, - UINT16 *MachineType, - UINT16 *SubSystem - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - FileName - GC_TODO: add argument description - Fptr - GC_TODO: add argument description - MachineType - GC_TODO: add argument description - SubSystem - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - /*++ - -Routine Description: - - Given a file pointer to a supposed PE32 image file, verify that it is indeed a - PE32 image file, and then return the machine type in the supplied pointer. - -Arguments: - - Fptr File pointer to the already-opened PE32 file - MachineType Location to stuff the machine type of the PE32 file. This is needed - because the image may be Itanium-based, IA32, or EBC. - -Returns: - - 0 success - non-zero otherwise - ---*/ - EFI_IMAGE_DOS_HEADER DosHeader; - EFI_IMAGE_FILE_HEADER FileHdr; - EFI_IMAGE_OPTIONAL_HEADER OptionalHdr; - UINT32 PESig; - STATUS Status; - - Status = STATUS_ERROR; - // - // Position to the start of the file - // - fseek (Fptr, 0, SEEK_SET); - // - // Read the DOS header - // - if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) { - Error (NULL, 0, 0, FileName, "failed to read the DOS stub from the input file"); - goto Finish; - } - // - // Check the magic number (0x5A4D) - // - if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) { - Error (NULL, 0, 0, FileName, "input file does not appear to be a PE32 image (magic number)"); - goto Finish; - } - // - // Position into the file and check the PE signature - // - fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET); - if (fread (&PESig, sizeof (PESig), 1, Fptr) != 1) { - Error (NULL, 0, 0, FileName, "failed to read PE signature bytes"); - goto Finish; - } - // - // Check the PE signature in the header "PE\0\0" - // - if (PESig != EFI_IMAGE_NT_SIGNATURE) { - Error (NULL, 0, 0, FileName, "file does not appear to be a PE32 image (signature)"); - goto Finish; - } - // - // Read the file header - // - if (fread (&FileHdr, sizeof (FileHdr), 1, Fptr) != 1) { - Error (NULL, 0, 0, FileName, "failed to read PE file header from input file"); - goto Finish; - } - // - // Read the optional header so we can get the subsystem - // - if (fread (&OptionalHdr, sizeof (OptionalHdr), 1, Fptr) != 1) { - Error (NULL, 0, 0, FileName, "failed to read COFF optional header from input file"); - goto Finish; - } - - *SubSystem = OptionalHdr.Subsystem; - if (mOptions.Verbose) { - fprintf (stdout, " Got subsystem = 0x%X from image\n", (int) *SubSystem); - } - // - // Good to go - // - Status = STATUS_SUCCESS; -Finish: - fseek (Fptr, 0, SEEK_SET); - return Status; -} - -static -int -ParseCommandLine ( - int Argc, - char *Argv[] - ) -/*++ - -Routine Description: - - Given the Argc/Argv program arguments, and a pointer to an options structure, - parse the command-line options and check their validity. - - -Arguments: - - Argc - standard C main() argument count - Argv - standard C main() argument list - -Returns: - - STATUS_SUCCESS success - non-zero otherwise - ---*/ -// GC_TODO: ] - add argument and description to function comment -{ - // - // Clear out the options - // - memset ((char *) &mOptions, 0, sizeof (mOptions)); - // - // Skip over the program name - // - Argc--; - Argv++; - // - // If no arguments, assume they want usage info - // - if (Argc == 0) { - Usage (); - return STATUS_ERROR; - } - // - // Process until no more arguments - // - while ((Argc > 0) && (Argv[0][0] == '-')) { - if (stricmp (Argv[0], "-o") == 0) { - // - // Output filename specified with -o - // Make sure there's another parameter - // - if (Argc > 1) { - strcpy (mOptions.OutFileName, Argv[1]); - } else { - Error (NULL, 0, 0, Argv[0], "missing output file name with option"); - Usage (); - return STATUS_ERROR; - } - - Argv++; - Argc--; - } else if ((stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) { - // - // Help option - // - Usage (); - return STATUS_ERROR; - } else if (stricmp (Argv[0], "-v") == 0) { - // - // -v for verbose - // - mOptions.Verbose = 1; - } else if (stricmp (Argv[0], "-dump") == 0) { - // - // -dump for dumping an image - // - mOptions.Dump = 1; - } else { - Error (NULL, 0, 0, Argv[0], "unrecognized option"); - Usage (); - return STATUS_ERROR; - } - // - // Next argument - // - Argv++; - Argc--; - } - // - // Better be one more arg for input file name - // - if (Argc == 0) { - Error (NULL, 0, 0, "input file name required", NULL); - Usage (); - return STATUS_ERROR; - } - - if (Argc != 1) { - Error (NULL, 0, 0, Argv[1], "extra arguments on command line"); - return STATUS_ERROR; - } - - strcpy (mOptions.InFileName, Argv[0]); - return STATUS_SUCCESS; -} - -static -void -Usage ( - VOID - ) -/*++ - -Routine Description: - - Print usage information for this utility. - -Arguments: - - None. - -Returns: - - Nothing. - ---*/ -{ - int Index; - static const char *Msg[] = { - UTILITY_NAME " version "UTILITY_VERSION " - TE image utility", - " Generate a TE image from an EFI PE32 image", - " Usage: "UTILITY_NAME " {-v} {-dump} {-h|-?} {-o OutFileName} InFileName", - " [-e|-b] [FileName(s)]", - " where:", - " -v - for verbose output", - " -dump - to dump the input file to a text file", - " -h -? - for this help information", - " -o OutFileName - to write output to OutFileName rather than InFileName"DEFAULT_OUTPUT_EXTENSION, - " InFileName - name of the input PE32 file", - "", - NULL - }; - for (Index = 0; Msg[Index] != NULL; Index++) { - fprintf (stdout, "%s\n", Msg[Index]); - } -} - -static -VOID -DumpImage ( - INT8 *FileName - ) -/*++ - -Routine Description: - - Dump a specified image information - -Arguments: - - FileName - File name pointer to the image to dump - -Returns: - - Nothing. - ---*/ -{ - FILE *InFptr; - EFI_TE_IMAGE_HEADER TEImageHeader; - INT8 *NamePtr; - - // - // Open the input file - // - InFptr = NULL; - - if ((InFptr = fopen (FileName, "rb")) == NULL) { - Error (NULL, 0, 0, FileName, "failed to open input file for reading"); - return ; - } - - if (fread (&TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER), 1, InFptr) != 1) { - Error (NULL, 0, 0, FileName, "failed to read image header from input file"); - goto Finish; - } - - if (TEImageHeader.Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) { - Error (NULL, 0, 0, FileName, "Image does not appear to be a TE image (bad signature)"); - goto Finish; - } - // - // Dump the header - // - fprintf (stdout, "Header (%d bytes):\n", sizeof (EFI_TE_IMAGE_HEADER)); - fprintf (stdout, " Signature: 0x%04X (TE)\n", (UINT32) TEImageHeader.Signature); - NamePtr = GetMachineTypeStr (TEImageHeader.Machine); - fprintf (stdout, " Machine: 0x%04X (%s)\n", (UINT32) TEImageHeader.Machine, NamePtr); - NamePtr = GetSubsystemTypeStr (TEImageHeader.Subsystem); - fprintf (stdout, " Subsystem: 0x%02X (%s)\n", (UINT32) TEImageHeader.Subsystem, NamePtr); - fprintf (stdout, " Number of sections 0x%02X\n", (UINT32) TEImageHeader.NumberOfSections); - fprintf (stdout, " Stripped size: 0x%04X\n", (UINT32) TEImageHeader.StrippedSize); - fprintf (stdout, " Entry point: 0x%08X\n", TEImageHeader.AddressOfEntryPoint); - fprintf (stdout, " Base of code: 0x%08X\n", TEImageHeader.BaseOfCode); - fprintf (stdout, " Data directories:\n"); - fprintf ( - stdout, - " %8X [%8X] RVA [size] of Base Relocation Directory\n", - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress, - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size - ); - fprintf ( - stdout, - " %8X [%8X] RVA [size] of Debug Directory\n", - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress, - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size - ); - -Finish: - if (InFptr != NULL) { - fclose (InFptr); - } -} - -static -INT8 * -GetMachineTypeStr ( - UINT16 MachineType - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - MachineType - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - int Index; - - for (Index = 0; mMachineTypes[Index].Name != NULL; Index++) { - if (mMachineTypes[Index].Value == MachineType) { - return mMachineTypes[Index].Name; - } - } - - return "unknown"; -} - -static -INT8 * -GetSubsystemTypeStr ( - UINT16 SubsystemType - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - SubsystemType - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - int Index; - - for (Index = 0; mSubsystemTypes[Index].Name != NULL; Index++) { - if (mSubsystemTypes[Index].Value == SubsystemType) { - return mSubsystemTypes[Index].Name; - } - } - - return "unknown"; -} diff --git a/Tools/CodeTools/TianoTools/GenTEImage/build.xml b/Tools/CodeTools/TianoTools/GenTEImage/build.xml deleted file mode 100644 index e79f9574a9..0000000000 --- a/Tools/CodeTools/TianoTools/GenTEImage/build.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/GuidChk/CommonUtils.h b/Tools/CodeTools/TianoTools/GuidChk/CommonUtils.h deleted file mode 100644 index f7a331e5d7..0000000000 --- a/Tools/CodeTools/TianoTools/GuidChk/CommonUtils.h +++ /dev/null @@ -1,57 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - CommonUtils.h - -Abstract: - - Common utility defines and structure definitions. - ---*/ - -#ifndef _COMMON_UTILS_H_ -#define _COMMON_UTILS_H_ - -// -// Basic types -// -typedef unsigned char UINT8; -typedef char INT8; -typedef unsigned short UINT16; -typedef unsigned int UINT32; - -typedef UINT8 BOOLEAN; -typedef UINT32 STATUS; - -#define TRUE 1 -#define FALSE 0 - -#define STATUS_SUCCESS 0 -#define STATUS_WARNING 1 -#define STATUS_ERROR 2 - -// -// Linked list of strings -// -typedef struct _STRING_LIST { - struct _STRING_LIST *Next; - char *Str; -} STRING_LIST; - -int -CreateGuidList ( - INT8 *OutFileName - ) -; - -#endif // #ifndef _COMMON_UTILS_H_ diff --git a/Tools/CodeTools/TianoTools/GuidChk/FileSearch.c b/Tools/CodeTools/TianoTools/GuidChk/FileSearch.c deleted file mode 100644 index 8b5b58fddf..0000000000 --- a/Tools/CodeTools/TianoTools/GuidChk/FileSearch.c +++ /dev/null @@ -1,285 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - FileSearch.c - -Abstract: - - Module used to support file searches on the system. - ---*/ - -#include - -#include "CommonUtils.h" -#include "FileSearch.h" -#include "UtilsMsgs.h" - -// -// Internal file search flag for sanity checks -// -#define FILE_SEARCH_STARTED 0x8000 -#define FILE_SEARCH_INITED 0x4000 - -static -BOOLEAN -FileSearchMeetsCriteria ( - FILE_SEARCH_DATA *FSData - ); - -/*****************************************************************************/ -STATUS -FileSearchInit ( - FILE_SEARCH_DATA *FSData - ) -{ - memset ((char *) FSData, 0, sizeof (FILE_SEARCH_DATA)); - FSData->Handle = INVALID_HANDLE_VALUE; - FSData->FileSearchFlags = FILE_SEARCH_INITED; - FSData->FileName[0] = 0; - return STATUS_SUCCESS; -} - -STATUS -FileSearchStart ( - FILE_SEARCH_DATA *FSData, - char *FileMask, - UINT32 SearchFlags - ) -{ - BOOLEAN Done; - - // - // Save their flags, and set a flag to indicate that they called this - // start function so we can perform extended checking in the other - // routines we have in this module. - // - FSData->FileSearchFlags |= (SearchFlags | FILE_SEARCH_STARTED); - FSData->FileName[0] = 0; - - // - // Begin the search - // - FSData->Handle = FindFirstFile (FileMask, &(FSData->FindData)); - if (FSData->Handle == INVALID_HANDLE_VALUE) { - return STATUS_ERROR; - } - // - // Keep looping through until we find a file meeting the caller's - // criteria per the search flags - // - Done = FALSE; - while (!Done) { - // - // If we're done (we found a match) copy the file name found and return - // - Done = FileSearchMeetsCriteria (FSData); - if (Done) { - return STATUS_SUCCESS; - } - // - // Go on to next file - // - if (!FindNextFile (FSData->Handle, &(FSData->FindData))) { - return STATUS_NOT_FOUND; - } - } - // - // Not reached - // - return STATUS_NOT_FOUND; -} - -// -// Find the next file meeting their criteria and return it. -// -STATUS -FileSearchFindNext ( - FILE_SEARCH_DATA *FSData - ) -{ - BOOLEAN Done; - - Done = FALSE; - while (!Done) { - if (!FindNextFile (FSData->Handle, &(FSData->FindData))) { - return STATUS_NOT_FOUND; - } - // - // See if it matches their criteria - // - Done = FileSearchMeetsCriteria (FSData); - if (Done) { - return STATUS_SUCCESS; - } - } - // - // Not reached - // - return STATUS_NOT_FOUND; -} -// -// Perform any cleanup necessary to close down a search -// -STATUS -FileSearchDestroy ( - FILE_SEARCH_DATA *FSData - ) -{ - if (FSData->Handle != INVALID_HANDLE_VALUE) { - FindClose (FSData->Handle); - FSData->Handle = INVALID_HANDLE_VALUE; - } - - FSData->FileName[0] = 0; - FSData->FileSearchFlags = 0; - return STATUS_SUCCESS; -} - -static -BOOLEAN -FileSearchMeetsCriteria ( - FILE_SEARCH_DATA *FSData - ) -{ - BOOLEAN Status; - STRING_LIST *StrList; - UINT32 ExtLen; - UINT32 FileNameLen; - - Status = FALSE; - - // - // First clear the flag indicating this is neither a file or a - // directory. - // - FSData->FileFlags &= ~(FILE_SEARCH_DIR | FILE_SEARCH_FILE); - - // - // We found a file. See if it matches the user's search criteria. First - // check for this being a directory, and they want directories, and - // it's not "." and it's not ".." - // - if ((FSData->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && - (FSData->FileSearchFlags & FILE_SEARCH_DIR) && - (strcmp (FSData->FindData.cFileName, ".")) && - (strcmp (FSData->FindData.cFileName, "..")) - ) { - // - // Assume we'll make it past this check - // - Status = TRUE; - // - // If they have a list of exclude directories, then check for those - // - StrList = FSData->ExcludeDirs; - while (StrList != NULL) { - if (stricmp (FSData->FindData.cFileName, StrList->Str) == 0) { - Status = FALSE; - break; - } - - StrList = StrList->Next; - } - // - // If we didn't fail due to excluded directories, then set the dir flag - // - if (Status) { - FSData->FileFlags |= FILE_SEARCH_DIR; - } - // - // Else check for a file, and they want files.... - // - } else if (((FSData->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) && - (FSData->FileSearchFlags & FILE_SEARCH_FILE) - ) { - // - // See if it's in our list of excluded files - // - Status = TRUE; - StrList = FSData->ExcludeFiles; - while (StrList != NULL) { - if (stricmp (FSData->FindData.cFileName, StrList->Str) == 0) { - Status = FALSE; - break; - } - - StrList = StrList->Next; - } - - if (Status) { - // - // See if it's in our list of excluded file extensions - // - FileNameLen = strlen (FSData->FindData.cFileName); - StrList = FSData->ExcludeExtensions; - while (StrList != NULL) { - ExtLen = strlen (StrList->Str); - if (stricmp ( - FSData->FindData.cFileName + FileNameLen - ExtLen, - StrList->Str - ) == 0) { - Status = FALSE; - break; - } - - StrList = StrList->Next; - } - } - - if (Status) { - FSData->FileFlags |= FILE_SEARCH_FILE; - } - } - // - // If it's a match, copy the filename into another field of the structure - // for portability. - // - if (Status) { - strcpy (FSData->FileName, FSData->FindData.cFileName); - } - - return Status; -} -// -// Exclude a list of subdirectories. -// -STATUS -FileSearchExcludeDirs ( - FILE_SEARCH_DATA *FSData, - STRING_LIST *StrList - ) -{ - FSData->ExcludeDirs = StrList; - return STATUS_SUCCESS; -} - -STATUS -FileSearchExcludeFiles ( - FILE_SEARCH_DATA *FSData, - STRING_LIST *StrList - ) -{ - FSData->ExcludeFiles = StrList; - return STATUS_SUCCESS; -} - -STATUS -FileSearchExcludeExtensions ( - FILE_SEARCH_DATA *FSData, - STRING_LIST *StrList - ) -{ - FSData->ExcludeExtensions = StrList; - return STATUS_SUCCESS; -} diff --git a/Tools/CodeTools/TianoTools/GuidChk/FileSearch.h b/Tools/CodeTools/TianoTools/GuidChk/FileSearch.h deleted file mode 100644 index bc40265366..0000000000 --- a/Tools/CodeTools/TianoTools/GuidChk/FileSearch.h +++ /dev/null @@ -1,108 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - FileSearch.h - -Abstract: - - Header file to support file searching. - ---*/ - -#ifndef _FILE_SEARCH_H_ -#define _FILE_SEARCH_H_ - -// -// Since the file searching routines are OS dependent, put the -// necessary include paths in this header file so that the non-OS-dependent -// files don't need to include these windows-specific header files. -// -#include -#include -#include -#include -#include - -// -// Return codes of some of the file search routines -// -#define STATUS_NOT_FOUND 0x1000 - -// -// Flags for what to search for. Also used in the FileFlags return field. -// -#define FILE_SEARCH_DIR 0x0001 -#define FILE_SEARCH_FILE 0x0002 - -// -// Here's our class definition -// -typedef struct { - HANDLE Handle; - WIN32_FIND_DATA FindData; - UINT32 FileSearchFlags; // DIRS, FILES, etc - UINT32 FileFlags; - INT8 FileName[MAX_PATH]; // for portability - STRING_LIST *ExcludeDirs; - STRING_LIST *ExcludeFiles; - STRING_LIST *ExcludeExtensions; -} FILE_SEARCH_DATA; - -// -// Here's our member functions -// -STATUS -FileSearchInit ( - FILE_SEARCH_DATA *FSData - ) -; - -STATUS -FileSearchDestroy ( - FILE_SEARCH_DATA *FSData - ) -; - -STATUS -FileSearchStart ( - FILE_SEARCH_DATA *FSData, - char *FileMask, - UINT32 SearchFlags - ) -; - -STATUS -FileSearchFindNext ( - FILE_SEARCH_DATA *FSData - ) -; - -STATUS -FileSearchExcludeDirs ( - FILE_SEARCH_DATA *FSData, - STRING_LIST *StrList - ) -; -STATUS -FileSearchExcludeExtensions ( - FILE_SEARCH_DATA *FSData, - STRING_LIST *StrList - ) -; -STATUS -FileSearchExcludeFiles ( - FILE_SEARCH_DATA *FSData, - STRING_LIST *StrList - ) -; -#endif diff --git a/Tools/CodeTools/TianoTools/GuidChk/GuidChk.c b/Tools/CodeTools/TianoTools/GuidChk/GuidChk.c deleted file mode 100644 index de88405872..0000000000 --- a/Tools/CodeTools/TianoTools/GuidChk/GuidChk.c +++ /dev/null @@ -1,2348 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - GuidChk.c - -Abstract: - - Parse files in a directory and subdirectories to find all guid definitions. - Then check them against each other to make sure there are no duplicates. - ---*/ - -#include -#include -#include -#include - -#include "CommonUtils.h" -#include "FileSearch.h" -#include "UtilsMsgs.h" - -#define MAX_LINE_LEN 180 // we concatenate two lines sometimes -// Define a structure that correlates filename extensions to an enumerated -// type. -// -typedef struct { - INT8 *Extension; - INT8 ExtensionCode; -} FILE_TYPE_TABLE_ENTRY; - -#define FILE_EXTENSION_UNKNOWN 0 -#define FILE_EXTENSION_C 1 -#define FILE_EXTENSION_H 2 -#define FILE_EXTENSION_IA32_ASM 3 -#define FILE_EXTENSION_IA32_INC 4 -#define FILE_EXTENSION_IA64_ASM 5 -#define FILE_EXTENSION_IA64_INC 6 -#define FILE_EXTENSION_PKG 7 -#define FILE_EXTENSION_INF 8 - -FILE_TYPE_TABLE_ENTRY FileTypeTable[] = { - ".c", - FILE_EXTENSION_C, - ".h", - FILE_EXTENSION_H, - ".inc", - FILE_EXTENSION_IA32_INC, - ".asm", - FILE_EXTENSION_IA32_ASM, - ".s", - FILE_EXTENSION_IA64_ASM, - ".pkg", - FILE_EXTENSION_PKG, - ".inf", - FILE_EXTENSION_INF, - ".i", - FILE_EXTENSION_IA64_INC, - NULL, - 0 -}; - -typedef struct EFI_GUID { - UINT32 Data1; - UINT16 Data2; - UINT16 Data3; - UINT8 Data4[8]; -} EFI_GUID; - -typedef struct { - INT8 Data[4]; - INT8 DataLen; -} EFI_SIGNATURE; - -typedef struct _GUID_RECORD { - struct _GUID_RECORD *Next; - BOOLEAN Reported; - INT8 *FileName; - INT8 *SymName; - EFI_GUID Guid; -} GUID_RECORD; - -typedef struct _SIGNATURE_RECORD { - struct _SIGNATURE_RECORD *Next; - BOOLEAN Reported; - INT8 *FileName; - EFI_SIGNATURE Signature; -} SIGNATURE_RECORD; - -// -// Utility options -// -typedef struct { - INT8 DatabaseOutputFileName[MAX_PATH]; // with -b option - STRING_LIST *ExcludeDirs; // list of directory names not to process - STRING_LIST *ExcludeSubDirs; // list of directory names to not process subdirectories (build) - STRING_LIST *ExcludeFiles; // list of files to exclude (make.inf) - STRING_LIST *ExcludeExtensions; // list of filename extensions to exclude (.inf, .pkg) - BOOLEAN Verbose; - BOOLEAN PrintFound; - BOOLEAN CheckGuids; - BOOLEAN CheckSignatures; - BOOLEAN GuidXReference; -} OPTIONS; - -static -STATUS -ProcessArgs ( - int Argc, - char *Argv[] - ); - -static -VOID -Usage ( - VOID - ); - -static -STATUS -ProcessDirectory ( - INT8 *Path, - INT8 *DirectoryName - ); - -static -STATUS -ProcessFile ( - INT8 *DirectoryName, - INT8 *FileName - ); - -static -UINT32 -GetFileExtension ( - INT8 *FileName - ); - -static -UINT32 -SkipWhiteSpace ( - INT8 *Str - ); - -static -UINT32 -ValidSymbolName ( - INT8 *Name - ); - -static -STATUS -ProcessCFileGuids ( - INT8 *FileName - ); - -static -STATUS -AddSignature ( - INT8 *FileName, - INT8 *StrDef, - UINT32 SigSize - ); - -static -STATUS -ProcessCFileSigs ( - INT8 *FileName - ); - -static -STATUS -ProcessINFFileGuids ( - INT8 *FileName - ); - -static -STATUS -ProcessPkgFileGuids ( - INT8 *FileName - ); - -static -STATUS -ProcessIA32FileGuids ( - INT8 *FileName - ); - -static -STATUS -ProcessIA64FileGuids ( - INT8 *FileName - ); - -static -BOOLEAN -IsIA64GuidLine ( - INT8 *Line, - UINT32 *GuidHigh, - UINT32 *GuidLow, - BOOLEAN *Low, - INT8 *SymName - ); - -static -STATUS -AddGuid11 ( - INT8 *FileName, - UINT32 *Data, - INT8 *SymName - ); - -static -STATUS -AddPkgGuid ( - INT8 *FileName, - UINT32 *Data, - UINT64 *Data64 - ); - -static -STATUS -AddGuid16 ( - INT8 *FileName, - UINT32 *Data - ); - -static -STATUS -AddGuid64x2 ( - INT8 *FileName, - UINT32 DataHH, // Upper 32-bits of upper 64 bits of guid - UINT32 DataHL, // Lower 32-bits of upper 64 bits - UINT32 DataLH, - UINT32 DataLL - ); - -static -VOID -FreeGuids ( - VOID - ); - -static -VOID -FreeSigs ( - VOID - ); - -static -STATUS -CheckDuplicates ( - VOID - ); - -// -// static -// VOID -// ReportGuid ( -// INT8 *FileName, -// GUID_RECORD *FileRecord -// ); -// -static -VOID -FreeOptions ( - VOID - ); - -static -BOOLEAN -CheckGuidData ( - UINT32 *GuidData, - UINT32 DataCount - ); - -/**************************** GLOBALS ****************************************/ -static GUID_RECORD *gGuidList = NULL; -static SIGNATURE_RECORD *gSignatureList = NULL; -static OPTIONS gOptions; - -/*****************************************************************************/ -int -main ( - int Argc, - char *Argv[] - ) -{ - INT8 *Cwd; - STATUS Status; - - SetUtilityName ("GuidChk"); - // - // Get the current working directory and then process the command line - // arguments. - // - Cwd = _getcwd (NULL, 0); - Status = ProcessArgs (Argc, Argv); - if (Status != STATUS_SUCCESS) { - return Status; - } - - if (gOptions.CheckGuids || gOptions.CheckSignatures) { - Status = ProcessDirectory (Cwd, NULL); - if (Status == STATUS_SUCCESS) { - // - // Check for duplicates - // - Status = CheckDuplicates (); - } - } - - if (gOptions.DatabaseOutputFileName[0] != 0) { - CreateGuidList (gOptions.DatabaseOutputFileName); - } - // - // Free up the memory - // - free (Cwd); - FreeGuids (); - FreeSigs (); - FreeOptions (); - return GetUtilityStatus (); -} - -static -STATUS -ProcessArgs ( - int Argc, - char *Argv[] - ) -{ - STRING_LIST *StrList; - - memset ((char *) &gOptions, 0, sizeof (gOptions)); - // - // skip over program name - // - Argc--; - Argv++; - - if (Argc == 0) { - Usage (); - return STATUS_ERROR; - } - - while (Argc > 0) { - // - // Look for options - // - if ((Argv[0][0] == '-') || (Argv[0][0] == '/')) { - switch (Argv[0][1]) { - // - // Help option - // - case 'h': - case 'H': - case '?': - Usage (); - return STATUS_ERROR; - break; - - // - // Check guids option - // - case 'g': - case 'G': - gOptions.CheckGuids = TRUE; - break; - - // - // Check signatures option - // - case 's': - case 'S': - gOptions.CheckSignatures = TRUE; - break; - - // - // Print guids found option - // - case 'p': - case 'P': - gOptions.PrintFound = TRUE; - break; - - // - // Exclude files option - // - case 'f': - case 'F': - // - // Check for another arg - // - if (Argc < 2) { - Error (NULL, 0, 0, Argv[0], "missing argument with option"); - Usage (); - return STATUS_ERROR; - } - - StrList = malloc (sizeof (STRING_LIST)); - if (StrList == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - memset ((char *) StrList, 0, sizeof (STRING_LIST)); - StrList->Str = Argv[1]; - StrList->Next = gOptions.ExcludeFiles; - gOptions.ExcludeFiles = StrList; - Argc--; - Argv++; - break; - - // - // Exclude directories option - // - case 'd': - case 'D': - // - // Check for another arg - // - if (Argc < 2) { - Error (NULL, 0, 0, Argv[0], "missing argument with option"); - Usage (); - return STATUS_ERROR; - } - - StrList = malloc (sizeof (STRING_LIST)); - if (StrList == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - memset ((char *) StrList, 0, sizeof (STRING_LIST)); - StrList->Str = Argv[1]; - StrList->Next = gOptions.ExcludeDirs; - gOptions.ExcludeDirs = StrList; - Argc--; - Argv++; - break; - - // - // -u exclude all subdirectories of a given directory option - // - case 'u': - case 'U': - // - // Check for another arg - // - if (Argc < 2) { - Error (NULL, 0, 0, Argv[0], "missing argument with option"); - Usage (); - return STATUS_ERROR; - } - - StrList = malloc (sizeof (STRING_LIST)); - if (StrList == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - memset ((char *) StrList, 0, sizeof (STRING_LIST)); - StrList->Str = Argv[1]; - StrList->Next = gOptions.ExcludeSubDirs; - gOptions.ExcludeSubDirs = StrList; - Argc--; - Argv++; - break; - - // - // -e exclude by filename extension option - // - case 'e': - case 'E': - // - // Check for another arg - // - if (Argc < 2) { - Error (NULL, 0, 0, Argv[0], "missing argument with option"); - Usage (); - return STATUS_ERROR; - } - - StrList = malloc (sizeof (STRING_LIST)); - if (StrList == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - memset ((char *) StrList, 0, sizeof (STRING_LIST)); - // - // Let them put a * in front of the filename extension - // - StrList->Str = Argv[1]; - if (StrList->Str[0] == '*') { - StrList->Str++; - } - - StrList->Next = gOptions.ExcludeExtensions; - gOptions.ExcludeExtensions = StrList; - Argc--; - Argv++; - break; - - // - // Print guid with matching symbol name for guid definitions found - // - case 'x': - case 'X': - gOptions.GuidXReference = 1; - break; - - // - // -b Print the internal database list to a file - // - case 'b': - case 'B': - // - // Check for one more arg - // - if (Argc < 2) { - Error (NULL, 0, 0, Argv[0], "must specify file name with option"); - Usage (); - return STATUS_ERROR; - } - - strcpy (gOptions.DatabaseOutputFileName, Argv[1]); - Argc--; - Argv++; - break; - - default: - Error (NULL, 0, 0, Argv[0], "invalid option"); - Usage (); - return STATUS_ERROR; - } - } else { - break; - } - // - // Next arg - // - Argc--; - Argv++; - } - - if (Argc > 0) { - Error (NULL, 0, 0, Argv[0], "invalid argument"); - Usage (); - return STATUS_ERROR; - } - // - // Have to check signatures, GUIDs, or dump the GUID database. - // - if ((!gOptions.CheckGuids) && (!gOptions.CheckSignatures) && (gOptions.DatabaseOutputFileName[0] == 0)) { - Error (NULL, 0, 0, "nothing to do", "must specify -g, -s, and/or -b"); - Usage (); - return STATUS_ERROR; - } - - return STATUS_SUCCESS; -} -// -// Print usage instructions -// -static -VOID -Usage ( - VOID - ) -{ - int Index; - char *Str[] = { - "GuidChk - scan files for duplicate GUID or signature definitions", - "", - "Usage: GuidChk {options}\n", - " Options: ", - " -d dirname exclude searching of a directory", - " -f filename exclude searching of a file", - " -e extension exclude searching of files by extension", - " -p print all GUIDS found", - " -g check for duplicate guids", - " -s check for duplicate signatures", - " -x print guid+defined symbol name", - " -b outfile write internal GUID+basename list to outfile", - " -u dirname exclude searching all subdirectories of a directory", - " -h -? print this help text", - " ", - " Example: GuidChk -g -u build -d fv -f make.inf -e .pkg", - "", - NULL - }; - for (Index = 0; Str[Index] != NULL; Index++) { - fprintf (stdout, "%s\n", Str[Index]); - } -} -// -// Process an entire directory by name -// -static -STATUS -ProcessDirectory ( - INT8 *Path, - INT8 *DirectoryName - ) -{ - FILE_SEARCH_DATA FSData; - char *FileMask; - BOOLEAN Done; - UINT32 Len; - BOOLEAN NoSubdirs; - STRING_LIST *SLPtr; - - // - // Root directory may be null - // - if (DirectoryName != NULL) { - // - // printf ("Processing directory: %s\n", DirectoryName); - // - } - // - // Initialize our file searching - // - FileSearchInit (&FSData); - - // - // Exclude some directories, files, and extensions - // - FileSearchExcludeDirs (&FSData, gOptions.ExcludeDirs); - FileSearchExcludeExtensions (&FSData, gOptions.ExcludeExtensions); - FileSearchExcludeFiles (&FSData, gOptions.ExcludeFiles); - // - // See if this directory is in the list of directories that they - // don't want to process subdirectories of - // - NoSubdirs = FALSE; - if (DirectoryName != NULL) { - for (SLPtr = gOptions.ExcludeSubDirs; SLPtr != NULL; SLPtr = SLPtr->Next) { - if (stricmp (SLPtr->Str, DirectoryName) == 0) { - // - // printf ("not processing subdirectories of %s\n", DirectoryName); - // - NoSubdirs = TRUE; - break; - } - } - } - // - // Create a filemask of files to search for. We'll append "\*.*" on the - // end, so allocate some extra bytes. - // - Len = strlen (Path) + 10; - if (DirectoryName != NULL) { - Len += strlen (DirectoryName); - } - - FileMask = malloc (Len); - if (FileMask == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - // - // Now put it all together - // - strcpy (FileMask, Path); - if ((DirectoryName != NULL) && (strlen (DirectoryName) > 0)) { - strcat (FileMask, "\\"); - strcat (FileMask, DirectoryName); - } - - strcat (FileMask, "\\*.*"); - - // - // Start file searching for files and directories - // - FileSearchStart (&FSData, FileMask, FILE_SEARCH_FILE | FILE_SEARCH_DIR); - - // - // Now hack the "\*.*" off the end of the filemask so we can use it to pass - // the full directory path on recursive calls to process directories. - // - FileMask[strlen (FileMask) - 4] = 0; - - // - // Loop until no more files - // - Done = FALSE; - while (!Done) { - // - // printf ("Found %s...", FSData.FileName); - // - if (FSData.FileFlags & FILE_SEARCH_DIR) { - // - // printf ("directory\n"); - // - if (!NoSubdirs) { - ProcessDirectory (FileMask, FSData.FileName); - } - } else if (FSData.FileFlags & FILE_SEARCH_FILE) { - // - // printf ("file\n"); - // - ProcessFile (FileMask, FSData.FileName); - } else { - // - // printf ("unknown\n"); - // - } - - if (FileSearchFindNext (&FSData) != STATUS_SUCCESS) { - Done = TRUE; - } - } - // - // Free up allocated memory - // - free (FileMask); - - // - // Free up our file searching - // - FileSearchDestroy (&FSData); - - return STATUS_SUCCESS; -} -// -// Process a single file. -// -static -STATUS -ProcessFile ( - INT8 *DirectoryName, - INT8 *FileName - ) -{ - STATUS Status; - UINT32 FileExtension; - INT8 FullFileName[MAX_PATH]; - - Status = STATUS_SUCCESS; - - sprintf (FullFileName, "%s\\%s", DirectoryName, FileName); - // - // printf ("Found file: %s\n", FullFileName); - // - FileExtension = GetFileExtension (FileName); - - // - // Process these for GUID checks - // - if (gOptions.CheckGuids) { - switch (FileExtension) { - case FILE_EXTENSION_C: - case FILE_EXTENSION_H: - Status = ProcessCFileGuids (FullFileName); - break; - - case FILE_EXTENSION_PKG: - Status = ProcessPkgFileGuids (FullFileName); - break; - - case FILE_EXTENSION_IA32_INC: - case FILE_EXTENSION_IA32_ASM: - Status = ProcessIA32FileGuids (FullFileName); - break; - - case FILE_EXTENSION_INF: - Status = ProcessINFFileGuids (FullFileName); - break; - - case FILE_EXTENSION_IA64_INC: - case FILE_EXTENSION_IA64_ASM: - Status = ProcessIA64FileGuids (FullFileName); - break; - - default: - // - // No errors anyway - // - Status = STATUS_SUCCESS; - break; - } - } - - if (gOptions.CheckSignatures) { - switch (FileExtension) { - case FILE_EXTENSION_C: - case FILE_EXTENSION_H: - Status = ProcessCFileSigs (FullFileName); - break; - - default: - // - // No errors anyway - // - Status = STATUS_SUCCESS; - break; - } - } - - return Status; -} -// -// Return a code indicating the file name extension. -// -static -UINT32 -GetFileExtension ( - INT8 *FileName - ) -{ - INT8 *Extension; - int Index; - - // - // Look back for a filename extension - // - for (Extension = FileName + strlen (FileName) - 1; Extension >= FileName; Extension--) { - if (*Extension == '.') { - for (Index = 0; FileTypeTable[Index].Extension != NULL; Index++) { - if (stricmp (FileTypeTable[Index].Extension, Extension) == 0) { - return FileTypeTable[Index].ExtensionCode; - } - } - } - } - - return FILE_TYPE_UNKNOWN; -} -// -// Process a .pkg file. -// -// Look for FFS_FILEGUID=35b898ca-b6a9-49ce-8c72-904735cc49b7 -// -static -STATUS -ProcessPkgFileGuids ( - INT8 *FileName - ) -{ - FILE *Fptr; - INT8 Line[MAX_LINE_LEN * 2]; - INT8 *Cptr; - INT8 *Cptr2; - UINT32 GuidScan[11]; - UINT64 Guid64; - - if ((Fptr = fopen (FileName, "r")) == NULL) { - Error (NULL, 0, 0, FileName, "could not open input file for reading"); - return STATUS_ERROR; - } - // - // Read lines from the file until done - // - while (fgets (Line, sizeof (Line), Fptr) != NULL) { - Cptr = Line; - Cptr += SkipWhiteSpace (Line); - if (strncmp (Cptr, "FFS_FILEGUID", 12) == 0) { - Cptr += 12; - Cptr += SkipWhiteSpace (Cptr); - if (*Cptr == '=') { - Cptr++; - Cptr += SkipWhiteSpace (Cptr + 1); - // - // Blank out dashes on the line. - // - for (Cptr2 = Cptr; *Cptr2; Cptr2++) { - if (*Cptr2 == '-') { - *Cptr2 = ' '; - } - } - - if (sscanf ( - Cptr, - "%X %X %X %X %I64X", - &GuidScan[0], - &GuidScan[1], - &GuidScan[2], - &GuidScan[3], - &Guid64 - ) == 5) { - AddPkgGuid (FileName, GuidScan, &Guid64); - } else { - DebugMsg (NULL, 0, 0, FileName, "GUID scan failed"); - } - } - } - } - - fclose (Fptr); - return STATUS_SUCCESS; -} -// -// Process an IA32 assembly file. -// -// Look for: -// FIND_FD_GUID_VAL equ 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h -// PEI_GUID_FileNameGuid_Gmch815 equ 081818181h, 08181h, 08181h, 081h, 081h, 081h, 081h, 081h, 081h, 081h, 081h -// -static -STATUS -ProcessIA32FileGuids ( - INT8 *FileName - ) -{ - FILE *Fptr; - INT8 Line[MAX_LINE_LEN]; - INT8 *Cptr; - INT8 CSave; - INT8 *CSavePtr; - UINT32 Len; - UINT32 GuidData[16]; - UINT32 Index; - - if ((Fptr = fopen (FileName, "r")) == NULL) { - Error (NULL, 0, 0, FileName, "could not open input file for reading"); - return STATUS_ERROR; - } - // - // Read lines from the file until done - // - while (fgets (Line, sizeof (Line), Fptr) != NULL) { - Cptr = Line; - Cptr += SkipWhiteSpace (Line); - // - // Look for xxxGUIDyyy equ 01h, 02h, 03h, ... - // - Len = ValidSymbolName (Cptr); - if (Len) { - // - // Terminate the line after the symbol name, then look for "guid" in - // the name. - // - CSavePtr = Cptr + Len; - CSave = *CSavePtr; - *CSavePtr = 0; - while (*Cptr) { - if (strnicmp (Cptr, "guid", 4) == 0) { - break; - } - - Cptr++; - } - // - // If we found the string "guid", continue - // - if (*Cptr) { - // - // Restore the character on the line where we null-terminated the symbol - // - *CSavePtr = CSave; - Cptr = CSavePtr; - Len = SkipWhiteSpace (Cptr); - // - // Had to be some white space - // - if (Len) { - Cptr += Len; - // - // now look for "equ" - // - if (strnicmp (Cptr, "equ", 3) == 0) { - Cptr += 3; - Cptr += SkipWhiteSpace (Cptr); - // - // Now scan all the data - // - for (Index = 0; Index < 16; Index++) { - if (sscanf (Cptr, "%X", &GuidData[Index]) != 1) { - break; - } - // - // Skip to next - // - while (isxdigit (*Cptr)) { - Cptr++; - } - - if ((*Cptr != 'h') && (*Cptr != 'H')) { - break; - } else { - Cptr++; - while (*Cptr && (isspace (*Cptr) || (*Cptr == ','))) { - Cptr++; - } - } - } - // - // Now see which form we had - // - if (Index == 16) { - AddGuid16 (FileName, GuidData); - } else if (Index == 11) { - AddGuid11 (FileName, GuidData, NULL); - } - } - } - } - } - } - - fclose (Fptr); - return STATUS_SUCCESS; -} -// -// Found and parsed an IA32 assembly code guid. Save the 16 bytes off in the list -// of guids. -// -static -STATUS -AddGuid16 ( - INT8 *FileName, - UINT32 *Data - ) -{ - GUID_RECORD *NewRec; - int Index; - - // - // Sanity check the data - // - if (!CheckGuidData (Data, 16)) { - return STATUS_ERROR; - } - // - // Allocate memory for a new guid structure - // - NewRec = malloc (sizeof (GUID_RECORD)); - if (NewRec == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - memset ((char *) NewRec, 0, sizeof (GUID_RECORD)); - NewRec->FileName = malloc (strlen (FileName) + 1); - if (NewRec->FileName == NULL) { - free (NewRec); - Error (NULL, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - strcpy (NewRec->FileName, FileName); - NewRec->Guid.Data1 = (UINT32) (Data[0] | (Data[1] << 8) | (Data[2] << 16) | (Data[3] << 24)); - NewRec->Guid.Data2 = (UINT16) (Data[4] | (Data[5] << 8)); - NewRec->Guid.Data3 = (UINT16) (Data[6] | (Data[7] << 8)); - for (Index = 0; Index < 8; Index++) { - NewRec->Guid.Data4[Index] = (UINT8) Data[Index + 8]; - } - // - // Add it to the list - // - NewRec->Next = gGuidList; - gGuidList = NewRec; - - // - // Report it - // ReportGuid (FileName, NewRec); - // - return STATUS_SUCCESS; -} -// -// Add a GUID defined as GuidLow: 0x1122334455667788 -// GuidHi: 0x99AABBCCDDEEFF00 -// -// These are equivalent: -// { 0x11223344, 0x5566, 0x7788, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00 } -// and: -// Low: 00FFEEDDCCBBAA99 -// Hi: 7788556611223344 -// -static -STATUS -AddGuid64x2 ( - INT8 *FileName, - UINT32 DataHH, // Upper 32-bits of upper 64 bits of guid - UINT32 DataHL, // Lower 32-bits of upper 64 bits - UINT32 DataLH, - UINT32 DataLL - ) -{ - GUID_RECORD *NewRec; - int Index; - - // - // Allocate memory for a new guid structure - // - NewRec = malloc (sizeof (GUID_RECORD)); - if (NewRec == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - memset ((char *) NewRec, 0, sizeof (GUID_RECORD)); - NewRec->FileName = malloc (strlen (FileName) + 1); - if (NewRec->FileName == NULL) { - free (NewRec); - Error (NULL, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - strcpy (NewRec->FileName, FileName); - NewRec->Guid.Data1 = DataHL; - NewRec->Guid.Data2 = (UINT16) DataHH; - NewRec->Guid.Data3 = (UINT16) (DataHH >> 16); - for (Index = 0; Index < 4; Index++) { - NewRec->Guid.Data4[Index] = (UINT8) DataLL; - DataLL >>= 8; - } - - for (Index = 0; Index < 4; Index++) { - NewRec->Guid.Data4[Index + 4] = (UINT8) DataLH; - DataLH >>= 8; - } - // - // Add it to the list - // - NewRec->Next = gGuidList; - gGuidList = NewRec; - - // - // Report it - // ReportGuid (FileName, NewRec); - // - return STATUS_SUCCESS; -} -// -// Process INF files. Look for: -// FILE_GUID = 240612B6-A063-11d4-9A3A-0090273FC14D -// -static -STATUS -ProcessINFFileGuids ( - INT8 *FileName - ) -{ - FILE *Fptr; - INT8 Line[MAX_LINE_LEN * 2]; - INT8 *Cptr; - INT8 *Cptr2; - UINT32 GuidScan[11]; - UINT64 Guid64; - - if ((Fptr = fopen (FileName, "r")) == NULL) { - Error (NULL, 0, 0, FileName, "could not open input file for reading"); - return STATUS_ERROR; - } - // - // Read lines from the file until done - // - while (fgets (Line, sizeof (Line), Fptr) != NULL) { - Cptr = Line; - Cptr += SkipWhiteSpace (Line); - if (strncmp (Cptr, "FILE_GUID", 9) == 0) { - Cptr += 9; - Cptr += SkipWhiteSpace (Cptr); - if (*Cptr == '=') { - Cptr++; - Cptr += SkipWhiteSpace (Cptr + 1); - // - // Blank out dashes on the line. - // - for (Cptr2 = Cptr; *Cptr2; Cptr2++) { - if (*Cptr2 == '-') { - *Cptr2 = ' '; - } - } - - if (sscanf ( - Cptr, - "%X %X %X %X %I64X", - &GuidScan[0], - &GuidScan[1], - &GuidScan[2], - &GuidScan[3], - &Guid64 - ) == 5) { - AddPkgGuid (FileName, GuidScan, &Guid64); - } else { - DebugMsg (NULL, 0, 0, FileName, "GUID scan failed"); - } - } - } - } - - fclose (Fptr); - return STATUS_SUCCESS; -} -// -// Parse ('g','m','a','p','a','b','c','d') -// -static -STATUS -AddSignature ( - INT8 *FileName, - INT8 *StrDef, - UINT32 SigSize - ) -{ - SIGNATURE_RECORD *NewRec; - INT8 *Cptr; - UINT32 Index; - BOOLEAN Fail; - - // - // Allocate memory for the new record - // - Fail = FALSE; - NewRec = malloc (sizeof (SIGNATURE_RECORD)); - if (NewRec == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - // - // Allocate memory to save the file name - // - NewRec->FileName = malloc (strlen (FileName) + 1); - if (NewRec->FileName == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - free (NewRec); - return STATUS_ERROR; - } - // - // Fill in the fields - // - strcpy (NewRec->FileName, FileName); - NewRec->Signature.DataLen = (UINT8) SigSize; - // - // Skip to open parenthesis - // - Cptr = StrDef; - Cptr += SkipWhiteSpace (Cptr); - if (*Cptr != '(') { - Fail = TRUE; - goto Done; - } - - Cptr++; - // - // Skip to first ' and start processing - // - while (*Cptr && (*Cptr != '\'')) { - Cptr++; - } - - for (Index = 0; Index < SigSize; Index++) { - if (*Cptr == '\'') { - Cptr++; - NewRec->Signature.Data[Index] = (INT8) *Cptr; - // - // Skip to closing quote - // - Cptr++; - if (*Cptr != '\'') { - Fail = TRUE; - break; - } - // - // Skip over closing quote, go to next one - // - Cptr++; - while (*Cptr && (*Cptr != '\'')) { - Cptr++; - } - } else { - Fail = TRUE; - DebugMsg (NULL, 0, 0, StrDef, "failed to parse signature"); - break; - } - } - -Done: - if (Fail) { - free (NewRec->FileName); - free (NewRec); - return STATUS_ERROR; - } - - NewRec->Next = gSignatureList; - gSignatureList = NewRec; - return STATUS_SUCCESS; -} -// -// Look for: -// #define POOL_HEAD_SIGNATURE EFI_SIGNATURE_16('p','h') -// #define GCD_MEMORY_MAP_SIGNATURE EFI_SIGNATURE_32('g','m','a','p') -// #define GCD_MEMORY_MAP_SIGNATURE EFI_SIGNATURE_64('g','m','a','p','a','b','c','d') -// -static -STATUS -ProcessCFileSigs ( - INT8 *FileName - ) -{ - FILE *Fptr; - INT8 Line[MAX_LINE_LEN * 2]; - INT8 *Cptr; - UINT32 Len; - UINT32 LineLen; - - if ((Fptr = fopen (FileName, "r")) == NULL) { - Error (NULL, 0, 0, FileName, "could not open input file for reading"); - return STATUS_ERROR; - } - // - // Read lines from the file until done - // - while (fgets (Line, sizeof (Line), Fptr) != NULL) { - Cptr = Line; - Cptr += SkipWhiteSpace (Line); - // - // look for #define xxxGUIDxxx value - // - if (*Cptr == '#') { - Cptr++; - Cptr += SkipWhiteSpace (Cptr); - // - // Look for "define" - // - if (!strncmp (Cptr, "define", 6)) { - Cptr += 6; - // - // Better be whitespace - // - Len = SkipWhiteSpace (Cptr); - if (Len) { - Cptr += Len; - // - // See if it's a valid symbol name - // - Len = ValidSymbolName (Cptr); - if (Len) { - // - // It is a valid symbol name. See if there's a line continuation, - // and if so, read one more line. - // Skip over the symbol name and look for the string "EFI_SIGNATURE_xx" - // - LineLen = strlen (Line); - if ((Line[LineLen - 1] == '\n') && (Line[LineLen - 2] == '\\')) { - fgets (Line + LineLen - 2, sizeof (Line) - LineLen, Fptr); - } else if (Line[LineLen - 1] == '\\') { - fgets (Line + LineLen - 1, sizeof (Line) - LineLen, Fptr); - } - - Cptr += Len; - Cptr += SkipWhiteSpace (Cptr); - if (strncmp (Cptr, "EFI_SIGNATURE_16", 16) == 0) { - AddSignature (FileName, Cptr + 16, 2); - } else if (strncmp (Cptr, "EFI_SIGNATURE_32", 16) == 0) { - AddSignature (FileName, Cptr + 16, 4); - } else if (strncmp (Cptr, "EFI_SIGNATURE_64", 16) == 0) { - AddSignature (FileName, Cptr + 16, 8); - } - } - } - } - } - } - - fclose (Fptr); - return STATUS_SUCCESS; -} -// -// look for #define xxxGUIDyyy { 0x...} -// xxx EFI_GUID GuidName = { 0x... }; -// -static -STATUS -ProcessCFileGuids ( - INT8 *FileName - ) -{ - FILE *Fptr; - INT8 Line[MAX_LINE_LEN * 2]; - INT8 *Cptr; - INT8 CSave; - INT8 *CSavePtr; - INT8 *TempCptr; - INT8 *SymName; - UINT32 Len; - UINT32 LineLen; - UINT32 GuidScan[11]; - - if ((Fptr = fopen (FileName, "r")) == NULL) { - Error (NULL, 0, 0, FileName, "could not open input file for reading"); - return STATUS_ERROR; - } - // - // Read lines from the file until done - // - while (fgets (Line, sizeof (Line), Fptr) != NULL) { - Cptr = Line; - Cptr += SkipWhiteSpace (Line); - // - // look for #define xxxGUIDxxx value - // - if (*Cptr == '#') { - Cptr++; - Cptr += SkipWhiteSpace (Cptr); - // - // Look for "define" - // - if (!strncmp (Cptr, "define", 6)) { - Cptr += 6; - // - // Better be whitespace - // - Len = SkipWhiteSpace (Cptr); - if (Len) { - Cptr += Len; - // - // See if it's a valid symbol name - // - Len = ValidSymbolName (Cptr); - if (Len) { - // - // It is a valid symbol name. See if there's a line continuation, - // and if so, read one more line. - // Then truncate after the symbol name, look for the string "GUID", - // and continue. - // - SymName = Cptr; - LineLen = strlen (Line); - if ((Line[LineLen - 1] == '\n') && (Line[LineLen - 2] == '\\')) { - fgets (Line + LineLen - 2, sizeof (Line) - LineLen, Fptr); - } else if (Line[LineLen - 1] == '\\') { - fgets (Line + LineLen - 1, sizeof (Line) - LineLen, Fptr); - } - - CSavePtr = Cptr + Len; - CSave = *CSavePtr; - *CSavePtr = 0; - while (*Cptr) { - if (strncmp (Cptr, "GUID", 4) == 0) { - break; - } - - Cptr++; - } - // - // If we didn't run out of string, then we found the GUID string. - // Now look for { 0x....... } - // - if (*Cptr) { - Cptr = CSavePtr; - *CSavePtr = CSave; - Cptr += SkipWhiteSpace (Cptr); - if (*Cptr == '{') { - *Cptr = 0; - Cptr++; - // - // 0x665E3FF6, 0x46CC, 0x11d4, 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } - // If you have one suffixed with "L", then it doesn't work. So hack off 'L' characters - // in the string. - // - for (TempCptr = Cptr; *TempCptr; TempCptr++) { - if (*TempCptr == 'L') { - if (*(TempCptr + 1) == ',') { - *TempCptr = ','; - *(TempCptr + 1) = ' '; - } - } - } - - if (sscanf ( - Cptr, - "%X, %X, %X, %X, %X, %X, %X, %X, %X, %X, %X", - &GuidScan[0], - &GuidScan[1], - &GuidScan[2], - &GuidScan[3], - &GuidScan[4], - &GuidScan[5], - &GuidScan[6], - &GuidScan[7], - &GuidScan[8], - &GuidScan[9], - &GuidScan[10] - ) == 11) { - AddGuid11 (FileName, GuidScan, SymName); - } - } - } - } - } - } - // - // Else look for "static EFI_GUID xxxGUIDxxx = { 0x.... }; - // - } else if ((CSavePtr = strstr (Line, "EFI_GUID")) != NULL) { - // - // Read the next line if line continuation - // - LineLen = strlen (Line); - if ((Line[LineLen - 1] == '\n') && (Line[LineLen - 2] == '\\')) { - fgets (Line + LineLen - 2, sizeof (Line) - LineLen, Fptr); - } else if (Line[LineLen - 1] == '\\') { - fgets (Line + LineLen - 1, sizeof (Line) - LineLen, Fptr); - } - - Cptr = CSavePtr + 8; - Cptr += SkipWhiteSpace (Cptr); - // - // Should be variable name next - // - Len = ValidSymbolName (Cptr); - SymName = Cptr; - Cptr += Len; - Cptr += SkipWhiteSpace (Cptr); - if (*Cptr == '=') { - Cptr++; - Cptr += SkipWhiteSpace (Cptr); - // - // Should be open-brace next to define guid - // - if (*Cptr == '{') { - Cptr++; - // - // 0x665E3FF6, 0x46CC, 0x11d4, 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } - // - if (sscanf ( - Cptr, - "%X, %X, %X, %X, %X, %X, %X, %X, %X, %X, %X", - &GuidScan[0], - &GuidScan[1], - &GuidScan[2], - &GuidScan[3], - &GuidScan[4], - &GuidScan[5], - &GuidScan[6], - &GuidScan[7], - &GuidScan[8], - &GuidScan[9], - &GuidScan[10] - ) == 11) { - AddGuid11 (FileName, GuidScan, Cptr); - // - // printf ("Found guid: %s", Cptr); - // - } - } - } - } - } - - fclose (Fptr); - return STATUS_SUCCESS; -} -// -// Process Intel Itanium(TM) GUID definitions. Look for: -// #define Cs870MemoryTestPEIMGuidL 0x9C2403386E1C8FAA -// #define Cs870MemoryTestPEIMGuidH 0xE89E95C6180342f0 -// in either order. -// This function assumes no blank lines between definitions. -// -static -STATUS -ProcessIA64FileGuids ( - INT8 *FileName - ) -{ - FILE *Fptr; - INT8 Line[MAX_LINE_LEN]; - UINT32 Guid1H; - UINT32 Guid1L; - UINT32 Guid2H; - UINT32 Guid2L; - INT8 SymName1[MAX_LINE_LEN]; - INT8 SymName2[MAX_LINE_LEN]; - BOOLEAN Done; - BOOLEAN LowFirst; - BOOLEAN FoundLow; - - if ((Fptr = fopen (FileName, "r")) == NULL) { - Error (NULL, 0, 0, FileName, "could not open input file for reading"); - return STATUS_ERROR; - } - - Done = FALSE; - if (fgets (Line, sizeof (Line), Fptr) == NULL) { - Done = 1; - } - // - // Read lines from the file until done. Since the guid definition takes - // two lines, we read lines in different places to recover gracefully - // from mismatches. For example, if you thought you found the first half, - // but the next line had a symbol mismatch, then you have to process the - // line again in case it's the start of a new definition. - // - while (!Done) { - // - // Check current line for GUID definition. Assume low define first. - // - if (IsIA64GuidLine (Line, &Guid1H, &Guid1L, &FoundLow, SymName1)) { - // - // Might have to swap guids later. Save off if we found the LOW first - // - if (FoundLow) { - LowFirst = TRUE; - } else { - LowFirst = FALSE; - } - // - // Read the next line and try for the rest of the guid definition - // - if (fgets (Line, sizeof (Line), Fptr) == NULL) { - Done = 1; - } else { - if (IsIA64GuidLine (Line, &Guid2H, &Guid2L, &FoundLow, SymName2)) { - // - // Found another. If the symbol names match, then save it off. - // - if (strcmp (SymName1, SymName2) == 0) { - // - // Yea, found one. Save it off. - // - if (LowFirst) { - AddGuid64x2 (FileName, Guid2H, Guid2L, Guid1H, Guid1L); - } else { - AddGuid64x2 (FileName, Guid1H, Guid1L, Guid2H, Guid2L); - } - // - // Read the next line for processing - // - if (fgets (Line, sizeof (Line), Fptr) == NULL) { - Done = 1; - } - } else { - // - // Don't get another line so that we reprocess this line in case it - // contains the start of a new definition. - // fprintf (stdout, "Symbol name mismatch: %s: %s != %s\n", - // FileName, SymName1, SymName2); - // - } - } else { - // - // Second line was not a guid definition. Get the next line from the - // file. - // - if (fgets (Line, sizeof (Line), Fptr) == NULL) { - Done = 1; - } - } - } - } else { - // - // Not a guid define line. Next. - // - if (fgets (Line, sizeof (Line), Fptr) == NULL) { - Done = 1; - } - } - } - - fclose (Fptr); - return STATUS_SUCCESS; -} -// -// Given a line from an Itanium-based assembly file, check the line for a guid -// defininition. One of either: -// #define Cs870MemoryTestPEIMGuidL 0x9C2403386E1C8FAA -// #define Cs870MemoryTestPEIMGuidH 0xE89E95C6180342f0 -// Return the defined value as two 32-bit values, and whether it's a high -// or low guid. -// -static -BOOLEAN -IsIA64GuidLine ( - INT8 *Line, - UINT32 *GuidHigh, - UINT32 *GuidLow, - BOOLEAN *FoundLow, - INT8 *SymName - ) -{ - INT8 *Cptr; - INT8 CSave; - INT8 *CSavePtr; - INT8 *SymStart; - UINT32 Len; - - Cptr = Line; - Cptr += SkipWhiteSpace (Cptr); - // - // look for #define xxxGUID[L|H] 0xHexValue - // - if (*Cptr == '#') { - Cptr++; - Cptr += SkipWhiteSpace (Cptr); - // - // Look for "define" - // - if (!strncmp (Cptr, "define", 6)) { - Cptr += 6; - // - // Better be whitespace - // - Len = SkipWhiteSpace (Cptr); - if (Len) { - Cptr += Len; - // - // See if it's a valid symbol name - // - Len = ValidSymbolName (Cptr); - if (Len) { - // - // Save the start so we can copy it to their string if later checks are ok - // - SymStart = Cptr; - // - // It is a valid symbol name, look for the string GuidL or GuidH - // - CSavePtr = Cptr + Len; - CSave = *CSavePtr; - *CSavePtr = 0; - while (*Cptr) { - if (strncmp (Cptr, "GuidL", 5) == 0) { - *FoundLow = 1; - break; - } else if (strncmp (Cptr, "GuidH", 5) == 0) { - *FoundLow = 0; - break; - } - - Cptr++; - } - // - // If we didn't run out of string, then we found the GUID string. - // Restore the null character we inserted above and continue. - // Now look for 0x....... - // - if (*Cptr) { - // - // Return symbol name less the "L" or "H" - // - strcpy (SymName, SymStart); - SymName[strlen (SymName) - 1] = 0; - Cptr = CSavePtr; - *CSavePtr = CSave; - Cptr += SkipWhiteSpace (Cptr); - if ((*Cptr == '0') && (*(Cptr + 1) == 'x')) { - // - // skip over "0x" - // - Cptr += 2; - // - // 0x0123456789ABCDEF -- null terminate after 8 characters, - // scan, replace the character and scan at that point. - // - CSave = *(Cptr + 8); - *(Cptr + 8) = 0; - if (sscanf (Cptr, "%X", GuidHigh) == 1) { - *(Cptr + 8) = CSave; - if (sscanf (Cptr + 8, "%X", GuidLow) == 1) { - return TRUE; - } - } - } - } - } - } - } - } - - return FALSE; -} -// -// Look at the characters in the string and determine if it's a valid -// symbol name. Basically [a-zA-Z_][a-zA-Z_0-9]* -// -static -UINT32 -ValidSymbolName ( - INT8 *Name - ) -{ - int Len; - - Len = 0; - - // - // Test first character - // - if (((*Name >= 'a') && (*Name <= 'z')) || ((*Name >= 'A') && (*Name <= 'Z')) || (*Name == '_')) { - Name++; - Len = 1; - while (*Name) { - if (((*Name >= 'a') && (*Name <= 'z')) || - ((*Name >= 'A') && (*Name <= 'Z')) || - ((*Name >= '0') && (*Name <= '9')) || - (*Name == '_') - ) { - Name++; - Len++; - } else { - break; - } - } - } - - return Len; -} - -static -UINT32 -SkipWhiteSpace ( - INT8 *Str - ) -{ - UINT32 Len; - Len = 0; - while (isspace (*Str) && *Str) { - Len++; - Str++; - } - - return Len; -} -// -// found FFS_FILEGUID=35b898ca-b6a9-49ce-8c72-904735cc49b7 -// -static -STATUS -AddPkgGuid ( - INT8 *FileName, - UINT32 *Data, - UINT64 *Data64 - ) -{ - GUID_RECORD *NewRec; - int Index; - - // - // Sanity check the data - // - if ((Data[1] | Data[2] | Data[3]) & 0xFFFF0000) { - Error (NULL, 0, 0, "out of range value for GUID data word(s) [1] - [3]", NULL); - return STATUS_ERROR; - } - // - // More checks for Data64? - // Allocate memory for a new one guid structure - // - NewRec = malloc (sizeof (GUID_RECORD)); - if (NewRec == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - memset ((char *) NewRec, 0, sizeof (GUID_RECORD)); - NewRec->FileName = malloc (strlen (FileName) + 1); - if (NewRec->FileName == NULL) { - free (NewRec); - Error (NULL, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - strcpy (NewRec->FileName, FileName); - NewRec->Guid.Data1 = Data[0]; - NewRec->Guid.Data2 = (UINT16) Data[1]; - NewRec->Guid.Data3 = (UINT16) Data[2]; - NewRec->Guid.Data4[0] = (UINT8) Data[3]; - NewRec->Guid.Data4[1] = (UINT8) (Data[3] >> 8); - for (Index = 2; Index < 8; Index++) { - NewRec->Guid.Data4[Index] = (UINT8) *Data64; - *Data64 >>= 8; - } - // - // Add it to the list - // - NewRec->Next = gGuidList; - gGuidList = NewRec; - - // - // Report it - // ReportGuid (FileName, NewRec); - // - return STATUS_SUCCESS; -} -// -// Add a guid consisting of 11 fields to our list of guids -// -static -STATUS -AddGuid11 ( - INT8 *FileName, - UINT32 *Data, - INT8 *SymName - ) -{ - GUID_RECORD *NewRec; - int Index; - - // - // Sanity check the data - // - if (!CheckGuidData (Data, 11)) { - return STATUS_ERROR; - } - // - // Allocate memory for a new one guid structure - // - NewRec = malloc (sizeof (GUID_RECORD)); - if (NewRec == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - memset ((char *) NewRec, 0, sizeof (GUID_RECORD)); - NewRec->FileName = malloc (strlen (FileName) + 1); - if (NewRec->FileName == NULL) { - free (NewRec); - Error (NULL, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - strcpy (NewRec->FileName, FileName); - if (SymName != NULL) { - NewRec->SymName = malloc (strlen (SymName) + 1); - if (NewRec->SymName == NULL) { - free (NewRec); - Error (NULL, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - } - - strcpy (NewRec->SymName, SymName); - - NewRec->Guid.Data1 = Data[0]; - NewRec->Guid.Data2 = (UINT16) Data[1]; - NewRec->Guid.Data3 = (UINT16) Data[2]; - for (Index = 0; Index < 8; Index++) { - NewRec->Guid.Data4[Index] = (UINT8) Data[3 + Index]; - } - // - // Add it to the list - // - NewRec->Next = gGuidList; - gGuidList = NewRec; - - // - // Report it - // ReportGuid (FileName, NewRec); - // - return STATUS_SUCCESS; -} -// -// For debug purposes, print each guid found -// -// static -// VOID -// ReportGuid ( -// INT8 *FileName, -// GUID_RECORD *NewGuid -// ) -// { -// //fprintf (stdout, "%s: 0x%08X\n", FileName, NewGuid->Guid.Data1); -// } -// -// Free up memory we allocated to keep track of guids defined. -// -static -VOID -FreeGuids ( - VOID - ) -{ - GUID_RECORD *NextRec; - while (gGuidList != NULL) { - NextRec = gGuidList->Next; - if (gGuidList->FileName != NULL) { - free (gGuidList->FileName); - } - - if (gGuidList->SymName != NULL) { - free (gGuidList->SymName); - } - - free (gGuidList); - gGuidList = NextRec; - } -} - -static -VOID -FreeSigs ( - VOID - ) -{ - SIGNATURE_RECORD *NextRec; - while (gSignatureList != NULL) { - NextRec = gSignatureList->Next; - if (gSignatureList->FileName != NULL) { - free (gSignatureList->FileName); - } - - free (gSignatureList); - gSignatureList = NextRec; - } -} -// -// Scan through all guids defined and compare each for duplicates. -// -static -STATUS -CheckDuplicates ( - VOID - ) -{ - GUID_RECORD *CurrentFile; - - GUID_RECORD *TempFile; - SIGNATURE_RECORD *CurrentSig; - SIGNATURE_RECORD *TempSig; - STATUS Status; - int Index; - int DupCount; - int Len; - BOOLEAN Same; - UINT32 GuidSum; - INT8 *SymName; - - Status = STATUS_SUCCESS; - - // - // If we're checking guids..... - // - if (gOptions.CheckGuids) { - // - // If -p option, print all guids found - // - if (gOptions.PrintFound) { - CurrentFile = gGuidList; - while (CurrentFile != NULL) { - fprintf ( - stdout, - "GUID: 0x%08X 0x%04X 0x%04X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X %s\n", - (UINT32) CurrentFile->Guid.Data1, - (UINT32) CurrentFile->Guid.Data2, - (UINT32) CurrentFile->Guid.Data3, - (UINT32) CurrentFile->Guid.Data4[0], - (UINT32) CurrentFile->Guid.Data4[1], - (UINT32) CurrentFile->Guid.Data4[2], - (UINT32) CurrentFile->Guid.Data4[3], - (UINT32) CurrentFile->Guid.Data4[4], - (UINT32) CurrentFile->Guid.Data4[5], - (UINT32) CurrentFile->Guid.Data4[6], - (UINT32) CurrentFile->Guid.Data4[7], - CurrentFile->FileName - ); - CurrentFile = CurrentFile->Next; - } - } - - if (gOptions.GuidXReference) { - CurrentFile = gGuidList; - while (CurrentFile != NULL) { - // - // If no symbol name, print "unknown" - // - SymName = CurrentFile->SymName; - if (SymName == NULL) { - SymName = "unknown"; - } - - fprintf ( - stdout, - "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X %s\n", - (UINT32) CurrentFile->Guid.Data1, - (UINT32) CurrentFile->Guid.Data2, - (UINT32) CurrentFile->Guid.Data3, - (UINT32) CurrentFile->Guid.Data4[0], - (UINT32) CurrentFile->Guid.Data4[1], - (UINT32) CurrentFile->Guid.Data4[2], - (UINT32) CurrentFile->Guid.Data4[3], - (UINT32) CurrentFile->Guid.Data4[4], - (UINT32) CurrentFile->Guid.Data4[5], - (UINT32) CurrentFile->Guid.Data4[6], - (UINT32) CurrentFile->Guid.Data4[7], - SymName - ); - CurrentFile = CurrentFile->Next; - } - } - // - // Now go through all guids and report duplicates. - // - CurrentFile = gGuidList; - while (CurrentFile != NULL) { - DupCount = 0; - TempFile = CurrentFile->Next; - while (TempFile) { - // - // Compare the guids - // - if ((CurrentFile->Guid.Data1 == TempFile->Guid.Data1) && - (CurrentFile->Guid.Data2 == TempFile->Guid.Data2) && - (CurrentFile->Guid.Data3 == TempFile->Guid.Data3) - ) { - // - // OR in all the guid bytes so we can ignore NULL-guid definitions. - // - GuidSum = CurrentFile->Guid.Data1 | CurrentFile->Guid.Data2 | CurrentFile->Guid.Data3; - Same = TRUE; - for (Index = 0; Index < 8; Index++) { - GuidSum |= CurrentFile->Guid.Data4[Index]; - if (CurrentFile->Guid.Data4[Index] != TempFile->Guid.Data4[Index]) { - Same = FALSE; - break; - } - } - // - // If they're the same, and the guid was non-zero, print a message. - // - if (Same && GuidSum) { - if (DupCount == 0) { - Error (NULL, 0, 0, "duplicate GUIDS found", NULL); - fprintf (stdout, " FILE1: %s\n", CurrentFile->FileName); - } - - DupCount++; - fprintf (stdout, " FILE%d: %s\n", DupCount + 1, TempFile->FileName); - // - // Flag it as reported so we don't report it again if there's three or more - // - TempFile->Reported = TRUE; - } - } - // - // Next one - // - TempFile = TempFile->Next; - } - // - // Print the guid if we found duplicates - // - if (DupCount) { - fprintf ( - stdout, - " GUID: 0x%08X 0x%04X 0x%04X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", - (UINT32) CurrentFile->Guid.Data1, - (UINT32) CurrentFile->Guid.Data2, - (UINT32) CurrentFile->Guid.Data3, - (UINT32) CurrentFile->Guid.Data4[0], - (UINT32) CurrentFile->Guid.Data4[1], - (UINT32) CurrentFile->Guid.Data4[2], - (UINT32) CurrentFile->Guid.Data4[3], - (UINT32) CurrentFile->Guid.Data4[4], - (UINT32) CurrentFile->Guid.Data4[5], - (UINT32) CurrentFile->Guid.Data4[6], - (UINT32) CurrentFile->Guid.Data4[7] - ); - // - // return STATUS_ERROR; - // - } - // - // Find the next one that hasn't been reported - // - do { - CurrentFile = CurrentFile->Next; - } while ((CurrentFile != NULL) && (CurrentFile->Reported)); - } - } - - if (gOptions.CheckSignatures) { - // - // Print ones found if specified - // - if (gOptions.PrintFound) { - CurrentSig = gSignatureList; - while (CurrentSig != NULL) { - Len = CurrentSig->Signature.DataLen; - for (Index = 0; Index < Len; Index++) { - fprintf (stdout, "%c", CurrentSig->Signature.Data[Index]); - } - - fprintf (stdout, " %s\n", CurrentSig->FileName); - CurrentSig = CurrentSig->Next; - } - } - - CurrentSig = gSignatureList; - while (CurrentSig != NULL) { - DupCount = 0; - TempSig = CurrentSig->Next; - Len = CurrentSig->Signature.DataLen; - while (TempSig) { - // - // Check for same length, then do string compare - // - if (Len == TempSig->Signature.DataLen) { - if (strncmp (CurrentSig->Signature.Data, TempSig->Signature.Data, Len) == 0) { - // - // Print header message if first failure for this sig - // - if (DupCount == 0) { - Error (NULL, 0, 0, "duplicate signatures found", NULL); - fprintf (stdout, " FILE1: %s\n", CurrentSig->FileName); - } - - DupCount++; - fprintf (stdout, " FILE%d: %s\n", DupCount + 1, TempSig->FileName); - TempSig->Reported = TRUE; - } - } - - TempSig = TempSig->Next; - } - - if (DupCount) { - fprintf (stdout, " SIG: "); - for (Index = 0; Index < Len; Index++) { - fprintf (stdout, "%c", CurrentSig->Signature.Data[Index]); - } - - fprintf (stdout, "\n"); - } - // - // On to the next one that hasn't been reported - // - do { - CurrentSig = CurrentSig->Next; - } while ((CurrentSig != NULL) && (CurrentSig->Reported)); - } - } - - return Status; -} - -static -VOID -FreeOptions ( - VOID - ) -/*++ - -Routine Description: - Free up any memory we allocated when processing command-line options. - -Arguments: - None. - -Returns: - NA - -Notes: - We don't free up the ->Str fields because we did not allocate them. - Instead, we just set the pointer to point to the actual parameter - from the command line. - ---*/ -{ - STRING_LIST *Ptr; - while (gOptions.ExcludeDirs != NULL) { - Ptr = gOptions.ExcludeDirs->Next; - // - // free (gOptions.ExcludeDirs->Str); - // - free (gOptions.ExcludeDirs); - gOptions.ExcludeDirs = Ptr; - } - - while (gOptions.ExcludeSubDirs != NULL) { - Ptr = gOptions.ExcludeSubDirs->Next; - // - // free (gOptions.ExcludeSubDirs->Str); - // - free (gOptions.ExcludeSubDirs); - gOptions.ExcludeSubDirs = Ptr; - } - - while (gOptions.ExcludeExtensions != NULL) { - Ptr = gOptions.ExcludeExtensions->Next; - // - // free (gOptions.ExcludeExtensions->Str); - // - free (gOptions.ExcludeExtensions); - gOptions.ExcludeExtensions = Ptr; - } - - while (gOptions.ExcludeFiles != NULL) { - Ptr = gOptions.ExcludeFiles->Next; - // - // free (gOptions.ExcludeFiles->Str); - // - free (gOptions.ExcludeFiles); - gOptions.ExcludeFiles = Ptr; - } -} -// -// Given an array of 32-bit data, validate the data for the given number of -// guid data. For example, it might have been scanned as 16 bytes of data, or -// 11 fields of data. -// -static -BOOLEAN -CheckGuidData ( - UINT32 *Data, - UINT32 DataCount - ) -{ - UINT32 Index; - - if (DataCount == 16) { - for (Index = 0; Index < 16; Index++) { - if (Data[Index] &~0xFF) { - return FALSE; - } - } - - return TRUE; - } else if (DataCount == 11) { - // - // Data[0] never out of range (32-bit) - // - if ((Data[1] | Data[2]) &~0xFFFF) { - // - // Error ("Out of range value for GUID data word(s) [1] and/or [2]"); - // - return FALSE; - } - - for (Index = 0; Index < 8; Index++) { - if (Data[Index + 3] &~0xFF) { - // - // Error ("Out of range value for GUID data byte(s) [4] - [11]"); - // - return FALSE; - } - } - - return TRUE; - } - - return FALSE; -} diff --git a/Tools/CodeTools/TianoTools/GuidChk/GuidList.c b/Tools/CodeTools/TianoTools/GuidChk/GuidList.c deleted file mode 100644 index bb6a44d85e..0000000000 --- a/Tools/CodeTools/TianoTools/GuidChk/GuidList.c +++ /dev/null @@ -1,186 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - GuidList.c - -Abstract: - - Utility to create a GUID-to-name listing file that can - be used by other utilities. Basic operation is to take the - table of name+GUIDs that we have compiled into this utility, - and create a text file that can be parsed by other utilities - to do replacement of "name" with "GUID". - -Notes: - To add a new GUID to this database: - 1. Add a "#include EFI_GUID_DEFINITION(name)" statement below - 2. Modify the mGuidList[] array below to add the new GUID name - - The only issue that may come up is that, if the source GUID file - is not in the standard GUID directory, then this utility won't - compile because the #include fails. In this case you'd need - to define a new macro (if it's in a standard place) or modify - this utility's makefile to add the path to your new .h file. - ---*/ - -#include -#include -#include -#include - -#include -#include -#include - -#include "EfiUtilityMsgs.h" - - -#define GUID_XREF(varname, guid) { \ - #varname, #guid, guid \ - } - -#define NULL_GUID \ - { \ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 \ - } - -typedef struct { - INT8 *VariableName; - INT8 *DefineName; - EFI_GUID Guid; -} GUID_LIST; - -// -// This is our table of all GUIDs we want to print out to create -// a GUID-to-name cross reference. -// Use the #defined name from the GUID definition's source .h file. -// -static GUID_LIST mGuidList[] = { - GUID_XREF(gAprioriGuid, EFI_APRIORI_GUID), - GUID_XREF(gEfiAcpiTableStorageGuid, EFI_ACPI_TABLE_STORAGE_GUID), - // FIXME The next line was removed in the port to R9. - // GUID_XREF(gEfiDefaultBmpLogoGuid, EFI_DEFAULT_BMP_LOGO_GUID), - GUID_XREF(gEfiAcpiTableStorageGuid, EFI_ACPI_TABLE_STORAGE_GUID), - // - // Terminator - // - { - NULL, - NULL, - NULL_GUID - } -}; - -void -PrintGuidText ( - FILE *OutFptr, - INT8 *VariableName, - INT8 *DefineName, - EFI_GUID *Guid - ); - -int -CreateGuidList ( - INT8 *OutFileName - ) -/*++ - -Routine Description: - Print our GUID/name list to the specified output file. - -Arguments: - OutFileName - name of the output file to write our results to. - -Returns: - 0 if successful - nonzero otherwise - ---*/ -{ - FILE *OutFptr; - int Index; - - // - // Open output file for writing. If the name is NULL, then write to stdout - // - if (OutFileName != NULL) { - OutFptr = fopen (OutFileName, "w"); - if (OutFptr == NULL) { - Error (NULL, 0, 0, OutFileName, "failed to open output file for writing"); - return STATUS_ERROR; - } - } else { - OutFptr = stdout; - } - - for (Index = 0; mGuidList[Index].VariableName != NULL; Index++) { - PrintGuidText (OutFptr, mGuidList[Index].VariableName, mGuidList[Index].DefineName, &mGuidList[Index].Guid); - } - // - // Close the output file if they specified one. - // - if (OutFileName != NULL) { - fclose (OutFptr); - } - - return STATUS_SUCCESS; -} - -void -PrintGuidText ( - FILE *OutFptr, - INT8 *VariableName, - INT8 *DefineName, - EFI_GUID *Guid - ) -/*++ - -Routine Description: - Print a GUID/name combo in INF-style format - - guid-guid-guid-guid DEFINE_NAME gName - -Arguments: - OutFptr - file pointer to which to write the output - VariableName - the GUID variable's name - DefineName - the name used in the #define - Guid - pointer to the GUID value - -Returns: - NA - ---*/ -{ - if (OutFptr == NULL) { - OutFptr = stdout; - } - - fprintf ( - OutFptr, - "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X %s %s\n", - Guid->Data1, - Guid->Data2, - Guid->Data3, - Guid->Data4[0], - Guid->Data4[1], - Guid->Data4[2], - Guid->Data4[3], - Guid->Data4[4], - Guid->Data4[5], - Guid->Data4[6], - Guid->Data4[7], - DefineName, - VariableName - ); -} diff --git a/Tools/CodeTools/TianoTools/GuidChk/UtilsMsgs.c b/Tools/CodeTools/TianoTools/GuidChk/UtilsMsgs.c deleted file mode 100644 index 8aa343fc19..0000000000 --- a/Tools/CodeTools/TianoTools/GuidChk/UtilsMsgs.c +++ /dev/null @@ -1,490 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - UtilsMsgs.c - -Abstract: - - EFI tools utility functions to display warning, error, and informational - messages. - ---*/ - -#include -#include -#include -#include - -#include - -#include "EfiUtilityMsgs.h" - -#define MAX_LINE_LEN 200 - -// -// Declare module globals for keeping track of the the utility's -// name and other settings. -// -static STATUS mStatus = STATUS_SUCCESS; -static INT8 mUtilityName[50] = { 0 }; -static INT8 *mSourceFileName = NULL; -static UINT32 mSourceFileLineNum = 0; -static UINT32 mErrorCount = 0; -static UINT32 mWarningCount = 0; -static UINT32 mDebugMsgMask = 0; - -static -void -PrintMessage ( - INT8 *Type, - INT8 *FileName, - UINT32 LineNumber, - UINT32 MessageCode, - INT8 *Text, - INT8 *MsgFmt, - va_list List - ); - -void -Error ( - INT8 *FileName, - UINT32 LineNumber, - UINT32 MessageCode, - INT8 *Text, - INT8 *MsgFmt, - ... - ) -/*++ - -Routine Description: - Prints an error message. - -Arguments: - All arguments are optional, though the printed message may be useless if - at least something valid is not specified. - - FileName - name of the file or application. If not specified, then the - utilty name (as set by the utility calling SetUtilityName() - earlier) is used. Otherwise "Unknown utility" is used. - - LineNumber - the line number of error, typically used by parsers. If the - utility is not a parser, then 0 should be specified. Otherwise - the FileName and LineNumber info can be used to cause - MS Visual Studio to jump to the error. - - MessageCode - an application-specific error code that can be referenced in - other documentation. - - Text - the text in question, typically used by parsers. - - MsgFmt - the format string for the error message. Can contain formatting - controls for use with the varargs. - -Returns: - None. - -Notes: - We print the following (similar to the Warn() and Debug() - W - Typical error/warning message format: - - bin\VfrCompile.cpp(330) : error C2660: 'AddVfrDataStructField' : function does not take 2 parameters - - BUGBUG -- these three utility functions are almost identical, and - should be modified to share code. - - Visual Studio does not find error messages with: - - " error :" - " error 1:" - " error c1:" - " error 1000:" - " error c100:" - - It does find: - " error c1000:" ---*/ -{ - va_list List; - mErrorCount++; - va_start (List, MsgFmt); - PrintMessage ("error", FileName, LineNumber, MessageCode, Text, MsgFmt, List); - va_end (List); - // - // Set status accordingly - // - if (mStatus < STATUS_ERROR) { - mStatus = STATUS_ERROR; - } -} - -void -ParserError ( - UINT32 MessageCode, - INT8 *Text, - INT8 *MsgFmt, - ... - ) -/*++ - -Routine Description: - Print a parser error, using the source file name and line number - set by a previous call to SetParserPosition(). - -Arguments: - MessageCode - application-specific error code - Text - text to print in the error message - MsgFmt - format string to print at the end of the error message - ... - -Returns: - NA - ---*/ -{ - va_list List; - mErrorCount++; - va_start (List, MsgFmt); - PrintMessage ("error", mSourceFileName, mSourceFileLineNum, MessageCode, Text, MsgFmt, List); - va_end (List); - // - // Set status accordingly - // - if (mStatus < STATUS_ERROR) { - mStatus = STATUS_ERROR; - } -} - -void -ParserWarning ( - UINT32 ErrorCode, - INT8 *OffendingText, - INT8 *MsgFmt, - ... - ) -/*++ - -Routine Description: - Print a parser warning, using the source file name and line number - set by a previous call to SetParserPosition(). - -Arguments: - ErrorCode - application-specific error code - OffendingText - text to print in the warning message - MsgFmt - format string to print at the end of the warning message - ... - -Returns: - NA - ---*/ -{ - va_list List; - mWarningCount++; - va_start (List, MsgFmt); - PrintMessage ("warning", mSourceFileName, mSourceFileLineNum, ErrorCode, OffendingText, MsgFmt, List); - va_end (List); - // - // Set status accordingly - // - if (mStatus < STATUS_WARNING) { - mStatus = STATUS_WARNING; - } -} - -void -Warning ( - INT8 *FileName, - UINT32 LineNumber, - UINT32 MessageCode, - INT8 *Text, - INT8 *MsgFmt, - ... - ) -/*++ - -Routine Description: - Print a warning message. - -Arguments: - FileName - name of the file where the warning was detected, or the name - of the application that detected the warning - - LineNumber - the line number where the warning was detected (parsers). - 0 should be specified if the utility is not a parser. - - MessageCode - an application-specific warning code that can be referenced in - other documentation. - - Text - the text in question (parsers) - - MsgFmt - the format string for the warning message. Can contain formatting - controls for use with varargs. - - ... - -Returns: - None. - ---*/ -{ - va_list List; - mWarningCount++; - va_start (List, MsgFmt); - PrintMessage ("warning", FileName, LineNumber, MessageCode, Text, MsgFmt, List); - va_end (List); - // - // Set status accordingly - // - if (mStatus < STATUS_WARNING) { - mStatus = STATUS_WARNING; - } -} - -void -DebugMsg ( - INT8 *FileName, - UINT32 LineNumber, - UINT32 MsgMask, - INT8 *Text, - INT8 *MsgFmt, - ... - ) -/*++ - -Routine Description: - Print a warning message. - -Arguments: - FileName - typically the name of the utility printing the debug message, but - can be the name of a file being parsed. - - LineNumber - the line number in FileName (parsers) - - MsgMask - an application-specific bitmask that, in combination with mDebugMsgMask, - determines if the debug message gets printed. - - Text - the text in question (parsers) - - MsgFmt - the format string for the debug message. Can contain formatting - controls for use with varargs. - - ... -Returns: - None. - ---*/ -{ - va_list List; - // - // If the debug mask is not applicable, then do nothing. - // - if ((MsgMask != 0) && ((mDebugMsgMask & MsgMask) == 0)) { - return ; - } - - va_start (List, MsgFmt); - PrintMessage ("debug", FileName, LineNumber, 0, Text, MsgFmt, List); - va_end (List); -} - -static -void -PrintMessage ( - INT8 *Type, - INT8 *FileName, - UINT32 LineNumber, - UINT32 MessageCode, - INT8 *Text, - INT8 *MsgFmt, - va_list List - ) -/*++ - -Routine Description: - Worker routine for all the utility printing services. Prints the message in - a format that Visual Studio will find when scanning build outputs for - errors or warnings. - -Arguments: - Type - "warning" or "error" string to insert into the message to be - printed. The first character of this string (converted to uppercase) - is used to preceed the MessageCode value in the output string. - - FileName - name of the file where the warning was detected, or the name - of the application that detected the warning - - LineNumber - the line number where the warning was detected (parsers). - 0 should be specified if the utility is not a parser. - - MessageCode - an application-specific warning code that can be referenced in - other documentation. - - Text - part of the message to print - - MsgFmt - the format string for the message. Can contain formatting - controls for use with varargs. - - List - Variable function parameter list. -Returns: - None. - -Notes: - If FileName == NULL then this utility will use the string passed into SetUtilityName(). - - LineNumber is only used if the caller is a parser, in which case FileName refers to the - file being parsed. - - Text and MsgFmt are both optional, though it would be of little use calling this function with - them both NULL. - - Output will typically be of the form: - () : : : - - Parser (LineNumber != 0) - VfrCompile.cpp(330) : error E2660: AddVfrDataStructField : function does not take 2 parameters - Generic utility (LineNumber == 0) - UtilityName : error E1234 : Text string : MsgFmt string and args - ---*/ -{ - INT8 Line[MAX_LINE_LEN]; - INT8 Line2[MAX_LINE_LEN]; - INT8 *Cptr; - // - // If given a filename, then add it (and the line number) to the string. - // If there's no filename, then use the program name if provided. - // - if (FileName != NULL) { - Cptr = FileName; - } else if (mUtilityName[0] != 0) { - Cptr = mUtilityName; - } else { - Cptr = "Unknown utility"; - } - - strcpy (Line, Cptr); - if (LineNumber != 0) { - sprintf (Line2, "(%d)", LineNumber); - strcat (Line, Line2); - } - // - // Have to print an error code or Visual Studio won't find the - // message for you. It has to be decimal digits too. - // - sprintf (Line2, " : %s %c%04d", Type, toupper (Type[0]), MessageCode); - strcat (Line, Line2); - fprintf (stdout, "%s", Line); - // - // If offending text was provided, then print it - // - if (Text != NULL) { - fprintf (stdout, ": %s ", Text); - } - // - // Print formatted message if provided - // - if (MsgFmt != NULL) { - vsprintf (Line2, MsgFmt, List); - fprintf (stdout, ": %s", Line2); - } - - fprintf (stdout, "\n"); -} - -void -ParserSetPosition ( - INT8 *SourceFileName, - UINT32 LineNum - ) -/*++ - -Routine Description: - Set the position in a file being parsed. This can be used to - print error messages deeper down in a parser. - -Arguments: - SourceFileName - name of the source file being parsed - LineNum - line number of the source file being parsed - -Returns: - NA - ---*/ -{ - mSourceFileName = SourceFileName; - mSourceFileLineNum = LineNum; -} - -void -SetUtilityName ( - INT8 *UtilityName - ) -/*++ - -Routine Description: - All printed error/warning/debug messages follow the same format, and - typically will print a filename or utility name followed by the error - text. However if a filename is not passed to the print routines, then - they'll print the utility name if you call this function early in your - app to set the utility name. - -Arguments: - UtilityName - name of the utility, which will be printed with all - error/warning/debug messags. - -Returns: - NA - ---*/ -{ - // - // Save the name of the utility in our local variable. Make sure its - // length does not exceed our buffer. - // - if (UtilityName != NULL) { - if (strlen (UtilityName) >= sizeof (mUtilityName)) { - Error (UtilityName, 0, 0, "application error", "utility name length exceeds internal buffer size"); - strncpy (mUtilityName, UtilityName, sizeof (mUtilityName) - 1); - mUtilityName[sizeof (mUtilityName) - 1] = 0; - return ; - } else { - strcpy (mUtilityName, UtilityName); - } - } else { - Error (NULL, 0, 0, "application error", "SetUtilityName() called with NULL utility name"); - } -} - -STATUS -GetUtilityStatus ( - VOID - ) -/*++ - -Routine Description: - When you call Error() or Warning(), this module keeps track of it and - sets a local mStatus to STATUS_ERROR or STATUS_WARNING. When the utility - exits, it can call this function to get the status and use it as a return - value. - -Arguments: - None. - -Returns: - Worst-case status reported, as defined by which print function was called. - ---*/ -{ - return mStatus; -} diff --git a/Tools/CodeTools/TianoTools/GuidChk/UtilsMsgs.h b/Tools/CodeTools/TianoTools/GuidChk/UtilsMsgs.h deleted file mode 100644 index 5f6c7010b4..0000000000 --- a/Tools/CodeTools/TianoTools/GuidChk/UtilsMsgs.h +++ /dev/null @@ -1,106 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - UtilsMsgs.h - -Abstract: - - Prototypes for the EFI tools utility functions. - ---*/ - -#ifndef _UTILS_MESSAGES_H_ -#define _UTILS_MESSAGES_H_ - -STATUS -GetUtilityStatus ( - VOID - ) -; - -// -// If someone prints an error message and didn't specify a source file name, -// then we print the utility name instead. However they must tell us the -// utility name early on via this function. -// -VOID -SetUtilityName ( - INT8 *ProgramName - ) -; - -void -Error ( - INT8 *FileName, - UINT32 LineNumber, - UINT32 ErrorCode, - INT8 *OffendingText, - INT8 *MsgFmt, - ... - ) -; - -void -Warning ( - INT8 *FileName, - UINT32 LineNumber, - UINT32 ErrorCode, - INT8 *OffendingText, - INT8 *MsgFmt, - ... - ) -; - -void -DebugMsg ( - INT8 *FileName, - UINT32 LineNumber, - UINT32 MsgLevel, - INT8 *OffendingText, - INT8 *MsgFmt, - ... - ) -; - -void -SetDebugMsgMask ( - UINT32 MsgMask - ) -; - -void -ParserSetPosition ( - INT8 *SourceFileName, - UINT32 LineNum - ) -; - -void -ParserError ( - UINT32 ErrorCode, - INT8 *OffendingText, - INT8 *MsgFmt, - ... - ) -; - -void -ParserWarning ( - UINT32 ErrorCode, - INT8 *OffendingText, - INT8 *MsgFmt, - ... - ) -; - -#endif diff --git a/Tools/CodeTools/TianoTools/GuidChk/build.xml b/Tools/CodeTools/TianoTools/GuidChk/build.xml deleted file mode 100644 index aec3ad1e9c..0000000000 --- a/Tools/CodeTools/TianoTools/GuidChk/build.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/Include/Common/BaseTypes.h b/Tools/CodeTools/TianoTools/Include/Common/BaseTypes.h deleted file mode 100644 index b87e7141e6..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Common/BaseTypes.h +++ /dev/null @@ -1,212 +0,0 @@ -/** @file - Processor or Compiler specific defines for all supported processors. - - This file is stand alone self consistent set of definitions. - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: BaseTypes.h - -**/ - -#ifndef __BASE_TYPES_H__ -#define __BASE_TYPES_H__ - -// -// Include processor specific binding -// -#include -#include - -#define MEMORY_FENCE() MemoryFence () -#define BREAKPOINT() CpuBreakpoint () -#define DEADLOOP() CpuDeadLoop () - -typedef struct { - UINT32 Data1; - UINT16 Data2; - UINT16 Data3; - UINT8 Data4[8]; -} GUID; - - -// -// Modifiers to absract standard types to aid in debug of problems -// -#define CONST const -#define STATIC static -#define VOID void - -// -// Modifiers for Data Types used to self document code. -// This concept is borrowed for UEFI specification. -// -#ifndef IN -// -// Some other envirnments use this construct, so #ifndef to prevent -// mulitple definition. -// -#define IN -#define OUT -#define OPTIONAL -#endif - -// -// Constants. They may exist in other build structures, so #ifndef them. -// -#ifndef TRUE -// -// BugBug: UEFI specification claims 1 and 0. We are concerned about the -// complier portability so we did it this way. -// -#define TRUE ((BOOLEAN)(1==1)) -#endif - -#ifndef FALSE -#define FALSE ((BOOLEAN)(0==1)) -#endif - -#ifndef NULL -#define NULL ((VOID *) 0) -#endif - -// -// Support for variable length argument lists using the ANSI standard. -// -// Since we are using the ANSI standard we used the standard nameing and -// did not folow the coding convention -// -// VA_LIST - typedef for argument list. -// VA_START (VA_LIST Marker, argument before the ...) - Init Marker for use. -// VA_END (VA_LIST Marker) - Clear Marker -// VA_ARG (VA_LIST Marker, var arg size) - Use Marker to get an argumnet from -// the ... list. You must know the size and pass it in this macro. -// -// example: -// -// UINTN -// ExampleVarArg ( -// IN UINTN NumberOfArgs, -// ... -// ) -// { -// VA_LIST Marker; -// UINTN Index; -// UINTN Result; -// -// // -// // Initialize the Marker -// // -// VA_START (Marker, NumberOfArgs); -// for (Index = 0, Result = 0; Index < NumberOfArgs; Index++) { -// // -// // The ... list is a series of UINTN values, so average them up. -// // -// Result += VA_ARG (Marker, UINTN); -// } -// -// VA_END (Marker); -// return Result -// } -// - -#define _INT_SIZE_OF(n) ((sizeof (n) + sizeof (UINTN) - 1) &~(sizeof (UINTN) - 1)) - -// -// Also support coding convention rules for var arg macros -// -#ifndef VA_START - -// typedef CHAR8 *VA_LIST; -// #define VA_START(ap, v) (ap = (VA_LIST) & (v) + _INT_SIZE_OF (v)) -// #define VA_ARG(ap, t) (*(t *) ((ap += _INT_SIZE_OF (t)) - _INT_SIZE_OF (t))) -// #define VA_END(ap) (ap = (VA_LIST) 0) -// Use the native arguments for tools. -#define VA_START va_start -#define VA_ARG va_arg -#define VA_END va_end -#define VA_LIST va_list - -#endif - -/// -/// CONTAINING_RECORD - returns a pointer to the structure -/// from one of it's elements. -/// -#define _CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field))) - -/// -/// ALIGN_POINTER - aligns a pointer to the lowest boundry -/// -#define ALIGN_POINTER(p, s) ((VOID *) ((p) + (((s) - ((UINTN) (p))) & ((s) - 1)))) - -/// -/// ALIGN_VARIABLE - aligns a variable up to the next natural boundry for int size of a processor -/// -#define ALIGN_VARIABLE(Value, Adjustment) \ - Adjustment = 0U; \ - if ((UINTN) (Value) % sizeof (UINTN)) { \ - (Adjustment) = (UINTN)(sizeof (UINTN) - ((UINTN) (Value) % sizeof (UINTN))); \ - } \ - (Value) = (UINTN)((UINTN) (Value) + (UINTN) (Adjustment)) - -// -// EFI Error Codes common to all execution phases -// - -typedef INTN RETURN_STATUS; - -/// -/// Set the upper bit to indicate EFI Error. -/// -#define ENCODE_ERROR(a) (MAX_BIT | (a)) - -#define ENCODE_WARNING(a) (a) -#define RETURN_ERROR(a) ((a) < 0) - -#define RETURN_SUCCESS 0 -#define RETURN_LOAD_ERROR ENCODE_ERROR (1) -#define RETURN_INVALID_PARAMETER ENCODE_ERROR (2) -#define RETURN_UNSUPPORTED ENCODE_ERROR (3) -#define RETURN_BAD_BUFFER_SIZE ENCODE_ERROR (4) -#define RETURN_BUFFER_TOO_SMALL ENCODE_ERROR (5) -#define RETURN_NOT_READY ENCODE_ERROR (6) -#define RETURN_DEVICE_ERROR ENCODE_ERROR (7) -#define RETURN_WRITE_PROTECTED ENCODE_ERROR (8) -#define RETURN_OUT_OF_RESOURCES ENCODE_ERROR (9) -#define RETURN_VOLUME_CORRUPTED ENCODE_ERROR (10) -#define RETURN_VOLUME_FULL ENCODE_ERROR (11) -#define RETURN_NO_MEDIA ENCODE_ERROR (12) -#define RETURN_MEDIA_CHANGED ENCODE_ERROR (13) -#define RETURN_NOT_FOUND ENCODE_ERROR (14) -#define RETURN_ACCESS_DENIED ENCODE_ERROR (15) -#define RETURN_NO_RESPONSE ENCODE_ERROR (16) -#define RETURN_NO_MAPPING ENCODE_ERROR (17) -#define RETURN_TIMEOUT ENCODE_ERROR (18) -#define RETURN_NOT_STARTED ENCODE_ERROR (19) -#define RETURN_ALREADY_STARTED ENCODE_ERROR (20) -#define RETURN_ABORTED ENCODE_ERROR (21) -#define RETURN_ICMP_ERROR ENCODE_ERROR (22) -#define RETURN_TFTP_ERROR ENCODE_ERROR (23) -#define RETURN_PROTOCOL_ERROR ENCODE_ERROR (24) -#define RETURN_INCOMPATIBLE_VERSION ENCODE_ERROR (25) -#define RETURN_SECURITY_VIOLATION ENCODE_ERROR (26) -#define RETURN_CRC_ERROR ENCODE_ERROR (27) -#define RETURN_END_OF_MEDIA ENCODE_ERROR (28) -#define RETURN_END_OF_FILE ENCODE_ERROR (31) - -#define RETURN_WARN_UNKNOWN_GLYPH ENCODE_WARNING (1) -#define RETURN_WARN_DELETE_FAILURE ENCODE_WARNING (2) -#define RETURN_WARN_WRITE_FAILURE ENCODE_WARNING (3) -#define RETURN_WARN_BUFFER_TOO_SMALL ENCODE_WARNING (4) - -typedef UINT64 PHYSICAL_ADDRESS; - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/Common/Capsule.h b/Tools/CodeTools/TianoTools/Include/Common/Capsule.h deleted file mode 100644 index 0434fdf7f2..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Common/Capsule.h +++ /dev/null @@ -1,67 +0,0 @@ -/** @file - Defines for the EFI Capsule functionality. - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: Capsule.h - - @par Revision Reference: - These definitions are from Capsule Spec Version 0.9. - -**/ - -#ifndef _EFI_CAPSULE_H_ -#define _EFI_CAPSULE_H_ - -// -// Bits in the flags field of the capsule header -// -#define EFI_CAPSULE_HEADER_FLAG_SETUP 0x00000001 // supports setup changes - - -#define CAPSULE_BLOCK_DESCRIPTOR_SIGNATURE EFI_SIGNATURE_32 ('C', 'B', 'D', 'S') - -// -// An array of these describe the blocks that make up a capsule for -// a capsule update. -// -typedef struct { - UINT64 Length; // length of the data block - EFI_PHYSICAL_ADDRESS Data; // physical address of the data block - UINT32 Signature; // CBDS - UINT32 CheckSum; // to sum this structure to 0 -} EFI_CAPSULE_BLOCK_DESCRIPTOR; - -typedef struct { - EFI_GUID OemGuid; - UINT32 HeaderSize; - // - // UINT8 OemHdrData[]; - // -} EFI_CAPSULE_OEM_HEADER; - -typedef struct { - EFI_GUID CapsuleGuid; - UINT32 HeaderSize; - UINT32 Flags; - UINT32 CapsuleImageSize; - UINT32 SequenceNumber; - EFI_GUID InstanceId; - UINT32 OffsetToSplitInformation; - UINT32 OffsetToCapsuleBody; - UINT32 OffsetToOemDefinedHeader; - UINT32 OffsetToAuthorInformation; - UINT32 OffsetToRevisionInformation; - UINT32 OffsetToShortDescription; - UINT32 OffsetToLongDescription; - UINT32 OffsetToApplicableDevices; -} EFI_CAPSULE_HEADER; - -#endif // #ifndef _EFI_CAPSULE_H_ diff --git a/Tools/CodeTools/TianoTools/Include/Common/Dependency.h b/Tools/CodeTools/TianoTools/Include/Common/Dependency.h deleted file mode 100644 index 744027d2f3..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Common/Dependency.h +++ /dev/null @@ -1,50 +0,0 @@ -/** @file - This module contains data specific to dependency expressions - and local function prototypes. - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: Dependency.h - -**/ - -#ifndef __DEPENDENCY_H__ -#define __DEPENDENCY_H__ - -/// EFI_DEP_BEFORE - If present, this must be the first and only opcode -#define EFI_DEP_BEFORE 0x00 - -/// EFI_DEP_AFTER - If present, this must be the first and only opcode -#define EFI_DEP_AFTER 0x01 - -#define EFI_DEP_PUSH 0x02 -#define EFI_DEP_AND 0x03 -#define EFI_DEP_OR 0x04 -#define EFI_DEP_NOT 0x05 -#define EFI_DEP_TRUE 0x06 -#define EFI_DEP_FALSE 0x07 -#define EFI_DEP_END 0x08 - -/// EFI_DEP_SOR - If present, this must be the first opcode -#define EFI_DEP_SOR 0x09 - -/// -/// EFI_DEP_REPLACE_TRUE - Used to dynamically patch the dependecy expression -/// to save time. A EFI_DEP_PUSH is evauated one an -/// replaced with EFI_DEP_REPLACE_TRUE -/// -#define EFI_DEP_REPLACE_TRUE 0xff - -/// -/// Define the initial size of the dependency expression evaluation stack -/// -#define DEPEX_STACK_SIZE_INCREMENT 0x1000 - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/Common/EfiImage.h b/Tools/CodeTools/TianoTools/Include/Common/EfiImage.h deleted file mode 100644 index 2f5c580e98..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Common/EfiImage.h +++ /dev/null @@ -1,716 +0,0 @@ -/** @file - EFI image format for PE32+. Please note some data structures are different - for IA-32 and Itanium-based images, look for UINTN and the #ifdef EFI_IA64 - - @bug Fix text - doc as defined in MSFT EFI specification. - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: EfiImage.h - -**/ - -#ifndef __EFI_IMAGE_H__ -#define __EFI_IMAGE_H__ - -// -// PE32+ Subsystem type for EFI images -// -#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION 10 -#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 -#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 -#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13 - -// -// BugBug: Need to get a real answer for this problem. This is not in the -// PE specification. -// -// A SAL runtime driver does not get fixed up when a transition to -// virtual mode is made. In all other cases it should be treated -// like a EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER image -// -#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13 - -// -// PE32+ Machine type for EFI images -// -#define IMAGE_FILE_MACHINE_I386 0x014c -#define IMAGE_FILE_MACHINE_IA64 0x0200 -#define IMAGE_FILE_MACHINE_EBC 0x0EBC -#define IMAGE_FILE_MACHINE_X64 0x8664 -// -// Support old names for backward compatible -// -#define EFI_IMAGE_MACHINE_IA32 IMAGE_FILE_MACHINE_I386 -#define EFI_IMAGE_MACHINE_IA64 IMAGE_FILE_MACHINE_IA64 -#define EFI_IMAGE_MACHINE_IPF IMAGE_FILE_MACHINE_IA64 -#define EFI_IMAGE_MACHINE_EBC IMAGE_FILE_MACHINE_EBC -#define EFI_IMAGE_MACHINE_X64 IMAGE_FILE_MACHINE_X64 - -#define EFI_IMAGE_DOS_SIGNATURE 0x5A4D // MZ -#define EFI_IMAGE_OS2_SIGNATURE 0x454E // NE -#define EFI_IMAGE_OS2_SIGNATURE_LE 0x454C // LE -#define EFI_IMAGE_NT_SIGNATURE 0x00004550 // PE00 -#define EFI_IMAGE_EDOS_SIGNATURE 0x44454550 // PEED - -/// -/// PE images can start with an optional DOS header, so if an image is run -/// under DOS it can print an error message. -/// -typedef struct { - UINT16 e_magic; // Magic number - UINT16 e_cblp; // Bytes on last page of file - UINT16 e_cp; // Pages in file - UINT16 e_crlc; // Relocations - UINT16 e_cparhdr; // Size of header in paragraphs - UINT16 e_minalloc; // Minimum extra paragraphs needed - UINT16 e_maxalloc; // Maximum extra paragraphs needed - UINT16 e_ss; // Initial (relative) SS value - UINT16 e_sp; // Initial SP value - UINT16 e_csum; // Checksum - UINT16 e_ip; // Initial IP value - UINT16 e_cs; // Initial (relative) CS value - UINT16 e_lfarlc; // File address of relocation table - UINT16 e_ovno; // Overlay number - UINT16 e_res[4]; // Reserved words - UINT16 e_oemid; // OEM identifier (for e_oeminfo) - UINT16 e_oeminfo; // OEM information; e_oemid specific - UINT16 e_res2[10]; // Reserved words - UINT32 e_lfanew; // File address of new exe header -} EFI_IMAGE_DOS_HEADER; - -/// -/// File header format. -/// -typedef struct { - UINT16 Machine; - UINT16 NumberOfSections; - UINT32 TimeDateStamp; - UINT32 PointerToSymbolTable; - UINT32 NumberOfSymbols; - UINT16 SizeOfOptionalHeader; - UINT16 Characteristics; -} EFI_IMAGE_FILE_HEADER; - -#define EFI_IMAGE_SIZEOF_FILE_HEADER 20 - -#define EFI_IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file. -#define EFI_IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references). -#define EFI_IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file. -#define EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file. -#define EFI_IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed. -#define EFI_IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine. -#define EFI_IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file -#define EFI_IMAGE_FILE_SYSTEM 0x1000 // System File. -#define EFI_IMAGE_FILE_DLL 0x2000 // File is a DLL. -#define EFI_IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed. -#define EFI_IMAGE_FILE_MACHINE_UNKNOWN 0 -#define EFI_IMAGE_FILE_MACHINE_I386 0x14c // Intel 386. -#define EFI_IMAGE_FILE_MACHINE_R3000 0x162 // MIPS* little-endian, 0540 big-endian -#define EFI_IMAGE_FILE_MACHINE_R4000 0x166 // MIPS* little-endian -#define EFI_IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP* -#define EFI_IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM* PowerPC Little-Endian -#define EFI_IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine -// -// * Other names and brands may be claimed as the property of others. -// - -/// -/// Directory format. -/// -typedef struct { - UINT32 VirtualAddress; - UINT32 Size; -} EFI_IMAGE_DATA_DIRECTORY; - -#define EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16 - -typedef struct { - UINT16 Magic; - UINT8 MajorLinkerVersion; - UINT8 MinorLinkerVersion; - UINT32 SizeOfCode; - UINT32 SizeOfInitializedData; - UINT32 SizeOfUninitializedData; - UINT32 AddressOfEntryPoint; - UINT32 BaseOfCode; - UINT32 BaseOfData; - UINT32 BaseOfBss; - UINT32 GprMask; - UINT32 CprMask[4]; - UINT32 GpValue; -} EFI_IMAGE_ROM_OPTIONAL_HEADER; - -#define EFI_IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 -#define EFI_IMAGE_SIZEOF_ROM_OPTIONAL_HEADER sizeof (EFI_IMAGE_ROM_OPTIONAL_HEADER) - -typedef struct { - EFI_IMAGE_FILE_HEADER FileHeader; - EFI_IMAGE_ROM_OPTIONAL_HEADER OptionalHeader; -} EFI_IMAGE_ROM_HEADERS; - -/// -/// @attention -/// EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64 -/// are for use ONLY by tools. All proper EFI code MUST use -/// EFI_IMAGE_OPTIONAL_HEADER ONLY!!! -/// -#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b - -typedef struct { - // - // Standard fields. - // - UINT16 Magic; - UINT8 MajorLinkerVersion; - UINT8 MinorLinkerVersion; - UINT32 SizeOfCode; - UINT32 SizeOfInitializedData; - UINT32 SizeOfUninitializedData; - UINT32 AddressOfEntryPoint; - UINT32 BaseOfCode; - UINT32 BaseOfData; - // - // NT additional fields. - // - UINT32 ImageBase; - UINT32 SectionAlignment; - UINT32 FileAlignment; - UINT16 MajorOperatingSystemVersion; - UINT16 MinorOperatingSystemVersion; - UINT16 MajorImageVersion; - UINT16 MinorImageVersion; - UINT16 MajorSubsystemVersion; - UINT16 MinorSubsystemVersion; - UINT32 Win32VersionValue; - UINT32 SizeOfImage; - UINT32 SizeOfHeaders; - UINT32 CheckSum; - UINT16 Subsystem; - UINT16 DllCharacteristics; - UINT32 SizeOfStackReserve; - UINT32 SizeOfStackCommit; - UINT32 SizeOfHeapReserve; - UINT32 SizeOfHeapCommit; - UINT32 LoaderFlags; - UINT32 NumberOfRvaAndSizes; - EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES]; -} EFI_IMAGE_OPTIONAL_HEADER32; - -/// -/// @attention -/// EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64 -/// are for use ONLY by tools. All proper EFI code MUST use -/// EFI_IMAGE_OPTIONAL_HEADER ONLY!!! -/// -#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b - -typedef struct { - // - // Standard fields. - // - UINT16 Magic; - UINT8 MajorLinkerVersion; - UINT8 MinorLinkerVersion; - UINT32 SizeOfCode; - UINT32 SizeOfInitializedData; - UINT32 SizeOfUninitializedData; - UINT32 AddressOfEntryPoint; - UINT32 BaseOfCode; - // - // NT additional fields. - // - UINT64 ImageBase; - UINT32 SectionAlignment; - UINT32 FileAlignment; - UINT16 MajorOperatingSystemVersion; - UINT16 MinorOperatingSystemVersion; - UINT16 MajorImageVersion; - UINT16 MinorImageVersion; - UINT16 MajorSubsystemVersion; - UINT16 MinorSubsystemVersion; - UINT32 Win32VersionValue; - UINT32 SizeOfImage; - UINT32 SizeOfHeaders; - UINT32 CheckSum; - UINT16 Subsystem; - UINT16 DllCharacteristics; - UINT64 SizeOfStackReserve; - UINT64 SizeOfStackCommit; - UINT64 SizeOfHeapReserve; - UINT64 SizeOfHeapCommit; - UINT32 LoaderFlags; - UINT32 NumberOfRvaAndSizes; - EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES]; -} EFI_IMAGE_OPTIONAL_HEADER64; - -/// -/// @attention -/// EFI_IMAGE_NT_HEADERS32 and EFI_IMAGE_HEADERS64 are for use ONLY -/// by tools. All proper EFI code MUST use EFI_IMAGE_NT_HEADERS ONLY!!! -/// -typedef struct { - UINT32 Signature; - EFI_IMAGE_FILE_HEADER FileHeader; - EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader; -} EFI_IMAGE_NT_HEADERS32; - -#define EFI_IMAGE_SIZEOF_NT_OPTIONAL32_HEADER sizeof (EFI_IMAGE_NT_HEADERS32) - -typedef struct { - UINT32 Signature; - EFI_IMAGE_FILE_HEADER FileHeader; - EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader; -} EFI_IMAGE_NT_HEADERS64; - -#define EFI_IMAGE_SIZEOF_NT_OPTIONAL64_HEADER sizeof (EFI_IMAGE_NT_HEADERS64) - -// -// Processor specific definition of EFI_IMAGE_OPTIONAL_HEADER so the -// type name EFI_IMAGE_OPTIONAL_HEADER is appropriate to the build. Same for -// EFI_IMAGE_NT_HEADERS. These definitions MUST be used by ALL EFI code. -// -#if defined (MDE_CPU_IA32) - -typedef EFI_IMAGE_OPTIONAL_HEADER32 EFI_IMAGE_OPTIONAL_HEADER; -typedef EFI_IMAGE_NT_HEADERS32 EFI_IMAGE_NT_HEADERS; - -#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC -#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \ - (((Machine) == EFI_IMAGE_MACHINE_IA32) || ((Machine) == EFI_IMAGE_MACHINE_EBC)) - -#elif defined (MDE_CPU_IPF) - -typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER; -typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS; - -#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC -#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \ - (((Machine) == EFI_IMAGE_MACHINE_IPF) || ((Machine) == EFI_IMAGE_MACHINE_EBC)) - -#elif defined (MDE_CPU_X64) - -typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER; -typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS; - -#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC -#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \ - (((Machine) == EFI_IMAGE_MACHINE_X64) || ((Machine) == EFI_IMAGE_MACHINE_EBC)) - -#elif defined (MDE_CPU_EBC) - -// -// This is just to make sure you can cross compile with the EBC compiiler. -// It does not make sense to have a PE loader coded in EBC. You need to -// understand the basic -// -typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER; -typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS; - -#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC -#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_EBC) - -#else -#error Unknown Processor Type -#endif - - -#define EFI_IMAGE_FIRST_SECTION(ntheader) \ - ( \ - (EFI_IMAGE_SECTION_HEADER *) \ - ( \ - (UINT32) ntheader + \ - FIELD_OFFSET (EFI_IMAGE_NT_HEADERS, OptionalHeader) + \ - ((EFI_IMAGE_NT_HEADERS *) (ntheader))->FileHeader.SizeOfOptionalHeader \ - ) \ - ) - -// -// Subsystem Values -// -#define EFI_IMAGE_SUBSYSTEM_UNKNOWN 0 -#define EFI_IMAGE_SUBSYSTEM_NATIVE 1 -#define EFI_IMAGE_SUBSYSTEM_WINDOWS_GUI 2 -#define EFI_IMAGE_SUBSYSTEM_WINDOWS_CUI 3. -#define EFI_IMAGE_SUBSYSTEM_OS2_CUI 5 -#define EFI_IMAGE_SUBSYSTEM_POSIX_CUI 7 - -// -// Directory Entries -// -#define EFI_IMAGE_DIRECTORY_ENTRY_EXPORT 0 -#define EFI_IMAGE_DIRECTORY_ENTRY_IMPORT 1 -#define EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE 2 -#define EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 -#define EFI_IMAGE_DIRECTORY_ENTRY_SECURITY 4 -#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC 5 -#define EFI_IMAGE_DIRECTORY_ENTRY_DEBUG 6 -#define EFI_IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 -#define EFI_IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 -#define EFI_IMAGE_DIRECTORY_ENTRY_TLS 9 -#define EFI_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 - -// -// Section header format. -// -#define EFI_IMAGE_SIZEOF_SHORT_NAME 8 - -typedef struct { - UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME]; - union { - UINT32 PhysicalAddress; - UINT32 VirtualSize; - } Misc; - UINT32 VirtualAddress; - UINT32 SizeOfRawData; - UINT32 PointerToRawData; - UINT32 PointerToRelocations; - UINT32 PointerToLinenumbers; - UINT16 NumberOfRelocations; - UINT16 NumberOfLinenumbers; - UINT32 Characteristics; -} EFI_IMAGE_SECTION_HEADER; - -#define EFI_IMAGE_SIZEOF_SECTION_HEADER 40 - -#define EFI_IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved. -#define EFI_IMAGE_SCN_CNT_CODE 0x00000020 -#define EFI_IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 -#define EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 - -#define EFI_IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved. -#define EFI_IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information. -#define EFI_IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image. -#define EFI_IMAGE_SCN_LNK_COMDAT 0x00001000 - -#define EFI_IMAGE_SCN_ALIGN_1BYTES 0x00100000 -#define EFI_IMAGE_SCN_ALIGN_2BYTES 0x00200000 -#define EFI_IMAGE_SCN_ALIGN_4BYTES 0x00300000 -#define EFI_IMAGE_SCN_ALIGN_8BYTES 0x00400000 -#define EFI_IMAGE_SCN_ALIGN_16BYTES 0x00500000 -#define EFI_IMAGE_SCN_ALIGN_32BYTES 0x00600000 -#define EFI_IMAGE_SCN_ALIGN_64BYTES 0x00700000 - -#define EFI_IMAGE_SCN_MEM_DISCARDABLE 0x02000000 -#define EFI_IMAGE_SCN_MEM_NOT_CACHED 0x04000000 -#define EFI_IMAGE_SCN_MEM_NOT_PAGED 0x08000000 -#define EFI_IMAGE_SCN_MEM_SHARED 0x10000000 -#define EFI_IMAGE_SCN_MEM_EXECUTE 0x20000000 -#define EFI_IMAGE_SCN_MEM_READ 0x40000000 -#define EFI_IMAGE_SCN_MEM_WRITE 0x80000000 - -/// -/// Symbol format. -/// -#define EFI_IMAGE_SIZEOF_SYMBOL 18 - -// -// Section values. -// -// Symbols have a section number of the section in which they are -// defined. Otherwise, section numbers have the following meanings: -// -#define EFI_IMAGE_SYM_UNDEFINED (UINT16) 0 // Symbol is undefined or is common. -#define EFI_IMAGE_SYM_ABSOLUTE (UINT16) -1 // Symbol is an absolute value. -#define EFI_IMAGE_SYM_DEBUG (UINT16) -2 // Symbol is a special debug item. -// -// Type (fundamental) values. -// -#define EFI_IMAGE_SYM_TYPE_NULL 0 // no type. -#define EFI_IMAGE_SYM_TYPE_VOID 1 // -#define EFI_IMAGE_SYM_TYPE_CHAR 2 // type character. -#define EFI_IMAGE_SYM_TYPE_SHORT 3 // type short integer. -#define EFI_IMAGE_SYM_TYPE_INT 4 -#define EFI_IMAGE_SYM_TYPE_LONG 5 -#define EFI_IMAGE_SYM_TYPE_FLOAT 6 -#define EFI_IMAGE_SYM_TYPE_DOUBLE 7 -#define EFI_IMAGE_SYM_TYPE_STRUCT 8 -#define EFI_IMAGE_SYM_TYPE_UNION 9 -#define EFI_IMAGE_SYM_TYPE_ENUM 10 // enumeration. -#define EFI_IMAGE_SYM_TYPE_MOE 11 // member of enumeration. -#define EFI_IMAGE_SYM_TYPE_BYTE 12 -#define EFI_IMAGE_SYM_TYPE_WORD 13 -#define EFI_IMAGE_SYM_TYPE_UINT 14 -#define EFI_IMAGE_SYM_TYPE_DWORD 15 - -// -// Type (derived) values. -// -#define EFI_IMAGE_SYM_DTYPE_NULL 0 // no derived type. -#define EFI_IMAGE_SYM_DTYPE_POINTER 1 -#define EFI_IMAGE_SYM_DTYPE_FUNCTION 2 -#define EFI_IMAGE_SYM_DTYPE_ARRAY 3 - -// -// Storage classes. -// -#define EFI_IMAGE_SYM_CLASS_END_OF_FUNCTION (UINT8) -1 -#define EFI_IMAGE_SYM_CLASS_NULL 0 -#define EFI_IMAGE_SYM_CLASS_AUTOMATIC 1 -#define EFI_IMAGE_SYM_CLASS_EXTERNAL 2 -#define EFI_IMAGE_SYM_CLASS_STATIC 3 -#define EFI_IMAGE_SYM_CLASS_REGISTER 4 -#define EFI_IMAGE_SYM_CLASS_EXTERNAL_DEF 5 -#define EFI_IMAGE_SYM_CLASS_LABEL 6 -#define EFI_IMAGE_SYM_CLASS_UNDEFINED_LABEL 7 -#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8 -#define EFI_IMAGE_SYM_CLASS_ARGUMENT 9 -#define EFI_IMAGE_SYM_CLASS_STRUCT_TAG 10 -#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_UNION 11 -#define EFI_IMAGE_SYM_CLASS_UNION_TAG 12 -#define EFI_IMAGE_SYM_CLASS_TYPE_DEFINITION 13 -#define EFI_IMAGE_SYM_CLASS_UNDEFINED_STATIC 14 -#define EFI_IMAGE_SYM_CLASS_ENUM_TAG 15 -#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16 -#define EFI_IMAGE_SYM_CLASS_REGISTER_PARAM 17 -#define EFI_IMAGE_SYM_CLASS_BIT_FIELD 18 -#define EFI_IMAGE_SYM_CLASS_BLOCK 100 -#define EFI_IMAGE_SYM_CLASS_FUNCTION 101 -#define EFI_IMAGE_SYM_CLASS_END_OF_STRUCT 102 -#define EFI_IMAGE_SYM_CLASS_FILE 103 -#define EFI_IMAGE_SYM_CLASS_SECTION 104 -#define EFI_IMAGE_SYM_CLASS_WEAK_EXTERNAL 105 - -// -// type packing constants -// -#define EFI_IMAGE_N_BTMASK 017 -#define EFI_IMAGE_N_TMASK 060 -#define EFI_IMAGE_N_TMASK1 0300 -#define EFI_IMAGE_N_TMASK2 0360 -#define EFI_IMAGE_N_BTSHFT 4 -#define EFI_IMAGE_N_TSHIFT 2 - -// -// Communal selection types. -// -#define EFI_IMAGE_COMDAT_SELECT_NODUPLICATES 1 -#define EFI_IMAGE_COMDAT_SELECT_ANY 2 -#define EFI_IMAGE_COMDAT_SELECT_SAME_SIZE 3 -#define EFI_IMAGE_COMDAT_SELECT_EXACT_MATCH 4 -#define EFI_IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 - -#define EFI_IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 -#define EFI_IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 -#define EFI_IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 - -/// -/// Relocation format. -/// -typedef struct { - UINT32 VirtualAddress; - UINT32 SymbolTableIndex; - UINT16 Type; -} EFI_IMAGE_RELOCATION; - -#define EFI_IMAGE_SIZEOF_RELOCATION 10 - -// -// I386 relocation types. -// -#define EFI_IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary -#define EFI_IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address -#define EFI_IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address -#define EFI_IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address -#define EFI_IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included -#define EFI_IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address -#define EFI_IMAGE_REL_I386_SECTION 012 -#define EFI_IMAGE_REL_I386_SECREL 013 -#define EFI_IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address - -/// -/// Based relocation format. -/// -typedef struct { - UINT32 VirtualAddress; - UINT32 SizeOfBlock; -} EFI_IMAGE_BASE_RELOCATION; - -#define EFI_IMAGE_SIZEOF_BASE_RELOCATION 8 - -// -// Based relocation types. -// -#define EFI_IMAGE_REL_BASED_ABSOLUTE 0 -#define EFI_IMAGE_REL_BASED_HIGH 1 -#define EFI_IMAGE_REL_BASED_LOW 2 -#define EFI_IMAGE_REL_BASED_HIGHLOW 3 -#define EFI_IMAGE_REL_BASED_HIGHADJ 4 -#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5 -#define EFI_IMAGE_REL_BASED_IA64_IMM64 9 -#define EFI_IMAGE_REL_BASED_DIR64 10 - -/// -/// Line number format. -/// -typedef struct { - union { - UINT32 SymbolTableIndex; // Symbol table index of function name if Linenumber is 0. - UINT32 VirtualAddress; // Virtual address of line number. - } Type; - UINT16 Linenumber; // Line number. -} EFI_IMAGE_LINENUMBER; - -#define EFI_IMAGE_SIZEOF_LINENUMBER 6 - -// -// Archive format. -// -#define EFI_IMAGE_ARCHIVE_START_SIZE 8 -#define EFI_IMAGE_ARCHIVE_START "!\n" -#define EFI_IMAGE_ARCHIVE_END "`\n" -#define EFI_IMAGE_ARCHIVE_PAD "\n" -#define EFI_IMAGE_ARCHIVE_LINKER_MEMBER "/ " -#define EFI_IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " - -typedef struct { - UINT8 Name[16]; // File member name - `/' terminated. - UINT8 Date[12]; // File member date - decimal. - UINT8 UserID[6]; // File member user id - decimal. - UINT8 GroupID[6]; // File member group id - decimal. - UINT8 Mode[8]; // File member mode - octal. - UINT8 Size[10]; // File member size - decimal. - UINT8 EndHeader[2]; // String to end header. -} EFI_IMAGE_ARCHIVE_MEMBER_HEADER; - -#define EFI_IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 - -// -// DLL support. -// - -/// -/// DLL Export Format -/// -typedef struct { - UINT32 Characteristics; - UINT32 TimeDateStamp; - UINT16 MajorVersion; - UINT16 MinorVersion; - UINT32 Name; - UINT32 Base; - UINT32 NumberOfFunctions; - UINT32 NumberOfNames; - UINT32 AddressOfFunctions; - UINT32 AddressOfNames; - UINT32 AddressOfNameOrdinals; -} EFI_IMAGE_EXPORT_DIRECTORY; - -/// -/// DLL support. -/// Import Format -/// -typedef struct { - UINT16 Hint; - UINT8 Name[1]; -} EFI_IMAGE_IMPORT_BY_NAME; - -typedef struct { - union { - UINT32 Function; - UINT32 Ordinal; - EFI_IMAGE_IMPORT_BY_NAME *AddressOfData; - } u1; -} EFI_IMAGE_THUNK_DATA; - -#define EFI_IMAGE_ORDINAL_FLAG 0x80000000 -#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0) -#define EFI_IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) - -typedef struct { - UINT32 Characteristics; - UINT32 TimeDateStamp; - UINT32 ForwarderChain; - UINT32 Name; - EFI_IMAGE_THUNK_DATA *FirstThunk; -} EFI_IMAGE_IMPORT_DESCRIPTOR; - -/// -/// Debug Format -/// -#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2 - -typedef struct { - UINT32 Characteristics; - UINT32 TimeDateStamp; - UINT16 MajorVersion; - UINT16 MinorVersion; - UINT32 Type; - UINT32 SizeOfData; - UINT32 RVA; - UINT32 FileOffset; -} EFI_IMAGE_DEBUG_DIRECTORY_ENTRY; - -#define CODEVIEW_SIGNATURE_NB10 0x3031424E // "NB10" -typedef struct { - UINT32 Signature; // "NB10" - UINT32 Unknown; - UINT32 Unknown2; - UINT32 Unknown3; - // - // Filename of .PDB goes here - // -} EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY; - -#define CODEVIEW_SIGNATURE_RSDS 0x53445352 // "RSDS" -typedef struct { - UINT32 Signature; // "RSDS" - UINT32 Unknown; - UINT32 Unknown2; - UINT32 Unknown3; - UINT32 Unknown4; - UINT32 Unknown5; - // - // Filename of .PDB goes here - // -} EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY; - -// -// .pdata entries for X64 -// -typedef struct { - UINT32 FunctionStartAddress; - UINT32 FunctionEndAddress; - UINT32 UnwindInfoAddress; -} RUNTIME_FUNCTION; - -typedef struct { - UINT8 Version:3; - UINT8 Flags:5; - UINT8 SizeOfProlog; - UINT8 CountOfUnwindCodes; - UINT8 FrameRegister:4; - UINT8 FrameRegisterOffset:4; -} UNWIND_INFO; - -/// -/// Header format for TE images -/// -typedef struct { - UINT16 Signature; // signature for TE format = "VZ" - UINT16 Machine; // from the original file header - UINT8 NumberOfSections; // from the original file header - UINT8 Subsystem; // from original optional header - UINT16 StrippedSize; // how many bytes we removed from the header - UINT32 AddressOfEntryPoint; // offset to entry point -- from original optional header - UINT32 BaseOfCode; // from original image -- required for ITP debug - UINT64 ImageBase; // from original file header - EFI_IMAGE_DATA_DIRECTORY DataDirectory[2]; // only base relocation and debug directory -} EFI_TE_IMAGE_HEADER; - -#define EFI_TE_IMAGE_HEADER_SIGNATURE 0x5A56 // "VZ" - -// -// Data directory indexes in our TE image header -// -#define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC 0 -#define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG 1 - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/Common/FirmwareFileSystem.h b/Tools/CodeTools/TianoTools/Include/Common/FirmwareFileSystem.h deleted file mode 100644 index 5678a95524..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Common/FirmwareFileSystem.h +++ /dev/null @@ -1,98 +0,0 @@ -/** @file - This file defines the data structures that comprise the FFS file system. - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: FirmwareFileSystem.h - - @par Revision Reference: - These definitions are from Firmware File System Spec 0.9. - -**/ - -#ifndef __EFI_FFS_FILE_SYSTEM_H__ -#define __EFI_FFS_FILE_SYSTEM_H__ - -/// -/// FFS specific file types -/// -#define EFI_FV_FILETYPE_FFS_PAD 0xF0 - -// -// FFS File Attributes -// -#define FFS_ATTRIB_TAIL_PRESENT 0x01 -#define FFS_ATTRIB_RECOVERY 0x02 -#define FFS_ATTRIB_HEADER_EXTENSION 0x04 -#define FFS_ATTRIB_DATA_ALIGNMENT 0x38 -#define FFS_ATTRIB_CHECKSUM 0x40 - -/// -/// FFS_FIXED_CHECKSUM is the default checksum value used when the -/// FFS_ATTRIB_CHECKSUM attribute bit is clear -/// note this is NOT an architecturally defined value, but is in this file for -/// implementation convenience -/// -#define FFS_FIXED_CHECKSUM 0x5A - -// -// File state definitions -// -#define EFI_FILE_HEADER_CONSTRUCTION 0x01 -#define EFI_FILE_HEADER_VALID 0x02 -#define EFI_FILE_DATA_VALID 0x04 -#define EFI_FILE_MARKED_FOR_UPDATE 0x08 -#define EFI_FILE_DELETED 0x10 -#define EFI_FILE_HEADER_INVALID 0x20 - -#define EFI_FILE_ALL_STATE_BITS (EFI_FILE_HEADER_CONSTRUCTION | \ - EFI_FILE_HEADER_VALID | \ - EFI_FILE_DATA_VALID | \ - EFI_FILE_MARKED_FOR_UPDATE | \ - EFI_FILE_DELETED | \ - EFI_FILE_HEADER_INVALID \ - ) - -#define EFI_TEST_FFS_ATTRIBUTES_BIT(FvbAttributes, TestAttributes, Bit) \ - ( \ - (BOOLEAN) ( \ - (FvbAttributes & EFI_FVB_ERASE_POLARITY) ? (((~TestAttributes) & Bit) == Bit) : ((TestAttributes & Bit) == Bit) \ - ) \ - ) - -typedef UINT16 EFI_FFS_FILE_TAIL; - -/// -/// FFS file integrity check structure -/// -typedef union { - struct { - UINT8 Header; - UINT8 File; - } Checksum; - UINT16 TailReference; -} EFI_FFS_INTEGRITY_CHECK; - -// -// FFS file header definition -// -typedef UINT8 EFI_FFS_FILE_ATTRIBUTES; -typedef UINT8 EFI_FFS_FILE_STATE; - -typedef struct { - EFI_GUID Name; - EFI_FFS_INTEGRITY_CHECK IntegrityCheck; - EFI_FV_FILETYPE Type; - EFI_FFS_FILE_ATTRIBUTES Attributes; - UINT8 Size[3]; - EFI_FFS_FILE_STATE State; -} EFI_FFS_FILE_HEADER; - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/Common/FirmwareVolumeHeader.h b/Tools/CodeTools/TianoTools/Include/Common/FirmwareVolumeHeader.h deleted file mode 100644 index 038dce6f7f..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Common/FirmwareVolumeHeader.h +++ /dev/null @@ -1,109 +0,0 @@ -/** @file - Defines data structure that is the volume header found at the beginning of - all firmware volumes that are either memory mapped, or have an - associated FirmwareVolumeBlock protocol. - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: FirmwareVolumeHeader.h - - @par Revision Reference: - These definitions are from Firmware Volume Block Spec 0.9. - -**/ - -#ifndef __EFI_FIRMWARE_VOLUME_HEADER_H__ -#define __EFI_FIRMWARE_VOLUME_HEADER_H__ - -// -// Firmware Volume Block Attributes definition -// -typedef UINT32 EFI_FVB_ATTRIBUTES; - -// -// Firmware Volume Block Attributes bit definitions -// -#define EFI_FVB_READ_DISABLED_CAP 0x00000001 -#define EFI_FVB_READ_ENABLED_CAP 0x00000002 -#define EFI_FVB_READ_STATUS 0x00000004 - -#define EFI_FVB_WRITE_DISABLED_CAP 0x00000008 -#define EFI_FVB_WRITE_ENABLED_CAP 0x00000010 -#define EFI_FVB_WRITE_STATUS 0x00000020 - -#define EFI_FVB_LOCK_CAP 0x00000040 -#define EFI_FVB_LOCK_STATUS 0x00000080 - -#define EFI_FVB_STICKY_WRITE 0x00000200 -#define EFI_FVB_MEMORY_MAPPED 0x00000400 -#define EFI_FVB_ERASE_POLARITY 0x00000800 - -#define EFI_FVB_ALIGNMENT_CAP 0x00008000 -#define EFI_FVB_ALIGNMENT_2 0x00010000 -#define EFI_FVB_ALIGNMENT_4 0x00020000 -#define EFI_FVB_ALIGNMENT_8 0x00040000 -#define EFI_FVB_ALIGNMENT_16 0x00080000 -#define EFI_FVB_ALIGNMENT_32 0x00100000 -#define EFI_FVB_ALIGNMENT_64 0x00200000 -#define EFI_FVB_ALIGNMENT_128 0x00400000 -#define EFI_FVB_ALIGNMENT_256 0x00800000 -#define EFI_FVB_ALIGNMENT_512 0x01000000 -#define EFI_FVB_ALIGNMENT_1K 0x02000000 -#define EFI_FVB_ALIGNMENT_2K 0x04000000 -#define EFI_FVB_ALIGNMENT_4K 0x08000000 -#define EFI_FVB_ALIGNMENT_8K 0x10000000 -#define EFI_FVB_ALIGNMENT_16K 0x20000000 -#define EFI_FVB_ALIGNMENT_32K 0x40000000 -#define EFI_FVB_ALIGNMENT_64K 0x80000000 - -#define EFI_FVB_CAPABILITIES (EFI_FVB_READ_DISABLED_CAP | \ - EFI_FVB_READ_ENABLED_CAP | \ - EFI_FVB_WRITE_DISABLED_CAP | \ - EFI_FVB_WRITE_ENABLED_CAP | \ - EFI_FVB_LOCK_CAP \ - ) - -#define EFI_FVB_STATUS (EFI_FVB_READ_STATUS | EFI_FVB_WRITE_STATUS | EFI_FVB_LOCK_STATUS) - -/// -/// Firmware Volume Header Revision definition -/// -#define EFI_FVH_REVISION 0x01 - -/// -/// Firmware Volume Header Signature definition -/// -#define EFI_FVH_SIGNATURE EFI_SIGNATURE_32 ('_', 'F', 'V', 'H') - -/// -/// Firmware Volume Header Block Map Entry definition -/// -typedef struct { - UINT32 NumBlocks; - UINT32 BlockLength; -} EFI_FV_BLOCK_MAP_ENTRY; - -/// -/// Firmware Volume Header definition -/// -typedef struct { - UINT8 ZeroVector[16]; - EFI_GUID FileSystemGuid; - UINT64 FvLength; - UINT32 Signature; - EFI_FVB_ATTRIBUTES Attributes; - UINT16 HeaderLength; - UINT16 Checksum; - UINT8 Reserved[3]; - UINT8 Revision; - EFI_FV_BLOCK_MAP_ENTRY FvBlockMap[1]; -} EFI_FIRMWARE_VOLUME_HEADER; - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/Common/FirmwareVolumeImageFormat.h b/Tools/CodeTools/TianoTools/Include/Common/FirmwareVolumeImageFormat.h deleted file mode 100644 index 14fa41bf26..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Common/FirmwareVolumeImageFormat.h +++ /dev/null @@ -1,277 +0,0 @@ -/** @file - This file defines the data structures that are architecturally defined for file - images loaded via the FirmwareVolume protocol. The Firmware Volume specification - is the basis for these definitions. - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: FimrwareVolumeImageFormat.h - - @par Revision Reference: - These definitions are from Firmware Volume Spec 0.9. - -**/ - -#ifndef __FIRMWARE_VOLUME_IMAGE_FORMAT_H__ -#define __FIRMWARE_VOLUME_IMAGE_FORMAT_H__ - -// -// pack all data structures since this is actually a binary format and we cannot -// allow internal padding in the data structures because of some compilerism.. -// -#pragma pack(1) -// -// //////////////////////////////////////////////////////////////////////////// -// -// Architectural file types -// -typedef UINT8 EFI_FV_FILETYPE; - -#define EFI_FV_FILETYPE_ALL 0x00 -#define EFI_FV_FILETYPE_RAW 0x01 -#define EFI_FV_FILETYPE_FREEFORM 0x02 -#define EFI_FV_FILETYPE_SECURITY_CORE 0x03 -#define EFI_FV_FILETYPE_PEI_CORE 0x04 -#define EFI_FV_FILETYPE_DXE_CORE 0x05 -#define EFI_FV_FILETYPE_PEIM 0x06 -#define EFI_FV_FILETYPE_DRIVER 0x07 -#define EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER 0x08 -#define EFI_FV_FILETYPE_APPLICATION 0x09 -// -// File type 0x0A is reserved and should not be used -// -#define EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE 0x0B - -// -// //////////////////////////////////////////////////////////////////////////// -// -// Section types -// -typedef UINT8 EFI_SECTION_TYPE; - -// -// ************************************************************ -// The section type EFI_SECTION_ALL is a psuedo type. It is -// used as a wildcard when retrieving sections. The section -// type EFI_SECTION_ALL matches all section types. -// ************************************************************ -// -#define EFI_SECTION_ALL 0x00 - -// -// ************************************************************ -// Encapsulation section Type values -// ************************************************************ -// -#define EFI_SECTION_COMPRESSION 0x01 -#define EFI_SECTION_GUID_DEFINED 0x02 - -// -// ************************************************************ -// Leaf section Type values -// ************************************************************ -// -#define EFI_SECTION_FIRST_LEAF_SECTION_TYPE 0x10 - -#define EFI_SECTION_PE32 0x10 -#define EFI_SECTION_PIC 0x11 -#define EFI_SECTION_TE 0x12 -#define EFI_SECTION_DXE_DEPEX 0x13 -#define EFI_SECTION_VERSION 0x14 -#define EFI_SECTION_USER_INTERFACE 0x15 -#define EFI_SECTION_COMPATIBILITY16 0x16 -#define EFI_SECTION_FIRMWARE_VOLUME_IMAGE 0x17 -#define EFI_SECTION_FREEFORM_SUBTYPE_GUID 0x18 -#define EFI_SECTION_RAW 0x19 -#define EFI_SECTION_PEI_DEPEX 0x1B - -#define EFI_SECTION_LAST_LEAF_SECTION_TYPE 0x1B -#define EFI_SECTION_LAST_SECTION_TYPE 0x1B - -// -// //////////////////////////////////////////////////////////////////////////// -// -// Common section header -// -typedef struct { - UINT8 Size[3]; - UINT8 Type; -} EFI_COMMON_SECTION_HEADER; - -#define SECTION_SIZE(SectionHeaderPtr) \ - ((UINT32) (*((UINT32 *) ((EFI_COMMON_SECTION_HEADER *) SectionHeaderPtr)->Size) & 0x00ffffff)) - -// -// //////////////////////////////////////////////////////////////////////////// -// -// Compression section -// -// -// CompressionType values -// -#define EFI_NOT_COMPRESSED 0x00 -#define EFI_STANDARD_COMPRESSION 0x01 -#define EFI_CUSTOMIZED_COMPRESSION 0x02 - -typedef struct { - EFI_COMMON_SECTION_HEADER CommonHeader; - UINT32 UncompressedLength; - UINT8 CompressionType; -} EFI_COMPRESSION_SECTION; - -// -// //////////////////////////////////////////////////////////////////////////// -// -// GUID defined section -// -typedef struct { - EFI_COMMON_SECTION_HEADER CommonHeader; - EFI_GUID SectionDefinitionGuid; - UINT16 DataOffset; - UINT16 Attributes; -} EFI_GUID_DEFINED_SECTION; - -// -// Bit values for Attributes -// -#define EFI_GUIDED_SECTION_PROCESSING_REQUIRED 0x01 -#define EFI_GUIDED_SECTION_AUTH_STATUS_VALID 0x02 - -// -// Bit values for AuthenticationStatus -// -#define EFI_AGGREGATE_AUTH_STATUS_PLATFORM_OVERRIDE 0x000001 -#define EFI_AGGREGATE_AUTH_STATUS_IMAGE_SIGNED 0x000002 -#define EFI_AGGREGATE_AUTH_STATUS_NOT_TESTED 0x000004 -#define EFI_AGGREGATE_AUTH_STATUS_TEST_FAILED 0x000008 -#define EFI_AGGREGATE_AUTH_STATUS_ALL 0x00000f - -#define EFI_LOCAL_AUTH_STATUS_PLATFORM_OVERRIDE 0x010000 -#define EFI_LOCAL_AUTH_STATUS_IMAGE_SIGNED 0x020000 -#define EFI_LOCAL_AUTH_STATUS_NOT_TESTED 0x040000 -#define EFI_LOCAL_AUTH_STATUS_TEST_FAILED 0x080000 -#define EFI_LOCAL_AUTH_STATUS_ALL 0x0f0000 - -// -// //////////////////////////////////////////////////////////////////////////// -// -// PE32+ section -// -typedef struct { - EFI_COMMON_SECTION_HEADER CommonHeader; -} EFI_PE32_SECTION; - -// -// //////////////////////////////////////////////////////////////////////////// -// -// PIC section -// -typedef struct { - EFI_COMMON_SECTION_HEADER CommonHeader; -} EFI_PIC_SECTION; - -// -// //////////////////////////////////////////////////////////////////////////// -// -// PEIM header section -// -typedef struct { - EFI_COMMON_SECTION_HEADER CommonHeader; -} EFI_PEIM_HEADER_SECTION; - -// -// //////////////////////////////////////////////////////////////////////////// -// -// DEPEX section -// -typedef struct { - EFI_COMMON_SECTION_HEADER CommonHeader; -} EFI_DEPEX_SECTION; - -// -// //////////////////////////////////////////////////////////////////////////// -// -// Version section -// -typedef struct { - EFI_COMMON_SECTION_HEADER CommonHeader; - UINT16 BuildNumber; - INT16 VersionString[1]; -} EFI_VERSION_SECTION; - -// -// //////////////////////////////////////////////////////////////////////////// -// -// User interface section -// -typedef struct { - EFI_COMMON_SECTION_HEADER CommonHeader; - INT16 FileNameString[1]; -} EFI_USER_INTERFACE_SECTION; - -// -// //////////////////////////////////////////////////////////////////////////// -// -// Code16 section -// -typedef struct { - EFI_COMMON_SECTION_HEADER CommonHeader; -} EFI_CODE16_SECTION; - -// -// //////////////////////////////////////////////////////////////////////////// -// -// Firmware Volume Image section -// -typedef struct { - EFI_COMMON_SECTION_HEADER CommonHeader; -} EFI_FIRMWARE_VOLUME_IMAGE_SECTION; - -// -// //////////////////////////////////////////////////////////////////////////// -// -// Freeform subtype GUID section -// -typedef struct { - EFI_COMMON_SECTION_HEADER CommonHeader; - EFI_GUID SubTypeGuid; -} EFI_FREEFORM_SUBTYPE_GUID_SECTION; - -// -// //////////////////////////////////////////////////////////////////////////// -// -// Raw section -// -typedef struct { - EFI_COMMON_SECTION_HEADER CommonHeader; -} EFI_RAW_SECTION; - -// -// undo the pragma from the beginning... -// -#pragma pack() - -typedef union { - EFI_COMMON_SECTION_HEADER *CommonHeader; - EFI_COMPRESSION_SECTION *CompressionSection; - EFI_GUID_DEFINED_SECTION *GuidDefinedSection; - EFI_PE32_SECTION *Pe32Section; - EFI_PIC_SECTION *PicSection; - EFI_PEIM_HEADER_SECTION *PeimHeaderSection; - EFI_DEPEX_SECTION *DependencySection; - EFI_VERSION_SECTION *VersionSection; - EFI_USER_INTERFACE_SECTION *UISection; - EFI_CODE16_SECTION *Code16Section; - EFI_FIRMWARE_VOLUME_IMAGE_SECTION *FVImageSection; - EFI_FREEFORM_SUBTYPE_GUID_SECTION *FreeformSubtypeSection; - EFI_RAW_SECTION *RawSection; -} EFI_FILE_SECTION_POINTER; - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/Common/InternalFormRepresentation.h b/Tools/CodeTools/TianoTools/Include/Common/InternalFormRepresentation.h deleted file mode 100644 index bf3d824fbd..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Common/InternalFormRepresentation.h +++ /dev/null @@ -1,422 +0,0 @@ -/** @file - This file defines the encoding for the VFR (Visual Form Representation) language. - IFR is primarily consumed by the EFI presentation engine, and produced by EFI - internal application and drivers as well as all add-in card option-ROM drivers - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: InternalFormRepresentation.h - - @par Revision Reference: - These definitions are from Human Interface Infrastructure Spec Version 0.92. - -**/ - -#ifndef __EFI_INTERNAL_FORM_REPRESENTATION_H__ -#define __EFI_INTERNAL_FORM_REPRESENTATION_H__ - -// -// The following types are currently defined: -// -typedef UINT32 RELOFST; -typedef CHAR16 *EFI_STRING; - -// -// IFR Op codes -// -#define EFI_IFR_FORM_OP 0x01 -#define EFI_IFR_SUBTITLE_OP 0x02 -#define EFI_IFR_TEXT_OP 0x03 -#define EFI_IFR_GRAPHIC_OP 0x04 -#define EFI_IFR_ONE_OF_OP 0x05 -#define EFI_IFR_CHECKBOX_OP 0x06 -#define EFI_IFR_NUMERIC_OP 0x07 -#define EFI_IFR_PASSWORD_OP 0x08 -#define EFI_IFR_ONE_OF_OPTION_OP 0x09 // ONEOF OPTION field -#define EFI_IFR_SUPPRESS_IF_OP 0x0A -#define EFI_IFR_END_FORM_OP 0x0B -#define EFI_IFR_HIDDEN_OP 0x0C -#define EFI_IFR_END_FORM_SET_OP 0x0D -#define EFI_IFR_FORM_SET_OP 0x0E -#define EFI_IFR_REF_OP 0x0F -#define EFI_IFR_END_ONE_OF_OP 0x10 -#define EFI_IFR_END_OP EFI_IFR_END_ONE_OF_OP -#define EFI_IFR_INCONSISTENT_IF_OP 0x11 -#define EFI_IFR_EQ_ID_VAL_OP 0x12 -#define EFI_IFR_EQ_ID_ID_OP 0x13 -#define EFI_IFR_EQ_ID_LIST_OP 0x14 -#define EFI_IFR_AND_OP 0x15 -#define EFI_IFR_OR_OP 0x16 -#define EFI_IFR_NOT_OP 0x17 -#define EFI_IFR_END_IF_OP 0x18 // for endif of inconsistentif, suppressif, grayoutif -#define EFI_IFR_GRAYOUT_IF_OP 0x19 -#define EFI_IFR_DATE_OP 0x1A -#define EFI_IFR_TIME_OP 0x1B -#define EFI_IFR_STRING_OP 0x1C -#define EFI_IFR_LABEL_OP 0x1D -#define EFI_IFR_SAVE_DEFAULTS_OP 0x1E -#define EFI_IFR_RESTORE_DEFAULTS_OP 0x1F -#define EFI_IFR_BANNER_OP 0x20 -#define EFI_IFR_INVENTORY_OP 0x21 -#define EFI_IFR_EQ_VAR_VAL_OP 0x22 -#define EFI_IFR_ORDERED_LIST_OP 0x23 -#define EFI_IFR_VARSTORE_OP 0x24 -#define EFI_IFR_VARSTORE_SELECT_OP 0x25 -#define EFI_IFR_VARSTORE_SELECT_PAIR_OP 0x26 -#define EFI_IFR_TRUE_OP 0x27 -#define EFI_IFR_FALSE_OP 0x28 -#define EFI_IFR_GT_OP 0x29 -#define EFI_IFR_GE_OP 0x2A -#define EFI_IFR_OEM_DEFINED_OP 0x2B -#define EFI_IFR_LAST_OPCODE EFI_IFR_OEM_DEFINED_OP -#define EFI_IFR_OEM_OP 0xFE -#define EFI_IFR_NV_ACCESS_COMMAND 0xFF - -// -// Define values for the flags fields in some VFR opcodes. These are -// bitmasks. -// -#define EFI_IFR_FLAG_DEFAULT 0x01 -#define EFI_IFR_FLAG_MANUFACTURING 0x02 -#define EFI_IFR_FLAG_INTERACTIVE 0x04 -#define EFI_IFR_FLAG_NV_ACCESS 0x08 -#define EFI_IFR_FLAG_RESET_REQUIRED 0x10 -#define EFI_IFR_FLAG_LATE_CHECK 0x20 - -#define EFI_NON_DEVICE_CLASS 0x00 // Useful when you do not want something in the Device Manager -#define EFI_DISK_DEVICE_CLASS 0x01 -#define EFI_VIDEO_DEVICE_CLASS 0x02 -#define EFI_NETWORK_DEVICE_CLASS 0x04 -#define EFI_INPUT_DEVICE_CLASS 0x08 -#define EFI_ON_BOARD_DEVICE_CLASS 0x10 -#define EFI_OTHER_DEVICE_CLASS 0x20 - -#define EFI_SETUP_APPLICATION_SUBCLASS 0x00 -#define EFI_GENERAL_APPLICATION_SUBCLASS 0x01 -#define EFI_FRONT_PAGE_SUBCLASS 0x02 -#define EFI_SINGLE_USE_SUBCLASS 0x03 // Used to display a single entity and then exit - -// -// Used to flag dynamically created op-codes. This is meaningful to the IFR Library set -// and the browser since we need to distinguish between compiled NV map data and created data. -// We do not allow new entries to be created in the NV map dynamically however we still need -// to display this information correctly. To dynamically create op-codes and assume that their -// data will be saved, ensure that the NV starting location they refer to is pre-defined in the -// NV map. -// -#define EFI_IFR_FLAG_CREATED 128 - -#pragma pack(1) -// -// IFR Structure definitions -// -typedef struct { - UINT8 OpCode; - UINT8 Length; -} EFI_IFR_OP_HEADER; - -typedef struct { - EFI_IFR_OP_HEADER Header; - EFI_GUID Guid; - STRING_REF FormSetTitle; - STRING_REF Help; - EFI_PHYSICAL_ADDRESS CallbackHandle; - UINT16 Class; - UINT16 SubClass; - UINT16 NvDataSize; // set once, size of the NV data as defined in the script -} EFI_IFR_FORM_SET; - -typedef struct { - EFI_IFR_OP_HEADER Header; - UINT16 FormId; - STRING_REF FormTitle; -} EFI_IFR_FORM; - -typedef struct { - EFI_IFR_OP_HEADER Header; - UINT16 LabelId; -} EFI_IFR_LABEL; - -typedef struct { - EFI_IFR_OP_HEADER Header; - STRING_REF SubTitle; -} EFI_IFR_SUBTITLE; - -typedef struct { - EFI_IFR_OP_HEADER Header; - STRING_REF Help; - STRING_REF Text; - STRING_REF TextTwo; - UINT8 Flags; // This is included solely for purposes of interactive/dynamic support. - UINT16 Key; // Value to be passed to caller to identify this particular op-code -} EFI_IFR_TEXT; - -// -// goto -// -typedef struct { - EFI_IFR_OP_HEADER Header; - UINT16 FormId; - STRING_REF Prompt; - STRING_REF Help; // The string Token for the context-help - UINT8 Flags; // This is included solely for purposes of interactive/dynamic support. - UINT16 Key; // Value to be passed to caller to identify this particular op-code -} EFI_IFR_REF; - -typedef struct { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_END_FORM; - -typedef struct { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_END_FORM_SET; - -// -// Also notice that the IFR_ONE_OF and IFR_CHECK_BOX are identical in structure......code assumes this to be true, if this ever -// changes we need to revisit the InitializeTagStructures code -// -typedef struct { - EFI_IFR_OP_HEADER Header; - UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name - UINT8 Width; // The Size of the Data being saved - STRING_REF Prompt; // The String Token for the Prompt - STRING_REF Help; // The string Token for the context-help -} EFI_IFR_ONE_OF; - -typedef struct { - EFI_IFR_OP_HEADER Header; - UINT16 QuestionId; // The offset in NV for storage of the data - UINT8 MaxEntries; // The maximum number of options in the ordered list (=size of NVStore) - STRING_REF Prompt; // The string token for the prompt - STRING_REF Help; // The string token for the context-help -} EFI_IFR_ORDERED_LIST; - -typedef struct { - EFI_IFR_OP_HEADER Header; - UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name - UINT8 Width; // The Size of the Data being saved - STRING_REF Prompt; // The String Token for the Prompt - STRING_REF Help; // The string Token for the context-help - UINT8 Flags; // For now, if non-zero, means that it is the default option, - further definition likely - UINT16 Key; // Value to be passed to caller to identify this particular op-code -} EFI_IFR_CHECKBOX, EFI_IFR_CHECK_BOX; - -typedef struct { - EFI_IFR_OP_HEADER Header; - STRING_REF Option; // The string token describing the option - UINT16 Value; // The value associated with this option that is stored in the NVRAM if chosen - UINT8 Flags; // For now, if non-zero, means that it is the default option, - further definition likely above - UINT16 Key; // Value to be passed to caller to identify this particular op-code -} EFI_IFR_ONE_OF_OPTION; - -typedef struct { - EFI_IFR_OP_HEADER Header; - UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name - UINT8 Width; // The Size of the Data being saved - STRING_REF Prompt; // The String Token for the Prompt - STRING_REF Help; // The string Token for the context-help - UINT8 Flags; // This is included solely for purposes of interactive/dynamic support. - UINT16 Key; // Value to be passed to caller to identify this particular op-code - UINT16 Minimum; - UINT16 Maximum; - UINT16 Step; // If step is 0, then manual input is specified, otherwise, left/right arrow selection is called for - UINT16 Default; -} EFI_IFR_NUMERIC; - -// -// There is an interesting twist with regards to Time and Date. This is one of the few items which can accept input from -// a user, however may or may not need to use storage in the NVRAM space. The decided method for determining if NVRAM space -// will be used (only for a TimeOp or DateOp) is: If .QuestionId == 0 && .Width == 0 (normally an impossibility) then use system -// resources to store the data away and not NV resources. In other words, the setup engine will call gRT->SetTime, and gRT->SetDate -// for the saving of data, and the values displayed will be from the gRT->GetXXXX series of calls. -// -typedef struct { - EFI_IFR_NUMERIC Hour; - EFI_IFR_NUMERIC Minute; - EFI_IFR_NUMERIC Second; -} EFI_IFR_TIME; - -typedef struct { - EFI_IFR_NUMERIC Year; - EFI_IFR_NUMERIC Month; - EFI_IFR_NUMERIC Day; -} EFI_IFR_DATE; - -typedef struct { - EFI_IFR_OP_HEADER Header; - UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name - UINT8 Width; // The Size of the Data being saved -- BUGBUG -- remove someday - STRING_REF Prompt; // The String Token for the Prompt - STRING_REF Help; // The string Token for the context-help - UINT8 Flags; // This is included solely for purposes of interactive/dynamic support. - UINT16 Key; // Value to be passed to caller to identify this particular op-code - UINT8 MinSize; // Minimum allowable sized password - UINT8 MaxSize; // Maximum allowable sized password - UINT16 Encoding; -} EFI_IFR_PASSWORD; - -typedef struct { - EFI_IFR_OP_HEADER Header; - UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name - UINT8 Width; // The Size of the Data being saved -- BUGBUG -- remove someday - STRING_REF Prompt; // The String Token for the Prompt - STRING_REF Help; // The string Token for the context-help - UINT8 Flags; // This is included solely for purposes of interactive/dynamic support. - UINT16 Key; // Value to be passed to caller to identify this particular op-code - UINT8 MinSize; // Minimum allowable sized password - UINT8 MaxSize; // Maximum allowable sized password -} EFI_IFR_STRING; - -typedef struct { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_END_ONE_OF; - -typedef struct { - EFI_IFR_OP_HEADER Header; - UINT16 Value; - UINT16 Key; -} EFI_IFR_HIDDEN; - -typedef struct { - EFI_IFR_OP_HEADER Header; - UINT8 Flags; -} EFI_IFR_SUPPRESS; - -typedef struct { - EFI_IFR_OP_HEADER Header; - UINT8 Flags; -} EFI_IFR_GRAY_OUT; - -typedef struct { - EFI_IFR_OP_HEADER Header; - STRING_REF Popup; - UINT8 Flags; -} EFI_IFR_INCONSISTENT; - -typedef struct { - EFI_IFR_OP_HEADER Header; - UINT16 QuestionId; // offset into variable storage - UINT8 Width; // size of variable storage - UINT16 Value; // value to compare against -} EFI_IFR_EQ_ID_VAL; - -typedef struct { - EFI_IFR_OP_HEADER Header; - UINT16 QuestionId; // offset into variable storage - UINT8 Width; // size of variable storage - UINT16 ListLength; - UINT16 ValueList[1]; -} EFI_IFR_EQ_ID_LIST; - -typedef struct { - EFI_IFR_OP_HEADER Header; - UINT16 QuestionId1; // offset into variable storage for first value to compare - UINT8 Width; // size of variable storage (must be same for both) - UINT16 QuestionId2; // offset into variable storage for second value to compare -} EFI_IFR_EQ_ID_ID; - -typedef struct { - EFI_IFR_OP_HEADER Header; - UINT16 VariableId; // offset into variable storage - UINT16 Value; // value to compare against -} EFI_IFR_EQ_VAR_VAL; - -typedef struct { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_AND; - -typedef struct { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_OR; - -typedef struct { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_NOT; - -typedef struct { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_END_EXPR, EFI_IFR_END_IF; - -typedef struct { - EFI_IFR_OP_HEADER Header; - UINT16 FormId; - STRING_REF Prompt; - STRING_REF Help; - UINT8 Flags; - UINT16 Key; -} EFI_IFR_SAVE_DEFAULTS; - -typedef struct { - EFI_IFR_OP_HEADER Header; - STRING_REF Help; - STRING_REF Text; - STRING_REF TextTwo; // optional text -} EFI_IFR_INVENTORY; - -typedef struct { - EFI_IFR_OP_HEADER Header; - EFI_GUID Guid; // GUID for the variable - UINT16 VarId; // variable store ID, as referenced elsewhere in the form - UINT16 Size; // size of the variable storage -} EFI_IFR_VARSTORE; - -typedef struct { - EFI_IFR_OP_HEADER Header; - UINT16 VarId; // variable store ID, as referenced elsewhere in the form -} EFI_IFR_VARSTORE_SELECT; - -// -// Used for the ideqid VFR statement where two variable stores may be referenced in the -// same VFR statement. -// A browser should treat this as an EFI_IFR_VARSTORE_SELECT statement and assume that all following -// IFR opcodes use the VarId as defined here. -// -typedef struct { - EFI_IFR_OP_HEADER Header; - UINT16 VarId; // variable store ID, as referenced elsewhere in the form - UINT16 SecondaryVarId; // variable store ID, as referenced elsewhere in the form -} EFI_IFR_VARSTORE_SELECT_PAIR; - -typedef struct { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_TRUE; - -typedef struct { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_FALSE; - -typedef struct { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_GT; - -typedef struct { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_GE; - -// -// Save defaults and restore defaults have same structure -// -#define EFI_IFR_RESTORE_DEFAULTS EFI_IFR_SAVE_DEFAULTS - -typedef struct { - EFI_IFR_OP_HEADER Header; - STRING_REF Title; // The string token for the banner title - UINT16 LineNumber; // 1-based line number - UINT8 Alignment; // left, center, or right-aligned -} EFI_IFR_BANNER; - -#define EFI_IFR_BANNER_ALIGN_LEFT 0 -#define EFI_IFR_BANNER_ALIGN_CENTER 1 -#define EFI_IFR_BANNER_ALIGN_RIGHT 2 -#define EFI_IFR_BANNER_TIMEOUT 0xFF - -#pragma pack() - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/Common/MultiPhase.h b/Tools/CodeTools/TianoTools/Include/Common/MultiPhase.h deleted file mode 100644 index 93867a5e8a..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Common/MultiPhase.h +++ /dev/null @@ -1,84 +0,0 @@ -/** @file - This includes some definitions that will be used in both PEI and DXE phases. - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: MultiPhase.h - -**/ - -#ifndef __MULTI_PHASE_H__ -#define __MULTI_PHASE_H__ - -// -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// -// Needed EFI defines for PEI -// -typedef UINT64 EFI_PHYSICAL_ADDRESS; - -typedef enum { - EfiReservedMemoryType, - EfiLoaderCode, - EfiLoaderData, - EfiBootServicesCode, - EfiBootServicesData, - EfiRuntimeServicesCode, - EfiRuntimeServicesData, - EfiConventionalMemory, - EfiUnusableMemory, - EfiACPIReclaimMemory, - EfiACPIMemoryNVS, - EfiMemoryMappedIO, - EfiMemoryMappedIOPortSpace, - EfiPalCode, - EfiMaxMemoryType -} EFI_MEMORY_TYPE; - -typedef UINT32 EFI_STATUS_CODE_TYPE; -typedef UINT32 EFI_STATUS_CODE_VALUE; - -typedef struct { - UINT16 HeaderSize; - UINT16 Size; - EFI_GUID Type; -} EFI_STATUS_CODE_DATA; - -typedef struct { - UINT64 Signature; - UINT32 Revision; - UINT32 HeaderSize; - UINT32 CRC32; - UINT32 Reserved; -} EFI_TABLE_HEADER; - -#define EFI_PAGE_SIZE 4096 - - -typedef VOID *EFI_HANDLE; -typedef UINT16 EFI_HII_HANDLE; -typedef UINT16 STRING_REF; -typedef struct { - INT16 Value; - INT16 Exponent; -} EFI_EXP_BASE10_DATA; - -// -// Define macros to build data structure signatures from characters. -// -#define EFI_SIGNATURE_16(A, B) ((A) | (B << 8)) -#define EFI_SIGNATURE_32(A, B, C, D) (EFI_SIGNATURE_16 (A, B) | (EFI_SIGNATURE_16 (C, D) << 16)) -#define EFI_SIGNATURE_64(A, B, C, D, E, F, G, H) \ - (EFI_SIGNATURE_32 (A, B, C, D) | ((UINT64) (EFI_SIGNATURE_32 (E, F, G, H)) << 32)) - - -#include - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/Common/UefiBaseTypes.h b/Tools/CodeTools/TianoTools/Include/Common/UefiBaseTypes.h deleted file mode 100644 index 4954c10bf2..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Common/UefiBaseTypes.h +++ /dev/null @@ -1,85 +0,0 @@ -/** @file - This file makes the BaseTypes.h backward compatible with the ones used in the - past for EFI and Tiano development. It's mostly just prepending an EFI_ on the - definitions. - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: UefiBaseTypes.h - -**/ - -#ifndef __UEFI_BASE_TYPES_H__ -#define __UEFI_BASE_TYPES_H__ - -#include - -typedef UINT64 EFI_LBA; - -#define EFIERR(_a) ENCODE_ERROR(_a) - -#define EFI_MAX_BIT MAX_BIT -#define EFI_MAX_ADDRESS MAX_ADDRESS -#define EFI_BREAKPOINT() CpuBreakpoint () -#define EFI_DEADLOOP() CpuDeadLoop () -#define EFI_ERROR(A) RETURN_ERROR(A) - -typedef GUID EFI_GUID; -typedef RETURN_STATUS EFI_STATUS; - -#define EFI_SUCCESS RETURN_SUCCESS -#define EFI_LOAD_ERROR RETURN_LOAD_ERROR -#define EFI_INVALID_PARAMETER RETURN_INVALID_PARAMETER -#define EFI_UNSUPPORTED RETURN_UNSUPPORTED -#define EFI_BAD_BUFFER_SIZE RETURN_BAD_BUFFER_SIZE -#define EFI_BUFFER_TOO_SMALL RETURN_BUFFER_TOO_SMALL -#define EFI_NOT_READY RETURN_NOT_READY -#define EFI_DEVICE_ERROR RETURN_DEVICE_ERROR -#define EFI_WRITE_PROTECTED RETURN_WRITE_PROTECTED -#define EFI_OUT_OF_RESOURCES RETURN_OUT_OF_RESOURCES -#define EFI_VOLUME_CORRUPTED RETURN_VOLUME_CORRUPTED -#define EFI_VOLUME_FULL RETURN_VOLUME_FULL -#define EFI_NO_MEDIA RETURN_NO_MEDIA -#define EFI_MEDIA_CHANGED RETURN_MEDIA_CHANGED -#define EFI_NOT_FOUND RETURN_NOT_FOUND -#define EFI_ACCESS_DENIED RETURN_ACCESS_DENIED -#define EFI_NO_RESPONSE RETURN_NO_RESPONSE -#define EFI_NO_MAPPING RETURN_NO_MAPPING -#define EFI_TIMEOUT RETURN_TIMEOUT -#define EFI_NOT_STARTED RETURN_NOT_STARTED -#define EFI_ALREADY_STARTED RETURN_ALREADY_STARTED -#define EFI_ABORTED RETURN_ABORTED -#define EFI_ICMP_ERROR RETURN_ICMP_ERROR -#define EFI_TFTP_ERROR RETURN_TFTP_ERROR -#define EFI_PROTOCOL_ERROR RETURN_PROTOCOL_ERROR -#define EFI_INCOMPATIBLE_VERSION RETURN_INCOMPATIBLE_VERSION -#define EFI_SECURITY_VIOLATION RETURN_SECURITY_VIOLATION -#define EFI_CRC_ERROR RETURN_CRC_ERROR -#define EFI_END_OF_MEDIA RETURN_END_OF_MEDIA -#define EFI_END_OF_FILE RETURN_END_OF_FILE - -#define EFI_WARN_UNKNOWN_GLYPH RETURN_WARN_UNKNOWN_GLYPH -#define EFI_WARN_DELETE_FAILURE RETURN_WARN_DELETE_FAILURE -#define EFI_WARN_WRITE_FAILURE RETURN_WARN_WRITE_FAILURE -#define EFI_WARN_BUFFER_TOO_SMALL RETURN_WARN_BUFFER_TOO_SMALL - -// -// The EFI memory allocation functions work in units of EFI_PAGEs that are -// 4K. This should in no way be confused with the page size of the processor. -// An EFI_PAGE is just the quanta of memory in EFI. -// -#define EFI_PAGE_MASK 0xFFF -#define EFI_PAGE_SHIFT 12 - -#define EFI_SIZE_TO_PAGES(a) (((a) >> EFI_PAGE_SHIFT) + (((a) & EFI_PAGE_MASK) ? 1 : 0)) - -#define EFI_PAGES_TO_SIZE(a) ( (a) << EFI_PAGE_SHIFT) - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/Common/Variable.h b/Tools/CodeTools/TianoTools/Include/Common/Variable.h deleted file mode 100644 index bc0d6408d7..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Common/Variable.h +++ /dev/null @@ -1,78 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - EfiVariable.h - -Abstract: - - Header file for EFI Variable Services - ---*/ - -#ifndef _EFI_VARIABLE_H_ -#define _EFI_VARIABLE_H_ - -#define VARIABLE_STORE_SIGNATURE EFI_SIGNATURE_32 ('$', 'V', 'S', 'S') - -#define MAX_VARIABLE_SIZE 1024 - -#define VARIABLE_DATA 0x55AA - -// -// Variable Store Header flags -// -#define VARIABLE_STORE_FORMATTED 0x5a -#define VARIABLE_STORE_HEALTHY 0xfe - -// -// Variable Store Status -// -typedef enum { - EfiRaw, - EfiValid, - EfiInvalid, - EfiUnknown -} VARIABLE_STORE_STATUS; - -// -// Variable State flags -// -#define VAR_IN_DELETED_TRANSITION 0xfe // Variable is in obsolete transistion -#define VAR_DELETED 0xfd // Variable is obsolete -#define VAR_ADDED 0x7f // Variable has been completely added -#define IS_VARIABLE_STATE(_c, _Mask) (BOOLEAN) (((~_c) & (~_Mask)) != 0) - -#pragma pack(1) - -typedef struct { - UINT32 Signature; - UINT32 Size; - UINT8 Format; - UINT8 State; - UINT16 Reserved; - UINT32 Reserved1; -} VARIABLE_STORE_HEADER; - -typedef struct { - UINT16 StartId; - UINT8 State; - UINT8 Reserved; - UINT32 Attributes; - UINTN NameSize; - UINTN DataSize; - EFI_GUID VendorGuid; -} VARIABLE_HEADER; - -#pragma pack() - -#endif // _EFI_VARIABLE_H_ diff --git a/Tools/CodeTools/TianoTools/Include/Common/WorkingBlockHeader.h b/Tools/CodeTools/TianoTools/Include/Common/WorkingBlockHeader.h deleted file mode 100644 index 235b740e83..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Common/WorkingBlockHeader.h +++ /dev/null @@ -1,47 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - EfiWorkingBlockHeader.h - -Abstract: - - Defines data structure that is the headers found at the runtime - updatable firmware volumes, such as the FileSystemGuid of the - working block, the header structure of the variable block, FTW - working block, or event log block. - ---*/ - -#ifndef _EFI_WORKING_BLOCK_HEADER_H_ -#define _EFI_WORKING_BLOCK_HEADER_H_ - -// -// EFI Fault tolerant working block header -// The header is immediately followed by the write queue. -// -typedef struct { - EFI_GUID Signature; - UINT32 Crc; - UINT32 WorkingBlockValid : 1; - UINT32 WorkingBlockInvalid : 1; -#define WORKING_BLOCK_VALID 0x1 -#define WORKING_BLOCK_INVALID 0x2 - UINT32 Reserved : 6; - UINT8 Reserved3[3]; - UINTN WriteQueueSize; - // - // UINT8 WriteQueue[WriteQueueSize]; - // -} EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER; - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/Guid/AcpiTableStorage.h b/Tools/CodeTools/TianoTools/Include/Guid/AcpiTableStorage.h deleted file mode 100644 index 80b1154828..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Guid/AcpiTableStorage.h +++ /dev/null @@ -1,30 +0,0 @@ -/** @file - The ACPI table storage file is fully FFS compliant. - The file is a number of sections of type EFI_SECTION_RAW. - This GUID is used to identify the file as an ACPI table storage file. - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: AcpiTableStorage.h - - @par Revision Reference: - GUID defined in ACPI Table Storage Spec Version 0.9. - -**/ - -#ifndef _ACPI_TABLE_STORAGE_H_ -#define _ACPI_TABLE_STORAGE_H_ - -#define EFI_ACPI_TABLE_STORAGE_GUID \ - { 0x7e374e25, 0x8e01, 0x4fee, {0x87, 0xf2, 0x39, 0xc, 0x23, 0xc6, 0x6, 0xcd } } - -extern EFI_GUID gEfiAcpiTableStorageGuid; - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/Guid/Apriori.h b/Tools/CodeTools/TianoTools/Include/Guid/Apriori.h deleted file mode 100644 index ba92560d7e..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Guid/Apriori.h +++ /dev/null @@ -1,32 +0,0 @@ -/** @file - GUID used as an FV filename for A Priori file. The A Priori file contains a - list of FV filenames that the DXE dispatcher will schedule reguardless of - the dependency grammer. - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: Apriori.h - - @par Revision Reference: - GUID defined in DXE CIS spec version 0.91B - -**/ - -#ifndef __APRIORI_GUID_H__ -#define __APRIORI_GUID_H__ - -#define EFI_APRIORI_GUID \ - { \ - 0xfc510ee7, 0xffdc, 0x11d4, {0xbd, 0x41, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \ - } - -extern EFI_GUID gAprioriGuid; - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/Guid/Capsule.h b/Tools/CodeTools/TianoTools/Include/Guid/Capsule.h deleted file mode 100644 index 7864b924de..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Guid/Capsule.h +++ /dev/null @@ -1,43 +0,0 @@ -/** @file - GUIDs used for EFI Capsule - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: Capsule.h - - @par Revision Reference: - GUIDs defined in Capsule Spec Version 0.9 - -**/ - -#ifndef __CAPSULE_GUID_H__ -#define __CAPSULE_GUID_H__ - -// -// This is the GUID of the capsule header of the image on disk. -// -#define EFI_CAPSULE_GUID \ - { \ - 0x3B6686BD, 0x0D76, 0x4030, {0xB7, 0x0E, 0xB5, 0x51, 0x9E, 0x2F, 0xC5, 0xA0 } \ - } - -// -// This is the GUID of the configuration results file created by the capsule -// application. -// -#define EFI_CONFIG_FILE_NAME_GUID \ - { \ - 0x98B8D59B, 0xE8BA, 0x48EE, {0x98, 0xDD, 0xC2, 0x95, 0x39, 0x2F, 0x1E, 0xDB } \ - } - -extern EFI_GUID gEfiCapsuleGuid; -extern EFI_GUID gEfiConfigFileNameGuid; - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/Guid/FirmwareFileSystem.h b/Tools/CodeTools/TianoTools/Include/Guid/FirmwareFileSystem.h deleted file mode 100644 index 06bfa7d583..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Guid/FirmwareFileSystem.h +++ /dev/null @@ -1,40 +0,0 @@ -/** @file - Guid used to define the Firmware File System. See the Framework Firmware - File System Specification for more details. - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: FirmwareFileSystem.h - - @par Revision Reference: - Guids defined in Firmware File System Spec 0.9 - -**/ - -#ifndef __FIRMWARE_FILE_SYSTEM_GUID_H__ -#define __FIRMWARE_FILE_SYSTEM_GUID_H__ - -// -// GUIDs defined by the FFS specification. -// -#define EFI_FIRMWARE_FILE_SYSTEM_GUID \ - { \ - 0x7A9354D9, 0x0468, 0x444a, {0x81, 0xCE, 0x0B, 0xF6, 0x17, 0xD8, 0x90, 0xDF } \ - } - -#define EFI_FFS_VOLUME_TOP_FILE_GUID \ - { \ - 0x1BA0062E, 0xC779, 0x4582, {0x85, 0x66, 0x33, 0x6A, 0xE8, 0xF7, 0x8F, 0x9 } \ - } - -extern EFI_GUID gEfiFirmwareFileSystemGuid; -extern EFI_GUID gEfiFirmwareVolumeTopFileGuid; - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/Ia32/ProcessorBind.h b/Tools/CodeTools/TianoTools/Include/Ia32/ProcessorBind.h deleted file mode 100644 index 587d8a69ab..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Ia32/ProcessorBind.h +++ /dev/null @@ -1,167 +0,0 @@ -/** @file - Processor or Compiler specific defines and types for x64. - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: ProcessorBind.h - -**/ - -#ifndef __PROCESSOR_BIND_H__ -#define __PROCESSOR_BIND_H__ - -// -// Define the processor type so other code can make processor based choices -// -#define MDE_CPU_IA32 - -// -// Make sure we are useing the correct packing rules per EFI specification -// -#ifndef __GNUC__ -#pragma pack() -#endif - -#if _MSC_EXTENSIONS - -// -// Disable warning that make it impossible to compile at /W4 -// This only works for Microsoft* tools -// - -// -// Disabling bitfield type checking warnings. -// -#pragma warning ( disable : 4214 ) - -// -// Disabling the unreferenced formal parameter warnings. -// -#pragma warning ( disable : 4100 ) - -// -// Disable slightly different base types warning as CHAR8 * can not be set -// to a constant string. -// -#pragma warning ( disable : 4057 ) - -// -// ASSERT(FALSE) or while (TRUE) are legal constructes so supress this warning -// -#pragma warning ( disable : 4127 ) - - -#endif - - -#if !defined(__GNUC__) && (__STDC_VERSION__ < 199901L) - // - // No ANSI C 2000 stdint.h integer width declarations, so define equivalents - // - - #if _MSC_EXTENSIONS - - // - // use Microsoft* C complier dependent interger width types - // - typedef unsigned __int64 UINT64; - typedef __int64 INT64; - typedef unsigned __int32 UINT32; - typedef __int32 INT32; - typedef unsigned short UINT16; - typedef unsigned short CHAR16; - typedef short INT16; - typedef unsigned char BOOLEAN; - typedef unsigned char UINT8; - typedef char CHAR8; - typedef char INT8; - #else - - // - // Assume standard IA-32 alignment. - // BugBug: Need to check portability of long long - // - typedef unsigned long long UINT64; - typedef long long INT64; - typedef unsigned int UINT32; - typedef int INT32; - typedef unsigned short UINT16; - typedef unsigned short CHAR16; - typedef short INT16; - typedef unsigned char BOOLEAN; - typedef unsigned char UINT8; - typedef char CHAR8; - typedef char INT8; - #endif - - #define UINT8_MAX 0xff - -#else - // - // Use ANSI C 2000 stdint.h integer width declarations - // - #include "stdint.h" - typedef uint8_t BOOLEAN; - typedef int8_t INT8; - typedef uint8_t UINT8; - typedef int16_t INT16; - typedef uint16_t UINT16; - typedef int32_t INT32; - typedef uint32_t UINT32; - typedef int64_t INT64; - typedef uint64_t UINT64; - typedef char CHAR8; - typedef uint16_t CHAR16; - -#endif - -typedef UINT32 UINTN; -typedef INT32 INTN; - - -// -// Processor specific defines -// -#define MAX_BIT 0x80000000 -#define MAX_2_BITS 0xC0000000 - -// -// Maximum legal IA-32 address -// -#define MAX_ADDRESS 0xFFFFFFFF - -// -// Modifier to ensure that all protocol member functions and EFI intrinsics -// use the correct C calling convention. All protocol member functions and -// EFI intrinsics are required to modify thier member functions with EFIAPI. -// -#if _MSC_EXTENSIONS - // - // Microsoft* compiler requires _EFIAPI useage, __cdecl is Microsoft* specific C. - // - #define EFIAPI __cdecl -#endif - -#if __GNUC__ - #define EFIAPI __attribute__((cdecl)) -#endif - -// -// The Microsoft* C compiler can removed references to unreferenced data items -// if the /OPT:REF linker option is used. We defined a macro as this is a -// a non standard extension -// -#if _MSC_EXTENSIONS - #define GLOBAL_REMOVE_IF_UNREFERENCED __declspec(selectany) -#else - #define GLOBAL_REMOVE_IF_UNREFERENCED -#endif - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/IndustryStandard/pci22.h b/Tools/CodeTools/TianoTools/Include/IndustryStandard/pci22.h deleted file mode 100644 index 7fee279e80..0000000000 --- a/Tools/CodeTools/TianoTools/Include/IndustryStandard/pci22.h +++ /dev/null @@ -1,481 +0,0 @@ -/** @file - Support for PCI 2.2 standard. - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: pci22.h - -**/ - -#ifndef _PCI22_H -#define _PCI22_H - -#define PCI_MAX_SEGMENT 0 - -#define PCI_MAX_BUS 255 - -#define PCI_MAX_DEVICE 31 -#define PCI_MAX_FUNC 7 - -// -// Command -// -#define PCI_VGA_PALETTE_SNOOP_DISABLED 0x20 - -#pragma pack(push, 1) -typedef struct { - UINT16 VendorId; - UINT16 DeviceId; - UINT16 Command; - UINT16 Status; - UINT8 RevisionID; - UINT8 ClassCode[3]; - UINT8 CacheLineSize; - UINT8 LatencyTimer; - UINT8 HeaderType; - UINT8 BIST; -} PCI_DEVICE_INDEPENDENT_REGION; - -typedef struct { - UINT32 Bar[6]; - UINT32 CISPtr; - UINT16 SubsystemVendorID; - UINT16 SubsystemID; - UINT32 ExpansionRomBar; - UINT8 CapabilityPtr; - UINT8 Reserved1[3]; - UINT32 Reserved2; - UINT8 InterruptLine; - UINT8 InterruptPin; - UINT8 MinGnt; - UINT8 MaxLat; -} PCI_DEVICE_HEADER_TYPE_REGION; - -typedef struct { - PCI_DEVICE_INDEPENDENT_REGION Hdr; - PCI_DEVICE_HEADER_TYPE_REGION Device; -} PCI_TYPE00; - -typedef struct { - UINT32 Bar[2]; - UINT8 PrimaryBus; - UINT8 SecondaryBus; - UINT8 SubordinateBus; - UINT8 SecondaryLatencyTimer; - UINT8 IoBase; - UINT8 IoLimit; - UINT16 SecondaryStatus; - UINT16 MemoryBase; - UINT16 MemoryLimit; - UINT16 PrefetchableMemoryBase; - UINT16 PrefetchableMemoryLimit; - UINT32 PrefetchableBaseUpper32; - UINT32 PrefetchableLimitUpper32; - UINT16 IoBaseUpper16; - UINT16 IoLimitUpper16; - UINT8 CapabilityPtr; - UINT8 Reserved[3]; - UINT32 ExpansionRomBAR; - UINT8 InterruptLine; - UINT8 InterruptPin; - UINT16 BridgeControl; -} PCI_BRIDGE_CONTROL_REGISTER; - -typedef struct { - PCI_DEVICE_INDEPENDENT_REGION Hdr; - PCI_BRIDGE_CONTROL_REGISTER Bridge; -} PCI_TYPE01; - -typedef union { - PCI_TYPE00 Device; - PCI_TYPE01 Bridge; -} PCI_TYPE_GENERIC; - -typedef struct { - UINT32 CardBusSocketReg; // Cardus Socket/ExCA Base - // Address Register - // - UINT16 Reserved; - UINT16 SecondaryStatus; // Secondary Status - UINT8 PciBusNumber; // PCI Bus Number - UINT8 CardBusBusNumber; // CardBus Bus Number - UINT8 SubordinateBusNumber; // Subordinate Bus Number - UINT8 CardBusLatencyTimer; // CardBus Latency Timer - UINT32 MemoryBase0; // Memory Base Register 0 - UINT32 MemoryLimit0; // Memory Limit Register 0 - UINT32 MemoryBase1; - UINT32 MemoryLimit1; - UINT32 IoBase0; - UINT32 IoLimit0; // I/O Base Register 0 - UINT32 IoBase1; // I/O Limit Register 0 - UINT32 IoLimit1; - UINT8 InterruptLine; // Interrupt Line - UINT8 InterruptPin; // Interrupt Pin - UINT16 BridgeControl; // Bridge Control -} PCI_CARDBUS_CONTROL_REGISTER; - -// -// Definitions of PCI class bytes and manipulation macros. -// -#define PCI_CLASS_OLD 0x00 -#define PCI_CLASS_OLD_OTHER 0x00 -#define PCI_CLASS_OLD_VGA 0x01 - -#define PCI_CLASS_MASS_STORAGE 0x01 -#define PCI_CLASS_MASS_STORAGE_SCSI 0x00 -#define PCI_CLASS_MASS_STORAGE_IDE 0x01 // obsolete -#define PCI_CLASS_IDE 0x01 -#define PCI_CLASS_MASS_STORAGE_FLOPPY 0x02 -#define PCI_CLASS_MASS_STORAGE_IPI 0x03 -#define PCI_CLASS_MASS_STORAGE_RAID 0x04 -#define PCI_CLASS_MASS_STORAGE_OTHER 0x80 - -#define PCI_CLASS_NETWORK 0x02 -#define PCI_CLASS_NETWORK_ETHERNET 0x00 -#define PCI_CLASS_ETHERNET 0x00 // obsolete -#define PCI_CLASS_NETWORK_TOKENRING 0x01 -#define PCI_CLASS_NETWORK_FDDI 0x02 -#define PCI_CLASS_NETWORK_ATM 0x03 -#define PCI_CLASS_NETWORK_ISDN 0x04 -#define PCI_CLASS_NETWORK_OTHER 0x80 - -#define PCI_CLASS_DISPLAY 0x03 -#define PCI_CLASS_DISPLAY_CTRL 0x03 // obsolete -#define PCI_CLASS_DISPLAY_VGA 0x00 -#define PCI_CLASS_VGA 0x00 // obsolete -#define PCI_CLASS_DISPLAY_XGA 0x01 -#define PCI_CLASS_DISPLAY_3D 0x02 -#define PCI_CLASS_DISPLAY_OTHER 0x80 -#define PCI_CLASS_DISPLAY_GFX 0x80 -#define PCI_CLASS_GFX 0x80 // obsolete -#define PCI_CLASS_BRIDGE 0x06 -#define PCI_CLASS_BRIDGE_HOST 0x00 -#define PCI_CLASS_BRIDGE_ISA 0x01 -#define PCI_CLASS_ISA 0x01 // obsolete -#define PCI_CLASS_BRIDGE_EISA 0x02 -#define PCI_CLASS_BRIDGE_MCA 0x03 -#define PCI_CLASS_BRIDGE_P2P 0x04 -#define PCI_CLASS_BRIDGE_PCMCIA 0x05 -#define PCI_CLASS_BRIDGE_NUBUS 0x06 -#define PCI_CLASS_BRIDGE_CARDBUS 0x07 -#define PCI_CLASS_BRIDGE_RACEWAY 0x08 -#define PCI_CLASS_BRIDGE_ISA_PDECODE 0x80 -#define PCI_CLASS_ISA_POSITIVE_DECODE 0x80 // obsolete -#define PCI_CLASS_SERIAL 0x0C -#define PCI_CLASS_SERIAL_FIREWIRE 0x00 -#define PCI_CLASS_SERIAL_ACCESS_BUS 0x01 -#define PCI_CLASS_SERIAL_SSA 0x02 -#define PCI_CLASS_SERIAL_USB 0x03 -#define PCI_CLASS_SERIAL_FIBRECHANNEL 0x04 -#define PCI_CLASS_SERIAL_SMB 0x05 - -#define IS_CLASS1(_p, c) ((_p)->Hdr.ClassCode[2] == (c)) -#define IS_CLASS2(_p, c, s) (IS_CLASS1 (_p, c) && ((_p)->Hdr.ClassCode[1] == (s))) -#define IS_CLASS3(_p, c, s, p) (IS_CLASS2 (_p, c, s) && ((_p)->Hdr.ClassCode[0] == (p))) - -#define IS_PCI_DISPLAY(_p) IS_CLASS1 (_p, PCI_CLASS_DISPLAY) -#define IS_PCI_VGA(_p) IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA, 0) -#define IS_PCI_8514(_p) IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA, 1) -#define IS_PCI_GFX(_p) IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_GFX, 0) -#define IS_PCI_OLD(_p) IS_CLASS1 (_p, PCI_CLASS_OLD) -#define IS_PCI_OLD_VGA(_p) IS_CLASS2 (_p, PCI_CLASS_OLD, PCI_CLASS_OLD_VGA) -#define IS_PCI_IDE(_p) IS_CLASS2 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_IDE) -#define IS_PCI_SCSI(_p) IS_CLASS3 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_SCSI, 0) -#define IS_PCI_RAID(_p) IS_CLASS3 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_RAID, 0) -#define IS_PCI_LPC(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA, 0) -#define IS_PCI_P2P(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_P2P, 0) -#define IS_PCI_P2P_SUB(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_P2P, 1) -#define IS_PCI_USB(_p) IS_CLASS2 (_p, PCI_CLASS_SERIAL, PCI_CLASS_SERIAL_USB) - -#define HEADER_TYPE_DEVICE 0x00 -#define HEADER_TYPE_PCI_TO_PCI_BRIDGE 0x01 -#define HEADER_TYPE_CARDBUS_BRIDGE 0x02 - -#define HEADER_TYPE_MULTI_FUNCTION 0x80 -#define HEADER_LAYOUT_CODE 0x7f - -#define IS_PCI_BRIDGE(_p) (((_p)->Hdr.HeaderType & HEADER_LAYOUT_CODE) == (HEADER_TYPE_PCI_TO_PCI_BRIDGE)) -#define IS_CARDBUS_BRIDGE(_p) (((_p)->Hdr.HeaderType & HEADER_LAYOUT_CODE) == (HEADER_TYPE_CARDBUS_BRIDGE)) -#define IS_PCI_MULTI_FUNC(_p) ((_p)->Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION) - -#define PCI_DEVICE_ROMBAR 0x30 -#define PCI_BRIDGE_ROMBAR 0x38 - -#define PCI_MAX_BAR 6 -#define PCI_MAX_CONFIG_OFFSET 0x100 -// -// bugbug: this is supported in PCI spec v2.3 -// -#define PCI_EXP_MAX_CONFIG_OFFSET 0x1000 - -#define PCI_VENDOR_ID_OFFSET 0x00 -#define PCI_DEVICE_ID_OFFSET 0x02 -#define PCI_COMMAND_OFFSET 0x04 -#define PCI_PRIMARY_STATUS_OFFSET 0x06 -#define PCI_REVISION_ID_OFFSET 0x08 -#define PCI_CLASSCODE_OFFSET 0x09 -#define PCI_CACHELINE_SIZE_OFFSET 0x0C -#define PCI_LATENCY_TIMER_OFFSET 0x0D -#define PCI_HEADER_TYPE_OFFSET 0x0E -#define PCI_BIST_OFFSET 0x0F - -#define PCI_BRIDGE_CONTROL_REGISTER_OFFSET 0x3E -#define PCI_BRIDGE_STATUS_REGISTER_OFFSET 0x1E - -#define PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET 0x18 -#define PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET 0x19 -#define PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET 0x1a - -typedef struct { - UINT8 Register; - UINT8 Function; - UINT8 Device; - UINT8 Bus; - UINT8 Reserved[4]; -} DEFIO_PCI_ADDR; - -typedef union { - struct { - UINT32 Reg : 8; - UINT32 Func : 3; - UINT32 Dev : 5; - UINT32 Bus : 8; - UINT32 Reserved : 7; - UINT32 Enable : 1; - } Bits; - UINT32 Uint32; -} PCI_CONFIG_ACCESS_CF8; - -#pragma pack() - -#define EFI_ROOT_BRIDGE_LIST 'eprb' -#define PCI_EXPANSION_ROM_HEADER_SIGNATURE 0xaa55 -#define EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE 0x0EF1 -#define PCI_DATA_STRUCTURE_SIGNATURE EFI_SIGNATURE_32 ('P', 'C', 'I', 'R') -#define PCI_CODE_TYPE_PCAT_IMAGE 0x00 -#define PCI_CODE_TYPE_EFI_IMAGE 0x03 -#define EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED 0x0001 - -#define EFI_PCI_COMMAND_IO_SPACE 0x0001 -#define EFI_PCI_COMMAND_MEMORY_SPACE 0x0002 -#define EFI_PCI_COMMAND_BUS_MASTER 0x0004 -#define EFI_PCI_COMMAND_SPECIAL_CYCLE 0x0008 -#define EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE 0x0010 -#define EFI_PCI_COMMAND_VGA_PALETTE_SNOOP 0x0020 -#define EFI_PCI_COMMAND_PARITY_ERROR_RESPOND 0x0040 -#define EFI_PCI_COMMAND_STEPPING_CONTROL 0x0080 -#define EFI_PCI_COMMAND_SERR 0x0100 -#define EFI_PCI_COMMAND_FAST_BACK_TO_BACK 0x0200 - -#define EFI_PCI_BRIDGE_CONTROL_PARITY_ERROR_RESPONSE 0x0001 -#define EFI_PCI_BRIDGE_CONTROL_SERR 0x0002 -#define EFI_PCI_BRIDGE_CONTROL_ISA 0x0004 -#define EFI_PCI_BRIDGE_CONTROL_VGA 0x0008 -#define EFI_PCI_BRIDGE_CONTROL_VGA_16 0x0010 -#define EFI_PCI_BRIDGE_CONTROL_MASTER_ABORT 0x0020 -#define EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS 0x0040 -#define EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK 0x0080 -#define EFI_PCI_BRIDGE_CONTROL_PRIMARY_DISCARD_TIMER 0x0100 -#define EFI_PCI_BRIDGE_CONTROL_SECONDARY_DISCARD_TIMER 0x0200 -#define EFI_PCI_BRIDGE_CONTROL_TIMER_STATUS 0x0400 -#define EFI_PCI_BRIDGE_CONTROL_DISCARD_TIMER_SERR 0x0800 - -// -// Following are the PCI-CARDBUS bridge control bit -// -#define EFI_PCI_BRIDGE_CONTROL_IREQINT_ENABLE 0x0080 -#define EFI_PCI_BRIDGE_CONTROL_RANGE0_MEMORY_TYPE 0x0100 -#define EFI_PCI_BRIDGE_CONTROL_RANGE1_MEMORY_TYPE 0x0200 -#define EFI_PCI_BRIDGE_CONTROL_WRITE_POSTING_ENABLE 0x0400 - -// -// Following are the PCI status control bit -// -#define EFI_PCI_STATUS_CAPABILITY 0x0010 -#define EFI_PCI_STATUS_66MZ_CAPABLE 0x0020 -#define EFI_PCI_FAST_BACK_TO_BACK_CAPABLE 0x0080 -#define EFI_PCI_MASTER_DATA_PARITY_ERROR 0x0100 - -#define EFI_PCI_CAPABILITY_PTR 0x34 -#define EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR 0x14 - -#pragma pack(1) -typedef struct { - UINT16 Signature; // 0xaa55 - UINT8 Reserved[0x16]; - UINT16 PcirOffset; -} PCI_EXPANSION_ROM_HEADER; - -typedef struct { - UINT16 Signature; // 0xaa55 - UINT16 InitializationSize; - UINT32 EfiSignature; // 0x0EF1 - UINT16 EfiSubsystem; - UINT16 EfiMachineType; - UINT16 CompressionType; - UINT8 Reserved[8]; - UINT16 EfiImageHeaderOffset; - UINT16 PcirOffset; -} EFI_PCI_EXPANSION_ROM_HEADER; - -typedef struct { - UINT16 Signature; // 0xaa55 - UINT8 Size512; - UINT8 Reserved[15]; - UINT16 PcirOffset; -} EFI_LEGACY_EXPANSION_ROM_HEADER; - -typedef union { - UINT8 *Raw; - PCI_EXPANSION_ROM_HEADER *Generic; - EFI_PCI_EXPANSION_ROM_HEADER *Efi; - EFI_LEGACY_EXPANSION_ROM_HEADER *PcAt; -} EFI_PCI_ROM_HEADER; - -typedef struct { - UINT32 Signature; // "PCIR" - UINT16 VendorId; - UINT16 DeviceId; - UINT16 Reserved0; - UINT16 Length; - UINT8 Revision; - UINT8 ClassCode[3]; - UINT16 ImageLength; - UINT16 CodeRevision; - UINT8 CodeType; - UINT8 Indicator; - UINT16 Reserved1; -} PCI_DATA_STRUCTURE; - -// -// PCI Capability List IDs and records -// -#define EFI_PCI_CAPABILITY_ID_PMI 0x01 -#define EFI_PCI_CAPABILITY_ID_AGP 0x02 -#define EFI_PCI_CAPABILITY_ID_VPD 0x03 -#define EFI_PCI_CAPABILITY_ID_SLOTID 0x04 -#define EFI_PCI_CAPABILITY_ID_MSI 0x05 -#define EFI_PCI_CAPABILITY_ID_HOTPLUG 0x06 -#define EFI_PCI_CAPABILITY_ID_PCIX 0x07 -// -// bugbug: this ID is defined in PCI spec v2.3 -// -#define EFI_PCI_CAPABILITY_ID_PCIEXP 0x10 - -typedef struct { - UINT8 CapabilityID; - UINT8 NextItemPtr; -} EFI_PCI_CAPABILITY_HDR; - -// -// Capability EFI_PCI_CAPABILITY_ID_PMI -// -typedef struct { - EFI_PCI_CAPABILITY_HDR Hdr; - UINT16 PMC; - UINT16 PMCSR; - UINT8 BridgeExtention; - UINT8 Data; -} EFI_PCI_CAPABILITY_PMI; - -// -// Capability EFI_PCI_CAPABILITY_ID_AGP -// -typedef struct { - EFI_PCI_CAPABILITY_HDR Hdr; - UINT8 Rev; - UINT8 Reserved; - UINT32 Status; - UINT32 Command; -} EFI_PCI_CAPABILITY_AGP; - -// -// Capability EFI_PCI_CAPABILITY_ID_VPD -// -typedef struct { - EFI_PCI_CAPABILITY_HDR Hdr; - UINT16 AddrReg; - UINT32 DataReg; -} EFI_PCI_CAPABILITY_VPD; - -// -// Capability EFI_PCI_CAPABILITY_ID_SLOTID -// -typedef struct { - EFI_PCI_CAPABILITY_HDR Hdr; - UINT8 ExpnsSlotReg; - UINT8 ChassisNo; -} EFI_PCI_CAPABILITY_SLOTID; - -// -// Capability EFI_PCI_CAPABILITY_ID_MSI -// -typedef struct { - EFI_PCI_CAPABILITY_HDR Hdr; - UINT16 MsgCtrlReg; - UINT32 MsgAddrReg; - UINT16 MsgDataReg; -} EFI_PCI_CAPABILITY_MSI32; - -typedef struct { - EFI_PCI_CAPABILITY_HDR Hdr; - UINT16 MsgCtrlReg; - UINT32 MsgAddrRegLsdw; - UINT32 MsgAddrRegMsdw; - UINT16 MsgDataReg; -} EFI_PCI_CAPABILITY_MSI64; - -// -// Capability EFI_PCI_CAPABILITY_ID_HOTPLUG -// -typedef struct { - EFI_PCI_CAPABILITY_HDR Hdr; - // - // not finished - fields need to go here - // -} EFI_PCI_CAPABILITY_HOTPLUG; - -// -// Capability EFI_PCI_CAPABILITY_ID_PCIX -// -typedef struct { - EFI_PCI_CAPABILITY_HDR Hdr; - UINT16 CommandReg; - UINT32 StatusReg; -} EFI_PCI_CAPABILITY_PCIX; - -typedef struct { - EFI_PCI_CAPABILITY_HDR Hdr; - UINT16 SecStatusReg; - UINT32 StatusReg; - UINT32 SplitTransCtrlRegUp; - UINT32 SplitTransCtrlRegDn; -} EFI_PCI_CAPABILITY_PCIX_BRDG; - -#define DEVICE_ID_NOCARE 0xFFFF - -#define PCI_ACPI_UNUSED 0 -#define PCI_BAR_NOCHANGE 0 -#define PCI_BAR_OLD_ALIGN 0xFFFFFFFFFFFFFFFFULL -#define PCI_BAR_EVEN_ALIGN 0xFFFFFFFFFFFFFFFEULL -#define PCI_BAR_SQUAD_ALIGN 0xFFFFFFFFFFFFFFFDULL -#define PCI_BAR_DQUAD_ALIGN 0xFFFFFFFFFFFFFFFCULL - -#define PCI_BAR_IDX0 0x00 -#define PCI_BAR_IDX1 0x01 -#define PCI_BAR_IDX2 0x02 -#define PCI_BAR_IDX3 0x03 -#define PCI_BAR_IDX4 0x04 -#define PCI_BAR_IDX5 0x05 -#define PCI_BAR_ALL 0xFF - -#pragma pack(pop) - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/Library/PeCoffLib.h b/Tools/CodeTools/TianoTools/Include/Library/PeCoffLib.h deleted file mode 100644 index 08e8195a8a..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Library/PeCoffLib.h +++ /dev/null @@ -1,131 +0,0 @@ -/** @file - Memory Only PE COFF loader - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: PeCoffLib.h - -**/ - -#ifndef __BASE_PE_COFF_LIB_H__ -#define __BASE_PE_COFF_LIB_H__ - -// -// Return status codes from the PE/COFF Loader services -// BUGBUG: Find where used and see if can be replaced by RETURN_STATUS codes -// -#define IMAGE_ERROR_SUCCESS 0 -#define IMAGE_ERROR_IMAGE_READ 1 -#define IMAGE_ERROR_INVALID_PE_HEADER_SIGNATURE 2 -#define IMAGE_ERROR_INVALID_MACHINE_TYPE 3 -#define IMAGE_ERROR_INVALID_SUBSYSTEM 4 -#define IMAGE_ERROR_INVALID_IMAGE_ADDRESS 5 -#define IMAGE_ERROR_INVALID_IMAGE_SIZE 6 -#define IMAGE_ERROR_INVALID_SECTION_ALIGNMENT 7 -#define IMAGE_ERROR_SECTION_NOT_LOADED 8 -#define IMAGE_ERROR_FAILED_RELOCATION 9 -#define IMAGE_ERROR_FAILED_ICACHE_FLUSH 10 - - -// -// PE/COFF Loader Read Function passed in by caller -// -typedef -RETURN_STATUS -(EFIAPI *PE_COFF_LOADER_READ_FILE) ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINTN *ReadSize, - OUT VOID *Buffer - ); - -// -// Context structure used while PE/COFF image is being loaded and relocated -// -typedef struct { - PHYSICAL_ADDRESS ImageAddress; - UINT64 ImageSize; - PHYSICAL_ADDRESS DestinationAddress; - PHYSICAL_ADDRESS EntryPoint; - PE_COFF_LOADER_READ_FILE ImageRead; - VOID *Handle; - VOID *FixupData; - UINT32 SectionAlignment; - UINT32 PeCoffHeaderOffset; - UINT32 DebugDirectoryEntryRva; - VOID *CodeView; - CHAR8 *PdbPointer; - UINTN SizeOfHeaders; - UINT32 ImageCodeMemoryType; - UINT32 ImageDataMemoryType; - UINT32 ImageError; - UINTN FixupDataSize; - UINT16 Machine; - UINT16 ImageType; - BOOLEAN RelocationsStripped; - BOOLEAN IsTeImage; -} PE_COFF_LOADER_IMAGE_CONTEXT; - - -/** - Retrieves information on a PE/COFF image - - @param ImageContext The context of the image being loaded - - @retval EFI_SUCCESS The information on the PE/COFF image was collected. - @retval EFI_INVALID_PARAMETER ImageContext is NULL. - @retval EFI_UNSUPPORTED The PE/COFF image is not supported. - @retval Otherwise The error status from reading the PE/COFF image using the - ImageContext->ImageRead() function - -**/ -RETURN_STATUS -EFIAPI -PeCoffLoaderGetImageInfo ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -; - -/** - Relocates a PE/COFF image in memory - - @param ImageContext Contains information on the loaded image to relocate - - @retval EFI_SUCCESS if the PE/COFF image was relocated - @retval EFI_LOAD_ERROR if the image is not a valid PE/COFF image - @retval EFI_UNSUPPORTED not support - -**/ -RETURN_STATUS -EFIAPI -PeCoffLoaderRelocateImage ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -; - -/** - Loads a PE/COFF image into memory - - @param ImageContext Contains information on image to load into memory - - @retval EFI_SUCCESS if the PE/COFF image was loaded - @retval EFI_BUFFER_TOO_SMALL if the caller did not provide a large enough buffer - @retval EFI_LOAD_ERROR if the image is a runtime driver with no relocations - @retval EFI_INVALID_PARAMETER if the image address is invalid - -**/ -RETURN_STATUS -EFIAPI -PeCoffLoaderLoadImage ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -; - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/Library/PrintLib.h b/Tools/CodeTools/TianoTools/Include/Library/PrintLib.h deleted file mode 100644 index 9c65459a59..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Library/PrintLib.h +++ /dev/null @@ -1,406 +0,0 @@ -/** @file - Library that provides print services - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: PrintLib.h - -**/ - -#ifndef __PRINT_LIB_H__ -#define __PRINT_LIB_H__ - -// -// Print primitives -// -#define LEFT_JUSTIFY 0x01 -#define COMMA_TYPE 0x08 -#define PREFIX_ZERO 0x20 - -/** - Produces a Null-terminated Unicode string in an output buffer based on - a Null-terminated Unicode format string and a VA_LIST argument list - - Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer - and BufferSize. - The Unicode string is produced by parsing the format string specified by FormatString. - Arguments are pulled from the variable argument list specified by Marker based on the - contents of the format string. - The length of the produced output buffer is returned. - If BufferSize is 0, then no output buffer is produced and 0 is returned. - - If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT(). - If BufferSize is not 0 and FormatString is NULL, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than - PcdMaximumUnicodeStringLength Unicode characters, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string - contains more than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT(). - - @param StartOfBuffer APointer to the output buffer for the produced Null-terminated - Unicode string. - @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. - @param FormatString Null-terminated Unicode format string. - @param Marker VA_LIST marker for the variable argument list. - - @return return Length of the produced output buffer. - -**/ -UINTN -EFIAPI -UnicodeVSPrint ( - OUT CHAR16 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR16 *FormatString, - IN VA_LIST Marker - ); - -/** - Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated - Unicode format string and variable argument list. - - Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer - and BufferSize. - The Unicode string is produced by parsing the format string specified by FormatString. - Arguments are pulled from the variable argument list based on the contents of the format string. - The length of the produced output buffer is returned. - If BufferSize is 0, then no output buffer is produced and 0 is returned. - - If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT(). - If BufferSize is not 0 and FormatString is NULL, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than - PcdMaximumUnicodeStringLength Unicode characters, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string - contains more than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT(). - - @param StartOfBuffer APointer to the output buffer for the produced Null-terminated - Unicode string. - @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. - @param FormatString Null-terminated Unicode format string. - - @return Length of the produced output buffer. - -**/ -UINTN -EFIAPI -UnicodeSPrint ( - OUT CHAR16 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR16 *FormatString, - ... - ); - -/** - Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated - ASCII format string and a VA_LIST argument list - - Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer - and BufferSize. - The Unicode string is produced by parsing the format string specified by FormatString. - Arguments are pulled from the variable argument list specified by Marker based on the - contents of the format string. - The length of the produced output buffer is returned. - If BufferSize is 0, then no output buffer is produced and 0 is returned. - - If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT(). - If BufferSize is not 0 and FormatString is NULL, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than - PcdMaximumUnicodeStringLength Unicode characters, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string - contains more than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT(). - - @param StartOfBuffer APointer to the output buffer for the produced Null-terminated - Unicode string. - @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. - @param FormatString Null-terminated Unicode format string. - @param Marker VA_LIST marker for the variable argument list. - - @return Length of the produced output buffer. - -**/ -UINTN -EFIAPI -UnicodeVSPrintAsciiFormat ( - OUT CHAR16 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR8 *FormatString, - IN VA_LIST Marker - ); - -/** - Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated - ASCII format string and variable argument list. - - Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer - and BufferSize. - The Unicode string is produced by parsing the format string specified by FormatString. - Arguments are pulled from the variable argument list based on the contents of the - format string. - The length of the produced output buffer is returned. - If BufferSize is 0, then no output buffer is produced and 0 is returned. - - If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT(). - If BufferSize is not 0 and FormatString is NULL, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than - PcdMaximumUnicodeStringLength Unicode characters, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string - contains more than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT(). - - @param StartOfBuffer APointer to the output buffer for the produced Null-terminated - Unicode string. - @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. - @param FormatString Null-terminated Unicode format string. - - @return Length of the produced output buffer. - -**/ -UINTN -EFIAPI -UnicodeSPrintAsciiFormat ( - OUT CHAR16 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR8 *FormatString, - ... - ); - -/** - Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated - ASCII format string and a VA_LIST argument list. - - Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer - and BufferSize. - The ASCII string is produced by parsing the format string specified by FormatString. - Arguments are pulled from the variable argument list specified by Marker based on - the contents of the format string. - The length of the produced output buffer is returned. - If BufferSize is 0, then no output buffer is produced and 0 is returned. - - If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT(). - If BufferSize is not 0 and FormatString is NULL, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than - PcdMaximumUnicodeStringLength ASCII characters, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string - contains more than PcdMaximumUnicodeStringLength ASCII characters, then ASSERT(). - - @param StartOfBuffer APointer to the output buffer for the produced Null-terminated - ASCII string. - @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. - @param FormatString Null-terminated Unicode format string. - @param Marker VA_LIST marker for the variable argument list. - - @return Length of the produced output buffer. - -**/ -UINTN -EFIAPI -AsciiVSPrint ( - OUT CHAR8 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR8 *FormatString, - IN VA_LIST Marker - ); - -/** - Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated - ASCII format string and variable argument list. - - Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer - and BufferSize. - The ASCII string is produced by parsing the format string specified by FormatString. - Arguments are pulled from the variable argument list based on the contents of the - format string. - The length of the produced output buffer is returned. - If BufferSize is 0, then no output buffer is produced and 0 is returned. - - If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT(). - If BufferSize is not 0 and FormatString is NULL, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than - PcdMaximumUnicodeStringLength ASCII characters, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string - contains more than PcdMaximumUnicodeStringLength ASCII characters, then ASSERT(). - - @param StartOfBuffer APointer to the output buffer for the produced Null-terminated - ASCII string. - @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. - @param FormatString Null-terminated Unicode format string. - - @return Length of the produced output buffer. - -**/ -UINTN -EFIAPI -AsciiSPrint ( - OUT CHAR8 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR8 *FormatString, - ... - ); - -/** - Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated - ASCII format string and a VA_LIST argument list. - - Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer - and BufferSize. - The ASCII string is produced by parsing the format string specified by FormatString. - Arguments are pulled from the variable argument list specified by Marker based on - the contents of the format string. - The length of the produced output buffer is returned. - If BufferSize is 0, then no output buffer is produced and 0 is returned. - - If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT(). - If BufferSize is not 0 and FormatString is NULL, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than - PcdMaximumUnicodeStringLength ASCII characters, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string - contains more than PcdMaximumUnicodeStringLength ASCII characters, then ASSERT(). - - @param StartOfBuffer APointer to the output buffer for the produced Null-terminated - ASCII string. - @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. - @param FormatString Null-terminated Unicode format string. - @param Marker VA_LIST marker for the variable argument list. - - @return Length of the produced output buffer. - -**/ -UINTN -EFIAPI -AsciiVSPrintUnicodeFormat ( - OUT CHAR8 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR16 *FormatString, - IN VA_LIST Marker - ); - -/** - Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated - ASCII format string and variable argument list. - - Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer - and BufferSize. - The ASCII string is produced by parsing the format string specified by FormatString. - Arguments are pulled from the variable argument list based on the contents of the - format string. - The length of the produced output buffer is returned. - If BufferSize is 0, then no output buffer is produced and 0 is returned. - - If BufferSize is not 0 and StartOfBuffer is NULL, then ASSERT(). - If BufferSize is not 0 and FormatString is NULL, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than - PcdMaximumUnicodeStringLength ASCII characters, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string - contains more than PcdMaximumUnicodeStringLength ASCII characters, then ASSERT(). - - @param StartOfBuffer APointer to the output buffer for the produced Null-terminated - ASCII string. - @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. - @param FormatString Null-terminated Unicode format string. - - @return Length of the produced output buffer. - -**/ -UINTN -EFIAPI -AsciiSPrintUnicodeFormat ( - OUT CHAR8 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR16 *FormatString, - ... - ); - -/** - Converts a decimal value to a Null-terminated Unicode string. - - Converts the decimal number specified by Value to a Null-terminated Unicode - string specified by Buffer containing at most Width characters. - If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed. - The total number of characters placed in Buffer is returned. - If the conversion contains more than Width characters, then only the first - Width characters are returned, and the total number of characters - required to perform the conversion is returned. - Additional conversion parameters are specified in Flags. - The Flags bit LEFT_JUSTIFY is always ignored. - All conversions are left justified in Buffer. - If Width is 0, PREFIX_ZERO is ignored in Flags. - If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas - are inserted every 3rd digit starting from the right. - If Value is < 0, then the fist character in Buffer is a '-'. - If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, - then Buffer is padded with '0' characters so the combination of the optional '-' - sign character, '0' characters, digit characters for Value, and the Null-terminator - add up to Width characters. - - If Buffer is NULL, then ASSERT(). - If unsupported bits are set in Flags, then ASSERT(). - If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT() - - @param Buffer Pointer to the output buffer for the produced Null-terminated - Unicode string. - @param Flags The bitmask of flags that specify left justification, zero pad, and commas. - @param Value The 64-bit signed value to convert to a string. - @param Width The maximum number of Unicode characters to place in Buffer. - - @return Total number of characters required to perform the conversion. - -**/ -UINTN -EFIAPI -UnicodeValueToString ( - IN OUT CHAR16 *Buffer, - IN UINTN Flags, - IN INT64 Value, - IN UINTN Width - ); - -/** - Converts a decimal value to a Null-terminated ASCII string. - - Converts the decimal number specified by Value to a Null-terminated ASCII string - specified by Buffer containing at most Width characters. - If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed. - The total number of characters placed in Buffer is returned. - If the conversion contains more than Width characters, then only the first Width - characters are returned, and the total number of characters required to perform - the conversion is returned. - Additional conversion parameters are specified in Flags. - The Flags bit LEFT_JUSTIFY is always ignored. - All conversions are left justified in Buffer. - If Width is 0, PREFIX_ZERO is ignored in Flags. - If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas - are inserted every 3rd digit starting from the right. - If Value is < 0, then the fist character in Buffer is a '-'. - If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then Buffer - is padded with '0' characters so the combination of the optional '-' - sign character, '0' characters, digit characters for Value, and the - Null-terminator add up to Width characters. - - If Buffer is NULL, then ASSERT(). - If unsupported bits are set in Flags, then ASSERT(). - If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT() - - @param Buffer Pointer to the output buffer for the produced Null-terminated - ASCII string. - @param Flags The bitmask of flags that specify left justification, zero pad, and commas. - @param Value The 64-bit signed value to convert to a string. - @param Width The maximum number of ASCII characters to place in Buffer. - - @return Total number of characters required to perform the conversion. - -**/ -UINTN -EFIAPI -AsciiValueToString ( - IN OUT CHAR8 *Buffer, - IN UINTN Flags, - IN INT64 Value, - IN UINTN Width - ); - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/Protocol/DevicePath.h b/Tools/CodeTools/TianoTools/Include/Protocol/DevicePath.h deleted file mode 100644 index d01999904f..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Protocol/DevicePath.h +++ /dev/null @@ -1,94 +0,0 @@ -/** @file - The device path protocol as defined in EFI 1.0. - - The device path represents a programatic path to a device. It's the view - from a software point of view. It also must persist from boot to boot, so - it can not contain things like PCI bus numbers that change from boot to boot. - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: DevicePath.h - -**/ - -#ifndef __EFI_DEVICE_PATH_PROTOCOL_H__ -#define __EFI_DEVICE_PATH_PROTOCOL_H__ - -// -// Device Path protocol -// -#define EFI_DEVICE_PATH_PROTOCOL_GUID \ - { \ - 0x9576e91, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ - } - -#pragma pack(1) - -typedef struct { - UINT8 Type; - UINT8 SubType; - UINT8 Length[2]; -} EFI_DEVICE_PATH_PROTOCOL; - -#pragma pack() - -#define EFI_DP_TYPE_MASK 0x7F -#define EFI_DP_TYPE_UNPACKED 0x80 -#define END_DEVICE_PATH_TYPE 0x7f - -#define EFI_END_ENTIRE_DEVICE_PATH 0xff -#define EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff -#define EFI_END_INSTANCE_DEVICE_PATH 0x01 -#define END_ENTIRE_DEVICE_PATH_SUBTYPE EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE -#define END_INSTANCE_DEVICE_PATH_SUBTYPE EFI_END_INSTANCE_DEVICE_PATH - -#define EFI_END_DEVICE_PATH_LENGTH (sizeof (EFI_DEVICE_PATH_PROTOCOL)) -#define END_DEVICE_PATH_LENGTH EFI_END_DEVICE_PATH_LENGTH - -#define DP_IS_END_TYPE(a) -#define DP_IS_END_SUBTYPE(a) (((a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE) -#define DevicePathSubType(a) ((a)->SubType) -#define IsDevicePathUnpacked(a) ((a)->Type & EFI_DP_TYPE_UNPACKED) - -#define EfiDevicePathNodeLength(a) (((a)->Length[0]) | ((a)->Length[1] << 8)) -#define DevicePathNodeLength(a) (EfiDevicePathNodeLength(a)) -#define EfiNextDevicePathNode(a) ((EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) (a)) + EfiDevicePathNodeLength (a))) -#define NextDevicePathNode(a) (EfiNextDevicePathNode(a)) - -#define EfiDevicePathType(a) (((a)->Type) & EFI_DP_TYPE_MASK) -#define DevicePathType(a) (EfiDevicePathType(a)) -#define EfiIsDevicePathEndType(a) (EfiDevicePathType (a) == END_DEVICE_PATH_TYPE) -#define IsDevicePathEndType(a) (EfiIsDevicePathEndType(a)) - - -#define EfiIsDevicePathEndSubType(a) ((a)->SubType == EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE) -#define IsDevicePathEndSubType(a) (EfiIsDevicePathEndSubType(a)) -#define EfiIsDevicePathEndInstanceSubType(a) ((a)->SubType == EFI_END_INSTANCE_DEVICE_PATH) - -#define EfiIsDevicePathEnd(a) (EfiIsDevicePathEndType (a) && EfiIsDevicePathEndSubType (a)) -#define IsDevicePathEnd(a) (EfiIsDevicePathEnd(a)) -#define EfiIsDevicePathEndInstance(a) (EfiIsDevicePathEndType (a) && EfiIsDevicePathEndInstanceSubType (a)) - - -#define SetDevicePathNodeLength(a,l) { \ - (a)->Length[0] = (UINT8) (l); \ - (a)->Length[1] = (UINT8) ((l) >> 8); \ - } - -#define SetDevicePathEndNode(a) { \ - (a)->Type = END_DEVICE_PATH_TYPE; \ - (a)->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; \ - (a)->Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL); \ - (a)->Length[1] = 0; \ - } - -extern EFI_GUID gEfiDevicePathProtocolGuid; - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/Protocol/GuidedSectionExtraction.h b/Tools/CodeTools/TianoTools/Include/Protocol/GuidedSectionExtraction.h deleted file mode 100644 index d98c56a7bc..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Protocol/GuidedSectionExtraction.h +++ /dev/null @@ -1,102 +0,0 @@ -/** @file - This file declares GUIDed section extraction protocol. - - This interface provides a means of decoding a GUID defined encapsulation - section. There may be multiple different GUIDs associated with the GUIDed - section extraction protocol. That is, all instances of the GUIDed section - extraction protocol must have the same interface structure. - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: GuidedSectionExtraction.h - - @par Revision Reference: - This protocol is defined in Firmware Volume Specification. - Version 0.9 - -**/ - -#ifndef __GUIDED_SECTION_EXTRACTION_PROTOCOL_H__ -#define __GUIDED_SECTION_EXTRACTION_PROTOCOL_H__ - - -// -// Protocol GUID definition. Each GUIDed section extraction protocol has the -// same interface but with different GUID. All the GUIDs is defined here. -// May add multiple GUIDs here. -// -#define EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID \ - { \ - 0xFC1BCDB0, 0x7D31, 0x49aa, {0x93, 0x6A, 0xA4, 0x60, 0x0D, 0x9D, 0xD0, 0x83 } \ - } - -// -// Forward reference for pure ANSI compatability -// -typedef struct _EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL; - -// -// Protocol member functions -// -/** - Processes the input section and returns the data contained therein along - with the authentication status. - - @param This Indicates the EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL instance. - @param InputSection Buffer containing the input GUIDed section to be processed. - @param OutputBuffer *OutputBuffer is allocated from boot services pool memory - and contains the new section stream. - @param OutputSize A pointer to a caller-allocated UINTN in which the size - of *OutputBuffer allocation is stored. - @param AuthenticationStatus A pointer to a caller-allocated UINT32 that - indicates the authentication status of the output buffer. - - @retval EFI_SUCCESS The InputSection was successfully processed and the - section contents were returned. - @retval EFI_OUT_OF_RESOURCES The system has insufficient resources to - process the request. - @retval EFI_INVALID_PARAMETER The GUID in InputSection does not match - this instance of the GUIDed Section Extraction Protocol. - -**/ - -typedef -EFI_STATUS -(EFIAPI *EFI_EXTRACT_GUIDED_SECTION) ( - IN EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *This, - IN VOID *InputSection, - OUT VOID **OutputBuffer, - OUT UINTN *OutputSize, - OUT UINT32 *AuthenticationStatus - ); - -// -// Protocol definition -// -/** - @par Protocol Description: - If a GUID-defined section is encountered when doing section extraction, - the section extraction driver calls the appropriate instance of the GUIDed - Section Extraction Protocol to extract the section stream contained therein. - - @param ExtractSection - Takes the GUIDed section as input and produces the section stream data. - -**/ -struct _EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL { - EFI_EXTRACT_GUIDED_SECTION ExtractSection; -}; - -// -// may add other GUID here -// -extern EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid; - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/Protocol/Hii.h b/Tools/CodeTools/TianoTools/Include/Protocol/Hii.h deleted file mode 100644 index ceeba1c7fb..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Protocol/Hii.h +++ /dev/null @@ -1,1024 +0,0 @@ -/** @file - This file defines the Human Interface Infrastructure protocol which will - be used by resources which want to publish IFR/Font/String data and have it - collected by the Configuration engine. - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: Hii.h - - @par Revision Reference: - This protocol is defined in HII spec 0.92. - -**/ - -#ifndef __HII_H__ -#define __HII_H__ - - -#define EFI_HII_PROTOCOL_GUID \ - { \ - 0xea816d2c, 0xcee5, 0x4f02, {0x99, 0xb5, 0xd3, 0x90, 0x5c, 0xbb, 0xd0, 0x77 } \ - } - -// BugBug: -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// If UGA goes away we need to put this some place. I'm not sure where? -// -//typedef struct { -// UINT8 Blue; -// UINT8 Green; -// UINT8 Red; -// UINT8 Reserved; -//} EFI_UGA_PIXEL; - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// - -typedef struct _EFI_HII_PROTOCOL EFI_HII_PROTOCOL; - -// -// Global definition -// -#define NARROW_CHAR 0xFFF0 -#define WIDE_CHAR 0xFFF1 -#define NON_BREAKING_CHAR 0xFFF2 -#define GLYPH_WIDTH 8 -#define GLYPH_HEIGHT 19 - -#define EFI_HII_FONT 1 -#define EFI_HII_STRING 2 -#define EFI_HII_IFR 3 -#define EFI_HII_KEYBOARD 4 -#define EFI_HII_HANDLES 5 -#define EFI_HII_VARIABLE 6 -#define EFI_HII_DEVICE_PATH 7 - - -// References to string tokens must use this macro to enable scanning for -// token usages. -// -#define STRING_TOKEN(t) t - -// -// The following types are currently defined: -// -typedef UINT16 EFI_FORM_ID; -typedef UINT16 EFI_FORM_LABEL; - -#pragma pack(1) - -typedef struct { - UINT32 Length; - UINT16 Type; -} EFI_HII_PACK_HEADER; - -// -// A form list consists of a large variety of structure -// possibilities so to represent the binary blob of data -// associated with a package of forms, we will assume a -// pointer to a self-describing data buffer. -// -typedef struct { - EFI_HII_PACK_HEADER Header; -} EFI_HII_IFR_PACK; - -typedef struct { - EFI_HII_PACK_HEADER Header; // Must be filled in - EFI_HANDLE ImageHandle; // Must be filled in - EFI_HANDLE DeviceHandle; // Optional - EFI_HANDLE ControllerHandle; // Optional - EFI_HANDLE CallbackHandle; // Optional - EFI_HANDLE COBExportHandle; // Optional -} EFI_HII_HANDLE_PACK; - -// -// ******************************************************** -// EFI_VARIABLE_CONTENTS -// ******************************************************** -// -typedef struct { - EFI_HII_PACK_HEADER Header; - EFI_GUID VariableGuid; - UINT32 VariableNameLength; - UINT16 VariableId; - // - // CHAR16 VariableName[]; //Null-terminated - // -} EFI_HII_VARIABLE_PACK; - -// -// ******************************************************** -// EFI_DEVICE_PATH_PACK -// ******************************************************** -// -typedef struct { - EFI_HII_PACK_HEADER Header; - // - // EFI_DEVICE_PATH DevicePath[]; - // -} EFI_HII_DEVICE_PATH_PACK; - -// -// ******************************************************** -// EFI_HII_DATA_TABLE -// ******************************************************** -// -typedef struct { - EFI_HII_HANDLE HiiHandle; - EFI_GUID PackageGuid; - UINT32 DataTableSize; - UINT32 IfrDataOffset; - UINT32 StringDataOffset; - UINT32 VariableDataOffset; - UINT32 DevicePathOffset; - UINT32 NumberOfVariableData; - UINT32 NumberOfLanguages; - // - // EFI_HII_DEVICE_PATH_PACK DevicePath[]; - // EFI_HII_VARIABLE_PACK VariableData[]; - // EFI_HII_IFR_PACK IfrData; - // EFI_HII_STRING_PACK StringData[]; - // -} EFI_HII_DATA_TABLE; - -// -// ******************************************************** -// EFI_HII_EXPORT_TABLE -// ******************************************************** -// -typedef struct { - UINT32 NumberOfHiiDataTables; - EFI_GUID Revision; - // - // EFI_HII_DATA_TABLE HiiDataTable[]; - // -} EFI_HII_EXPORT_TABLE; - -typedef struct { - BOOLEAN FormSetUpdate; // If TRUE, next variable is significant - EFI_PHYSICAL_ADDRESS FormCallbackHandle; // If not 0, will update Formset with this info - BOOLEAN FormUpdate; // If TRUE, next variable is significant - UINT16 FormValue; // specify which form is to be updated if FormUpdate value is TRUE. - STRING_REF FormTitle; // If not 0, will update Form with this info - UINT16 DataCount; // The number of Data entries in this structure - UINT8 *Data; // An array of 1+ op-codes, specified by DataCount -} EFI_HII_UPDATE_DATA; - -// -// String attributes -// -#define LANG_RIGHT_TO_LEFT 0x00000001 - -// -// A string package is used to localize strings to a particular -// language. The package is associated with a particular driver -// or set of drivers. Tools are used to associate tokens with -// string references in forms and in programs. These tokens are -// language agnostic. When paired with a language pack (directly -// or indirectly), the string token resolves into an actual -// UNICODE string. The NumStringPointers determines how many -// StringPointers (offset values) there are as well as the total -// number of Strings that are defined. -// -typedef struct { - EFI_HII_PACK_HEADER Header; - RELOFST LanguageNameString; - RELOFST PrintableLanguageName; - UINT32 NumStringPointers; - UINT32 Attributes; - // - // RELOFST StringPointers[]; - // EFI_STRING Strings[]; - // -} EFI_HII_STRING_PACK; - -// -// Glyph Attributes -// -#define EFI_GLYPH_NON_SPACING 1 -#define EFI_GLYPH_WIDE 2 - -typedef struct { - CHAR16 UnicodeWeight; - UINT8 Attributes; - UINT8 GlyphCol1[GLYPH_HEIGHT]; -} EFI_NARROW_GLYPH; - -typedef struct { - CHAR16 UnicodeWeight; - UINT8 Attributes; - UINT8 GlyphCol1[GLYPH_HEIGHT]; - UINT8 GlyphCol2[GLYPH_HEIGHT]; - UINT8 Pad[3]; -} EFI_WIDE_GLYPH; - -// -// A font list consists of a font header followed by a series -// of glyph structures. Note that fonts are not language specific. -// -typedef struct { - EFI_HII_PACK_HEADER Header; - UINT16 NumberOfNarrowGlyphs; - UINT16 NumberOfWideGlyphs; -} EFI_HII_FONT_PACK; - -// -// The IfrData in the EFI_HII_IFR_PACK structure definition -// is variable length, and not really part of the header. To -// simplify from code the size of the header, define an -// identical structure that does not include the IfrData field. -// Then use sizeof() this new structure to determine the -// actual size of the header. -// -typedef struct { - EFI_HII_PACK_HEADER Header; -} EFI_HII_IFR_PACK_HEADER; - -// -// pedef EFI_HII_PACK_HEADER EFI_HII_IFR_PACK_HEADER; -// -typedef enum { - EfiKeyLCtrl, - EfiKeyA0, - EfiKeyLAlt, - EfiKeySpaceBar, - EfiKeyA2, - EfiKeyA3, - EfiKeyA4, - EfiKeyRCtrl, - EfiKeyLeftArrow, - EfiKeyDownArrow, - EfiKeyRightArrow, - EfiKeyZero, - EfiKeyPeriod, - EfiKeyEnter, - EfiKeyLShift, - EfiKeyB0, - EfiKeyB1, - EfiKeyB2, - EfiKeyB3, - EfiKeyB4, - EfiKeyB5, - EfiKeyB6, - EfiKeyB7, - EfiKeyB8, - EfiKeyB9, - EfiKeyB10, - EfiKeyRshift, - EfiKeyUpArrow, - EfiKeyOne, - EfiKeyTwo, - EfiKeyThree, - EfiKeyCapsLock, - EfiKeyC1, - EfiKeyC2, - EfiKeyC3, - EfiKeyC4, - EfiKeyC5, - EfiKeyC6, - EfiKeyC7, - EfiKeyC8, - EfiKeyC9, - EfiKeyC10, - EfiKeyC11, - EfiKeyC12, - EfiKeyFour, - EfiKeyFive, - EfiKeySix, - EfiKeyPlus, - EfiKeyTab, - EfiKeyD1, - EfiKeyD2, - EfiKeyD3, - EfiKeyD4, - EfiKeyD5, - EfiKeyD6, - EfiKeyD7, - EfiKeyD8, - EfiKeyD9, - EfiKeyD10, - EfiKeyD11, - EfiKeyD12, - EfiKeyD13, - EfiKeyDel, - EfiKeyEnd, - EfiKeyPgDn, - EfiKeySeven, - EfiKeyEight, - EfiKeyNine, - EfiKeyE0, - EfiKeyE1, - EfiKeyE2, - EfiKeyE3, - EfiKeyE4, - EfiKeyE5, - EfiKeyE6, - EfiKeyE7, - EfiKeyE8, - EfiKeyE9, - EfiKeyE10, - EfiKeyE11, - EfiKeyE12, - EfiKeyBackSpace, - EfiKeyIns, - EfiKeyHome, - EfiKeyPgUp, - EfiKeyNLck, - EfiKeySlash, - EfiKeyAsterisk, - EfiKeyMinus, - EfiKeyEsc, - EfiKeyF1, - EfiKeyF2, - EfiKeyF3, - EfiKeyF4, - EfiKeyF5, - EfiKeyF6, - EfiKeyF7, - EfiKeyF8, - EfiKeyF9, - EfiKeyF10, - EfiKeyF11, - EfiKeyF12, - EfiKeyPrint, - EfiKeySLck, - EfiKeyPause -} EFI_KEY; - -typedef struct { - EFI_KEY Key; - CHAR16 Unicode; - CHAR16 ShiftedUnicode; - CHAR16 AltGrUnicode; - CHAR16 ShiftedAltGrUnicode; - UINT16 Modifier; -} EFI_KEY_DESCRIPTOR; - -// -// This structure allows a sparse set of keys to be redefined -// or a complete redefinition of the keyboard layout. Most -// keyboards have a lot of commonality in their layouts, therefore -// only defining those keys that need to change from the default -// minimizes the passed in information. -// -// Additionally, when an update occurs, the active keyboard layout -// will be switched to the newly updated keyboard layout. This -// allows for situations that when a keyboard layout driver is -// loaded as part of system initialization, the system will default -// the keyboard behavior to the new layout. -// -// Each call to update the keyboard mapping should contain the -// complete set of key descriptors to be updated, since every -// call to the HII which contains an EFI_HII_KEYBOARD_PACK will -// wipe the previous set of overrides. A call to -// -typedef struct { - EFI_HII_PACK_HEADER Header; - EFI_KEY_DESCRIPTOR *Descriptor; - UINT8 DescriptorCount; -} EFI_HII_KEYBOARD_PACK; - -// -// The EFI_HII_PACKAGES can contain different types of packages just -// after the structure as inline data. -// -typedef struct { - UINTN NumberOfPackages; - EFI_GUID *GuidId; - // - // EFI_HII_HANDLE_PACK *HandlePack; // Only one pack. - // EFI_HII_IFR_PACK *IfrPack; // Only one pack. - // EFI_HII_FONT_PACK *FontPack[]; // Multiple packs ok - // EFI_HII_STRING_PACK *StringPack[]; // Multiple packs ok - // EFI_HII_KEYBOARD_PACK *KeyboardPack[]; // Multiple packs ok - // -} EFI_HII_PACKAGES; - -typedef struct _EFI_HII_VARIABLE_PACK_LIST { - struct _EFI_HII_VARIABLE_PACK_LIST *NextVariablePack; - EFI_HII_VARIABLE_PACK *VariablePack; -} EFI_HII_VARIABLE_PACK_LIST; - -#pragma pack() - -/** - Registers the various packs that are passed in via the Packages parameter. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - - @param Packages A pointer to an EFI_HII_PACKAGES package instance. - - @param Handle A pointer to the EFI_HII_HANDLE instance. - - @retval EFI_SUCCESS Data was extracted from Packages, the database - was updated with the data, and Handle returned successfully. - - @retval EFI_INVALID_PARAMETER The content of Packages was invalid. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_NEW_PACK) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_PACKAGES *Packages, - OUT EFI_HII_HANDLE *Handle - ); - -/** - Removes a package from the HII database. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - - @param Handle The handle that was registered to the data that is requested - for removal. - - @retval EFI_SUCCESS The data associated with the Handle was removed - from the HII database. - - @retval EFI_INVALID_PARAMETER The Handle was not valid. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_REMOVE_PACK) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_HANDLE Handle - ); - -/** - Determines the handles that are currently active in the database. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - - @param HandleBufferLength On input, a pointer to the length of the handle - buffer. On output, the length of the handle buffer that is required - for the handles found. - - @param Handle An array of EFI_HII_HANDLE instances returned. - - @retval EFI_SUCCESS Handle was updated successfully. - - @retval EFI_BUFFER_TOO_SMALL The HandleBufferLength parameter indicates - that Handle is too small to support the number of handles. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_FIND_HANDLES) ( - IN EFI_HII_PROTOCOL *This, - IN OUT UINT16 *HandleBufferLength, - OUT EFI_HII_HANDLE *Handle - ); - -/** - Exports the contents of the database into a buffer. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - - @param Handle An EFI_HII_HANDLE that corresponds to the desired - handle to export. If the value is 0, the entire database will be exported. - In either case, the data will be exported in a format described by the - structure definition of EFI_HII_EXPORT_TABLE. - - @param BufferSize - On input, a pointer to the length of the buffer. On output, the length - of the buffer that is required for the export data. - - @param Buffer A pointer to a buffer that will contain the results of the export function. - - @retval EFI_SUCCESS The buffer was successfully filled with BufferSize amount of data. - - @retval EFI_BUFFER_TOO_SMALL The value in BufferSize was too small to contain the export data. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_EXPORT) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_HANDLE Handle, - IN OUT UINTN *BufferSize, - OUT VOID *Buffer - ); - -/** - Remove any new strings that were added after the initial string export - for this handle. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - - @param Handle The handle on which the string resides. - - @retval EFI_SUCCESS Remove strings from the handle successfully. - - @retval EFI_INVALID_PARAMETER The Handle was unknown. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_RESET_STRINGS) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_HANDLE Handle - ); - -/** - Tests if all of the characters in a string have corresponding font characters. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - - @param StringToTest A pointer to a Unicode string. - - @param FirstMissing A pointer to an index into the string. On input, - the index of the first character in the StringToTest to examine. On exit, - the index of the first character encountered for which a glyph is unavailable. - If all glyphs in the string are available, the index is the index of the - terminator of the string. - - @param GlyphBufferSize A pointer to a value. On output, if the function - returns EFI_SUCCESS, it contains the amount of memory that is required to - store the string¡¯s glyph equivalent. - - @retval EFI_SUCCESS All glyphs are available. Note that an empty string - always returns this value. - - @retval EFI_NOT_FOUND A glyph was not found for a character. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_TEST_STRING) ( - IN EFI_HII_PROTOCOL *This, - IN CHAR16 *StringToTest, - IN OUT UINT32 *FirstMissing, - OUT UINT32 *GlyphBufferSize - ); - -/** - Translates a Unicode character into the corresponding font glyph. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - - @param Source A pointer to a Unicode string. - - @param Index On input, the offset into the string from which to fetch - the character.On successful completion, the index is updated to the first - character past the character(s) making up the just extracted glyph. - - @param GlyphBuffer Pointer to an array where the glyphs corresponding - to the characters in the source may be stored. GlyphBuffer is assumed - to be wide enough to accept a wide glyph character. - - @param BitWidth If EFI_SUCCESS was returned, the UINT16 pointed to by - this value is filled with the length of the glyph in pixels. It is unchanged - if the call was unsuccessful. - - @param InternalStatus The cell pointed to by this parameter must be - initialized to zero prior to invoking the call the first time for any string. - - @retval EFI_SUCCESS It worked. - - @retval EFI_NOT_FOUND A glyph for a character was not found. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_GET_GLYPH) ( - IN EFI_HII_PROTOCOL *This, - IN CHAR16 *Source, - IN OUT UINT16 *Index, - OUT UINT8 **GlyphBuffer, - OUT UINT16 *BitWidth, - IN OUT UINT32 *InternalStatus - ); - -/** - Translates a glyph into the format required for input to the Universal - Graphics Adapter (UGA) Block Transfer (BLT) routines. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - - @param GlyphBuffer A pointer to the buffer that contains glyph data. - - @param Foreground The foreground setting requested to be used for the - generated BltBuffer data. - - @param Background The background setting requested to be used for the - generated BltBuffer data. - - @param Count The entry in the BltBuffer upon which to act. - - @param Width The width in bits of the glyph being converted. - - @param Height The height in bits of the glyph being converted - - @param BltBuffer A pointer to the buffer that contains the data that is - ready to be used by the UGA BLT routines. - - @retval EFI_SUCCESS It worked. - - @retval EFI_NOT_FOUND A glyph for a character was not found. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_GLYPH_TO_BLT) ( - IN EFI_HII_PROTOCOL *This, - IN UINT8 *GlyphBuffer, - IN EFI_UGA_PIXEL Foreground, - IN EFI_UGA_PIXEL Background, - IN UINTN Count, - IN UINTN Width, - IN UINTN Height, - IN OUT EFI_UGA_PIXEL *BltBuffer - ); - -/** - Allows a new string to be added to an already existing string package. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - - @param Pointer to a NULL-terminated string containing a single ISO 639-2 - language identifier, indicating the language in which the string is translated. - - @param Handle The handle of the language pack to which the string is to be added. - - @param Reference The identifier of the string to be added. If the reference - value is zero, then the string will be assigned a new identifier on that - handle for the language specified. Otherwise, the string will be updated - with the NewString Value. - - @param NewString The string to be added. - - @retval EFI_SUCCESS The string was effectively registered. - - @retval EFI_INVALID_PARAMETER The Handle was unknown. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_NEW_STRING) ( - IN EFI_HII_PROTOCOL *This, - IN CHAR16 *Language, - IN EFI_HII_HANDLE Handle, - IN OUT STRING_REF *Reference, - IN CHAR16 *NewString - ); - -/** - Allows a program to determine the primary languages that are supported - on a given handle. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - - @param Handle The handle on which the strings reside. - - @param LanguageString A string allocated by GetPrimaryLanguages() that - contains a list of all primary languages registered on the handle. - - @retval EFI_SUCCESS LanguageString was correctly returned. - - @retval EFI_INVALID_PARAMETER The Handle was unknown. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_GET_PRI_LANGUAGES) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_HANDLE Handle, - OUT EFI_STRING *LanguageString - ); - -/** - Allows a program to determine which secondary languages are supported - on a given handle for a given primary language. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - - @param Handle The handle on which the strings reside. - - @param PrimaryLanguage Pointer to a NULL-terminated string containing a single - ISO 639-2 language identifier, indicating the primary language. - - @param LanguageString A string allocated by GetSecondaryLanguages() - containing a list of all secondary languages registered on the handle. - - @retval EFI_SUCCESS LanguageString was correctly returned. - - @retval EFI_INVALID_PARAMETER The Handle was unknown. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_GET_SEC_LANGUAGES) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_HANDLE Handle, - IN CHAR16 *PrimaryLanguage, - OUT EFI_STRING *LanguageString - ); - -/** - Extracts a string from a package already registered with the EFI HII database. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - - @param Handle The handle on which the string resides. - - @param Token The string token assigned to the string. - - @param Raw If TRUE, the string is returned unedited in the internal - storage format described above. If false, the string returned is edited - by replacing with and by removing special characters such - as the prefix. - - @param LanguageString Pointer to a NULL-terminated string containing a - single ISO 639-2 language identifier, indicating the language to print. - If the LanguageString is empty (starts with a NULL), the default system - language will be used to determine the language. - - @param BufferLength Length of the StringBuffer. - - @param StringBuffer The buffer designed to receive the characters in the string. - - @retval EFI_SUCCESS StringBuffer is filled with a NULL-terminated string. - - @retval EFI_INVALID_PARAMETER The handle or string token is unknown. - - @retval EFI_BUFFER_TOO_SMALL The buffer provided was not large enough to - allow the entire string to be stored. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_GET_STRING) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_HANDLE Handle, - IN STRING_REF Token, - IN BOOLEAN Raw, - IN CHAR16 *LanguageString, - IN OUT UINTN *BufferLength, - OUT EFI_STRING StringBuffer - ); - -/** - Allows a program to extract a part of a string of not more than a given width. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - - @param Handle The handle on which the string resides. - - @param Token The string token assigned to the string. - - @param Index On input, the offset into the string where the line is to start. - On output, the index is updated to point to beyond the last character returned - in the call. - - @param LineWidth The maximum width of the line in units of narrow glyphs. - - @param LanguageString Pointer to a NULL-terminated string containing a - single ISO 639-2 language identifier, indicating the language to print. - - @param BufferLength Pointer to the length of the StringBuffer. - - @param StringBuffer The buffer designed to receive the characters in the string. - - @retval EFI_SUCCESS StringBuffer filled with characters that will fit on the line. - - @retval EFI_NOT_FOUND The font glyph for at least one of the characters in - the string is not in the font database. - - @retval EFI_BUFFER_TOO_SMALL The buffer provided was not large enough - to allow the entire string to be stored. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_GET_LINE) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_HANDLE Handle, - IN STRING_REF Token, - IN OUT UINT16 *Index, - IN UINT16 LineWidth, - IN CHAR16 *LanguageString, - IN OUT UINT16 *BufferLength, - OUT EFI_STRING StringBuffer - ); - -/** - Allows a program to extract a form or form package that has previously - been registered with the HII database. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - - @param Handle Handle on which the form resides. - - @param FormId The ID of the form to return. If the ID is zero, - the entire form package is returned. - - @param BufferLength On input, the length of the Buffer. On output, - the length of the returned buffer, - - @param Buffer The buffer designed to receive the form(s). - - @retval EFI_SUCCESS Buffer filled with the requested forms. BufferLength - was updated. - - @retval EFI_INVALID_PARAMETER The handle is unknown. - - @retval EFI_NOT_FOUND A form on the requested handle cannot be found with - the requested FormId. - - @retval EFI_BUFFER_TOO_SMALL The buffer provided was not large enough - to allow the form to be stored. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_GET_FORMS) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_HANDLE Handle, - IN EFI_FORM_ID FormId, - IN OUT UINTN *BufferLength, - OUT UINT8 *Buffer - ); - -/** - Extracts the defaults that are associated with a given handle in the HII database. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - - @param Handle The HII handle from which will have default data retrieved. - - @param DefaultMask The mask used to specify some type of default override when extracting - the default image data. - - @param VariablePackList A indirect pointer to the first entry of a link list with - type EFI_HII_VARIABLE_PACK_LIST. - - @retval EFI_SUCCESS The VariablePackList was populated with the appropriate - default setting data. - - @retval EFI_NOT_FOUND The IFR does not have any explicit or default map(s). - - @retval EFI_INVALID_PARAMETER The HII database entry associated with Handle - contain invalid data. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_GET_DEFAULT_IMAGE) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_HANDLE Handle, - IN UINTN DefaultMask, - OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList - ); - -/** - Allows the caller to update a form or form package that has previously been - registered with the EFI HII database. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - - @param Handle Handle of the package where the form to be updated resides. - - @param Label The label inside the form package where the update is to take place. - - @param AddData If TRUE, adding data at a given Label; otherwise, - if FALSE, removing data at a given Label. - - @param Data The buffer containing the new tags to insert after the Label - - @retval EFI_SUCCESS The form was updated with the new tags. - - @retval EFI_INVALID_PARAMETER The buffer for the buffer length does not - contain an integral number of tags. - - @retval EFI_NOT_FOUND The Handle, Label, or FormId was not found. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_UPDATE_FORM) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_HANDLE Handle, - IN EFI_FORM_LABEL Label, - IN BOOLEAN AddData, - IN EFI_HII_UPDATE_DATA *Data - ); - -/** - Retrieves the current keyboard layout. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - - @param DescriptorCount A pointer to the number of Descriptor entries being - described in the keyboard layout being retrieved. - - @param Descriptor A pointer to a buffer containing an array of EFI_KEY_DESCRIPTOR - entries. Each entry will reflect the definition of a specific physical key. - - @retval EFI_SUCCESS The keyboard layout was retrieved successfully. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_GET_KEYBOARD_LAYOUT) ( - IN EFI_HII_PROTOCOL *This, - OUT UINT16 *DescriptorCount, - OUT EFI_KEY_DESCRIPTOR *Descriptor - ); - -/** - @par Protocol Description: - The HII Protocol manages the HII database, which is a repository for data - having to do with fonts, strings, forms, keyboards, and other future human - interface items. - - @param NewPack - Extracts the various packs from a package list. - - @param RemovePack - Removes a package from the HII database. - - @param FindHandles - Determines the handles that are currently active in the database. - - @param ExportDatabase - Export the entire contents of the database to a buffer. - - @param TestString - Tests if all of the characters in a string have corresponding font characters. - - @param GetGlyph - Translates a Unicode character into the corresponding font glyph. - - @param GlyphToBlt - Converts a glyph value into a format that is ready for a UGA BLT command. - - @param NewString - Allows a new string to be added to an already existing string package. - - @param GetPrimaryLanguages - Allows a program to determine the primary languages that are supported - on a given handle. - - @param GetSecondaryLanguages - Allows a program to determine which secondary languages are supported - on a given handle for a given primary language. - - @param GetString - Extracts a string from a package that is already registered with the - EFI HII database. - - @param ResetString - Remove any new strings that were added after the initial string export - for this handle. - - @param GetLine - Allows a program to extract a part of a string of not more than a given width. - - @param GetForms - Allows a program to extract a form or form package that has been previously registered. - - @param GetDefaultImage - Allows a program to extract the nonvolatile image that represents the default storage image. - - @param UpdateForm - Allows a program to update a previously registered form. - - @param GetKeyboardLayout - Allows a program to extract the current keyboard layout. - -**/ -struct _EFI_HII_PROTOCOL { - EFI_HII_NEW_PACK NewPack; - EFI_HII_REMOVE_PACK RemovePack; - EFI_HII_FIND_HANDLES FindHandles; - EFI_HII_EXPORT ExportDatabase; - - EFI_HII_TEST_STRING TestString; - EFI_HII_GET_GLYPH GetGlyph; - EFI_HII_GLYPH_TO_BLT GlyphToBlt; - - EFI_HII_NEW_STRING NewString; - EFI_HII_GET_PRI_LANGUAGES GetPrimaryLanguages; - EFI_HII_GET_SEC_LANGUAGES GetSecondaryLanguages; - EFI_HII_GET_STRING GetString; - EFI_HII_RESET_STRINGS ResetStrings; - EFI_HII_GET_LINE GetLine; - EFI_HII_GET_FORMS GetForms; - EFI_HII_GET_DEFAULT_IMAGE GetDefaultImage; - EFI_HII_UPDATE_FORM UpdateForm; - - EFI_HII_GET_KEYBOARD_LAYOUT GetKeyboardLayout; -}; - -extern EFI_GUID gEfiHiiProtocolGuid; - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/Protocol/UgaDraw.h b/Tools/CodeTools/TianoTools/Include/Protocol/UgaDraw.h deleted file mode 100644 index 5586bdfffb..0000000000 --- a/Tools/CodeTools/TianoTools/Include/Protocol/UgaDraw.h +++ /dev/null @@ -1,168 +0,0 @@ -/** @file - UGA Draw protocol from the EFI 1.1 specification. - - Abstraction of a very simple graphics device. - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: UgaDraw.h - -**/ - -#ifndef __UGA_DRAW_H__ -#define __UGA_DRAW_H__ - -#define EFI_UGA_DRAW_PROTOCOL_GUID \ - { \ - 0x982c298b, 0xf4fa, 0x41cb, {0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39 } \ - } - -typedef struct _EFI_UGA_DRAW_PROTOCOL EFI_UGA_DRAW_PROTOCOL; - -/** - Return the current video mode information. - - @param This Protocol instance pointer. - @param HorizontalResolution Current video horizontal resolution in pixels - @param VerticalResolution Current video vertical resolution in pixels - @param ColorDepth Current video color depth in bits per pixel - @param RefreshRate Current video refresh rate in Hz. - - @retval EFI_SUCCESS Mode information returned. - @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode () - @retval EFI_INVALID_PARAMETER One of the input args was NULL. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_UGA_DRAW_PROTOCOL_GET_MODE) ( - IN EFI_UGA_DRAW_PROTOCOL *This, - OUT UINT32 *HorizontalResolution, - OUT UINT32 *VerticalResolution, - OUT UINT32 *ColorDepth, - OUT UINT32 *RefreshRate - ) -; - -/** - Return the current video mode information. - - @param This Protocol instance pointer. - @param HorizontalResolution Current video horizontal resolution in pixels - @param VerticalResolution Current video vertical resolution in pixels - @param ColorDepth Current video color depth in bits per pixel - @param RefreshRate Current video refresh rate in Hz. - - @retval EFI_SUCCESS Mode information returned. - @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode () - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_UGA_DRAW_PROTOCOL_SET_MODE) ( - IN EFI_UGA_DRAW_PROTOCOL *This, - IN UINT32 HorizontalResolution, - IN UINT32 VerticalResolution, - IN UINT32 ColorDepth, - IN UINT32 RefreshRate - ) -; - -typedef struct { - UINT8 Blue; - UINT8 Green; - UINT8 Red; - UINT8 Reserved; -} EFI_UGA_PIXEL; - -typedef union { - EFI_UGA_PIXEL Pixel; - UINT32 Raw; -} EFI_UGA_PIXEL_UNION; - -typedef enum { - EfiUgaVideoFill, - EfiUgaVideoToBltBuffer, - EfiUgaBltBufferToVideo, - EfiUgaVideoToVideo, - EfiUgaBltMax -} EFI_UGA_BLT_OPERATION; - -/** - Type specifying a pointer to a function to perform an UGA Blt operation. - - The following table defines actions for BltOperations: - - EfiUgaVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY) - directly to every pixel of the video display rectangle - (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). - Only one pixel will be used from the BltBuffer. Delta is NOT used. - - EfiUgaVideoToBltBuffer - Read data from the video display rectangle - (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in - the BltBuffer rectangle (DestinationX, DestinationY ) - (DestinationX + Width, DestinationY + Height). If DestinationX or - DestinationY is not zero then Delta must be set to the length in bytes - of a row in the BltBuffer. - - EfiUgaBltBufferToVideo - Write data from the BltBuffer rectangle - (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the - video display rectangle (DestinationX, DestinationY) - (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is - not zero then Delta must be set to the length in bytes of a row in the - BltBuffer. - - EfiUgaVideoToVideo - Copy from the video display rectangle (SourceX, SourceY) - (SourceX + Width, SourceY + Height) .to the video display rectangle - (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). - The BltBuffer and Delta are not used in this mode. - - - @param[in] This - Protocol instance pointer. - @param[in] BltBuffer - Buffer containing data to blit into video buffer. This - buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL) - @param[in] BltOperation - Operation to perform on BlitBuffer and video memory - @param[in] SourceX - X coordinate of source for the BltBuffer. - @param[in] SourceY - Y coordinate of source for the BltBuffer. - @param[in] DestinationX - X coordinate of destination for the BltBuffer. - @param[in] DestinationY - Y coordinate of destination for the BltBuffer. - @param[in] Width - Width of rectangle in BltBuffer in pixels. - @param[in] Height - Hight of rectangle in BltBuffer in pixels. - @param[in] Delta - OPTIONAL - - @retval EFI_SUCCESS - The Blt operation completed. - @retval EFI_INVALID_PARAMETER - BltOperation is not valid. - @retval EFI_DEVICE_ERROR - A hardware error occured writting to the video buffer. - ---*/ -typedef -EFI_STATUS -(EFIAPI *EFI_UGA_DRAW_PROTOCOL_BLT) ( - IN EFI_UGA_DRAW_PROTOCOL * This, - IN EFI_UGA_PIXEL * BltBuffer, OPTIONAL - IN EFI_UGA_BLT_OPERATION BltOperation, - IN UINTN SourceX, - IN UINTN SourceY, - IN UINTN DestinationX, - IN UINTN DestinationY, - IN UINTN Width, - IN UINTN Height, - IN UINTN Delta OPTIONAL - ); - -struct _EFI_UGA_DRAW_PROTOCOL { - EFI_UGA_DRAW_PROTOCOL_GET_MODE GetMode; - EFI_UGA_DRAW_PROTOCOL_SET_MODE SetMode; - EFI_UGA_DRAW_PROTOCOL_BLT Blt; -}; - -extern EFI_GUID gEfiUgaDrawProtocolGuid; - -#endif diff --git a/Tools/CodeTools/TianoTools/Include/X64/ProcessorBind.h b/Tools/CodeTools/TianoTools/Include/X64/ProcessorBind.h deleted file mode 100644 index f865ce8790..0000000000 --- a/Tools/CodeTools/TianoTools/Include/X64/ProcessorBind.h +++ /dev/null @@ -1,193 +0,0 @@ -/** @file - Processor or Compiler specific defines and types x64 (Intel(r) EM64T, AMD64). - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: ProcessorBind.h - -**/ - -#ifndef __PROCESSOR_BIND_H__ -#define __PROCESSOR_BIND_H__ - -// -// Define the processor type so other code can make processor based choices -// -#define MDE_CPU_X64 - - -// -// Make sure we are useing the correct packing rules per EFI specification -// -#pragma pack() - - -#if _MSC_EXTENSIONS - -// -// Disable warning that make it impossible to compile at /W4 -// This only works for Microsoft* tools -// - -// -// Disabling bitfield type checking warnings. -// -#pragma warning ( disable : 4214 ) - -// -// Disabling the unreferenced formal parameter warnings. -// -#pragma warning ( disable : 4100 ) - -// -// Disable slightly different base types warning as CHAR8 * can not be set -// to a constant string. -// -#pragma warning ( disable : 4057 ) - -// -// ASSERT(FALSE) or while (TRUE) are legal constructes so supress this warning -// -#pragma warning ( disable : 4127 ) - - -#endif - - -#if (__STDC_VERSION__ < 199901L) - // - // No ANSI C 2000 stdint.h integer width declarations, so define equivalents - // - - #if _MSC_EXTENSIONS - - - // - // use Microsoft C complier dependent interger width types - // - typedef unsigned __int64 UINT64; - typedef __int64 INT64; - typedef unsigned __int32 UINT32; - typedef __int32 INT32; - typedef unsigned short UINT16; - typedef unsigned short CHAR16; - typedef short INT16; - typedef unsigned char BOOLEAN; - typedef unsigned char UINT8; - typedef char CHAR8; - typedef char INT8; - #else - #ifdef _EFI_P64 - // - // P64 - is Intel Itanium(TM) speak for pointers being 64-bit and longs and ints - // are 32-bits - // - typedef unsigned long long UINT64; - typedef long long INT64; - typedef unsigned int UINT32; - typedef int INT32; - typedef unsigned short CHAR16; - typedef unsigned short UINT16; - typedef short INT16; - typedef unsigned char BOOLEAN; - typedef unsigned char UINT8; - typedef char CHAR8; - typedef char INT8; - #else - // - // Assume LP64 - longs and pointers are 64-bit. Ints are 32-bit. - // - typedef unsigned long UINT64; - typedef long INT64; - typedef unsigned int UINT32; - typedef int INT32; - typedef unsigned short UINT16; - typedef unsigned short CHAR16; - typedef short INT16; - typedef unsigned char BOOLEAN; - typedef unsigned char UINT8; - typedef char CHAR8; - typedef char INT8; - #endif - #endif - - #define UINT8_MAX 0xff - -#else - // - // Use ANSI C 2000 stdint.h integer width declarations - // - #include - typedef uint8_t BOOLEAN; - typedef int8_t INT8; - typedef uint8_t UINT8; - typedef int16_t INT16; - typedef uint16_t UINT16; - typedef int32_t INT32; - typedef uint32_t UINT32; - typedef int64_t INT64; - typedef uint64_t UINT64; - typedef char CHAR8; - typedef uint16_t CHAR16; - -#endif - -typedef UINT64 UINTN; -typedef INT64 INTN; - - -// -// Processor specific defines -// -#define MAX_BIT 0x8000000000000000 -#define MAX_2_BITS 0xC000000000000000 - -// -// Maximum legal Itanium-based address -// -#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF - -// -// Modifier to ensure that all protocol member functions and EFI intrinsics -// use the correct C calling convention. All protocol member functions and -// EFI intrinsics are required to modify thier member functions with EFIAPI. -// -#if _MSC_EXTENSIONS - /// - /// Define the standard calling convention reguardless of optimization level. - /// __cdecl is Microsoft* specific C extension. - /// - #define EFIAPI __cdecl -#elif __GNUC__ - /// - /// Define the standard calling convention reguardless of optimization level. - /// efidecl is an extension to GCC that supports the differnece between x64 - /// GCC ABI and x64 Microsoft* ABI. EFI is closer to the Microsoft* ABI and - /// EFIAPI makes sure the right ABI is used for public interfaces. - /// eficecl is a work in progress and we do not yet have the compiler - /// - #define EFIAPI -#else - #define EFIAPI -#endif - -// -// The Microsoft* C compiler can removed references to unreferenced data items -// if the /OPT:REF linker option is used. We defined a macro as this is a -// a non standard extension -// -#if _MSC_EXTENSIONS - #define GLOBAL_REMOVE_IF_UNREFERENCED __declspec(selectany) -#else - #define GLOBAL_REMOVE_IF_UNREFERENCED -#endif - -#endif - diff --git a/Tools/CodeTools/TianoTools/MakeDeps/MakeDeps.c b/Tools/CodeTools/TianoTools/MakeDeps/MakeDeps.c deleted file mode 100755 index 3943df0654..0000000000 --- a/Tools/CodeTools/TianoTools/MakeDeps/MakeDeps.c +++ /dev/null @@ -1,1284 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - MakeDeps.c - -Abstract: - - Recursively scan source files to find include files and emit them to - create dependency lists. - ---*/ - -#include -#include -#include -#include - -#include - -#include "EfiUtilityMsgs.h" -#include "CommonLib.h" - -// -// Structure to maintain a linked list of strings -// -typedef struct _STRING_LIST { - struct _STRING_LIST *Next; - char *Str; -} STRING_LIST; - -#define UTILITY_NAME "MakeDeps" - -#define MAX_LINE_LEN 2048 -#define MAX_PATH 2048 -#define START_NEST_DEPTH 1 -#define MAX_NEST_DEPTH 1000 // just in case we get in an endless loop. -// -// Define the relative paths used by the special #include macros -// -#define PROTOCOL_DIR_PATH "Protocol/" -#define GUID_DIR_PATH "Guid/" -#define ARCH_PROTOCOL_DIR_PATH "ArchProtocol/" -#define PPI_PROTOCOL_DIR_PATH "Ppi/" - -// -// Use this structure to keep track of all the special #include forms -// -typedef struct { - INT8 *IncludeMacroName; - INT8 *PathName; -} INCLUDE_MACRO_CONVERSION; - -// -// This data is used to convert #include macros like: -// #include EFI_PROTOCOL_DEFINITION(xxx) -// into -// #include Protocol/xxx/xxx.h -// -static const INCLUDE_MACRO_CONVERSION mMacroConversion[] = { - "EFI_PROTOCOL_DEFINITION", - PROTOCOL_DIR_PATH, - "EFI_GUID_DEFINITION", - GUID_DIR_PATH, - "EFI_ARCH_PROTOCOL_DEFINITION", - ARCH_PROTOCOL_DIR_PATH, - "EFI_PROTOCOL_PRODUCER", - PROTOCOL_DIR_PATH, - "EFI_PROTOCOL_CONSUMER", - PROTOCOL_DIR_PATH, - "EFI_PROTOCOL_DEPENDENCY", - PROTOCOL_DIR_PATH, - "EFI_ARCH_PROTOCOL_PRODUCER", - ARCH_PROTOCOL_DIR_PATH, - "EFI_ARCH_PROTOCOL_CONSUMER", - ARCH_PROTOCOL_DIR_PATH, - "EFI_ARCH_PROTOCOL_DEPENDENCY", - ARCH_PROTOCOL_DIR_PATH, - "EFI_PPI_DEFINITION", - PPI_PROTOCOL_DIR_PATH, - "EFI_PPI_PRODUCER", - PPI_PROTOCOL_DIR_PATH, - "EFI_PPI_CONSUMER", - PPI_PROTOCOL_DIR_PATH, - "EFI_PPI_DEPENDENCY", - PPI_PROTOCOL_DIR_PATH, - NULL, - NULL -}; - -typedef struct _SYMBOL { - struct _SYMBOL *Next; - INT8 *Name; - INT8 *Value; -} SYMBOL; - -// -// Here's all our globals. We need a linked list of include paths, a linked -// list of source files, a linked list of subdirectories (appended to each -// include path when searching), and flags to keep track of command-line options. -// -static struct { - STRING_LIST *IncludePaths; // all include paths to search - STRING_LIST *SourceFiles; // all source files to parse - STRING_LIST *SubDirs; // appended to each include path when searching - SYMBOL *SymbolTable; // for replacement strings - FILE *OutFptr; // output dependencies to this file - BOOLEAN Verbose; // for more detailed output - BOOLEAN IgnoreNotFound; // no warnings if files not found - BOOLEAN QuietMode; // -q - don't print missing file warnings - BOOLEAN NoSystem; // don't process #include files - BOOLEAN NeverFail; // always return success - BOOLEAN NoDupes; // to not list duplicate dependency files (for timing purposes) - BOOLEAN UseSumDeps; // use summary dependency files if found - INT8 TargetFileName[MAX_PATH]; // target object filename - INT8 SumDepsPath[MAX_PATH]; // path to summary files - INT8 *OutFileName; // -o option -} mGlobals; - -static -STATUS -ProcessFile ( - INT8 *TargetFileName, - INT8 *FileName, - UINT32 NestDepth, - STRING_LIST *ProcessedFiles - ); - -static -FILE * -FindFile ( - INT8 *FileName, - UINT32 FileNameLen - ); - -static -void -PrintDependency ( - INT8 *Target, - INT8 *DependentFile - ); - -static -void -ReplaceSymbols ( - INT8 *Str, - UINT32 StrSize - ); - -static -STATUS -ProcessArgs ( - int Argc, - char *Argv[] - ); - -static -void -Usage ( - VOID - ); - -static -void -FreeLists ( - VOID - ); - -int -main ( - int Argc, - char *Argv[] - ) -/*++ - -Routine Description: - - Call the routine to parse the command-line options, then process each file - to build dependencies. - -Arguments: - - Argc - Standard C main() argc. - Argv - Standard C main() argv. - -Returns: - - 0 if successful - nonzero otherwise - ---*/ -{ - STRING_LIST *File; - STRING_LIST ProcessedFiles; - STRING_LIST *TempList; - STATUS Status; - INT8 *Cptr; - INT8 TargetFileName[MAX_PATH]; - - SetUtilityName (UTILITY_NAME); - // - // Process the command-line arguments - // - Status = ProcessArgs (Argc, Argv); - if (Status != STATUS_SUCCESS) { - return STATUS_ERROR; - } - // - // Go through the list of source files and process each. - // - memset (&ProcessedFiles, 0, sizeof (STRING_LIST)); - File = mGlobals.SourceFiles; - while (File != NULL) { - // - // Clear out our list of processed files - // - TempList = ProcessedFiles.Next; - while (ProcessedFiles.Next != NULL) { - TempList = ProcessedFiles.Next->Next; - free (ProcessedFiles.Next->Str); - free (ProcessedFiles.Next); - ProcessedFiles.Next = TempList; - } - // - // Replace filename extension with ".obj" if they did not - // specifically specify the target file - // - if (mGlobals.TargetFileName[0] == 0) { - strcpy (TargetFileName, File->Str); - // - // Find the .extension - // - for (Cptr = TargetFileName + strlen (TargetFileName) - 1; - (*Cptr != '\\' && *Cptr != '/') && (Cptr > TargetFileName) && (*Cptr != '.'); - Cptr-- - ) - ; - if (Cptr == TargetFileName) { - Error (NULL, 0, 0, File->Str, "could not locate extension in filename"); - goto Finish; - } - // - // Tack on the ".obj" - // - strcpy (Cptr, ".obj"); - } else { - // - // Copy the target filename they specified - // - strcpy (TargetFileName, mGlobals.TargetFileName); - } - - Status = ProcessFile (TargetFileName, File->Str, START_NEST_DEPTH, &ProcessedFiles); - if (Status != STATUS_SUCCESS) { - goto Finish; - } - - File = File->Next; - } - -Finish: - // - // Free up memory - // - FreeLists (); - // - // Free up our processed files list - // - TempList = ProcessedFiles.Next; - while (ProcessedFiles.Next != NULL) { - TempList = ProcessedFiles.Next->Next; - free (ProcessedFiles.Next->Str); - free (ProcessedFiles.Next); - ProcessedFiles.Next = TempList; - } - // - // Close our output file - // - if ((mGlobals.OutFptr != stdout) && (mGlobals.OutFptr != NULL)) { - fprintf(mGlobals.OutFptr, "\t\n"); // file ending flag - fclose (mGlobals.OutFptr); - } - - if (mGlobals.NeverFail) { - return STATUS_SUCCESS; - } - // - // If any errors, then delete our output so that it will get created - // again on a rebuild. - // - if ((GetUtilityStatus () == STATUS_ERROR) && (mGlobals.OutFileName != NULL)) { - remove (mGlobals.OutFileName); - } - - return GetUtilityStatus (); -} - -static -STATUS -ProcessFile ( - INT8 *TargetFileName, - INT8 *FileName, - UINT32 NestDepth, - STRING_LIST *ProcessedFiles - ) -/*++ - -Routine Description: - - Given a source file name, open the file and parse all #include lines. - -Arguments: - - TargetFileName - name of the usually .obj target - FileName - name of the file to process - NestDepth - how deep we're nested in includes - ProcessedFiles - list of processed files. - -Returns: - - standard status. - ---*/ -{ - FILE *Fptr; - INT8 Line[MAX_LINE_LEN]; - INT8 *Cptr; - INT8 *EndPtr; - INT8 *SaveCptr; - INT8 EndChar; - INT8 FileNameCopy[MAX_PATH]; - INT8 MacroIncludeFileName[MAX_LINE_LEN]; - INT8 SumDepsFile[MAX_PATH]; - STATUS Status; - UINT32 Index; - UINT32 LineNum; - STRING_LIST *ListPtr; - - Status = STATUS_SUCCESS; - Fptr = NULL; - // - // Print the file being processed. Indent so you can tell the include nesting - // depth. - // - if (mGlobals.Verbose) { - fprintf (stdout, "%*cProcessing file '%s'\n", NestDepth * 2, ' ', FileName); - } - // - // If we're using summary dependency files, and a matching .dep file is - // found for this file, then just emit the summary dependency file as - // a dependency and return. - // - if (mGlobals.UseSumDeps) { - strcpy (SumDepsFile, mGlobals.SumDepsPath); - strcat (SumDepsFile, FileName); - for (Cptr = SumDepsFile + strlen (SumDepsFile) - 1; - (*Cptr != '\\' && *Cptr != '/') && (Cptr > SumDepsFile) && (*Cptr != '.'); - Cptr-- - ) - ; - if (*Cptr == '.') { - strcpy (Cptr, ".dep"); - } else { - strcat (SumDepsFile, ".dep"); - } - // - // See if the summary dep file exists. Could use _stat() function, but - // it's less portable. - // - if ((Fptr = fopen (SumDepsFile, "r")) != NULL) { - PrintDependency (TargetFileName, SumDepsFile); - return STATUS_SUCCESS; - } - } - // - // If we're not doing duplicates, and we've already seen this filename, - // then return - // - if (mGlobals.NoDupes) { - for (ListPtr = ProcessedFiles->Next; ListPtr != NULL; ListPtr = ListPtr->Next) { - if (stricmp (FileName, ListPtr->Str) == 0) { - break; - } - } - // - // If we found a match, we're done. If we didn't, create a new element - // and add it to the list. - // - if (ListPtr != NULL) { - // - // Print a message if verbose mode - // - if (mGlobals.Verbose) { - DebugMsg (NULL, 0, 0, FileName, "duplicate include -- not processed again"); - } - - return STATUS_SUCCESS; - } - - ListPtr = malloc (sizeof (STRING_LIST)); - ListPtr->Str = malloc (strlen (FileName) + 1); - strcpy (ListPtr->Str, FileName); - ListPtr->Next = ProcessedFiles->Next; - ProcessedFiles->Next = ListPtr; - } - - // - // Make sure we didn't exceed our maximum nesting depth - // - if (NestDepth > MAX_NEST_DEPTH) { - Error (NULL, 0, 0, FileName, "max nesting depth exceeded on file"); - goto Finish; - } - // - // Make a local copy of the filename. Then we can manipulate it - // if we have to. - // - strcpy (FileNameCopy, FileName); - // - // Try to open the file locally - // - if ((Fptr = fopen (FileNameCopy, "r")) == NULL) { - // - // Try to find it among the paths. - // - Fptr = FindFile (FileNameCopy, sizeof (FileNameCopy)); - if (Fptr == NULL) { - // - // If this is not the top-level file, and the command-line argument - // said to ignore missing files, then return ok - // - if (NestDepth != START_NEST_DEPTH) { - if (mGlobals.IgnoreNotFound) { - if (!mGlobals.QuietMode) { - DebugMsg (NULL, 0, 0, FileNameCopy, "could not find file"); - } - - return STATUS_SUCCESS; - } else { - Error (NULL, 0, 0, FileNameCopy, "could not find file"); - return STATUS_ERROR; - } - } else { - // - // Top-level (first) file. Emit an error. - // - Error (NULL, 0, 0, FileNameCopy, "could not find file"); - return STATUS_ERROR; - } - } - } - // - // Print the dependency, with string substitution - // - PrintDependency (TargetFileName, FileNameCopy); - - // - // Now read in lines and find all #include lines. Allow them to indent, and - // to put spaces between the # and include. - // - LineNum = 0; - while ((fgets (Line, sizeof (Line), Fptr) != NULL) && (Status == STATUS_SUCCESS)) { - LineNum++; - Cptr = Line; - // - // Skip preceeding spaces on the line - // - while (*Cptr && (isspace (*Cptr))) { - Cptr++; - } - // - // Check for # character - // - if (*Cptr == '#') { - Cptr++; - // - // Check for "include" - // - while (*Cptr && (isspace (*Cptr))) { - Cptr++; - } - - if (strncmp (Cptr, "include", 7) == 0) { - // - // Skip over "include" and move on to filename as "file" or - // - Cptr += 7; - while (*Cptr && (isspace (*Cptr))) { - Cptr++; - } - - if (*Cptr == '<') { - EndChar = '>'; - } else if (*Cptr == '"') { - EndChar = '"'; - } else { - // - // Handle special #include MACRO_NAME(file) - // Set EndChar to null so we fall through on processing below. - // - EndChar = 0; - // - // Look for all the special include macros and convert accordingly. - // - for (Index = 0; mMacroConversion[Index].IncludeMacroName != NULL; Index++) { - // - // Save the start of the string in case some macros are substrings - // of others. - // - SaveCptr = Cptr; - if (strncmp ( - Cptr, - mMacroConversion[Index].IncludeMacroName, - strlen (mMacroConversion[Index].IncludeMacroName) - ) == 0) { - // - // Skip over the macro name - // - Cptr += strlen (mMacroConversion[Index].IncludeMacroName); - // - // Skip over open parenthesis, blank spaces, then find closing - // parenthesis or blank space - // - while (*Cptr && (isspace (*Cptr))) { - Cptr++; - } - - if (*Cptr == '(') { - Cptr++; - while (*Cptr && (isspace (*Cptr))) { - Cptr++; - } - - EndPtr = Cptr; - while (*EndPtr && !isspace (*EndPtr) && (*EndPtr != ')')) { - EndPtr++; - } - - *EndPtr = 0; - // - // Create the path - // - strcpy (MacroIncludeFileName, mMacroConversion[Index].PathName); - strcat (MacroIncludeFileName, Cptr); - strcat (MacroIncludeFileName, "/"); - strcat (MacroIncludeFileName, Cptr); - strcat (MacroIncludeFileName, ".h"); - // - // Process immediately, then break out of the outside FOR loop. - // - Status = ProcessFile (TargetFileName, MacroIncludeFileName, NestDepth + 1, ProcessedFiles); - break; - } - } - // - // Restore the start - // - Cptr = SaveCptr; - } - // - // Don't recognize the include line? Ignore it. We assume that the - // file compiles anyway. - // - if (mMacroConversion[Index].IncludeMacroName == NULL) { - // - // Warning (FileNameCopy, LineNum, 0, "could not parse line", NULL); - // Status = STATUS_WARNING; - // - } - } - // - // Process "normal" includes. If the endchar is 0, then the - // file has already been processed. Otherwise look for the - // endchar > or ", and process the include file. - // - if (EndChar != 0) { - Cptr++; - EndPtr = Cptr; - while (*EndPtr && (*EndPtr != EndChar)) { - EndPtr++; - } - - if (*EndPtr == EndChar) { - // - // If we're processing it, do it - // - if ((EndChar != '>') || (!mGlobals.NoSystem)) { - // - // Null terminate the filename and try to process it. - // - *EndPtr = 0; - Status = ProcessFile (TargetFileName, Cptr, NestDepth + 1, ProcessedFiles); - } - } else { - Warning (FileNameCopy, LineNum, 0, "malformed include", "missing closing %c", EndChar); - Status = STATUS_WARNING; - goto Finish; - } - } - } - } - } - -Finish: - // - // Close open files and return status - // - if (Fptr != NULL) { - fclose (Fptr); - } - - return Status; -} - -static -void -PrintDependency ( - INT8 *TargetFileName, - INT8 *DependentFile - ) -/*++ - -Routine Description: - - Given a target (.obj) file name, and a dependent file name, do any string - substitutions (per the command line options) on the file names, then - print the dependency line of form: - - TargetFileName : DependentFile - -Arguments: - - TargetFileName - build target file name - DependentFile - file on which TargetFileName depends - -Returns: - - None - ---*/ -{ - INT8 Str[MAX_PATH]; - - // - // Go through the symbols and do replacements - // - strcpy (Str, DependentFile); - ReplaceSymbols (Str, sizeof (Str)); - fprintf (mGlobals.OutFptr, "%s\n", Str); -} - -static -void -ReplaceSymbols ( - INT8 *Str, - UINT32 StrSize - ) -{ - SYMBOL *Sym; - INT8 StrCopy[MAX_LINE_LEN]; - INT8 *From; - INT8 *To; - BOOLEAN Replaced; - - // - // Go through the entire string to look for replacement strings at - // every position. - // - From = Str; - To = StrCopy; - while (*From) { - // - // Copy the character - // - *To = *From; - Replaced = FALSE; - // - // Go through each symbol and try to find a string substitution - // - Sym = mGlobals.SymbolTable; - while (Sym != NULL) { - if (strnicmp (From, Sym->Value, strlen (Sym->Value)) == 0) { - // - // Replace the string, then advance the pointers past the - // replaced strings - // - strcpy (To, Sym->Name); - To += strlen (Sym->Name); - From += strlen (Sym->Value); - Replaced = TRUE; - // - // Break from the while() - // - break; - } else { - Sym = Sym->Next; - } - } - - if (!Replaced) { - From++; - To++; - } - } - // - // Null terminate, and return it - // - *To = 0; - if (strlen (StrCopy) < StrSize) { - strcpy (Str, StrCopy); - } -} -// -// Given a filename, try to find it along the include paths. -// -static -FILE * -FindFile ( - INT8 *FileName, - UINT32 FileNameLen - ) -{ - FILE *Fptr; - STRING_LIST *List; - STRING_LIST *SubDir; - INT8 FullFileName[MAX_PATH * 2]; - - // - // Traverse the list of paths and try to find the file - // - List = mGlobals.IncludePaths; - while (List != NULL) { - // - // Put the path and filename together - // - if (strlen (List->Str) + strlen (FileName) + 1 > sizeof (FullFileName)) { - Error ( - __FILE__, - __LINE__, - 0, - "application error", - "cannot concatenate '%s' + '%s'", - List->Str, - FileName - ); - return NULL; - } - // - // Append the filename to this include path and try to open the file. - // - strcpy (FullFileName, List->Str); - strcat (FullFileName, FileName); - if ((Fptr = fopen (FullFileName, "r")) != NULL) { - // - // Return the file name - // - if (FileNameLen <= strlen (FullFileName)) { - Error (__FILE__, __LINE__, 0, "application error", "internal path name of insufficient length"); - // - // fprintf (stdout, "File length > %d: %s\n", FileNameLen, FullFileName); - // - return NULL; - } - - strcpy (FileName, FullFileName); - return Fptr; - } - // - // Didn't find it there. Now try this directory with every subdirectory - // the user specified on the command line - // - for (SubDir = mGlobals.SubDirs; SubDir != NULL; SubDir = SubDir->Next) { - strcpy (FullFileName, List->Str); - strcat (FullFileName, SubDir->Str); - strcat (FullFileName, FileName); - if ((Fptr = fopen (FullFileName, "r")) != NULL) { - // - // Return the file name - // - if (FileNameLen <= strlen (FullFileName)) { - Error (__FILE__, __LINE__, 0, "application error", "internal path name of insufficient length"); - return NULL; - } - - strcpy (FileName, FullFileName); - return Fptr; - } - } - - List = List->Next; - } - // - // Not found - // - return NULL; -} -// -// Process the command-line arguments -// -static -STATUS -ProcessArgs ( - int Argc, - char *Argv[] - ) -{ - STRING_LIST *NewList; - STRING_LIST *LastIncludePath; - STRING_LIST *LastSourceFile; - SYMBOL *Symbol; - int Index; - // - // Clear our globals - // - memset ((char *) &mGlobals, 0, sizeof (mGlobals)); - mGlobals.NoDupes = TRUE; - // - // Skip program name - // - Argc--; - Argv++; - // - // Initialize locals - // - LastIncludePath = NULL; - LastSourceFile = NULL; - // - // Process until no more args - // - while (Argc) { - // - // -i path add include search path - // - if (stricmp (Argv[0], "-i") == 0) { - // - // check for one more arg - // - if (Argc > 1) { - // - // Allocate memory for a new list element, fill it in, and - // add it to our list of include paths. Always make sure it - // has a "\" on the end of it. - // - NewList = malloc (sizeof (STRING_LIST)); - if (NewList == NULL) { - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - NewList->Next = NULL; - NewList->Str = malloc (strlen (Argv[1]) + 2); - if (NewList->Str == NULL) { - free (NewList); - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - strcpy (NewList->Str, Argv[1]); - if (NewList->Str[strlen (NewList->Str) - 1] != '\\' && NewList->Str[strlen (NewList->Str) - 1] != '/') { - strcat (NewList->Str, "/"); - } - // - // Add it to the end of the our list of include paths - // - if (mGlobals.IncludePaths == NULL) { - mGlobals.IncludePaths = NewList; - } else { - LastIncludePath->Next = NewList; - } - - LastIncludePath = NewList; - // - // fprintf (stdout, "Added path: %s\n", NewList->Str); - // - } else { - Error (NULL, 0, 0, Argv[0], "option requires an include path"); - Usage (); - return STATUS_ERROR; - } - - Argc--; - Argv++; - } else if (stricmp (Argv[0], "-f") == 0) { - // - // Check for one more arg - // - if (Argc > 1) { - // - // Allocate memory for a new list element, fill it in, and - // add it to our list of source files. - // - NewList = malloc (sizeof (STRING_LIST)); - if (NewList == NULL) { - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - NewList->Next = NULL; - // - // Allocate space to replace ".c" with ".obj", plus null termination - // - NewList->Str = malloc (strlen (Argv[1]) + 5); - if (NewList->Str == NULL) { - free (NewList); - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - strcpy (NewList->Str, Argv[1]); - if (mGlobals.SourceFiles == NULL) { - mGlobals.SourceFiles = NewList; - } else { - LastSourceFile->Next = NewList; - } - - LastSourceFile = NewList; - } else { - Error (NULL, 0, 0, Argv[0], "option requires a file name"); - Usage (); - return STATUS_ERROR; - } - // - // The C compiler first looks for #include files in the directory where - // the source file came from. Add the file's source directory to the - // list of include paths. - // - NewList = malloc (sizeof (STRING_LIST)); - if (NewList == NULL) { - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - NewList->Next = NULL; - NewList->Str = malloc (strlen (Argv[1]) + 3); - if (NewList->Str == NULL) { - free (NewList); - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - strcpy (NewList->Str, Argv[1]); - // - // Back up in the source file name to the last backslash and terminate after it. - // - for (Index = strlen (NewList->Str) - 1; (Index > 0) && (NewList->Str[Index] != '\\' && NewList->Str[Index] != '/'); Index--) - ; - if (Index < 0) { - strcpy (NewList->Str, "./"); - } else { - NewList->Str[Index + 1] = 0; - } - // - // Add it to the end of the our list of include paths - // - if (mGlobals.IncludePaths == NULL) { - mGlobals.IncludePaths = NewList; - } else { - LastIncludePath->Next = NewList; - } - - if (mGlobals.Verbose) { - fprintf (stdout, "Adding include path: %s\n", NewList->Str); - } - - LastIncludePath = NewList; - Argc--; - Argv++; - } else if (stricmp (Argv[0], "-s") == 0) { - // - // -s subdir add subdirectory subdir to list of subdirecties to scan. - // Check for one more arg first. - // - if (Argc > 1) { - // - // Allocate memory for a new list element, fill it in, and - // add it to our list of subdirectory include paths. Always - // make sure it has a "\" on the end of it. - // - NewList = malloc (sizeof (STRING_LIST)); - if (NewList == NULL) { - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - NewList->Str = malloc (strlen (Argv[1]) + 2); - if (NewList->Str == NULL) { - free (NewList); - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - strcpy (NewList->Str, Argv[1]); - if (NewList->Str[strlen (NewList->Str) - 1] != '\\' && NewList->Str[strlen (NewList->Str) - 1] != '/') { - strcat (NewList->Str, "/"); - } - - NewList->Next = mGlobals.SubDirs; - mGlobals.SubDirs = NewList; - } else { - Error (NULL, 0, 0, Argv[0], "option requires a subdirectory name"); - Usage (); - return STATUS_ERROR; - } - - Argc--; - Argv++; - } else if (stricmp (Argv[0], "-sub") == 0) { - // - // -sub symname symvalue to do string substitution in the output - // - if (Argc > 2) { - // - // Allocate memory for the symbol object - // - Symbol = malloc (sizeof (SYMBOL)); - if (Symbol == NULL) { - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - // - // Allocate memory for the symbol name and value, then save copies - // - Symbol->Name = malloc (strlen (Argv[1]) + 1); - if (Symbol->Name == NULL) { - free (Symbol); - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - strcpy (Symbol->Name, Argv[1]); - Symbol->Value = malloc (strlen (Argv[2]) + 1); - if (Symbol->Value == NULL) { - free (Symbol->Name); - free (Symbol); - Error (__FILE__, __LINE__, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - strcpy (Symbol->Value, Argv[2]); - // - // Add it to the list - // - Symbol->Next = mGlobals.SymbolTable; - mGlobals.SymbolTable = Symbol; - } else { - Error (NULL, 0, 0, Argv[0], "option requires a symbol name and value"); - Usage (); - return STATUS_ERROR; - } - // - // Skip over args - // - Argc -= 2; - Argv += 2; - } else if (stricmp (Argv[0], "-nosystem") == 0) { - mGlobals.NoSystem = TRUE; - } else if (stricmp (Argv[0], "-nodupes") == 0) { - mGlobals.NoDupes = TRUE; - } else if (stricmp (Argv[0], "-nodups") == 0) { - mGlobals.NoDupes = TRUE; - } else if (stricmp (Argv[0], "-target") == 0) { - // - // -target TargetFileName - Target object file (only one allowed right - // now) is TargetFileName rather than SourceFile.obj - // - if (Argc > 1) { - strcpy (mGlobals.TargetFileName, Argv[1]); - } else { - Error (NULL, 0, 0, Argv[0], "option requires a target file name"); - Usage (); - return STATUS_ERROR; - } - - Argc--; - Argv++; - } else if (stricmp (Argv[0], "-usesumdeps") == 0) { - // - // -usesumdeps Path - if we find an included file xxx.h, and file - // Path/xxx.dep exists, list Path/xxx.dep as a dependency rather than - // xxx.h and don't parse xxx.h. This allows you to create a dependency - // file for a commonly included file, and have its dependency file updated - // only if its included files are updated. Then anyone else including this - // common include file can simply have a dependency on that file's .dep file - // rather than on all the files included by it. Confusing enough? - // - mGlobals.UseSumDeps = 1; - if (Argc > 1) { - strcpy (mGlobals.SumDepsPath, Argv[1]); - // - // Add slash on end if not there - // - if (mGlobals.SumDepsPath[strlen (mGlobals.SumDepsPath) - 1] != '\\' && mGlobals.SumDepsPath[strlen (mGlobals.SumDepsPath) - 1] != '/') { - strcat (mGlobals.SumDepsPath, "/"); - } - } else { - Error (NULL, 0, 0, Argv[0], "option requires path to summary dependency files"); - Usage (); - return STATUS_ERROR; - } - - Argc--; - Argv++; - - } else if (stricmp (Argv[0], "-o") == 0) { - // - // -o OutputFileName - specify an output filename for dependency list - // check for one more arg - // - if (Argc > 1) { - // - // Try to open the file - // - if ((mGlobals.OutFptr = fopen (Argv[1], "w")) == NULL) { - Error (NULL, 0, 0, Argv[1], "could not open file for writing"); - return STATUS_ERROR; - } - - mGlobals.OutFileName = Argv[1]; - } else { - Error (NULL, 0, 0, Argv[0], "option requires output file name"); - Usage (); - return STATUS_ERROR; - } - - Argc--; - Argv++; - } else if (stricmp (Argv[0], "-v") == 0) { - mGlobals.Verbose = TRUE; - } else if (stricmp (Argv[0], "-neverfail") == 0) { - mGlobals.NeverFail = TRUE; - } else if (stricmp (Argv[0], "-q") == 0) { - mGlobals.QuietMode = TRUE; - } else if (stricmp (Argv[0], "-ignorenotfound") == 0) { - mGlobals.IgnoreNotFound = TRUE; - } else if ((stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) { - Usage (); - return STATUS_ERROR; - } else { - Error (NULL, 0, 0, Argv[0], "unrecognized option"); - Usage (); - return STATUS_ERROR; - } - - Argc--; - Argv++; - } - // - // Had to specify at least one source file - // - if (mGlobals.SourceFiles == NULL) { - Error (NULL, 0, 0, "must specify one source file name", NULL); - Usage (); - return STATUS_ERROR; - } - // - // Assume output to stdout if not specified - // - if (mGlobals.OutFptr == NULL) { - mGlobals.OutFptr = stdout; - } - - return STATUS_SUCCESS; -} -// -// Free the global string lists we allocated memory for -// -static -void -FreeLists ( - VOID - ) -{ - STRING_LIST *Temp; - SYMBOL *NextSym; - - // - // printf ("Free lists....."); - // - // Traverse the include paths, freeing each - // printf ("freeing include paths\n"); - // - while (mGlobals.IncludePaths != NULL) { - Temp = mGlobals.IncludePaths->Next; - // - // printf ("Freeing include path string '%s' at 0x%X\n", - // mGlobals.IncludePaths->Str, (int)(mGlobals.IncludePaths->Str)); - // - free (mGlobals.IncludePaths->Str); - // - // printf ("Freeing include path object at 0x%X\n", (int)(mGlobals.IncludePaths)); - // - free (mGlobals.IncludePaths); - mGlobals.IncludePaths = Temp; - } - // - // Traverse the source files, freeing each - // - while (mGlobals.SourceFiles != NULL) { - Temp = mGlobals.SourceFiles->Next; - free (mGlobals.SourceFiles->Str); - free (mGlobals.SourceFiles); - mGlobals.SourceFiles = Temp; - } - // - // Traverse the subdirectory list, freeing each - // - while (mGlobals.SubDirs != NULL) { - Temp = mGlobals.SubDirs->Next; - free (mGlobals.SubDirs->Str); - free (mGlobals.SubDirs); - mGlobals.SubDirs = Temp; - } - // - // Free the symbol table - // - while (mGlobals.SymbolTable != NULL) { - NextSym = mGlobals.SymbolTable->Next; - free (mGlobals.SymbolTable->Name); - free (mGlobals.SymbolTable->Value); - mGlobals.SymbolTable = NextSym; - } - // - // printf ("done\n"); - // -} - -static -void -Usage ( - VOID - ) -/*++ - -Routine Description: - - Print usage information for this utility. - -Arguments: - - None. - -Returns: - - Nothing. - ---*/ -{ - int Index; - static const char *Str[] = { - UTILITY_NAME " -- make dependencies", - " Usage: MakeDeps [options]", - " Options include:", - " -h or -? for this help information", - " -f SourceFile add SourceFile to list of files to scan", - " -i IncludePath add IncludePath to list of search paths", - " -o OutputFile write output dependencies to OutputFile", - " -s SubDir for each IncludePath, also search IncludePath\\SubDir", - " -v for verbose output", - " -ignorenotfound don't warn for files not found", - " -target Target for single SourceFile, target is Target, not SourceFile.obj", - " -q quiet mode to not report files not found if ignored", - " -sub sym str replace all occurrances of 'str' with 'sym' in the output", - " -nosystem not process system files", - " -neverfail always return a success return code", - // - // " -nodupes keep track of include files, don't rescan duplicates", - // - " -usesumdeps path use summary dependency files in 'path' directory.", - "", - NULL - }; - for (Index = 0; Str[Index] != NULL; Index++) { - fprintf (stdout, "%s\n", Str[Index]); - } -} diff --git a/Tools/CodeTools/TianoTools/MakeDeps/build.xml b/Tools/CodeTools/TianoTools/MakeDeps/build.xml deleted file mode 100755 index 60c34c2dfa..0000000000 --- a/Tools/CodeTools/TianoTools/MakeDeps/build.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/ModifyInf/ModifyInf.c b/Tools/CodeTools/TianoTools/ModifyInf/ModifyInf.c deleted file mode 100755 index 6008feb981..0000000000 --- a/Tools/CodeTools/TianoTools/ModifyInf/ModifyInf.c +++ /dev/null @@ -1,321 +0,0 @@ -/*++ - -Copyright (c) 1999-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -Module Name: - - ModifyInf.c - -Abstract: - - It is a simple tool to modify some fields in a FV inf file - and output a new FV inf file. - ---*/ - -#include "stdio.h" -#include "string.h" - -// -// Read a line into buffer including '\r\n' -// -int -ReadLine ( - char *LineBuffer, - FILE *fp - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - LineBuffer - GC_TODO: add argument description - fp - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - int CharC; - char *Line; - - Line = LineBuffer; - - while ((CharC = fgetc (fp)) != EOF) { - *Line++ = (char) CharC; - if (CharC == 0x0a) { - break; - } - } - - *Line = 0; - - if (CharC == EOF) { - return 0; - } else { - return 1; - } - -} -// -// Write a line into output file -// -int -WriteLine ( - char *Line, - FILE *fp - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - Line - GC_TODO: add argument description - fp - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - fwrite (Line, strlen (Line), 1, fp); - return 0; -} -// -// Apply patterns to a line -// Currently there are 2 patterns to support -// '==' replace a field value with a new value -// '+=' append a string at the end of original line -// '-' prevent the line from applying any patterns -// it has the highest priority -// -int -ApplyPattern ( - char *Line, - char *argv[], - int argc - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - Line - GC_TODO: add argument description - ] - GC_TODO: add argument description - argc - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - static char Section[256]; - char PatternBuffer[256]; - char *Pattern; - char *Pattern1; - char *Pattern2; - int PatternNum; - char *Ptr; - - Pattern = PatternBuffer; - - PatternNum = argc; - - // - // For section field - // record current scope section into static buffer - // - Ptr = Line; - if (*Ptr == '[') { - while (*Ptr != ']') { - if (!(*Ptr++)) { - return -1; - } - } - - strcpy (Section, Line); - Section[Ptr - Line + 1] = 0; - } - // - // Apply each pattern on the line - // - while (PatternNum-- > 3) { - - strcpy (Pattern, argv[PatternNum]); - - // - // For pattern '-' - // keep it unmodified by other patterns - // - if (*Pattern == '-') { - if (strstr (Line, Pattern + 1)) { - return 0; - } else { - continue; - } - } - // - // For other patterns - // get its section at first if it has - // - if (*Pattern == '[') { - if (strncmp (Section, Pattern, strlen (Section))) { - // - // This pattern can't be appied for current section - // - continue; - } - // - // Strip the section field - // - while (*Pattern != ']') { - if (!(*Pattern++)) { - return -1; - } - } - - Pattern++; - } - // - // Apply patterns - // - Pattern1 = strstr (Pattern, "=="); - Pattern2 = strstr (Pattern, "+="); - if (Pattern1) { - // - // For pattern '==' - // replace the field value with a new string - // - if (!strncmp (Line, Pattern, Pattern1 - Pattern)) { - Pattern1 += 2; - Ptr = strstr (Line, "="); - if (!Ptr) { - return -1; - } - - while (*(++Ptr) == ' ') - ; - *Ptr = 0; - strcat (Line, Pattern1); - strcat (Line, "\r\n"); - } - } else if (Pattern2) { - // - // For pattern '+=' - // append a string at end of the original string - // - if (!strncmp (Line, Pattern, Pattern2 - Pattern)) { - Pattern2 += 2; - Ptr = Line; - while (*Ptr != 0x0D && *Ptr != 0x0A) { - Ptr++; - } - - *Ptr = 0; - strcat (Line, Pattern2); - strcat (Line, "\r\n"); - } - } - } - - return 0; -} - -void -Usage ( - void - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - None - -Returns: - - GC_TODO: add return values - ---*/ -{ - printf ("ModifyInf InputFVInfFileName OutputFVInfFileName [Pattern strings]\r\n"); -} - -int -main ( - int argc, - char*argv[] - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - argc - GC_TODO: add argument description - ] - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - char LineBuffer[256]; - FILE *fpin; - FILE *fpout; - - if (argc < 3) { - Usage (); - return -1; - } - - fpin = fopen (argv[1], "rb"); - if (!fpin) { - printf ("Can't open input file!\r\n"); - return -1; - } - - fpout = fopen (argv[2], "wb"); - if (!fpout) { - fclose (fpin); - printf ("Can't create output file!\r\n"); - return -1; - } - - while (ReadLine (LineBuffer, fpin)) { - ApplyPattern (LineBuffer, argv, argc); - WriteLine (LineBuffer, fpout); - } - - fclose (fpin); - fclose (fpout); - - return 0; -} diff --git a/Tools/CodeTools/TianoTools/ModifyInf/build.xml b/Tools/CodeTools/TianoTools/ModifyInf/build.xml deleted file mode 100644 index a695ae0e80..0000000000 --- a/Tools/CodeTools/TianoTools/ModifyInf/build.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/Pccts/CHANGES_FROM_131.txt b/Tools/CodeTools/TianoTools/Pccts/CHANGES_FROM_131.txt deleted file mode 100644 index 500d84f2e8..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/CHANGES_FROM_131.txt +++ /dev/null @@ -1,522 +0,0 @@ -CHANGES FROM 1.31 - -This file contains the migration of PCCTS from 1.31 in the order that -changes were made. 1.32b7 is the last beta before full 1.32. -Terence Parr, Parr Research Corporation 1995. - - -====================================================================== -1.32b1 -Added Russell Quong to banner, changed banner for output slightly -Fixed it so that you have before / after actions for C++ in class def -Fixed bug in optimizer that made it sometimes forget to set internal - token pointers. Only showed up when a {...} was in the "wrong spot". - -====================================================================== -1.32b2 -Added fixes by Dave Seidel for PC compilers in 32 bit mode (config.h -and set.h). - -====================================================================== -1.32b3 -Fixed hideous bug in code generator for wildcard and for ~token op. - -from Dave Seidel - - Added pcnames.bat - 1. in antlr/main.c: change strcasecmp() to stricmp() - - 2. in dlg/output.c: use DLEXER_C instead on "DLexer.C" - - 3. in h/PBlackBox.h: use instead of - -====================================================================== -1.32b4 -When the -ft option was used, any path prefix screwed up -the gate on the .h files - -Fixed yet another bug due to the optimizer. - -The exception handling thing was a bit wacko: - -a : ( A B )? A B - | A C - ; - exception ... - -caused an exception if "A C" was the input. In other words, -it found that A C didn't match the (A B)? pred and caused -an exception rather than trying the next alt. All I did -was to change the zzmatch_wsig() macros. - -Fixed some problems in gen.c relating to the name of token -class bit sets in the output. - -Added the tremendously cool generalized predicate. For the -moment, I'll give this bried description. - -a : <>? blah - | foo - ; - -This implies that (assuming blah and foo are syntactically -ambiguous) "predicate" indicates the semantic validity of -applying "blah". If "predicate" is false, "foo" is attempted. - -Previously, you had to say: - -a : <>? ID - | ID - ; - -Now, you can simply use "predicate" without the ?: operator -if you turn on ANTLR command line option: "-prc on". This -tells ANTLR to compute that all by itself. It computes n -tokens of lookahead where LT(n) or LATEXT(n) is the farthest -ahead you look. - -If you give a predicate using "-prc on" that is followed -by a construct that can recognize more than one n-sequence, -you will get a warning from ANTLR. For example, - -a : <getText())>>? (ID|INT) - ; - -This is wrong because the predicate will be applied to INTs -as well as ID's. You should use this syntax to make -the predicate more specific: - -a : (ID)? => <getText())>>? (ID|INT) - ; - -which says "don't apply the predicate unless ID is the -current lookahead context". - -You cannot currently have anything in the "(context)? =>" -except sequences such as: - -( LPAREN ID | LPAREN SCOPE )? => <>? - -I haven't tested this THAT much, but it does work for the -C++ grammar. - -====================================================================== -1.32b5 - -Added getLine() to the ANTLRTokenBase and DLGBasedToken classes -left line() for backward compatibility. ----- -Removed SORCERER_TRANSFORM from the ast.h stuff. -------- -Fixed bug in code gen of ANTLR such that nested syn preds work more -efficiently now. The ANTLRTokenBuffer was getting very large -with nested predicates. ------- -Memory leak is now gone from ANTLRTokenBuf; all tokens are deleted. -For backward compatibility reasons, you have to say parser->deleteTokens() -or mytokenbuffer->deleteTokens() but later it will be the default mode. -Say this after the parser is constructed. E.g., - - ParserBlackBox p(stdin); - p.parser()->deleteTokens(); - p.parser()->start_symbol(); - - -============================== -1.32b6 - -Changed so that deleteTokens() will do a delete ((ANTLRTokenBase *)) -on the ptr. This gets the virtual destructor. - -Fixed some weird things in the C++ header files (a few return types). - -Made the AST routines correspond to the book and SORCERER stuff. - -New token stuff: See testcpp/14/test.g - -ANTLR accepts a #pragma gc_tokens which says -[1] Generate label = copy(LT(1)) instead of label=LT(1) for - all labeled token references. -[2] User now has to define ANTLRTokenPtr (as a class or a typedef - to just a pointer) as well as the ANTLRToken class itself. - See the example. - -To delete tokens in token buffer, use deleteTokens() message on parser. - - All tokens that fall off the ANTLRTokenBuffer get deleted - which is what currently happens when deleteTokens() message - has been sent to token buffer. - -We always generate ANTLRTokenPtr instead of 'ANTLRToken *' now. -Then if no pragma set, ANTLR generates a - - class ANTLRToken; - typedef ANTLRToken *ANTLRTokenPtr; - -in each file. - -Made a warning for x:rule_ref <<$x>>; still no warning for $i's, however. -class BB { - -a : x:b y:A <<$x -$y>> - ; - -b : B; - -} -generates -Antlr parser generator Version 1.32b6 1989-1995 -test.g, line 3: error: There are no token ptrs for rule references: '$x' - -=================== -1.32b7: - -[With respect to token object garbage collection (GC), 1.32b7 - backtracks from 1.32b6, but results in better and less intrusive GC. - This is the last beta version before full 1.32.] - -BIGGEST CHANGES: - -o The "#pragma gc_tokens" is no longer used. - -o .C files are now .cpp files (hence, makefiles will have to - be changed; or you can rerun genmk). This is a good move, - but causes some backward incompatibility problems. You can - avoid this by changing CPP_FILE_SUFFIX to ".C" in pccts/h/config.h. - -o The token object class hierarchy has been flattened to include - only three classes: ANTLRAbstractToken, ANTLRCommonToken, and - ANTLRCommonNoRefCountToken. The common token now does garbage - collection via ref counting. - -o "Smart" pointers are now used for garbage collection. That is, - ANTLRTokenPtr is used instead of "ANTLRToken *". - -o The antlr.1 man page has been cleaned up slightly. - -o The SUN C++ compiler now complains less about C++ support code. - -o Grammars which subclass ANTLRCommonToken must wrap all token - pointer references in mytoken(token_ptr). This is the only - serious backward incompatibility. See below. - - -MINOR CHANGES: - --------------------------------------------------------- -1 deleteTokens() - -The deleteTokens() message to the parser or token buffer has been changed -to one of: - - void noGarbageCollectTokens() { inputTokens->noGarbageCollectTokens(); } - void garbageCollectTokens() { inputTokens->garbageCollectTokens(); } - -The token buffer deletes all non-referenced tokens by default now. - --------------------------------------------------------- -2 makeToken() - -The makeToken() message returns a new type. The function should look -like: - - virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt, - ANTLRChar *txt, - int line) - { - ANTLRAbstractToken *t = new ANTLRCommonToken(tt,txt); - t->setLine(line); - return t; - } - --------------------------------------------------------- -3 TokenType - -Changed TokenType-> ANTLRTokenType (often forces changes in AST defs due -to #[] constructor called to AST(tokentype, string)). - --------------------------------------------------------- -4 AST() - -You must define AST(ANTLRTokenPtr t) now in your AST class definition. -You might also have to include ATokPtr.h above the definition; e.g., -if AST is defined in a separate file, such as AST.h, it's a good idea -to include ATOKPTR_H (ATokPtr.h). For example, - - #include ATOKPTR_H - class AST : public ASTBase { - protected: - ANTLRTokenPtr token; - public: - AST(ANTLRTokenPtr t) { token = t; } - void preorder_action() { - char *s = token->getText(); - printf(" %s", s); - } - }; - -Note the use of smart pointers rather than "ANTLRToken *". - --------------------------------------------------------- -5 SUN C++ - -From robertb oakhill.sps.mot.com Bob Bailey. Changed ANTLR C++ output -to avoid an error in Sun C++ 3.0.1. Made "public" return value -structs created to hold multiple return values public. - --------------------------------------------------------- -6 genmk - -Fixed genmk so that target List.* is not included anymore. It's -called SList.* anyway. - --------------------------------------------------------- -7 \r vs \n - -Scott Vorthmann fixed antlr.g in ANTLR so that \r -is allowed as the return character as well as \n. - --------------------------------------------------------- -8 Exceptions - -Bug in exceptions attached to labeled token/tokclass references. Didn't gen -code for exceptions. This didn't work: - -a : "help" x:ID - ; - exception[x] - catch MismatchedToken : <> - -Now ANTLR generates (which is kinda big, but necessary): - - if ( !_match_wsig(ID) ) { - if ( guessing ) goto fail; - _signal=MismatchedToken; - switch ( _signal ) { - case MismatchedToken : - printf("eh?\n"); - _signal = NoSignal; - break; - default : - goto _handler; - } - } - -which implies that you can recover and continue parsing after a missing/bad -token reference. - --------------------------------------------------------- -9 genmk - -genmk now correctly uses config file for CPP_FILE_SUFFIX stuff. - --------------------------------------------------------- -10 general cleanup / PURIFY - -Anthony Green suggested a bunch of good general -clean up things for the code; he also suggested a few things to -help out the "PURIFY" memory allocation checker. - --------------------------------------------------------- -11 $-variable references. - -Manuel ORNATO indicated that a $-variable outside of a rule caused -ANTLR to crash. I fixed this. - -12 Tom Moog suggestion - -Fail action of semantic predicate needs "{}" envelope. FIXED. - -13 references to LT(1). - -I have enclosed all assignments such as: - - _t22 = (ANTLRTokenPtr)LT(1); - -in "if ( !guessing )" so that during backtracking the reference count -for token objects is not increased. - - -TOKEN OBJECT GARBAGE COLLECTION - -1 INTRODUCTION - -The class ANTLRCommonToken is now garbaged collected through a "smart" -pointer called ANTLRTokenPtr using reference counting. Any token -object not referenced by your grammar actions is destroyed by the -ANTLRTokenBuffer when it must make room for more token objects. -Referenced tokens are then destroyed in your parser when local -ANTLRTokenPtr objects are deleted. For example, - -a : label:ID ; - -would be converted to something like: - -void yourclass::a(void) -{ - zzRULE; - ANTLRTokenPtr label=NULL; // used to be ANTLRToken *label; - zzmatch(ID); - label = (ANTLRTokenPtr)LT(1); - consume(); - ... -} - -When the "label" object is destroyed (it's just a pointer to your -input token object LT(1)), it decrements the reference count on the -object created for the ID. If the count goes to zero, the object -pointed by label is deleted. - -To correctly manage the garbage collection, you should use -ANTLRTokenPtr instead of "ANTLRToken *". Most ANTLR support code -(visible to the user) has been modified to use the smart pointers. - -*************************************************************** -Remember that any local objects that you create are not deleted when a -lonjmp() is executed. Unfortunately, the syntactic predicates (...)? -use setjmp()/longjmp(). There are some situations when a few tokens -will "leak". -*************************************************************** - -2 DETAILS - -o The default is to perform token object garbage collection. - You may use parser->noGarbageCollectTokens() to turn off - garbage collection. - - -o The type ANTLRTokenPtr is always defined now (automatically). - If you do not wish to use smart pointers, you will have to - redefined ANTLRTokenPtr by subclassing, changing the header - file or changing ANTLR's code generation (easy enough to - do in gen.c). - -o If you don't use ParserBlackBox, the new initialization sequence is: - - ANTLRTokenPtr aToken = new ANTLRToken; - scan.setToken(mytoken(aToken)); - - where mytoken(aToken) gets an ANTLRToken * from the smart pointer. - -o Define C++ preprocessor symbol DBG_REFCOUNTTOKEN to see a bunch of - debugging stuff for reference counting if you suspect something. - - -3 WHY DO I HAVE TO TYPECAST ALL MY TOKEN POINTERS NOW?????? - -If you subclass ANTLRCommonToken and then attempt to refer to one of -your token members via a token pointer in your grammar actions, the -C++ compiler will complain that your token object does not have that -member. For example, if you used to do this - -<< -class ANTLRToken : public ANTLRCommonToken { - int muck; - ... -}; ->> - -class Foo { -a : t:ID << t->muck = ...; >> ; -} - -Now, you must do change the t->muck reference to: - -a : t:ID << mytoken(t)->muck = ...; >> ; - -in order to downcast 't' to be an "ANTLRToken *" not the -"ANTLRAbstractToken *" resulting from ANTLRTokenPtr::operator->(). -The macro is defined as: - -/* - * Since you cannot redefine operator->() to return one of the user's - * token object types, we must down cast. This is a drag. Here's - * a macro that helps. template: "mytoken(a-smart-ptr)->myfield". - */ -#define mytoken(tp) ((ANTLRToken *)(tp.operator->())) - -You have to use macro mytoken(grammar-label) now because smart -pointers are not specific to a parser's token objects. In other -words, the ANTLRTokenPtr class has a pointer to a generic -ANTLRAbstractToken not your ANTLRToken; the ANTLR support code must -use smart pointers too, but be able to work with any kind of -ANTLRToken. Sorry about this, but it's C++'s fault not mine. Some -nebulous future version of the C++ compilers should obviate the need -to downcast smart pointers with runtime type checking (and by allowing -different return type of overridden functions). - -A way to have backward compatible code is to shut off the token object -garbage collection; i.e., use parser->noGarbageCollectTokens() and -change the definition of ANTLRTokenPtr (that's why you get source code -). - - -PARSER EXCEPTION HANDLING - -I've noticed some weird stuff with the exception handling. I intend -to give this top priority for the "book release" of ANTLR. - -========== -1.32 Full Release - -o Changed Token class hierarchy to be (Thanks to Tom Moog): - - ANTLRAbstractToken - ANTLRRefCountToken - ANTLRCommonToken - ANTLRNoRefCountCommonToken - -o Added virtual panic() to ANTLRAbstractToken. Made ANTLRParser::panic() - virtual also. - -o Cleaned up the dup() stuff in AST hierarchy to use shallowCopy() to - make node copies. John Farr at Medtronic suggested this. I.e., - if you want to use dup() with either ANTLR or SORCERER or -transform - mode with SORCERER, you must defined shallowCopy() as: - - virtual PCCTS_AST *shallowCopy() - { - return new AST; - p->setDown(NULL); - p->setRight(NULL); - return p; - } - - or - - virtual PCCTS_AST *shallowCopy() - { - return new AST(*this); - } - - if you have defined a copy constructor such as - - AST(const AST &t) // shallow copy constructor - { - token = t.token; - iconst = t.iconst; - setDown(NULL); - setRight(NULL); - } - -o Added a warning with -CC and -gk are used together. This is broken, - hence a warning is appropriate. - -o Added warning when #-stuff is used w/o -gt option. - -o Updated MPW installation. - -o "Miller, Philip W." suggested - that genmk be use RENAME_OBJ_FLAG RENAME_EXE_FLAG instead of - hardcoding "-o" in genmk.c. - -o made all exit() calls use EXIT_SUCCESS or EXIT_FAILURE. - -=========================================================================== -1.33 - -EXIT_FAILURE and EXIT_SUCCESS were not always defined. I had to modify -a bunch of files to use PCCTS_EXIT_XXX, which forces a new version. Sorry -about that. - diff --git a/Tools/CodeTools/TianoTools/Pccts/CHANGES_FROM_133.txt b/Tools/CodeTools/TianoTools/Pccts/CHANGES_FROM_133.txt deleted file mode 100644 index 2128c4ff25..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/CHANGES_FROM_133.txt +++ /dev/null @@ -1,2448 +0,0 @@ -======================================================================= -List of Implemented Fixes and Changes for Maintenance Releases of PCCTS -======================================================================= - - DISCLAIMER - - The software and these notes are provided "as is". They may include - typographical or technical errors and their authors disclaims all - liability of any kind or nature for damages due to error, fault, - defect, or deficiency regardless of cause. All warranties of any - kind, either express or implied, including, but not limited to, the - implied warranties of merchantability and fitness for a particular - purpose are disclaimed. - - - ------------------------------------------------------- - Note: Items #153 to #1 are now in a separate file named - CHANGES_FROM_133_BEFORE_MR13.txt - ------------------------------------------------------- - -#312. (Changed in MR33) Bug caused by change #299. - - In change #299 a warning message was suppressed when there was - no LT(1) in a semantic predicate and max(k,ck) was 1. The - changed caused the code which set a default predicate depth for - the semantic predicate to be left as 0 rather than set to 1. - - This manifested as an error at line #1559 of mrhost.c - - Reported by Peter Dulimov. - -#311. (Changed in MR33) Added sorcer/lib to Makefile. - - Reported by Dale Martin. - -#310. (Changed in MR32) In C mode zzastPush was spelled zzastpush in one case. - - Reported by Jean-Claude Durand - -#309. (Changed in MR32) Renamed baseName because of VMS name conflict - - Renamed baseName to pcctsBaseName to avoid library name conflict with - VMS library routine. Reported by Jean-François PIÉRONNE. - -#308. (Changed in MR32) Used "template" as name of formal in C routine - - In astlib.h routine ast_scan a formal was named "template". This caused - problems when the C code was compiled with a C++ compiler. Reported by - Sabyasachi Dey. - -#307. (Changed in MR31) Compiler dependent bug in function prototype generation - - The code which generated function prototypes contained a bug which - was compiler/optimization dependent. Under some circumstance an - extra character would be included in portions of a function prototype. - - Reported by David Cook. - -#306. (Changed in MR30) Validating predicate following a token - - A validating predicate which immediately followed a token match - consumed the token after the predicate rather than before. Prior - to this fix (in the following example) isValidTimeScaleValue() in - the predicate would test the text for TIMESCALE rather than for - NUMBER: - - time_scale : - TIMESCALE - <getText())>>? - ts:NUMBER - ( us:MICROSECOND << tVal = ...>> - | ns:NANOSECOND << tVal = ... >> - ) - - Reported by Adalbert Perbandt. - -#305. (Changed in MR30) Alternatives with guess blocks inside (...)* blocks. - - In MR14 change #175 fixed a bug in the prediction expressions for guess - blocks which were of the form (alpha)? beta. Unfortunately, this - resulted in a new bug as exemplified by the example below, which computed - the first set for r as {B} rather than {B C}: - - r : ( (A)? B - | C - )* - - This example doesn't make any sense as A is not a prefix of B, but it - illustrates the problem. This bug did not appear for: - - r : ( (A)? - | C - )* - - because it does not use the (alpha)? beta form. - - Item #175 fixed an asymmetry in ambiguity messages for the following - constructs which appear to have identical ambiguities (between repeating - the loop vs. exiting the loop). MR30 retains this fix, but the implementation - is slightly different. - - r_star : ( (A B)? )* A ; - r_plus : ( (A B)? )+ A ; - - Reported by Arpad Beszedes (beszedes inf.u-szeged.hu). - -#304. (Changed in MR30) Crash when mismatch between output value counts. - - For a rule such as: - - r1 : r2>[i,j]; - r2 >[int i, int j] : A; - - If there were extra actuals for the reference to rule r2 from rule r1 - there antlr would crash. This bug was introduced by change #276. - - Reported by Sinan Karasu. - -#303. (Changed in MR30) DLGLexerBase::replchar - - DLGLexerBase::replchar and the C mode routine zzreplchar did not work - properly when the new character was 0. - - Reported with fix by Philippe Laporte - -#302. (Changed in MR28) Fix significant problems in initial release of MR27. - -#301. (Changed in MR27) Default tab stops set to 2 spaces. - - To have antlr generate true tabs rather than spaces, use "antlr -tab 0". - To generate 4 spaces per tab stop use "antlr -tab 4" - -#300. (Changed in MR27) - - Consider the following methods of constructing an AST from ID: - - rule1! - : id:ID << #0 = #[id]; >> ; - - rule2! - : id:ID << #0 = #id; >> ; - - rule3 - : ID ; - - rule4 - : id:ID << #0 = #id; >> ; - - For rule_2, the AST corresponding to id would always be NULL. This - is because the user explicitly suppressed AST construction using the - "!" operator on the rule. In MR27 the use of an AST expression - such as #id overrides the "!" operator and forces construction of - the AST. - - This fix does not apply to C mode ASTs when the ASTs are referenced - using numbers rather than symbols. - - For C mode, this requires that the (optional) function/macro zzmk_ast - be defined. This functions copies information from an attribute into - a previously allocated AST. - - Reported by Jan Langer (jan langernetz.de) - -#299. (Changed in MR27) Don't warn if k=1 and semantic predicate missing LT(i) - - If a semantic does not have a reference to LT(i) or (C mode LATEXT(i)) - then pccts doesn't know how many lookahead tokens to use for context. - However, if max(k,ck) is 1 then there is really only one choice and - the warning is unnecessary. - -#298. (Changed in MR27) Removed "register" for lastpos in dlgauto.c zzgettok - -#297. (Changed in MR27) Incorrect prototypes when used with classic C - - There were a number of errors in function headers when antlr was - built with compilers that do not have __STDC__ or __cplusplus set. - - The functions which have variable length argument lists now use - PCCTS_USE_STDARG rather than __USE_PROTOTYPES__ to determine - whether to use stdargs or varargs. - -#296. (Changed in MR27) Complex return types in rules. - - The following return type was not properly handled when - unpacking a struct with containing multiple return values: - - rule > [int i, IIR_Bool (IIR_Decl::*constraint)()] : ... - - Instead of using "constraint", the program got lost and used - an empty string. - - Reported by P.A. Wilsey. - -#295. (Changed in MR27) Extra ";" following zzGUESS_DONE sometimes. - - Certain constructs with guess blocks in MR23 led to extra ";" - preceding the "else" clause of an "if". - - Reported by P.A. Wilsey. - -#294. (Changed in MR27) Infinite loop in antlr for nested blocks - - An oversight in detecting an empty alternative sometimes led - to an infinite loop in antlr when it encountered a rule with - nested blocks and guess blocks. - - Reported by P.A. Wilsey. - -#293. (Changed in MR27) Sorcerer optimization of _t->type() - - Sorcerer generated code may contain many calls to _t->type() in a - single statement. This change introduces a temporary variable - to eliminate unnnecesary function calls. - - Change implemented by Tom Molteno (tim videoscript.com). - -#292. (Changed in MR27) - - WARNING: Item #267 changes the signature of methods in the AST class. - - **** Be sure to revise your AST functions of the same name *** - -#291. (Changed in MR24) - - Fix to serious code generation error in MR23 for (...)+ block. - -#290. (Changed in MR23) - - Item #247 describes a change in the way {...} blocks handled - an error. Consider: - - r1 : {A} b ; - b : B; - - with input "C". - - Prior to change #247, the error would resemble "expected B - - found C". This is correct but incomplete, and therefore - misleading. In #247 it was changed to "expected A, B - found - C". This was fine, except for users of parser exception - handling because the exception was generated in the epilogue - for {...} block rather than in rule b. This made it difficult - for users of parser exception handling because B was not - expected in that context. Those not using parser exception - handling didn't notice the difference. - - The current change restores the behavior prior to #247 when - parser exceptions are present, but retains the revised behavior - otherwise. This change should be visible only when exceptions - are in use and only for {...} blocks and sub-blocks of the form - (something|something | something | epsilon) where epsilon represents - an empty production and it is the last alternative of a sub-block. - In contrast, (something | epsilon | something) should generate the - same code as before, even when exceptions are used. - - Reported by Philippe Laporte (philippe at transvirtual.com). - -#289. (Changed in MR23) Bug in matching complement of a #tokclass - - Prior to MR23 when a #tokclass was matched in both its complemented form - and uncomplemented form, the bit set generated for its first use was used - for both cases. However, the prediction expression was correctly computed - in both cases. This meant that the second case would never be matched - because, for the second appearance, the prediction expression and the - set to be matched would be complements of each other. - - Consider: - - #token A "a" - #token B "b" - #token C "c" - #tokclass AB {A B} - - r1 : AB /* alt 1x */ - | ~AB /* alt 1y */ - ; - - Prior to MR23, this resulted in alternative 1y being unreachable. Had it - been written: - - r2 : ~AB /* alt 2x */ - : AB /* alt 2y */ - - then alternative 2y would have become unreachable. - - This bug was only for the case of complemented #tokclass. For complemented - #token the proper code was generated. - -#288. (Changed in MR23) #errclass not restricted to choice points - - The #errclass directive is supposed to allow a programmer to define - print strings which should appear in syntax error messages as a replacement - for some combinations of tokens. For instance: - - #errclass Operator {PLUS MINUS TIMES DIVIDE} - - If a syntax message includes all four of these tokens, and there is no - "better" choice of error class, the word "Operator" will be used rather - than a list of the four token names. - - Prior to MR23 the #errclass definitions were used only at choice points - (which call the FAIL macro). In other cases where there was no choice - (e.g. where a single token or token class were matched) the #errclass - information was not used. - - With MR23 the #errclass declarations are used for syntax error messages - when matching a #tokclass, a wildcard (i.e. "*"), or the complement of a - #token or #tokclass (e.g. ~Operator). - - Please note that #errclass may now be defined using #tokclass names - (see Item #284). - - Reported by Philip A. Wilsey. - -#287. (Changed in MR23) Print name for #tokclass - - Item #148 describes how to give a print name to a #token so that,for - example, #token ID could have the expression "identifier" in syntax - error messages. This has been extended to #tokclass: - - #token ID("identifier") "[a-zA-Z]+" - #tokclass Primitive("primitive type") - {INT, FLOAT, CHAR, FLOAT, DOUBLE, BOOL} - - This is really a cosmetic change, since #tokclass names do not appear - in any error messages. - -#286. (Changed in MR23) Makefile change to use of cd - - In cases where a pccts subdirectory name matched a directory identified - in a $CDPATH environment variable the build would fail. All makefile - cd commands have been changed from "cd xyz" to "cd ./xyz" in order - to avoid this problem. - -#285. (Changed in MR23) Check for null pointers in some dlg structures - - An invalid regular expression can cause dlg to build an invalid - structure to represent the regular expression even while it issues - error messages. Additional pointer checks were added. - - Reported by Robert Sherry. - -#284. (Changed in MR23) Allow #tokclass in #errclass definitions - - Previously, a #tokclass reference in the definition of an - #errclass was not handled properly. Instead of being expanded - into the set of tokens represented by the #tokclass it was - treated somewhat like an #errclass. However, in a later phase - when all #errclass were expanded into the corresponding tokens - the #tokclass reference was not expanded (because it wasn't an - #errclass). In effect the reference was ignored. - - This has been fixed. - - Problem reported by Mike Dimmick (mike dimmick.demon.co.uk). - -#283. (Changed in MR23) Option -tmake invoke's parser's tmake - - When the string #(...) appears in an action antlr replaces it with - a call to ASTBase::tmake(...) to construct an AST. It is sometimes - useful to change the tmake routine so that it has access to information - in the parser - something which is not possible with a static method - in an application where they may be multiple parsers active. - - The antlr option -tmake replaces the call to ASTBase::tmake with a call - to a user supplied tmake routine. - -#282. (Changed in MR23) Initialization error for DBG_REFCOUNTTOKEN - - When the pre-processor symbol DBG_REFCOUNTTOKEN is defined - incorrect code is generated to initialize ANTLRRefCountToken::ctor and - dtor. - - Fix reported by Sven Kuehn (sven sevenkuehn.de). - -#281. (Changed in MR23) Addition of -noctor option for Sorcerer - - Added a -noctor option to suppress generation of the blank ctor - for users who wish to define their own ctor. - - Contributed by Jan Langer (jan langernetz.de). - -#280. (Changed in MR23) Syntax error message for EOF token - - The EOF token now receives special treatment in syntax error messages - because there is no text matched by the eof token. The token name - of the eof token is used unless it is "@" - in which case the string - "" is used. - - Problem reported by Erwin Achermann (erwin.achermann switzerland.org). - -#279. (Changed in MR23) Exception groups - - There was a bug in the way that exception groups were attached to - alternatives which caused problems when there was a block contained - in an alternative. For instance, in the following rule; - - statement : IF S { ELSE S } - exception .... - ; - - the exception would be attached to the {...} block instead of the - entire alternative because it was attached, in error, to the last - alternative instead of the last OPEN alternative. - - Reported by Ty Mordane (tymordane hotmail.com). - -#278. (Changed in MR23) makefile changes - - Contributed by Tomasz Babczynski (faster lab05-7.ict.pwr.wroc.pl). - - The -cfile option is not absolutely needed: when extension of - source file is one of the well-known C/C++ extensions it is - treated as C/C++ source - - The gnu make defines the CXX variable as the default C++ compiler - name, so I added a line to copy this (if defined) to the CCC var. - - Added a -sor option: after it any -class command defines the class - name for sorcerer, not for ANTLR. A file extended with .sor is - treated as sorcerer input. Because sorcerer can be called multiple - times, -sor option can be repeated. Any files and classes (one class - per group) after each -sor makes one tree parser. - - Not implemented: - - 1. Generate dependences for user c/c++ files. - 2. Support for -sor in c mode not. - - I have left the old genmk program in the directory as genmk_old.c. - -#277. (Changed in MR23) Change in macro for failed semantic predicates - - In the past, a semantic predicate that failed generated a call to - the macro zzfailed_pred: - - #ifndef zzfailed_pred - #define zzfailed_pred(_p) \ - if (guessing) { \ - zzGUESS_FAIL; \ - } else { \ - something(_p) - } - #endif - - If a user wished to use the failed action option for semantic predicates: - - rule : <>? [my_fail_action] A - | ... - - - the code for my_fail_action would have to contain logic for handling - the guess part of the zzfailed_pred macro. The user should not have - to be aware of the guess logic in writing the fail action. - - The zzfailed_pred has been rewritten to have three arguments: - - arg 1: the stringized predicate of the semantic predicate - arg 2: 0 => there is no user-defined fail action - 1 => there is a user-defined fail action - arg 3: the user-defined fail action (if defined) - otherwise a no-operation - - The zzfailed_pred macro is now defined as: - - #ifndef zzfailed_pred - #define zzfailed_pred(_p,_hasuseraction,_useraction) \ - if (guessing) { \ - zzGUESS_FAIL; \ - } else { \ - zzfailed_pred_action(_p,_hasuseraction,_useraction) \ - } - #endif - - - With zzfailed_pred_action defined as: - - #ifndef zzfailed_pred_action - #define zzfailed_pred_action(_p,_hasuseraction,_useraction) \ - if (_hasUserAction) { _useraction } else { failedSemanticPredicate(_p); } - #endif - - In C++ mode failedSemanticPredicate() is a virtual function. - In C mode the default action is a fprintf statement. - - Suggested by Erwin Achermann (erwin.achermann switzerland.org). - -#276. (Changed in MR23) Addition of return value initialization syntax - - In an attempt to reduce the problems caused by the PURIFY macro I have - added new syntax for initializing the return value of rules and the - antlr option "-nopurify". - - A rule with a single return argument: - - r1 > [Foo f = expr] : - - now generates code that resembles: - - Foo r1(void) { - Foo _retv = expr; - ... - } - - A rule with more than one return argument: - - r2 > [Foo f = expr1, Bar b = expr2 ] : - - generates code that resembles: - - struct _rv1 { - Foo f; - Bar b; - } - - _rv1 r2(void) { - struct _rv1 _retv; - _retv.f = expr1; - _retv.b = expr2; - ... - } - - C++ style comments appearing in the initialization list may cause problems. - -#275. (Changed in MR23) Addition of -nopurify option to antlr - - A long time ago the PURIFY macro was introduced to initialize - return value arguments and get rid of annying messages from program - that checked for unitialized variables. - - This has caused significant annoyance for C++ users that had - classes with virtual functions or non-trivial contructors because - it would zero the object, including the pointer to the virtual - function table. This could be defeated by redefining - the PURIFY macro to be empty, but it was a constant surprise to - new C++ users of pccts. - - I would like to remove it, but I fear that some existing programs - depend on it and would break. My temporary solution is to add - an antlr option -nopurify which disables generation of the PURIFY - macro call. - - The PURIFY macro should be avoided in favor of the new syntax - for initializing return arguments described in item #275. - - To avoid name clash, the PURIFY macro has been renamed PCCTS_PURIFY. - -#274. (Changed in MR23) DLexer.cpp renamed to DLexer.h - (Changed in MR23) ATokPtr.cpp renamed to ATokPtrImpl.h - - These two files had .cpp extensions but acted like .h files because - there were included in other files. This caused problems for many IDE. - I have renamed them. The ATokPtrImpl.h was necessary because there was - already an ATokPtr.h. - -#273. (Changed in MR23) Default win32 library changed to multi-threaded DLL - - The model used for building the Win32 debug and release libraries has changed - to multi-threaded DLL. - - To make this change in your MSVC 6 project: - - Project -> Settings - Select the C++ tab in the right pane of the dialog box - Select "Category: Code Generation" - Under "Use run-time library" select one of the following: - - Multi-threaded DLL - Debug Multi-threaded DLL - - Suggested by Bill Menees (bill.menees gogallagher.com) - -#272. (Changed in MR23) Failed semantic predicate reported via virtual function - - In the past, a failed semantic predicated reported the problem via a - macro which used fprintf(). The macro now expands into a call on - the virtual function ANTLRParser::failedSemanticPredicate(). - -#271. (Changed in MR23) Warning for LT(i), LATEXT(i) in token match actions - - An bug (or at least an oddity) is that a reference to LT(1), LA(1), - or LATEXT(1) in an action which immediately follows a token match - in a rule refers to the token matched, not the token which is in - the lookahead buffer. Consider: - - r : abc <> D <> E; - - In this case LT(1) in action alpha will refer to the next token in - the lookahead buffer ("D"), but LT(1) in action beta will refer to - the token matched by D - the preceding token. - - A warning has been added for users about this when an action - following a token match contains a reference to LT(1), LA(1), or LATEXT(1). - - This behavior should be changed, but it appears in too many programs - now. Another problem, perhaps more significant, is that the obvious - fix (moving the consume() call to before the action) could change the - order in which input is requested and output appears in existing programs. - - This problem was reported, along with a fix by Benjamin Mandel - (beny sd.co.il). However, I felt that changing the behavior was too - dangerous for existing code. - -#270. (Changed in MR23) Removed static objects from PCCTSAST.cpp - - There were some statically allocated objects in PCCTSAST.cpp - These were changed to non-static. - -#269. (Changed in MR23) dlg output for initializing static array - - The output from dlg contains a construct similar to the - following: - - struct XXX { - static const int size; - static int array1[5]; - }; - - const int XXX::size = 4; - int XXX::array1[size+1]; - - - The problem is that although the expression "size+1" used in - the definition of array1 is equal to 5 (the expression used to - declare array), it is not considered equivalent by some compilers. - - Reported with fix by Volker H. Simonis (simonis informatik.uni-tuebingen.de) - -#268. (Changed in MR23) syn() routine output when k > 1 - - The syn() routine is supposed to print out the text of the - token causing the syntax error. It appears that it always - used the text from the first lookahead token rather than the - appropriate one. The appropriate one is computed by comparing - the token codes of lookahead token i (for i = 1 to k) with - the FIRST(i) set. - - This has been corrected in ANTLRParser::syn(). - - Reported by Bill Menees (bill.menees gogallagher.com) - -#267. (Changed in MR23) AST traversal functions client data argument - - The AST traversal functions now take an extra (optional) parameter - which can point to client data: - - preorder_action(void* pData = NULL) - preorder_before_action(void* pData = NULL) - preorder_after_action(void* pData = NULL) - - **** Warning: this changes the AST signature. *** - **** Be sure to revise your AST functions of the same name *** - - Bill Menees (bill.menees gogallagher.com) - -#266. (Changed in MR23) virtual function printMessage() - - Bill Menees (bill.menees gogallagher.com) has completed the - tedious taks of replacing all calls to fprintf() with calls - to the virtual function printMessage(). For classes which - have a pointer to the parser it forwards the printMessage() - call to the parser's printMessage() routine. - - This should make it significanly easier to redirect pccts - error and warning messages. - -#265. (Changed in MR23) Remove "labase++" in C++ mode - - In C++ mode labase++ is called when a token is matched. - It appears that labase is not used in C++ mode at all, so - this code has been commented out. - -#264. (Changed in MR23) Complete rewrite of ParserBlackBox.h - - The parser black box (PBlackBox.h) was completely rewritten - by Chris Uzdavinis (chris atdesk.com) to improve its robustness. - -#263. (Changed in MR23) -preamble and -preamble_first rescinded - - Changes for item #253 have been rescinded. - -#262. (Changed in MR23) Crash with -alpha option during traceback - - Under some circumstances a -alpha traceback was started at the - "wrong" time. As a result, internal data structures were not - initialized. - - Reported by Arpad Beszedes (beszedes inf.u-szeged.hu). - -#261. (Changed in MR23) Defer token fetch for C++ mode - - Item #216 has been revised to indicate that use of the defer fetch - option (ZZDEFER_FETCH) requires dlg option -i. - -#260. (MR22) Raise default lex buffer size from 8,000 to 32,000 bytes. - - ZZLEXBUFSIZE is the size (in bytes) of the buffer used by dlg - generated lexers. The default value has been raised to 32,000 and - the value used by antlr, dlg, and sorcerer has also been raised to - 32,000. - -#259. (MR22) Default function arguments in C++ mode. - - If a rule is declared: - - rr [int i = 0] : .... - - then the declaration generated by pccts resembles: - - void rr(int i = 0); - - however, the definition must omit the default argument: - - void rr(int i) {...} - - In the past the default value was not omitted. In MR22 - the generated code resembles: - - void rr(int i /* = 0 */ ) {...} - - Implemented by Volker H. Simonis (simonis informatik.uni-tuebingen.de) - - - Note: In MR23 this was changed so that nested C style comments - ("/* ... */") would not cause problems. - -#258. (MR22) Using a base class for your parser - - In item #102 (MR10) the class statement was extended to allow one - to specify a base class other than ANTLRParser for the generated - parser. It turned out that this was less than useful because - the constructor still specified ANTLRParser as the base class. - - The class statement now uses the first identifier appearing after - the ":" as the name of the base class. For example: - - class MyParser : public FooParser { - - Generates in MyParser.h: - - class MyParser : public FooParser { - - Generates in MyParser.cpp something that resembles: - - MyParser::MyParser(ANTLRTokenBuffer *input) : - FooParser(input,1,0,0,4) - { - token_tbl = _token_tbl; - traceOptionValueDefault=1; // MR10 turn trace ON - } - - The base class constructor must have a signature similar to - that of ANTLRParser. - -#257. (MR21a) Removed dlg statement that -i has no effect in C++ mode. - - This was incorrect. - -#256. (MR21a) Malformed syntax graph causes crash after error message. - - In the past, certain kinds of errors in the very first grammar - element could cause the construction of a malformed graph - representing the grammar. This would eventually result in a - fatal internal error. The code has been changed to be more - resistant to this particular error. - -#255. (MR21a) ParserBlackBox(FILE* f) - - This constructor set openByBlackBox to the wrong value. - - Reported by Kees Bakker (kees_bakker tasking.nl). - -#254. (MR21a) Reporting syntax error at end-of-file - - When there was a syntax error at the end-of-file the syntax - error routine would substitute "" for the programmer's - end-of-file symbol. This substitution is now done only when - the programmer does not define his own end-of-file symbol - or the symbol begins with the character "@". - - Reported by Kees Bakker (kees_bakker tasking.nl). - -#253. (MR21) Generation of block preamble (-preamble and -preamble_first) - - *** This change was rescinded by item #263 *** - - The antlr option -preamble causes antlr to insert the code - BLOCK_PREAMBLE at the start of each rule and block. It does - not insert code before rules references, token references, or - actions. By properly defining the macro BLOCK_PREAMBLE the - user can generate code which is specific to the start of blocks. - - The antlr option -preamble_first is similar, but inserts the - code BLOCK_PREAMBLE_FIRST(PreambleFirst_123) where the symbol - PreambleFirst_123 is equivalent to the first set defined by - the #FirstSetSymbol described in Item #248. - - I have not investigated how these options interact with guess - mode (syntactic predicates). - -#252. (MR21) Check for null pointer in trace routine - - When some trace options are used when the parser is generated - without the trace enabled, the current rule name may be a - NULL pointer. A guard was added to check for this in - restoreState. - - Reported by Douglas E. Forester (dougf projtech.com). - -#251. (MR21) Changes to #define zzTRACE_RULES - - The macro zzTRACE_RULES was being use to pass information to - AParser.h. If this preprocessor symbol was not properly - set the first time AParser.h was #included, the declaration - of zzTRACEdata would be omitted (it is used by the -gd option). - Subsequent #includes of AParser.h would be skipped because of - the #ifdef guard, so the declaration of zzTracePrevRuleName would - never be made. The result was that proper compilation was very - order dependent. - - The declaration of zzTRACEdata was made unconditional and the - problem of removing unused declarations will be left to optimizers. - - Diagnosed by Douglas E. Forester (dougf projtech.com). - -#250. (MR21) Option for EXPERIMENTAL change to error sets for blocks - - The antlr option -mrblkerr turns on an experimental feature - which is supposed to provide more accurate syntax error messages - for k=1, ck=1 grammars. When used with k>1 or ck>1 grammars the - behavior should be no worse than the current behavior. - - There is no problem with the matching of elements or the computation - of prediction expressions in pccts. The task is only one of listing - the most appropriate tokens in the error message. The error sets used - in pccts error messages are approximations of the exact error set when - optional elements in (...)* or (...)+ are involved. While entirely - correct, the error messages are sometimes not 100% accurate. - - There is also a minor philosophical issue. For example, suppose the - grammar expects the token to be an optional A followed by Z, and it - is X. X, of course, is neither A nor Z, so an error message is appropriate. - Is it appropriate to say "Expected Z" ? It is correct, it is accurate, - but it is not complete. - - When k>1 or ck>1 the problem of providing the exactly correct - list of tokens for the syntax error messages ends up becoming - equivalent to evaluating the prediction expression for the - alternatives twice. However, for k=1 ck=1 grammars the prediction - expression can be computed easily and evaluated cheaply, so I - decided to try implementing it to satisfy a particular application. - This application uses the error set in an interactive command language - to provide prompts which list the alternatives available at that - point in the parser. The user can then enter additional tokens to - complete the command line. To do this required more accurate error - sets then previously provided by pccts. - - In some cases the default pccts behavior may lead to more robust error - recovery or clearer error messages then having the exact set of tokens. - This is because (a) features like -ge allow the use of symbolic names for - certain sets of tokens, so having extra tokens may simply obscure things - and (b) the error set is use to resynchronize the parser, so a good - choice is sometimes more important than having the exact set. - - Consider the following example: - - Note: All examples code has been abbreviated - to the absolute minimum in order to make the - examples concise. - - star1 : (A)* Z; - - The generated code resembles: - - old new (with -mrblkerr) - --//----------- -------------------- - for (;;) { for (;;) { - match(A); match(A); - } } - match(Z); if (! A and ! Z) then - FAIL(...{A,Z}...); - } - match(Z); - - - With input X - old message: Found X, expected Z - new message: Found X, expected A, Z - - For the example: - - star2 : (A|B)* Z; - - old new (with -mrblkerr) - ------------- -------------------- - for (;;) { for (;;) { - if (!A and !B) break; if (!A and !B) break; - if (...) { if (...) { - - } } - else { else { - FAIL(...{A,B,Z}...) FAIL(...{A,B}...); - } } - } } - match(B); if (! A and ! B and !Z) then - FAIL(...{A,B,Z}...); - } - match(B); - - With input X - old message: Found X, expected Z - new message: Found X, expected A, B, Z - With input A X - old message: Found X, expected Z - new message: Found X, expected A, B, Z - - This includes the choice of looping back to the - star block. - - The code for plus blocks: - - plus1 : (A)+ Z; - - The generated code resembles: - - old new (with -mrblkerr) - ------------- -------------------- - do { do { - match(A); match(A); - } while (A) } while (A) - match(Z); if (! A and ! Z) then - FAIL(...{A,Z}...); - } - match(Z); - - With input A X - old message: Found X, expected Z - new message: Found X, expected A, Z - - This includes the choice of looping back to the - plus block. - - For the example: - - plus2 : (A|B)+ Z; - - old new (with -mrblkerr) - ------------- -------------------- - do { do { - if (A) { - match(A); - } else if (B) { - match(B); - } else { - if (cnt > 1) break; - FAIL(...{A,B,Z}...) FAIL(...{A,B}...); - } } - cnt++; - } } - - match(Z); if (! A and ! B and !Z) then - FAIL(...{A,B,Z}...); - } - match(B); - - With input X - old message: Found X, expected A, B, Z - new message: Found X, expected A, B - With input A X - old message: Found X, expected Z - new message: Found X, expected A, B, Z - - This includes the choice of looping back to the - star block. - -#249. (MR21) Changes for DEC/VMS systems - - Jean-François Piéronne (jfp altavista.net) has updated some - VMS related command files and fixed some minor problems related - to building pccts under the DEC/VMS operating system. For DEC/VMS - users the most important differences are: - - a. Revised makefile.vms - b. Revised genMMS for genrating VMS style makefiles. - -#248. (MR21) Generate symbol for first set of an alternative - - pccts can generate a symbol which represents the tokens which may - appear at the start of a block: - - rr : #FirstSetSymbol(rr_FirstSet) ( Foo | Bar ) ; - - This will generate the symbol rr_FirstSet of type SetWordType with - elements Foo and Bar set. The bits can be tested using code similar - to the following: - - if (set_el(Foo, &rr_FirstSet)) { ... - - This can be combined with the C array zztokens[] or the C++ routine - tokenName() to get the print name of the token in the first set. - - The size of the set is given by the newly added enum SET_SIZE, a - protected member of the generated parser's class. The number of - elements in the generated set will not be exactly equal to the - value of SET_SIZE because of synthetic tokens created by #tokclass, - #errclass, the -ge option, and meta-tokens such as epsilon, and - end-of-file. - - The #FirstSetSymbol must appear immediately before a block - such as (...)+, (...)*, and {...}, and (...). It may not appear - immediately before a token, a rule reference, or action. However - a token or rule reference can be enclosed in a (...) in order to - make the use of #pragma FirstSetSymbol legal. - - rr_bad : #FirstSetSymbol(rr_bad_FirstSet) Foo; // Illegal - - rr_ok : #FirstSetSymbol(rr_ok_FirstSet) (Foo); // Legal - - Do not confuse FirstSetSymbol sets with the sets used for testing - lookahead. The sets used for FirstSetSymbol have one element per bit, - so the number of bytes is approximately the largest token number - divided by 8. The sets used for testing lookahead store 8 lookahead - sets per byte, so the length of the array is approximately the largest - token number. - - If there is demand, a similar routine for follow sets can be added. - -#247. (MR21) Misleading error message on syntax error for optional elements. - - =================================================== - The behavior has been revised when parser exception - handling is used. See Item #290 - =================================================== - - Prior to MR21, tokens which were optional did not appear in syntax - error messages if the block which immediately followed detected a - syntax error. - - Consider the following grammar which accepts Number, Word, and Other: - - rr : {Number} Word; - - For this rule the code resembles: - - if (LA(1) == Number) { - match(Number); - consume(); - } - match(Word); - - Prior to MR21, the error message for input "$ a" would be: - - line 1: syntax error at "$" missing Word - - With MR21 the message will be: - - line 1: syntax error at "$" expecting Word, Number. - - The generate code resembles: - - if ( (LA(1)==Number) ) { - zzmatch(Number); - consume(); - } - else { - if ( (LA(1)==Word) ) { - /* nothing */ - } - else { - FAIL(... message for both Number and Word ...); - } - } - match(Word); - - The code generated for optional blocks in MR21 is slightly longer - than the previous versions, but it should give better error messages. - - The code generated for: - - { a | b | c } - - should now be *identical* to: - - ( a | b | c | ) - - which was not the case prior to MR21. - - Reported by Sue Marvin (sue siara.com). - -#246. (Changed in MR21) Use of $(MAKE) for calls to make - - Calls to make from the makefiles were replaced with $(MAKE) - because of problems when using gmake. - - Reported with fix by Sunil K.Vallamkonda (sunil siara.com). - -#245. (Changed in MR21) Changes to genmk - - The following command line options have been added to genmk: - - -cfiles ... - - To add a user's C or C++ files into makefile automatically. - The list of files must be enclosed in apostrophes. This - option may be specified multiple times. - - -compiler ... - - The name of the compiler to use for $(CCC) or $(CC). The - default in C++ mode is "CC". The default in C mode is "cc". - - -pccts_path ... - - The value for $(PCCTS), the pccts directory. The default - is /usr/local/pccts. - - Contributed by Tomasz Babczynski (t.babczynski ict.pwr.wroc.pl). - -#244. (Changed in MR21) Rename variable "not" in antlr.g - - When antlr.g is compiled with a C++ compiler, a variable named - "not" causes problems. Reported by Sinan Karasu - (sinan.karasu boeing.com). - -#243 (Changed in MR21) Replace recursion with iteration in zzfree_ast - - Another refinement to zzfree_ast in ast.c to limit recursion. - - NAKAJIMA Mutsuki (muc isr.co.jp). - - -#242. (Changed in MR21) LineInfoFormatStr - - Added an #ifndef/#endif around LineInfoFormatStr in pcctscfg.h. - -#241. (Changed in MR21) Changed macro PURIFY to a no-op - - *********************** - *** NOT IMPLEMENTED *** - *********************** - - The PURIFY macro was changed to a no-op because it was causing - problems when passing C++ objects. - - The old definition: - - #define PURIFY(r,s) memset((char *) &(r),'\\0',(s)); - - The new definition: - - #define PURIFY(r,s) /* nothing */ -#endif - -#240. (Changed in MR21) sorcerer/h/sorcerer.h _MATCH and _MATCHRANGE - - Added test for NULL token pointer. - - Suggested by Peter Keller (keller ebi.ac.uk) - -#239. (Changed in MR21) C++ mode AParser::traceGuessFail - - If tracing is turned on when the code has been generated - without trace code, a failed guess generates a trace report - even though there are no other trace reports. This - make the behavior consistent with other parts of the - trace system. - - Reported by David Wigg (wiggjd sbu.ac.uk). - -#238. (Changed in MR21) Namespace version #include files - - Changed reference from CStdio to cstdio (and other - #include file names) in the namespace version of pccts. - Should have known better. - -#237. (Changed in MR21) ParserBlackBox(FILE*) - - In the past, ParserBlackBox would close the FILE in the dtor - even though it was not opened by ParserBlackBox. The problem - is that there were two constructors, one which accepted a file - name and did an fopen, the other which accepted a FILE and did - not do an fopen. There is now an extra member variable which - remembers whether ParserBlackBox did the open or not. - - Suggested by Mike Percy (mpercy scires.com). - -#236. (Changed in MR21) tmake now reports down pointer problem - - When ASTBase::tmake attempts to update the down pointer of - an AST it checks to see if the down pointer is NULL. If it - is not NULL it does not do the update and returns NULL. - An attempt to update the down pointer is almost always a - result of a user error. This can lead to difficult to find - problems during tree construction. - - With this change, the routine calls a virtual function - reportOverwriteOfDownPointer() which calls panic to - report the problem. Users who want the old behavior can - redefined the virtual function in their AST class. - - Suggested by Sinan Karasu (sinan.karasu boeing.com) - -#235. (Changed in MR21) Made ANTLRParser::resynch() virtual - - Suggested by Jerry Evans (jerry swsl.co.uk). - -#234. (Changed in MR21) Implicit int for function return value - - ATokenBuffer:bufferSize() did not specify a type for the - return value. - - Reported by Hai Vo-Ba (hai fc.hp.com). - -#233. (Changed in MR20) Converted to MSVC 6.0 - - Due to external circumstances I have had to convert to MSVC 6.0 - The MSVC 5.0 project files (.dsw and .dsp) have been retained as - xxx50.dsp and xxx50.dsw. The MSVC 6.0 files are named xxx60.dsp - and xxx60.dsw (where xxx is the related to the directory/project). - -#232. (Changed in MR20) Make setwd bit vectors protected in parser.h - - The access for the setwd array in the parser header was not - specified. As a result, it would depend on the code which - preceded it. In MR20 it will always have access "protected". - - Reported by Piotr Eljasiak (eljasiak zt.gdansk.tpsa.pl). - -#231. (Changed in MR20) Error in token buffer debug code. - - When token buffer debugging is selected via the pre-processor - symbol DEBUG_TOKENBUFFER there is an erroneous check in - AParser.cpp: - - #ifdef DEBUG_TOKENBUFFER - if (i >= inputTokens->bufferSize() || - inputTokens->minTokens() < LLk ) /* MR20 Was "<=" */ - ... - #endif - - Reported by David Wigg (wiggjd sbu.ac.uk). - -#230. (Changed in MR20) Fixed problem with #define for -gd option - - There was an error in setting zzTRACE_RULES for the -gd (trace) option. - - Reported by Gary Funck (gary intrepid.com). - -#229. (Changed in MR20) Additional "const" for literals - - "const" was added to the token name literal table. - "const" was added to some panic() and similar routine - -#228. (Changed in MR20) dlg crashes on "()" - - The following token defintion will cause DLG to crash. - - #token "()" - - When there is a syntax error in a regular expression - many of the dlg routines return a structure which has - null pointers. When this is accessed by callers it - generates the crash. - - I have attempted to fix the more common cases. - - Reported by Mengue Olivier (dolmen bigfoot.com). - -#227. (Changed in MR20) Array overwrite - - Steveh Hand (sassth unx.sas.com) reported a problem which - was traced to a temporary array which was not properly - resized for deeply nested blocks. This has been fixed. - -#226. (Changed in MR20) -pedantic conformance - - G. Hobbelt (i_a mbh.org) and THM made many, many minor - changes to create prototypes for all the functions and - bring antlr, dlg, and sorcerer into conformance with - the gcc -pedantic option. - - This may require uses to add pccts/h/pcctscfg.h to some - files or makefiles in order to have __USE_PROTOS defined. - -#225 (Changed in MR20) AST stack adjustment in C mode - - The fix in #214 for AST stack adjustment in C mode missed - some cases. - - Reported with fix by Ger Hobbelt (i_a mbh.org). - -#224 (Changed in MR20) LL(1) and LL(2) with #pragma approx - - This may take a record for the oldest, most trival, lexical - error in pccts. The regular expressions for LL(1) and LL(2) - lacked an escape for the left and right parenthesis. - - Reported by Ger Hobbelt (i_a mbh.org). - -#223 (Changed in MR20) Addition of IBM_VISUAL_AGE directory - - Build files for antlr, dlg, and sorcerer under IBM Visual Age - have been contributed by Anton Sergeev (ags mlc.ru). They have - been placed in the pccts/IBM_VISUAL_AGE directory. - -#222 (Changed in MR20) Replace __STDC__ with __USE_PROTOS - - Most occurrences of __STDC__ replaced with __USE_PROTOS due to - complaints from several users. - -#221 (Changed in MR20) Added #include for DLexerBase.h to PBlackBox. - - Added #include for DLexerBase.h to PBlackBox. - -#220 (Changed in MR19) strcat arguments reversed in #pred parse - - The arguments to strcat are reversed when creating a print - name for a hash table entry for use with #pred feature. - - Problem diagnosed and fix reported by Scott Harrington - (seh4 ix.netcom.com). - -#219. (Changed in MR19) C Mode routine zzfree_ast - - Changes to reduce use of recursion for AST trees with only right - links or only left links in the C mode routine zzfree_ast. - - Implemented by SAKAI Kiyotaka (ksakai isr.co.jp). - -#218. (Changed in MR19) Changes to support unsigned char in C mode - - Changes to antlr.h and err.h to fix omissions in use of zzchar_t - - Implemented by SAKAI Kiyotaka (ksakai isr.co.jp). - -#217. (Changed in MR19) Error message when dlg -i and -CC options selected - - *** This change was rescinded by item #257 *** - - The parsers generated by pccts in C++ mode are not able to support the - interactive lexer option (except, perhaps, when using the deferred fetch - parser option.(Item #216). - - DLG now warns when both -i and -CC are selected. - - This warning was suggested by David Venditti (07751870267-0001 t-online.de). - -#216. (Changed in MR19) Defer token fetch for C++ mode - - Implemented by Volker H. Simonis (simonis informatik.uni-tuebingen.de) - - Normally, pccts keeps the lookahead token buffer completely filled. - This requires max(k,ck) tokens of lookahead. For some applications - this can cause deadlock problems. For example, there may be cases - when the parser can't tell when the input has been completely consumed - until the parse is complete, but the parse can't be completed because - the input routines are waiting for additional tokens to fill the - lookahead buffer. - - When the ANTLRParser class is built with the pre-processor option - ZZDEFER_FETCH defined, the fetch of new tokens by consume() is deferred - until LA(i) or LT(i) is called. - - To test whether this option has been built into the ANTLRParser class - use "isDeferFetchEnabled()". - - Using the -gd trace option with the default tracein() and traceout() - routines will defeat the effort to defer the fetch because the - trace routines print out information about the lookahead token at - the start of the rule. - - Because the tracein and traceout routines are virtual it is - easy to redefine them in your parser: - - class MyParser { - << - virtual void tracein(ANTLRChar * ruleName) - { fprintf(stderr,"Entering: %s\n", ruleName); } - virtual void traceout(ANTLRChar * ruleName) - { fprintf(stderr,"Leaving: %s\n", ruleName); } - >> - - The originals for those routines are pccts/h/AParser.cpp - - This requires use of the dlg option -i (interactive lexer). - - This is implemented only for C++ mode. - - This is experimental. The interaction with guess mode (syntactic - predicates)is not known. - -#215. (Changed in MR19) Addition of reset() to DLGLexerBase - - There was no obvious way to reset the lexer for reuse. The - reset() method now does this. - - Suggested by David Venditti (07751870267-0001 t-online.de). - -#214. (Changed in MR19) C mode: Adjust AST stack pointer at exit - - In C mode the AST stack pointer needs to be reset if there will - be multiple calls to the ANTLRx macros. - - Reported with fix by Paul D. Smith (psmith baynetworks.com). - -#213. (Changed in MR18) Fatal error with -mrhoistk (k>1 hoisting) - - When rearranging code I forgot to un-comment a critical line of - code that handles hoisting of predicates with k>1 lookahead. This - is now fixed. - - Reported by Reinier van den Born (reinier vnet.ibm.com). - -#212. (Changed in MR17) Mac related changes by Kenji Tanaka - - Kenji Tanaka (kentar osa.att.ne.jp) has made a number of changes for - Macintosh users. - - a. The following Macintosh MPW files aid in installing pccts on Mac: - - pccts/MPW_Read_Me - - pccts/install68K.mpw - pccts/installPPC.mpw - - pccts/antlr/antlr.r - pccts/antlr/antlr68K.make - pccts/antlr/antlrPPC.make - - pccts/dlg/dlg.r - pccts/dlg/dlg68K.make - pccts/dlg/dlgPPC.make - - pccts/sorcerer/sor.r - pccts/sorcerer/sor68K.make - pccts/sorcerer/sorPPC.make - - They completely replace the previous Mac installation files. - - b. The most significant is a change in the MAC_FILE_CREATOR symbol - in pcctscfg.h: - - old: #define MAC_FILE_CREATOR 'MMCC' /* Metrowerks C/C++ Text files */ - new: #define MAC_FILE_CREATOR 'CWIE' /* Metrowerks C/C++ Text files */ - - c. Added calls to special_fopen_actions() where necessary. - -#211. (Changed in MR16a) C++ style comment in dlg - - This has been fixed. - -#210. (Changed in MR16a) Sor accepts \r\n, \r, or \n for end-of-line - - A user requested that Sorcerer be changed to accept other forms - of end-of-line. - -#209. (Changed in MR16) Name of files changed. - - Old: CHANGES_FROM_1.33 - New: CHANGES_FROM_133.txt - - Old: KNOWN_PROBLEMS - New: KNOWN_PROBLEMS.txt - -#208. (Changed in MR16) Change in use of pccts #include files - - There were problems with MS DevStudio when mixing Sorcerer and - PCCTS in the same source file. The problem is caused by the - redefinition of setjmp in the MS header file setjmp.h. In - setjmp.h the pre-processor symbol setjmp was redefined to be - _setjmp. A later effort to execute #include resulted - in an effort to #include <_setjmp.h>. I'm not sure whether this - is a bug or a feature. In any case, I decided to fix it by - avoiding the use of pre-processor symbols in #include statements - altogether. This has the added benefit of making pre-compiled - headers work again. - - I've replaced statements: - - old: #include PCCTS_SETJMP_H - new: #include "pccts_setjmp.h" - - Where pccts_setjmp.h contains: - - #ifndef __PCCTS_SETJMP_H__ - #define __PCCTS_SETJMP_H__ - - #ifdef PCCTS_USE_NAMESPACE_STD - #include - #else - #include - #endif - - #endif - - A similar change has been made for other standard header files - required by pccts and sorcerer: stdlib.h, stdarg.h, stdio.h, etc. - - Reported by Jeff Vincent (JVincent novell.com) and Dale Davis - (DalDavis spectrace.com). - -#207. (Changed in MR16) dlg reports an invalid range for: [\0x00-\0xff] - - ----------------------------------------------------------------- - Note from MR23: This fix does not work. I am investigating why. - ----------------------------------------------------------------- - - dlg will report that this is an invalid range. - - Diagnosed by Piotr Eljasiak (eljasiak no-spam.zt.gdansk.tpsa.pl): - - I think this problem is not specific to unsigned chars - because dlg reports no error for the range [\0x00-\0xfe]. - - I've found that information on range is kept in field - letter (unsigned char) of Attrib struct. Unfortunately - the letter value internally is for some reasons increased - by 1, so \0xff is represented here as 0. - - That's why dlg complains about the range [\0x00-\0xff] in - dlg_p.g: - - if ($$.letter > $2.letter) { - error("invalid range ", zzline); - } - - The fix is: - - if ($$.letter > $2.letter && 255 != $$2.letter) { - error("invalid range ", zzline); - } - -#206. (Changed in MR16) Free zzFAILtext in ANTLRParser destructor - - The ANTLRParser destructor now frees zzFAILtext. - - Problem and fix reported by Manfred Kogler (km cast.uni-linz.ac.at). - -#205. (Changed in MR16) DLGStringReset argument now const - - Changed: void DLGStringReset(DLGChar *s) {...} - To: void DLGStringReset(const DLGChar *s) {...} - - Suggested by Dale Davis (daldavis spectrace.com) - -#204. (Changed in MR15a) Change __WATCOM__ to __WATCOMC__ in pcctscfg.h - - Reported by Oleg Dashevskii (olegdash my-dejanews.com). - -#203. (Changed in MR15) Addition of sorcerer to distribution kit - - I have finally caved in to popular demand. The pccts 1.33mr15 - kit will include sorcerer. The separate sorcerer kit will be - discontinued. - -#202. (Changed) in MR15) Organization of MS Dev Studio Projects in Kit - - Previously there was one workspace that contained projects for - all three parts of pccts: antlr, dlg, and sorcerer. Now each - part (and directory) has its own workspace/project and there - is an additional workspace/project to build a library from the - .cpp files in the pccts/h directory. - - The library build will create pccts_debug.lib or pccts_release.lib - according to the configuration selected. - - If you don't want to build pccts 1.33MR15 you can download a - ready-to-run kit for win32 from http://www.polhode.com/win32.zip. - The ready-to-run for win32 includes executables, a pre-built static - library for the .cpp files in the pccts/h directory, and a sample - application - - You will need to define the environment variable PCCTS to point to - the root of the pccts directory hierarchy. - -#201. (Changed in MR15) Several fixes by K.J. Cummings (cummings peritus.com) - - Generation of SETJMP rather than SETJMP_H in gen.c. - - (Sor B19) Declaration of ref_vars_inits for ref_var_inits in - pccts/sorcerer/sorcerer.h. - -#200. (Changed in MR15) Remove operator=() in AToken.h - - User reported that WatCom couldn't handle use of - explicit operator =(). Replace with equivalent - using cast operator. - -#199. (Changed in MR15) Don't allow use of empty #tokclass - - Change antlr.g to disallow empty #tokclass sets. - - Reported by Manfred Kogler (km cast.uni-linz.ac.at). - -#198. Revised ANSI C grammar due to efforts by Manuel Kessler - - Manuel Kessler (mlkessler cip.physik.uni-wuerzburg.de) - - Allow trailing ... in function parameter lists. - Add bit fields. - Allow old-style function declarations. - Support cv-qualified pointers. - Better checking of combinations of type specifiers. - Release of memory for local symbols on scope exit. - Allow input file name on command line as well as by redirection. - - and other miscellaneous tweaks. - - This is not part of the pccts distribution kit. It must be - downloaded separately from: - - http://www.polhode.com/ansi_mr15.zip - -#197. (Changed in MR14) Resetting the lookahead buffer of the parser - - Explanation and fix by Sinan Karasu (sinan.karasu boeing.com) - - Consider the code used to prime the lookahead buffer LA(i) - of the parser when init() is called: - - void - ANTLRParser:: - prime_lookahead() - { - int i; - for(i=1;i<=LLk; i++) consume(); - dirty=0; - //lap = 0; // MR14 - Sinan Karasu (sinan.karusu boeing.com) - //labase = 0; // MR14 - labase=lap; // MR14 - } - - When the parser is instantiated, lap=0,labase=0 is set. - - The "for" loop runs LLk times. In consume(), lap = lap +1 (mod LLk) is - computed. Therefore, lap(before the loop) == lap (after the loop). - - Now the only problem comes in when one does an init() of the parser - after an Eof has been seen. At that time, lap could be non zero. - Assume it was lap==1. Now we do a prime_lookahead(). If LLk is 2, - then - - consume() - { - NLA = inputTokens->getToken()->getType(); - dirty--; - lap = (lap+1)&(LLk-1); - } - - or expanding NLA, - - token_type[lap&(LLk-1)]) = inputTokens->getToken()->getType(); - dirty--; - lap = (lap+1)&(LLk-1); - - so now we prime locations 1 and 2. In prime_lookahead it used to set - lap=0 and labase=0. Now, the next token will be read from location 0, - NOT 1 as it should have been. - - This was never caught before, because if a parser is just instantiated, - then lap and labase are 0, the offending assignment lines are - basically no-ops, since the for loop wraps around back to 0. - -#196. (Changed in MR14) Problems with "(alpha)? beta" guess - - Consider the following syntactic predicate in a grammar - with 2 tokens of lookahead (k=2 or ck=2): - - rule : ( alpha )? beta ; - alpha : S t ; - t : T U - | T - ; - beta : S t Z ; - - When antlr computes the prediction expression with one token - of lookahead for alts 1 and 2 of rule t it finds an ambiguity. - - Because the grammar has a lookahead of 2 it tries to compute - two tokens of lookahead for alts 1 and 2 of t. Alt 1 clearly - has a lookahead of (T U). Alt 2 is one token long so antlr - tries to compute the follow set of alt 2, which means finding - the things which can follow rule t in the context of (alpha)?. - This cannot be computed, because alpha is only part of a rule, - and antlr can't tell what part of beta is matched by alpha and - what part remains to be matched. Thus it impossible for antlr - to properly determine the follow set of rule t. - - Prior to 1.33MR14, the follow of (alpha)? was computed as - FIRST(beta) as a result of the internal representation of - guess blocks. - - With MR14 the follow set will be the empty set for that context. - - Normally, one expects a rule appearing in a guess block to also - appear elsewhere. When the follow context for this other use - is "ored" with the empty set, the context from the other use - results, and a reasonable follow context results. However if - there is *no* other use of the rule, or it is used in a different - manner then the follow context will be inaccurate - it was - inaccurate even before MR14, but it will be inaccurate in a - different way. - - For the example given earlier, a reasonable way to rewrite the - grammar: - - rule : ( alpha )? beta - alpha : S t ; - t : T U - | T - ; - beta : alpha Z ; - - If there are no other uses of the rule appearing in the guess - block it will generate a test for EOF - a workaround for - representing a null set in the lookahead tests. - - If you encounter such a problem you can use the -alpha option - to get additional information: - - line 2: error: not possible to compute follow set for alpha - in an "(alpha)? beta" block. - - With the antlr -alpha command line option the following information - is inserted into the generated file: - - #if 0 - - Trace of references leading to attempt to compute the follow set of - alpha in an "(alpha)? beta" block. It is not possible for antlr to - compute this follow set because it is not known what part of beta has - already been matched by alpha and what part remains to be matched. - - Rules which make use of the incorrect follow set will also be incorrect - - 1 #token T alpha/2 line 7 brief.g - 2 end alpha alpha/3 line 8 brief.g - 2 end (...)? block at start/1 line 2 brief.g - - #endif - - At the moment, with the -alpha option selected the program marks - any rules which appear in the trace back chain (above) as rules with - possible problems computing follow set. - - Reported by Greg Knapen (gregory.knapen bell.ca). - -#195. (Changed in MR14) #line directive not at column 1 - - Under certain circunstances a predicate test could generate - a #line directive which was not at column 1. - - Reported with fix by David Kågedal (davidk lysator.liu.se) - (http://www.lysator.liu.se/~davidk/). - -#194. (Changed in MR14) (C Mode only) Demand lookahead with #tokclass - - In C mode with the demand lookahead option there is a bug in the - code which handles matches for #tokclass (zzsetmatch and - zzsetmatch_wsig). - - The bug causes the lookahead pointer to get out of synchronization - with the current token pointer. - - The problem was reported with a fix by Ger Hobbelt (hobbelt axa.nl). - -#193. (Changed in MR14) Use of PCCTS_USE_NAMESPACE_STD - - The pcctscfg.h now contains the following definitions: - - #ifdef PCCTS_USE_NAMESPACE_STD - #define PCCTS_STDIO_H - #define PCCTS_STDLIB_H - #define PCCTS_STDARG_H - #define PCCTS_SETJMP_H - #define PCCTS_STRING_H - #define PCCTS_ASSERT_H - #define PCCTS_ISTREAM_H - #define PCCTS_IOSTREAM_H - #define PCCTS_NAMESPACE_STD namespace std {}; using namespace std; - #else - #define PCCTS_STDIO_H - #define PCCTS_STDLIB_H - #define PCCTS_STDARG_H - #define PCCTS_SETJMP_H - #define PCCTS_STRING_H - #define PCCTS_ASSERT_H - #define PCCTS_ISTREAM_H - #define PCCTS_IOSTREAM_H - #define PCCTS_NAMESPACE_STD - #endif - - The runtime support in pccts/h uses these pre-processor symbols - consistently. - - Also, antlr and dlg have been changed to generate code which uses - these pre-processor symbols rather than having the names of the - #include files hard-coded in the generated code. - - This required the addition of "#include pcctscfg.h" to a number of - files in pccts/h. - - It appears that this sometimes causes problems for MSVC 5 in - combination with the "automatic" option for pre-compiled headers. - In such cases disable the "automatic" pre-compiled headers option. - - Suggested by Hubert Holin (Hubert.Holin Bigfoot.com). - -#192. (Changed in MR14) Change setText() to accept "const ANTLRChar *" - - Changed ANTLRToken::setText(ANTLRChar *) to setText(const ANTLRChar *). - This allows literal strings to be used to initialize tokens. Since - the usual token implementation (ANTLRCommonToken) makes a copy of the - input string, this was an unnecessary limitation. - - Suggested by Bob McWhirter (bob netwrench.com). - -#191. (Changed in MR14) HP/UX aCC compiler compatibility problem - - Needed to explicitly declare zzINF_DEF_TOKEN_BUFFER_SIZE and - zzINF_BUFFER_TOKEN_CHUNK_SIZE as ints in pccts/h/AParser.cpp. - - Reported by David Cook (dcook bmc.com). - -#190. (Changed in MR14) IBM OS/2 CSet compiler compatibility problem - - Name conflict with "_cs" in pccts/h/ATokenBuffer.cpp - - Reported by David Cook (dcook bmc.com). - -#189. (Changed in MR14) -gxt switch in C mode - - The -gxt switch in C mode didn't work because of incorrect - initialization. - - Reported by Sinan Karasu (sinan boeing.com). - -#188. (Changed in MR14) Added pccts/h/DLG_stream_input.h - - This is a DLG stream class based on C++ istreams. - - Contributed by Hubert Holin (Hubert.Holin Bigfoot.com). - -#187. (Changed in MR14) Rename config.h to pcctscfg.h - - The PCCTS configuration file has been renamed from config.h to - pcctscfg.h. The problem with the original name is that it led - to name collisions when pccts parsers were combined with other - software. - - All of the runtime support routines in pccts/h/* have been - changed to use the new name. Existing software can continue - to use pccts/h/config.h. The contents of pccts/h/config.h is - now just "#include "pcctscfg.h". - - I don't have a record of the user who suggested this. - -#186. (Changed in MR14) Pre-processor symbol DllExportPCCTS class modifier - - Classes in the C++ runtime support routines are now declared: - - class DllExportPCCTS className .... - - By default, the pre-processor symbol is defined as the empty - string. This if for use by MSVC++ users to create DLL classes. - - Suggested by Manfred Kogler (km cast.uni-linz.ac.at). - -#185. (Changed in MR14) Option to not use PCCTS_AST base class for ASTBase - - Normally, the ASTBase class is derived from PCCTS_AST which contains - functions useful to Sorcerer. If these are not necessary then the - user can define the pre-processor symbol "PCCTS_NOT_USING_SOR" which - will cause the ASTBase class to replace references to PCCTS_AST with - references to ASTBase where necessary. - - The class ASTDoublyLinkedBase will contain a pure virtual function - shallowCopy() that was formerly defined in class PCCTS_AST. - - Suggested by Bob McWhirter (bob netwrench.com). - -#184. (Changed in MR14) Grammars with no tokens generate invalid tokens.h - - Reported by Hubert Holin (Hubert.Holin bigfoot.com). - -#183. (Changed in MR14) -f to specify file with names of grammar files - - In DEC/VMS it is difficult to specify very long command lines. - The -f option allows one to place the names of the grammar files - in a data file in order to bypass limitations of the DEC/VMS - command language interpreter. - - Addition supplied by Bernard Giroud (b_giroud decus.ch). - -#182. (Changed in MR14) Output directory option for DEC/VMS - - Fix some problems with the -o option under DEC/VMS. - - Fix supplied by Bernard Giroud (b_giroud decus.ch). - -#181. (Changed in MR14) Allow chars > 127 in DLGStringInput::nextChar() - - Changed DLGStringInput to cast the character using (unsigned char) - so that languages with character codes greater than 127 work - without changes. - - Suggested by Manfred Kogler (km cast.uni-linz.ac.at). - -#180. (Added in MR14) ANTLRParser::getEofToken() - - Added "ANTLRToken ANTLRParser::getEofToken() const" to match the - setEofToken routine. - - Requested by Manfred Kogler (km cast.uni-linz.ac.at). - -#179. (Fixed in MR14) Memory leak for BufFileInput subclass of DLGInputStream - - The BufFileInput class described in Item #142 neglected to release - the allocated buffer when an instance was destroyed. - - Reported by Manfred Kogler (km cast.uni-linz.ac.at). - -#178. (Fixed in MR14) Bug in "(alpha)? beta" guess blocks first sets - - In 1.33 vanilla, and all maintenance releases prior to MR14 - there is a bug in the handling of guess blocks which use the - "long" form: - - (alpha)? beta - - inside a (...)*, (...)+, or {...} block. - - This problem does *not* apply to the case where beta is omitted - or when the syntactic predicate is on the leading edge of an - alternative. - - The problem is that both alpha and beta are stored in the - syntax diagram, and that some analysis routines would fail - to skip the alpha portion when it was not on the leading edge. - Consider the following grammar with -ck 2: - - r : ( (A)? B )* C D - - | A B /* forces -ck 2 computation for old antlr */ - /* reports ambig for alts 1 & 2 */ - - | B C /* forces -ck 2 computation for new antlr */ - /* reports ambig for alts 1 & 3 */ - ; - - The prediction expression for the first alternative should be - LA(1)={B C} LA(2)={B C D}, but previous versions of antlr - would compute the prediction expression as LA(1)={A C} LA(2)={B D} - - Reported by Arpad Beszedes (beszedes inf.u-szeged.hu) who provided - a very clear example of the problem and identified the probable cause. - -#177. (Changed in MR14) #tokdefs and #token with regular expression - - In MR13 the change described by Item #162 caused an existing - feature of antlr to fail. Prior to the change it was possible - to give regular expression definitions and actions to tokens - which were defined via the #tokdefs directive. - - This now works again. - - Reported by Manfred Kogler (km cast.uni-linz.ac.at). - -#176. (Changed in MR14) Support for #line in antlr source code - - Note: this was implemented by Arpad Beszedes (beszedes inf.u-szeged.hu). - - In 1.33MR14 it is possible for a pre-processor to generate #line - directives in the antlr source and have those line numbers and file - names used in antlr error messages and in the #line directives - generated by antlr. - - The #line directive may appear in the following forms: - - #line ll "sss" xx xx ... - - where ll represents a line number, "sss" represents the name of a file - enclosed in quotation marks, and xxx are arbitrary integers. - - The following form (without "line") is not supported at the moment: - - # ll "sss" xx xx ... - - The result: - - zzline - - is replaced with ll from the # or #line directive - - FileStr[CurFile] - - is updated with the contents of the string (if any) - following the line number - - Note - ---- - The file-name string following the line number can be a complete - name with a directory-path. Antlr generates the output files from - the input file name (by replacing the extension from the file-name - with .c or .cpp). - - If the input file (or the file-name from the line-info) contains - a path: - - "../grammar.g" - - the generated source code will be placed in "../grammar.cpp" (i.e. - in the parent directory). This is inconvenient in some cases - (even the -o switch can not be used) so the path information is - removed from the #line directive. Thus, if the line-info was - - #line 2 "../grammar.g" - - then the current file-name will become "grammar.g" - - In this way, the generated source code according to the grammar file - will always be in the current directory, except when the -o switch - is used. - -#175. (Changed in MR14) Bug when guess block appears at start of (...)* - - In 1.33 vanilla and all maintenance releases prior to 1.33MR14 - there is a bug when a guess block appears at the start of a (...)+. - Consider the following k=1 (ck=1) grammar: - - rule : - ( (STAR)? ZIP )* ID ; - - Prior to 1.33MR14, the generated code resembled: - - ... - zzGUESS_BLOCK - while ( 1 ) { - if ( ! LA(1)==STAR) break; - zzGUESS - if ( !zzrv ) { - zzmatch(STAR); - zzCONSUME; - zzGUESS_DONE - zzmatch(ZIP); - zzCONSUME; - ... - - Note that the routine uses STAR for the prediction expression - rather than ZIP. With 1.33MR14 the generated code resembles: - - ... - while ( 1 ) { - if ( ! LA(1)==ZIP) break; - ... - - This problem existed only with (...)* blocks and was caused - by the slightly more complicated graph which represents (...)* - blocks. This caused the analysis routine to compute the first - set for the alpha part of the "(alpha)? beta" rather than the - beta part. - - Both (...)+ and {...} blocks handled the guess block correctly. - - Reported by Arpad Beszedes (beszedes inf.u-szeged.hu) who provided - a very clear example of the problem and identified the probable cause. - -#174. (Changed in MR14) Bug when action precedes syntactic predicate - - In 1.33 vanilla, and all maintenance releases prior to MR14, - there was a bug when a syntactic predicate was immediately - preceded by an action. Consider the following -ck 2 grammar: - - rule : - <> - (alpha)? beta C - | A B - ; - - alpha : A ; - beta : A B; - - Prior to MR14, the code generated for the first alternative - resembled: - - ... - zzGUESS - if ( !zzrv && LA(1)==A && LA(2)==A) { - alpha(); - zzGUESS_DONE - beta(); - zzmatch(C); - zzCONSUME; - } else { - ... - - The prediction expression (i.e. LA(1)==A && LA(2)==A) is clearly - wrong because LA(2) should be matched to B (first[2] of beta is {B}). - - With 1.33MR14 the prediction expression is: - - ... - if ( !zzrv && LA(1)==A && LA(2)==B) { - alpha(); - zzGUESS_DONE - beta(); - zzmatch(C); - zzCONSUME; - } else { - ... - - This will only affect users in which alpha is shorter than - than max(k,ck) and there is an action immediately preceding - the syntactic predicate. - - This problem was reported by reported by Arpad Beszedes - (beszedes inf.u-szeged.hu) who provided a very clear example - of the problem and identified the presence of the init-action - as the likely culprit. - -#173. (Changed in MR13a) -glms for Microsoft style filenames with -gl - - With the -gl option antlr generates #line directives using the - exact name of the input files specified on the command line. - An oddity of the Microsoft C and C++ compilers is that they - don't accept file names in #line directives containing "\" - even though these are names from the native file system. - - With -glms option, the "\" in file names appearing in #line - directives is replaced with a "/" in order to conform to - Microsoft compiler requirements. - - Reported by Erwin Achermann (erwin.achermann switzerland.org). - -#172. (Changed in MR13) \r\n in antlr source counted as one line - - Some MS software uses \r\n to indicate a new line. Antlr - now recognizes this in counting lines. - - Reported by Edward L. Hepler (elh ece.vill.edu). - -#171. (Changed in MR13) #tokclass L..U now allowed - - The following is now allowed: - - #tokclass ABC { A..B C } - - Reported by Dave Watola (dwatola amtsun.jpl.nasa.gov) - -#170. (Changed in MR13) Suppression for predicates with lookahead depth >1 - - In MR12 the capability for suppression of predicates with lookahead - depth=1 was introduced. With MR13 this had been extended to - predicates with lookahead depth > 1 and released for use by users - on an experimental basis. - - Consider the following grammar with -ck 2 and the predicate in rule - "a" with depth 2: - - r1 : (ab)* "@" - ; - - ab : a - | b - ; - - a : (A B)? => <>? A B C - ; - - b : A B C - ; - - Normally, the predicate would be hoisted into rule r1 in order to - determine whether to call rule "ab". However it should *not* be - hoisted because, even if p is false, there is a valid alternative - in rule b. With "-mrhoistk on" the predicate will be suppressed. - - If "-info p" command line option is present the following information - will appear in the generated code: - - while ( (LA(1)==A) - #if 0 - - Part (or all) of predicate with depth > 1 suppressed by alternative - without predicate - - pred << p(LATEXT(2))>>? - depth=k=2 ("=>" guard) rule a line 8 t1.g - tree context: - (root = A - B - ) - - The token sequence which is suppressed: ( A B ) - The sequence of references which generate that sequence of tokens: - - 1 to ab r1/1 line 1 t1.g - 2 ab ab/1 line 4 t1.g - 3 to b ab/2 line 5 t1.g - 4 b b/1 line 11 t1.g - 5 #token A b/1 line 11 t1.g - 6 #token B b/1 line 11 t1.g - - #endif - - A slightly more complicated example: - - r1 : (ab)* "@" - ; - - ab : a - | b - ; - - a : (A B)? => <>? (A B | D E) - ; - - b : <>? D E - ; - - - In this case, the sequence (D E) in rule "a" which lies behind - the guard is used to suppress the predicate with context (D E) - in rule b. - - while ( (LA(1)==A || LA(1)==D) - #if 0 - - Part (or all) of predicate with depth > 1 suppressed by alternative - without predicate - - pred << q(LATEXT(2))>>? - depth=k=2 rule b line 11 t2.g - tree context: - (root = D - E - ) - - The token sequence which is suppressed: ( D E ) - The sequence of references which generate that sequence of tokens: - - 1 to ab r1/1 line 1 t2.g - 2 ab ab/1 line 4 t2.g - 3 to a ab/1 line 4 t2.g - 4 a a/1 line 8 t2.g - 5 #token D a/1 line 8 t2.g - 6 #token E a/1 line 8 t2.g - - #endif - && - #if 0 - - pred << p(LATEXT(2))>>? - depth=k=2 ("=>" guard) rule a line 8 t2.g - tree context: - (root = A - B - ) - - #endif - - (! ( LA(1)==A && LA(2)==B ) || p(LATEXT(2)) ) { - ab(); - ... - -#169. (Changed in MR13) Predicate test optimization for depth=1 predicates - - When the MR12 generated a test of a predicate which had depth 1 - it would use the depth >1 routines, resulting in correct but - inefficient behavior. In MR13, a bit test is used. - -#168. (Changed in MR13) Token expressions in context guards - - The token expressions appearing in context guards such as: - - (A B)? => <>? someRule - - are computed during an early phase of antlr processing. As - a result, prior to MR13, complex expressions such as: - - ~B - L..U - ~L..U - TokClassName - ~TokClassName - - were not computed properly. This resulted in incorrect - context being computed for such expressions. - - In MR13 these context guards are verified for proper semantics - in the initial phase and then re-evaluated after complex token - expressions have been computed in order to produce the correct - behavior. - - Reported by Arpad Beszedes (beszedes inf.u-szeged.hu). - -#167. (Changed in MR13) ~L..U - - Prior to MR13, the complement of a token range was - not properly computed. - -#166. (Changed in MR13) token expression L..U - - The token U was represented as an unsigned char, restricting - the use of L..U to cases where U was assigned a token number - less than 256. This is corrected in MR13. - -#165. (Changed in MR13) option -newAST - - To create ASTs from an ANTLRTokenPtr antlr usually calls - "new AST(ANTLRTokenPtr)". This option generates a call - to "newAST(ANTLRTokenPtr)" instead. This allows a user - to define a parser member function to create an AST object. - - Similar changes for ASTBase::tmake and ASTBase::link were not - thought necessary since they do not create AST objects, only - use existing ones. - -#164. (Changed in MR13) Unused variable _astp - - For many compilations, we have lived with warnings about - the unused variable _astp. It turns out that this varible - can *never* be used because the code which references it was - commented out. - - This investigation was sparked by a note from Erwin Achermann - (erwin.achermann switzerland.org). - -#163. (Changed in MR13) Incorrect makefiles for testcpp examples - - All the examples in pccts/testcpp/* had incorrect definitions - in the makefiles for the symbol "CCC". Instead of CCC=CC they - had CC=$(CCC). - - There was an additional problem in testcpp/1/test.g due to the - change in ANTLRToken::getText() to a const member function - (Item #137). - - Reported by Maurice Mass (maas cuci.nl). - -#162. (Changed in MR13) Combining #token with #tokdefs - - When it became possible to change the print-name of a - #token (Item #148) it became useful to give a #token - statement whose only purpose was to giving a print name - to the #token. Prior to this change this could not be - combined with the #tokdefs feature. - -#161. (Changed in MR13) Switch -gxt inhibits generation of tokens.h - -#160. (Changed in MR13) Omissions in list of names for remap.h - - When a user selects the -gp option antlr creates a list - of macros in remap.h to rename some of the standard - antlr routines from zzXXX to userprefixXXX. - - There were number of omissions from the remap.h name - list related to the new trace facility. This was reported, - along with a fix, by Bernie Solomon (bernard ug.eds.com). - -#159. (Changed in MR13) Violations of classic C rules - - There were a number of violations of classic C style in - the distribution kit. This was reported, along with fixes, - by Bernie Solomon (bernard ug.eds.com). - -#158. (Changed in MR13) #header causes problem for pre-processors - - A user who runs the C pre-processor on antlr source suggested - that another syntax be allowed. With MR13 such directives - such as #header, #pragma, etc. may be written as "\#header", - "\#pragma", etc. For escaping pre-processor directives inside - a #header use something like the following: - - \#header - << - \#include - >> - -#157. (Fixed in MR13) empty error sets for rules with infinite recursion - - When the first set for a rule cannot be computed due to infinite - left recursion and it is the only alternative for a block then - the error set for the block would be empty. This would result - in a fatal error. - - Reported by Darin Creason (creason genedax.com) - -#156. (Changed in MR13) DLGLexerBase::getToken() now public - -#155. (Changed in MR13) Context behind predicates can suppress - - With -mrhoist enabled the context behind a guarded predicate can - be used to suppress other predicates. Consider the following grammar: - - r0 : (r1)+; - - r1 : rp - | rq - ; - rp : <

>? B ; - rq : (A)? => <>? (A|B); - - In earlier versions both predicates "p" and "q" would be hoisted into - rule r0. With MR12c predicate p is suppressed because the context which - follows predicate q includes "B" which can "cover" predicate "p". In - other words, in trying to decide in r0 whether to call r1, it doesn't - really matter whether p is false or true because, either way, there is - a valid choice within r1. - -#154. (Changed in MR13) Making hoist suppression explicit using <> - - A common error, even among experienced pccts users, is to code - an init-action to inhibit hoisting rather than a leading action. - An init-action does not inhibit hoisting. - - This was coded: - - rule1 : <<;>> rule2 - - This is what was meant: - - rule1 : <<;>> <<;>> rule2 - - With MR13, the user can code: - - rule1 : <<;>> <> rule2 - - The following will give an error message: - - rule1 : <> rule2 - - If the <> appears as an init-action rather than a leading - action an error message is issued. The meaning of an init-action - containing "nohoist" is unclear: does it apply to just one - alternative or to all alternatives ? - - - - - - - - - ------------------------------------------------------- - Note: Items #153 to #1 are now in a separate file named - CHANGES_FROM_133_BEFORE_MR13.txt - ------------------------------------------------------- diff --git a/Tools/CodeTools/TianoTools/Pccts/CHANGES_FROM_133_BEFORE_MR13.txt b/Tools/CodeTools/TianoTools/Pccts/CHANGES_FROM_133_BEFORE_MR13.txt deleted file mode 100644 index bba5ecdd64..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/CHANGES_FROM_133_BEFORE_MR13.txt +++ /dev/null @@ -1,3666 +0,0 @@ - - ------------------------------------------------------------ - This is the second part of a two part file. - This is a list of changes to pccts 1.33 prior to MR13 - For more recent information see CHANGES_FROM_133.txt - ------------------------------------------------------------ - - DISCLAIMER - - The software and these notes are provided "as is". They may include - typographical or technical errors and their authors disclaims all - liability of any kind or nature for damages due to error, fault, - defect, or deficiency regardless of cause. All warranties of any - kind, either express or implied, including, but not limited to, the - implied warranties of merchantability and fitness for a particular - purpose are disclaimed. - - -#153. (Changed in MR12b) Bug in computation of -mrhoist suppression set - - Consider the following grammar with k=1 and "-mrhoist on": - - r1 : (A)? => ((p>>? x /* l1 */ - | r2 /* l2 */ - ; - r2 : A /* l4 */ - | (B)? => <>? y /* l5 */ - ; - - In earlier versions the mrhoist routine would see that both l1 and - l2 contained predicates and would assume that this prevented either - from acting to suppress the other predicate. In the example above - it didn't realize the A at line l4 is capable of suppressing the - predicate at l1 even though alt l2 contains (indirectly) a predicate. - - This is fixed in MR12b. - - Reported by Reinier van den Born (reinier@vnet.ibm.com) - -#153. (Changed in MR12a) Bug in computation of -mrhoist suppression set - - An oversight similar to that described in Item #152 appeared in - the computation of the set that "covered" a predicate. If a - predicate expression included a term such as p=AND(q,r) the context - of p was taken to be context(q) & context(r), when it should have - been context(q) | context(r). This is fixed in MR12a. - -#152. (Changed in MR12) Bug in generation of predicate expressions - - The primary purpose for MR12 is to make quite clear that MR11 is - obsolete and to fix the bug related to predicate expressions. - - In MR10 code was added to optimize the code generated for - predicate expression tests. Unfortunately, there was a - significant oversight in the code which resulted in a bug in - the generation of code for predicate expression tests which - contained predicates combined using AND: - - r0 : (r1)* "@" ; - r1 : (AAA)? => <

>? r2 ; - r2 : (BBB)? => <>? Q - | (BBB)? => <>? Q - ; - - In MR11 (and MR10 when using "-mrhoist on") the code generated - for r0 to predict r1 would be equivalent to: - - if ( LA(1)==Q && - (LA(1)==AAA && LA(1)==BBB) && - ( p && ( q || r )) ) { - - This is incorrect because it expresses the idea that LA(1) - *must* be AAA in order to attempt r1, and *must* be BBB to - attempt r2. The result was that r1 became unreachable since - both condition can not be simultaneously true. - - The general philosophy of code generation for predicates - can be summarized as follows: - - a. If the context is true don't enter an alt - for which the corresponding predicate is false. - - If the context is false then it is okay to enter - the alt without evaluating the predicate at all. - - b. A predicate created by ORing of predicates has - context which is the OR of their individual contexts. - - c. A predicate created by ANDing of predicates has - (surprise) context which is the OR of their individual - contexts. - - d. Apply these rules recursively. - - e. Remember rule (a) - - The correct code should express the idea that *if* LA(1) is - AAA then p must be true to attempt r1, but if LA(1) is *not* - AAA then it is okay to attempt r1, provided that *if* LA(1) is - BBB then one of q or r must be true. - - if ( LA(1)==Q && - ( !(LA(1)==AAA || LA(1)==BBB) || - ( ! LA(1) == AAA || p) && - ( ! LA(1) == BBB || q || r ) ) ) { - - I believe this is fixed in MR12. - - Reported by Reinier van den Born (reinier@vnet.ibm.com) - -#151a. (Changed in MR12) ANTLRParser::getLexer() - - As a result of several requests, I have added public methods to - get a pointer to the lexer belonging to a parser. - - ANTLRTokenStream *ANTLRParser::getLexer() const - - Returns a pointer to the lexer being used by the - parser. ANTLRTokenStream is the base class of - DLGLexer - - ANTLRTokenStream *ANTLRTokenBuffer::getLexer() const - - Returns a pointer to the lexer being used by the - ANTLRTokenBuffer. ANTLRTokenStream is the base - class of DLGLexer - - You must manually cast the ANTLRTokenStream to your program's - lexer class. Because the name of the lexer's class is not fixed. - Thus it is impossible to incorporate it into the DLGLexerBase - class. - -#151b.(Changed in MR12) ParserBlackBox member getLexer() - - The template class ParserBlackBox now has a member getLexer() - which returns a pointer to the lexer. - -#150. (Changed in MR12) syntaxErrCount and lexErrCount now public - - See Item #127 for more information. - -#149. (Changed in MR12) antlr option -info o (letter o for orphan) - - If there is more than one rule which is not referenced by any - other rule then all such rules are listed. This is useful for - alerting one to rules which are not used, but which can still - contribute to ambiguity. For example: - - start : a Z ; - unused: a A ; - a : (A)+ ; - - will cause an ambiguity report for rule "a" which will be - difficult to understand if the user forgets about rule "unused" - simply because it is not used in the grammar. - -#148. (Changed in MR11) #token names appearing in zztokens,token_tbl - - In a #token statement like the following: - - #token Plus "\+" - - the string "Plus" appears in the zztokens array (C mode) and - token_tbl (C++ mode). This string is used in most error - messages. In MR11 one has the option of using some other string, - (e.g. "+") in those tables. - - In MR11 one can write: - - #token Plus ("+") "\+" - #token RP ("(") "\(" - #token COM ("comment begin") "/\*" - - A #token statement is allowed to appear in more than one #lexclass - with different regular expressions. However, the token name appears - only once in the zztokens/token_tbl array. This means that only - one substitute can be specified for a given #token name. The second - attempt to define a substitute name (different from the first) will - result in an error message. - -#147. (Changed in MR11) Bug in follow set computation - - There is a bug in 1.33 vanilla and all maintenance releases - prior to MR11 in the computation of the follow set. The bug is - different than that described in Item #82 and probably more - common. It was discovered in the ansi.g grammar while testing - the "ambiguity aid" (Item #119). The search for a bug started - when the ambiguity aid was unable to discover the actual source - of an ambiguity reported by antlr. - - The problem appears when an optimization of the follow set - computation is used inappropriately. The result is that the - follow set used is the "worst case". In other words, the error - can lead to false reports of ambiguity. The good news is that - if you have a grammar in which you have addressed all reported - ambiguities you are ok. The bad news is that you may have spent - time fixing ambiguities that were not real, or used k=2 when - ck=2 might have been sufficient, and so on. - - The following grammar demonstrates the problem: - - ------------------------------------------------------------ - expr : ID ; - - start : stmt SEMI ; - - stmt : CASE expr COLON - | expr SEMI - | plain_stmt - ; - - plain_stmt : ID COLON ; - ------------------------------------------------------------ - - When compiled with k=1 and ck=2 it will report: - - warning: alts 2 and 3 of the rule itself ambiguous upon - { IDENTIFIER }, { COLON } - - When antlr analyzes "stmt" it computes the first[1] set of all - alternatives. It finds an ambiguity between alts 2 and 3 for ID. - It then computes the first[2] set for alternatives 2 and 3 to resolve - the ambiguity. In computing the first[2] set of "expr" (which is - only one token long) it needs to determine what could follow "expr". - Under a certain combination of circumstances antlr forgets that it - is trying to analyze "stmt" which can only be followed by SEMI and - adds to the first[2] set of "expr" the "global" follow set (including - "COLON") which could follow "expr" (under other conditions) in the - phrase "CASE expr COLON". - -#146. (Changed in MR11) Option -treport for locating "difficult" alts - - It can be difficult to determine which alternatives are causing - pccts to work hard to resolve an ambiguity. In some cases the - ambiguity is successfully resolved after much CPU time so there - is no message at all. - - A rough measure of the amount of work being peformed which is - independent of the CPU speed and system load is the number of - tnodes created. Using "-info t" gives information about the - total number of tnodes created and the peak number of tnodes. - - Tree Nodes: peak 1300k created 1416k lost 0 - - It also puts in the generated C or C++ file the number of tnodes - created for a rule (at the end of the rule). However this - information is not sufficient to locate the alternatives within - a rule which are causing the creation of tnodes. - - Using: - - antlr -treport 100000 .... - - causes antlr to list on stdout any alternatives which require the - creation of more than 100,000 tnodes, along with the lookahead sets - for those alternatives. - - The following is a trivial case from the ansi.g grammar which shows - the format of the report. This report might be of more interest - in cases where 1,000,000 tuples were created to resolve the ambiguity. - - ------------------------------------------------------------------------- - There were 0 tuples whose ambiguity could not be resolved - by full lookahead - There were 157 tnodes created to resolve ambiguity between: - - Choice 1: statement/2 line 475 file ansi.g - Choice 2: statement/3 line 476 file ansi.g - - Intersection of lookahead[1] sets: - - IDENTIFIER - - Intersection of lookahead[2] sets: - - LPARENTHESIS COLON AMPERSAND MINUS - STAR PLUSPLUS MINUSMINUS ONESCOMPLEMENT - NOT SIZEOF OCTALINT DECIMALINT - HEXADECIMALINT FLOATONE FLOATTWO IDENTIFIER - STRING CHARACTER - ------------------------------------------------------------------------- - -#145. (Documentation) Generation of Expression Trees - - Item #99 was misleading because it implied that the optimization - for tree expressions was available only for trees created by - predicate expressions and neglected to mention that it required - the use of "-mrhoist on". The optimization applies to tree - expressions created for grammars with k>1 and for predicates with - lookahead depth >1. - - In MR11 the optimized version is always used so the -mrhoist on - option need not be specified. - -#144. (Changed in MR11) Incorrect test for exception group - - In testing for a rule's exception group the label a pointer - is compared against '\0'. The intention is "*pointer". - - Reported by Jeffrey C. Fried (Jeff@Fried.net). - -#143. (Changed in MR11) Optional ";" at end of #token statement - - Fixes problem of: - - #token X "x" - - << - parser action - >> - - Being confused with: - - #token X "x" <> - -#142. (Changed in MR11) class BufFileInput subclass of DLGInputStream - - Alexey Demakov (demakov@kazbek.ispras.ru) has supplied class - BufFileInput derived from DLGInputStream which provides a - function lookahead(char *string) to test characters in the - input stream more than one character ahead. - - The default amount of lookahead is specified by the constructor - and defaults to 8 characters. This does *not* include the one - character of lookahead maintained internally by DLG in member "ch" - and which is not available for testing via BufFileInput::lookahead(). - - This is a useful class for overcoming the one-character-lookahead - limitation of DLG without resorting to a lexer capable of - backtracking (like flex) which is not integrated with antlr as is - DLG. - - There are no restrictions on copying or using BufFileInput.* except - that the authorship and related information must be retained in the - source code. - - The class is located in pccts/h/BufFileInput.* of the kit. - -#141. (Changed in MR11) ZZDEBUG_CONSUME for ANTLRParser::consume() - - A debug aid has been added to file ANTLRParser::consume() in - file AParser.cpp: - - #ifdef ZZDEBUG_CONSUME_ACTION - zzdebug_consume_action(); - #endif - - Suggested by Sramji Ramanathan (ps@kumaran.com). - -#140. (Changed in MR11) #pred to define predicates - - +---------------------------------------------------+ - | Note: Assume "-prc on" for this entire discussion | - +---------------------------------------------------+ - - A problem with predicates is that each one is regarded as - unique and capable of disambiguating cases where two - alternatives have identical lookahead. For example: - - rule : <>? A - | <>? A - ; - - will not cause any error messages or warnings to be issued - by earlier versions of pccts. To compare the text of the - predicates is an incomplete solution. - - In 1.33MR11 I am introducing the #pred statement in order to - solve some problems with predicates. The #pred statement allows - one to give a symbolic name to a "predicate literal" or a - "predicate expression" in order to refer to it in other predicate - expressions or in the rules of the grammar. - - The predicate literal associated with a predicate symbol is C - or C++ code which can be used to test the condition. A - predicate expression defines a predicate symbol in terms of other - predicate symbols using "!", "&&", and "||". A predicate symbol - can be defined in terms of a predicate literal, a predicate - expression, or *both*. - - When a predicate symbol is defined with both a predicate literal - and a predicate expression, the predicate literal is used to generate - code, but the predicate expression is used to check for two - alternatives with identical predicates in both alternatives. - - Here are some examples of #pred statements: - - #pred IsLabel <>? - #pred IsLocalVar <>? - #pred IsGlobalVar <>? - #pred IsVar <>? IsLocalVar || IsGlobalVar - #pred IsScoped <>? IsLabel || IsLocalVar - - I hope that the use of EBNF notation to describe the syntax of the - #pred statement will not cause problems for my readers (joke). - - predStatement : "#pred" - CapitalizedName - ( - "<>?" - | "<>?" predOrExpr - | predOrExpr - ) - ; - - predOrExpr : predAndExpr ( "||" predAndExpr ) * ; - - predAndExpr : predPrimary ( "&&" predPrimary ) * ; - - predPrimary : CapitalizedName - | "!" predPrimary - | "(" predOrExpr ")" - ; - - What is the purpose of this nonsense ? - - To understand how predicate symbols help, you need to realize that - predicate symbols are used in two different ways with two different - goals. - - a. Allow simplification of predicates which have been combined - during predicate hoisting. - - b. Allow recognition of identical predicates which can't disambiguate - alternatives with common lookahead. - - First we will discuss goal (a). Consider the following rule: - - rule0: rule1 - | ID - | ... - ; - - rule1: rule2 - | rule3 - ; - - rule2: <>? ID ; - rule3: <>? ID ; - - When the predicates in rule2 and rule3 are combined by hoisting - to create a prediction expression for rule1 the result is: - - if ( LA(1)==ID - && ( isX(LATEXT(1) || !isX(LATEXT(1) ) ) { rule1(); ... - - This is inefficient, but more importantly, can lead to false - assumptions that the predicate expression distinguishes the rule1 - alternative with some other alternative with lookahead ID. In - MR11 one can write: - - #pred IsX <>? - - ... - - rule2: <>? ID ; - rule3: <>? ID ; - - During hoisting MR11 recognizes this as a special case and - eliminates the predicates. The result is a prediction - expression like the following: - - if ( LA(1)==ID ) { rule1(); ... - - Please note that the following cases which appear to be equivalent - *cannot* be simplified by MR11 during hoisting because the hoisting - logic only checks for a "!" in the predicate action, not in the - predicate expression for a predicate symbol. - - *Not* equivalent and is not simplified during hoisting: - - #pred IsX <>? - #pred NotX <>? - ... - rule2: <>? ID ; - rule3: <>? ID ; - - *Not* equivalent and is not simplified during hoisting: - - #pred IsX <>? - #pred NotX !IsX - ... - rule2: <>? ID ; - rule3: <>? ID ; - - Now we will discuss goal (b). - - When antlr discovers that there is a lookahead ambiguity between - two alternatives it attempts to resolve the ambiguity by searching - for predicates in both alternatives. In the past any predicate - would do, even if the same one appeared in both alternatives: - - rule: <>? X - | <>? X - ; - - The #pred statement is a start towards solving this problem. - During ambiguity resolution (*not* predicate hoisting) the - predicates for the two alternatives are expanded and compared. - Consider the following example: - - #pred Upper <>? - #pred Lower <>? - #pred Alpha <>? Upper || Lower - - rule0: rule1 - | <>? ID - ; - - rule1: - | rule2 - | rule3 - ... - ; - - rule2: <>? ID; - rule3: <>? ID; - - The definition of #pred Alpha expresses: - - a. to test the predicate use the C code "isAlpha(LATEXT(1))" - - b. to analyze the predicate use the information that - Alpha is equivalent to the union of Upper and Lower, - - During ambiguity resolution the definition of Alpha is expanded - into "Upper || Lower" and compared with the predicate in the other - alternative, which is also "Upper || Lower". Because they are - identical MR11 will report a problem. - - ------------------------------------------------------------------------- - t10.g, line 5: warning: the predicates used to disambiguate rule rule0 - (file t10.g alt 1 line 5 and alt 2 line 6) - are identical when compared without context and may have no - resolving power for some lookahead sequences. - ------------------------------------------------------------------------- - - If you use the "-info p" option the output file will contain: - - +----------------------------------------------------------------------+ - |#if 0 | - | | - |The following predicates are identical when compared without | - | lookahead context information. For some ambiguous lookahead | - | sequences they may not have any power to resolve the ambiguity. | - | | - |Choice 1: rule0/1 alt 1 line 5 file t10.g | - | | - | The original predicate for choice 1 with available context | - | information: | - | | - | OR expr | - | | - | pred << Upper>>? | - | depth=k=1 rule rule2 line 14 t10.g | - | set context: | - | ID | - | | - | pred << Lower>>? | - | depth=k=1 rule rule3 line 15 t10.g | - | set context: | - | ID | - | | - | The predicate for choice 1 after expansion (but without context | - | information): | - | | - | OR expr | - | | - | pred << isUpper(LATEXT(1))>>? | - | depth=k=1 rule line 1 t10.g | - | | - | pred << isLower(LATEXT(1))>>? | - | depth=k=1 rule line 2 t10.g | - | | - | | - |Choice 2: rule0/2 alt 2 line 6 file t10.g | - | | - | The original predicate for choice 2 with available context | - | information: | - | | - | pred << Alpha>>? | - | depth=k=1 rule rule0 line 6 t10.g | - | set context: | - | ID | - | | - | The predicate for choice 2 after expansion (but without context | - | information): | - | | - | OR expr | - | | - | pred << isUpper(LATEXT(1))>>? | - | depth=k=1 rule line 1 t10.g | - | | - | pred << isLower(LATEXT(1))>>? | - | depth=k=1 rule line 2 t10.g | - | | - | | - |#endif | - +----------------------------------------------------------------------+ - - The comparison of the predicates for the two alternatives takes - place without context information, which means that in some cases - the predicates will be considered identical even though they operate - on disjoint lookahead sets. Consider: - - #pred Alpha - - rule1: <>? ID - | <>? Label - ; - - Because the comparison of predicates takes place without context - these will be considered identical. The reason for comparing - without context is that otherwise it would be necessary to re-evaluate - the entire predicate expression for each possible lookahead sequence. - This would require more code to be written and more CPU time during - grammar analysis, and it is not yet clear whether anyone will even make - use of the new #pred facility. - - A temporary workaround might be to use different #pred statements - for predicates you know have different context. This would avoid - extraneous warnings. - - The above example might be termed a "false positive". Comparison - without context will also lead to "false negatives". Consider the - following example: - - #pred Alpha - #pred Beta - - rule1: <>? A - | rule2 - ; - - rule2: <>? A - | <>? B - ; - - The predicate used for alt 2 of rule1 is (Alpha || Beta). This - appears to be different than the predicate Alpha used for alt1. - However, the context of Beta is B. Thus when the lookahead is A - Beta will have no resolving power and Alpha will be used for both - alternatives. Using the same predicate for both alternatives isn't - very helpful, but this will not be detected with 1.33MR11. - - To properly handle this the predicate expression would have to be - evaluated for each distinct lookahead context. - - To determine whether two predicate expressions are identical is - difficult. The routine may fail to identify identical predicates. - - The #pred feature also compares predicates to see if a choice between - alternatives which is resolved by a predicate which makes the second - choice unreachable. Consider the following example: - - #pred A <>? - #pred B <>? - #pred A_or_B A || B - - r : s - | t - ; - s : <>? ID - ; - t : <>? ID - ; - - ---------------------------------------------------------------------------- - t11.g, line 5: warning: the predicate used to disambiguate the - first choice of rule r - (file t11.g alt 1 line 5 and alt 2 line 6) - appears to "cover" the second predicate when compared without context. - The second predicate may have no resolving power for some lookahead - sequences. - ---------------------------------------------------------------------------- - -#139. (Changed in MR11) Problem with -gp in C++ mode - - The -gp option to add a prefix to rule names did not work in - C++ mode. This has been fixed. - - Reported by Alexey Demakov (demakov@kazbek.ispras.ru). - -#138. (Changed in MR11) Additional makefiles for non-MSVC++ MS systems - - Sramji Ramanathan (ps@kumaran.com) has supplied makefiles for - building antlr and dlg with Win95/NT development tools that - are not based on MSVC5. They are pccts/antlr/AntlrMS.mak and - pccts/dlg/DlgMS.mak. - - The first line of the makefiles require a definition of PCCTS_HOME. - - These are in additiion to the AntlrMSVC50.* and DlgMSVC50.* - supplied by Jeff Vincent (JVincent@novell.com). - -#137. (Changed in MR11) Token getType(), getText(), getLine() const members - - -------------------------------------------------------------------- - If you use ANTLRCommonToken this change probably does not affect you. - -------------------------------------------------------------------- - - For a long time it has bothered me that these accessor functions - in ANTLRAbstractToken were not const member functions. I have - refrained from changing them because it require users to modify - existing token class definitions which are derived directly - from ANTLRAbstractToken. I think it is now time. - - For those who are not used to C++, a "const member function" is a - member function which does not modify its own object - the thing - to which "this" points. This is quite different from a function - which does not modify its arguments - - Most token definitions based on ANTLRAbstractToken have something like - the following in order to create concrete definitions of the pure - virtual methods in ANTLRAbstractToken: - - class MyToken : public ANTLRAbstractToken { - ... - ANTLRTokenType getType() {return _type; } - int getLine() {return _line; } - ANTLRChar * getText() {return _text; } - ... - } - - The required change is simply to put "const" following the function - prototype in the header (.h file) and the definition file (.cpp if - it is not inline): - - class MyToken : public ANTLRAbstractToken { - ... - ANTLRTokenType getType() const {return _type; } - int getLine() const {return _line; } - ANTLRChar * getText() const {return _text; } - ... - } - - This was originally proposed a long time ago by Bruce - Guenter (bruceg@qcc.sk.ca). - -#136. (Changed in MR11) Added getLength() to ANTLRCommonToken - - Classes ANTLRCommonToken and ANTLRCommonTokenNoRefCountToken - now have a member function: - - int getLength() const { return strlen(getText()) } - - Suggested by Sramji Ramanathan (ps@kumaran.com). - -#135. (Changed in MR11) Raised antlr's own default ZZLEXBUFSIZE to 8k - -#134a. (ansi_mr10.zip) T.J. Parr's ANSI C grammar made 1.33MR11 compatible - - There is a typographical error in the definition of BITWISEOREQ: - - #token BITWISEOREQ "!=" should be "\|=" - - When this change is combined with the bugfix to the follow set cache - problem (Item #147) and a minor rearrangement of the grammar - (Item #134b) it becomes a k=1 ck=2 grammar. - -#134b. (ansi_mr10.zip) T.J. Parr's ANSI C grammar made 1.33MR11 compatible - - The following changes were made in the ansi.g grammar (along with - using -mrhoist on): - - ansi.g - ====== - void tracein(char *) ====> void tracein(const char *) - void traceout(char *) ====> void traceout(const char *) - - getType()==IDENTIFIER ? isTypeName(LT(1)->getText()) : 1>>? - ====> <getText())>>? - - <<(LT(1)->getType()==LPARENTHESIS && LT(2)->getType()==IDENTIFIER) ? \ - isTypeName(LT(2)->getText()) : 1>>? - ====> (LPARENTHESIS IDENTIFIER)? => <getText())>>? - - <<(LT(1)->getType()==LPARENTHESIS && LT(2)->getType()==IDENTIFIER) ? \ - isTypeName(LT(2)->getText()) : 1>>? - ====> (LPARENTHESIS IDENTIFIER)? => <getText())>>? - - added to init(): traceOptionValueDefault=0; - added to init(): traceOption(-1); - - change rule "statement": - - statement - : plain_label_statement - | case_label_statement - | <<;>> expression SEMICOLON - | compound_statement - | selection_statement - | iteration_statement - | jump_statement - | SEMICOLON - ; - - plain_label_statement - : IDENTIFIER COLON statement - ; - - case_label_statement - : CASE constant_expression COLON statement - | DEFAULT COLON statement - ; - - support.cpp - =========== - void tracein(char *) ====> void tracein(const char *) - void traceout(char *) ====> void traceout(const char *) - - added to tracein(): ANTLRParser::tracein(r); // call superclass method - added to traceout(): ANTLRParser::traceout(r); // call superclass method - - Makefile - ======== - added to AFLAGS: -mrhoist on -prc on - -#133. (Changed in 1.33MR11) Make trace options public in ANTLRParser - - In checking T.J. Parr's ANSI C grammar for compatibility with - 1.33MR11 discovered that it was inconvenient to have the - trace facilities with protected access. - -#132. (Changed in 1.33MR11) Recognition of identical predicates in alts - - Prior to 1.33MR11, there would be no ambiguity warning when the - very same predicate was used to disambiguate both alternatives: - - test: ref B - | ref C - ; - - ref : <>? A - - In 1.33MR11 this will cause the warning: - - warning: the predicates used to disambiguate rule test - (file v98.g alt 1 line 1 and alt 2 line 2) - are identical and have no resolving power - - ----------------- Note ----------------- - - This is different than the following case - - test: <>? A B - | <>? A C - ; - - In this case there are two distinct predicates - which have exactly the same text. In the first - example there are two references to the same - predicate. The problem represented by this - grammar will be addressed later. - -#131. (Changed in 1.33MR11) Case insensitive command line options - - Command line switches like "-CC" and keywords like "on", "off", - and "stdin" are no longer case sensitive in antlr, dlg, and sorcerer. - -#130. (Changed in 1.33MR11) Changed ANTLR_VERSION to int from string - - The ANTLR_VERSION was not an integer, making it difficult to - perform conditional compilation based on the antlr version. - - Henceforth, ANTLR_VERSION will be: - - (base_version * 10000) + release number - - thus 1.33MR11 will be: 133*100+11 = 13311 - - Suggested by Rainer Janssen (Rainer.Janssen@Informatik.Uni-Oldenburg.DE). - -#129. (Changed in 1.33MR11) Addition of ANTLR_VERSION to .h - - The following code is now inserted into .h amd - stdpccts.h: - - #ifndef ANTLR_VERSION - #define ANTLR_VERSION 13311 - #endif - - Suggested by Rainer Janssen (Rainer.Janssen@Informatik.Uni-Oldenburg.DE) - -#128. (Changed in 1.33MR11) Redundant predicate code in (<>? ...)+ - - Prior to 1.33MR11, the following grammar would generate - redundant tests for the "while" condition. - - rule2 : (<>? X)+ X - | B - ; - - The code would resemble: - - if (LA(1)==X) { - if (pred) { - do { - if (!pred) {zzfailed_pred(" pred");} - zzmatch(X); zzCONSUME; - } while (LA(1)==X && pred && pred); - } else {... - - With 1.33MR11 the redundant predicate test is omitted. - -#127. (Changed in 1.33MR11) - - Count Syntax Errors Count DLG Errors - ------------------- ---------------- - - C++ mode ANTLRParser:: DLGLexerBase:: - syntaxErrCount lexErrCount - C mode zzSyntaxErrCount zzLexErrCount - - The C mode variables are global and initialized to 0. - They are *not* reset to 0 automatically when antlr is - restarted. - - The C++ mode variables are public. They are initialized - to 0 by the constructors. They are *not* reset to 0 by the - ANTLRParser::init() method. - - Suggested by Reinier van den Born (reinier@vnet.ibm.com). - -#126. (Changed in 1.33MR11) Addition of #first <<...>> - - The #first <<...>> inserts the specified text in the output - files before any other #include statements required by pccts. - The only things before the #first text are comments and - a #define ANTLR_VERSION. - - Requested by and Esa Pulkkinen (esap@cs.tut.fi) and Alexin - Zoltan (alexin@inf.u-szeged.hu). - -#125. (Changed in 1.33MR11) Lookahead for (guard)? && <

>? predicates - - When implementing the new style of guard predicate (Item #113) - in 1.33MR10 I decided to temporarily ignore the problem of - computing the "narrowest" lookahead context. - - Consider the following k=1 grammar: - - start : a - | b - ; - - a : (A)? && <>? ab ; - b : (B)? && <>? ab ; - - ab : A | B ; - - In MR10 the context for both "a" and "b" was {A B} because this is - the first set of rule "ab". Normally, this is not a problem because - the predicate which follows the guard inhibits any ambiguity report - by antlr. - - In MR11 the first set for rule "a" is {A} and for rule "b" it is {B}. - -#124. A Note on the New "&&" Style Guarded Predicates - - I've been asked several times, "What is the difference between - the old "=>" style guard predicates and the new style "&&" guard - predicates, and how do you choose one over the other" ? - - The main difference is that the "=>" does not apply the - predicate if the context guard doesn't match, whereas - the && form always does. What is the significance ? - - If you have a predicate which is not on the "leading edge" - it cannot be hoisted. Suppose you need a predicate that - looks at LA(2). You must introduce it manually. The - classic example is: - - castExpr : - LP typeName RP - | .... - ; - - typeName : <>? ID - | STRUCT ID - ; - - The problem is that typeName isn't on the leading edge - of castExpr, so the predicate isTypeName won't be hoisted into - castExpr to help make a decision on which production to choose. - - The *first* attempt to fix it is this: - - castExpr : - <>? - LP typeName RP - | .... - ; - - Unfortunately, this won't work because it ignores - the problem of STRUCT. The solution is to apply - isTypeName() in castExpr if LA(2) is an ID and - don't apply it when LA(2) is STRUCT: - - castExpr : - (LP ID)? => <>? - LP typeName RP - | .... - ; - - In conclusion, the "=>" style guarded predicate is - useful when: - - a. the tokens required for the predicate - are not on the leading edge - b. there are alternatives in the expression - selected by the predicate for which the - predicate is inappropriate - - If (b) were false, then one could use a simple - predicate (assuming "-prc on"): - - castExpr : - <>? - LP typeName RP - | .... - ; - - typeName : <>? ID - ; - - So, when do you use the "&&" style guarded predicate ? - - The new-style "&&" predicate should always be used with - predicate context. The context guard is in ADDITION to - the automatically computed context. Thus it useful for - predicates which depend on the token type for reasons - other than context. - - The following example is contributed by Reinier van den Born - (reinier@vnet.ibm.com). - - +-------------------------------------------------------------------------+ - | This grammar has two ways to call functions: | - | | - | - a "standard" call syntax with parens and comma separated args | - | - a shell command like syntax (no parens and spacing separated args) | - | | - | The former also allows a variable to hold the name of the function, | - | the latter can also be used to call external commands. | - | | - | The grammar (simplified) looks like this: | - | | - | fun_call : ID "(" { expr ("," expr)* } ")" | - | /* ID is function name */ | - | | "@" ID "(" { expr ("," expr)* } ")" | - | /* ID is var containing fun name */ | - | ; | - | | - | command : ID expr* /* ID is function name */ | - | | path expr* /* path is external command name */ | - | ; | - | | - | path : ID /* left out slashes and such */ | - | | "@" ID /* ID is environment var */ | - | ; | - | | - | expr : .... | - | | "(" expr ")"; | - | | - | call : fun_call | - | | command | - | ; | - | | - | Obviously the call is wildly ambiguous. This is more or less how this | - | is to be resolved: | - | | - | A call begins with an ID or an @ followed by an ID. | - | | - | If it is an ID and if it is an ext. command name -> command | - | if followed by a paren -> fun_call | - | otherwise -> command | - | | - | If it is an @ and if the ID is a var name -> fun_call | - | otherwise -> command | - | | - | One can implement these rules quite neatly using && predicates: | - | | - | call : ("@" ID)? && <>? fun_call | - | | (ID)? && <>? command | - | | (ID "(")? fun_call | - | | command | - | ; | - | | - | This can be done better, so it is not an ideal example, but it | - | conveys the principle. | - +-------------------------------------------------------------------------+ - -#123. (Changed in 1.33MR11) Correct definition of operators in ATokPtr.h - - The return value of operators in ANTLRTokenPtr: - - changed: unsigned ... operator !=(...) - to: int ... operator != (...) - changed: unsigned ... operator ==(...) - to: int ... operator == (...) - - Suggested by R.A. Nelson (cowboy@VNET.IBM.COM) - -#122. (Changed in 1.33MR11) Member functions to reset DLG in C++ mode - - void DLGFileReset(FILE *f) { input = f; found_eof = 0; } - void DLGStringReset(DLGChar *s) { input = s; p = &input[0]; } - - Supplied by R.A. Nelson (cowboy@VNET.IBM.COM) - -#121. (Changed in 1.33MR11) Another attempt to fix -o (output dir) option - - Another attempt is made to improve the -o option of antlr, dlg, - and sorcerer. This one by JVincent (JVincent@novell.com). - - The current rule: - - a. If -o is not specified than any explicit directory - names are retained. - - b. If -o is specified than the -o directory name overrides any - explicit directory names. - - c. The directory name of the grammar file is *not* stripped - to create the main output file. However it is stil subject - to override by the -o directory name. - -#120. (Changed in 1.33MR11) "-info f" output to stdout rather than stderr - - Added option 0 (e.g. "-info 0") which is a noop. - -#119. (Changed in 1.33MR11) Ambiguity aid for grammars - - The user can ask for additional information on ambiguities reported - by antlr to stdout. At the moment, only one ambiguity report can - be created in an antlr run. - - This feature is enabled using the "-aa" (Ambiguity Aid) option. - - The following options control the reporting of ambiguities: - - -aa ruleName Selects reporting by name of rule - -aa lineNumber Selects reporting by line number - (file name not compared) - - -aam Selects "multiple" reporting for a token - in the intersection set of the - alternatives. - - For instance, the token ID may appear dozens - of times in various paths as the program - explores the rules which are reachable from - the point of an ambiguity. With option -aam - every possible path the search program - encounters is reported. - - Without -aam only the first encounter is - reported. This may result in incomplete - information, but the information may be - sufficient and much shorter. - - -aad depth Selects the depth of the search. - The default value is 1. - - The number of paths to be searched, and the - size of the report can grow geometrically - with the -ck value if a full search for all - contributions to the source of the ambiguity - is explored. - - The depth represents the number of tokens - in the lookahead set which are matched against - the set of ambiguous tokens. A depth of 1 - means that the search stops when a lookahead - sequence of just one token is matched. - - A k=1 ck=6 grammar might generate 5,000 items - in a report if a full depth 6 search is made - with the Ambiguity Aid. The source of the - problem may be in the first token and obscured - by the volume of data - I hesitate to call - it information. - - When the user selects a depth > 1, the search - is first performed at depth=1 for both - alternatives, then depth=2 for both alternatives, - etc. - - Sample output for rule grammar in antlr.g itself: - - +---------------------------------------------------------------------+ - | Ambiguity Aid | - | | - | Choice 1: grammar/70 line 632 file a.g | - | Choice 2: grammar/82 line 644 file a.g | - | | - | Intersection of lookahead[1] sets: | - | | - | "\}" "class" "#errclass" "#tokclass" | - | | - | Choice:1 Depth:1 Group:1 ("#errclass") | - | 1 in (...)* block grammar/70 line 632 a.g | - | 2 to error grammar/73 line 635 a.g | - | 3 error error/1 line 894 a.g | - | 4 #token "#errclass" error/2 line 895 a.g | - | | - | Choice:1 Depth:1 Group:2 ("#tokclass") | - | 2 to tclass grammar/74 line 636 a.g | - | 3 tclass tclass/1 line 937 a.g | - | 4 #token "#tokclass" tclass/2 line 938 a.g | - | | - | Choice:1 Depth:1 Group:3 ("class") | - | 2 to class_def grammar/75 line 637 a.g | - | 3 class_def class_def/1 line 669 a.g | - | 4 #token "class" class_def/3 line 671 a.g | - | | - | Choice:1 Depth:1 Group:4 ("\}") | - | 2 #token "\}" grammar/76 line 638 a.g | - | | - | Choice:2 Depth:1 Group:5 ("#errclass") | - | 1 in (...)* block grammar/83 line 645 a.g | - | 2 to error grammar/93 line 655 a.g | - | 3 error error/1 line 894 a.g | - | 4 #token "#errclass" error/2 line 895 a.g | - | | - | Choice:2 Depth:1 Group:6 ("#tokclass") | - | 2 to tclass grammar/94 line 656 a.g | - | 3 tclass tclass/1 line 937 a.g | - | 4 #token "#tokclass" tclass/2 line 938 a.g | - | | - | Choice:2 Depth:1 Group:7 ("class") | - | 2 to class_def grammar/95 line 657 a.g | - | 3 class_def class_def/1 line 669 a.g | - | 4 #token "class" class_def/3 line 671 a.g | - | | - | Choice:2 Depth:1 Group:8 ("\}") | - | 2 #token "\}" grammar/96 line 658 a.g | - +---------------------------------------------------------------------+ - - For a linear lookahead set ambiguity (where k=1 or for k>1 but - when all lookahead sets [i] with i>? A ; - c : A ; - - Prior to 1.33MR10 the code generated for "start" would resemble: - - while { - if (LA(1)==A && - (!LA(1)==A || isUpper())) { - a(); - } - }; - - This code is wrong because it makes rule "c" unreachable from - "start". The essence of the problem is that antlr fails to - recognize that there can be a valid alternative within "a" even - when the predicate <>? is false. - - In 1.33MR10 with -mrhoist the hoisting of the predicate into - "start" is suppressed because it recognizes that "c" can - cover all the cases where the predicate is false: - - while { - if (LA(1)==A) { - a(); - } - }; - - With the antlr "-info p" switch the user will receive information - about the predicate suppression in the generated file: - - -------------------------------------------------------------- - #if 0 - - Hoisting of predicate suppressed by alternative without predicate. - The alt without the predicate includes all cases where - the predicate is false. - - WITH predicate: line 7 v1.g - WITHOUT predicate: line 7 v1.g - - The context set for the predicate: - - A - - The lookahead set for the alt WITHOUT the semantic predicate: - - A - - The predicate: - - pred << isUpper(LATEXT(1))>>? - depth=k=1 rule b line 9 v1.g - set context: - A - tree context: null - - Chain of referenced rules: - - #0 in rule start (line 5 v1.g) to rule a - #1 in rule a (line 7 v1.g) - - #endif - -------------------------------------------------------------- - - A predicate can be suppressed by a combination of alternatives - which, taken together, cover a predicate: - - start : (a)* "@" ; - - a : b | ca | cb | cc ; - - b : <>? ( A | B | C ) ; - - ca : A ; - cb : B ; - cc : C ; - - Consider a more complex example in which "c" covers only part of - a predicate: - - start : (a)* "@" ; - - a : b - | c - ; - - b : <>? - ( A - | X - ); - - c : A - ; - - Prior to 1.33MR10 the code generated for "start" would resemble: - - while { - if ( (LA(1)==A || LA(1)==X) && - (! (LA(1)==A || LA(1)==X) || isUpper()) { - a(); - } - }; - - With 1.33MR10 and -mrhoist the predicate context is restricted to - the non-covered lookahead. The code resembles: - - while { - if ( (LA(1)==A || LA(1)==X) && - (! (LA(1)==X) || isUpper()) { - a(); - } - }; - - With the antlr "-info p" switch the user will receive information - about the predicate restriction in the generated file: - - -------------------------------------------------------------- - #if 0 - - Restricting the context of a predicate because of overlap - in the lookahead set between the alternative with the - semantic predicate and one without - Without this restriction the alternative without the predicate - could not be reached when input matched the context of the - predicate and the predicate was false. - - WITH predicate: line 11 v4.g - WITHOUT predicate: line 12 v4.g - - The original context set for the predicate: - - A X - - The lookahead set for the alt WITHOUT the semantic predicate: - - A - - The intersection of the two sets - - A - - The original predicate: - - pred << isUpper(LATEXT(1))>>? - depth=k=1 rule b line 15 v4.g - set context: - A X - tree context: null - - The new (modified) form of the predicate: - - pred << isUpper(LATEXT(1))>>? - depth=k=1 rule b line 15 v4.g - set context: - X - tree context: null - - #endif - -------------------------------------------------------------- - - The bad news about -mrhoist: - - (a) -mrhoist does not analyze predicates with lookahead - depth > 1. - - (b) -mrhoist does not look past a guarded predicate to - find context which might cover other predicates. - - For these cases you might want to use syntactic predicates. - When a semantic predicate fails during guess mode the guess - fails and the next alternative is tried. - - Limitation (a) is illustrated by the following example: - - start : (stmt)* EOF ; - - stmt : cast - | expr - ; - cast : <>? LP ID RP ; - - expr : LP ID RP ; - - This is not much different from the first example, except that - it requires two tokens of lookahead context to determine what - to do. This predicate is NOT suppressed because the current version - is unable to handle predicates with depth > 1. - - A predicate can be combined with other predicates during hoisting. - In those cases the depth=1 predicates are still handled. Thus, - in the following example the isUpper() predicate will be suppressed - by line #4 when hoisted from "bizarre" into "start", but will still - be present in "bizarre" in order to predict "stmt". - - start : (bizarre)* EOF ; // #1 - // #2 - bizarre : stmt // #3 - | A // #4 - ; - - stmt : cast - | expr - ; - - cast : <>? LP ID RP ; - - expr : LP ID RP ; - | <>? A - - Limitation (b) is illustrated by the following example of a - context guarded predicate: - - rule : (A)? <

>? // #1 - (A // #2 - |B // #3 - ) // #4 - | <> B // #5 - ; - - Recall that this means that when the lookahead is NOT A then - the predicate "p" is ignored and it attempts to match "A|B". - Ideally, the "B" at line #3 should suppress predicate "q". - However, the current version does not attempt to look past - the guard predicate to find context which might suppress other - predicates. - - In some cases -mrhoist will lead to the reporting of ambiguities - which were not visible before: - - start : (a)* "@"; - a : bc | d; - bc : b | c ; - - b : <>? A; - c : A ; - - d : A ; - - In this case there is a true ambiguity in "a" between "bc" and "d" - which can both match "A". Without -mrhoist the predicate in "b" - is hoisted into "a" and there is no ambiguity reported. However, - with -mrhoist, the predicate in "b" is suppressed by "c" (as it - should be) making the ambiguity in "a" apparent. - - The motivations for these changes were hoisting problems reported - by Reinier van den Born (reinier@vnet.ibm.com) and several others. - -#116. (Changed in 1.33MR10) C++ mode: tracein/traceout rule name is (const char *) - - The prototype for C++ mode routine tracein (and traceout) has changed from - "char *" to "const char *". - -#115. (Changed in 1.33MR10) Using guess mode with exception handlers in C mode - - The definition of the C mode macros zzmatch_wsig and zzsetmatch_wsig - neglected to consider guess mode. When control passed to the rule's - parse exception handler the routine would exit without ever closing the - guess block. This would lead to unpredictable behavior. - - In 1.33MR10 the behavior of exceptions in C mode and C++ mode should be - identical. - -#114. (Changed in 1.33MR10) difference in [zz]resynch() between C and C++ modes - - There was a slight difference in the way C and C++ mode resynchronized - following a parsing error. The C routine would sometimes skip an extra - token before attempting to resynchronize. - - The C routine was changed to match the C++ routine. - -#113. (Changed in 1.33MR10) new context guarded pred: (g)? && <

>? expr - - The existing context guarded predicate: - - rule : (guard)? => <

>? expr - | next_alternative - ; - - generates code which resembles: - - if (lookahead(expr) && (!guard || pred)) { - expr() - } else .... - - This is not suitable for some applications because it allows - expr() to be invoked when the predicate is false. This is - intentional because it is meant to mimic automatically computed - predicate context. - - The new context guarded predicate uses the guard information - differently because it has a different goal. Consider: - - rule : (guard)? && <

>? expr - | next_alternative - ; - - The new style of context guarded predicate is equivalent to: - - rule : <>? expr - | next_alternative - ; - - It generates code which resembles: - - if (lookahead(expr) && guard && pred) { - expr(); - } else ... - - Both forms of guarded predicates severely restrict the form of - the context guard: it can contain no rule references, no - (...)*, no (...)+, and no {...}. It may contain token and - token class references, and alternation ("|"). - - Addition for 1.33MR11: in the token expression all tokens must - be at the same height of the token tree: - - (A ( B | C))? && ... is ok (all height 2) - (A ( B | ))? && ... is not ok (some 1, some 2) - (A B C D | E F G H)? && ... is ok (all height 4) - (A B C D | E )? && ... is not ok (some 4, some 1) - - This restriction is required in order to properly compute the lookahead - set for expressions like: - - rule1 : (A B C)? && <>? rule2 ; - rule2 : (A|X) (B|Y) (C|Z); - - This addition was suggested by Rienier van den Born (reinier@vnet.ibm.com) - -#112. (Changed in 1.33MR10) failed validation predicate in C guess mode - - John Lilley (jlilley@empathy.com) suggested that failed validation - predicates abort a guess rather than reporting a failed error. - This was installed in C++ mode (Item #4). Only now was it noticed - that the fix was never installed for C mode. - -#111. (Changed in 1.33MR10) moved zzTRACEIN to before init action - - When the antlr -gd switch is present antlr generates calls to - zzTRACEIN at the start of a rule and zzTRACEOUT at the exit - from a rule. Prior to 1.33MR10 Tthe call to zzTRACEIN was - after the init-action, which could cause confusion because the - init-actions were reported with the name of the enclosing rule, - rather than the active rule. - -#110. (Changed in 1.33MR10) antlr command line copied to generated file - - The antlr command line is now copied to the generated file near - the start. - -#109. (Changed in 1.33MR10) improved trace information - - The quality of the trace information provided by the "-gd" - switch has been improved significantly. Here is an example - of the output from a test program. It shows the rule name, - the first token of lookahead, the call depth, and the guess - status: - - exit rule gusxx {"?"} depth 2 - enter rule gusxx {"?"} depth 2 - enter rule gus1 {"o"} depth 3 guessing - guess done - returning to rule gus1 {"o"} at depth 3 - (guess mode continues - an enclosing guess is still active) - guess done - returning to rule gus1 {"Z"} at depth 3 - (guess mode continues - an enclosing guess is still active) - exit rule gus1 {"Z"} depth 3 guessing - guess done - returning to rule gusxx {"o"} at depth 2 (guess mode ends) - enter rule gus1 {"o"} depth 3 - guess done - returning to rule gus1 {"o"} at depth 3 (guess mode ends) - guess done - returning to rule gus1 {"Z"} at depth 3 (guess mode ends) - exit rule gus1 {"Z"} depth 3 - line 1: syntax error at "Z" missing SC - ... - - Rule trace reporting is controlled by the value of the integer - [zz]traceOptionValue: when it is positive tracing is enabled, - otherwise it is disabled. Tracing during guess mode is controlled - by the value of the integer [zz]traceGuessOptionValue. When - it is positive AND [zz]traceOptionValue is positive rule trace - is reported in guess mode. - - The values of [zz]traceOptionValue and [zz]traceGuessOptionValue - can be adjusted by subroutine calls listed below. - - Depending on the presence or absence of the antlr -gd switch - the variable [zz]traceOptionValueDefault is set to 0 or 1. When - the parser is initialized or [zz]traceReset() is called the - value of [zz]traceOptionValueDefault is copied to [zz]traceOptionValue. - The value of [zz]traceGuessOptionValue is always initialzed to 1, - but, as noted earlier, nothing will be reported unless - [zz]traceOptionValue is also positive. - - When the parser state is saved/restored the value of the trace - variables are also saved/restored. If a restore causes a change in - reporting behavior from on to off or vice versa this will be reported. - - When the -gd option is selected, the macro "#define zzTRACE_RULES" - is added to appropriate output files. - - C++ mode - -------- - int traceOption(int delta) - int traceGuessOption(int delta) - void traceReset() - int traceOptionValueDefault - - C mode - -------- - int zzTraceOption(int delta) - int zzTraceGuessOption(int delta) - void zzTraceReset() - int zzTraceOptionValueDefault - - The argument "delta" is added to the traceOptionValue. To - turn on trace when inside a particular rule one: - - rule : <> - ( - rest-of-rule - ) - <> - ; /* fail clause */ <> - - One can use the same idea to turn *off* tracing within a - rule by using a delta of (-1). - - An improvement in the rule trace was suggested by Sramji - Ramanathan (ps@kumaran.com). - -#108. A Note on Deallocation of Variables Allocated in Guess Mode - - NOTE - ------------------------------------------------------ - This mechanism only works for heap allocated variables - ------------------------------------------------------ - - The rewrite of the trace provides the machinery necessary - to properly free variables or undo actions following a - failed guess. - - The macro zzUSER_GUESS_HOOK(guessSeq,zzrv) is expanded - as part of the zzGUESS macro. When a guess is opened - the value of zzrv is 0. When a longjmp() is executed to - undo the guess, the value of zzrv will be 1. - - The macro zzUSER_GUESS_DONE_HOOK(guessSeq) is expanded - as part of the zzGUESS_DONE macro. This is executed - whether the guess succeeds or fails as part of closing - the guess. - - The guessSeq is a sequence number which is assigned to each - guess and is incremented by 1 for each guess which becomes - active. It is needed by the user to associate the start of - a guess with the failure and/or completion (closing) of a - guess. - - Guesses are nested. They must be closed in the reverse - of the order that they are opened. - - In order to free memory used by a variable during a guess - a user must write a routine which can be called to - register the variable along with the current guess sequence - number provided by the zzUSER_GUESS_HOOK macro. If the guess - fails, all variables tagged with the corresponding guess - sequence number should be released. This is ugly, but - it would require a major rewrite of antlr 1.33 to use - some mechanism other than setjmp()/longjmp(). - - The order of calls for a *successful* guess would be: - - zzUSER_GUESS_HOOK(guessSeq,0); - zzUSER_GUESS_DONE_HOOK(guessSeq); - - The order of calls for a *failed* guess would be: - - zzUSER_GUESS_HOOK(guessSeq,0); - zzUSER_GUESS_HOOK(guessSeq,1); - zzUSER_GUESS_DONE_HOOK(guessSeq); - - The default definitions of these macros are empty strings. - - Here is an example in C++ mode. The zzUSER_GUESS_HOOK and - zzUSER_GUESS_DONE_HOOK macros and myGuessHook() routine - can be used without change in both C and C++ versions. - - ---------------------------------------------------------------------- - << - - #include "AToken.h" - - typedef ANTLRCommonToken ANTLRToken; - - #include "DLGLexer.h" - - int main() { - - { - DLGFileInput in(stdin); - DLGLexer lexer(&in,2000); - ANTLRTokenBuffer pipe(&lexer,1); - ANTLRCommonToken aToken; - P parser(&pipe); - - lexer.setToken(&aToken); - parser.init(); - parser.start(); - }; - - fclose(stdin); - fclose(stdout); - return 0; - } - - >> - - << - char *s=NULL; - - #undef zzUSER_GUESS_HOOK - #define zzUSER_GUESS_HOOK(guessSeq,zzrv) myGuessHook(guessSeq,zzrv); - #undef zzUSER_GUESS_DONE_HOOK - #define zzUSER_GUESS_DONE_HOOK(guessSeq) myGuessHook(guessSeq,2); - - void myGuessHook(int guessSeq,int zzrv) { - if (zzrv == 0) { - fprintf(stderr,"User hook: starting guess #%d\n",guessSeq); - } else if (zzrv == 1) { - free (s); - s=NULL; - fprintf(stderr,"User hook: failed guess #%d\n",guessSeq); - } else if (zzrv == 2) { - free (s); - s=NULL; - fprintf(stderr,"User hook: ending guess #%d\n",guessSeq); - }; - } - - >> - - #token A "a" - #token "[\t \ \n]" <> - - class P { - - start : (top)+ - ; - - top : (which) ? <> - | other <> - ; <> - - which : which2 - ; - - which2 : which3 - ; - which3 - : (label)? <> - | (global)? <> - | (exclamation)? <> - ; - - label : <getText());>> A ":" ; - - global : <getText());>> A "::" ; - - exclamation : <getText());>> A "!" ; - - other : <getText());>> "other" ; - - } - ---------------------------------------------------------------------- - - This is a silly example, but illustrates the idea. For the input - "a ::" with tracing enabled the output begins: - - ---------------------------------------------------------------------- - enter rule "start" depth 1 - enter rule "top" depth 2 - User hook: starting guess #1 - enter rule "which" depth 3 guessing - enter rule "which2" depth 4 guessing - enter rule "which3" depth 5 guessing - User hook: starting guess #2 - enter rule "label" depth 6 guessing - guess failed - User hook: failed guess #2 - guess done - returning to rule "which3" at depth 5 (guess mode continues - - an enclosing guess is still active) - User hook: ending guess #2 - User hook: starting guess #3 - enter rule "global" depth 6 guessing - exit rule "global" depth 6 guessing - guess done - returning to rule "which3" at depth 5 (guess mode continues - - an enclosing guess is still active) - User hook: ending guess #3 - enter rule "global" depth 6 guessing - exit rule "global" depth 6 guessing - exit rule "which3" depth 5 guessing - exit rule "which2" depth 4 guessing - exit rule "which" depth 3 guessing - guess done - returning to rule "top" at depth 2 (guess mode ends) - User hook: ending guess #1 - enter rule "which" depth 3 - ..... - ---------------------------------------------------------------------- - - Remember: - - (a) Only init-actions are executed during guess mode. - (b) A rule can be invoked multiple times during guess mode. - (c) If the guess succeeds the rule will be called once more - without guess mode so that normal actions will be executed. - This means that the init-action might need to distinguish - between guess mode and non-guess mode using the variable - [zz]guessing. - -#107. (Changed in 1.33MR10) construction of ASTs in guess mode - - Prior to 1.33MR10, when using automatic AST construction in C++ - mode for a rule, an AST would be constructed for elements of the - rule even while in guess mode. In MR10 this no longer occurs. - -#106. (Changed in 1.33MR10) guess variable confusion - - In C++ mode a guess which failed always restored the parser state - using zzGUESS_DONE as part of zzGUESS_FAIL. Prior to 1.33MR10, - C mode required an explicit call to zzGUESS_DONE after the - call to zzGUESS_FAIL. - - Consider: - - rule : (alpha)? beta - | ... - ; - - The generated code resembles: - - zzGUESS - if (!zzrv && LA(1)==ID) { <==== line #1 - alpha - zzGUESS_DONE - beta - } else { - if (! zzrv) zzGUESS_DONE <==== line #2a - .... - - However, in some cases line #2 was rendered: - - if (guessing) zzGUESS_DONE <==== line #2b - - This would work for simple test cases, but would fail in - some cases where there was a guess while another guess was active. - One kind of failure would be to match up the zzGUESS_DONE at line - #2b with the "outer" guess which was still active. The outer - guess would "succeed" when only the inner guess should have - succeeded. - - In 1.33MR10 the behavior of zzGUESS and zzGUESS_FAIL in C and - and C++ mode should be identical. - - The same problem appears in 1.33 vanilla in some places. For - example: - - start : { (sub)? } ; - - or: - - start : ( - B - | ( sub )? - | C - )+ - ; - - generates incorrect code. - - The general principle is: - - (a) use [zz]guessing only when deciding between a call to zzFAIL - or zzGUESS_FAIL - - (b) use zzrv in all other cases - - This problem was discovered while testing changes to item #105. - I believe this is now fixed. My apologies. - -#105. (Changed in 1.33MR10) guess block as single alt of (...)+ - - Prior to 1.33MR10 the following constructs: - - rule_plus : ( - (sub)? - )+ - ; - - rule_star : ( - (sub)? - )* - ; - - generated incorrect code for the guess block (which could result - in runtime errors) because of an incorrect optimization of a - block with only a single alternative. - - The fix caused some changes to the fix described in Item #49 - because there are now three code generation sequences for (...)+ - blocks containing a guess block: - - a. single alternative which is a guess block - b. multiple alternatives in which the last is a guess block - c. all other cases - - Forms like "rule_star" can have unexpected behavior when there - is a syntax error: if the subrule "sub" is not matched *exactly* - then "rule_star" will consume no tokens. - - Reported by Esa Pulkkinen (esap@cs.tut.fi). - -#104. (Changed in 1.33MR10) -o option for dlg - - There was problem with the code added by item #74 to handle the - -o option of dlg. This should fix it. - -#103. (Changed in 1.33MR10) ANDed semantic predicates - - Rescinded. - - The optimization was a mistake. - The resulting problem is described in Item #150. - -#102. (Changed in 1.33MR10) allow "class parser : .... {" - - The syntax of the class statement ("class parser-name {") - has been extended to allow for the specification of base - classes. An arbirtrary number of tokens may now appear - between the class name and the "{". They are output - again when the class declaration is generated. For - example: - - class Parser : public MyBaseClassANTLRparser { - - This was suggested by a user, but I don't have a record - of who it was. - -#101. (Changed in 1.33MR10) antlr -info command line switch - - -info - - p - extra predicate information in generated file - - t - information about tnode use: - at the end of each rule in generated file - summary on stderr at end of program - - m - monitor progress - prints name of each rule as it is started - flushes output at start of each rule - - f - first/follow set information to stdout - - 0 - no operation (added in 1.33MR11) - - The options may be combined and may appear in any order. - For example: - - antlr -info ptm -CC -gt -mrhoist on mygrammar.g - -#100a. (Changed in 1.33MR10) Predicate tree simplification - - When the same predicates can be referenced in more than one - alternative of a block large predicate trees can be formed. - - The difference that these optimizations make is so dramatic - that I have decided to use it even when -mrhoist is not selected. - - Consider the following grammar: - - start : ( all )* ; - - all : a - | d - | e - | f - ; - - a : c A B - | c A C - ; - - c : <>? - ; - - d : <>? B C - ; - - e : <>? B C - ; - - f : e X Y - ; - - In rule "a" there is a reference to rule "c" in both alternatives. - The length of the predicate AAA is k=2 and it can be followed in - alternative 1 only by (A B) while in alternative 2 it can be - followed only by (A C). Thus they do not have identical context. - - In rule "all" the alternatives which refer to rules "e" and "f" allow - elimination of the duplicate reference to predicate CCC. - - The table below summarized the kind of simplification performed by - 1.33MR10. In the table, X and Y stand for single predicates - (not trees). - - (OR X (OR Y (OR Z))) => (OR X Y Z) - (AND X (AND Y (AND Z))) => (AND X Y Z) - - (OR X (... (OR X Y) ... )) => (OR X (... Y ... )) - (AND X (... (AND X Y) ... )) => (AND X (... Y ... )) - (OR X (... (AND X Y) ... )) => (OR X (... ... )) - (AND X (... (OR X Y) ... )) => (AND X (... ... )) - - (AND X) => X - (OR X) => X - - In a test with a complex grammar for a real application, a predicate - tree with six OR nodes and 12 leaves was reduced to "(OR X Y Z)". - - In 1.33MR10 there is a greater effort to release memory used - by predicates once they are no longer in use. - -#100b. (Changed in 1.33MR10) Suppression of extra predicate tests - - The following optimizations require that -mrhoist be selected. - - It is relatively easy to optimize the code generated for predicate - gates when they are of the form: - - (AND X Y Z ...) - or (OR X Y Z ...) - - where X, Y, Z, and "..." represent individual predicates (leaves) not - predicate trees. - - If the predicate is an AND the contexts of the X, Y, Z, etc. are - ANDed together to create a single Tree context for the group and - context tests for the individual predicates are suppressed: - - -------------------------------------------------- - Note: This was incorrect. The contexts should be - ORed together. This has been fixed. A more - complete description is available in item #152. - --------------------------------------------------- - - Optimization 1: (AND X Y Z ...) - - Suppose the context for Xtest is LA(1)==LP and the context for - Ytest is LA(1)==LP && LA(2)==ID. - - Without the optimization the code would resemble: - - if (lookaheadContext && - !(LA(1)==LP && LA(1)==LP && LA(2)==ID) || - ( (! LA(1)==LP || Xtest) && - (! (LA(1)==LP || LA(2)==ID) || Xtest) - )) {... - - With the -mrhoist optimization the code would resemble: - - if (lookaheadContext && - ! (LA(1)==LP && LA(2)==ID) || (Xtest && Ytest) {... - - Optimization 2: (OR X Y Z ...) with identical contexts - - Suppose the context for Xtest is LA(1)==ID and for Ytest - the context is also LA(1)==ID. - - Without the optimization the code would resemble: - - if (lookaheadContext && - ! (LA(1)==ID || LA(1)==ID) || - (LA(1)==ID && Xtest) || - (LA(1)==ID && Ytest) {... - - With the -mrhoist optimization the code would resemble: - - if (lookaheadContext && - (! LA(1)==ID) || (Xtest || Ytest) {... - - Optimization 3: (OR X Y Z ...) with distinct contexts - - Suppose the context for Xtest is LA(1)==ID and for Ytest - the context is LA(1)==LP. - - Without the optimization the code would resemble: - - if (lookaheadContext && - ! (LA(1)==ID || LA(1)==LP) || - (LA(1)==ID && Xtest) || - (LA(1)==LP && Ytest) {... - - With the -mrhoist optimization the code would resemble: - - if (lookaheadContext && - (zzpf=0, - (LA(1)==ID && (zzpf=1) && Xtest) || - (LA(1)==LP && (zzpf=1) && Ytest) || - !zzpf) { - - These may appear to be of similar complexity at first, - but the non-optimized version contains two tests of each - context while the optimized version contains only one - such test, as well as eliminating some of the inverted - logic (" !(...) || "). - - Optimization 4: Computation of predicate gate trees - - When generating code for the gates of predicate expressions - antlr 1.33 vanilla uses a recursive procedure to generate - "&&" and "||" expressions for testing the lookahead. As each - layer of the predicate tree is exposed a new set of "&&" and - "||" expressions on the lookahead are generated. In many - cases the lookahead being tested has already been tested. - - With -mrhoist a lookahead tree is computed for the entire - lookahead expression. This means that predicates with identical - context or context which is a subset of another predicate's - context disappear. - - This is especially important for predicates formed by rules - like the following: - - uppperCaseVowel : <>? vowel; - vowel: : <>? LETTERS; - - These predicates are combined using AND since both must be - satisfied for rule upperCaseVowel. They have identical - context which makes this optimization very effective. - - The affect of Items #100a and #100b together can be dramatic. In - a very large (but real world) grammar one particular predicate - expression was reduced from an (unreadable) 50 predicate leaves, - 195 LA(1) terms, and 5500 characters to an (easily comprehensible) - 3 predicate leaves (all different) and a *single* LA(1) term. - -#99. (Changed in 1.33MR10) Code generation for expression trees - - Expression trees are used for k>1 grammars and predicates with - lookahead depth >1. This optimization must be enabled using - "-mrhoist on". (Clarification added for 1.33MR11). - - In the processing of expression trees, antlr can generate long chains - of token comparisons. Prior to 1.33MR10 there were many redundant - parenthesis which caused problems for compilers which could handle - expressions of only limited complexity. For example, to test an - expression tree (root R A B C D), antlr would generate something - resembling: - - (LA(1)==R && (LA(2)==A || (LA(2)==B || (LA(2)==C || LA(2)==D))))) - - If there were twenty tokens to test then there would be twenty - parenthesis at the end of the expression. - - In 1.33MR10 the generated code for tree expressions resembles: - - (LA(1)==R && (LA(2)==A || LA(2)==B || LA(2)==C || LA(2)==D)) - - For "complex" expressions the output is indented to reflect the LA - number being tested: - - (LA(1)==R - && (LA(2)==A || LA(2)==B || LA(2)==C || LA(2)==D - || LA(2)==E || LA(2)==F) - || LA(1)==S - && (LA(2)==G || LA(2)==H)) - - - Suggested by S. Bochnak (S.Bochnak@@microTool.com.pl), - -#98. (Changed in 1.33MR10) Option "-info p" - - When the user selects option "-info p" the program will generate - detailed information about predicates. If the user selects - "-mrhoist on" additional detail will be provided explaining - the promotion and suppression of predicates. The output is part - of the generated file and sandwiched between #if 0/#endif statements. - - Consider the following k=1 grammar: - - start : ( all ) * ; - - all : ( a - | b - ) - ; - - a : c B - ; - - c : <>? - | B - ; - - b : <>? X - ; - - Below is an excerpt of the output for rule "start" for the three - predicate options (off, on, and maintenance release style hoisting). - - For those who do not wish to use the "-mrhoist on" option for code - generation the option can be used in a "diagnostic" mode to provide - valuable information: - - a. where one should insert null actions to inhibit hoisting - b. a chain of rule references which shows where predicates are - being hoisted - - ====================================================================== - Example of "-info p" with "-mrhoist on" - ====================================================================== - #if 0 - - Hoisting of predicate suppressed by alternative without predicate. - The alt without the predicate includes all cases where the - predicate is false. - - WITH predicate: line 11 v36.g - WITHOUT predicate: line 12 v36.g - - The context set for the predicate: - - B - - The lookahead set for alt WITHOUT the semantic predicate: - - B - - The predicate: - - pred << LATEXT(1)>>? depth=k=1 rule c line 11 v36.g - - set context: - B - tree context: null - - Chain of referenced rules: - - #0 in rule start (line 1 v36.g) to rule all - #1 in rule all (line 3 v36.g) to rule a - #2 in rule a (line 8 v36.g) to rule c - #3 in rule c (line 11 v36.g) - - #endif - && - #if 0 - - pred << LATEXT(1)>>? depth=k=1 rule b line 15 v36.g - - set context: - X - tree context: null - - #endif - ====================================================================== - Example of "-info p" with the default -prc setting ( "-prc off") - ====================================================================== - #if 0 - - OR - pred << LATEXT(1)>>? depth=k=1 rule c line 11 v36.g - - set context: - nil - tree context: null - - pred << LATEXT(1)>>? depth=k=1 rule b line 15 v36.g - - set context: - nil - tree context: null - - #endif - ====================================================================== - Example of "-info p" with "-prc on" and "-mrhoist off" - ====================================================================== - #if 0 - - OR - pred << LATEXT(1)>>? depth=k=1 rule c line 11 v36.g - - set context: - B - tree context: null - - pred << LATEXT(1)>>? depth=k=1 rule b line 15 v36.g - - set context: - X - tree context: null - - #endif - ====================================================================== - -#97. (Fixed in 1.33MR10) "Predicate applied for more than one ... " - - In 1.33 vanilla, the grammar listed below produced this message for - the first alternative (only) of rule "b": - - warning: predicate applied for >1 lookahead 1-sequences - [you may only want one lookahead 1-sequence to apply. - Try using a context guard '(...)? =>' - - In 1.33MR10 the message is issued for both alternatives. - - top : (a)*; - a : b | c ; - - b : <>? ( AAA | BBB ) - | <>? ( XXX | YYY ) - ; - - c : AAA | XXX; - -#96. (Fixed in 1.33MR10) Guard predicates ignored when -prc off - - Prior to 1.33MR10, guard predicate code was not generated unless - "-prc on" was selected. - - This was incorrect, since "-prc off" (the default) is supposed to - disable only AUTOMATIC computation of predicate context, not the - programmer specified context supplied by guard predicates. - -#95. (Fixed in 1.33MR10) Predicate guard context length was k, not max(k,ck) - - Prior to 1.33MR10, predicate guards were computed to k tokens rather - than max(k,ck). Consider the following grammar: - - a : ( A B C)? => <>? (A|X) (B|Y) (C|Z) ; - - The code generated by 1.33 vanilla with "-k 1 -ck 3 -prc on" - for the predicate in "a" resembles: - - if ( (! LA(1)==A) || AAA(LATEXT(1))) {... - - With 1.33MR10 and the same options the code resembles: - - if ( (! (LA(1)==A && LA(2)==B && LA(3)==C) || AAA(LATEXT(1))) {... - -#94. (Fixed in 1.33MR10) Predicates followed by rule references - - Prior to 1.33MR10, a semantic predicate which referenced a token - which was off the end of the rule caused an incomplete context - to be computed (with "-prc on") for the predicate under some circum- - stances. In some cases this manifested itself as illegal C code - (e.g. "LA(2)==[Ep](1)" in the k=2 examples below: - - all : ( a ) *; - - a : <>? ID X - | <>? Y - | Z - ; - - This might also occur when the semantic predicate was followed - by a rule reference which was shorter than the length of the - semantic predicate: - - all : ( a ) *; - - a : <>? ID X - | <>? y - | Z - ; - - y : Y ; - - Depending on circumstance, the resulting context might be too - generous because it was too short, or too restrictive because - of missing alternatives. - -#93. (Changed in 1.33MR10) Definition of Purify macro - - Ofer Ben-Ami (gremlin@cs.huji.ac.il) has supplied a definition - for the Purify macro: - - #define PURIFY(r, s) memset((char *) &(r), '\0', (s)); - - Note: This may not be the right thing to do for C++ objects that - have constructors. Reported by Bonny Rais (bonny@werple.net.au). - - For those cases one should #define PURIFY to an empty macro in the - #header or #first actions. - -#92. (Fixed in 1.33MR10) Guarded predicates and hoisting - - When a guarded predicate participates in hoisting it is linked into - a predicate expression tree. Prior to 1.33MR10 this link was never - cleared and the next time the guard was used to construct a new - tree the link could contain a spurious reference to another element - which had previosly been joined to it in the semantic predicate tree. - - For example: - - start : ( all ) *; - all : ( a | b ) ; - - start2 : ( all2 ) *; - all2 : ( a ) ; - - a : (A)? => <>? A ; - b : (B)? => <>? B ; - - Prior to 1.33MR10 the code for "start2" would include a spurious - reference to the BBB predicate which was left from constructing - the predicate tree for rule "start" (i.e. or(AAA,BBB) ). - - In 1.33MR10 this problem is avoided by cloning the original guard - each time it is linked into a predicate tree. - -#91. (Changed in 1.33MR10) Extensive changes to semantic pred hoisting - - ============================================ - This has been rendered obsolete by Item #117 - ============================================ - -#90. (Fixed in 1.33MR10) Semantic pred with LT(i) and i>max(k,ck) - - There is a bug in antlr 1.33 vanilla and all maintenance releases - prior to 1.33MR10 which allows semantic predicates to reference - an LT(i) or LATEXT(i) where i is larger than max(k,ck). When - this occurs antlr will attempt to mark the ith element of an array - in which there are only max(k,ck) elements. The result cannot - be predicted. - - Using LT(i) or LATEXT(i) for i>max(k,ck) is reported as an error - in 1.33MR10. - -#89. Rescinded - -#88. (Fixed in 1.33MR10) Tokens used in semantic predicates in guess mode - - Consider the behavior of a semantic predicate during guess mode: - - rule : a:A ( - <>? b:B - | c:C - ); - - Prior to MR10 the assignment of the token or attribute to - $a did not occur during guess mode, which would cause the - semantic predicate to misbehave because $a would be null. - - In 1.33MR10 a semantic predicate with a reference to an - element label (such as $a) forces the assignment to take - place even in guess mode. - - In order to work, this fix REQUIRES use of the $label format - for token pointers and attributes referenced in semantic - predicates. - - The fix does not apply to semantic predicates using the - numeric form to refer to attributes (e.g. <>?). - The user will receive a warning for this case. - - Reported by Rob Trout (trout@mcs.cs.kent.edu). - -#87. (Fixed in 1.33MR10) Malformed guard predicates - - Context guard predicates may contain only references to - tokens. They may not contain references to (...)+ and - (...)* blocks. This is now checked. This replaces the - fatal error message in item #78 with an appropriate - (non-fatal) error messge. - - In theory, context guards should be allowed to reference - rules. However, I have not had time to fix this. - Evaluation of the guard takes place before all rules have - been read, making it difficult to resolve a forward reference - to rule "zzz" - it hasn't been read yet ! To postpone evaluation - of the guard until all rules have been read is too much - for the moment. - -#86. (Fixed in 1.33MR10) Unequal set size in set_sub - - Routine set_sub() in pccts/support/set/set.h did not work - correctly when the sets were of unequal sizes. Rewrote - set_equ to make it simpler and remove unnecessary and - expensive calls to set_deg(). This routine was not used - in 1.33 vanila. - -#85. (Changed in 1.33MR10) Allow redefinition of MaxNumFiles - - Raised the maximum number of input files to 99 from 20. - Put a #ifndef/#endif around the "#define MaxNumFiles 99". - -#84. (Fixed in 1.33MR10) Initialize zzBadTok in macro zzRULE - - Initialize zzBadTok to NULL in zzRULE macro of AParser.h. - in order to get rid of warning messages. - -#83. (Fixed in 1.33MR10) False warnings with -w2 for #tokclass - - When -w2 is selected antlr gives inappropriate warnings about - #tokclass names not having any associated regular expressions. - Since a #tokclass is not a "real" token it will never have an - associated regular expression and there should be no warning. - - Reported by Derek Pappas (derek.pappas@eng.sun.com) - -#82. (Fixed in 1.33MR10) Computation of follow sets with multiple cycles - - Reinier van den Born (reinier@vnet.ibm.com) reported a problem - in the computation of follow sets by antlr. The problem (bug) - exists in 1.33 vanilla and all maintenance releases prior to 1.33MR10. - - The problem involves the computation of follow sets when there are - cycles - rules which have mutual references. I believe the problem - is restricted to cases where there is more than one cycle AND - elements of those cycles have rules in common. Even when this - occurs it may not affect the code generated - but it might. It - might also lead to undetected ambiguities. - - There were no changes in antlr or dlg output from the revised version. - - The following fragment demonstates the problem by giving different - follow sets (option -pa) for var_access when built with k=1 and ck=2 on - 1.33 vanilla and 1.33MR10: - - echo_statement : ECHO ( echo_expr )* - ; - - echo_expr : ( command )? - | expression - ; - - command : IDENTIFIER - { concat } - ; - - expression : operand ( OPERATOR operand )* - ; - - operand : value - | START command END - ; - - value : concat - | TYPE operand - ; - - concat : var_access { CONCAT value } - ; - - var_access : IDENTIFIER { INDEX } - - ; -#81. (Changed in 1.33MR10) C mode use of attributes and ASTs - - Reported by Isaac Clark (irclark@mindspring.com). - - C mode code ignores attributes returned by rules which are - referenced using element labels when ASTs are enabled (-gt option). - - 1. start : r:rule t:Token <<$start=$r;>> - - The $r refrence will not work when combined with - the -gt option. - - 2. start : t:Token <<$start=$t;>> - - The $t reference works in all cases. - - 3. start : rule <<$0=$1;>> - - Numeric labels work in all cases. - - With MR10 the user will receive an error message for case 1 when - the -gt option is used. - -#80. (Fixed in 1.33MR10) (...)? as last alternative of block - - A construct like the following: - - rule : a - | (b)? - ; - - does not make sense because there is no alternative when - the guess block fails. This is now reported as a warning - to the user. - - Previously, there was a code generation error for this case: - the guess block was not "closed" when the guess failed. - This could cause an infinite loop or other problems. This - is now fixed. - - Example problem: - - #header<< - #include - #include "charptr.h" - >> - - << - #include "charptr.c" - main () - { - ANTLR(start(),stdin); - } - >> - - #token "[\ \t]+" << zzskip(); >> - #token "[\n]" << zzline++; zzskip(); >> - - #token Word "[a-z]+" - #token Number "[0-9]+" - - - start : (test1)? - | (test2)? - ; - test1 : (Word Word Word Word)? - | (Word Word Word Number)? - ; - test2 : (Word Word Number Word)? - | (Word Word Number Number)? - ; - - Test data which caused infinite loop: - - a 1 a a - -#79. (Changed in 1.33MR10) Use of -fh with multiple parsers - - Previously, antlr always used the pre-processor symbol - STDPCCTS_H as a gate for the file stdpccts.h. This - caused problems when there were multiple parsers defined - because they used the same gate symbol. - - In 1.33MR10, the -fh filename is used to generate the - gate file for stdpccts.h. For instance: - - antlr -fh std_parser1.h - - generates the pre-processor symbol "STDPCCTS_std_parser1_H". - - Reported by Ramanathan Santhanam (ps@kumaran.com). - -#78. (Changed in 1.33MR9) Guard predicates that refer to rules - - ------------------------ - Please refer to Item #87 - ------------------------ - - Guard predicates are processed during an early phase - of antlr (during parsing) before all data structures - are completed. - - There is an apparent bug in earlier versions of 1.33 - which caused guard predicates which contained references - to rules (rather than tokens) to reference a structure - which hadn't yet been initialized. - - In some cases (perhaps all cases) references to rules - in guard predicates resulted in the use of "garbage". - -#79. (Changed in 1.33MR9) Jeff Vincent (JVincent@novell.com) - - Previously, the maximum length file name was set - arbitrarily to 300 characters in antlr, dlg, and sorcerer. - - The config.h file now attempts to define the maximum length - filename using _MAX_PATH from stdlib.h before falling back - to using the value 300. - -#78. (Changed in 1.33MR9) Jeff Vincent (JVincent@novell.com) - - Put #ifndef/#endif around definition of ZZLEXBUFSIZE in - antlr. - -#77. (Changed in 1.33MR9) Arithmetic overflow for very large grammars - - In routine HandleAmbiguities() antlr attempts to compute the - number of possible elements in a set that is order of - number-of-tokens raised to the number-of-lookahead-tokens power. - For large grammars or large lookahead (e.g. -ck 7) this can - cause arithmetic overflow. - - With 1.33MR9, arithmetic overflow in this computation is reported - the first time it happens. The program continues to run and - the program branches based on the assumption that the computed - value is larger than any number computed by counting actual cases - because 2**31 is larger than the number of bits in most computers. - - Before 1.33MR9 overflow was not reported. The behavior following - overflow is not predictable by anyone but the original author. - - NOTE - - In 1.33MR10 the warning message is suppressed. - The code which detects the overflow allows the - computation to continue without an error. The - error message itself made made users worry. - -#76. (Changed in 1.33MR9) Jeff Vincent (JVincent@novell.com) - - Jeff Vincent has convinced me to make ANTLRCommonToken and - ANTLRCommonNoRefCountToken use variable length strings - allocated from the heap rather than fixed length strings. - By suitable definition of setText(), the copy constructor, - and operator =() it is possible to maintain "copy" semantics. - By "copy" semantics I mean that when a token is copied from - an existing token it receives its own, distinct, copy of the - text allocated from the heap rather than simply a pointer - to the original token's text. - - ============================================================ - W * A * R * N * I * N * G - ============================================================ - - It is possible that this may cause problems for some users. - For those users I have included the old version of AToken.h as - pccts/h/AToken_traditional.h. - -#75. (Changed in 1.33MR9) Bruce Guenter (bruceg@qcc.sk.ca) - - Make DLGStringInput const correct. Since this is infrequently - subclassed, it should affect few users, I hope. - -#74. (Changed in 1.33MR9) -o (output directory) option - - Antlr does not properly handle the -o output directory option - when the filename of the grammar contains a directory part. For - example: - - antlr -o outdir pccts_src/myfile.g - - causes antlr create a file called "outdir/pccts_src/myfile.cpp. - It SHOULD create outdir/myfile.cpp - - The suggested code fix has been installed in antlr, dlg, and - Sorcerer. - -#73. (Changed in 1.33MR9) Hoisting of semantic predicates and -mrhoist - - ============================================ - This has been rendered obsolete by Item #117 - ============================================ - -#72. (Changed in 1.33MR9) virtual saveState()/restoreState()/guess_XXX - - The following methods in ANTLRParser were made virtual at - the request of S. Bochnak (S.Bochnak@microTool.com.pl): - - saveState() and restoreState() - guess(), guess_fail(), and guess_done() - -#71. (Changed in 1.33MR9) Access to omitted command line argument - - If a switch requiring arguments is the last thing on the - command line, and the argument is omitted, antlr would core. - - antlr test.g -prc - - instead of - - antlr test.g -prc off - -#70. (Changed in 1.33MR9) Addition of MSVC .dsp and .mak build files - - The following MSVC .dsp and .mak files for pccts and sorcerer - were contributed by Stanislaw Bochnak (S.Bochnak@microTool.com.pl) - and Jeff Vincent (JVincent@novell.com) - - PCCTS Distribution Kit - ---------------------- - pccts/PCCTSMSVC50.dsw - - pccts/antlr/AntlrMSVC50.dsp - pccts/antlr/AntlrMSVC50.mak - - pccts/dlg/DlgMSVC50.dsp - pccts/dlg/DlgMSVC50.mak - - pccts/support/msvc.dsp - - Sorcerer Distribution Kit - ------------------------- - pccts/sorcerer/SorcererMSVC50.dsp - pccts/sorcerer/SorcererMSVC50.mak - - pccts/sorcerer/lib/msvc.dsp - -#69. (Changed in 1.33MR9) Change "unsigned int" to plain "int" - - Declaration of max_token_num in misc.c as "unsigned int" - caused comparison between signed and unsigned ints giving - warning message without any special benefit. - -#68. (Changed in 1.33MR9) Add void return for dlg internal_error() - - Get rid of "no return value" message in internal_error() - in file dlg/support.c and dlg/dlg.h. - -#67. (Changed in Sor) sor.g: lisp() has no return value - - Added a "void" for the return type. - -#66. (Added to Sor) sor.g: ZZLEXBUFSIZE enclosed in #ifndef/#endif - - A user needed to be able to change the ZZLEXBUFSIZE for - sor. Put the definition of ZZLEXBUFSIZE inside #ifndef/#endif - -#65. (Changed in 1.33MR9) PCCTSAST::deepCopy() and ast_dup() bug - - Jeff Vincent (JVincent@novell.com) found that deepCopy() - made new copies of only the direct descendents. No new - copies were made of sibling nodes, Sibling pointers are - set to zero by shallowCopy(). - - PCCTS_AST::deepCopy() has been changed to make a - deep copy in the traditional sense. - - The deepCopy() routine depends on the behavior of - shallowCopy(). In all sor examples I've found, - shallowCopy() zeroes the right and down pointers. - - Original Tree Original deepCopy() Revised deepCopy - ------------- ------------------- ---------------- - a->b->c A A - | | | - d->e->f D D->E->F - | | | - g->h->i G G->H->I - | | - j->k J->K - - While comparing deepCopy() for C++ mode with ast_dup for - C mode I found a problem with ast_dup(). - - Routine ast_dup() has been changed to make a deep copy - in the traditional sense. - - Original Tree Original ast_dup() Revised ast_dup() - ------------- ------------------- ---------------- - a->b->c A->B->C A - | | | - d->e->f D->E->F D->E->F - | | | - g->h->i G->H->I G->H->I - | | | - j->k J->K J->K - - - I believe this affects transform mode sorcerer programs only. - -#64. (Changed in 1.33MR9) anltr/hash.h prototype for killHashTable() - -#63. (Changed in 1.33MR8) h/charptr.h does not zero pointer after free - - The charptr.h routine now zeroes the pointer after free(). - - Reported by Jens Tingleff (jensting@imaginet.fr) - -#62. (Changed in 1.33MR8) ANTLRParser::resynch had static variable - - The static variable "consumed" in ANTLRParser::resynch was - changed into an instance variable of the class with the - name "resynchConsumed". - - Reported by S.Bochnak@microTool.com.pl - -#61. (Changed in 1.33MR8) Using rule>[i,j] when rule has no return values - - Previously, the following code would cause antlr to core when - it tried to generate code for rule1 because rule2 had no return - values ("upward inheritance"): - - rule1 : <> - rule2 > [i,j] - ; - - rule2 : Anything ; - - Reported by S.Bochnak@microTool.com.pl - - Verified correct operation of antlr MR8 when missing or extra - inheritance arguments for all combinations. When there are - missing or extra arguments code will still be generated even - though this might cause the invocation of a subroutine with - the wrong number of arguments. - -#60. (Changed in 1.33MR7) Major changes to exception handling - - There were significant problems in the handling of exceptions - in 1.33 vanilla. The general problem is that it can only - process one level of exception handler. For example, a named - exception handler, an exception handler for an alternative, or - an exception for a subrule always went to the rule's exception - handler if there was no "catch" which matched the exception. - - In 1.33MR7 the exception handlers properly "nest". If an - exception handler does not have a matching "catch" then the - nextmost outer exception handler is checked for an appropriate - "catch" clause, and so on until an exception handler with an - appropriate "catch" is found. - - There are still undesirable features in the way exception - handlers are implemented, but I do not have time to fix them - at the moment: - - The exception handlers for alternatives are outside the - block containing the alternative. This makes it impossible - to access variables declared in a block or to resume the - parse by "falling through". The parse can still be easily - resumed in other ways, but not in the most natural fashion. - - This results in an inconsistentcy between named exception - handlers and exception handlers for alternatives. When - an exception handler for an alternative "falls through" - it goes to the nextmost outer handler - not the "normal - action". - - A major difference between 1.33MR7 and 1.33 vanilla is - the default action after an exception is caught: - - 1.33 Vanilla - ------------ - In 1.33 vanilla the signal value is set to zero ("NoSignal") - and the code drops through to the code following the exception. - For named exception handlers this is the "normal action". - For alternative exception handlers this is the rule's handler. - - 1.33MR7 - ------- - In 1.33MR7 the signal value is NOT automatically set to zero. - - There are two cases: - - For named exception handlers: if the signal value has been - set to zero the code drops through to the "normal action". - - For all other cases the code branches to the nextmost outer - exception handler until it reaches the handler for the rule. - - The following macros have been defined for convenience: - - C/C++ Mode Name - -------------------- - (zz)suppressSignal - set signal & return signal arg to 0 ("NoSignal") - (zz)setSignal(intValue) - set signal & return signal arg to some value - (zz)exportSignal - copy the signal value to the return signal arg - - I'm not sure why PCCTS make a distinction between the local - signal value and the return signal argument, but I'm loathe - to change the code. The burden of copying the local signal - value to the return signal argument can be given to the - default signal handler, I suppose. - -#59. (Changed in 1.33MR7) Prototypes for some functions - - Added prototypes for the following functions to antlr.h - - zzconsumeUntil() - zzconsumeUntilToken() - -#58. (Changed in 1.33MR7) Added defintion of zzbufsize to dlgauto.h - -#57. (Changed in 1.33MR7) Format of #line directive - - Previously, the -gl directive for line 1234 would - resemble: "# 1234 filename.g". This caused problems - for some compilers/pre-processors. In MR7 it generates - "#line 1234 filename.g". - -#56. (Added in 1.33MR7) Jan Mikkelsen - - Move PURIFY macro invocaton to after rule's init action. - -#55. (Fixed in 1.33MR7) Unitialized variables in ANTLRParser - - Member variables inf_labase and inf_last were not initialized. - (See item #50.) - -#54. (Fixed in 1.33MR6) Brad Schick (schick@interacess.com) - - Previously, the following constructs generated the same - code: - - rule1 : (A B C)? - | something-else - ; - - rule2 : (A B C)? () - | something-else - ; - - In all versions of pccts rule1 guesses (A B C) and then - consume all three tokens if the guess succeeds. In MR6 - rule2 guesses (A B C) but consumes NONE of the tokens - when the guess succeeds because "()" matches epsilon. - -#53. (Explanation for 1.33MR6) What happens after an exception is caught ? - - The Book is silent about what happens after an exception - is caught. - - The following code fragment prints "Error Action" followed - by "Normal Action". - - test : Word ex:Number <> - exception[ex] - catch NoViableAlt: - <> - ; - - The reason for "Normal Action" is that the normal flow of the - program after a user-written exception handler is to "drop through". - In the case of an exception handler for a rule this results in - the exection of a "return" statement. In the case of an - exception handler attached to an alternative, rule, or token - this is the code that would have executed had there been no - exception. - - The user can achieve the desired result by using a "return" - statement. - - test : Word ex:Number <> - exception[ex] - catch NoViableAlt: - <> - ; - - The most powerful mechanism for recovery from parse errors - in pccts is syntactic predicates because they provide - backtracking. Exceptions allow "return", "break", - "consumeUntil(...)", "goto _handler", "goto _fail", and - changing the _signal value. - -#52. (Fixed in 1.33MR6) Exceptions without syntactic predicates - - The following generates bad code in 1.33 if no syntactic - predicates are present in the grammar. - - test : Word ex:Number <> - exception[ex] - catch NoViableAlt: - <> - - There is a reference to a guess variable. In C mode - this causes a compiler error. In C++ mode it generates - an extraneous check on member "guessing". - - In MR6 correct code is generated for both C and C++ mode. - -#51. (Added to 1.33MR6) Exception operator "@" used without exceptions - - In MR6 added a warning when the exception operator "@" is - used and no exception group is defined. This is probably - a case where "\@" or "@" is meant. - -#50. (Fixed in 1.33MR6) Gunnar Rxnning (gunnar@candleweb.no) - http://www.candleweb.no/~gunnar/ - - Routines zzsave_antlr_state and zzrestore_antlr_state don't - save and restore all the data needed when switching states. - - Suggested patch applied to antlr.h and err.h for MR6. - -#49. (Fixed in 1.33MR6) Sinan Karasu (sinan@boeing.com) - - Generated code failed to turn off guess mode when leaving a - (...)+ block which contained a guess block. The result was - an infinite loop. For example: - - rule : ( - (x)? - | y - )+ - - Suggested code fix implemented in MR6. Replaced - - ... else if (zzcnt>1) break; - - with: - - C++ mode: - ... else if (zzcnt>1) {if (!zzrv) zzGUESS_DONE; break;}; - C mode: - ... else if (zzcnt>1) {if (zzguessing) zzGUESS_DONE; break;}; - -#48. (Fixed in 1.33MR6) Invalid exception element causes core - - A label attached to an invalid construct can cause - pccts to crash while processing the exception associated - with the label. For example: - - rule : t:(B C) - exception[t] catch MismatchedToken: <> - - Version MR6 generates the message: - - reference in exception handler to undefined label 't' - -#47. (Fixed in 1.33MR6) Manuel Ornato - - Under some circumstances involving a k >1 or ck >1 - grammar and a loop block (i.e. (...)* ) pccts will - fail to detect a syntax error and loop indefinitely. - The problem did not exist in 1.20, but has existed - from 1.23 to the present. - - Fixed in MR6. - - --------------------------------------------------- - Complete test program - --------------------------------------------------- - #header<< - #include - #include "charptr.h" - >> - - << - #include "charptr.c" - main () - { - ANTLR(global(),stdin); - } - >> - - #token "[\ \t]+" << zzskip(); >> - #token "[\n]" << zzline++; zzskip(); >> - - #token B "b" - #token C "c" - #token D "d" - #token E "e" - #token LP "\(" - #token RP "\)" - - #token ANTLREOF "@" - - global : ( - (E liste) - | liste - | listed - ) ANTLREOF - ; - - listeb : LP ( B ( B | C )* ) RP ; - listec : LP ( C ( B | C )* ) RP ; - listed : LP ( D ( B | C )* ) RP ; - liste : ( listeb | listec )* ; - - --------------------------------------------------- - Sample data causing infinite loop - --------------------------------------------------- - e (d c) - --------------------------------------------------- - -#46. (Fixed in 1.33MR6) Robert Richter - (Robert.Richter@infotech.tu-chemnitz.de) - - This item from the list of known problems was - fixed by item #18 (below). - -#45. (Fixed in 1.33MR6) Brad Schick (schick@interaccess.com) - - The dependency scanner in VC++ mistakenly sees a - reference to an MPW #include file even though properly - #ifdef/#endif in config.h. The suggested workaround - has been implemented: - - #ifdef MPW - ..... - #define MPW_CursorCtl_Header - #include MPW_CursorCtl_Header - ..... - #endif - -#44. (Fixed in 1.33MR6) cast malloc() to (char *) in charptr.c - - Added (char *) cast for systems where malloc returns "void *". - -#43. (Added to 1.33MR6) Bruce Guenter (bruceg@qcc.sk.ca) - - Add setLeft() and setUp methods to ASTDoublyLinkedBase - for symmetry with setRight() and setDown() methods. - -#42. (Fixed in 1.33MR6) Jeff Katcher (jkatcher@nortel.ca) - - C++ style comment in antlr.c corrected. - -#41. (Added in 1.33MR6) antlr -stdout - - Using "antlr -stdout ..." forces the text that would - normally go to the grammar.c or grammar.cpp file to - stdout. - -#40. (Added in 1.33MR6) antlr -tab to change tab stops - - Using "antlr -tab number ..." changes the tab stops - for the grammar.c or grammar.cpp file. The number - must be between 0 and 8. Using 0 gives tab characters, - values between 1 and 8 give the appropriate number of - space characters. - -#39. (Fixed in 1.33MR5) Jan Mikkelsen - - Commas in function prototype still not correct under - some circumstances. Suggested code fix installed. - -#38. (Fixed in 1.33MR5) ANTLRTokenBuffer constructor - - Have ANTLRTokenBuffer ctor initialize member "parser" to null. - -#37. (Fixed in 1.33MR4) Bruce Guenter (bruceg@qcc.sk.ca) - - In ANTLRParser::FAIL(int k,...) released memory pointed to by - f[i] (as well as f itself. Should only free f itself. - -#36. (Fixed in 1.33MR3) Cortland D. Starrett (cort@shay.ecn.purdue.edu) - - Neglected to properly declare isDLGmaxToken() when fixing problem - reported by Andreas Magnusson. - - Undo "_retv=NULL;" change which caused problems for return values - from rules whose return values weren't pointers. - - Failed to create bin directory if it didn't exist. - -#35. (Fixed in 1.33MR2) Andreas Magnusson -(Andreas.Magnusson@mailbox.swipnet.se) - - Repair bug introduced by 1.33MR1 for #tokdefs. The original fix - placed "DLGmaxToken=9999" and "DLGminToken=0" in the TokenType enum - in order to fix a problem with an aggresive compiler assigning an 8 - bit enum which might be too narrow. This caused #tokdefs to assume - that there were 9999 real tokens. The repair to the fix causes antlr to - ignore TokenTypes "DLGmaxToken" and "DLGminToken" in a #tokdefs file. - -#34. (Added to 1.33MR1) Add public DLGLexerBase::set_line(int newValue) - - Previously there was no public function for changing the line - number maintained by the lexer. - -#33. (Fixed in 1.33MR1) Franklin Chen (chen@adi.com) - - Accidental use of EXIT_FAILURE rather than PCCTS_EXIT_FAILURE - in pccts/h/AParser.cpp. - -#32. (Fixed in 1.33MR1) Franklin Chen (chen@adi.com) - - In PCCTSAST.cpp lines 405 and 466: Change - - free (t) - to - free ( (char *)t ); - - to match prototype. - -#31. (Added to 1.33MR1) Pointer to parser in ANTLRTokenBuffer - Pointer to parser in DLGLexerBase - - The ANTLRTokenBuffer class now contains a pointer to the - parser which is using it. This is established by the - ANTLRParser constructor calling ANTLRTokenBuffer:: - setParser(ANTLRParser *p). - - When ANTLRTokenBuffer::setParser(ANTLRParser *p) is - called it saves the pointer to the parser and then - calls ANTLRTokenStream::setParser(ANTLRParser *p) - so that the lexer can also save a pointer to the - parser. - - There is also a function getParser() in each class - with the obvious purpose. - - It is possible that these functions will return NULL - under some circumstances (e.g. a non-DLG lexer is used). - -#30. (Added to 1.33MR1) function tokenName(int token) standard - - The generated parser class now includes the - function: - - static const ANTLRChar * tokenName(int token) - - which returns a pointer to the "name" corresponding - to the token. - - The base class (ANTLRParser) always includes the - member function: - - const ANTLRChar * parserTokenName(int token) - - which can be accessed by objects which have a pointer - to an ANTLRParser, but do not know the name of the - parser class (e.g. ANTLRTokenBuffer and DLGLexerBase). - -#29. (Added to 1.33MR1) Debugging DLG lexers - - If the pre-processor symbol DEBUG_LEXER is defined - then DLexerBase will include code for printing out - key information about tokens which are recognized. - - The debug feature of the lexer is controlled by: - - int previousDebugValue=lexer.debugLexer(newValue); - - a value of 0 disables output - a value of 1 enables output - - Even if the lexer debug code is compiled into DLexerBase - it must be enabled before any output is generated. For - example: - - DLGFileInput in(stdin); - MyDLG lexer(&in,2000); - - lexer.setToken(&aToken); - - #if DEBUG_LEXER - lexer.debugLexer(1); // enable debug information - #endif - -#28. (Added to 1.33MR1) More control over DLG header - - Version 1.33MR1 adds the following directives to PCCTS - for C++ mode: - - #lexprefix <> - - Adds source code to the DLGLexer.h file - after the #include "DLexerBase.h" but - before the start of the class definition. - - #lexmember <> - - Adds source code to the DLGLexer.h file - as part of the DLGLexer class body. It - appears immediately after the start of - the class and a "public: statement. - -#27. (Fixed in 1.33MR1) Comments in DLG actions - - Previously, DLG would not recognize comments as a special case. - Thus, ">>" in the comments would cause errors. This is fixed. - -#26. (Fixed in 1.33MR1) Removed static variables from error routines - - Previously, the existence of statically allocated variables - in some of the parser's member functions posed a danger when - there was more than one parser active. - - Replaced with dynamically allocated/freed variables in 1.33MR1. - -#25. (Fixed in 1.33MR1) Use of string literals in semantic predicates - - Previously, it was not possible to place a string literal in - a semantic predicate because it was not properly "stringized" - for the report of a failed predicate. - -#24. (Fixed in 1.33MR1) Continuation lines for semantic predicates - - Previously, it was not possible to continue semantic - predicates across a line because it was not properly - "stringized" for the report of a failed predicate. - - rule : <>?[ a very - long statement ] - -#23. (Fixed in 1.33MR1) {...} envelope for failed semantic predicates - - Previously, there was a code generation error for failed - semantic predicates: - - rule : <>?[ stmt1; stmt2; ] - - which generated code which resembled: - - if (! xyz()) stmt1; stmt2; - - It now puts the statements in a {...} envelope: - - if (! xyz()) { stmt1; stmt2; }; - -#22. (Fixed in 1.33MR1) Continuation of #token across lines using "\" - - Previously, it was not possible to continue a #token regular - expression across a line. The trailing "\" and newline caused - a newline to be inserted into the regular expression by DLG. - - Fixed in 1.33MR1. - -#21. (Fixed in 1.33MR1) Use of ">>" (right shift operator in DLG actions - - It is now possible to use the C++ right shift operator ">>" - in DLG actions by using the normal escapes: - - #token "shift-right" << value=value \>\> 1;>> - -#20. (Version 1.33/19-Jan-97 Karl Eccleson - P.A. Keller (P.A.Keller@bath.ac.uk) - - There is a problem due to using exceptions with the -gh option. - - Suggested fix now in 1.33MR1. - -#19. (Fixed in 1.33MR1) Tom Piscotti and John Lilley - - There were problems suppressing messages to stdin and stdout - when running in a window environment because some functions - which uses fprint were not virtual. - - Suggested change now in 1.33MR1. - - I believe all functions containing error messages (excluding those - indicating internal inconsistency) have been placed in functions - which are virtual. - -#18. (Version 1.33/ 22-Nov-96) John Bair (jbair@iftime.com) - - Under some combination of options a required "return _retv" is - not generated. - - Suggested fix now in 1.33MR1. - -#17. (Version 1.33/3-Sep-96) Ron House (house@helios.usq.edu.au) - - The routine ASTBase::predorder_action omits two "tree->" - prefixes, which results in the preorder_action belonging - to the wrong node to be invoked. - - Suggested fix now in 1.33MR1. - -#16. (Version 1.33/7-Jun-96) Eli Sternheim - - Routine consumeUntilToken() does not check for end-of-file - condition. - - Suggested fix now in 1.33MR1. - -#15. (Version 1.33/8 Apr 96) Asgeir Olafsson - - Problem with tree duplication of doubly linked ASTs in ASTBase.cpp. - - Suggested fix now in 1.33MR1. - -#14. (Version 1.33/28-Feb-96) Andreas.Magnusson@mailbox.swipnet.se - - Problem with definition of operator = (const ANTLRTokenPtr rhs). - - Suggested fix now in 1.33MR1. - -#13. (Version 1.33/13-Feb-96) Franklin Chen (chen@adi.com) - - Sun C++ Compiler 3.0.1 can't compile testcpp/1 due to goto in - block with destructors. - - Apparently fixed. Can't locate "goto". - -#12. (Version 1.33/10-Nov-95) Minor problems with 1.33 code - - The following items have been fixed in 1.33MR1: - - 1. pccts/antlr/main.c line 142 - - "void" appears in classic C code - - 2. no makefile in support/genmk - - 3. EXIT_FAILURE/_SUCCESS instead of PCCTS_EXIT_FAILURE/_SUCCESS - - pccts/h/PCCTSAST.cpp - pccts/h/DLexerBase.cpp - pccts/testcpp/6/test.g - - 4. use of "signed int" isn't accepted by AT&T cfront - - pccts/h/PCCTSAST.h line 42 - - 5. in call to ANTLRParser::FAIL the var arg err_k is passed as - "int" but is declared "unsigned int". - - 6. I believe that a failed validation predicate still does not - get put in a "{...}" envelope, despite the release notes. - - 7. The #token ">>" appearing in the DLG grammar description - causes DLG to generate the string literal "\>\>" which - is non-conforming and will cause some compilers to - complain (scan.c function act10 line 143 of source code). - -#11. (Version 1.32b6) Dave Kuhlman (dkuhlman@netcom.com) - - Problem with file close in gen.c. Already fixed in 1.33. - -#10. (Version 1.32b6/29-Aug-95) - - pccts/antlr/main.c contains a C++ style comments on lines 149 - and 176 which causes problems for most C compilers. - - Already fixed in 1.33. - -#9. (Version 1.32b4/14-Mar-95) dlgauto.h #include "config.h" - - The file pccts/h/dlgauto.h should probably contain a #include - "config.h" as it uses the #define symbol __USE_PROTOS. - - Added to 1.33MR1. - -#8. (Version 1.32b4/6-Mar-95) Michael T. Richter (mtr@igs.net) - - In C++ output mode anonymous tokens from in-line regular expressions - can create enum values which are too wide for the datatype of the enum - assigned by the C++ compiler. - - Fixed in 1.33MR1. - -#7. (Version 1.32b4/6-Mar-95) C++ does not imply __STDC__ - - In err.h the combination of # directives assumes that a C++ - compiler has __STDC__ defined. This is not necessarily true. - - This problem also appears in the use of __USE_PROTOS which - is appropriate for both Standard C and C++ in antlr/gen.c - and antlr/lex.c - - Fixed in 1.33MR1. - -#6. (Version 1.32 ?/15-Feb-95) Name conflict for "TokenType" - - Already fixed in 1.33. - -#5. (23-Jan-95) Douglas_Cuthbertson.JTIDS@jtids_qmail.hanscom.af.mil - - The fail action following a semantic predicate is not enclosed in - "{...}". This can lead to problems when the fail action contains - more than one statement. - - Fixed in 1.33MR1. - -#4 . (Version 1.33/31-Mar-96) jlilley@empathy.com (John Lilley) - - Put briefly, a semantic predicate ought to abort a guess if it fails. - - Correction suggested by J. Lilley has been added to 1.33MR1. - -#3 . (Version 1.33) P.A.Keller@bath.ac.uk - - Extra commas are placed in the K&R style argument list for rules - when using both exceptions and ASTs. - - Fixed in 1.33MR1. - -#2. (Version 1.32b6/2-Oct-95) Brad Schick - - Construct #[] generates zzastnew() in C++ mode. - - Already fixed in 1.33. - -#1. (Version 1.33) Bob Bailey (robert@oakhill.sps.mot.com) - - Previously, config.h assumed that all PC systems required - "short" file names. The user can now override that - assumption with "#define LONGFILENAMES". - - Added to 1.33MR1. diff --git a/Tools/CodeTools/TianoTools/Pccts/CHANGES_SUMMARY.txt b/Tools/CodeTools/TianoTools/Pccts/CHANGES_SUMMARY.txt deleted file mode 100644 index 91defae169..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/CHANGES_SUMMARY.txt +++ /dev/null @@ -1,2049 +0,0 @@ -====================================================================== - - CHANGES_SUMMARY.TXT - - A QUICK overview of changes from 1.33 in reverse order - - A summary of additions rather than bug fixes and minor code changes. - - Numbers refer to items in CHANGES_FROM_133*.TXT - which may contain additional information. - - DISCLAIMER - - The software and these notes are provided "as is". They may include - typographical or technical errors and their authors disclaims all - liability of any kind or nature for damages due to error, fault, - defect, or deficiency regardless of cause. All warranties of any - kind, either express or implied, including, but not limited to, the - implied warranties of merchantability and fitness for a particular - purpose are disclaimed. - -====================================================================== - -#258. You can specify a user-defined base class for your parser - - The base class must constructor must have a signature similar to - that of ANTLRParser. - -#253. Generation of block preamble (-preamble and -preamble_first) - - The antlr option -preamble causes antlr to insert the code - BLOCK_PREAMBLE at the start of each rule and block. - - The antlr option -preamble_first is similar, but inserts the - code BLOCK_PREAMBLE_FIRST(PreambleFirst_123) where the symbol - PreambleFirst_123 is equivalent to the first set defined by - the #FirstSetSymbol described in Item #248. - -#248. Generate symbol for first set of an alternative - - rr : #FirstSetSymbol(rr_FirstSet) ( Foo | Bar ) ; - -#216. Defer token fetch for C++ mode - - When the ANTLRParser class is built with the pre-processor option - ZZDEFER_FETCH defined, the fetch of new tokens by consume() is deferred - until LA(i) or LT(i) is called. - -#215. Use reset() to reset DLGLexerBase -#188. Added pccts/h/DLG_stream_input.h -#180. Added ANTLRParser::getEofToken() -#173. -glms for Microsoft style filenames with -gl -#170. Suppression for predicates with lookahead depth >1 - - Consider the following grammar with -ck 2 and the predicate in rule - "a" with depth 2: - - r1 : (ab)* "@" - ; - - ab : a - | b - ; - - a : (A B)? => <>? A B C - ; - - b : A B C - ; - - Normally, the predicate would be hoisted into rule r1 in order to - determine whether to call rule "ab". However it should *not* be - hoisted because, even if p is false, there is a valid alternative - in rule b. With "-mrhoistk on" the predicate will be suppressed. - - If "-info p" command line option is present the following information - will appear in the generated code: - - while ( (LA(1)==A) - #if 0 - - Part (or all) of predicate with depth > 1 suppressed by alternative - without predicate - - pred << p(LATEXT(2))>>? - depth=k=2 ("=>" guard) rule a line 8 t1.g - tree context: - (root = A - B - ) - - The token sequence which is suppressed: ( A B ) - The sequence of references which generate that sequence of tokens: - - 1 to ab r1/1 line 1 t1.g - 2 ab ab/1 line 4 t1.g - 3 to b ab/2 line 5 t1.g - 4 b b/1 line 11 t1.g - 5 #token A b/1 line 11 t1.g - 6 #token B b/1 line 11 t1.g - - #endif - - A slightly more complicated example: - - r1 : (ab)* "@" - ; - - ab : a - | b - ; - - a : (A B)? => <>? (A B | D E) - ; - - b : <>? D E - ; - - - In this case, the sequence (D E) in rule "a" which lies behind - the guard is used to suppress the predicate with context (D E) - in rule b. - - while ( (LA(1)==A || LA(1)==D) - #if 0 - - Part (or all) of predicate with depth > 1 suppressed by alternative - without predicate - - pred << q(LATEXT(2))>>? - depth=k=2 rule b line 11 t2.g - tree context: - (root = D - E - ) - - The token sequence which is suppressed: ( D E ) - The sequence of references which generate that sequence of tokens: - - 1 to ab r1/1 line 1 t2.g - 2 ab ab/1 line 4 t2.g - 3 to a ab/1 line 4 t2.g - 4 a a/1 line 8 t2.g - 5 #token D a/1 line 8 t2.g - 6 #token E a/1 line 8 t2.g - - #endif - && - #if 0 - - pred << p(LATEXT(2))>>? - depth=k=2 ("=>" guard) rule a line 8 t2.g - tree context: - (root = A - B - ) - - #endif - - (! ( LA(1)==A && LA(2)==B ) || p(LATEXT(2)) ) { - ab(); - ... - -#165. (Changed in MR13) option -newAST - - To create ASTs from an ANTLRTokenPtr antlr usually calls - "new AST(ANTLRTokenPtr)". This option generates a call - to "newAST(ANTLRTokenPtr)" instead. This allows a user - to define a parser member function to create an AST object. - -#161. (Changed in MR13) Switch -gxt inhibits generation of tokens.h - -#158. (Changed in MR13) #header causes problem for pre-processors - - A user who runs the C pre-processor on antlr source suggested - that another syntax be allowed. With MR13 such directives - such as #header, #pragma, etc. may be written as "\#header", - "\#pragma", etc. For escaping pre-processor directives inside - a #header use something like the following: - - \#header - << - \#include - >> - -#155. (Changed in MR13) Context behind predicates can suppress - - With -mrhoist enabled the context behind a guarded predicate can - be used to suppress other predicates. Consider the following grammar: - - r0 : (r1)+; - - r1 : rp - | rq - ; - rp : <

>? B ; - rq : (A)? => <>? (A|B); - - In earlier versions both predicates "p" and "q" would be hoisted into - rule r0. With MR12c predicate p is suppressed because the context which - follows predicate q includes "B" which can "cover" predicate "p". In - other words, in trying to decide in r0 whether to call r1, it doesn't - really matter whether p is false or true because, either way, there is - a valid choice within r1. - -#154. (Changed in MR13) Making hoist suppression explicit using <> - - A common error, even among experienced pccts users, is to code - an init-action to inhibit hoisting rather than a leading action. - An init-action does not inhibit hoisting. - - This was coded: - - rule1 : <<;>> rule2 - - This is what was meant: - - rule1 : <<;>> <<;>> rule2 - - With MR13, the user can code: - - rule1 : <<;>> <> rule2 - - The following will give an error message: - - rule1 : <> rule2 - - If the <> appears as an init-action rather than a leading - action an error message is issued. The meaning of an init-action - containing "nohoist" is unclear: does it apply to just one - alternative or to all alternatives ? - -#151a. Addition of ANTLRParser::getLexer(), ANTLRTokenStream::getLexer() - - You must manually cast the ANTLRTokenStream to your program's - lexer class. Because the name of the lexer's class is not fixed. - Thus it is impossible to incorporate it into the DLGLexerBase - class. - -#151b.(Changed in MR12) ParserBlackBox member getLexer() - -#150. (Changed in MR12) syntaxErrCount and lexErrCount now public - -#149. (Changed in MR12) antlr option -info o (letter o for orphan) - - If there is more than one rule which is not referenced by any - other rule then all such rules are listed. This is useful for - alerting one to rules which are not used, but which can still - contribute to ambiguity. - -#148. (Changed in MR11) #token names appearing in zztokens,token_tbl - - One can write: - - #token Plus ("+") "\+" - #token RP ("(") "\(" - #token COM ("comment begin") "/\*" - - The string in parenthesis will be used in syntax error messages. - -#146. (Changed in MR11) Option -treport for locating "difficult" alts - - It can be difficult to determine which alternatives are causing - pccts to work hard to resolve an ambiguity. In some cases the - ambiguity is successfully resolved after much CPU time so there - is no message at all. - - A rough measure of the amount of work being peformed which is - independent of the CPU speed and system load is the number of - tnodes created. Using "-info t" gives information about the - total number of tnodes created and the peak number of tnodes. - - Tree Nodes: peak 1300k created 1416k lost 0 - - It also puts in the generated C or C++ file the number of tnodes - created for a rule (at the end of the rule). However this - information is not sufficient to locate the alternatives within - a rule which are causing the creation of tnodes. - - Using: - - antlr -treport 100000 .... - - causes antlr to list on stdout any alternatives which require the - creation of more than 100,000 tnodes, along with the lookahead sets - for those alternatives. - - The following is a trivial case from the ansi.g grammar which shows - the format of the report. This report might be of more interest - in cases where 1,000,000 tuples were created to resolve the ambiguity. - - ------------------------------------------------------------------------- - There were 0 tuples whose ambiguity could not be resolved - by full lookahead - There were 157 tnodes created to resolve ambiguity between: - - Choice 1: statement/2 line 475 file ansi.g - Choice 2: statement/3 line 476 file ansi.g - - Intersection of lookahead[1] sets: - - IDENTIFIER - - Intersection of lookahead[2] sets: - - LPARENTHESIS COLON AMPERSAND MINUS - STAR PLUSPLUS MINUSMINUS ONESCOMPLEMENT - NOT SIZEOF OCTALINT DECIMALINT - HEXADECIMALINT FLOATONE FLOATTWO IDENTIFIER - STRING CHARACTER - ------------------------------------------------------------------------- - -#143. (Changed in MR11) Optional ";" at end of #token statement - - Fixes problem of: - - #token X "x" - - << - parser action - >> - - Being confused with: - - #token X "x" <> - -#142. (Changed in MR11) class BufFileInput subclass of DLGInputStream - - Alexey Demakov (demakov@kazbek.ispras.ru) has supplied class - BufFileInput derived from DLGInputStream which provides a - function lookahead(char *string) to test characters in the - input stream more than one character ahead. - The class is located in pccts/h/BufFileInput.* of the kit. - -#140. #pred to define predicates - - +---------------------------------------------------+ - | Note: Assume "-prc on" for this entire discussion | - +---------------------------------------------------+ - - A problem with predicates is that each one is regarded as - unique and capable of disambiguating cases where two - alternatives have identical lookahead. For example: - - rule : <>? A - | <>? A - ; - - will not cause any error messages or warnings to be issued - by earlier versions of pccts. To compare the text of the - predicates is an incomplete solution. - - In 1.33MR11 I am introducing the #pred statement in order to - solve some problems with predicates. The #pred statement allows - one to give a symbolic name to a "predicate literal" or a - "predicate expression" in order to refer to it in other predicate - expressions or in the rules of the grammar. - - The predicate literal associated with a predicate symbol is C - or C++ code which can be used to test the condition. A - predicate expression defines a predicate symbol in terms of other - predicate symbols using "!", "&&", and "||". A predicate symbol - can be defined in terms of a predicate literal, a predicate - expression, or *both*. - - When a predicate symbol is defined with both a predicate literal - and a predicate expression, the predicate literal is used to generate - code, but the predicate expression is used to check for two - alternatives with identical predicates in both alternatives. - - Here are some examples of #pred statements: - - #pred IsLabel <>? - #pred IsLocalVar <>? - #pred IsGlobalVar <>? - #pred IsVar <>? IsLocalVar || IsGlobalVar - #pred IsScoped <>? IsLabel || IsLocalVar - - I hope that the use of EBNF notation to describe the syntax of the - #pred statement will not cause problems for my readers (joke). - - predStatement : "#pred" - CapitalizedName - ( - "<>?" - | "<>?" predOrExpr - | predOrExpr - ) - ; - - predOrExpr : predAndExpr ( "||" predAndExpr ) * ; - - predAndExpr : predPrimary ( "&&" predPrimary ) * ; - - predPrimary : CapitalizedName - | "!" predPrimary - | "(" predOrExpr ")" - ; - - What is the purpose of this nonsense ? - - To understand how predicate symbols help, you need to realize that - predicate symbols are used in two different ways with two different - goals. - - a. Allow simplification of predicates which have been combined - during predicate hoisting. - - b. Allow recognition of identical predicates which can't disambiguate - alternatives with common lookahead. - - First we will discuss goal (a). Consider the following rule: - - rule0: rule1 - | ID - | ... - ; - - rule1: rule2 - | rule3 - ; - - rule2: <>? ID ; - rule3: <>? ID ; - - When the predicates in rule2 and rule3 are combined by hoisting - to create a prediction expression for rule1 the result is: - - if ( LA(1)==ID - && ( isX(LATEXT(1) || !isX(LATEXT(1) ) ) { rule1(); ... - - This is inefficient, but more importantly, can lead to false - assumptions that the predicate expression distinguishes the rule1 - alternative with some other alternative with lookahead ID. In - MR11 one can write: - - #pred IsX <>? - - ... - - rule2: <>? ID ; - rule3: <>? ID ; - - During hoisting MR11 recognizes this as a special case and - eliminates the predicates. The result is a prediction - expression like the following: - - if ( LA(1)==ID ) { rule1(); ... - - Please note that the following cases which appear to be equivalent - *cannot* be simplified by MR11 during hoisting because the hoisting - logic only checks for a "!" in the predicate action, not in the - predicate expression for a predicate symbol. - - *Not* equivalent and is not simplified during hoisting: - - #pred IsX <>? - #pred NotX <>? - ... - rule2: <>? ID ; - rule3: <>? ID ; - - *Not* equivalent and is not simplified during hoisting: - - #pred IsX <>? - #pred NotX !IsX - ... - rule2: <>? ID ; - rule3: <>? ID ; - - Now we will discuss goal (b). - - When antlr discovers that there is a lookahead ambiguity between - two alternatives it attempts to resolve the ambiguity by searching - for predicates in both alternatives. In the past any predicate - would do, even if the same one appeared in both alternatives: - - rule: <>? X - | <>? X - ; - - The #pred statement is a start towards solving this problem. - During ambiguity resolution (*not* predicate hoisting) the - predicates for the two alternatives are expanded and compared. - Consider the following example: - - #pred Upper <>? - #pred Lower <>? - #pred Alpha <>? Upper || Lower - - rule0: rule1 - | <>? ID - ; - - rule1: - | rule2 - | rule3 - ... - ; - - rule2: <>? ID; - rule3: <>? ID; - - The definition of #pred Alpha expresses: - - a. to test the predicate use the C code "isAlpha(LATEXT(1))" - - b. to analyze the predicate use the information that - Alpha is equivalent to the union of Upper and Lower, - - During ambiguity resolution the definition of Alpha is expanded - into "Upper || Lower" and compared with the predicate in the other - alternative, which is also "Upper || Lower". Because they are - identical MR11 will report a problem. - - ------------------------------------------------------------------------- - t10.g, line 5: warning: the predicates used to disambiguate rule rule0 - (file t10.g alt 1 line 5 and alt 2 line 6) - are identical when compared without context and may have no - resolving power for some lookahead sequences. - ------------------------------------------------------------------------- - - If you use the "-info p" option the output file will contain: - - +----------------------------------------------------------------------+ - |#if 0 | - | | - |The following predicates are identical when compared without | - | lookahead context information. For some ambiguous lookahead | - | sequences they may not have any power to resolve the ambiguity. | - | | - |Choice 1: rule0/1 alt 1 line 5 file t10.g | - | | - | The original predicate for choice 1 with available context | - | information: | - | | - | OR expr | - | | - | pred << Upper>>? | - | depth=k=1 rule rule2 line 14 t10.g | - | set context: | - | ID | - | | - | pred << Lower>>? | - | depth=k=1 rule rule3 line 15 t10.g | - | set context: | - | ID | - | | - | The predicate for choice 1 after expansion (but without context | - | information): | - | | - | OR expr | - | | - | pred << isUpper(LATEXT(1))>>? | - | depth=k=1 rule line 1 t10.g | - | | - | pred << isLower(LATEXT(1))>>? | - | depth=k=1 rule line 2 t10.g | - | | - | | - |Choice 2: rule0/2 alt 2 line 6 file t10.g | - | | - | The original predicate for choice 2 with available context | - | information: | - | | - | pred << Alpha>>? | - | depth=k=1 rule rule0 line 6 t10.g | - | set context: | - | ID | - | | - | The predicate for choice 2 after expansion (but without context | - | information): | - | | - | OR expr | - | | - | pred << isUpper(LATEXT(1))>>? | - | depth=k=1 rule line 1 t10.g | - | | - | pred << isLower(LATEXT(1))>>? | - | depth=k=1 rule line 2 t10.g | - | | - | | - |#endif | - +----------------------------------------------------------------------+ - - The comparison of the predicates for the two alternatives takes - place without context information, which means that in some cases - the predicates will be considered identical even though they operate - on disjoint lookahead sets. Consider: - - #pred Alpha - - rule1: <>? ID - | <>? Label - ; - - Because the comparison of predicates takes place without context - these will be considered identical. The reason for comparing - without context is that otherwise it would be necessary to re-evaluate - the entire predicate expression for each possible lookahead sequence. - This would require more code to be written and more CPU time during - grammar analysis, and it is not yet clear whether anyone will even make - use of the new #pred facility. - - A temporary workaround might be to use different #pred statements - for predicates you know have different context. This would avoid - extraneous warnings. - - The above example might be termed a "false positive". Comparison - without context will also lead to "false negatives". Consider the - following example: - - #pred Alpha - #pred Beta - - rule1: <>? A - | rule2 - ; - - rule2: <>? A - | <>? B - ; - - The predicate used for alt 2 of rule1 is (Alpha || Beta). This - appears to be different than the predicate Alpha used for alt1. - However, the context of Beta is B. Thus when the lookahead is A - Beta will have no resolving power and Alpha will be used for both - alternatives. Using the same predicate for both alternatives isn't - very helpful, but this will not be detected with 1.33MR11. - - To properly handle this the predicate expression would have to be - evaluated for each distinct lookahead context. - - To determine whether two predicate expressions are identical is - difficult. The routine may fail to identify identical predicates. - - The #pred feature also compares predicates to see if a choice between - alternatives which is resolved by a predicate which makes the second - choice unreachable. Consider the following example: - - #pred A <>? - #pred B <>? - #pred A_or_B A || B - - r : s - | t - ; - s : <>? ID - ; - t : <>? ID - ; - - ---------------------------------------------------------------------------- - t11.g, line 5: warning: the predicate used to disambiguate the - first choice of rule r - (file t11.g alt 1 line 5 and alt 2 line 6) - appears to "cover" the second predicate when compared without context. - The second predicate may have no resolving power for some lookahead - sequences. - ---------------------------------------------------------------------------- - -#132. (Changed in 1.33MR11) Recognition of identical predicates in alts - - Prior to 1.33MR11, there would be no ambiguity warning when the - very same predicate was used to disambiguate both alternatives: - - test: ref B - | ref C - ; - - ref : <>? A - - In 1.33MR11 this will cause the warning: - - warning: the predicates used to disambiguate rule test - (file v98.g alt 1 line 1 and alt 2 line 2) - are identical and have no resolving power - - ----------------- Note ----------------- - - This is different than the following case - - test: <>? A B - | <>? A C - ; - - In this case there are two distinct predicates - which have exactly the same text. In the first - example there are two references to the same - predicate. The problem represented by this - grammar will be addressed later. - - -#127. (Changed in 1.33MR11) - - Count Syntax Errors Count DLG Errors - ------------------- ---------------- - - C++ mode ANTLRParser:: DLGLexerBase:: - syntaxErrCount lexErrCount - C mode zzSyntaxErrCount zzLexErrCount - - The C mode variables are global and initialized to 0. - They are *not* reset to 0 automatically when antlr is - restarted. - - The C++ mode variables are public. They are initialized - to 0 by the constructors. They are *not* reset to 0 by the - ANTLRParser::init() method. - - Suggested by Reinier van den Born (reinier@vnet.ibm.com). - -#126. (Changed in 1.33MR11) Addition of #first <<...>> - - The #first <<...>> inserts the specified text in the output - files before any other #include statements required by pccts. - The only things before the #first text are comments and - a #define ANTLR_VERSION. - - Requested by and Esa Pulkkinen (esap@cs.tut.fi) and Alexin - Zoltan (alexin@inf.u-szeged.hu). - -#124. A Note on the New "&&" Style Guarded Predicates - - I've been asked several times, "What is the difference between - the old "=>" style guard predicates and the new style "&&" guard - predicates, and how do you choose one over the other" ? - - The main difference is that the "=>" does not apply the - predicate if the context guard doesn't match, whereas - the && form always does. What is the significance ? - - If you have a predicate which is not on the "leading edge" - it is cannot be hoisted. Suppose you need a predicate that - looks at LA(2). You must introduce it manually. The - classic example is: - - castExpr : - LP typeName RP - | .... - ; - - typeName : <>? ID - | STRUCT ID - ; - - The problem is that isTypeName() isn't on the leading edge - of typeName, so it won't be hoisted into castExpr to help - make a decision on which production to choose. - - The *first* attempt to fix it is this: - - castExpr : - <>? - LP typeName RP - | .... - ; - - Unfortunately, this won't work because it ignores - the problem of STRUCT. The solution is to apply - isTypeName() in castExpr if LA(2) is an ID and - don't apply it when LA(2) is STRUCT: - - castExpr : - (LP ID)? => <>? - LP typeName RP - | .... - ; - - In conclusion, the "=>" style guarded predicate is - useful when: - - a. the tokens required for the predicate - are not on the leading edge - b. there are alternatives in the expression - selected by the predicate for which the - predicate is inappropriate - - If (b) were false, then one could use a simple - predicate (assuming "-prc on"): - - castExpr : - <>? - LP typeName RP - | .... - ; - - typeName : <>? ID - ; - - So, when do you use the "&&" style guarded predicate ? - - The new-style "&&" predicate should always be used with - predicate context. The context guard is in ADDITION to - the automatically computed context. Thus it useful for - predicates which depend on the token type for reasons - other than context. - - The following example is contributed by Reinier van den Born - (reinier@vnet.ibm.com). - - +-------------------------------------------------------------------------+ - | This grammar has two ways to call functions: | - | | - | - a "standard" call syntax with parens and comma separated args | - | - a shell command like syntax (no parens and spacing separated args) | - | | - | The former also allows a variable to hold the name of the function, | - | the latter can also be used to call external commands. | - | | - | The grammar (simplified) looks like this: | - | | - | fun_call : ID "(" { expr ("," expr)* } ")" | - | /* ID is function name */ | - | | "@" ID "(" { expr ("," expr)* } ")" | - | /* ID is var containing fun name */ | - | ; | - | | - | command : ID expr* /* ID is function name */ | - | | path expr* /* path is external command name */ | - | ; | - | | - | path : ID /* left out slashes and such */ | - | | "@" ID /* ID is environment var */ | - | ; | - | | - | expr : .... | - | | "(" expr ")"; | - | | - | call : fun_call | - | | command | - | ; | - | | - | Obviously the call is wildly ambiguous. This is more or less how this | - | is to be resolved: | - | | - | A call begins with an ID or an @ followed by an ID. | - | | - | If it is an ID and if it is an ext. command name -> command | - | if followed by a paren -> fun_call | - | otherwise -> command | - | | - | If it is an @ and if the ID is a var name -> fun_call | - | otherwise -> command | - | | - | One can implement these rules quite neatly using && predicates: | - | | - | call : ("@" ID)? && <>? fun_call | - | | (ID)? && <>? command | - | | (ID "(")? fun_call | - | | command | - | ; | - | | - | This can be done better, so it is not an ideal example, but it | - | conveys the principle. | - +-------------------------------------------------------------------------+ - -#122. (Changed in 1.33MR11) Member functions to reset DLG in C++ mode - - void DLGFileReset(FILE *f) { input = f; found_eof = 0; } - void DLGStringReset(DLGChar *s) { input = s; p = &input[0]; } - - Supplied by R.A. Nelson (cowboy@VNET.IBM.COM) - -#119. (Changed in 1.33MR11) Ambiguity aid for grammars - - The user can ask for additional information on ambiguities reported - by antlr to stdout. At the moment, only one ambiguity report can - be created in an antlr run. - - This feature is enabled using the "-aa" (Ambiguity Aid) option. - - The following options control the reporting of ambiguities: - - -aa ruleName Selects reporting by name of rule - -aa lineNumber Selects reporting by line number - (file name not compared) - - -aam Selects "multiple" reporting for a token - in the intersection set of the - alternatives. - - For instance, the token ID may appear dozens - of times in various paths as the program - explores the rules which are reachable from - the point of an ambiguity. With option -aam - every possible path the search program - encounters is reported. - - Without -aam only the first encounter is - reported. This may result in incomplete - information, but the information may be - sufficient and much shorter. - - -aad depth Selects the depth of the search. - The default value is 1. - - The number of paths to be searched, and the - size of the report can grow geometrically - with the -ck value if a full search for all - contributions to the source of the ambiguity - is explored. - - The depth represents the number of tokens - in the lookahead set which are matched against - the set of ambiguous tokens. A depth of 1 - means that the search stops when a lookahead - sequence of just one token is matched. - - A k=1 ck=6 grammar might generate 5,000 items - in a report if a full depth 6 search is made - with the Ambiguity Aid. The source of the - problem may be in the first token and obscured - by the volume of data - I hesitate to call - it information. - - When the user selects a depth > 1, the search - is first performed at depth=1 for both - alternatives, then depth=2 for both alternatives, - etc. - - Sample output for rule grammar in antlr.g itself: - - +---------------------------------------------------------------------+ - | Ambiguity Aid | - | | - | Choice 1: grammar/70 line 632 file a.g | - | Choice 2: grammar/82 line 644 file a.g | - | | - | Intersection of lookahead[1] sets: | - | | - | "\}" "class" "#errclass" "#tokclass" | - | | - | Choice:1 Depth:1 Group:1 ("#errclass") | - | 1 in (...)* block grammar/70 line 632 a.g | - | 2 to error grammar/73 line 635 a.g | - | 3 error error/1 line 894 a.g | - | 4 #token "#errclass" error/2 line 895 a.g | - | | - | Choice:1 Depth:1 Group:2 ("#tokclass") | - | 2 to tclass grammar/74 line 636 a.g | - | 3 tclass tclass/1 line 937 a.g | - | 4 #token "#tokclass" tclass/2 line 938 a.g | - | | - | Choice:1 Depth:1 Group:3 ("class") | - | 2 to class_def grammar/75 line 637 a.g | - | 3 class_def class_def/1 line 669 a.g | - | 4 #token "class" class_def/3 line 671 a.g | - | | - | Choice:1 Depth:1 Group:4 ("\}") | - | 2 #token "\}" grammar/76 line 638 a.g | - | | - | Choice:2 Depth:1 Group:5 ("#errclass") | - | 1 in (...)* block grammar/83 line 645 a.g | - | 2 to error grammar/93 line 655 a.g | - | 3 error error/1 line 894 a.g | - | 4 #token "#errclass" error/2 line 895 a.g | - | | - | Choice:2 Depth:1 Group:6 ("#tokclass") | - | 2 to tclass grammar/94 line 656 a.g | - | 3 tclass tclass/1 line 937 a.g | - | 4 #token "#tokclass" tclass/2 line 938 a.g | - | | - | Choice:2 Depth:1 Group:7 ("class") | - | 2 to class_def grammar/95 line 657 a.g | - | 3 class_def class_def/1 line 669 a.g | - | 4 #token "class" class_def/3 line 671 a.g | - | | - | Choice:2 Depth:1 Group:8 ("\}") | - | 2 #token "\}" grammar/96 line 658 a.g | - +---------------------------------------------------------------------+ - - For a linear lookahead set ambiguity (where k=1 or for k>1 but - when all lookahead sets [i] with i>? A ; - c : A ; - - Prior to 1.33MR10 the code generated for "start" would resemble: - - while { - if (LA(1)==A && - (!LA(1)==A || isUpper())) { - a(); - } - }; - - This code is wrong because it makes rule "c" unreachable from - "start". The essence of the problem is that antlr fails to - recognize that there can be a valid alternative within "a" even - when the predicate <>? is false. - - In 1.33MR10 with -mrhoist the hoisting of the predicate into - "start" is suppressed because it recognizes that "c" can - cover all the cases where the predicate is false: - - while { - if (LA(1)==A) { - a(); - } - }; - - With the antlr "-info p" switch the user will receive information - about the predicate suppression in the generated file: - - -------------------------------------------------------------- - #if 0 - - Hoisting of predicate suppressed by alternative without predicate. - The alt without the predicate includes all cases where - the predicate is false. - - WITH predicate: line 7 v1.g - WITHOUT predicate: line 7 v1.g - - The context set for the predicate: - - A - - The lookahead set for the alt WITHOUT the semantic predicate: - - A - - The predicate: - - pred << isUpper(LATEXT(1))>>? - depth=k=1 rule b line 9 v1.g - set context: - A - tree context: null - - Chain of referenced rules: - - #0 in rule start (line 5 v1.g) to rule a - #1 in rule a (line 7 v1.g) - - #endif - -------------------------------------------------------------- - - A predicate can be suppressed by a combination of alternatives - which, taken together, cover a predicate: - - start : (a)* "@" ; - - a : b | ca | cb | cc ; - - b : <>? ( A | B | C ) ; - - ca : A ; - cb : B ; - cc : C ; - - Consider a more complex example in which "c" covers only part of - a predicate: - - start : (a)* "@" ; - - a : b - | c - ; - - b : <>? - ( A - | X - ); - - c : A - ; - - Prior to 1.33MR10 the code generated for "start" would resemble: - - while { - if ( (LA(1)==A || LA(1)==X) && - (! (LA(1)==A || LA(1)==X) || isUpper()) { - a(); - } - }; - - With 1.33MR10 and -mrhoist the predicate context is restricted to - the non-covered lookahead. The code resembles: - - while { - if ( (LA(1)==A || LA(1)==X) && - (! (LA(1)==X) || isUpper()) { - a(); - } - }; - - With the antlr "-info p" switch the user will receive information - about the predicate restriction in the generated file: - - -------------------------------------------------------------- - #if 0 - - Restricting the context of a predicate because of overlap - in the lookahead set between the alternative with the - semantic predicate and one without - Without this restriction the alternative without the predicate - could not be reached when input matched the context of the - predicate and the predicate was false. - - WITH predicate: line 11 v4.g - WITHOUT predicate: line 12 v4.g - - The original context set for the predicate: - - A X - - The lookahead set for the alt WITHOUT the semantic predicate: - - A - - The intersection of the two sets - - A - - The original predicate: - - pred << isUpper(LATEXT(1))>>? - depth=k=1 rule b line 15 v4.g - set context: - A X - tree context: null - - The new (modified) form of the predicate: - - pred << isUpper(LATEXT(1))>>? - depth=k=1 rule b line 15 v4.g - set context: - X - tree context: null - - #endif - -------------------------------------------------------------- - - The bad news about -mrhoist: - - (a) -mrhoist does not analyze predicates with lookahead - depth > 1. - - (b) -mrhoist does not look past a guarded predicate to - find context which might cover other predicates. - - For these cases you might want to use syntactic predicates. - When a semantic predicate fails during guess mode the guess - fails and the next alternative is tried. - - Limitation (a) is illustrated by the following example: - - start : (stmt)* EOF ; - - stmt : cast - | expr - ; - cast : <>? LP ID RP ; - - expr : LP ID RP ; - - This is not much different from the first example, except that - it requires two tokens of lookahead context to determine what - to do. This predicate is NOT suppressed because the current version - is unable to handle predicates with depth > 1. - - A predicate can be combined with other predicates during hoisting. - In those cases the depth=1 predicates are still handled. Thus, - in the following example the isUpper() predicate will be suppressed - by line #4 when hoisted from "bizarre" into "start", but will still - be present in "bizarre" in order to predict "stmt". - - start : (bizarre)* EOF ; // #1 - // #2 - bizarre : stmt // #3 - | A // #4 - ; - - stmt : cast - | expr - ; - - cast : <>? LP ID RP ; - - expr : LP ID RP ; - | <>? A - - Limitation (b) is illustrated by the following example of a - context guarded predicate: - - rule : (A)? <

>? // #1 - (A // #2 - |B // #3 - ) // #4 - | <> B // #5 - ; - - Recall that this means that when the lookahead is NOT A then - the predicate "p" is ignored and it attempts to match "A|B". - Ideally, the "B" at line #3 should suppress predicate "q". - However, the current version does not attempt to look past - the guard predicate to find context which might suppress other - predicates. - - In some cases -mrhoist will lead to the reporting of ambiguities - which were not visible before: - - start : (a)* "@"; - a : bc | d; - bc : b | c ; - - b : <>? A; - c : A ; - - d : A ; - - In this case there is a true ambiguity in "a" between "bc" and "d" - which can both match "A". Without -mrhoist the predicate in "b" - is hoisted into "a" and there is no ambiguity reported. However, - with -mrhoist, the predicate in "b" is suppressed by "c" (as it - should be) making the ambiguity in "a" apparent. - - The motivations for these changes were hoisting problems reported - by Reinier van den Born (reinier@vnet.ibm.com) and several others. - -#113. (Changed in 1.33MR10) new context guarded pred: (g)? && <

>? expr - - The existing context guarded predicate: - - rule : (guard)? => <

>? expr - | next_alternative - ; - - generates code which resembles: - - if (lookahead(expr) && (!guard || pred)) { - expr() - } else .... - - This is not suitable for some applications because it allows - expr() to be invoked when the predicate is false. This is - intentional because it is meant to mimic automatically computed - predicate context. - - The new context guarded predicate uses the guard information - differently because it has a different goal. Consider: - - rule : (guard)? && <

>? expr - | next_alternative - ; - - The new style of context guarded predicate is equivalent to: - - rule : <>? expr - | next_alternative - ; - - It generates code which resembles: - - if (lookahead(expr) && guard && pred) { - expr(); - } else ... - - Both forms of guarded predicates severely restrict the form of - the context guard: it can contain no rule references, no - (...)*, no (...)+, and no {...}. It may contain token and - token class references, and alternation ("|"). - - Addition for 1.33MR11: in the token expression all tokens must - be at the same height of the token tree: - - (A ( B | C))? && ... is ok (all height 2) - (A ( B | ))? && ... is not ok (some 1, some 2) - (A B C D | E F G H)? && ... is ok (all height 4) - (A B C D | E )? && ... is not ok (some 4, some 1) - - This restriction is required in order to properly compute the lookahead - set for expressions like: - - rule1 : (A B C)? && <>? rule2 ; - rule2 : (A|X) (B|Y) (C|Z); - - This addition was suggested by Rienier van den Born (reinier@vnet.ibm.com) - -#109. (Changed in 1.33MR10) improved trace information - - The quality of the trace information provided by the "-gd" - switch has been improved significantly. Here is an example - of the output from a test program. It shows the rule name, - the first token of lookahead, the call depth, and the guess - status: - - exit rule gusxx {"?"} depth 2 - enter rule gusxx {"?"} depth 2 - enter rule gus1 {"o"} depth 3 guessing - guess done - returning to rule gus1 {"o"} at depth 3 - (guess mode continues - an enclosing guess is still active) - guess done - returning to rule gus1 {"Z"} at depth 3 - (guess mode continues - an enclosing guess is still active) - exit rule gus1 {"Z"} depth 3 guessing - guess done - returning to rule gusxx {"o"} at depth 2 (guess mode ends) - enter rule gus1 {"o"} depth 3 - guess done - returning to rule gus1 {"o"} at depth 3 (guess mode ends) - guess done - returning to rule gus1 {"Z"} at depth 3 (guess mode ends) - exit rule gus1 {"Z"} depth 3 - line 1: syntax error at "Z" missing SC - ... - - Rule trace reporting is controlled by the value of the integer - [zz]traceOptionValue: when it is positive tracing is enabled, - otherwise it is disabled. Tracing during guess mode is controlled - by the value of the integer [zz]traceGuessOptionValue. When - it is positive AND [zz]traceOptionValue is positive rule trace - is reported in guess mode. - - The values of [zz]traceOptionValue and [zz]traceGuessOptionValue - can be adjusted by subroutine calls listed below. - - Depending on the presence or absence of the antlr -gd switch - the variable [zz]traceOptionValueDefault is set to 0 or 1. When - the parser is initialized or [zz]traceReset() is called the - value of [zz]traceOptionValueDefault is copied to [zz]traceOptionValue. - The value of [zz]traceGuessOptionValue is always initialzed to 1, - but, as noted earlier, nothing will be reported unless - [zz]traceOptionValue is also positive. - - When the parser state is saved/restored the value of the trace - variables are also saved/restored. If a restore causes a change in - reporting behavior from on to off or vice versa this will be reported. - - When the -gd option is selected, the macro "#define zzTRACE_RULES" - is added to appropriate output files. - - C++ mode - -------- - int traceOption(int delta) - int traceGuessOption(int delta) - void traceReset() - int traceOptionValueDefault - - C mode - -------- - int zzTraceOption(int delta) - int zzTraceGuessOption(int delta) - void zzTraceReset() - int zzTraceOptionValueDefault - - The argument "delta" is added to the traceOptionValue. To - turn on trace when inside a particular rule one: - - rule : <> - ( - rest-of-rule - ) - <> - ; /* fail clause */ <> - - One can use the same idea to turn *off* tracing within a - rule by using a delta of (-1). - - An improvement in the rule trace was suggested by Sramji - Ramanathan (ps@kumaran.com). - -#108. A Note on Deallocation of Variables Allocated in Guess Mode - - NOTE - ------------------------------------------------------ - This mechanism only works for heap allocated variables - ------------------------------------------------------ - - The rewrite of the trace provides the machinery necessary - to properly free variables or undo actions following a - failed guess. - - The macro zzUSER_GUESS_HOOK(guessSeq,zzrv) is expanded - as part of the zzGUESS macro. When a guess is opened - the value of zzrv is 0. When a longjmp() is executed to - undo the guess, the value of zzrv will be 1. - - The macro zzUSER_GUESS_DONE_HOOK(guessSeq) is expanded - as part of the zzGUESS_DONE macro. This is executed - whether the guess succeeds or fails as part of closing - the guess. - - The guessSeq is a sequence number which is assigned to each - guess and is incremented by 1 for each guess which becomes - active. It is needed by the user to associate the start of - a guess with the failure and/or completion (closing) of a - guess. - - Guesses are nested. They must be closed in the reverse - of the order that they are opened. - - In order to free memory used by a variable during a guess - a user must write a routine which can be called to - register the variable along with the current guess sequence - number provided by the zzUSER_GUESS_HOOK macro. If the guess - fails, all variables tagged with the corresponding guess - sequence number should be released. This is ugly, but - it would require a major rewrite of antlr 1.33 to use - some mechanism other than setjmp()/longjmp(). - - The order of calls for a *successful* guess would be: - - zzUSER_GUESS_HOOK(guessSeq,0); - zzUSER_GUESS_DONE_HOOK(guessSeq); - - The order of calls for a *failed* guess would be: - - zzUSER_GUESS_HOOK(guessSeq,0); - zzUSER_GUESS_HOOK(guessSeq,1); - zzUSER_GUESS_DONE_HOOK(guessSeq); - - The default definitions of these macros are empty strings. - - Here is an example in C++ mode. The zzUSER_GUESS_HOOK and - zzUSER_GUESS_DONE_HOOK macros and myGuessHook() routine - can be used without change in both C and C++ versions. - - ---------------------------------------------------------------------- - << - - #include "AToken.h" - - typedef ANTLRCommonToken ANTLRToken; - - #include "DLGLexer.h" - - int main() { - - { - DLGFileInput in(stdin); - DLGLexer lexer(&in,2000); - ANTLRTokenBuffer pipe(&lexer,1); - ANTLRCommonToken aToken; - P parser(&pipe); - - lexer.setToken(&aToken); - parser.init(); - parser.start(); - }; - - fclose(stdin); - fclose(stdout); - return 0; - } - - >> - - << - char *s=NULL; - - #undef zzUSER_GUESS_HOOK - #define zzUSER_GUESS_HOOK(guessSeq,zzrv) myGuessHook(guessSeq,zzrv); - #undef zzUSER_GUESS_DONE_HOOK - #define zzUSER_GUESS_DONE_HOOK(guessSeq) myGuessHook(guessSeq,2); - - void myGuessHook(int guessSeq,int zzrv) { - if (zzrv == 0) { - fprintf(stderr,"User hook: starting guess #%d\n",guessSeq); - } else if (zzrv == 1) { - free (s); - s=NULL; - fprintf(stderr,"User hook: failed guess #%d\n",guessSeq); - } else if (zzrv == 2) { - free (s); - s=NULL; - fprintf(stderr,"User hook: ending guess #%d\n",guessSeq); - }; - } - - >> - - #token A "a" - #token "[\t \ \n]" <> - - class P { - - start : (top)+ - ; - - top : (which) ? <> - | other <> - ; <> - - which : which2 - ; - - which2 : which3 - ; - which3 - : (label)? <> - | (global)? <> - | (exclamation)? <> - ; - - label : <getText());>> A ":" ; - - global : <getText());>> A "::" ; - - exclamation : <getText());>> A "!" ; - - other : <getText());>> "other" ; - - } - ---------------------------------------------------------------------- - - This is a silly example, but illustrates the idea. For the input - "a ::" with tracing enabled the output begins: - - ---------------------------------------------------------------------- - enter rule "start" depth 1 - enter rule "top" depth 2 - User hook: starting guess #1 - enter rule "which" depth 3 guessing - enter rule "which2" depth 4 guessing - enter rule "which3" depth 5 guessing - User hook: starting guess #2 - enter rule "label" depth 6 guessing - guess failed - User hook: failed guess #2 - guess done - returning to rule "which3" at depth 5 (guess mode continues - - an enclosing guess is still active) - User hook: ending guess #2 - User hook: starting guess #3 - enter rule "global" depth 6 guessing - exit rule "global" depth 6 guessing - guess done - returning to rule "which3" at depth 5 (guess mode continues - - an enclosing guess is still active) - User hook: ending guess #3 - enter rule "global" depth 6 guessing - exit rule "global" depth 6 guessing - exit rule "which3" depth 5 guessing - exit rule "which2" depth 4 guessing - exit rule "which" depth 3 guessing - guess done - returning to rule "top" at depth 2 (guess mode ends) - User hook: ending guess #1 - enter rule "which" depth 3 - ..... - ---------------------------------------------------------------------- - - Remember: - - (a) Only init-actions are executed during guess mode. - (b) A rule can be invoked multiple times during guess mode. - (c) If the guess succeeds the rule will be called once more - without guess mode so that normal actions will be executed. - This means that the init-action might need to distinguish - between guess mode and non-guess mode using the variable - [zz]guessing. - -#101. (Changed in 1.33MR10) antlr -info command line switch - - -info - - p - extra predicate information in generated file - - t - information about tnode use: - at the end of each rule in generated file - summary on stderr at end of program - - m - monitor progress - prints name of each rule as it is started - flushes output at start of each rule - - f - first/follow set information to stdout - - 0 - no operation (added in 1.33MR11) - - The options may be combined and may appear in any order. - For example: - - antlr -info ptm -CC -gt -mrhoist on mygrammar.g - -#100a. (Changed in 1.33MR10) Predicate tree simplification - - When the same predicates can be referenced in more than one - alternative of a block large predicate trees can be formed. - - The difference that these optimizations make is so dramatic - that I have decided to use it even when -mrhoist is not selected. - - Consider the following grammar: - - start : ( all )* ; - - all : a - | d - | e - | f - ; - - a : c A B - | c A C - ; - - c : <>? - ; - - d : <>? B C - ; - - e : <>? B C - ; - - f : e X Y - ; - - In rule "a" there is a reference to rule "c" in both alternatives. - The length of the predicate AAA is k=2 and it can be followed in - alternative 1 only by (A B) while in alternative 2 it can be - followed only by (A C). Thus they do not have identical context. - - In rule "all" the alternatives which refer to rules "e" and "f" allow - elimination of the duplicate reference to predicate CCC. - - The table below summarized the kind of simplification performed by - 1.33MR10. In the table, X and Y stand for single predicates - (not trees). - - (OR X (OR Y (OR Z))) => (OR X Y Z) - (AND X (AND Y (AND Z))) => (AND X Y Z) - - (OR X (... (OR X Y) ... )) => (OR X (... Y ... )) - (AND X (... (AND X Y) ... )) => (AND X (... Y ... )) - (OR X (... (AND X Y) ... )) => (OR X (... ... )) - (AND X (... (OR X Y) ... )) => (AND X (... ... )) - - (AND X) => X - (OR X) => X - - In a test with a complex grammar for a real application, a predicate - tree with six OR nodes and 12 leaves was reduced to "(OR X Y Z)". - - In 1.33MR10 there is a greater effort to release memory used - by predicates once they are no longer in use. - -#100b. (Changed in 1.33MR10) Suppression of extra predicate tests - - The following optimizations require that -mrhoist be selected. - - It is relatively easy to optimize the code generated for predicate - gates when they are of the form: - - (AND X Y Z ...) - or (OR X Y Z ...) - - where X, Y, Z, and "..." represent individual predicates (leaves) not - predicate trees. - - If the predicate is an AND the contexts of the X, Y, Z, etc. are - ANDed together to create a single Tree context for the group and - context tests for the individual predicates are suppressed: - - -------------------------------------------------- - Note: This was incorrect. The contexts should be - ORed together. This has been fixed. A more - complete description is available in item #152. - --------------------------------------------------- - - Optimization 1: (AND X Y Z ...) - - Suppose the context for Xtest is LA(1)==LP and the context for - Ytest is LA(1)==LP && LA(2)==ID. - - Without the optimization the code would resemble: - - if (lookaheadContext && - !(LA(1)==LP && LA(1)==LP && LA(2)==ID) || - ( (! LA(1)==LP || Xtest) && - (! (LA(1)==LP || LA(2)==ID) || Xtest) - )) {... - - With the -mrhoist optimization the code would resemble: - - if (lookaheadContext && - ! (LA(1)==LP && LA(2)==ID) || (Xtest && Ytest) {... - - Optimization 2: (OR X Y Z ...) with identical contexts - - Suppose the context for Xtest is LA(1)==ID and for Ytest - the context is also LA(1)==ID. - - Without the optimization the code would resemble: - - if (lookaheadContext && - ! (LA(1)==ID || LA(1)==ID) || - (LA(1)==ID && Xtest) || - (LA(1)==ID && Ytest) {... - - With the -mrhoist optimization the code would resemble: - - if (lookaheadContext && - (! LA(1)==ID) || (Xtest || Ytest) {... - - Optimization 3: (OR X Y Z ...) with distinct contexts - - Suppose the context for Xtest is LA(1)==ID and for Ytest - the context is LA(1)==LP. - - Without the optimization the code would resemble: - - if (lookaheadContext && - ! (LA(1)==ID || LA(1)==LP) || - (LA(1)==ID && Xtest) || - (LA(1)==LP && Ytest) {... - - With the -mrhoist optimization the code would resemble: - - if (lookaheadContext && - (zzpf=0, - (LA(1)==ID && (zzpf=1) && Xtest) || - (LA(1)==LP && (zzpf=1) && Ytest) || - !zzpf) { - - These may appear to be of similar complexity at first, - but the non-optimized version contains two tests of each - context while the optimized version contains only one - such test, as well as eliminating some of the inverted - logic (" !(...) || "). - - Optimization 4: Computation of predicate gate trees - - When generating code for the gates of predicate expressions - antlr 1.33 vanilla uses a recursive procedure to generate - "&&" and "||" expressions for testing the lookahead. As each - layer of the predicate tree is exposed a new set of "&&" and - "||" expressions on the lookahead are generated. In many - cases the lookahead being tested has already been tested. - - With -mrhoist a lookahead tree is computed for the entire - lookahead expression. This means that predicates with identical - context or context which is a subset of another predicate's - context disappear. - - This is especially important for predicates formed by rules - like the following: - - uppperCaseVowel : <>? vowel; - vowel: : <>? LETTERS; - - These predicates are combined using AND since both must be - satisfied for rule upperCaseVowel. They have identical - context which makes this optimization very effective. - - The affect of Items #100a and #100b together can be dramatic. In - a very large (but real world) grammar one particular predicate - expression was reduced from an (unreadable) 50 predicate leaves, - 195 LA(1) terms, and 5500 characters to an (easily comprehensible) - 3 predicate leaves (all different) and a *single* LA(1) term. - -#98. (Changed in 1.33MR10) Option "-info p" - - When the user selects option "-info p" the program will generate - detailed information about predicates. If the user selects - "-mrhoist on" additional detail will be provided explaining - the promotion and suppression of predicates. The output is part - of the generated file and sandwiched between #if 0/#endif statements. - - Consider the following k=1 grammar: - - start : ( all ) * ; - - all : ( a - | b - ) - ; - - a : c B - ; - - c : <>? - | B - ; - - b : <>? X - ; - - Below is an excerpt of the output for rule "start" for the three - predicate options (off, on, and maintenance release style hoisting). - - For those who do not wish to use the "-mrhoist on" option for code - generation the option can be used in a "diagnostic" mode to provide - valuable information: - - a. where one should insert null actions to inhibit hoisting - b. a chain of rule references which shows where predicates are - being hoisted - - ====================================================================== - Example of "-info p" with "-mrhoist on" - ====================================================================== - #if 0 - - Hoisting of predicate suppressed by alternative without predicate. - The alt without the predicate includes all cases where the - predicate is false. - - WITH predicate: line 11 v36.g - WITHOUT predicate: line 12 v36.g - - The context set for the predicate: - - B - - The lookahead set for alt WITHOUT the semantic predicate: - - B - - The predicate: - - pred << LATEXT(1)>>? depth=k=1 rule c line 11 v36.g - - set context: - B - tree context: null - - Chain of referenced rules: - - #0 in rule start (line 1 v36.g) to rule all - #1 in rule all (line 3 v36.g) to rule a - #2 in rule a (line 8 v36.g) to rule c - #3 in rule c (line 11 v36.g) - - #endif - && - #if 0 - - pred << LATEXT(1)>>? depth=k=1 rule b line 15 v36.g - - set context: - X - tree context: null - - #endif - ====================================================================== - Example of "-info p" with the default -prc setting ( "-prc off") - ====================================================================== - #if 0 - - OR - pred << LATEXT(1)>>? depth=k=1 rule c line 11 v36.g - - set context: - nil - tree context: null - - pred << LATEXT(1)>>? depth=k=1 rule b line 15 v36.g - - set context: - nil - tree context: null - - #endif - ====================================================================== - Example of "-info p" with "-prc on" and "-mrhoist off" - ====================================================================== - #if 0 - - OR - pred << LATEXT(1)>>? depth=k=1 rule c line 11 v36.g - - set context: - B - tree context: null - - pred << LATEXT(1)>>? depth=k=1 rule b line 15 v36.g - - set context: - X - tree context: null - - #endif - ====================================================================== - -#60. (Changed in 1.33MR7) Major changes to exception handling - - There were significant problems in the handling of exceptions - in 1.33 vanilla. The general problem is that it can only - process one level of exception handler. For example, a named - exception handler, an exception handler for an alternative, or - an exception for a subrule always went to the rule's exception - handler if there was no "catch" which matched the exception. - - In 1.33MR7 the exception handlers properly "nest". If an - exception handler does not have a matching "catch" then the - nextmost outer exception handler is checked for an appropriate - "catch" clause, and so on until an exception handler with an - appropriate "catch" is found. - - There are still undesirable features in the way exception - handlers are implemented, but I do not have time to fix them - at the moment: - - The exception handlers for alternatives are outside the - block containing the alternative. This makes it impossible - to access variables declared in a block or to resume the - parse by "falling through". The parse can still be easily - resumed in other ways, but not in the most natural fashion. - - This results in an inconsistentcy between named exception - handlers and exception handlers for alternatives. When - an exception handler for an alternative "falls through" - it goes to the nextmost outer handler - not the "normal - action". - - A major difference between 1.33MR7 and 1.33 vanilla is - the default action after an exception is caught: - - 1.33 Vanilla - ------------ - In 1.33 vanilla the signal value is set to zero ("NoSignal") - and the code drops through to the code following the exception. - For named exception handlers this is the "normal action". - For alternative exception handlers this is the rule's handler. - - 1.33MR7 - ------- - In 1.33MR7 the signal value is NOT automatically set to zero. - - There are two cases: - - For named exception handlers: if the signal value has been - set to zero the code drops through to the "normal action". - - For all other cases the code branches to the nextmost outer - exception handler until it reaches the handler for the rule. - - The following macros have been defined for convenience: - - C/C++ Mode Name - -------------------- - (zz)suppressSignal - set signal & return signal arg to 0 ("NoSignal") - (zz)setSignal(intValue) - set signal & return signal arg to some value - (zz)exportSignal - copy the signal value to the return signal arg - - I'm not sure why PCCTS make a distinction between the local - signal value and the return signal argument, but I'm loathe - to change the code. The burden of copying the local signal - value to the return signal argument can be given to the - default signal handler, I suppose. - -#53. (Explanation for 1.33MR6) What happens after an exception is caught ? - - The Book is silent about what happens after an exception - is caught. - - The following code fragment prints "Error Action" followed - by "Normal Action". - - test : Word ex:Number <> - exception[ex] - catch NoViableAlt: - <> - ; - - The reason for "Normal Action" is that the normal flow of the - program after a user-written exception handler is to "drop through". - In the case of an exception handler for a rule this results in - the exection of a "return" statement. In the case of an - exception handler attached to an alternative, rule, or token - this is the code that would have executed had there been no - exception. - - The user can achieve the desired result by using a "return" - statement. - - test : Word ex:Number <> - exception[ex] - catch NoViableAlt: - <> - ; - - The most powerful mechanism for recovery from parse errors - in pccts is syntactic predicates because they provide - backtracking. Exceptions allow "return", "break", - "consumeUntil(...)", "goto _handler", "goto _fail", and - changing the _signal value. - -#41. (Added in 1.33MR6) antlr -stdout - - Using "antlr -stdout ..." forces the text that would - normally go to the grammar.c or grammar.cpp file to - stdout. - -#40. (Added in 1.33MR6) antlr -tab to change tab stops - - Using "antlr -tab number ..." changes the tab stops - for the grammar.c or grammar.cpp file. The number - must be between 0 and 8. Using 0 gives tab characters, - values between 1 and 8 give the appropriate number of - space characters. - -#34. (Added to 1.33MR1) Add public DLGLexerBase::set_line(int newValue) - - Previously there was no public function for changing the line - number maintained by the lexer. - -#28. (Added to 1.33MR1) More control over DLG header - - Version 1.33MR1 adds the following directives to PCCTS - for C++ mode: - - #lexprefix <> - - Adds source code to the DLGLexer.h file - after the #include "DLexerBase.h" but - before the start of the class definition. - - #lexmember <> - - Adds source code to the DLGLexer.h file - as part of the DLGLexer class body. It - appears immediately after the start of - the class and a "public: statement. - diff --git a/Tools/CodeTools/TianoTools/Pccts/KNOWN_PROBLEMS.txt b/Tools/CodeTools/TianoTools/Pccts/KNOWN_PROBLEMS.txt deleted file mode 100644 index 5a9b22e1bd..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/KNOWN_PROBLEMS.txt +++ /dev/null @@ -1,241 +0,0 @@ - - ======================================================= - Known Problems In PCCTS - Last revised 14 November 1998 - ======================================================= - -#17. The dlg fix for handling characters up to 255 is incorrect. - - See item #207. - - Reported by Frank Hartmann. - -#16. A note about "&&" predicates (Mike Dimmick) - - Mike Dimmick has pointed out a potential pitfall in the use of the - "&&" style predicate. Consider: - - r0: (g)? => <

>? r1 - | ... - ; - r1: A | B; - - If the context guard g is not a subset of the lookahead context for r1 - (in other words g is neither A nor B) then the code may execute r1 - even when the lookahead context is not satisfied. This is an error - by the person coding the grammer, and the error should be reported to - the user, but it isn't. expect. Some examples I've run seem to - indicate that such an error actually results in the rule becoming - unreachable. - - When g is properly coded the code is correct, the problem is when g - is not properly coded. - - A second problem reported by Mike Dimmick is that the test for a - failed validation predicate is equivalent to a test on the predicate - along. In other words, if the "&&" has not been hoisted then it may - falsely report a validation error. - -#15. (Changed in MR23) Warning for LT(i), LATEXT(i) in token match actions - - An bug (or at least an oddity) is that a reference to LT(1), LA(1), - or LATEXT(1) in an action which immediately follows a token match - in a rule refers to the token matched, not the token which is in - the lookahead buffer. Consider: - - r : abc <> D <> E; - - In this case LT(1) in action alpha will refer to the next token in - the lookahead buffer ("D"), but LT(1) in action beta will refer to - the token matched by D - the preceding token. - - A warning has been added which warns users about this when an action - following a token match contains a reference to LT(1), LA(1), or LATEXT(1). - - This behavior should be changed, but it appears in too many programs - now. Another problem, perhaps more significant, is that the obvious - fix (moving the consume() call to before the action) could change the - order in which input is requested and output appears in existing programs. - - This problem was reported, along with a fix by Benjamin Mandel - (beny@sd.co.il). However, I felt that changing the behavior was too - dangerous for existing code. - -#14. Parsing bug in dlg - - THM: I have been unable to reproduce this problem. - - Reported by Rick Howard Mijenix Corporation (rickh@mijenix.com). - - The regular expression parser (in rexpr.c) fails while - trying to parse the following regular expression: - - {[a-zA-Z]:}(\\\\[a-zA-Z0-9]*)+ - - See my comment in the following excerpt from rexpr.c: - - /* - * ::= ( '|' {} )* - * - * Return -1 if syntax error - * Return 0 if none found - * Return 1 if a regExrp was found - */ - static - regExpr(g) - GraphPtr g; - { - Graph g1, g2; - - if ( andExpr(&g1) == -1 ) - { - return -1; - } - - while ( token == '|' ) - { - int a; - next(); - a = andExpr(&g2); - if ( a == -1 ) return -1; /* syntax error below */ - else if ( !a ) return 1; /* empty alternative */ - g1 = BuildNFA_AorB(g1, g2); - } - - if ( token!='\0' ) return -1; - ***** - ***** It appears to fail here becuause token is 125 - the closing '}' - ***** If I change it to: - ***** if ( token!='\0' && token!='}' && token!= ')' ) return -1; - ***** - ***** It succeeds, but I'm not sure this is the corrrect approach. - ***** - *g = g1; - return 1; - } - -#13. dlg reports an invalid range for: [\0x00-\0xff] - - Diagnosed by Piotr Eljasiak (eljasiak@no-spam.zt.gdansk.tpsa.pl): - - Fixed in MR16. - -#12. Strings containing comment actions - - Sequences that looked like C style comments appearing in string - literals are improperly parsed by antlr/dlg. - - << fprintf(out," /* obsolete */ "); - - For this case use: - - << fprintf(out," \/\* obsolete \*\/ "); - - Reported by K.J. Cummings (cummings@peritus.com). - -#11. User hook for deallocation of variables on guess fail - - The mechanism outlined in Item #108 works only for - heap allocated variables. - -#10. Label re-initialization in ( X {y:Y} )* - - If a label assignment is optional and appears in a - (...)* or (...)+ block it will not be reset to NULL - when it is skipped by a subsequent iteration. - - Consider the example: - - ( X { y:Y })* Z - - with input: - - X Y X Z - - The first time through the block Y will be matched and - y will be set to point to the token. On the second - iteration of the (...)* block there is no match for Y. - But y will not be reset to NULL, as the user might - expect, it will contain a reference to the Y that was - matched in the first iteration. - - The work-around is to manually reset y: - - ( X << y = NULL; >> { y:Y } )* Z - - or - - ( X ( y:Y | << y = NULL; >> /* epsilon */ ) )* Z - - Reported by Jeff Vincent (JVincent@novell.com). - -#9. PCCTAST.h PCCTSAST::setType() is a noop - -#8. #tokdefs with ~Token and . - - THM: I have been unable to reproduce this problem. - - When antlr uses #tokdefs to define tokens the fields of - #errclass and #tokclass do not get properly defined. - When it subsequently attempts to take the complement of - the set of tokens (using ~Token or .) it can refer to - tokens which don't have names, generating a fatal error. - -#7. DLG crashes on some invalid inputs - - THM: In MR20 have fixed the most common cases. - - The following token defintion will cause DLG to crash. - - #token "()" - - Reported by Mengue Olivier (dolmen@bigfoot.com). - -#6. On MS systems \n\r is treated as two new lines - - Fixed. - -#5. Token expressions in #tokclass - - #errclass does not support TOK1..TOK2 or ~TOK syntax. - #tokclass does not support ~TOKEN syntax - - A workaround for #errclass TOK1..TOK2 is to use a - #tokclass. - - Reported by Dave Watola (dwatola@amtsun.jpl.nasa.gov) - -#4. A #tokdef must appear "early" in the grammar file. - - The "early" section of the grammar file is the only - place where the following directives may appear: - - #header - #first - #tokdefs - #parser - - Any other kind of statement signifiies the end of the - "early" section. - -#3. Use of PURIFY macro for C++ mode - - Item #93 of the CHANGES_FROM_1.33 describes the use of - the PURIFY macro to zero arguments to be passed by - upward inheritance. - - #define PURIFY(r, s) memset((char *) &(r), '\0', (s)); - - This may not be the right thing to do for C++ objects that - have constructors. Reported by Bonny Rais (bonny@werple.net.au). - - For those cases one should #define PURIFY to be an empty macro - in the #header or #first actions. - -#2. Fixed in 1.33MR10 - See CHANGES_FROM_1.33 Item #80. - -#1. The quality of support for systems with 8.3 file names leaves - much to be desired. Since the kit is distributed using the - long file names and the make file uses long file names it requires - some effort to generate. This will probably not be changed due - to the large number of systems already written using the long - file names. diff --git a/Tools/CodeTools/TianoTools/Pccts/MPW_Read_Me b/Tools/CodeTools/TianoTools/Pccts/MPW_Read_Me deleted file mode 100644 index 70a9d1bcad..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/MPW_Read_Me +++ /dev/null @@ -1,21 +0,0 @@ - -1. You can control the creator type of generated files by changing a value of - #if control statement. - - - pccts:h:pcctscfg.h - - line 225-231 - - #if 0 - #define MAC_FILE_CREATOR 'MPS ' /* MPW Text files */ - #endif - #if 0 - #define MAC_FILE_CREATOR 'KAHL' /* THINK C/Symantec C++ Text files */ - #endif - #if 0 - #define MAC_FILE_CREATOR 'CWIE' /* Metrowerks C/C++ Text files */ - #endif - -2. If you want to build 68K version. You must convert all source files to Macintosh - format before compile. diff --git a/Tools/CodeTools/TianoTools/Pccts/NOTES.bcc b/Tools/CodeTools/TianoTools/Pccts/NOTES.bcc deleted file mode 100644 index 1ac05b17c5..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/NOTES.bcc +++ /dev/null @@ -1,184 +0,0 @@ -March 95 -Version 1.32 of pccts - -At the moment this file is available via anonymous FTP at - - Node: marvin.ecn.purdue.edu - File: pub/pccts/1.32/NOTES.BCC - -Mail corrections or additions to David Seidel <71333.1575@compuserve.com> -=============================================================================== -Notes on Building PCCTS 1.32 with Borland C++ - -David Seidel, Innovative Data Concepts Incorporated -CompuServe: 71333,1575 -Internet: 71333.1575@compuserve.com - dseidel@delphi.com - -I have gotten ANTLR and DLG to succesfully build with BCC 4.0, but have found -from experience that ANTLR, in particular, is likely to run out of memory -with grammars over a certain size, or with larger values for the -k and -ck -options. Now that BCC 4.02 and the new Borland Power Pack for DOS is now -available, I feel that there is no excuse not to build these tools as -32-bit executables, as they ought to be. - -For people without the Power Pack, the makefiles below should be fairly easily -modified to build 16-bit real-mode executables, but I don't really recommend -it. As an alternative, you might consider the highly regarded DJGPP compiler -(a DOS port of the Gnu GCC compiler, with a DOS extender included). Hopefully -some other PCCTS who has DJGPP can provode whatever advice is necessary. The -Watcom compiler is also an excellent possibility (albeit a commercial one), -and I hope to make available Watcom makefiles in the near future. - -Here are the makefiles I am using. Both makefiles use a compiler configuration -file that contains compiler switches such as optimization settings. I call -this file bor32.cfg and keep a copy in both the ANTLR and DLG subdirectories. - -==== File: bor32.cfg (cut here) =============================================== --w- --RT- --x- --N- --k- --d --O2-e-l --Z --D__STDC__=1 -==== End of file bor32.cfg (cut here) ========================================= - -==== File: antlr\bor32.mak (cut here) ========================================= -# -# ANTLR 1.32 Makefile for Borland C++ 4.02 with DPMI 32-bit DOS extender by -# David Seidel -# Innovative Data Concepts Incorporated -# 71333.1575@compuserve.com (or) dseidel@delphi.com -# -# Notes: 1. Compiler switches (optimization etc.) are contained in the -# file bor32.cfg. -# 2. This makefile requires Borland C++ 4.02 or greater with -# the DOS Power Pack add-on package. -# 3. Change the BCCDIR macro below to the topmost directory in -# which BCC is installed on your system. -# - -BCCDIR = d:\bc4 -CC = bcc32 -SET = ..\support\set -PCCTS_H = ..\h -ANTLR = ..\bin\antlr -DLG = ..\bin\dlg -CFLAGS = -I$(BCCDIR)\include -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN \ - +bor32.cfg -LIBS = dpmi32 cw32 -OBJ_EXT = obj -OBJS = antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj fset.obj \ - gen.obj globals.obj hash.obj lex.obj main.obj misc.obj pred.obj dialog.obj \ - set.obj - -.c.obj: - $(CC) -c $(CFLAGS) {$&.c } - -antlr.exe: $(OBJS) - tlink32 @&&| --Tpe -ax -c -s -L$(BCCDIR)\lib + -$(BCCDIR)\lib\c0x32 $** -$@ - -$(LIBS) -; -| - copy *.exe ..\bin - - -# *********** Target list of PC machines *********** -# -# Don't worry about the ambiguity messages coming from antlr -# for making antlr.c etc... [should be 10 of them, I think] -# - -# leave this commented out for initial build! -#antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g -# $(ANTLR) antlr.g - -antlr.$(OBJ_EXT): antlr.c mode.h tokens.h - -scan.$(OBJ_EXT): scan.c mode.h tokens.h - -# leave this commented out for initial build! -#scan.c mode.h: parser.dlg -# $(DLG) -C2 parser.dlg scan.c - -set.$(OBJ_EXT): $(SET)\set.c - $(CC) -c $(CFLAGS) $(SET)\set.c - -==== End of file antlr\bor32.mak (cut here) =================================== - -==== File: dlg\bor32.mak (cut here) =========================================== -# -# DLG 1.32 Makefile for Borland C++ 4.02 with DPMI 32-bit DOS extender by -# David Seidel -# Innovative Data Concepts Incorporated -# 71333.1575@compuserve.com (or) dseidel@delphi.com -# -# Notes: 1. Compiler switches (optimization etc.) are contained in the -# file bor32.cfg. -# 2. This makefile requires Borland C++ 4.02 or greater with -# the DOS Power Pack add-on package. -# 3. Change the BCCDIR macro below to the topmost directory in -# which BCC is installed on your system. -# - - -BCCDIR = d:\bc4 -CC = bcc32 -SET = ..\support\set -PCCTS_H = ..\h -ANTLR = ..\bin\antlr -DLG = ..\bin\dlg -CFLAGS = -I$(BCCDIR)\include -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN \ - +bor32.cfg -LIBS = dpmi32 cw32 -OBJ_EXT = obj -OBJS = dlg_p.obj dlg_a.obj main.obj err.obj support.obj \ - output.obj relabel.obj automata.obj set.obj - -.c.obj: - $(CC) -c $(CFLAGS) {$&.c } - -dlg.exe : $(OBJS) - tlink32 @&&| --Tpe -ax -c -s -L$(BCCDIR)\lib + -c0x32 $** -$@ - -$(LIBS) -; -| - copy *.exe ..\bin - -dlg_p.obj: dlg_p.c - -dlg_a.obj: dlg_a.c - -main.obj: main.c - -err.obj: err.c - -support.obj: support.c - -output.obj: output.c - -relabel.obj: relabel.c - -automata.obj: automata.c - -set.$(OBJ_EXT): $(SET)\set.c - $(CC) -c $(CFLAGS) $(SET)\set.c - -==== End of file dlg\bor32.mak (cut here) ===================================== - - - - - - diff --git a/Tools/CodeTools/TianoTools/Pccts/NOTES.msvc b/Tools/CodeTools/TianoTools/Pccts/NOTES.msvc deleted file mode 100644 index 86f8ed66e0..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/NOTES.msvc +++ /dev/null @@ -1,189 +0,0 @@ - - Microsoft Visual C Stuff - - -[Tom Moog 2-Oct-98 - - Users of Microsoft Visual C++ should download a separate - ready-to-run zip file from my web site. It contains - binaries, static library, and a sample project. -] - -[ - Two notes added by Tom Moog 23-Sep-97. I believe the *.dsp and - *.mak files that were once at the end of this file are now obsolete. - - The following MSVC .dsp and .mak files for pccts and sorcerer - were contributed by Stanislaw Bochnak (S.Bochnak@microtool.com.pl) - and Jeff Vincent (jvincent@novell.com) - - PCCTS Distribution Kit - ---------------------- - pccts/antlr/AntlrMSVC50.dsp - pccts/antlr/AntlrMSVC50.mak - - pccts/dlg/DlgMSVC50.dsp - pccts/dlg/DlgMSVC50.mak - - pccts/support/genmk/watgenmk.mak - pccts/support/msvc.dsp - - Sorcerer Distribution Kit - ------------------------- - pccts/sorcerer/SorcererMSVC50.dsp - pccts/sorcerer/SorcererMSVC50.mak - - pccts/sorcerer/lib/msvc.dsp - - I do not have an MS based computer. If you discover problems - please report them so as to save trouble for others in the future. -] - -[ - Modified by Terence Parr (September 1995) to change .C to .cpp -] - -[ - This file contains notes on MSVC for Windows NT console execs by Dave - Seidel and an explanation of flags etc.. by John Hall; good luck, - Terence -] - -=============================================================================== -Date: Sat, 31 Dec 1994 11:40:36 -0500 (EST) -From: David Seidel <75342.2034@compuserve.com> - -I've succesfully build 1.31b3 with djgpp for DOS and MSVC 2.0 for Windows -NT. The only (minor) problem I had was that GNU make (version 3.71, in the -djgpp port) complained about "multiple targets" in both the antlr and dlg -makefiles. I got around the error by, in each makefile, commenting out the -$(SRC) dependency, for example: - - antlr: $(OBJ) #$(SRC) - -I don't know why this is happenning, since you haven't changed that part of -the makefile at all, and I think this used to work ok... - -Here are the makefiles I built from within the MSVC 2.0 environment for antlr -and dlg and Windows NT console executables. Please feel free to pass them -on. Of course, as soon as 1.31 "goes gold", I will send you nice new -binaries. I'm not going to bother to keep doing both Borland and djgpp for -DOS however. Instead, I'll just keep the djgpp version up to date and also -provide WinNT binaries. - -Dave -=============================================================================== - - How to port PCCTS 1.10 (and 1.32 hopefully) to Visual C++ - - By - - John Hall - -Here is how to compile an ANTLR grammar in Visual C++. These steps -describe how to have your ANTLR grammar parse the input file the user -selects when they choose File Open in your Windows application. (Even -if you aren't using Visual C++, the steps should be portable enough to -other compilers.) - - * Make sure that ANTLR and DLG generate ANSI code (use the -ga - switch). - - * Set the following compiler flags in Visual C++ (these are in the - Memory Model category of the compiler options in the Project - Options menu): - - FLAG MEANING - ==== ============================================================== - /AL Large memory model (multiple data segments; data items must be - smaller than 64K). - - /Gtn Allocates all items whose size is greater than or equal to n - in a new data segment. (I let n be 256: /Gt256.) - - /Gx- All references to data items are done with far addressing in - case they are placed in a far segment. - - * Add the following member variable to the attributes section of your - derived CDocument class (you will need to make sure you also - include stdio.h): - - FILE *fp; - - * Add the following method to your derived CDocument class: - - BOOL CAppDoc::OnOpenDocument(const char* pszPathName) - { - // Call CDocument's OnOpenDocument to do housekeeping for us - // DON'T add anything to the loading section of Serialize - if (!CDocument::OnOpenDocument(pszPathName)) - return FALSE; - - // Open input file - if ((fp = fopen(pszPathName, "r")) == NULL) - return FALSE; - - // Parse input file - ANTLR(start(), fp); - - // Close input file - fclose(fp); - return TRUE; - } - - (Note: additional code may be necessary, depending on your parser. - For example, if your parser uses PCCTS's symbol table library, you - will need to insert calls to zzs_init and zzs_done.) - - * Compile the generated C files as C++ files. (I renamed the files - to have a .CPP extension to fool Visual C++ into thinking they were - C++ files. One might also use the /Tp switch, but that switch - requires you separately include the filename.) [I used this step - as an easy out for all the external linking errors I was getting - that I couldn't fix by declaring things extern "C".] - - * Make sure the __STDC__ portion of the generated files gets - compiled. (Either define __STDC__ yourself or else change all - occurrences of __STDC__ to __cplusplus in the generated files. You - can define __STDC__ in the Preprocessor category of the compiler - options.) - - ================================================================ - = Note 23-Sep-97: This is probably not necessary any more. = - = With 1.33MRxxx the use of __STDC__ was replaced with the = - = macro __USE_PROTOS to control the compilation of prototypes. = - ================================================================ - -That last step is important for Visual C++, but may not apply to other -compilers. For C++ compilers, whether __STDC__ is defined is -implementation dependent (ARM, page 379). Apparently, Visual C++ does -not to define it; it also does not support "old style" C function -definitions (which is okay, according to page 404 of the ARM). Those -two things together caused problems when trying to port the code. -When it saw this: - -#ifdef __STDC__ -void -globals(AST **_root) -#else -globals(_root) -AST **_root; -#endif - -it skipped the __STDC__ section and tried to process the "old style" -function definition, where it choked. - -When you finally get your parser to compile and link without error, -you may get General Protection Fault errors at run time. The problem -I had was that a NULL was passed to a variable argument function -without an explicit cast. The function grabbed a pointer (32-bits) -off the stack using va_arg, but the NULL was passed silently as the -integer 0 (16 bits), making the resulting pointer was invalid. (This -was in PCCTS's sample C parser.) - -There is one other thing I might suggest to help you avoid a run-time -error. Make sure you redefine the default error reporting function, -zzsyn. To do this, put "#define USER_ZZSYN" in your #header section -and put your own zzsyn somewhere. You can then pop up a MessageBox or -print the error to some output window. -=============================================================================== diff --git a/Tools/CodeTools/TianoTools/Pccts/README b/Tools/CodeTools/TianoTools/Pccts/README deleted file mode 100644 index d089b638b4..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/README +++ /dev/null @@ -1,159 +0,0 @@ - - Parr Research Corporation - with - Purdue University Electrical Engineering - and - University of Minnesota, AHPCRC - - Terence Parr - Russell Quong - Will Cohen - Hank Dietz - - -A central place for information about PCCTS 1.33 is: - - http://www.polhode.com/pccts.html - -The maintenance release is available from: - - http://www.polhode.com/pccts133mr.zip - -There is a ready-to-run version for win32 for Microsoft Visual Studio -at the same site. It is available from: - - http://www.polhode.com/win32.zip - -New users should visit http://www.polhode.com/pccts.html in -order to get the following document: - - "Notes For New Users of PCCTS" - -This is a Postscript file of about 40 pages which is extremely -useful for someone starting out. It is a based on 1.33mr21 - -When you have a little more experience, be sure to review the -following documents in the distribution kit: - - CHANGES_FROM_133.txt - CHANGES_FROM_133_BEFORE_MR13.txt - KNOWN_PROBLEMS.txt - -------------------------------------------------------------------------- - INSTALLATION (Unix) -------------------------------------------------------------------------- -0. Download http://www.polhode.com/pccts133mr.zip - -1. Unzip the distribution kit to your preferred location. - If there are newline problems try using zip -a ... - -2. cd to the main pccts directory. - -3. make - - This will create: - - antlr - dlg - sorcerer - genmk - -4. Copy to /usr/local/bin or /usr/local/bin if you like. If you - don't wish to then add pccts/bin to your path. - -5. To get an up-to-date list of program options execute the - program with no command line options. To get up-to-date - documentation read CHANGES_FROM_133*.txt and KNOWN_PROBLEMS.txt - at: - - http://www.polhode.com/pccts.html - -6. You need not create a library. The makefile created by genmk - assumes that the files are not part of a library. - - If you wish to create a library from elements of pccts/h: - - If the first letter of the filename is lowercase (uppercase) it is - related to the code generated using the pccts C mode (C++ mode). - Some of the .c and .cpp files in the h directory are not meant to - be placed in a library and will not compile because they are meant - to be #include in pccts generated files which are grammar specific. - - For C++ users place the following elements in the library: - - AParser.cpp - ASTBase.cpp - ATokenBuffer.cpp - BufFileInput.cpp (optional) - DLexerBase.cpp - PCCTSAST.cpp - SList.cpp - -------------------------------------------------------------------------- - INSTALLATION (Win32) -------------------------------------------------------------------------- - -I've tried to keep the win32 kit to the minimum necessary to get -up and running. The complete kit contains additional information -(some historical), source code, and DevStudio projects for -rebuilding pccts from the source code. - -The kit is now distributed with both MSVC 5 and MSVC6 style projects. - -0. Download http://www.polhode.com/win32.zip. - - You may also wish to download: - - http://www.polhode.com/CHANGES_FROM_133.txt - http://www.polhode.com/CHANGES_FROM_133_BEFORE_MR13.txt - http://www.polhode.com/KNOWN_PROBLEMS.txt - -1. Unzip the distribution kit to your preferred location. - - This will create: - - a pccts directory tree - pccts/bin/*.exe - pccts/lib/*.lib - pccts/h/* - sorcerer/lib/* - sorcerer/h/* - - an example directory tree - pccts\example\calcAST\* - pccts\example\simple\* - -2. Define the environment variable PCCTS to point to the main - pccts directory. - -3. Try building the simple project: pccts\example\simple\simple50.dsw - or simple60.dsw. - -4. Try building the complex project: pccts\example\calcAST\calcAST50.dsw - or calcAST60.dsw. - -------------------------------------------------------------------------- - INSTALLATION (DEC/VMS) -------------------------------------------------------------------------- - -DEC/VMS support added by Piéronne Jean-François (jfp@altavista.net) - -0. Download http://www.polhode.com/pccts133mr.zip - -1. Unzip the distribution kit to your preferred location. - -2. set default to the main pccts directory. - -3. @makefile.vms - - This will create in directory [.bin]: - - antlr.exe - dlg.exe - sorcerer.exe - genmk.exe - -5. To get an up-to-date list of program options execute the - program with no command line options. To get up-to-date - documentation read CHANGES_FROM_133*.txt and KNOWN_PROBLEMS.txt - at http://www.polhode.com/pccts.html. diff --git a/Tools/CodeTools/TianoTools/Pccts/RIGHTS b/Tools/CodeTools/TianoTools/Pccts/RIGHTS deleted file mode 100644 index 9db175ff40..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/RIGHTS +++ /dev/null @@ -1,26 +0,0 @@ - -SOFTWARE RIGHTS - -We reserve no LEGAL rights to the Purdue Compiler Construction Tool -Set (PCCTS) -- PCCTS is in the public domain. An individual or -company may do whatever they wish with source code distributed with -PCCTS or the code generated by PCCTS, including the incorporation of -PCCTS, or its output, into commerical software. - -We encourage users to develop software with PCCTS. However, we do ask -that credit is given to us for developing PCCTS. By "credit", we mean -that if you incorporate our source code into one of your programs -(commercial product, research project, or otherwise) that you -acknowledge this fact somewhere in the documentation, research report, -etc... If you like PCCTS and have developed a nice tool with the -output, please mention that you developed it using PCCTS. In -addition, we ask that this header remain intact in our source code. -As long as these guidelines are kept, we expect to continue enhancing -this system and expect to make other tools available as they are -completed. - -ANTLR 1.33 -Terence Parr -Parr Research Corporation -with Purdue University and AHPCRC, University of Minnesota -1989-1995 diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/AntlrMS.mak b/Tools/CodeTools/TianoTools/Pccts/antlr/AntlrMS.mak deleted file mode 100644 index 7c14993ee0..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/AntlrMS.mak +++ /dev/null @@ -1,233 +0,0 @@ -# PCCTS directory - -# You will need to set the LIB variable similar to this. -# LIB="C:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/lib;c:/Microsoft Visual Studio .NET 2003/Vc7/PlatformSDK/Lib" - -# PCCTS_HOME= -PCCTS_HOME=$(WORKSPACE)\Tools\Source\TianoTools\Pccts -ANTLR_SRC=$(PCCTS_HOME)\antlr -PCCTS_H=$(PCCTS_HOME)\h - - -# Support directories -SET=$(PCCTS_HOME)\support\set - - -# Compiler stuff -CC = cl -CFLAGS = /nologo -I "." -I "$(PCCTS_H)" -I "$(SET)" -D "USER_ZZSYN" -D "PC" \ - -D "ZZLEXBUFSIZE=65536" /D "LONGFILENAMES" /Zi /W3 -D__USE_PROTOS /wd4700 - -ANTLR_OBJS = antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \ - fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \ - misc.obj pred.obj egman.obj mrhoist.obj fcache.obj - -SUPPORT_OBJS = set.obj - -# Dependencies - -$(WORKSPACE)\Tools\bin\antlr.exe: $(ANTLR_OBJS) $(SUPPORT_OBJS) - $(CC) $(CFLAGS) -o antlr.exe $(ANTLR_OBJS) $(SUPPORT_OBJS) - del *.obj - move antlr.exe $(WORKSPACE)\Tools\bin - - -antlr.obj: $(ANTLR_SRC)\antlr.c \ - $(PCCTS_H)\antlr.h \ - $(PCCTS_H)\config.h \ - $(PCCTS_H)\dlgdef.h \ - $(SET)\set.h \ - $(ANTLR_SRC)\generic.h \ - $(ANTLR_SRC)\hash.h \ - $(ANTLR_SRC)\mode.h \ - $(ANTLR_SRC)\proto.h \ - $(ANTLR_SRC)\syn.h \ - $(ANTLR_SRC)\tokens.h \ - - $(CC) -c $(CFLAGS) $(ANTLR_SRC)\antlr.c - -scan.obj: $(ANTLR_SRC)\scan.c \ - $(PCCTS_H)\antlr.h \ - $(PCCTS_H)\config.h \ - $(PCCTS_H)\dlgauto.h \ - $(PCCTS_H)\dlgdef.h \ - $(SET)\set.h \ - $(ANTLR_SRC)\generic.h \ - $(ANTLR_SRC)\hash.h \ - $(ANTLR_SRC)\mode.h \ - $(ANTLR_SRC)\proto.h \ - $(ANTLR_SRC)\syn.h \ - $(ANTLR_SRC)\tokens.h \ - - $(CC) -c $(CFLAGS) $(ANTLR_SRC)\scan.c - -err.obj: $(ANTLR_SRC)\err.c \ - $(PCCTS_H)\antlr.h \ - $(PCCTS_H)\config.h \ - $(PCCTS_H)\dlgdef.h \ - $(PCCTS_H)\err.h \ - $(SET)\set.h \ - $(ANTLR_SRC)\generic.h \ - $(ANTLR_SRC)\hash.h \ - $(ANTLR_SRC)\proto.h \ - $(ANTLR_SRC)\syn.h \ - $(ANTLR_SRC)\tokens.h \ - - $(CC) -c $(CFLAGS) $(ANTLR_SRC)\err.c - -bits.obj: $(ANTLR_SRC)\bits.c \ - $(PCCTS_H)\config.h \ - $(PCCTS_H)\dlgdef.h \ - $(SET)\set.h \ - $(ANTLR_SRC)\generic.h \ - $(ANTLR_SRC)\hash.h \ - $(ANTLR_SRC)\proto.h \ - $(ANTLR_SRC)\syn.h \ - - $(CC) -c $(CFLAGS) $(ANTLR_SRC)\bits.c - -build.obj: $(ANTLR_SRC)\build.c \ - $(PCCTS_H)\config.h \ - $(PCCTS_H)\dlgdef.h \ - $(SET)\set.h \ - $(ANTLR_SRC)\generic.h \ - $(ANTLR_SRC)\hash.h \ - $(ANTLR_SRC)\proto.h \ - $(ANTLR_SRC)\syn.h \ - - $(CC) -c $(CFLAGS) $(ANTLR_SRC)\build.c - -fset2.obj: $(ANTLR_SRC)\fset2.c \ - $(PCCTS_H)\config.h \ - $(PCCTS_H)\dlgdef.h \ - $(SET)\set.h \ - $(ANTLR_SRC)\generic.h \ - $(ANTLR_SRC)\hash.h \ - $(ANTLR_SRC)\proto.h \ - $(ANTLR_SRC)\syn.h \ - - $(CC) -c $(CFLAGS) $(ANTLR_SRC)\fset2.c - -fset.obj: $(ANTLR_SRC)\fset.c \ - $(PCCTS_H)\config.h \ - $(PCCTS_H)\dlgdef.h \ - $(SET)\set.h \ - $(ANTLR_SRC)\generic.h \ - $(ANTLR_SRC)\hash.h \ - $(ANTLR_SRC)\proto.h \ - $(ANTLR_SRC)\syn.h \ - - $(CC) -c $(CFLAGS) $(ANTLR_SRC)\fset.c - -gen.obj: $(ANTLR_SRC)\gen.c \ - $(PCCTS_H)\config.h \ - $(PCCTS_H)\dlgdef.h \ - $(SET)\set.h \ - $(ANTLR_SRC)\generic.h \ - $(ANTLR_SRC)\hash.h \ - $(ANTLR_SRC)\proto.h \ - $(ANTLR_SRC)\syn.h \ - - $(CC) -c $(CFLAGS) $(ANTLR_SRC)\gen.c - -globals.obj: $(ANTLR_SRC)\globals.c \ - $(PCCTS_H)\config.h \ - $(SET)\set.h \ - $(ANTLR_SRC)\generic.h \ - $(ANTLR_SRC)\hash.h \ - $(ANTLR_SRC)\proto.h \ - $(ANTLR_SRC)\syn.h \ - - $(CC) -c $(CFLAGS) $(ANTLR_SRC)\globals.c - -hash.obj: $(ANTLR_SRC)\hash.c \ - $(PCCTS_H)\config.h \ - $(ANTLR_SRC)\hash.h \ - - $(CC) -c $(CFLAGS) $(ANTLR_SRC)\hash.c - -lex.obj: $(ANTLR_SRC)\lex.c \ - $(PCCTS_H)\config.h \ - $(SET)\set.h \ - $(ANTLR_SRC)\generic.h \ - $(ANTLR_SRC)\hash.h \ - $(ANTLR_SRC)\proto.h \ - $(ANTLR_SRC)\syn.h \ - - $(CC) -c $(CFLAGS) $(ANTLR_SRC)\lex.c - -main.obj: $(ANTLR_SRC)\main.c \ - $(PCCTS_H)\antlr.h \ - $(PCCTS_H)\config.h \ - $(PCCTS_H)\dlgdef.h \ - $(SET)\set.h \ - $(ANTLR_SRC)\generic.h \ - $(ANTLR_SRC)\hash.h \ - $(ANTLR_SRC)\mode.h \ - $(ANTLR_SRC)\proto.h \ - $(ANTLR_SRC)\stdpccts.h \ - $(ANTLR_SRC)\syn.h \ - $(ANTLR_SRC)\tokens.h \ - - $(CC) -c $(CFLAGS) $(ANTLR_SRC)\main.c - -misc.obj: $(ANTLR_SRC)\misc.c \ - $(PCCTS_H)\config.h \ - $(PCCTS_H)\dlgdef.h \ - $(SET)\set.h \ - $(ANTLR_SRC)\generic.h \ - $(ANTLR_SRC)\hash.h \ - $(ANTLR_SRC)\proto.h \ - $(ANTLR_SRC)\syn.h \ - - $(CC) -c $(CFLAGS) $(ANTLR_SRC)\misc.c - -pred.obj: $(ANTLR_SRC)\pred.c \ - $(PCCTS_H)\config.h \ - $(PCCTS_H)\dlgdef.h \ - $(SET)\set.h \ - $(ANTLR_SRC)\generic.h \ - $(ANTLR_SRC)\hash.h \ - $(ANTLR_SRC)\proto.h \ - $(ANTLR_SRC)\syn.h \ - - $(CC) -c $(CFLAGS) $(ANTLR_SRC)\pred.c - -egman.obj: $(ANTLR_SRC)\egman.c \ - $(PCCTS_H)\config.h \ - $(SET)\set.h \ - $(ANTLR_SRC)\generic.h \ - $(ANTLR_SRC)\hash.h \ - $(ANTLR_SRC)\proto.h \ - $(ANTLR_SRC)\syn.h \ - - $(CC) -c $(CFLAGS) $(ANTLR_SRC)\egman.c - -mrhoist.obj: $(ANTLR_SRC)\mrhoist.c \ - $(ANTLR_SRC)\generic.h \ - $(ANTLR_SRC)\hash.h \ - $(ANTLR_SRC)\proto.h \ - $(ANTLR_SRC)\syn.h \ - - $(CC) -c $(CFLAGS) $(ANTLR_SRC)\mrhoist.c - -fcache.obj: $(ANTLR_SRC)\fcache.c \ - $(ANTLR_SRC)\generic.h \ - $(ANTLR_SRC)\hash.h \ - $(ANTLR_SRC)\proto.h \ - $(ANTLR_SRC)\syn.h \ - - $(CC) -c $(CFLAGS) $(ANTLR_SRC)\fcache.c - -set.obj: $(SET)\set.c \ - $(PCCTS_H)\config.h \ - $(SET)\set.h \ - - $(CC) -c $(CFLAGS) $(SET)\set.c - -clean: - del *.obj - -distclean: - del *.obj - del $(WORKSPACE)\Tools\bin\antlr.exe diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/AntlrPPC.mak b/Tools/CodeTools/TianoTools/Pccts/antlr/AntlrPPC.mak deleted file mode 100644 index 9ede60d64c..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/AntlrPPC.mak +++ /dev/null @@ -1,101 +0,0 @@ -# Target: antlrPPC -# Sources: ::support:set:set.c -# antlr.c -# bits.c -# build.c -# egman.c -# err.c -# fcache.c -# fset2.c -# fset.c -# gen.c -# globals.c -# hash.c -# lex.c -# main.c -# misc.c -# mrhoist.c -# pred.c -# scan.c -# Created: Sunday, May 17, 1998 10:24:53 PM -# Author: Kenji Tanaka -MAKEFILE = antlrPPC.make -¥MondoBuild¥ = {MAKEFILE} # Make blank to avoid rebuilds when makefile is modified -Includes = ¶ - -i "::h:" ¶ - -i "::support:set:" -Sym¥PPC = -ObjDir¥PPC = :Obj: -PPCCOptions = {Includes} {Sym¥PPC} -w off -d MPW -d __STDC__=1 -d USER_ZZSYN -Objects¥PPC = ¶ - "{ObjDir¥PPC}set.c.x" ¶ - "{ObjDir¥PPC}antlr.c.x" ¶ - "{ObjDir¥PPC}bits.c.x" ¶ - "{ObjDir¥PPC}build.c.x" ¶ - "{ObjDir¥PPC}egman.c.x" ¶ - "{ObjDir¥PPC}err.c.x" ¶ - "{ObjDir¥PPC}fcache.c.x" ¶ - "{ObjDir¥PPC}fset2.c.x" ¶ - "{ObjDir¥PPC}fset.c.x" ¶ - "{ObjDir¥PPC}gen.c.x" ¶ - "{ObjDir¥PPC}globals.c.x" ¶ - "{ObjDir¥PPC}hash.c.x" ¶ - "{ObjDir¥PPC}lex.c.x" ¶ - "{ObjDir¥PPC}main.c.x" ¶ - "{ObjDir¥PPC}misc.c.x" ¶ - "{ObjDir¥PPC}mrhoist.c.x" ¶ - "{ObjDir¥PPC}pred.c.x" ¶ - "{ObjDir¥PPC}scan.c.x" -antlrPPC ÄÄ {¥MondoBuild¥} {Objects¥PPC} - PPCLink ¶ - -o {Targ} {Sym¥PPC} ¶ - {Objects¥PPC} ¶ - -t 'MPST' ¶ - -c 'MPS ' ¶ - "{SharedLibraries}InterfaceLib" ¶ - "{SharedLibraries}StdCLib" ¶ - #"{SharedLibraries}MathLib" ¶ - "{PPCLibraries}StdCRuntime.o" ¶ - "{PPCLibraries}PPCCRuntime.o" ¶ - "{PPCLibraries}PPCToolLibs.o" -"{ObjDir¥PPC}set.c.x" Ä {¥MondoBuild¥} "::support:set:set.c" - {PPCC} "::support:set:set.c" -o {Targ} {PPCCOptions} -"{ObjDir¥PPC}antlr.c.x" Ä {¥MondoBuild¥} antlr.c - {PPCC} antlr.c -o {Targ} {PPCCOptions} -"{ObjDir¥PPC}bits.c.x" Ä {¥MondoBuild¥} bits.c - {PPCC} bits.c -o {Targ} {PPCCOptions} -"{ObjDir¥PPC}build.c.x" Ä {¥MondoBuild¥} build.c - {PPCC} build.c -o {Targ} {PPCCOptions} -"{ObjDir¥PPC}egman.c.x" Ä {¥MondoBuild¥} egman.c - {PPCC} egman.c -o {Targ} {PPCCOptions} -"{ObjDir¥PPC}err.c.x" Ä {¥MondoBuild¥} err.c - {PPCC} err.c -o {Targ} {PPCCOptions} -"{ObjDir¥PPC}fcache.c.x" Ä {¥MondoBuild¥} fcache.c - {PPCC} fcache.c -o {Targ} {PPCCOptions} -"{ObjDir¥PPC}fset2.c.x" Ä {¥MondoBuild¥} fset2.c - {PPCC} fset2.c -o {Targ} {PPCCOptions} -"{ObjDir¥PPC}fset.c.x" Ä {¥MondoBuild¥} fset.c - {PPCC} fset.c -o {Targ} {PPCCOptions} -"{ObjDir¥PPC}gen.c.x" Ä {¥MondoBuild¥} gen.c - {PPCC} gen.c -o {Targ} {PPCCOptions} -"{ObjDir¥PPC}globals.c.x" Ä {¥MondoBuild¥} globals.c - {PPCC} globals.c -o {Targ} {PPCCOptions} -"{ObjDir¥PPC}hash.c.x" Ä {¥MondoBuild¥} hash.c - {PPCC} hash.c -o {Targ} {PPCCOptions} -"{ObjDir¥PPC}lex.c.x" Ä {¥MondoBuild¥} lex.c - {PPCC} lex.c -o {Targ} {PPCCOptions} -"{ObjDir¥PPC}main.c.x" Ä {¥MondoBuild¥} main.c - {PPCC} main.c -o {Targ} {PPCCOptions} -"{ObjDir¥PPC}misc.c.x" Ä {¥MondoBuild¥} misc.c - {PPCC} misc.c -o {Targ} {PPCCOptions} -"{ObjDir¥PPC}mrhoist.c.x" Ä {¥MondoBuild¥} mrhoist.c - {PPCC} mrhoist.c -o {Targ} {PPCCOptions} -"{ObjDir¥PPC}pred.c.x" Ä {¥MondoBuild¥} pred.c - {PPCC} pred.c -o {Targ} {PPCCOptions} -"{ObjDir¥PPC}scan.c.x" Ä {¥MondoBuild¥} scan.c - {PPCC} scan.c -o {Targ} {PPCCOptions} - -antlrPPC ÄÄ antlr.r - Rez antlr.r -o antlrPPC -a -Install Ä antlrPPC - Duplicate -y antlrPPC "{MPW}"Tools:antlr diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/README b/Tools/CodeTools/TianoTools/Pccts/antlr/README deleted file mode 100644 index d7fc95916e..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/README +++ /dev/null @@ -1,19 +0,0 @@ - ANTLR 1.33 - -This directory contains the files necessary to build ANTLR. - -If you do a "make scrub", ANTLR will have to run on antlr.g and DLG -will have to run on parser.dlg. Either - -(1) ANTLR uses the previous antlr in that directory to rebuild itself -(2) Needs to find antlr on the search path - -You will find that running "antlr -gh antlr.g" will result in about -10 ambiguity warnings. These are normal. Don't worry. - -If you do a "make clean" right after installation, ANTLR and DLG should -not need to run; only the C files will compile. - -Don't forget to go into the makefile to uncomment the appropriate -definitions for your OS/architecture/compiler or see the appropriate -NOTES.?? file. diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/antlr.1 b/Tools/CodeTools/TianoTools/Pccts/antlr/antlr.1 deleted file mode 100644 index acfa85b066..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/antlr.1 +++ /dev/null @@ -1,209 +0,0 @@ -.TH ANTLR 1 "September 1995" "ANTLR" "PCCTS Manual Pages" -.SH NAME -antlr \- ANother Tool for Language Recognition -.SH SYNTAX -.LP -\fBantlr\fR [\fIoptions\fR] \fIgrammar_files\fR -.SH DESCRIPTION -.PP -\fIAntlr\fP converts an extended form of context-free grammar into a -set of C functions which directly implement an efficient form of -deterministic recursive-descent LL(k) parser. Context-free grammars -may be augmented with predicates to allow semantics to influence -parsing; this allows a form of context-sensitive parsing. Selective -backtracking is also available to handle non-LL(k) and even -non-LALR(k) constructs. \fIAntlr\fP also produces a definition of a -lexer which can be automatically converted into C code for a DFA-based -lexer by \fIdlg\fR. Hence, \fIantlr\fR serves a function much like -that of \fIyacc\fR, however, it is notably more flexible and is more -integrated with a lexer generator (\fIantlr\fR directly generates -\fIdlg\fR code, whereas \fIyacc\fR and \fIlex\fR are given independent -descriptions). Unlike \fIyacc\fR which accepts LALR(1) grammars, -\fIantlr\fR accepts LL(k) grammars in an extended BNF notation \(em -which eliminates the need for precedence rules. -.PP -Like \fIyacc\fR grammars, \fIantlr\fR grammars can use -automatically-maintained symbol attribute values referenced as dollar -variables. Further, because \fIantlr\fR generates top-down parsers, -arbitrary values may be inherited from parent rules (passed like -function parameters). \fIAntlr\fP also has a mechanism for creating -and manipulating abstract-syntax-trees. -.PP -There are various other niceties in \fIantlr\fR, including the ability to -spread one grammar over multiple files or even multiple grammars in a single -file, the ability to generate a version of the grammar with actions stripped -out (for documentation purposes), and lots more. -.SH OPTIONS -.IP "\fB-ck \fIn\fR" -Use up to \fIn\fR symbols of lookahead when using compressed (linear -approximation) lookahead. This type of lookahead is very cheap to -compute and is attempted before full LL(k) lookahead, which is of -exponential complexity in the worst case. In general, the compressed -lookahead can be much deeper (e.g, \f(CW-ck 10\fP) than the full -lookahead (which usually must be less than 4). -.IP \fB-CC\fP -Generate C++ output from both ANTLR and DLG. -.IP \fB-cr\fP -Generate a cross-reference for all rules. For each rule, print a list -of all other rules that reference it. -.IP \fB-e1\fP -Ambiguities/errors shown in low detail (default). -.IP \fB-e2\fP -Ambiguities/errors shown in more detail. -.IP \fB-e3\fP -Ambiguities/errors shown in excruciating detail. -.IP "\fB-fe\fP file" -Rename \fBerr.c\fP to file. -.IP "\fB-fh\fP file" -Rename \fBstdpccts.h\fP header (turns on \fB-gh\fP) to file. -.IP "\fB-fl\fP file" -Rename lexical output, \fBparser.dlg\fP, to file. -.IP "\fB-fm\fP file" -Rename file with lexical mode definitions, \fBmode.h\fP, to file. -.IP "\fB-fr\fP file" -Rename file which remaps globally visible symbols, \fBremap.h\fP, to file. -.IP "\fB-ft\fP file" -Rename \fBtokens.h\fP to file. -.IP \fB-ga\fP -Generate ANSI-compatible code (default case). This has not been -rigorously tested to be ANSI XJ11 C compliant, but it is close. The -normal output of \fIantlr\fP is currently compilable under both K&R, -ANSI C, and C++\(emthis option does nothing because \fIantlr\fP -generates a bunch of #ifdef's to do the right thing depending on the -language. -.IP \fB-gc\fP -Indicates that \fIantlr\fP should generate no C code, i.e., only -perform analysis on the grammar. -.IP \fB-gd\fP -C code is inserted in each of the \fIantlr\fR generated parsing functions to -provide for user-defined handling of a detailed parse trace. The inserted -code consists of calls to the user-supplied macros or functions called -\fBzzTRACEIN\fR and \fBzzTRACEOUT\fP. The only argument is a -\fIchar *\fR pointing to a C-style string which is the grammar rule -recognized by the current parsing function. If no definition is given -for the trace functions, upon rule entry and exit, a message will be -printed indicating that a particular rule as been entered or exited. -.IP \fB-ge\fP -Generate an error class for each non-terminal. -.IP \fB-gh\fP -Generate \fBstdpccts.h\fP for non-ANTLR-generated files to include. -This file contains all defines needed to describe the type of parser -generated by \fIantlr\fP (e.g. how much lookahead is used and whether -or not trees are constructed) and contains the \fBheader\fP action -specified by the user. -.IP \fB-gk\fP -Generate parsers that delay lookahead fetches until needed. Without -this option, \fIantlr\fP generates parsers which always have \fIk\fP -tokens of lookahead available. -.IP \fB-gl\fP -Generate line info about grammar actions in C parser of the form -\fB#\ \fIline\fP\ "\fIfile\fP"\fR which makes error messages from -the C/C++ compiler make more sense as they will \*Qpoint\*U into the -grammar file not the resulting C file. Debugging is easier as well, -because you will step through the grammar not C file. -.IP \fB-gs\fR -Do not generate sets for token expression lists; instead generate a -\fB||\fP-separated sequence of \fBLA(1)==\fItoken_number\fR. The -default is to generate sets. -.IP \fB-gt\fP -Generate code for Abstract-Syntax Trees. -.IP \fB-gx\fP -Do not create the lexical analyzer files (dlg-related). This option -should be given when the user wishes to provide a customized lexical -analyzer. It may also be used in \fImake\fR scripts to cause only the -parser to be rebuilt when a change not affecting the lexical structure -is made to the input grammars. -.IP "\fB-k \fIn\fR" -Set k of LL(k) to \fIn\fR; i.e. set tokens of look-ahead (default==1). -.IP "\fB-o\fP dir -Directory where output files should go (default="."). This is very -nice for keeping the source directory clear of ANTLR and DLG spawn. -.IP \fB-p\fP -The complete grammar, collected from all input grammar files and -stripped of all comments and embedded actions, is listed to -\fBstdout\fP. This is intended to aid in viewing the entire grammar -as a whole and to eliminate the need to keep actions concisely stated -so that the grammar is easier to read. Hence, it is preferable to -embed even complex actions directly in the grammar, rather than to -call them as subroutines, since the subroutine call overhead will be -saved. -.IP \fB-pa\fP -This option is the same as \fB-p\fP except that the output is -annotated with the first sets determined from grammar analysis. -.IP "\fB-prc on\fR -Turn on the computation and hoisting of predicate context. -.IP "\fB-prc off\fR -Turn off the computation and hoisting of predicate context. This -option makes 1.10 behave like the 1.06 release with option \fB-pr\fR -on. Context computation is off by default. -.IP "\fB-rl \fIn\fR -Limit the maximum number of tree nodes used by grammar analysis to -\fIn\fP. Occasionally, \fIantlr\fP is unable to analyze a grammar -submitted by the user. This rare situation can only occur when the -grammar is large and the amount of lookahead is greater than one. A -nonlinear analysis algorithm is used by PCCTS to handle the general -case of LL(k) parsing. The average complexity of analysis, however, is -near linear due to some fancy footwork in the implementation which -reduces the number of calls to the full LL(k) algorithm. An error -message will be displayed, if this limit is reached, which indicates -the grammar construct being analyzed when \fIantlr\fP hit a -non-linearity. Use this option if \fIantlr\fP seems to go out to -lunch and your disk start thrashing; try \fIn\fP=10000 to start. Once -the offending construct has been identified, try to remove the -ambiguity that \fIantlr\fP was trying to overcome with large lookahead -analysis. The introduction of (...)? backtracking blocks eliminates -some of these problems\ \(em \fIantlr\fP does not analyze alternatives -that begin with (...)? (it simply backtracks, if necessary, at run -time). -.IP \fB-w1\fR -Set low warning level. Do not warn if semantic predicates and/or -(...)? blocks are assumed to cover ambiguous alternatives. -.IP \fB-w2\fR -Ambiguous parsing decisions yield warnings even if semantic predicates -or (...)? blocks are used. Warn if predicate context computed and -semantic predicates incompletely disambiguate alternative productions. -.IP \fB-\fR -Read grammar from standard input and generate \fBstdin.c\fP as the -parser file. -.SH "SPECIAL CONSIDERATIONS" -.PP -\fIAntlr\fP works... we think. There is no implicit guarantee of -anything. We reserve no \fBlegal\fP rights to the software known as -the Purdue Compiler Construction Tool Set (PCCTS) \(em PCCTS is in the -public domain. An individual or company may do whatever they wish -with source code distributed with PCCTS or the code generated by -PCCTS, including the incorporation of PCCTS, or its output, into -commercial software. We encourage users to develop software with -PCCTS. However, we do ask that credit is given to us for developing -PCCTS. By "credit", we mean that if you incorporate our source code -into one of your programs (commercial product, research project, or -otherwise) that you acknowledge this fact somewhere in the -documentation, research report, etc... If you like PCCTS and have -developed a nice tool with the output, please mention that you -developed it using PCCTS. As long as these guidelines are followed, -we expect to continue enhancing this system and expect to make other -tools available as they are completed. -.SH FILES -.IP *.c -output C parser. -.IP *.cpp -output C++ parser when C++ mode is used. -.IP \fBparser.dlg\fP -output \fIdlg\fR lexical analyzer. -.IP \fBerr.c\fP -token string array, error sets and error support routines. Not used in -C++ mode. -.IP \fBremap.h\fP -file that redefines all globally visible parser symbols. The use of -the #parser directive creates this file. Not used in -C++ mode. -.IP \fBstdpccts.h\fP -list of definitions needed by C files, not generated by PCCTS, that -reference PCCTS objects. This is not generated by default. Not used in -C++ mode. -.IP \fBtokens.h\fP -output \fI#defines\fR for tokens used and function prototypes for -functions generated for rules. -.SH "SEE ALSO" -.LP -dlg(1), pccts(1) diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/antlr.c b/Tools/CodeTools/TianoTools/Pccts/antlr/antlr.c deleted file mode 100644 index 8aaef794e1..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/antlr.c +++ /dev/null @@ -1,3564 +0,0 @@ -/* - * A n t l r T r a n s l a t i o n H e a d e r - * - * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001 - * Purdue University Electrical Engineering - * With AHPCRC, University of Minnesota - * ANTLR Version 1.33MR33 - * - * ..\bin\antlr -gh antlr.g - * - */ - -#define ANTLR_VERSION 13333 -#include "pcctscfg.h" -#include "pccts_stdio.h" - -#include "pcctscfg.h" -#include "set.h" -#include -#include "syn.h" -#include "hash.h" -#include "generic.h" -#define zzcr_attr(attr,tok,t) -#define zzSET_SIZE 20 -#include "antlr.h" -#include "tokens.h" -#include "dlgdef.h" -#include "mode.h" - -/* MR23 In order to remove calls to PURIFY use the antlr -nopurify option */ - -#ifndef PCCTS_PURIFY -#define PCCTS_PURIFY(r,s) memset((char *) &(r),'\0',(s)); -#endif - -ANTLR_INFO - - -/* MR20 G. Hobbelt For Borland C++ 4.x & 5.x compiling with ALL warnings enabled */ -#if defined(__TURBOC__) -#pragma warn -aus /* unused assignment of 'xxx' */ -#endif - - -#ifdef __USE_PROTOS -static void chkToken(char *, char *, char *, int); -#else -static void chkToken(); -#endif - -#ifdef __USE_PROTOS -static int isDLGmaxToken(char *Token); /* MR3 */ -#else -static int isDLGmaxToken(); /* MR3 */ -#endif - -static int class_nest_level = 0; - -/* MR20 G. Hobbelt extern definitions moved to antlr.h */ - - - -void -#ifdef __USE_PROTOS -grammar(void) -#else -grammar() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - Graph g; - { - zzBLOCK(zztasp2); - zzMake0; - { - for (;;) { - if ( !((setwd1[LA(1)]&0x1))) break; - if ( (LA(1)==94) ) { - zzmatch(94); zzCONSUME; - zzmatch(Action); - - if ( HdrAction==NULL ) { - HdrAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(HdrAction!=NULL, "rule grammar: cannot allocate header action"); - strcpy(HdrAction, LATEXT(1)); - } - else warn("additional #header statement ignored"); - zzCONSUME; - - } - else { - if ( (LA(1)==95) ) { - zzmatch(95); zzCONSUME; - zzmatch(Action); - - if ( FirstAction==NULL ) { - FirstAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(FirstAction!=NULL, "rule grammar: cannot allocate #first action"); - strcpy(FirstAction, LATEXT(1)); - } else { - warn("additional #first statement ignored"); - }; - zzCONSUME; - - } - else { - if ( (LA(1)==96) ) { - zzmatch(96); zzCONSUME; - zzmatch(QuotedTerm); - - if ( GenCC ) { - warn("#parser meta-op incompatible with -CC; ignored"); - } - else { - if ( strcmp(ParserName,"zzparser")==0 ) { - ParserName=StripQuotes(mystrdup(LATEXT(1))); - if ( RulePrefix[0]!='\0' ) - { - warn("#parser meta-op incompatible with '-gp prefix'; '-gp' ignored"); - RulePrefix[0]='\0'; - } - } - else warn("additional #parser statement ignored"); - } - zzCONSUME; - - } - else { - if ( (LA(1)==97) ) { - zzmatch(97); zzCONSUME; - zzmatch(QuotedTerm); - { - char *fname; - zzantlr_state st; FILE *f; struct zzdlg_state dst; - UserTokenDefsFile = mystrdup(LATEXT(1)); - zzsave_antlr_state(&st); - zzsave_dlg_state(&dst); - fname = mystrdup(LATEXT(1)); - f = fopen(StripQuotes(fname), "r"); - if ( f==NULL ) {warn(eMsg1("cannot open token defs file '%s'", fname+1));} - else { - ANTLRm(enum_file(fname+1), f, PARSE_ENUM_FILE); - UserDefdTokens = 1; - } - zzrestore_antlr_state(&st); - zzrestore_dlg_state(&dst); - } - zzCONSUME; - - } - else break; /* MR6 code for exiting loop "for sure" */ - } - } - } - zzLOOP(zztasp2); - } - zzEXIT(zztasp2); - } - } - { - zzBLOCK(zztasp2); - zzMake0; - { - for (;;) { - if ( !((setwd1[LA(1)]&0x2))) break; - if ( (LA(1)==Action) ) { - zzmatch(Action); - { - UserAction *ua = newUserAction(LATEXT(1)); - ua->file = action_file; ua->line = action_line; - if ( class_nest_level>0 ) list_add(&class_before_actions, ua); - else list_add(&BeforeActions, ua); - } - zzCONSUME; - - } - else { - if ( (LA(1)==108) ) { - laction(); - } - else { - if ( (LA(1)==109) ) { - lmember(); - } - else { - if ( (LA(1)==110) ) { - lprefix(); - } - else { - if ( (LA(1)==116) ) { - aLexclass(); - } - else { - if ( (LA(1)==120) ) { - token(); - } - else { - if ( (LA(1)==117) ) { - error(); - } - else { - if ( (LA(1)==118) ) { - tclass(); - } - else { - if ( (LA(1)==111) ) { - aPred(); - } - else { - if ( (LA(1)==133) ) { - default_exception_handler(); - } - else { - if ( (LA(1)==99) ) { - class_def(); - } - else { - if ( (LA(1)==98) ) { - zzmatch(98); - - if ( class_nest_level==0 ) - warn("missing class definition for trailing '}'"); - class_nest_level--; - zzCONSUME; - - } - else break; /* MR6 code for exiting loop "for sure" */ - } - } - } - } - } - } - } - } - } - } - } - zzLOOP(zztasp2); - } - zzEXIT(zztasp2); - } - } - rule(); - g=zzaArg(zztasp1,3); SynDiag = (Junction *) zzaArg(zztasp1,3 ).left; - { - zzBLOCK(zztasp2); - zzMake0; - { - for (;;) { - if ( !((setwd1[LA(1)]&0x4))) break; - if ( (LA(1)==NonTerminal) ) { - rule(); - if ( zzaArg(zztasp2,1 ).left!=NULL ) { - g.right = NULL; - -/* MR21a */ /* Avoid use of a malformed graph when CannotContinue */ - /* MR21a */ /* is already set */ - /* MR21a */ - /* MR21a */ if (! (CannotContinue && g.left == NULL)) { - /* MR21a */ g = Or(g, zzaArg(zztasp2,1)); - /* MR21a */ } - /* MR21a */ } - } - else { - if ( (LA(1)==116) ) { - aLexclass(); - } - else { - if ( (LA(1)==120) ) { - token(); - } - else { - if ( (LA(1)==117) ) { - error(); - } - else { - if ( (LA(1)==118) ) { - tclass(); - } - else { - if ( (LA(1)==111) ) { - aPred(); - } - else { - if ( (LA(1)==99) ) { - class_def(); - } - else { - if ( (LA(1)==98) ) { - zzmatch(98); - - if ( class_nest_level==0 ) - warn("missing class definition for trailing '}'"); - class_nest_level--; - zzCONSUME; - - } - else break; /* MR6 code for exiting loop "for sure" */ - } - } - } - } - } - } - } - zzLOOP(zztasp2); - } - zzEXIT(zztasp2); - } - } - { - zzBLOCK(zztasp2); - zzMake0; - { - for (;;) { - if ( !((setwd1[LA(1)]&0x8))) break; - if ( (LA(1)==Action) ) { - zzmatch(Action); - { - UserAction *ua = newUserAction(LATEXT(1)); - ua->file = action_file; ua->line = action_line; - if ( class_nest_level>0 ) list_add(&class_after_actions, ua); - else list_add(&AfterActions, ua); - } - zzCONSUME; - - } - else { - if ( (LA(1)==108) ) { - laction(); - } - else { - if ( (LA(1)==109) ) { - lmember(); - } - else { - if ( (LA(1)==110) ) { - lprefix(); - } - else { - if ( (LA(1)==117) ) { - error(); - } - else { - if ( (LA(1)==118) ) { - tclass(); - } - else { - if ( (LA(1)==99) ) { - class_def(); - } - else { - if ( (LA(1)==111) ) { - aPred(); - } - else { - if ( (LA(1)==98) ) { - zzmatch(98); - - if ( class_nest_level==0 ) - warn("missing class definition for trailing '}'"); - class_nest_level--; - zzCONSUME; - - } - else break; /* MR6 code for exiting loop "for sure" */ - } - } - } - } - } - } - } - } - zzLOOP(zztasp2); - } - zzEXIT(zztasp2); - } - } - zzmatch(Eof); zzCONSUME; - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - CannotContinue=TRUE; - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd1, 0x10); - } -} - -void -#ifdef __USE_PROTOS -class_def(void) -#else -class_def() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - int go=1; char name[MaxRuleName+1]; - zzmatch(99); zzCONSUME; - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==NonTerminal) ) { - zzmatch(NonTerminal); - if(go) strncpy(name,LATEXT(1),MaxRuleName); - zzCONSUME; - - } - else { - if ( (LA(1)==TokenTerm) ) { - zzmatch(TokenTerm); - if(go) strncpy(name,LATEXT(1),MaxRuleName); - zzCONSUME; - - } - else {zzFAIL(1,zzerr1,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - - if ( CurrentClassName[0]!='\0' && strcmp(CurrentClassName,name)!=0 - && GenCC ) { - err("only one grammar class allowed in this release"); - go = 0; - } - else strcpy(CurrentClassName, name); - if ( !GenCC ) { err("class meta-op used without C++ option"); } - { - zzBLOCK(zztasp2); - zzMake0; - { - while ( (setwd1[LA(1)]&0x20) ) { - zzsetmatch(zzerr2, zzerr3); - if (ClassDeclStuff == NULL) { - /* MR10 */ ClassDeclStuff=(char *)calloc(MaxClassDeclStuff+1,sizeof(char)); - /* MR10 */ }; - /* MR10 */ strncat(ClassDeclStuff," ",MaxClassDeclStuff); - /* MR10 */ strncat(ClassDeclStuff,LATEXT(1),MaxClassDeclStuff); - /* MR22 */ do { - /* MR22 */ if (0 == strcmp(LATEXT(1),"public")) break; - /* MR22 */ if (0 == strcmp(LATEXT(1),"private")) break; - /* MR22 */ if (0 == strcmp(LATEXT(1),"protected")) break; - /* MR22 */ if (0 == strcmp(LATEXT(1),"virtual")) break; - /* MR22 */ if (0 == strcmp(LATEXT(1),",")) break; - /* MR22 */ if (0 == strcmp(LATEXT(1),":")) break; - /* MR22 */ if (BaseClassName != NULL) break; - /* MR22 */ BaseClassName=(char *)calloc(strlen(LATEXT(1))+1,sizeof(char)); - /* MR22 */ require(BaseClassName!=NULL, "rule grammar: cannot allocate base class name"); - /* MR22 */ strcpy(BaseClassName,LATEXT(1)); - /* MR22 */ } while (0); - /* MR10 */ - zzCONSUME; - - zzLOOP(zztasp2); - } - zzEXIT(zztasp2); - } - } - zzmatch(102); - - no_classes_found = 0; - if ( class_nest_level>=1 ) {warn("cannot have nested classes");} - else class_nest_level++; - zzCONSUME; - - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - CannotContinue=TRUE; - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd1, 0x40); - } -} - -void -#ifdef __USE_PROTOS -rule(void) -#else -rule() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - - - ExceptionGroup *eg; - RuleEntry *q; Junction *p; Graph r; int f, l; ECnode *e; - set toksrefd, rulesrefd; - char *pdecl=NULL, *ret=NULL, *a; CurRetDef = CurParmDef = NULL; - CurExGroups = NULL; - CurElementLabels = NULL; - CurAstLabelsInActions = NULL; /* MR27 */ - /* We want a new element label hash table for each rule */ - if ( Elabel!=NULL ) killHashTable(Elabel); - Elabel = newHashTable(); - attribsRefdFromAction = empty; - zzmatch(NonTerminal); - q=NULL; - if ( hash_get(Rname, LATEXT(1))!=NULL ) { - err(eMsg1("duplicate rule definition: '%s'",LATEXT(1))); - CannotContinue=TRUE; - } - else - { - q = (RuleEntry *)hash_add(Rname, - LATEXT(1), - (Entry *)newRuleEntry(LATEXT(1))); - CurRule = q->str; - } - CurRuleNode = q; - f = CurFile; l = zzline; - NumRules++; - zzCONSUME; - - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==103) ) { - zzmatch(103); - if ( q!=NULL ) q->noAST = TRUE; - zzCONSUME; - - } - else { - if ( (setwd1[LA(1)]&0x80) ) { - } - else {zzFAIL(1,zzerr4,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - { - zzBLOCK(zztasp2); - zzMake0; - { - ; - if ( (setwd2[LA(1)]&0x1) ) { - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (LA(1)==104) ) { - zzmatch(104); zzCONSUME; - } - else { - if ( (LA(1)==PassAction) ) { - } - else {zzFAIL(1,zzerr5,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp3); - } - } - zzmatch(PassAction); - pdecl = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(pdecl!=NULL, "rule rule: cannot allocate param decl"); - strcpy(pdecl, LATEXT(1)); - CurParmDef = pdecl; - zzCONSUME; - - } - else { - if ( (setwd2[LA(1)]&0x2) ) { - } - else {zzFAIL(1,zzerr6,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==105) ) { - zzmatch(105); zzCONSUME; - zzmatch(PassAction); - ret = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(ret!=NULL, "rule rule: cannot allocate ret type"); - strcpy(ret, LATEXT(1)); - CurRetDef = ret; - zzCONSUME; - - } - else { - if ( (setwd2[LA(1)]&0x4) ) { - } - else {zzFAIL(1,zzerr7,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==QuotedTerm) ) { - zzmatch(QuotedTerm); - if ( q!=NULL ) q->egroup=mystrdup(LATEXT(1)); - zzCONSUME; - - } - else { - if ( (LA(1)==106) ) { - } - else {zzFAIL(1,zzerr8,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - - if ( GenEClasseForRules && q!=NULL ) { - e = newECnode; - require(e!=NULL, "cannot allocate error class node"); - if ( q->egroup == NULL ) {a = q->str; a[0] = (char)toupper(a[0]);} - else a = q->egroup; - if ( Tnum( a ) == 0 ) - { - e->tok = addTname( a ); - list_add(&eclasses, (char *)e); - if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]); - /* refers to itself */ - list_add(&(e->elist), mystrdup(q->str)); - } - else { - warn(eMsg1("default errclass for '%s' would conflict with token/errclass/tokclass",a)); - if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]); - free((char *)e); - } - } - BlkLevel++; - if (BlkLevel >= MAX_BLK_LEVEL) fatal("Blocks nested too deeply"); - /* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID; - /* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; - zzmatch(106); - inAlt=1; - zzCONSUME; - - block( &toksrefd, &rulesrefd ); - r = makeBlk(zzaArg(zztasp1,7),0, NULL /* pFirstSetSymbol */ ); - CurRuleBlk = (Junction *)r.left; - CurRuleBlk->blockid = CurBlockID; - CurRuleBlk->jtype = RuleBlk; - if ( q!=NULL ) CurRuleBlk->rname = q->str; - CurRuleBlk->file = f; - CurRuleBlk->line = l; - CurRuleBlk->pdecl = pdecl; - CurRuleBlk->ret = ret; - CurRuleBlk->lock = makelocks(); - CurRuleBlk->pred_lock = makelocks(); - CurRuleBlk->tokrefs = toksrefd; - CurRuleBlk->rulerefs = rulesrefd; - p = newJunction(); /* add EndRule Node */ - ((Junction *)r.right)->p1 = (Node *)p; - r.right = (Node *) p; - p->jtype = EndRule; - p->lock = makelocks(); - p->pred_lock = makelocks(); - CurRuleBlk->end = p; - if ( q!=NULL ) q->rulenum = NumRules; - zzaArg(zztasp1,7) = r; - - /* MR23 */ CurBlockID_array[BlkLevel] = (-1); - /* MR23 */ CurAltNum_array[BlkLevel] = (-1); - --BlkLevel; - altFixup();leFixup();egFixup(); - zzmatch(107); - inAlt=0; - zzCONSUME; - - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==Action) ) { - zzmatch(Action); - a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(a!=NULL, "rule rule: cannot allocate error action"); - strcpy(a, LATEXT(1)); - CurRuleBlk->erraction = a; - zzCONSUME; - - } - else { - if ( (setwd2[LA(1)]&0x8) ) { - } - else {zzFAIL(1,zzerr9,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - { - zzBLOCK(zztasp2); - zzMake0; - { - while ( (LA(1)==133) ) { - eg = exception_group(); - - if ( eg!=NULL ) { - list_add(&CurExGroups, (void *)eg); - if (eg->label == NULL || *eg->label=='\0' ) q->has_rule_exception = 1; - } - zzLOOP(zztasp2); - } - zzEXIT(zztasp2); - } - } - if ( q==NULL ) zzaArg(zztasp1,0 ).left = NULL; else zzaArg(zztasp1,0) = zzaArg(zztasp1,7); - CurRuleBlk->exceptions = CurExGroups; - CurRuleBlk->el_labels = CurElementLabels; - CurRuleNode->ast_labels_in_actions = CurAstLabelsInActions; - CurRuleNode = NULL; - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - CannotContinue=TRUE; - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd2, 0x10); - } -} - -void -#ifdef __USE_PROTOS -laction(void) -#else -laction() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - char *a; - zzmatch(108); zzCONSUME; - zzmatch(Action); - - a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(a!=NULL, "rule laction: cannot allocate action"); - strcpy(a, LATEXT(1)); - list_add(&LexActions, a); - zzCONSUME; - - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - CannotContinue=TRUE; - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd2, 0x20); - } -} - -void -#ifdef __USE_PROTOS -lmember(void) -#else -lmember() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - char *a; - zzmatch(109); zzCONSUME; - zzmatch(Action); - - /* MR1 */ if (! GenCC) { - /* MR1 */ err("Use #lexmember only in C++ mode (to insert code in DLG class header"); - /* MR1 */ } else { - /* MR1 */ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - /* MR1 */ require(a!=NULL, "rule lmember: cannot allocate action"); - /* MR1 */ strcpy(a, LATEXT(1)); - /* MR1 */ list_add(&LexMemberActions, a); - /* MR1 */ }; - /* MR1 */ - zzCONSUME; - - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - CannotContinue=TRUE; - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd2, 0x40); - } -} - -void -#ifdef __USE_PROTOS -lprefix(void) -#else -lprefix() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - char *a; - zzmatch(110); zzCONSUME; - zzmatch(Action); - - /* MR1 */ if (! GenCC) { - /* MR1 */ err("Use #lexprefix only in C++ mode (to insert code in DLG class header"); - /* MR1 */ } else { - /* MR1 */ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - /* MR1 */ require(a!=NULL, "rule lprefix: cannot allocate action"); - /* MR1 */ strcpy(a, LATEXT(1)); - /* MR1 */ list_add(&LexPrefixActions, a); - /* MR1 */ }; - /* MR1 */ - zzCONSUME; - - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - CannotContinue=TRUE; - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd2, 0x80); - } -} - -void -#ifdef __USE_PROTOS -aPred(void) -#else -aPred() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - PredEntry *predEntry=NULL; - char *name=NULL; - Predicate *predExpr=NULL; - char *predLiteral=NULL; - int save_file; - int save_line; - int predExprPresent=0; - zzmatch(111); - - MR_usingPredNames=1; /* will need to use -mrhoist version of genPredTree */ - zzCONSUME; - - zzmatch(TokenTerm); - name=mystrdup(LATEXT(1)); - zzCONSUME; - - - /* don't free - referenced in predicates */ - - CurPredName=(char *)calloc(1,strlen(name) + 10); - strcat(CurPredName,"#pred "); - strcat(CurPredName,name); - - predEntry=(PredEntry *) hash_get(Pname,name); - if (predEntry != NULL) { - warnFL(eMsg1("#pred %s previously defined - ignored",name), - FileStr[action_file],action_line); - name=NULL; -}; - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==Pred) ) { - zzmatch(Pred); - predLiteral=mystrdup(LATEXT(1)); - save_line=action_line; - save_file=action_file; - zzCONSUME; - - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (setwd3[LA(1)]&0x1) ) { - predExpr = predOrExpr(); - - predExprPresent=1; - } - else { - if ( (setwd3[LA(1)]&0x2) ) { - } - else {zzFAIL(1,zzerr10,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp3); - } - } - if (predLiteral != NULL && name != NULL) { - - /* - * predExpr may be NULL due to syntax errors - * or simply omitted by the user - */ - - predEntry=newPredEntry(name); - predEntry->file=save_file; - predEntry->line=save_line; - predExpr=MR_predFlatten(predExpr); - predEntry->predLiteral=predLiteral; - if (! predExprPresent || predExpr == NULL) { - predExpr=new_pred(); - predExpr->expr=predLiteral; - predExpr->source=newActionNode(); - predExpr->source->action=predExpr->expr; - predExpr->source->rname=CurPredName; - predExpr->source->line=action_line; - predExpr->source->file=action_file; - predExpr->source->is_predicate=1; - predExpr->k=predicateLookaheadDepth(predExpr->source); - }; - predEntry->pred=predExpr; - hash_add(Pname,name,(Entry *)predEntry); - predExpr=NULL; - }; - predicate_free(predExpr); - } - else { - if ( (setwd3[LA(1)]&0x4) ) { - save_line=zzline; save_file=CurFile; - predExpr = predOrExpr(); - - if (predExpr != NULL && name != NULL) { - predEntry=newPredEntry(name); - predEntry->file=CurFile; - predEntry->line=zzline; - predExpr=MR_predFlatten(predExpr); - predEntry->pred=predExpr; - hash_add(Pname,name,(Entry *)predEntry); - predExpr=NULL; - }; - predicate_free(predExpr); - } - else {zzFAIL(1,zzerr11,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==107) ) { - zzmatch(107); zzCONSUME; - } - else { - if ( (setwd3[LA(1)]&0x8) ) { - } - else {zzFAIL(1,zzerr12,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - predicate_free(predExpr); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd3, 0x10); - } -} - -Predicate * -#ifdef __USE_PROTOS -predOrExpr(void) -#else -predOrExpr() -#endif -{ - Predicate * _retv; - zzRULE; - zzBLOCK(zztasp1); - PCCTS_PURIFY(_retv,sizeof(Predicate * )) - zzMake0; - { - Predicate *ORnode; - Predicate *predExpr; - Predicate **tail=NULL; - predExpr = predAndExpr(); - - - ORnode=new_pred(); - ORnode->expr=PRED_OR_LIST; - if (predExpr != NULL) { - ORnode->down=predExpr; - tail=&predExpr->right; - }; - { - zzBLOCK(zztasp2); - zzMake0; - { - while ( (LA(1)==112) ) { - zzmatch(112); zzCONSUME; - predExpr = predAndExpr(); - - - if (predExpr != NULL) { - *tail=predExpr; - tail=&predExpr->right; - }; - zzLOOP(zztasp2); - } - zzEXIT(zztasp2); - } - } - - _retv=ORnode; - ORnode=NULL; - zzEXIT(zztasp1); - return _retv; -fail: - zzEXIT(zztasp1); - predicate_free(ORnode); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd3, 0x20); - return _retv; - } -} - -Predicate * -#ifdef __USE_PROTOS -predAndExpr(void) -#else -predAndExpr() -#endif -{ - Predicate * _retv; - zzRULE; - zzBLOCK(zztasp1); - PCCTS_PURIFY(_retv,sizeof(Predicate * )) - zzMake0; - { - Predicate *ANDnode; - Predicate *predExpr; - Predicate **tail=NULL; - predExpr = predPrimary(); - - - ANDnode=new_pred(); - ANDnode->expr=PRED_AND_LIST; - if (predExpr != NULL) { - ANDnode->down=predExpr; - tail=&predExpr->right; - }; - { - zzBLOCK(zztasp2); - zzMake0; - { - while ( (LA(1)==113) ) { - zzmatch(113); zzCONSUME; - predExpr = predPrimary(); - - - if (predExpr != NULL) { - *tail=predExpr; - tail=&predExpr->right; - }; - zzLOOP(zztasp2); - } - zzEXIT(zztasp2); - } - } - - _retv=ANDnode; - ANDnode=NULL; - zzEXIT(zztasp1); - return _retv; -fail: - zzEXIT(zztasp1); - predicate_free(ANDnode); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd3, 0x40); - return _retv; - } -} - -Predicate * -#ifdef __USE_PROTOS -predPrimary(void) -#else -predPrimary() -#endif -{ - Predicate * _retv; - zzRULE; - zzBLOCK(zztasp1); - PCCTS_PURIFY(_retv,sizeof(Predicate * )) - zzMake0; - { - - char *name=NULL; - PredEntry *predEntry=NULL; - Predicate *predExpr=NULL; - if ( (LA(1)==TokenTerm) ) { - zzmatch(TokenTerm); - name=mystrdup(LATEXT(1)); - zzCONSUME; - - - predEntry=(PredEntry *) hash_get(Pname,name); - if (predEntry == NULL) { - warnFL(eMsg1("no previously defined #pred with name \"%s\"",name), - FileStr[CurFile],zzline); - name=NULL; - _retv=NULL; - } else { - predExpr=predicate_dup(predEntry->pred); - predExpr->predEntry=predEntry; - _retv=predExpr; - }; - } - else { - if ( (LA(1)==114) ) { - zzmatch(114); zzCONSUME; - predExpr = predOrExpr(); - - zzmatch(115); - - _retv=predExpr; - zzCONSUME; - - } - else { - if ( (LA(1)==103) ) { - zzmatch(103); zzCONSUME; - predExpr = predPrimary(); - - - predExpr->inverted=!predExpr->inverted; - _retv=predExpr; - } - else {zzFAIL(1,zzerr13,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - } - zzEXIT(zztasp1); - return _retv; -fail: - zzEXIT(zztasp1); - - predicate_free(predExpr); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd3, 0x80); - return _retv; - } -} - -void -#ifdef __USE_PROTOS -aLexclass(void) -#else -aLexclass() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - zzmatch(116); zzCONSUME; - zzmatch(TokenTerm); - lexclass(mystrdup(LATEXT(1))); - zzCONSUME; - - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - CannotContinue=TRUE; - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd4, 0x1); - } -} - -void -#ifdef __USE_PROTOS -error(void) -#else -error() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - char *t=NULL; ECnode *e; int go=1; TermEntry *p; - zzmatch(117); zzCONSUME; - { - zzBLOCK(zztasp2); - zzMake0; - { - ; - if ( (LA(1)==TokenTerm) ) { - zzmatch(TokenTerm); - t=mystrdup(LATEXT(1)); - zzCONSUME; - - } - else { - if ( (LA(1)==QuotedTerm) ) { - zzmatch(QuotedTerm); - t=mystrdup(LATEXT(1)); - zzCONSUME; - - } - else {zzFAIL(1,zzerr14,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - e = newECnode; - require(e!=NULL, "cannot allocate error class node"); - e->lexclass = CurrentLexClass; - if ( Tnum( (t=StripQuotes(t)) ) == 0 ) - { - if ( hash_get(Texpr, t) != NULL ) - warn(eMsg1("errclass name conflicts with regular expression '%s'",t)); - e->tok = addTname( t ); - set_orel(e->tok, &imag_tokens); - require((p=(TermEntry *)hash_get(Tname, t)) != NULL, - "hash table mechanism is broken"); - p->classname = 1; /* entry is errclass name, not token */ - list_add(&eclasses, (char *)e); - } - else - { - warn(eMsg1("redefinition of errclass or conflict w/token or tokclass '%s'; ignored",t)); - free( (char *)e ); - go=0; -} - zzmatch(102); zzCONSUME; - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==NonTerminal) ) { - zzmatch(NonTerminal); - if ( go ) t=mystrdup(LATEXT(1)); - zzCONSUME; - - } - else { - if ( (LA(1)==TokenTerm) ) { - zzmatch(TokenTerm); - if ( go ) t=mystrdup(LATEXT(1)); - zzCONSUME; - - } - else { - if ( (LA(1)==QuotedTerm) ) { - zzmatch(QuotedTerm); - if ( go ) t=mystrdup(LATEXT(1)); - zzCONSUME; - - } - else {zzFAIL(1,zzerr15,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - } - zzEXIT(zztasp2); - } - } - if ( go ) list_add(&(e->elist), t); - { - zzBLOCK(zztasp2); - zzMake0; - { - while ( (setwd4[LA(1)]&0x2) ) { - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (LA(1)==NonTerminal) ) { - zzmatch(NonTerminal); - if ( go ) t=mystrdup(LATEXT(1)); - zzCONSUME; - - } - else { - if ( (LA(1)==TokenTerm) ) { - zzmatch(TokenTerm); - if ( go ) t=mystrdup(LATEXT(1)); - zzCONSUME; - - } - else { - if ( (LA(1)==QuotedTerm) ) { - zzmatch(QuotedTerm); - if ( go ) t=mystrdup(LATEXT(1)); - zzCONSUME; - - } - else {zzFAIL(1,zzerr16,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - } - zzEXIT(zztasp3); - } - } - if ( go ) list_add(&(e->elist), t); - zzLOOP(zztasp2); - } - zzEXIT(zztasp2); - } - } - zzmatch(98); zzCONSUME; - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - CannotContinue=TRUE; - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd4, 0x4); - } -} - -void -#ifdef __USE_PROTOS -tclass(void) -#else -tclass() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - char *t=NULL; TCnode *e; int go=1,tok,totok; TermEntry *p, *term, *toterm; - char *akaString=NULL; int save_file; int save_line; - char *totext=NULL; - zzmatch(118); zzCONSUME; - zzmatch(TokenTerm); - t=mystrdup(LATEXT(1)); - zzCONSUME; - - e = newTCnode; - require(e!=NULL, "cannot allocate token class node"); - e->lexclass = CurrentLexClass; - if ( Tnum( t ) == 0 ) - { - e->tok = addTname( t ); - set_orel(e->tok, &imag_tokens); - set_orel(e->tok, &tokclasses); - require((p=(TermEntry *)hash_get(Tname, t)) != NULL, - "hash table mechanism is broken"); - p->classname = 1; /* entry is class name, not token */ - p->tclass = e; /* save ptr to this tclass def */ - list_add(&tclasses, (char *)e); - } - else - { - warn(eMsg1("redefinition of tokclass or conflict w/token '%s'; ignored",t)); - free( (char *)e ); - go=0; -} - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==114) ) { - zzmatch(114); zzCONSUME; - zzmatch(QuotedTerm); - akaString=mystrdup(StripQuotes(LATEXT(1))); - /* MR11 */ save_file=CurFile;save_line=zzline; - /* MR23 */ - zzCONSUME; - - zzmatch(115); zzCONSUME; - } - else { - if ( (LA(1)==102) ) { - } - else {zzFAIL(1,zzerr17,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - - /* MR23 */ if (p!= NULL && akaString != NULL) { - /* MR23 */ if (p->akaString != NULL) { - /* MR23 */ if (strcmp(p->akaString,akaString) != 0) { - /* MR23 */ warnFL(eMsg2("this #tokclass statment conflicts with a previous #tokclass %s(\"%s\") statement", - /* MR23 */ t,p->akaString), - /* MR23 */ FileStr[save_file],save_line); - /* MR23 */ }; - /* MR23 */ } else { - /* MR23 */ p->akaString=akaString; - /* MR23 */ }; - /* MR23 */ }; - /* MR23 */ - zzmatch(102); zzCONSUME; - { - zzBLOCK(zztasp2); - int zzcnt=1; - zzMake0; - { - do { - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (LA(1)==TokenTerm) ) { - zzmatch(TokenTerm); - if ( go ) { - term = (TermEntry *) hash_get(Tname, LATEXT(1)); - if ( term==NULL && UserDefdTokens ) { - err("implicit token definition not allowed with #tokdefs"); - go = 0; - } - else {t=mystrdup(LATEXT(1)); tok=addTname(LATEXT(1));} - } - zzCONSUME; - - { - zzBLOCK(zztasp4); - zzMake0; - { - if ( (LA(1)==119) ) { - zzmatch(119); zzCONSUME; - zzmatch(TokenTerm); - if ( go ) { - toterm = (TermEntry *) hash_get(Tname, LATEXT(1)); - if ( toterm==NULL && UserDefdTokens ) { - err("implicit token definition not allowed with #tokdefs"); - go = 0; - } else { - totext=mystrdup(LATEXT(1)); totok=addTname(LATEXT(1)); - } - } - zzCONSUME; - - } - else { - if ( (setwd4[LA(1)]&0x8) ) { - } - else {zzFAIL(1,zzerr18,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp4); - } - } - } - else { - if ( (LA(1)==QuotedTerm) ) { - zzmatch(QuotedTerm); - if ( go ) { - term = (TermEntry *) hash_get(Texpr, LATEXT(1)); - if ( term==NULL && UserDefdTokens ) { - err("implicit token definition not allowed with #tokdefs"); - go = 0; - } - else {t=mystrdup(LATEXT(1)); tok=addTexpr(LATEXT(1));} - } - zzCONSUME; - - } - else {zzFAIL(1,zzerr19,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp3); - } - } - if ( go ) { - if (totext == NULL) { - list_add(&(e->tlist), t); - } else { - list_add(&(e->tlist),".."); - list_add(&(e->tlist),t); - list_add(&(e->tlist),totext); - } - totext=NULL; - } - zzLOOP(zztasp2); - } while ( (setwd4[LA(1)]&0x10) ); - zzEXIT(zztasp2); - } - } - zzmatch(98); zzCONSUME; - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - CannotContinue=TRUE; - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd4, 0x20); - } -} - -void -#ifdef __USE_PROTOS -token(void) -#else -token() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - char *t=NULL, *e=NULL, *a=NULL; int tnum=0; - char *akaString=NULL; TermEntry *te;int save_file=0,save_line=0; - zzmatch(120); - tokenActionActive=1; - zzCONSUME; - - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==TokenTerm) ) { - zzmatch(TokenTerm); - t=mystrdup(LATEXT(1)); - zzCONSUME; - - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (LA(1)==114) ) { - zzmatch(114); zzCONSUME; - zzmatch(QuotedTerm); - akaString=mystrdup(StripQuotes(LATEXT(1))); - /* MR11 */ save_file=CurFile;save_line=zzline; - /* MR11 */ - zzCONSUME; - - zzmatch(115); zzCONSUME; - } - else { - if ( (setwd4[LA(1)]&0x40) ) { - } - else {zzFAIL(1,zzerr20,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp3); - } - } - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (LA(1)==121) ) { - zzmatch(121); zzCONSUME; - zzmatch(122); - tnum = atoi(LATEXT(1)); - zzCONSUME; - - } - else { - if ( (setwd4[LA(1)]&0x80) ) { - } - else {zzFAIL(1,zzerr21,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp3); - } - } - } - else { - if ( (setwd5[LA(1)]&0x1) ) { - } - else {zzFAIL(1,zzerr22,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==QuotedTerm) ) { - zzmatch(QuotedTerm); - e=mystrdup(LATEXT(1)); - zzCONSUME; - - } - else { - if ( (setwd5[LA(1)]&0x2) ) { - } - else {zzFAIL(1,zzerr23,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==Action) ) { - zzmatch(Action); - - a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(a!=NULL, "rule token: cannot allocate action"); - strcpy(a, LATEXT(1)); - zzCONSUME; - - } - else { - if ( (setwd5[LA(1)]&0x4) ) { - } - else {zzFAIL(1,zzerr24,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==107) ) { - zzmatch(107); zzCONSUME; - } - else { - if ( (setwd5[LA(1)]&0x8) ) { - } - else {zzFAIL(1,zzerr25,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - chkToken(t, e, a, tnum); - if (t != NULL) { - te=(TermEntry *)hash_get(Tname,t); - if (te != NULL && akaString != NULL) { - if (te->akaString != NULL) { - if (strcmp(te->akaString,akaString) != 0) { - warnFL(eMsg2("this #token statment conflicts with a previous #token %s(\"%s\") statement", - t,te->akaString), - FileStr[save_file],save_line); - }; - } else { - te->akaString=akaString; - }; - }; - }; - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - CannotContinue=TRUE; - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd5, 0x10); - } -} - -void -#ifdef __USE_PROTOS -block(set * toksrefd,set * rulesrefd) -#else -block(toksrefd,rulesrefd) - set *toksrefd; -set *rulesrefd ; -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - - Graph g, b; - set saveblah; - int saveinalt = inAlt; - ExceptionGroup *eg; - * toksrefd = empty; - * rulesrefd = empty; - set_clr(AST_nodes_refd_in_actions); - CurBlockID++; - /* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID; - CurAltNum = 1; - /* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; - saveblah = attribsRefdFromAction; - attribsRefdFromAction = empty; - alt( toksrefd,rulesrefd ); - b = g = zzaArg(zztasp1,1); - - if ( ((Junction *)g.left)->p1->ntype == nAction ) - { - ActionNode *actionNode=(ActionNode *) - ( ( (Junction *)g.left) ->p1); - if (!actionNode->is_predicate ) - { - actionNode->init_action = TRUE; - /* MR12c */ if (actionNode->noHoist) { - /* MR12c */ errFL("<> appears as init-action - use <<>> <>", - /* MR12c */ FileStr[actionNode->file],actionNode->line); - /* MR12c */ }; - } - } - ((Junction *)g.left)->blockid = CurBlockID; - { - zzBLOCK(zztasp2); - zzMake0; - { - while ( (LA(1)==133) ) { - eg = exception_group(); - - - if ( eg!=NULL ) { - /* MR7 ***** eg->altID = makeAltID(CurBlockID,CurAltNum); *****/ - /* MR7 ***** CurAltStart->exception_label = eg->altID; *****/ - list_add(&CurExGroups, (void *)eg); - } - zzLOOP(zztasp2); - } - zzEXIT(zztasp2); - } - } - CurAltNum++; - /* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; - { - zzBLOCK(zztasp2); - zzMake0; - { - while ( (LA(1)==123) ) { - zzmatch(123); - inAlt=1; - zzCONSUME; - - alt( toksrefd,rulesrefd ); - g = Or(g, zzaArg(zztasp2,2)); - - ((Junction *)g.left)->blockid = CurBlockID; - { - zzBLOCK(zztasp3); - zzMake0; - { - while ( (LA(1)==133) ) { - eg = exception_group(); - - - if ( eg!=NULL ) { - /* MR7 ***** eg->altID = makeAltID(CurBlockID,CurAltNum); *****/ - /* MR7 ***** CurAltStart->exception_label = eg->altID; *****/ - list_add(&CurExGroups, (void *)eg); - } - zzLOOP(zztasp3); - } - zzEXIT(zztasp3); - } - } - CurAltNum++; - /* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; - zzLOOP(zztasp2); - } - zzEXIT(zztasp2); - } - } - zzaArg(zztasp1,0) = b; - attribsRefdFromAction = saveblah; inAlt = saveinalt; - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - CannotContinue=TRUE; - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd5, 0x20); - } -} - -void -#ifdef __USE_PROTOS -alt(set * toksrefd,set * rulesrefd) -#else -alt(toksrefd,rulesrefd) - set *toksrefd; -set *rulesrefd ; -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - int n=0; Graph g; int e_num=0, old_not=0; Node *node; set elems, dif; - int first_on_line = 1, use_def_MT_handler = 0; - g.left=NULL; g.right=NULL; - - CurAltStart = NULL; - elems = empty; - inAlt = 1; - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==88) ) { - zzmatch(88); - use_def_MT_handler = 1; - zzCONSUME; - - } - else { - if ( (setwd5[LA(1)]&0x40) ) { - } - else {zzFAIL(1,zzerr26,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - { - zzBLOCK(zztasp2); - zzMake0; - { - ; - while ( (setwd5[LA(1)]&0x80) ) { - { - zzBLOCK(zztasp3); - zzMake0; - { - old_not=0; - if ( (LA(1)==124) ) { - zzmatch(124); - old_not=1; - zzCONSUME; - - } - else { - if ( (setwd6[LA(1)]&0x1) ) { - } - else {zzFAIL(1,zzerr27,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp3); - } - } - node = element( old_not, first_on_line, use_def_MT_handler ); - - if ( node!=NULL && node->ntype!=nAction ) first_on_line = 0; - - if ( zzaArg(zztasp2,2 ).left!=NULL ) { - g = Cat(g, zzaArg(zztasp2,2)); - n++; - if ( node!=NULL ) { - if ( node->ntype!=nAction ) e_num++; - /* record record number of all rule and token refs */ - if ( node->ntype==nToken ) { - TokNode *tk = (TokNode *)((Junction *)zzaArg(zztasp2,2 ).left)->p1; - tk->elnum = e_num; - set_orel(e_num, &elems); - } - else if ( node->ntype==nRuleRef ) { - RuleRefNode *rn = (RuleRefNode *)((Junction *)zzaArg(zztasp2,2 ).left)->p1; - rn->elnum = e_num; - set_orel(e_num, rulesrefd); - } - } - } - zzLOOP(zztasp2); - } - zzEXIT(zztasp2); - } - } - if ( n == 0 ) g = emptyAlt(); - zzaArg(zztasp1,0) = g; - /* We want to reduce number of LT(i) calls and the number of - * local attribute variables in C++ mode (for moment, later we'll - * do for C also). However, if trees are being built, they - * require most of the attrib variables to create the tree nodes - * with; therefore, we gen a token ptr for each token ref in C++ - */ - if ( GenCC && !GenAST ) - { - /* This now free's the temp set -ATG 5/6/95 */ - set temp; - temp = set_and(elems, attribsRefdFromAction); - set_orin( toksrefd, temp); - set_free(temp); -} -else set_orin( toksrefd, elems); -if ( GenCC ) { - dif = set_dif(attribsRefdFromAction, elems); - if ( set_deg(dif)>0 ) - err("one or more $i in action(s) refer to non-token elements"); - set_free(dif); -} -set_free(elems); -set_free(attribsRefdFromAction); -inAlt = 0; - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - CannotContinue=TRUE; - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd6, 0x2); - } -} - -LabelEntry * -#ifdef __USE_PROTOS -element_label(void) -#else -element_label() -#endif -{ - LabelEntry * _retv; - zzRULE; - zzBLOCK(zztasp1); - PCCTS_PURIFY(_retv,sizeof(LabelEntry * )) - zzMake0; - { - TermEntry *t=NULL; LabelEntry *l=NULL; RuleEntry *r=NULL; char *lab; - zzmatch(LABEL); - lab = mystrdup(LATEXT(1)); - zzCONSUME; - - - UsedNewStyleLabel = 1; - if ( UsedOldStyleAttrib ) err("cannot mix with new-style labels with old-style $i"); - t = (TermEntry *) hash_get(Tname, lab); - if ( t==NULL ) t = (TermEntry *) hash_get(Texpr, lab); - if ( t==NULL ) r = (RuleEntry *) hash_get(Rname, lab); - if ( t!=NULL ) { - err(eMsg1("label definition clashes with token/tokclass definition: '%s'", lab)); - _retv = NULL; - } - else if ( r!=NULL ) { - err(eMsg1("label definition clashes with rule definition: '%s'", lab)); - _retv = NULL; - } - else { - /* we don't clash with anybody else */ - l = (LabelEntry *) hash_get(Elabel, lab); - if ( l==NULL ) { /* ok to add new element label */ - l = (LabelEntry *)hash_add(Elabel, - lab, - (Entry *)newLabelEntry(lab)); - /* add to list of element labels for this rule */ - list_add(&CurElementLabels, (void *)lab); - /* MR7 */ leAdd(l); /* list of labels waiting for exception group definitions */ - _retv = l; - } - else { - err(eMsg1("label definitions must be unique per rule: '%s'", lab)); - _retv = NULL; -} -} - zzmatch(106); zzCONSUME; - zzEXIT(zztasp1); - return _retv; -fail: - zzEXIT(zztasp1); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd6, 0x4); - return _retv; - } -} - -Node * -#ifdef __USE_PROTOS -element(int old_not,int first_on_line,int use_def_MT_handler) -#else -element(old_not,first_on_line,use_def_MT_handler) - int old_not; -int first_on_line; -int use_def_MT_handler ; -#endif -{ - Node * _retv; - zzRULE; - zzBLOCK(zztasp1); - PCCTS_PURIFY(_retv,sizeof(Node * )) - zzMake0; - { - - Attrib blk; - Predicate *pred = NULL; - int local_use_def_MT_handler=0; - ActionNode *act; - RuleRefNode *rr; - set toksrefd, rulesrefd; - TermEntry *term; - TokNode *p=NULL; RuleRefNode *q; int approx=0; - LabelEntry *label=NULL; - int predMsgDone=0; - int semDepth=0; - int ampersandStyle; - int height; /* MR11 */ - int equal_height; /* MR11 */ - - char* pFirstSetSymbol = NULL; /* MR21 */ - - _retv = NULL; - if ( (setwd6[LA(1)]&0x8) ) { - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==LABEL) ) { - label = element_label(); - - } - else { - if ( (setwd6[LA(1)]&0x10) ) { - } - else {zzFAIL(1,zzerr28,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==TokenTerm) ) { - zzmatch(TokenTerm); - - term = (TermEntry *) hash_get(Tname, LATEXT(1)); - if ( term==NULL && UserDefdTokens ) { - err("implicit token definition not allowed with #tokdefs"); - zzaRet.left = zzaRet.right = NULL; - } - else { - zzaRet = buildToken(LATEXT(1)); - p=((TokNode *)((Junction *)zzaRet.left)->p1); - term = (TermEntry *) hash_get(Tname, LATEXT(1)); - require( term!= NULL, "hash table mechanism is broken"); - p->tclass = term->tclass; - p->complement = old_not; - if ( label!=NULL ) { - p->el_label = label->str; - label->elem = (Node *)p; - } - } - zzCONSUME; - - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (LA(1)==119) ) { - zzmatch(119); zzCONSUME; - { - zzBLOCK(zztasp4); - zzMake0; - { - if ( (LA(1)==QuotedTerm) ) { - zzmatch(QuotedTerm); - if ( p!=NULL ) setUpperRange(p, LATEXT(1)); - zzCONSUME; - - } - else { - if ( (LA(1)==TokenTerm) ) { - zzmatch(TokenTerm); - if ( p!=NULL ) setUpperRange(p, LATEXT(1)); - zzCONSUME; - - } - else {zzFAIL(1,zzerr29,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp4); - } - } - } - else { - if ( (setwd6[LA(1)]&0x20) ) { - } - else {zzFAIL(1,zzerr30,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp3); - } - } - - if ( p!=NULL && (p->upper_range!=0 || p->tclass || old_not) ) - list_add(&MetaTokenNodes, (void *)p); - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (LA(1)==125) ) { - zzmatch(125); - if ( p!=NULL ) p->astnode=ASTroot; - zzCONSUME; - - } - else { - if ( (setwd6[LA(1)]&0x40) ) { - if ( p!=NULL ) p->astnode=ASTchild; - } - else { - if ( (LA(1)==103) ) { - zzmatch(103); - if ( p!=NULL ) p->astnode=ASTexclude; - zzCONSUME; - - } - else {zzFAIL(1,zzerr31,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - } - zzEXIT(zztasp3); - } - } - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (LA(1)==88) ) { - zzmatch(88); - local_use_def_MT_handler = 1; - zzCONSUME; - - } - else { - if ( (setwd6[LA(1)]&0x80) ) { - } - else {zzFAIL(1,zzerr32,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp3); - } - } - - if ( p!=NULL && first_on_line ) { - CurAltStart = (Junction *)zzaRet.left; - altAdd(CurAltStart); /* MR7 */ - p->altstart = CurAltStart; - } - if ( p!=NULL ) - p->use_def_MT_handler = use_def_MT_handler || local_use_def_MT_handler; - _retv = (Node *)p; - } - else { - if ( (LA(1)==QuotedTerm) ) { - zzmatch(QuotedTerm); - - term = (TermEntry *) hash_get(Texpr, LATEXT(1)); - if ( term==NULL && UserDefdTokens ) { - err("implicit token definition not allowed with #tokdefs"); - zzaRet.left = zzaRet.right = NULL; - } - else { - zzaRet = buildToken(LATEXT(1)); p=((TokNode *)((Junction *)zzaRet.left)->p1); - p->complement = old_not; - if ( label!=NULL ) { - p->el_label = label->str; - label->elem = (Node *)p; - } - } - zzCONSUME; - - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (LA(1)==119) ) { - zzmatch(119); zzCONSUME; - { - zzBLOCK(zztasp4); - zzMake0; - { - if ( (LA(1)==QuotedTerm) ) { - zzmatch(QuotedTerm); - if ( p!=NULL ) setUpperRange(p, LATEXT(1)); - zzCONSUME; - - } - else { - if ( (LA(1)==TokenTerm) ) { - zzmatch(TokenTerm); - if ( p!=NULL ) setUpperRange(p, LATEXT(1)); - zzCONSUME; - - } - else {zzFAIL(1,zzerr33,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp4); - } - } - } - else { - if ( (setwd7[LA(1)]&0x1) ) { - } - else {zzFAIL(1,zzerr34,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp3); - } - } - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (LA(1)==125) ) { - zzmatch(125); - if ( p!=NULL ) p->astnode=ASTroot; - zzCONSUME; - - } - else { - if ( (setwd7[LA(1)]&0x2) ) { - if ( p!=NULL ) p->astnode=ASTchild; - } - else { - if ( (LA(1)==103) ) { - zzmatch(103); - if ( p!=NULL ) p->astnode=ASTexclude; - zzCONSUME; - - } - else {zzFAIL(1,zzerr35,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - } - zzEXIT(zztasp3); - } - } - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (LA(1)==88) ) { - zzmatch(88); - local_use_def_MT_handler = 1; - zzCONSUME; - - } - else { - if ( (setwd7[LA(1)]&0x4) ) { - } - else {zzFAIL(1,zzerr36,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp3); - } - } - - if ( p!=NULL && (p->upper_range!=0 || p->tclass || old_not) ) - list_add(&MetaTokenNodes, (void *)p); - - if ( first_on_line ) { - CurAltStart = (Junction *)zzaRet.left; - altAdd(CurAltStart); /* MR7 */ - p->altstart = CurAltStart; - } - if ( p!=NULL ) - p->use_def_MT_handler = use_def_MT_handler || local_use_def_MT_handler; - _retv = (Node *)p; - } - else { - if ( (LA(1)==WildCard) ) { - if ( old_not ) warn("~ WILDCARD is an undefined operation (implies 'nothing')"); - zzmatch(WildCard); - zzaRet = buildWildCard(LATEXT(1)); p=((TokNode *)((Junction *)zzaRet.left)->p1); - zzCONSUME; - - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (LA(1)==125) ) { - zzmatch(125); - p->astnode=ASTroot; - zzCONSUME; - - } - else { - if ( (setwd7[LA(1)]&0x8) ) { - p->astnode=ASTchild; - } - else { - if ( (LA(1)==103) ) { - zzmatch(103); - p->astnode=ASTexclude; - zzCONSUME; - - } - else {zzFAIL(1,zzerr37,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - } - zzEXIT(zztasp3); - } - } - list_add(&MetaTokenNodes, (void *)p); - - if ( first_on_line ) { - CurAltStart = (Junction *)zzaRet.left; - altAdd(CurAltStart); /* MR7 */ - p->altstart = CurAltStart; - if ( label!=NULL ) { - p->el_label = label->str; - label->elem = (Node *)p; - } - } - _retv = (Node *)p; - } - else { - if ( (LA(1)==NonTerminal) ) { - if ( old_not ) warn("~ NONTERMINAL is an undefined operation"); - zzmatch(NonTerminal); - zzaRet = buildRuleRef(LATEXT(1)); - zzCONSUME; - - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (LA(1)==103) ) { - zzmatch(103); - q = (RuleRefNode *) ((Junction *)zzaRet.left)->p1; - q->astnode=ASTexclude; - zzCONSUME; - - } - else { - if ( (setwd7[LA(1)]&0x10) ) { - } - else {zzFAIL(1,zzerr38,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp3); - } - } - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (setwd7[LA(1)]&0x20) ) { - { - zzBLOCK(zztasp4); - zzMake0; - { - if ( (LA(1)==104) ) { - zzmatch(104); zzCONSUME; - } - else { - if ( (LA(1)==PassAction) ) { - } - else {zzFAIL(1,zzerr39,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp4); - } - } - zzmatch(PassAction); - addParm(((Junction *)zzaRet.left)->p1, LATEXT(1)); - zzCONSUME; - - } - else { - if ( (setwd7[LA(1)]&0x40) ) { - } - else {zzFAIL(1,zzerr40,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp3); - } - } - rr=(RuleRefNode *) ((Junction *)zzaRet.left)->p1; - { - zzBLOCK(zztasp3); - zzMake0; - { - char *a; - if ( (LA(1)==105) ) { - zzmatch(105); zzCONSUME; - zzmatch(PassAction); - - a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(a!=NULL, "rule element: cannot allocate assignment"); - strcpy(a, LATEXT(1)); - rr->assign = a; - zzCONSUME; - - } - else { - if ( (setwd7[LA(1)]&0x80) ) { - } - else {zzFAIL(1,zzerr41,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp3); - } - } - - if ( label!=NULL ) { - rr->el_label = label->str; - label->elem = (Node *)rr; - } - if ( first_on_line ) { - CurAltStart = (Junction *)zzaRet.left; - altAdd(CurAltStart); /* MR7 */ - ((RuleRefNode *)((Junction *)zzaRet.left)->p1)->altstart = CurAltStart; - } - _retv = (Node *)rr; - } - else {zzFAIL(1,zzerr42,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - } - } - zzEXIT(zztasp2); - } - } - } - else { - if ( (LA(1)==Action) ) { - if ( old_not ) warn("~ ACTION is an undefined operation"); - zzmatch(Action); - zzaArg(zztasp1,0) = buildAction(LATEXT(1),action_file,action_line, 0); - zzCONSUME; - - if ( first_on_line ) { /* MR7 */ - CurAltStart = (Junction *)zzaArg(zztasp1,0 ).left; /* MR7 */ - altAdd(CurAltStart); /* MR7 */ - }; - _retv = (Node *) ((Junction *)zzaArg(zztasp1,0 ).left)->p1; - } - else { - if ( (LA(1)==Pred) ) { - if ( old_not ) warn("~ SEMANTIC-PREDICATE is an undefined operation"); - zzmatch(Pred); - zzaArg(zztasp1,0) = buildAction(LATEXT(1),action_file,action_line, 1); - zzCONSUME; - - act = (ActionNode *) ((Junction *)zzaArg(zztasp1,0 ).left)->p1; - if (numericActionLabel) { /* MR10 */ - list_add(&NumericPredLabels,act); /* MR10 */ - numericActionLabel=0; /* MR10 */ - }; /* MR10 */ - { - zzBLOCK(zztasp2); - zzMake0; - { - char *a; - if ( (LA(1)==PassAction) ) { - zzmatch(PassAction); - - a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(a!=NULL, "rule element: cannot allocate predicate fail action"); - strcpy(a, LATEXT(1)); - act->pred_fail = a; - zzCONSUME; - - } - else { - if ( (setwd8[LA(1)]&0x1) ) { - } - else {zzFAIL(1,zzerr43,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - if ( first_on_line ) { /* MR7 */ - CurAltStart = (Junction *)zzaArg(zztasp1,0 ).left; /* MR7 */ - altAdd(CurAltStart); /* MR7 */ - }; - _retv = (Node *)act; - } - else { - if ( (setwd8[LA(1)]&0x2) ) { - if ( old_not ) warn("~ BLOCK is an undefined operation"); - BlkLevel++; - if (BlkLevel >= MAX_BLK_LEVEL) fatal("Blocks nested too deeply"); - /* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID; - /* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==Pragma) ) { - zzmatch(Pragma); zzCONSUME; - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (LA(1)==126) ) { - zzmatch(126); - approx=LL_k; - zzCONSUME; - - } - else { - if ( (LA(1)==127) ) { - zzmatch(127); - approx = 1; - zzCONSUME; - - } - else { - if ( (LA(1)==128) ) { - zzmatch(128); - approx = 2; - zzCONSUME; - - } - else {zzFAIL(1,zzerr44,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - } - zzEXIT(zztasp3); - } - } - } - else { - if ( (setwd8[LA(1)]&0x4) ) { - } - else {zzFAIL(1,zzerr45,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==FirstSetSymbol) ) { - zzmatch(FirstSetSymbol); zzCONSUME; - zzmatch(114); zzCONSUME; - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (LA(1)==NonTerminal) ) { - zzmatch(NonTerminal); - - /* MR21 */ pFirstSetSymbol = (char *) calloc(strlen(LATEXT(1))+1, - /* MR21 */ sizeof(char)); - /* MR21 */ require(pFirstSetSymbol!=NULL, - /* MR21 */ "cannot allocate first set name"); - /* MR21 */ strcpy(pFirstSetSymbol, LATEXT(1)); - /* MR21 */ - zzCONSUME; - - } - else { - if ( (LA(1)==TokenTerm) ) { - zzmatch(TokenTerm); - - /* MR21 */ pFirstSetSymbol = (char *) calloc(strlen(LATEXT(1))+1, - /* MR21 */ sizeof(char)); - /* MR21 */ require(pFirstSetSymbol!=NULL, - /* MR21 */ "cannot allocate first set name"); - /* MR21 */ strcpy(pFirstSetSymbol, LATEXT(1)); - /* MR21 */ - zzCONSUME; - - } - else {zzFAIL(1,zzerr46,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp3); - } - } - zzmatch(115); zzCONSUME; - } - else { - if ( (setwd8[LA(1)]&0x8) ) { - } - else {zzFAIL(1,zzerr47,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==114) ) { - zzmatch(114); zzCONSUME; - block( &toksrefd,&rulesrefd ); - zzmatch(115); - blk = zzaRet = zzaArg(zztasp2,2); - /* MR23 */ CurBlockID_array[BlkLevel] = (-1); - /* MR23 */ CurAltNum_array[BlkLevel] = (-1); - --BlkLevel; - zzCONSUME; - - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (LA(1)==129) ) { - zzmatch(129); - zzaRet = makeLoop(zzaRet,approx,pFirstSetSymbol); - zzCONSUME; - - } - else { - if ( (LA(1)==130) ) { - zzmatch(130); - zzaRet = makePlus(zzaRet,approx,pFirstSetSymbol); - zzCONSUME; - - } - else { - if ( (LA(1)==131) ) { - zzmatch(131); zzCONSUME; - { - zzBLOCK(zztasp4); - zzMake0; - { - if ( (setwd8[LA(1)]&0x10) ) { - { - zzBLOCK(zztasp5); - zzMake0; - { - if ( (LA(1)==132) ) { - zzmatch(132); - ampersandStyle=0; - zzCONSUME; - - } - else { - if ( (LA(1)==113) ) { - zzmatch(113); - ampersandStyle=1; - zzCONSUME; - - } - else {zzFAIL(1,zzerr48,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp5); - } - } - zzmatch(Pred); - zzaRet = buildAction(LATEXT(1),action_file,action_line,1); - zzCONSUME; - - act = (ActionNode *) ((Junction *)zzaRet.left)->p1; - semDepth=predicateLookaheadDepth(act); - if (numericActionLabel) { /* MR10 */ - list_add(&NumericPredLabels,act); /* MR10 */ - numericActionLabel=0; /* MR10 */ - }; /* MR10 */ - { - zzBLOCK(zztasp5); - zzMake0; - { - char *a; - if ( (LA(1)==PassAction) ) { - zzmatch(PassAction); - - a = (char *)calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(a!=NULL, "rule element: cannot allocate predicate fail action"); - strcpy(a, LATEXT(1)); - act->pred_fail = a; - zzCONSUME; - - } - else { - if ( (setwd8[LA(1)]&0x20) ) { - } - else {zzFAIL(1,zzerr49,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp5); - } - } - if ( first_on_line) { /* MR7 */ - CurAltStart=(Junction *)zzaRet.left; /* MR7 */ - altAdd(CurAltStart); /* MR7 */ - }; - _retv = (Node *)act; - - pred = computePredFromContextGuard(blk,&predMsgDone); /* MR10 */ - if ( pred==NULL) { /* MR10 */ - if ( !predMsgDone) err("invalid or missing context guard"); /* MR10 */ - predMsgDone=1; /* MR10 */ - } else { /* MR10 */ - act->guardNodes=(Junction *)blk.left; /* MR11 */ - pred->expr = act->action; - pred->source = act; - /* MR10 */ pred->ampersandStyle = ampersandStyle; /* 0 means (g)? => ... 1 means (g)? && ... */ - /* MR13 */ if (pred->tcontext != NULL) { - /* MR13 */ height=MR_max_height_of_tree(pred->tcontext); - /* MR13 */ equal_height=MR_all_leaves_same_height(pred->tcontext,height); - /* MR13 */ if (! equal_height) { - /* MR13 */ errFL("in guarded predicates all tokens in the guard must be at the same height", - /* MR13 */ FileStr[act->file],act->line); - /* MR13 */ }; - /* MR13 */ } - /* MR10 */ if (ampersandStyle) { - /* MR10 */ act->ampersandPred = pred; - /* MR11 */ if (! HoistPredicateContext) { - /* MR11 */ errFL("without \"-prc on\" (guard)? && <>? ... doesn't make sense", - /* MR11 */ FileStr[act->file],act->line); - /* MR11 */ }; - /* MR10 */ } else { - /* MR10 */ act->guardpred = pred; - /* MR10 */ }; - /* MR10 */ if (pred->k != semDepth) { - /* MR10 */ warn(eMsgd2("length of guard (%d) does not match the length of semantic predicate (%d)", - /* MR10 */ pred->k,semDepth)); - /* MR10 */ }; - } - } - else { - if ( (setwd8[LA(1)]&0x40) ) { - zzaRet = makeBlk(zzaRet,approx,pFirstSetSymbol); - FoundGuessBlk = 1; - ((Junction *) ((Junction *)zzaRet.left)->p1)->guess=1; - if ( ! first_on_line ) { - err("(...)? predicate must be first element of production"); - } - } - else {zzFAIL(1,zzerr50,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp4); - } - } - } - else { - if ( (setwd8[LA(1)]&0x80) ) { - zzaRet = makeBlk(zzaRet,approx,pFirstSetSymbol); - } - else {zzFAIL(1,zzerr51,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - } - } - zzEXIT(zztasp3); - } - } - - if ( pred==NULL && !predMsgDone) { /* MR10 */ - ((Junction *)((Junction *)zzaRet.left)->p1)->blockid = CurBlockID; - ((Junction *)((Junction *)zzaRet.left)->p1)->tokrefs = toksrefd; - ((Junction *)((Junction *)zzaRet.left)->p1)->rulerefs = rulesrefd; - if ( first_on_line ) { /* MR7 */ - CurAltStart = (Junction *)((Junction *)((Junction *)zzaRet.left)->p1); /* MR7 */ - altAdd(CurAltStart); /* MR7 */ - }; /* MR7 */ - _retv = (Node *) ((Junction *)zzaRet.left)->p1; - } - } - else { - if ( (LA(1)==102) ) { - zzmatch(102); zzCONSUME; - block( &toksrefd,&rulesrefd ); - zzaRet = makeOpt(zzaArg(zztasp2,2),approx,pFirstSetSymbol); - /* MR23 */ CurBlockID_array[BlkLevel] = (-1); - /* MR23 */ CurAltNum_array[BlkLevel] = (-1); - --BlkLevel; - zzmatch(98); - - ((Junction *)((Junction *)zzaRet.left)->p1)->blockid = CurBlockID; - ((Junction *)((Junction *)zzaRet.left)->p1)->tokrefs = toksrefd; - ((Junction *)((Junction *)zzaRet.left)->p1)->rulerefs = rulesrefd; - zzCONSUME; - - if ( first_on_line ) { /* MR7 */ - CurAltStart = (Junction *) ((Junction *)((Junction *)zzaRet.left)->p1); /* MR7 */ - altAdd(CurAltStart); /* MR7 */ - }; - _retv = (Node *) ((Junction *)zzaRet.left)->p1; - } - else {zzFAIL(1,zzerr52,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - } - else { - if ( (LA(1)==129) ) { - zzmatch(129); - warn("don't you want a ')' with that '*'?"); CannotContinue=TRUE; - zzCONSUME; - - } - else { - if ( (LA(1)==130) ) { - zzmatch(130); - warn("don't you want a ')' with that '+'?"); CannotContinue=TRUE; - zzCONSUME; - - } - else { - if ( (LA(1)==105) ) { - zzmatch(105); - warn("'>' can only appear after a nonterminal"); CannotContinue=TRUE; - zzCONSUME; - - } - else { - if ( (LA(1)==PassAction) ) { - zzmatch(PassAction); - warn("[...] out of context 'rule > [...]'"); - CannotContinue=TRUE; - zzCONSUME; - - } - else {zzFAIL(1,zzerr53,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - } - } - } - } - } - } - zzEXIT(zztasp1); - return _retv; -fail: - zzEXIT(zztasp1); - CannotContinue=TRUE; - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd9, 0x1); - return _retv; - } -} - -void -#ifdef __USE_PROTOS -default_exception_handler(void) -#else -default_exception_handler() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - DefaultExGroup = exception_group(); - - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd9, 0x2); - } -} - -ExceptionGroup * -#ifdef __USE_PROTOS -exception_group(void) -#else -exception_group() -#endif -{ - ExceptionGroup * _retv; - zzRULE; - zzBLOCK(zztasp1); - PCCTS_PURIFY(_retv,sizeof(ExceptionGroup * )) - zzMake0; - { - ExceptionHandler *h; LabelEntry *label=NULL; /* MR6 */ - FoundException = 1; FoundExceptionGroup = 1; - zzmatch(133); - _retv = (ExceptionGroup *)calloc(1, sizeof(ExceptionGroup)); - zzCONSUME; - - { - zzBLOCK(zztasp2); - zzMake0; - { - char *p; - if ( (LA(1)==PassAction) ) { - zzmatch(PassAction); - - p = LATEXT(1)+1; - p[strlen(p)-1] = '\0'; /* kill trailing space */ - label = (LabelEntry *) hash_get(Elabel, LATEXT(1)+1); - if ( label==NULL ) - { - err(eMsg1("unknown label in exception handler: '%s'", LATEXT(1)+1)); - } - zzCONSUME; - - } - else { - if ( (setwd9[LA(1)]&0x4) ) { - } - else {zzFAIL(1,zzerr54,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - { - zzBLOCK(zztasp2); - zzMake0; - { - while ( (LA(1)==135) ) { - h = exception_handler(); - - list_add(&(_retv->handlers), (void *)h); - zzLOOP(zztasp2); - } - zzEXIT(zztasp2); - } - } - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==134) ) { - zzmatch(134); zzCONSUME; - zzmatch(106); zzCONSUME; - zzmatch(Action); - { - ExceptionHandler *eh = (ExceptionHandler *) - calloc(1, sizeof(ExceptionHandler)); - char *a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(eh!=NULL, "exception: cannot allocate handler"); - require(a!=NULL, "exception: cannot allocate action"); - strcpy(a, LATEXT(1)); - eh->action = a; - eh->signalname = (char *) calloc(strlen("default")+1, sizeof(char)); - require(eh->signalname!=NULL, "exception: cannot allocate sig name"); - strcpy(eh->signalname, "default"); - list_add(&(_retv->handlers), (void *)eh); - } - zzCONSUME; - - } - else { - if ( (setwd9[LA(1)]&0x8) ) { - } - else {zzFAIL(1,zzerr55,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - - if ( label!=NULL ) { - /* Record ex group in sym tab for this label */ - if ( label->ex_group!=NULL ) { - err(eMsg1("duplicate exception handler for label '%s'",label->str)); - } else { - label->ex_group = _retv; - /* Label the exception group itself */ - _retv->label = label->str; - /* Make the labelled element pt to the exception also */ - /* MR6 */ if (label->elem == NULL) { - /* MR6 */ err(eMsg1("reference in exception handler to undefined label '%s'",label->str)); - /* MR6 */ } else { - switch ( label->elem->ntype ) { - case nRuleRef : - { - RuleRefNode *r = (RuleRefNode *)label->elem; - r->ex_group = _retv; - break; - } - case nToken : - { - TokNode *t = (TokNode *)label->elem; - t->ex_group = _retv; - break; - } - } /* end switch */ - /* MR6 */ }; /* end test on label->elem */ - } /* end test on label->ex_group */ - - } /* end test on exception label */ - -/* MR7 */ - /* MR7 */ if (BlkLevel == 1 && label == NULL) { - /* MR7 */ _retv->forRule=1; - /* MR7 */ } else if (label == NULL) { - /* MR7 */ _retv->altID = makeAltID(CurBlockID_array[BlkLevel], CurAltNum_array[BlkLevel]); - /* MR7 */ egAdd(_retv); - /* MR7 */ } else { - /* MR7 */ _retv->labelEntry=label; - /* MR7 */ }; - /* MR7 */ - /* MR7 */ /* You may want to remove this exc from the rule list */ - /* MR7 */ /* and handle at the labeled element site. */ - /* MR7 */ - /* MR7 */ if (label != NULL) { - /* MR7 */ _retv = NULL; - /* MR7 */ }; - zzEXIT(zztasp1); - return _retv; -fail: - zzEXIT(zztasp1); - CannotContinue=TRUE; - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd9, 0x10); - return _retv; - } -} - -ExceptionHandler * -#ifdef __USE_PROTOS -exception_handler(void) -#else -exception_handler() -#endif -{ - ExceptionHandler * _retv; - zzRULE; - zzBLOCK(zztasp1); - PCCTS_PURIFY(_retv,sizeof(ExceptionHandler * )) - zzMake0; - { - ; - zzmatch(135); - - _retv = (ExceptionHandler *)calloc(1, sizeof(ExceptionHandler)); - require(_retv!=NULL, "exception: cannot allocate handler"); - zzCONSUME; - - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==NonTerminal) ) { - zzmatch(NonTerminal); - - _retv->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(_retv->signalname!=NULL, "exception: cannot allocate sig name"); - strcpy(_retv->signalname, LATEXT(1)); - zzCONSUME; - - } - else { - if ( (LA(1)==TokenTerm) ) { - zzmatch(TokenTerm); - - _retv->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(_retv->signalname!=NULL, "exception: cannot allocate sig name"); - strcpy(_retv->signalname, LATEXT(1)); - zzCONSUME; - - } - else {zzFAIL(1,zzerr56,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - zzmatch(106); zzCONSUME; - { - zzBLOCK(zztasp2); - zzMake0; - { - _retv->action = NULL; - if ( (LA(1)==Action) ) { - zzmatch(Action); - - _retv->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(_retv->action!=NULL, "exception: cannot allocate action"); - strcpy(_retv->action, LATEXT(1)); - zzCONSUME; - - } - else { - if ( (setwd9[LA(1)]&0x20) ) { - } - else {zzFAIL(1,zzerr57,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - zzEXIT(zztasp1); - return _retv; -fail: - zzEXIT(zztasp1); - CannotContinue=TRUE; - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd9, 0x40); - return _retv; - } -} - -void -#ifdef __USE_PROTOS -enum_file(char * fname) -#else -enum_file(fname) - char *fname ; -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - if ( (setwd9[LA(1)]&0x80) ) { - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==143) ) { - zzmatch(143); zzCONSUME; - zzmatch(ID); zzCONSUME; - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (LA(1)==149) ) { - zzmatch(149); zzCONSUME; - zzmatch(ID); zzCONSUME; - } - else { - if ( (setwd10[LA(1)]&0x1) ) { - } - else {zzFAIL(1,zzerr58,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp3); - } - } - } - else { - if ( (setwd10[LA(1)]&0x2) ) { - } - else {zzFAIL(1,zzerr59,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==151) ) { - { - zzBLOCK(zztasp3); - int zzcnt=1; - zzMake0; - { - do { - enum_def( fname ); - zzLOOP(zztasp3); - } while ( (LA(1)==151) ); - zzEXIT(zztasp3); - } - } - } - else { - if ( (LA(1)==149) ) { - defines( fname ); - } - else {zzFAIL(1,zzerr60,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - } - else { - if ( (LA(1)==Eof) ) { - } - else {zzFAIL(1,zzerr61,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd10, 0x4); - } -} - -void -#ifdef __USE_PROTOS -defines(char * fname) -#else -defines(fname) - char *fname ; -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - int v; int maxt=(-1); char *t; - { - zzBLOCK(zztasp2); - int zzcnt=1; - zzMake0; - { - do { - zzmatch(149); zzCONSUME; - zzmatch(ID); - t = mystrdup(LATEXT(1)); - zzCONSUME; - - zzmatch(INT); - - v = atoi(LATEXT(1)); - /* fprintf(stderr, "#token %s=%d\n", t, v);*/ - - /* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */ - /* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */ - /* MR2 Don't let #tokdefs be confused by */ - /* MR2 DLGminToken and DLGmaxToken */ - - if ( ! isDLGmaxToken(t)) { /* MR2 */ - TokenNum = v; - if ( v>maxt ) maxt=v; - if ( Tnum( t ) == 0 ) { - addForcedTname( t, v ); - } else { - warnFL(eMsg1("redefinition of token %s; ignored",t), fname,zzline); - }; -}; - zzCONSUME; - - zzLOOP(zztasp2); - } while ( (LA(1)==149) ); - zzEXIT(zztasp2); - } - } - TokenNum = maxt + 1; - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd10, 0x8); - } -} - -void -#ifdef __USE_PROTOS -enum_def(char * fname) -#else -enum_def(fname) - char *fname ; -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - int v= 0; int maxt=(-1); char *t; - zzmatch(151); zzCONSUME; - zzmatch(ID); zzCONSUME; - zzmatch(152); zzCONSUME; - zzmatch(ID); - t = mystrdup(LATEXT(1)); - zzCONSUME; - - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==153) ) { - zzmatch(153); zzCONSUME; - zzmatch(INT); - v=atoi(LATEXT(1)); - zzCONSUME; - - } - else { - if ( (setwd10[LA(1)]&0x10) ) { - v++; - } - else {zzFAIL(1,zzerr62,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - - /* fprintf(stderr, "#token %s=%d\n", t, v);*/ - TokenNum = v; - if ( v>maxt ) maxt=v; /* MR3 */ - if ( Tnum( t ) == 0 ) addForcedTname( t, v ); - else { - warnFL(eMsg1("redefinition of token %s; ignored",t), fname,zzline); - } - { - zzBLOCK(zztasp2); - zzMake0; - { - while ( (LA(1)==154) ) { - zzmatch(154); zzCONSUME; - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (LA(1)==ID)&&(isDLGmaxToken(LATEXT(1))) ) { - if (!(isDLGmaxToken(LATEXT(1))) ) {zzfailed_pred(" isDLGmaxToken(LATEXT(1))",0 /* report */, { 0; /* no user action */ } );} - zzmatch(ID); zzCONSUME; - { - zzBLOCK(zztasp4); - zzMake0; - { - if ( (LA(1)==153) ) { - zzmatch(153); zzCONSUME; - zzmatch(INT); zzCONSUME; - } - else { - if ( (setwd10[LA(1)]&0x20) ) { - } - else {zzFAIL(1,zzerr63,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp4); - } - } - } - else { - if ( (LA(1)==ID) ) { - zzmatch(ID); - t = mystrdup(LATEXT(1)); - zzCONSUME; - - { - zzBLOCK(zztasp4); - zzMake0; - { - if ( (LA(1)==153) ) { - zzmatch(153); zzCONSUME; - zzmatch(INT); - v=atoi(LATEXT(1)); - zzCONSUME; - - } - else { - if ( (setwd10[LA(1)]&0x40) ) { - v++; - } - else {zzFAIL(1,zzerr64,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp4); - } - } - - /* fprintf(stderr, "#token %s=%d\n", t, v);*/ - TokenNum = v; - if ( v>maxt ) maxt=v; /* MR3 */ - if ( Tnum( t ) == 0 ) addForcedTname( t, v ); - else { - warnFL(eMsg1("redefinition of token %s; ignored",t), fname,zzline); - } - } - else { - if ( (setwd10[LA(1)]&0x80) ) { - } - else {zzFAIL(1,zzerr65,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - } - zzEXIT(zztasp3); - } - } - zzLOOP(zztasp2); - } - zzEXIT(zztasp2); - } - } - zzmatch(155); zzCONSUME; - zzmatch(156); - TokenNum = maxt + 1; - zzCONSUME; - - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd11, 0x1); - } -} - - -/* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */ -/* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */ -/* MR2 Don't let #tokdefs be confused by */ -/* MR2 DLGminToken and DLGmaxToken */ - -/* semantic check on DLGminToken and DLGmaxmaxToken in #tokdefs */ - -#ifdef __USE_PROTOS -static int isDLGmaxToken(char *Token) -#else -static int isDLGmaxToken(Token) -char * Token; -#endif -{ -static char checkStr1[] = "DLGmaxToken"; -static char checkStr2[] = "DLGminToken"; - - if (strcmp(Token, checkStr1) == 0) -return 1; -else if (strcmp(Token, checkStr2) == 0) -return 1; -else -return 0; -} - -/* semantics of #token */ -static void -#ifdef __USE_PROTOS -chkToken(char *t, char *e, char *a, int tnum) -#else -chkToken(t,e,a,tnum) -char *t, *e, *a; -int tnum; -#endif -{ -TermEntry *p; - - /* check to see that they don't try to redefine a token as a token class */ -if ( t!=NULL ) { -p = (TermEntry *) hash_get(Tname, t); -if ( p!=NULL && p->classname ) { - err(eMsg1("redefinition of #tokclass '%s' to #token not allowed; ignored",t)); - if ( a!=NULL ) free((char *)a); - return; -} -} - - if ( t==NULL && e==NULL ) { /* none found */ -err("#token requires at least token name or rexpr"); -} -else if ( t!=NULL && e!=NULL ) { /* both found */ -if ( UserDefdTokens ) { /* if #tokdefs, must not define new */ - p = (TermEntry *) hash_get(Tname, t); - if ( p == NULL) { - err(eMsg1("new token definition '%s' not allowed - only #token with name already defined by #tokdefs file allowed",t)); - return; - }; -} -Tklink(t, e); -if ( a!=NULL ) { - if ( hasAction(e) ) { - err(eMsg1("redefinition of action for %s; ignored",e)); - } - else setHasAction(e, a); -} -} -else if ( t!=NULL ) { /* only one found */ -if ( UserDefdTokens ) { - p = (TermEntry *) hash_get(Tname, t); - if (p == NULL) { - err(eMsg1("new token definition '%s' not allowed - only #token with name already defined by #tokdefs file allowed",t)); - }; - return; -} -if ( Tnum( t ) == 0 ) addTname( t ); -else { - err(eMsg1("redefinition of token %s; ignored",t)); -} -if ( a!=NULL ) { - err(eMsg1("action cannot be attached to a token name (%s); ignored",t)); - free((char *)a); -} -} -else if ( e!=NULL ) { -if ( Tnum( e ) == 0 ) addTexpr( e ); -else { - if ( hasAction(e) ) { - err(eMsg1("redefinition of action for expr %s; ignored",e)); - } - else if ( a==NULL ) { - err(eMsg1("redefinition of expr %s; ignored",e)); - } -} -if ( a!=NULL ) setHasAction(e, a); -} - - /* if a token type number was specified, then add the token ID and 'tnum' -* pair to the ForcedTokens list. (only applies if an id was given) -*/ -if ( t!=NULL && tnum>0 ) -{ -if ( set_el(tnum, reserved_positions) ) -{ - err(eMsgd("a token has already been forced to token number %d; ignored", tnum)); -} -else -{ - list_add(&ForcedTokens, newForcedToken(t,tnum)); - set_orel(tnum, &reserved_positions); -} -} -} - -static int -#ifdef __USE_PROTOS -match_token(char *s, char **nxt) -#else -match_token(s,nxt) -char *s; -char **nxt; -#endif -{ - if ( !(*s>='A' && *s<='Z') ) return 0; - s++; - while ( (*s>='a' && *s<='z') || - (*s>='A' && *s<='Z') || - (*s>='0' && *s<='9') || - *s=='_' ) - { - s++; - } - if ( *s!=' ' && *s!='}' ) return 0; - *nxt = s; - return 1; -} - -static int -#ifdef __USE_PROTOS -match_rexpr(char *s, char **nxt) -#else -match_rexpr(s,nxt) -char *s; -char **nxt; -#endif -{ - if ( *s!='"' ) return 0; - s++; - while ( *s!='"' ) - { - if ( *s=='\n' || *s=='\r' ) /* MR13 */ - warn("eoln found in regular expression"); - if ( *s=='\\' ) s++; - s++; - } - *nxt = s+1; - return 1; -} - -/* -* Walk a string "{ A .. Z }" where A..Z is a space separated list -* of token references (either labels or reg exprs). Return a -* string "inlineX_set" for some unique integer X. Basically, -* we pretend as if we had seen "#tokclass inlineX { A .. Z }" -* on the input stream outside of an action. -*/ -char * -#ifdef __USE_PROTOS -inline_set(char *s) -#else -inline_set(s) -char *s; -#endif -{ - char *nxt; - fprintf(stderr, "found consumeUntil( {...} )\n"); - while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;} - if ( *s!='{' ) - { - err("malformed consumeUntil( {...} ); missing '{'"); - return "bad_set"; - } - s++; - while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;} - while ( *s!='}' ) - { - if ( match_token(s,&nxt) ) fprintf(stderr, "found token %s\n", s); - else if ( match_rexpr(s,&nxt) ) fprintf(stderr, "found rexpr %s\n", s); - else { - err("invalid element in consumeUntil( {...} )"); - return "bad_set"; - } - s = nxt; - while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;} - } - return "inlineX_set"; -} - -/* ANTLR-specific syntax error message generator -* (define USER_ZZSYN when compiling so don't get 2 definitions) -*/ -void -#ifdef __USE_PROTOS -zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, -int k, char *bad_text) -#else -zzsyn(text, tok, egroup, eset, etok, k, bad_text) -char *text, *egroup, *bad_text; -int tok; -int etok; -int k; -SetWordType *eset; -#endif -{ -fprintf(stderr, ErrHdr, FileStr[CurFile]!=NULL?FileStr[CurFile]:"stdin", zzline); -fprintf(stderr, " syntax error at \"%s\"", (tok==zzEOF_TOKEN)?"EOF":text); -if ( !etok && !eset ) {fprintf(stderr, "\n"); return;} -if ( k==1 ) fprintf(stderr, " missing"); -else -{ -fprintf(stderr, "; \"%s\" not", bad_text); -if ( zzset_deg(eset)>1 ) fprintf(stderr, " in"); -} -if ( zzset_deg(eset)>0 ) zzedecode(eset); -else fprintf(stderr, " %s", zztokens[etok]); -if ( strlen(egroup) > (size_t)0 ) fprintf(stderr, " in %s", egroup); -fprintf(stderr, "\n"); -} diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/antlr.g b/Tools/CodeTools/TianoTools/Pccts/antlr/antlr.g deleted file mode 100644 index e6eda6010c..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/antlr.g +++ /dev/null @@ -1,2586 +0,0 @@ -/* - * antlr.g -- PCCTS Version 1.xx ANTLR - * - * Parse an antlr input grammar and build a syntax-diagram. - * - * Written in itself (needs at least 1.06 to work) - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-1995 - */ - -/* MR1 */ -/* MR1 10-Apr-97 MR1 Replace #if logic with #include "pcctscfg.h" */ -/* MR1 */ - -#header << - #include "pcctscfg.h" - #include "set.h" - #include - #include "syn.h" - #include "hash.h" - #include "generic.h" - #define zzcr_attr(attr,tok,t) - >> - -<< - -/* MR20 G. Hobbelt For Borland C++ 4.x & 5.x compiling with ALL warnings enabled */ -#if defined(__TURBOC__) -#pragma warn -aus /* unused assignment of 'xxx' */ -#endif - - -#ifdef __USE_PROTOS -static void chkToken(char *, char *, char *, int); -#else -static void chkToken(); -#endif - -#ifdef __USE_PROTOS -static int isDLGmaxToken(char *Token); /* MR3 */ -#else -static int isDLGmaxToken(); /* MR3 */ -#endif - -static int class_nest_level = 0; - -/* MR20 G. Hobbelt extern definitions moved to antlr.h */ - ->> - -#lexaction << -/* maintained, but not used for now */ -set AST_nodes_refd_in_actions = set_init; -int inAlt = 0; -set attribsRefdFromAction = set_init; /* MR20 */ -int UsedOldStyleAttrib = 0; -int UsedNewStyleLabel = 0; -#ifdef __USE_PROTOS -char *inline_set(char *); -#else -char *inline_set(); -#endif - -/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */ -/* MR1 in DLG action */ - -int tokenActionActive=0; /* MR1 */ - ->> - -#lexclass STRINGS -#token QuotedTerm "\"" << zzmode(START); >> -#token "\n|\r|\r\n" << - zzline++; - warn("eoln found in string"); - zzskip(); - >> -#token "\\(\n|\r|\r\n)" << zzline++; zzmore(); >> -#token "\\~[]" << zzmore(); >> -#token "~[\n\r\"\\]+" << zzmore(); >> - -#lexclass ACTION_STRINGS -#token "\"" << zzmode(ACTIONS); zzmore(); >> -#token "\n|\r|\r\n" << - zzline++; - warn("eoln found in string (in user action)"); - zzskip(); - >> -#token "\\(\n|\r|\r\n)" << zzline++; zzmore(); >> -#token "\\~[]" << zzmore(); >> -#token "~[\n\r\"\\]+" << zzmore(); >> - -#lexclass ACTION_CHARS -#token "'" << zzmode(ACTIONS); zzmore(); >> -#token "\n|\r|\r\n" << - zzline++; - warn("eoln found in char literal (in user action)"); - zzskip(); - >> -#token "\\~[]" << zzmore(); >> -#token "~[\n\r'\\]+" << zzmore(); >> - -#lexclass ACTION_COMMENTS -#token "\*/" << zzmode(ACTIONS); zzmore(); >> -#token "\*" << zzmore(); >> -#token "\n|\r|\r\n" << zzline++; zzmore(); DAWDLE; >> -#token "~[\n\r\*]+" << zzmore(); >> - -#lexclass TOK_DEF_COMMENTS -#token "\*/" << zzmode(PARSE_ENUM_FILE); - zzmore(); >> -#token "\*" << zzmore(); >> -#token "\n|\r|\r\n" << zzline++; zzmore(); DAWDLE; >> -#token "~[\n\r\*]+" << zzmore(); >> - -#lexclass TOK_DEF_CPP_COMMENTS -#token "\n|\r|\r\n" << zzline++; zzmode(PARSE_ENUM_FILE); zzskip(); DAWDLE; >> -#token "~[\n\r]+" << zzskip(); >> - -#lexclass ACTION_CPP_COMMENTS -#token "\n|\r|\r\n" << zzline++; zzmode(ACTIONS); zzmore(); DAWDLE; >> -#token "~[\n\r]+" << zzmore(); >> - -#lexclass CPP_COMMENTS -#token "\n|\r|\r\n" << zzline++; zzmode(START); zzskip(); DAWDLE; >> -#token "~[\n\r]+" << zzskip(); >> - -#lexclass COMMENTS -#token "\*/" << zzmode(START); zzskip(); >> -#token "\*" << zzskip(); >> -#token "\n|\r|\r\n" << zzline++; zzskip(); DAWDLE; >> -#token "~[\n\r\*]+" << zzskip(); >> - -/* - * This lexical class accepts actions of type [..] and <<..>> - * - * It translates the following special items for C: - * - * $j --> "zzaArg(current zztasp, j)" - * $i.j --> "zzaArg(zztaspi, j)" - * $i.nondigit> "zzaArg(current zztasp, i).nondigit" - * $$ --> "zzaRet" - * $alnum --> "alnum" (used to ref parameters) - * $rule --> "zzaRet" - * $retval --> "_retv.retval" if > 1 return values else "_retv" - * $[token, text] --> "zzconstr_attr(token, text)" - * $[] --> "zzempty_attr()" - * - * It translates the following special items for C++: - * (attributes are now stored with 'Token' and $i's are only - * pointers to the Tokens. Rules don't have attributes now.) - * - * $j --> "_tbj" where b is the block level - * $i.j --> "_tij" - * $j->nondigit> "_tbj->nondigit" - * $$ --> "$$" - * $alnum --> "alnum" (used to ref parameters) - * $rule --> "$rule" - * $retval --> "_retv.retval" if > 1 return values else "_retv" - * $[token, text] --> invalid - * $[] --> invalid - * - * And, for trees: - * - * #0 --> "(*_root)" - * #i --> "zzastArg(i)" - * #[args] --> "zzmk_ast(zzastnew(), args)" - * #[] --> "zzastnew()" - * #( root, child1, ..., childn ) - * --> "zztmake(root, child1, ...., childn, NULL)" - * #() --> "NULL" - * - * For C++, ... - * - * #0 --> "(*_root)" - * #i --> "_astbi" where b is the block level - * #alnum --> "alnum_ast" (used to ref #label) - * #[args] --> "new AST(args)" - * #[] --> "new AST" - * #( root, child1, ..., childn ) - * --> "AST::tmake(root, child1, ...., childn, NULL)" - * #() --> "NULL" - * - * To escape, - * - * \] --> ] - * \) --> ) - * \$ --> $ - * \# --> # - * - * A stack is used to nest action terminators because they can be nested - * like crazy: << #[$[..],..] >> - */ -#lexclass ACTIONS -#token Action "\>\>" << /* these do not nest */ - zzmode(START); - NLATEXT[0] = ' '; - NLATEXT[1] = ' '; - zzbegexpr[0] = ' '; - zzbegexpr[1] = ' '; - if ( zzbufovf ) { - err( eMsgd("action buffer overflow; size %d",ZZLEXBUFSIZE)); - } - -/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */ -/* MR1 in DLG action */ -/* MR1 Doesn't matter what kind of action it is - reset*/ - - tokenActionActive=0; /* MR1 */ - >> -#token Pred "\>\>?" << /* these do not nest */ - zzmode(START); - NLATEXT[0] = ' '; - NLATEXT[1] = ' '; - zzbegexpr[0] = '\0'; - if ( zzbufovf ) { - err( eMsgd("predicate buffer overflow; size %d",ZZLEXBUFSIZE)); - }; -#ifdef __cplusplus__ -/* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); -#else -#ifdef __STDC__ -/* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); -#else -#ifdef __USE_PROTOS -/* MRxx */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); -#else -/* MR10 */ list_apply(CurActionLabels,mark_label_used_in_sem_pred); -#endif -#endif -#endif - >> -#token PassAction "\]" << if ( topint() == ']' ) { - popint(); - if ( istackempty() ) /* terminate action */ - { - zzmode(START); - NLATEXT[0] = ' '; - zzbegexpr[0] = ' '; - if ( zzbufovf ) { - err( eMsgd("parameter buffer overflow; size %d",ZZLEXBUFSIZE)); - } - } - else { - /* terminate $[..] and #[..] */ - if ( GenCC ) zzreplstr("))"); - else zzreplstr(")"); - zzmore(); - } - } - else if ( topint() == '|' ) { /* end of simple [...] */ - popint(); - zzmore(); - } - else zzmore(); - >> -#token "consumeUntil\( [\ \t]* \{~[\}]+\} [\ \t]* \)" - << - zzmore(); - zzreplstr(inline_set(zzbegexpr+ - strlen("consumeUntil("))); - >> -#token "consumeUntil\( ~[\)]+ \)" - << zzmore(); >> -#token "\n|\r|\r\n" << zzline++; zzmore(); DAWDLE; >> -#token "\>" << zzmore(); >> -#token "$" << zzmore(); >> -#token "$$" << if ( !GenCC ) {zzreplstr("zzaRet"); zzmore();} - else err("$$ use invalid in C++ mode"); >> - -#token "$\[\]" << if ( !GenCC ) {zzreplstr("zzempty_attr"); zzmore();} - else err("$[] use invalid in C++ mode"); >> -#token "$\[" << - pushint(']'); - if ( !GenCC ) zzreplstr("zzconstr_attr("); - else err("$[..] use invalid in C++ mode"); - zzmore(); - >> -#token "$[0-9]+" <<{ - static char buf[100]; - numericActionLabel=1; /* MR10 */ - if ( strlen(zzbegexpr)>(size_t)85 ) - fatal("$i attrib ref too big"); - set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction); - if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s)", - BlkLevel-1,zzbegexpr+1); - else sprintf(buf,"_t%d%s", - BlkLevel-1,zzbegexpr+1); - zzreplstr(buf); - zzmore(); - UsedOldStyleAttrib = 1; - if ( UsedNewStyleLabel ) - err("cannot mix old-style $i with new-style labels"); - } - >> -#token "$[0-9]+." <<{ - static char buf[100]; - numericActionLabel=1; /* MR10 */ - if ( strlen(zzbegexpr)>(size_t)85 ) - fatal("$i.field attrib ref too big"); - zzbegexpr[strlen(zzbegexpr)-1] = ' '; - set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction); - if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s).", - BlkLevel-1,zzbegexpr+1); - else sprintf(buf,"_t%d%s.", - BlkLevel-1,zzbegexpr+1); - zzreplstr(buf); - zzmore(); - UsedOldStyleAttrib = 1; - if ( UsedNewStyleLabel ) - err("cannot mix old-style $i with new-style labels"); - } - >> -#token "$[0-9]+.[0-9]+" <<{ - static char buf[100]; - static char i[20], j[20]; - char *p,*q; - numericActionLabel=1; /* MR10 */ - if (strlen(zzbegexpr)>(size_t)85) fatal("$i.j attrib ref too big"); - for (p=zzbegexpr+1,q= &i[0]; *p!='.'; p++) { - if ( q == &i[20] ) - fatalFL("i of $i.j attrib ref too big", - FileStr[CurFile], zzline ); - *q++ = *p; - } - *q = '\0'; - for (p++, q= &j[0]; *p!='\0'; p++) { - if ( q == &j[20] ) - fatalFL("j of $i.j attrib ref too big", - FileStr[CurFile], zzline ); - *q++ = *p; - } - *q = '\0'; - if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%s,%s)",i,j); - else sprintf(buf,"_t%s%s",i,j); - zzreplstr(buf); - zzmore(); - UsedOldStyleAttrib = 1; - if ( UsedNewStyleLabel ) - err("cannot mix old-style $i with new-style labels"); - } - >> -#token "$[_a-zA-Z][_a-zA-Z0-9]*" - <<{ static char buf[300]; LabelEntry *el; - zzbegexpr[0] = ' '; - if ( CurRule != NULL && - strcmp(CurRule, &zzbegexpr[1])==0 ) { - if ( !GenCC ) zzreplstr("zzaRet"); - } - else if ( CurRetDef != NULL && - strmember(CurRetDef, &zzbegexpr[1])) { - if ( hasMultipleOperands( CurRetDef ) ) { - require (strlen(zzbegexpr)<=(size_t)285, - "$retval attrib ref too big"); - sprintf(buf,"_retv.%s",&zzbegexpr[1]); - zzreplstr(buf); - } - else zzreplstr("_retv"); - } - else if ( CurParmDef != NULL && - strmember(CurParmDef, &zzbegexpr[1])) { - ; - } - else if ( Elabel==NULL ) { - { err("$-variables in actions outside of rules are not allowed"); } - } else if ( (el=(LabelEntry *)hash_get(Elabel, &zzbegexpr[1]))!=NULL ) { -/* MR10 */ -/* MR10 */ /* element labels might exist without an elem when */ -/* MR10 */ /* it is a forward reference (to a rule) */ -/* MR10 */ -/* MR10 */ if ( GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) ) -/* MR10 */ { err(eMsg1("There are no token ptrs for rule references: '$%s'",&zzbegexpr[1])); } -/* MR10 */ -/* MR10 */ if ( !GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) && GenAST) { -/* MR10 */ err("You can no longer use attributes returned by rules when also using ASTs"); -/* MR10 */ err(" Use upward inheritance (\"rule >[Attrib a] : ... <<$a=...\>\>\")"); -/* MR10 */ }; -/* MR10 */ -/* MR10 */ /* keep track of <<... $label ...>> for semantic predicates in guess mode */ -/* MR10 */ /* element labels contain pointer to the owners node */ -/* MR10 */ -/* MR10 */ if (el->elem != NULL && el->elem->ntype == nToken) { -/* MR10 */ list_add(&CurActionLabels,el); -/* MR10 */ }; - } - else - warn(eMsg1("$%s not parameter, return value, (defined) element label",&zzbegexpr[1])); - } - zzmore(); - >> -#token "#0" << zzreplstr("(*_root)"); zzmore(); chkGTFlag(); >> -#token "#\[\]" << if ( GenCC ) { - if (NewAST) zzreplstr("(newAST)"); - else zzreplstr("(new AST)");} - else {zzreplstr("zzastnew()");} zzmore(); - chkGTFlag(); - >> -#token "#\(\)" << zzreplstr("NULL"); zzmore(); chkGTFlag(); >> -#token "#[0-9]+" <<{ - static char buf[100]; - if ( strlen(zzbegexpr)>(size_t)85 ) - fatal("#i AST ref too big"); - if ( GenCC ) sprintf(buf,"_ast%d%s",BlkLevel-1,zzbegexpr+1); - else sprintf(buf,"zzastArg(%s)",zzbegexpr+1); - zzreplstr(buf); - zzmore(); - set_orel(atoi(zzbegexpr+1), &AST_nodes_refd_in_actions); - chkGTFlag(); - } - >> - -/* MR14 Arpad Beszedes 26-May-98 - Add support for #line directives when antlr source is pre-processed - #lexclass ACTIONS -*/ - -#token "#line[\ \t]* [0-9]+ {[\ \t]* \"~[\"]+\" ([\ \t]* [0-9]*)* } (\n|\r|\r\n)" - << - zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore(); - getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr); - >> - -#token "#line ~[\n\r]* (\n|\r|\r\n)" - << - zzline++; zzmore(); - >> - -/* MR14 end of a block to support #line in antlr source code */ - -#token "#[_a-zA-Z][_a-zA-Z0-9]*" - << - if ( !(strcmp(zzbegexpr, "#ifdef")==0 || - strcmp(zzbegexpr, "#if")==0 || - strcmp(zzbegexpr, "#else")==0 || - strcmp(zzbegexpr, "#endif")==0 || - strcmp(zzbegexpr, "#ifndef")==0 || - strcmp(zzbegexpr, "#define")==0 || - strcmp(zzbegexpr, "#pragma")==0 || - strcmp(zzbegexpr, "#undef")==0 || - strcmp(zzbegexpr, "#import")==0 || - strcmp(zzbegexpr, "#line")==0 || - strcmp(zzbegexpr, "#include")==0 || - strcmp(zzbegexpr, "#error")==0) ) - { - static char buf[100]; - sprintf(buf, "%s_ast", zzbegexpr+1); -/* MR27 */ list_add(&CurAstLabelsInActions, mystrdup(zzbegexpr+1)); - zzreplstr(buf); - chkGTFlag(); - } - zzmore(); - >> -#token "#\[" << - pushint(']'); - if ( GenCC ) { - if (NewAST) zzreplstr("(newAST("); - else zzreplstr("(new AST("); } - else zzreplstr("zzmk_ast(zzastnew(),"); - zzmore(); - chkGTFlag(); - >> -#token "#\(" << - pushint('}'); - if ( GenCC ) { - if (tmakeInParser) { - zzreplstr("tmake("); - } - else { - zzreplstr("ASTBase::tmake("); - } - } - else { - zzreplstr("zztmake("); - } - zzmore(); - chkGTFlag(); - >> -#token "#" << zzmore(); >> -#token "\)" << - if ( istackempty() ) - zzmore(); - else if ( topint()==')' ) { - popint(); - } - else if ( topint()=='}' ) { - popint(); - /* terminate #(..) */ - zzreplstr(", NULL)"); - } - zzmore(); - >> -#token "\[" << - pushint('|'); /* look for '|' to terminate simple [...] */ - zzmore(); - >> -#token "\(" << - pushint(')'); - zzmore(); - >> - -#token "\\\]" << zzreplstr("]"); zzmore(); >> -#token "\\\)" << zzreplstr(")"); zzmore(); >> - -/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */ -/* MR1 in DLG action */ - -#token "\\>" << if (! tokenActionActive) zzreplstr(">"); /* MR1 */ - zzmore(); /* MR1 */ - >> /* MR1 */ - - -#token "'" << zzmode(ACTION_CHARS); zzmore();>> -#token "\"" << zzmode(ACTION_STRINGS); zzmore();>> -#token "\\$" << zzreplstr("$"); zzmore(); >> -#token "\\#" << zzreplstr("#"); zzmore(); >> -#token "\\(\n|\r|\r\n)" << zzline++; zzmore(); >> -#token "\\~[\]\)>$#]" << zzmore(); >> /* escaped char, always ignore */ -#token "/" << zzmore(); >> -#token "/\*" << zzmode(ACTION_COMMENTS); zzmore(); >> -#token "\*/" << warn("Missing /*; found dangling */ in action"); zzmore(); >> -#token "//" << zzmode(ACTION_CPP_COMMENTS); zzmore(); >> -#token "~[\n\r\)\(\\$#\>\]\[\"'/]+" << zzmore(); >> - -#lexclass START -#token "[\t\ ]+" << zzskip(); >> /* Ignore White */ -#token "\n|\r|\r\n" << zzline++; zzskip(); >> /* Track Line # */ -#token "\[" << zzmode(ACTIONS); zzmore(); - istackreset(); - pushint(']'); >> -#token "\<\<" << action_file=CurFile; action_line=zzline; - zzmode(ACTIONS); zzmore(); - list_free(&CurActionLabels,0); /* MR10 */ - numericActionLabel=0; /* MR10 */ - istackreset(); - pushint('>'); >> -#token "\"" << zzmode(STRINGS); zzmore(); >> -#token "/\*" << zzmode(COMMENTS); zzskip(); >> -#token "\*/" << warn("Missing /*; found dangling */"); zzskip(); >> -#token "//" << zzmode(CPP_COMMENTS); zzskip(); >> - -/* MR14 Arpad Beszedes 26-May-98 - Add support for #line directives when antlr source is pre-processed - #lexclass START -*/ - -#token "#line[\ \t]* [0-9]+ {[\ \t]* \"~[\"]+\" ([\ \t]* [0-9]*)* } (\n|\r|\r\n)" - << - zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore(); - getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr); - >> - -#token "#line ~[\n\r]* (\n|\r|\r\n)" - << - zzline++; zzmore(); - >> - -/* MR14 end of a block to support #line in antlr source code */ - -/* */ -/* 8-Apr-97 Regularize escape sequence for ">>" */ -/* appearing in string literals */ -/* */ - -#token "\>\>" << warn("Missing <<; found dangling \>\>"); zzskip(); >> /* MR1 */ -#token WildCard "." -#token "\@" <> /* MR6 */ -#token Eof "@" - << /* L o o k F o r A n o t h e r F i l e */ - { - FILE *new_input; - new_input = NextFile(); - if ( new_input == NULL ) { NLA=Eof; return; } - fclose( input ); - input = new_input; - zzrdstream( input ); - zzskip(); /* Skip the Eof (@) char i.e continue */ - } - >> - -#token LABEL - -#errclass "grammar-element" { element } -#errclass "meta-symbol" { "\}" "!" ";" "\|" "\~" "^" "\)" } - -#token Pragma "{\\}#pragma" /* MR21 */ -#token FirstSetSymbol "{\\}#FirstSetSymbol" /* MR21 */ -/* - * Get a grammar -- Build a list of rules like: - * - * o-->Rule1--o - * | - * o-->Rule2--o - * | - * ... - * | - * o-->RuleN--o - */ - -/* rule grammar */ - -grammar : <> - ( "{\\}#header" Action /* MR13 */ - << - if ( HdrAction==NULL ) { - HdrAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(HdrAction!=NULL, "rule grammar: cannot allocate header action"); - strcpy(HdrAction, LATEXT(1)); - } - else warn("additional #header statement ignored"); - >> - | "{\\}#first" Action - << - if ( FirstAction==NULL ) { - FirstAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(FirstAction!=NULL, "rule grammar: cannot allocate #first action"); - strcpy(FirstAction, LATEXT(1)); - } else { - warn("additional #first statement ignored"); - }; - >> - - | "{\\}#parser" QuotedTerm - << - if ( GenCC ) { - warn("#parser meta-op incompatible with -CC; ignored"); - } - else { - if ( strcmp(ParserName,"zzparser")==0 ) { - ParserName=StripQuotes(mystrdup(LATEXT(1))); - if ( RulePrefix[0]!='\0' ) - { - warn("#parser meta-op incompatible with '-gp prefix'; '-gp' ignored"); - RulePrefix[0]='\0'; - } - } - else warn("additional #parser statement ignored"); - } - >> - | "{\\}#tokdefs" QuotedTerm - <<{ - char *fname; - zzantlr_state st; FILE *f; struct zzdlg_state dst; - UserTokenDefsFile = mystrdup(LATEXT(1)); - zzsave_antlr_state(&st); - zzsave_dlg_state(&dst); - fname = mystrdup(LATEXT(1)); - f = fopen(StripQuotes(fname), "r"); - if ( f==NULL ) {warn(eMsg1("cannot open token defs file '%s'", fname+1));} - else { - ANTLRm(enum_file(fname+1), f, PARSE_ENUM_FILE); - UserDefdTokens = 1; - } - zzrestore_antlr_state(&st); - zzrestore_dlg_state(&dst); - }>> - )* - ( Action - <<{ - UserAction *ua = newUserAction(LATEXT(1)); - ua->file = action_file; ua->line = action_line; - if ( class_nest_level>0 ) list_add(&class_before_actions, ua); - else list_add(&BeforeActions, ua); - }>> - | laction - | lmember /* MR1 */ - | lprefix /* MR1 */ - | aLexclass - | token - | error - | tclass - | aPred /* MR11 */ - | default_exception_handler - | class_def - | "\}" - << - if ( class_nest_level==0 ) - warn("missing class definition for trailing '}'"); - class_nest_level--; - >> - )* - - rule <> - ( rule - - <> - - | aLexclass - | token - | error - | tclass - | aPred /* MR11 */ - | class_def - | "\}" - << - if ( class_nest_level==0 ) - warn("missing class definition for trailing '}'"); - class_nest_level--; - >> - )* - ( Action - <<{ - UserAction *ua = newUserAction(LATEXT(1)); - ua->file = action_file; ua->line = action_line; - if ( class_nest_level>0 ) list_add(&class_after_actions, ua); - else list_add(&AfterActions, ua); - }>> - | laction - | lmember /* MR1 */ - | lprefix /* MR1 */ - | error - | tclass - | class_def - | aPred /* MR11 */ - | "\}" - << - if ( class_nest_level==0 ) - warn("missing class definition for trailing '}'"); - class_nest_level--; - >> - )* - Eof - ; - <> - -/* rule class_def */ - -class_def - : <> - "class" - ( NonTerminal <> - | TokenTerm <> - ) - << - if ( CurrentClassName[0]!='\0' && strcmp(CurrentClassName,name)!=0 - && GenCC ) { - err("only one grammar class allowed in this release"); - go = 0; - } - else strcpy(CurrentClassName, name); - >> - <> - -/* MR10 */ (~ "\{" -/* MR10 */ <> -/* MR10 */ )* - - "\{" - << - no_classes_found = 0; - if ( class_nest_level>=1 ) {warn("cannot have nested classes");} - else class_nest_level++; - >> - ; - <> - -/* - * Build -o-->o-R-o-->o- where -o-R-o- is the block from rule 'block'. - * Construct the RuleBlk front and EndRule node on the end of the - * block. This is used to add FOLLOW pointers to the rule end. Add the - * new rule name to the Rname hash table and sets its rulenum. - * Store the parameter definitions if any are found. - * - * Note that locks are required on the RuleBlk and EndRule nodes to thwart - * infinite recursion. - * - * Return the left graph pointer == NULL to indicate error/dupl rule def. - */ - -/* rule rule */ - -rule : << - - ExceptionGroup *eg; - RuleEntry *q; Junction *p; Graph r; int f, l; ECnode *e; - set toksrefd, rulesrefd; - char *pdecl=NULL, *ret=NULL, *a; CurRetDef = CurParmDef = NULL; - CurExGroups = NULL; - CurElementLabels = NULL; - CurAstLabelsInActions = NULL; /* MR27 */ - /* We want a new element label hash table for each rule */ - if ( Elabel!=NULL ) killHashTable(Elabel); - Elabel = newHashTable(); - attribsRefdFromAction = empty; - >> - NonTerminal - <str; - } - CurRuleNode = q; - f = CurFile; l = zzline; - NumRules++; - >> - { "!" <noAST = TRUE;>> } - { <<;>> - {"\<"} - PassAction - << pdecl = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(pdecl!=NULL, "rule rule: cannot allocate param decl"); - strcpy(pdecl, LATEXT(1)); - CurParmDef = pdecl; - >> - } - { "\>" - PassAction - << ret = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(ret!=NULL, "rule rule: cannot allocate ret type"); - strcpy(ret, LATEXT(1)); - CurRetDef = ret; - >> - } - { QuotedTerm <egroup=mystrdup(LATEXT(1));>> } - << - if ( GenEClasseForRules && q!=NULL ) { - e = newECnode; - require(e!=NULL, "cannot allocate error class node"); - if ( q->egroup == NULL ) {a = q->str; a[0] = (char)toupper(a[0]);} - else a = q->egroup; - if ( Tnum( a ) == 0 ) - { - e->tok = addTname( a ); - list_add(&eclasses, (char *)e); - if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]); - /* refers to itself */ - list_add(&(e->elist), mystrdup(q->str)); - } - else { - warn(eMsg1("default errclass for '%s' would conflict with token/errclass/tokclass",a)); - if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]); - free((char *)e); - } - } - >> - <= MAX_BLK_LEVEL) fatal("Blocks nested too deeply"); -/* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID; -/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; - >> - - ":" <> - block[&toksrefd, &rulesrefd] - <blockid = CurBlockID; - CurRuleBlk->jtype = RuleBlk; - if ( q!=NULL ) CurRuleBlk->rname = q->str; - CurRuleBlk->file = f; - CurRuleBlk->line = l; - CurRuleBlk->pdecl = pdecl; - CurRuleBlk->ret = ret; - CurRuleBlk->lock = makelocks(); - CurRuleBlk->pred_lock = makelocks(); - CurRuleBlk->tokrefs = toksrefd; - CurRuleBlk->rulerefs = rulesrefd; - p = newJunction(); /* add EndRule Node */ - ((Junction *)r.right)->p1 = (Node *)p; - r.right = (Node *) p; - p->jtype = EndRule; - p->lock = makelocks(); - p->pred_lock = makelocks(); - CurRuleBlk->end = p; - if ( q!=NULL ) q->rulenum = NumRules; - $7 = r; - >> - << - /* MR23 */ CurBlockID_array[BlkLevel] = (-1); - /* MR23 */ CurAltNum_array[BlkLevel] = (-1); - --BlkLevel; - >> - <> /* MR7 */ - ";" <> - { Action - << a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(a!=NULL, "rule rule: cannot allocate error action"); - strcpy(a, LATEXT(1)); - CurRuleBlk->erraction = a; - >> - } - ( exception_group > [eg] - <label == NULL || *eg->label=='\0' ) q->has_rule_exception = 1; - } - >> - )* - <> - <exceptions = CurExGroups;>> - <el_labels = CurElementLabels;>> - <ast_labels_in_actions = CurAstLabelsInActions;>> /* MR27 */ - <> /* MR27 Moved */ - ; - <> - -/* - * pragma : "{\\}#pragma" "dup\-labeled\-tokens" - * <> - * ; - */ - -/* rule laction */ - -laction : <> - - "{\\}#lexaction" - Action - << - a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(a!=NULL, "rule laction: cannot allocate action"); - strcpy(a, LATEXT(1)); - list_add(&LexActions, a); - >> - ; - <> - -/* MR1 */ -/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ -/* MR1 via #lexmember <<....>> & #lexprefix <<...>> */ -/* MR1 */ - -/* rule lmember */ - -lmember: <> /* MR1 */ - -/* MR1 */ "{\\}#lexmember" -/* MR1 */ Action -/* MR1 */ << -/* MR1 */ if (! GenCC) { -/* MR1 */ err("Use #lexmember only in C++ mode (to insert code in DLG class header"); -/* MR1 */ } else { -/* MR1 */ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); -/* MR1 */ require(a!=NULL, "rule lmember: cannot allocate action"); -/* MR1 */ strcpy(a, LATEXT(1)); -/* MR1 */ list_add(&LexMemberActions, a); -/* MR1 */ }; -/* MR1 */ >> -/* MR1 */ ; -/* MR1 */ <> - -/* rule lprefix */ - -lprefix: <> /* MR1 */ - -/* MR1 */ "{\\}#lexprefix" -/* MR1 */ Action -/* MR1 */ << -/* MR1 */ if (! GenCC) { -/* MR1 */ err("Use #lexprefix only in C++ mode (to insert code in DLG class header"); -/* MR1 */ } else { -/* MR1 */ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); -/* MR1 */ require(a!=NULL, "rule lprefix: cannot allocate action"); -/* MR1 */ strcpy(a, LATEXT(1)); -/* MR1 */ list_add(&LexPrefixActions, a); -/* MR1 */ }; -/* MR1 */ >> -/* MR1 */ ; -/* MR1 */ <> - -/* - * #pred upper <>? predicate literal - * #pred lower <>? predicate literal - * #pred up_or_low upper || lower predicate expression - * concealed interdependence - * #pred up_or_low_2 <>? A || B predicate literal equals predicate expr - * analyze using lower||upper - * generate using isLetter() - */ - -/* rule aPref */ - -aPred: <> - - "{\\}#pred" - - << - MR_usingPredNames=1; /* will need to use -mrhoist version of genPredTree */ - >> - - /* used to allow NonTerminal but it caused problems - when a rule name immediately followed a #pred statement */ - - TokenTerm <> - - << - /* don't free - referenced in predicates */ - - CurPredName=(char *)calloc(1,strlen(name) + 10); - strcat(CurPredName,"#pred "); - strcat(CurPredName,name); - - predEntry=(PredEntry *) hash_get(Pname,name); - if (predEntry != NULL) { - warnFL(eMsg1("#pred %s previously defined - ignored",name), - FileStr[action_file],action_line); - name=NULL; - }; - >> - - ( - - Pred <> - - { - predOrExpr>[predExpr] <> - } - - <file=save_file; - predEntry->line=save_line; - predExpr=MR_predFlatten(predExpr); - predEntry->predLiteral=predLiteral; - if (! predExprPresent || predExpr == NULL) { - predExpr=new_pred(); - predExpr->expr=predLiteral; - predExpr->source=newActionNode(); - predExpr->source->action=predExpr->expr; - predExpr->source->rname=CurPredName; - predExpr->source->line=action_line; - predExpr->source->file=action_file; - predExpr->source->is_predicate=1; - predExpr->k=predicateLookaheadDepth(predExpr->source); - }; - predEntry->pred=predExpr; - hash_add(Pname,name,(Entry *)predEntry); - predExpr=NULL; - }; - predicate_free(predExpr); - >> - - | - <> - - predOrExpr>[predExpr] - - <file=CurFile; - predEntry->line=zzline; - predExpr=MR_predFlatten(predExpr); - predEntry->pred=predExpr; - hash_add(Pname,name,(Entry *)predEntry); - predExpr=NULL; - }; - predicate_free(predExpr); - >> - ) - {";"} -; - -/* fail */ - -<> - -/* rule predOrExpr */ - -predOrExpr>[Predicate *result] : - <> - predAndExpr>[predExpr] - << - ORnode=new_pred(); - ORnode->expr=PRED_OR_LIST; - if (predExpr != NULL) { - ORnode->down=predExpr; - tail=&predExpr->right; - }; - >> - ( "\|\|" predAndExpr>[predExpr] - << - if (predExpr != NULL) { - *tail=predExpr; - tail=&predExpr->right; - }; - >> - )* - << - $result=ORnode; - ORnode=NULL; - >> -; - -/* fail */ - -<> - -/* rule predAndExpr */ - -predAndExpr>[Predicate *result] : - <> - predPrimary>[predExpr] - << - ANDnode=new_pred(); - ANDnode->expr=PRED_AND_LIST; - if (predExpr != NULL) { - ANDnode->down=predExpr; - tail=&predExpr->right; - }; - >> - ( "&&" predPrimary>[predExpr] - << - if (predExpr != NULL) { - *tail=predExpr; - tail=&predExpr->right; - }; - >> - )* - << - $result=ANDnode; - ANDnode=NULL; - >> -; - -/* fail */ - -<> - - -/* rule predPrimary */ - -predPrimary>[Predicate *result] : - << - char *name=NULL; - PredEntry *predEntry=NULL; - Predicate *predExpr=NULL; - >> - - TokenTerm <> - - << - predEntry=(PredEntry *) hash_get(Pname,name); - if (predEntry == NULL) { - warnFL(eMsg1("no previously defined #pred with name \"%s\"",name), - FileStr[CurFile],zzline); - name=NULL; - $result=NULL; - } else { - predExpr=predicate_dup(predEntry->pred); - predExpr->predEntry=predEntry; - $result=predExpr; - }; - >> - - | "\(" predOrExpr>[predExpr] "\)" - << - $result=predExpr; - >> - - | "!" predPrimary>[predExpr] - << - predExpr->inverted=!predExpr->inverted; - $result=predExpr; - >> -; - -/* fail */ << - predicate_free(predExpr); - >> - -/* rule aLexclass */ - -aLexclass: "{\\}#lexclass" TokenTerm <> - ; - <> - -/* rule error */ - -error : <> - "{\\}#errclass" - (<<;>> TokenTerm <> - | QuotedTerm <> - ) - <lexclass = CurrentLexClass; - if ( Tnum( (t=StripQuotes(t)) ) == 0 ) - { - if ( hash_get(Texpr, t) != NULL ) - warn(eMsg1("errclass name conflicts with regular expression '%s'",t)); - e->tok = addTname( t ); - set_orel(e->tok, &imag_tokens); - require((p=(TermEntry *)hash_get(Tname, t)) != NULL, - "hash table mechanism is broken"); - p->classname = 1; /* entry is errclass name, not token */ - list_add(&eclasses, (char *)e); - } - else - { - warn(eMsg1("redefinition of errclass or conflict w/token or tokclass '%s'; ignored",t)); - free( (char *)e ); - go=0; - } - >> - "\{" - ( NonTerminal <> - | TokenTerm <> - | QuotedTerm <> - ) - <elist), t);>> - ( - ( NonTerminal <> - | TokenTerm <> - | QuotedTerm <> - ) - <elist), t);>> - )* - "\}" - ; - <> - -/* rule tclass */ - -tclass : <> - <> - <> - "{\\}#tokclass" TokenTerm <> - <lexclass = CurrentLexClass; - if ( Tnum( t ) == 0 ) - { - e->tok = addTname( t ); - set_orel(e->tok, &imag_tokens); - set_orel(e->tok, &tokclasses); - require((p=(TermEntry *)hash_get(Tname, t)) != NULL, - "hash table mechanism is broken"); - p->classname = 1; /* entry is class name, not token */ - p->tclass = e; /* save ptr to this tclass def */ - list_add(&tclasses, (char *)e); - } - else - { - warn(eMsg1("redefinition of tokclass or conflict w/token '%s'; ignored",t)); - free( (char *)e ); - go=0; - } - >> -/* MR23 */ { -/* MR23 */ "\(" -/* MR23 */ QuotedTerm -/* MR23 */ <> -/* MR23 */ "\)" -/* MR23 */ } -/* MR23 */ -/* MR23 */ -/* MR23 */ << -/* MR23 */ if (p!= NULL && akaString != NULL) { -/* MR23 */ if (p->akaString != NULL) { -/* MR23 */ if (strcmp(p->akaString,akaString) != 0) { -/* MR23 */ warnFL(eMsg2("this #tokclass statment conflicts with a previous #tokclass %s(\"%s\") statement", -/* MR23 */ t,p->akaString), -/* MR23 */ FileStr[save_file],save_line); -/* MR23 */ }; -/* MR23 */ } else { -/* MR23 */ p->akaString=akaString; -/* MR23 */ }; -/* MR23 */ }; -/* MR23 */ >> - - "\{" - ( - ( TokenTerm - <> - - { - ".." - TokenTerm - - <> - } - - | QuotedTerm - <> - ) - <tlist), t); - } else { - list_add(&(e->tlist),".."); - list_add(&(e->tlist),t); - list_add(&(e->tlist),totext); - } - totext=NULL; - } - >> - )+ // MR15 Manfred Kogler - forbid empty #tokclass sets (was "+") - "\}" - ; - <> - -/* rule token */ - -token : <> - <> /* MR11 */ - "{\\}#token" - -/* MR1 10-Apr-97 MR1 Allow shift right operator in DLG actions */ -/* MR1 Danger when parser feedback to lexer */ -/* MR1 */ - - <> /* MR1 */ - { TokenTerm <> - -/* MR11 */ { -/* MR11 */ "\(" -/* MR11 */ QuotedTerm -/* MR11 */ <> -/* MR11 */ "\)" -/* MR11 */ } - - { "=" "[0-9]+" /* define the token type number */ - <> - } - } - { QuotedTerm <> } - { Action - << - a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(a!=NULL, "rule token: cannot allocate action"); - strcpy(a, LATEXT(1)); - >> - } - - { ";" } /* MR11 */ - - <> - - <akaString != NULL) { - if (strcmp(te->akaString,akaString) != 0) { - warnFL(eMsg2("this #token statment conflicts with a previous #token %s(\"%s\") statement", - t,te->akaString), - FileStr[save_file],save_line); - }; - } else { - te->akaString=akaString; - }; - }; - }; - >> - ; - <> - -/* rule block */ - -block[set *toksrefd, set *rulesrefd] - : << - Graph g, b; - set saveblah; - int saveinalt = inAlt; - ExceptionGroup *eg; - *$toksrefd = empty; - *$rulesrefd = empty; - set_clr(AST_nodes_refd_in_actions); - CurBlockID++; -/* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID; - CurAltNum = 1; -/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; - saveblah = attribsRefdFromAction; - attribsRefdFromAction = empty; - >> - - alt[toksrefd,rulesrefd] <> - - << - if ( ((Junction *)g.left)->p1->ntype == nAction ) - { - ActionNode *actionNode=(ActionNode *) - ( ( (Junction *)g.left) ->p1); - if (!actionNode->is_predicate ) - { - actionNode->init_action = TRUE; -/* MR12c */ if (actionNode->noHoist) { -/* MR12c */ errFL("<> appears as init-action - use <<>> <>", -/* MR12c */ FileStr[actionNode->file],actionNode->line); -/* MR12c */ }; - } - } - ((Junction *)g.left)->blockid = CurBlockID; - >> - - ( exception_group > [eg] - << - if ( eg!=NULL ) { -/* MR7 ***** eg->altID = makeAltID(CurBlockID,CurAltNum); *****/ -/* MR7 ***** CurAltStart->exception_label = eg->altID; *****/ - list_add(&CurExGroups, (void *)eg); - } - >> - )* - <> - - ( "\|" <> - alt[toksrefd,rulesrefd] <> - << - ((Junction *)g.left)->blockid = CurBlockID; - >> - - ( exception_group > [eg] - << - if ( eg!=NULL ) { -/* MR7 ***** eg->altID = makeAltID(CurBlockID,CurAltNum); *****/ -/* MR7 ***** CurAltStart->exception_label = eg->altID; *****/ - list_add(&CurExGroups, (void *)eg); - } - >> - )* - - <> - - )* - <<$0 = b;>> - <> - ; - <> - -/* rule alt */ - -alt[set *toksrefd, set *rulesrefd] - : <> - { "\@" /* handle MismatchedToken signals with default handler */ - <> - } - - ( <<;>> /* MR9 Removed unreferenced variable "tok" */ - { <> "\~" <> } - element[old_not, first_on_line, use_def_MT_handler] > [node] - <ntype!=nAction ) first_on_line = 0;>> - << - if ( $2.left!=NULL ) { - g = Cat(g, $2); - n++; - if ( node!=NULL ) { - if ( node->ntype!=nAction ) e_num++; - /* record record number of all rule and token refs */ - if ( node->ntype==nToken ) { - TokNode *tk = (TokNode *)((Junction *)$2.left)->p1; - tk->elnum = e_num; - set_orel(e_num, &elems); - } - else if ( node->ntype==nRuleRef ) { - RuleRefNode *rn = (RuleRefNode *)((Junction *)$2.left)->p1; - rn->elnum = e_num; - set_orel(e_num, $rulesrefd); - } - } - } - >> - )* - <0 ) - err("one or more $i in action(s) refer to non-token elements"); - set_free(dif); - } - set_free(elems); - set_free(attribsRefdFromAction); - inAlt = 0; - >> - ; - <> - -/* rule element_label */ - -element_label > [LabelEntry *label] - : <> - LABEL <> - << - UsedNewStyleLabel = 1; - if ( UsedOldStyleAttrib ) err("cannot mix with new-style labels with old-style $i"); - t = (TermEntry *) hash_get(Tname, lab); - if ( t==NULL ) t = (TermEntry *) hash_get(Texpr, lab); - if ( t==NULL ) r = (RuleEntry *) hash_get(Rname, lab); - if ( t!=NULL ) { - err(eMsg1("label definition clashes with token/tokclass definition: '%s'", lab)); - $label = NULL; - } - else if ( r!=NULL ) { - err(eMsg1("label definition clashes with rule definition: '%s'", lab)); - $label = NULL; - } - else { - /* we don't clash with anybody else */ - l = (LabelEntry *) hash_get(Elabel, lab); - if ( l==NULL ) { /* ok to add new element label */ - l = (LabelEntry *)hash_add(Elabel, - lab, - (Entry *)newLabelEntry(lab)); - /* add to list of element labels for this rule */ - list_add(&CurElementLabels, (void *)lab); -/* MR7 */ leAdd(l); /* list of labels waiting for exception group definitions */ - $label = l; - } - else { - err(eMsg1("label definitions must be unique per rule: '%s'", lab)); - $label = NULL; - } - } - >> - ":" - ; - -/* rule element */ - -element[int old_not, int first_on_line, int use_def_MT_handler] > [Node *node] - : << - Attrib blk; - Predicate *pred = NULL; - int local_use_def_MT_handler=0; - ActionNode *act; - RuleRefNode *rr; - set toksrefd, rulesrefd; - TermEntry *term; - TokNode *p=NULL; RuleRefNode *q; int approx=0; - LabelEntry *label=NULL; - int predMsgDone=0; - int semDepth=0; - int ampersandStyle; - int height; /* MR11 */ - int equal_height; /* MR11 */ - - char* pFirstSetSymbol = NULL; /* MR21 */ - - $node = NULL; - >> - {element_label>[label]} - ( TokenTerm - << - term = (TermEntry *) hash_get(Tname, LATEXT(1)); - if ( term==NULL && UserDefdTokens ) { - err("implicit token definition not allowed with #tokdefs"); - $$.left = $$.right = NULL; - } - else { - $$ = buildToken(LATEXT(1)); - p=((TokNode *)((Junction *)$$.left)->p1); - term = (TermEntry *) hash_get(Tname, LATEXT(1)); - require( term!= NULL, "hash table mechanism is broken"); - p->tclass = term->tclass; - p->complement = $old_not; - if ( label!=NULL ) { - p->el_label = label->str; - label->elem = (Node *)p; - } - } - >> - { ".." - ( QuotedTerm - <> - | TokenTerm - <> - ) - } - << - if ( p!=NULL && (p->upper_range!=0 || p->tclass || $old_not) ) - list_add(&MetaTokenNodes, (void *)p); - >> - ( "^" <astnode=ASTroot;>> - | <astnode=ASTchild;>> - | "!" <astnode=ASTexclude;>> - ) - { "\@" <> } - << - if ( p!=NULL && $first_on_line ) { - CurAltStart = (Junction *)$$.left; - altAdd(CurAltStart); /* MR7 */ - p->altstart = CurAltStart; - } - if ( p!=NULL ) - p->use_def_MT_handler = $use_def_MT_handler || local_use_def_MT_handler; - $node = (Node *)p; - >> - | QuotedTerm - << - term = (TermEntry *) hash_get(Texpr, LATEXT(1)); - if ( term==NULL && UserDefdTokens ) { - err("implicit token definition not allowed with #tokdefs"); - $$.left = $$.right = NULL; - } - else { - $$ = buildToken(LATEXT(1)); p=((TokNode *)((Junction *)$$.left)->p1); - p->complement = $old_not; - if ( label!=NULL ) { - p->el_label = label->str; - label->elem = (Node *)p; - } - } - >> - { ".." - ( QuotedTerm - <> - | TokenTerm - <> - ) - } - ( "^" <astnode=ASTroot;>> - | <astnode=ASTchild;>> - | "!" <astnode=ASTexclude;>> - ) - { "\@" <> } - << - if ( p!=NULL && (p->upper_range!=0 || p->tclass || $old_not) ) - list_add(&MetaTokenNodes, (void *)p); - >> - << - if ( $first_on_line ) { - CurAltStart = (Junction *)$$.left; - altAdd(CurAltStart); /* MR7 */ - p->altstart = CurAltStart; - } - if ( p!=NULL ) - p->use_def_MT_handler = $use_def_MT_handler || local_use_def_MT_handler; - $node = (Node *)p; - >> - - | <> - "." - <<$$ = buildWildCard(LATEXT(1)); p=((TokNode *)((Junction *)$$.left)->p1);>> - ( "^" <astnode=ASTroot;>> - | <astnode=ASTchild;>> - | "!" <astnode=ASTexclude;>> - ) - <> - << - if ( $first_on_line ) { - CurAltStart = (Junction *)$$.left; - altAdd(CurAltStart); /* MR7 */ - p->altstart = CurAltStart; - if ( label!=NULL ) { - p->el_label = label->str; - label->elem = (Node *)p; - } - } - $node = (Node *)p; - >> - - | <> - NonTerminal - <<$$ = buildRuleRef(LATEXT(1));>> - { "!" <p1; - q->astnode=ASTexclude;>> - } - { {"\<"} - PassAction <p1, LATEXT(1));>> - } - <p1;>> - { <> - "\>" - PassAction - << - a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(a!=NULL, "rule element: cannot allocate assignment"); - strcpy(a, LATEXT(1)); - rr->assign = a; - >> - } - << - if ( label!=NULL ) { - rr->el_label = label->str; - label->elem = (Node *)rr; - } - if ( $first_on_line ) { - CurAltStart = (Junction *)$$.left; - altAdd(CurAltStart); /* MR7 */ - ((RuleRefNode *)((Junction *)$$.left)->p1)->altstart = CurAltStart; - } - $node = (Node *)rr; - >> - ) - - | <> - Action <<$0 = buildAction(LATEXT(1),action_file,action_line, 0);>> - <> /* MR7 */ - <<$node = (Node *) ((Junction *)$0.left)->p1;>> - - | <> - Pred <<$0 = buildAction(LATEXT(1),action_file,action_line, 1);>> - <p1;>> - <> - { <> - PassAction - << - a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(a!=NULL, "rule element: cannot allocate predicate fail action"); - strcpy(a, LATEXT(1)); - act->pred_fail = a; - >> - } - <> /* MR7 */ - <<$node = (Node *)act;>> - - | <> - <= MAX_BLK_LEVEL) fatal("Blocks nested too deeply"); -/* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID; -/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; - >> - { Pragma - ( "approx" <> - | "LL\(1\)" <> /* MR20 */ - | "LL\(2\)" <> /* MR20 */ - ) - } - -/* MR21 */ { FirstSetSymbol -/* MR21 */ "\(" -/* MR21 */ ( NonTerminal -/* MR21 */ << -/* MR21 */ pFirstSetSymbol = (char *) calloc(strlen(LATEXT(1))+1, -/* MR21 */ sizeof(char)); -/* MR21 */ require(pFirstSetSymbol!=NULL, -/* MR21 */ "cannot allocate first set name"); -/* MR21 */ strcpy(pFirstSetSymbol, LATEXT(1)); -/* MR21 */ >> -/* MR21 */ | TokenTerm -/* MR21 */ << -/* MR21 */ pFirstSetSymbol = (char *) calloc(strlen(LATEXT(1))+1, -/* MR21 */ sizeof(char)); -/* MR21 */ require(pFirstSetSymbol!=NULL, -/* MR21 */ "cannot allocate first set name"); -/* MR21 */ strcpy(pFirstSetSymbol, LATEXT(1)); -/* MR21 */ >> -/* MR21 */ ) -/* MR21 */ "\)" -/* MR21 */ } - - ( - - "\(" block[&toksrefd,&rulesrefd] "\)" - <> - - ( "\*" <<$$ = makeLoop($$,approx,pFirstSetSymbol);>> - | "\+" <<$$ = makePlus($$,approx,pFirstSetSymbol);>> - | "?" - ( - ( "=>" <> - | "&&" <> /* MR10 (g)? && <

>? */ - ) - Pred /* generalized predicate */ - /* first make into a predicate */ - <<$$ = buildAction(LATEXT(1),action_file,action_line,1);>> - <p1;>> - <> /* MR10 */ - <> - { <> - PassAction - << - a = (char *)calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(a!=NULL, "rule element: cannot allocate predicate fail action"); - strcpy(a, LATEXT(1)); - act->pred_fail = a; - >> - } - <> - <<$node = (Node *)act;>> - - /* for now, just snag context */ - << - pred = computePredFromContextGuard(blk,&predMsgDone); /* MR10 */ - if ( pred==NULL) { /* MR10 */ - if ( !predMsgDone) err("invalid or missing context guard"); /* MR10 */ - predMsgDone=1; /* MR10 */ - } else { /* MR10 */ - act->guardNodes=(Junction *)blk.left; /* MR11 */ - pred->expr = act->action; - pred->source = act; -/* MR10 */ pred->ampersandStyle = ampersandStyle; /* 0 means (g)? => ... 1 means (g)? && ... */ -/* MR13 */ if (pred->tcontext != NULL) { -/* MR13 */ height=MR_max_height_of_tree(pred->tcontext); -/* MR13 */ equal_height=MR_all_leaves_same_height(pred->tcontext,height); -/* MR13 */ if (! equal_height) { -/* MR13 */ errFL("in guarded predicates all tokens in the guard must be at the same height", -/* MR13 */ FileStr[act->file],act->line); -/* MR13 */ }; -/* MR13 */ } -/* MR10 */ if (ampersandStyle) { -/* MR10 */ act->ampersandPred = pred; -/* MR11 */ if (! HoistPredicateContext) { -/* MR11 */ errFL("without \"-prc on\" (guard)? && <>? ... doesn't make sense", -/* MR11 */ FileStr[act->file],act->line); -/* MR11 */ }; -/* MR10 */ } else { -/* MR10 */ act->guardpred = pred; -/* MR10 */ }; -/* MR10 */ if (pred->k != semDepth) { -/* MR10 */ warn(eMsgd2("length of guard (%d) does not match the length of semantic predicate (%d)", -/* MR10 */ pred->k,semDepth)); -/* MR10 */ }; - } - >> - | <<$$ = makeBlk($$,approx,pFirstSetSymbol); - FoundGuessBlk = 1; - ((Junction *) ((Junction *)$$.left)->p1)->guess=1; - if ( !$first_on_line ) { - err("(...)? predicate must be first element of production"); - } - >> - ) - | <<$$ = makeBlk($$,approx,pFirstSetSymbol);>> - ) - << - if ( pred==NULL && !predMsgDone) { /* MR10 */ - ((Junction *)((Junction *)$$.left)->p1)->blockid = CurBlockID; - ((Junction *)((Junction *)$$.left)->p1)->tokrefs = toksrefd; - ((Junction *)((Junction *)$$.left)->p1)->rulerefs = rulesrefd; - if ( $first_on_line ) { /* MR7 */ - CurAltStart = (Junction *)((Junction *)((Junction *)$$.left)->p1); /* MR7 */ - altAdd(CurAltStart); /* MR7 */ - }; /* MR7 */ - $node = (Node *) ((Junction *)$$.left)->p1; - } - >> - - | "\{" block[&toksrefd,&rulesrefd] - <<$$ = makeOpt($2,approx,pFirstSetSymbol); - /* MR23 */ CurBlockID_array[BlkLevel] = (-1); - /* MR23 */ CurAltNum_array[BlkLevel] = (-1); - --BlkLevel; - >> - "\}" - << - ((Junction *)((Junction *)$$.left)->p1)->blockid = CurBlockID; - ((Junction *)((Junction *)$$.left)->p1)->tokrefs = toksrefd; - ((Junction *)((Junction *)$$.left)->p1)->rulerefs = rulesrefd; - >> - <p1); /* MR7 */ - altAdd(CurAltStart); /* MR7 */ - }; - >> - <<$node = (Node *) ((Junction *)$$.left)->p1;>> - - ) - -/* Error catching alternatives */ - | "\*" <> - | "\+" <> - | "\>" <' can only appear after a nonterminal"); CannotContinue=TRUE;>> - | PassAction < [...]'"); - CannotContinue=TRUE;>> - ; - <> - -/* rule default_exception_handler */ - -default_exception_handler - : exception_group > [DefaultExGroup] - ; - -/* rule exception_group */ - -exception_group > [ExceptionGroup *eg] - : <> /* MR6 */ - - "exception" <<$eg = (ExceptionGroup *)calloc(1, sizeof(ExceptionGroup));>> - { <> - PassAction /* did they attach a label? */ - << - p = LATEXT(1)+1; - p[strlen(p)-1] = '\0'; /* kill trailing space */ - label = (LabelEntry *) hash_get(Elabel, LATEXT(1)+1); - if ( label==NULL ) - { - err(eMsg1("unknown label in exception handler: '%s'", LATEXT(1)+1)); - } - >> - } - ( exception_handler > [h] - <handlers), (void *)h);>> - )* - { "default" ":" Action - <<{ - ExceptionHandler *eh = (ExceptionHandler *) - calloc(1, sizeof(ExceptionHandler)); - char *a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require(eh!=NULL, "exception: cannot allocate handler"); - require(a!=NULL, "exception: cannot allocate action"); - strcpy(a, LATEXT(1)); - eh->action = a; - eh->signalname = (char *) calloc(strlen("default")+1, sizeof(char)); - require(eh->signalname!=NULL, "exception: cannot allocate sig name"); - strcpy(eh->signalname, "default"); - list_add(&($eg->handlers), (void *)eh); - }>> - } - - << - if ( label!=NULL ) { - /* Record ex group in sym tab for this label */ - if ( label->ex_group!=NULL ) { - err(eMsg1("duplicate exception handler for label '%s'",label->str)); - } else { - label->ex_group = $eg; - /* Label the exception group itself */ - $eg->label = label->str; - /* Make the labelled element pt to the exception also */ -/* MR6 */ if (label->elem == NULL) { -/* MR6 */ err(eMsg1("reference in exception handler to undefined label '%s'",label->str)); -/* MR6 */ } else { - switch ( label->elem->ntype ) { - case nRuleRef : - { - RuleRefNode *r = (RuleRefNode *)label->elem; - r->ex_group = $eg; - break; - } - case nToken : - { - TokNode *t = (TokNode *)label->elem; - t->ex_group = $eg; - break; - } - } /* end switch */ -/* MR6 */ }; /* end test on label->elem */ - } /* end test on label->ex_group */ - - } /* end test on exception label */ - -/* MR7 */ -/* MR7 */ if (BlkLevel == 1 && label == NULL) { -/* MR7 */ $eg->forRule=1; -/* MR7 */ } else if (label == NULL) { -/* MR7 */ $eg->altID = makeAltID(CurBlockID_array[BlkLevel], CurAltNum_array[BlkLevel]); -/* MR7 */ egAdd($eg); -/* MR7 */ } else { -/* MR7 */ $eg->labelEntry=label; -/* MR7 */ }; -/* MR7 */ -/* MR7 */ /* You may want to remove this exc from the rule list */ -/* MR7 */ /* and handle at the labeled element site. */ -/* MR7 */ -/* MR7 */ if (label != NULL) { -/* MR7 */ $eg = NULL; -/* MR7 */ }; - - >> - ; - <> - -/* rule exception_handler */ - -exception_handler > [ExceptionHandler *eh] - : <<;>> /* MR9 Removed unreferenced variable "a" */ - "catch" - << - $eh = (ExceptionHandler *)calloc(1, sizeof(ExceptionHandler)); - require($eh!=NULL, "exception: cannot allocate handler"); - >> - ( NonTerminal - << - $eh->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require($eh->signalname!=NULL, "exception: cannot allocate sig name"); - strcpy($eh->signalname, LATEXT(1)); - >> - | TokenTerm - << - $eh->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require($eh->signalname!=NULL, "exception: cannot allocate sig name"); - strcpy($eh->signalname, LATEXT(1)); - >> - ) - ":" - { <<$eh->action = NULL;>> - Action - << - $eh->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - require($eh->action!=NULL, "exception: cannot allocate action"); - strcpy($eh->action, LATEXT(1)); - >> - } - ; - <> - -#token NonTerminal "[a-z] [A-Za-z0-9_]*" - << - while ( zzchar==' ' || zzchar=='\t' ) { - zzadvance(); - } - if ( zzchar == ':' && inAlt ) NLA = LABEL; - >> -#token TokenTerm "[A-Z] [A-Za-z0-9_]*" - << - while ( zzchar==' ' || zzchar=='\t' ) { - zzadvance(); - } - if ( zzchar == ':' && inAlt ) NLA = LABEL; - >> -#token "{\\}#[A-Za-z0-9_]*" <> - -#lexclass PARSE_ENUM_FILE - -#token "[\t\ ]+" << zzskip(); >> /* Ignore White */ -#token "\n|\r|\r\n" << zzline++; zzskip(); >> /* Track Line # */ -#token "//" << zzmode(TOK_DEF_CPP_COMMENTS); zzmore(); >> -#token "/\*" << zzmode(TOK_DEF_COMMENTS); zzskip(); >> -#token "#ifdef" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> -#token "#if" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> -#token "#ifndef" << ; >> -#token "#else" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> -#token "#endif" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> -#token "#undef" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> -#token "#import" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >> -#token "@" << ; >> - -/* rule enum_file */ - -enum_file[char *fname] - : { "#ifndef" ID - { "#define" ID /* ignore if it smells like a gate */ - /* First #define after the first #ifndef (if any) is ignored */ - } - } - ( ( enum_def[$fname] )+ - | defines[$fname] - ) - | - ; - -/* rule defines */ - -defines[char *fname] - : <> /* MR3 */ - ( - "#define" ID - <> - INT - << - v = atoi(LATEXT(1)); -/* fprintf(stderr, "#token %s=%d\n", t, v);*/ - - /* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */ - /* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */ - /* MR2 Don't let #tokdefs be confused by */ - /* MR2 DLGminToken and DLGmaxToken */ - - if ( ! isDLGmaxToken(t)) { /* MR2 */ - TokenNum = v; - if ( v>maxt ) maxt=v; - if ( Tnum( t ) == 0 ) { - addForcedTname( t, v ); - } else { - warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline); - }; - }; - >> - )+ - <> - ; - -/* rule enum_def */ - -enum_def[char *fname] - : <> /* MR3 */ - "enum" ID - "\{" - ID - <> - ( "=" INT <> - | <> - ) - << -/* fprintf(stderr, "#token %s=%d\n", t, v);*/ - TokenNum = v; - if ( v>maxt ) maxt=v; /* MR3 */ - if ( Tnum( t ) == 0 ) addForcedTname( t, v ); - else { - warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline); - } - >> - ( "," - - /* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */ - /* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */ - /* MR2 Don't let #tokdefs be confused by */ - /* MR2 DLGminToken and DLGmaxToken */ - - { - <>? ID { "=" INT } /* MR2 */ - | ID /* MR2 */ - <> - ( "=" INT <> - | <> - ) - << -/* fprintf(stderr, "#token %s=%d\n", t, v);*/ - TokenNum = v; - if ( v>maxt ) maxt=v; /* MR3 */ - if ( Tnum( t ) == 0 ) addForcedTname( t, v ); - else { - warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline); - } - >> - } - )* - "\}" - ";" - <> /* MR3 */ - ; - -#token INT "[0-9]+" -#token ID "[a-zA-Z_][_a-zA-Z0-9]*" - -#lexclass START - -/* MR14 Arpad Beszedes 26-May-98 - Add support for #line directives when antlr source is pre-processed -*/ - -#lexaction -<< - -static char * -#ifdef __USE_PROTOS -getFileNameFromTheLineInfo(char *toStr, char *fromStr) -#else -getFileNameFromTheLineInfo(toStr, fromStr) -char *toStr, *fromStr; -#endif -{ - int i, j, k; - - if (!fromStr || !toStr) return toStr; - - /* find the first " */ - - for (i=0; - (i> - -<< - -/* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */ -/* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */ -/* MR2 Don't let #tokdefs be confused by */ -/* MR2 DLGminToken and DLGmaxToken */ - -/* semantic check on DLGminToken and DLGmaxmaxToken in #tokdefs */ - -#ifdef __USE_PROTOS -static int isDLGmaxToken(char *Token) -#else -static int isDLGmaxToken(Token) - char * Token; -#endif -{ - static char checkStr1[] = "DLGmaxToken"; - static char checkStr2[] = "DLGminToken"; - - if (strcmp(Token, checkStr1) == 0) - return 1; - else if (strcmp(Token, checkStr2) == 0) - return 1; - else - return 0; -} - -/* semantics of #token */ -static void -#ifdef __USE_PROTOS -chkToken(char *t, char *e, char *a, int tnum) -#else -chkToken(t,e,a,tnum) -char *t, *e, *a; -int tnum; -#endif -{ - TermEntry *p; - - /* check to see that they don't try to redefine a token as a token class */ - if ( t!=NULL ) { - p = (TermEntry *) hash_get(Tname, t); - if ( p!=NULL && p->classname ) { - err(eMsg1("redefinition of #tokclass '%s' to #token not allowed; ignored",t)); - if ( a!=NULL ) free((char *)a); - return; - } - } - - if ( t==NULL && e==NULL ) { /* none found */ - err("#token requires at least token name or rexpr"); - } - else if ( t!=NULL && e!=NULL ) { /* both found */ - if ( UserDefdTokens ) { /* if #tokdefs, must not define new */ - p = (TermEntry *) hash_get(Tname, t); - if ( p == NULL) { -err(eMsg1("new token definition '%s' not allowed - only #token with name already defined by #tokdefs file allowed",t)); - return; - }; - } - Tklink(t, e); - if ( a!=NULL ) { - if ( hasAction(e) ) { - err(eMsg1("redefinition of action for %s; ignored",e)); - } - else setHasAction(e, a); - } - } - else if ( t!=NULL ) { /* only one found */ - if ( UserDefdTokens ) { - p = (TermEntry *) hash_get(Tname, t); - if (p == NULL) { -err(eMsg1("new token definition '%s' not allowed - only #token with name already defined by #tokdefs file allowed",t)); - }; - return; - } - if ( Tnum( t ) == 0 ) addTname( t ); - else { - err(eMsg1("redefinition of token %s; ignored",t)); - } - if ( a!=NULL ) { - err(eMsg1("action cannot be attached to a token name (%s); ignored",t)); - free((char *)a); - } - } - else if ( e!=NULL ) { - if ( Tnum( e ) == 0 ) addTexpr( e ); - else { - if ( hasAction(e) ) { - err(eMsg1("redefinition of action for expr %s; ignored",e)); - } - else if ( a==NULL ) { - err(eMsg1("redefinition of expr %s; ignored",e)); - } - } - if ( a!=NULL ) setHasAction(e, a); - } - - /* if a token type number was specified, then add the token ID and 'tnum' - * pair to the ForcedTokens list. (only applies if an id was given) - */ - if ( t!=NULL && tnum>0 ) - { - if ( set_el(tnum, reserved_positions) ) - { - err(eMsgd("a token has already been forced to token number %d; ignored", tnum)); - } - else - { - list_add(&ForcedTokens, newForcedToken(t,tnum)); - set_orel(tnum, &reserved_positions); - } - } -} ->> - -<< -static int -#ifdef __USE_PROTOS -match_token(char *s, char **nxt) -#else -match_token(s,nxt) -char *s; -char **nxt; -#endif -{ - if ( !(*s>='A' && *s<='Z') ) return 0; - s++; - while ( (*s>='a' && *s<='z') || - (*s>='A' && *s<='Z') || - (*s>='0' && *s<='9') || - *s=='_' ) - { - s++; - } - if ( *s!=' ' && *s!='}' ) return 0; - *nxt = s; - return 1; -} - -static int -#ifdef __USE_PROTOS -match_rexpr(char *s, char **nxt) -#else -match_rexpr(s,nxt) -char *s; -char **nxt; -#endif -{ - if ( *s!='"' ) return 0; - s++; - while ( *s!='"' ) - { - if ( *s=='\n' || *s=='\r' ) /* MR13 */ - warn("eoln found in regular expression"); - if ( *s=='\\' ) s++; - s++; - } - *nxt = s+1; - return 1; -} - -/* - * Walk a string "{ A .. Z }" where A..Z is a space separated list - * of token references (either labels or reg exprs). Return a - * string "inlineX_set" for some unique integer X. Basically, - * we pretend as if we had seen "#tokclass inlineX { A .. Z }" - * on the input stream outside of an action. - */ -char * -#ifdef __USE_PROTOS -inline_set(char *s) -#else -inline_set(s) -char *s; -#endif -{ - char *nxt; - fprintf(stderr, "found consumeUntil( {...} )\n"); - while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;} - if ( *s!='{' ) - { - err("malformed consumeUntil( {...} ); missing '{'"); - return "bad_set"; - } - s++; - while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;} - while ( *s!='}' ) - { - if ( match_token(s,&nxt) ) fprintf(stderr, "found token %s\n", s); - else if ( match_rexpr(s,&nxt) ) fprintf(stderr, "found rexpr %s\n", s); - else { - err("invalid element in consumeUntil( {...} )"); - return "bad_set"; - } - s = nxt; - while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;} - } - return "inlineX_set"; -} ->> - -<< -/* ANTLR-specific syntax error message generator - * (define USER_ZZSYN when compiling so don't get 2 definitions) - */ -void -#ifdef __USE_PROTOS -zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, -int k, char *bad_text) -#else -zzsyn(text, tok, egroup, eset, etok, k, bad_text) -char *text, *egroup, *bad_text; -int tok; -int etok; -int k; -SetWordType *eset; -#endif -{ - fprintf(stderr, ErrHdr, FileStr[CurFile]!=NULL?FileStr[CurFile]:"stdin", zzline); - fprintf(stderr, " syntax error at \"%s\"", (tok==zzEOF_TOKEN)?"EOF":text); - if ( !etok && !eset ) {fprintf(stderr, "\n"); return;} - if ( k==1 ) fprintf(stderr, " missing"); - else - { - fprintf(stderr, "; \"%s\" not", bad_text); - if ( zzset_deg(eset)>1 ) fprintf(stderr, " in"); - } - if ( zzset_deg(eset)>0 ) zzedecode(eset); - else fprintf(stderr, " %s", zztokens[etok]); - if ( strlen(egroup) > (size_t)0 ) fprintf(stderr, " in %s", egroup); - fprintf(stderr, "\n"); -} ->> - -#lexaction << -#ifdef __USE_PROTOS -void mark_label_used_in_sem_pred(LabelEntry *le) /* MR10 */ -#else -void mark_label_used_in_sem_pred(le) /* MR10 */ - LabelEntry *le; -#endif -{ - TokNode *tn; - require (le->elem->ntype == nToken,"mark_label_used... ntype != nToken"); - tn=(TokNode *)le->elem; - require (tn->label != 0,"mark_label_used... TokNode has no label"); - tn->label_used_in_semantic_pred=1; -} ->> diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/antlr.r b/Tools/CodeTools/TianoTools/Pccts/antlr/antlr.r deleted file mode 100644 index e3de38759f..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/antlr.r +++ /dev/null @@ -1,787 +0,0 @@ -/* - File: antlrMPW.r - Target: antlr 133MR - Created: Monday, June 15, 1998 4:41:11 AM - Author: Kenji Tanaka (kentar@osa.att.ne.jp) -*/ - -#include "cmdo.r" - -resource 'cmdo' (128, "Antlr") { - { /* array dialogs: 5 elements */ - /* [1] */ - 295, - "ANTLR -- Purdue Compiler Construction To" - "ol Set (PCCTS) LL(k) parser generator.", - { /* array itemArray: 12 elements */ - /* [1] */ - NotDependent { - - }, - CheckOption { - NotSet, - {18, 23, 33, 223}, - "Read grammar from stdin", - "-", - "Read grammar from stdin." - }, - /* [2] */ - NotDependent { - - }, - CheckOption { - NotSet, - {38, 23, 53, 310}, - "Send grammar.c/grammar.cpp to stdout", - "-stdout", - "Send grammar.c/grammar.cpp to stdout." - }, - /* [3] */ - NotDependent { - - }, - MultiFiles { - "Grammar File(s)É", - "Choose the grammar specification files y" - "ou wish to have ANTLR process.", - {79, 22, 98, 152}, - "Grammar specification:", - "", - MultiInputFiles { - { /* array MultiTypesArray: 1 elements */ - /* [1] */ - text - }, - ".g", - "Files ending in .g", - "All text files" - } - }, - /* [4] */ - NotDependent { - - }, - Files { - DirOnly, - OptionalFile { - {58, 168, 74, 298}, - {79, 169, 98, 299}, - "Output Directory", - ":", - "-o", - "", - "Choose the directory where ANTLR will pu" - "t its output.", - dim, - "Output DirectoryÉ", - "", - "" - }, - NoMore { - - } - }, - /* [5] */ - NotDependent { - - }, - Redirection { - StandardOutput, - {126, 27} - }, - /* [6] */ - NotDependent { - - }, - Redirection { - DiagnosticOutput, - {126, 178} - }, - /* [7] */ - NotDependent { - - }, - TextBox { - gray, - {117, 20, 167, 300}, - "Redirection" - }, - /* [8] */ - NotDependent { - - }, - NestedDialog { - 5, - {20, 324, 40, 460}, - "Parse OptionsÉ", - "Parse control options may be set with th" - "is button." - }, - /* [9] */ - NotDependent { - - }, - NestedDialog { - 2, - {50, 324, 70, 460}, - "Generate OptionsÉ", - "Various command line options may be set " - "with this button." - }, - /* [10] */ - NotDependent { - - }, - NestedDialog { - 3, - {78, 324, 98, 460}, - "More OptionsÉ", - "Antlr has ALOT of options. There are eve" - "n more to be found with this button." - }, - /* [11] */ - NotDependent { - - }, - NestedDialog { - 4, - {106, 324, 126, 460}, - "Rename OptionsÉ", - "Options for renaming output files may be" - " set with this button." - }, - /* [12] */ - NotDependent { - - }, - VersionDialog { - VersionString { - "1.33MR" - }, - "PCCTS was written by Terence Parr, Russe" - "ll Quong, Will Cohen, and Hank Dietz: 19" - "89-1998. MPW port by Scott Haney.", - noDialog - } - }, - /* [2] */ - 295, - "Use this dialog to specify command line " - "Generate Options.", - { /* array itemArray: 15 elements */ - /* [1] */ - NotDependent { - - }, - CheckOption { - NotSet, - {18, 25, 33, 225}, - "Generate C++ code", - "-CC", - "Generate C++ output from both ANTLR and " - "DLG." - }, - /* [2] */ - NotDependent { - - }, - CheckOption { - NotSet, - {38, 25, 53, 225}, - "Generate ASTs", - "-gt", - "Generate code for Abstract-Syntax-Trees " - "(ASTs)." - }, - /* [3] */ - NotDependent { - - }, - CheckOption { - NotSet, - {58, 25, 73, 225}, - "Generate line info", - "-gl", - "If this option is checked, ANTLR will ge" - "nerate line info about grammaractions, t" - "hereby making debugging easier since com" - "pile errors will point to the grammar fi" - "le." - }, - /* [4] */ - NotDependent { - - }, - CheckOption { - NotSet, - {78, 25, 93, 225}, - "Generate error classes", - "-ge", - "If this option is checked, ANTLR will ge" - "nerate an error class foreach non-termin" - "al." - }, - /* [5] */ - NotDependent { - - }, - CheckOption { - NotSet, - {98, 25, 113, 225}, - "Don't generate Code", - "-gc", - "If this option is checked, ANTLR will ge" - "nerate no code, i.e. it will only perfor" - "m analysis on the grammar." - }, - /* [6] */ - NotDependent { - - }, - CheckOption { - NotSet, - {118, 25, 133, 225}, - "Delay lookahead fetches", - "-gk", - "If this option is checked, ANTLR will ge" - "nerate a parser that delays lookahead fe" - "tches until needed." - }, - /* [7] */ - NotDependent { - - }, - CheckOption { - NotSet, - {138, 25, 153, 225}, - "Use newAST(...)", - "-newAST", - "In C++ mode use \"newAST(...)\" rather tha" - "n \"new AST(...)\"" - }, - /* [8] */ - NotDependent { - - }, - CheckOption { - NotSet, - {18, 235, 33, 435}, - "Support parse traces", - "-gd", - "If this option is checked, ANTLR inserts" - " code in each parsing function to provid" - "e for user-defined handling of a detaile" - "d parse trace. The code consists of call" - "s to zzTRACEIN and zzTRACEOUT." - }, - /* [9] */ - NotDependent { - - }, - CheckOption { - NotSet, - {38, 235, 53, 435}, - "Generate cross-references", - "-cr", - "If this option is checked, ANTLR will ge" - "nerate a cross reference for all rules. " - "For each rule it will print a list of al" - "l other rules that refrence it." - }, - /* [10] */ - NotDependent { - - }, - CheckOption { - NotSet, - {58, 235, 73, 435}, - "Don't create Lexer files", - "-gx", - "If this option is checked, ANTLR will no" - "t generate DLG-related output files. Thi" - "s option should be used if one wants a c" - "ustom lexical analyzer or if one has mad" - "e changes to the grammar not affecting t" - "he lexical structure." - }, - /* [11] */ - NotDependent { - - }, - CheckOption { - NotSet, - {78, 235, 93, 460}, - "Don't generate token expr sets", - "-gs", - "If this option is checked, ANTLR will no" - "t generate sets for token expression set" - "s; instead, it will generate a || separa" - "ted sequence of LA(1)==token #. " - }, - /* [12] */ - NotDependent { - - }, - CheckOption { - NotSet, - {98, 235, 113, 460}, - "Generate ANSI-compatible", - "-ga", - "Generate ANSI-compatible code (default=F" - "ALSE)" - }, - /* [13] */ - NotDependent { - - }, - CheckOption { - NotSet, - {118, 235, 133, 460}, - "Don't generate tokens.h", - "-gxt", - "Do not generate tokens.h (default=FALSE)" - }, - /* [13] */ - NotDependent { - - }, - CheckOption { - NotSet, - {138, 235, 153, 460}, - "Provide \"(alpha)? beta\" info", - "-alpha", - "Provide additional information for \"(alpha)? beta\" error messages" - }, - /* [14] */ - NotDependent { - - }, - RegularEntry { - "Tabs(1 to 8):", - {162, 23, 177, 117}, - {163, 125, 179, 196}, - "", - keepCase, - "-tab", - "Width of tabs (1 to 8) for grammar.c/gra" - "mmar.cpp files." - }, - /* [15] */ - NotDependent { - - }, - RegularEntry { - "Function Prefix:", - {161, 236, 177, 342}, - {162, 345, 177, 454}, - "", - keepCase, - "-gp", - "Prefix all generated rule functions with" - " a string." - } - }, - /* [3] */ - 295, - "Use this dialog to specify still more co" - "mmand line options.", - { /* array itemArray: 12 elements */ - /* [1] */ - NotDependent { - - }, - RadioButtons { - { /* array radioArray: 3 elements */ - /* [1] */ - {38, 25, 53, 85}, "None", "", Set, "When this option is selected, ANTLR will" - " not print the grammar to stdout.", - /* [2] */ - {38, 100, 53, 160}, "Yes", "-p", NotSet, "When this option is selected, ANTLR will" - " print the grammar, stripped of all acti" - "ons and comments, to stdout.", - /* [3] */ - {38, 175, 53, 235}, "More", "-pa", NotSet, "When this option is selected, ANTLR will" - " print the grammar, stripped of all acti" - "ons and comments, to stdout. It will als" - "o annotate the output with the first set" - "s determined from grammar analysis." - } - }, - /* [2] */ - NotDependent { - - }, - TextBox { - gray, - {28, 15, 60, 250}, - "Grammar Printing" - }, - /* [3] */ - NotDependent { - - }, - RadioButtons { - { /* array radioArray: 3 elements */ - /* [1] */ - {88, 25, 103, 85}, "Low", "", Set, "When this option is selected, ANTLR will" - " show ambiguities/errors in low detail.", - /* [2] */ - {88, 100, 103, 160}, "Medium", "-e2", NotSet, "When this option is selected, ANTLR will" - " show ambiguities/errors in more detail.", - /* [3] */ - {88, 175, 103, 235}, "High", "-e3", NotSet, "When this option is selected, ANTLR will" - " show ambiguities/errors in excruciating" - " detail." - } - }, - /* [4] */ - NotDependent { - - }, - TextBox { - gray, - {78, 15, 110, 250}, - "Error reporting" - }, - /* [5] */ - NotDependent { - - }, - CheckOption { - NotSet, - {130, 22, 145, 222}, - "More warnings", - "-w2", - "If this option is checked, ANTLR will wa" - "rn if semantic predicates and/or (É)? bl" - "ocks are assumed to cover ambiguous alte" - "rnatives." - }, - /* [6] */ - NotDependent { - - }, - RegularEntry { - "Report when tnode usage exceeds:", - {162, 23, 180, 253}, - {162, 255, 178, 326}, - "", - keepCase, - "-treport", - "Report when tnode usage exceeds value du" - "ring ambiguity resolution." - }, - /* [7] */ - NotDependent { - - }, - CheckOption { - NotSet, - {40, 292, 55, 431}, - "Predicate", - "-info p", - "With the antlr \"-info p\" switch the user" - " will receive information about the pred" - "icate suppression in the generated file." - }, - /* [8] */ - NotDependent { - - }, - CheckOption { - NotSet, - {60, 292, 75, 430}, - "Tree Nodes", - "-info t", - "Using \"-info t\" gives information about " - "the total number of tnodes created and t" - "he peak number of tnodes." - }, - /* [9] */ - NotDependent { - - }, - CheckOption { - NotSet, - {80, 292, 95, 425}, - "First/follow", - "-info f", - "first/follow set information." - }, - /* [10] */ - NotDependent { - - }, - CheckOption { - NotSet, - {100, 292, 115, 425}, - "Monitor progress", - "-info m", - "prints name of each rule as it is starte" - "d and flushes output at start of each rule." - }, - /* [11] */ - NotDependent { - - }, - CheckOption { - NotSet, - {120, 292, 135, 416}, - "Orphan rules", - "-info o", - "If there is more than one rule which is " - "not referenced by any other rule then al" - "l such rules are listed." - }, - /* [12] */ - NotDependent { - - }, - TextBox { - gray, - {28, 279, 147, 451}, - "Extra info" - } - }, - /* [4] */ - 295, - "Use this dialog to specify command line " - "options relating to renaming output file" - "s.", - { /* array itemArray: 7 elements */ - /* [1] */ - NotDependent { - - }, - RegularEntry { - "Errors file name:", - {35, 25, 50, 205}, - {35, 205, 51, 300}, - "err.c", - keepCase, - "-fe", - "This entry specifies the name ANTLR uses" - " for the errors file." - }, - /* [2] */ - NotDependent { - - }, - RegularEntry { - "Lexical output name:", - {60, 25, 75, 205}, - {60, 205, 76, 300}, - "parser.dlg", - keepCase, - "-fl", - "This entry specifies the name ANTLR uses" - " for the lexical output file." - }, - /* [3] */ - NotDependent { - - }, - RegularEntry { - "Lexical modes name:", - {85, 25, 100, 205}, - {85, 205, 101, 300}, - "mode.h", - keepCase, - "-fm", - "This entry specifies the name ANTLR uses" - " for the lexical mode definitions file." - }, - /* [4] */ - NotDependent { - - }, - RegularEntry { - "Remap file name:", - {110, 25, 125, 205}, - {110, 205, 126, 300}, - "remap.h", - keepCase, - "-fr", - "This entry specifies the name ANTLR uses" - " for the file that remaps globally visib" - "le symbols." - }, - /* [5] */ - NotDependent { - - }, - RegularEntry { - "Tokens file name:", - {135, 25, 150, 205}, - {135, 205, 151, 300}, - "tokens.h", - keepCase, - "-ft", - "This entry specifies the name ANTLR uses" - " for the tokens file." - }, - /* [6] */ - NotDependent { - - }, - CheckOption { - NotSet, - {160, 25, 175, 175}, - "Create std header", - "-gh", - "If this option is checked, ANTLR will cr" - "eate a standard header file named, by de" - "fault 'stdpccts.h'. This name can be alt" - "ered using the entry right next door." - }, - /* [7] */ - Or { - { /* array OrArray: 1 elements */ - /* [1] */ - 6 - } - }, - RegularEntry { - "Std header file name:", - {160, 175, 175, 355}, - {160, 355, 176, 450}, - "stdpccts.h", - keepCase, - "-fh", - "This entry specifies the name ANTLR uses" - " for the standard header file." - } - }, - /* [5] */ - 295, - "Use this dialog to specify parse options" - ".", - { /* array itemArray: 9 elements */ - /* [1] */ - NotDependent { - - }, - RegularEntry { - "Lookahead:", - {23, 27, 38, 152}, - {46, 29, 62, 154}, - "1", - keepCase, - "-k", - "This entry specifies the number of token" - "s of lookahead." - }, - /* [2] */ - NotDependent { - - }, - RegularEntry { - "Compr lookahead:", - {22, 167, 37, 292}, - {46, 172, 62, 297}, - "", - keepCase, - "-ck", - "This entry specifies the number of token" - "s of lookahead when using compressed (li" - "near approximation) lookahead. In genera" - "l, the compressed lookahead is much deep" - "er than the full lookahead." - }, - /* [3] */ - NotDependent { - - }, - RegularEntry { - "Max tree nodes:", - {22, 312, 37, 437}, - {46, 315, 62, 445}, - "", - keepCase, - "-rl", - "This entry specifies the maximum number " - "of tokens of tree nodes used by the gram" - "mar analysis." - }, - /* [4] */ - NotDependent { - - }, - CheckOption { - NotSet, - {76, 25, 91, 350}, - "Maintenance Release style hoisting", - "-mrhoist", - "Turn on/off k=1 Maintenance Release styl" - "e hoisting." - }, - /* [5] */ - NotDependent { - - }, - CheckOption { - NotSet, - {96, 25, 111, 431}, - "EXPERIMENTAL Maintenance Release style h" - "oisting", - "-mrhoistk", - "Turn on/off k>1 EXPERIMENTAL Maintenance" - " Release style hoisting." - }, - /* [6] */ - NotDependent { - - }, - CheckOption { - NotSet, - {116, 25, 131, 363}, - "Compute context for hoisted predicates", - "-prc on", - "Turn on/off computation of context for h" - "oisted predicates." - }, - /* [7] */ - NotDependent { - - }, - RegularEntry { - "Ambiguity aid:", - {140, 27, 155, 125}, - {141, 135, 155, 209}, - "", - keepCase, - "-aa", - "Ambiguity aid for a rule (rule name or l" - "ine number)." - }, - /* [8] */ - NotDependent { - - }, - RegularEntry { - "Limits exp growth:", - {140, 236, 155, 361}, - {139, 372, 155, 452}, - "", - keepCase, - "-aad", - "Limits exp growth of -aa listing - defau" - "lt=1 (max=ck value)." - }, - /* [9] */ - NotDependent { - - }, - CheckOption { - NotSet, - {164, 26, 179, 366}, - "Lookahead token may appear multiple time" - "s", - "-aam", - "Lookahead token may appear multiple time" - "s in -aa listing." - } - } - } -}; - diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/antlr1.txt b/Tools/CodeTools/TianoTools/Pccts/antlr/antlr1.txt deleted file mode 100644 index 4a7d22e7f2..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/antlr1.txt +++ /dev/null @@ -1,264 +0,0 @@ - - - -ANTLR(1) PCCTS Manual Pages ANTLR(1) - - - -NAME - antlr - ANother Tool for Language Recognition - -SYNTAX - antlr [_o_p_t_i_o_n_s] _g_r_a_m_m_a_r__f_i_l_e_s - -DESCRIPTION - _A_n_t_l_r converts an extended form of context-free grammar into - a set of C functions which directly implement an efficient - form of deterministic recursive-descent LL(k) parser. - Context-free grammars may be augmented with predicates to - allow semantics to influence parsing; this allows a form of - context-sensitive parsing. Selective backtracking is also - available to handle non-LL(k) and even non-LALR(k) con- - structs. _A_n_t_l_r also produces a definition of a lexer which - can be automatically converted into C code for a DFA-based - lexer by _d_l_g. Hence, _a_n_t_l_r serves a function much like that - of _y_a_c_c, however, it is notably more flexible and is more - integrated with a lexer generator (_a_n_t_l_r directly generates - _d_l_g code, whereas _y_a_c_c and _l_e_x are given independent - descriptions). Unlike _y_a_c_c which accepts LALR(1) grammars, - _a_n_t_l_r accepts LL(k) grammars in an extended BNF notation - - which eliminates the need for precedence rules. - - Like _y_a_c_c grammars, _a_n_t_l_r grammars can use automatically- - maintained symbol attribute values referenced as dollar - variables. Further, because _a_n_t_l_r generates top-down - parsers, arbitrary values may be inherited from parent rules - (passed like function parameters). _A_n_t_l_r also has a mechan- - ism for creating and manipulating abstract-syntax-trees. - - There are various other niceties in _a_n_t_l_r, including the - ability to spread one grammar over multiple files or even - multiple grammars in a single file, the ability to generate - a version of the grammar with actions stripped out (for - documentation purposes), and lots more. - -OPTIONS - -ck _n - Use up to _n symbols of lookahead when using compressed - (linear approximation) lookahead. This type of looka- - head is very cheap to compute and is attempted before - full LL(k) lookahead, which is of exponential complex- - ity in the worst case. In general, the compressed loo- - kahead can be much deeper (e.g, -ck 10) _t_h_a_n _t_h_e _f_u_l_l - _l_o_o_k_a_h_e_a_d (_w_h_i_c_h _u_s_u_a_l_l_y _m_u_s_t _b_e _l_e_s_s _t_h_a_n _4). - - -CC Generate C++ output from both ANTLR and DLG. - - -cr Generate a cross-reference for all rules. For each - rule, print a list of all other rules that reference - it. - - -e1 Ambiguities/errors shown in low detail (default). - - -e2 Ambiguities/errors shown in more detail. - - -e3 Ambiguities/errors shown in excruciating detail. - - -fe file - Rename err.c to file. - - -fh file - Rename stdpccts.h header (turns on -gh) to file. - - -fl file - Rename lexical output, parser.dlg, to file. - - -fm file - Rename file with lexical mode definitions, mode.h, to - file. - - -fr file - Rename file which remaps globally visible symbols, - remap.h, to file. - - -ft file - Rename tokens.h to file. - - -ga Generate ANSI-compatible code (default case). This has - not been rigorously tested to be ANSI XJ11 C compliant, - but it is close. The normal output of _a_n_t_l_r is - currently compilable under both K&R, ANSI C, and C++- - this option does nothing because _a_n_t_l_r generates a - bunch of #ifdef's to do the right thing depending on - the language. - - -gc Indicates that _a_n_t_l_r should generate no C code, i.e., - only perform analysis on the grammar. - - -gd C code is inserted in each of the _a_n_t_l_r generated pars- - ing functions to provide for user-defined handling of a - detailed parse trace. The inserted code consists of - calls to the user-supplied macros or functions called - zzTRACEIN and zzTRACEOUT. The only argument is a _c_h_a_r - * pointing to a C-style string which is the grammar - rule recognized by the current parsing function. If no - definition is given for the trace functions, upon rule - entry and exit, a message will be printed indicating - that a particular rule as been entered or exited. - - -ge Generate an error class for each non-terminal. - - -gh Generate stdpccts.h for non-ANTLR-generated files to - include. This file contains all defines needed to - describe the type of parser generated by _a_n_t_l_r (e.g. - how much lookahead is used and whether or not trees are - constructed) and contains the header action specified - by the user. - - -gk Generate parsers that delay lookahead fetches until - needed. Without this option, _a_n_t_l_r generates parsers - which always have _k tokens of lookahead available. - - -gl Generate line info about grammar actions in C parser of - the form # _l_i_n_e "_f_i_l_e" which makes error messages from - the C/C++ compiler make more sense as they will point - into the grammar file not the resulting C file. - Debugging is easier as well, because you will step - through the grammar not C file. - - -gs Do not generate sets for token expression lists; - instead generate a ||-separated sequence of - LA(1)==_t_o_k_e_n__n_u_m_b_e_r. The default is to generate sets. - - -gt Generate code for Abstract-Syntax Trees. - - -gx Do not create the lexical analyzer files (dlg-related). - This option should be given when the user wishes to - provide a customized lexical analyzer. It may also be - used in _m_a_k_e scripts to cause only the parser to be - rebuilt when a change not affecting the lexical struc- - ture is made to the input grammars. - - -k _n Set k of LL(k) to _n; i.e. set tokens of look-ahead - (default==1). - - -o dir - Directory where output files should go (default="."). - This is very nice for keeping the source directory - clear of ANTLR and DLG spawn. - - -p The complete grammar, collected from all input grammar - files and stripped of all comments and embedded - actions, is listed to stdout. This is intended to aid - in viewing the entire grammar as a whole and to elim- - inate the need to keep actions concisely stated so that - the grammar is easier to read. Hence, it is preferable - to embed even complex actions directly in the grammar, - rather than to call them as subroutines, since the sub- - routine call overhead will be saved. - - -pa This option is the same as -p except that the output is - annotated with the first sets determined from grammar - analysis. - - -prc on - Turn on the computation and hoisting of predicate con- - text. - - -prc off - Turn off the computation and hoisting of predicate con- - text. This option makes 1.10 behave like the 1.06 - release with option -pr on. Context computation is off - by default. - - -rl _n - Limit the maximum number of tree nodes used by grammar - analysis to _n. Occasionally, _a_n_t_l_r is unable to - analyze a grammar submitted by the user. This rare - situation can only occur when the grammar is large and - the amount of lookahead is greater than one. A non- - linear analysis algorithm is used by PCCTS to handle - the general case of LL(k) parsing. The average com- - plexity of analysis, however, is near linear due to - some fancy footwork in the implementation which reduces - the number of calls to the full LL(k) algorithm. An - error message will be displayed, if this limit is - reached, which indicates the grammar construct being - analyzed when _a_n_t_l_r hit a non-linearity. Use this - option if _a_n_t_l_r seems to go out to lunch and your disk - start thrashing; try _n=10000 to start. Once the - offending construct has been identified, try to remove - the ambiguity that _a_n_t_l_r was trying to overcome with - large lookahead analysis. The introduction of (...)? - backtracking blocks eliminates some of these problems - - _a_n_t_l_r does not analyze alternatives that begin with - (...)? (it simply backtracks, if necessary, at run - time). - - -w1 Set low warning level. Do not warn if semantic - predicates and/or (...)? blocks are assumed to cover - ambiguous alternatives. - - -w2 Ambiguous parsing decisions yield warnings even if - semantic predicates or (...)? blocks are used. Warn if - predicate context computed and semantic predicates - incompletely disambiguate alternative productions. - - - Read grammar from standard input and generate stdin.c - as the parser file. - -SPECIAL CONSIDERATIONS - _A_n_t_l_r works... we think. There is no implicit guarantee of - anything. We reserve no legal rights to the software known - as the Purdue Compiler Construction Tool Set (PCCTS) - PCCTS - is in the public domain. An individual or company may do - whatever they wish with source code distributed with PCCTS - or the code generated by PCCTS, including the incorporation - of PCCTS, or its output, into commercial software. We - encourage users to develop software with PCCTS. However, we - do ask that credit is given to us for developing PCCTS. By - "credit", we mean that if you incorporate our source code - into one of your programs (commercial product, research pro- - ject, or otherwise) that you acknowledge this fact somewhere - in the documentation, research report, etc... If you like - PCCTS and have developed a nice tool with the output, please - mention that you developed it using PCCTS. As long as these - guidelines are followed, we expect to continue enhancing - this system and expect to make other tools available as they - are completed. - -FILES - *.c output C parser. - - *.cpp - output C++ parser when C++ mode is used. - - parser.dlg - output _d_l_g lexical analyzer. - - err.c - token string array, error sets and error support rou- - tines. Not used in C++ mode. - - remap.h - file that redefines all globally visible parser sym- - bols. The use of the #parser directive creates this - file. Not used in C++ mode. - - stdpccts.h - list of definitions needed by C files, not generated by - PCCTS, that reference PCCTS objects. This is not gen- - erated by default. Not used in C++ mode. - - tokens.h - output #_d_e_f_i_n_e_s for tokens used and function prototypes - for functions generated for rules. - - -SEE ALSO - dlg(1), pccts(1) - - - - - diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/bits.c b/Tools/CodeTools/TianoTools/Pccts/antlr/bits.c deleted file mode 100644 index ddd9bd6053..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/bits.c +++ /dev/null @@ -1,1025 +0,0 @@ -/* bits.c -- manage creation and output of bit sets used by the parser. - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2001 - */ - -#include -#include -#include -#include -#include "pcctscfg.h" -#include "set.h" -#include "syn.h" -#include "hash.h" -#include "generic.h" -#include "dlgdef.h" - -/* char is only thing that is pretty much always known == 8 bits - * This allows output of antlr (set stuff, anyway) to be androgynous (portable) - */ -typedef unsigned char SetWordType; -#define BitsPerByte 8 -#define BitsPerWord BitsPerByte*sizeof(SetWordType) - -static SetWordType *setwd = NULL; -int setnum = -1; -int wordnum = 0; - -int esetnum = 0; - -/* Used to convert native wordsize, which ANTLR uses (via set.c) to manipulate sets, - to bytes that are most portable size-wise. - */ -void -#ifdef __USE_PROTOS -DumpIntAsChars( FILE *f, char *format, unsigned wd ) -#else -DumpIntAsChars( f, format, wd ) -FILE *f; -char *format; -unsigned wd; -#endif -{ - int i; - /* uses max of 32 bit unsigned integer for the moment */ - static unsigned long byte_mask[sizeof(unsigned long)] = - { 0xFF, 0xFF00UL, 0xFF0000UL, 0xFF000000UL }; /* MR20 G. Hobbelt */ -/* 0xFF00000000, 0xFF0000000000, 0xFF000000000000, 0xFF00000000000000 };*/ - - /* for each byte in the word */ - assert(sizeof(unsigned) <= 4); /* M20 G. Hobbelt Sanity check */ - for (i=0; i>(i*BitsPerByte)); - if ( itok))); - return empty; - } - r = RulePtr[q->rulenum]; - r->end->halt = TRUE; /* don't let reach fall off end of rule here */ - rk = empty; - REACH(r, 1, &rk, a); - r->end->halt = FALSE; - return a; -} - -/* - * scan the list of tokens/eclasses/nonterminals filling the new eclass - * with the set described by the list. Note that an eclass can be - * quoted to allow spaces etc... However, an eclass must not conflict - * with a reg expr found elsewhere. The reg expr will be taken over - * the eclass name. - */ -static void -#ifdef __USE_PROTOS -doEclass( char *eclass ) -#else -doEclass( eclass ) -char *eclass; -#endif -{ - TermEntry *q; - ECnode *p; - TCnode *tcnode; - ListNode *e; - unsigned int t; - unsigned deg=0; - set a; - require(eclass!=NULL, "doEclass: NULL eset"); - - p = (ECnode *) eclass; - lexmode(p->lexclass); /* switch to lexclass where errclass is defined */ - p->eset = empty; - for (e = (p->elist)->next; e!=NULL; e=e->next) - { - q = NULL; /* MR23 */ - - if ( islower( *((char *)e->elem) ) ) /* is it a rule ref? (alias FIRST request) */ - { - a = Efirst((char *)e->elem, p); - set_orin(&p->eset, a); - deg += set_deg(a); - set_free( a ); - continue; - } - else if ( *((char *)e->elem)=='"' ) - { - t = 0; - q = (TermEntry *) hash_get(Texpr, (char *) e->elem); - if ( q == NULL ) - { - /* if quoted and not an expr look for eclass name */ - q = (TermEntry *) hash_get(Tname, *((char **)&(e->elem))=StripQuotes((char *)e->elem)); - if ( q != NULL ) t = q->token; - } - else t = q->token; - } - else /* labelled token/eclass/tokclass */ - { - q = (TermEntry *) hash_get(Tname, (char *)e->elem); - if ( q != NULL ) - { - if ( strcmp((char *)e->elem, TokenString(p->tok))==0 ) - { - warnNoFL(eMsg1("self-referential error class '%s'; ignored", - (char *)e->elem)); - continue; - } - else - t = q->token; - } - else t=0; - } - if ( t!=0 ) - { - if (isTermEntryTokClass(q)) { /* MR23 */ - tcnode = q->tclass; /* MR23 */ - set_orin(&p->eset, tcnode->tset); /* MR23 */ - deg = set_deg(p->eset); /* MR23 */ - } /* MR23 */ - else { - set_orel(t, &p->eset); - deg++; - } - } - else warnNoFL(eMsg2("undefined token '%s' referenced in errclass '%s'; ignored", - (char *)e->elem, TokenString(p->tok))); - } - p->setdeg = deg; -} - -void -#ifdef __USE_PROTOS -ComputeErrorSets( void ) -#else -ComputeErrorSets( ) -#endif -{ -#ifdef __cplusplus - list_apply(eclasses, (void (*)(void *)) doEclass); -#else -#ifdef __USE_PROTOS - list_apply(eclasses, (void (*)(void *)) doEclass); -#else - list_apply(eclasses, doEclass); -#endif -#endif -} - -void -#ifdef __USE_PROTOS -ComputeTokSets( void ) -#else -ComputeTokSets( ) -#endif -{ - ListNode *t, *e = NULL, *e1, *e2; - int something_changed; - int i; - TCnode *p; - TermEntry *q, *q1, *q2; - - if ( tclasses == NULL ) return; - - /* turn lists of token/tokclass references into sets */ - for (t = tclasses->next; t!=NULL; t=t->next) - { - p = (TCnode *) t->elem; - - /* if wild card, then won't have entries in tclass, assume all_tokens */ - if ( p->tok == WildCardToken ) - { - p->tset = set_dup(all_tokens); - continue; - } - - lexmode(p->lexclass); /* switch to lexclass where tokclass is defined */ - p->tset = empty; - - /* instantiate all tokens/token_classes into the tset */ - for (e = (p->tlist)->next; e!=NULL; e=e->next) - { - char *tokstr; - tokstr = (char *)e->elem; - if ( *tokstr == '"' ) { - q = (TermEntry *) hash_get(Texpr, tokstr); - require(q!=NULL, "ComputeTokSets: no token def"); - set_orel(q->token, &p->tset); - } else if (tokstr[0] == '.') { - e1=e->next; - e2=e1->next; - e=e2; - q1= (TermEntry *) hash_get(Tname, (char *)e1->elem); - require(q1!=NULL, "ComputeTokSets: no token def"); - q2= (TermEntry *) hash_get(Tname, (char *)e2->elem); - require(q2!=NULL, "ComputeTokSets: no token def"); - - if (set_el(q1->token,imag_tokens)) { -errNoFL(eMsg2("can't define #tokclass %s using #tokclass or #errclass %s", - TokenString(p->tok),(char *)e1->elem) ); - } - if (set_el(q2->token,imag_tokens)) { -errNoFL(eMsg2("can't define #tokclass %s using #tokclass or #errclass %s", - TokenString(p->tok),(char *)e2->elem) ); - } - if (q1->token > q2->token) { -errNoFL(eMsg3("for #tokclass %s %s..%s - first token number > second token number", - TokenString(p->tok),(char *)e1->elem,(char *)e2->elem) ); - for (i=q2->token; i<=q1->token; i++) { set_orel(i, &p->tset); } - } else { - for (i=q1->token; i<=q2->token; i++) { set_orel(i, &p->tset); } - } - } else { - q = (TermEntry *) hash_get(Tname, tokstr); - require(q!=NULL, "ComputeTokSets: no token def"); - set_orel(q->token, &p->tset); - } - } - } - - /* Go thru list of tokclasses again looking for tokclasses in sets */ -again: - something_changed = 0; - for (t = tclasses->next; t!=NULL; t=t->next) - { - set tcl; - p = (TCnode *) t->elem; - tcl = set_and(p->tset, tokclasses); - if ( !set_nil(tcl) ) - { - int tk; - /* replace refs to tokclasses with the associated set of tokens */ - something_changed = 1; - while ( !set_nil(tcl) ) - { - tk = set_int(tcl); /* grab one of the tok class refs */ - set_rm(tk, tcl); - if ( p->tok != tk ) /* tokclass ref to yourself? */ - { - q = (TermEntry *) hash_get(Tname, TokenString(tk)); - require(q!=NULL, "#tokclass not in hash table"); - set_orin(&p->tset, q->tclass->tset); - } - set_rm(tk, p->tset); /* remove ref that we replaced */ - } - } - set_free(tcl); - } - if ( something_changed ) goto again; -} - -void -#ifdef __USE_PROTOS -DumpRemainingTokSets(void) -#else -DumpRemainingTokSets() -#endif -{ - TCnode *p; - ListNode *t; - - /* Go thru tclasses (for the last time) and dump the sets not dumped - * during code gen; yes, this is a bogus way to do this, but ComputeTokSets() - * can't dump the defs as the error file and tok file has not been created - * yet etc... - */ - if ( tclasses==NULL ) return; - for (t = tclasses->next; t!=NULL; t=t->next) - { - unsigned e; - p = (TCnode *) t->elem; - if ( p->dumped ) continue; - e = DefErrSet(&(p->tset), 0, TokenString(p->tok)); - p->dumped = 1; - p->setnum = e; - } -} - - -/* replace a subset of an error set with an error class name if a subset is found - * repeat process until no replacements made - */ -void -#ifdef __USE_PROTOS -SubstErrorClass( set *f ) -#else -SubstErrorClass( f ) -set *f; -#endif -{ - int max, done = 0; - ListNode *p; - ECnode *ec, *maxclass = NULL; - set a; - require(f!=NULL, "SubstErrorClass: NULL eset"); - - if ( eclasses == NULL ) return; - while ( !done ) - { - max = 0; - maxclass = NULL; - for (p=eclasses->next; p!=NULL; p=p->next) /* chk all error classes */ - { - ec = (ECnode *) p->elem; - if ( ec->setdeg > max ) - { - if ( set_sub(ec->eset, *f) || set_equ(ec->eset, *f) ) - {maxclass = ec; max=ec->setdeg;} - } - } - if ( maxclass != NULL ) /* if subset found, replace with token */ - { - a = set_dif(*f, maxclass->eset); - set_orel((unsigned)maxclass->tok, &a); - set_free(*f); - *f = a; - } - else done = 1; - } -} - -int -#ifdef __USE_PROTOS -DefErrSet1(int nilOK, set *f, int subst, char *name ) -#else -DefErrSet1(nilOK, f, subst, name ) -int nilOK; -set *f; -int subst; /* should be substitute error classes? */ -char *name; -#endif -{ - if ( GenCC ) return DefErrSetForCC1(nilOK, f, subst, name, "_set"); - else return DefErrSetForC1(nilOK, f, subst, name, "_set"); -} - -int -#ifdef __USE_PROTOS -DefErrSet( set *f, int subst, char *name ) -#else -DefErrSet( f, subst, name ) -set *f; -int subst; /* should be substitute error classes? */ -char *name; -#endif -{ - return DefErrSet1(0,f,subst,name); -} - -int -#ifdef __USE_PROTOS -DefErrSetWithSuffix(int nilOK, set *f, int subst, char *name, const char* suffix) -#else -DefErrSetWithSuffix(nilOK, f, subst, name, suffix ) -int nilOK; -set *f; -int subst; /* should be substitute error classes? */ -char *name; -char *suffix; -#endif -{ - if ( GenCC ) return DefErrSetForCC1(nilOK, f, subst, name, suffix ); - else return DefErrSetForC1(nilOK, f, subst, name, suffix); -} - -/* Define a new error set. WARNING...set-implementation dependent. - */ -int -#ifdef __USE_PROTOS -DefErrSetForC1(int nilOK, set *f, int subst, char * name, const char * suffix) -#else -DefErrSetForC1(nilOK, f, subst, name, suffix) -int nilOK; /* MR13 */ -set *f; -int subst; /* should be substitute error classes? */ -char *name; -const char *suffix; -#endif -{ - unsigned *p, *endp; - int e=1; - - if (!nilOK) require(!set_nil(*f), "DefErrSetForC1: nil set to dump?"); - - if ( subst ) SubstErrorClass(f); - p = f->setword; - endp = &(f->setword[f->n]); - esetnum++; - if ( name!=NULL ) - fprintf(DefFile, "extern SetWordType %s%s[];\n", name, suffix); - else - fprintf(DefFile, "extern SetWordType zzerr%d[];\n", esetnum); - if ( name!=NULL ) { - fprintf(ErrFile, "SetWordType %s%s[%d] = {", - name, - suffix, - NumWords(TokenNum-1)*sizeof(unsigned)); - } - else { - fprintf(ErrFile, "SetWordType zzerr%d[%d] = {", - esetnum, - NumWords(TokenNum-1)*sizeof(unsigned)); - } - while ( p < endp ) - { - if ( e > 1 ) fprintf(ErrFile, ", "); - DumpIntAsChars(ErrFile, "0x%x", *p++); - if ( e == 3 ) - { - DAWDLE; - if ( p < endp ) fprintf(ErrFile, ","); - fprintf(ErrFile, "\n\t"); - e=1; - } - else e++; - } - fprintf(ErrFile, "};\n"); - - return esetnum; -} - -int -#ifdef __USE_PROTOS -DefErrSetForC( set *f, int subst, char *name ) -#else -DefErrSetForC( f, subst, name ) -set *f; -int subst; /* should be substitute error classes? */ -char *name; -#endif -{ - return DefErrSetForC1(0,f,subst,name, "_set"); -} - -/* Define a new error set. WARNING...set-implementation dependent; - * Only used when -CC on. - */ - -int -#ifdef __USE_PROTOS -DefErrSetForCC1(int nilOK, set *f, int subst, char *name, const char *suffix ) -#else -DefErrSetForCC1(nilOK, f, subst, name, suffix ) -int nilOK; /* MR13 */ -set *f; -int subst; /* should be substitute error classes? */ -char *name; -const char *suffix; -#endif -{ - unsigned *p, *endp; - int e=1; - - if (!nilOK) require(!set_nil(*f), "DefErrSetForCC1: nil set to dump?"); - - if ( subst ) SubstErrorClass(f); - p = f->setword; - endp = &(f->setword[f->n]); - esetnum++; - - if ( name!=NULL ) { - fprintf(Parser_h, "\tstatic SetWordType %s%s[%d];\n", name, suffix, - NumWords(TokenNum-1)*sizeof(unsigned)); - fprintf(Parser_c, "SetWordType %s::%s%s[%d] = {", - CurrentClassName, - name, - suffix, - NumWords(TokenNum-1)*sizeof(unsigned)); - } - else { - fprintf(Parser_c, "SetWordType %s::err%d[%d] = {", - CurrentClassName, - esetnum, - NumWords(TokenNum-1)*sizeof(unsigned)); - fprintf(Parser_h, "\tstatic SetWordType err%d[%d];\n", esetnum, - NumWords(TokenNum-1)*sizeof(unsigned)); - } - - while ( p < endp ) - { - if ( e > 1 ) fprintf(Parser_c, ", "); - DumpIntAsChars(Parser_c, "0x%x", *p++); - if ( e == 3 ) - { - if ( p < endp ) fprintf(Parser_c, ","); - fprintf(Parser_c, "\n\t"); - e=1; - } - else e++; - } - fprintf(Parser_c, "};\n"); - - return esetnum; -} - -int -#ifdef __USE_PROTOS -DefErrSetForCC( set *f, int subst, char *name ) -#else -DefErrSetForCC( f, subst, name ) -set *f; -int subst; /* should be substitute error classes? */ -char *name; -#endif -{ - return DefErrSetForCC1(0,f,subst,name, "_set"); -} - -void -#ifdef __USE_PROTOS -GenParser_c_Hdr(void) -#else -GenParser_c_Hdr() -#endif -{ - int i,j; - TermEntry *te; - char * hasAkaName = NULL; /* MR23 */ - - hasAkaName = (char *) malloc(TokenNum+1); /* MR23 */ - require(hasAkaName!=NULL, "Cannot alloc hasAkaName\n"); /* MR23 */ - for (i = 0; i < TokenNum; i++) hasAkaName[i]='0'; /* MR23 */ - hasAkaName[TokenNum] = 0; /* MR23 */ - - fprintf(Parser_c, "/*\n"); - fprintf(Parser_c, " * %s: P a r s e r S u p p o r t\n", CurrentClassName); - fprintf(Parser_c, " *\n"); - fprintf(Parser_c, " * Generated from:"); - for (i=0; i=LastTokenCounted ) - { - fprintf(Parser_c, ",\n\t/* %02d */\t\"invalid\"", i); - continue; - } - if ( TokenString(i) != NULL ) { - te=(TermEntry *) hash_get(Tname,TokenString(i)); /* MR11 */ - if (te == NULL || te->akaString == NULL) { /* MR11 */ - fprintf(Parser_c, ",\n\t/* %02d */\t\"%s\"", i, TokenString(i)); - } else { - hasAkaName[i] = '1'; /* MR23 */ - fprintf(Parser_c, ",\n\t/* %02d */\t\"%s\"", i, te->akaString); /* MR11 */ - } - } - else - { - /* look in all lexclasses for the reg expr */ - for (j=0; j=NumLexClasses ) - { - if ( UserDefdTokens ) - { - fprintf(Parser_c, ",\n\t/* %02d */\t\"\"", i); - } - else - fatal_internal(eMsgd("No label or expr for token %d",i)); - } - } - } - fprintf(Parser_c, "\n};\n"); - - /* Build constructors */ - fprintf(Parser_c, "\n%s::", CurrentClassName); - fprintf(Parser_c, "%s(ANTLRTokenBuffer *input) : %s(input,%d,%d,%d,%d)\n", - CurrentClassName, - (BaseClassName == NULL ? "ANTLRParser" : BaseClassName), - OutputLL_k, - FoundGuessBlk, - DemandLookahead, - NumWords(TokenNum-1)*sizeof(unsigned)); - fprintf(Parser_c, "{\n"); - fprintf(Parser_c, "\ttoken_tbl = _token_tbl;\n"); - if (TraceGen) { - fprintf(Parser_c, "\ttraceOptionValueDefault=1;\t\t// MR10 turn trace ON\n"); - } else { - fprintf(Parser_c, "\ttraceOptionValueDefault=0;\t\t// MR10 turn trace OFF\n"); - }; - fprintf(Parser_c, "}\n\n"); - free ( (void *) hasAkaName); -} - -void -#ifdef __USE_PROTOS -GenParser_h_Hdr(void) -#else -GenParser_h_Hdr() -#endif -{ - int i; - - fprintf(Parser_h, "/*\n"); - fprintf(Parser_h, " * %s: P a r s e r H e a d e r \n", CurrentClassName); - fprintf(Parser_h, " *\n"); - fprintf(Parser_h, " * Generated from:"); - for (i=0; i 1 ) fprintf(ErrFile, "#define LL_K %d\n", OutputLL_k); -#ifdef DUM - if ( LexGen ) fprintf(ErrFile, "#define zzEOF_TOKEN %d\n", (TokenInd!=NULL?TokenInd[EofToken]:EofToken)); -#endif - fprintf(ErrFile, "#define zzSET_SIZE %d\n", NumWords(TokenNum-1)*sizeof(unsigned)); - if ( DemandLookahead ) fprintf(ErrFile, "#define DEMAND_LOOK\n"); - fprintf(ErrFile, "#include \"antlr.h\"\n"); - if ( GenAST ) fprintf(ErrFile, "#include \"ast.h\"\n"); - - if ( UserDefdTokens ) fprintf(ErrFile, "#include %s\n", UserTokenDefsFile); - /* still need this one as it has the func prototypes */ - fprintf(ErrFile, "#include \"%s\"\n", DefFileName); - fprintf(ErrFile, "#include \"dlgdef.h\"\n"); - fprintf(ErrFile, "#include \"err.h\"\n\n"); - - /* Dump a zztokens for each automaton */ - if ( strcmp(ParserName, DefaultParserName)!=0 ) - { - fprintf(ErrFile, "ANTLRChar *%s_zztokens[%d]={\n", ParserName, TokenNum-1); - } - else - { - fprintf(ErrFile, "ANTLRChar *zztokens[%d]={\n", TokenNum-1); - } - fprintf(ErrFile, "\t/* 00 */\t\"Invalid\""); - for (i=1; i=LastTokenCounted ) - { - fprintf(ErrFile, ",\n\t/* %02d */\t\"invalid\"", i); - continue; - } - if ( TokenString(i) != NULL ) { - te=(TermEntry *) hash_get(Tname,TokenString(i)); /* MR11 */ - if (te == NULL || te->akaString == NULL) { /* MR11 */ - fprintf(ErrFile, ",\n\t/* %02d */\t\"%s\"", i, TokenString(i)); - } else { - fprintf(ErrFile, ",\n\t/* %02d */\t\"%s\"", i, te->akaString); /* MR11 */ - } - } - else - { - /* look in all lexclasses for the reg expr */ - for (j=0; j=NumLexClasses ) - { - if ( UserDefdTokens ) - { - fprintf(ErrFile, ",\n\t/* %02d */\t\"\"", i); - } - else - fatal_internal(eMsgd("No label or expr for token %d",i)); - } - } - } - fprintf(ErrFile, "\n};\n"); -} - -void -#ifdef __USE_PROTOS -dumpExpr( FILE *f, char *e ) -#else -dumpExpr( f, e ) -FILE *f; -char *e; -#endif -{ - while ( *e!='\0' ) - { - if ( *e=='\\' && *(e+1)=='\\' ) - {putc('\\', f); putc('\\', f); e+=2;} - else if ( *e=='\\' && *(e+1)=='"' ) - {putc('\\', f); putc('"', f); e+=2;} - else if ( *e=='\\' ) {putc('\\', f); putc('\\', f); e++;} - else {putc(*e, f); e++;} - } -} - -int -#ifdef __USE_PROTOS -isTermEntryTokClass(TermEntry *te) -#else -isTermEntryTokClass(te) -TermEntry *te; -#endif -{ - ListNode *t; - TCnode *p; - TermEntry *q; - char *tokstr; - - if (tclasses == NULL) return 0; - - for (t = tclasses->next; t!=NULL; t=t->next) - { - p = (TCnode *) t->elem; - tokstr = TokenString(p->tok); - lexmode(p->lexclass); /* switch to lexclass where tokclass is defined */ - q = (TermEntry *) hash_get(Tname, tokstr); - if (q == te) return 1; - } - return 0; -} diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/build.c b/Tools/CodeTools/TianoTools/Pccts/antlr/build.c deleted file mode 100644 index 4eb3b02af1..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/build.c +++ /dev/null @@ -1,813 +0,0 @@ -/* - * build.c -- functions associated with building syntax diagrams. - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2001 - */ - -#include -#include -#include -#include "pcctscfg.h" -#include "set.h" -#include "syn.h" -#include "hash.h" -#include "generic.h" -#include "dlgdef.h" - -#define SetBlk(g, t, approx, first_set_symbol) { \ - ((Junction *)g.left)->jtype = t; \ - ((Junction *)g.left)->approx = approx; \ - ((Junction *)g.left)->pFirstSetSymbol = first_set_symbol; \ - ((Junction *)g.left)->end = (Junction *) g.right; \ - ((Junction *)g.right)->jtype = EndBlk;} - -/* Add the parameter string 'parm' to the parms field of a block-type junction - * g.left points to the sentinel node on a block. i.e. g.left->p1 points to - * the actual junction with its jtype == some block-type. - */ -void -#ifdef __USE_PROTOS -addParm( Node *p, char *parm ) -#else -addParm( p, parm ) -Node *p; -char *parm; -#endif -{ - char *q = (char *) malloc( strlen(parm) + 1 ); - require(p!=NULL, "addParm: NULL object\n"); - require(q!=NULL, "addParm: unable to alloc parameter\n"); - - strcpy(q, parm); - if ( p->ntype == nRuleRef ) - { - ((RuleRefNode *)p)->parms = q; - } - else if ( p->ntype == nJunction ) - { - ((Junction *)p)->parm = q; /* only one parameter allowed on subrules */ - } - else fatal_internal("addParm: invalid node for adding parm"); -} - -/* - * Build an action node for the syntax diagram - * - * buildAction(ACTION) ::= --o-->ACTION-->o-- - * - * Where o is a junction node. - */ -Graph -#ifdef __USE_PROTOS -buildAction( char *action, int file, int line, int is_predicate ) -#else -buildAction( action, file, line, is_predicate ) -char *action; -int file; -int line; -int is_predicate; -#endif -{ - Junction *j1, *j2; - Graph g; - ActionNode *a; - require(action!=NULL, "buildAction: invalid action"); - - j1 = newJunction(); - j2 = newJunction(); - a = newActionNode(); - a->action = (char *) malloc( strlen(action)+1 ); - require(a->action!=NULL, "buildAction: cannot alloc space for action\n"); - strcpy(a->action, action); - j1->p1 = (Node *) a; - a->next = (Node *) j2; - a->is_predicate = is_predicate; - - if (is_predicate) { - PredEntry *predEntry; - char *t; - char *key; - char *u; - int inverted=0; - - t=key=(char *)calloc(1,strlen(a->action)+1); - - for (u=a->action; *u != '\0' ; u++) { - if (*u != ' ') { - if (t==key && *u=='!') { - inverted=!inverted; - } else { - *t++=*u; - }; - }; - }; - - *t='\0'; - - - predEntry=(PredEntry *)hash_get(Pname,key); - a->predEntry=predEntry; - if (predEntry != NULL) a->inverted=inverted; - } else { -/* MR12c */ char *strStart=a->action; -/* MR12c */ char *strEnd; -/* MR12c */ strEnd=strStart+strlen(strStart)-1; -/* MR12c */ for ( ; strEnd >= strStart && isspace(*strEnd); strEnd--) *strEnd=0; -/* MR12c */ while (*strStart != '\0' && isspace(*strStart)) strStart++; -/* MR12c */ if (ci_strequ(strStart,"nohoist")) { -/* MR12c */ a->noHoist=1; -/* MR12c */ } - } - - g.left = (Node *) j1; g.right = (Node *) j2; - a->file = file; - a->line = line; - a->rname = CurRule; /* MR10 */ - return g; -} - -/* - * Build a token node for the syntax diagram - * - * buildToken(TOKEN) ::= --o-->TOKEN-->o-- - * - * Where o is a junction node. - */ -Graph -#ifdef __USE_PROTOS -buildToken( char *text ) -#else -buildToken( text ) -char *text; -#endif -{ - Junction *j1, *j2; - Graph g; - TokNode *t; - require(text!=NULL, "buildToken: invalid token name"); - - j1 = newJunction(); - j2 = newJunction(); - t = newTokNode(); - t->altstart = CurAltStart; - if ( *text == '"' ) {t->label=FALSE; t->token = addTexpr( text );} - else {t->label=TRUE; t->token = addTname( text );} - j1->p1 = (Node *) t; - t->next = (Node *) j2; - g.left = (Node *) j1; g.right = (Node *) j2; - return g; -} - -/* - * Build a wild-card node for the syntax diagram - * - * buildToken(TOKEN) ::= --o-->'.'-->o-- - * - * Where o is a junction node. - */ -Graph -#ifdef __USE_PROTOS -buildWildCard( char *text ) -#else -buildWildCard( text ) -char *text; -#endif -{ - Junction *j1, *j2; - Graph g; - TokNode *t; - TCnode *w; - TermEntry *p; - require(text!=NULL, "buildWildCard: invalid token name"); - - j1 = newJunction(); - j2 = newJunction(); - t = newTokNode(); - - /* If the ref a wild card, make a token class for it */ - if ( Tnum(WildCardString) == 0 ) - { - w = newTCnode; - w->tok = addTname( WildCardString ); - set_orel(w->tok, &imag_tokens); - set_orel(w->tok, &tokclasses); - WildCardToken = w->tok; - require((p=(TermEntry *)hash_get(Tname, WildCardString)) != NULL, - "hash table mechanism is broken"); - p->classname = 1; /* entry is class name, not token */ - p->tclass = w; /* save ptr to this tclass def */ - list_add(&tclasses, (char *)w); - } - else { - p=(TermEntry *)hash_get(Tname, WildCardString); - require( p!= NULL, "hash table mechanism is broken"); - w = p->tclass; - } - - t->token = w->tok; - t->wild_card = 1; - t->tclass = w; - - t->altstart = CurAltStart; - j1->p1 = (Node *) t; - t->next = (Node *) j2; - g.left = (Node *) j1; g.right = (Node *) j2; - return g; -} - -void -#ifdef __USE_PROTOS -setUpperRange(TokNode *t, char *text) -#else -setUpperRange(t, text) -TokNode *t; -char *text; -#endif -{ - require(t!=NULL, "setUpperRange: NULL token node"); - require(text!=NULL, "setUpperRange: NULL token string"); - - if ( *text == '"' ) {t->upper_range = addTexpr( text );} - else {t->upper_range = addTname( text );} -} - -/* - * Build a rule reference node of the syntax diagram - * - * buildRuleRef(RULE) ::= --o-->RULE-->o-- - * - * Where o is a junction node. - * - * If rule 'text' has been defined already, don't alloc new space to store string. - * Set r->text to point to old copy in string table. - */ -Graph -#ifdef __USE_PROTOS -buildRuleRef( char *text ) -#else -buildRuleRef( text ) -char *text; -#endif -{ - Junction *j1, *j2; - Graph g; - RuleRefNode *r; - RuleEntry *p; - require(text!=NULL, "buildRuleRef: invalid rule name"); - - j1 = newJunction(); - j2 = newJunction(); - r = newRNode(); - r->altstart = CurAltStart; - r->assign = NULL; - if ( (p=(RuleEntry *)hash_get(Rname, text)) != NULL ) r->text = p->str; - else r->text = mystrdup( text ); - j1->p1 = (Node *) r; - r->next = (Node *) j2; - g.left = (Node *) j1; g.right = (Node *) j2; - return g; -} - -/* - * Or two subgraphs into one graph via: - * - * Or(G1, G2) ::= --o-G1-o-- - * | ^ - * v | - * o-G2-o - * - * Set the altnum of junction starting G2 to 1 + altnum of junction starting G1. - * If, however, the G1 altnum is 0, make it 1 and then - * make G2 altnum = G1 altnum + 1. - */ -Graph -#ifdef __USE_PROTOS -Or( Graph g1, Graph g2 ) -#else -Or( g1, g2 ) -Graph g1; -Graph g2; -#endif -{ - Graph g; - require(g1.left != NULL, "Or: invalid graph"); - require(g2.left != NULL && g2.right != NULL, "Or: invalid graph"); - - ((Junction *)g1.left)->p2 = g2.left; - ((Junction *)g2.right)->p1 = g1.right; - /* set altnums */ - if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1; - ((Junction *)g2.left)->altnum = ((Junction *)g1.left)->altnum + 1; - g.left = g2.left; - g.right = g1.right; - return g; -} - -/* - * Catenate two subgraphs - * - * Cat(G1, G2) ::= --o-G1-o-->o-G2-o-- - * Cat(NULL,G2)::= --o-G2-o-- - * Cat(G1,NULL)::= --o-G1-o-- - */ -Graph -#ifdef __USE_PROTOS -Cat( Graph g1, Graph g2 ) -#else -Cat( g1, g2 ) -Graph g1; -Graph g2; -#endif -{ - Graph g; - - if ( g1.left == NULL && g1.right == NULL ) return g2; - if ( g2.left == NULL && g2.right == NULL ) return g1; - ((Junction *)g1.right)->p1 = g2.left; - g.left = g1.left; - g.right = g2.right; - return g; -} - -/* - * Make a subgraph an optional block - * - * makeOpt(G) ::= --o-->o-G-o-->o-- - * | ^ - * v | - * o-------o - * - * Note that this constructs {A|B|...|Z} as if (A|B|...|Z|) was found. - * - * The node on the far right is added so that every block owns its own - * EndBlk node. - */ -Graph -#ifdef __USE_PROTOS -makeOpt( Graph g1, int approx, char * pFirstSetSymbol ) -#else -makeOpt( g1, approx, pFirstSetSymbol ) -Graph g1; -int approx; -char * pFirstSetSymbol; -#endif -{ - Junction *j1,*j2,*p; - Graph g; - require(g1.left != NULL && g1.right != NULL, "makeOpt: invalid graph"); - - j1 = newJunction(); - j2 = newJunction(); - ((Junction *)g1.right)->p1 = (Node *) j2; /* add node to G at end */ - - /* MR21 - * - * There is code in genBlk which recognizes the node created - * by emptyAlt() as a special case and bypasses it. We don't - * want this to happen for the optBlk. - */ - - g = emptyAlt3(); /* MR21 */ - if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1; - ((Junction *)g.left)->altnum = ((Junction *)g1.left)->altnum + 1; - for(p=(Junction *)g1.left; p->p2!=NULL; p=(Junction *)p->p2) - {;} /* find last alt */ - p->p2 = g.left; /* add optional alternative */ - ((Junction *)g.right)->p1 = (Node *)j2; /* opt alt points to EndBlk */ - g1.right = (Node *)j2; - SetBlk(g1, aOptBlk, approx, pFirstSetSymbol); - j1->p1 = g1.left; /* add generic node in front */ - g.left = (Node *) j1; - g.right = g1.right; - return g; -} - -/* - * Make a graph into subblock - * - * makeBlk(G) ::= --o-->o-G-o-->o-- - * - * The node on the far right is added so that every block owns its own - * EndBlk node. - */ -Graph -#ifdef __USE_PROTOS -makeBlk( Graph g1, int approx, char * pFirstSetSymbol ) -#else -makeBlk( g1, approx, pFirstSetSymbol ) -Graph g1; -int approx; -char * pFirstSetSymbol; -#endif -{ - Junction *j,*j2; - Graph g; - require(g1.left != NULL && g1.right != NULL, "makeBlk: invalid graph"); - - j = newJunction(); - j2 = newJunction(); - ((Junction *)g1.right)->p1 = (Node *) j2; /* add node to G at end */ - g1.right = (Node *)j2; - SetBlk(g1, aSubBlk, approx, pFirstSetSymbol); - j->p1 = g1.left; /* add node in front */ - g.left = (Node *) j; - g.right = g1.right; - - return g; -} - -/* - * Make a subgraph into a loop (closure) block -- (...)* - * - * makeLoop(G) ::= |---| - * v | - * --o-->o-->o-G-o-->o-- - * | ^ - * v | - * o-----------o - * - * After making loop, always place generic node out front. It becomes - * the start of enclosing block. The aLoopBlk is the target of the loop. - * - * Loop blks have TWO EndBlk nodes--the far right and the node that loops back - * to the aLoopBlk node. Node with which we can branch past loop == aLoopBegin and - * one which is loop target == aLoopBlk. - * The branch-past (initial) aLoopBegin node has end - * pointing to the last EndBlk node. The loop-target node has end==NULL. - * - * Loop blocks have a set of locks (from 1..CLL_k) on the aLoopBlk node. - */ -Graph -#ifdef __USE_PROTOS -makeLoop( Graph g1, int approx, char * pFirstSetSymbol ) -#else -makeLoop( g1, approx, pFirstSetSymbol) -Graph g1; -int approx; -char * pFirstSetSymbol; -#endif -{ - Junction *back, *front, *begin; - Graph g; - require(g1.left != NULL && g1.right != NULL, "makeLoop: invalid graph"); - - back = newJunction(); - front = newJunction(); - begin = newJunction(); - g = emptyAlt3(); - ((Junction *)g1.right)->p2 = g1.left; /* add loop branch to G */ - ((Junction *)g1.right)->p1 = (Node *) back; /* add node to G at end */ - ((Junction *)g1.right)->jtype = EndBlk; /* mark 1st EndBlk node */ - ((Junction *)g1.left)->jtype = aLoopBlk; /* mark 2nd aLoopBlk node */ - ((Junction *)g1.left)->end = (Junction *) g1.right; - ((Junction *)g1.left)->lock = makelocks(); - ((Junction *)g1.left)->pred_lock = makelocks(); - g1.right = (Node *) back; - begin->p1 = (Node *) g1.left; - g1.left = (Node *) begin; - begin->p2 = (Node *) g.left; /* make bypass arc */ - ((Junction *)g.right)->p1 = (Node *) back; - SetBlk(g1, aLoopBegin, approx, pFirstSetSymbol); - front->p1 = g1.left; /* add node to front */ - g1.left = (Node *) front; - - return g1; -} - -/* - * Make a subgraph into a plus block -- (...)+ -- 1 or more times - * - * makePlus(G) ::= |---| - * v | - * --o-->o-G-o-->o-- - * - * After making loop, always place generic node out front. It becomes - * the start of enclosing block. The aPlusBlk is the target of the loop. - * - * Plus blks have TWO EndBlk nodes--the far right and the node that loops back - * to the aPlusBlk node. - * - * Plus blocks have a set of locks (from 1..CLL_k) on the aPlusBlk node. - */ -Graph -#ifdef __USE_PROTOS -makePlus( Graph g1, int approx, char * pFirstSetSymbol) -#else -makePlus( g1, approx, pFirstSetSymbol) -Graph g1; -int approx; -char * pFirstSetSymbol; -#endif -{ - int has_empty_alt_already = 0; - Graph g; - Junction *j2, *j3, *first_alt; - Junction *last_alt=NULL, *p; - require(g1.left != NULL && g1.right != NULL, "makePlus: invalid graph"); - - first_alt = (Junction *)g1.left; - j2 = newJunction(); - j3 = newJunction(); - if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1; - ((Junction *)g1.right)->p2 = g1.left; /* add loop branch to G */ - ((Junction *)g1.right)->p1 = (Node *) j2; /* add node to G at end */ - ((Junction *)g1.right)->jtype = EndBlk; /* mark 1st EndBlk node */ - g1.right = (Node *) j2; - SetBlk(g1, aPlusBlk, approx, pFirstSetSymbol); - ((Junction *)g1.left)->lock = makelocks(); - ((Junction *)g1.left)->pred_lock = makelocks(); - j3->p1 = g1.left; /* add node to front */ - g1.left = (Node *) j3; - - /* add an optional branch which is the "exit" branch of loop */ - /* FIRST, check to ensure that there does not already exist - * an optional path. - */ - /* find last alt */ - for(p=first_alt; p!=NULL; p=(Junction *)p->p2) - { - if ( p->p1->ntype == nJunction && - p->p1!=NULL && - ((Junction *)p->p1)->jtype==Generic && - ((Junction *)p->p1)->p1!=NULL && - ((Junction *)((Junction *)p->p1)->p1)->jtype==EndBlk ) - { - has_empty_alt_already = 1; - } - last_alt = p; - } - if ( !has_empty_alt_already ) - { - require(last_alt!=NULL, "last_alt==NULL; bad (..)+"); - g = emptyAlt(); - last_alt->p2 = g.left; - ((Junction *)g.right)->p1 = (Node *) j2; - - /* make sure lookahead computation ignores this alt for - * FIRST("(..)+"); but it's still used for computing the FIRST - * of each alternative. - */ - ((Junction *)g.left)->ignore = 1; - } - - return g1; -} - -/* - * Return an optional path: --o-->o-- - */ - -Graph -#ifdef __USE_PROTOS -emptyAlt( void ) -#else -emptyAlt( ) -#endif -{ - Junction *j1, *j2; - Graph g; - - j1 = newJunction(); - j2 = newJunction(); - j1->p1 = (Node *) j2; - g.left = (Node *) j1; - g.right = (Node *) j2; - - return g; -} - -/* MR21 - * - * There is code in genBlk which recognizes the node created - * by emptyAlt() as a special case and bypasses it. We don't - * want this to happen for the optBlk. - */ - -Graph -#ifdef __USE_PROTOS -emptyAlt3( void ) -#else -emptyAlt3( ) -#endif -{ - Junction *j1, *j2, *j3; - Graph g; - - j1 = newJunction(); - j2 = newJunction(); - j3 = newJunction(); - j1->p1 = (Node *) j2; - j2->p1 = (Node *) j3; - g.left = (Node *) j1; - g.right = (Node *) j3; - - return g; -} - -/* N o d e A l l o c a t i o n */ - -TokNode * -#ifdef __USE_PROTOS -newTokNode( void ) -#else -newTokNode( ) -#endif -{ - static TokNode *FreeList = NULL; - TokNode *p, *newblk; - - if ( FreeList == NULL ) - { - newblk = (TokNode *)calloc(TokenBlockAllocSize, sizeof(TokNode)); - if ( newblk == NULL ) - fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule)); - for (p=newblk; p<&(newblk[TokenBlockAllocSize]); p++) - { - p->next = (Node *)FreeList; /* add all new token nodes to FreeList */ - FreeList = p; - } - } - p = FreeList; - FreeList = (TokNode *)FreeList->next;/* remove a TokNode node */ - p->next = NULL; /* NULL the ptr we used */ - memset( (char *) p, 0, sizeof(TokNode)); /* MR10 */ - p->ntype = nToken; - p->rname = CurRule; - p->file = CurFile; - p->line = zzline; - p->altstart = NULL; - - return p; -} - -RuleRefNode * -#ifdef __USE_PROTOS -newRNode( void ) -#else -newRNode( ) -#endif -{ - static RuleRefNode *FreeList = NULL; - RuleRefNode *p, *newblk; - - if ( FreeList == NULL ) - { - newblk = (RuleRefNode *)calloc(RRefBlockAllocSize, sizeof(RuleRefNode)); - if ( newblk == NULL ) - fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule)); - for (p=newblk; p<&(newblk[RRefBlockAllocSize]); p++) - { - p->next = (Node *)FreeList; /* add all new rref nodes to FreeList */ - FreeList = p; - } - } - p = FreeList; - FreeList = (RuleRefNode *)FreeList->next;/* remove a Junction node */ - p->next = NULL; /* NULL the ptr we used */ - memset( (char *) p, 0, sizeof(RuleRefNode)); /* MR10 */ - p->ntype = nRuleRef; - p->rname = CurRule; - p->file = CurFile; - p->line = zzline; - p->astnode = ASTinclude; - p->altstart = NULL; - - return p; -} - -static int junctionSeqNumber=0; /* MR10 */ - -Junction * -#ifdef __USE_PROTOS -newJunction( void ) -#else -newJunction( ) -#endif -{ - static Junction *FreeList = NULL; - Junction *p, *newblk; - - if ( FreeList == NULL ) - { - newblk = (Junction *)calloc(JunctionBlockAllocSize, sizeof(Junction)); - if ( newblk == NULL ) - fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule)); - for (p=newblk; p<&(newblk[JunctionBlockAllocSize]); p++) - { - p->p1 = (Node *)FreeList; /* add all new Junction nodes to FreeList */ - FreeList = p; - } - } - p = FreeList; - FreeList = (Junction *)FreeList->p1;/* remove a Junction node */ - p->p1 = NULL; /* NULL the ptr we used */ - memset( (char *) p, 0, sizeof(Junction)); /* MR10 */ - p->ntype = nJunction; - p->visited = 0; - p->jtype = Generic; - p->rname = CurRule; - p->file = CurFile; - p->line = zzline; - p->exception_label = NULL; - p->fset = (set *) calloc(CLL_k+1, sizeof(set)); - require(p->fset!=NULL, "cannot allocate fset in newJunction"); - p->seq=++junctionSeqNumber; /* MR10 */ - - return p; -} - -ActionNode * -#ifdef __USE_PROTOS -newActionNode( void ) -#else -newActionNode( ) -#endif -{ - static ActionNode *FreeList = NULL; - ActionNode *p, *newblk; - - if ( FreeList == NULL ) - { - newblk = (ActionNode *)calloc(ActionBlockAllocSize, sizeof(ActionNode)); - if ( newblk == NULL ) - fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule)); - for (p=newblk; p<&(newblk[ActionBlockAllocSize]); p++) - { - p->next = (Node *)FreeList; /* add all new Action nodes to FreeList */ - FreeList = p; - } - } - p = FreeList; - FreeList = (ActionNode *)FreeList->next;/* remove an Action node */ - memset( (char *) p, 0, sizeof(ActionNode)); /* MR10 */ - p->ntype = nAction; - p->next = NULL; /* NULL the ptr we used */ - p->done = 0; - p->pred_fail = NULL; - p->guardpred = NULL; - p->ampersandPred = NULL; - return p; -} - -/* - * allocate the array of locks (1..CLL_k) used to inhibit infinite recursion. - * Infinite recursion can occur in (..)* blocks, FIRST calcs and FOLLOW calcs. - * Therefore, we need locks on aLoopBlk, RuleBlk, EndRule nodes. - * - * if ( lock[k]==TRUE ) then we have been here before looking for k tokens - * of lookahead. - */ -char * -#ifdef __USE_PROTOS -makelocks( void ) -#else -makelocks( ) -#endif -{ - char *p = (char *) calloc(CLL_k+1, sizeof(char)); - require(p!=NULL, "cannot allocate lock array"); - - return p; -} - -#if 0 -** #ifdef __USE_PROTOS -** void my_memset(char *p,char value,int count) -** #else -** void my_memset(p,value,count) -** char *p; -** char value; -** int count; -** #endif -** { -** int i; -** -** for (i=0; i - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/dumpcycles.c b/Tools/CodeTools/TianoTools/Pccts/antlr/dumpcycles.c deleted file mode 100644 index 8156159f71..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/dumpcycles.c +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include - -#include "set.h" -#include "syn.h" -#include "hash.h" -#include "generic.h" - -void -#ifdef __USE_PROTOS -dumpcycles(void) -#else -dumpcycles() -#endif -{ - Cycle *c; - CacheEntry *f; - ListNode *p; - int i=0; - int k; - int degree; - - for (k=1; k <= CLL_k; k++) { - if (Cycles[k] == NULL) continue; - - for (p = Cycles[k]->next; p!=NULL; p=p->next) { - c = (Cycle *) p->elem; - degree=set_deg(c->cyclicDep); - fprintf(stderr,"Cycle %d: (degree %d) %s -->\n", i++, degree, RulePtr[c->croot]->rname); - fprintf(stderr," *self*\n"); - MR_dumpRuleSet(c->cyclicDep); - fprintf(stderr,"\n"); - f = (CacheEntry *) - hash_get(Fcache,Fkey(RulePtr[c->croot]->rname,'o',k)); - if (f == NULL) { - fprintf(stderr," *** FOLLOW(%s) must be in cache but isn't ***\n", - RulePtr[c->croot]->rname); - }; - }; - }; -} - -void -#ifdef __USE_PROTOS -dumpfostack(int k) -#else -dumpfostack(k) -int k; -#endif -{ - int i=0; - int *pi; - - fprintf(stderr,"\n"); - if (FoStack[k] == NULL) { - fprintf(stderr,"FoStack[%d] is null\n",k); - }; - if (FoTOS[k] == NULL) { - fprintf(stderr,"FoTOS[%d] is null\n",k); - } - if (FoTOS[k] != NULL && FoStack[k] != NULL) { - for (pi=FoStack[k]; pi <= FoTOS[k]; pi++) { - i++; - fprintf(stderr,"#%d rule %d %s\n",i,*pi,RulePtr[*pi]->rname); - } - } -} diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/dumpnode.c b/Tools/CodeTools/TianoTools/Pccts/antlr/dumpnode.c deleted file mode 100644 index 2a34c6fcd5..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/dumpnode.c +++ /dev/null @@ -1,423 +0,0 @@ -#include -#include - -#include "set.h" -#include "syn.h" -#include "hash.h" -#include "generic.h" - -#ifdef __USE_PROTOS -void dumpset1(set s) -#else -void dumpset1(s) - set s; -#endif -{ - if (set_nil(s)) { - fprintf(stderr,"{}"); - } else { - s_fprT(stderr,s); - }; -} - -#ifdef __USE_PROTOS -void dumpset(set s) -#else -void dumpset(s) - set s; -#endif -{ - dumpset1(s); - fprintf(stderr,"\n"); -} - -#ifdef __USE_PROTOS -int isEndRule(Node * p) -#else -int isEndRule(p) - Node * p; -#endif -{ - int result=0; - if ( p->ntype == nJunction && - ( (Junction *) p)->jtype == EndRule) { - result=1; - }; - return result; -} - -#ifdef __USE_PROTOS -void dumppred1(int depth,Predicate *p) -#else -void dumppred1(depth,p) - int depth; - Predicate *p; -#endif -{ - int i; - int k; - - for (i=0; iexpr == PRED_AND_LIST || - p->expr == PRED_OR_LIST) { - fprintf(stderr," %s", (p->expr == NULL ? "null expr" : p->expr)); - if (p->inverted) fprintf(stderr," predicate inverted !"); - if (p->redundant) { - fprintf(stderr," Redundant!"); - }; - if (p->isConst) fprintf(stderr," const %d !",p->constValue); - fprintf(stderr,"\n"); - } else { - fprintf(stderr,"predicate k=%d",p->k); - k=set_int(p->completionSet); - if (k >= 0) { - fprintf(stderr," Incomplete Set=%d !",k); - }; - k=set_int(p->completionTree); - if (k >= 0) { - fprintf(stderr," Incomplete Tree=%d !",k); - }; - if (p->redundant) { - fprintf(stderr," Redundant!"); - }; - fprintf(stderr," \"%s\" (%x)", (p->expr == NULL ? "null expr" : p->expr) ,p); - if (p->source != NULL) { - fprintf(stderr,"line %d",p->source->line); - }; - if (p->inverted) fprintf(stderr," predicate inverted !"); - fprintf(stderr,"\n"); - for (i=0; iscontext[1]); - for (i=0; itcontext); - fprintf(stderr,"\n"); - }; - fprintf(stderr,"\n"); - if (p->down != NULL) { - dumppred1(depth+1,p->down); - }; - if (p->right != NULL) { - dumppred1(depth,p->right); - }; -} - -#ifdef __USE_PROTOS -void dumppred(Predicate *p) -#else -void dumppred(p) - Predicate *p; -#endif -{ - fprintf(stderr,"---------------------------------\n"); - dumppred1(0,p); - fprintf(stderr,"\n"); -} - -#ifdef __USE_PROTOS -void dumppredtree(Predicate *p) -#else -void dumppredtree(p) - Predicate *p; -#endif -{ - fprintf(stderr,"predicate k=%d \"%s\" line %d\n",p->k,p->expr,p->source->line); - dumpset(p->scontext[1]); -} - -#ifdef __USE_PROTOS -void dumppredexpr(Predicate *p) -#else -void dumppredexpr(p) - Predicate *p; -#endif -{ - fprintf(stderr," pred expr \"%s\"\n",p->expr); -} - -#ifdef __USE_PROTOS -void dt(Tree *t) -#else -void dt(t) - Tree *t; -#endif -{ - MR_dumpTreeF(stderr,0,t,5); -} - -#ifdef __USE_PROTOS -void d(Node * p) -#else -void d(p) - Node * p; -#endif -{ - - Junction *j; - RuleRefNode *r; - TokNode *t; - ActionNode *a; - - if (p==NULL) { - fprintf(stderr,"dumpNode: Node is NULL"); - return; - }; - - switch (p->ntype) { - case nJunction : - j = (Junction *) p; - fprintf(stderr, "Junction (#%d in rule %s line %d) ",j->seq,j->rname,j->line); - if (j->guess) fprintf(stderr,"guess block "); - switch (j->jtype ) { - case aSubBlk : - fprintf(stderr,"aSubBlk"); - break; - case aOptBlk : - fprintf(stderr,"aOptBlk"); - break; - case aLoopBegin : - fprintf(stderr,"aLoopBeginBlk"); - break; - case aLoopBlk : - fprintf(stderr,"aLoopBlk"); - break; - case aPlusBlk : - fprintf(stderr,"aPlusBlk"); - break; - case EndBlk : - fprintf(stderr,"EndBlk"); - break; - case RuleBlk : - fprintf(stderr,"RuleBlk"); - break; - case Generic : - fprintf(stderr,"Generic"); - break; - case EndRule : - fprintf(stderr,"EndRule"); - break; - }; - if (j->halt) fprintf(stderr," halt!"); - if (j->p1) fprintf(stderr," p1 valid"); - if (j->p2) { - if (j->p2->ntype == nJunction) { - fprintf(stderr," (p2=#%d)",( (Junction *) j->p2)->seq); - } else { - fprintf(stderr," (p2 valid)"); - }; - }; - if (j->ignore) fprintf(stderr, " ignore/plus-block-bypass"); - if (j->fset != NULL && set_deg(*j->fset) != 0) { - fprintf(stderr,"\nfset:\n"); - dumpset(*j->fset); - }; - if (j->ftree != NULL) { - fprintf(stderr,"\nftree:\n"); - preorder(j->ftree); - }; - fprintf(stderr,"\n"); - break; - case nRuleRef : - r = (RuleRefNode *) p; - fprintf(stderr, "RuleRefNode (in rule %s line %d) to rule %s\n", r->rname,r->line,r->text); - break; - case nToken : - t = (TokNode *) p; - fprintf(stderr, "TokNode (in rule %s line %d) token %s\n",t->rname,t->line,TerminalString(t->token)); - break; - case nAction : - a =(ActionNode *) p; - if (a->is_predicate) { - fprintf(stderr, "Predicate (in rule %s line %d) %s",a->rname,a->line,a->action); - if (a->inverted) fprintf(stderr," action inverted !"); - if (a->guardpred != NULL) { - fprintf(stderr," guarded"); - dumppredexpr(a->guardpred); - if (a->ampersandPred) { - fprintf(stderr," \"&&\" style"); - } else { - fprintf(stderr," \"=>\" style"); - }; - }; - if (a->predEntry != NULL) fprintf(stderr," predEntry \"%s\" ",a->predEntry->str); - fprintf(stderr,"\n"); - } else if (a->init_action) { - fprintf(stderr, "Init-Action (in rule %s line %d) %s\n",a->rname,a->line,a->action); - } else { - fprintf(stderr, "Action (in rule %s line %d) %s\n",a->rname,a->line,a->action); - }; - break; - }; -} - -#ifdef __USE_PROTOS -Node * dp1(Node * p) -#else -Node * dp1(p) - Node * p; -#endif -{ - Node *result=NULL; - - if (p->ntype == nJunction) { - result=( (Junction *) p )->p1; - d(result); - } else { - fprintf(stderr,"dp1: Not a Junction node"); - }; - return result; -} - -#ifdef __USE_PROTOS -Node * dp2(Node * p) -#else -Node * dp2(p) - Node * p; -#endif -{ - Node *result=NULL; - - if (p->ntype == nJunction) { - result=( (Junction *) p )->p2; - d(result); - } else { - fprintf(stderr,"dp2: Not a Junction node"); - }; - return result; -} - -#ifdef __USE_PROTOS -Node * dn(Node * p) -#else -Node * dn(p) - Node * p; -#endif - -{ - Node *result=NULL; - - if (p->ntype == nRuleRef) { - result=( (RuleRefNode *)p )->next; - } else if (p->ntype == nAction) { - result=( (ActionNode *)p )->next; - } else if (p->ntype == nToken) { - result=( (TokNode *)p )->next; - } else { - fprintf(stderr,"No next field: Neither a RuleRefNode, ActionNode, nor TokNode"); - }; - if (result != NULL) d(result); - return result; -} - -#ifdef __USE_PROTOS -void df(Node * p) -#else -void df(p) - Node * p; -#endif -{ - int count=0; - Node *next; - - fprintf(stderr,"\n#%d ",++count); - d(p); - - for (next=p; next != NULL && !isEndRule(next) ; ) { - fprintf(stderr,"#%d ",++count); - if (next->ntype == nJunction) { - next=dp1(next); - } else { - next=dn(next); - }; - }; -} - -#ifdef __USE_PROTOS -Node * dfn(Node * p,int target) -#else -Node * dfn(p,target) - Node * p; - int target; -#endif -{ - Node *result=NULL; - int count=0; - Node *next; - - fprintf(stderr,"#%d ",++count); - d(p); - - for (next=p; next != NULL && !isEndRule(next) ; ) { - fprintf(stderr,"#%d ",++count); - if (next->ntype == nJunction) { - next=dp1(next); - } else { - next=dn(next); - }; - if (count == target) { - result=next; - break; - }; - }; - return result; -} - - -static int findnodeMatch; - -#ifdef __USE_PROTOS -Junction *findnode1(Node *n) -#else -Junction *findnode1(n) - Node *n; -#endif -{ - Node *next; - Junction *j; - Junction *match; - - if (n == NULL) return NULL; - if (n->ntype == nJunction) { - j=(Junction *) n; - if (j->seq == findnodeMatch) return j; - if (j->jtype == EndRule) return NULL; - if (j->jtype != RuleBlk && j->jtype != EndBlk) { - if (j->p2 != NULL && !j->ignore) { - match=findnode1(j->p2); - if (match != NULL) return match; - }; - }; - }; - next=MR_advance(n); - return findnode1(next); -} - -#ifdef __USE_PROTOS -Junction *findnode(int match) -#else -Junction *findnode(match) - int match; -#endif -{ - Junction *j; - Junction *result=NULL; - - findnodeMatch=match; - - for (j=SynDiag; j != NULL; j=(Junction *)j->p2) { - require (j->ntype == nJunction && j->jtype == RuleBlk,"Not a rule block"); - result=findnode1( (Node *) j); - if (result != NULL) break; - }; - if (result != NULL) { - d( (Node *) result); - }; - return result; -} diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/egman.c b/Tools/CodeTools/TianoTools/Pccts/antlr/egman.c deleted file mode 100644 index c8a633fc06..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/egman.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * egman.c - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33MR10 - * 2001 - * - */ - -#include -#include - -#include "set.h" -#include "syn.h" -#include "hash.h" -#include "generic.h" -#include "proto.h" - -static ExceptionGroup **egArray=NULL; /* ExceptionGroup by BlkLevel */ -static LabelEntry **leArray=NULL; /* LabelEntry by BlkLevel */ -static Junction **altArray=NULL; /* start of alternates */ -static int arraySize=0; -static int highWater=0; -static ExceptionGroup *lastEG=NULL; /* used in altFixup() */ -static int lastBlkLevel=0; /* used in altFixup() */ - -#ifdef __USE_PROTOS -static void arrayCheck(void); -#else -static void arrayCheck(); -#endif - -/* Called to add an exception group for an alternative EG */ - -#ifdef __USE_PROTOS -void egAdd(ExceptionGroup * eg) -#else -void egAdd(eg) -ExceptionGroup *eg; -#endif -{ - int i; - - ExceptionGroup *nextEG; - ExceptionGroup *innerEG; - - LabelEntry *nextLE; - LabelEntry *innerLE; - - Junction *nextAlt; - Junction *innerAlt; - - lastEG=eg; - lastBlkLevel=BlkLevel; - - arrayCheck(); - eg->pendingLink=egArray[BlkLevel]; - egArray[BlkLevel]=eg; - - /* EG for alternates already have their altID filled in */ - - for (i=BlkLevel+1; i<=highWater ; i++) { - for (innerEG=egArray[i]; innerEG != NULL ; innerEG=nextEG) { - nextEG=innerEG->pendingLink; - innerEG->pendingLink=NULL; - innerEG->outerEG=eg; - }; - egArray[i]=NULL; - }; - - /* - * for patching up the LabelEntry you might use an EG for the - * current alternative - unlike patching up an alternative EG - * i.e. start the loop at BlkLevel rather than (BlkLevel+1) - * fill it in only if the EG and the LE are for the very - * same alternative if they're at the same BlkLevel - * it's easier to leave the LE on this list (filled in) rather than - * trying to selectively remove it. It will eventually be - * removed anyway when the BlkLevel gets small enough. - */ - - for (i=BlkLevel; i<=highWater ; i++) { - for (innerLE=leArray[i]; innerLE != NULL ; innerLE=nextLE) { - nextLE=innerLE->pendingLink; - if (BlkLevel != i || - innerLE->curAltNum == CurAltNum_array[BlkLevel]) { - if (innerLE->outerEG == NULL) { - innerLE->outerEG=eg; - }; - }; - }; - if (BlkLevel != i) leArray[i]=NULL; - }; - -/* - * For the start of alternatives it is necessary to make a - * distinction between the exception group for the current - * alternative and the "fallback" EG for the block which - * contains the alternative - * - * The fallback outerEG is used to handle the case where - * no alternative of a block matches. In that case the - * signal is "NoViableAlt" (or "NoSemViableAlt" and the - * generator needs the EG of the block CONTAINING the - * current one. - * - * rule: ( ( ( a - * | b - * ) - * | c - * ) - * | d - * ); - */ - - for (i=BlkLevel; i <= highWater ; i++) { - for (innerAlt=altArray[i]; innerAlt != NULL ; innerAlt=nextAlt) { - nextAlt=innerAlt->pendingLink; - - /* first fill in the EG for the current alternative */ - /* but leave it on the list in order to get the fallback EG */ - /* if the EG is at the same LEVEL as the alternative then */ - /* fill it in only if in the very same alternative */ - /* */ - /* rule: ( a */ - /* | b */ - /* | c exception ... */ - /* ) */ - /* */ - /* if the EG is outside the alternative (e.g. BlkLevel < i) */ - /* then it doesn't matter about the alternative */ - /* */ - /* rule: ( a */ - /* | b */ - /* | c */ - /* ) exception ... */ - /* */ - -#if 0 - printf("BlkLevel=%d i=%d altnum=%d CurAltNum=%d altID=%s\n", - BlkLevel,i,innerAlt->curAltNum,CurAltNum_array[BlkLevel],eg->altID); -#endif - if (BlkLevel != i || - innerAlt->curAltNum == CurAltNum_array[BlkLevel]) { - if (innerAlt->exception_label == NULL) { - innerAlt->exception_label=eg->altID; - }; - }; - - /* ocurs at a later pass then for the exception_label */ - /* if an outerEG has been found then fill in the outer EG */ - /* remove if from the list when the BlkLevel gets smaller */ - - if (BlkLevel != i) { - if (innerAlt->outerEG == NULL) { - innerAlt->outerEG=eg; - }; - }; - }; - if (BlkLevel != i) altArray[i]=NULL; - }; -} - -#ifdef __USE_PROTOS -void leAdd(LabelEntry * le) -#else -void leAdd(le) -LabelEntry *le; -#endif - -{ - arrayCheck(); - le->pendingLink=leArray[BlkLevel]; - le->curAltNum=CurAltNum_array[BlkLevel]; - leArray[BlkLevel]=le; -} - -#ifdef __USE_PROTOS -void altAdd(Junction *alt) -#else -void altAdd(alt) -Junction *alt; -#endif - -{ - arrayCheck(); -#if 0 - printf("BlkLevel=%d CurAltNum=%d\n", - BlkLevel,CurAltNum_array[BlkLevel]); -#endif - alt->curAltNum=CurAltNum_array[BlkLevel]; - alt->pendingLink=altArray[BlkLevel]; - altArray[BlkLevel]=alt; -} - -static void -#ifdef __USE_PROTOS -arrayCheck(void) -#else -arrayCheck() -#endif -{ - ExceptionGroup **egArrayNew; - LabelEntry **leArrayNew; - Junction **altArrayNew; - int arraySizeNew; - int i; - - if (BlkLevel > highWater) highWater=BlkLevel; - - if (BlkLevel >= arraySize) { - arraySizeNew=BlkLevel+5; /* MR20 */ - egArrayNew=(ExceptionGroup **) - calloc(arraySizeNew,sizeof(ExceptionGroup *)); - leArrayNew=(LabelEntry **) - calloc(arraySizeNew,sizeof(LabelEntry *)); - altArrayNew=(Junction **) - calloc(arraySizeNew,sizeof(Junction *)); - for (i=0; ipendingLink; - innerEG->pendingLink=NULL; - }; - egArray[i]=NULL; - }; - lastEG=NULL; - lastBlkLevel=0; -} - -/* always call leFixup() BEFORE egFixup() */ - -#ifdef __USE_PROTOS -void leFixup(void) -#else -void leFixup() -#endif -{ - - int i; - LabelEntry *nextLE; - LabelEntry *innerLE; - - for (i=BlkLevel; i<=highWater ; i++) { - for (innerLE=leArray[i]; innerLE != NULL ; innerLE=nextLE) { - nextLE=innerLE->pendingLink; - innerLE->pendingLink=NULL; - }; - leArray[i]=NULL; - }; -} - -/* always call altFixup() BEFORE egFixup() */ - -#ifdef __USE_PROTOS -void altFixup(void) -#else -void altFixup() -#endif -{ - - int i; - Junction *nextAlt; - Junction *innerAlt; - - for (i=BlkLevel; i<=highWater ; i++) { - for (innerAlt=altArray[i]; innerAlt != NULL ; innerAlt=nextAlt) { - - /* if an outerEG has been found then fill in the outer EG */ - - if (lastBlkLevel <= i) { - if (innerAlt->outerEG == NULL) { - innerAlt->outerEG=lastEG; - }; - }; - nextAlt=innerAlt->pendingLink; - innerAlt->pendingLink=NULL; - }; - altArray[i]=NULL; - }; -} - diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/err.c b/Tools/CodeTools/TianoTools/Pccts/antlr/err.c deleted file mode 100644 index ca239398cf..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/err.c +++ /dev/null @@ -1,538 +0,0 @@ -/* - * A n t l r S e t s / E r r o r F i l e H e a d e r - * - * Generated from: antlr.g - * - * Terence Parr, Russell Quong, Will Cohen, and Hank Dietz: 1989-2001 - * Parr Research Corporation - * with Purdue University Electrical Engineering - * With AHPCRC, University of Minnesota - * ANTLR Version 1.33MR33 - */ - -#define ANTLR_VERSION 13333 -#include "pcctscfg.h" -#include "pccts_stdio.h" - -#include "pcctscfg.h" -#include "set.h" -#include -#include "syn.h" -#include "hash.h" -#include "generic.h" -#define zzcr_attr(attr,tok,t) -#define zzSET_SIZE 20 -#include "antlr.h" -#include "tokens.h" -#include "dlgdef.h" -#include "err.h" - -ANTLRChar *zztokens[157]={ - /* 00 */ "Invalid", - /* 01 */ "Eof", - /* 02 */ "QuotedTerm", - /* 03 */ "\\n|\\r|\\r\\n", - /* 04 */ "\\(\\n|\\r|\\r\\n)", - /* 05 */ "\\~[]", - /* 06 */ "~[\\n\\r\"\\]+", - /* 07 */ "\"", - /* 08 */ "\\n|\\r|\\r\\n", - /* 09 */ "\\(\\n|\\r|\\r\\n)", - /* 10 */ "\\~[]", - /* 11 */ "~[\\n\\r\"\\]+", - /* 12 */ "'", - /* 13 */ "\\n|\\r|\\r\\n", - /* 14 */ "\\~[]", - /* 15 */ "~[\\n\\r'\\]+", - /* 16 */ "\\*/", - /* 17 */ "\\*", - /* 18 */ "\\n|\\r|\\r\\n", - /* 19 */ "~[\\n\\r\\*]+", - /* 20 */ "\\*/", - /* 21 */ "\\*", - /* 22 */ "\\n|\\r|\\r\\n", - /* 23 */ "~[\\n\\r\\*]+", - /* 24 */ "\\n|\\r|\\r\\n", - /* 25 */ "~[\\n\\r]+", - /* 26 */ "\\n|\\r|\\r\\n", - /* 27 */ "~[\\n\\r]+", - /* 28 */ "\\n|\\r|\\r\\n", - /* 29 */ "~[\\n\\r]+", - /* 30 */ "\\*/", - /* 31 */ "\\*", - /* 32 */ "\\n|\\r|\\r\\n", - /* 33 */ "~[\\n\\r\\*]+", - /* 34 */ "Action", - /* 35 */ "Pred", - /* 36 */ "PassAction", - /* 37 */ "consumeUntil\\( [\\ \\t]* \\{~[\\}]+\\} [\\ \\t]* \\)", - /* 38 */ "consumeUntil\\( ~[\\)]+ \\)", - /* 39 */ "\\n|\\r|\\r\\n", - /* 40 */ "\\>", - /* 41 */ "$", - /* 42 */ "$$", - /* 43 */ "$\\[\\]", - /* 44 */ "$\\[", - /* 45 */ "$[0-9]+", - /* 46 */ "$[0-9]+.", - /* 47 */ "$[0-9]+.[0-9]+", - /* 48 */ "$[_a-zA-Z][_a-zA-Z0-9]*", - /* 49 */ "#0", - /* 50 */ "#\\[\\]", - /* 51 */ "#\\(\\)", - /* 52 */ "#[0-9]+", - /* 53 */ "#line[\\ \\t]* [0-9]+ {[\\ \\t]* \"~[\"]+\" ([\\ \\t]* [0-9]*)* } (\\n|\\r|\\r\\n)", - /* 54 */ "#line ~[\\n\\r]* (\\n|\\r|\\r\\n)", - /* 55 */ "#[_a-zA-Z][_a-zA-Z0-9]*", - /* 56 */ "#\\[", - /* 57 */ "#\\(", - /* 58 */ "#", - /* 59 */ "\\)", - /* 60 */ "\\[", - /* 61 */ "\\(", - /* 62 */ "\\\\]", - /* 63 */ "\\\\)", - /* 64 */ "\\>", - /* 65 */ "'", - /* 66 */ "\"", - /* 67 */ "\\$", - /* 68 */ "\\#", - /* 69 */ "\\(\\n|\\r|\\r\\n)", - /* 70 */ "\\~[\\]\\)>$#]", - /* 71 */ "/", - /* 72 */ "/\\*", - /* 73 */ "\\*/", - /* 74 */ "//", - /* 75 */ "~[\\n\\r\\)\\(\\$#\\>\\]\\[\"'/]+", - /* 76 */ "[\\t\\ ]+", - /* 77 */ "\\n|\\r|\\r\\n", - /* 78 */ "\\[", - /* 79 */ "\\<\\<", - /* 80 */ "\"", - /* 81 */ "/\\*", - /* 82 */ "\\*/", - /* 83 */ "//", - /* 84 */ "#line[\\ \\t]* [0-9]+ {[\\ \\t]* \"~[\"]+\" ([\\ \\t]* [0-9]*)* } (\\n|\\r|\\r\\n)", - /* 85 */ "#line ~[\\n\\r]* (\\n|\\r|\\r\\n)", - /* 86 */ "\\>\\>", - /* 87 */ "WildCard", - /* 88 */ "\\@", - /* 89 */ "LABEL", - /* 90 */ "grammar-element", - /* 91 */ "meta-symbol", - /* 92 */ "Pragma", - /* 93 */ "FirstSetSymbol", - /* 94 */ "{\\}#header", - /* 95 */ "{\\}#first", - /* 96 */ "{\\}#parser", - /* 97 */ "{\\}#tokdefs", - /* 98 */ "\\}", - /* 99 */ "class", - /* 100 */ "NonTerminal", - /* 101 */ "TokenTerm", - /* 102 */ "\\{", - /* 103 */ "!", - /* 104 */ "\\<", - /* 105 */ "\\>", - /* 106 */ ":", - /* 107 */ ";", - /* 108 */ "{\\}#lexaction", - /* 109 */ "{\\}#lexmember", - /* 110 */ "{\\}#lexprefix", - /* 111 */ "{\\}#pred", - /* 112 */ "\\|\\|", - /* 113 */ "&&", - /* 114 */ "\\(", - /* 115 */ "\\)", - /* 116 */ "{\\}#lexclass", - /* 117 */ "{\\}#errclass", - /* 118 */ "{\\}#tokclass", - /* 119 */ "..", - /* 120 */ "{\\}#token", - /* 121 */ "=", - /* 122 */ "[0-9]+", - /* 123 */ "\\|", - /* 124 */ "\\~", - /* 125 */ "^", - /* 126 */ "approx", - /* 127 */ "LL\\(1\\)", - /* 128 */ "LL\\(2\\)", - /* 129 */ "\\*", - /* 130 */ "\\+", - /* 131 */ "?", - /* 132 */ "=>", - /* 133 */ "exception", - /* 134 */ "default", - /* 135 */ "catch", - /* 136 */ "{\\}#[A-Za-z0-9_]*", - /* 137 */ "[\\t\\ ]+", - /* 138 */ "\\n|\\r|\\r\\n", - /* 139 */ "//", - /* 140 */ "/\\*", - /* 141 */ "#ifdef", - /* 142 */ "#if", - /* 143 */ "#ifndef", - /* 144 */ "#else", - /* 145 */ "#endif", - /* 146 */ "#undef", - /* 147 */ "#import", - /* 148 */ "ID", - /* 149 */ "#define", - /* 150 */ "INT", - /* 151 */ "enum", - /* 152 */ "\\{", - /* 153 */ "=", - /* 154 */ ",", - /* 155 */ "\\}", - /* 156 */ ";" -}; -SetWordType zzerr1[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr2[20] = {0xfc,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xf3, - 0xbf,0xff,0xff,0xff, 0xff,0xff,0xff,0x1f}; -SetWordType zzerr3[20] = {0xfc,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xfb, - 0x3b,0xf7,0xf7,0xc7, 0xff,0xff,0xff,0x1f}; -SetWordType zzerr4[20] = {0x4,0x0,0x0,0x0, 0x10,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x80,0x7,0x0,0x0, 0x0,0x0,0x0,0x0}; -SetWordType setwd1[157] = {0x0,0x50,0xa0,0x20,0x20,0x20,0x20, - 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, - 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, - 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, - 0x20,0x20,0x20,0x6a,0x20,0xa0,0x20,0x20, - 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, - 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, - 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, - 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, - 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, - 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, - 0x20,0x20,0x20,0x0,0x0,0x20,0x20,0x21, - 0x21,0x21,0x21,0x6e,0x6e,0x64,0x20,0x0, - 0x20,0xa0,0xa0,0xa0,0x20,0x6a,0x6a,0x6a, - 0x6e,0x20,0x20,0x20,0x20,0x66,0x6e,0x6e, - 0x20,0x66,0x20,0x20,0x20,0x20,0x20,0x20, - 0x20,0x20,0x20,0x20,0x20,0x20,0x62,0x20, - 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, - 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, - 0x20,0x20,0x20,0x20,0x20,0x20}; -SetWordType zzerr5[20] = {0x0,0x0,0x0,0x0, 0x10,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x0,0x1,0x0,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr6[20] = {0x4,0x0,0x0,0x0, 0x10,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x0,0x7,0x0,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr7[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x0,0x6,0x0,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr8[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x0,0x4,0x0,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr9[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x1c,0xf0,0x70,0x1, 0x20,0x0,0x0,0x0}; -SetWordType setwd2[157] = {0x0,0xf8,0x6,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0xf8,0x0,0x1,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0xf8,0xf8,0xf8,0x0,0x0, - 0x0,0x1,0x2,0x6,0x0,0xf8,0xf8,0xf8, - 0xf8,0x0,0x0,0x0,0x0,0xf8,0xf8,0xf8, - 0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0xe8,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0}; -SetWordType zzerr10[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0xbc,0xf8,0x74,0x1, 0x20,0x0,0x0,0x0}; -SetWordType zzerr11[20] = {0x0,0x0,0x0,0x0, 0x8,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0xa0,0x0,0x4,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr12[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x1c,0xf8,0x70,0x1, 0x20,0x0,0x0,0x0}; -SetWordType zzerr13[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0xa0,0x0,0x4,0x0, 0x0,0x0,0x0,0x0}; -SetWordType setwd3[157] = {0x0,0xfa,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0xfa,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0xfa,0xfa,0xfa,0x5,0x0, - 0x5,0x0,0x0,0x0,0xe2,0xfa,0xfa,0xfa, - 0xfa,0xc0,0x80,0x5,0xe0,0xfa,0xfa,0xfa, - 0x0,0xfa,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0xfa,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0}; -SetWordType zzerr14[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x20,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr15[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr16[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr17[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x40,0x0,0x4,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr18[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x24,0x0,0x80,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr19[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x20,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr20[20] = {0x6,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x1c,0xf8,0x74,0x3, 0x20,0x0,0x0,0x0}; -SetWordType zzerr21[20] = {0x6,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x1c,0xf8,0x70,0x3, 0x20,0x0,0x0,0x0}; -SetWordType setwd4[157] = {0x0,0xe5,0xda,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0xe5,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0xed,0xe5,0xe7,0x1a,0x0, - 0x0,0x0,0x0,0x0,0xc0,0xe5,0xe5,0xe5, - 0xe5,0x0,0x0,0x0,0x0,0xe5,0xe5,0xe5, - 0x0,0xe5,0x40,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0xe5,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0}; -SetWordType zzerr22[20] = {0x6,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x3c,0xf8,0x70,0x1, 0x20,0x0,0x0,0x0}; -SetWordType zzerr23[20] = {0x6,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x1c,0xf8,0x70,0x1, 0x20,0x0,0x0,0x0}; -SetWordType zzerr24[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x1c,0xf8,0x70,0x1, 0x20,0x0,0x0,0x0}; -SetWordType zzerr25[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x1c,0xf8,0x70,0x1, 0x20,0x0,0x0,0x0}; -SetWordType zzerr26[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x5, - 0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0}; -SetWordType setwd5[157] = {0x0,0x1f,0xc1,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0xdf,0xc0,0xc0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0xc0,0x0,0xc0,0x0,0x0,0xc0,0xc0,0x0, - 0x0,0x0,0x0,0x7f,0x1f,0xdf,0xc0,0xc0, - 0x0,0x0,0xc0,0x0,0x67,0x1f,0x1f,0x1f, - 0x1f,0x0,0x0,0xc0,0x60,0x1f,0x1f,0x1f, - 0x0,0x1f,0x0,0x0,0x40,0xc0,0x0,0x0, - 0x0,0x0,0xc0,0xc0,0x0,0x0,0x5f,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0}; -SetWordType zzerr27[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4, - 0x0,0x0,0x0,0x10, 0x0,0x0,0x0,0x0}; -SetWordType zzerr28[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x80,0x2, - 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr29[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x20,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr30[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xd, - 0x0,0x0,0x80,0x0, 0x20,0x0,0x0,0x0}; -SetWordType zzerr31[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xd, - 0x0,0x0,0x0,0x0, 0x20,0x0,0x0,0x0}; -SetWordType zzerr32[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x5, - 0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0}; -SetWordType zzerr33[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x20,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; -SetWordType setwd6[157] = {0x0,0x0,0xfd,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0xe1,0xe1,0xe1,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0xfd,0x60,0xe9,0x0,0x0,0xe1,0xe1,0x0, - 0x0,0x0,0x0,0xe2,0x0,0xfd,0xfd,0xe1, - 0x20,0x0,0xe1,0x0,0xe2,0x0,0x0,0x0, - 0x0,0x0,0x0,0xe1,0xe2,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0xe2,0xe0,0x20,0x0, - 0x0,0x0,0xe1,0xe1,0x0,0x0,0xe2,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0}; -SetWordType zzerr34[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xd, - 0x0,0x0,0x80,0x0, 0x20,0x0,0x0,0x0}; -SetWordType zzerr35[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xd, - 0x0,0x0,0x0,0x0, 0x20,0x0,0x0,0x0}; -SetWordType zzerr36[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x5, - 0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0}; -SetWordType zzerr37[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xc, - 0x0,0x0,0x0,0x0, 0x20,0x0,0x0,0x0}; -SetWordType zzerr38[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4, - 0x84,0x9,0x8,0x18, 0x20,0x0,0x0,0x0}; -SetWordType zzerr39[20] = {0x0,0x0,0x0,0x0, 0x10,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x0,0x1,0x0,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr40[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4, - 0x4,0x9,0x8,0x18, 0x20,0x0,0x0,0x0}; -SetWordType zzerr41[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4, - 0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0}; -SetWordType zzerr42[20] = {0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x80,0x0, - 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; -SetWordType setwd7[157] = {0x0,0x0,0xdf,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0xdf,0xdf,0xff,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0xdf,0x3,0xdf,0x0,0x0,0xdf,0xdf,0x0, - 0x0,0x0,0x0,0xdf,0x0,0xdf,0xdf,0xdf, - 0x1,0x30,0xdf,0x0,0xdf,0x0,0x0,0x0, - 0x0,0x0,0x0,0xdf,0xdf,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0xdf,0xdf,0x1,0x0, - 0x0,0x0,0xdf,0xdf,0x0,0x0,0xdf,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0}; -SetWordType zzerr43[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4, - 0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0}; -SetWordType zzerr44[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0xc0, 0x1,0x0,0x0,0x0}; -SetWordType zzerr45[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x30, - 0x40,0x0,0x4,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr46[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr47[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x20, - 0x40,0x0,0x4,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr48[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x0,0x0,0x2,0x0, 0x10,0x0,0x0,0x0}; -SetWordType zzerr49[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4, - 0x4,0x8,0x8,0x18, 0x20,0x0,0x0,0x0}; -SetWordType zzerr50[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4, - 0x4,0x8,0xa,0x18, 0x30,0x0,0x0,0x0}; -SetWordType zzerr51[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4, - 0x4,0x8,0x8,0x18, 0x28,0x0,0x0,0x0}; -SetWordType zzerr52[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x40,0x0,0x4,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr53[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x4, - 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; -SetWordType setwd8[157] = {0x0,0x0,0xe1,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0xe1,0xe1,0xe1,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0xe1,0x0,0xe1,0x0,0x0,0xe3,0xe7,0x0, - 0x0,0x0,0x0,0xe1,0x0,0xe1,0xe1,0xef, - 0x0,0x0,0xe1,0x0,0xe1,0x0,0x0,0x0, - 0x0,0x0,0x10,0xef,0xe1,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0xe1,0xe1,0x0,0x0, - 0x0,0x0,0xe1,0xe1,0x0,0x10,0xe1,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0}; -SetWordType zzerr54[20] = {0x2,0x0,0x0,0x0, 0x14,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x1c,0xf8,0x78,0x9, 0xe0,0x0,0x0,0x0}; -SetWordType zzerr55[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x1c,0xf8,0x78,0x9, 0x60,0x0,0x0,0x0}; -SetWordType zzerr56[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x30,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr57[20] = {0x2,0x0,0x0,0x0, 0x4,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x1c,0xf8,0x78,0x9, 0xe0,0x0,0x0,0x0}; -SetWordType setwd9[157] = {0x0,0x7c,0x1,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x7f,0x1,0x1,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x1,0x0,0x1,0x0,0x0,0x1,0x1,0x0, - 0x0,0x0,0x0,0x7f,0x7e,0x7f,0x1,0x1, - 0x0,0x0,0x1,0x0,0x7d,0x7e,0x7e,0x7e, - 0x7e,0x0,0x0,0x1,0x7d,0x7e,0x7e,0x7e, - 0x0,0x7e,0x0,0x0,0x7d,0x1,0x0,0x0, - 0x0,0x0,0x1,0x1,0x0,0x0,0x7f,0x64, - 0x64,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x80,0x0,0x0,0x0,0x0,0x0,0x80,0x0, - 0x80,0x0,0x0,0x0,0x0,0x0}; -SetWordType zzerr58[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0, 0x0,0x0,0xa0,0x0}; -SetWordType zzerr59[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0, 0x0,0x80,0xa0,0x0}; -SetWordType zzerr60[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0, 0x0,0x0,0xa0,0x0}; -SetWordType zzerr61[20] = {0x2,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0, 0x0,0x80,0xa0,0x0}; -SetWordType zzerr62[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xe}; -SetWordType zzerr63[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xe}; -SetWordType zzerr64[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xe}; -SetWordType zzerr65[20] = {0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0, 0x0,0x0,0x10,0xc}; -SetWordType setwd10[157] = {0x0,0xc,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0, - 0x3,0x0,0x0,0xf0,0xf0,0x0}; -SetWordType setwd11[157] = {0x0,0x1,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x1,0x0,0x0,0x0,0x0,0x0}; diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/fcache.c b/Tools/CodeTools/TianoTools/Pccts/antlr/fcache.c deleted file mode 100644 index ff7dcdfdd5..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/fcache.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * fcache.c - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33MR10 - * - */ - -#include -#include - -#include "pcctscfg.h" - -#include "set.h" -#include "syn.h" -#include "hash.h" -#include "generic.h" - -#ifdef __USE_PROTOS -CacheEntry *dumpFcache1(char *prev) -#else -CacheEntry *dumpFcache1(prev) - char *prev; -#endif -{ - Entry **table=Fcache; - - int low=0; - int hi=0; - - CacheEntry *least=NULL; - - Entry **p; - - for (p=table; p<&(table[HashTableSize]); p++) { - - CacheEntry *q =(CacheEntry *) *p; - - if ( q != NULL && low==0 ) low = p-table; - while ( q != NULL ) { - if (strcmp(q->str,prev) > 0) { - if (least == NULL) { - least=q; - } else { - if (strcmp(q->str,least->str) < 0) { - least=q; - }; - }; - }; - q = q->next; - }; - - if ( *p != NULL ) hi = p-table; - } - return least; -} - -#ifdef __USE_PROTOS -void reportFcache(CacheEntry *q) -#else -void reportFcache(q) - CacheEntry *q; -#endif -{ - char *qstr; - - fprintf(stdout,"\nrule "); - for (qstr=q->str; *qstr != '*' ; qstr++) { - fprintf(stdout,"%c",*qstr); - }; - - qstr++; - if (*qstr == 'i') fprintf(stdout," First["); - if (*qstr == 'o') fprintf(stdout," Follow["); - qstr++; - fprintf(stdout,"%s]",qstr); - if (q->incomplete) fprintf(stdout," *** incomplete ***"); - fprintf(stdout,"\n"); - MR_dumpTokenSet(stdout,1,q->fset); -} - -void -#ifdef __USE_PROTOS -DumpFcache(void) -#else -DumpFcache() -#endif -{ - - char *prev=""; - int n=0; - CacheEntry *next; - - fprintf(stdout,"\n\nDump of First/Follow Cache\n"); - - for(;;) { - next=dumpFcache1(prev); - if (next == NULL) break; - reportFcache(next); - ++n; - prev=next->str; - }; - fprintf(stdout,"\nEnd dump of First/Follow Cache\n"); -} diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/fset.c b/Tools/CodeTools/TianoTools/Pccts/antlr/fset.c deleted file mode 100644 index e1a76ec620..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/fset.c +++ /dev/null @@ -1,1555 +0,0 @@ -/* - * fset.c - * - * Compute FIRST and FOLLOW sets. - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2001 - */ - -#include -#include - -#include "pcctscfg.h" - -#include "set.h" -#include "syn.h" -#include "hash.h" -#include "generic.h" -#include "dlgdef.h" -#include "limits.h" - -#ifdef __USE_PROTOS -static void ensure_predicates_cover_ambiguous_lookahead_sequences - (Junction *, Junction *, char *, Tree *); -#else -static void ensure_predicates_cover_ambiguous_lookahead_sequences(); -#endif - -/* - * What tokens are k tokens away from junction q? - * - * Follow both p1 and p2 paths (unless RuleBlk) to collect the tokens k away from this - * node. - * We lock the junction according to k--the lookahead. If we have been at this - * junction before looking for the same, k, number of lookahead tokens, we will - * do it again and again...until we blow up the stack. Locks are only used on aLoopBlk, - * RuleBlk, aPlusBlk and EndRule junctions to remove/detect infinite recursion from - * FIRST and FOLLOW calcs. - * - * If p->jtype == EndRule we are going to attempt a FOLLOW. (FOLLOWs are really defined - * in terms of FIRST's, however). To proceed with the FOLLOW, p->halt cannot be - * set. p->halt is set to indicate that a reference to the current rule is in progress - * and the FOLLOW is not desirable. - * - * If we attempt a FOLLOW and find that there is no FOLLOW or REACHing beyond the EndRule - * junction yields an empty set, replace the empty set with EOF. No FOLLOW means that - * only EOF can follow the current rule. This normally occurs only on the start symbol - * since all other rules are referenced by another rule somewhere. - * - * Normally, both p1 and p2 are followed. However, checking p2 on a RuleBlk node is - * the same as checking the next rule which is clearly incorrect. - * - * Cycles in the FOLLOW sense are possible. e.g. Fo(c) requires Fo(b) which requires - * Fo(c). Both Fo(b) and Fo(c) are defined to be Fo(b) union Fo(c). Let's say - * Fo(c) is attempted first. It finds all of the FOLLOW symbols and then attempts - * to do Fo(b) which finds of its FOLLOW symbols. So, we have: - * - * Fo(c) - * / \ - * a set Fo(b) - * / \ - * a set Fo(c) .....Hmmmm..... Infinite recursion! - * - * The 2nd Fo(c) is not attempted and Fo(b) is left deficient, but Fo(c) is now - * correctly Fo(c) union Fo(b). We wish to pick up where we left off, so the fact - * that Fo(b) terminated early means that we lack Fo(c) in the Fo(b) set already - * laying around. SOOOOoooo, we track FOLLOW cycles. All FOLLOW computations are - * cached in a hash table. After the sequence of FOLLOWs finish, we reconcile all - * cycles --> correct all Fo(rule) sets in the cache. - * - * Confused? Good! Read my MS thesis [Purdue Technical Report TR90-30]. - * TJP 8/93 -- can now read PhD thesis from Purdue. - * - * Also, FIRST sets are cached in the hash table. Keys are (rulename,Fi/Fo,k). - * Only FIRST sets, for which the FOLLOW is not included, are stored. - * - * SPECIAL CASE of (...)+ blocks: - * I added an optional alt so that the alts could see what - * was behind the (...)+ block--thus using enough lookahead - * to branch out rather than just enough to distinguish - * between alts in the (...)+. However, when the FIRST("(...)+") is - * is needed, must not use this last "optional" alt. This routine - * turns off this path by setting a new 'ignore' flag for - * the alt and then resetting it afterwards. - */ - -set -#ifdef __USE_PROTOS -rJunc( Junction *p, int k, set *rk ) -#else -rJunc( p, k, rk ) -Junction *p; -int k; -set *rk; -#endif -{ - set a, b; - - require(p!=NULL, "rJunc: NULL node"); - require(p->ntype==nJunction, "rJunc: not junction"); - -#ifdef DBG_LL1 - if ( p->jtype == RuleBlk ) fprintf(stderr, "FIRST(%s,%d) \n",((Junction *)p)->rname,k); - else fprintf(stderr, "rJunc: %s in rule %s\n", - decodeJType[p->jtype], ((Junction *)p)->rname); -#endif - /* if this is one of the added optional alts for (...)+ then return */ - - /* no need to pop backtrace - hasn't been pushed */ - - if ( p->ignore ) return empty; - - if (MR_MaintainBackTrace) MR_pointerStackPush(&MR_BackTraceStack,p); - -/* MR14 */ if (AlphaBetaTrace && p->alpha_beta_guess_end) { -/* MR14 */ warnFL( -/* MR14 */ "not possible to compute follow set for alpha in an \"(alpha)? beta\" block. ", -/* MR14 */ FileStr[p->file],p->line); -/* MR14 */ MR_alphaBetaTraceReport(); -/* MR14 */ }; - -/* MR14 */ if (p->alpha_beta_guess_end) { -/* MR14 */ if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); -/* MR14 */ return empty; -/* MR14 */ } - - /* locks are valid for aLoopBlk,aPlusBlk,RuleBlk,EndRule junctions only */ - if ( p->jtype==aLoopBlk || p->jtype==RuleBlk || - p->jtype==aPlusBlk || p->jtype==EndRule ) - { - require(p->lock!=NULL, "rJunc: lock array is NULL"); - if ( p->lock[k] ) - { - if ( p->jtype == EndRule ) /* FOLLOW cycle? */ - { -#ifdef DBG_LL1 - fprintf(stderr, "FOLLOW cycle to %s: panic!\n", p->rname); -#endif - if (! MR_AmbSourceSearch) RegisterCycle(p->rname, k); - } - if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); - return empty; - } - if ( p->jtype == RuleBlk && - p->end->halt && - ! MR_AmbSourceSearch) /* check for FIRST cache */ - { - CacheEntry *q = (CacheEntry *) hash_get(Fcache, Fkey(p->rname,'i',k)); - if ( q != NULL ) - { - set_orin(rk, q->rk); - if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); - return set_dup( q->fset ); - } - } - if ( p->jtype == EndRule && - !p->halt && /* MR11 was using cache even when halt set */ - ! MR_AmbSourceSearch) /* FOLLOW set cached already? */ - { - CacheEntry *q = (CacheEntry *) hash_get(Fcache, Fkey(p->rname,'o',k)); - if ( q != NULL ) - { -#ifdef DBG_LL1 - fprintf(stderr, "cache for FOLLOW(%s,%d):", p->rname,k); - s_fprT(stderr, q->fset); - if ( q->incomplete ) fprintf(stderr, " (incomplete)"); - fprintf(stderr, "\n"); -#endif - if ( !q->incomplete ) - { - if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); - return set_dup( q->fset ); - } - } - } - p->lock[k] = TRUE; /* This rule is busy */ - } - - a = b = empty; - - if ( p->jtype == EndRule ) - { - if (p->halt ) /* don't want FOLLOW here? */ /* unless MR10 hoisting */ - { - p->lock[k] = FALSE; - set_orel(k, rk); /* indicate this k value needed */ - if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); - return empty; - } - if (! MR_AmbSourceSearch) FoPush(p->rname, k); /* Attempting FOLLOW */ - if ( p->p1 == NULL ) set_orel((TokenInd!=NULL?TokenInd[EofToken]:EofToken), &a);/* if no FOLLOW assume EOF */ -#ifdef DBG_LL1 - fprintf(stderr, "-->FOLLOW(%s,%d)\n", p->rname,k); -#endif - } - - if ( p->p1 != NULL ) { -/* MR14 */ if (p->guess) { -/* MR14 */ if (p->guess_analysis_point == NULL) { -/* MR14 */ Node * guess_point; -/* MR14 */ guess_point=(Node *)analysis_point(p); -/* MR14 */ if (guess_point == (Node *)p) { -/* MR14 */ guess_point=p->p1; -/* MR14 */ } -/* MR14 */ p->guess_analysis_point=guess_point; -/* MR14 */ } -/* MR14 */ REACH(p->guess_analysis_point, k, rk, a); - } else { - REACH(p->p1, k, rk, a); - } - } - - /* C a c h e R e s u l t s */ - - if ( p->jtype == RuleBlk && p->end->halt && ! MR_AmbSourceSearch) /* can save FIRST set? */ - { - CacheEntry *q = newCacheEntry( Fkey(p->rname,'i',k) ); - /*fprintf(stderr, "Caching %s FIRST %d\n", p->rname, k);*/ - hash_add(Fcache, Fkey(p->rname,'i',k), (Entry *)q); - q->fset = set_dup( a ); - q->rk = set_dup( *rk ); - } - - if ( p->jtype == EndRule && - !p->halt && /* MR11 was using cache even with halt set */ - ! MR_AmbSourceSearch) /* just completed FOLLOW? */ - { - /* Cache Follow set */ - CacheEntry *q = (CacheEntry *) hash_get(Fcache, Fkey(p->rname,'o',k)); - if ( q==NULL ) - { - q = newCacheEntry( Fkey(p->rname,'o',k) ); - hash_add(Fcache, Fkey(p->rname,'o',k), (Entry *)q); - } - /*fprintf(stderr, "Caching %s FOLLOW %d\n", p->rname, k);*/ - if ( set_nil(a) && !q->incomplete ) - { - /* Don't ever save a nil set as complete. - * Turn it into an eof set. - */ - set_orel(EofToken, &a); - } - set_orin(&(q->fset), a); - FoPop( k ); - if ( FoTOS[k] == NULL && Cycles[k] != NULL ) ResolveFoCycles(k); -#ifdef DBG_LL1 - fprintf(stderr, "saving FOLLOW(%s,%d):", p->rname, k); - s_fprT(stderr, q->fset); - if ( q->incomplete ) fprintf(stderr, " (incomplete)"); - fprintf(stderr, "\n"); -#endif - } - - if (p->jtype != RuleBlk && p->p2 != NULL && /* MR14 */ ! p->guess) { - REACH(p->p2, k, rk, b); - } - - if ( p->jtype==aLoopBlk || p->jtype==RuleBlk || - p->jtype==aPlusBlk || p->jtype==EndRule ) - p->lock[k] = FALSE; /* unlock node */ - - set_orin(&a, b); - set_free(b); - if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); - return a; -} - -set -#ifdef __USE_PROTOS -rRuleRef( RuleRefNode *p, int k, set *rk_out ) -#else -rRuleRef( p, k, rk_out ) -RuleRefNode *p; -int k; -set *rk_out; -#endif -{ - set rk; - Junction *r; - int k2; - set a, rk2, b; - int save_halt; - RuleEntry *q = (RuleEntry *) hash_get(Rname, p->text); - require(p!=NULL, "rRuleRef: NULL node"); - require(p->ntype==nRuleRef, "rRuleRef: not rule ref"); - -#ifdef DBG_LL1 - fprintf(stderr, "rRuleRef: %s\n", p->text); -#endif - - if (MR_MaintainBackTrace) MR_pointerStackPush(&MR_BackTraceStack,p); - - if ( q == NULL ) - { - warnFL( eMsg1("rule %s not defined",p->text), FileStr[p->file], p->line ); - REACH(p->next, k, rk_out, a); - if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); - return a; - } - rk2 = empty; - -/* MR9 Problems with rule references in guarded predicates */ -/* MR9 Perhaps can use hash table to find rule ? */ - -/* MR9 */ if (RulePtr == NULL) { -/* MR9 */ fatalFL(eMsg2("Rule %s uses rule %s via RulePtr before it has been initialized", -/* MR9 */ p->rname,q->str),FileStr[p->file],p->line); -/* MR9 */ }; - - r = RulePtr[q->rulenum]; - if ( r->lock[k] ) - { - errNoFL( eMsg2("infinite left-recursion to rule %s from rule %s", - r->rname, p->rname) ); - - if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); - - return empty; - } - - save_halt = r->end->halt; - r->end->halt = TRUE; /* don't let reach fall off end of rule here */ - rk = empty; - REACH(r, k, &rk, a); - r->end->halt = save_halt; - while ( !set_nil(rk) ) { - k2 = set_int(rk); /* MR11 this messes up the ambiguity search routine */ - set_rm(k2, rk); - REACH(p->next, k2, &rk2, b); /* MR11 by changing the value of k */ - set_orin(&a, b); - set_free(b); - } - set_free(rk); /* this has no members, but free it's memory */ - set_orin(rk_out, rk2); /* remember what we couldn't do */ - set_free(rk2); - if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); - return a; -} - -/* - * Return FIRST sub k ( token_node ) - * - * TJP 10/11/93 modified this so that token nodes that are actually - * ranges (T1..T2) work. - */ -set -#ifdef __USE_PROTOS -rToken( TokNode *p, int k, set *rk ) -#else -rToken( p, k, rk ) -TokNode *p; -int k; -set *rk; -#endif -{ - set a; - - require(p!=NULL, "rToken: NULL node"); - require(p->ntype==nToken, "rToken: not token node"); - -#ifdef DBG_LL1 - fprintf(stderr, "rToken: %s\n", (TokenString(p->token)!=NULL)?TokenString(p->token): - ExprString(p->token)); -#endif - - - if (MR_MaintainBackTrace) MR_pointerStackPush(&MR_BackTraceStack,p); - - if (MR_AmbSourceSearch && (k-1) == 0) { - - set localConstrain; - set intersection; - - localConstrain=fset[maxk-k+1]; - - if (! set_nil(p->tset)) { - intersection=set_and(localConstrain,p->tset); - if (! set_nil(intersection)) { - MR_backTraceReport(); - }; - set_free(intersection); - } else { - if (set_el( (unsigned) p->token,localConstrain)) { - MR_backTraceReport(); - } - }; - }; - - if ( k-1 == 0 ) { - - if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); - - if ( !set_nil(p->tset) ) { - return set_dup(p->tset); - } else { - return set_of(p->token); - }; - } - - REACH(p->next, k-1, rk, a); - - if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); - - return a; -} - -set -#ifdef __USE_PROTOS -rAction( ActionNode *p, int k, set *rk ) -#else -rAction( p, k, rk ) -ActionNode *p; -int k; -set *rk; -#endif -{ - set a; - - require(p!=NULL, "rJunc: NULL node"); - require(p->ntype==nAction, "rJunc: not action"); - -/* MR11 */ if (p->is_predicate && p->ampersandPred != NULL) { -/* MR11 */ Predicate *pred=p->ampersandPred; -/* MR11 */ if (k <= pred->k) { -/* MR11 */ REACH(p->guardNodes,k,rk,a); -/* MR11 */ return a; -/* MR11 */ }; -/* MR11 */ }; - - /* it might be a good idea when doing an MR_AmbSourceSearch - to *not* look behind predicates under some circumstances - we'll look into that later - */ - - REACH(p->next, k, rk, a); /* ignore actions */ - return a; -} - - /* A m b i g u i t y R e s o l u t i o n */ - - -void -#ifdef __USE_PROTOS -dumpAmbigMsg( set *fset, FILE *f, int want_nls ) -#else -dumpAmbigMsg( fset, f, want_nls ) -set *fset; -FILE *f; -int want_nls; -#endif -{ - int i; - - set copy; /* MR11 */ - - if ( want_nls ) fprintf(f, "\n\t"); - else fprintf(f, " "); - - for (i=1; i<=CLL_k; i++) - { - copy=set_dup(fset[i]); /* MR11 */ - - if ( i>1 ) - { - if ( !want_nls ) fprintf(f, ", "); - } - if ( set_deg(copy) > 3 && elevel == 1 ) - { - int e,m; - fprintf(f, "{"); - for (m=1; m<=3; m++) - { - e=set_int(copy); - fprintf(f, " %s", TerminalString(e)); - set_rm(e, copy); - } - fprintf(f, " ... }"); - } - else s_fprT(f, copy); - if ( want_nls ) fprintf(f, "\n\t"); - set_free(copy); - } - fprintf(f, "\n"); - -} - -static void -#ifdef __USE_PROTOS -verify_context(Predicate *predicate) -#else -verify_context(predicate) -Predicate *predicate; -#endif -{ - if ( predicate == NULL ) return; - - if ( predicate->expr == PRED_OR_LIST || - predicate->expr == PRED_AND_LIST ) - { - verify_context(predicate->down); - verify_context(predicate->right); /* MR10 */ - return; - } - - if ( !predicate->source->ctxwarned && predicate->source->guardpred==NULL && - ((predicate->k > 1 && - !is_single_tuple(predicate->tcontext)) || - ( predicate->k == 1 && - set_deg(predicate->scontext[1])>1 )) ) - { - -/* MR9 Suppress annoying messages caused by our own clever(?) fix */ - - fprintf(stderr, ErrHdr, FileStr[predicate->source->file], - predicate->source->line); - fprintf(stderr, " warning: predicate applied for >1 lookahead %d-sequences\n", predicate->k); - fprintf(stderr, ErrHdr, FileStr[predicate->source->file], - predicate->source->line); - fprintf(stderr, " predicate text: \"%s\"\n", - (predicate->expr == NULL ? "(null)" : predicate->expr) ); - fprintf(stderr, ErrHdr, FileStr[predicate->source->file], - predicate->source->line); - fprintf(stderr, " You may only want one lookahead %d-sequence to apply\n", predicate->k); - fprintf(stderr, ErrHdr, FileStr[predicate->source->file], - predicate->source->line); - fprintf(stderr, " Try using a context guard '(...)? =>'\n"); - predicate->source->ctxwarned = 1; - } - verify_context(predicate->right); /* MR10 */ -} - -/* - * If delta is the set of ambiguous lookahead sequences, then make sure that - * the predicate(s) for productions alt1,alt2 cover the sequences in delta. - * - * For example, - * a : <>? (A B|A C) - * | b - * ; - * b : <>? A B - * | A C - * ; - * - * This should give a warning that (A C) predicts both productions and alt2 - * does not have a predicate in the production that generates (A C). - * - * The warning detection is simple. Let delta = LOOK(alt1) intersection LOOK(alt2). - * Now, if ( delta set-difference context(predicates-for-alt1) != empty then - * alt1 does not "cover" all ambiguous sequences. - * - * If ambig is nonempty, then ambig in LL(k) sense -> use tree info; else use fset - * info. Actually, sets are used only if k=1 for this grammar. - */ -static void -#ifdef __USE_PROTOS -ensure_predicates_cover_ambiguous_lookahead_sequences - ( Junction *alt1, Junction *alt2, char *sub, Tree *ambig ) -#else -ensure_predicates_cover_ambiguous_lookahead_sequences( alt1, alt2, sub, ambig ) -Junction *alt1; -Junction *alt2; -char *sub; -Tree *ambig; -#endif -{ - if ( !ParseWithPredicates ) return; - - if ( ambig!=NULL ) - { - Tree *non_covered = NULL; - if ( alt1->predicate!=NULL ) - non_covered = tdif(ambig, alt1->predicate, alt1->fset, alt2->fset); - if ( (non_covered!=NULL || alt1->predicate==NULL) && WarningLevel>1 ) - { - fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line); - fprintf(stderr, " warning: alt %d %shas no predicate to resolve ambiguity", - alt1->altnum, sub); - if ( alt1->predicate!=NULL && non_covered!=NULL ) - { - fprintf(stderr, " upon"); - preorder(non_covered); - } - else if ( alt1->predicate==NULL ) - { - fprintf(stderr, " upon"); - preorder(ambig->down); - } - fprintf(stderr, "\n"); - } - Tfree(non_covered); - non_covered = NULL; - if ( alt2->predicate!=NULL ) - non_covered = tdif(ambig, alt2->predicate, alt1->fset, alt2->fset); - if ( (non_covered!=NULL || alt2->predicate==NULL) && WarningLevel>1 ) - { - fprintf(stderr, ErrHdr, FileStr[alt2->file], alt2->line); - fprintf(stderr, " warning: alt %d %shas no predicate to resolve ambiguity", - alt2->altnum, sub); - if ( alt2->predicate!=NULL && non_covered!=NULL ) - { - fprintf(stderr, " upon"); - preorder(non_covered); - } - else if ( alt2->predicate==NULL ) - { - fprintf(stderr, " upon"); - preorder(ambig->down); - } - fprintf(stderr, "\n"); - } - Tfree(non_covered); - } - else if ( !set_nil(alt1->fset[1]) ) - { - set delta, non_covered; - delta = set_and(alt1->fset[1], alt2->fset[1]); - non_covered = set_dif(delta, covered_set(alt1->predicate)); - if ( set_deg(non_covered)>0 && WarningLevel>1 ) - { - fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line); - fprintf(stderr, " warning: alt %d %shas no predicate to resolve ambiguity", - alt1->altnum, sub); - if ( alt1->predicate!=NULL ) - { - fprintf(stderr, " upon "); - s_fprT(stderr, non_covered); - } - fprintf(stderr, "\n"); - } - set_free( non_covered ); - non_covered = set_dif(delta, covered_set(alt2->predicate)); - if ( set_deg(non_covered)>0 && WarningLevel>1 ) - { - fprintf(stderr, ErrHdr, FileStr[alt2->file], alt2->line); - fprintf(stderr, " warning: alt %d %shas no predicate to resolve ambiguity", - alt2->altnum, sub); - if ( alt2->predicate!=NULL ) - { - fprintf(stderr, " upon "); - s_fprT(stderr, non_covered); - } - fprintf(stderr, "\n"); - } - set_free( non_covered ); - set_free( delta ); - } - else fatal_internal("productions have no lookahead in predicate checking routine"); -} - -#ifdef __USE_PROTOS -void MR_doPredicatesHelp(int inGuessBlock,Junction *alt1,Junction *alt2,int jtype,char *sub) -#else -void MR_doPredicatesHelp(inGuessBlock,alt1,alt2,jtype,sub) - int inGuessBlock; - Junction *alt1; - Junction *alt2; - int jtype; - char *sub; -#endif -{ - Predicate *p1; - Predicate *p2; - - Junction *parentRule=MR_nameToRuleBlk(alt1->rname); - - if (inGuessBlock && WarningLevel <= 1) return; - - /* let antlr give the usual error message */ - - if (alt1->predicate == NULL && alt2->predicate == NULL) return; - - if ( (jtype == RuleBlk || jtype == aSubBlk) - && (alt1->predicate == NULL && alt2->predicate != NULL)) { - fprintf(stderr, ErrHdr, FileStr[parentRule->file],parentRule->line); - fprintf(stderr," warning: alt %d line %d and alt %d line %d of %s\n%s%s%s", - alt1->altnum, - alt1->line, - alt2->altnum, - alt2->line, - sub, - " These alts have ambig lookahead sequences resolved by a predicate for\n", - " the second choice. The second choice may not be reachable.\n", - " You may want to use a complementary predicate or rearrange the alts\n" - ); - return; - }; - - /* first do the easy comparison. then do the hard one */ - - if (MR_comparePredicates(alt1->predicate,alt2->predicate)) { - - if (jtype == aLoopBegin || jtype == aPlusBlk ) { - - /* I'm not sure this code is reachable. - Predicates following a (...)+ or (...)* block are probably - considered validation predicates and therefore not - participate in the predication expression - */ - - fprintf(stderr, ErrHdr,FileStr[parentRule->file],parentRule->line); - fprintf(stderr," warning: %s of %s in rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s", - "the predicates used to disambiguate optional/exit paths of ", - sub, - CurRule, - FileStr[alt1->file], - alt1->altnum, - alt1->line, - alt2->altnum, - alt2->line, - " are identical and have no resolving power\n"); - } else { - fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line); - fprintf(stderr," warning: %s rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s", - "the predicates used to disambiguate", - CurRule, - FileStr[alt1->file], - alt1->altnum, - alt1->line, - alt2->altnum, - alt2->line, - " are identical and have no resolving power\n"); - }; - } else { - p1=predicate_dup_without_context(alt1->predicate); - p1=MR_unfold(p1); - MR_clearPredEntry(p1); - MR_simplifyInverted(p1,0); - p1=MR_predSimplifyALL(p1); - p2=predicate_dup_without_context(alt2->predicate); - p2=MR_unfold(p2); - MR_clearPredEntry(p2); - MR_simplifyInverted(p2,0); - p2=MR_predSimplifyALL(p2); - if (MR_comparePredicates(p1,p2)) { - if (jtype == aLoopBegin || jtype == aPlusBlk ) { - fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line); - fprintf(stderr," warning: %s of %s in rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s%s", - "the predicates used to disambiguate optional/exit paths of ", - sub, - CurRule, - FileStr[alt1->file], - alt1->altnum, - alt1->line, - alt2->altnum, - alt2->line, - " are identical when compared without context and may have no\n", - " resolving power for some lookahead sequences.\n"); - } else { - fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line); - fprintf(stderr," warning: %s rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s%s", - "the predicates used to disambiguate", - CurRule, - FileStr[alt1->file], - alt1->altnum, - alt1->line, - alt2->altnum, - alt2->line, - " are identical when compared without context and may have no\n", - " resolving power for some lookahead sequences.\n"); - }; - if (InfoP) { - fprintf(output,"\n#if 0\n\n"); - fprintf(output,"The following predicates are identical when compared without\n"); - fprintf(output," lookahead context information. For some ambiguous lookahead\n"); - fprintf(output," sequences they may not have any power to resolve the ambiguity.\n"); - fprintf(output,"\n"); - - fprintf(output,"Choice 1: %s alt %d line %d file %s\n\n", - MR_ruleNamePlusOffset( (Node *) alt1), - alt1->altnum, - alt1->line, - FileStr[alt1->file]); - fprintf(output," The original predicate for choice 1 with available context information:\n\n"); - MR_dumpPred1(2,alt1->predicate,1); - fprintf(output," The predicate for choice 1 after expansion (but without context information):\n\n"); - MR_dumpPred1(2,p1,0); - if (p1 == NULL) { - Predicate *phelp; - fprintf(output," The predicate for choice 1 after expansion (but before simplification)\n\n"); - phelp=predicate_dup_without_context(alt1->predicate); - phelp=MR_unfold(phelp); - MR_clearPredEntry(phelp); - MR_simplifyInverted(phelp,0); - phelp=MR_predSimplifyALLX(phelp,1); - MR_dumpPred1(2,phelp,0); - predicate_free(phelp); - }; - fprintf(output,"\n"); - - fprintf(output,"Choice 2: %s alt %d line %d file %s\n\n", - MR_ruleNamePlusOffset( (Node *) alt2), - alt2->altnum, - alt2->line, - FileStr[alt2->file]); - fprintf(output," The original predicate for choice 2 with available context information:\n\n"); - MR_dumpPred1(1,alt2->predicate,1); - fprintf(output," The predicate for choice 2 after expansion (but without context information):\n\n"); - MR_dumpPred1(1,p2,0); - if (p2 == NULL) { - Predicate *phelp; - fprintf(output," The predicate for choice 2 after expansion (but before simplification)\n\n"); - phelp=predicate_dup_without_context(alt2->predicate); - phelp=MR_unfold(phelp); - MR_clearPredEntry(phelp); - MR_simplifyInverted(phelp,0); - phelp=MR_predSimplifyALLX(phelp,1); - MR_dumpPred1(2,phelp,0); - predicate_free(phelp); - }; - fprintf(output,"\n#endif\n"); - }; - } else if (MR_secondPredicateUnreachable(p1,p2)) { - if (jtype == aLoopBegin || jtype == aPlusBlk ) { - fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line); - fprintf(stderr," warning: %s of %s in rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s%s", - "the predicate used to disambiguate the first choice of the optional/exit paths of ", - sub, - CurRule, - FileStr[alt1->file], - alt1->altnum, - alt1->line, - alt2->altnum, - alt2->line, - " appears to \"cover\" the second predicate when compared without context.\n", - " The second predicate may have no resolving power for some lookahead sequences.\n"); - } else { - fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line); - fprintf(stderr," warning: %s rule %s\n (file %s alt %d line %d and alt %d line %d)\n%s%s", - "the predicate used to disambiguate the first choice of", - CurRule, - FileStr[alt1->file], - alt1->altnum, - alt1->line, - alt2->altnum, - alt2->line, - " appears to \"cover\" the second predicate when compared without context.\n", - " The second predicate may have no resolving power for some lookahead sequences.\n"); - }; - if (InfoP) { - fprintf(output,"\n#if 0\n\n"); - fprintf(output,"The first predicate appears to \"cover\" the second predicate when they\n"); - fprintf(output," are compared without lookahead context information. For some ambiguous\n"); - fprintf(output," lookahead sequences the second predicate may not have any power to\n"); - fprintf(output," resolve the ambiguity.\n"); - fprintf(output,"\n"); - fprintf(output,"Choice 1: %s alt %d line %d file %s\n\n", - MR_ruleNamePlusOffset( (Node *) alt1), - alt1->altnum, - alt1->line, - FileStr[alt1->file]); - fprintf(output," The original predicate for choice 1 with available context information:\n\n"); - MR_dumpPred1(2,alt1->predicate,1); - fprintf(output," The predicate for choice 1 after expansion (but without context information):\n\n"); - MR_dumpPred1(2,p1,0); - if (p1 == NULL) { - Predicate *phelp; - fprintf(output," The predicate for choice 1 after expansion (but before simplification)\n\n"); - phelp=predicate_dup_without_context(alt1->predicate); - phelp=MR_unfold(phelp); - MR_clearPredEntry(phelp); - MR_simplifyInverted(phelp,0); - phelp=MR_predSimplifyALLX(phelp,1); - MR_dumpPred1(2,phelp,0); - predicate_free(phelp); - }; - fprintf(output,"\n"); - - fprintf(output,"Choice 2: %s alt %d line %d file %s\n\n", - MR_ruleNamePlusOffset( (Node *) alt2), - alt2->altnum, - alt2->line, - FileStr[alt2->file]); - fprintf(output," The original predicate for choice 2 with available context information:\n\n"); - MR_dumpPred1(1,alt2->predicate,1); - fprintf(output," The predicate for choice 2 after expansion (but without context information):\n\n"); - MR_dumpPred1(1,p2,0); - if (p2 == NULL) { - Predicate *phelp; - fprintf(output," The predicate for choice 2 after expansion (but before simplification)\n\n"); - phelp=predicate_dup_without_context(alt2->predicate); - phelp=MR_unfold(phelp); - MR_clearPredEntry(phelp); - MR_simplifyInverted(phelp,0); - phelp=MR_predSimplifyALLX(phelp,1); - MR_dumpPred1(2,phelp,0); - predicate_free(phelp); - }; - fprintf(output,"\n#endif\n"); - }; - }; - predicate_free(p1); - predicate_free(p2); - }; -} - -static int totalOverflow=0; /* MR9 */ - -void -#ifdef __USE_PROTOS -HandleAmbiguity( Junction *block, Junction *alt1, Junction *alt2, int jtype ) -#else -HandleAmbiguity( block, alt1, alt2, jtype ) -Junction *block; -Junction *alt1; -Junction *alt2; -int jtype; -#endif -{ - unsigned **ftbl; - set *fset, b; - int i, numAmbig,n2; - Tree *ambig=NULL, *t, *u; - char *sub = ""; - long n; - int thisOverflow=0; /* MR9 */ - long set_deg_value; /* MR10 */ - long threshhold; /* MR10 */ - - require(block!=NULL, "NULL block"); - require(block->ntype==nJunction, "invalid block"); - - /* These sets are used to constrain LL_k set, but are made CLL_k long anyway */ - fset = (set *) calloc(CLL_k+1, sizeof(set)); - require(fset!=NULL, "cannot allocate fset"); - ftbl = (unsigned **) calloc(CLL_k+1, sizeof(unsigned *)); - require(ftbl!=NULL, "cannot allocate ftbl"); - - /* create constraint table and count number of possible ambiguities (use<=LL_k) */ - for (n=1,i=1; i<=CLL_k; i++) - { - b = set_and(alt1->fset[i], alt2->fset[i]); -/* MR9 */ set_deg_value = set_deg(b); -/* MR10 */ if (n > 0) { -/* MR10 */ threshhold = LONG_MAX / n; -/* MR10 */ if (set_deg_value <= threshhold) { -/* MR10 */ n *= set_deg_value; -/* MR10 */ } else { -/* MR10 */ n=LONG_MAX; -/* MR9 */ if (totalOverflow == 0) { -#if 0 - /* MR10 comment this out because it just makes users worry */ - -/* MR9 */ warnNoFL("Overflow in computing number of possible ambiguities in HandleAmbiguity\n"); -#endif -/* MR9 */ }; -/* MR9 */ thisOverflow++; -/* MR9 */ totalOverflow++; -/* MR9 */ }; -/* MR10 */ } else { -/* MR10 */ n *= set_deg_value; -/* MR9 */ }; - fset[i] = set_dup(b); - ftbl[i] = set_pdq(b); - set_free(b); - } - - switch ( jtype ) - { - case aSubBlk: sub = "of (..) "; break; - case aOptBlk: sub = "of {..} "; break; - case aLoopBegin: sub = "of (..)* "; break; - case aLoopBlk: sub = "of (..)* "; break; - case aPlusBlk: sub = "of (..)+ "; break; - case RuleBlk: sub = "of the rule itself "; break; - default : sub = ""; break; - } - - /* If the block is marked as a compressed lookahead only block, then - * simply return; ambiguity warning is given only at warning level 2. - */ - if ( block->approx>0 ) - { - if ( ParseWithPredicates ) - { - if (alt1->predicate != NULL) predicate_free(alt1->predicate); /* MR12 */ - if (alt2->predicate != NULL) predicate_free(alt2->predicate); /* MR12 */ - - require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); - alt1->predicate = MR_find_predicates_and_supp((Node *)alt1->p1); - require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); - require (MR_predicate_context_completed(alt1->predicate),"predicate alt 1 not completed"); - alt1->predicate=MR_predSimplifyALL(alt1->predicate); - - require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); - alt2->predicate = MR_find_predicates_and_supp((Node *)alt2->p1); - require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); - require (MR_predicate_context_completed(alt2->predicate),"predicate alt 2 not completed"); - alt2->predicate=MR_predSimplifyALL(alt2->predicate); - - MR_doPredicatesHelp(0,alt1,alt2,jtype,sub); - - if ( HoistPredicateContext - && (alt1->predicate!=NULL||alt2->predicate!=NULL) ) - { - verify_context(alt1->predicate); - verify_context(alt2->predicate); - } - - if ( HoistPredicateContext - && (alt1->predicate!=NULL||alt2->predicate!=NULL) - && WarningLevel>1 ) - ensure_predicates_cover_ambiguous_lookahead_sequences(alt1, alt2, sub, ambig); - } - - if ( WarningLevel>1 ) - { - fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line); - if ( jtype == aLoopBegin || jtype == aPlusBlk ) - fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub); - else - fprintf(stderr, " warning(approx): alts %d and %d %sambiguous upon", - alt1->altnum, alt2->altnum, sub); - dumpAmbigMsg(fset, stderr, 0); - MR_traceAmbSource(fset,alt1,alt2); - } - for (i=1; i<=CLL_k; i++) set_free( fset[i] ); - free((char *)fset); - for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] ); - free((char *)ftbl); - return; - } - - /* if all sets have degree 1 for k=1 permutation; - * don't bother doing full LL(k) analysis. - * (This "if" block handles the LL(1) case) - */ - - n2 = 0; - for (i=1; ifset[i])+set_deg(alt2->fset[i]); - - /* here STARTS the special case in which the lookahead sets for alt1 and alt2 - all have degree 1 for kp1)!=NULL ) - { - if ( WarningLevel==1 ) - { - for (i=1; i<=CLL_k; i++) set_free( fset[i] ); - free((char *)fset); - for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] ); - free((char *)ftbl); - return; - } - - fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line); - if ( jtype == aLoopBegin || jtype == aPlusBlk ) - fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub); - else - fprintf(stderr, " warning: alts %d and %d %sambiguous upon", - alt1->altnum, alt2->altnum, sub); - dumpAmbigMsg(fset, stderr, 0); - MR_traceAmbSource(fset,alt1,alt2); - } - - ambig = NULL; - if ( LL_k>1 ) ambig = make_tree_from_sets(alt1->fset, alt2->fset); - if ( ParseWithPredicates ) - { - if (alt1->predicate != NULL) predicate_free(alt1->predicate); /* MR12 */ - if (alt2->predicate != NULL) predicate_free(alt2->predicate); /* MR12 */ - - require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); - alt1->predicate = MR_find_predicates_and_supp((Node *)alt1->p1); - require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); - require (MR_predicate_context_completed(alt1->predicate),"predicate alt 1 not completed"); - alt1->predicate=MR_predSimplifyALL(alt1->predicate); - - require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); - alt2->predicate = MR_find_predicates_and_supp((Node *)alt2->p1); - require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); - require (MR_predicate_context_completed(alt2->predicate),"predicate alt 2 not completed"); - alt2->predicate=MR_predSimplifyALL(alt2->predicate); - - MR_doPredicatesHelp(0,alt1,alt2,jtype,sub); - - if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) ) - { - verify_context(alt1->predicate); - verify_context(alt2->predicate); - } - if (HoistPredicateContext&&(alt1->predicate!=NULL||alt2->predicate!=NULL) && WarningLevel>1) - ensure_predicates_cover_ambiguous_lookahead_sequences(alt1, alt2, sub, ambig); - if ( WarningLevel == 1 && - (alt1->predicate!=NULL||alt2->predicate!=NULL)) - { - for (i=1; i<=CLL_k; i++) set_free( fset[i] ); - free((char *)fset); - for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] ); - free((char *)ftbl); - Tfree(ambig); - return; - } - } -/* end TJP (10/24/93) */ - - fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line); - if ( jtype == aLoopBegin || jtype == aPlusBlk ) - fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub); - else - fprintf(stderr, " warning: alts %d and %d %sambiguous upon", - alt1->altnum, alt2->altnum, sub); - if ( elevel == 3 && LL_k>1 ) - { - preorder(ambig); - fprintf(stderr, "\n"); - for (i=1; i<=CLL_k; i++) set_free( fset[i] ); - free((char *)fset); - for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] ); - free((char *)ftbl); - Tfree(ambig); - return; - }; - - Tfree(ambig); - dumpAmbigMsg(fset, stderr, 0); - - /* because this is a special case in which both alt1 and alt2 have - lookahead sets of degree 1 for kaltnum; - CurAmbigAlt2 = alt2->altnum; - CurAmbigbtype = sub; - CurAmbigfile = alt1->file; - CurAmbigline = alt1->line; - - /* Don't do full LL(n) analysis if (...)? block because the block, - by definition, defies LL(n) analysis. - If guess (...)? block and ambiguous then don't remove anything from - 2nd alt to resolve ambig. - Want to predict with LL sup 1 ( n ) decision not LL(n) if guess block - since it is much cheaper than LL(n). LL sup 1 ( n ) "covers" the LL(n) - lookahead information. - - Note: LL(n) context cannot be computed for semantic predicates when - followed by (..)?. - - If (..)? then we scream "AAAHHHH! No LL(n) analysis will help" - - Is 'ambig' always defined if we enter this if? I hope so - because the 'ensure...()' func references it. TJP Nov 1993. - */ - - /* THM MR30: Instead of using first_item_is_guss_block we use - first_item_is_guess_block_extra which will look inside a - loop block for a guess block. In other words ( (...)? )*. - It there is an ambiguity in this circumstance then we suppress - the normal methods of resolving ambiguities. - */ - - if ( first_item_is_guess_block_extra((Junction *)alt1->p1)!=NULL ) - { - if ( ParseWithPredicates ) - { - if (alt1->predicate != NULL) predicate_free(alt1->predicate); /* MR12 */ - if (alt2->predicate != NULL) predicate_free(alt2->predicate); /* MR12 */ - require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); - alt1->predicate = MR_find_predicates_and_supp((Node *)alt1->p1); - require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); - require (MR_predicate_context_completed(alt1->predicate),"predicate alt 1 not completed"); - alt1->predicate=MR_predSimplifyALL(alt1->predicate); - - require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); - alt2->predicate = MR_find_predicates_and_supp((Node *)alt2->p1); - require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); - require (MR_predicate_context_completed(alt2->predicate),"predicate alt 2 not completed"); - alt2->predicate=MR_predSimplifyALL(alt2->predicate); - - MR_doPredicatesHelp(1,alt1,alt2,jtype,sub); - - if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) ) - { - verify_context(alt1->predicate); - verify_context(alt2->predicate); - } - if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) && WarningLevel>1 ) - ensure_predicates_cover_ambiguous_lookahead_sequences(alt1, alt2, sub, ambig); - if ( WarningLevel==1 && - (alt1->predicate!=NULL||alt2->predicate!=NULL)) - { - for (i=1; i<=CLL_k; i++) set_free( fset[i] ); - free((char *)fset); - for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] ); - free((char *)ftbl); - return; - } - } - - if ( WarningLevel>1 ) - { - fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line); - if ( jtype == aLoopBegin || jtype == aPlusBlk ) - fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub); - else - fprintf(stderr, " warning: alts %d and %d %sambiguous upon", - alt1->altnum, alt2->altnum, sub); - dumpAmbigMsg(fset, stderr, 0); - MR_traceAmbSource(fset,alt1,alt2); - } - - for (i=1; i<=CLL_k; i++) set_free( fset[i] ); - free((char *)fset); - for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] ); - free((char *)ftbl); - return; - } - - /* Not resolved with (..)? block. Do full LL(n) analysis */ - - /* ambig is the set of k-tuples truly in common between alt 1 and alt 2 */ - /* MR11 VerifyAmbig once used fset destructively */ - - ambig = VerifyAmbig(alt1, alt2, ftbl, fset, &t, &u, &numAmbig); - - /* are all things in intersection really ambigs? */ - - if (thisOverflow || numAmbig < n ) /* MR9 */ - { - Tree *v; - - /* remove ambig permutation from 2nd alternative to resolve ambig; - * We want to compute the set of artificial tuples, arising from - * LL sup 1 (n) compression, that collide with real tuples from the - * 2nd alternative. This is the set of "special case" tuples that - * the LL sup 1 (n) decision template maps incorrectly. - */ - - /* when generating code in genExpr() it does - * - * if ( genExprSets(j->fset) && !genExprTree(j->ftree)) {... - * - * Sooooo the j->ftree is the tree of alt2 - * after removal of conflicts, not alt1 ! - */ - - if ( ambig!=NULL ) - { - /* at the top of ambig is an ALT node */ - - for (v=ambig->down; v!=NULL; v=v->right) - { - u = trm_perm(u, v); /* remove v FROM u */ - } -/* fprintf(stderr, "after rm alt2:"); preorder(u); fprintf(stderr, "\n");*/ - } - Tfree( t ); - alt1->ftree = tappend(alt1->ftree, u); - alt1->ftree = tleft_factor(alt1->ftree); - } - - if ( ambig==NULL ) - { - for (i=1; i<=CLL_k; i++) set_free( fset[i] ); - free((char *)fset); - for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] ); - free((char *)ftbl); - return; - } - - ambig = tleft_factor(ambig); - -/* TJP: - * At this point, we surely have an LL(k) ambiguity. Check for predicates - */ - if ( ParseWithPredicates ) - { - if (alt1->predicate != NULL) predicate_free(alt1->predicate); /* MR12 */ - if (alt2->predicate != NULL) predicate_free(alt2->predicate); /* MR12 */ - require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); - alt1->predicate = MR_find_predicates_and_supp((Node *)alt1->p1); - require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); - require (MR_predicate_context_completed(alt1->predicate),"predicate alt 1 not completed"); - alt1->predicate=MR_predSimplifyALL(alt1->predicate); - - require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); - alt2->predicate = MR_find_predicates_and_supp((Node *)alt2->p1); - require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); - require (MR_predicate_context_completed(alt2->predicate),"predicate alt 2 not completed"); - alt2->predicate=MR_predSimplifyALL(alt2->predicate); - - MR_doPredicatesHelp(0,alt1,alt2,jtype,sub); - - if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) ) - { - verify_context(alt1->predicate); - verify_context(alt2->predicate); - } - if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) && WarningLevel>1 ) - ensure_predicates_cover_ambiguous_lookahead_sequences(alt1, alt2, sub, ambig); - if ( WarningLevel==1 && - (alt1->predicate!=NULL||alt2->predicate!=NULL)) - { - - /* We found at least one pred for at least one of the alts; - * If warnings are low, just return. - */ - - Tfree(ambig); - for (i=1; i<=CLL_k; i++) set_free( fset[i] ); - free((char *)fset); - for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] ); - free((char *)ftbl); - return; - } - /* else we're gonna give a warning */ - } -/* end TJP addition */ - - fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line); - if ( jtype == aLoopBegin || jtype == aPlusBlk ) - fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub); - else - fprintf(stderr, " warning: alts %d and %d %sambiguous upon", - alt1->altnum, alt2->altnum, sub); - if ( elevel == 3 ) - { - preorder(ambig->down); /* <===== k>1 ambiguity message data */ - fprintf(stderr, "\n"); - } else { - MR_skipped_e3_report=1; - dumpAmbigMsg(fset, stderr, 0); - }; - - MR_traceAmbSourceK(ambig,alt1,alt2); /* <====== k>1 ambiguity aid */ - - Tfree(ambig); - - for (i=1; i<=CLL_k; i++) set_free( fset[i] ); - free((char *)fset); - for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] ); - free((char *)ftbl); -} - -/* Don't analyze alpha block of (alpha)?beta; if (alpha)? then analyze - * Return the 1st node of the beta block if present else return j. - */ -Junction * -#ifdef __USE_PROTOS -analysis_point( Junction *j ) -#else -analysis_point( j ) -Junction *j; -#endif -{ - Junction *gblock; - - /* MR13b When there was an action/predicate preceding a guess block - the guess block became invisible at the analysis_point. - - first_item_is_guess_block accepts any kind of node, - despite the fact that the formal is a junction. But - I don't want to have to change it all over the place - until I know it works. - */ - - if ( j->ntype != nJunction && j->ntype != nAction) return j; - - gblock = first_item_is_guess_block((Junction *)j); - - if ( gblock!=NULL ) - { - Junction *past = gblock->end; - Junction *p; - require(past!=NULL, "analysis_point: no end block on (...)? block"); - - for (p=(Junction *)past->p1; p!=NULL; ) - { - if ( p->ntype==nAction ) - { - p=(Junction *)((ActionNode *)p)->next; - continue; - } - if ( p->ntype!=nJunction ) - { - past->alpha_beta_guess_end=1; /* MR14 */ - return (Junction *)past->p1; - } - if ( p->jtype==EndBlk || p->jtype==EndRule ) - { - return j; - } -/* MR6 */ -/* MR6 A guess block is of the form "(alpha)? beta" or "(alpha)?". */ -/* MR6 When beta is omitted (second form) this means "(alpha)? alpha". */ -/* MR6 The program does not store another copy of alpha in this case. */ -/* MR6 During analysis when the program needs to know what follows the */ -/* MR6 guess clause. It calls this routine. */ -/* MR6 */ -/* MR6 If it is of the form "(alpha)? beta" it returns a pointer to beta.*/ -/* MR6 */ -/* MR6 If it is of the form "(alpha)?" it returns a pointer to the guess */ -/* MR6 block itself thereby reusing the junction tree. */ -/* MR6 */ -/* MR6 It works by searching the "next in sequence" chain (skipping actions) */ -/* MR6 searching for a RuleRef or Token node. (Those are the only 4 kinds */ -/* MR6 of nodes: Junctions, RuleRef, Token, and Action.) */ -/* MR6 */ -/* MR6 This won't work for the special case "(alpha)? ()" because it has no */ -/* MR6 rule references or token nodes. It eventually encounters a */ -/* MR6 junction of type EndBlk or EndRule and says to its caller: nothing */ -/* MR6 more here to analyze - must be of the form "(alpha)?". */ -/* MR6 */ -/* MR6 In the case of "(alpha)? ()" it should return a pointer to "()" */ -/* MR6 */ -/* MR6 I think. */ -/* MR6 */ - if ( p->jtype!=Generic) { /* MR6 */ - past->alpha_beta_guess_end=1; /* MR14 */ - return (Junction *)past->p1; /* MR6 */ - }; /* MR6 */ - p=(Junction *)p->p1; - } - } - return j; -} - -set -#ifdef __USE_PROTOS -First( Junction *j, int k, int jtype, int *max_k ) -#else -First( j, k, jtype, max_k ) -Junction *j; -int k; -int jtype; -int *max_k; -#endif -{ - Junction *alt1, *alt2; - set a, rk, fCurBlk; - int savek; - int p1, p2; - - int save_maintainBackTrace; - - require(j->ntype==nJunction, "First: non junction passed"); - - /* C o m p u t e F I R S T s e t w i t h k l o o k a h e a d */ - fCurBlk = rk = empty; - for (alt1=j; alt1!=NULL; alt1 = (Junction *)alt1->p2 ) - { - Junction * p = NULL; - Junction * p1junction = NULL; - p = analysis_point((Junction *)alt1->p1); - p1junction = (Junction *) (alt1->p1); -#if 0 - if (p != p1junction) { - fprintf(stdout,"Analysis point for #%d is #%d", p1junction->seq, p->seq); /* debug */ - } -#endif - REACH(p, k, &rk, alt1->fset[k]); - require(set_nil(rk), "rk != nil"); - set_free(rk); - set_orin(&fCurBlk, alt1->fset[k]); - } - - /* D e t e c t A m b i g u i t i e s */ - *max_k = 1; - for (p1=1,alt1=j; alt1!=NULL; alt1 = (Junction *)alt1->p2, p1++) - { - for (p2=1,alt2=(Junction *)alt1->p2; alt2!=NULL; alt2 = (Junction *)alt2->p2, p2++) - { - savek = k; - a = set_and(alt1->fset[k], alt2->fset[k]); - while ( !set_nil(a) ) - { - /* if we have hit the max k requested, just give warning */ - if ( j->approx==k ) { - } - - if ( k==CLL_k ) - { -#ifdef NOT_USED -*** int save_LL_k = LL_k; -*** int save_CLL_k = CLL_k; -*** /* Get new LL_k from interactive feature if enabled */ -*** if ( AImode ) -*** AmbiguityDialog(j, jtype, alt1, alt2, &CLL_k, &LL_k); -#endif - *max_k = CLL_k; - save_maintainBackTrace=MR_MaintainBackTrace; - if (AlphaBetaTrace) MR_MaintainBackTrace=0; - HandleAmbiguity(j, alt1, alt2, jtype); - MR_MaintainBackTrace=save_maintainBackTrace; - break; - } - else - { - Junction *p = analysis_point((Junction *)alt1->p1); - Junction *q = analysis_point((Junction *)alt2->p1); - k++; /* attempt ambig alts again with more lookahead */ - - REACH(p, k, &rk, alt1->fset[k]); - require(set_nil(rk), "rk != nil"); - REACH(q, k, &rk, alt2->fset[k]); - require(set_nil(rk), "rk != nil"); - set_free(a); - a = set_and(alt1->fset[k], alt2->fset[k]); - if ( k > *max_k ) *max_k = k; - } - } - set_free(a); - k = savek; - } - } - - return fCurBlk; -} diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/fset2.c b/Tools/CodeTools/TianoTools/Pccts/antlr/fset2.c deleted file mode 100644 index 7f686a53d5..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/fset2.c +++ /dev/null @@ -1,2250 +0,0 @@ -/* - * fset2.c - * - * Compute FIRST sets for full LL(k) - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2001 - */ - -#include -#include "pcctscfg.h" -#include - -#ifdef PCCTS_USE_STDARG -#include -#else -#include -#endif - -#include "set.h" -#include "syn.h" -#include "hash.h" -#include "generic.h" -#include "dlgdef.h" - -/* ick! globals. Used by permute() to track which elements of a set have been used */ - -static int *findex; -set *fset; /* MR11 make global */ -static unsigned **ftbl; -static set *constrain; /* pts into fset. constrains tToken() to 'constrain' */ -int ConstrainSearch; -int maxk; /* set to initial k upon tree construction request */ - /* MR11 make global */ -static Tree *FreeList = NULL; - -#ifdef __USE_PROTOS -static int tmember_of_context(Tree *, Predicate *); -#else -static int tmember_of_context(); -#endif - -#if TREE_DEBUG -set set_of_tnodes_in_use; -int stop_on_tnode_seq_number=(-1); /* (-1) to disable */ -#endif - -/* Do root - * Then each sibling - */ - -void -#ifdef __USE_PROTOS -preorder( Tree *tree ) -#else -preorder( tree ) -Tree *tree; -#endif -{ - if ( tree == NULL ) return; - if ( tree->down != NULL ) fprintf(stderr, " ("); - if ( tree->token == ALT ) fprintf(stderr, " ALT"); - else fprintf(stderr, " %s", TerminalString(tree->token)); - if ( tree->token==EpToken ) fprintf(stderr, "(%d)", tree->v.rk); - preorder(tree->down); - if ( tree->down != NULL ) fprintf(stderr, " )"); - preorder(tree->right); -} - -#ifdef __USE_PROTOS -int MR_tree_matches_constraints(int k,set * constrain,Tree *t) -#else -int MR_tree_matches_constraints(k,constrain,t) - int k; - set * constrain; - Tree * t; -#endif -{ - int i; - Tree *u; - - if (k == 0) return 1; - - /* for testing guard predicates: if the guard tree is shorter - than the constraint then it is a match. The reason is that - a guard of (A B) should be equivalent to a guard of (A B . . .) - where "." matches every token. Thus a match which runs out - of tree before constraint is a match. - */ - - if (t == NULL) return 1; - require (set_deg(constrain[0]) == 1, - "MR_tree_matches_constraints: set_deg != 1"); - i=set_int(constrain[0]); - if (t->token != i) return 0; - if (k-1 == 0) return 1; - for (u=t->down; u != NULL; u=u->right) { - if (MR_tree_matches_constraints(k-1,&constrain[1],u)) { - return 1; - }; - }; - return 0; -} - -/* check the depth of each primary sibling to see that it is exactly - * k deep. e.g.; - * - * ALT - * | - * A ------- B - * | | - * C -- D E - * - * Remove all branches <= k deep. - * - * Added by TJP 9-23-92 to make the LL(k) constraint mechanism to work. - */ - -static int pruneCount=0; -static int prunePeak=200; - -Tree * -#ifdef __USE_PROTOS -prune( Tree *t, int k ) -#else -prune( t, k ) -Tree *t; -int k; -#endif -{ - pruneCount++; - if (pruneCount > prunePeak+100) { - prunePeak=pruneCount; -#if 0 -*** fprintf(stderr,"pruneCount=%d\n",pruneCount); -/*** preorder(t); ***/ -*** fprintf(stderr,"\n",pruneCount); -#endif - }; - if ( t == NULL ) { - pruneCount--; - return NULL; - }; - if ( t->token == ALT ) fatal_internal("prune: ALT node in FIRST tree"); - if ( t->right!=NULL ) t->right = prune(t->right, k); - if ( k>1 ) - { - if ( t->down!=NULL ) t->down = prune(t->down, k-1); - if ( t->down == NULL ) - { - Tree *r = t->right; - t->right = NULL; - Tfree(t); - pruneCount--; - return r; - } - } - pruneCount--; - return t; -} - -/* build a tree (root child1 child2 ... NULL) */ -#ifdef PCCTS_USE_STDARG -Tree *tmake(Tree *root, ...) -#else -Tree *tmake(va_alist) -va_dcl -#endif -{ - Tree *w; - va_list ap; - Tree *child, *sibling=NULL, *tail=NULL; -#ifndef PCCTS_USE_STDARG - Tree *root; -#endif - -#ifdef PCCTS_USE_STDARG - va_start(ap, root); -#else - va_start(ap); - root = va_arg(ap, Tree *); -#endif - child = va_arg(ap, Tree *); - while ( child != NULL ) - { -#ifdef DUM - /* added "find end of child" thing TJP March 1994 */ - for (w=child; w->right!=NULL; w=w->right) {;} /* find end of child */ -#else - w = child; -#endif - - if ( sibling == NULL ) {sibling = child; tail = w;} - else {tail->right = child; tail = w;} - child = va_arg(ap, Tree *); - } - - /* was "root->down = sibling;" */ - if ( root==NULL ) root = sibling; - else root->down = sibling; - - va_end(ap); - return root; -} - -Tree * -#ifdef __USE_PROTOS -tnode( int tok ) -#else -tnode( tok ) -int tok; -#endif -{ - Tree *p, *newblk; - static int n=0; - - if ( FreeList == NULL ) - { - /*fprintf(stderr, "tnode: %d more nodes\n", TreeBlockAllocSize);*/ - if ( TreeResourceLimit > 0 ) - { - if ( (n+TreeBlockAllocSize) >= TreeResourceLimit ) - { - fprintf(stderr, ErrHdr, FileStr[CurAmbigfile], CurAmbigline); - fprintf(stderr, " hit analysis resource limit while analyzing alts %d and %d %s\n", - CurAmbigAlt1, - CurAmbigAlt2, - CurAmbigbtype); - exit(PCCTS_EXIT_FAILURE); - } - } - newblk = (Tree *)calloc(TreeBlockAllocSize, sizeof(Tree)); - if ( newblk == NULL ) - { - fprintf(stderr, ErrHdr, FileStr[CurAmbigfile], CurAmbigline); - fprintf(stderr, " out of memory while analyzing alts %d and %d %s\n", - CurAmbigAlt1, - CurAmbigAlt2, - CurAmbigbtype); - exit(PCCTS_EXIT_FAILURE); - } - n += TreeBlockAllocSize; - for (p=newblk; p<&(newblk[TreeBlockAllocSize]); p++) - { - p->right = FreeList; /* add all new Tree nodes to Free List */ - FreeList = p; - } - } - p = FreeList; - FreeList = FreeList->right; /* remove a tree node */ - p->right = NULL; /* zero out ptrs */ - p->down = NULL; - p->token = tok; - - TnodesAllocated++; /* MR10 */ - TnodesInUse++; /* MR10 */ - if (TnodesInUse > TnodesPeak) TnodesPeak=TnodesInUse; /* MR10 */ - -#ifdef TREE_DEBUG - require(!p->in_use, "tnode: node in use!"); - p->in_use = 1; - p->seq=TnodesAllocated; - set_orel( (unsigned) TnodesAllocated,&set_of_tnodes_in_use); - if (stop_on_tnode_seq_number == p->seq) { - fprintf(stderr,"\n*** just allocated tnode #%d ***\n", - stop_on_tnode_seq_number); - }; -#endif - return p; -} - -static Tree * -#ifdef __USE_PROTOS -eofnode( int k ) -#else -eofnode( k ) -int k; -#endif -{ - Tree *t=NULL; - int i; - - for (i=1; i<=k; i++) - { - t = tmake(tnode((TokenInd!=NULL?TokenInd[EofToken]:EofToken)), t, NULL); - } - return t; -} - - - -void -#ifdef __USE_PROTOS -_Tfree( Tree *t ) -#else -_Tfree( t ) -Tree *t; -#endif -{ - if ( t!=NULL ) - { -#ifdef TREE_DEBUG - if (t->seq == stop_on_tnode_seq_number) { - fprintf(stderr,"\n*** just freed tnode #%d ***\n",t->seq); - }; - require(t->in_use, "_Tfree: node not in use!"); - t->in_use = 0; - set_rm( (unsigned) t->seq,set_of_tnodes_in_use); -#endif - t->right = FreeList; - FreeList = t; - TnodesInUse--; /* MR10 */ - } -} - -/* tree duplicate */ -Tree * -#ifdef __USE_PROTOS -tdup( Tree *t ) -#else -tdup( t ) -Tree *t; -#endif -{ - Tree *u; - - if ( t == NULL ) return NULL; - u = tnode(t->token); - u->v.rk = t->v.rk; - u->right = tdup(t->right); - u->down = tdup(t->down); - return u; -} - -/* tree duplicate (assume tree is a chain downwards) */ -Tree * -#ifdef __USE_PROTOS -tdup_chain( Tree *t ) -#else -tdup_chain( t ) -Tree *t; -#endif -{ - Tree *u; - - if ( t == NULL ) return NULL; - u = tnode(t->token); - u->v.rk = t->v.rk; - u->down = tdup(t->down); - return u; -} - -Tree * -#ifdef __USE_PROTOS -tappend( Tree *t, Tree *u ) -#else -tappend( t, u ) -Tree *t; -Tree *u; -#endif -{ - Tree *w; - -/*** fprintf(stderr, "tappend("); - *** preorder(t); fprintf(stderr, ","); - *** preorder(u); fprintf(stderr, " )\n"); -*/ - if ( t == NULL ) return u; - if ( t->token == ALT && t->right == NULL ) return tappend(t->down, u); - for (w=t; w->right!=NULL; w=w->right) {;} - w->right = u; - return t; -} - -/* dealloc all nodes in a tree */ -void -#ifdef __USE_PROTOS -Tfree( Tree *t ) -#else -Tfree( t ) -Tree *t; -#endif -{ - if ( t == NULL ) return; - Tfree( t->down ); - Tfree( t->right ); - _Tfree( t ); -} - -/* find all children (alts) of t that require remaining_k nodes to be LL_k - * tokens long. - * - * t-->o - * | - * a1--a2--...--an <-- LL(1) tokens - * | | | - * b1 b2 ... bn <-- LL(2) tokens - * | | | - * . . . - * . . . - * z1 z2 ... zn <-- LL(LL_k) tokens - * - * We look for all [Ep] needing remaining_k nodes and replace with u. - * u is not destroyed or actually used by the tree (a copy is made). - */ -Tree * -#ifdef __USE_PROTOS -tlink( Tree *t, Tree *u, int remaining_k ) -#else -tlink( t, u, remaining_k ) -Tree *t; -Tree *u; -int remaining_k; -#endif -{ - Tree *p; - require(remaining_k!=0, "tlink: bad tree"); - - if ( t==NULL ) return NULL; - /*fprintf(stderr, "tlink: u is:"); preorder(u); fprintf(stderr, "\n");*/ - if ( t->token == EpToken && t->v.rk == remaining_k ) - { - require(t->down==NULL, "tlink: invalid tree"); - if ( u == NULL ) { -/* MR10 */ Tree *tt=t->right; -/* MR10 */ _Tfree(t); -/* MR10 */ return tt; - }; - p = tdup( u ); - p->right = t->right; - _Tfree( t ); - return p; - } - t->down = tlink(t->down, u, remaining_k); - t->right = tlink(t->right, u, remaining_k); - return t; -} - -/* remove as many ALT nodes as possible while still maintaining semantics */ -Tree * -#ifdef __USE_PROTOS -tshrink( Tree *t ) -#else -tshrink( t ) -Tree *t; -#endif -{ - if ( t == NULL ) return NULL; - t->down = tshrink( t->down ); - t->right = tshrink( t->right ); - if ( t->down == NULL ) - { - if ( t->token == ALT ) - { - Tree *u = t->right; - _Tfree(t); - return u; /* remove useless alts */ - } - return t; - } - - /* (? (ALT (? ...)) s) ==> (? (? ...) s) where s = sibling, ? = match any */ - if ( t->token == ALT && t->down->right == NULL) - { - Tree *u = t->down; - u->right = t->right; - _Tfree( t ); - return u; - } - /* (? (A (ALT t)) s) ==> (? (A t) s) where A is a token; s,t siblings */ - if ( t->token != ALT && t->down->token == ALT && t->down->right == NULL ) - { - Tree *u = t->down->down; - _Tfree( t->down ); - t->down = u; - return t; - } - return t; -} - -Tree * -#ifdef __USE_PROTOS -tflatten( Tree *t ) -#else -tflatten( t ) -Tree *t; -#endif -{ - if ( t == NULL ) return NULL; - t->down = tflatten( t->down ); - t->right = tflatten( t->right ); - if ( t->down == NULL ) return t; - - if ( t->token == ALT ) - { - Tree *u; - /* find tail of children */ - for (u=t->down; u->right!=NULL; u=u->right) {;} - u->right = t->right; - u = t->down; - _Tfree( t ); - return u; - } - return t; -} - -Tree * -#ifdef __USE_PROTOS -tJunc( Junction *p, int k, set *rk ) -#else -tJunc( p, k, rk ) -Junction *p; -int k; -set *rk; -#endif -{ - Tree *t=NULL, *u=NULL; - Junction *alt; - Tree *tail=NULL, *r; - -#ifdef DBG_TRAV - fprintf(stderr, "tJunc(%d): %s in rule %s\n", k, - decodeJType[p->jtype], ((Junction *)p)->rname); -#endif - -/* MR14 */ if (AlphaBetaTrace && p->alpha_beta_guess_end) { -/* MR14 */ warnFL( -/* MR14 */ "not possible to compute follow set for alpha in an \"(alpha)? beta\" block. ", -/* MR14 */ FileStr[p->file],p->line); -/* MR14 */ MR_alphaBetaTraceReport(); -/* MR14 */ }; - -/* MR14 */ if (p->alpha_beta_guess_end) { -/* MR14 */ return NULL; -/* MR14 */ } - - if ( p->jtype==aLoopBlk || p->jtype==RuleBlk || - p->jtype==aPlusBlk || p->jtype==aSubBlk || p->jtype==aOptBlk ) - { - if ( p->jtype!=aSubBlk && p->jtype!=aOptBlk ) { - require(p->lock!=NULL, "rJunc: lock array is NULL"); - if ( p->lock[k] ) return NULL; - p->lock[k] = TRUE; - } - -/* MR10 */ if (MR_MaintainBackTrace) { -/* MR10 */ if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p); -/* MR10 */ }; - - TRAV(p->p1, k, rk, tail); - -/* MR10 */ if (MR_MaintainBackTrace) { -/* MR10 */ if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack); -/* MR10 */ }; - - if ( p->jtype==RuleBlk ) {p->lock[k] = FALSE; return tail;} - r = tmake(tnode(ALT), tail, NULL); - for (alt=(Junction *)p->p2; alt!=NULL; alt = (Junction *)alt->p2) - { - /* if this is one of the added optional alts for (...)+ then break */ - if ( alt->ignore ) break; - - if ( tail==NULL ) {TRAV(alt->p1, k, rk, tail); r->down = tail;} - else - { -/* MR10 */ if (MR_MaintainBackTrace) { -/* MR10 */ if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p); -/* MR10 */ }; - - TRAV(alt->p1, k, rk, tail->right); - -/* MR10 */ if (MR_MaintainBackTrace) { -/* MR10 */ if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack); -/* MR10 */ }; - if ( tail->right != NULL ) tail = tail->right; - } - } - if ( p->jtype!=aSubBlk && p->jtype!=aOptBlk ) p->lock[k] = FALSE; -#ifdef DBG_TREES - fprintf(stderr, "blk(%s) returns:",((Junction *)p)->rname); preorder(r); fprintf(stderr, "\n"); -#endif - if ( r->down == NULL ) {_Tfree(r); return NULL;} - return r; - } - - if ( p->jtype==EndRule ) - { - if ( p->halt ) /* don't want FOLLOW here? */ - { -/**** if ( ContextGuardTRAV ) return NULL; ****/ - set_orel( (unsigned) k, rk); /* indicate this k value needed */ /* MR10 cast */ - t = tnode(EpToken); - t->v.rk = k; - return t; - } - require(p->lock!=NULL, "rJunc: lock array is NULL"); - if ( p->lock[k] ) return NULL; - /* if no FOLLOW assume k EOF's */ - if ( p->p1 == NULL ) return eofnode(k); - p->lock[k] = TRUE; - } - -/* MR14 */ if (p->p1 != NULL && p->guess && p->guess_analysis_point == NULL) { -/* MR14 */ Node * guess_point; -/* MR14 */ guess_point=(Node *)analysis_point(p); -/* MR14 */ if (guess_point == (Node *)p) { -/* MR14 */ guess_point=p->p1; -/* MR14 */ } -/* MR14 */ p->guess_analysis_point=guess_point; -/* MR14 */ } - - if ( p->p2 == NULL ) - { - -/* MR10 */ if (MR_MaintainBackTrace) { -/* MR10 */ if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p); -/* MR10 */ }; - -/* M14 */ if (p->guess_analysis_point != NULL) { -/* M14 */ TRAV(p->guess_analysis_point, k, rk,t); -/* M14 */ } else { - TRAV(p->p1, k, rk,t); -/* M14 */ } - -/* MR10 */ if (MR_MaintainBackTrace) { -/* MR10 */ if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack); -/* MR10 */ }; - - if ( p->jtype==EndRule ) p->lock[k]=FALSE; - return t; - } - -/* MR10 */ if (MR_MaintainBackTrace) { -/* MR10 */ if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p); -/* MR10 */ }; - -/* M14 */ if (p->guess_analysis_point != NULL) { -/* M14 */ TRAV(p->guess_analysis_point, k, rk,t); -/* M14 */ } else { - TRAV(p->p1, k, rk,t); -/* M14 */ } - -/* MR10 */ if (MR_MaintainBackTrace) { -/* MR10 */ if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack); -/* MR10 */ }; - - if ( p->jtype!=RuleBlk && /* MR14 */ !p->guess) TRAV(p->p2, k, rk, u); - - if ( p->jtype==EndRule ) p->lock[k] = FALSE;/* unlock node */ - - if ( t==NULL ) return tmake(tnode(ALT), u, NULL); - return tmake(tnode(ALT), t, u, NULL); -} - -Tree * -#ifdef __USE_PROTOS -tRuleRef( RuleRefNode *p, int k, set *rk_out ) -#else -tRuleRef( p, k, rk_out ) -RuleRefNode *p; -int k; -set *rk_out; -#endif -{ - int k2; - Tree *t=NULL, *u=NULL; - Junction *r; - set rk, rk2; - int save_halt; - RuleEntry *q = (RuleEntry *) hash_get(Rname, p->text); - -#ifdef DBG_TRAV - fprintf(stderr, "tRuleRef: %s\n", p->text); -#endif - if ( q == NULL ) - { - TRAV(p->next, k, rk_out, t);/* ignore undefined rules */ - return t; - } - rk = rk2 = empty; - if (RulePtr == NULL) fatal("RulePtr==NULL"); - r = RulePtr[q->rulenum]; - if ( r->lock[k] ) return NULL; - save_halt = r->end->halt; - r->end->halt = TRUE; /* don't let reach fall off end of rule here */ - -/* MR10 */ if (MR_MaintainBackTrace) { -/* MR10 */ MR_pointerStackPush(&MR_BackTraceStack,p); -/* MR10 */ }; - - TRAV(r, k, &rk, t); - -/* MR10 */ if (MR_MaintainBackTrace) { -/* MR10 */ MR_pointerStackPop(&MR_BackTraceStack); -/* MR10 */ }; - - r->end->halt = save_halt; -#ifdef DBG_TREES - fprintf(stderr, "after ruleref, t is:"); preorder(t); fprintf(stderr, "\n"); -#endif - t = tshrink( t ); - while ( !set_nil(rk) ) { /* any k left to do? if so, link onto tree */ - k2 = set_int(rk); - set_rm(k2, rk); - -/* MR10 */ if (MR_MaintainBackTrace) { -/* MR10 */ MR_pointerStackPush(&MR_BackTraceStack,p); -/* MR10 */ }; - - TRAV(p->next, k2, &rk2, u); - -/* MR10 */ if (MR_MaintainBackTrace) { -/* MR10 */ MR_pointerStackPop(&MR_BackTraceStack); -/* MR10 */ }; - - t = tlink(t, u, k2); /* any alts missing k2 toks, add u onto end */ - Tfree(u); /* MR10 */ - } - set_free(rk); /* rk is empty, but free it's memory */ - set_orin(rk_out, rk2); /* remember what we couldn't do */ - set_free(rk2); - return t; -} - -Tree * -#ifdef __USE_PROTOS -tToken( TokNode *p, int k, set *rk ) -#else -tToken( p, k, rk ) -TokNode *p; -int k; -set *rk; -#endif -{ - Tree *t=NULL, *tset=NULL, *u; - - if (ConstrainSearch) { - if (MR_AmbSourceSearch) { - require(constrain>=fset&&constrain<=&(fset[CLL_k]),"tToken: constrain is not a valid set"); - } else { - require(constrain>=fset&&constrain<=&(fset[LL_k]),"tToken: constrain is not a valid set"); - }; - constrain = &fset[maxk-k+1]; - } - -#ifdef DBG_TRAV - fprintf(stderr, "tToken(%d): %s\n", k, TerminalString(p->token)); - if ( ConstrainSearch ) { - fprintf(stderr, "constrain is:"); s_fprT(stderr, *constrain); fprintf(stderr, "\n"); - } -#endif - - /* is it a meta token (set of tokens)? */ - - if ( !set_nil(p->tset) ) - { - unsigned e=0; - set a; - Tree *n, *tail = NULL; - - if ( ConstrainSearch ) { - a = set_and(p->tset, *constrain); - if (set_nil(a)) { /* MR10 */ - set_free(a); /* MR11 */ - return NULL; /* MR10 */ - }; /* MR10 */ - } else { - a = set_dup(p->tset); - }; - - for (; !set_nil(a); set_rm(e, a)) - { - e = set_int(a); - n = tnode(e); - if ( tset==NULL ) { tset = n; tail = n; } - else { tail->right = n; tail = n; } - } - set_free( a ); - } - else if ( ConstrainSearch && !set_el(p->token, *constrain) ) - { -/* fprintf(stderr, "ignoring token %s(%d)\n", TerminalString(p->token), - k);*/ - return NULL; - } - else { - tset = tnode( p->token ); - }; - -/* MR10 */ if (MR_MaintainBackTrace) { -/* MR10 */ if (k == 1) { -/* MR10 */ MR_pointerStackPush(&MR_BackTraceStack,p); -/* MR13 */ if (MR_SuppressSearch) { -/* MR13 */ MR_suppressSearchReport(); -/* MR13 */ } else { -/* MR10 */ MR_backTraceReport(); -/* MR13 */ }; -/* MR10 */ MR_pointerStackPop(&MR_BackTraceStack); -/* MR11 */ Tfree(tset); -/* MR11 */ return NULL; -/* MR10 */ }; -/* MR10 */ }; - - if ( k == 1 ) return tset; - - if (MR_MaintainBackTrace) { - MR_pointerStackPush(&MR_BackTraceStack,p); - }; - - TRAV(p->next, k-1, rk, t); - - if (MR_MaintainBackTrace) { - Tfree(t); - Tfree(tset); - MR_pointerStackPop(&MR_BackTraceStack); - return NULL; - }; - - /* here, we are positive that, at least, this tree will not contribute - * to the LL(2) tree since it will be too shallow, IF t==NULL. - * If doing a context guard walk, then don't prune. - */ - if ( t == NULL && !ContextGuardTRAV ) /* tree will be too shallow */ - { - if ( tset!=NULL ) Tfree( tset ); - return NULL; - } -#ifdef DBG_TREES - fprintf(stderr, "tToken(%d)->next:",k); preorder(t); fprintf(stderr, "\n"); -#endif - - /* if single token root, then just make new tree and return */ - /* MR10 - set_nil(p->tset) isn't a good test because of ConstraintSearch */ - - if (tset->right == NULL) return tmake(tset, t, NULL); /* MR10 */ - - /* here we must make a copy of t as a child of each element of the tset; - * e.g., "T1..T3 A" would yield ( nil ( T1 A ) ( T2 A ) ( T3 A ) ) - */ - for (u=tset; u!=NULL; u=u->right) - { - /* make a copy of t and hook it onto bottom of u */ - u->down = tdup(t); - } - Tfree( t ); -#ifdef DBG_TREES - fprintf(stderr, "range is:"); preorder(tset); fprintf(stderr, "\n"); -#endif - return tset; -} - -Tree * -#ifdef __USE_PROTOS -tAction( ActionNode *p, int k, set *rk ) -#else -tAction( p, k, rk ) -ActionNode *p; -int k; -set *rk; -#endif -{ - Tree *t=NULL; - set *save_fset=NULL; - int i; - - /* fprintf(stderr, "tAction\n"); */ - -/* An MR_SuppressSearch is looking for things that can be - reached even when the predicate is false. - - There are three kinds of predicates: - plain: r1: <

>? r2 - guarded: r1: (A)? => <

>? r2 - ampersand style: r1: (A)? && <

>? r2 - - Of the three kinds of predicates, only a guard predicate - has things which are reachable even when the predicate - is false. To be reachable the constraint must *not* - match the guard. - -*/ - - if (p->is_predicate && MR_SuppressSearch) { - - Predicate *pred=p->guardpred; - - if (pred == NULL) { - t=NULL; - goto EXIT; - }; - constrain = &fset[maxk-k+1]; - if (pred->k == 1) { - set dif; - dif=set_dif(*constrain,pred->scontext[1]); - if (set_nil(dif)) { - set_free(dif); - t=NULL; - goto EXIT; - }; - set_free(dif); - } else { - if (MR_tree_matches_constraints(k,constrain,pred->tcontext)) { - t=NULL; - goto EXIT; - }; - } - }; - - /* The ampersand predicate differs from the - other predicates because its first set - is a subset of the first set behind the predicate - - r1: (A)? && <

>? r2 ; - r2: A | B; - - In this case first[1] of r1 is A, even - though first[1] of r2 is {A B}. - */ - - if (p->is_predicate && p->ampersandPred != NULL) { - - Predicate *pred=p->ampersandPred; - Tree *tAND; - Tree *tset; - - if (k <= pred->k) { - if (MR_MaintainBackTrace) MR_pointerStackPush(&MR_BackTraceStack,p); - TRAV(p->guardNodes,k,rk,t); - if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack); - return t; - } else { - require (k>1,"tAction for ampersandpred: k <= 1"); - if (ConstrainSearch) { - if (MR_AmbSourceSearch) { - require(constrain>=fset&&constrain<=&(fset[CLL_k]), - "tToken: constrain is not a valid set"); - } else { - require(constrain>=fset&&constrain<=&(fset[LL_k]), - "tToken: constrain is not a valid set"); - }; - save_fset=(set *) calloc (CLL_k+1,sizeof(set)); - require (save_fset != NULL,"tAction save_fset alloc"); - for (i=1; i <= CLL_k ; i++) { - save_fset[i]=set_dup(fset[i]); - }; - if (pred->k == 1) { - constrain = &fset[maxk-k+1]; - set_andin(constrain,pred->scontext[1]); - if (set_nil(*constrain)) { - t=NULL; - goto EXIT; - }; - } else { - constrain = &fset[maxk-k+1]; - if (! MR_tree_matches_constraints(pred->k,constrain,pred->tcontext)) { - t=NULL; - goto EXIT; - }; /* end loop on i */ - }; /* end loop on pred scontext/tcontext */ - }; /* end if on k > pred->k */ - }; /* end if on constrain search */ - - TRAV(p->next,k,rk,t); - - if (t != NULL) { - t=tshrink(t); - t=tflatten(t); - t=tleft_factor(t); - if (pred->tcontext != NULL) { - tAND=MR_computeTreeAND(t,pred->tcontext); - } else { - tset=MR_make_tree_from_set(pred->scontext[1]); - tAND=MR_computeTreeAND(t,tset); - Tfree(tset); - }; - Tfree(t); - t=tAND; - }; - goto EXIT; - - }; /* end if on ampersand predicate */ - - TRAV(p->next,k,rk,t); - -EXIT: - if (save_fset != NULL) { - for (i=1 ; i <= CLL_k ; i++) { - set_free(fset[i]); - fset[i]=save_fset[i]; - }; - free ( (char *) save_fset); - }; - return t; -} - -/* see if e exists in s as a possible input permutation (e is always a chain) */ - -int -#ifdef __USE_PROTOS -tmember( Tree *e, Tree *s ) -#else -tmember( e, s ) -Tree *e; -Tree *s; -#endif -{ - if ( e==NULL||s==NULL ) return 0; -/** fprintf(stderr, "tmember("); -*** preorder(e); fprintf(stderr, ","); -*** preorder(s); fprintf(stderr, " )\n"); -*/ - if ( s->token == ALT && s->right == NULL ) return tmember(e, s->down); - if ( e->token!=s->token ) - { - if ( s->right==NULL ) return 0; - return tmember(e, s->right); - } - if ( e->down==NULL && s->down == NULL ) return 1; - if ( tmember(e->down, s->down) ) return 1; - if ( s->right==NULL ) return 0; - return tmember(e, s->right); -} - -/* see if e exists in s as a possible input permutation (e is always a chain); - * Only check s to the depth of e. In other words, 'e' can be a shorter - * sequence than s. - */ -int -#ifdef __USE_PROTOS -tmember_constrained( Tree *e, Tree *s) -#else -tmember_constrained( e, s ) -Tree *e; -Tree *s; -#endif -{ - if ( e==NULL||s==NULL ) return 0; -/** fprintf(stderr, "tmember_constrained("); -*** preorder(e); fprintf(stderr, ","); -*** preorder(s); fprintf(stderr, " )\n"); -**/ - if ( s->token == ALT && s->right == NULL ) - return tmember_constrained(e, s->down); - if ( e->token!=s->token ) - { - if ( s->right==NULL ) return 0; - return tmember_constrained(e, s->right); - } - if ( e->down == NULL ) return 1; /* if s is matched to depth of e return */ - if ( tmember_constrained(e->down, s->down) ) return 1; - if ( s->right==NULL ) return 0; - return tmember_constrained(e, s->right); -} - -/* combine (? (A t) ... (A u) ...) into (? (A t u)) */ -Tree * -#ifdef __USE_PROTOS -tleft_factor( Tree *t ) -#else -tleft_factor( t ) -Tree *t; -#endif -{ - Tree *u, *v, *trail, *w; - - /* left-factor what is at this level */ - if ( t == NULL ) return NULL; - for (u=t; u!=NULL; u=u->right) - { - trail = u; - v=u->right; - while ( v!=NULL ) - { - if ( u->token == v->token ) - { - if ( u->down!=NULL ) - { - for (w=u->down; w->right!=NULL; w=w->right) {;} - w->right = v->down; /* link children together */ - } - else u->down = v->down; - trail->right = v->right; /* unlink factored node */ - _Tfree( v ); - v = trail->right; - } - else {trail = v; v=v->right;} - } - } - /* left-factor what is below */ - for (u=t; u!=NULL; u=u->right) u->down = tleft_factor( u->down ); - return t; -} - -/* remove the permutation p from t if present */ -Tree * -#ifdef __USE_PROTOS -trm_perm( Tree *t, Tree *p ) -#else -trm_perm( t, p ) -Tree *t; -Tree *p; -#endif -{ - /* - fprintf(stderr, "trm_perm("); - preorder(t); fprintf(stderr, ","); - preorder(p); fprintf(stderr, " )\n"); - */ - if ( t == NULL || p == NULL ) return NULL; - if ( t->token == ALT ) - { - t->down = trm_perm(t->down, p); - if ( t->down == NULL ) /* nothing left below, rm cur node */ - { - Tree *u = t->right; - _Tfree( t ); - return trm_perm(u, p); - } - t->right = trm_perm(t->right, p); /* look for more instances of p */ - return t; - } - if ( p->token != t->token ) /* not found, try a sibling */ - { - t->right = trm_perm(t->right, p); - return t; - } - t->down = trm_perm(t->down, p->down); - if ( t->down == NULL ) /* nothing left below, rm cur node */ - { - Tree *u = t->right; - _Tfree( t ); - return trm_perm(u, p); - } - t->right = trm_perm(t->right, p); /* look for more instances of p */ - return t; -} - -/* add the permutation 'perm' to the LL_k sets in 'fset' */ -void -#ifdef __USE_PROTOS -tcvt( set *fset, Tree *perm ) -#else -tcvt( fset, perm ) -set *fset; -Tree *perm; -#endif -{ - if ( perm==NULL ) return; - set_orel(perm->token, fset); - tcvt(fset+1, perm->down); -} - -/* for each element of ftbl[k], make it the root of a tree with permute(ftbl[k+1]) - * as a child. - */ -Tree * -#ifdef __USE_PROTOS -permute( int k, int max_k ) -#else -permute( k, max_k ) -int k, max_k; -#endif -{ - Tree *t, *u; - - if ( k>max_k ) return NULL; - if ( ftbl[k][findex[k]] == nil ) return NULL; - t = permute(k+1, max_k); - if ( t==NULL&&k maxk will have to change. - */ -Tree * -#ifdef __USE_PROTOS -VerifyAmbig( Junction *alt1, Junction *alt2, unsigned **ft, set *fs, Tree **t, Tree **u, int *numAmbig ) -#else -VerifyAmbig( alt1, alt2, ft, fs, t, u, numAmbig ) -Junction *alt1; -Junction *alt2; -unsigned **ft; -set *fs; -Tree **t; -Tree **u; -int *numAmbig; -#endif -{ - set rk; - Tree *perm, *ambig=NULL; - Junction *p; - int k; - int tnodes_at_start=TnodesAllocated; - int tnodes_at_end; - int tnodes_used; - set *save_fs; - int j; - - save_fs=(set *) calloc(CLL_k+1,sizeof(set)); - require(save_fs != NULL,"save_fs calloc"); - - for (j=0; j <= CLL_k ; j++) save_fs[j]=set_dup(fs[j]); - - maxk = LL_k; /* NOTE: for now, we look for LL_k */ - ftbl = ft; - fset = fs; - constrain = &(fset[1]); - findex = (int *) calloc(LL_k+1, sizeof(int)); - if ( findex == NULL ) - { - fprintf(stderr, ErrHdr, FileStr[CurAmbigfile], CurAmbigline); - fprintf(stderr, " out of memory while analyzing alts %d and %d of %s\n", - CurAmbigAlt1, - CurAmbigAlt2, - CurAmbigbtype); - exit(PCCTS_EXIT_FAILURE); - } - for (k=1; k<=LL_k; k++) findex[k] = 0; - - rk = empty; - ConstrainSearch = 1; /* consider only tokens in ambig sets */ - - p = analysis_point((Junction *)alt1->p1); - TRAV(p, LL_k, &rk, *t); - *t = tshrink( *t ); - *t = tflatten( *t ); - *t = tleft_factor( *t ); /* MR10 */ - *t = prune(*t, LL_k); - *t = tleft_factor( *t ); - -/*** fprintf(stderr, "after shrink&flatten&prune&left_factor:"); preorder(*t); fprintf(stderr, "\n");*/ - if ( *t == NULL ) - { -/*** fprintf(stderr, "TreeIncomplete --> no LL(%d) ambiguity\n", LL_k);*/ - Tfree( *t ); /* kill if impossible to have ambig */ - *t = NULL; - } - - p = analysis_point((Junction *)alt2->p1); - - TRAV(p, LL_k, &rk, *u); - *u = tshrink( *u ); - *u = tflatten( *u ); - *t = tleft_factor( *t ); /* MR10 */ - *u = prune(*u, LL_k); - *u = tleft_factor( *u ); -/* fprintf(stderr, "after shrink&flatten&prune&lfactor:"); preorder(*u); fprintf(stderr, "\n");*/ - if ( *u == NULL ) - { -/* fprintf(stderr, "TreeIncomplete --> no LL(%d) ambiguity\n", LL_k);*/ - Tfree( *u ); - *u = NULL; - } - - for (k=1; k<=LL_k; k++) set_clr( fs[k] ); - - ambig = tnode(ALT); - k = 0; - if ( *t!=NULL && *u!=NULL ) - { - while ( (perm=permute(1,LL_k))!=NULL ) - { -/* fprintf(stderr, "chk perm:"); preorder(perm); fprintf(stderr, "\n");*/ - if ( tmember(perm, *t) && tmember(perm, *u) ) - { -/* fprintf(stderr, "ambig upon"); preorder(perm); fprintf(stderr, "\n");*/ - - k++; - perm->right = ambig->down; - ambig->down = perm; - tcvt(&(fs[1]), perm); - } - else Tfree( perm ); - } - } - - for (j=0; j <= CLL_k ; j++) fs[j]=save_fs[j]; - free( (char *) save_fs); - - tnodes_at_end=TnodesAllocated; - tnodes_used=tnodes_at_end - tnodes_at_start; - - if (TnodesReportThreshold > 0 && tnodes_used > TnodesReportThreshold) { - fprintf(stdout,"There were %d tuples whose ambiguity could not be resolved by full lookahead\n",k); - fprintf(stdout,"There were %d tnodes created to resolve ambiguity between:\n\n",tnodes_used); - fprintf(stdout," Choice 1: %s line %d file %s\n", - MR_ruleNamePlusOffset( (Node *) alt1),alt1->line,FileStr[alt1->file]); - fprintf(stdout," Choice 2: %s line %d file %s\n", - MR_ruleNamePlusOffset( (Node *) alt2),alt2->line,FileStr[alt2->file]); - for (j=1; j <= CLL_k ; j++) { - fprintf(stdout,"\n Intersection of lookahead[%d] sets:\n",j); - MR_dumpTokenSet(stdout,2,fs[j]); - }; - fprintf(stdout,"\n"); - }; - - *numAmbig = k; - if ( ambig->down == NULL ) {_Tfree(ambig); ambig = NULL;} - free( (char *)findex ); -/* fprintf(stderr, "final ambig:"); preorder(ambig); fprintf(stderr, "\n");*/ - return ambig; -} - -static Tree * -#ifdef __USE_PROTOS -bottom_of_chain( Tree *t ) -#else -bottom_of_chain( t ) -Tree *t; -#endif -{ - if ( t==NULL ) return NULL; - for (; t->down != NULL; t=t->down) {;} - return t; -} - -/* - * Make a tree from k sets where the degree of the first k-1 sets is 1. - */ -Tree * -#ifdef __USE_PROTOS -make_tree_from_sets( set *fset1, set *fset2 ) -#else -make_tree_from_sets( fset1, fset2 ) -set *fset1; -set *fset2; -#endif -{ - set inter; - int i; - Tree *t=NULL, *n, *u; - unsigned *p,*q; - require(LL_k>1, "make_tree_from_sets: LL_k must be > 1"); - - /* do the degree 1 sets first */ - for (i=1; i<=LL_k-1; i++) - { - inter = set_and(fset1[i], fset2[i]); - require(set_deg(inter)==1, "invalid set to tree conversion"); - n = tnode(set_int(inter)); - if (t==NULL) t=n; else tmake(t, n, NULL); - set_free(inter); - } - - /* now add the chain of tokens at depth k */ - u = bottom_of_chain(t); - inter = set_and(fset1[LL_k], fset2[LL_k]); - if ( (q=p=set_pdq(inter)) == NULL ) fatal_internal("Can't alloc space for set_pdq"); - /* first one is linked to bottom, then others are sibling linked */ - n = tnode(*p++); - u->down = n; - u = u->down; - while ( *p != nil ) - { - n = tnode(*p); - u->right = n; - u = u->right; - p++; - } - free((char *)q); - - return t; -} - -/* create and return the tree of lookahead k-sequences that are in t, but not - * in the context of predicates in predicate list p. - */ -Tree * -#ifdef __USE_PROTOS -tdif( Tree *ambig_tuples, Predicate *p, set *fset1, set *fset2 ) -#else -tdif( ambig_tuples, p, fset1, fset2 ) -Tree *ambig_tuples; -Predicate *p; -set *fset1; -set *fset2; -#endif -{ - unsigned **ft; - Tree *dif=NULL; - Tree *perm; - set b; - int i,k; - - if ( p == NULL ) return tdup(ambig_tuples); - - ft = (unsigned **) calloc(CLL_k+1, sizeof(unsigned *)); - require(ft!=NULL, "cannot allocate ft"); - for (i=1; i<=CLL_k; i++) - { - b = set_and(fset1[i], fset2[i]); - ft[i] = set_pdq(b); - set_free(b); - } - findex = (int *) calloc(LL_k+1, sizeof(int)); - if ( findex == NULL ) - { - fatal_internal("out of memory in tdif while checking predicates"); - } - for (k=1; k<=LL_k; k++) findex[k] = 0; - -#ifdef DBG_TRAV - fprintf(stderr, "tdif_%d[", p->k); - preorder(ambig_tuples); - fprintf(stderr, ","); - preorder(p->tcontext); - fprintf(stderr, "] ="); -#endif - - ftbl = ft; - while ( (perm=permute(1,p->k))!=NULL ) - { -#ifdef DBG_TRAV - fprintf(stderr, "test perm:"); preorder(perm); fprintf(stderr, "\n"); -#endif - if ( tmember_constrained(perm, ambig_tuples) && - !tmember_of_context(perm, p) ) - { -#ifdef DBG_TRAV - fprintf(stderr, "satisfied upon"); preorder(perm); fprintf(stderr, "\n"); -#endif - k++; - if ( dif==NULL ) dif = perm; - else - { - perm->right = dif; - dif = perm; - } - } - else Tfree( perm ); - } - -#ifdef DBG_TRAV - preorder(dif); - fprintf(stderr, "\n"); -#endif - - for (i=1; i<=CLL_k; i++) free( (char *)ft[i] ); - free((char *)ft); - free((char *)findex); - - return dif; -} - -/* is lookahead sequence t a member of any context tree for any - * predicate in p? - */ -static int -#ifdef __USE_PROTOS -tmember_of_context( Tree *t, Predicate *p ) -#else -tmember_of_context( t, p ) -Tree *t; -Predicate *p; -#endif -{ - for (; p!=NULL; p=p->right) - { - if ( p->expr==PRED_AND_LIST || p->expr==PRED_OR_LIST ) - return tmember_of_context(t, p->down); - if ( tmember_constrained(t, p->tcontext) ) return 1; - if ( tmember_of_context(t, p->down) ) return 1; - } - return 0; -} - -int -#ifdef __USE_PROTOS -is_single_tuple( Tree *t ) -#else -is_single_tuple( t ) -Tree *t; -#endif -{ - if ( t == NULL ) return 0; - if ( t->right != NULL ) return 0; - if ( t->down == NULL ) return 1; - return is_single_tuple(t->down); -} - - -/* MR10 Check that a context guard contains only allowed things */ -/* MR10 (mainly token references). */ - -#ifdef __USE_PROTOS -int contextGuardOK(Node *p,int h,int *hmax) -#else -int contextGuardOK(p,h,hmax) - Node *p; - int h; - int *hmax; -#endif -{ - Junction *j; - TokNode *tn; - - if (p == NULL) return 1; - if (p->ntype == nToken) { - h++; - if (h > *hmax) *hmax=h; - tn=(TokNode *)p; - if (tn->el_label != NULL) { - warnFL(eMsg1("a label (\"%s\") for a context guard element is meaningless",tn->el_label), - FileStr[p->file],p->line); - }; - return contextGuardOK( ( (TokNode *) p)->next,h,hmax); - } else if (p->ntype == nAction) { - goto Fail; - } else if (p->ntype == nRuleRef) { - goto Fail; - } else { - require (p->ntype == nJunction,"Unexpected ntype"); - j=(Junction *) p; - if (j->jtype != Generic && - j->jtype != aSubBlk && /* pretty sure this one is allowed */ -/**** j->jtype != aOptBlk && ****/ /* pretty sure this one is allowed */ /* MR11 not any more ! */ - j->jtype != EndBlk) { - errFL("A context guard may not contain an option block: {...} or looping block: (...)* or (...)+", - FileStr[p->file],p->line); - contextGuardOK(j->p1,h,hmax); - return 0; - }; - /* do both p1 and p2 so use | rather than || */ - return contextGuardOK(j->p2,h,hmax) | contextGuardOK(j->p1,h,hmax); - }; -Fail: - errFL("A context guard may contain only Token references - guard will be ignored", - FileStr[p->file],p->line); - contextGuardOK( ( (ActionNode *) p)->next,h,hmax); - return 0; -} - -/* - * Look at a (...)? generalized-predicate context-guard and compute - * either a lookahead set (k==1) or a lookahead tree for k>1. The - * k level is determined by the guard itself rather than the LL_k - * variable. For example, ( A B )? is an LL(2) guard and ( ID )? - * is an LL(1) guard. For the moment, you can only have a single - * tuple in the guard. Physically, the block must look like this - * --o-->TOKEN-->o-->o-->TOKEN-->o-- ... -->o-->TOKEN-->o-- - * An error is printed for any other type. - */ -Predicate * -#ifdef __USE_PROTOS -computePredFromContextGuard(Graph blk,int *msgDone) /* MR10 */ -#else -computePredFromContextGuard(blk,msgDone) /* MR10 */ - Graph blk; - int *msgDone; /* MR10 */ -#endif -{ - Junction *junc = (Junction *)blk.left, *p; - Tree *t=NULL; - Predicate *pred = NULL; - set scontext, rk; - int ok; - int hmax=0; - - require(junc!=NULL && junc->ntype == nJunction, "bad context guard"); - -/* MR10 Check for anything other than Tokens and generic junctions */ - - *msgDone=0; /* MR10 */ - ok=contextGuardOK( (Node *)junc,0,&hmax); /* MR10 */ - if (! ok) { /* MR10 */ - *msgDone=1; /* MR10 */ - return NULL; /* MR10 */ - }; /* MR10 */ - if (hmax == 0) { -errFL("guard is 0 tokens long",FileStr[junc->file],junc->line); /* MR11 */ - *msgDone=1; - return NULL; - }; - if (hmax > CLL_k) { /* MR10 */ -errFL(eMsgd2("guard is %d tokens long - lookahead is limited to max(k,ck)==%d", /* MR10 */ - hmax,CLL_k), /* MR10 */ - FileStr[junc->file],junc->line); /* MR10 */ - *msgDone=1; /* MR10 */ - return NULL; /* MR10 */ - }; /* MR10 */ - - rk = empty; - p = junc; - pred = new_pred(); - pred->k = hmax; /* MR10 should be CLL_k, not LLK ? */ - if (hmax > 1 ) /* MR10 was LL_k */ - { - ConstrainSearch = 0; - ContextGuardTRAV = 1; - TRAV(p, hmax, &rk, t); /* MR10 was LL_k */ - ContextGuardTRAV = 0; - set_free(rk); - t = tshrink( t ); - t = tflatten( t ); - t = tleft_factor( t ); -/* - fprintf(stderr, "ctx guard:"); - preorder(t); - fprintf(stderr, "\n"); -*/ - pred->tcontext = t; - } - else - { - REACH(p, 1, &rk, scontext); - require(set_nil(rk), "rk != nil"); - set_free(rk); -/* - fprintf(stderr, "LL(1) ctx guard is:"); - s_fprT(stderr, scontext); - fprintf(stderr, "\n"); -*/ - pred->scontext[1] = scontext; - } - - list_add(&ContextGuardPredicateList,pred); /* MR13 */ - - return pred; -} - -/* MR13 - When the context guard is originally computed the - meta-tokens are not known. -*/ - -#ifdef __USE_PROTOS -void recomputeContextGuard(Predicate *pred) -#else -void recomputeContextGuard(pred) - Predicate *pred; -#endif -{ - Tree * t=NULL; - set scontext; - set rk; - ActionNode * actionNode; - Junction * p; - - actionNode=pred->source; - require (actionNode != NULL,"context predicate's source == NULL"); - - p=actionNode->guardNodes; - require (p != NULL,"context predicate's guardNodes == NULL"); - - rk = empty; - if (pred->k > 1 ) - { - ConstrainSearch = 0; - ContextGuardTRAV = 1; - TRAV(p, pred->k, &rk, t); - ContextGuardTRAV = 0; - set_free(rk); - t = tshrink( t ); - t = tflatten( t ); - t = tleft_factor( t ); - Tfree(pred->tcontext); - pred->tcontext = t; - } - else - { - REACH(p, 1, &rk, scontext); - require(set_nil(rk), "rk != nil"); - set_free(rk); - set_free(pred->scontext[1]); - pred->scontext[1] = scontext; - } -} - -/* MR11 - had enough of flags yet ? */ - -int MR_AmbSourceSearch=0; -int MR_AmbSourceSearchGroup=0; -int MR_AmbSourceSearchChoice=0; -int MR_AmbSourceSearchLimit=0; -int MR_matched_AmbAidRule=0; - -static set *matchSets[2]={NULL,NULL}; -static int *tokensInChain=NULL; -static Junction *MR_AmbSourceSearchJ[2]; - -void MR_traceAmbSourceKclient() -{ - int i; - set *save_fset; - int save_ConstrainSearch; - set incomplete; - Tree *t; - - if (matchSets[0] == NULL) { - matchSets[0]=(set *) calloc (CLL_k+1,sizeof(set)); - require (matchSets[0] != NULL,"matchSets[0] alloc"); - matchSets[1]=(set *) calloc (CLL_k+1,sizeof(set)); - require (matchSets[1] != NULL,"matchSets[1] alloc"); - }; - - for (i=1 ; i <= MR_AmbSourceSearchLimit ; i++) { - set_clr(matchSets[0][i]); - set_orel( (unsigned) tokensInChain[i], - &matchSets[0][i]); - set_clr(matchSets[1][i]); - set_orel( (unsigned) tokensInChain[i], - &matchSets[1][i]); - }; - - save_fset=fset; - save_ConstrainSearch=ConstrainSearch; - - - - for (i=0 ; i < 2 ; i++) { - -#if 0 -** fprintf(stdout," Choice:%d Depth:%d ",i+1,MR_AmbSourceSearchLimit); -** fprintf(stdout,"("); -** for (j=1 ; j <= MR_AmbSourceSearchLimit ; j++) { -** if (j != 1) fprintf(stdout," "); -** fprintf(stdout,"%s",TerminalString(tokensInChain[j])); -** }; -** fprintf(stdout,")\n\n"); -#endif - - fset=matchSets[i]; - - MR_AmbSourceSearch=1; - MR_MaintainBackTrace=1; - MR_AmbSourceSearchChoice=i; - ConstrainSearch=1; - - maxk = MR_AmbSourceSearchLimit; - - incomplete=empty; - t=NULL; - - constrain = &(fset[1]); - MR_pointerStackReset(&MR_BackTraceStack); - - TRAV(MR_AmbSourceSearchJ[i],maxk,&incomplete,t); - - Tfree(t); - - require (set_nil(incomplete),"MR_traceAmbSourceK TRAV incomplete"); - require (MR_BackTraceStack.count == 0,"K: MR_BackTraceStack.count != 0"); - - set_free(incomplete); - }; - - ConstrainSearch=save_ConstrainSearch; - fset=save_fset; - MR_AmbSourceSearch=0; - MR_MaintainBackTrace=0; - MR_AmbSourceSearchChoice=0; -} - -#ifdef __USE_PROTOS -Tree *tTrunc(Tree *t,int depth) -#else -Tree *tTrunc(t,depth) - Tree *t; -#endif -{ - Tree *u; - - require ( ! (t == NULL && depth > 0),"tree too short"); - - if (depth == 0) return NULL; - - if (t->token == ALT) { - u=tTrunc(t->down,depth); - } else { - u=tnode(t->token); - u->down=tTrunc(t->down,depth-1); - }; - if (t->right != NULL) u->right=tTrunc(t->right,depth); - return u; -} - -#ifdef __USE_PROTOS -void MR_iterateOverTree(Tree *t,int chain[]) -#else -void MR_iterateOverTree(t,chain) - Tree *t; - int chain[]; -#endif -{ - if (t == NULL) return; - chain[0]=t->token; - if (t->down != NULL) { - MR_iterateOverTree(t->down,&chain[1]); - } else { - MR_traceAmbSourceKclient(); - }; - MR_iterateOverTree(t->right,&chain[0]); - chain[0]=0; -} - -#ifdef __USE_PROTOS -void MR_traceAmbSourceK(Tree *t,Junction *alt1,Junction *alt2) -#else -void MR_traceAmbSourceK(t,alt1,alt2) - Tree *t; - Junction *alt1; - Junction *alt2; -#endif -{ - int i; - int depth; - int maxDepth; - Tree *truncatedTree; - - if (MR_AmbAidRule == NULL) return; - - if ( ! ( - strcmp(MR_AmbAidRule,alt1->rname) == 0 || - strcmp(MR_AmbAidRule,alt2->rname) == 0 || - MR_AmbAidLine==alt1->line || - MR_AmbAidLine==alt2->line - ) - ) return; - - MR_matched_AmbAidRule++; - - /* there are no token sets in trees, only in TokNodes */ - - MR_AmbSourceSearchJ[0]=analysis_point( (Junction *) alt1->p1); - MR_AmbSourceSearchJ[1]=analysis_point( (Junction *) alt2->p1); - - if (tokensInChain == NULL) { - tokensInChain=(int *) calloc (CLL_k+1,sizeof(int)); - require (tokensInChain != NULL,"tokensInChain alloc"); - }; - - MR_AmbSourceSearchGroup=0; - - fprintf(stdout,"\n"); - fprintf(stdout," Ambiguity Aid "); - fprintf(stdout, - (MR_AmbAidDepth <= LL_k ? - "(-k %d -aa %s %s -aad %d)\n\n" : - "(-k %d -aa %s %s [-k value limits -aad %d])\n\n"), - LL_k, - MR_AmbAidRule, - (MR_AmbAidMultiple ? "-aam" : ""), - MR_AmbAidDepth); - - for (i=0 ; i < 2 ; i++) { - fprintf(stdout," Choice %d: %-25s line %d file %s\n", - (i+1), - MR_ruleNamePlusOffset( (Node *) MR_AmbSourceSearchJ[i]), - MR_AmbSourceSearchJ[i]->line, - FileStr[MR_AmbSourceSearchJ[i]->file]); - }; - - fprintf(stdout,"\n"); - - if (MR_AmbAidDepth < LL_k) { - maxDepth=MR_AmbAidDepth; - } else { - maxDepth=LL_k; - }; - - for (depth=1 ; depth <= maxDepth; depth++) { - MR_AmbSourceSearchLimit=depth; - if (depth < LL_k) { - truncatedTree=tTrunc(t,depth); - truncatedTree=tleft_factor(truncatedTree); - MR_iterateOverTree(truncatedTree,&tokensInChain[1]); /* <===== */ - Tfree(truncatedTree); - } else { - MR_iterateOverTree(t,tokensInChain); /* <===== */ - }; - fflush(stdout); - fflush(stderr); - }; - - fprintf(stdout,"\n"); - MR_AmbSourceSearch=0; - MR_MaintainBackTrace=0; - MR_AmbSourceSearchGroup=0; - MR_AmbSourceSearchChoice=0; - MR_AmbSourceSearchLimit=0; - -} - - -/* this if for k=1 grammars only - - this is approximate only because of the limitations of linear - approximation lookahead. Don't want to do a k=3 search when - the user only specified a ck=3 grammar -*/ - -#ifdef __USE_PROTOS -void MR_traceAmbSource(set *matchSets,Junction *alt1, Junction *alt2) -#else -void MR_traceAmbSource(matchSets,alt1,alt2) - set *matchSets; - Junction *alt1; - Junction *alt2; -#endif -{ - set *save_fset; - Junction *p[2]; - int i; - int j; - set *dup_matchSets; - set intersection; - set incomplete; - set tokensUsed; - int depth; - - if (MR_AmbAidRule == NULL) return; - if ( ! ( - strcmp(MR_AmbAidRule,alt1->rname) == 0 || - strcmp(MR_AmbAidRule,alt2->rname) == 0 || - MR_AmbAidLine==alt1->line || - MR_AmbAidLine==alt2->line - ) - ) return; - - MR_matched_AmbAidRule++; - - save_fset=fset; - - dup_matchSets=(set *) calloc(CLL_k+1,sizeof(set)); - require (dup_matchSets != NULL,"Can't allocate dup_matchSets"); - - p[0]=analysis_point( (Junction *) alt1->p1); - p[1]=analysis_point( (Junction *) alt2->p1); - - fprintf(stdout,"\n"); - - fprintf(stdout," Ambiguity Aid "); - fprintf(stdout, - (MR_AmbAidDepth <= CLL_k ? - "(-ck %d -aa %s %s -aad %d)\n\n" : - "(-ck %d -aa %s %s [-ck value limits -aad %d])\n\n"), - CLL_k, - MR_AmbAidRule, - (MR_AmbAidMultiple ? "-aam" : ""), - MR_AmbAidDepth); - - for (i=0 ; i < 2 ; i++) { - fprintf(stdout," Choice %d: %-25s line %d file %s\n", - (i+1), - MR_ruleNamePlusOffset( (Node *) p[i]), - p[i]->line,FileStr[p[i]->file]); - }; - - for (j=1; j <= CLL_k ; j++) { - fprintf(stdout,"\n Intersection of lookahead[%d] sets:\n",j); - intersection=set_and(alt1->fset[j],alt2->fset[j]); - MR_dumpTokenSet(stdout,2,intersection); - set_free(intersection); - }; - - fprintf(stdout,"\n"); - - require (1 <= MR_AmbAidDepth && MR_AmbAidDepth <= CLL_k, - "illegal MR_AmbAidDepth"); - - MR_AmbSourceSearchGroup=0; - for (depth=1; depth <= MR_AmbAidDepth; depth++) { - MR_AmbSourceSearchLimit=depth; - for (i=0 ; i < 2 ; i++) { - -/*** fprintf(stdout," Choice:%d Depth:%d\n\n",i+1,depth); ***/ - - for (j=0 ; j <= CLL_k ; j++) { dup_matchSets[j]=set_dup(matchSets[j]); }; - fset=dup_matchSets; - - fflush(output); - fflush(stdout); - - MR_AmbSourceSearch=1; - MR_MaintainBackTrace=1; - MR_AmbSourceSearchChoice=i; - - maxk = depth; - tokensUsed=empty; - incomplete=empty; - - constrain = &(fset[1]); - MR_pointerStackReset(&MR_BackTraceStack); - - REACH(p[i],depth,&incomplete,tokensUsed); - - fflush(output); - fflush(stdout); - - require (set_nil(incomplete),"MR_traceAmbSource REACH incomplete"); - require (MR_BackTraceStack.count == 0,"1: MR_BackTraceStack.count != 0"); - - set_free(incomplete); - set_free(tokensUsed); - - for (j=0 ; j <= CLL_k ; j++) { set_free(dup_matchSets[j]); }; - }; - }; - - fprintf(stdout,"\n"); - - MR_AmbSourceSearch=0; - MR_MaintainBackTrace=0; - MR_AmbSourceSearchGroup=0; - MR_AmbSourceSearchChoice=0; - MR_AmbSourceSearchLimit=0; - - fset=save_fset; - free ( (char *) dup_matchSets); -} - -static int itemCount; - -void MR_backTraceDumpItemReset() { - itemCount=0; -} - -#ifdef __USE_PROTOS -void MR_backTraceDumpItem(FILE *f,int skip,Node *n) -#else -void MR_backTraceDumpItem(f,skip,n) - FILE *f; - int skip; - Node *n; -#endif -{ - TokNode *tn; - RuleRefNode *rrn; - Junction *j; - ActionNode *a; - - switch (n->ntype) { - case nToken: - itemCount++; if (skip) goto EXIT; - tn=(TokNode *)n; - if (set_nil(tn->tset)) { - fprintf(f," %2d #token %-23s",itemCount,TerminalString(tn->token)); - } else { - fprintf(f," %2d #tokclass %-20s",itemCount,TerminalString(tn->token)); - }; - break; - case nRuleRef: - itemCount++; if (skip) goto EXIT; - rrn=(RuleRefNode *)n; - fprintf(f," %2d to %-27s",itemCount,rrn->text); - break; - case nAction: - a=(ActionNode *)n; - goto EXIT; - case nJunction: - - j=(Junction *)n; - - switch (j->jtype) { - case aSubBlk: - if (j->guess) { - itemCount++; if (skip) goto EXIT; - fprintf(f," %2d %-30s",itemCount,"in (...)? block at"); - break; - }; -/****** fprintf(f," %2d %-32s",itemCount,"in (...) block at"); *******/ -/****** break; *******/ - goto EXIT; - case aOptBlk: - itemCount++; if (skip) goto EXIT; - fprintf(f," %2d %-30s",itemCount,"in {...} block"); - break; - case aLoopBlk: - itemCount++; if (skip) goto EXIT; - fprintf(f," %2d %-30s",itemCount,"in (...)* block"); - break; - case EndBlk: - if (j->alpha_beta_guess_end) { - itemCount++; if (skip) goto EXIT; - fprintf(f," %2d %-30s",itemCount,"end (...)? block at"); - break; - }; - goto EXIT; -/****** fprintf(f," %2d %-32s",itemCount,"end of a block at"); *****/ -/****** break; *****/ - case RuleBlk: - itemCount++; if (skip) goto EXIT; - fprintf(f," %2d %-30s",itemCount,j->rname); - break; - case Generic: - goto EXIT; - case EndRule: - itemCount++; if (skip) goto EXIT; - fprintf (f," %2d end %-26s",itemCount,j->rname); - break; - case aPlusBlk: - itemCount++; if (skip) goto EXIT; - fprintf(f," %2d %-30s",itemCount,"in (...)+ block"); - break; - case aLoopBegin: - goto EXIT; - }; - break; - }; - fprintf(f," %-23s line %-4d %s\n",MR_ruleNamePlusOffset(n),n->line,FileStr[n->file]); -EXIT: - return; -} - - -static PointerStack previousBackTrace={0,0,NULL}; - -#ifdef __USE_PROTOS -void MR_backTraceReport(void) -#else -void MR_backTraceReport() -#endif -{ - int i; - int match = 0; - int limitMatch; - - Node *p; - TokNode *tn; - set remainder; - int depth; - - /* Even when doing a k=2 search this routine can get - called when there is only 1 token on the stack. - This is because something like rRuleRef can change - the search value of k from 2 to 1 temporarily. - It does this because the it wants to know the k=1 - first set before it does a k=2 search - */ - - depth=0; - for (i=0; i < MR_BackTraceStack.count ; i++) { - p=(Node *) MR_BackTraceStack.data[i]; - if (p->ntype == nToken) depth++; - }; - -/* MR14 */ if (MR_AmbSourceSearch) { -/* MR14 */ require (depth <= MR_AmbSourceSearchLimit,"depth > MR_AmbSourceSearchLimit"); -/* MR14 */ } - - /* MR23 THM - Traceback report was being called at the wrong time for -alpha reports */ - /* Reported by Arpad Beszedes (beszedes@inf.u-szeged.hu) */ - - if (MR_AmbSourceSearchLimit == 0 || depth < MR_AmbSourceSearchLimit) { - return; - }; - - MR_backTraceDumpItemReset(); - - limitMatch=MR_BackTraceStack.count; - if (limitMatch > previousBackTrace.count) { - limitMatch=previousBackTrace.count; - }; - - for (match=0; match < limitMatch; match++) { - if (MR_BackTraceStack.data[match] != - previousBackTrace.data[match]) { - break; - }; - }; - - /* not sure at the moment why there would be duplicates */ - - if (match != MR_BackTraceStack.count) { - - fprintf(stdout," Choice:%d Depth:%d Group:%d", - (MR_AmbSourceSearchChoice+1), - MR_AmbSourceSearchLimit, - ++MR_AmbSourceSearchGroup); - - depth=0; - fprintf(stdout," ("); - for (i=0; i < MR_BackTraceStack.count ; i++) { - p=(Node *) MR_BackTraceStack.data[i]; - if (p->ntype != nToken) continue; - tn=(TokNode *)p; - if (depth != 0) fprintf(stdout," "); - fprintf(stdout,TerminalString(tn->token)); - depth++; - if (! MR_AmbAidMultiple) { - if (set_nil(tn->tset)) { - set_rm( (unsigned) tn->token,fset[depth]); - } else { - remainder=set_dif(fset[depth],tn->tset); - set_free(fset[depth]); - fset[depth]=remainder; - }; - }; - }; - fprintf(stdout,")\n"); - - for (i=0; i < MR_BackTraceStack.count ; i++) { - MR_backTraceDumpItem(stdout, (i -#include -#include -#include "pcctscfg.h" -#include "set.h" -#include "syn.h" -#include "hash.h" -#include "generic.h" -#include "dlgdef.h" - -#define NumExprPerLine 4 -static int on1line=0; -static set tokensRefdInBlock; - - /* T r a n s l a t i o n T a b l e s */ - -/* C_Trans[node type] == pointer to function that knows how to translate that node. */ -#ifdef __cplusplus -void (*C_Trans[NumNodeTypes+1])(...) = { - NULL, - NULL, /* See next table. -Junctions have many types */ - (void (*)(...)) genRuleRef, - (void (*)(...)) genToken, - (void (*)(...)) genAction - }; -#else -void (*C_Trans[NumNodeTypes+1])() = { - NULL, - NULL, /* See next table. -Junctions have many types */ - genRuleRef, - genToken, - genAction - }; -#endif - -/* C_JTrans[Junction type] == pointer to function that knows how to translate that - * kind of junction node. - */ -#ifdef __cplusplus -void (*C_JTrans[NumJuncTypes+1])(...) = { - NULL, - (void (*)(...)) genSubBlk, - (void (*)(...)) genOptBlk, - (void (*)(...)) genLoopBlk, - (void (*)(...)) genEndBlk, - (void (*)(...)) genRule, - (void (*)(...)) genJunction, - (void (*)(...)) genEndRule, - (void (*)(...)) genPlusBlk, - (void (*)(...)) genLoopBegin - }; -#else -void (*C_JTrans[NumJuncTypes+1])() = { - NULL, - genSubBlk, - genOptBlk, - genLoopBlk, - genEndBlk, - genRule, - genJunction, - genEndRule, - genPlusBlk, - genLoopBegin - }; -#endif - -#define PastWhiteSpace(s) while (*(s) == ' ' || *(s) == '\t') {s++;} - -static int tabs = 0; - -/* MR6 Got tired of text running off page when using standard tab stops */ - -#define TAB { int i; \ - if (TabWidth==0) { \ - for (i=0; irname);} - else gen1("zzTRACEOUT((ANTLRChar *)\"%s\");\n", q->rname); - } -} - -static void -#ifdef __USE_PROTOS -warn_about_using_gk_option(void) -#else -warn_about_using_gk_option() -#endif -{ - static int warned_already=0; - - if ( !DemandLookahead || warned_already ) return; - warned_already = 1; - warnNoFL("-gk option could cause trouble for <<...>>? predicates"); -} - -void -#ifdef __USE_PROTOS -freeBlkFsets( Junction *q ) -#else -freeBlkFsets( q ) -Junction *q; -#endif -{ - int i; - Junction *alt; - require(q!=NULL, "freeBlkFsets: invalid node"); - - for (alt=q; alt != NULL; alt= (Junction *) alt->p2 ) - { - for (i=1; i<=CLL_k; i++) set_free(alt->fset[i]); - } -} - -/* - * Generate a local variable allocation for each token references - * in this block. - */ -static void -#ifdef __USE_PROTOS -genTokenPointers( Junction *q ) -#else -genTokenPointers( q ) -Junction *q; -#endif -{ - /* Rule refs are counted and can be referenced, but their - * value is not set to anything useful ever. - * - * The ptrs are to be named _tij where i is the current level - * and j is the element number within an alternative. - */ - int first=1, t=0; - set a; - tokensRefdInBlock = q->tokrefs; - - if ( set_deg(q->tokrefs) == 0 ) return; - a = set_dup(q->tokrefs); - gen("ANTLRTokenPtr "); - for (; !set_nil(a); set_rm(t, a)) - { - t = set_int(a); - if ( first ) first = 0; - else _gen(","); - if ( !DontCopyTokens ) _gen2("_tv%d%d,", BlkLevel, t); - _gen2("_t%d%d", BlkLevel, t); - if ( !DontCopyTokens ) {_gen2("= &_tv%d%d", BlkLevel, t);} - else _gen("=NULL"); - } - _gen(";\n"); - set_free(a); -} - -static int -#ifdef __USE_PROTOS -hasDefaultException(ExceptionGroup *eg) -#else -hasDefaultException(eg) -ExceptionGroup *eg; -#endif -{ - ListNode *q; - - for (q = eg->handlers->next; q!=NULL; q=q->next) - { - ExceptionHandler *eh = (ExceptionHandler *)q->elem; - if ( strcmp("default", eh->signalname)==0 ) { - return 1; - } - } - return 0; -} -static void -#ifdef __USE_PROTOS -dumpException(ExceptionGroup *eg, int no_default_case) -#else -dumpException(eg, no_default_case) -ExceptionGroup *eg; -int no_default_case; -#endif -{ - char *outerLabel; /* MR7 */ - int altHandler=0; /* MR7 */ - int namedHandler=0; /* MR7 */ - - outerLabel=findOuterHandlerLabel(eg); /* MR7 */ - - if (eg->label != NULL) { /* MR7 */ - namedHandler=1; /* MR7 */ - } else if (eg->forRule) { /* MR7 */ - /* nothing */ /* MR20 */ - } else { /* MR7 */ - altHandler=1; /* MR7 */ - }; /* MR7 */ - -#if 0 -** if (! eg->used) { /* MR7 */ -** warnFL("exception group never used", /* MR7 */ -** FileStr[eg->altstart->file],eg->altstart->line); /* MR7 */ -** }; /* MR7 */ -#endif - - if (namedHandler) { /* MR7 */ - gen1("switch ( _signal ) { /* [%s] */\n",eg->label); /* MR7 */ - } else { /* MR7 */ - gen("switch ( _signal ) {\n"); /* MR7 */ - gen("case NoSignal: break; /* MR7 */\n"); /* MR7 */ - }; /* MR7 */ - { - ListNode *q; - for (q = eg->handlers->next; q!=NULL; q=q->next) - { - ExceptionHandler *eh = (ExceptionHandler *)q->elem; - if ( strcmp("default", eh->signalname)==0 ) { - gen("default :\n"); - tabs++; - dumpAction(eh->action, output, tabs, -1, 1, 1); - gen("_signal=NoSignal; /* MR7 */\n"); /* MR7 */ - gen("break; /* MR7 */\n"); /* MR7 */ - tabs--; - gen("}\n"); - - /* copied from later code in dumpException */ /* MR7 */ - - if (namedHandler) { /* MR7 */ - gen("if (_signal != NoSignal)"); /* MR7 */ - _gen1(" goto %s_handler; /* MR7 */\n",outerLabel);/* MR7 */ - } else if (altHandler) { /* MR7 */ - gen1("goto %s_handler; /* MR7 */\n",outerLabel); /* MR7 */ - }; - return; - } - gen1("case %s :\n", eh->signalname); - tabs++; - if ( eh->action != NULL ) - { - dumpAction(eh->action, output, tabs, -1, 1, 1); - gen("break; /* MR7 */\n"); /* MR7 */ - } - tabs--; - } - } - if ( no_default_case ) return; - - gen("default :\n"); - tabs++; /* MR7 */ - gen("break; /* MR7 */\n"); /* MR7 */ - tabs--; /* MR7 */ - - tabs++; -/***** gen("*_retsignal = _signal;\n"); *****/ - - tabs--; - gen("}\n"); - - if (namedHandler) { /* MR7 */ - gen("if (_signal != NoSignal)"); /* MR7 */ - _gen1(" goto %s_handler; /* MR7 */\n",outerLabel); /* MR7 */ - } else if (altHandler) { /* MR7 */ - gen1("goto %s_handler; /* MR7 */\n",outerLabel); /* MR7 */ - }; - -} - -static void -#ifdef __USE_PROTOS -dumpExceptions(ListNode *list) -#else -dumpExceptions(list) -ListNode *list; -#endif -{ - ListNode *p; - - for (p = list->next; p!=NULL; p=p->next) - { - ExceptionGroup *eg = (ExceptionGroup *) p->elem; - _gen2("%s%s_handler:\n", - eg->label==NULL?"":eg->label, - eg->altID==NULL?"":eg->altID); - if ( eg->altID!=NULL ) dumpException(eg, 0); - else { - /* This must be the rule exception handler */ - dumpException(eg, 1); - if ( !hasDefaultException(eg) ) - { - gen("default :\n"); - tabs++; - gen("zzdflthandlers(_signal,_retsignal);\n"); - tabs--; - gen("}\n"); - } - } - } -} - -/* For each element label that is found in a rule, generate a unique - * Attribute (and AST pointer if GenAST) variable. - */ -void -#ifdef __USE_PROTOS -genElementLabels(ListNode *list) -#else -genElementLabels(list) -ListNode *list; -#endif -{ - int first=1; - ListNode *p; - - if ( GenCC ) {gen("ANTLRTokenPtr");} - else {gen("Attrib");} - for (p = list->next; p!=NULL; p=p->next) - { - char *ep = (char *)p->elem; - if ( first ) first = 0; - else _gen(","); - if ( GenCC ) {_gen1(" %s=NULL",ep);} - else {_gen1(" %s",ep);} - } - _gen(";\n"); - - if ( !GenAST ) return; - - first = 1; - gen("AST"); - for (p = list->next; p!=NULL; p=p->next) - { - char *ep = (char *)p->elem; - if ( first ) first = 0; - else _gen(","); - _gen1(" *%s_ast=NULL",ep); - } - _gen(";\n"); -} - -/* - * Generate a local variable allocation for each token or rule reference - * in this block. - */ -static void -#ifdef __USE_PROTOS -genASTPointers( Junction *q ) -#else -genASTPointers( q ) -Junction *q; -#endif -{ - int first=1, t; - set a; - - a = set_or(q->tokrefs, q->rulerefs); - if ( set_deg(a) > 0 ) - { - gen("AST "); - for (; !set_nil(a); set_rm(t, a)) - { - t = set_int(a); - if ( first ) first = 0; - else _gen(","); - _gen2("*_ast%d%d=NULL", BlkLevel, t); - } - set_free(a); - } - _gen(";\n"); -} - -static void -#ifdef __USE_PROTOS -BLOCK_Head( void ) -#else -BLOCK_Head( ) -#endif -{ - gen("{\n"); - tabs++; - if ( !GenCC ) gen1("zzBLOCK(zztasp%d);\n", BlkLevel); -} - -static void -#ifdef __USE_PROTOS -BLOCK_Tail( void ) -#else -BLOCK_Tail( ) -#endif -{ - if ( !GenCC ) gen1("zzEXIT(zztasp%d);\n", BlkLevel); - if ( !GenCC ) gen("}\n"); - tabs--; - gen("}\n"); -} - -static void -#ifdef __USE_PROTOS -BLOCK_Preamble( Junction *q ) -#else -BLOCK_Preamble( q ) -Junction *q; -#endif -{ - ActionNode *a; - Junction *begin; - - BLOCK_Head(); - if ( GenCC ) genTokenPointers(q); - if ( GenCC&&GenAST ) genASTPointers(q); - if ( q->jtype == aPlusBlk ) gen("int zzcnt=1;\n"); - if ( q->parm != NULL && !q->predparm ) gen1("zzaPush(%s);\n", q->parm) - else if ( !GenCC ) gen("zzMake0;\n"); - if ( !GenCC ) gen("{\n"); - if ( q->jtype == aLoopBegin ) begin = (Junction *) ((Junction *)q->p1); - else begin = q; - if ( has_guess_block_as_first_item(begin) ) - { - gen("zzGUESS_BLOCK\n"); - } - if ( q->jtype == aLoopBegin ) - a = findImmedAction( ((Junction *)q->p1)->p1 ); /* look at aLoopBlk */ - else - a = findImmedAction( q->p1 ); - if ( a!=NULL && !a->is_predicate) { -/* MR21 */ if (!a->noHoist) dumpActionPlus(a, a->action, output, tabs, a->file, a->line, 1); - a->done = 1; /* remove action. We have already handled it */ - } -} - -void -#ifdef __USE_PROTOS -genCombinedPredTreeContextOrig( Predicate *p ) -#else -genCombinedPredTreeContextOrig( p ) -Predicate *p; -#endif -{ - static set *ctx=NULL; /* genExprSets() is destructive, make copy*/ - require(p!=NULL, "can't make context tree for NULL pred tree"); - -#ifdef DBG_PRED - fprintf(stderr, "enter genCombinedPredTreeContextOrig(%s,0x%x) with sets:\n", p->expr, p); - s_fprT(stderr, p->scontext[1]); - fprintf(stderr, "\n"); -#endif - if ( p->down == NULL ) - { -/*** if ( p->k>1 && p->tcontext!=NULL ) ***/ - if ( p->tcontext!=NULL ) - { - _gen("("); - genExprTree(p->tcontext, 1); - _gen(")"); - } -/*** else if ( p->k==1 && set_deg(p->scontext[1])>0 ) ***/ - else if ( set_deg(p->scontext[1])>0 ) - { - if ( ctx==NULL ) ctx = (set *)calloc(CLL_k+1, sizeof(set)); - require(ctx!=NULL, "ctx cannot allocate"); - ctx[0]=empty; - ctx[1]=set_dup(p->scontext[1]); - _gen("("); - genExprSets(&(ctx[0]), p->k); - _gen(")"); - set_free(ctx[1]); - } - else if ( p->expr==PRED_AND_LIST || p->expr==PRED_OR_LIST ) { - fatal_internal("pred tree is orphan OR or AND list"); - } - else { - if (! HoistPredicateContext) { - _gen(" 1 /* no context: prc is off */ "); - } else { - fatal_internal("pred tree context is empty"); - }; - } - return; - } - -/* MR10 - make AND just like OR */ - - if ( p->expr == PRED_AND_LIST ) - { - Predicate *list = p->down; - for (; list!=NULL; list=list->right) - { - genCombinedPredTreeContextOrig(list); - if ( list->right!=NULL ) _gen("|| /* MR10 was wrong */ "); - }; - return; - } - - if ( p->expr == PRED_OR_LIST ) - { - Predicate *list = p->down; - for (; list!=NULL; list=list->right) - { - genCombinedPredTreeContextOrig(list); - if ( list->right!=NULL ) _gen("||"); - }; - return; - }; - - fatal("pred tree is really wacked"); -} - -/* [genCombinedPredTreeContext] */ - -void -#ifdef __USE_PROTOS -genCombinedPredTreeContext( Predicate *p ) -#else -genCombinedPredTreeContext( p ) -Predicate *p; -#endif -{ - Tree *t; - int predDepth=0; - - if (0 && ! MR_usingPredNames && ! MRhoisting) { - genCombinedPredTreeContextOrig(p); - } else { -/* MR13 */ MR_pred_depth(p,&predDepth); -/* MR13 */ if (predDepth == 1) { -/* MR13 */ -/* MR13 */ set scontext[2]; -/* MR13 */ scontext[0]=empty; -/* MR13 */ scontext[1]=MR_compute_pred_set(p); -/* MR13 */ if (set_nil(scontext[1])) { -/* MR13 */ _gen(" 1 /* MR12 no context (-prc off) */ "); -/* MR13 */ } else { -/* MR13 */ _gen("("); -/* MR13 */ genExprSets(&scontext[0], 1); -/* MR13 */ set_free(scontext[1]); -/* MR13 */ _gen(")"); -/* MR13 */ }; - - } else { - t=MR_compute_pred_tree_context(p); - if (t == NULL) { - _gen(" 1 /* MR12 no context (-prc off) */ "); - } else { - _gen("("); - genExprTree(t, 1); - Tfree(t); /* MR10 */ - _gen(")"); - }; - }; - }; -} - -/* [genPredTreeGate] */ - -void -#ifdef __USE_PROTOS -genPredTreeGate( Predicate *p, int in_and_expr ) -#else -genPredTreeGate( p, in_and_expr ) -Predicate *p; -int in_and_expr; -#endif -{ - if ( in_and_expr ) - { - _gen("!("); - genCombinedPredTreeContext(p); - _gen(")||"); - if ( p->down!=NULL ) _gen("\n"); - } - else - { - _gen("("); - genCombinedPredTreeContext(p); - _gen(")&&"); - if ( p->down!=NULL ) _gen("\n"); - } -} - -#ifdef __USE_PROTOS -void genPredEntry(Predicate *p,int outer) -#else -void genPredEntry(p,outer) - Predicate *p; - int outer; -#endif -{ - int inverted=0; - Predicate *q; - int localOuter=outer; - int needRP=0; - - if (p == NULL) return; - - if (p->predEntry != NULL && p->predEntry->predLiteral != NULL) { - if (p->inverted != p->predEntry->pred->inverted) { - _gen("! /* inverted pred */ ("); - needRP=1; - } else { - if (!localOuter) _gen("("); - needRP=1; - }; - dumpAction(p->predEntry->predLiteral,output,0,p->source->file,p->source->line,0); - if (needRP) _gen(")"); - return; - }; - - inverted=p->inverted; - - if (inverted) { - _gen(" ! /* inverted pred */ ("); - localOuter=1; - }; - - if (p->expr == PRED_OR_LIST) { - if (!localOuter) _gen("("); - for (q=p->down; q != NULL ; q=q->right) { - genPredEntry(q,0); - if (q->right != NULL) _gen(" || "); - }; - if (!localOuter) _gen(")"); - } else if (p->expr == PRED_AND_LIST) { - if (!localOuter) _gen("("); - for (q=p->down; q != NULL ; q=q->right) { - genPredEntry(q,0); - if (q->right != NULL) _gen(" && "); - }; - if (!localOuter) _gen(")"); - } else { - if (!localOuter) _gen("("); - require (p->source != NULL,"predEntry->source == NULL"); - require (p->source->inverted == 0,"dumpPredEntry p->source->inverted != 0"); - dumpAction(p->source->action,output,0,p->source->file,p->source->line,0); - if (!localOuter) _gen(")"); - }; - - if (inverted) { - _gen(")"); - } -} - -void -#ifdef __USE_PROTOS -dumpPredAction(ActionNode *anode, - char *s,FILE *output,int tabs,int file,int line,int final_newline) -#else -dumpPredAction(anode, - s,output,tabs,file,line,final_newline) - - ActionNode *anode; - char *s; - FILE *output; - int tabs; - int file; - int line; - int final_newline; -#endif -{ - PredEntry *predEntry=anode->predEntry; - int inverted=anode->inverted; - Predicate *workPred; - - if (predEntry == NULL) { - - /* inline predicate literal */ - - require(inverted == 0,"dumpPredAction action->inverted"); - dumpAction(s,output,tabs,file,line,final_newline); - - } else { - - /* a reference to a predicate - possibly with an inverted source */ - - if (predEntry->predLiteral != NULL) { - if (inverted) _gen("! /* inverted pred */ ("); - dumpAction(predEntry->predLiteral,output,0,anode->file,anode->line,0); - if (inverted) _gen(")"); - } else { - workPred=predicate_dup(predEntry->pred); - if (inverted) workPred->inverted=!workPred->inverted; - genPredEntry(workPred,1); - predicate_free(workPred); - }; - }; -} - -/* [genPred] */ - -void -#ifdef __USE_PROTOS -genPred(Predicate *p, Node *j,int suppress_sva) -#else -genPred(p,j,suppress_sva) - Predicate *p; - Node *j; - int suppress_sva; -#endif -{ - if ( FoundException && !suppress_sva) {_gen("(_sva=(");} /* MR11 suppress_sva */ - else {_gen("(");} - if ( GenLineInfo && j->file != -1 ) _gen("\n"); - if (p->source != NULL && p->source->ampersandPred != NULL) { - if (p->source->ampersandPred->k == 1) { - - set ctx[2]; - - ctx[0]=empty; - ctx[1]=set_dup(p->source->ampersandPred->scontext[1]); - - _gen("("); - genExprSets(&(ctx[0]), p->k); - _gen(") && "); - set_free(ctx[1]); - } else { - _gen("( "); - genExprTree(p->source->ampersandPred->tcontext,1); - _gen(" ) && "); - }; - }; - - dumpPredAction((ActionNode *)p->source, - p->expr, output, 0, -1 /*indicates no line info*/, j->line, 0); - - if ( FoundException && !suppress_sva) /* MR11 suppress_sva */ - {_gen("),_sva)");} /* MR10 - get red of "meant ==" messages */ - else {_gen(")");} -} - -void -#ifdef __USE_PROTOS -MR_distinctORcontextOpt(Predicate *p,Node *j,int in_and_expr) -#else -MR_distinctORcontextOpt(p,j,in_and_expr) - Predicate *p; - Node *j; - int in_and_expr; -#endif -{ - Predicate *q; - - _gen(" /* MR10 Distinct OR context optimization */ \n"); - - if (in_and_expr) { - gen("zzpf=0,\n"); - for (q=p->down; q != NULL; q=q->right) { - gen("( "); - genCombinedPredTreeContext(q); - _gen(" && (zzpf=1, "); - genPred(q,j,0); - _gen(" )) ||\n"); - }; - gen("!zzpf)"); - } else { - require (0, - "MR_distinctORcontextOpt: can't get here when using MR_predSimplify"); -#if 0 -** for (q=p->down; q != NULL; q=q->right) { -** gen("( "); -** genCombinedPredTreeContext(q); -** _gen(" && "); -** genPred(q,j); -** if (q->right != NULL) { -** _gen(" ) ||\n"); -** }; -** }; -** gen(")"); -#endif - }; -} - -void -#ifdef __USE_PROTOS -genPredTreeOrig( Predicate *p, Node *j, int in_and_expr ) -#else -genPredTreeOrig( p, j, in_and_expr ) -Predicate *p; -Node *j; -int in_and_expr; -#endif -{ - -/* MR10 */ int allHaveContext=1; -/* MR10 */ int noneHaveContext=1; - -/* MR10 */ MR_predContextPresent(p,&allHaveContext,&noneHaveContext); - - if ( ! noneHaveContext ) /* MR10 context guards ignored when -prc off */ - { - _gen("("); - genPredTreeGate(p, in_and_expr); - } - - /* if leaf node, just gen predicate */ - - if ( p->down==NULL ) - { - genPred(p,j,0); - if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */ - return; - } - - /* if AND list, do both preds (only two possible) */ - if ( p->expr == PRED_AND_LIST ) - { -#if 0 -** _gen("("); -** genPredTreeOrig(p->down, j, 1); -** _gen("&&"); -** genPredTreeOrig(p->down->right, j, 1); -** _gen(")"); -** if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */ -** return; -#endif - /* MR11 - make it work with AND with more than two children - like OR */ - - Predicate *list; - _gen("("); - list = p->down; - for (; list!=NULL; list=list->right) - { - genPredTreeOrig(list, j, 1); - if ( list->right!=NULL ) _gen("&&"); - } - _gen(")"); - if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */ - return; - }; - - if ( p->expr == PRED_OR_LIST ) - { - Predicate *list; - _gen("("); - list = p->down; - for (; list!=NULL; list=list->right) - { - genPredTreeOrig(list, j, 0); - if ( list->right!=NULL ) _gen("||"); - } - _gen(")"); - if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */ - return; - } - - fatal_internal("genPredTreeOrig: predicate tree is wacked"); -} - -#if 0 -** Predicate member dummyPredDepth is no longer used in MR10 -** but we might need it again in the future -** -** if (MRhoisting) { -** if ( !noneHaveContext && -** ! in_and_expr && -** p->source != NULL && -** p->source->dummyPredicateDepth > 0 && -** p->down == NULL) { -** _gen("("); -** genCombinedPredTreeContext(p); -** _gen(" )\n"); -** return; -** }; -** }; -#endif - -/* [genPredTree] */ - -/* in_and_expr - - what to do if the context is wrong - what to do if the context is correct but the predicate is false - - remember: if the context is wrong it's the same as if the - predicate is true as far as enabling an alternative - - Consider (AND p q r) - - if in an ... && ... expression then you don't want - the entire predicate chain to fail just because the - context for one component is wrong: so return true - - Consider (OR p q r) - - if in an ... || ... expression then you don't want - the entire predicate chain to succeed just because - the context for one component is correct when the - corresponding test is false: so return false when - the context is correct but the test is false. -*/ - -void -#ifdef __USE_PROTOS -genPredTree( Predicate *p, Node *j, int in_and_expr, int suppress_sva ) -#else -genPredTree( p, j, in_and_expr, suppress_sva) - Predicate *p; - Node *j; - int in_and_expr; - int suppress_sva; -#endif -{ - - int allHaveContext=1; - int noneHaveContext=1; - Tree *groupTree; - Tree *oneTree; - Predicate *q; - int identicalORcontextOptimization=0; - int identicalANDcontextOptimization=0; - - if (0 && !MR_usingPredNames && !MRhoisting) { - genPredTreeOrig(p,j,in_and_expr); - return; - }; - - MR_predContextPresent(p,&allHaveContext,&noneHaveContext); - - if ( ! noneHaveContext ) { /* MR10 context guards ignored when -prc off */ - - _gen("("); - - /* MR10 optimize OR predicates which are all leaves */ - - if (p->expr == PRED_OR_LIST && MR_allPredLeaves(p->down)) { - groupTree=MR_compute_pred_tree_context(p); - for (q=p->down ; q != NULL ; q=q->right) { - oneTree=MR_compute_pred_tree_context(q); - if (! MR_tree_equ(groupTree,oneTree)) { - Tfree(oneTree); - break; - }; - Tfree(oneTree); - }; - Tfree(groupTree); - if (q == NULL) { - _gen("/* MR10 individual OR gates suppressed when all predicates are leaves"); - _gen(" with identical context */\n"); - genPredTreeGate(p,in_and_expr); /* use the parent's in_and_expr for this gate */ - identicalORcontextOptimization=1; - } else { - MR_distinctORcontextOpt(p,j,in_and_expr); - return; - }; - } else if (p->expr == PRED_AND_LIST && MR_allPredLeaves(p->down)) { - - /* MR12 optimize AND predicates which are all leaves */ - - groupTree=MR_compute_pred_tree_context(p); - for (q=p->down ; q != NULL ; q=q->right) { - oneTree=MR_compute_pred_tree_context(q); - if (! MR_tree_equ(groupTree,oneTree)) { - Tfree(oneTree); - break; - }; - Tfree(oneTree); - }; - Tfree(groupTree); - if (q == NULL) { - _gen("/* MR12 individual AND gates suppressed when all predicates are leaves"); - _gen(" with identical context */\n"); - genPredTreeGate(p,in_and_expr); /* use the parent's in_and_expr for this gate */ - identicalANDcontextOptimization=1; - } else { - genPredTreeGate(p, in_and_expr); - }; - } else { - genPredTreeGate(p, in_and_expr); - }; - } - - /* if leaf node, just gen predicate */ - - if ( p->down==NULL ) - { - genPred(p,j,suppress_sva); - if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */ - return; - } - - /* if AND list, do both preds (only two possible) */ - /* MR10 not any more ! */ - - if ( p->expr == PRED_AND_LIST ) - { - Predicate *list; - _gen("("); - list = p->down; - for (; list != NULL; list=list->right) { - if (identicalANDcontextOptimization) { - genPred(list, j,suppress_sva); - } else { - genPredTree(list, j, 1, suppress_sva); /* in and context */ - }; - if ( list->right!=NULL ) _gen("&&"); - }; - _gen(")"); - if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */ - return; - } - - if ( p->expr == PRED_OR_LIST ) - { - Predicate *list; - _gen("("); - list = p->down; - for (; list!=NULL; list=list->right) - { - if (identicalORcontextOptimization) { - genPred(list, j,suppress_sva); - } else { - genPredTree(list, j, 0, suppress_sva); - }; - if ( list->right!=NULL ) _gen("||"); - } - _gen(")"); - if ( ! noneHaveContext ) _gen(")"); /* MR10 context guards ignored when -prc off */ - return; - } - - fatal_internal("predicate tree is wacked"); -} - -/* [genPredTreeMainXX] */ - -Predicate * /* MR10 */ -#ifdef __USE_PROTOS -genPredTreeMainXX( Predicate *p, Node *j ,int in_and_expr) -#else -genPredTreeMainXX( p, j ,in_and_expr) - Predicate *p; - Node *j; - int in_and_expr; -#endif -{ - - int allHaveContext=1; - int noneHaveContext=1; - -#if 0 - fprintf(stderr,"Pred before\n"); - dumppred(p); - fprintf(stderr,"\n"); - fprintf(stderr,"Pred after\n"); - dumppred(p); - fprintf(stderr,"\n"); -#endif - - p=MR_predSimplifyALL(p); /* MR10 */ - - require (MR_predicate_context_completed(p),"predicate context is not complete"); - - MR_cleanup_pred_trees(p); /* MR10 */ - - MR_predContextPresent(p,&allHaveContext,&noneHaveContext); - if (!noneHaveContext & !allHaveContext) { - warnFL("predicate contains elements both with and without context", - FileStr[j->file],j->line); - }; - - if (InfoP) { - _gen("\n#if 0\n\n"); - MR_dumpPred(p,1); - _gen("#endif\n"); - }; - genPredTree(p,j,in_and_expr,0); - return p; -} - -Predicate * /* MR10 */ -#ifdef __USE_PROTOS -genPredTreeMain( Predicate *p, Node *j) -#else -genPredTreeMain( p, j) - Predicate *p; - Node *j; -#endif -{ - return genPredTreeMainXX(p,j,1); -} - -static void -#ifdef __USE_PROTOS -genExprTreeOriginal( Tree *t, int k ) -#else -genExprTreeOriginal( t, k ) -Tree *t; -int k; -#endif -{ - require(t!=NULL, "genExprTreeOriginal: NULL tree"); - - if ( t->token == ALT ) - { - _gen("("); genExprTreeOriginal(t->down, k); _gen(")"); - if ( t->right!=NULL ) - { - _gen("||"); - on1line++; - if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); } - _gen("("); genExprTreeOriginal(t->right, k); _gen(")"); - } - return; - } - if ( t->down!=NULL ) _gen("("); - _gen1("LA(%d)==",k); - if ( TokenString(t->token) == NULL ) _gen1("%d", t->token) - else _gen1("%s", TokenString(t->token)); - if ( t->down!=NULL ) - { - _gen("&&"); - on1line++; - if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); } - _gen("("); genExprTreeOriginal(t->down, k+1); _gen(")"); - } - if ( t->down!=NULL ) _gen(")"); - if ( t->right!=NULL ) - { - _gen("||"); - on1line++; - if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); } - _gen("("); genExprTreeOriginal(t->right, k); _gen(")"); - } -} - -#ifdef __USE_PROTOS -static void MR_LAtokenString(int k,int token) -#else -static void MR_LAtokenString(k,token) - int k; - int token; -#endif -{ - char *ts; - - ts=TokenString(token); - if (ts == NULL) { - _gen2(" LA(%d)==%d",k,token); - } else { - _gen2(" LA(%d)==%s",k,ts); - }; -} - - -#ifdef __USE_PROTOS -static int MR_countLeaves(Tree *t) -#else -static int MR_countLeaves(t) - Tree *t; -#endif -{ - if (t == NULL) return 0; - if (t->token == ALT) { - return MR_countLeaves(t->down)+MR_countLeaves(t->right); - } else { - return 1+MR_countLeaves(t->down)+MR_countLeaves(t->right); - }; -} - -#ifdef __USE_PROTOS -static void MR_genOneLine(Tree *tree,int k) -#else -static void MR_genOneLine(tree,k) - Tree *tree; - int k; -#endif -{ - if (tree == NULL) return; - if (tree->token == ALT) { - MR_genOneLine(tree->down,k); - } else { - MR_LAtokenString(k,tree->token); - if (tree->down != NULL && - tree->down->right == NULL) { - _gen(" &&"); - MR_genOneLine(tree->down,k+1); - } else if (tree->down != NULL) { - _gen(" && ("); - MR_genOneLine(tree->down,k+1); - _gen(")"); - }; - }; - if (tree->right != NULL) { - _gen(" ||"); - MR_genOneLine(tree->right,k); - }; -} - -static int across; -static int depth; -static int lastkonline; - -#ifdef __USE_PROTOS -static void MR_genMultiLine(Tree *tree,int k) -#else -static void MR_genMultiLine(tree,k) - Tree *tree; - int k; -#endif -{ - int i; - - if (tree == NULL) return; - if (tree->token == ALT) { - MR_genMultiLine(tree,k); - } else { - MR_LAtokenString(k,tree->token); - lastkonline=k; - across++; - if (tree->down != NULL && tree->down->right == NULL) { - if (across > 3) { - _gen("\n"); - across=0; - lastkonline=0; - for (i=0 ; i < depth+k ; i++) _gen(" "); - _gen("&&"); - } else { - _gen(" &&"); - }; - MR_genMultiLine(tree->down,k+1); - } else if (tree->down != NULL) { - _gen("\n"); - lastkonline=0; - across=0; - for (i=0 ; i < depth+k ; i++) _gen(" "); - _gen("&& ("); - MR_genMultiLine(tree->down,k+1); - _gen(")"); - }; - }; - if (tree->right != NULL) { - if (k < lastkonline) { - _gen("\n"); - across=0; - lastkonline=0; - for (i=0; i < depth+k-1 ; i++) _gen(" "); - _gen("||"); - } else if (across > 3 ) { - _gen("\n"); - across=0; - lastkonline=0; - for (i=0; i < depth+k ; i++) _gen(" "); - _gen("||"); - } else { - _gen(" ||"); - }; - MR_genMultiLine(tree->right,k); - }; -} - -#ifdef __USE_PROTOS -static void genExprTree(Tree *tree,int k) -#else -static void genExprTree(tree,k) - Tree *tree; - int k; -#endif -{ - int count; - -#if 0 - /* MR20 THM This was probably an error. - The routine should probably reference that static - "across" and this declaration hides it. - */ - - int across; -#endif - - require (tree != NULL,"genExprTree: tree is NULL"); - require (k > 0,"genExprTree: k <= 0"); - - if (0 && !MRhoisting) { /* MR11 make new version standard */ - genExprTreeOriginal(tree,k); - } else { - count=MR_countLeaves(tree); - if (count < 5) { - MR_genOneLine(tree,k); - } else { - _gen("\n"); - across=0; - depth=0; - lastkonline=0; - MR_genMultiLine(tree,k); - _gen("\n"); - }; - }; -} - - -/* - * Generate LL(k) type expressions of the form: - * - * (LA(1) == T1 || LA(1) == T2 || ... || LA(1) == Tn) && - * (LA(2) == T1 || LA(2) == T2 || ... || LA(2) == Tn) && - * ..... - * (LA(k) == T1 || LA(k) == T2 || ... || LA(k) == Tn) - * - * If GenExprSetsOpt generate: - * - * (setwdi[LA(1)]&(1<= 1. - * - * This routine is visible only to this file and cannot answer a TRANS message. - * - */ - -/* [genExpr] */ - -static int -#ifdef __USE_PROTOS -genExpr( Junction *j ) -#else -genExpr( j ) -Junction *j; -#endif -{ - int max_k; - - /* if full LL(k) is sufficient, then don't use approximate (-ck) lookahead - * from CLL_k..LL_k - */ - { - int limit; - if ( j->ftree!=NULL ) limit = LL_k; - else limit = CLL_k; - max_k = genExprSets(j->fset, limit); - } - - /* Do tests for real tuples from other productions that conflict with - * artificial tuples generated by compression (using sets of tokens - * rather than k-trees). - */ - if ( j->ftree != NULL ) - { - _gen(" && !("); genExprTree(j->ftree, 1); _gen(")"); - } - - if ( ParseWithPredicates && j->predicate!=NULL ) - { - Predicate *p = j->predicate; - warn_about_using_gk_option(); - _gen("&&"); - j->predicate=genPredTreeMain(p, (Node *)j); /* MR10 */ - } - - return max_k; -} - -static int -#ifdef __USE_PROTOS -genExprSets( set *fset, int limit ) -#else -genExprSets( fset, limit ) -set *fset; -int limit; -#endif -{ - int k = 1; - int max_k = 0; - unsigned *e, *g, firstTime=1; - - if (set_nil(fset[1])) { - _gen(" 0 /* MR13 empty set expression - undefined rule ? infinite left recursion ? */ "); - MR_BadExprSets++; - }; - - if ( GenExprSetsOpt ) - { - while ( k <= limit && !set_nil(fset[k]) ) /* MR11 */ - { - if ( set_deg(fset[k])==1 ) /* too simple for a set? */ - { - int e; - _gen1("(LA(%d)==",k); - e = set_int(fset[k]); - if ( TokenString(e) == NULL ) _gen1("%d)", e) - else _gen1("%s)", TokenString(e)); - } - else - { - NewSet(); - FillSet( fset[k] ); - _gen3("(setwd%d[LA(%d)]&0x%x)", wordnum, k, 1<max_k ) max_k = k; - if ( k == CLL_k ) break; - k++; - if ( k<=limit && !set_nil(fset[k]) ) _gen(" && "); /* MR11 */ - on1line++; - if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); } - } - return max_k; - } - - while ( k<= limit && !set_nil(fset[k]) ) /* MR11 */ - { - if ( (e=g=set_pdq(fset[k])) == NULL ) fatal_internal("genExpr: cannot allocate IF expr pdq set"); - for (; *e!=nil; e++) - { - if ( !firstTime ) _gen(" || ") else { _gen("("); firstTime = 0; } - on1line++; - if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); } - _gen1("LA(%d)==",k); - if ( TokenString(*e) == NULL ) _gen1("%d", *e) - else _gen1("%s", TokenString(*e)); - } - free( (char *)g ); - _gen(")"); - if ( k>max_k ) max_k = k; - if ( k == CLL_k ) break; - k++; - if ( k <= limit && !set_nil(fset[k]) ) { firstTime=1; _gen(" && "); } /* MR11 */ - on1line++; - if ( on1line > NumExprPerLine ) { on1line=0; _gen("\n"); } - } - return max_k; -} - -/* - * Generate code for any type of block. If the last alternative in the block is - * empty (not even an action) don't bother doing it. This permits us to handle - * optional and loop blocks as well. - * - * Only do this block, return after completing the block. - * This routine is visible only to this file and cannot answer a TRANS message. - */ -static set -#ifdef __USE_PROTOS -genBlk( Junction *q, int jtype, int *max_k, int *need_right_curly, int * lastAltEmpty /* MR23 */) -#else -genBlk( q, jtype, max_k, need_right_curly, lastAltEmpty /* MR23 */) -Junction *q; -int jtype; -int *max_k; -int *need_right_curly; -int *lastAltEmpty; /* MR23 */ -#endif -{ - set f; - Junction *alt; - int a_guess_in_block = 0; - require(q!=NULL, "genBlk: invalid node"); - require(q->ntype == nJunction, "genBlk: not junction"); - *need_right_curly=0; - *lastAltEmpty = 0; /* MR23 */ - if ( q->p2 == NULL ) /* only one alternative? Then don't need if */ - { - if (first_item_is_guess_block((Junction *)q->p1)!=NULL ) - { - if (jtype != aLoopBlk && jtype != aOptBlk && jtype != aPlusBlk) { - warnFL("(...)? as only alternative of block is unnecessary", FileStr[q->file], q->line); - }; - gen("zzGUESS\n"); /* guess anyway to make output code consistent */ -/* MR10 disable */ /**** gen("if ( !zzrv )\n"); ****/ -/* MR10 */ gen("if ( !zzrv ) {\n"); tabs++; (*need_right_curly)++; - }; - TRANS(q->p1); - return empty; /* no decision to be made-->no error set */ - } - - f = First(q, 1, jtype, max_k); - for (alt=q; alt != NULL; alt= (Junction *) alt->p2 ) - { - if ( alt->p2 == NULL ) /* chk for empty alt */ - { - Node *p = alt->p1; - if ( p->ntype == nJunction ) - { - /* we have empty alt */ -/* MR23 - There is a conflict between giving good error information for non-exceptions - and making life easy for those using parser exception handling. Consider: - - r: { A } b; - b: B; - - with input "C" - - Before MR21 the error message would be "expecting B - found C". After MR21 - the error message would be "expcect A, B - found C". This was good, but it - caused problems for those using parser exceptions because the reference to - B was generated inside the {...} where B really wasn't part of the block. - - In MR23 this has been changed for the case where exceptions are in use to - not generate the extra check in the tail of the {A} block. -*/ - - -/* MR23 */ if (isEmptyAlt( ((Junction *)p)->p1, (Node *)q->end)) { -/* MR23 */ *lastAltEmpty = 1; -/* MR23 */ if (FoundException) { -/* MR23 */ /* code to restore state if a prev alt didn't follow guess */ -/* MR23 */ if ( a_guess_in_block && jtype != aPlusBlk) { -/* MR23 */ gen("if ( !zzrv ) zzGUESS_DONE; /* MR28 */\n"); -/* MR23 */ } -/* MR23 */ break; -/* MR23 */ }; -/* MR28 */ if (jtype == aPlusBlk) { -/* MR28 */ break; -/* MR28 */ } -/* MR23 */ } - } - } /* end of for loop on alt */ - -/* MR10 */ if (alt->p2 == NULL && -/* MR10 */ ( q->jtype == aSubBlk || q->jtype == RuleBlk) ) { -/* MR10 */ if (first_item_is_guess_block(alt)) { -/* MR10 */ warnFL("(...)? as last alternative of block is unnecessary", -/* MR10 */ FileStr[alt->file],alt->line); -/* MR10 */ }; -/* MR10 */ }; - - if ( alt != q ) gen("else ") - else - { - if ( DemandLookahead ) { - if ( !GenCC ) {gen1("LOOK(%d);\n", *max_k);} - else gen1("look(%d);\n", *max_k); - } - } - - if ( alt!=q ) - { - _gen("{\n"); - tabs++; - (*need_right_curly)++; - /* code to restore state if a prev alt didn't follow guess */ - if ( a_guess_in_block ) - gen("if ( !zzrv ) zzGUESS_DONE;\n"); - } - if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL ) - { - a_guess_in_block = 1; - gen("zzGUESS\n"); - } - gen("if ( "); - if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL ) _gen("!zzrv && "); - genExpr(alt); - _gen(" ) "); - _gen("{\n"); - tabs++; - TRANS(alt->p1); - --tabs; - gen("}\n"); -/* MR10 */ if (alt->p2 == NULL) { -/* MR10 */ if (first_item_is_guess_block(alt)) { -/* MR10 */ gen("/* MR10 */ else {\n"); -/* MR10 */ tabs++; -/* MR10 */ (*need_right_curly)++; -/* MR10 */ /* code to restore state if a prev alt didn't follow guess */ -/* MR10 */ gen("/* MR10 */ if ( !zzrv ) zzGUESS_DONE;\n"); -/* MR10 */ gen("/* MR10 */ if (0) {} /* last alternative of block is guess block */\n"); -/* MR10 */ }; -/* MR10 */ }; - } - return f; -} - -static int -#ifdef __USE_PROTOS -has_guess_block_as_first_item( Junction *q ) -#else -has_guess_block_as_first_item( q ) -Junction *q; -#endif -{ - Junction *alt; - - for (alt=q; alt != NULL; alt= (Junction *) alt->p2 ) - { - if ( first_item_is_guess_block((Junction *)alt->p1)!=NULL ) return 1; - } - return 0; -} - -static int -#ifdef __USE_PROTOS -has_guess_block_as_last_item( Junction *q ) -#else -has_guess_block_as_last_item( q ) -Junction *q; -#endif -{ - Junction *alt; - - if (q == NULL) return 0; - for (alt=q; alt->p2 != NULL && !( (Junction *) alt->p2)->ignore; alt= (Junction *) alt->p2 ) {}; - return first_item_is_guess_block( (Junction *) alt->p1) != NULL; -} - -/* MR30 See description of first_item_is_guess_block for background */ - -Junction * -#ifdef __USE_PROTOS -first_item_is_guess_block_extra(Junction *q ) -#else -first_item_is_guess_block_extra(q) -Junction *q; -#endif -{ - while ( q!=NULL && - ( ( q->ntype==nAction ) || - ( q->ntype==nJunction && - (q->jtype==Generic || q->jtype == aLoopBlk) - ) - ) - ) - { - if ( q->ntype==nJunction ) q = (Junction *)q->p1; - else q = (Junction *) ((ActionNode *)q)->next; - } - - if ( q==NULL ) return NULL; - if ( q->ntype!=nJunction ) return NULL; - if ( q->jtype!=aSubBlk ) return NULL; - if ( !q->guess ) return NULL; - - return q; -} - -/* return NULL if 1st item of alt is NOT (...)? block; else return ptr to aSubBlk node - * of (...)?; This function ignores actions and predicates. - */ - -Junction * -#ifdef __USE_PROTOS -first_item_is_guess_block( Junction *q ) -#else -first_item_is_guess_block( q ) -Junction *q; -#endif -{ - Junction * qOriginal = q; /* DEBUG */ - - /* MR14 Couldn't find aSubBlock which was a guess block when it lay - behind aLoopBlk. The aLoopBlk only appear in conjunction with - aLoopBegin, but the routine didn't know that. I think. - - MR14a Added extra parentheses to clarify precedence - - MR30 This appears to have been a mistake. The First set was then - computed incorrectly for: - - r : ( (A)? B - | C - )* - - The routine analysis_point was seeing the guess block when - it was still analyzing the loopBegin block. As a consequence, - when it looked for the analysis_point it was processing the B, but - skipping over the C alternative altogether because it thought - it was looking at a guess block, not realizing there was a loop - block in front of the loopBegin. - - loopBegin loopBlk subBlk/guess A G EB G B EB EB EB ER - | | | ^ ^ - | | | | - | +-> G C G ----------------------+ | - | | - +--- G G G -------------------------------------+ - - Reported by Arpad Beszedes (beszedes@inf.u-szeged.hu). - - MR30 This is still more complicated. This fix caused ambiguity messages - to be reported for "( (A B)? )* A B" but not for "( (A B)? )+". Why is - there a difference when these are outwardly identical ? It is because the - start of a (...)* block is represented by two nodes: a loopBegin block - followed by a loopBlock whereas the start of a (...)+ block is - represented as a single node: a plusBlock. So if first_item_is_guess_block - is called when the current node is a loopBegin it starts with the - loop block rather than the the sub block which follows the loop block. - However, we can't just skip past the loop block because some routines - depend on the old implementation. So, we provide a new implementation - which does skip the loopBlock. However, which should be called when ? - I'm not sure, but my guess is that first_item_is_guess_block_extra (the - new one) should only be called for the ambiguity routines. - - */ - - while ( q!=NULL && - ( ( q->ntype==nAction ) || - ( q->ntype==nJunction && - (q->jtype==Generic /*** || q->jtype == aLoopBlk ***/ ) /*** MR30 Undo MR14 change ***/ - ) - ) - ) - { - if ( q->ntype==nJunction ) q = (Junction *)q->p1; - else q = (Junction *) ((ActionNode *)q)->next; - } - - if ( q==NULL ) return NULL; - if ( q->ntype!=nJunction ) return NULL; - if ( q->jtype!=aSubBlk ) return NULL; - if ( !q->guess ) return NULL; - - return q; -} - -/* MR1 */ -/* MR1 10-Apr-97 MR1 Routine to stringize failed semantic predicates msgs */ -/* MR1 */ - -#define STRINGIZEBUFSIZE 1024 - -static char stringizeBuf[STRINGIZEBUFSIZE]; -char * -#ifdef __USE_PROTOS -stringize(char * s) -#else -stringize(s) -char *s; -#endif - -{ - char *p; - char *stop; - - p=stringizeBuf; - stop=&stringizeBuf[1015]; - - if (s != 0) { - while (*s != 0) { - if (p >= stop) { - goto stringizeStop; - } else if (*s == '\n') { - *p++='\\'; - *p++='n'; - *p++='\\'; - *p++=*s++; - } else if (*s == '\\') { - *p++=*s; - *p++=*s++; - } else if (*s == '\"') { - *p++='\\'; - *p++=*s++; - while (*s != 0) { - if (p >= stop) { - goto stringizeStop; - } else if (*s == '\n') { - *p++='\\'; - *p++=*s++; - } else if (*s == '\\') { - *p++=*s++; - *p++=*s++; - } else if (*s == '\"') { - *p++='\\'; - *p++=*s++; - break; - } else { - *p++=*s++; - }; - }; - } else if (*s == '\'') { - *p++=*s++; - while (*s != 0) { - if (p >= stop) { - goto stringizeStop; - } else if (*s == '\'') { - *p++=*s++; - break; - } else if (*s == '\\') { - *p++=*s++; - *p++=*s++; - } else if (*s == '\"') { - *p++='\\'; - *p++=*s++; - break; - } else { - *p++=*s++; - }; - }; - } else { - *p++=*s++; - }; - }; - }; - goto stringizeExit; -stringizeStop: - *p++='.'; - *p++='.'; - *p++='.'; -stringizeExit: - *p=0; - return stringizeBuf; -} - -#ifdef __USE_PROTOS -int isNullAction(char *s) -#else -int isNullAction(s) - char *s; -#endif -{ - char *p; - for (p=s; *p != '\0' ; p++) { - if (*p != ';' && *p !=' ') return 0; - }; - return 1; -} -/* MR1 */ -/* MR1 End of Routine to stringize code for failed predicates msgs */ -/* MR1 */ - -/* Generate an action. Don't if action is NULL which means that it was already - * handled as an init action. - */ -void -#ifdef __USE_PROTOS -genAction( ActionNode *p ) -#else -genAction( p ) -ActionNode *p; -#endif -{ - require(p!=NULL, "genAction: invalid node and/or rule"); - require(p->ntype==nAction, "genAction: not action"); - - if ( !p->done ) /* MR10 */ /* MR11 */ - { - if ( p->is_predicate) - { - if ( p->guardpred != NULL ) - { - Predicate *guardDup=predicate_dup(p->guardpred); /* MR10 */ - gen("if (!"); - guardDup=genPredTreeMain(guardDup, (Node *)p); - predicate_free(guardDup); - } -/* MR10 */ else if (p->ampersandPred != NULL) { -/* MR10 */ gen("if (!"); -/* MR10 */ p->ampersandPred=genPredTreeMain(p->ampersandPred, (Node *)p); -/* MR10 */ } - else - { - gen("if (!("); - /* make sure that '#line n' is on front of line */ - if ( GenLineInfo && p->file != -1 ) _gen("\n"); - dumpPredAction(p,p->action, output, 0, p->file, p->line, 0); - _gen(")"); - } - -/* MR23 Change failed predicate macro to have three arguments: - - macro arg 1: The stringized predicate itself - macro arg 2: 0 => no user-defined error action - 1 => user-defined error action - macro arg 3: The user-defined error action - - This gives the user more control of the error action. -*/ - tabs++; - gen3(") {zzfailed_pred(\"%s\",%s, { %s } );}\n", /* MR23 */ - stringize(p->action), /* MR23 */ - (p->pred_fail == NULL ? /* MR23/MR27 */ - "0 /* report */" : "1 /* user action */"), /* MR23/MR27 */ - (p->pred_fail == NULL ? /* MR23 */ - "0; /* no user action */" : p->pred_fail)); /* MR23 */ - tabs--; - } - else /* not a predicate */ - { - if (! isNullAction(p->action) && !p->noHoist) { - if ( FoundGuessBlk ) { - if ( GenCC ) { - gen("if ( !guessing ) {\n"); - } else { - gen("zzNON_GUESS_MODE {\n"); - }; - }; - dumpActionPlus(p, p->action, output, tabs, p->file, p->line, 1); /* MR21 */ - if ( FoundGuessBlk ) gen("}\n"); - }; - } - } - TRANS(p->next) -} - -/* - * if invoking rule has !noAST pass zzSTR to rule ref and zzlink it in - * else pass addr of temp root ptr (&_ast) (don't zzlink it in). - * - * if ! modifies rule-ref, then never link it in and never pass zzSTR. - * Always pass address of temp root ptr. - */ -void -#ifdef __USE_PROTOS -genRuleRef( RuleRefNode *p ) -#else -genRuleRef( p ) -RuleRefNode *p; -#endif -{ - Junction *q; - char *handler_id = ""; - RuleEntry *r, *r2; - char *parm = "", *exsig = ""; - - int genRuleRef_emittedGuessGuard=0; /* MR10 */ - - require(p!=NULL, "genRuleRef: invalid node and/or rule"); - require(p->ntype==nRuleRef, "genRuleRef: not rule reference"); - - if ( p->altstart!=NULL && p->altstart->exception_label!=NULL ) - handler_id = p->altstart->exception_label; - - r = (RuleEntry *) hash_get(Rname, p->text); - if ( r == NULL ) - { - warnFL( eMsg1("rule %s not defined", - p->text), FileStr[p->file], p->line ); - return; - } - -/* MR8 5-Aug-97 Reported by S.Bochnak@microtool.com.pl */ -/* Don't do assign when no return values declared */ -/* Move definition of q up and use it to guard p->assign */ - - q = RulePtr[r->rulenum]; /* find definition of ref'd rule */ /* MR8 */ - - r2 = (RuleEntry *) hash_get(Rname, p->rname); - if ( r2 == NULL ) {warnNoFL("Rule hash table is screwed up beyond belief"); return;} - - OutLineInfo(output,p->line,FileStr[p->file]); - - if ( GenCC && GenAST ) { - gen("_ast = NULL;\n"); - } - - if ( FoundGuessBlk && p->assign!=NULL && q->ret != NULL ) { /* MR8 */ - if ( GenCC ) { - gen("if ( !guessing ) {\n"); - } else { - gen("zzNON_GUESS_MODE {\n"); - }; - tabs++; /* MR11 */ - genRuleRef_emittedGuessGuard=1; /* MR11 */ - }; - - if ( FoundException ) exsig = "&_signal"; - - tab(); - if ( GenAST ) - { - if ( GenCC ) { -/**** if ( r2->noAST || p->astnode==ASTexclude ) -****/ - { -/**** _gen("_ast = NULL;\n"); -****/ - parm = "&_ast"; - } -/*** we always want to set just a pointer now, then set correct -pointer after - - else { - _gen("_astp = -(_tail==NULL)?(&_sibling):(&(_tail->_right));\n"); - parm = "_astp"; - } -****/ - } - else { - if ( r2->noAST || p->astnode==ASTexclude ) - { - _gen("_ast = NULL; "); - parm = "&_ast"; - } - else parm = "zzSTR"; - } - if ( p->assign!=NULL && q->ret!=NULL ) /* MR8 */ - { - if ( !hasMultipleOperands(p->assign) ) {_gen1("%s = ",p->assign);} /* MR23 */ - else _gen1("{ struct _rv%d _trv; _trv = ", r->rulenum); - } - if ( FoundException ) { - _gen5("%s%s(%s,&_signal%s%s); ", - RulePrefix, - p->text, - parm, - (p->parms!=NULL)?",":"", - (p->parms!=NULL)?p->parms:""); - if ( p->ex_group!=NULL ) { - _gen("\n"); - gen("if (_signal) {\n"); - tabs++; - dumpException(p->ex_group, 0); - tabs--; - gen("}"); - } - else { - _gen1("if (_signal) goto %s_handler;", handler_id); - } - } - else { - _gen5("%s%s(%s%s%s);", - RulePrefix, - p->text, - parm, - (p->parms!=NULL)?",":"", - (p->parms!=NULL)?p->parms:""); - } - if ( GenCC && (r2->noAST || p->astnode==ASTexclude) ) - { - /* rule has a ! or element does */ - /* still need to assign to #i so we can play with it */ - _gen("\n"); - gen2("_ast%d%d = (AST *)_ast;", BlkLevel-1, p->elnum); - } - else if ( !r2->noAST && p->astnode == ASTinclude ) - { - /* rule doesn't have a ! and neither does element */ -/* MR10 */ if (FoundGuessBlk && !genRuleRef_emittedGuessGuard) { -/* MR10 */ _gen("\n"); -/* MR10 */ if (GenCC) gen ("if (!guessing) { /* MR10 */") -/* MR10 */ else gen ("if (!zzguessing) { /* MR10 */\n"); -/* MR10 */ tabs++; -/* MR10 */ }; - if ( GenCC ) { - _gen("\n"); - gen("if ( _tail==NULL ) _sibling = _ast; else _tail->setRight(_ast);\n"); - gen2("_ast%d%d = (AST *)_ast;\n", BlkLevel-1, p->elnum); - tab(); - } - else _gen(" "); - if ( GenCC ) { - _gen("ASTBase::"); } - else _gen("zz"); - _gen("link(_root, &_sibling, &_tail);"); - -/* MR10 */ if (FoundGuessBlk && !genRuleRef_emittedGuessGuard) { /* MR10 */ -/* MR10 */ _gen("\n"); -/* MR10 */ tabs--; -/* MR10 */ if (GenCC) gen ("}; /* MR10 */") -/* MR10 */ else gen ("}; /* MR10 */"); -/* MR10 */ }; - } - } - else - { - if ( p->assign!=NULL && q->ret!=NULL ) /* MR8 */ - { - if ( !hasMultipleOperands(p->assign) ) {_gen1("%s = ",p->assign);} /* MR23 */ - else _gen1("{ struct _rv%d _trv; _trv = ", r->rulenum); - } - if ( FoundException ) { - _gen4("%s%s(&_signal%s%s); ", - RulePrefix, - p->text, - (p->parms!=NULL)?",":"", - (p->parms!=NULL)?p->parms:""); - if ( p->ex_group!=NULL ) { - _gen("\n"); - gen("if (_signal) {\n"); - tabs++; - dumpException(p->ex_group, 0); - tabs--; - gen("}"); - } - else { - _gen1("if (_signal) goto %s_handler;", handler_id); - } - } - else { - _gen3("%s%s(%s);", - RulePrefix, - p->text, - (p->parms!=NULL)?p->parms:""); - } - if ( p->assign!=NULL && q->ret!=NULL ) _gen("\n"); /* MR8 */ - } - - if ( p->assign!=NULL && q->ret!=NULL) { /* MR8 */ - if ( hasMultipleOperands(p->assign) ) /* MR23 */ - { - _gen("\n"); - dumpRetValAssign(p->assign, q->ret, p); /* MR30 */ - _gen("}"); - } - } - _gen("\n"); - - /* Handle element labels now */ - if ( p->el_label!=NULL ) - { - if ( GenAST ) - { - if ( GenCC ) { - gen3("%s_ast = _ast%d%d;\n", p->el_label, BlkLevel-1, p->elnum); - } - else {gen1("%s_ast = zzastCur;\n", p->el_label);} - } - else if (!GenCC ) { - gen1("%s = zzaCur;\n", p->el_label); - } - } - - if ( FoundGuessBlk && p->assign!=NULL && q->ret!=NULL ) { /* MR8 */ - /* in guessing mode, don't branch to handler upon error */ - tabs--; /* MR11 */ - gen("} else {\n"); - tabs++; /* MR11 */ - if ( FoundException ) { - gen6("%s%s(%s%s&_signal%s%s);\n", - RulePrefix, - p->text, - parm, - (*parm!='\0')?",":"", - (p->parms!=NULL)?",":"", - (p->parms!=NULL)?p->parms:""); - } - else { - gen5("%s%s(%s%s%s);\n", - RulePrefix, - p->text, - parm, - (p->parms!=NULL && *parm!='\0')?",":"", - (p->parms!=NULL)?p->parms:""); - } - tabs--; /* MR11 */ - gen("}\n"); - } - TRANS(p->next) -} - -/* - * Generate code to match a token. - * - * Getting the next token is tricky. We want to ensure that any action - * following a token is executed before the next GetToken(); - */ -void -#ifdef __USE_PROTOS -genToken( TokNode *p ) -#else -genToken( p ) -TokNode *p; -#endif -{ - RuleEntry *r; - char *handler_id = ""; - ActionNode *a; - char *set_name; - char *set_nameErrSet; - int complement; - int ast_label_in_action = 0; /* MR27 */ - int pushedCmodeAST = 0; /* MR27 */ - - require(p!=NULL, "genToken: invalid node and/or rule"); - require(p->ntype==nToken, "genToken: not token"); - if ( p->altstart!=NULL && p->altstart->exception_label!=NULL ) - handler_id = p->altstart->exception_label; - - r = (RuleEntry *) hash_get(Rname, p->rname); - if ( r == NULL ) {warnNoFL("Rule hash table is screwed up beyond belief"); return;} - -/* - * MR27 Has the element label been referenced as an AST (with the # operator) ? - * If so, then we'll want to build the AST even though the user has used - * the ! operator. - */ -/* MR27 */ if (GenAST && p->el_label != NULL) { -/* MR27 */ ast_label_in_action = list_search_cstring(r->ast_labels_in_actions, -/* MR27 */ p->el_label); -/* MR27 */ } - - OutLineInfo(output,p->line,FileStr[p->file]); - - if ( !set_nil(p->tset) ) /* implies '.', ~Tok, or tokenclass */ - { - unsigned e; - unsigned eErrSet = 0; - set b; - set bErrSet; /* MR23 */ - b = set_dup(p->tset); - bErrSet = set_dup(p->tset); /* MR23 */ - complement = p->complement; /* MR23 */ - if ( p->tclass!=NULL && complement == 0 /* MR23 */) { /* token class not complemented*/ - static char buf[MaxRuleName+20]; /* MR23 */ - static char bufErrSet[MaxRuleName+20]; /* MR23 */ - if ( p->tclass->dumped ) { - e = p->tclass->setnum; - eErrSet = p->tclass->setnumErrSet; - } - else { - e = DefErrSet(&b, 0, TokenString(p->token)); - eErrSet = DefErrSetWithSuffix(0, &bErrSet, 1, TokenString(p->token), "_errset"); - p->tclass->dumped = 1; /* indicate set has been created */ - p->tclass->setnum = e; - p->tclass->setnumErrSet = eErrSet; /* MR23 */ - } - sprintf(buf, "%s_set", TokenString(p->token)); - sprintf(bufErrSet, "%s_errset", TokenString(p->token)); /* MR23 */ - set_name = buf; - set_nameErrSet = bufErrSet; /* MR23 */ - } - - /* MR23 - Forgot about the case of ~TOKCLASS. */ - - else if ( p->tclass!=NULL && complement != 0 /* MR23 */) - { - static char buf[MaxRuleName+20]; /* MR23 */ - static char bufErrSet[MaxRuleName+20]; /* MR23 */ - if ( p->tclass->dumpedComplement ) { - e = p->tclass->setnumComplement; - eErrSet = p->tclass->setnumErrSetComplement; - } - else { - e = DefErrSetWithSuffix(0, &b, 0, TokenString(p->token), "_setbar"); - eErrSet = DefErrSetWithSuffix(0, &bErrSet, 1, TokenString(p->token), "_errsetbar"); - p->tclass->dumpedComplement = 1; /* indicate set has been created */ - p->tclass->setnumComplement = e; - p->tclass->setnumErrSetComplement = eErrSet; /* MR23 */ - } - sprintf(buf, "%s_setbar", TokenString(p->token)); - sprintf(bufErrSet, "%s_errsetbar", TokenString(p->token)); /* MR23 */ - set_name = buf; - set_nameErrSet = bufErrSet; /* MR23 */ - } - else { /* wild card */ - static char buf[sizeof("zzerr")+10]; - static char bufErrSet[sizeof("zzerr")+10]; - int n = DefErrSet( &b, 0, NULL ); - int nErrSet = DefErrSetWithSuffix(0, &bErrSet, 1, NULL, "_set"); - if ( GenCC ) sprintf(buf, "err%d", n); - else sprintf(buf, "zzerr%d", n); - if ( GenCC ) sprintf(bufErrSet, "err%d", nErrSet); - else sprintf(bufErrSet, "zzerr%d", nErrSet); - set_name = buf; - set_nameErrSet = bufErrSet; - } - - if ( !FoundException ) { -/* MR23 */ gen2("zzsetmatch(%s, %s);", set_name, set_nameErrSet); - } - else if ( p->ex_group==NULL ) { - if ( p->use_def_MT_handler ) - gen3("zzsetmatch_wdfltsig(%s,(ANTLRTokenType)%d,%s);", - set_name, - p->token, - tokenFollowSet(p)) - else - gen2("zzsetmatch_wsig(%s, %s_handler);", - set_name, - handler_id); - } - else - { - gen1("if ( !_setmatch_wsig(%s) ) {\n", set_name); - tabs++; -/* MR6 */ if (FoundGuessBlk) { -/* MR6 */ if ( GenCC ) {gen("if ( guessing ) goto fail;\n");} -/* MR6 */ else gen("if ( zzguessing ) goto fail;\n"); -/* MR6 */ }; - gen("_signal=MismatchedToken;\n"); - dumpException(p->ex_group, 0); - tabs--; - gen("}\n"); - } - set_free(b); - set_free(bErrSet); - } - else if ( TokenString(p->token)!=NULL ) - { - if ( FoundException ) { - if ( p->use_def_MT_handler ) - gen2("zzmatch_wdfltsig(%s,%s);",TokenString(p->token),tokenFollowSet(p)) - else if ( p->ex_group==NULL ) - { - gen2("zzmatch_wsig(%s, %s_handler);", - TokenString(p->token), - handler_id); - } - else - { -/* MR6 */ if (GenCC) { -/* MR6 */ gen1("if ( !_match_wsig(%s) ) {\n", TokenString(p->token)); -/* MR6 */ } else { -/* MR6 */ gen1("if ( !_zzmatch_wsig(%s) ) {\n", TokenString(p->token)); -/* MR6 */ }; - tabs++; -/* MR6 */ if (FoundGuessBlk) { -/* MR6 */ if ( GenCC ) {gen("if ( guessing ) goto fail;\n");} -/* MR6 */ else gen("if ( zzguessing ) goto fail;\n"); -/* MR6 */ }; - gen("_signal=MismatchedToken;\n"); - dumpException(p->ex_group, 0); - tabs--; - gen("}\n"); - } - } - else gen1("zzmatch(%s);", TokenString(p->token)); - } - else { - if ( FoundException ) { - if ( p->use_def_MT_handler ) - gen2("zzmatch_wdfltsig((ANTLRTokenType)%d,%s);", - p->token,tokenFollowSet(p)) - else - gen2("zzmatch_wsig(%d,%s_handler);",p->token,handler_id); - } - else {gen1("zzmatch(%d);", p->token);} - } - - a = findImmedAction( p->next ); - /* generate the token labels */ - if ( GenCC && p->elnum>0 ) - { - /* If building trees in C++, always gen the LT() assigns */ - if ( set_el(p->elnum, tokensRefdInBlock) || GenAST ) - { -/* MR10 */ if ( FoundGuessBlk ) { -/* MR10 */ gen("\n"); -/* MR10 */ if (p->label_used_in_semantic_pred) { -/* MR10 */ gen2(" _t%d%d = (ANTLRTokenPtr)LT(1); /* MR10 */\n", BlkLevel-1, p->elnum); -/* MR10 */ } else { -/* MR10 */ gen("if ( !guessing ) {\n"); tab(); -/* MR10 */ _gen2(" _t%d%d = (ANTLRTokenPtr)LT(1);\n", BlkLevel-1, p->elnum); -/* MR10 */ gen("}\n"); -/* MR10 */ }; -/* MR10 */ } else { -/* MR10 */ _gen2(" _t%d%d = (ANTLRTokenPtr)LT(1);", BlkLevel-1, p->elnum); -/* MR10 */ }; -/* MR10 */ - } - -/* - * MR23 labase is never used in the C++ runtime library. - * and this code is generated only in C++ mode - */ - -/*** if ( LL_k>1 ) / * MR23 disabled */ -/*** if ( !DemandLookahead ) _gen(" labase++;"); / * MR23 disabled */ -/*** _gen("\n"); / * MR23 disabled */ -/*** tab(); / * MR23 disabled */ - } - if ( GenAST ) - { - if ( FoundGuessBlk && - (ast_label_in_action || !(p->astnode == ASTexclude || r->noAST)) ) - { - if ( GenCC ) {_gen("if ( !guessing ) {\n"); tab();} - else {_gen("zzNON_GUESS_MODE {\n"); tab();} - } - -/* MR27 addition when labels referenced when operator ! used */ - - pushedCmodeAST = 0; /* MR27 */ - if (ast_label_in_action && (p->astnode == ASTexclude || r->noAST)) { - _gen("\n"); - if (GenCC) { -/* MR13 */ if (NewAST) { -/* MR13 */ gen4("_ast%d%d = newAST(_t%d%d); /* MR27 */\n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum); -/* MR13 */ } else { -/* MR13 */ gen4("_ast%d%d = new AST(_t%d%d); /* MR27 */\n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum); -/* MR13 */ } - } - else { - pushedCmodeAST = 1; - gen("zzastPush(zzmk_ast(zzastnew(),zzaCur)); /* MR27 */"); - } - } - -/* end MR27 addition for labels referenced when operator ! used */ - - if (!r->noAST ) - { - if (GenCC && !(p->astnode == ASTexclude) ) { - _gen("\n"); -/* MR13 */ if (NewAST) { -/* MR13 */ gen4("_ast%d%d = newAST(_t%d%d);\n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum); -/* MR13 */ } else { -/* MR13 */ gen4("_ast%d%d = new AST(_t%d%d);\n", BlkLevel-1, p->elnum, BlkLevel-1, p->elnum); -/* MR13 */ } - tab(); - } - if ( GenCC && !(p->astnode == ASTexclude) ) - {_gen2("_ast%d%d->", BlkLevel-1, p->elnum);} - else _gen(" "); - if ( p->astnode==ASTchild ) { - if ( !GenCC ) _gen("zz"); - _gen("subchild(_root, &_sibling, &_tail);"); - } - else if ( p->astnode==ASTroot ) { - if ( !GenCC ) _gen("zz"); - _gen("subroot(_root, &_sibling, &_tail);"); - } - if ( GenCC && !(p->astnode == ASTexclude) ) { - _gen("\n"); - tab(); - } - } - else if ( !GenCC ) { - if (! pushedCmodeAST) _gen(" zzastDPush;"); - } - if ( FoundGuessBlk && - (ast_label_in_action || !(p->astnode == ASTexclude || r->noAST)) ) - {gen("}\n"); tab();} - } - - /* Handle element labels now */ - if ( p->el_label!=NULL ) - { - int done_NON_GUESSMODE=0; - - _gen("\n"); - -/* MR10 */ /* do Attrib / Token ptr for token label used in semantic pred */ -/* MR10 */ /* for these cases do assign even in guess mode */ -/* MR10 */ -/* MR10 */ if (p->label_used_in_semantic_pred) { -/* MR10 */ if ( GenCC ) { -/* MR10 */ if ( set_el(p->elnum, tokensRefdInBlock) || GenAST ) { -/* MR10 */ gen3("%s = _t%d%d;", p->el_label, BlkLevel-1, p->elnum); -/* MR10 */ } else { -/* MR10 */ gen1("%s = (ANTLRTokenPtr)LT(1);\n", p->el_label); -/* MR10 */ }; -/* MR10 */ } else { -/* MR10 */ gen1("%s = zzaCur;", p->el_label); -/* MR10 */ }; -/* MR10 */ if (FoundGuessBlk) _gen(" /* MR10 */"); -/* MR10 */ _gen("\n"); -/* MR10 */ }; - - /* Do Attrib / Token ptr */ - -/* MR10 */ if (! p->label_used_in_semantic_pred) { -/* MR10 */ -/* MR10 */ if ( FoundGuessBlk ) { -/* MR10 */ if (! done_NON_GUESSMODE) { -/* MR10 */ done_NON_GUESSMODE=1; -/* MR10 */ if ( GenCC ) {gen("if ( !guessing ) {\n"); tab();} -/* MR10 */ else {gen("zzNON_GUESS_MODE {\n"); tab();} -/* MR10 */ }; -/* MR10 */ }; -/* MR10 */ -/* MR10 */ if ( GenCC ) { -/* MR10 */ if ( set_el(p->elnum, tokensRefdInBlock) || GenAST ) { -/* MR10 */ gen3("%s = _t%d%d;\n", p->el_label, BlkLevel-1, p->elnum); -/* MR10 */ } else { -/* MR10 */ gen1("%s = (ANTLRTokenPtr)LT(1);\n", p->el_label); -/* MR10 */ }; -/* MR10 */ } else { -/* MR10 */ gen1("%s = zzaCur;\n", p->el_label); -/* MR10 */ }; -/* MR10 */ }; - - /* Do AST ptr */ - - if (GenAST && (ast_label_in_action || !(p->astnode == ASTexclude || r->noAST) )) /* MR27 */ - { - -/* MR10 */ if ( FoundGuessBlk ) { -/* MR10 */ if (! done_NON_GUESSMODE) { -/* MR10 */ done_NON_GUESSMODE=1; -/* MR10 */ if ( GenCC ) {gen("if ( !guessing ) {\n"); tab();} -/* MR10 */ else {gen("zzNON_GUESS_MODE {\n"); tab();} -/* MR10 */ }; -/* MR10 */ }; - - if ( GenCC ) { - gen3("%s_ast = _ast%d%d;\n", p->el_label, BlkLevel-1, p->elnum); - } - else {gen1("%s_ast = zzastCur;\n", p->el_label);} - } - -/* MR10 */ if (done_NON_GUESSMODE) { -/* MR10 */ gen("}\n"); tab(); -/* MR10 */ }; - - } - - /* Handle any actions immediately following action */ - if ( a != NULL ) /* MR10 */ /* MR11 */ - { - /* delay next token fetch until after action */ - _gen("\n"); - if ( a->is_predicate) - { -#if 0 -/* Disabled in MR30 ************************************************************ - And moved into genAction - ***************************************************************************** -*/ - - gen("if (!("); - - /* make sure that '#line n' is on front of line */ /* MR14 */ - if ( GenLineInfo && p->file != -1 ) _gen("\n"); /* MR14 */ - dumpPredAction(a,a->action, output, 0, a->file, a->line, 0); - -/* MR23 Change failed predicate macro to have three arguments: - - macro arg 1: The stringized predicate itself - macro arg 2: 0 => no user-defined error action - 1 => user-defined error action - macro arg 3: The user-defined error action - - This gives the user more control of the error action. -*/ - _gen(")) \n"); - tabs++; - gen3(" {zzfailed_pred(\"%s\",%s,{ %s } );}\n", /* MR23 */ - stringize(a->action), /* MR23 */ - (a->pred_fail == NULL ? /* MR23/MR27 */ - "0 /* report */" : "1 /* user action */"), /* MR23/MR27 */ - (a->pred_fail == NULL ? /* MR23 */ - "0; /* no user action */" : a->pred_fail)); /* MR23 */ - tabs--; -/* Disabled in MR30 ************************************************************ - And moved into genAction - ***************************************************************************** -*/ -#endif - } - else /* MR9 a regular action - not a predicate action */ - { - -/* MR23: Search an action which is not a predicate for LT(i), - LA(i), or LATEXT(i) in order to warn novice users that - it refers to the previous matched token, not the next - one. This is different than the case for semantic - predicates. -*/ - -/* MR23 */ if (GenCC) { -/* MR23 */ if (strstr(a->action, "LT(") != NULL) LTinTokenAction = 1; -/* MR23 */ } -/* MR23 */ else { -/* MR23 */ if (strstr(a->action, "LA(") != NULL) LTinTokenAction = 1; -/* MR23 */ if (strstr(a->action, "LATEXT(") != NULL) LTinTokenAction = 1; -/* MR23 */ } - - if ( FoundGuessBlk ) { - if ( GenCC ) {gen("if ( !guessing ) {\n");} - else gen("zzNON_GUESS_MODE {\n"); - } - dumpActionPlus(a, a->action, output, tabs, a->file, a->line, 1); /* MR21 */ - if ( FoundGuessBlk ) gen("}\n"); - a->done = 1; /* MR30 */ - } -/*** a->done = 1; MR30 Moved up into then branch for true actions, but not predicates ***/ - if ( !DemandLookahead ) { - if ( GenCC ) { - if ( FoundException && p->use_def_MT_handler ) gen("if (!_signal)"); - _gen(" consume();") - if ( FoundException && p->use_def_MT_handler ) - _gen(" _signal=NoSignal;"); - _gen("\n"); - } - else - { - if ( FoundException && p->use_def_MT_handler ) _gen("if (!_signal)"); - _gen(" zzCONSUME;\n"); - if ( FoundException && p->use_def_MT_handler ) _gen(" _signal=NoSignal;"); - _gen("\n"); - } - } - else gen("\n"); - if (a->done) { /* MR30 */ - TRANS( a->next ); /* MR30 */ - } /* MR30 */ - else { /* MR30 */ - TRANS( p->next ); /* MR30 */ - } /* MR30 */ - } - else - { - if ( !DemandLookahead ) { - if ( GenCC ) { - if (FoundException && p->use_def_MT_handler) _gen("if (!_signal)"); - _gen(" consume();") - if (FoundException&&p->use_def_MT_handler) _gen(" _signal=NoSignal;"); - _gen("\n"); - } - else { - if (FoundException && p->use_def_MT_handler) _gen("if (!_signal)"); - _gen(" zzCONSUME;"); - if ( FoundException && p->use_def_MT_handler ) _gen(" _signal=NoSignal;"); - _gen("\n"); - } - } - else _gen("\n"); - TRANS(p->next); - } -} - -/* MR21 - * - * There was a bug in the code generation for {...} which causes it - * to omit the optional tokens from the error messages. The easiest - * way to fix this was to make the opt block look like a sub block: - * - * { a | b | c } - * - * becomes (internally): - * - * ( a | b | c | ) - * - * The code for genOptBlk is now identical to genSubBlk except for - * cosmetic changes. - */ - -void -#ifdef __USE_PROTOS -genOptBlk( Junction *q ) -#else -genOptBlk( q ) -Junction *q; -#endif -{ - int max_k; - set f; - int need_right_curly; - set savetkref; - int lastAltEmpty; /* MR23 */ - savetkref = tokensRefdInBlock; - require(q->ntype == nJunction, "genOptBlk: not junction"); - require(q->jtype == aOptBlk, "genOptBlk: not opt block"); - - OutLineInfo(output,q->line,FileStr[q->file]); - BLOCK_Preamble(q); - BlkLevel++; - BlockPreambleOption(q,q->pFirstSetSymbol); /* MR21 */ - f = genBlk(q, aOptBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */); -/* MR23 - Bypass error clause generation when exceptions are used in {...} block - See multi-line note in genBlk near call to isEmptyAlt. -*/ - if (! FoundException) { - if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k,0 /* use plus block bypass ? */ );} - } - else { - gen("/* MR23 skip error clause for {...} when exceptions in use */\n"); - } - { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} } - freeBlkFsets(q); - --BlkLevel; - BLOCK_Tail(); - - if ( q->guess ) - { - gen("zzGUESS_DONE\n"); - } - - /* must duplicate if (alpha)?; one guesses (validates), the - * second pass matches */ - if ( q->guess && analysis_point(q)==q ) - { - OutLineInfo(output,q->line,FileStr[q->file]); - BLOCK_Preamble(q); - BlkLevel++; - f = genBlk(q, aSubBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */); - if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k,0 /* use plus block bypass ? */ );} - { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} } - freeBlkFsets(q); - --BlkLevel; - BLOCK_Tail(); - } - - tokensRefdInBlock = savetkref; - if (q->end->p1 != NULL) TRANS(q->end->p1); -} - -/* - * Generate code for a loop blk of form: - * - * |---| - * v | - * --o-G-o-->o-- - */ -void -#ifdef __USE_PROTOS -genLoopBlk( Junction *begin, Junction *q, Junction *start, int max_k ) -#else -genLoopBlk( begin, q, start, max_k ) -Junction *begin; -Junction *q; -Junction *start; /* where to start generating code from */ -int max_k; -#endif -{ - set f; - int need_right_curly; - set savetkref; - Junction *guessBlock; /* MR10 */ - int singleAlt; /* MR10 */ - int lastAltEmpty; /* MR23 */ - - savetkref = tokensRefdInBlock; - require(q->ntype == nJunction, "genLoopBlk: not junction"); - require(q->jtype == aLoopBlk, "genLoopBlk: not loop block"); - - if ( q->visited ) return; - q->visited = TRUE; - - /* first_item_is_guess_block doesn't care what kind of node it is */ - - guessBlock=first_item_is_guess_block( (Junction *) q->p1); /* MR10 */ - singleAlt=q->p2==NULL; /* MR10 */ - - if (singleAlt && !guessBlock) /* MR10 */ /* only one alternative? */ - { - if ( DemandLookahead ) { - if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);} - else gen1("look(%d);\n", max_k); - } - gen("while ( "); - if ( begin!=NULL ) genExpr(begin); - else genExpr(q); - /* if no predicates have been hoisted for this single alt (..)* - * do so now - */ - require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); - if ( ParseWithPredicates && begin->predicate==NULL ) - { - Predicate *a = MR_find_predicates_and_supp((Node *)q->p1); - require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); - - if ( a!=NULL ) - { - _gen("&&"); - a=genPredTreeMain(a, (Node *)q); /* MR10 */ - } -/* MR10 */ if (MRhoisting) { -/* MR10 */ predicate_free(a); -/* MR10 */ }; - } - _gen(" ) {\n"); - tabs++; - TRANS(q->p1); - if ( !GenCC ) gen1("zzLOOP(zztasp%d);\n", BlkLevel-1); - if ( DemandLookahead ) { - if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);} - else gen1("look(%d);\n", max_k); - } - --tabs; - gen("}\n"); - freeBlkFsets(q); - q->visited = FALSE; - tokensRefdInBlock = savetkref; - return; - } - gen("for (;;) {\n"); /* MR20 G. Hobbelt */ - tabs++; -/* MR6 */ -/* MR6 "begin" can never be null when called from genLoopBegin */ -/* MR6 because q==(Junction *)begin->p1 and we know q is valid */ -/* MR6 */ -/* MR6 from genLoopBegin: */ -/* MR6 */ -/* MR6 if ( LL_k>1 && !set_nil(q->fset[2]) ) */ -/* MR6 genLoopBlk( q, (Junction *)q->p1, q, max_k ); */ -/* MR6 else genLoopBlk( q, (Junction *)q->p1, NULL, max_k ); */ -/* MR6 */ - if ( begin!=NULL ) - { - if ( DemandLookahead ) - { - if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);} - else gen1("look(%d);\n", max_k); - } - /* The bypass arc of the (...)* predicts what to do when you fail, but - * ONLY after having tested the loop start expression. To avoid this, - * we simply break out of the (...)* loop when we find something that - * is not in the prediction of the loop (all alts thereof). - */ - gen("if ( !("); - -/*** TJP says: It used to use the prediction expression for the bypass arc - of the (...)*. HOWEVER, if a non LL^1(k) decision was found, this - thing would miss the ftree stored in the aLoopBegin node and generate - an LL^1(k) decision anyway. - - *** genExpr((Junction *)begin->p2); - ***/ - - genExpr((Junction *)begin); - _gen(")) break;\n"); - - } - - /* generate code for terminating loop (this is optional branch) */ - - f = genBlk(q, aLoopBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */); - set_free(f); - freeBlkFsets(q); - - /* generate code for terminating loop (this is optional branch) */ - -/* MR6 */ -/* MR6 30-May-97 Bug reported by Manuel Ornato */ -/* MR6 A definite bug involving the exit from a loop block */ -/* MR6 In 1.23 and later versions (including 1.33) Instead */ -/* MR6 exiting the block and reporting a syntax error the */ -/* MR6 code loops forever. */ -/* MR6 Looking at 1.20 which generates proper code it is not */ -/* MR6 clear which of two changes should be undone. */ -/* MR6 This is my best guess. */ -/* MR6 From earlier MR6 note we know that begin can never be */ -/* MR6 null when genLoopBlk called from genLoopBegin */ -/* MR6 */ -/* MR6 */ if ( begin==NULL) { -/* MR6 */ /* code for exiting loop "for sure" */ -/* MR6 */ gen("/* Suppressed by MR6 */ /*** else break; ***/\n"); -/* MR6 */ }; - -/* MR10 */if (singleAlt && guessBlock) { -/* MR10 */ tabs--; -/* MR6 */ gen("} else break; /* MR6 code for exiting loop \"for sure\" */\n"); -/* MR10 */ need_right_curly--; -/* MR10 */ } else { -/* MR6 */ gen("else break; /* MR6 code for exiting loop \"for sure\" */\n"); -/* MR10 */ }; - - { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} } - if ( !GenCC ) gen1("zzLOOP(zztasp%d);\n", BlkLevel-1); - --tabs; - gen("}\n"); - q->visited = FALSE; - tokensRefdInBlock = savetkref; -} - -/* - * Generate code for a loop blk of form: - * - * |---| - * v | - * --o-->o-->o-G-o-->o-- - * | ^ - * v | - * o-----------o - * - * q->end points to the last node (far right) in the blk. - * - * Note that q->end->jtype must be 'EndBlk'. - * - * Generate code roughly of the following form: - * - * do { - * ... code for alternatives ... - * } while ( First Set of aLoopBlk ); - * - * OR if > 1 alternative - * - * do { - * ... code for alternatives ... - * else break; - * } while ( 1 ); - */ -void -#ifdef __USE_PROTOS -genLoopBegin( Junction *q ) -#else -genLoopBegin( q ) -Junction *q; -#endif -{ - set f; - int i; - int max_k; - set savetkref; - savetkref = tokensRefdInBlock; - require(q!=NULL, "genLoopBegin: invalid node and/or rule"); - require(q->ntype == nJunction, "genLoopBegin: not junction"); - require(q->jtype == aLoopBegin, "genLoopBegin: not loop block"); - require(q->p2!=NULL, "genLoopBegin: invalid Loop Graph"); - - OutLineInfo(output,q->line,FileStr[q->file]); - - BLOCK_Preamble(q); - BlkLevel++; - BlockPreambleOption(q,q->pFirstSetSymbol); /* MR21 */ - f = First(q, 1, aLoopBegin, &max_k); - /* If not simple LL(1), must specify to start at LoopBegin, not LoopBlk */ - if ( LL_k>1 && !set_nil(q->fset[2]) ) - genLoopBlk( q, (Junction *)q->p1, q, max_k ); - else genLoopBlk( q, (Junction *)q->p1, NULL, max_k ); - - for (i=1; i<=CLL_k; i++) set_free(q->fset[i]); - for (i=1; i<=CLL_k; i++) set_free(((Junction *)q->p2)->fset[i]); - --BlkLevel; - BLOCK_Tail(); - set_free(f); - tokensRefdInBlock = savetkref; -/* MR21 */ if (MR_BlkErr) { -/* MR21 */ set f, fArray[2]; -/* MR21 */ f = ComputeErrorSet(q,1,0 /* use plus block bypass ? */ ); -/* MR21 */ fArray[0]= empty; -/* MR21 */ fArray[1]= set_dup(f); -/* MR21 */ gen("if ("); -/* MR21 */ genExprSets(fArray,1); /* note: destroys set arguments */ -/* MR21 */ _gen(") { /* MR21 option -mrblksynerr */\n"); -/* MR21 */ tabs++; -/* MR21 */ tab(); -/* MR21 */ _gen("/* nothing */ }\n"); -/* MR21 */ tab(); -/* MR21 */ makeErrorClause(q,f,1,0 /* use plus block bypass ? */ ); /* frees set */ -/* MR21 */ tabs--; -/* MR21 */ }; - if (q->end->p1 != NULL) TRANS(q->end->p1); -} - -/* - * Generate code for a loop blk of form: - * - * |---| - * v | - * --o-G-o-->o-- - * - * q->end points to the last node (far right) in the blk. - * Note that q->end->jtype must be 'EndBlk'. - * - * Generate code roughly of the following form: - * - * do { - * ... code for alternatives ... - * } while ( First Set of aPlusBlk ); - * - * OR if > 1 alternative - * - * do { - * ... code for alternatives ... - * else if not 1st time through, break; - * } while ( 1 ); - */ -void -#ifdef __USE_PROTOS -genPlusBlk( Junction *q ) -#else -genPlusBlk( q ) -Junction *q; -#endif -{ - int max_k; - set f; - int need_right_curly; - int lastAltEmpty; /* MR23 */ - set savetkref; - Junction *guessBlock; /* MR10 */ - int singleAlt; /* MR10 */ - - savetkref = tokensRefdInBlock; - require(q!=NULL, "genPlusBlk: invalid node and/or rule"); - require(q->ntype == nJunction, "genPlusBlk: not junction"); - require(q->jtype == aPlusBlk, "genPlusBlk: not Plus block"); - require(q->p2 != NULL, "genPlusBlk: not a valid Plus block"); - - if ( q->visited ) return; - q->visited = TRUE; - OutLineInfo(output,q->line,FileStr[q->file]); - BLOCK_Preamble(q); - BlkLevel++; - - BlockPreambleOption((Junction *)q, q->pFirstSetSymbol); /* MR21 */ - - /* first_item_is_guess_block doesn't care what kind of node it is */ - - guessBlock=first_item_is_guess_block( (Junction *)q->p1); /* MR10 */ - - /* if the ignore flag is set on the 2nd alt and that alt is empty, - * then it is the implied optional alternative that we added for (...)+ - * and, hence, only 1 alt. - */ - -/* MR10 Reported by Pulkkinen Esa (esap@cs.tut.fi) - * Outer code for guess blocks ignored when there is only one alt - * for a (...)+ block. - * Force use of regular code rather than "optimized" code for that case - */ - - singleAlt=( ( (Junction *) q->p2)->p2 == NULL) && - ( ( (Junction *) q->p2)->ignore ); /* only one alternative? */ - - if (singleAlt && !guessBlock) /* MR10 */ - { - - Predicate *a=NULL; - /* if the only alt has a semantic predicate, hoist it; must test before - * entering loop. - */ - if ( ParseWithPredicates ) - { - require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); - a = MR_find_predicates_and_supp((Node *)q); - require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty"); - - if ( a!=NULL ) { - gen("if ("); - a=genPredTreeMain(a, (Node *)q); /* MR10 */ - _gen(") {\n"); - } - } - gen("do {\n"); - tabs++; - TRANS(q->p1); - if ( !GenCC ) gen1("zzLOOP(zztasp%d);\n", BlkLevel-1); - f = First(q, 1, aPlusBlk, &max_k); - if ( DemandLookahead ) { - if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);} - else gen1("look(%d);\n", max_k); - } - --tabs; - gen("} while ( "); - if ( q->parm!=NULL && q->predparm ) _gen1("(%s) && ", q->parm); - genExpr(q); - if ( ParseWithPredicates && a!=NULL ) - { - if (! MR_comparePredicates(q->predicate,a)) { - _gen("&&"); - a=genPredTreeMain(a, (Node *)q); /* MR10 */ - }; - } - _gen(" );\n"); - if ( ParseWithPredicates && a!=NULL ) gen("}\n"); - --BlkLevel; - BLOCK_Tail(); - q->visited = FALSE; - freeBlkFsets(q); - set_free(f); - tokensRefdInBlock = savetkref; -/* MR21 */ if (MR_BlkErr) { -/* MR21 */ set f, fArray[2]; -/* MR21 */ f = ComputeErrorSet(q,1,1 /* use plus block bypass ? */ ); -/* MR21 */ fArray[0]= empty; -/* MR21 */ fArray[1]= set_dup(f); -/* MR21 */ gen("if ("); -/* MR21 */ genExprSets(fArray,1); /* note: destroys set arguments */ -/* MR21 */ _gen(") { /* MR21 option -mrblksynerr */\n"); -/* MR21 */ tabs++; -/* MR21 */ tab(); -/* MR21 */ _gen("/* nothing */ }\n"); -/* MR21 */ tab(); -/* MR21 */ makeErrorClause(q,f,1,1 /* use plus block bypass ? */ ); /* frees set */ -/* MR21 */ tabs--; -/* MR21 */ }; - if (q->end->p1 != NULL) TRANS(q->end->p1); -/* MR10 */ if (MRhoisting) { -/* MR10 */ predicate_free(a); -/* MR10 */ }; - return; - } - gen("do {\n"); - tabs++; - f = genBlk(q, aPlusBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */); -/* MR6 */ -/* MR6 Sinan Karasu (sinan@tardis.ds.boeing.com) */ -/* MR6 Failed to turn off guess mode when leaving block */ -/* MR6 */ -/* MR6 */ if ( has_guess_block_as_last_item(q) ) { -/* MR10 */ gen("/* MR10 ()+ */ else {\n"); -/* MR10 */ tabs++; -/* MR10 */ need_right_curly++; -/* MR10 */ gen("/* MR10 ()+ */ if ( !zzrv ) zzGUESS_DONE;\n"); -/* MR6 */ gen("/* MR10 ()+ */ if ( zzcnt > 1 ) break;\n"); -/* MR10 */ } else { -/* MR10 */ gen("/* MR10 ()+ */ else {\n"); -/* MR10 */ tabs++; -/* MR10 */ need_right_curly++; -/* MR10 */ gen("if ( zzcnt > 1 ) break;\n"); -/* MR10 */ }; - -/* MR21 */ if (MR_BlkErr && 1 >= max_k) { -/* MR21 */ set f; -/* MR21 */ f = ComputeErrorSet(q,1,0 /* use plus block bypass ? */ ); -/* MR21 */ tabs++; -/* MR21 */ tab(); -/* MR21 */ makeErrorClause(q,f,1,0 /* use plus block bypass ? */ ); /* frees set */ -/* MR21 */ tabs--; -/* MR21 */ } -/* MR21 */ else { - tab(); - makeErrorClause(q,f,max_k,1 /* use plus block bypass ? */); - /* MR21 I think this generates the wrong set ? */ - /* MR21 because it includes the plus block bypass ? */ - /* MR21 but I'm afraid to change it without additional checking */ - } - - { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} } - freeBlkFsets(q); - gen("zzcnt++;"); - if ( !GenCC ) _gen1(" zzLOOP(zztasp%d);", BlkLevel-1); - _gen("\n"); - if ( DemandLookahead ) { - if ( !GenCC ) {gen1("LOOK(%d);\n", max_k);} - else gen1("look(%d);\n", max_k); - } - --tabs; - if ( q->parm!=NULL && q->predparm ) {gen1("} while (%s);\n", q->parm);} - else gen("} while ( 1 );\n"); - --BlkLevel; - BLOCK_Tail(); - q->visited = FALSE; - tokensRefdInBlock = savetkref; -/* MR21 */ if (MR_BlkErr) { -/* MR21 */ set f, fArray[2]; -/* MR21 */ f = ComputeErrorSet(q,1,1 /* use plus block bypass ? */ ); -/* MR21 */ fArray[0]= empty; -/* MR21 */ fArray[1]= set_dup(f); -/* MR21 */ gen("if ("); -/* MR21 */ genExprSets(fArray,1); /* note: destroys set arguments */ -/* MR21 */ _gen(") { /* MR21 option -mrblksynerr */\n"); -/* MR21 */ tabs++; -/* MR21 */ tab(); -/* MR21 */ _gen("/* nothing */ }\n"); -/* MR21 */ tab(); -/* MR21 */ makeErrorClause(q,f,1,1 /* use plus block bypass ? */ ); /* frees set */ -/* MR21 */ tabs--; -/* MR21 */ }; - if (q->end->p1 != NULL) TRANS(q->end->p1); -} - -/* - * Generate code for a sub blk of alternatives of form: - * - * --o-G1--o-- - * | ^ - * v /| - * o-G2-o| - * | ^ - * v | - * .......... - * | ^ - * v / - * o-Gn-o - * - * q points to the 1st junction of blk (upper-left). - * q->end points to the last node (far right) in the blk. - * Note that q->end->jtype must be 'EndBlk'. - * The last node in every alt points to q->end. - * - * Generate code of the following form: - * if ( First(G1) ) { - * ...code for G1... - * } - * else if ( First(G2) ) { - * ...code for G2... - * } - * ... - * else { - * ...code for Gn... - * } - */ - -void -#ifdef __USE_PROTOS -genSubBlk( Junction *q ) -#else -genSubBlk( q ) -Junction *q; -#endif -{ - int max_k; - set f; - int need_right_curly; - int lastAltEmpty; /* MR23 */ - set savetkref; - savetkref = tokensRefdInBlock; - require(q->ntype == nJunction, "genSubBlk: not junction"); - require(q->jtype == aSubBlk, "genSubBlk: not subblock"); - - OutLineInfo(output,q->line,FileStr[q->file]); - BLOCK_Preamble(q); - BlkLevel++; - BlockPreambleOption(q,q->pFirstSetSymbol); /* MR21 */ - f = genBlk(q, aSubBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */); - -/* MR23 - Bypass error clause generation when exceptions are used in a sub block - in which the last alternative is epsilon. Example: "(A | B | )". - See multi-line note in genBlk near call to isEmptyAlt. -*/ - if (FoundException && lastAltEmpty) { - gen("/* MR23 skip error clause for (...| epsilon) when exceptions in use */\n"); - } - else { - if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k,0 /* use plus block bypass ? */ );} - } - - { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} } - freeBlkFsets(q); - --BlkLevel; - BLOCK_Tail(); - - if ( q->guess ) - { - gen("zzGUESS_DONE\n"); - } - - /* must duplicate if (alpha)?; one guesses (validates), the - * second pass matches */ - if ( q->guess && analysis_point(q)==q ) - { - OutLineInfo(output,q->line,FileStr[q->file]); - BLOCK_Preamble(q); - BlkLevel++; - f = genBlk(q, aSubBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */); - if ( q->p2 != NULL ) {tab(); makeErrorClause(q,f,max_k,0 /* use plus block bypass ? */);} - { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} } - freeBlkFsets(q); - --BlkLevel; - BLOCK_Tail(); - } - - tokensRefdInBlock = savetkref; - if (q->end->p1 != NULL) TRANS(q->end->p1); -} - -static int TnodesAllocatedPrevRule=0; - -/* - * Generate code for a rule. - * - * rule--> o-->o-Alternatives-o-->o - * Or, - * rule--> o-->o-Alternative-o-->o - * - * The 1st junction is a RuleBlk. The second can be a SubBlk or just a junction - * (one alternative--no block), the last is EndRule. - * The second to last is EndBlk if more than one alternative exists in the rule. - * - * To get to the init-action for a rule, we must bypass the RuleBlk, - * and possible SubBlk. - * Mark any init-action as generated so genBlk() does not regenerate it. - */ -void -#ifdef __USE_PROTOS -genRule( Junction *q ) -#else -genRule( q ) -Junction *q; -#endif -{ - - const char * returnValueInitializer; - -do { /* MR10 Change recursion into iteration */ - - int max_k; - set follow, rk, f; - ActionNode *a; - RuleEntry *r; - int lastAltEmpty; /* MR23 */ - static int file = -1; - int need_right_curly; - require(q->ntype == nJunction, "genRule: not junction"); - require(q->jtype == RuleBlk, "genRule: not rule"); - -/* MR14 */ require (MR_BackTraceStack.count == 0,"-alpha MR_BackTraceStack.count != 0"); -/* MR14 */ MR_pointerStackReset(&MR_BackTraceStack); -/* MR14 */ if (AlphaBetaTrace) MR_MaintainBackTrace=1; - - CurRule=q->rname; /* MR11 */ - - r = (RuleEntry *) hash_get(Rname, q->rname); - if ( r == NULL ) warnNoFL("Rule hash table is screwed up beyond belief"); - if ( q->file != file ) /* open new output file if need to */ - { -/* MR6 */ -/* MR6 Simpler to debug when output goes to stdout rather than a file */ -/* MR6 */ -/* MR6 */ if (UseStdout) { -/* MR6 */ output = stdout; -/* MR6 */ } else { -/* MR6 */ if ( output != NULL) fclose( output ); -/* MR6 */ output = fopen(OutMetaName(outname(FileStr[q->file])), "w"); -/* MR6 */ }; - require(output != NULL, "genRule: can't open output file"); - -#ifdef SPECIAL_FOPEN - special_fopen_actions(OutMetaName(outname(FileStr[q->file]))); /* MR1 */ -#endif - if ( file == -1 ) genHdr1(q->file); - else genHdr(q->file); - file = q->file; - } - - if (InfoM) { - fprintf(stderr," rule %s\n",q->rname); - fflush(output); - }; - -#if 0 - if (strcmp(q->rname,"***debug***") == 0) { - fprintf(stderr,"***debug*** %s reached\n",q->rname); - MR_break(); - }; -#endif - - DumpFuncHeader(q,r); - tabs++; - - /* MR23 - - If there is a single return value then it can be initialized in - the declaration using assignment syntax. If there are multiple - return values then antlr creates a struct and initialization takes - place element by element for each element of the struct. For - multiple elements the initialization is by assignment so we have - to wait until all declarations are done before emitting that code - - because of restrictions in C which don't exist in C++. - - In the past (before MR23) the only kind of initialization was - the PURIFY macro which was just a memset() of 0. Now we allow - the user to specify an initial value. PURIFY is still used in C - mode because C does not have constructors. However, PURIFY is - not used in C++ mode because it might overwrite information created - by elements which have their own ctor. - - */ - - if ( q->ret!=NULL ) - { - if ( hasMultipleOperands(q->ret) ) /* MR23 */ - { - - /* Emit initialization code later. */ - - gen1("struct _rv%d _retv;\n",r->rulenum); - } - else - { - /* Emit initialization code now. */ - - tab(); - DumpType(q->ret, output); - returnValueInitializer = getInitializer(q->ret); - if (returnValueInitializer == NULL) { /* MR23 */ - gen(" _retv;\n"); /* MR1 MR3 */ - } /* MR23 */ - else { /* MR23 */ - gen1(" _retv = %s;\n", returnValueInitializer); /* MR23 */ - } /* MR23 */ - } - } - - OutLineInfo(output,q->line,FileStr[q->file]); - - if (InfoM) { - fflush(output); - }; - - gen("zzRULE;\n"); - if ( FoundException ) - { - gen("int _sva=1;\n"); - } - if ( GenCC && GenAST ) - gen("ASTBase *_ast = NULL, *_sibling = NULL, *_tail = NULL;\n"); - if ( GenCC ) genTokenPointers(q); - if ( GenCC&&GenAST ) genASTPointers(q); - if ( q->el_labels!=NULL ) genElementLabels(q->el_labels); - if ( FoundException ) gen("int _signal=NoSignal;\n"); - - if ( !GenCC ) gen1("zzBLOCK(zztasp%d);\n", BlkLevel); - -/* MR10 */ /* move zzTRACEIN to before init action */ - -/* MR10 */ if ( TraceGen ) { -/* MR10 */ if ( GenCC ) {gen1("zzTRACEIN(\"%s\");\n", q->rname);} -/* MR10 */ else gen1("zzTRACEIN((ANTLRChar *)\"%s\");\n", q->rname); -/* MR10 */ } - -/* MR7 Moved PURIFY() to after all local variables have been declared */ -/* MR7 so that the generated code is valid C as well as C++ */ -/* MR7 Jan Mikkelsen 10-June-1997 */ - - - /* - MR23 Do the PURIFY macro only for C mode. - C++ users should use constructors or initialization expressions. - */ - - if ( q->ret != NULL ) /* MR7 */ - { /* MR7 */ - if (hasMultipleOperands(q->ret)) { /* MR23 */ - if (PURIFY == TRUE) { - gen1("PCCTS_PURIFY(_retv,sizeof(struct _rv%d))\n",r->rulenum); /* MR23 */ - } - } /* MR7 */ - else { /* MR7 */ - - /* MR23 - If there were only one return value operand and - it had an initializer then it would have been - initiailized in the declaration. - */ - - returnValueInitializer = getInitializer(q->ret); /* MR23 */ - if (returnValueInitializer == NULL) { /* MR23 */ - if (PURIFY == TRUE) { - gen("PCCTS_PURIFY(_retv,sizeof("); /* MR23 */ - DumpType(q->ret, output); /* MR7 */ - gen("))\n"); /* MR7 */ - } - } /* MR23 */ - } /* MR7 */ - - if (hasMultipleOperands(q->ret)) { /* MR23 */ - DumpInitializers(output, r, q->ret); /* MR23 */ - } - - } - if ( !GenCC ) gen("zzMake0;\n"); - if ( FoundException ) gen("*_retsignal = NoSignal;\n"); - - if ( !GenCC ) gen("{\n"); - - if ( has_guess_block_as_first_item((Junction *)q->p1) ) - { - gen("zzGUESS_BLOCK\n"); - } - - /* L o o k F o r I n i t A c t i o n */ - if ( ((Junction *)q->p1)->jtype == aSubBlk ) - a = findImmedAction( ((Junction *)q->p1)->p1 ); - else - a = findImmedAction( q->p1 ); /* only one alternative in rule */ - if ( a!=NULL && !a->is_predicate) - { - /* MR21 */ if (!a->noHoist) dumpActionPlus(a, a->action, output, tabs, a->file, a->line, 1); - a->done = 1; /* ignore action. We have already handled it */ - } - - BlkLevel++; - q->visited = TRUE; /* mark RULE as visited for FIRST/FOLLOW */ - BlockPreambleOption((Junction *)q->p1, NULL); /* MR21 */ - f = genBlk((Junction *)q->p1, RuleBlk, &max_k, &need_right_curly, &lastAltEmpty /* MR23 */); - if ( q->p1 != NULL ) - if ( ((Junction *)q->p1)->p2 != NULL ) - {tab(); makeErrorClause((Junction *)q->p1,f,max_k,0 /* use plus block bypass ? */);} - { int i; for (i=1; i<=need_right_curly; i++) {tabs--; gen("}\n");} } - freeBlkFsets((Junction *)q->p1); - q->visited = FALSE; - --BlkLevel; - if ( !GenCC ) gen1("zzEXIT(zztasp%d);\n", BlkLevel); - - genTraceOut(q); - - if ( q->ret!=NULL ) gen("return _retv;\n") else gen("return;\n"); - /* E r r o r R e c o v e r y */ - NewSet(); - rk = empty; - -/* MR14 */ if (r->dontComputeErrorSet) { -/* MR14 */ follow=empty; - } else { - MR_pointerStackReset(&MR_BackTraceStack); /* MR14 */ - MR_ErrorSetComputationActive=1; - REACH(q->end, 1, &rk, follow); - MR_ErrorSetComputationActive=0; - require (MR_BackTraceStack.count == 0,"K: MR_BackTraceStack.count != 0"); - } - - FillSet( follow ); - set_free( follow ); - - /* MR20 G. Hobbelt - Isn't it so that "fail:" is ONLY referenced when: - - !FoundException || FoundGuessBlk ? - - Therefore add the "if" around this piece of code generation... - - Should guessing mode also use _handler label instead of "fail" - when exception handling is active? gen can automatically put - "if (guessing)" there so as to skip all kinds of user code. - - */ - - if ( !FoundException || FoundGuessBlk ) /* MR20 G. Hobbelt */ - { /* MR20 G. Hobbelt */ - _gen("fail:\n"); - if ( !GenCC ) gen("zzEXIT(zztasp1);\n"); - if ( FoundGuessBlk ) { - if ( !GenCC ) {gen("if ( zzguessing ) zzGUESS_FAIL;\n");} - else gen("if ( guessing ) zzGUESS_FAIL;\n"); - } - if ( q->erraction!=NULL ) - dumpAction(q->erraction, output, tabs, q->file, q->line, 1); - if ( GenCC ) - { - gen1("syn(zzBadTok, %s, zzMissSet, zzMissTok, zzErrk);\n", - r->egroup==NULL?"(ANTLRChar *)\"\"":r->egroup); - } - else - { - gen1("zzsyn(zzMissText, zzBadTok, %s, zzMissSet, zzMissTok, zzErrk, zzBadText);\n", - r->egroup==NULL?"(ANTLRChar *)\"\"":r->egroup); - } - gen3("%sresynch(setwd%d, 0x%x);\n", GenCC?"":"zz", wordnum, 1<ret!=NULL ) { - genTraceOut(q); - gen("return _retv;\n"); - } else if ( q->exceptions!=NULL ) { - genTraceOut(q); - gen("return;\n"); - } else if (!FoundException) { /* MR10 */ - genTraceOut(q); /* MR10 */ - }; - - } /* MR20 G. Hobbelt */ - - if ( !GenCC ) gen("}\n"); - - /* Gen code for exception handlers */ - /* make sure each path out contains genTraceOut() */ - - if ( q->exceptions!=NULL ) - { - - gen("/* exception handlers */\n"); - - dumpExceptions(q->exceptions); - - if ( !r->has_rule_exception ) - { - _gen("_handler:\n"); - gen("zzdflthandlers(_signal,_retsignal);\n"); - } -/* MR20 G. Gobbelt The label "adios" is never referenced */ - -#if 0 - _gen("_adios:\n"); -#endif - if ( q->ret!=NULL ) { - genTraceOut(q); - gen("return _retv;\n"); - } - else { - genTraceOut(q); - gen("return;\n"); - } - } - else if ( FoundException ) - { - _gen("_handler:\n"); - gen("zzdflthandlers(_signal,_retsignal);\n"); - -/* MR1 */ -/* MR1 7-Apr-97 Fix suggested by: John Bair (jbair@iftime.com) */ -/* MR1 */ - - if ( q->ret != NULL) { /* MR1 */ - genTraceOut(q); /* MR10 */ - gen("return _retv;\n"); /* MR1 */ - } else { /* MR1 */ - genTraceOut(q); /* MR10 */ - gen("return;\n") ; /* MR1 */ - }; /* MR1 */ - } - - tabs--; - gen("}\n"); - -/* MR10 Tired of looking at stacks that are as deep as the number of */ -/* MR10 rules. Changes recursion to iteration. */ - - MR_releaseResourcesUsedInRule( (Node *) q ); /* MR10 */ - - if (InfoT) { - fprintf(output,"\n/* tnodes created for rule %s: %d */\n", - q->rname, (TnodesAllocated-TnodesAllocatedPrevRule) ); - }; - - TnodesAllocatedPrevRule=TnodesAllocated; - - if (q->p2 == NULL) dumpAfterActions( output ); - q=(Junction *)q->p2; - require(q==NULL || q->jtype==RuleBlk,"RuleBlk p2 does not point to another RuleBlk"); - -} while (q != NULL); - -/**** The old code ****/ -/**** if ( q->p2 != NULL ) {TRANS(q->p2);} ****/ /* generate code for next rule too */ -/**** else dumpAfterActions( output ); ****/ - -} - - -/* This is for the function definition, not the declaration. */ - -static void -#ifdef __USE_PROTOS -DumpFuncHeader( Junction *q, RuleEntry *r ) -#else -DumpFuncHeader( q, r ) -Junction *q; -RuleEntry *r; -#endif -{ -/* */ -/* MR1 10-Apr-97 MR1 Simplify insertion of commas in function header */ -/* */ - int needComma; /* MR1 */ - - - /* A N S I */ - _gen("\n"); - if ( q->ret!=NULL ) - { - if ( hasMultipleOperands(q->ret) ) /* MR23 */ - { - if (GenCC) gen2("%s::_rv%d\n", CurrentClassName, r->rulenum) - else gen1("struct _rv%d\n",r->rulenum); - } - else - { - DumpType(q->ret, output); - gen("\n"); - } - } - else - { - _gen("void\n"); - } -/* MR1 */ -/* MR1 10-Apr-97 133MR1 Replace __STDC__ with __USE_PROTOS */ -/* MR1 */ - if ( !GenCC ) _gen("#ifdef __USE_PROTOS\n"); /* MR1 */ - if ( !GenCC ) gen2("%s%s(", RulePrefix, q->rname) - else gen3("%s::%s%s(", CurrentClassName, RulePrefix,q->rname); - - /* If we generate C++ method names, we must hide default arguments */ - /* which can appear in the parameter declaration list. */ - /* NOTICE: this is done only here, for the method definition, but */ - /* not for the method declaration inside the class */ - /* definition. This is exactly the behaviour defined in */ - /* C++ standard for default paramters. */ - - DumpANSIFunctionArgDef(output,q, 0 /* emit initializers ? */); - _gen("\n"); - - if ( GenCC ) { - gen("{\n"); - return; - } - - /* K & R */ - gen("#else\n"); - gen2("%s%s(", RulePrefix, q->rname); - needComma=0; /* MR1 */ - if ( GenAST ) /* MR1 */ - { /* MR1 */ - _gen("_root"); /* MR1 */ - needComma=1; /* MR1 */ - } /* MR1 */ - if ( FoundException ) /* MR1 */ - { /* MR1 */ - if (needComma) {_gen(",");needComma=0;}; /* MR1 */ - _gen("_retsignal"); /* MR1 */ - needComma=1; /* MR1 */ - } /* MR1 */ -/* MR5 Change below by Jan Mikkelsen (janm@zeta.org.au) 26-May-97 MR5 */ - DumpListOfParmNames( q->pdecl, output, needComma ); /* MR5 */ - gen(")\n"); - if ( GenAST ) gen("AST **_root;\n"); - if ( FoundException ) gen("int *_retsignal;\n"); - DumpOldStyleParms( q->pdecl, output ); - gen("#endif\n"); - gen("{\n"); -} - -void -#ifdef __USE_PROTOS -DumpANSIFunctionArgDef(FILE *f, Junction *q, int bInitializer) -#else -DumpANSIFunctionArgDef(f,q,bInitializer) -FILE *f; -Junction *q; -int bInitializer; -#endif -{ - if ( GenAST ) - { - if ( GenCC ) {fprintf(f,"ASTBase **_root");} - else fprintf(f,"AST**_root"); - if ( !FoundException && q->pdecl!=NULL ) fprintf(f,","); - } - if ( FoundException ) - { - if ( GenAST ) fprintf(f,","); - fprintf(f,"int *_retsignal"); - if ( q->pdecl!=NULL ) { - fprintf(f,","); - } - } - if ( q->pdecl!=NULL ) { - DumpFormals(f, q->pdecl, bInitializer); /* MR23 */ - } - else { - if ( !GenAST && !FoundException ) { - fprintf(f,"void"); - } - } - fprintf(f,")"); -} - -void -#ifdef __USE_PROTOS -genJunction( Junction *q ) -#else -genJunction( q ) -Junction *q; -#endif -{ - require(q->ntype == nJunction, "genJunction: not junction"); - require(q->jtype == Generic, "genJunction: not generic junction"); - - if ( q->p1 != NULL ) TRANS(q->p1); - if ( q->p2 != NULL ) TRANS(q->p2); -} - -void -#ifdef __USE_PROTOS -genEndBlk( Junction *q ) -#else -genEndBlk( q ) -Junction *q; -#endif -{ -} - -void -#ifdef __USE_PROTOS -genEndRule( Junction *q ) -#else -genEndRule( q ) -Junction *q; -#endif -{ -} - -void -#ifdef __USE_PROTOS -genHdr( int file ) -#else -genHdr( file ) -int file; -#endif -{ - int i; - - _gen("/*\n"); - _gen(" * A n t l r T r a n s l a t i o n H e a d e r\n"); - _gen(" *\n"); - _gen(" * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n"); - _gen(" * Purdue University Electrical Engineering\n"); - _gen(" * With AHPCRC, University of Minnesota\n"); - _gen1(" * ANTLR Version %s\n", Version); - _gen(" *\n"); -/* MR10 */ _gen(" * "); -/* MR10 */ for (i=0 ; i < Save_argc ; i++) { -/* MR10 */ _gen(" "); -/* MR10 */ _gen(Save_argv[i]); -/* MR10 */ }; - _gen("\n"); - _gen(" *\n"); - _gen(" */\n\n"); - if (FirstAction != NULL ) dumpAction( FirstAction, output, 0, -1, 0, 1); /* MR11 MR15b */ - _gen1("#define ANTLR_VERSION %s\n", VersionDef); - _gen("#include \"pcctscfg.h\"\n"); - _gen("#include \"pccts_stdio.h\"\n"); - if ( strcmp(ParserName, DefaultParserName)!=0 ) - _gen2("#define %s %s\n", DefaultParserName, ParserName); - if ( strcmp(ParserName, DefaultParserName)!=0 ) - {_gen1("#include \"%s\"\n", RemapFileName);} - OutLineInfo(output,1,FileStr[file]); - if ( GenCC ) { - if ( UserTokenDefsFile != NULL ) - fprintf(output, "#include %s\n", UserTokenDefsFile); - else - fprintf(output, "#include \"%s\"\n", DefFileName); - } - - if ( HdrAction != NULL ) dumpAction( HdrAction, output, 0, -1, 0, 1); - if ( !GenCC && FoundGuessBlk ) - { - _gen("#define ZZCAN_GUESS\n"); - _gen("#include \"pccts_setjmp.h\"\n"); /* MR15 K.J. Cummings (cummings@peritus.com) */ - } - if ( FoundException ) - { - _gen("#define EXCEPTION_HANDLING\n"); - _gen1("#define NUM_SIGNALS %d\n", NumSignals); - } - if ( !GenCC && OutputLL_k > 1 ) _gen1("#define LL_K %d\n", OutputLL_k); - if ( GenAST&&!GenCC ) _gen("#define GENAST\n\n"); - if ( GenAST ) { - if ( GenCC ) {_gen1("#include \"%s\"\n\n", ASTBASE_H);} - else _gen("#include \"ast.h\"\n\n"); - } - if ( !GenCC && DemandLookahead ) _gen("#define DEMAND_LOOK\n\n"); -#ifdef DUM - if ( !GenCC && LexGen ) { - _gen1("#define zzEOF_TOKEN %d\n", (TokenInd!=NULL?TokenInd[EofToken]:EofToken)); - } -#endif - /* ###WARNING: This will have to change when SetWordSize changes */ - if ( !GenCC ) _gen1("#define zzSET_SIZE %d\n", NumWords(TokenNum-1)*sizeof(unsigned)); - if (TraceGen) { - _gen("#ifndef zzTRACE_RULES\n"); /* MR20 */ - _gen("#define zzTRACE_RULES\n"); /* MR20 */ - _gen("#endif\n"); /* MR22 */ - }; - if ( !GenCC ) {_gen("#include \"antlr.h\"\n");} - else { - _gen1("#include \"%s\"\n", APARSER_H); - _gen1("#include \"%s.h\"\n", CurrentClassName); - } - if ( !GenCC ) { - if ( UserDefdTokens ) - {_gen1("#include %s\n", UserTokenDefsFile);} - /* still need this one as it has the func prototypes */ - _gen1("#include \"%s\"\n", DefFileName); - } - /* still need this one as it defines the DLG interface */ - if ( !GenCC ) _gen("#include \"dlgdef.h\"\n"); - if ( LexGen && GenCC ) _gen1("#include \"%s\"\n", DLEXERBASE_H); - if ( GenCC ) _gen1("#include \"%s\"\n", ATOKPTR_H); - if ( !GenCC && LexGen ) _gen1("#include \"%s\"\n", ModeFileName); - -/* MR10 Ofer Ben-Ami (gremlin@cs.huji.ac.il) */ -/* MR10 Finally, a definition of the Purify macro */ - - if (PURIFY == TRUE) { /* MR23 */ - _gen("\n/* MR23 In order to remove calls to PURIFY use the antlr"); /* MR23 */ - _gen(" -nopurify option */\n\n"); /* MR23 */ - _gen("#ifndef PCCTS_PURIFY\n"); - _gen("#define PCCTS_PURIFY(r,s) memset((char *) &(r),'\\0',(s));\n"); - _gen("#endif\n\n"); - } /* MR23 */ -} - -void -#ifdef __USE_PROTOS -genHdr1( int file ) -#else -genHdr1( file ) -int file; -#endif -{ - ListNode *p; - - genHdr(file); - if ( GenAST ) - { - if ( !GenCC ) { - _gen("#include \"ast.c\"\n"); - _gen("zzASTgvars\n\n"); - } - } - if ( !GenCC ) _gen("ANTLR_INFO\n"); - if ( BeforeActions != NULL ) - { - for (p = BeforeActions->next; p!=NULL; p=p->next) - { - UserAction *ua = (UserAction *)p->elem; - dumpAction( ua->action, output, 0, ua->file, ua->line, 1); - } - } - - if ( !FoundException ) return; - - if ( GenCC ) - { - _gen1("\nvoid %s::\n", CurrentClassName); - _gen("zzdflthandlers( int _signal, int *_retsignal )\n"); - _gen("{\n"); - } - else - { - _gen("\nvoid\n"); -/* MR1 */ -/* MR1 10-Apr-97 133MR1 Replace __STDC__ with __USE_PROTOS */ -/* MR1 */ - _gen("#ifdef __USE_PROTOS\n"); /* MR1 */ - _gen("zzdflthandlers( int _signal, int *_retsignal )\n"); - _gen("#else\n"); - _gen("zzdflthandlers( _signal, _retsignal )\n"); - _gen("int _signal;\n"); - _gen("int *_retsignal;\n"); - _gen("#endif\n"); - _gen("{\n"); - } - tabs++; - if ( DefaultExGroup!=NULL ) - { - dumpException(DefaultExGroup, 1); - if ( !hasDefaultException(DefaultExGroup) ) - { - gen("default :\n"); - tabs++; - gen("*_retsignal = _signal;\n"); - tabs--; - gen("}\n"); - } - } - else { - gen("*_retsignal = _signal;\n"); - } - - tabs--; - _gen("}\n\n"); -} - -void -#ifdef __USE_PROTOS -genStdPCCTSIncludeFile( FILE *f,char *gate ) /* MR10 */ -#else -genStdPCCTSIncludeFile( f , gate) /* MR10 */ -FILE *f; -char * gate; /* MR10 */ -#endif -{ -/* MR10 Ramanathan Santhanam (ps@kumaran.com) */ -/* MR10 Same preprocessor symbol use to gate stdpccts.h */ -/* MR10 even when two grammars are in use. */ -/* MR10 Derive gate symbol from -fh filename */ - - if (gate == NULL) { - fprintf(f,"#ifndef STDPCCTS_H\n"); /* MR10 */ - fprintf(f,"#define STDPCCTS_H\n"); /* MR10 */ - } else { - fprintf(f,"#ifndef STDPCCTS_%s_H\n",gate); /* MR10 */ - fprintf(f,"#define STDPCCTS_%s_H\n",gate); /* MR10 */ - }; - fprintf(f,"/*\n"); - if (gate == NULL) { - fprintf(f," * %s -- P C C T S I n c l u d e\n", stdpccts); - } else { - fprintf(f," * Standard PCCTS include file with -fh %s -- P C C T S I n c l u d e\n", stdpccts); - } - fprintf(f," *\n"); - fprintf(f," * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n"); - fprintf(f," * Purdue University Electrical Engineering\n"); - fprintf(f," * With AHPCRC, University of Minnesota\n"); - fprintf(f," * ANTLR Version %s\n", Version); - fprintf(f," */\n\n"); - - fprintf(f,"#ifndef ANTLR_VERSION\n"); - fprintf(f,"#define ANTLR_VERSION %s\n", VersionDef); - fprintf(f,"#endif\n\n"); - - if (FirstAction != NULL ) dumpAction(FirstAction, f, 0, -1, 0, 1); /* MR11 */ - - fprintf(f,"#include \"pcctscfg.h\"\n"); - fprintf(f,"#include \"pccts_stdio.h\"\n"); - if ( GenCC ) - { - if ( UserDefdTokens ) - fprintf(f, "#include %s\n", UserTokenDefsFile); - else { - fprintf(f, "#include \"%s\"\n", DefFileName); - } - - fprintf(f, "#include \"%s\"\n", ATOKEN_H); - - if ( HdrAction != NULL ) dumpAction( HdrAction, f, 0, -1, 0, 1); - - fprintf(f, "#include \"%s\"\n", ATOKENBUFFER_H); - - if ( OutputLL_k > 1 ) fprintf(f,"static const unsigned LL_K=%d;\n", OutputLL_k); - if ( GenAST ) { - fprintf(f, "#include \"%s\"\n", ASTBASE_H); - } - - if (TraceGen) { - fprintf(f,"#ifndef zzTRACE_RULES\n"); /* MR20 */ - fprintf(f,"#define zzTRACE_RULES\n"); /* MR20 */ - fprintf(f,"#endif\n"); /* MR22 */ - }; - - fprintf(f,"#include \"%s\"\n", APARSER_H); - fprintf(f,"#include \"%s.h\"\n", CurrentClassName); - if ( LexGen ) fprintf(f,"#include \"%s\"\n", DLEXERBASE_H); - fprintf(f, "#endif\n"); - return; - } - - if ( strcmp(ParserName, DefaultParserName)!=0 ) - fprintf(f, "#define %s %s\n", DefaultParserName, ParserName); - if ( strcmp(ParserName, DefaultParserName)!=0 ) - fprintf(f, "#include \"%s\"\n", RemapFileName); - if ( UserTokenDefsFile != NULL ) - fprintf(f, "#include %s\n", UserTokenDefsFile); - if ( HdrAction != NULL ) dumpAction( HdrAction, f, 0, -1, 0, 1); - if ( FoundGuessBlk ) - { - fprintf(f,"#define ZZCAN_GUESS\n"); - fprintf(f,"#include \"pccts_setjmp.h\"\n"); - } - if (TraceGen) { - fprintf(f,"#ifndef zzTRACE_RULES\n"); /* MR20 */ - fprintf(f,"#define zzTRACE_RULES\n"); /* MR20 */ - fprintf(f,"#endif\n"); /* MR22 */ - }; - if ( OutputLL_k > 1 ) fprintf(f,"#define LL_K %d\n", OutputLL_k); - if ( GenAST ) fprintf(f,"#define GENAST\n"); - if ( FoundException ) - { -/* MR1 7-Apr-97 1.33MR1 */ -/* MR1 Fix suggested by: */ -/* MR1 Francois-Xavier Fontaine (fontaine_f@istvax.ist.lu) */ - - fprintf(f,"#define EXCEPTION_HANDLING\n"); /* MR1 */ - fprintf(f,"#define NUM_SIGNALS %d\n", NumSignals); /* MR1 */ - } - if ( DemandLookahead ) fprintf(f,"#define DEMAND_LOOK\n"); -#ifdef DUM - if ( LexGen ) fprintf(f, "#define zzEOF_TOKEN %d\n", (TokenInd!=NULL?TokenInd[EofToken]:EofToken)); -#endif - /* ###WARNING: This will have to change when SetWordSize changes */ - fprintf(f, "#define zzSET_SIZE %d\n", NumWords(TokenNum-1)*sizeof(unsigned)); - if (TraceGen) { - fprintf(f,"#ifndef zzTRACE_RULES\n"); /* MR20 */ - fprintf(f,"#define zzTRACE_RULES\n"); /* MR20 */ - fprintf(f,"#endif\n"); /* MR22 */ - }; - fprintf(f,"#include \"antlr.h\"\n"); - if ( GenAST ) fprintf(f,"#include \"ast.h\"\n"); - if ( UserDefdTokens ) - fprintf(f, "#include %s\n", UserTokenDefsFile); - /* still need this one as it has the func prototypes */ - fprintf(f, "#include \"%s\"\n", DefFileName); - /* still need this one as it defines the DLG interface */ - fprintf(f,"#include \"dlgdef.h\"\n"); - /* don't need this one unless DLG is used */ - if ( LexGen ) fprintf(f,"#include \"%s\"\n", ModeFileName); - fprintf(f,"#endif\n"); -} - -/* dump action 's' to file 'output' starting at "local" tab 'tabs' - Dump line information in front of action if GenLineInfo is set - If file == -1 then GenLineInfo is ignored. - The user may redefine the LineInfoFormatStr to his/her liking - most compilers will like the default, however. - - June '93; changed so that empty lines are left alone so that - line information is correct for the compiler/debuggers. -*/ -void -#ifdef __USE_PROTOS -dumpAction( char *s, FILE *output, int tabs, int file, int line, -int final_newline ) -#else -dumpAction( s, output, tabs, file, line, final_newline ) -char *s; -FILE *output; -int tabs; -int file; -int line; -int final_newline; -#endif -{ - int inDQuote, inSQuote; - require(s!=NULL, "dumpAction: NULL action"); - require(output!=NULL, eMsg1("dumpAction: output FILE is NULL for %s",s)); - - if ( GenLineInfo && file != -1 ) - { - OutLineInfo(output,line,FileStr[file]); - } - PastWhiteSpace( s ); - /* don't print a tab if first non-white char is a # (preprocessor command) */ - if ( *s!='#' ) {TAB;} - inDQuote = inSQuote = FALSE; - while ( *s != '\0' ) - { - if ( *s == '\\' ) - { - fputc( *s++, output ); /* Avoid '"' Case */ - if ( *s == '\0' ) return; - if ( *s == '\'' ) fputc( *s++, output ); - if ( *s == '\"' ) fputc( *s++, output ); - } - if ( *s == '\'' ) - { - if ( !inDQuote ) inSQuote = !inSQuote; - } - if ( *s == '"' ) - { - if ( !inSQuote ) inDQuote = !inDQuote; - } - if ( *s == '\n' ) - { - fputc('\n', output); - s++; - PastWhiteSpace( s ); - if ( *s == '}' ) - { - --tabs; - TAB; - fputc( *s++, output ); - continue; - } - if ( *s == '\0' ) return; - if ( *s != '#' ) /* #define, #endif etc.. start at col 1 */ - { - TAB; - } - } - if ( *s == '}' && !(inSQuote || inDQuote) ) - { - --tabs; /* Indent one fewer */ - } - if ( *s == '{' && !(inSQuote || inDQuote) ) - { - tabs++; /* Indent one more */ - } - fputc( *s, output ); - s++; - } - if ( final_newline ) fputc('\n', output); -} - -static void -#ifdef __USE_PROTOS -dumpAfterActions( FILE *output ) -#else -dumpAfterActions( output ) -FILE *output; -#endif -{ - ListNode *p; - require(output!=NULL, "dumpAfterActions: output file was NULL for some reason"); - if ( AfterActions != NULL ) - { - for (p = AfterActions->next; p!=NULL; p=p->next) - { - UserAction *ua = (UserAction *)p->elem; - dumpAction( ua->action, output, 0, ua->file, ua->line, 1); - } - } - fclose( output ); -} - -/* - * Find the next action in the stream of execution. Do not pass - * junctions with more than one path leaving them. - * Only pass generic junctions. - * - * Scan forward while (generic junction with p2==NULL) - * If we stop on an action, return ptr to the action - * else return NULL; - */ -static ActionNode * -#ifdef __USE_PROTOS -findImmedAction( Node *q ) -#else -findImmedAction( q ) -Node *q; -#endif -{ - Junction *j; - require(q!=NULL, "findImmedAction: NULL node"); - require(q->ntype>=1 && q->ntype<=NumNodeTypes, "findImmedAction: invalid node"); - - while ( q->ntype == nJunction ) - { - j = (Junction *)q; - if ( j->jtype != Generic || j->p2 != NULL ) return NULL; - q = j->p1; - if ( q == NULL ) return NULL; - } - if ( q->ntype == nAction ) return (ActionNode *)q; - return NULL; -} - -static void -#ifdef __USE_PROTOS -dumpRetValAssign( char *retval, char *ret_def, RuleRefNode * ruleRef /* MR30 */) -#else -dumpRetValAssign( retval, ret_def, ruleRef /* MR30 */) -char *retval; -char *ret_def; -RuleRefNode *ruleRefNode; -#endif -{ - char *q = ret_def; - - tab(); - while ( *retval != '\0' && *q != '\0') - { - while ( isspace((*retval)) ) retval++; - while ( *retval!=',' && *retval!='\0' ) fputc(*retval++, output); - fprintf(output, " = _trv."); - - DumpNextNameInDef(&q, output); - while ( isspace(*q) ) q++; - fputc(';', output); fputc(' ', output); - if ( *retval == ',' ) retval++; - } - if (*retval == '\0' && *q != '\0') { -/* MR30 */ errFL("Fewer output values than output formals for rule reference", -/* MR30 */ FileStr[ruleRef->file],ruleRef->line); - } - if (*retval != '\0' && *q == '\0') { -/* MR30 */ errFL("More output actuals than output formals for rule reference", -/* MR30 */ FileStr[ruleRef->file],ruleRef->line); - } -} - -/* This function computes the set of tokens that can possibly be seen k - * tokens in the future from point j - */ - -static set -#ifdef __USE_PROTOS -ComputeErrorSet( Junction *j, int k, int usePlusBlockBypass) -#else -ComputeErrorSet( j, k, usePlusBlockBypass ) -Junction *j; -int k; -int usePlusBlockBypass; -#endif -{ - Junction *alt1; - set a, rk, f; - require(j->ntype==nJunction, "ComputeErrorSet: non junction passed"); - - f = rk = empty; - for (alt1=j; alt1!=NULL; alt1 = (Junction *)alt1->p2) - { - if (alt1->ignore && ! usePlusBlockBypass) continue; /* MR21 - Ignore aPlusBlk forward p2 */ - REACH(alt1->p1, k, &rk, a); - require(set_nil(rk), "ComputeErrorSet: rk != nil"); - set_free(rk); - set_orin(&f, a); - set_free(a); - } - return f; -} - -static char * -#ifdef __USE_PROTOS -tokenFollowSet(TokNode *p) -#else -tokenFollowSet(p) -TokNode *p; -#endif -{ - static char buf[100]; - set rk, a; - int n; - rk = empty; - - REACH(p->next, 1, &rk, a); - require(set_nil(rk), "rk != nil"); - set_free(rk); - n = DefErrSet( &a, 0, NULL ); - set_free(a); - if ( GenCC ) - sprintf(buf, "err%d", n); - else - sprintf(buf, "zzerr%d", n); - return buf; -} - -static void -#ifdef __USE_PROTOS -makeErrorClause( Junction *q, set f, int max_k, int usePlusBlockBypass ) -#else -makeErrorClause( q, f, max_k, usePlusBlockBypass ) -Junction *q; -set f; -int max_k; -int usePlusBlockBypass; -#endif -{ - char * handler_id=""; /* MR7 */ - int nilf=0; /* MR13 */ - RuleEntry *ruleEntry; /* MR14 */ - - if ( FoundException ) - { - _gen("else {\n"); - tabs++; - if ( FoundGuessBlk ) - { - if ( GenCC ) {gen("if ( guessing ) goto fail;\n");} - else gen("if ( zzguessing ) goto fail;\n"); - } - gen("if (_sva) _signal=NoViableAlt;\n"); - gen("else _signal=NoSemViableAlt;\n"); - if (q->outerEG != NULL) { - handler_id=q->outerEG->altID; -#if 0 - } else { - printf("q->curAltNum=%d q->exception_label=%s\n",q->curAltNum,q->exception_label); - gen("*** DEBUG *** outerEG==NULL\n"); -#endif - }; - gen1("goto %s_handler; /* MR7 */\n",handler_id); /* MR7 */ - tabs--; - gen("}\n"); - return; - } - - if ( max_k == 1 ) - { -/* MR13 */ nilf=set_nil(f); - if ( GenCC ) { - _gen1("else {FAIL(1,err%d", DefErrSet1(1,&f,1,NULL)); - } else { - _gen1("else {zzFAIL(1,zzerr%d", DefErrSet1(1,&f,1,NULL)); - }; - set_free(f); - } - else - { - int i; - set_free(f); - if ( GenCC ) {_gen1("else {FAIL(%d", max_k);} - else _gen1("else {zzFAIL(%d", max_k); - - ruleEntry = (RuleEntry *) hash_get(Rname,q->rname); - - for (i=1; i<=max_k; i++) - { -/* MR14 */ if (ruleEntry->dontComputeErrorSet) { -/* MR14 */ f=empty; - } else { - f = ComputeErrorSet(q, i, usePlusBlockBypass /* use plus block bypass ? */ ); - } - - if ( GenCC ) {_gen1(",err%d", DefErrSet( &f, 1, NULL ));} - else _gen1(",zzerr%d", DefErrSet( &f, 1, NULL )); - - set_free(f); - } - } - _gen(",&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;}\n"); -/* MR13 */ if (nilf) { -/* MR13 */ errFL("empty error set for alt - probably because of undefined rule or infinite left recursion", -/* MR13 */ FileStr[q->file],q->line); -/* MR13 */ gen(" /* MR13 empty error set for this alt - undef rule ? infinite left recursion ? */"); -/* MR13 */ }; -} - -static /* MR7 */ -#ifdef __USE_PROTOS -char * findOuterHandlerLabel(ExceptionGroup *eg) /* MR7 */ -#else -char * findOuterHandlerLabel(eg) /* MR7 */ -ExceptionGroup *eg; /* MR7 */ -#endif -{ - char *label=NULL; /* MR7 */ - ExceptionGroup *outerEG; /* MR7 */ - - if (eg->forRule == 0) { /* MR7 */ - if (eg->labelEntry != NULL) { /* MR7 */ - outerEG=eg->labelEntry->outerEG; /* MR7 */ - if (outerEG != NULL) { /* MR7 */ - label=outerEG->altID; /* MR7 */ - outerEG->used=1; /* MR7 */ - }; /* MR7 */ - } else if (eg->outerEG != NULL) { /* MR7 */ - outerEG=eg->outerEG; /* MR7 */ - label=outerEG->altID; /* MR7 */ - outerEG->used=1; /* MR7 */ - }; /* MR7 */ - }; /* MR7 */ - return (label==NULL ? "" : label); /* MR7 */ -} /* MR7 */ - -/*** debug ***/ -#if 0 -** static /* MR7 */ -** #ifdef __USE_PROTOS -** char * findOuterAltHandlerLabel(Junction *startJ) /* MR7 */ -** #else -** char * findOuterAltHandlerLabel(startJ) /* MR7 */ -** Junction *startJ; /* MR7 */ -** #endif -** { /* MR7 */ -** char *label=NULL; /* MR7 */ -** Junction *alt; /* MR7 */ -** /* MR7 */ -** for (alt=startJ; alt != NULL; alt=alt->outerAltstart) { /* MR7 */ -** label=alt->exception_label; /* MR7 */ -** if (label != NULL) break; /* MR7 */ -** }; /* MR7 */ -** return (label==NULL ? "" : label); /* MR7 */ -** } /* MR7 */ -#endif - -#ifdef __USE_PROTOS -static void OutLineInfo(FILE *file,int line,char *fileName) -#else -static void OutLineInfo(file,line,fileName) - FILE * file; - int line; - char * fileName; -#endif -{ - static char * prevFileName=NULL; - static char * prevFileNameMS=NULL; - - char * p; - char * q; - - if (! GenLineInfo) return; - - if (!GenLineInfoMS) { - fprintf(file, LineInfoFormatStr,line,fileName); - } else { - if (fileName == prevFileName) { - fprintf(file, LineInfoFormatStr,line,prevFileNameMS); - } else { - if (prevFileNameMS != NULL) free (prevFileNameMS); - prevFileNameMS=(char *)calloc(1,strlen(fileName)+1); - require(prevFileNameMS != NULL,"why not do this in calloc wrapper"); - q=prevFileNameMS; - for (p=fileName; *p != 0; p++) { - *q=*p; - if (*q == '\\') *q='/'; - q++; - } - } - prevFileName=fileName; - }; -} - -#if 0 - -/* MR21 */ - -#ifdef __USE_PROTOS -void OutFirstSetSymbol(Junction *q, char * pSymbol) -#else -void OutFirstSetSymbol(q, pSymbol) - Junction* q; - char * pSymbol -#endif -{ - - set f; - if (pSymbol == NULL) return; - gen1("/** #FirstSetSymbol(%s) **/\n",pSymbol); - f = ComputeErrorSet(q, 1, 0 /* use plus block bypass ? */); - DefErrSetWithSuffix (0 /* nil ok */, &f,0 /* no substitute */, pSymbol, ""); - set_free(f); -} -#endif - -/* MR21 */ - -#ifdef __USE_PROTOS -void BlockPreambleOption(Junction *q, char * pSymbol) -#else -void BlockPreambleOption(q, pSymbol) - Junction* q; - char * pSymbol; -#endif -{ - set f = empty; - if (pSymbol != NULL) { - f = ComputeErrorSet(q, 1, 0 /* use plus block bypass ? */); - gen1("/** #FirstSetSymbol(%s) **/\n",pSymbol); - DefErrSetWithSuffix (0 /* nil ok */, &f,0 /* no substitute */, pSymbol, ""); - } - set_free(f); -} - -/* MR21 */ - -void -#ifdef __USE_PROTOS -dumpActionPlus(ActionNode *a, char *s, FILE *output, int tabs, int file, int line, -int final_newline ) -#else -dumpActionPlus(a, s, output, tabs, file, line, final_newline ) -ActionNode *a; -char *s; -FILE *output; -int tabs; -int file; -int line; -int final_newline; -#endif -{ - dumpAction(s,output,tabs,file,line,final_newline); -} - - -#if 0 -** #ifdef __USE_PROTOS -** void MR_ErrorSets(Junction *q, int max_k, int usePlusBlockBypass) -** #else -** void MR_ErrorSets(q, max_k, usePlusBlockBypass) -** Junction *q; -** int max_k; -** int usePlusBlockBypass; -** #endif -** { -** int k; -** set setResult; -** Junction* alt1; -** Junction* p; -** set rk; -** -** require (max_k <= CLL_k, "k > CLL_k"); -** -** -** for (k = 1; k <= CLL_k; k++) {set_clr(q->fset[k]); } -** -** for (k = 1; k <= max_k; k++) { -** for (alt1=q; alt1 != NULL; alt1 = (Junction *)alt1->p2) -** { -** if (alt1->ignore && ! usePlusBlockBypass) continue; -** p = analysis_point((Junction *)alt1->p1); -** REACH(p, k, &rk, setResult); -** require(set_nil(rk), "rk != nil"); -** set_orin(&q->fset[k], setResult); -** } -** } -** } -#endif - - -#ifdef __USE_PROTOS -void DumpInitializers(FILE* output, RuleEntry *r, char * pReturn) -#else -void DumpInitializers(output, r, pReturn) -FILE* output; -RuleEntry *r; -char * pReturn; -#endif -{ - char *p = pReturn; - char *pDataType; - char *pSymbol; - char *pEqualSign; - char *pValue; - char *pSeparator; - int nest = 0; - char *q; - - require(pReturn!=NULL, "DumpInitializer: invalid string"); - - while (*p != 0) { - p = endFormal(p, - &pDataType, - &pSymbol, - &pEqualSign, - &pValue, - &pSeparator, - &nest); - if (nest != 0) return; - if (pValue != NULL) { - tab(); - q = strBetween(pSymbol, pEqualSign, pSeparator); - fprintf(output, "_retv.%s", q); - q = strBetween(pValue, NULL, pSeparator); - fprintf(output, " = %s;\n", q); - } - } -} - -#ifdef __USE_PROTOS -void DumpFormals(FILE* output, char * pReturn, int bInitializer) -#else -void DumpFormals(output, pReturn, bInitializer) -FILE* output; -char * pReturn; -int bInitializer; -#endif -{ - char *p = pReturn; - char *pDataType; - char *pSymbol; - char *pEqualSign; - char *pValue; - char *pSeparator; - int nest = 0; - char *q; - int count = 0; - - require(pReturn!=NULL, "DumpFormals: invalid string"); - - while (*p != 0) { - p = endFormal(p, - &pDataType, - &pSymbol, - &pEqualSign, - &pValue, - &pSeparator, - &nest); - if (nest != 0) return; - if (count > 0) fprintf(output,","); - if (pDataType != NULL && pSymbol != NULL) { - q = strBetween(pDataType, pSymbol, pSeparator); - fprintf(output, "%s", q); - q = strBetween(pSymbol, pEqualSign, pSeparator); - fprintf(output," %s",q); - if (pValue != NULL) { - q = strBetween(pValue, NULL, pSeparator); - if (bInitializer != 0) { - fprintf(output, " = %s", q); - } - } - } - count++; - } -} - -/* MR23 Check for empty alt in a more intelligent way. - Previously, an empty alt for genBlk had to point directly - to the endBlock. This did not work once I changed {...} - blocks to look like (...|...| epsilon) since there were - intervening generics. This fixes the problem for this - particular case. Things like actions or empty blocks of - various kinds will still cause problems, but I wasnt't - prepared to handle pathological cases like (A|()*). It - does handle (A | ()), which is a recommended idiom for - epsilon. - - Actually, this isn't quite correct since it doesn't handle - the case of the ignore bit in the plus block bypass, but - I'm too tired to figure out the correct fix, and will just - work around it. -*/ - -#ifdef __USE_PROTOS -int isEmptyAlt(Node * alt, Node * endBlock) -#else -int isEmptyAlt(alt, endBlock) -Node * alt; -Node * endBlock; -#endif -{ - Node * n = alt; - Junction * j; - while (n != endBlock) { - switch (n->ntype) { - - case nRuleRef: - return 0; - - case nToken: - return 0; - - case nAction: - return 0; - - case nJunction: - goto JUNCTION; - - default: - fatal_internal("Invalid node type"); - return 0; - } -JUNCTION: - j = (Junction *) n; - - switch (j->jtype) { - case Generic: - { - n = j->p1; - goto NEXT; - } - - case aSubBlk: - { - n = j->p1; /* MR26 */ - goto NEXT; /* MR26 */ - } - - case EndBlk: - return 0; - - case EndRule: - return 1; - - default: - return 0; - } -NEXT: continue; - } - return 1; -} diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/generic.h b/Tools/CodeTools/TianoTools/Pccts/antlr/generic.h deleted file mode 100644 index 8d736d5200..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/generic.h +++ /dev/null @@ -1,286 +0,0 @@ -/* - * generic.h -- generic include stuff for new PCCTS ANTLR. - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2001 - */ - -#define StrSame 0 - -#define DefaultParserName "zzparser" - -/* MR9 JVincent@novell.com Allow user to override default ZZLEXBUFSIZE */ -/* MR11 thm Raise antlr's own default ZZLEXBUFSIZE to 8k */ -/* MR22 thm Raise antlr's own default ZZLEXBUFSIZE to 32k */ - -#ifndef ZZLEXBUFSIZE -#define ZZLEXBUFSIZE 32000 -#endif - -/* Tree/FIRST/FOLLOW defines -- valid only after all grammar has been read */ -#define ALT TokenNum+1 -#define SET TokenNum+2 -#define TREE_REF TokenNum+3 - - /* E r r o r M a c r o s */ - -#define fatal(err) fatalFL(err, __FILE__, __LINE__) -#define fatal_internal(err) fatal_intern(err, __FILE__, __LINE__) - - -#define eMsg1(s,a) eMsg3(s,a,NULL,NULL) -#define eMsg2(s,a,b) eMsg3(s,a,b,NULL) - - /* S a n i t y C h e c k i n g */ - -#ifndef require -#define require(expr, err) {if ( !(expr) ) fatal_internal(err);} -#endif - - /* L i s t N o d e s */ - -typedef struct _ListNode { - void *elem; /* pointer to any kind of element */ - struct _ListNode *next; - } ListNode; - -/* Define a Cycle node which is used to track lists of cycles for later - * reconciliation by ResolveFoCycles(). - */ -typedef struct _c { - int croot; /* cycle root */ - set cyclicDep; /* cyclic dependents */ - unsigned deg; /* degree of FOLLOW set of croot */ - } Cycle; - -typedef struct _e { - int tok; /* error class name == TokenStr[tok] */ - ListNode *elist; /* linked list of elements in error set */ - set eset; - int setdeg; /* how big is the set */ - int lexclass; /* which lex class is it in? */ - } ECnode; - -typedef struct _TCnode { - int tok; /* token class name */ - ListNode *tlist; /* linked list of elements in token set */ - set tset; - int lexclass; /* which lex class is it in? */ - unsigned char dumped; /* this def has been been dumped */ - unsigned char dumpedComplement; /* this def has been been dumped */ - unsigned setnum; /* which set number is this guy? (if dumped) */ - unsigned setnumComplement; /* MR23 */ - unsigned setnumErrSet; /* MR23 which set is this #tokclass error set (if dumped) */ - unsigned setnumErrSetComplement; /* MR23 */ - } TCnode; - -typedef struct _ft { - char *token; /* id of token type to remap */ - int tnum; /* move token type to which token position */ - } ForcedToken; - -typedef struct _ContextGuardPredicates { /* MR13 */ - Predicate *pred; /* MR13 */ - } ContextGuardPredicates; /* MR13 */ - -#define newListNode (ListNode *) calloc(1, sizeof(ListNode)); -#define newCycle (Cycle *) calloc(1, sizeof(Cycle)); -#define newECnode (ECnode *) calloc(1, sizeof(ECnode)); -#define newTCnode (TCnode *) calloc(1, sizeof(TCnode)); - - - /* H a s h T a b l e E n t r i e s */ - -typedef struct _t { /* Token name or expression */ - char *str; - struct _t *next; - int token; /* token number */ - unsigned char classname; /* is it a err/tok class name or token */ - TCnode *tclass; /* ptr to token class */ - char *action; - char *akaString; - } TermEntry; - -typedef struct _r { /* Rule name and ptr to start of rule */ - char *str; - struct _t *next; - int rulenum; /* RulePtr[rulenum]== ptr to RuleBlk junction */ - unsigned char noAST;/* gen AST construction code? (def==gen code) */ - char *egroup; /* which error group (err reporting stuff) */ -#if 0 - /* MR27 This appears to never be used. Delete this code later. */ - - ListNode *el_labels;/* list of element labels ref in all of rule */ -#endif - ListNode *ast_labels_in_actions; /* MR27 */ - unsigned char has_rule_exception; - char dontComputeErrorSet; /* MR14 - don't compute error set - special for rule in alpha part of - (alpha)? beta block */ - } RuleEntry; - -typedef struct _f { /* cache Fi/Fo set */ - char *str; /* key == (rulename, computation, k) */ - struct _f *next; - set fset; /* First/Follow of rule */ - set rk; /* set of k's remaining to be done after ruleref */ - int incomplete; /* only w/FOLLOW sets. Use only if complete */ - } CacheEntry; - -typedef struct _LabelEntry { /* element labels */ - char *str; - struct _f *next; - Node *elem; /* which element does it point to? */ - ExceptionGroup *ex_group; - /* Is there an exception attached to label? */ - ExceptionGroup *outerEG; /* MR7 */ - /* next EG if ex_group doesn't catch it MR7 */ - struct _LabelEntry *pendingLink; /* MR7 */ - /* too lazy to use ListNode ? MR7 */ - int curAltNum; /* MR7 */ - } LabelEntry; - -typedef struct _SignalEntry { - char *str; - struct _f *next; - int signum; /* unique signal number */ - } SignalEntry; - -typedef struct _PredEntry { /* MR11 predicate name and ptr to string */ - char *str; - struct _PredEntry *next; - int file; - int line; - Predicate *pred; - char *predLiteral; - } PredEntry; - -typedef struct _PointerStack { /* MR10 */ - int count; - int size; - void **data; - } PointerStack; - -#define newTermEntry(s) (TermEntry *) newEntry(s, sizeof(TermEntry)) -#define newRuleEntry(s) (RuleEntry *) newEntry(s, sizeof(RuleEntry)) -#define newCacheEntry(s) (CacheEntry *) newEntry(s, sizeof(CacheEntry)) -#define newLabelEntry(s) (LabelEntry *) newEntry(s, sizeof(LabelEntry)) -#define newSignalEntry(s) (SignalEntry *) newEntry(s, sizeof(SignalEntry)) -#define newPredEntry(s) (PredEntry *) newEntry(s,sizeof(PredEntry)) - -typedef struct _UserAction { - char *action; - int file, line; - } UserAction; - - - /* L e x i c a l C l a s s */ - -/* to switch lex classes, switch ExprStr and Texpr (hash table) */ -typedef struct _lc { - char *classnum, **exprs; - Entry **htable; - } LClass; - -typedef struct _exprOrder { - char *expr; - int lclass; - } Expr; - - -typedef Graph Attrib; - - /* M a x i m u m s */ - -/* MR20 Note G. Hobbelt These values are superceded by values in hash.h */ - -#ifndef HashTableSize -#define HashTableSize 253 -#endif -#ifndef StrTableSize -#define StrTableSize 15000 /* all tokens, nonterminals, rexprs stored here */ -#endif -#define MaxLexClasses 50 /* how many automatons */ -/* TokenStart and EofToken are ignored if #tokdefs meta-op is used */ -#define TokenStart 2 /* MUST be in 1 + EofToken */ -#define EofToken 1 /* Always predefined to be 1 */ - -#ifndef MaxNumFiles -#define MaxNumFiles 99 -#endif - -/**** MR9 JVincent@novell.com Move to pcctscfg.h */ -/**** #define MaxFileName 300 ****/ /* MR9 Move to pcctscfg.h */ /* largest file name size */ - -#define MaxRuleName 100 /* largest rule name size */ -#define TSChunk 100 /* how much to expand TokenStr/ExprStr each time */ -#define TIChunk TSChunk /* expand TokenInd by same as TokenStr to mirror them */ -#define FoStackSize 100 /* deepest FOLLOW recursion possible */ - -#define MaxClassDeclStuff 256 /* MR10 */ - -#define NumPredefinedSignals 3 - - /* S t a n d a r d S i g n a l s */ - -#define sigNoSignal 0 -#define sigMismatchedToken 1 -#define sigNoViableAlt 2 -#define sigNoSemViableAlt 3 - - - -/* AST token types */ -#define ASTexclude 0 -#define ASTchild 1 -#define ASTroot 2 -#define ASTinclude 3 /* include subtree made by rule ref */ - - -#define PredictionVariable "zzpr_expr" -#define PredictionLexClassSuffix "_zzpred" - -#define WildCardString "WildCard" - -#if 0 - /* Removed in version 1.33MR19 - Don't understand why this never caused problems before - */ - - /********************************************************* - #ifndef ANTLRm - #define ANTLRm(st, f, _m) zzbufsize = ZZLEXBUFSIZE;\ - zzmode(_m); \ - zzenterANTLR(f); \ - st; ++zzasp; \ - zzleaveANTLR(f); - #endif - *********************************************************/ -#endif - -#include "proto.h" -#include "pcctscfg.h" /* MR14 */ -#include diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/globals.c b/Tools/CodeTools/TianoTools/Pccts/antlr/globals.c deleted file mode 100644 index 59d00320a0..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/globals.c +++ /dev/null @@ -1,484 +0,0 @@ -/* - * globals.c -- File containing all variables/tables visible to all files. - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2001 - */ - -#include - -#include "pcctscfg.h" - -#include "set.h" -#include "syn.h" -#include "hash.h" -#include "generic.h" - -char Version[] = "1.33MR33" ; /* PCCTS version number */ /* MRXXX */ -char VersionDef[] = "13333"; /* same (except int equiv for preproc symbol) */ /* MRXXX */ - -char LexStartSymbol[] = "START";/* Name of starting lexical class/automaton */ -char *RemapFileName = "remap.h"; -char *DlgFileName = "parser.dlg"; -char *DefFileName = "tokens.h"; -char *ErrFileName = "err.c"; -char *ModeFileName = "mode.h"; -char *StdMsgName = NULL; - -char *ParserName = DefaultParserName; - -/* list of PCCTS supplied support symbols; these are renamed when more than - * one ANTLR-generated parsers are linked together to avoid name conflicts. - * Can't use '##' ANSIC preprocessor concat operator with K&R and: - * #define zzskip zzparser ## skip - * will not work for ANSI/C++ as 'zzparserskip' is created w/o zzparser - * being substituted--ack!!! - */ -char *StandardSymbols[] = { -/* ANTLR stuff */ - "zzStackOvfMsg", - "zzasp", - "zzaStack", - "inf_tokens", - "inf_text", - "inf_text_buffer", - "inf_text_buffer_ptr", - "inf_text_buffer_size", - "inf_labase", - "inf_last", - "inf_lap", - "zztokenLA", - "zztextLA", - "zzlap", - "zzlabase", - "zztoktext", - "zztoken", - "zzdirty", - "zzguessing", - "zzguess_start", - "zzresynch", - "zzinf_tokens", - "zzinf_text", - "zzinf_text_buffer", - "zzinf_labase", - "zzinf_last", - "zzfill_inf_look", - "zzFAIL", - "zzsave_antlr_state", - "zzrestore_antlr_state", - "zzsyn", - "zzset_el", - "zzset_deg", - "zzedecode", - "_zzsetmatch", - "_zzmatch", - "_inf_zzgettok", - "zzconsumeUntil", - "zzconsumeUntilToken", - "_zzmatch_wsig", - "_zzsetmatch_wsig", - "_zzmatch_wdfltsig", - "_zzsetmatch_wdfltsig", - "zzdflthandlers", -/* DLG stuff */ - "zzreal_line", - "zzcharfull", - "zzerr", - "zzlextext", - "zzbegexpr", - "zzendexpr", - "zzbufsize", - "zzbegcol", - "zzendcol", - "zzline", - "zzchar", - "zzbufovf", - "zzrdstream", - "zzrdfunc", - "zzrdstr", - "zzclose_stream", - "zzsave_dlg_state", - "zzrestore_dlg_state", - "zzmode", - "zzskip", - "zzmore", - "zzreplchar", - "zzreplstr", - "zzgettok", - "zzadvance", - "zzerrstd", - "zzerr_in", - "zzconstr_attr", - "zzempty_attr", - "zzerraction", - "zztokens", /* list of token regular expressions */ - "dfa", - "accepts", - "actions", - "zzTraceOptionValue", /* MR10 */ - "zzTraceGuessOptionValue", /* MR10 */ - "zzTraceCurrentRuleName", /* MR10 */ - "zzTraceDepth", /* MR10 */ - "zzGuessSeq", /* MR10 */ - "zzSyntaxErrCount", /* MR11 */ - "zzLexErrCount", /* MR11 */ - "zzTraceGuessDone", /* MR13 - BJS */ - "zzTraceGuessFail", /* MR13 - BJS */ - "zzTraceGuessOption", /* MR13 - BJS */ - "zzTraceIn", /* MR13 - BJS */ - "zzTraceOption", /* MR13 - BJS */ - "zzTraceOut", /* MR13 - BJS */ - "zzTraceReset", /* MR13 - BJS */ - NULL /* must be present */ -}; - -/* list of PCCTS supplied support functions; these are renamed when more than - * one ANTLR-generated parsers are linked together to avoid name conflicts. - */ -char *ASTSymbols[] = { - "AST", - "zzast_sp", - "zzastStack", - "zzlink", - "zzastnew", - "zzsubchild", - "zzsubroot", - "zzpre_ast", - "zzfree_ast", - "zztmake", - "zzdup_ast", - "zztfree", - "zzdouble_link", - NULL /* must be present */ -}; - -/* Current ambiguity examination information */ -int CurAmbigAlt1, CurAmbigAlt2, CurAmbigline, CurAmbigfile; -char *CurAmbigbtype; - - - /* M e t h o d T a b l e s */ -/* - * The following tables are used to fill syntax diagram nodes with the correct - * function pointers for computing FIRST sets and printing themselves. - */ - -/* fpTraverse[node type] == pointer to function that calculates trees - * representing the FIRST sets for that node (maintains spatial info). - * We use 'struct _tree' not 'tree' due to a g++ 2.4.3 bug. - */ -#ifdef __cplusplus -struct _tree *(*fpTraverse[NumNodeTypes+1])(... /* Node *, int, set * */) = { - NULL, - (struct _tree *(*)(...)) tJunc, - (struct _tree *(*)(...)) tRuleRef, - (struct _tree *(*)(...)) tToken, - (struct _tree *(*)(...)) tAction -}; -#else -Tree *(*fpTraverse[NumNodeTypes+1])() = { - NULL, - tJunc, - tRuleRef, - tToken, - tAction -}; -#endif - -/* fpReach[node type] == pointer to function that calculates FIRST set for - * that node. (r stands for reach). We use 'struct _set' not 'set' - * due to a g++ 2.4.3 bug. - */ -#ifdef __cplusplus -struct _set (*fpReach[NumNodeTypes+1])(... /* Node *, int, set * */) = { - NULL, - (struct _set (*)(...)) rJunc, - (struct _set (*)(...)) rRuleRef, - (struct _set (*)(...)) rToken, - (struct _set (*)(...)) rAction -}; -#else -set (*fpReach[NumNodeTypes+1])() = { - NULL, - rJunc, - rRuleRef, - rToken, - rAction -}; -#endif - -/* fpPrint[node type] == pointer to function that knows how to print that node. */ -#ifdef __cplusplus -void (*fpPrint[NumNodeTypes+1])(... /* Node * */) = { - NULL, - (void (*)(...)) pJunc, - (void (*)(...)) pRuleRef, - (void (*)(...)) pToken, - (void (*)(...)) pAction -}; -#else -void (*fpPrint[NumNodeTypes+1])() = { - NULL, - pJunc, - pRuleRef, - pToken, - pAction -}; -#endif - -char *decodeJType[] = { - "invalid", - "aSubBlk", - "aOptBlk", - "aLoopBlk", - "EndBlk", - "RuleBlk", - "Generic", - "EndRule", - "aPlusBlk", - "aLoopBegin" -}; - - - /* H a s h T a b l e s */ - -Entry **Tname, /* Table of all token names (maps name to tok num)*/ - **Texpr, /* Table of all token expressions - (maps expr to tok num) */ - **Rname, /* Table of all Rules (has ptr to start of rule) */ - **Fcache, /* Cache of First/Follow Computations */ - **Tcache; /* Tree cache; First/Follow for permute trees */ -Entry **Elabel; /* Table of all element label names */ -Entry **Sname; /* Signal names */ -Entry **Pname; /* symbolic predicate names MR11 */ - - - /* V a r i a b l e s */ - -int Save_argc; /* MR10 */ -char **Save_argv; /* MR10 */ -int EpToken=0; /* Imaginary Epsilon token number */ -int WildCardToken=0; -int CurFile= -1; /* Index into FileStr table */ -char *CurPredName=NULL; /* MR11 */ -char *CurRule=NULL; /* Pointer to current rule name */ -int CurRuleDebug=0; /* MR13 debug flag */ -RuleEntry *CurRuleNode=NULL;/* Pointer to current rule node in syntax tree */ -char *CurRetDef=NULL; /* Pointer to current return type definition */ -char *CurParmDef=NULL; /* Pointer to current parameter definition */ -Junction *CurRuleBlk=NULL; /* Pointer to current block node for enclosing block */ -ListNode *CurExGroups=NULL; /* Current list of exception groups for rule/alts */ -ListNode *CurElementLabels=NULL; -ListNode *CurAstLabelsInActions=NULL; /* MR27 */ - -/* MR10 used by <<>>? to set "label_used_in_semantic_pred" */ -/* MR10 this will force LT(i) assignment even in guess mode */ - -ListNode *CurActionLabels=NULL; /* MR10 Element Labels appearing in last action */ -int numericActionLabel=0 ; /* MR10 << ... $1 ... >> or << ... $1 ... >>? */ -ListNode *NumericPredLabels=NULL; /* MR10 << ... $1 ... >>? ONLY */ -ListNode *ContextGuardPredicateList=NULL; /* MR13 for re-evaluating predicates - after meta tokens are defined */ - -int CurBlockID=0; /* Unique int for each block */ -int CurAltNum=0; -Junction *CurAltStart = NULL; /* Junction node that starts the alt */ -Junction *OuterAltStart = NULL; /* For chaining exception groups MR7 */ -int NumRules=0; /* Rules are from 1 to n */ -FILE *output=NULL; /* current parser output file */ -FILE *input=NULL; /* current grammar input file */ -char *FileStr[MaxNumFiles];/* Ptr to array of file names on command-line */ -int NumFiles=0; /* current grammar file number */ -#ifdef __cplusplus -void (**fpTrans)(...), /* array of ptrs to funcs that translate nodes */ - (**fpJTrans)(...); /* ... that translate junctions */ -#else -void (**fpTrans)(), /* array of ptrs to funcs that translate nodes */ - (**fpJTrans)(); /* ... that translate junctions */ -#endif -int **FoStack; /* Array of LL_k ptrs to stacks of rule numbers */ -int **FoTOS; /* FOLLOW stack top-of-stack pointers */ -Junction *SynDiag = NULL; /* Pointer to start of syntax diagram */ -int BlkLevel=1; /* Current block level. Set by antlr.g, used by - * scanner to translate $i.j attributes */ -set reserved_positions; /* set of token positions reserved by '#token T=i' cmds */ -set all_tokens; /* set of all token types */ -set imag_tokens; /* set of all imaginary token types (EpToken, errclasses...) */ -set tokclasses; /* set of all token class token types */ -ListNode *ForcedTokens = 0; /* list of token_id/token_num pairs to remap */ -ListNode *MetaTokenNodes=NULL; /* list of meta token refs such as token classes etc... */ -int *TokenInd=NULL; /* an indirection level between token num and position - * of that token def in TokenStr and ExprStr */ -int LastTokenCounted=0; /* ==TokenNum if no token renumbering (same as old TokenNum) */ -int TokenNum=TokenStart; -char **TokenStr=NULL; /* map token # to token name */ -char **ExprStr=NULL; /* map token # to expr */ -Junction **RulePtr=NULL; /* map rule # to RuleBlk node of rule */ -ListNode *ExprOrder=NULL; /* list of exprs as they are found in grammar */ -ListNode *BeforeActions=NULL;/* list of grammar actions before rules */ -ListNode *AfterActions=NULL;/* list of grammar actions after rules */ -ListNode *LexActions=NULL; /* list of lexical actions */ - -/* MR1 */ -/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ -/* MR1 via #lexmember <<....>> */ -/* MR1 via #lexprefix <<....>> */ -/* MR1 */ - -ListNode *LexMemberActions=NULL;/* list of lexical header member decl MR1 */ -ListNode *LexPrefixActions=NULL;/* list of lexical header #include decl MR1 */ -ListNode **Cycles=NULL; /* list of cycles (for each k) found when - doing FOLLOWs */ -ListNode *eclasses=NULL; /* list of error classes */ -ListNode *tclasses=NULL; /* list of token classes */ -LClass lclass[MaxLexClasses]; /* array of lex class definitions */ -int CurrentLexClass; /* index into lclass */ -int NumLexClasses=0; /* in range 1..MaxLexClasses (init 0) */ - -char *HdrAction=NULL; /* action defined with #header */ -char *FirstAction=NULL; /* action defined with #first MR11 */ -FILE *ErrFile; /* sets and error recovery stuff */ -FILE *DefFile=NULL; /* list of tokens, return value structs, setwd defs */ -FILE *MRinfoFile=NULL; /* MR10 information file */ -int MRinfo=0; /* MR10 */ -int MRinfoSeq=0; /* MR10 */ -int InfoP=0; /* MR10 predicates */ -int InfoT=0; /* MR10 tnodes */ -int InfoF=0; /* MR10 first/follow sets */ -int InfoM=0; /* MR10 monitor progress */ -int InfoO=0; /* MR12 orphan rules */ -int TnodesInUse=0; /* MR10 */ -int TnodesPeak=0; /* MR10 */ -int TnodesAllocated=0; /* MR10 */ -int TnodesReportThreshold=0; /* MR11 */ -int PotentialSuppression=0; /* MR10 */ -int PotentialDummy=0; /* MR10 */ -int CannotContinue=FALSE; -int OutputLL_k = 1; /* LL_k for parsing must be power of 2 */ -int action_file; /* used to track start of action */ -int action_line; -int FoundGuessBlk=0; /* there is a (...)? block somewhere in grammar */ -int FoundException=0; /* there is an exception somewhere in grammar */ -/* MR6 Distinguish between @ operator and real exception */ -/* MR6 by keeping separate flags for @ operator and real exceptions */ -int FoundAtOperator=0; /* MR6 */ -int FoundExceptionGroup=0; /* MR6 */ -int pLevel=0; /* print Level */ -int pAlt1,pAlt2; /* print "==>" in front of these alts */ - -/* C++ output stuff */ -FILE *Parser_h, /* where subclass of ANTLRParser goes */ - *Parser_c; /* where code for subclass of ANTLRParser goes */ -char Parser_h_Name[MaxFileName+1] = ""; -char Parser_c_Name[MaxFileName+1] = ""; -char MRinfoFile_Name[MaxFileName+1] = ""; /* MR10 */ -char *ClassDeclStuff=NULL; /* MR10 */ -char *BaseClassName=NULL; /* MR22 */ -/* list of actions inside the #class {...} defs */ -ListNode *class_before_actions=NULL; -ListNode *class_after_actions=NULL; - -char CurrentClassName[MaxRuleName]=""; -int no_classes_found=1; -char *UserTokenDefsFile; -int UserDefdTokens=0; /* found #tokdefs? */ -char *OutputDirectory=TopDirectory; -ExceptionGroup *DefaultExGroup = NULL; -int NumSignals = NumPredefinedSignals; -int ContextGuardTRAV=0; - -char *MR_AmbAidRule=NULL; /* MR11 */ -int MR_AmbAidLine=0; /* MR11 */ -int MR_AmbAidDepth=0; /* MR11 */ -int MR_AmbAidMultiple=0; /* MR11 */ -int MR_skipped_e3_report=0; /* MR11 */ -int MR_usingPredNames=0; /* MR11 */ -int MR_BadExprSets=0; /* MR13 */ -int MR_Inhibit_Tokens_h_Gen=0; /* MR13 */ -int NewAST=0; /* MR13 */ -int tmakeInParser=0; /* MR23 */ -int AlphaBetaTrace=0; /* MR14 */ -int MR_BlkErr=0; /* MR21 */ -int MR_AlphaBetaMessageCount=0; /* MR14 */ -int MR_AlphaBetaWarning=0; /* MR14 */ -int MR_ErrorSetComputationActive=0; /* MR14 */ -int MR_MaintainBackTrace=0; /* MR14 */ -set MR_CompromisedRules; /* MR14 */ - -Junction *MR_RuleBlkWithHalt; /* MR10 */ - - /* C m d - L i n e O p t i o n s */ - -int LL_k=1; /* how many tokens of full lookahead */ -int CLL_k= -1; /* how many tokens of compressed lookahead */ -int PrintOut = FALSE; /* print out the grammar */ -int PrintAnnotate = FALSE;/* annotate printout with FIRST sets */ -int CodeGen=TRUE; /* Generate output code? */ -int LexGen=TRUE; /* Generate lexical files? (tokens.h, parser.dlg) */ -int GenAST=FALSE; /* Generate AST's? */ -int GenANSI=FALSE; /* Generate ANSI code where necessary */ -int GenExprSetsOpt=TRUE;/* use sets not (LA(1)==tok) expression lists */ -int GenCR=FALSE; /* Generate cross reference? */ -int GenLineInfo=FALSE; /* Generate # line "file" stuff? */ -int GenLineInfoMS=FALSE;/* Like -gl but replace "\" with "/" for MS C/C++ systems */ -int TraceGen=FALSE; /* Generate code to trace rule invocation */ -int elevel=1; /* error level for ambiguity messages */ -int GenEClasseForRules=0;/* don't generate eclass for each rule */ -int TreeResourceLimit= -1;/* don't limit tree resource */ -int DemandLookahead = 0;/* demand/delayed lookahead or not */ -char *RulePrefix = ""; /* prefix each generated rule with this */ -char *stdpccts = "stdpccts.h";/* where to generate std pccts include file */ -int GenStdPccts = 0; /* don't gen stdpccts.h? */ -int ParseWithPredicates = 1; -int WarningLevel = 1; -int UseStdout = 0; /* MR6 */ -int TabWidth = 2; /* MR6 */ /* MR27 */ -int HoistPredicateContext = 0; -int MRhoisting = 0; /* MR9 */ -int MRhoistingk = 0; /* MR13 */ -int MR_debugGenRule=0; /* MR11 */ - -int GenCC = 0; /* Generate C++ output */ - -PointerStack MR_BackTraceStack={0,0,NULL}; /* MR10 */ -PointerStack MR_PredRuleRefStack={0,0,NULL}; /* MR10 */ -PointerStack MR_RuleBlkWithHaltStack={0,0,NULL}; /* MR10 */ - -/* DontCopyTokens and Pragma_DupLabeledTokens were a bad idea. I've just - turned them off rather than backpatching the code. Who knows? We - may need them in the future. - */ -int DontCopyTokens = 1; /* in C++, don't copy ANTLRToken passed to ANTLR */ - -/* Remember if LT(i), LA(i), or LATEXT(i) used in an action which is not - a predicate. If so, give a warning for novice users. -*/ - -int LTinTokenAction = 0; /* MR23 */ -int PURIFY = 1; /* MR23 */ - -int CurBlockID_array[MAX_BLK_LEVEL]; /* MR23 */ -int CurAltNum_array[MAX_BLK_LEVEL]; /* MR23 */ diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/hash.c b/Tools/CodeTools/TianoTools/Pccts/antlr/hash.c deleted file mode 100644 index 68fe8fd227..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/hash.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * hash.c - * - * Manage hash tables. - * - * The following functions are visible: - * - * char *mystrdup(char *); Make space and copy string - * Entry **newHashTable(); Create and return initialized hash table - * Entry *hash_add(Entry **, char *, Entry *) - * Entry *hash_get(Entry **, char *) - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2001 - */ - -#include -#include "pcctscfg.h" -#include "hash.h" - -#ifdef __USE_PROTOS -#include -#else -#ifdef VAXC -#include -#else -#include -#endif -#endif -#include - -#define StrSame 0 - -#define fatal(err) \ - {fprintf(stderr, "%s(%d):", __FILE__, __LINE__); \ - fprintf(stderr, " %s\n", err); exit(PCCTS_EXIT_FAILURE);} -#define require(expr, err) {if ( !(expr) ) fatal(err);} - -static unsigned size = HashTableSize; -static char *strings = NULL; -static char *strp; -static unsigned strsize = StrTableSize; - -/* create the hash table and string table for terminals (string table only once) */ -Entry ** -#ifdef __USE_PROTOS -newHashTable( void ) -#else -newHashTable( ) -#endif -{ - Entry **table; - - table = (Entry **) calloc(size, sizeof(Entry *)); - require( table != NULL, "cannot allocate hash table"); - if ( strings == NULL ) - { - strings = (char *) calloc(strsize, sizeof(char)); - require( strings != NULL, "cannot allocate string table"); - strp = strings; - } - return table; -} - -void -#ifdef __USE_PROTOS -killHashTable( Entry **table ) -#else -killHashTable( table ) -Entry **table; -#endif -{ - /* for now, just free table, forget entries */ - free( (char *) table ); /* MR10 cast */ -} - -/* Given a table, add 'rec' with key 'key' (add to front of list). return ptr to entry */ -Entry * -#ifdef __USE_PROTOS -hash_add( Entry **table, char *key, Entry *rec ) -#else -hash_add( table, key, rec ) -Entry **table; -char *key; -Entry *rec; -#endif -{ - unsigned h=0; - char *p=key; - require(table!=NULL && key!=NULL && rec!=NULL, "add: invalid addition"); - - Hash(p,h,size); - rec->next = table[h]; /* Add to singly-linked list */ - table[h] = rec; - return rec; -} - -/* Return ptr to 1st entry found in table under key (return NULL if none found) */ -Entry * -#ifdef __USE_PROTOS -hash_get( Entry **table, char *key ) -#else -hash_get( table, key ) -Entry **table; -char *key; -#endif -{ - unsigned h=0; - char *p=key; - Entry *q; -/* require(table!=NULL && key!=NULL, "get: invalid table and/or key");*/ - if ( !(table!=NULL && key!=NULL) ) *((char *) 34) = 3; - - Hash(p,h,size); - for (q = table[h]; q != NULL; q = q->next) - { - if ( strcmp(key, q->str) == StrSame ) return( q ); - } - return( NULL ); -} - -#ifdef DEBUG_HASH -void -#ifdef __USE_PROTOS -hashStat( Entry **table ) -#else -hashStat( table ) -Entry **table; -#endif -{ - static unsigned short count[20]; - int i,n=0,low=0, hi=0; - Entry **p; - float avg=0.0; - - for (i=0; i<20; i++) count[i] = 0; - for (p=table; p<&(table[size]); p++) - { - Entry *q = *p; - int len; - - if ( q != NULL && low==0 ) low = p-table; - len = 0; - if ( q != NULL ) fprintf(stderr, "[%d]", p-table); - while ( q != NULL ) - { - len++; - n++; - fprintf(stderr, " %s", q->str); - q = q->next; - if ( q == NULL ) fprintf(stderr, "\n"); - } - count[len]++; - if ( *p != NULL ) hi = p-table; - } - - fprintf(stderr, "Storing %d recs used %d hash positions out of %d\n", - n, size-count[0], size); - fprintf(stderr, "%f %% utilization\n", - ((float)(size-count[0]))/((float)size)); - for (i=0; i<20; i++) - { - if ( count[i] != 0 ) - { - avg += (((float)(i*count[i]))/((float)n)) * i; - fprintf(stderr, "Bucket len %d == %d (%f %% of recs)\n", - i, count[i], ((float)(i*count[i]))/((float)n)); - } - } - fprintf(stderr, "Avg bucket length %f\n", avg); - fprintf(stderr, "Range of hash function: %d..%d\n", low, hi); -} -#endif - -/* Add a string to the string table and return a pointer to it. - * Bump the pointer into the string table to next avail position. - */ -char * -#ifdef __USE_PROTOS -mystrdup( char *s ) -#else -mystrdup( s ) -char *s; -#endif -{ - char *start=strp; - require(s!=NULL, "mystrdup: NULL string"); - - while ( *s != '\0' ) - { - require( strp <= &(strings[strsize-2]), - "string table overflow\nIncrease StrTableSize in hash.h and recompile hash.c\n"); - *strp++ = *s++; - } - *strp++ = '\0'; - - return( start ); -} diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/hash.h b/Tools/CodeTools/TianoTools/Pccts/antlr/hash.h deleted file mode 100644 index 3969c40b4a..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/hash.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * hash.h -- define hash table entries, sizes, hash function... - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2001 - */ - - /* H a s h T a b l e S t u f f */ - -#ifndef HashTableSize -#define HashTableSize 553 -#endif - -#ifndef StrTableSize -#ifdef PC32 -#define StrTableSize 1000000 -#endif -#endif - -#ifndef StrTableSize -#ifdef PC -#define StrTableSize 655200 -#endif -#endif - -#ifndef StrTableSize -#define StrTableSize 1000000 -#endif - -typedef struct _entry { /* Minimum hash table entry -- superclass */ - char *str; - struct _entry *next; - } Entry; - -/* Hash 's' using 'size', place into h (s is modified) */ -#define Hash(s,h,size) \ - {while ( *s != '\0' ) h = (h<<1) + *s++; \ - h %= size;} - -#ifdef __USE_PROTOS -Entry *hash_get(Entry **, char *), - **newHashTable(void), - *hash_add(Entry **, char *, Entry *); - -void killHashTable(Entry **); - -#else -Entry *hash_get(), **newHashTable(), *hash_add(); -void killHashTable(); /* MR9 23-Sep-97 */ -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/lex.c b/Tools/CodeTools/TianoTools/Pccts/antlr/lex.c deleted file mode 100644 index 8c524fe465..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/lex.c +++ /dev/null @@ -1,878 +0,0 @@ -/* - * lex.c -- Generate all of the lexical type files: parser.dlg tokens.h - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2001 - */ - -#include -#include -/* MR1 */ -/* MR1 10-Apr-97 MR1 Replace use of __STDC__ with __USE_PROTOS */ -/* MR1 */ -#include "pcctscfg.h" -#include "set.h" -#include "syn.h" -#include "hash.h" -#include "generic.h" - -#define DLGErrorString "invalid token" - -/* Generate a complete lexical description of the lexemes found in the grammar */ -void -#ifdef __USE_PROTOS -genLexDescr( void ) -#else -genLexDescr( ) -#endif -{ - ListNode *p; - FILE *dlgFile = fopen(OutMetaName(DlgFileName), "w"); - require(dlgFile!=NULL, eMsg1("genLexFile: cannot open %s", OutMetaName(DlgFileName)) ); -#ifdef SPECIAL_FOPEN - special_fopen_actions(OutMetaName(DlgFileName)); /* MR1 */ -#endif - fprintf(dlgFile, "<<\n"); - fprintf(dlgFile, "/* %s -- DLG Description of scanner\n", DlgFileName); - fprintf(dlgFile, " *\n"); - fprintf(dlgFile, " * Generated from:"); - {int i; for (i=0; i 1 ) fprintf(dlgFile, "#define LL_K %d\n", OutputLL_k); - if ( DemandLookahead ) fprintf(dlgFile, "#define DEMAND_LOOK\n"); - if (TraceGen) { - fprintf(dlgFile,"#ifndef zzTRACE_RULES\n"); /* MR20 */ - fprintf(dlgFile,"#define zzTRACE_RULES\n"); /* MR20 */ - fprintf(dlgFile,"#endif\n"); /* MR22 */ - }; - fprintf(dlgFile, "#include \"antlr.h\"\n"); - if ( GenAST ) { - fprintf(dlgFile, "#include \"ast.h\"\n"); - } - if ( UserDefdTokens ) - fprintf(dlgFile, "#include %s\n", UserTokenDefsFile); - /* still need this one as it has the func prototypes */ - fprintf(dlgFile, "#include \"%s\"\n", DefFileName); - fprintf(dlgFile, "#include \"dlgdef.h\"\n"); - fprintf(dlgFile, "LOOKAHEAD\n"); - fprintf(dlgFile, "\n"); - fprintf(dlgFile, "void\n"); - fprintf(dlgFile, "#ifdef __USE_PROTOS\n"); - fprintf(dlgFile, "zzerraction(void)\n"); - fprintf(dlgFile, "#else\n"); - fprintf(dlgFile, "zzerraction()\n"); - fprintf(dlgFile, "#endif\n"); - fprintf(dlgFile, "{\n"); - fprintf(dlgFile, "\t(*zzerr)(\"%s\");\n", DLGErrorString); - fprintf(dlgFile, "\tzzadvance();\n"); - fprintf(dlgFile, "\tzzskip();\n"); - fprintf(dlgFile, "}\n"); - } - fprintf(dlgFile, ">>\n\n"); - - /* dump all actions */ - -/* MR1 */ -/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ -/* MR1 via <<%%lexmember ....>> & <<%%lexprefix ...>> */ -/* MR1 */ - if (LexActions != NULL) { - for (p = LexActions->next; p!=NULL; p=p->next) - { -/* MR1 */ fprintf(dlgFile, "<<%%%%lexaction\n"); - dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 ); - fprintf(dlgFile, ">>\n\n"); - } - }; - -/* MR1 */ if (GenCC) { -/* MR1 */ fprintf(dlgFile,"<<%%%%parserclass %s>>\n\n",CurrentClassName); -/* MR1 */ }; - -/* MR1 */ if (LexPrefixActions != NULL) { -/* MR1 */ for (p = LexPrefixActions->next; p!=NULL; p=p->next) -/* MR1 */ { -/* MR1 */ fprintf(dlgFile, "<<%%%%lexprefix\n"); -/* MR1 */ dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 ); -/* MR1 */ fprintf(dlgFile, ">>\n\n"); -/* MR1 */ } -/* MR1 */ }; - -/* MR1 */ if (LexMemberActions != NULL) { -/* MR1 */ for (p = LexMemberActions->next; p!=NULL; p=p->next) -/* MR1 */ { -/* MR1 */ fprintf(dlgFile, "<<%%%%lexmember\n"); -/* MR1 */ dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 ); -/* MR1 */ fprintf(dlgFile, ">>\n\n"); -/* MR1 */ } -/* MR1 */ }; - - /* dump all regular expression rules/actions (skip sentinel node) */ - if ( ExprOrder == NULL ) { - warnNoFL("no regular expressions found in grammar"); - } - else dumpLexClasses(dlgFile); - fprintf(dlgFile, "%%%%\n"); - fclose( dlgFile ); -} - -/* For each lexical class, scan ExprOrder looking for expressions - * in that lexical class. Print out only those that match. - * Each element of the ExprOrder list has both an expr and an lclass - * field. - */ -void -#ifdef __USE_PROTOS -dumpLexClasses( FILE *dlgFile ) -#else -dumpLexClasses( dlgFile ) -FILE *dlgFile; -#endif -{ - int i; - TermEntry *t; - ListNode *p; - Expr *q; - - for (i=0; inext; p!=NULL; p=p->next) - { - q = (Expr *) p->elem; - if ( q->lclass != i ) continue; - lexmode(i); - t = (TermEntry *) hash_get(Texpr, q->expr); - require(t!=NULL, eMsg1("genLexDescr: rexpr %s not in hash table",q->expr) ); - if ( t->token == EpToken ) continue; - fprintf(dlgFile, "%s\n\t<<\n", StripQuotes(q->expr)); - /* replace " killed by StripQuotes() */ - q->expr[ strlen(q->expr) ] = '"'; - if ( !GenCC ) { - if ( TokenString(t->token) != NULL ) - fprintf(dlgFile, "\t\tNLA = %s;\n", TokenString(t->token)); - else - fprintf(dlgFile, "\t\tNLA = %d;\n", t->token); - } - if ( t->action != NULL ) dumpAction( t->action, dlgFile, 2,-1,0,1 ); - if ( GenCC ) { - if ( TokenString(t->token) != NULL ) - fprintf(dlgFile, "\t\treturn %s;\n", TokenString(t->token)); - else - fprintf(dlgFile, "\t\treturn (ANTLRTokenType)%d;\n", t->token); - } - fprintf(dlgFile, "\t>>\n\n"); - } - } -} - -/* Strip the leading path (if any) from a filename */ -char * -#ifdef __USE_PROTOS -StripPath( char *fileName ) -#else -StripPath( fileName ) -char *fileName; -#endif -{ - char *p; - static char dirSym[2] = DirectorySymbol; - - if(NULL != (p = strrchr(fileName, dirSym[0]))) - p++; - else - p = fileName; - - return(p); -} - -/* Generate a list of #defines && list of struct definitions for - * aggregate retv's */ -void -#ifdef __USE_PROTOS -genDefFile( void ) -#else -genDefFile( ) -#endif -{ - int i; - - /* If C++ mode and #tokdef used, then don't need anything in here since - * C++ puts all definitions in the class file name. - */ - if ( GenCC && UserTokenDefsFile ) return; - if ( MR_Inhibit_Tokens_h_Gen) return; - - DefFile = fopen(OutMetaName(DefFileName), "w"); - require(DefFile!=NULL, eMsg1("genDefFile: cannot open %s", OutMetaName(DefFileName)) ); -#ifdef SPECIAL_FOPEN - special_fopen_actions(OutMetaName(DefFileName)); /* MR1 */ -#endif - fprintf(DefFile, "#ifndef %s\n", StripPath(gate_symbol(DefFileName))); - fprintf(DefFile, "#define %s\n", StripPath(gate_symbol(DefFileName))); - - fprintf(DefFile, "/* %s -- List of labelled tokens and stuff\n", DefFileName); - fprintf(DefFile, " *\n"); - fprintf(DefFile, " * Generated from:"); - for (i=0; i1 ) - { - int j; - /* look in all lexclasses for the reg expr */ - -/* MR10 Derek Pappas */ -/* MR10 A #tokclass doesn't have associated regular expressiones */ -/* MR10 so don't warn user about it's omission */ - - p = (TermEntry *) hash_get(Tname, TokenString(i)); - - if (p != NULL && ! p->classname) { - for (j=0; j=NumLexClasses ) - { - warnNoFL(eMsg1("token label has no associated rexpr: %s",TokenString(i))); - } - }; - } - require((p=(TermEntry *)hash_get(Tname, TokenString(i))) != NULL, - "token not in sym tab when it should be"); - if ( !p->classname ) - { - if ( GenCC ) { - if ( !first ) fprintf(DefFile, ",\n"); - first = 0; - fprintf(DefFile, "\t%s=%d", TokenString(i), i); - } - else - fprintf(DefFile, "#define %s %d\n", TokenString(i), i); - } - } - } -/* MR1 */ -/* MR1 10-Apr-97 133MR1 Prevent use of varying sizes of integer */ -/* MR1 for the enum ANTLRTokenType */ -/* MR1 */ - if ( GenCC ) { /* MR1 */ - if ( !first ) fprintf(DefFile, ",\n"); /* MR14 */ - fprintf(DefFile, "\tDLGminToken=0"); /* MR1 */ - fprintf(DefFile, ",\n\tDLGmaxToken=9999};\n"); /* MR1 */ - }; /* MR1 */ - } - - if ( !GenCC ) GenRulePrototypes(DefFile, SynDiag); - - fprintf(DefFile, "\n#endif\n"); -} - -void -#ifdef __USE_PROTOS -GenRemapFile( void ) -#else -GenRemapFile( ) -#endif -{ - if ( strcmp(ParserName, DefaultParserName)!=0 ) - { - FILE *f; - int i; - - f = fopen(OutMetaName(RemapFileName), "w"); - require(f!=NULL, eMsg1("GenRemapFile: cannot open %s", OutMetaName(RemapFileName)) ); -#ifdef SPECIAL_FOPEN - special_fopen_actions(OutMetaName(RemapFileName)); /* MR1 */ -#endif - fprintf(f, "/* %s -- List of symbols to remap\n", RemapFileName); - fprintf(f, " *\n"); - fprintf(f, " * Generated from:"); - for (i=0; irname, ParserName, p->rname); - p = (Junction *)p->p2; - } -} - -/* Generate a bunch of #defines that rename all standard symbols to be - * "ParserName_symbol". The list of standard symbols to change is in - * globals.c. - */ -void -#ifdef __USE_PROTOS -GenPredefinedSymbolRedefs( FILE *f ) -#else -GenPredefinedSymbolRedefs( f ) -FILE *f; -#endif -{ - char **p; - - fprintf(f, "\n/* rename PCCTS-supplied symbols to be 'ParserName_symbol' */\n"); - for (p = &StandardSymbols[0]; *p!=NULL; p++) - { - fprintf(f, "#define %s %s_%s\n", *p, ParserName, *p); - } -} - -/* Generate a bunch of #defines that rename all AST symbols to be - * "ParserName_symbol". The list of AST symbols to change is in - * globals.c. - */ -void -#ifdef __USE_PROTOS -GenASTSymbolRedefs( FILE *f ) -#else -GenASTSymbolRedefs( f ) -FILE *f; -#endif -{ - char **p; - - fprintf(f, "\n/* rename PCCTS-supplied AST symbols to be 'ParserName_symbol' */\n"); - for (p = &ASTSymbols[0]; *p!=NULL; p++) - { - fprintf(f, "#define %s %s_%s\n", *p, ParserName, *p); - } -} - -/* redefine all sets generated by ANTLR; WARNING: 'zzerr', 'setwd' must match - * use in bits.c (DumpSetWd() etc...) - */ -void -#ifdef __USE_PROTOS -GenSetRedefs( FILE *f ) -#else -GenSetRedefs( f ) -FILE *f; -#endif -{ - int i; - - for (i=1; i<=wordnum; i++) - { - fprintf(f, "#define setwd%d %s_setwd%d\n", i, ParserName, i); - } - for (i=1; i<=esetnum; i++) - { - fprintf(f, "#define zzerr%d %s_err%d\n", i, ParserName, i); - } -} - -/* Find all return types/parameters that require structs and def - * all rules with ret types. - * - * This is for the declaration, not the definition. - */ -void -#ifdef __USE_PROTOS -GenRulePrototypes( FILE *f, Junction *p ) -#else -GenRulePrototypes( f, p ) -FILE *f; -Junction *p; -#endif -{ - int i; - - i = 1; - while ( p!=NULL ) - { - if ( p->ret != NULL ) - { -/* MR23 */ if ( hasMultipleOperands(p->ret) ) - { - DumpRetValStruct(f, p->ret, i); - } - fprintf(f, "\n#ifdef __USE_PROTOS\n"); -/* MR23 */ if ( hasMultipleOperands(p->ret) ) - { - fprintf(f, "extern struct _rv%d", i); - } - else - { - fprintf(f, "extern "); - DumpType(p->ret, f); - } - fprintf(f, " %s%s(", RulePrefix, p->rname); - DumpANSIFunctionArgDef(f,p,1 /* emit initializers ? */); - fprintf(f, ";\n"); - fprintf(f, "#else\n"); -/* MR23 */ if ( hasMultipleOperands(p->ret) ) - { - fprintf(f, "extern struct _rv%d", i); - } - else - { - fprintf(f, "extern "); - DumpType(p->ret, f); - } - fprintf(f, " %s%s();\n", RulePrefix, p->rname); - fprintf(f, "#endif\n"); - } - else - { - fprintf(f, "\n#ifdef __USE_PROTOS\n"); - fprintf(f, "void %s%s(", RulePrefix, p->rname); - DumpANSIFunctionArgDef(f,p, 1 /* emit initializers ? */ ); - fprintf(f, ";\n"); -#ifdef OLD - if ( p->pdecl != NULL || GenAST ) - { - if ( GenAST ) { - fprintf(f, "AST **%s",(p->pdecl!=NULL)?",":""); - } - if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl); - } - else fprintf(f, "void"); - fprintf(f, ");\n"); -#endif - fprintf(f, "#else\n"); - fprintf(f, "extern void %s%s();\n", RulePrefix, p->rname); - fprintf(f, "#endif\n"); - } - i++; - p = (Junction *)p->p2; - } -} - -/* Define all rules in the class.h file; generate any required - * struct definitions first, however. - */ -void -#ifdef __USE_PROTOS -GenRuleMemberDeclarationsForCC( FILE *f, Junction *q ) -#else -GenRuleMemberDeclarationsForCC( f, q ) -FILE *f; -Junction *q; -#endif -{ - Junction *p = q; - int i; - - fprintf(f, "private:\n"); - - /* Dump dflt handler declaration */ - fprintf(f, "\tvoid zzdflthandlers( int _signal, int *_retsignal );\n\n"); - - fprintf(f, "public:\n"); - - /* Dump return value structs */ - i = 1; - while ( p!=NULL ) - { - if ( p->ret != NULL ) - { -/* MR23 */ if ( hasMultipleOperands(p->ret) ) - { - DumpRetValStruct(f, p->ret, i); - } - } - i++; - p = (Junction *)p->p2; - } - - /* Dump member func defs && CONSTRUCTOR */ - fprintf(f, "\t%s(ANTLRTokenBuffer *input);\n", CurrentClassName); -/* - fprintf(f, "\t%s(ANTLRTokenBuffer *input, ANTLRTokenType eof);\n", - CurrentClassName); -*/ - - i = 1; - p = q; - while ( p!=NULL ) - { - if ( p->ret != NULL ) - { -/* MR23 */ if ( hasMultipleOperands(p->ret) ) - { - fprintf(f, "\tstruct _rv%d", i); - } - else - { - fprintf(f, "\t"); - DumpType(p->ret, f); - } - fprintf(f, " %s%s(",RulePrefix,p->rname); - DumpANSIFunctionArgDef(f,p, 1 /* emit initializers ? */ ); - fprintf(f, ";\n"); -#ifdef OLD - if ( p->pdecl != NULL || GenAST ) - { - if ( GenAST ) fprintf(f, "ASTBase **%s",(p->pdecl!=NULL)?",":""); - if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl); - } - fprintf(f, ");\n"); -#endif - } - else - { - fprintf(f, "\tvoid %s%s(",RulePrefix,p->rname); - DumpANSIFunctionArgDef(f,p, 1 /* emit initializers ? */); - fprintf(f, ";\n"); -#ifdef OLD - if ( p->pdecl != NULL || GenAST ) - { - if ( GenAST ) fprintf(f, "ASTBase **%s",(p->pdecl!=NULL)?",":""); - if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl); - } - fprintf(f, ");\n"); -#endif - } - i++; - p = (Junction *)p->p2; - } -} - -/* Given a list of ANSI-style parameter declarations, print out a - * comma-separated list of the symbols (w/o types). - * Basically, we look for a comma, then work backwards until start of - * the symbol name. Then print it out until 1st non-alnum char. Now, - * move on to next parameter. - * - */ - -/* MR5 Jan Mikkelsen 26-May-97 - added initalComma parameter */ - -void -#ifdef __USE_PROTOS -DumpListOfParmNames(char *pdecl, FILE *output, int initialComma) /* MR5 */ -#else -DumpListOfParmNames(pdecl, output, initialComma) /* MR5 */ -char *pdecl; /* MR5 */ -FILE *output; /* MR5 */ -int initialComma; /* MR5 */ -#endif -{ - int firstTime = 1, done = 0; - require(output!=NULL, "DumpListOfParmNames: NULL parm"); - - if ( pdecl == NULL ) return; - while ( !done ) - { - if ( !firstTime || initialComma ) putc(',', output); /* MR5 */ - done = DumpNextNameInDef(&pdecl, output); - firstTime = 0; - } -} - -/* given a list of parameters or return values, dump the next - * name to output. Return 1 if last one just printed, 0 if more to go. - */ - -/* MR23 Total rewrite */ - -int -#ifdef __USE_PROTOS -DumpNextNameInDef( char **q, FILE *output ) -#else -DumpNextNameInDef( q, output ) -char **q; -FILE *output; -#endif -{ - char *p; - char *t; - char *pDataType; - char *pSymbol; - char *pEqualSign; - char *pValue; - char *pSeparator; - int nest = 0; - - p = endFormal(*q, - &pDataType, - &pSymbol, - &pEqualSign, - &pValue, - &pSeparator, - &nest); - - /* MR26 Handle rule arguments such as: IIR_Bool (IIR_Decl::*contstraint)() - For this we need to strip off anything which follows the symbol. - */ - -/* MR26 */ t = pSymbol; -/* MR26 */ if (t != NULL) { -/* MR26 */ for (t = pSymbol; *t != 0; t++) { -/* MR26 */ if (! (isalpha(*t) || isdigit(*t) || *t == '_' || *t == '$')) break; -/* MR26 */ } -/* MR26 */ } -/* MR26 */ fprintf(output,strBetween(pSymbol, t, pSeparator)); - - *q = p; - return (*pSeparator == 0); -} - -/* Given a list of ANSI-style parameter declarations, dump K&R-style - * declarations, one per line for each parameter. Basically, convert - * comma to semi-colon, newline. - */ -void -#ifdef __USE_PROTOS -DumpOldStyleParms( char *pdecl, FILE *output ) -#else -DumpOldStyleParms( pdecl, output ) -char *pdecl; -FILE *output; -#endif -{ - require(output!=NULL, "DumpOldStyleParms: NULL parm"); - - if ( pdecl == NULL ) return; - while ( *pdecl != '\0' ) - { - if ( *pdecl == ',' ) - { - pdecl++; - putc(';', output); putc('\n', output); - while ( *pdecl==' ' || *pdecl=='\t' || *pdecl=='\n' ) pdecl++; - } - else {putc(*pdecl, output); pdecl++;} - } - putc(';', output); - putc('\n', output); -} - -/* Take in a type definition (type + symbol) and print out type only */ -/* MR23 Total rewrite */ - -void -#ifdef __USE_PROTOS -DumpType( char *s, FILE *f ) -#else -DumpType( s, f ) -char *s; -FILE *f; -#endif -{ - char *p; - char *pDataType; - char *pSymbol; - char *pEqualSign; - char *pValue; - char *pSeparator; - int nest = 0; - - require(s!=NULL, "DumpType: invalid type string"); - - p = endFormal(s, - &pDataType, - &pSymbol, - &pEqualSign, - &pValue, - &pSeparator, - &nest); - fprintf(f,strBetween(pDataType, pSymbol, pSeparator)); -} - -/* check to see if string e is a word in string s */ -int -#ifdef __USE_PROTOS -strmember( char *s, char *e ) -#else -strmember( s, e ) -char *s; -char *e; -#endif -{ - register char *p; - require(s!=NULL&&e!=NULL, "strmember: NULL string"); - - if ( *e=='\0' ) return 1; /* empty string is always member */ - do { - while ( *s!='\0' && !isalnum(*s) && *s!='_' ) - ++s; - p = e; - while ( *p!='\0' && *p==*s ) {p++; s++;} - if ( *p=='\0' ) { - if ( *s=='\0' ) return 1; - if ( !isalnum (*s) && *s != '_' ) return 1; - } - while ( isalnum(*s) || *s == '_' ) - ++s; - } while ( *s!='\0' ); - return 0; -} - -#if 0 - -/* MR23 Replaced by hasMultipleOperands() */ - -int -#ifdef __USE_PROTOS -HasComma( char *s ) -#else -HasComma( s ) -char *s; -#endif -{ - while (*s!='\0') - if ( *s++ == ',' ) return 1; - return 0; -} -#endif - - -/* MR23 Total rewrite */ - -void -#ifdef __USE_PROTOS -DumpRetValStruct( FILE *f, char *ret, int i ) -#else -DumpRetValStruct( f, ret, i ) -FILE *f; -char *ret; -int i; -#endif -{ - char *p = ret; - char *pDataType; - char *pSymbol; - char *pEqualSign; - char *pValue; - char *pSeparator; - int nest = 0; - - fprintf(f, "\nstruct _rv%d {\n", i); - while (*p != 0 && nest == 0) { - p = endFormal(p, - &pDataType, - &pSymbol, - &pEqualSign, - &pValue, - &pSeparator, - &nest); - fprintf(f,"\t"); - fprintf(f,strBetween(pDataType, pSymbol, pSeparator)); - fprintf(f," "); - fprintf(f,strBetween(pSymbol, pEqualSign, pSeparator)); - fprintf(f,";\n"); - } - fprintf(f,"};\n"); -} - -/* given "s" yield s -- DESTRUCTIVE (we modify s if starts with " else return s) */ -char * -#ifdef __USE_PROTOS -StripQuotes( char *s ) -#else -StripQuotes( s ) -char *s; -#endif -{ - if ( *s == '"' ) - { - s[ strlen(s)-1 ] = '\0'; /* remove last quote */ - return( s+1 ); /* return address past initial quote */ - } - return( s ); -} diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/main.c b/Tools/CodeTools/TianoTools/Pccts/antlr/main.c deleted file mode 100644 index 051ee4ec5d..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/main.c +++ /dev/null @@ -1,1747 +0,0 @@ -/* - * main.c -- main program for PCCTS ANTLR. - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2001 - */ - -/* To set a breakpoint just before exit look for "cleanUp". */ -/* To set a breakpoint for fatal error look for "fatal_intern" */ - -#include - -#include "pcctscfg.h" -#include "stdpccts.h" - -#define MAX_INT_STACK 50 -static int istack[MAX_INT_STACK]; /* Int stack */ -static int isp = MAX_INT_STACK; - -static int DontAcceptFiles = 0; /* if stdin, don't read files */ -static int DontAcceptStdin = 0; /* if files seen first, don't accept stdin */ - -static int tnodes_used_in_guard_predicates_etc; /* MR10 */ - - /* C m d - L i n e O p t i o n S t r u c t & F u n c s */ - -typedef struct _Opt { - char *option; - int arg; -#ifdef __cplusplus - void (*process)(...); -#else - void (*process)(); -#endif - char *descr; - } Opt; - -#ifdef __USE_PROTOS -extern void ProcessArgs(int, char **, Opt *); -#else -extern void ProcessArgs(); -#endif - -#ifdef __USE_PROTOS -int ci_strequ(char *a,char *b) -#else -int ci_strequ(a,b) - char *a; - char *b; -#endif -{ - for ( ;*a != 0 && *b != 0; a++, b++) { - if (toupper(*a) != toupper(*b)) return 0; - } - return (*a == *b); -} - -static void -#ifdef __USE_PROTOS -pStdin( void ) -#else -pStdin( ) -#endif -{ - if ( DontAcceptStdin ) - { - warnNoFL("'-' (stdin) ignored as files were specified first"); - return; - } - - require(NumFiles 8 ) { /* MR6 */ - warnNoFL("tab width must be between 1 and 8"); /* MR6 */ - TabWidth=0; /* MR6 */ - } /* MR6 */ -} /* MR6 */ - -static int ambAidDepthSpecified=0; /* MR11 */ - -static void /* MR11 */ -#ifdef __USE_PROTOS -pAAd( char *s, char *t ) /* MR11 */ -#else -pAAd( s, t ) /* MR11 */ -char *s; /* MR11 */ -char *t; /* MR11 */ -#endif -{ /* MR11 */ - ambAidDepthSpecified=1; /* MR11 */ - MR_AmbAidDepth = atoi(t); /* MR11 */ -} /* MR11 */ - -static void /* MR11 */ -#ifdef __USE_PROTOS -pTreport( char *s, char *t ) /* MR11 */ -#else -pTreport( s, t ) /* MR11 */ - char *s; /* MR11 */ - char *t; /* MR11 */ -#endif -{ /* MR11 */ - TnodesReportThreshold = atoi(t); /* MR11 */ -} /* MR11 */ - -#ifdef __USE_PROTOS -void chkGTFlag(void) /* 7-Apr-97 MR1 */ -#else -void chkGTFlag() /* 7-Apr-97 MR1 */ -#endif -{ - if ( !GenAST ) - warn("#-variable or other AST item referenced w/o -gt option"); -} - - -#ifdef __USE_PROTOS -static void pInfo(char *s, char *t) /* MR10 */ -#else -static void pInfo(s,t) /* MR10 */ - char *s; - char *t; -#endif -{ - char *p; - int q; - for (p=t; *p != 0; p++) { - q=tolower(*p); - if (q=='t') { - InfoT=1; - } else if (q=='p') { - InfoP=1; - } else if (q=='m') { - InfoM=1; - } else if (q=='o') { - InfoO=1; - } else if (q=='0') { - ; /* nothing */ - } else if (q=='f') { - InfoF=1; - } else { - warnNoFL(eMsgd("unrecognized -info option \"%c\"",(int)*p)); - }; - }; -} - -#ifdef __USE_PROTOS -static void pCGen(void) { CodeGen = FALSE; LexGen = FALSE; } -static void pLGen(void) { LexGen = FALSE; } -static void pXTGen(void){ MR_Inhibit_Tokens_h_Gen = TRUE; } -static void pTGen(void) { TraceGen = TRUE; } -static void pSGen(void) { GenExprSetsOpt = FALSE; } -static void pPrt(void) { PrintOut = TRUE; pCGen(); pLGen(); } -static void pPrtA(void) { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); } -static void pAst(void) { GenAST = TRUE; } -static void pANSI(void) { GenANSI = TRUE; } -static void pCr(void) { GenCR = TRUE; } -static void pNOPURIFY(void) { PURIFY = FALSE; } -/*static void pCt(void) { warnNoFL("-ct option is now the default"); }*/ -static void pLI(void) { GenLineInfo = TRUE; GenLineInfoMS = FALSE; } /* MR14 */ -static void pLIms(void) { GenLineInfo = TRUE; GenLineInfoMS = TRUE; } /* MR14 */ -static void pFr(char *s, char *t) {RemapFileName = t;} -static void pFe(char *s, char *t) {ErrFileName = t;} -static void pFl(char *s, char *t) {DlgFileName = t;} -static void pFm(char *s, char *t) {ModeFileName = t;} -static void pFt(char *s, char *t) {DefFileName = t;} - -static void pE1(void) { elevel = 1; } -static void pE2(void) { elevel = 2; } -static void pE3(void) { elevel = 3; } -static void pEGen(void) { GenEClasseForRules = 1; } -static void pDL(void) - { - DemandLookahead = 1; - if ( GenCC ) { - warnNoFL("-gk does not work currently in C++ mode; -gk turned off"); - DemandLookahead = 0; - } - } - -static void pAA(char *s,char *t) {MR_AmbAidRule = t;} /* MR11 */ -static void pAAm(char *s){MR_AmbAidMultiple = 1;} /* MR11 */ -static void pGHdr(void) { GenStdPccts = 1; } -static void pFHdr(char *s, char *t) { stdpccts = t; pGHdr(); } -static void pW1(void) { WarningLevel = 1; } -static void pNewAST(void) { NewAST = 1; } /* MR13 */ -static void ptmakeInParser(void) { tmakeInParser = 1; } /* MR23 */ -static void pAlpha(void) { AlphaBetaTrace = 1; } /* MR14 */ -static void pMR_BlkErr(void) { MR_BlkErr = 1; } /* MR21 */ -static void pStdout(void) {UseStdout = 1; } /* MR6 */ -static void pW2(void) { WarningLevel = 2; } -static void pCC(void) { GenCC = TRUE; } -#else -static void pCGen() { CodeGen = FALSE; LexGen = FALSE; } -static void pLGen() { LexGen = FALSE; } -static void pXTGen(){ MR_Inhibit_Tokens_h_Gen = TRUE; } /* MR14 */ -static void pTGen() { TraceGen = TRUE; } -static void pSGen() { GenExprSetsOpt = FALSE; } -static void pPrt() { PrintOut = TRUE; pCGen(); pLGen(); } -static void pPrtA() { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); } -static void pAst() { GenAST = TRUE; } -static void pANSI() { GenANSI = TRUE; } -static void pCr() { GenCR = TRUE; } -static void pNOPURIFY() { PURIFY = FALSE; } - -/*static void pCt() { warnNoFL("-ct option is now the default"); }*/ -static void pLI() { GenLineInfo = TRUE; GenLineInfoMS = FALSE; } /* MR14 */ -static void pLIms() { GenLineInfo = TRUE; GenLineInfoMS = TRUE; } /* MR14 */ -static void pFr(s,t) char *s, *t; {RemapFileName = t;} -static void pFe(s,t) char *s, *t; {ErrFileName = t;} -static void pFl(s,t) char *s, *t; {DlgFileName = t;} -static void pFm(s,t) char *s, *t; {ModeFileName = t;} -static void pFt(s,t) char *s, *t; {DefFileName = t;} - -static void pE1() { elevel = 1; } -static void pE2() { elevel = 2; } -static void pE3() { elevel = 3; } -static void pEGen() { GenEClasseForRules = 1; } -static void pDL() - { - DemandLookahead = 1; - if ( GenCC ) { - warnNoFL("-gk does not work currently in C++ mode; -gk turned off"); - DemandLookahead = 0; - } - } - -static void pAA(s,t) char *s; char *t; {MR_AmbAidRule = t;} /* MR11 BJS 20-Mar-98 */ -static void pAAm(s) char *s; {MR_AmbAidMultiple = 1;} /* MR11 BJS 20-Mar-98 */ -static void pGHdr() { GenStdPccts = 1; } -static void pFHdr(s,t) char *s, *t; { stdpccts = t; pGHdr(); } -static void pW1() { WarningLevel = 1; } -static void pNewAST() { NewAST = 1; } /* MR13 */ -static void ptmakeInParser() { tmakeInParser = 1; } /* MR23 */ -static void pAlpha() { AlphaBetaTrace = 1; } /* MR14 */ -static void pMR_BlkErr() { MR_BlkErr = 1; } /* MR21 */ -static void pStdout() {UseStdout = 1; } /* MR6 */ -static void pW2() { WarningLevel = 2; } -static void pCC() { GenCC = TRUE; } -#endif - -static void -#ifdef __USE_PROTOS -pPre( char *s, char *t ) -#else -pPre( s, t ) -char *s; -char *t; -#endif -{ - RulePrefix = t; -} - -static void -#ifdef __USE_PROTOS -pOut( char *s, char *t ) -#else -pOut( s, t ) -char *s; -char *t; -#endif -{ - OutputDirectory = t; -} - -static void -#ifdef __USE_PROTOS -pPred( void ) -#else -pPred( ) -#endif -{ - warnNoFL("-pr is no longer used (predicates employed if present); see -prc, -mrhoist, -mrhoistk"); -/* -** if ( DemandLookahead ) -** warnNoFL("-gk conflicts with -pr; -gk turned off"); -** DemandLookahead = 0; -** HoistPredicateContext = 0; -*/ -} - -static void -#ifdef __USE_PROTOS -pPredCtx( char *s, char *t ) -#else -pPredCtx(s,t) -char *s; -char *t; -#endif -{ - if ( ci_strequ(t,"on")) HoistPredicateContext = 1; - else if ( ci_strequ(t,"off")) HoistPredicateContext = 0; - if ( DemandLookahead ) - { - warnNoFL("-gk incompatible with semantic predicate usage; -gk turned off"); - DemandLookahead = 0; - } -} - -static void -#ifdef __USE_PROTOS -pMRhoist( char *s, char *t ) -#else -pMRhoist(s,t) -char *s; -char *t; -#endif -{ - if ( ci_strequ(t,"on")) MRhoisting = 1; - else if ( ci_strequ(t,"off")==0 ) MRhoisting = 0; - if (MRhoisting) { - fprintf(stderr,"Maintenance Release style hoisting enabled for predicates with lookahead depth = 1\n"); - fprintf(stderr," No longer considered experimental\n"); - fprintf(stderr," Can't consider suppression for predicates with lookahead depth > 1\n"); - fprintf(stderr," Implies -prc on but does *not* imply -mrhoistk for k>1 predicates\n"); - fprintf(stderr," This is a reminder, not a warning or error.\n"); - }; -} - -static void -#ifdef __USE_PROTOS -pMRhoistk( char *s, char *t ) -#else -pMRhoistk(s,t) -char *s; -char *t; -#endif -{ - if ( ci_strequ(t,"on")) MRhoistingk = 1; - else if ( ci_strequ(t,"off")==0 ) MRhoistingk = 0; - if (MRhoistingk) { - fprintf(stderr,"EXPERIMENTAL Maintenance Release style hoisting enabled\n"); - fprintf(stderr," Applies to predicates with lookahead depth > 1\n"); - fprintf(stderr," Implies -prc on and -mrhoist on\n"); - }; -} - -static void -#ifdef __USE_PROTOS -pTRes( char *s, char *t ) -#else -pTRes( s, t ) -char *s; -char *t; -#endif -{ - TreeResourceLimit = atoi(t); - if ( TreeResourceLimit <= 0 ) - { - warnNoFL("analysis resource limit (# of tree nodes) must be greater than 0"); - TreeResourceLimit = -1; /* set to no limit */ - } -} - -Opt options[] = { -#ifdef __cplusplus - { "-CC", 0, (void (*)(...)) pCC, "Generate C++ output (default=FALSE)"}, - { "-ck", 1, (void (*)(...)) pCk, "Set compressed lookahead depth; fast approximate lookahead"}, - { "-cr", 0, (void (*)(...)) pCr, "Generate cross reference (default=FALSE)"}, - { "-e1", 0, (void (*)(...)) pE1, "Ambiguities/errors shown in low detail (default)"}, - { "-e2", 0, (void (*)(...)) pE2, "Ambiguities/errors shown in more detail"}, - { "-e3", 0, (void (*)(...)) pE3, - "Ambiguities for k>1 grammars shown with exact tuples (not lookahead sets)"}, - { "-f", 1, (void (*)(...)) pFileList,"Read names of grammar files from specified file"}, /* MR14 */ - { "-fe", 1, (void (*)(...)) pFe, "Rename err.c"}, - { "-fh", 1, (void (*)(...)) pFHdr, "Rename stdpccts.h header (turns on -gh)"}, - { "-fl", 1, (void (*)(...)) pFl, "Rename lexical output--parser.dlg"}, - { "-fm", 1, (void (*)(...)) pFm, "Rename mode.h"}, - { "-fr", 1, (void (*)(...)) pFr, "Rename remap.h"}, - { "-ft", 1, (void (*)(...)) pFt, "Rename tokens.h"}, - { "-ga", 0, (void (*)(...)) pANSI, "Generate ANSI-compatible code (default=FALSE)"}, - { "-gc", 0, (void (*)(...)) pCGen, "Do not generate output parser code (default=FALSE)"}, - { "-gd", 0, (void (*)(...)) pTGen, "Generate code to trace rule invocation (default=FALSE)"}, - { "-ge", 0, (void (*)(...)) pEGen, "Generate an error class for each non-terminal (default=FALSE)"}, - { "-gh", 0, (void (*)(...)) pGHdr, "Generate stdpccts.h for non-ANTLR-generated-files to include"}, - { "-gk", 0, (void (*)(...)) pDL, "Generate parsers that delay lookahead fetches until needed"}, - { "-gl", 0, (void (*)(...)) pLI, "Generate line info about grammar actions in parser"}, - { "-glms", 0, (void (*)(...)) pLIms,"Like -gl but replace '\\' with '/' in #line filenames for MS C/C++ systems"}, - { "-gp", 1, (void (*)(...)) pPre, "Prefix all generated rule functions with a string"}, - { "-gs", 0, (void (*)(...)) pSGen, "Do not generate sets for token expression lists (default=FALSE)"}, - { "-gt", 0, (void (*)(...)) pAst, "Generate code for Abstract-Syntax-Trees (default=FALSE)"}, - { "-gx", 0, (void (*)(...)) pLGen, "Do not generate lexical (dlg-related) files (default=FALSE)"}, - { "-gxt",0, (void (*)(...)) pXTGen, "Do not generate tokens.h (default=FALSE)"}, - { "-k", 1, (void (*)(...)) pLLK, "Set full LL(k) lookahead depth (default==1)"}, - { "-o", 1, (void (*)(...)) pOut, OutputDirectoryOption}, - { "-p", 0, (void (*)(...)) pPrt, "Print out the grammar w/o actions (default=no)"}, - { "-pa", 0, (void (*)(...)) pPrtA, "Print out the grammar w/o actions & w/FIRST sets (default=no)"}, - { "-pr",0, (void (*)(...)) pPred, "no longer used; predicates employed if present"}, - { "-prc", 1, (void (*)(...)) pPredCtx,"Turn on/off computation of context for hoisted predicates"}, - { "-rl", 1, (void (*)(...)) pTRes, "Limit max # of tree nodes used by grammar analysis"}, - { "-stdout",0, (void (*)(...)) pStdout,"Send grammar.c/grammar.cpp to stdout"}, /* MR6 */ - { "-tab", 1, (void (*)(...)) pTab, "Width of tabs (1 to 8) for grammar.c/grammar.cpp files"}, /* MR6 */ - { "-w1", 0, (void (*)(...)) pW1, "Set the warning level to 1 (default)"}, - { "-w2", 0, (void (*)(...)) pW2, "Ambiguities yield warnings even if predicates or (...)? block"}, - { "-", 0, (void (*)(...)) pStdin, "Read grammar from stdin" }, - { "-mrhoist",1, (void (*)(...)) pMRhoist, /* MR9 */ - "Turn on/off k=1 Maintenance Release style hoisting"}, /* MR9 */ - { "-mrhoistk",1, (void (*)(...)) pMRhoistk, /* MR9 */ - "Turn on/off EXPERIMENTAL k>1 Maintenance Release style hoisting"}, /* MR13 */ - { "-aa" , 1, (void (*)(...)) pAA, "Ambiguity aid for a rule (rule name or line number)"}, /* MR11 */ - { "-aam" , 0, (void (*)(...)) pAAm, - "Lookahead token may appear multiple times in -aa listing"}, /* MR11 */ - { "-aad" , 1, (void (*)(...)) pAAd, - "Limits exp growth of -aa listing - default=1 (max=ck value)"}, /* MR11 */ - { "-info", 1, (void (*)(...)) pInfo, - "Extra info: p=pred t=tnodes f=first/follow m=monitor o=orphans 0=noop"}, /* MR12 */ - { "-treport",1,(void (*)(...)) pTreport, - "Report when tnode usage exceeds value during ambiguity resolution"}, /* MR11 */ - { "-newAST", 0, (void (*)(...)) pNewAST, - "In C++ mode use \"newAST(...)\" rather than \"new AST(...)\""}, /* MR13 */ - { "-tmake", 0, (void (*)(...)) ptmakeInParser, - "In C++ mode use parser's tmake method rather than \"ASTBase::tmake(...)\""}, /* MR23 */ - { "-alpha",0,(void (*)(...)) pAlpha, - "Provide additional information for \"(alpha)? beta\" error messages"}, /* MR14 */ - { "-mrblkerr",0,(void (*)(...)) pMR_BlkErr, /* MR21 */ - "EXPERIMENTAL change to (...)* and (...)+ syntax error sets"}, /* MR21 */ - { "-nopurify",0,(void (*)(...)) pNOPURIFY, - "Don't use the notorious PURIFY macro (replaced by MR23 initial value syntax) to zero return arguments of rules"}, /* MR23 */ - { "*", 0, (void (*)(...)) pFile, "" }, /* anything else is a file */ -#else - { "-CC", 0, pCC, "Generate C++ output (default=FALSE)"}, - { "-cr", 0, pCr, "Generate cross reference (default=FALSE)"}, - { "-ck", 1, pCk, "Set compressed lookahead depth; fast approximate lookahead"}, - { "-e1", 0, pE1, "Ambiguities/errors shown in low detail (default)"}, - { "-e2", 0, pE2, "Ambiguities/errors shown in more detail"}, - { "-e3", 0, pE3, "Ambiguities for k>1 grammars shown with exact tuples (not lookahead sets)"}, - { "-f", 1, pFileList,"Read names of grammar files from specified file"}, /* MR14 */ - { "-fe", 1, pFe, "Rename err.c"}, - { "-fh", 1, pFHdr, "Rename stdpccts.h header (turns on -gh)"}, - { "-fl", 1, pFl, "Rename lexical output--parser.dlg"}, - { "-fm", 1, pFm, "Rename mode.h"}, - { "-fr", 1, pFr, "Rename remap.h"}, - { "-ft", 1, pFt, "Rename tokens.h"}, - { "-ga", 0, pANSI, "Generate ANSI-compatible code (default=FALSE)"}, - { "-gc", 0, pCGen, "Do not generate output parser code (default=FALSE)"}, - { "-gd", 0, pTGen, "Generate code to trace rule invocation (default=FALSE)"}, - { "-ge", 0, pEGen, "Generate an error class for each non-terminal (default=FALSE)"}, - { "-gh", 0, pGHdr, "Generate stdpccts.h for non-ANTLR-generated-files to include"}, - { "-gk", 0, pDL, "Generate parsers that delay lookahead fetches until needed"}, - { "-gl", 0, pLI, "Generate line info about grammar actions in C parser"}, - { "-glms", 0, pLIms,"Like -gl but replace '\\' with '/' in #line filenames for MS C/C++ systems"}, - { "-gp", 1, pPre, "Prefix all generated rule functions with a string"}, - { "-gs", 0, pSGen, "Do not generate sets for token expression lists (default=FALSE)"}, - { "-gt", 0, pAst, "Generate code for Abstract-Syntax-Trees (default=FALSE)"}, - { "-gx", 0, pLGen, "Do not generate lexical (dlg-related) files (default=FALSE)"}, - { "-gxt",0, pXTGen, "Do not generate tokens.h (default=FALSE)"}, - { "-k", 1, pLLK, "Set full LL(k) lookahead depth (default==1)"}, - { "-o", 1, pOut, OutputDirectoryOption}, - { "-p", 0, pPrt, "Print out the grammar w/o actions (default=no)"}, - { "-pa", 0, pPrtA, "Print out the grammar w/o actions & w/FIRST sets (default=no)"}, - { "-pr",0, pPred, "no longer used; predicates employed if present"}, - { "-prc", 1, pPredCtx,"Turn on/off computation of context for hoisted predicates"}, - { "-rl", 1, pTRes, "Limit max # of tree nodes used by grammar analysis"}, - { "-stdout",0, pStdout, "Send grammar.c/grammar.cpp to stdout"}, /* MR6 */ - { "-tab", 1, pTab, "Width of tabs (1 to 8) for grammar.c/grammar.cpp files"}, /* MR6 */ - { "-w1", 0, pW1, "Set the warning level to 1 (default)"}, - { "-w2", 0, pW2, "Ambiguities yield warnings even if predicates or (...)? block"}, - { "-mrhoist",1,pMRhoist, /* MR9 */ - "Turn on/off k=1 Maintenance Release style hoisting"}, /* MR9 */ - { "-mrhoistk",1,pMRhoistk, /* MR13 */ - "Turn on/off k>1 EXPERIMENTAL Maintenance Release style hoisting"}, /* MR13 */ - { "-aa" ,1,pAA, "Ambiguity aid for a rule (rule name or line number)"}, /* MR11 */ - { "-aam" ,0,pAAm, - "Lookahead token may appear multiple times in -aa listing"}, /* MR11 */ - { "-aad" ,1,pAAd, - "Limits exp growth of -aa listing - default=1 (max=ck value)"}, /* MR11 */ - { "-info",1,pInfo, - "Extra info: p=pred t=tnodes f=first/follow m=monitor o=orphans 0=noop"}, /* MR11 */ - { "-treport",1,pTreport, - "Report when tnode usage exceeds value during ambiguity resolution"}, /* MR11 */ - { "-newAST", 0, pNewAST, - "In C++ mode use \"newAST(...)\" rather than \"new AST(...)\""}, /* MR13 */ - { "-tmake", 0, ptmakeInParser, - "In C++ mode use parser's tmake method rather than \"ASTBase::tmake(...)\""}, /* MR23 */ - { "-alpha",0, pAlpha, - "Provide additional information for \"(alpha)? beta\" error messages"}, /* MR14 */ - { "-mrblkerr",0,pMR_BlkErr, /* MR21 */ - "EXPERIMENTAL change to (...)* and (...)+ syntax error sets"}, /* MR21 */ - { "-nopurify",0,pNOPURIFY, - "Don't use the notorious PURIFY macro (replaced by MR23 initial value syntax) to zero return arguments of rules"}, /* MR23 */ - { "-", 0, pStdin, "Read grammar from stdin" }, - { "*", 0, pFile, "" }, /* anything else is a file */ -#endif - { NULL, 0, NULL } - }; - -void readDescr(); -void cleanUp(); - -#ifdef __USE_PROTOS -static void buildRulePtr( void ); -static void help( void ); -static void init( void ); -static void CompleteTokenSetRefs( void ); -static void ensure_no_C_file_collisions(char *); -static void CompleteContextGuards(void); -#else -static void buildRulePtr( ); -static void help( ); -static void init( ); -static void CompleteTokenSetRefs( ); -static void ensure_no_C_file_collisions(); -static void CompleteContextGuards(); -#endif - -static void -#ifdef __USE_PROTOS /* */ -report_numericPredLabels(ActionNode *a) -#else -report_numericPredLabels(a) -ActionNode *a; -#endif -{ /* MR10 */ - warnFL("numeric references to attributes (e.g. $i or $i.j) in semantic pred will be null during guess mode", /* MR10 */ - FileStr[a->file],a->line); /* MR10 */ -} /* MR10 */ - - /* M a i n */ - -int -#ifdef __USE_PROTOS -main( int argc, char *argv[] ) -#else -main( argc, argv ) -int argc; -char *argv[]; -#endif -{ - int i; - static char EPSTR[] = "[Ep]"; - - Save_argc=argc; /* MR10 */ - Save_argv=argv; /* MR10 */ - -/* malloc_debug(8);*/ - -#ifdef SPECIAL_INITS - special_inits(); /* MR1 */ -#endif - fprintf(stderr, "Antlr parser generator Version %s 1989-2001\n", Version); - if ( argc == 1 ) { help(); zzDIE; } - ProcessArgs(argc-1, &(argv[1]), options); - -/* MR14 */ if (MR_AmbAidRule && AlphaBetaTrace) { -/* MR14 */ fatal("Can't specify both -aa (ambiguity aid) and -alpha (\"(alpha)? beta\" aid)"); -/* MR14 */ } - - if (MRhoistingk) { /* MR13 */ - HoistPredicateContext=1; /* MR13 */ - MRhoisting=1; /* MR13 */ - }; /* MR13 */ - if (MRhoisting && ! HoistPredicateContext) { -/*** warnNoFL("Using \"-mrhoist\" forces \"-prc on\""); ***/ - HoistPredicateContext=1; - }; - if (HoistPredicateContext && ! MRhoisting) { - warnNoFL("When using predicate context (-prc on) -mrhoist on is recommended"); - } - /* Fix lookahead depth */ - /* Compressed lookahead must always be larger than or equal to full lookahead */ - if ( CLL_k < LL_k && CLL_k>0 ) - { - warnNoFL("must have compressed lookahead >= full LL(k) lookahead (setting -ck to -k)"); - CLL_k = LL_k; - } - if ( CLL_k == -1 ) CLL_k = LL_k; - OutputLL_k = CLL_k; - if ( ((CLL_k-1)&CLL_k)!=0 ) { /* output ll(k) must be power of 2 */ - int n; - for(n=1; n 1) { - warnNoFL("The -mrblkerr option is designed only for k=1 ck=1 grammars"); - } - }; - - if ( ! ambAidDepthSpecified) { - MR_AmbAidDepth=1; - } else { - if (MR_AmbAidDepth > CLL_k || MR_AmbAidDepth <= 0) { - warnNoFL(eMsgd( - "Ambiguity aid depth (\"-aad ...\") must be a number between 1 and max(k,ck)=%d",CLL_k)); - MR_AmbAidDepth=1; - }; - if (MR_AmbAidDepth == 0) { - MR_AmbAidDepth=2; - }; - }; - - if (MR_AmbAidRule != NULL) MR_AmbAidLine=atoi(MR_AmbAidRule); - - fpTrans = &(C_Trans[0]); /* Translate to C Language */ - fpJTrans = &(C_JTrans[0]); - init(); - lexclass(LexStartSymbol); - - readDescr(); - LastTokenCounted = TokenNum; - RemapForcedTokens(); - if ( CannotContinue ) {cleanUp(); zzDIE;} - if ( GenCC && no_classes_found ) fatal("required grammar class not found (exiting...)"); - if ( WarningLevel>1 && HdrAction == NULL ) - warnNoFL("no #header action was found"); - if ( FoundAtOperator && ! FoundExceptionGroup) { - warnNoFL("found the exception operator '@' - but no exception group was found"); - }; - EpToken = addTname(EPSTR); /* add imaginary token epsilon */ - set_orel(EpToken, &imag_tokens); - - /* this won't work for hand-built scanners since EofToken is not - * known. Forces EOF to be token type 1. - */ - set_orel(EofToken, &imag_tokens); - - set_size(NumWords(TokenNum-1)); - - /* compute the set of all known token types - * It represents the set of tokens from 1 to last_token_num + the - * reserved positions above that (if any). Don't include the set of - * imaginary tokens such as the token/error classes or EOF. - */ - { - set a; - a = set_dup(reserved_positions); - for (i=1; inext; p!=NULL; p=p->next) - { - UserAction *ua = (UserAction *)p->elem; - dumpAction( ua->action, Parser_h, 0, ua->file, ua->line, 1); - } - } - GenParser_c_Hdr(); - fprintf(Parser_h, "protected:\n"); /* MR20 */ - NewSetWd(); - TRANS(SynDiag); /* Translate to the target language */ - DumpSetWd(); - GenRuleMemberDeclarationsForCC(Parser_h, SynDiag); - if ( class_after_actions != NULL ) - { - ListNode *p; - for (p = class_after_actions->next; p!=NULL; p=p->next) - { - UserAction *ua = (UserAction *)p->elem; - dumpAction( ua->action, Parser_h, 0, ua->file, ua->line, 1); - } - } - DumpRemainingTokSets(); - fprintf(Parser_h, "};\n"); - fprintf(Parser_h, "\n#endif /* %s_h */\n", CurrentClassName); - fclose( Parser_h ); - fclose( Parser_c ); - } - } - - MR_orphanRules(stderr); - if (LTinTokenAction && WarningLevel >= 2) { - if (GenCC) { - warnNoFL("At least one <> following a token match contains a reference to LT(...)\n this will reference the immediately preceding token,\n not the one which follows as is the case with semantic predicates."); - } - warnNoFL("At least one <> following a token match contains a reference to LA(...) or LATEXT(...)\n this will reference the immediately preceding token,\n not the one which follows as is the case with semantic predicates."); - } - - if ( PrintOut ) - { - if ( SynDiag == NULL ) {warnNoFL("no grammar description recognized");} - else PRINT(SynDiag); - } - -#ifdef DBG_LL1 -#endif - GenRemapFile(); /* create remap.h */ -/* MR10 */ if (FoundGuessBlk) { -#ifdef __cplusplus__ -/* MR10 */ list_apply(NumericPredLabels, (void (*)(void *))report_numericPredLabels); -#else -#ifdef __USE_PROTOS -/* MR10 */ list_apply(NumericPredLabels, (void (*)(void *))report_numericPredLabels); -#else -/* MR10 */ list_apply(NumericPredLabels,report_numericPredLabels); -#endif -#endif -/* MR10 */ }; - - if (InfoT && TnodesAllocated > 0) { - if (TnodesPeak > 10000) { - fprintf(stdout,"\nTree Nodes: peak %dk created %dk lost %d\n", - (TnodesPeak/1000), - (TnodesAllocated/1000), - TnodesInUse-tnodes_used_in_guard_predicates_etc); - } else { - fprintf(stdout,"\nTree Nodes: peak %d created %d lost %d\n", - TnodesPeak, - TnodesAllocated, - TnodesInUse-tnodes_used_in_guard_predicates_etc); - }; - }; - if (InfoF) { - DumpFcache(); - }; - if (MR_skipped_e3_report) { - fprintf(stderr,"note: use -e3 to get exact information on ambiguous tuples\n"); - }; - if (MR_BadExprSets != 0) { - fprintf(stderr,"note: Unreachable C or C++ code was generated for empty expression sets,\n"); - fprintf(stderr," probably due to undefined rules or infinite left recursion.\n"); - fprintf(stderr," To locate: search the generated code for \"empty set expression\"\n"); - }; - if (MR_AmbAidRule != NULL && MR_matched_AmbAidRule==0) { - RuleEntry *q = (RuleEntry *) hash_get(Rname,MR_AmbAidRule); - if (MR_AmbAidLine == 0 && q == NULL) { - warnNoFL(eMsg2("there is no rule \"%s\" so \"-aa %s\" will never match", - MR_AmbAidRule,MR_AmbAidRule)); - } else { - warnNoFL(eMsg1("there was no ambiguity that matched \"-aa %s\"",MR_AmbAidRule)); - }; - }; - if (AlphaBetaTrace) { - - if (MR_AlphaBetaMessageCount == 0) { - fprintf(stderr,"note: there were no messages about \"(alpha)? beta\" blocks added to the generated code\n"); - } else { - fprintf(stderr,"note: there were %d messages about \"(alpha)? beta\" blocks added to the generated code\n", - MR_AlphaBetaMessageCount); - } - - if (set_null(MR_CompromisedRules)) { - fprintf(stderr,"note: the list of rules with compromised follow sets is empty\n"); - } else { - fprintf(stderr,"note: the following is a list of rules which *may* have incorrect\n"); - fprintf(stderr," follow sets computed as a result of an \"(alpha)? beta\" block\n"); - fprintf(stderr,"\n"); - MR_dumpRuleSet(MR_CompromisedRules); - fprintf(stderr,"\n"); - } - } - cleanUp(); - exit(PCCTS_EXIT_SUCCESS); - return 0; /* MR11 make compilers happy */ -} - -static void -#ifdef __USE_PROTOS -init( void ) -#else -init( ) -#endif -{ - SignalEntry *q; - - Tname = newHashTable(); - Rname = newHashTable(); - Fcache = newHashTable(); - Tcache = newHashTable(); - Sname = newHashTable(); - Pname = newHashTable(); /* MR11 */ - - /* Add default signal names */ - q = (SignalEntry *)hash_add(Sname, - "NoViableAlt", - (Entry *)newSignalEntry("NoViableAlt")); - require(q!=NULL, "cannot alloc signal entry"); - q->signum = sigNoViableAlt; - q = (SignalEntry *)hash_add(Sname, - "MismatchedToken", - (Entry *)newSignalEntry("MismatchedToken")); - require(q!=NULL, "cannot alloc signal entry"); - q->signum = sigMismatchedToken; - q = (SignalEntry *)hash_add(Sname, - "NoSemViableAlt", - (Entry *)newSignalEntry("NoSemViableAlt")); - require(q!=NULL, "cannot alloc signal entry"); - q->signum = sigNoSemViableAlt; - - reserved_positions = empty; - all_tokens = empty; - imag_tokens = empty; - tokclasses = empty; - TokenStr = (char **) calloc(TSChunk, sizeof(char *)); - require(TokenStr!=NULL, "main: cannot allocate TokenStr"); - FoStack = (int **) calloc(CLL_k+1, sizeof(int *)); - require(FoStack!=NULL, "main: cannot allocate FoStack"); - FoTOS = (int **) calloc(CLL_k+1, sizeof(int *)); - require(FoTOS!=NULL, "main: cannot allocate FoTOS"); - Cycles = (ListNode **) calloc(CLL_k+1, sizeof(ListNode *)); - require(Cycles!=NULL, "main: cannot allocate Cycles List"); - MR_CompromisedRules=empty; /* MR14 */ -} - -static void -#ifdef __USE_PROTOS -help( void ) -#else -help( ) -#endif -{ - Opt *p = options; - fprintf(stderr, "antlr [options] f1 f2 ... fn\n"); - while ( *(p->option) != '*' ) - { - fprintf(stderr, " %-9s%s %s\n", - p->option, - (p->arg)?"___":" ", - p->descr); - p++; - } -} - -/* The RulePtr array is filled in here. RulePtr exists primarily - * so that sets of rules can be maintained for the FOLLOW caching - * mechanism found in rJunc(). RulePtr maps a rule num from 1 to n - * to a pointer to its RuleBlk junction where n is the number of rules. - */ -static void -#ifdef __USE_PROTOS -buildRulePtr( void ) -#else -buildRulePtr( ) -#endif -{ - int r=1; - Junction *p = SynDiag; - RulePtr = (Junction **) calloc(NumRules+1, sizeof(Junction *)); - require(RulePtr!=NULL, "cannot allocate RulePtr array"); - - while ( p!=NULL ) - { - require(r<=NumRules, "too many rules???"); - RulePtr[r++] = p; - p = (Junction *)p->p2; - } -} - -void -#ifdef __USE_PROTOS -dlgerror(const char *s) -#else -dlgerror(s) -char *s; -#endif -{ - fprintf(stderr, ErrHdr, FileStr[CurFile], zzline); - fprintf(stderr, " lexical error: %s (text was '%s')\n", - ((s == NULL) ? "Lexical error" : s), zzlextext); -} - -void -#ifdef __USE_PROTOS -readDescr( void ) -#else -readDescr( ) -#endif -{ - zzerr = dlgerror; - input = NextFile(); - if ( input==NULL ) fatal("No grammar description found (exiting...)"); - ANTLR(grammar(), input); - tnodes_used_in_guard_predicates_etc=TnodesInUse; /* MR10 */ -} - -FILE * -#ifdef __USE_PROTOS -NextFile( void ) -#else -NextFile( ) -#endif -{ - FILE *f; - - for (;;) - { - CurFile++; - if ( CurFile >= NumFiles ) return(NULL); - if ( ci_strequ(FileStr[CurFile],"stdin")) return stdin; - f = fopen(FileStr[CurFile], "r"); - if ( f == NULL ) - { - warnNoFL( eMsg1("file %s doesn't exist; ignored", FileStr[CurFile]) ); - } - else - { - return(f); - } - } -} - -/* - * Return a string corresponding to the output file name associated - * with the input file name passed in. - * - * Observe the following rules: - * - * f.e --> f".c" - * f --> f".c" - * f. --> f".c" - * f.e.g --> f.e".c" - * - * Where f,e,g are arbitrarily long sequences of characters in a file - * name. - * - * In other words, if a ".x" appears on the end of a file name, make it - * ".c". If no ".x" appears, append ".c" to the end of the file name. - * - * C++ mode using .cpp not .c. - * - * Use malloc() for new string. - */ - -char * -#ifdef __USE_PROTOS -outname( char *fs ) -#else -outname( fs ) -char *fs; -#endif -{ - if ( GenCC) { - return outnameX(fs,CPP_FILE_SUFFIX); - } else { - return outnameX(fs,".c"); - }; -} - -char * -#ifdef __USE_PROTOS -outnameX( char *fs ,char *suffix) -#else -outnameX( fs , suffix ) -char *fs; -char *suffix; -#endif -{ - static char buf[MaxFileName+1]; - char *p; - require(fs!=NULL&&*fs!='\0', "outname: NULL filename"); - - p = buf; - strcpy(buf, fs); - while ( *p != '\0' ) {p++;} /* Stop on '\0' */ - while ( *p != '.' && p != buf ) {--p;} /* Find '.' */ - if ( p != buf ) *p = '\0'; /* Found '.' */ - require(strlen(buf) + 2 < (size_t)MaxFileName, "outname: filename too big"); - strcat(buf,suffix); - return( buf ); -} - -void -#ifdef __USE_PROTOS -fatalFL( char *err_, char *f, int l ) -#else -fatalFL( err_, f, l ) -char *err_; -char *f; -int l; -#endif -{ - fprintf(stderr, ErrHdr, f, l); - fprintf(stderr, " %s\n", err_); - cleanUp(); - exit(PCCTS_EXIT_FAILURE); -} - -void -#ifdef __USE_PROTOS -fatal_intern( char *err_, char *f, int l ) -#else -fatal_intern( err_, f, l ) -char *err_; -char *f; -int l; -#endif -{ - fprintf(stderr, ErrHdr, f, l); - fprintf(stderr, " #$%%*&@# internal error: %s\n", err_); - fprintf(stderr, ErrHdr, f, l); - fprintf(stderr, " [complain to nearest government official\n"); - fprintf(stderr, ErrHdr, f, l); - fprintf(stderr, " or send hate-mail to parrt@parr-research.com;\n"); - fprintf(stderr, ErrHdr, f, l); - fprintf(stderr, " please pray to the ``bug'' gods that there is a trival fix.]\n"); - cleanUp(); - exit(PCCTS_EXIT_FAILURE); -} - -void -#ifdef __USE_PROTOS -cleanUp( void ) -#else -cleanUp( ) -#endif -{ - if ( DefFile != NULL) fclose( DefFile ); -} - -/* sprintf up to 3 strings */ -char * -#ifdef __USE_PROTOS -eMsg3( char *s, char *a1, char *a2, char *a3 ) -#else -eMsg3( s, a1, a2, a3 ) -char *s; -char *a1; -char *a2; -char *a3; -#endif -{ - static char buf[250]; /* DANGEROUS as hell !!!!!! */ - - sprintf(buf, s, a1, a2, a3); - return( buf ); -} - -/* sprintf a decimal */ -char * -#ifdef __USE_PROTOS -eMsgd( char *s, int d ) -#else -eMsgd( s, d ) -char *s; -int d; -#endif -{ - static char buf[250]; /* DANGEROUS as hell !!!!!! */ - - sprintf(buf, s, d); - return( buf ); -} - -char * -#ifdef __USE_PROTOS -eMsgd2( char *s, int d1,int d2) -#else -eMsgd2( s, d1, d2 ) -char *s; -int d1; -int d2; -#endif -{ - static char buf[250]; /* DANGEROUS as hell !!!!!! */ - - sprintf(buf, s, d1, d2); - return( buf ); -} - -void -#ifdef __USE_PROTOS -s_fprT( FILE *f, set e ) -#else -s_fprT( f, e ) -FILE *f; -set e; -#endif -{ - register unsigned *p; - unsigned *q; - - if ( set_nil(e) ) return; - if ( (q=p=set_pdq(e)) == NULL ) fatal_internal("Can't alloc space for set_pdq"); - fprintf(f, "{"); - while ( *p != nil ) - { - fprintf(f, " %s", TerminalString(*p)); - p++; - } - fprintf(f, " }"); - free((char *)q); -} - -/* Return the token name or regular expression for a token number. */ -char * -#ifdef __USE_PROTOS -TerminalString( int token ) -#else -TerminalString( token ) -int token; -#endif -{ - int j; - static char imag_name[20]; - - /* look in all lexclasses for the token */ - if ( TokenString(token) != NULL ) return TokenString(token); - for (j=0; j0, "pushint: stack overflow"); - istack[--isp] = i; -} - -int -#ifdef __USE_PROTOS -popint( void ) -#else -popint( ) -#endif -{ - require(isp 0 ) - { - p = options; - while ( p->option != NULL ) - { - if ( strcmp(p->option, "*") == 0 || - ci_strequ(p->option, *argv) == 1 ) - { - if ( p->arg ) - { -/* MR9 26-Sep-97 Check for argv valid */ - if (argc-- > 0) { - (*p->process)( *argv, *(argv+1) ); - argv++; - } else { -fprintf(stderr,"error: required argument for option %s omitted\n",*argv); -exit(PCCTS_EXIT_FAILURE); - }; - } - else - (*p->process)( *argv ); - break; - } - p++; - } - argv++; - } -} - -static void -#ifdef __USE_PROTOS -CompleteContextGuards(void) -#else -CompleteContextGuards() -#endif -{ - ListNode * p; - Predicate * pred; - - if (ContextGuardPredicateList == NULL) return; - - for (p=ContextGuardPredicateList->next; p != NULL; p=p->next) { - pred=(Predicate *)p->elem; - recomputeContextGuard(pred); - } -} - -/* Go back into the syntax diagram and compute all meta tokens; i.e. - * turn all '.', ranges, token class refs etc... into actual token sets - */ -static void -#ifdef __USE_PROTOS -CompleteTokenSetRefs(void) -#else -CompleteTokenSetRefs() -#endif -{ - ListNode *p; - - if ( MetaTokenNodes==NULL ) return; - for (p = MetaTokenNodes->next; p!=NULL; p=p->next) - { - set a,b; - - TokNode *q = (TokNode *)p->elem; - if ( q->wild_card ) - { - q->tset = all_tokens; - } - else if ( q->tclass!=NULL ) - { - if ( q->complement ) q->tset = set_dif(all_tokens, q->tclass->tset); - else q->tset = q->tclass->tset; - } - else if ( q->upper_range!=0 ) - { - /* we have a range on our hands: make a set from q->token .. q->upper_range */ - int i; - a = empty; - for (i=q->token; i<=q->upper_range; i++) { set_orel(i, &a); } /* MR13 */ - -/* MR13 */ if (q->complement) { -/* MR13 */ q->tset = set_dif(all_tokens, a); -/* MR13 */ set_free(a); -/* MR13 */ } else { -/* MR13 */ q->tset = a; -/* MR13 */ } - - } - - /* at this point, it can only be a complemented single token */ - else if ( q->complement ) - { - a = set_of(q->token); - b = set_dif(all_tokens, a); - set_free(a); - q->tset=b; - } - else fatal("invalid meta token"); - } -} - -/* MR10: Jeff Vincent - MR10: Changed to remove directory information from n only if - MR10: if OutputDirectory was changed by user (-o option) -*/ - -char * -#ifdef __USE_PROTOS -OutMetaName(char *n) -#else -OutMetaName(n) -char *n; -#endif -{ - static char *dir_sym = DirectorySymbol; - static char newname[MaxFileName+1]; - char *p; - - /* If OutputDirectory is same as TopDirectory (platform default) then leave n alone. */ - if (strcmp(OutputDirectory, TopDirectory) == 0) /* TopDirectory is "." on Unix. */ - return n; - - /* p will point to filename without path information */ - if ((p = strrchr(n, *dir_sym)) != NULL) /* Directory symbol is "/" on Unix. */ - p++; - else - p = n; - - /* Copy new output directory into newname[] */ - strcpy(newname, OutputDirectory); - - /* if new output directory does not have trailing dir_sym, add it! */ - if (newname[strlen(newname)-1] != *dir_sym) { - strcat(newname, dir_sym); - } - strcat(newname, p); - return newname; -} - -char * -#ifdef __USE_PROTOS -pcctsBaseName(char *n) /* MR32 */ -#else -pcctsBaseName(n) -char *n; -#endif -{ - static char newname[MaxFileName+1]; - static char* dir_sym = DirectorySymbol; - int count = 0; - char *p; - - p = n; - - while ( *p != '\0' ) {p++;} /* go to end of string */ - while ( (*p != *dir_sym) && (p != n) ) {--p;} /* Find last DirectorySymbol */ - while ( *p == *dir_sym) p++; /* step forward if we're on a dir symbol */ - while ( *p != '\0' && *p != '.') - { - newname[count++] = *p; - p++; - } /* create a new name */ - newname[count] = '\0'; - return newname; -} - -static void -#ifdef __USE_PROTOS -ensure_no_C_file_collisions(char *class_c_file) -#else -ensure_no_C_file_collisions(class_c_file) -char *class_c_file; -#endif -{ - int i; - - for (i=0; i= NumFiles && CurFile >= 1 ) CurFile--; - fprintf(stderr, ErrHdr, FileStr[CurFile], zzline); - fprintf(stderr, " warning: %s\n", err); -} - -void -#ifdef __USE_PROTOS -warnNoCR( char *err ) -#else -warnNoCR( err ) -char *err; -#endif -{ - /* back up the file number if we hit an error at the end of the last file */ - if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--; - fprintf(stderr, ErrHdr, FileStr[CurFile], zzline); - fprintf(stderr, " warning: %s", err); -} - -void -#ifdef __USE_PROTOS -errNoFL(char *err) -#else -errNoFL(err) -char *err; -#endif -{ - fprintf(stderr, "error: %s\n", err); -} - -void -#ifdef __USE_PROTOS -errFL(char *err,char *f,int l) -#else -errFL(err,f,l) -char *err; -char *f; -int l; -#endif -{ - fprintf(stderr, ErrHdr, f, l); - fprintf(stderr, " error: %s\n", err); -} - -void -#ifdef __USE_PROTOS -err(char *err) -#else -err(err) -char *err; -#endif -{ - /* back up the file number if we hit an error at the end of the last file */ - if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--; - fprintf(stderr, ErrHdr, FileStr[CurFile], zzline); - fprintf(stderr, " error: %s\n", err); -} - -void -#ifdef __USE_PROTOS -errNoCR( char *err ) -#else -errNoCR( err ) -char *err; -#endif -{ - /* back up the file number if we hit an error at the end of the last file */ - if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--; - fprintf(stderr, ErrHdr, FileStr[CurFile], zzline); - fprintf(stderr, " error: %s", err); -} - -UserAction * -#ifdef __USE_PROTOS -newUserAction(char *s) -#else -newUserAction(s) -char *s; -#endif -{ - UserAction *ua = (UserAction *) calloc(1, sizeof(UserAction)); - require(ua!=NULL, "cannot allocate UserAction"); - - ua->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char)); - strcpy(ua->action, s); - return ua; -} - -/* Added by TJP September 1994 */ -/* Take in file.h and return file_h; names w/o '.'s are left alone */ -char * -#ifdef __USE_PROTOS -gate_symbol(char *name) -#else -gate_symbol(name) -char *name; -#endif -{ - static char buf[100]; - char *p; - sprintf(buf, "%s", name); - - for (p=buf; *p!='\0'; p++) - { - if ( *p=='.' ) *p = '_'; - } - return buf; -} - -char * -#ifdef __USE_PROTOS -makeAltID(int blockid, int altnum) -#else -makeAltID(blockid, altnum) -int blockid; -int altnum; -#endif -{ - static char buf[100]; - char *p; - sprintf(buf, "_blk%d_alt%d", blockid, altnum); - p = (char *)malloc(strlen(buf)+1); - strcpy(p, buf); - return p; -} diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/makefile b/Tools/CodeTools/TianoTools/Pccts/antlr/makefile deleted file mode 100644 index 2aa6cdfc34..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/makefile +++ /dev/null @@ -1,218 +0,0 @@ -# -# Makefile for ANTLR 1.33 -# -# SOFTWARE RIGHTS -# -# We reserve no LEGAL rights to the Purdue Compiler Construction Tool -# Set (PCCTS) -- PCCTS is in the public domain. An individual or -# company may do whatever they wish with source code distributed with -# PCCTS or the code generated by PCCTS, including the incorporation of -# PCCTS, or its output, into commerical software. -# -# We encourage users to develop software with PCCTS. However, we do ask -# that credit is given to us for developing PCCTS. By "credit", -# we mean that if you incorporate our source code into one of your -# programs (commercial product, research project, or otherwise) that you -# acknowledge this fact somewhere in the documentation, research report, -# etc... If you like PCCTS and have developed a nice tool with the -# output, please mention that you developed it using PCCTS. In -# addition, we ask that this header remain intact in our source code. -# As long as these guidelines are kept, we expect to continue enhancing -# this system and expect to make other tools available as they are -# completed. -# -# ANTLR 1.33 -# Terence Parr -# Parr Research Corporation -# with Purdue University -# and AHPCRC, University of Minnesota -# 1989-1995 -# -# Ported to Borland C++, IBM C-Set/2 and Microsoft 6.0 by -# Ed Harfmann -# Micro Data Base Systems -# Lafayette, Indiana -# -SET=../support/set -PCCTS_H=../h - -## -## Uncomment the appropriate section to build -## (both targets and 'make' variable definitions) -## Note that UNIX is the default -## - -# -# OS/2 & DOS 16 bit using MSC 6.0 -# -#CC=cl -#ANTLR=..\bin\antlr -#DLG=..\bin\dlg -#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) /AL /Za /W3 -DPC -DUSER_ZZSYN -#OUT_OBJ = -Fo -#LIBS=/NOD:LLIBCE LLIBCEP -#OBJ_EXT = obj -# -#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \ -# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \ -# misc.obj set.obj pred.obj egamn.obj -# link @<< -#$** /NOI -#$@ /STACK:14336 -# -#$(LIBS: = +^ -#) -#$(DEF_FILE) $(LFLAGS) ; -#<< -# bind $@ c:\os2\doscalls.lib -# copy *.exe ..\bin -# - -# -# Borland C++ for DOS -# -#CC=bcc -#ANTLR=..\bin\antlr -#DLG=..\bin\dlg -#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) -ml -ff- -w- -DPC -DUSER_ZZSYN -#OUT_OBJ = -o -#LIBS= emu mathl cl -#OBJ_EXT = obj -# -#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \ -# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \ -# misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj -# tlink @&&| -#C0L $** -#$@ /Tde /c -# -#$(LIBS) -#$(DEF_FILE) $(LFLAGS) ; -#| -# copy *.exe ..\bin -# - -# -# C-Set/2 for OS/2 -# -#CC=icc -#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) /Sa /W3 -DUSER_ZZSYN -D__STDC__ -#OUT_OBJ = -Fo -#LIBS= -#ANTLR=..\bin\antlr -#DLG=..\bin\dlg -#OBJ_EXT = obj -# -#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \ -# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \ -# misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj -# link386 @<< -#$** /NOI -#$@ /STACK:32768 -# -#$(LIBS: = +^ -#) -#$(DEF_FILE) $(LFLAGS) ; -#<< -# copy *.exe ..\bin -# - -# -# Borland C++ for OS/2 -# -#CC=bcc -#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) -w- -v -DUSER_ZZSYN -#OUT_OBJ = -o -#LIBS= c2 os2 -# -#ANTLR=..\bin\antlr -#DLG=..\bin\dlg -#OBJ_EXT = obj -#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \ -# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \ -# misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj -# tlink @&&| -#c02 $** -c -v -#antlr.exe -# -#C2 os2 -# -#| -# copy *.exe ..\bin -# - -# *********** Target list of PC machines *********** -# -# Don't worry about the ambiguity messages coming from antlr -# for making antlr.c etc... [should be 10 of them, I think] -# -#antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g -# $(ANTLR) antlr.g -# -#antlr.$(OBJ_EXT): antlr.c mode.h tokens.h -# -#scan.$(OBJ_EXT): scan.c mode.h tokens.h -# -#scan.c mode.h: parser.dlg -# $(DLG) -C2 parser.dlg scan.c -# -#set.$(OBJ_EXT): $(SET)/set.c -# $(CC) $(CFLAGS) -c $(OUT_OBJ)set.$(OBJ_EXT) $(SET)/set.c - - - -# -# UNIX (default) -# -CC=gcc -COPT=-O -ANTLR=${BIN_DIR}/antlr -DLG=${BIN_DIR}/dlg -OBJ_EXT=o -OUT_OBJ = -o -CFLAGS= $(COPT) -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN $(COTHER) -DZZLEXBUFSIZE=65536 -# -# SGI Users, use this CFLAGS -# -#CFLAGS= -O -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN -woff 3262 -OBJ=antlr.o scan.o err.o bits.o build.o fset2.o fset.o gen.o \ - globals.o hash.o lex.o main.o misc.o set.o pred.o egman.o mrhoist.o fcache.o - -antlr : $(OBJ) $(SRC) - $(CC) $(CFLAGS) -o $(BIN_DIR)/antlr $(OBJ) - -# what files does PCCTS generate (both ANTLR and DLG) -PCCTS_GEN=antlr.c scan.c err.c tokens.h mode.h parser.dlg stdpccts.h remap.h - -SRC=antlr.c scan.c err.c bits.c build.c fset2.c fset.c gen.c globals.c \ - hash.c lex.c main.c misc.c $(SET)/set.c pred.c egman.c mrhoist.c fcache.c - -# -# Don't worry about the ambiguity messages coming from antlr -# for making antlr.c etc... [should be 10 of them, I think] -# -#antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g -# $(ANTLR) -gh antlr.g - -antlr.o : antlr.c mode.h tokens.h - -scan.o : scan.c mode.h tokens.h - -#scan.c mode.h: parser.dlg -# $(DLG) -C2 parser.dlg scan.c - -set.o : $(SET)/set.c - $(CC) $(CFLAGS) -c -o set.o $(SET)/set.c - - -# -# ****** These next targets are common to UNIX and PC world ******** -# - -#clean up all the intermediate files -clean: - rm -f *.$(OBJ_EXT) core - -#remove everything in clean plus the PCCTS files generated -scrub: - rm -f $(PCCTS_GEN) *.$(OBJ_EXT) core diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/makefile.cygwin b/Tools/CodeTools/TianoTools/Pccts/antlr/makefile.cygwin deleted file mode 100644 index 956de0be07..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/makefile.cygwin +++ /dev/null @@ -1,219 +0,0 @@ -# -# Makefile for ANTLR 1.33 -# -# SOFTWARE RIGHTS -# -# We reserve no LEGAL rights to the Purdue Compiler Construction Tool -# Set (PCCTS) -- PCCTS is in the public domain. An individual or -# company may do whatever they wish with source code distributed with -# PCCTS or the code generated by PCCTS, including the incorporation of -# PCCTS, or its output, into commerical software. -# -# We encourage users to develop software with PCCTS. However, we do ask -# that credit is given to us for developing PCCTS. By "credit", -# we mean that if you incorporate our source code into one of your -# programs (commercial product, research project, or otherwise) that you -# acknowledge this fact somewhere in the documentation, research report, -# etc... If you like PCCTS and have developed a nice tool with the -# output, please mention that you developed it using PCCTS. In -# addition, we ask that this header remain intact in our source code. -# As long as these guidelines are kept, we expect to continue enhancing -# this system and expect to make other tools available as they are -# completed. -# -# ANTLR 1.33 -# Terence Parr -# Parr Research Corporation -# with Purdue University -# and AHPCRC, University of Minnesota -# 1989-1995 -# -# Ported to Borland C++, IBM C-Set/2 and Microsoft 6.0 by -# Ed Harfmann -# Micro Data Base Systems -# Lafayette, Indiana -# -SET=../support/set -PCCTS_H=../h - -## -## Uncomment the appropriate section to build -## (both targets and 'make' variable definitions) -## Note that UNIX is the default -## - -# -# OS/2 & DOS 16 bit using MSC 6.0 -# -#CC=cl -#ANTLR=..\bin\antlr -#DLG=..\bin\dlg -#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) /AL /Za /W3 -DPC -DUSER_ZZSYN -#OUT_OBJ = -Fo -#LIBS=/NOD:LLIBCE LLIBCEP -#OBJ_EXT = obj -# -#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \ -# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \ -# misc.obj set.obj pred.obj egamn.obj -# link @<< -#$** /NOI -#$@ /STACK:14336 -# -#$(LIBS: = +^ -#) -#$(DEF_FILE) $(LFLAGS) ; -#<< -# bind $@ c:\os2\doscalls.lib -# copy *.exe ..\bin -# - -# -# Borland C++ for DOS -# -#CC=bcc -#ANTLR=..\bin\antlr -#DLG=..\bin\dlg -#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) -ml -ff- -w- -DPC -DUSER_ZZSYN -#OUT_OBJ = -o -#LIBS= emu mathl cl -#OBJ_EXT = obj -# -#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \ -# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \ -# misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj -# tlink @&&| -#C0L $** -#$@ /Tde /c -# -#$(LIBS) -#$(DEF_FILE) $(LFLAGS) ; -#| -# copy *.exe ..\bin -# - -# -# C-Set/2 for OS/2 -# -#CC=icc -#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) /Sa /W3 -DUSER_ZZSYN -D__STDC__ -#OUT_OBJ = -Fo -#LIBS= -#ANTLR=..\bin\antlr -#DLG=..\bin\dlg -#OBJ_EXT = obj -# -#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \ -# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \ -# misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj -# link386 @<< -#$** /NOI -#$@ /STACK:32768 -# -#$(LIBS: = +^ -#) -#$(DEF_FILE) $(LFLAGS) ; -#<< -# copy *.exe ..\bin -# - -# -# Borland C++ for OS/2 -# -#CC=bcc -#CFLAGS= -I. -I$(SET) -I$(PCCTS_H) -w- -v -DUSER_ZZSYN -#OUT_OBJ = -o -#LIBS= c2 os2 -# -#ANTLR=..\bin\antlr -#DLG=..\bin\dlg -#OBJ_EXT = obj -#antlr.exe: antlr.obj scan.obj err.obj bits.obj build.obj fset2.obj \ -# fset.obj gen.obj globals.obj hash.obj lex.obj main.obj \ -# misc.obj set.obj pred.obj egman.obj mrhoist.obj fcache.obj -# tlink @&&| -#c02 $** -c -v -#antlr.exe -# -#C2 os2 -# -#| -# copy *.exe ..\bin -# - -# *********** Target list of PC machines *********** -# -# Don't worry about the ambiguity messages coming from antlr -# for making antlr.c etc... [should be 10 of them, I think] -# -#antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g -# $(ANTLR) antlr.g -# -#antlr.$(OBJ_EXT): antlr.c mode.h tokens.h -# -#scan.$(OBJ_EXT): scan.c mode.h tokens.h -# -#scan.c mode.h: parser.dlg -# $(DLG) -C2 parser.dlg scan.c -# -#set.$(OBJ_EXT): $(SET)/set.c -# $(CC) $(CFLAGS) -c $(OUT_OBJ)set.$(OBJ_EXT) $(SET)/set.c - - - -# -# UNIX (default) -# -BIN_DIR=../../../../bin -CC=gcc -COPT=-O -ANTLR=$(BIN_DIR)/antlr.exe -DLG=${BIN_DIR}/dlg.exe -OBJ_EXT=o -OUT_OBJ = -o -CFLAGS= $(COPT) -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN $(COTHER) -DZZLEXBUFSIZE=65536 -# -# SGI Users, use this CFLAGS -# -#CFLAGS= -O -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN -woff 3262 -OBJ=antlr.o scan.o err.o bits.o build.o fset2.o fset.o gen.o \ - globals.o hash.o lex.o main.o misc.o set.o pred.o egman.o mrhoist.o fcache.o - -antlr : $(OBJ) $(SRC) - $(CC) $(CFLAGS) -o $(BIN_DIR)/antlr.exe $(OBJ) - -# what files does PCCTS generate (both ANTLR and DLG) -PCCTS_GEN=antlr.c scan.c err.c tokens.h mode.h parser.dlg stdpccts.h remap.h - -SRC=antlr.c scan.c err.c bits.c build.c fset2.c fset.c gen.c globals.c \ - hash.c lex.c main.c misc.c $(SET)/set.c pred.c egman.c mrhoist.c fcache.c - -# -# Don't worry about the ambiguity messages coming from antlr -# for making antlr.c etc... [should be 10 of them, I think] -# -#antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g -# $(ANTLR) -gh antlr.g - -antlr.o : antlr.c mode.h tokens.h - -scan.o : scan.c mode.h tokens.h - -#scan.c mode.h: parser.dlg -# $(DLG) -C2 parser.dlg scan.c - -set.o : $(SET)/set.c - $(CC) $(CFLAGS) -c -o set.o $(SET)/set.c - - -# -# ****** These next targets are common to UNIX and PC world ******** -# - -#clean up all the intermediate files -clean: - rm -f *.$(OBJ_EXT) core - -#remove everything in clean plus the PCCTS files generated -scrub: - rm -f $(PCCTS_GEN) *.$(OBJ_EXT) core diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/makefile1 b/Tools/CodeTools/TianoTools/Pccts/antlr/makefile1 deleted file mode 100644 index dffc709478..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/makefile1 +++ /dev/null @@ -1,96 +0,0 @@ -# -# Makefile for ANTLR 1.33 -# -# SOFTWARE RIGHTS -# -# We reserve no LEGAL rights to the Purdue Compiler Construction Tool -# Set (PCCTS) -- PCCTS is in the public domain. An individual or -# company may do whatever they wish with source code distributed with -# PCCTS or the code generated by PCCTS, including the incorporation of -# PCCTS, or its output, into commerical software. -# -# We encourage users to develop software with PCCTS. However, we do ask -# that credit is given to us for developing PCCTS. By "credit", -# we mean that if you incorporate our source code into one of your -# programs (commercial product, research project, or otherwise) that you -# acknowledge this fact somewhere in the documentation, research report, -# etc... If you like PCCTS and have developed a nice tool with the -# output, please mention that you developed it using PCCTS. In -# addition, we ask that this header remain intact in our source code. -# As long as these guidelines are kept, we expect to continue enhancing -# this system and expect to make other tools available as they are -# completed. -# -# ANTLR 1.33 -# Terence Parr -# Parr Research Corporation -# with Purdue University -# and AHPCRC, University of Minnesota -# 1989-1995 -# -# Ported to Borland C++, IBM C-Set/2 and Microsoft 6.0 by -# Ed Harfmann -# Micro Data Base Systems -# Lafayette, Indiana -# -SET=../support/set -PCCTS_H=../h - -# -# UNIX (default) -# -CC=cc -ANTLR=${WORKSPACE}/Tools/bin/antlr -DLG=${WORKSPACE}/Tools/bin/dlg -OBJ_EXT=o -OUT_OBJ = -o -ANSI=-ansi -AOTHER= -CFLAGS= -O0 -g -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN $(COTHER) $(ANSI) -DZZLEXBUFSIZE=32000 -# -# SGI Users, use this CFLAGS -# -#CFLAGS= -O -I. -I$(SET) -I$(PCCTS_H) -DUSER_ZZSYN -woff 3262 - -OBJ=antlr.o scan.o err.o bits.o build.o fset2.o fset.o gen.o \ - globals.o hash.o lex.o main.o misc.o set.o pred.o egman.o mrhoist.o fcache.o $(OBJOTHER) - -antlr : $(OBJ) $(SRC) - $(CC) $(CFLAGS) -o antlr $(OBJ) - mv antlr ${WORKSPACE}/Tools/bin - -# what files does PCCTS generate (both ANTLR and DLG) -PCCTS_GEN=antlr.c scan.c err.c tokens.h mode.h parser.dlg stdpccts.h remap.h - -SRC=antlr.c scan.c err.c bits.c build.c fset2.c fset.c gen.c globals.c \ - hash.c lex.c main.c misc.c $(SET)/set.c pred.c egman.c mrhoist.c fcache.c - -# -# Don't worry about the ambiguity messages coming from antlr -# for making antlr.c etc... [should be 10 of them, I think] -# -antlr.c stdpccts.h parser.dlg tokens.h err.c : antlr.g - $(ANTLR) -gh antlr.g $(AOTHER) - -antlr.o : antlr.c mode.h tokens.h - -scan.o : scan.c mode.h tokens.h - -scan.c mode.h: parser.dlg - $(DLG) -C2 parser.dlg scan.c - -set.o : $(SET)/set.c - $(CC) $(CFLAGS) -c -o set.o $(SET)/set.c - - -# -# ****** These next targets are common to UNIX and PC world ******** -# - -#clean up all the intermediate files -clean: - rm -f *.$(OBJ_EXT) core - -#remove everything in clean plus the PCCTS files generated -scrub: - rm -f $(PCCTS_GEN) *.$(OBJ_EXT) core diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/misc.c b/Tools/CodeTools/TianoTools/Pccts/antlr/misc.c deleted file mode 100644 index 3f58da34c5..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/misc.c +++ /dev/null @@ -1,1864 +0,0 @@ -/* - * misc.c - * - * Manage tokens, regular expressions. - * Print methods for debugging - * Compute follow lists onto tail ends of rules. - * - * The following functions are visible: - * - * int addTname(char *); Add token name - * int addTexpr(char *); Add token expression - * int Tnum(char *); Get number of expr/token - * void Tklink(char *, char *); Link a name with an expression - * int hasAction(expr); Does expr already have action assigned? - * void setHasAction(expr); Indicate that expr now has an action - * Entry *newEntry(char *,int); Create new table entry with certain size - * void list_add(ListNode **list, char *e) - * void list_free(ListNode **list, int freeData); *** MR10 *** - * void list_apply(ListNode *list, void (*f)()) - * void lexclass(char *m); switch to new/old lexical class - * void lexmode(int i); switch to old lexical class i - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2001 - */ - -#include -#include "pcctscfg.h" -#include "set.h" -#include "syn.h" -#include "hash.h" -#include "generic.h" -#include "dlgdef.h" -#include - -static int tsize=TSChunk; /* size of token str arrays */ - -static void -#ifdef __USE_PROTOS -RemapForcedTokensInSyntaxDiagram(Node *); -#else -RemapForcedTokensInSyntaxDiagram(); -#endif - - /* T o k e n M a n i p u l a t i o n */ - -/* - * add token 't' to the TokenStr/Expr array. Make more room if necessary. - * 't' is either an expression or a token name. - * - * There is only one TokenStr array, but multiple ExprStr's. Therefore, - * for each lex class (element of lclass) we must extend the ExprStr array. - * ExprStr's and TokenStr are always all the same size. - * - * Also, there is a Texpr hash table for each automaton. - */ -static void -#ifdef __USE_PROTOS -Ttrack( char *t ) -#else -Ttrack( t ) -char *t; -#endif -{ - if ( TokenNum >= tsize ) /* terminal table overflow? */ - { - char **p; - int i, more, j; - - more = TSChunk * (1 + ((TokenNum-tsize) / TSChunk)); - tsize += more; - TokenStr = (char **) realloc((char *)TokenStr, tsize*sizeof(char *)); - require(TokenStr != NULL, "Ttrack: can't extend TokenStr"); - for (i=0; iexpr = e; - p->lclass = CurrentLexClass; - return p; -} - -/* switch to lexical class/mode m. This amounts to creating a new - * lex mode if one does not already exist and making ExprStr point - * to the correct char string array. We must also switch Texpr tables. - * - * BTW, we need multiple ExprStr arrays because more than one automaton - * may have the same label for a token, but with different expressions. - * We need to track an expr for each automaton. If we disallowed this - * feature, only one ExprStr would be required. - */ -void -#ifdef __USE_PROTOS -lexclass( char *m ) -#else -lexclass( m ) -char *m; -#endif -{ - int i; - TermEntry *p; - static char EOFSTR[] = "\"@\""; - - if ( hash_get(Tname, m) != NULL ) - { - warn(eMsg1("lexclass name conflicts with token/errclass label '%s'",m)); - } - /* does m already exist? */ - i = LexClassIndex(m); - if ( i != -1 ) {lexmode(i); return;} - /* must make new one */ - NumLexClasses++; - CurrentLexClass = NumLexClasses-1; - require(NumLexClasses<=MaxLexClasses, "number of allowable lexclasses exceeded\nIncrease MaxLexClasses in generic.h and recompile all C files"); - lclass[CurrentLexClass].classnum = m; - lclass[CurrentLexClass].exprs = (char **) calloc(tsize, sizeof(char *)); - require(lclass[CurrentLexClass].exprs!=NULL, - "lexclass: cannot allocate ExprStr"); - lclass[CurrentLexClass].htable = newHashTable(); - ExprStr = lclass[CurrentLexClass].exprs; - Texpr = lclass[CurrentLexClass].htable; - /* define EOF for each automaton */ - p = newTermEntry( EOFSTR ); - p->token = EofToken; /* couldn't have remapped tokens yet, use EofToken */ - hash_add(Texpr, EOFSTR, (Entry *)p); - list_add(&ExprOrder, (void *)newExpr(EOFSTR)); - /* note: we use the actual ExprStr array - * here as TokenInd doesn't exist yet - */ - ExprStr[EofToken] = EOFSTR; -} - -void -#ifdef __USE_PROTOS -lexmode( int i ) -#else -lexmode( i ) -int i; -#endif -{ - require(iaction!=NULL); -} - -void -#ifdef __USE_PROTOS -setHasAction( char *expr, char *action ) -#else -setHasAction( expr, action ) -char *expr; -char *action; -#endif -{ - TermEntry *p; - require(expr!=NULL, "setHasAction: invalid expr"); - - p = (TermEntry *) hash_get(Texpr, expr); - require(p!=NULL, eMsg1("setHasAction: expr '%s' doesn't exist",expr)); - p->action = action; -} - -ForcedToken * -#ifdef __USE_PROTOS -newForcedToken(char *token, int tnum) -#else -newForcedToken(token, tnum) -char *token; -int tnum; -#endif -{ - ForcedToken *ft = (ForcedToken *) calloc(1, sizeof(ForcedToken)); - require(ft!=NULL, "out of memory"); - ft->token = token; - ft->tnum = tnum; - return ft; -} - -/* - * Make a token indirection array that remaps token numbers and then walk - * the appropriate symbol tables and SynDiag to change token numbers - */ -void -#ifdef __USE_PROTOS -RemapForcedTokens(void) -#else -RemapForcedTokens() -#endif -{ - ListNode *p; - ForcedToken *q; - int max_token_number=0; /* MR9 23-Sep-97 Removed "unsigned" */ - int i; - - if ( ForcedTokens == NULL ) return; - - /* find max token num */ - for (p = ForcedTokens->next; p!=NULL; p=p->next) - { - q = (ForcedToken *) p->elem; - if ( q->tnum > max_token_number ) max_token_number = q->tnum; - } - fprintf(stderr, "max token number is %d\n", max_token_number); - - /* make token indirection array */ - TokenInd = (int *) calloc(max_token_number+1, sizeof(int)); - LastTokenCounted = TokenNum; - TokenNum = max_token_number+1; - require(TokenInd!=NULL, "RemapForcedTokens: cannot allocate TokenInd"); - - /* fill token indirection array and change token id htable ; swap token indices */ - for (i=1; inext; p!=NULL; p=p->next) - { - TermEntry *te; - int old_pos, t; - - q = (ForcedToken *) p->elem; - fprintf(stderr, "%s forced to %d\n", q->token, q->tnum); - te = (TermEntry *) hash_get(Tname, q->token); - require(te!=NULL, "RemapForcedTokens: token not in hash table"); - old_pos = te->token; - fprintf(stderr, "Before: TokenInd[old_pos==%d] is %d\n", old_pos, TokenInd[old_pos]); - fprintf(stderr, "Before: TokenInd[target==%d] is %d\n", q->tnum, TokenInd[q->tnum]); - q = (ForcedToken *) p->elem; - t = TokenInd[old_pos]; - TokenInd[old_pos] = q->tnum; - TokenInd[q->tnum] = t; - te->token = q->tnum; /* update token type id symbol table */ - fprintf(stderr, "After: TokenInd[old_pos==%d] is %d\n", old_pos, TokenInd[old_pos]); - fprintf(stderr, "After: TokenInd[target==%d] is %d\n", q->tnum, TokenInd[q->tnum]); - - /* Change the token number in the sym tab entry for the exprs - * at the old position of the token id and the target position - */ - /* update expr at target (if any) of forced token id */ - if ( q->tnum < TokenNum ) /* is it a valid position? */ - { - for (i=0; itnum]!=NULL ) - { - /* update the symbol table for this expr */ - TermEntry *e = (TermEntry *) hash_get(lclass[i].htable, lclass[i].exprs[q->tnum]); - require(e!=NULL, "RemapForcedTokens: expr not in hash table"); - e->token = old_pos; - fprintf(stderr, "found expr '%s' at target %d in lclass[%d]; changed to %d\n", - lclass[i].exprs[q->tnum], q->tnum, i, old_pos); - } - } - } - /* update expr at old position (if any) of forced token id */ - for (i=0; itoken = q->tnum; - fprintf(stderr, "found expr '%s' for id %s in lclass[%d]; changed to %d\n", - lclass[i].exprs[old_pos], q->token, i, q->tnum); - } - } - } - - /* Update SynDiag */ - RemapForcedTokensInSyntaxDiagram((Node *)SynDiag); -} - -static void -#ifdef __USE_PROTOS -RemapForcedTokensInSyntaxDiagram(Node *p) -#else -RemapForcedTokensInSyntaxDiagram(p) -Node *p; -#endif -{ - Junction *j = (Junction *) p; - RuleRefNode *r = (RuleRefNode *) p; - TokNode *t = (TokNode *)p; - - if ( p==NULL ) return; - require(p->ntype>=1 && p->ntype<=NumNodeTypes, "Remap...: invalid diagram node"); - switch ( p->ntype ) - { - case nJunction : - if ( j->visited ) return; - if ( j->jtype == EndRule ) return; - j->visited = TRUE; - RemapForcedTokensInSyntaxDiagram( j->p1 ); - RemapForcedTokensInSyntaxDiagram( j->p2 ); - j->visited = FALSE; - return; - case nRuleRef : - RemapForcedTokensInSyntaxDiagram( r->next ); - return; - case nToken : - if ( t->remapped ) return; /* we've been here before */ - t->remapped = 1; - fprintf(stderr, "remapping %d to %d\n", t->token, TokenInd[t->token]); - t->token = TokenInd[t->token]; - RemapForcedTokensInSyntaxDiagram( t->next ); - return; - case nAction : - RemapForcedTokensInSyntaxDiagram( ((ActionNode *)p)->next ); - return; - default : - fatal_internal("invalid node type"); - } -} - -/* - * Add a token name. Return the token number associated with it. If it already - * exists, then return the token number assigned to it. - * - * Track the order in which tokens are found so that the DLG output maintains - * that order. It also lets us map token numbers to strings. - */ -int -#ifdef __USE_PROTOS -addTname( char *token ) -#else -addTname( token ) -char *token; -#endif -{ - TermEntry *p; - require(token!=NULL, "addTname: invalid token name"); - - if ( (p=(TermEntry *)hash_get(Tname, token)) != NULL ) return p->token; - p = newTermEntry( token ); - Ttrack( p->str ); - p->token = TokenNum++; - hash_add(Tname, token, (Entry *)p); - return p->token; -} - -/* This is the same as addTname except we force the TokenNum to be tnum. - * We don't have to use the Forced token stuff as no tokens will have - * been defined with #tokens when this is called. This is only called - * when a #tokdefs meta-op is used. - */ -int -#ifdef __USE_PROTOS -addForcedTname( char *token, int tnum ) -#else -addForcedTname( token, tnum ) -char *token; -int tnum; -#endif -{ - TermEntry *p; - require(token!=NULL, "addTname: invalid token name"); - - if ( (p=(TermEntry *)hash_get(Tname, token)) != NULL ) return p->token; - p = newTermEntry( token ); - Ttrack( p->str ); - p->token = tnum; - hash_add(Tname, token, (Entry *)p); - return p->token; -} - -/* - * Add a token expr. Return the token number associated with it. If it already - * exists, then return the token number assigned to it. - */ -int -#ifdef __USE_PROTOS -addTexpr( char *expr ) -#else -addTexpr( expr ) -char *expr; -#endif -{ - TermEntry *p; - require(expr!=NULL, "addTexpr: invalid regular expression"); - - if ( (p=(TermEntry *)hash_get(Texpr, expr)) != NULL ) return p->token; - p = newTermEntry( expr ); - Ttrack( p->str ); - /* track the order in which they occur */ - list_add(&ExprOrder, (void *)newExpr(p->str)); - p->token = TokenNum++; - hash_add(Texpr, expr, (Entry *)p); - return p->token; -} - -/* return the token number of 'term'. Return 0 if no 'term' exists */ -int -#ifdef __USE_PROTOS -Tnum( char *term ) -#else -Tnum( term ) -char *term; -#endif -{ - TermEntry *p; - require(term!=NULL, "Tnum: invalid terminal"); - - if ( *term=='"' ) p = (TermEntry *) hash_get(Texpr, term); - else p = (TermEntry *) hash_get(Tname, term); - if ( p == NULL ) return 0; - else return p->token; -} - -/* associate a Name with an expr. If both have been already assigned - * token numbers, then an error is reported. Add the token or expr - * that has not been added if no error. This 'represents' the #token - * ANTLR pseudo-op. If both have not been defined, define them both - * linked to same token number. - */ -void -#ifdef __USE_PROTOS -Tklink( char *token, char *expr ) -#else -Tklink( token, expr ) -char *token; -char *expr; -#endif -{ - TermEntry *p, *q; - require(token!=NULL && expr!=NULL, "Tklink: invalid token name and/or expr"); - - p = (TermEntry *) hash_get(Tname, token); - q = (TermEntry *) hash_get(Texpr, expr); - if ( p != NULL && q != NULL ) /* both defined */ - { - warn( eMsg2("token name %s and rexpr %s already defined; ignored", - token, expr) ); - return; - } - if ( p==NULL && q==NULL ) /* both not defined */ - { - int t = addTname( token ); - q = newTermEntry( expr ); - hash_add(Texpr, expr, (Entry *)q); - q->token = t; - /* note: we use the actual ExprStr array - * here as TokenInd doesn't exist yet - */ - ExprStr[t] = q->str; - /* track the order in which they occur */ - list_add(&ExprOrder, (void *)newExpr(q->str)); - return; - } - if ( p != NULL ) /* one is defined, one is not */ - { - q = newTermEntry( expr ); - hash_add(Texpr, expr, (Entry *)q); - q->token = p->token; - ExprStr[p->token] = q->str; /* both expr and token str defined now */ - list_add(&ExprOrder, (void *)newExpr(q->str)); - } - else /* trying to associate name with expr here*/ - { - p = newTermEntry( token ); - hash_add(Tname, token, (Entry *)p); - p->token = q->token; - TokenStr[p->token] = p->str;/* both expr and token str defined now */ - } -} - -/* - * Given a string, this function allocates and returns a pointer to a - * hash table record of size 'sz' whose "str" pointer is reset to a position - * in the string table. - */ -Entry * -#ifdef __USE_PROTOS -newEntry( char *text, int sz ) -#else -newEntry( text, sz ) -char *text; -int sz; -#endif -{ - Entry *p; - require(text!=NULL, "new: NULL terminal"); - - if ( (p = (Entry *) calloc(1,sz)) == 0 ) - { - fatal_internal("newEntry: out of memory for terminals\n"); - exit(PCCTS_EXIT_FAILURE); - } - p->str = mystrdup(text); - - return(p); -} - -/* - * add an element to a list. - * - * Any non-empty list has a sentinel node whose 'elem' pointer is really - * a pointer to the last element. (i.e. length(list) = #elemIn(list)+1). - * Elements are appended to the list. - */ -void -#ifdef __USE_PROTOS -list_add( ListNode **list, void *e ) -#else -list_add( list, e ) -ListNode **list; -void *e; -#endif -{ - ListNode *p, *tail; - require(e!=NULL, "list_add: attempting to add NULL list element"); - - p = newListNode; - require(p!=NULL, "list_add: cannot alloc new list node"); - p->elem = e; - if ( *list == NULL ) - { - ListNode *sentinel = newListNode; - require(sentinel!=NULL, "list_add: cannot alloc sentinel node"); - *list=sentinel; - sentinel->next = p; - sentinel->elem = (char *)p; /* set tail pointer */ - } - else /* find end of list */ - { - tail = (ListNode *) (*list)->elem; /* get tail pointer */ - tail->next = p; - (*list)->elem = (char *) p; /* reset tail */ - } -} - -/* MR10 list_free() frees the ListNode elements in the list */ -/* MR10 if freeData then free the data elements of the list too */ - -void -#ifdef __USE_PROTOS -list_free(ListNode **list,int freeData) -#else -list_free(list,freeData) - ListNode **list; - int freeData; -#endif -{ - ListNode *p; - ListNode *next; - - if (list == NULL) return; - if (*list == NULL) return; - for (p=*list; p != NULL; p=next) { - next=p->next; - if (freeData && p->elem != NULL) { - free( (char *) p->elem); - }; - free( (char *) p); - }; - *list=NULL; -} - -void -#ifdef __USE_PROTOS -list_apply( ListNode *list, void (*f)(void *) ) -#else -list_apply( list, f ) -ListNode *list; -void (*f)(); -#endif -{ - ListNode *p; - require(f!=NULL, "list_apply: NULL function to apply"); - - if ( list == NULL ) return; - for (p = list->next; p!=NULL; p=p->next) (*f)( p->elem ); -} - -/* MR27 */ - -#ifdef __USE_PROTOS -int list_search_cstring(ListNode *list, char * cstring) -#else -int list_search_cstring(list, cstring) - ListNode * list; - char * cstring; -#endif -{ - ListNode *p; - if (list == NULL ) return 0; - for (p = list->next; p!=NULL; p=p->next) { - if (p->elem == NULL) continue; - if (0 == strcmp((char *) p->elem , cstring)) return 1; - } - return 0; -} - - /* F O L L O W C y c l e S t u f f */ - -/* make a key based upon (rulename, computation, k value). - * Computation values are 'i'==FIRST, 'o'==FOLLOW. - */ - -/* MR10 Make the key all characters so it can be read easily */ -/* MR10 by a simple dump program. Also, separates */ -/* MR10 'o' and 'i' from rule name */ - -char * -#ifdef __USE_PROTOS -Fkey( char *rule, int computation, int k ) -#else -Fkey( rule, computation, k ) -char *rule; -int computation; -int k; -#endif -{ - static char key[MaxRuleName+2+2+1]; /* MR10 */ - int i; - - if ( k > 99 ) /* MR10 */ - fatal("k>99 is too big for this implementation of ANTLR!\n"); /* MR10 */ - if ( (i=strlen(rule)) > MaxRuleName ) /* MR10 */ - fatal( eMsgd("rule name > max of %d\n", MaxRuleName) ); /* MR10 */ - strcpy(key,rule); - -/* MR10 */ key[i]='*'; -/* MR10 */ key[i+1] = (char) computation; /* MR20 G. Hobbelt */ -/* MR10 */ if (k < 10) { -/* MR10 */ key[i+2] = (char) ( '0' + k); -/* MR10 */ key[i+3] = '\0'; -/* MR10 */ } else { -/* MR10 */ key[i+2] = (char) ( '0' + k/10); -/* MR10 */ key[i+3] = (char) ( '0' + k % 10); -/* MR10 */ key[i+4] = '\0'; -/* MR10 */ }; - - return key; -} - -/* Push a rule onto the kth FOLLOW stack */ -void -#ifdef __USE_PROTOS -FoPush( char *rule, int k ) -#else -FoPush( rule, k ) -char *rule; -int k; -#endif -{ - RuleEntry *r; - require(rule!=NULL, "FoPush: tried to push NULL rule"); - require(k<=CLL_k, "FoPush: tried to access non-existent stack"); - - /*fprintf(stderr, "FoPush(%s)\n", rule);*/ - r = (RuleEntry *) hash_get(Rname, rule); - if ( r == NULL ) {fatal_internal( eMsg1("rule %s must be defined but isn't", rule) );} - if ( FoStack[k] == NULL ) /* Does the kth stack exist yet? */ - { - /*fprintf(stderr, "allocating FoStack\n");*/ - FoStack[k] = (int *) calloc(FoStackSize, sizeof(int)); - require(FoStack[k]!=NULL, "FoPush: cannot allocate FOLLOW stack\n"); - } - if ( FoTOS[k] == NULL ) - { - FoTOS[k]=FoStack[k]; - *(FoTOS[k]) = r->rulenum; - } - else - { -#ifdef MEMCHK - require(valid(FoStack[k]), "FoPush: invalid FoStack"); -#endif - if ( FoTOS[k] >= &(FoStack[k][FoStackSize-1]) ) - fatal( eMsgd("exceeded max depth of FOLLOW recursion (%d)\n", - FoStackSize) ); - require(FoTOS[k]>=FoStack[k], - eMsg1("FoPush: FoStack stack-ptr is playing out of its sandbox", - rule)); - ++(FoTOS[k]); - *(FoTOS[k]) = r->rulenum; - } - { - /* -**** int *p; -**** fprintf(stderr, "FoStack[k=%d]:\n", k); -**** for (p=FoStack[k]; p<=FoTOS[k]; p++) -**** { -**** fprintf(stderr, "\t%s\n", RulePtr[*p]->rname); -**** } - */ - } -} - -/* Pop one rule off of the FOLLOW stack. TOS ptr is NULL if empty. */ -void -#ifdef __USE_PROTOS -FoPop( int k ) -#else -FoPop( k ) -int k; -#endif -{ - require(k<=CLL_k, "FoPop: tried to access non-existent stack"); - /*fprintf(stderr, "FoPop\n");*/ - require(FoTOS[k]>=FoStack[k]&&FoTOS[k]<=&(FoStack[k][FoStackSize-1]), - "FoPop: FoStack stack-ptr is playing out of its sandbox"); - if ( FoTOS[k] == FoStack[k] ) FoTOS[k] = NULL; - else (FoTOS[k])--; -} - -/* Compute FOLLOW cycle. - * Mark all FOLLOW sets for rules in cycle as incomplete. - * Then, save cycle on the cycle list (Cycles) for later resolution. - * The Cycle is stored in the form: - * (head of cycle==croot, rest of rules in cycle==cyclicDep) - * - * e.g. (Fo means "FOLLOW of", "-->" means requires or depends on) - * - * Fo(x)-->Fo(a)-->Fo(b)-->Fo(c)-->Fo(x) - * ^----Infinite recursion (cycle) - * - * the cycle would be: x -> {a,b,c} or stored as (x,{a,b,c}). Fo(x) depends - * on the FOLLOW of a,b, and c. The root of a cycle is always complete after - * Fo(x) finishes. Fo(a,b,c) however are not. It turns out that all rules - * in a FOLLOW cycle have the same FOLLOW set. - */ -void -#ifdef __USE_PROTOS -RegisterCycle( char *rule, int k ) -#else -RegisterCycle( rule, k ) -char *rule; -int k; -#endif -{ - CacheEntry *f; - Cycle *c; - int *p; - RuleEntry *r; - require(rule!=NULL, "RegisterCycle: tried to register NULL rule"); - require(k<=CLL_k, "RegisterCycle: tried to access non-existent stack"); - - /*fprintf(stderr, "RegisterCycle(%s)\n", rule);*/ - /* Find cycle start */ - r = (RuleEntry *) hash_get(Rname, rule); - require(r!=NULL,eMsg1("rule %s must be defined but isn't", rule)); - require(FoTOS[k]>=FoStack[k]&&FoTOS[k]<=&(FoStack[k][FoStackSize-1]), - eMsg1("RegisterCycle(%s): FoStack stack-ptr is playing out of its sandbox", - rule)); -/*** if ( FoTOS[k]&(FoStack[k][FoStackSize-1]) ) -**** { -**** fprintf(stderr, "RegisterCycle(%s): FoStack stack-ptr is playing out of its sandbox\n", -**** rule); -**** fprintf(stderr, "RegisterCycle: sp==0x%x out of bounds 0x%x...0x%x\n", -**** FoTOS[k], FoStack[k], &(FoStack[k][FoStackSize-1])); -**** exit(PCCTS_EXIT_FAILURE); -**** } -****/ - -#ifdef MEMCHK - require(valid(FoStack[k]), "RegisterCycle: invalid FoStack"); -#endif - for (p=FoTOS[k]; *p != r->rulenum && p >= FoStack[k]; --p) {;} - require(p>=FoStack[k], "RegisterCycle: FoStack is screwed up beyond belief"); - if ( p == FoTOS[k] ) return; /* don't worry about cycles to oneself */ - - /* compute cyclic dependents (rules in cycle except head) */ - c = newCycle; - require(c!=NULL, "RegisterCycle: couldn't alloc new cycle"); - c->cyclicDep = empty; - c->croot = *p++; /* record root of cycle */ - for (; p<=FoTOS[k]; p++) - { - /* Mark all dependent rules as incomplete */ - f = (CacheEntry *) hash_get(Fcache, Fkey(RulePtr[*p]->rname,'o',k)); - if ( f==NULL ) - { - f = newCacheEntry( Fkey(RulePtr[*p]->rname,'o',k) ); - hash_add(Fcache, Fkey(RulePtr[*p]->rname,'o',k), (Entry *)f); - } - f->incomplete = TRUE; - - set_orel(*p, &(c->cyclicDep)); /* mark rule as dependent of croot */ - } - list_add(&(Cycles[k]), (void *)c); -} - -/* make all rules in cycle complete - * - * while ( some set has changed ) do - * for each cycle do - * if degree of FOLLOW set for croot > old degree then - * update all FOLLOW sets for rules in cyclic dependency - * change = TRUE - * endif - * endfor - * endwhile - */ -void -#ifdef __USE_PROTOS -ResolveFoCycles( int k ) -#else -ResolveFoCycles( k ) -int k; -#endif -{ - ListNode *p, *q; - Cycle *c; - int changed = 1; - CacheEntry *f,*g; - int r; -/* int i; */ /* MR10 not useful */ - unsigned d; - - unsigned *cursor; /* MR10 */ - unsigned *origin; /* MR10 */ - - /*fprintf(stderr, "Resolving following cycles for %d\n", k);*/ - while ( changed ) - { - changed = 0; -/* MR10 i = 0; */ - for (p = Cycles[k]->next; p!=NULL; p=p->next) - { - c = (Cycle *) p->elem; - /*fprintf(stderr, "cycle %d: %s -->", i++, RulePtr[c->croot]->rname);*/ - /*s_fprT(stderr, c->cyclicDep);*/ - /*fprintf(stderr, "\n");*/ - f = (CacheEntry *) - hash_get(Fcache, Fkey(RulePtr[c->croot]->rname,'o',k)); - require(f!=NULL, eMsg1("FOLLOW(%s) must be in cache but isn't", RulePtr[c->croot]->rname) ); - if ( (d=set_deg(f->fset)) > c->deg ) - { - /*fprintf(stderr, "Fo(%s) has changed\n", RulePtr[c->croot]->rname);*/ - changed = 1; - c->deg = d; /* update cycle FOLLOW set degree */ - -/* MR10 */ origin=set_pdq(c->cyclicDep); -/* MR10 */ for (cursor=origin; *cursor != nil; cursor++) { -/* MR10 */ r=*cursor; - -/******** while ( !set_nil(c->cyclicDep) ) { *****/ -/******** r = set_int(c->cyclicDep); *****/ -/******** set_rm(r, c->cyclicDep); *****/ - - /*fprintf(stderr, "updating Fo(%s)\n", RulePtr[r]->rname);*/ - g = (CacheEntry *) - hash_get(Fcache, Fkey(RulePtr[r]->rname,'o',k)); - require(g!=NULL, eMsg1("FOLLOW(%s) must be in cache but isn't", RulePtr[r]->rname) ); - set_orin(&(g->fset), f->fset); - g->incomplete = FALSE; - } -/* MR10 */ free( (char *) origin); -/* MR10 */ origin=NULL; - } - } -/* MR10 - this if statement appears to be meaningless since i is always 0 */ -/* MR10 if ( i == 1 ) changed = 0; */ /* if only 1 cycle, no need to repeat */ - } - /* kill Cycle list */ - for (q = Cycles[k]->next; q != NULL; q=p) - { - p = q->next; - set_free( ((Cycle *)q->elem)->cyclicDep ); - free((char *)q); - } - free( (char *)Cycles[k] ); - Cycles[k] = NULL; -} - - - /* P r i n t i n g S y n t a x D i a g r a m s */ - -static void -#ifdef __USE_PROTOS -pBlk( Junction *q, int btype ) -#else -pBlk( q, btype ) -Junction *q; -int btype; -#endif -{ - int k,a; - Junction *alt, *p; - - q->end->pvisited = TRUE; - if ( btype == aLoopBegin ) - { - require(q->p2!=NULL, "pBlk: invalid ()* block"); - PRINT(q->p1); - alt = (Junction *)q->p2; - PRINT(alt->p1); - if ( PrintAnnotate ) - { - printf(" /* Opt "); - k = 1; - while ( !set_nil(alt->fset[k]) ) - { - s_fprT(stdout, alt->fset[k]); - if ( k++ == CLL_k ) break; - if ( !set_nil(alt->fset[k]) ) printf(", "); - } - printf(" */\n"); - } - return; - } - for (a=1,alt=q; alt != NULL; alt= (Junction *) alt->p2, a++) - { - if ( alt->p1 != NULL ) PRINT(alt->p1); - if ( PrintAnnotate ) - { - printf( " /* [%d] ", alt->altnum); - k = 1; - while ( !set_nil(alt->fset[k]) ) - { - s_fprT(stdout, alt->fset[k]); - if ( k++ == CLL_k ) break; - if ( !set_nil(alt->fset[k]) ) printf(", "); - } - if ( alt->p2 == NULL && btype == aOptBlk ) - printf( " (optional branch) */\n"); - else printf( " */\n"); - } - - /* ignore implied empty alt of Plus blocks */ - if ( alt->p2 != NULL && ((Junction *)alt->p2)->ignore ) break; - - if ( alt->p2 != NULL && !(((Junction *)alt->p2)->p2==NULL && btype == aOptBlk) ) - { - if ( pLevel == 1 ) - { - printf("\n"); - if ( a+1==pAlt1 || a+1==pAlt2 ) printf("=>"); - printf("\t"); - } - else printf(" "); - printf("|"); - if ( pLevel == 1 ) - { - p = (Junction *) ((Junction *)alt->p2)->p1; - while ( p!=NULL ) - { - if ( p->ntype==nAction ) - { - p=(Junction *)((ActionNode *)p)->next; - continue; - } - if ( p->ntype!=nJunction ) - { - break; - } - if ( p->jtype==EndBlk || p->jtype==EndRule ) - { - p = NULL; - break; - } - p = (Junction *)p->p1; - } - if ( p==NULL ) printf("\n\t"); /* Empty alt? */ - } - } - } - q->end->pvisited = FALSE; -} - -/* How to print out a junction */ -void -#ifdef __USE_PROTOS -pJunc( Junction *q ) -#else -pJunc( q ) -Junction *q; -#endif -{ - int dum_k; - int doing_rule; - require(q!=NULL, "pJunc: NULL node"); - require(q->ntype==nJunction, "pJunc: not junction"); - - if ( q->pvisited == TRUE ) return; - q->pvisited = TRUE; - switch ( q->jtype ) - { - case aSubBlk : - if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k); - if ( q->end->p1 != NULL && ((Junction *)q->end->p1)->ntype==nJunction && - ((Junction *)q->end->p1)->jtype == EndRule ) doing_rule = 1; - else doing_rule = 0; - pLevel++; - if ( pLevel==1 ) - { - if ( pAlt1==1 ) printf("=>"); - printf("\t"); - } - else printf(" "); - if ( doing_rule ) - { - if ( pLevel==1 ) printf(" "); - pBlk(q,q->jtype); - } - else { - printf("("); - if ( pLevel==1 ) printf(" "); - pBlk(q,q->jtype); - if ( pLevel>1 ) printf(" "); - printf(")"); - } - if ( q->guess ) printf("?"); - pLevel--; - if ( PrintAnnotate ) freeBlkFsets(q); - if ( q->end->p1 != NULL ) PRINT(q->end->p1); - break; - case aOptBlk : - if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k); - pLevel++; - if ( pLevel==1 ) - { - if ( pAlt1==1 ) printf("=>"); - printf("\t"); - } - else printf(" "); - printf("{"); - if ( pLevel==1 ) printf(" "); - pBlk(q,q->jtype); - if ( pLevel>1 ) printf(" "); - else printf("\n\t"); - printf("}"); - pLevel--; - if ( PrintAnnotate ) freeBlkFsets(q); - if ( q->end->p1 != NULL ) PRINT(q->end->p1); - break; - case aLoopBegin : - if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k); - pLevel++; - if ( pLevel==1 ) - { - if ( pAlt1==1 ) printf("=>"); - printf("\t"); - } - else printf(" "); - printf("("); - if ( pLevel==1 ) printf(" "); - pBlk(q,q->jtype); - if ( pLevel>1 ) printf(" "); - else printf("\n\t"); - printf(")*"); - pLevel--; - if ( PrintAnnotate ) freeBlkFsets(q); - if ( q->end->p1 != NULL ) PRINT(q->end->p1); - break; - case aLoopBlk : - if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k); - pBlk(q,q->jtype); - if ( PrintAnnotate ) freeBlkFsets(q); - break; - case aPlusBlk : - if ( PrintAnnotate ) First(q, 1, q->jtype, &dum_k); - pLevel++; - if ( pLevel==1 ) - { - if ( pAlt1==1 ) printf("=>"); - printf("\t"); - } - else printf(" "); - printf("("); - if ( pLevel==1 ) printf(" "); - pBlk(q,q->jtype); - if ( pLevel>1 ) printf(" "); - printf(")+"); - pLevel--; - if ( PrintAnnotate ) freeBlkFsets(q); - if ( q->end->p1 != NULL ) PRINT(q->end->p1); - break; - case EndBlk : - break; - case RuleBlk : - printf( "\n%s :\n", q->rname); - PRINT(q->p1); - if ( q->p2 != NULL ) PRINT(q->p2); - break; - case Generic : - if ( q->p1 != NULL ) PRINT(q->p1); - q->pvisited = FALSE; - if ( q->p2 != NULL ) PRINT(q->p2); - break; - case EndRule : - printf( "\n\t;\n"); - break; - } - q->pvisited = FALSE; -} - -/* How to print out a rule reference node */ -void -#ifdef __USE_PROTOS -pRuleRef( RuleRefNode *p ) -#else -pRuleRef( p ) -RuleRefNode *p; -#endif -{ - require(p!=NULL, "pRuleRef: NULL node"); - require(p->ntype==nRuleRef, "pRuleRef: not rule ref node"); - - printf( " %s", p->text); - PRINT(p->next); -} - -/* How to print out a terminal node */ -void -#ifdef __USE_PROTOS -pToken( TokNode *p ) -#else -pToken( p ) -TokNode *p; -#endif -{ - require(p!=NULL, "pToken: NULL node"); - require(p->ntype==nToken, "pToken: not token node"); - - if ( p->wild_card ) printf(" ."); - printf( " %s", TerminalString(p->token)); - PRINT(p->next); -} - -/* How to print out a terminal node */ -void -#ifdef __USE_PROTOS -pAction( ActionNode *p ) -#else -pAction( p ) -ActionNode *p; -#endif -{ - require(p!=NULL, "pAction: NULL node"); - require(p->ntype==nAction, "pAction: not action node"); - - PRINT(p->next); -} - - /* F i l l F o l l o w L i s t s */ - -/* - * Search all rules for all rule reference nodes, q to rule, r. - * Add q->next to follow list dangling off of rule r. - * i.e. - * - * r: -o-R-o-->o--> Ptr to node following rule r in another rule - * | - * o--> Ptr to node following another reference to r. - * - * This is the data structure employed to avoid FOLLOW set computation. We - * simply compute the FIRST (reach) of the EndRule Node which follows the - * list found at the end of all rules which are referenced elsewhere. Rules - * not invoked by other rules have no follow list (r->end->p1==NULL). - * Generally, only start symbols are not invoked by another rule. - * - * Note that this mechanism also gives a free cross-reference mechanism. - * - * The entire syntax diagram is layed out like this: - * - * SynDiag - * | - * v - * o-->R1--o - * | - * o-->R2--o - * | - * ... - * | - * o-->Rn--o - * - */ -void -#ifdef __USE_PROTOS -FoLink( Node *p ) -#else -FoLink( p ) -Node *p; -#endif -{ - RuleEntry *q; - Junction *j = (Junction *) p; - RuleRefNode *r = (RuleRefNode *) p; - - if ( p==NULL ) return; - require(p->ntype>=1 && p->ntype<=NumNodeTypes, - eMsgd("FoLink: invalid diagram node: ntype==%d",p->ntype)); - switch ( p->ntype ) - { - case nJunction : - if ( j->fvisited ) return; - if ( j->jtype == EndRule ) return; - j->fvisited = TRUE; - FoLink( j->p1 ); - FoLink( j->p2 ); -/* MR14 */ -/* MR14 */ /* Need to determine whether the guess block is an */ -/* MR14 */ /* of the form (alpha)? beta before follow sets are */ -/* MR14 */ /* computed. This is necessary to solve problem */ -/* MR14 */ /* of doing follow on the alpha of an (alpha)? beta block. */ -/* MR14 */ -/* MR14 */ /* This is performed by analysis_point as a side-effect. */ -/* MR14 */ -/* MR14 */ -/* MR14 */ if (j->jtype == aSubBlk && j->guess) { -/* MR14 */ Junction *ignore; -/* MR14 */ ignore=analysis_point(j); -/* MR14 */ } -/* MR14 */ - return; - case nRuleRef : - if ( r->linked ) return; - q = (RuleEntry *) hash_get(Rname, r->text); - if ( q == NULL ) - { - warnFL( eMsg1("rule %s not defined",r->text), FileStr[r->file], r->line ); - } - else - { - if ( r->parms!=NULL && RulePtr[q->rulenum]->pdecl==NULL ) - { - warnFL( eMsg1("rule %s accepts no parameter(s)", r->text), - FileStr[r->file], r->line ); - } - if ( r->parms==NULL && RulePtr[q->rulenum]->pdecl!=NULL ) - { - warnFL( eMsg1("rule %s requires parameter(s)", r->text), - FileStr[r->file], r->line ); - } - if ( r->assign!=NULL && RulePtr[q->rulenum]->ret==NULL ) - { - warnFL( eMsg1("rule %s yields no return value(s)", r->text), - FileStr[r->file], r->line ); - } - if ( r->assign==NULL && RulePtr[q->rulenum]->ret!=NULL ) - { - warnFL( eMsg1("rule %s returns a value(s)", r->text), - FileStr[r->file], r->line ); - } - if ( !r->linked ) - { - addFoLink( r->next, r->rname, RulePtr[q->rulenum] ); - r->linked = TRUE; - } - } - FoLink( r->next ); - return; - case nToken : - FoLink( ((TokNode *)p)->next ); - return; - case nAction : - FoLink( ((ActionNode *)p)->next ); - return; - default : - fatal_internal("invalid node type"); - } -} - -/* - * Add a reference to the end of a rule. - * - * 'r' points to the RuleBlk node in a rule. r->end points to the last node - * (EndRule jtype) in a rule. - * - * Initial: - * r->end --> o - * - * After: - * r->end --> o-->o--> Ptr to node following rule r in another rule - * | - * o--> Ptr to node following another reference to r. - * - * Note that the links are added to the head of the list so that r->end->p1 - * always points to the most recently added follow-link. At the end, it should - * point to the last reference found in the grammar (starting from the 1st rule). - */ -void -#ifdef __USE_PROTOS -addFoLink( Node *p, char *rname, Junction *r ) -#else -addFoLink( p, rname, r ) -Node *p; -char *rname; -Junction *r; -#endif -{ - Junction *j; - require(r!=NULL, "addFoLink: incorrect rule graph"); - require(r->end!=NULL, "addFoLink: incorrect rule graph"); - require(r->end->jtype==EndRule, "addFoLink: incorrect rule graph"); - require(p!=NULL, "addFoLink: NULL FOLLOW link"); - - j = newJunction(); - j->rname = rname; /* rname on follow links point to target rule */ - j->p1 = p; /* link to other rule */ - j->p2 = (Node *) r->end->p1;/* point to head of list */ - r->end->p1 = (Node *) j; /* reset head to point to new node */ -} - -void -#ifdef __USE_PROTOS -GenCrossRef( Junction *p ) -#else -GenCrossRef( p ) -Junction *p; -#endif -{ - set a; - Junction *j; - RuleEntry *q; - unsigned e; - require(p!=NULL, "GenCrossRef: why are you passing me a null grammar?"); - - printf("Cross Reference:\n\n"); - a = empty; - for (; p!=NULL; p = (Junction *)p->p2) - { - printf("Rule %20s referenced by {", p->rname); - /* make a set of rules for uniqueness */ - for (j = (Junction *)(p->end)->p1; j!=NULL; j = (Junction *)j->p2) - { - q = (RuleEntry *) hash_get(Rname, j->rname); - require(q!=NULL, "GenCrossRef: FoLinks are screwed up"); - set_orel(q->rulenum, &a); - } - for (; !set_nil(a); set_rm(e, a)) - { - e = set_int(a); - printf(" %s", RulePtr[e]->rname); - } - printf(" }\n"); - } - set_free( a ); -} - -/* - The single argument is a pointer to the start of an element of a - C++ style function prototypet list. Given a pointer to the start of - an formal we must locate the comma (or the end of the string) - and locate the datatype, formal name, and initial value expression. - - The function returns a pointer to the character following the comma - which terminates the formal declaration, or a pointer to the end of - the string if none was found. - - I thought we were parsing specialists, how come I'm doing this by - hand written code ? - - Examples of input: - - Foo f, - Foo f = Foo(1), - Foo f = Foo(1,2), - Foo f = &farray[1,2], - Foo f = ",", - Foo f = ',', - TFoo f = TFoo(1,2), - - A non-zero value for nesting indicates a problem matching '(' and ')', - '[' and ']', '<' and '>', '{' and '}', or improperly terminated string - or character literal. - -*/ - - -/* - * Don't care if it is a valid string literal or not, just find the end - * Start with pointer to leading "\"" - */ - -#ifdef __USE_PROTOS -char * skipStringLiteral(char *pCurrent) -#else -char * skipStringLiteral(pCurrent) -char *pCurrent; -#endif -{ - char *p = pCurrent; - if (*p == 0) return p; - require (*p == '\"', "skipStringLiteral") - p++; - for (p = p; *p != 0; p++) { - if (*p == '\\') { - p++; - if (*p == 0) break; - p++; - } - if (*p == '\"') { - p++; - break; - } - } - return p; -} - -/* - * Don't care if it is a valid character literal or not, just find the end - * Start with pointer to leading "'" - */ - -#ifdef __USE_PROTOS -char * skipCharLiteral(char *pStart) -#else -char * skipCharLiteral(pStart) - char *pStart; -#endif -{ - char *p = pStart; - if (*p == 0) return p; - require (*p == '\'', "skipCharLiteral") - p++; - for (p = p; *p != 0; p++) { - if (*p == '\\') { - p++; - if (*p == 0) break; - p++; - } - if (*p == '\'') { - p++; - break; - } - } - return p; -} - -#ifdef __USE_PROTOS -char * skipSpaces(char *pStart) -#else -char * skipSpaces(pStart) -char * pStart; -#endif -{ - char *p = pStart; - while (*p != 0 && isspace(*p)) p++; - return p; -} - -#ifdef __USE_PROTOS -char * skipToSeparatorOrEqualSign(char *pStart, int *pNest) -#else -char * skipToSeparatorOrEqualSign(pStart, pNest) -char *pStart; -int *pNest; -#endif -{ - char *p = pStart; - - int nest = 0; - - *pNest = (-1); - - while (*p != 0) { - switch (*p) { - - case '(' : - case '[' : - case '<' : - case '{' : - nest++; - p++; - break; - - case ')' : - case ']' : - case '>' : - case '}' : - nest--; - p++; - break; - - case '"' : - p = skipStringLiteral(p); - break; - - case '\'' : - p = skipCharLiteral(p); - break; - - case '\\': - p++; - if (*p == 0) goto EXIT; - p++; - break; - - case ',': - case '=': - if (nest == 0) goto EXIT; - p++; - break; - - default: - p++; - } - } -EXIT: - *pNest = nest; - return p; -} - -#ifdef __USE_PROTOS -char * skipToSeparator(char *pStart, int *pNest) -#else -char * skipToSeparator(pStart, pNest) -char *pStart; -int *pNest; -#endif -{ - char * p = pStart; - for ( ; ; ) { - p = skipToSeparatorOrEqualSign(p, pNest); - if (*pNest != 0) return p; - if (*p == ',') return p; - if (*p == 0) return p; - p++; - } -} - -/* skip to just past the "=" separating the declaration from the initialization value */ - -#ifdef __USE_PROTOS -char * getInitializer(char *pStart) -#else -char * getInitializer(pStart) -char * pStart; -#endif -{ - char *p; - char *pDataType; - char *pSymbol; - char *pEqualSign; - char *pValue; - char *pSeparator; - int nest = 0; - - require(pStart!=NULL, "getInitializer: invalid string"); - - p = endFormal(pStart, - &pDataType, - &pSymbol, - &pEqualSign, - &pValue, - &pSeparator, - &nest); - if (nest != 0) return NULL; - if (pEqualSign == NULL) return NULL; - if (pValue == NULL) return NULL; - return strBetween(pValue, NULL, pSeparator); -} - -/* - Examines the string from pStart to pEnd-1. - If the string has 0 length or is entirely white space - returns 1. Otherwise 0. -*/ - -#ifdef __USE_PROTOS -int isWhiteString(const char *pStart, const char *pEnd) -#else -int isWhiteString(pStart, pEnd) -const char *pStart; -const char *pEnd; -#endif -{ - const char *p; - for (p = pStart; p < pEnd; p++) { - if (! isspace(*p)) return 0; - } - return 1; -} - -/* - This replaces HasComma() which couldn't distinguish - - foo ["a,b"] - - from: - - foo[a,b] - -*/ - -#ifdef __USE_PROTOS -int hasMultipleOperands(char *pStart) -#else -int hasMultipleOperands(pStart) -char *pStart; -#endif -{ - char *p = pStart; - int nest = 0; - - p = skipSpaces(p); - if (*p == 0) return 0; - p = skipToSeparator(p, &nest); - if (nest == 0 && *p == ',') return 1; - return 0; -} - - -#define MAX_STR_BETWEEN_WORK_AREA 1000 - -static char strBetweenWorkArea[MAX_STR_BETWEEN_WORK_AREA]; - - -/* - strBetween(pStart, pNext, pStop) - - Creates a null terminated string by copying the text between two pointers - to a work area. The start of the string is pStart. The end of the string - is the character before pNext, or if pNext is null then the character before - pStop. Trailing spaces are not included in the copy operation. - - This is used when a string contains several parts. The pNext part may be - optional. The pStop will stop the scan when the optional part is not present - (is a null pointer). -*/ - -#ifdef __USE_PROTOS -char *strBetween(char *pStart, char *pNext, char *pStop) -#else -char *strBetween(pStart, pNext, pStop) -char *pStart; -char *pNext; -char *pStop; -#endif -{ - char *p; - char *q = strBetweenWorkArea; - const char *pEnd; - - pEnd = (pNext != NULL) ? pNext : pStop; - - require (pEnd != NULL, "pEnd == NULL"); - require (pEnd >= pStart, "pEnd < pStart"); - for (pEnd--; pEnd >= pStart; pEnd--) { /* MR31 */ - if (! isspace(*pEnd)) break; - } - for (p = pStart; - p <= pEnd && q < &strBetweenWorkArea[MAX_STR_BETWEEN_WORK_AREA-2]; - p++, q++) { - *q = *p; - } - *q = 0; - return strBetweenWorkArea; -} - -/* - function Returns pointer to character following separator at - value which to continue search for next formal. If at the - end of the string a pointer to the null byte at the - end of the string is returned. - - pStart Pointer to the starting position of the formal list - - This may be the middle of a longer string, for example - when looking for the end of formal #3 starting from - the middle of the complete formal list. - - ppDataType Returns a pointer to the start of the data type in the - formal. Example: pointer to "Foo". - - ppSymbol Returns a pointer to the start of the formal symbol. - Example: pointer to "f". - - ppEqualSign Returns a pointer to the equal sign separating the - formal symbol from the initial value. If there is - no "=" then this will be NULL. - - ppValue Returns a pointer to the initial value part of the - formal declaration. Example: pointer to "&farray[1,2]" - - ppSeparator Returns a pointer to the character which terminated the - scan. This should be a pointer to a comma or a null - byte which terminates the string. - - pNest Returns the nesting level when a separator was found. - This is non-zero for any kind of error. This is zero - for a successful parse of this portion of the formal - list. - -*/ - -#ifdef __USE_PROTOS -char * endFormal(char *pStart, - char **ppDataType, - char **ppSymbol, - char **ppEqualSign, - char **ppValue, - char **ppSeparator, - int *pNest) -#else -char * endFormal(pStart, - ppDataType, - ppSymbol, - ppEqualSign, - ppValue, - ppSeparator, - pNest) -char *pStart; -char **ppDataType; -char **ppSymbol; -char **ppEqualSign; -char **ppValue; -char **ppSeparator; -int *pNest; - -#endif -{ - char *p = pStart; - char *q; - - *ppDataType = NULL; - *ppSymbol = NULL; - *ppEqualSign = NULL; - *ppValue = NULL; - *ppSeparator = NULL; - - *pNest = 0; - - /* The first non-blank is the start of the datatype */ - - p = skipSpaces(p); - if (*p == 0) goto EXIT; - *ppDataType = p; - - /* We are not looking for the symbol, we are looking - for the separator that follows the symbol. Then - we'll back up. - - Search for the ',' or '=" or null terminator. - */ - - p = skipToSeparatorOrEqualSign(p, pNest); - - if (*pNest != 0) goto EXIT; - - /* - Work backwards to find start of symbol - Skip spaces between the end of symbol and separator - Assume that there are no spaces in the formal, but - there is a space preceding the formal - */ - - for (q = &p[-1]; q >= *ppDataType; q--) { - if (! isspace(*q)) break; - } - if (q < *ppDataType) goto EXIT; - - /* - MR26 Handle things like: IIR_Bool (IIR_Decl::*constraint)() - Backup until we hit the end of a symbol string, then find the - start of the symbol string. This wont' work for functions - with prototypes, but works for the most common cases. For - others, use typedef names. - */ - -/* MR26 */ for (q = q; q >= *ppDataType; q--) { -/* MR26 */ if (isalpha(*q) || isdigit(*q) || *q == '_' || *q == '$') break; -/* MR26 */ } -/* MR26 */ if (q < *ppDataType) goto EXIT; - - for (q = q; q >= *ppDataType; q--) { - if ( ! (isalpha(*q) || isdigit(*q) || *q == '_' || *q == '$')) break; - } - - *ppSymbol = &q[1]; - - if (*p == ',' || *p == 0) { - *ppSeparator = p; - goto EXIT; - } - - *ppEqualSign = p; - p = skipSpaces(++p); - *ppValue = p; - if (*p == 0) goto EXIT; - - - while (*p != 0 && *pNest == 0 && *p != ',') { - p = skipToSeparator(p, pNest); - } - if (*pNest == 0) *ppSeparator = p; - -EXIT: - if (*p == ',') p++; - return p; -} diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/mode.h b/Tools/CodeTools/TianoTools/Pccts/antlr/mode.h deleted file mode 100644 index c08bf31ac7..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/mode.h +++ /dev/null @@ -1,12 +0,0 @@ -#define START 0 -#define STRINGS 1 -#define ACTION_STRINGS 2 -#define ACTION_CHARS 3 -#define ACTION_COMMENTS 4 -#define TOK_DEF_COMMENTS 5 -#define TOK_DEF_CPP_COMMENTS 6 -#define ACTION_CPP_COMMENTS 7 -#define CPP_COMMENTS 8 -#define COMMENTS 9 -#define ACTIONS 10 -#define PARSE_ENUM_FILE 11 diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/mrhoist.c b/Tools/CodeTools/TianoTools/Pccts/antlr/mrhoist.c deleted file mode 100644 index 110bf5996f..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/mrhoist.c +++ /dev/null @@ -1,3030 +0,0 @@ -/* - * mrhoist.c - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33MR10 - * - */ - -#include - -#include "pcctscfg.h" - -#include "set.h" -#include "syn.h" -#include "hash.h" -#include "generic.h" -#include "dlgdef.h" -#include - -#ifdef __USE_PROTOS -void dumppred(Predicate *); -#else -void dumppred(); -#endif - -/* - Try to determine whether predicate "first" is true for - all cases where "second" is true. Comparison takes place - without regard to context. - Assumes that predicate symbols have been expanded. - Assumes that there are no NAND or NOR nodes - -*/ - -#ifdef __USE_PROTOS -int MR_secondPredicateUnreachable(Predicate *first,Predicate *second) -#else -int MR_secondPredicateUnreachable(first,second) - Predicate *first; - Predicate *second; -#endif -{ - Predicate *f; - Predicate *s; - - if (first == NULL) { - return 1; - } else if (second == NULL) { - return 0; - } else if (first->down == NULL && second->down == NULL) { - if (first->source == second->source && - first->inverted == second->inverted) { - return 1; /* look identical - will never reach alt2 */ - } else { - return 0; /* look different */ - }; - } else if (first->down == NULL && second->down != NULL) { - - if (second->expr == PRED_AND_LIST) { - - /* unreachable if first covers any child of second */ - - for (s=second->down; s != NULL; s=s->right) { - if (MR_secondPredicateUnreachable(first,s)) { - return 1; - }; - }; - return 0; - } else if (second->expr == PRED_OR_LIST) { - - /* unreachable if first covers every child of second */ - - for (s=second->down; s != NULL; s=s->right) { - if (!MR_secondPredicateUnreachable(first,s)) { - return 0; - }; - }; - return 1; - } else { - require (0,"Illegal pred->expr"); - return 0; /* MR20 Make compiler happy */ - }; - } else if (first->down != NULL && second->down == NULL) { - if (first->expr == PRED_AND_LIST) { - - /* unreachable if every child of first covers second */ - - for (f=first->down; f != NULL; f=f->right) { - if (!MR_secondPredicateUnreachable(f,second)) { - return 0; - }; - }; - return 1; - } else if (first->expr == PRED_OR_LIST) { - - /* unreachable if any child of first covers second */ - - for (f=first->down; f != NULL; f=f->right) { - if (MR_secondPredicateUnreachable(f,second)) { - return 1; - }; - }; - return 0; - } else { - require (0,"Illegal predicate->expr"); - return 0; /* MR20 Make compiler happy */ - }; - } else { - - if (first->expr == PRED_AND_LIST && second->expr == PRED_AND_LIST) { - - /* unreachable if each child of first covers at least one child of second */ - - for (f=first->down; f != NULL ; f=f->right) { - for (s=second->down; s != NULL ; s=s->right) { - if (MR_secondPredicateUnreachable(f,s)) goto A_next_f; - }; - return 0; -A_next_f: - continue; - }; - return 1; - - } else if (first->expr == PRED_AND_LIST && second->expr == PRED_OR_LIST) { - - /* unreachable if each child of first covers ALL of second's children */ - - for (f=first->down; f != NULL ; f=f->right) { - for (s=second->down; s != NULL ; s=s->right) { - if (!MR_secondPredicateUnreachable(f,s)) return 0; - }; - }; - return 1; - - } else if (first->expr == PRED_OR_LIST && second->expr == PRED_AND_LIST) { - - /* unreachable if any child of second is covered by any child of first */ - - for (f=first->down; f != NULL ; f=f->right) { - for (s=second->down; s != NULL ; s=s->right) { - if (MR_secondPredicateUnreachable(f,s)) return 1; - }; - }; - return 0; - - } else if (first->expr == PRED_OR_LIST && second->expr == PRED_OR_LIST) { - - /* unreachable if every child of second is covered by some child of first */ - - for (f=first->down; f != NULL ; f=f->right) { - for (s=second->down; s != NULL ; s=s->right) { - if (MR_secondPredicateUnreachable(f,s)) goto B_next_f; - }; - return 0; -B_next_f: - continue; - }; - return 1; - - } else { - require (0,"Illegal predicate->expr"); - return 0; /* MR20 Make compiler happy */ - }; - }; - return 0; /* MR20 MSVC 5.0 complains about missing return statement */ -} - -#ifdef __USE_PROTOS -void MR_xxxIndent(FILE *f,int depth) -#else -void MR_xxxIndent(f,depth) - FILE *f; - int depth; -#endif -{ - int i; - - for (i=0; irname,rrn->line,FileStr[rrn->file],rrn->text); - }; - lastOne=MR_ruleReferenced(rrn); - if (lastOne != NULL) { - for (j=0; jrname,lastOne->line,FileStr[lastOne->file]); - }; -} - -#ifdef __USE_PROTOS -void MR_dumpTreeF(FILE *f,int depth,Tree *tree,int across) -#else -void MR_dumpTreeF(f,depth,tree,across) - FILE *f; - Tree *tree; - int depth; - int across; -#endif -{ - int newAcross=across; - - if (tree == NULL ) return; - if (tree->down != NULL ) { - fprintf(output,"\n"); - MR_outputIndent(depth); - fprintf(output, "(root ="); - }; - if (tree->token == ALT ) { - fprintf(output," %-16s","Alt"); - } else if (tree->token==EpToken ) { - fprintf(output,"(%d)%13s",tree->v.rk," "); - } else { - fprintf(output," %-16s",TerminalString(tree->token)); - }; - if (tree->down != NULL) { - fprintf(output,"\n"); - MR_outputIndent(depth+1); - MR_dumpTreeF(f,depth+1,tree->down,1); - newAcross=0; - fprintf(output,"\n"); - MR_outputIndent(depth); - fprintf(output,")"); - }; - if (newAcross > 3) { - fprintf(output,"\n"); - MR_outputIndent(depth); - newAcross=0; - }; - MR_dumpTreeF(f,depth,tree->right,newAcross+1); -} - -#ifdef __USE_PROTOS -void MR_dumpTreeX(int depth,Tree *tree,int across) -#else -void MR_dumpTreeX(depth,tree,across) - Tree *tree; - int depth; - int across; -#endif -{ - MR_dumpTreeF(output,depth,tree,across); -} - -#ifdef __USE_PROTOS -void MR_dumpTokenSet(FILE *f,int depth,set s) -#else -void MR_dumpTokenSet(f,depth,s) - FILE *f; - int depth; - set s; -#endif -{ - int i; - int j; - - unsigned *pdq; - - if (set_nil(s)) { - fprintf(f,"\n"); - MR_xxxIndent(f,depth+1); - fprintf(f,"nil\n"); - return; - }; - - pdq=set_pdq(s); - require(pdq != NULL,"set_pdq failed"); - i=0; - for (i=0 ; ; i=i+4) { - fprintf(f,"\n"); - MR_xxxIndent(f,depth+1); - for (j=0; j < 4 ; j++) { - if (pdq[i+j] == nil) break; - fprintf(f," %-16s",TerminalString(pdq[i+j])); - }; - if (pdq[i+j] == nil) break; - }; - fprintf(f,"\n"); - free( (char *) pdq); -} - -#ifdef __USE_PROTOS -void MR_dumpPred1(int depth,Predicate *p,int withContext) -#else -void MR_dumpPred1(depth,p,withContext) - int depth; - Predicate *p; - int withContext; -#endif -{ - unsigned k; - - if (p == NULL) { - MR_outputIndent(depth); - fprintf(output,"The predicate is empty (or always true)\n\n"); - return; - }; - if (p->down != NULL) { - MR_outputIndent(depth); - if (p->inverted) { - - /* MR14a Left out print expression in fprintf - Reported by Manuel Kessler (mlkessle@cip.physik.uni-wuerzburg.de) - */ - - if (p->expr == PRED_AND_LIST) fprintf(output,"%s NAND (not AND) expr\n\n",p->expr); - if (p->expr == PRED_OR_LIST) fprintf(output,"%s NOR (not OR) expr\n\n",p->expr); - } else { - fprintf(output,"%s expr\n\n",p->expr); - }; - } else { - MR_outputIndent(depth); - fprintf(output,"pred %s <<%s>>?\n", - (p->inverted ? " *not*" : ""), - (p->expr == NULL ? "null expr" : p->expr)); - MR_outputIndent(depth+1); - fprintf(output," "); - fprintf(output," depth=k=%d",p->k); - if (p->source != NULL && p->source->guardpred) { - fprintf(output," (\"=>\" guard)"); - } - if (p->source != NULL && p->source->ampersandPred != NULL) { - fprintf(output," (\"&&\" guard)"); - }; - k=set_int(p->completionSet); - if (k != nil) { - fprintf(output," Incomplete Set at k=%d !",k); - }; - k=set_int(p->completionTree); - if (k != nil) { - fprintf(output," Incomplete Tree at k=%d !",k); - }; - if (p->source != NULL) { - fprintf(output," rule %s line %d %s", - p->source->rname,p->source->line,FileStr[p->source->file]); - }; - fprintf(output,"\n"); - if (withContext && - (HoistPredicateContext || - ! set_nil(p->scontext[1]) || - p->tcontext != NULL)) { - if (p->k == 1) { - MR_outputIndent(depth+1); - fprintf(output,"set context: "); - MR_dumpTokenSet(output,depth+1,p->scontext[1]); - } - if (p->k != 1) { - MR_outputIndent(depth+1); - fprintf(output,"tree context:"); - if (p->tcontext == NULL) { - fprintf(output," null"); - } else { - MR_dumpTreeX(depth+2,p->tcontext,0); - }; - fprintf(output,"\n"); - }; - }; - fprintf(output,"\n"); - }; - if (p->down != NULL) { - MR_dumpPred1(depth+1,p->down,withContext); - }; - if (p->right != NULL) { - MR_dumpPred1(depth,p->right,withContext); - }; -} - -#ifdef __USE_PROTOS -void MR_dumpPred(Predicate *p,int withContext) -#else -void MR_dumpPred(p,withContext) - Predicate *p; - int withContext; -#endif -{ - MR_dumpPred1(0,p,withContext); -} - -#ifdef __USE_PROTOS -Tree * MR_make_tree_from_set(set s) -#else -Tree * MR_make_tree_from_set(s) - set s; -#endif -{ - Tree *t=NULL; - Tree *node; - Tree **tp=&t; - int i; - - unsigned *pdq=set_pdq(s); - - if (pdq != NULL) { - for (i=0 ; pdq[i] != nil ; i++) { - node=tnode( (int) pdq[i]); - *tp=node; - tp=&(node->right); - }; - *tp=NULL; - free ( (char *) pdq); - }; - return t; -} - -#ifdef __USE_PROTOS -void MR_check_pred_too_long(Predicate *p,set completion) -#else -void MR_check_pred_too_long(p,completion) - Predicate *p; - set completion; -#endif -{ - if (p != NULL && - p->source != NULL && - ! p->source->predTooLong) { - if ( !set_nil(completion)) { - p->source->predTooLong=1; -warnFL("It is unusual (but ok) for a semantic predicate to test context past the end of its own rule", - FileStr[p->source->file],p->source->line); - }; - }; -} - -#ifdef __USE_PROTOS -int MR_predicate_context_completed(Predicate *p) -#else -int MR_predicate_context_completed(p) - Predicate *p; -#endif -{ - if (p == NULL) return 1; - if (p->expr != PRED_AND_LIST && - p->expr != PRED_OR_LIST) { - if ( ! set_nil(p->completionSet)) return 0; - if ( ! set_nil(p->completionTree)) return 0; - }; - return MR_predicate_context_completed(p->down) & - MR_predicate_context_completed(p->right); -} - -#ifdef __USE_PROTOS -Node * MR_advance(Node *n) -#else -Node * MR_advance(n) - Node *n; -#endif -{ - if (n == NULL) return NULL; - switch (n->ntype) { - case nJunction: return ((Junction *)n)->p1; - case nToken: return ((TokNode *)n)->next; - case nRuleRef: return ((RuleRefNode *)n)->next; - case nAction: return ((ActionNode *)n)->next; - default: return NULL; - }; - return NULL; /* MSVC 5.0 complains about missing return statement */ -} - -#ifdef __USE_PROTOS -Junction * MR_find_endRule(Node *n) -#else -Junction * MR_find_endRule(n) - Node *n; -#endif -{ - Node *next; - if (n == NULL) return NULL; - for (next=n; next != NULL; next=MR_advance(next)) { - if (next->ntype == nJunction && - ( (Junction *) next)->jtype == EndRule) { - break; - }; - }; - return (Junction *)next; -} - -/* - Intersection: a branch which is shorter is chosen - over one which is longer: (A B C) intersect (A B) yields (A B). - - AND: a branch which is longer is chosen over the one - which is shorter: (A B C) AND (A B) yields (A B C) - -*/ - -#ifdef __USE_PROTOS -Tree *MR_computeTreeIntersection(Tree *l,Tree *r) -#else -Tree *MR_computeTreeIntersection(l,r) - Tree *l; - Tree *r; -#endif -{ - Tree *result=NULL; - Tree **tail; - Tree *p; - Tree *q; - Tree *match; - - if (l == NULL || r == NULL) return NULL; - for (p=l; p != NULL; p=p->right) { - require(p->token != EpToken,"MR_computeTreeIntersection: p->EpToken unexpected\n"); - require (p->token != ALT,"MR_computeTreeIntersection: p->ALT unexpected\n"); - }; - for (q=r; q != NULL; q=q->right) { - require(q->token != EpToken,"MR_computeTreeIntersection: q->EpToken unexpected\n"); - require(q->token != ALT,"MR_computeTreeIntersection: q->ALT unexpected\n"); - }; - - result=tnode(ALT); - tail=&(result->down); - - for (p=l; p != NULL ; p=p->right) { - for (q=r; q != NULL ; q=q->right) { - if (p->token == q->token) { - match=tnode(p->token); - match->down=MR_computeTreeIntersection(p->down,q->down); - *tail=match; - tail=&(match->right); - }; - }; - }; - - *tail=NULL; - result=tshrink(result); - result=tflatten( result ); - result=tleft_factor( result ); - return result; -} - -/* the predicates which are ANDed together have a common - context: they must all have common roots. Thus the - AND operation is more like an OR operation because - branches which are longer are grafted onto shorter - branches of the AND tree. For instance combining - (A B C) with (A B C D) gives (A B C D). There - should never be a case of (A B C) and (A B D) because - they have the same context. - - Actually, this may not be true once one throws in - guard predicates which are defined by the user, not - the context. -*/ - -/* requires input trees to be in "canonical" format */ - -#ifdef __USE_PROTOS -Tree *MR_computeTreeAND(Tree *l,Tree *r) -#else -Tree *MR_computeTreeAND(l,r) - Tree *l; - Tree *r; -#endif -{ - Tree *result=NULL; - Tree **tail; - Tree *p; - Tree *q; - Tree *match; - - if (l == NULL) return tdup(r); - if (r == NULL) return tdup(l); - - for (p=l; p != NULL; p=p->right) { -/**** require(p->token != EpToken,"MR_computeTreeAND: p->EpToken unexpected\n"); ****/ - require (p->token != ALT,"MR_computeTreeAND: p->ALT unexpected\n"); - }; - for (q=r; q != NULL; q=q->right) { -/**** require(q->token != EpToken,"MR_computeTreeAND: q->EpToken unexpected\n"); ****/ - require(q->token != ALT,"MR_computeTreeAND: q->ALT unexpected\n"); - }; - - result=tnode(ALT); - tail=&(result->down); - - for (p=l; p != NULL ; p=p->right) { - for (q=r; q != NULL ; q=q->right) { - if (p->token == q->token) { - match=tnode(p->token); - match->down=MR_computeTreeAND(p->down,q->down); - *tail=match; - tail=&(match->right); - }; - }; - }; - - *tail=NULL; - result=tshrink(result); - result=tflatten( result ); - result=tleft_factor( result ); - return result; -} - -#ifdef __USE_PROTOS -void MR_union_plain_sets1(Predicate *p,set *theUnion) -#else -void MR_union_plain_sets1(p,theUnion) - Predicate *p; - set *theUnion; -#endif -{ - if (p == NULL) return; - MR_union_plain_sets1(p->down,theUnion); - MR_union_plain_sets1(p->right,theUnion); - set_orin(theUnion,p->plainSet); - return; -} - -#ifdef __USE_PROTOS -set MR_union_plain_sets(Predicate *p) -#else -set MR_union_plain_sets(p) - Predicate *p; -#endif -{ - set theUnion; - - theUnion=empty; - - MR_union_plain_sets1(p,&theUnion); - return theUnion; -} - -/* does NOT left factor: do not want to merge - (A B) with (A) to get (A B) - in fact the opposite: (A B) with (A) gives (A) -*/ - -#ifdef __USE_PROTOS -Tree *MR_compute_pred_tree_ctxXX(Predicate *p) -#else -Tree *MR_compute_pred_tree_ctxXX(p) - Predicate *p; -#endif -{ - Tree *result=NULL; - Predicate *q; - Tree *t; - - if (p == NULL) return NULL; - -/* this appears strange: why do we OR the context - of and AND predicate ? It is because of the way - that predicates are evaluated: if the context is - wrong then it's the same as if the predicate was - true. That means that even when one leg of an - AND has unmatched context, if the other leg has - matched context and is true then the predicate - succeeds. It's only when all the legs have unmatched - context that this one can skip evaluation of the - predicates. -*/ - if (p->expr == PRED_OR_LIST || - p->expr == PRED_AND_LIST) { - for (q=p->down; q != NULL ; q=q->right) { - t=MR_compute_pred_tree_ctxXX(q); - result=tappend(result,t); - t=NULL; - }; - - result=tshrink(result); - result=tflatten( result ); - -/* does NOT left factor: do not want to merge - (A B) with (A) to get (A B) - in fact the opposite: (A B) with (A) gives (A) -*/ - -/**** result=tleft_factor( result ); ****/ - return result; - }; - -#if 0 -** if (p->expr == PRED_AND_LIST) { -** -** Predicate *l; -** Predicate *r; -** Tree *l1; -** Tree *r1; -** Tree *prevl1; -** -** l=p->down; -** require (l->right != NULL,"MR_compute_pred_tree - AND has only one child"); -** -**/* l1 and r1 should already be in "canonical" format */ -** -** l1=MR_compute_pred_tree(l); -** for (r=l->right; r != NULL; r=r->right) { -** r1=MR_compute_pred_tree(r); -** prevl1=l1; -** l1=MR_computeTreeAND(l1,r1); -** Tfree(r1); -** Tfree(prevl1); -** }; -** -**/* result from computeTreeAND should be in "canonical" format */ -** -** result=l1; -** -**/* result of MR_computeTreeAND should be in "canonical" format */ -** -** return result; -** }; -#endif - - if (p->k == 1) { - result=MR_make_tree_from_set(p->scontext[1]); - } else { - result=tdup(p->tcontext); - result=MR_remove_epsilon_from_tree(result); - result=tshrink(result); - result=tflatten(result); - result=tleft_factor(result); - }; - return result; -} - -#ifdef __USE_PROTOS -void MR_pred_depth(Predicate *p,int *maxDepth) -#else -void MR_pred_depth(p,maxDepth) - Predicate *p; - int *maxDepth; -#endif -{ - if (p == NULL) return; - if (p->expr != PRED_OR_LIST && - p->expr != PRED_AND_LIST) { - if (p->k > *maxDepth) *maxDepth=p->k; - }; - MR_pred_depth(p->down,maxDepth); - MR_pred_depth(p->right,maxDepth); -} - -/* this computes the OR of all the contexts */ - -#ifdef __USE_PROTOS -set MR_compute_pred_set(Predicate *p) -#else -set MR_compute_pred_set(p) - Predicate *p; -#endif -{ - set result; - Predicate *q; - - result=empty; - - if (p == NULL) return empty; - - if (p->expr == PRED_OR_LIST || - p->expr == PRED_AND_LIST) { /* yes, I do mean PRED_AND_LIST ! */ - /* remember: r1: (A)? => <

>? r2; */ - /* r2: (B)? => <>? r3; */ - set t; - - t=empty; - result=empty; - - for (q=p->down; q != NULL; q=q->right) { - t=MR_compute_pred_set(q); - set_orin(&result,t); - set_free(t); - }; - return result; - } else if (p->k > 1) { - return empty; - } else { - return set_dup(p->scontext[1]); - }; -} - -#ifdef __USE_PROTOS -set MR_First(int ck,Junction *j,set *incomplete) -#else -set MR_First(ck,j,incomplete) - int ck; - Junction *j; - set *incomplete; -#endif -{ - Junction *p; - set tokensUsed; - - tokensUsed=empty; - - require(j->ntype==nJunction, "MR_First: non junction passed"); - - p = analysis_point((Junction *)j->p1); - - REACH(p,ck,incomplete,tokensUsed); - - return tokensUsed; -} - -#ifdef __USE_PROTOS -void MR_cleanup_pred_trees(Predicate *p) -#else -void MR_cleanup_pred_trees(p) - Predicate *p; -#endif -{ - Tree *t; - - if (p == NULL) return; - if (p->expr != PRED_OR_LIST && - p->expr != PRED_AND_LIST) { - t=p->tcontext; - t=tshrink(t); - t=tflatten(t); - t=tleft_factor(t); - p->tcontext=t; - }; - MR_cleanup_pred_trees(p->down); - MR_cleanup_pred_trees(p->right); -} - -/* does NOT return canonical tree */ - -#ifdef __USE_PROTOS -Tree * MR_remove_epsilon_from_tree(Tree *t) -#else -Tree * MR_remove_epsilon_from_tree(t) - Tree *t; -#endif -{ - if (t == NULL) return NULL; - - /* I think ALT can be ignored as a special case */ - - if (t->token != EpToken) { - t->down=MR_remove_epsilon_from_tree(t->down); - t->right=MR_remove_epsilon_from_tree(t->right); - return t; - } else { - Tree *u; - u=MR_remove_epsilon_from_tree(t->right); - t->right=NULL; - Tfree(t); - return u; - }; -} - -#ifdef __USE_PROTOS -void MR_complete_set(int predDepth,set *tokensUsed,set *incomplete) -#else -void MR_complete_set(predDepth,tokensUsed,incomplete) - int predDepth; - set *tokensUsed; - set *incomplete; -#endif -{ - int i; - RuleRefNode *ruleRef; - set rk2; - set b; - int k2; - Junction *save_MR_RuleBlkWithHalt; - - if (set_int(*incomplete) > (unsigned) predDepth) { - return; - }; - - require(MR_PredRuleRefStack.count == MR_RuleBlkWithHaltStack.count, - "RuleRefStack and RuleBlkWithHaltStack not same size"); - - require(MR_RuleBlkWithHalt == NULL || - (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == TRUE), - "RuleBlkWithHalt has no halt set"); - - save_MR_RuleBlkWithHalt=MR_RuleBlkWithHalt; - - if (MR_RuleBlkWithHalt != NULL) { - MR_RuleBlkWithHalt->end->halt=FALSE; - }; - - for (i=MR_PredRuleRefStack.count-1; i >= 0 ; i--) { - ruleRef=(RuleRefNode *)MR_PredRuleRefStack.data[i]; - if (ruleRef == NULL) continue; - - MR_RuleBlkWithHalt=(Junction *)MR_RuleBlkWithHaltStack.data[i]; - if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=TRUE; - - rk2=empty; - b=empty; - - while ( !set_nil(*incomplete) ) { - k2=set_int(*incomplete); - if (k2 > predDepth) break; /* <=== another exit from loop */ - set_rm(k2,*incomplete); - REACH(ruleRef->next,k2,&rk2,b); - set_orin(tokensUsed,b); - set_free(b); - }; - - if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=FALSE; - - set_orin(incomplete,rk2); /* remember what we couldn't do */ - set_free(rk2); - if (set_int(*incomplete) > (unsigned) predDepth) break; /* <=== another exit from loop */ - }; - - MR_RuleBlkWithHalt=save_MR_RuleBlkWithHalt; - if (MR_RuleBlkWithHalt != NULL) { - MR_RuleBlkWithHalt->end->halt=TRUE; - }; -} - -#ifdef __USE_PROTOS -void MR_complete_tree(int predDepth,Tree **t,set *incomplete) -#else -void MR_complete_tree(predDepth,t,incomplete) - int predDepth; - Tree **t; - set *incomplete; -#endif -{ - int i; - RuleRefNode *ruleRef; - set rk2; - Tree *u; - unsigned k2; - Junction *save_MR_RuleBlkWithHalt; - int saveConstrainSearch; - - if (set_int(*incomplete) > (unsigned) predDepth) { - return; - }; - - require(MR_PredRuleRefStack.count == MR_RuleBlkWithHaltStack.count, - "RuleRefStack and RuleBlkWithHaltStack not same size"); - - require(MR_RuleBlkWithHalt == NULL || - (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == TRUE), - "RuleBlkWithHalt has no halt set"); - - save_MR_RuleBlkWithHalt=MR_RuleBlkWithHalt; - saveConstrainSearch=ConstrainSearch; - ConstrainSearch=0; - - if (MR_RuleBlkWithHalt != NULL) { - MR_RuleBlkWithHalt->end->halt=FALSE; - }; - - for (i=MR_PredRuleRefStack.count-1; i >= 0 ; i--) { - ruleRef=(RuleRefNode *)MR_PredRuleRefStack.data[i]; - if (ruleRef == NULL) continue; - - MR_RuleBlkWithHalt=(Junction *)MR_RuleBlkWithHaltStack.data[i]; - - if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=TRUE; - - rk2=empty; - - while ( !set_nil(*incomplete) ) { - k2 = set_int(*incomplete); - if (k2 > (unsigned) predDepth) break; /* <=== another exit from loop */ - set_rm(k2,*incomplete); - u = NULL; - - TRAV(ruleRef->next,k2,&rk2,u); - - /* any subtrees missing k2 tokens, add u onto end */ - - *t=tlink(*t,u,k2); - Tfree(u); - } - - set_orin(incomplete,rk2); /* remember what we couldn't do */ - set_free(rk2); - - if (MR_RuleBlkWithHalt != NULL) MR_RuleBlkWithHalt->end->halt=FALSE; - - if (set_int(*incomplete) > (unsigned) predDepth) break; /* <=== another exit from loop */ - }; - - MR_RuleBlkWithHalt=save_MR_RuleBlkWithHalt; - - if (MR_RuleBlkWithHalt != NULL) { - MR_RuleBlkWithHalt->end->halt=TRUE; - }; - ConstrainSearch=saveConstrainSearch; -} - -#ifdef __USE_PROTOS -void MR_complete_predicates(int predDepth,Predicate *pred) -#else -void MR_complete_predicates(predDepth,pred) - int predDepth; - Predicate *pred; -#endif -{ - if (pred == NULL) return; - if (pred->expr != PRED_AND_LIST && - pred->expr != PRED_OR_LIST) { - MR_complete_set(predDepth,&(pred->scontext[1]),&(pred->completionSet)); - MR_complete_tree(predDepth,&(pred->tcontext),&(pred->completionTree)); - }; - MR_complete_predicates(predDepth,pred->down); - MR_complete_predicates(predDepth,pred->right); -} - -#ifdef __USE_PROTOS -Junction * MR_junctionWithoutP2(Junction *j) -#else -Junction * MR_junctionWithoutP2(j) - Junction *j; -#endif -{ - Junction *thisAlt; - -/* don't want to follow p2 to the next alternative of this rule */ -/* insert a generic node with null p2 if necessary */ -/* however FIRST requires a junction */ - - thisAlt=j; - if (thisAlt->p2 != NULL) { - if (thisAlt->p1->ntype == nJunction) { - thisAlt=(Junction *) thisAlt->p1; - } else { - thisAlt=newJunction(); - thisAlt->p1=j->p1; - thisAlt->rname=j->rname; - thisAlt->file=j->file; - thisAlt->line=j->line; - j->p1=(Node *)thisAlt; - }; - }; - return thisAlt; -} - -#ifdef __USE_PROTOS -int MR_tree_equ(Tree *big, Tree *small) { -#else -int MR_tree_equ(big,small) - Tree *big; - Tree *small; -{ -#endif - - Tree *b; - Tree *s; - int bcount=0; - int scount=0; - - if (small == NULL && big == NULL) return 1; - if (small == NULL) return 0; - if (big == NULL) return 0; - - if (small->token == ALT) { - require(small->right == NULL, - "MR_tree_equ: small: ALT node has siblings"); - return MR_tree_equ(big,small->down); - }; - if (big->token == ALT) { - require(big->right == NULL, - "MR_tree_equ: big: ALT node has siblings"); - return MR_tree_equ(big->down,small); - }; - for (s=small; s != NULL; s=s->right) { - scount++; - require(s->token != EpToken,"MR_tree_equ: s->EpToken unexpected\n"); - }; - for (b=big; b != NULL; b=b->right) { - bcount++; - require(b->token != EpToken,"MR_tree_equ: b->EpToken unexpected\n"); - }; - - if (bcount != scount) return 0; - - for (s=small; s != NULL; s=s->right) { - for (b=big; b!= NULL; b=b->right) { - if (s->token == b->token) { - if (MR_tree_equ(b->down,s->down)) goto next_s; - }; - }; - return 0; -next_s: - continue; - }; - return 1; -} - -/* this does not compare sources - only contexts ! */ - -#ifdef __USE_PROTOS -int MR_identicalContext(Predicate *p,Predicate *q) -#else -int MR_identicalContext(p,q) - Predicate *p; - Predicate *q; -#endif -{ - if (p->k != q->k) return 0; - require ( (p->tcontext == NULL) == (q->tcontext == NULL), - "tcontext inconsistent"); - if (p->k == 1) { - return set_equ(p->scontext[1],q->scontext[1]); - } else { - return MR_tree_equ(p->tcontext,q->tcontext); - }; -} - -#ifdef __USE_PROTOS -void MR_reportSetSuppression(int predDepth, - set predSet,set plainSet,Junction *jPred,Junction *jPlain,Predicate *p) -#else -void MR_reportSetSuppression(predDepth,predSet,plainSet,jPred,jPlain,p) - int predDepth; - set predSet; - set plainSet; - Junction *jPred; - Junction *jPlain; - Predicate *p; -#endif -{ - if (InfoP) { - fprintf(output,"\n#if 0\n\n"); - fprintf(output,"Hoisting of predicate suppressed by alternative without predicate.\n"); - fprintf(output,"The alt without the predicate includes all cases where the predicate is false.\n\n"); - fprintf(output," WITH predicate: line %d %s\n",jPred->line,FileStr[jPred->file]); - if (jPlain != NULL) { - fprintf(output," WITHOUT predicate: line %d %s\n",jPlain->line,FileStr[jPlain->file]); - } else { - fprintf(output," WITHOUT predicate: all alternatives without predicates (combined)\n"); - }; - if (predDepth == 1) { - fprintf(output,"\nThe context set for the predicate:\n"); - MR_dumpTokenSet(output,1,predSet); - }; - fprintf(output,"\nThe lookahead set for the alt WITHOUT the semantic predicate:\n"); - MR_dumpTokenSet(output,1,plainSet); - fprintf(output,"\nThe predicate:\n\n"); - MR_dumpPred1(1,p,1); - fprintf(output,"Chain of referenced rules:\n\n"); - MR_dumpPredRuleRefStack(output,4); - fprintf(output,"\n#endif\n"); - }; -} - -#ifdef __USE_PROTOS -void MR_reportSetRestriction(int predDepth,set predSet,set plainSet, - Junction *jPred,Junction *jPlain,Predicate *origPred,Predicate *newPred) -#else -void MR_reportSetRestriction(predDepth,predSet,plainSet,jPred,jPlain,origPred,newPred) - int predDepth; - set predSet; - set plainSet; - Junction *jPred; - Junction *jPlain; - Predicate *origPred; - Predicate *newPred; -#endif -{ - set intersect; - - intersect=empty; - - if (! InfoP) return; - fprintf(output,"\n#if 0\n\n"); - fprintf(output,"Restricting the context of a predicate because of overlap in the lookahead set\n"); - fprintf(output," between the alternative with the semantic predicate and one without\n"); - fprintf(output,"Without this restriction the alternative without the predicate could not\n"); - fprintf(output," be reached when input matched the context of the predicate and the predicate\n"); - fprintf(output," was false.\n\n"); - - fprintf(output," WITH predicate: line %d %s\n",jPred->line,FileStr[jPred->file]); - if (jPlain != NULL) { - fprintf(output," WITHOUT predicate: line %d %s\n",jPlain->line,FileStr[jPlain->file]); - } else { - fprintf(output," WITHOUT predicate: all alternatives without predicates (combined)\n"); - }; - if (predDepth == 1) { - fprintf(output,"\nThe original context set for the predicate:\n"); - MR_dumpTokenSet(output,1,predSet); - }; - fprintf(output,"\nThe lookahead set for the alt WITHOUT the semantic predicate:\n"); - MR_dumpTokenSet(output,1,plainSet); - if (predDepth == 1) { - fprintf(output,"\nThe intersection of the two sets\n"); - intersect=set_and(predSet,plainSet); - MR_dumpTokenSet(output,1,intersect); - set_free(intersect); - }; - fprintf(output,"\nThe original predicate:\n\n"); - MR_dumpPred1(1,origPred,1); - fprintf(output,"The new (modified) form of the predicate:\n\n"); - MR_dumpPred1(1,newPred,1); - fprintf(output,"#endif\n"); -} - -/* don't use Pass3 by itself unless you know that inverted is not important */ - -#ifdef __USE_PROTOS -Predicate * MR_removeRedundantPredPass3(Predicate *p) -#else -Predicate * MR_removeRedundantPredPass3(p) - Predicate *p; -#endif -{ - Predicate *q; - - if (p == NULL) return NULL; - p->right=MR_removeRedundantPredPass3(p->right); - p->down=MR_removeRedundantPredPass3(p->down); - if (p->redundant) { - q=p->right; - p->right=NULL; - predicate_free(p); - return q; - }; - if (p->expr == PRED_AND_LIST || - p->expr == PRED_OR_LIST) { - if (p->down == NULL) { - q=p->right; - p->right=NULL; - predicate_free(p); - return q; - }; - if (p->down != NULL && p->down->right == NULL) { - q=p->down; - q->right=p->right; - p->right=NULL; - p->down=NULL; - return q; - }; - }; - return p; -} - -#ifdef __USE_PROTOS -void MR_removeRedundantPredPass2(Predicate *p) -#else -void MR_removeRedundantPredPass2(p) - Predicate *p; -#endif -{ - Predicate *q; - - if (p == NULL) return; - - if (p->expr == PRED_AND_LIST) { - for (q=p->down ; q != NULL ; q=q->right) { - MR_removeRedundantPredPass2(q); - if (q->isConst) { - if (q->constValue == 0) { - p->isConst=1; - p->constValue=0; - return; - } else { - q->redundant=1; - }; - }; - }; - }; - - if (p->expr == PRED_OR_LIST) { - for (q=p->down ; q != NULL ; q=q->right) { - MR_removeRedundantPredPass2(q); - if (q->isConst) { - if (q->constValue == 0) { - q->redundant=1; - } else { - p->isConst=1; - p->constValue=1; - return; - }; - }; - }; - }; - - return; -} - -#if 0 - this totally ignores the implications of guarded predicates - in which the part after the guard could possibly cover a predicate. - that would be much harder: - - rule : (A)? => <

>? sub1; /* 1 */ - | (B)? => <>? sub2 /* 2 */ - sub1 : (A)? => <>? A B /* 3 */ - | B /* 4 - suppresses line 2 */ - ; -#endif - -#ifdef __USE_PROTOS -void MR_apply_restriction1(Predicate *pred,set *plainSet,int *changed) -#else -void MR_apply_restriction1(pred,plainSet,changed) - Predicate *pred; - set *plainSet; - int *changed; -#endif -{ - if (pred == NULL) return; - MR_apply_restriction1(pred->right,plainSet,changed); - if (pred->down != NULL) { - MR_apply_restriction1(pred->down,plainSet,changed); - } else { - set t; - if (pred->k == 1) { - t=set_dif(pred->scontext[1],*plainSet); - if (*changed == 0 && - !set_equ(t,pred->scontext[1])) { - *changed=1; - }; - if (set_nil(t)) { - pred->redundant=1; - }; - set_free(pred->scontext[1]); - pred->scontext[1]=t; - }; - }; -} - -#ifdef __USE_PROTOS -void MR_orin_plainSet(Predicate *p,set plainSet) -#else -void MR_orin_plainSet(p,plainSet) - Predicate *p; - set plainSet; -#endif -{ - if (p == NULL) return; - MR_orin_plainSet(p->down,plainSet); - MR_orin_plainSet(p->right,plainSet); - set_orin(&p->plainSet,plainSet); -} - -Predicate *PRED_SUPPRESS; - -#ifdef __USE_PROTOS -Predicate * MR_find_in_aSubBlk(Junction *alt) -#else -Predicate * MR_find_in_aSubBlk(alt) - Junction *alt; -#endif -{ - Predicate *root=NULL; - Predicate **tail=NULL; - - Junction *p; - - int nAlts=0; - Junction **jList; - Predicate **predList; - int *matchList; - set predSet; - int i; - int j; - int m; - int predDepth; - set incomplete; - set union_plainSet; - set setChange; - int changed; - Predicate *newPred; - set setDif; - Predicate *origPred; - int depth1=1; /* const int */ - set *plainContext; - set plainSet; - - predSet=empty; - incomplete=empty; - union_plainSet=empty; - setChange=empty; - setDif=empty; - plainSet=empty; - - if (PRED_SUPPRESS == NULL) { - PRED_SUPPRESS=new_pred(); - PRED_SUPPRESS->expr="Predicate Suppressed"; - }; - - /* this section just counts the number of "interesting" alternatives */ - /* in order to allocate arrays */ - - for (p=alt; p!=NULL; p=(Junction *)p->p2) { - /* ignore empty alts */ - if ( p->p1->ntype != nJunction || - ((Junction *)p->p1)->jtype != EndBlk ) { - nAlts++; - }; - }; - - /* if this is a (...)+ block then don't count the last alt because - it can't be taken until at least one time through the block. - In other words it isn't a real choice until the (...)+ is entered - at which point the hoisting issue is moot. - Maybe look at "ignore" instead ? - */ - - if (alt->jtype == aPlusBlk) { - nAlts--; - }; - - jList=(Junction **)calloc(nAlts,sizeof(Junction *)); - require(jList!=NULL,"cannot allocate MR_find_in_aSubBlk jList"); - - plainContext=(set *)calloc(nAlts,sizeof(set)); - require(plainContext!=NULL,"cannot allocate MR_find_in_aSubBlk plainContext"); - for (m=0; m < nAlts; m++) plainContext[m]=empty; - - predList=(Predicate **)calloc(nAlts,sizeof(Predicate *)); - require(predList!=NULL,"cannot allocate MR_find_in_aSubBlk predList"); - - matchList=(int *)calloc(nAlts,sizeof(int)); - require(matchList!=NULL,"cannot allocate MR_find_in_aSubBlk matchList"); - - /* this section just fills in the arrays previously allocated */ - /* the most interesting one is matchList[] */ - /* */ - /* bit 0 => this alt has a semantic pred which is "covered" */ - /* by an alt without a semantic pred. Don't hoist. */ - - for (i=0,p=alt; - p!=NULL && ip2) { - - /* ignore empty alts */ - - if ( p->p1->ntype != nJunction || - ((Junction *)p->p1)->jtype != EndBlk ) { - jList[i]=MR_junctionWithoutP2(p); - predList[i]=find_predicates(p->p1); /* should be jList ????? */ - if (predList[i] != NULL) { - MR_cleanup_pred_trees(predList[i]); /* flatten & left factor */ - plainContext[i]=MR_union_plain_sets(predList[i]); - } else { - MR_set_reuse(&plainSet); - MR_set_reuse(&incomplete); - plainSet=MR_First(depth1,jList[i],&incomplete); - MR_complete_set(depth1,&plainSet,&incomplete); - require(set_nil(incomplete),"couldn't complete k=1"); - plainContext[i]=plainSet; - plainSet=empty; - }; - set_orin(&union_plainSet,plainContext[i]); - }; - }; - - if (nAlts == 1) { - goto EXIT_SIMPLE; - }; - -/* - * Looking for cases where alt i has a semantic pred and alt j does not. - * Don't care about cases where lookahead for semantic predicates overlap - * because normal predicate hoisting does the correct thing automatically. - * Don't care about cases where lookahead for alts without semantic predicates - * overlap because normal prediction does the correct thing automatically. - * - * When we find such a case check for one of three subcases: - * - * 1. if lookahead for alt i is contained in the lookahead for any - * alt j then ignore semantic predicate of alt i - * 2. if lookahead for alt i is not contained in the lookahead for - * any alt j then add add predicate i to the OR list to be hoisted - * 3. if lookahead for alt i overlaps the lookahead for some alt j then - * add a dummy semantic predicate for alt j - * - * There is an implicit assumption that the context of all alternatives following - * the rule being processed here are identical (but may vary from hoist to - * hoist depending on the place where the rule was invoked that led to hoisting - * these predicates. In othere words in the fragment: - * - * ( <>? a1 a2 a3 | <>? b1 b2 b3 ) - * - * both a3 and b3 have the same follow sets because they are both at the end of - * alternatives in the same block. - */ - - for (i=0; i < nAlts; i++) { - if (jList[i] == NULL) continue; - if (predList[i] == NULL) continue; - - /* if the predicate depth turns out to be one token only */ - /* then it is can be easily represented as a set and */ - /* compared to the junction set create by MR_First() */ - - predDepth=0; - MR_pred_depth(predList[i],&predDepth); - require (predDepth >= 1,"MR_find_in_aSubBlk: pred depth < 1"); - require (predDepth <= CLL_k,"MR_find_in_aSubBlk: predDepth > CLL_k"); - - /* complete predicates to predDepth - If completed to depth=1 then the context would be incomplete. - The context would be truncated and the predicate simplify routine - would have incomplete information. It would lead to - either false matches of failure to find true matches. - */ - - MR_complete_predicates(predDepth,predList[i]); - - if (predList[i] != NULL) { - MR_cleanup_pred_trees(predList[i]); /* flatten & left factor */ - }; - - /* If the predicate depth is 1 then it is possible to suppress - a predicate completely using a single plain alt. Check for suppression - by a single plain alt first because it gives better messages. If that - fails try the union of all the plain alts. - */ - - if (predDepth == 1) { - - MR_set_reuse(&predSet); - predSet=MR_compute_pred_set(predList[i]); /* ignores k>1 predicates */ - - for (j=0; j < nAlts; j++) { - if (jList[j] == NULL) continue; - if (j == i) continue; - - MR_set_reuse(&setDif); - setDif=set_dif(predSet,plainContext[j]); - if (set_nil(setDif)) { - matchList[i] |= 1; - MR_reportSetSuppression(predDepth,predSet,plainContext[j],jList[i],jList[j],predList[i]); - predicate_free(predList[i]); - predList[i]=PRED_SUPPRESS; - goto next_i; - }; - - }; /* end loop on j */ - - changed=0; - - /* predicate_dup is only to give good error messages */ - /* remember to do a predicate_free() */ - - origPred=predicate_dup(predList[i]); - MR_apply_restriction1(predList[i],&union_plainSet,&changed); - if (changed) { - - /* don't use Pass3 by itself unless you know that inverted is not important */ - - newPred=MR_removeRedundantPredPass3(predList[i]); - newPred=MR_predSimplifyALL(newPred); - if (newPred == NULL) { - matchList[i] |= 1; - MR_reportSetSuppression(predDepth,predSet,union_plainSet,jList[i], - NULL,origPred); - predList[i]=PRED_SUPPRESS; - } else { - MR_reportSetRestriction(predDepth,predSet,union_plainSet,jList[i], - NULL,origPred,newPred); - predList[i]=newPred; - }; - }; - predicate_free(origPred); - origPred=NULL; - }; - - /* - If the predicate depth is > 1 then it can't be suppressed completely - because the code doesn't support inspection of such things. They're - much messier than k=1 sets. - */ - - if (predDepth > 1 ) { - - changed=0; - - /* predicate_dup is only to give good error messages */ - /* remember to do a predicate_free() */ - - origPred=predicate_dup(predList[i]); - MR_apply_restriction1(predList[i],&union_plainSet,&changed); - if (changed) { - newPred=MR_removeRedundantPredPass3(predList[i]); - newPred=MR_predSimplifyALL(newPred); - if (newPred == NULL) { - matchList[i] |= 1; - MR_reportSetSuppression(predDepth,predSet,union_plainSet,jList[i], - NULL,origPred); - predList[i]=PRED_SUPPRESS; - } else { - MR_reportSetRestriction(predDepth,predSet,union_plainSet,jList[i], - NULL,origPred,newPred); - predList[i]=newPred; - }; - }; - predicate_free(origPred); - origPred=NULL; - }; -next_i: - continue; - }; - -EXIT_SIMPLE: - - root = new_pred(); - root->expr=PRED_OR_LIST; - tail = &(root->down); - - for (i=0 ; i< nAlts ; i++) { - if (jList[i] == NULL) continue; - - if (predList[i] == NULL) { - continue; - } else if ( (matchList[i] & 1) != 0) { - if (predList[i] != PRED_SUPPRESS) { - predicate_free(predList[i]); - }; - continue; - }; - - /* make an OR list of predicates */ - - *tail=predList[i]; - tail=&(predList[i]->right); - }; - - /* if just one pred, remove OR root */ - - if (root->down == NULL) { - predicate_free(root); - root=NULL; - } else if (root->down->right == NULL) { - Predicate *p=root->down; - root->down=NULL; - predicate_free(root); - root=p; - } - - root=MR_predSimplifyALL(root); - - MR_orin_plainSet(root,union_plainSet); - - set_free(predSet); - set_free(union_plainSet); - set_free(incomplete); - set_free(setChange); - set_free(setDif); - - for (m=0; m < nAlts; m++) set_free(plainContext[m]); - - free ( (char *) jList); - free ( (char *) predList); - free ( (char *) matchList); - free ( (char *) plainContext); - - return root; -} - -#ifdef __USE_PROTOS -void MR_predContextPresent(Predicate *p,int *allHaveContext,int *noneHaveContext) -#else -void MR_predContextPresent(p,allHaveContext,noneHaveContext) - Predicate *p; - int *allHaveContext; - int *noneHaveContext; -#endif -{ - if (p == NULL) return; - MR_predContextPresent(p->right,allHaveContext,noneHaveContext); - if (p->expr != PRED_AND_LIST && - p->expr != PRED_OR_LIST) { - if (set_nil(p->scontext[1]) == 0 || - (p->tcontext != NULL)) { - *noneHaveContext=0; - } else { - *allHaveContext=0; - }; - }; - MR_predContextPresent(p->down,allHaveContext,noneHaveContext); -} - -#ifdef __USE_PROTOS -int MR_pointerStackPush(PointerStack *ps,void *dataPointer) -#else -int MR_pointerStackPush(ps,dataPointer) - PointerStack *ps; - void *dataPointer; -#endif -{ - void **newStack; - int newSize; - int i; - - if (ps->count == ps->size) { - newSize=20+ps->size*2; - newStack=(void **)calloc(newSize,sizeof(void *)); - require (newStack != NULL,"cannot allocate PointerStack"); - for (i=0; i < ps->size; i++) { - newStack[i]=ps->data[i]; - }; - if (ps->data != NULL) free( (char *) ps->data); - ps->data=newStack; - ps->size=newSize; - }; - ps->data[ps->count]=dataPointer; - ps->count++; - return ps->count-1; -} - -#ifdef __USE_PROTOS -void * MR_pointerStackPop(PointerStack *ps) -#else -void * MR_pointerStackPop(ps) - PointerStack *ps; -#endif -{ - void *dataPointer; - - require(ps->count > 0,"MR_pointerStackPop underflow"); - - dataPointer=ps->data[ps->count-1]; - ps->data[ps->count-1]=NULL; - (ps->count)--; - return dataPointer; -} - -#ifdef __USE_PROTOS -void * MR_pointerStackTop(PointerStack *ps) -#else -void * MR_pointerStackTop(ps) - PointerStack *ps; -#endif -{ - require(ps->count > 0,"MR_pointerStackTop underflow"); - return ps->data[ps->count-1]; -} - -#ifdef __USE_PROTOS -void MR_pointerStackReset(PointerStack *ps) -#else -void MR_pointerStackReset(ps) - PointerStack *ps; -#endif -{ - int i; - if (ps->data != NULL) { - for (i=0; i < ps->count ; i++) { - ps->data[i]=NULL; - }; - }; - ps->count=0; -} - -#ifdef __USE_PROTOS -Junction *MR_nameToRuleBlk(char *name) -#else -Junction *MR_nameToRuleBlk(name) - char *name; -#endif -{ - RuleEntry *q; - - require (RulePtr != NULL,"MR_nameToRule: RulePtr not initialized"); - - if (name == NULL) return NULL; - - q = (RuleEntry *) hash_get(Rname,name); - - if ( q == NULL ) { - return NULL; - } else { - return RulePtr[q->rulenum]; - }; -} - -#ifdef __USE_PROTOS -Junction * MR_ruleReferenced(RuleRefNode *rrn) -#else -Junction * MR_ruleReferenced(rrn) - RuleRefNode *rrn; -#endif -{ - return MR_nameToRuleBlk(rrn->text); -} - -#ifdef __USE_PROTOS -void MR_comparePredLeaves(Predicate *me,Predicate *myParent,Predicate *him,Predicate *hisParent) -#else -void MR_comparePredLeaves(me,myParent,him,hisParent) - Predicate *me; - Predicate *myParent; - Predicate *him; - Predicate *hisParent; -#endif -{ - if (me == NULL) return; - if (me == him) { - MR_comparePredLeaves(me->right,myParent,him,hisParent); - return; - } else if (me->expr == PRED_AND_LIST || - me->expr == PRED_OR_LIST) { - MR_comparePredLeaves(me->down,me,him,hisParent); - MR_comparePredLeaves(me->right,myParent,him,hisParent); - return; - } else { - if (me->source != NULL) { - - /* predicate->invert can be set only in the predEntry predicates */ - /* thus they are only visible after the predEntry predicates have been "unfolded" */ - - int sameSource=(me->source == him->source); - int sameInvert=1 & - (1 + me->inverted + him->inverted + me->source->inverted + him->source->inverted); - int samePredEntry=(me->source->predEntry != NULL - && him->source->predEntry != NULL - && me->source->predEntry == him->source->predEntry); - if (sameInvert && (sameSource || samePredEntry)) { - if (MR_identicalContext(me,him)) { - - /* identical predicates */ - - if (hisParent->expr == PRED_OR_LIST && - myParent->expr == PRED_OR_LIST) { - me->redundant=1; - } else if (hisParent->expr == PRED_AND_LIST && - myParent->expr == PRED_AND_LIST) { - me->redundant=1; - } else if ( (hisParent->expr == PRED_OR_LIST && - myParent->expr == PRED_AND_LIST) - || - (hisParent->expr == PRED_AND_LIST && - myParent->expr == PRED_OR_LIST) - ) { - myParent->redundant=1; - } else { - require (0,"MR_comparePredLeaves: not both PRED_LIST"); - }; - }; - }; /* end same source or same predEntrr with same invert sense */ - - /* same predEntry but opposite invert sense */ - - if (!sameInvert && (sameSource || samePredEntry)) { - if (MR_identicalContext(me,him)) { - if (hisParent->expr == PRED_OR_LIST && - myParent->expr == PRED_OR_LIST) { - myParent->isConst=1; - myParent->constValue=1; - } else if (hisParent->expr == PRED_AND_LIST && - myParent->expr == PRED_AND_LIST) { - myParent->isConst=1; - myParent->constValue=0; - } else if ( (hisParent->expr == PRED_OR_LIST && - myParent->expr == PRED_AND_LIST) - || - (hisParent->expr == PRED_AND_LIST && - myParent->expr == PRED_OR_LIST) - ) { - me->redundant=1; - } else { - require (0,"MR_comparePredLeaves: not both PRED_LIST"); - }; - }; - }; /* end same predEntry with opposite invert sense */ - }; - - MR_comparePredLeaves(me->right,myParent,him,hisParent); - return; - }; -} - -#ifdef __USE_PROTOS -void MR_removeRedundantPredPass1(Predicate *me,Predicate *myParent) -#else -void MR_removeRedundantPredPass1(me,myParent) - Predicate *me; - Predicate *myParent; -#endif -{ - if (me == NULL) return; - if (me->redundant) { - MR_removeRedundantPredPass1(me->right,myParent); - return; - }; - if (me->expr == PRED_AND_LIST || - me->expr == PRED_OR_LIST) { - MR_removeRedundantPredPass1(me->down,me); - MR_removeRedundantPredPass1(me->right,myParent); - } else { - require (me->source != NULL,"me->source == NULL"); - if (myParent != NULL) { - MR_comparePredLeaves(myParent->down,myParent,me,myParent); - }; - MR_removeRedundantPredPass1(me->right,myParent); - }; -} - -/* pretty much ignores things with the inverted bit set */ - -#ifdef __USE_PROTOS -Predicate *MR_predFlatten(Predicate *p) -#else -Predicate *MR_predFlatten(p) - Predicate *p; -#endif -{ - if (p == NULL) return NULL; - if (p->expr == PRED_OR_LIST - || p->expr == PRED_AND_LIST) { - - Predicate *child; - Predicate *gchild; - Predicate **tail; - Predicate *next; - char *PRED_XXX_LIST=p->expr; - - require (p->down != NULL,"MR_predFlatten AND/OR no child"); - - - p->down=MR_predFlatten(p->down); - p->right=MR_predFlatten(p->right); - child=p->down; - if (child->right == NULL) { - child->right=p->right; - p->right=NULL; - p->down=NULL; - if (p->inverted) child->inverted=!child->inverted; - predicate_free(p); - return child; - }; - - /* make a single list of all children and grandchildren */ - - tail=&(p->down); - for (child=p->down; child != NULL; child=next) { - if (child->expr != PRED_XXX_LIST - || child->inverted - || child->predEntry != NULL) { - *tail=child; - tail=&(child->right); - next=child->right; - } else { - for (gchild=child->down; - gchild != NULL; - gchild=gchild->right) { - *tail=gchild; - tail=&(gchild->right); - }; - next=child->right; - child->right=NULL; - child->down=NULL; - predicate_free(child); - }; - }; - *tail=NULL; - return p; - } else { - p->right=MR_predFlatten(p->right); - return p; - }; -} - -static char *alwaysFalseWarning=NULL; - -#ifdef __USE_PROTOS -Predicate *checkPredicateConflict(Predicate *p) -#else -Predicate *checkPredicateConflict(p) - Predicate *p; -#endif -{ - if (p->isConst) { - if (p->constValue == 1) { - predicate_free(p); - return NULL; - } else { - if (InfoP && !p->conflictReported) { - p->conflictReported=1; - fprintf(output,"\n#if 0\n\n"); - fprintf(output,"The following predicate expression will always be false:\n\n"); - MR_dumpPred1(1,p,1); - fprintf(output,"\n#endif\n"); - }; - - if (alwaysFalseWarning != CurRule) { - alwaysFalseWarning=CurRule; - if (InfoP) { - warnNoFL(eMsg1("one (or more) predicate expression hoisted into rule \"%s\" are always false \ -- see output file for more information",CurRule)); - } else { - warnNoFL(eMsg1("one (or more) predicate expressions hoisted into rule \"%s\" are always false \ -- use \"-info p\" for more information",CurRule)); - }; - }; - }; - }; - return p; -} - - -#ifdef __USE_PROTOS -int MR_countPredNodes(Predicate *p) -#else -int MR_countPredNodes(p) - Predicate *p; -#endif -{ - if (p == NULL) return 0; - return 1 + MR_countPredNodes(p->down) + MR_countPredNodes(p->right); -} - -#ifdef __USE_PROTOS -Predicate *MR_predSimplifyALLX(Predicate *p,int skipPass3) -#else -Predicate *MR_predSimplifyALLX(p,skipPass3) - Predicate *p; - int skipPass3; -#endif -{ - int countBefore; - int countAfter; - - countAfter=MR_countPredNodes(p); - - do { - if (p == NULL) return NULL; - if (p->right == NULL && p->down == NULL) return p; - countBefore=countAfter; - MR_simplifyInverted(p,0); - p=MR_predFlatten(p); - MR_removeRedundantPredPass1(p,NULL); - MR_removeRedundantPredPass2(p); - if (! skipPass3) { - p=checkPredicateConflict(p); - p=MR_removeRedundantPredPass3(p); - }; - countAfter=MR_countPredNodes(p); - } while (countBefore != countAfter); - - return p; -} - -#ifdef __USE_PROTOS -Predicate *MR_predSimplifyALL(Predicate *p) -#else -Predicate *MR_predSimplifyALL(p) - Predicate *p; -#endif -{ - return MR_predSimplifyALLX(p,0); -} - -#ifdef __USE_PROTOS -void MR_releaseResourcesUsedInRule(Node *n) -#else -void MR_releaseResourcesUsedInRule(n) - Node *n; -#endif -{ - Node *next; - Junction *j; - int i; - - if (n == NULL) return; - if (n->ntype == nJunction) { - j=(Junction *) n; - - if (j->predicate != NULL) { - predicate_free(j->predicate); - j->predicate=NULL; - }; - for (i=0; i< CLL_k; i++) { - set_free(j->fset[i]); - j->fset[i]=empty; - }; - if (j->ftree != NULL) { - Tfree(j->ftree); - j->ftree=NULL; - }; - if (j->jtype == EndRule) return; - if (j->jtype != RuleBlk && j->jtype != EndBlk) { - if (j->p2 != NULL && !j->ignore) { /* MR11 */ - MR_releaseResourcesUsedInRule(j->p2); - }; - }; - }; - next=MR_advance(n); - MR_releaseResourcesUsedInRule(next); -} - -#ifdef __USE_PROTOS -int MR_allPredLeaves(Predicate *p) -#else -int MR_allPredLeaves(p) - Predicate *p; -#endif -{ - Predicate *q; - - if (p == NULL) return 1; - - for (q=p; q != NULL; q=q->right) { - if (q->down != NULL) return 0; - }; - return 1; -} - -/* make sure it works for the last rule in a file */ - -#ifdef __USE_PROTOS -int MR_offsetFromRule(Node *n) -#else -int MR_offsetFromRule(n) - Node *n; -#endif -{ - Junction *j; - int offset=(-1); - - for (j=SynDiag; j != NULL; j=(Junction *)j->p2) { - - require (j->ntype == nJunction && j->jtype == RuleBlk,"Not a rule block"); - - if (n->file < j->file) { - return offset; - }; - if (n->file == j->file) { - if (n->line < j->line) { - return (offset < 0) ? 0 : offset; - } else { - offset=n->line - j->line; - if (offset == 0) return 0; - }; - }; - }; - return offset; -} - -#define ruleNameMax 50 - -static char ruleNameStatic1[ruleNameMax]; -static char ruleNameStatic2[ruleNameMax+10]; - -#ifdef __USE_PROTOS -char * MR_ruleNamePlusOffset(Node *n) -#else -char * MR_ruleNamePlusOffset(n) - Node *n; -#endif -{ - int offset=MR_offsetFromRule(n); - - strncpy(ruleNameStatic1,n->rname,ruleNameMax); - if (offset < 0) { - sprintf(ruleNameStatic2,"%s/?",ruleNameStatic1); - } else { - sprintf(ruleNameStatic2,"%s/%d",ruleNameStatic1,offset+1); - }; - return ruleNameStatic2; -} - -#ifdef __USE_PROTOS -int MR_max_height_of_tree(Tree *t) -#else -int MR_max_height_of_tree(t) - Tree *t; -#endif -{ - int h; - int height=0; - Tree *u; - - if (t == NULL) return 0; - - require (t->token != ALT && t->token != EpToken,"MR_max_height_of_tree ALT or EpToken"); - - for (u=t; u != NULL; u=u->right) { - h=MR_max_height_of_tree(u->down)+1; - if (h > height) height=h; - }; - return height; -} - -#ifdef __USE_PROTOS -int MR_all_leaves_same_height(Tree *t,int depth) -#else -int MR_all_leaves_same_height(t,depth) - Tree *t; - int depth; -#endif -{ - if (t == NULL) { - return (depth==0); - }; - - require (t->token != ALT && t->token != EpToken,"MR_all_leaves_same_height ALT or EpToken"); - - if (depth == 0) { - return 0; - } else { - if ( ! MR_all_leaves_same_height(t->down,depth-1)) { - return 0; - }; - if (t->right == NULL) { - return 1; - } else { - return MR_all_leaves_same_height(t->right,depth); - }; - }; -} - -#ifdef __USE_PROTOS -void MR_projectTreeOntoSet(Tree *tree,int ck,set *ckset) -#else -void MR_projectTreeOntoSet(tree,ck,ckset) - Tree *tree; - int ck; - set *ckset; -#endif -{ - if (tree == NULL) return; - - require(tree->token != EpToken,"MR_projectTreeOntoSet: EpToken unexpected\n"); - - MR_projectTreeOntoSet(tree->right,ck,ckset); - if (tree->token == ALT) { - MR_projectTreeOntoSet(tree->down,ck,ckset); - } else { - if (ck > 1) { - MR_projectTreeOntoSet(tree->down,ck-1,ckset); - } else { - set_orel(tree->token,ckset); - }; - }; -} - -#ifdef __USE_PROTOS -int MR_comparePredicates(Predicate *a,Predicate *b) -#else -int MR_comparePredicates(a,b) - Predicate *a; - Predicate *b; -#endif -{ - Predicate *p; - Predicate *q; - - if (a == b) return 1; - if (a == NULL || b == NULL ) return 0; - if (a->down == NULL && b->down == NULL) { - - /* predicate->invert can be set only in the predEntry predicates */ - /* thus they are only visible after the predEntry predicates have been "unfolded" */ - - int sameSource=(a->source == b->source); - int sameInvert= 1 & (1 +a->inverted + b->inverted + - a->source->inverted + b->source->inverted); - int samePredEntry=(a->source->predEntry != NULL - && b->source->predEntry != NULL - && a->source->predEntry == b->source->predEntry); - if (sameInvert && (sameSource || samePredEntry)) { - if (MR_identicalContext(a,b)) { - return 1; - }; - }; - return 0; - }; - if (a->down == NULL || b->down == NULL) return 0; - if (a->expr != b->expr) return 0; - - for (p=a->down; p != NULL; p=p->right) { - for (q=b->down; q != NULL; q=q->right) { - if (MR_comparePredicates(p,q)) goto NEXT_P; - }; - return 0; -NEXT_P: - continue; - }; - return 1; -} - -/* - * action->inverted can be set only when a predicate symbol appears in - * a rule: "rule : <>? X". It cannot be set under any - * other circumstances. In particular it cannot be set by - * "#pred NotA !A" or by "#pred Nota <>?". The first case - * creates a predEntry and the predicate expression of that predEntry - * has inverted set. In the second case, the code for handling "!" - * is only present in buildAction, which is not called by the #pred - * semantic routines, only when a <<...>>? is recognized as part of - * a rule definition. - * - * predicate->inverted can only be set by a predicate created by a #pred - * expression, such as "#pred NotA !A" or "#pred NotXY ! (X && Y) or - * "#pred XbarY !(X && Y)". In particular, it cannot be set by any - * predicate expression occurring under any other circumstances. - * The #pred predicate expresssions are stored with in predEntry->pred - * and do not normally appear anywhere else until the predicates are - * "unfolded" in order to recognize redundancies, conflicts, and - * tautologies. - * - * The unfold routine expands all references to #pred expressions. - * - * The simplifyInvert goes through and propagates the invert bit so that - * all OR and AND nodes are un-inverted. - * - * Note that !(A and B) => (!A or !B) - * !(A or B) => (!A and !B) - * - * MR_unfold() is called to expand predicate symbols by replacing predicates - * that reference predicate entries with the copies of the predicate entries. - * Each reference receives a duplicate of the original. This is necessary - * because the next phase involves simplification and removal of redundant - * predicate nodes. Anyway, the point I'm making is that predicate->invert - * should not be set in any predicate until it has been expanded. - * - * This is a recursive structure, but there is no need for "recursive expansion" - * by which I mean a predicate symbol refers to other predicate symbols which - * must also be expanded. - * - * Recursive expansion is *not* performed by this routine because it is not - * necessary. Expansion of references is performed by predPrimary when - * a new predicate symbol is created by referring to others in the pred expr. - */ - -#ifdef __USE_PROTOS -Predicate *MR_unfold(Predicate *pred) -#else -Predicate *MR_unfold(pred) - Predicate *pred; -#endif -{ - Predicate *result; - - if (pred == NULL) return NULL; - - pred->right=MR_unfold(pred->right); - - if (pred->down == NULL) { - if (pred->source->predEntry != NULL) { - if (pred->source->predEntry->pred == NULL) { - ; /* do nothing */ /* a reference to a literal #pred (perhaps with "!" */ - } else { - result=predicate_dup_without_context(pred->source->predEntry->pred); - if (pred->inverted) { - result->inverted=!result->inverted; - }; - if (pred->source->inverted) { - result->inverted=!result->inverted; - }; - result->right=pred->right; - pred->right=NULL; - predicate_free(pred); -/*** result=MR_unfold(result); *** not necessary */ /* recursive expansion */ - return result; - }; - } else { - ; /* do nothing */ /* an inline literal predicate */ - }; - } else { - pred->down=MR_unfold(pred->down); - }; - return pred; -} - -/* this should be called immediately after MR_unfold() and - at no other times -*/ - -#ifdef __USE_PROTOS -void MR_simplifyInverted(Predicate *pred,int inverted) -#else -void MR_simplifyInverted(pred,inverted) - Predicate *pred; - int inverted; -#endif -{ - int newInverted; - - if (pred == NULL) return; - - MR_simplifyInverted(pred->right,inverted); - - newInverted= 1 & (inverted + pred->inverted); - - if (pred->down == NULL) { - pred->inverted=newInverted; - } else { - if (newInverted != 0) { - if (pred->expr == PRED_AND_LIST) { - pred->expr=PRED_OR_LIST; - } else { - pred->expr=PRED_AND_LIST; - }; - }; - pred->inverted=0; - MR_simplifyInverted(pred->down,newInverted); - }; -} - -/* only remove it from AND and OR nodes, not leaves */ - -#ifdef __USE_PROTOS -void MR_clearPredEntry(Predicate *p) -#else -void MR_clearPredEntry(p) - Predicate *p; -#endif -{ - if (p == NULL) return; - MR_clearPredEntry(p->down); - MR_clearPredEntry(p->right); - if (p->down != NULL) p->predEntry=NULL; -} - - -#ifdef __USE_PROTOS -void MR_orphanRules(FILE *f) -#else -void MR_orphanRules(f) - FILE *f; -#endif -{ - set a; - Junction *p; - unsigned e; - RuleEntry *re; - - a=empty; - - if (! InfoO) return; - - for (p=SynDiag; p!=NULL; p = (Junction *)p->p2) { - if ( (Junction *) (p->end)->p1 == NULL) { - re=(RuleEntry *) hash_get(Rname,p->rname); - require (re != NULL,"RuleEntry == NULL"); - set_orel(re->rulenum, &a); - } - } - - if (set_deg(a) > 1) { - fprintf(f,"note: Start rules: {"); - for (; !set_nil(a); set_rm(e,a)) { - e=set_int(a); - fprintf(f," %s",RulePtr[e]->rname); - }; - fprintf(f," }\n"); - }; - set_free( a ); -} - -/* merge (X Y) and (X) to create (X) */ - -static int *mergeChain; -static Tree *mergeTree; - -#ifdef __USE_PROTOS -Tree *MR_merge_tree_contexts_client(Tree *t,int chain[]) -#else -Tree *MR_merge_tree_contexts_client(t,chain) - Tree *t; - int chain[]; -#endif -{ - if (t == NULL) return NULL; - if (chain[0] == 0) { - Tree *u=t->right; - t->right=NULL; - Tfree(t); - return MR_merge_tree_contexts_client(u,&chain[0]); - } - if (chain[0] == t->token) { - t->down=MR_merge_tree_contexts_client(t->down,&chain[1]); - }; - t->right=MR_merge_tree_contexts_client(t->right,&chain[0]); - return t; -} - -#ifdef __USE_PROTOS -void MR_iterateOverTreeContexts(Tree *t,int chain[]) -#else -void MR_iterateOverTreeContexts(t,chain) - Tree *t; - int chain[]; -#endif -{ - if (t == NULL) return; - chain[0]=t->token; - if (t->down != NULL) { - MR_iterateOverTreeContexts(t->down,&chain[1]); - } else { - MR_merge_tree_contexts_client(mergeTree,mergeChain); - }; - MR_iterateOverTreeContexts(t->right,&chain[0]); - chain[0]=0; -} - -#ifdef __USE_PROTOS -Tree *MR_merge_tree_contexts(Tree *t) -#else -Tree *MR_merge_tree_contexts(t) - Tree *t; -#endif -{ - int h=MR_max_height_of_tree(t); - - mergeTree=t; - mergeChain=(int *) calloc(h+1,sizeof(int)); - require (mergeChain != NULL,"MR_merge_tree_contexts: can't alloc chain"); - MR_iterateOverTreeContexts(t,mergeChain); - t=tshrink(t); - t=tflatten(t); - t=tleft_factor(t); - free ( (char *) mergeChain); - mergeChain=NULL; - return t; -} - -#ifdef __USE_PROTOS -Tree *MR_compute_pred_tree_context(Predicate *p) -#else -Tree *MR_compute_pred_tree_context(p) - Predicate *p; -#endif -{ - Tree *t; - - t=MR_compute_pred_tree_ctxXX(p); - MR_merge_tree_contexts(t); - return t; -} - -#ifdef __USE_PROTOS -void MR_guardPred_plainSet(ActionNode *anode,Predicate *pred) -#else -void MR_guardPred_plainSet(anode,pred) - ActionNode *anode; - Predicate *pred; -#endif -{ - Junction *j; - Predicate *workPred; - set maskSet; - - maskSet=empty; - - if (!MRhoisting) return; - - /* it doesn't really matter whether the predicate has - depth k=1 or k>1 because we're not really looking - at the predicate itself, just the stuff "behind" - the predicate. - */ - - /* shouldn't have to worry about REACHing off the end - of the rule containing the predicate because the - Rule->end->halt should have been set already by the - the code which handles RuleRef nodes. - - We don't want to REACH off the end of the rule because - this would give the "global" follow context rather than - the "local" context. - - r1a : (A)? => <

>? r2 (A|B) - r1b : (A)? => <

>? r2 (A|C) - r2 : (); - - For r1a we want follow of predicate = {A B} - we want plainSet = {B} - For r1b we want follow of predicate = {A C} - we want plainSet = {C} - */ - - require (anode->next->ntype == nJunction,"MR_guardpred_plainSet not Junction"); - j=(Junction *)(anode->next); - - workPred=predicate_dup_without_context(pred); - workPred->k=1; - workPred->scontext[1]=MR_First(1,j, &(workPred->completionSet) ); - MR_complete_predicates(1,workPred); - if (pred->k == 1) { - maskSet=pred->scontext[1]; - } else { - MR_projectTreeOntoSet(pred->tcontext,1,&maskSet); - } - pred->plainSet=set_dif(workPred->scontext[1],maskSet); - predicate_free(workPred); -} - -/*******************************************************************************/ - -static Tree * suppressTree; -static int * suppressChain; /* element 0 not used */ -static set * suppressSets; -static Node * suppressNode; -static int suppressChainLength; -int MR_SuppressSearch=0; -static int suppressSucceeded; -static Predicate * suppressPredicate; - -#ifdef __USE_PROTOS -int MR_isChain(Tree *t) -#else -int MR_isChain(t) - Tree *t; -#endif -{ - Tree *u; - - for (u=t; u != NULL; u=u->down) { - if (u->right != NULL) return 0; - } - return 1; -} - -#ifdef __USE_PROTOS -int MR_suppressK_client(Tree *tree,int tokensInChain[]) -#else -int MR_suppressK_client(tree,tokensInChain) - Tree *tree; - int tokensInChain[]; -#endif -{ - int i; - set *save_fset; - int save_ConstrainSearch; - set incomplete; - Tree *t; - - suppressSucceeded=0; /* volatile */ - - if (suppressSets == NULL) { - suppressSets=(set *) calloc (CLL_k+1,sizeof(set)); - require (suppressSets != NULL,"MR_suppressK_client: suppressSets alloc"); - }; - - for (suppressChainLength=1; - tokensInChain[suppressChainLength+1] != 0; - suppressChainLength++) {}; - - require (suppressChainLength != 0,"MR_suppressK_client: chain empty"); - - for (i=1 ; i <= suppressChainLength ; i++) { - set_clr(suppressSets[i]); - set_orel( (unsigned) tokensInChain[i], - &suppressSets[i]); - }; - - save_fset=fset; - save_ConstrainSearch=ConstrainSearch; - - fset=suppressSets; - - MR_SuppressSearch=1; - MR_AmbSourceSearch=1; - MR_MaintainBackTrace=1; - ConstrainSearch=1; - - maxk = suppressChainLength; - - incomplete=empty; - t=NULL; - -/*** constrain = &(fset[1]); ***/ - - MR_setConstrainPointer(&(fset[1])); /* MR18 */ - - MR_pointerStackReset(&MR_BackTraceStack); - - TRAV(suppressNode,maxk,&incomplete,t); - - Tfree(t); - - require (set_nil(incomplete),"MR_suppressK_client TRAV incomplete"); - require (MR_BackTraceStack.count == 0, - "MR_suppressK_client: MR_BackTraceStack.count != 0"); - set_free(incomplete); - - ConstrainSearch=save_ConstrainSearch; - fset=save_fset; - - MR_AmbSourceSearch=0; - MR_MaintainBackTrace=0; - MR_SuppressSearch=0; - return suppressSucceeded; -} - -#ifdef __USE_PROTOS -Tree * MR_iterateOverTreeSuppressK(Tree *t,int chain[]) -#else -Tree * MR_iterateOverTreeSuppressK(t,chain) - Tree *t; - int chain[]; -#endif -{ - if (t == NULL) return NULL; - t->right=MR_iterateOverTreeSuppressK(t->right,&chain[0]); - chain[0]=t->token; - if (t->down != NULL) { - t->down=MR_iterateOverTreeSuppressK(t->down,&chain[1]); - if (t->down == NULL) { - Tree *u=t->right; - t->right=NULL; - Tfree(t); - chain[0]=0; - return u; - }; - } else { - MR_suppressK_client(suppressTree,suppressChain); - if (suppressSucceeded) { - Tree *u=t->right; - t->right=NULL; - Tfree(t); - chain[0]=0; - return u; - }; - }; - chain[0]=0; - return t; -} - -/* @@@ */ - -#ifdef __USE_PROTOS -Predicate * MR_suppressK(Node *j,Predicate *p) -#else -Predicate * MR_suppressK(j,p) - Node *j; - Predicate *p; -#endif -{ - Predicate *result; - int guardPred=0; - int ampersandPred=0; - Node *nodePrime; - - if (! MRhoistingk) { - return p; - } - - if (! MRhoisting) return p; - if (CLL_k == 1) return p; - - if (suppressChain == NULL) { - suppressChain=(int *) calloc(CLL_k+2,sizeof(int)); - require (suppressChain != NULL,"MR_suppressK: can't allocate chain"); - } - - if (p == NULL) return NULL; - - if (j->ntype == nJunction) { - nodePrime=(Node *) MR_junctionWithoutP2( (Junction *) j); - } else { - nodePrime=j; - }; - - p->down=MR_suppressK(j,p->down); - p->right=MR_suppressK(j,p->right); - if (p->down != NULL) { - result=p; - goto EXIT; - }; - if (p->k == 1) { - result=p; - goto EXIT; - }; - - if (p->source != NULL) { - if (p->source->guardpred != NULL) guardPred=1; - if (p->source->ampersandPred != NULL) ampersandPred=1; - } - - suppressPredicate=p; - suppressNode=nodePrime; /* was j*/ - - suppressTree=p->tcontext; - - if (guardPred || ampersandPred) { - p->tcontext=MR_iterateOverTreeSuppressK(suppressTree,&suppressChain[1]); - if (p->tcontext == NULL) { - predicate_free(p); - result=NULL; - goto EXIT; - }; - } else { - if (MR_isChain(p->tcontext)) { - p->tcontext=MR_iterateOverTreeSuppressK(suppressTree,&suppressChain[1]); - if (p->tcontext == NULL) { - predicate_free(p); - result=NULL; - goto EXIT; - }; - } - } - result=p; -EXIT: - return result; -} - -#ifdef __USE_PROTOS -void MR_suppressSearchReport(void) -#else -void MR_suppressSearchReport() -#endif -{ - int i; - Node *p; - TokNode *tn; - int depth; - set setAnd; - - /* number of tokens in back trace stack matches length of chain */ - - depth=0; - for (i=0; i < MR_BackTraceStack.count ; i++) { - p=(Node *) MR_BackTraceStack.data[i]; - if (p->ntype == nToken) depth++; - }; - - require (depth == suppressChainLength,"depth > suppressChainLength"); - - /* token codes match chain */ - - depth=0; - for (i=0; i < MR_BackTraceStack.count ; i++) { - p=(Node *) MR_BackTraceStack.data[i]; - if (p->ntype != nToken) continue; - tn=(TokNode *) p; - depth++; - if (set_nil(tn->tset)) { - require(set_el( (unsigned) tn->token,fset[depth]), - "MR_suppressSearchReport: no match to #token in chain"); - } else { - setAnd=set_and(fset[depth],tn->tset); - require(!set_nil(setAnd), - "MR_suppressSearchReport: no match to #token set in chain"); - set_free(setAnd); - }; - }; - - /* have a match - now remove it from the predicate */ - - suppressSucceeded=1; - - if (suppressSucceeded) { - fprintf(output,"\n"); - fprintf(output,"#if 0\n"); - fprintf(output,"\n"); - fprintf(output,"Part (or all) of predicate with depth > 1 suppressed by "); - fprintf(output,"alternative without predicate\n\n"); - MR_dumpPred(suppressPredicate,1); - fprintf(output,"The token sequence which is suppressed:"); - fprintf(output," ("); - for (i=1; i <= suppressChainLength; i++) { - fprintf(output," %s",TerminalString(suppressChain[i])); - }; - fprintf(output," )\n"); - fprintf(output,"The sequence of references which generate that sequence of tokens:\n\n"); - - MR_backTraceDumpItemReset(); - - for (i=0; i < MR_BackTraceStack.count ; i++) { - MR_backTraceDumpItem(output,0,(Node *) MR_BackTraceStack.data[i]); - }; - fprintf(output,"\n"); - fprintf(output,"#endif\n"); - } -} - -#ifdef __USE_PROTOS -void MR_markCompromisedRule(Node *n) -#else -void MR_markCompromisedRule(n) - Node *n; -#endif -{ - RuleEntry *q; - Node *mark=NULL; - Junction *j; - - if (n->ntype == nRuleRef) { - mark=(Node *) MR_ruleReferenced( (RuleRefNode *) n); - } else if (n->ntype == nToken) { - mark=n; - } else if (n->ntype == nJunction) { - j=(Junction *)n; - switch (j->jtype) { - case aOptBlk: - case aLoopBlk: - case RuleBlk: - case EndRule: - case aPlusBlk: - case aLoopBegin: - mark=n; - break; - default: - break; - }; - } - - if (mark == NULL) return; - - require (RulePtr != NULL,"RulePtr not initialized"); - - q = (RuleEntry *) hash_get(Rname,mark->rname); - require (q != NULL,"RuleEntry not found"); - set_orel(q->rulenum,&MR_CompromisedRules); -} - -#ifdef __USE_PROTOS -void MR_alphaBetaTraceReport(void) -#else -void MR_alphaBetaTraceReport() -#endif -{ - int i; - - if (! AlphaBetaTrace) return; - - MR_AlphaBetaMessageCount++; - - fprintf(output,"\n"); - fprintf(output,"#if 0\n"); - fprintf(output,"\n"); - fprintf(output,"Trace of references leading to attempt to compute the follow set of\n"); - fprintf(output,"alpha in an \"(alpha)? beta\" block. It is not possible for antlr to\n"); - fprintf(output,"compute this follow set because it is not known what part of beta has\n"); - fprintf(output,"already been matched by alpha and what part remains to be matched.\n"); - fprintf(output,"\n"); - fprintf(output,"Rules which make use of the incorrect follow set will also be incorrect\n"); - fprintf(output,"\n"); - - MR_backTraceDumpItemReset(); - - for (i=0; i < MR_BackTraceStack.count ; i++) { - MR_backTraceDumpItem(output,0,(Node *) MR_BackTraceStack.data[i]); - if (i < MR_BackTraceStack.count-1) { - MR_markCompromisedRule( (Node *) MR_BackTraceStack.data[i]); - }; - }; - fprintf(output,"\n"); - fprintf(output,"#endif\n"); -} - -#ifdef __USE_PROTOS -void MR_dumpRuleSet(set s) -#else -void MR_dumpRuleSet(s) - set s; -#endif -{ - unsigned *cursor; - unsigned *origin=set_pdq(s); - - require(origin != NULL,"set_pdq failed"); - - if (RulePtr == NULL) { - fprintf(stderr,"RulePtr[] not yet initialized"); - } else { - for (cursor=origin; *cursor != nil ; cursor++) { -/**** if (cursor != origin) fprintf(stderr,","); ****/ - fprintf(stderr," %s",RulePtr[*cursor]->rname); - fprintf(stderr,"\n"); - }; - free( (char *) origin); - }; -} diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/parser.dlg b/Tools/CodeTools/TianoTools/Pccts/antlr/parser.dlg deleted file mode 100644 index 8c43dff300..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/parser.dlg +++ /dev/null @@ -1,1387 +0,0 @@ -<< -/* parser.dlg -- DLG Description of scanner - * - * Generated from: antlr.g - * - * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001 - * Purdue University Electrical Engineering - * With AHPCRC, University of Minnesota - * ANTLR Version 1.33MR33 - */ - -#define ANTLR_VERSION 13333 -#include "pcctscfg.h" -#include "pccts_stdio.h" - -#include "pcctscfg.h" -#include "set.h" -#include -#include "syn.h" -#include "hash.h" -#include "generic.h" -#define zzcr_attr(attr,tok,t) -#include "antlr.h" -#include "tokens.h" -#include "dlgdef.h" -LOOKAHEAD - -void -#ifdef __USE_PROTOS -zzerraction(void) -#else -zzerraction() -#endif -{ - (*zzerr)("invalid token"); - zzadvance(); - zzskip(); -} ->> - -<<%%lexaction - -/* maintained, but not used for now */ -set AST_nodes_refd_in_actions = set_init; -int inAlt = 0; -set attribsRefdFromAction = set_init; /* MR20 */ -int UsedOldStyleAttrib = 0; -int UsedNewStyleLabel = 0; -#ifdef __USE_PROTOS -char *inline_set(char *); -#else -char *inline_set(); -#endif - -/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */ -/* MR1 in DLG action */ - -int tokenActionActive=0; /* MR1 */ - - ->> - -<<%%lexaction - - -static char * -#ifdef __USE_PROTOS -getFileNameFromTheLineInfo(char *toStr, char *fromStr) -#else -getFileNameFromTheLineInfo(toStr, fromStr) -char *toStr, *fromStr; -#endif -{ - int i, j, k; - - if (!fromStr || !toStr) return toStr; - - /* find the first " */ - - for (i=0; - (i> - -<<%%lexaction - -#ifdef __USE_PROTOS -void mark_label_used_in_sem_pred(LabelEntry *le) /* MR10 */ -#else -void mark_label_used_in_sem_pred(le) /* MR10 */ -LabelEntry *le; -#endif -{ - TokNode *tn; - require (le->elem->ntype == nToken,"mark_label_used... ntype != nToken"); - tn=(TokNode *)le->elem; - require (tn->label != 0,"mark_label_used... TokNode has no label"); - tn->label_used_in_semantic_pred=1; -} ->> - - -%%START - -@ - << - NLA = Eof; - /* L o o k F o r A n o t h e r F i l e */ - { - FILE *new_input; - new_input = NextFile(); - if ( new_input == NULL ) { NLA=Eof; return; } - fclose( input ); - input = new_input; - zzrdstream( input ); - zzskip(); /* Skip the Eof (@) char i.e continue */ - } - >> - -[\t\ ]+ - << - NLA = 76; - zzskip(); - >> - -\n|\r|\r\n - << - NLA = 77; - zzline++; zzskip(); - >> - -\[ - << - NLA = 78; - zzmode(ACTIONS); zzmore(); - istackreset(); - pushint(']'); - >> - -\<\< - << - NLA = 79; - action_file=CurFile; action_line=zzline; - zzmode(ACTIONS); zzmore(); - list_free(&CurActionLabels,0); /* MR10 */ - numericActionLabel=0; /* MR10 */ - istackreset(); - pushint('>'); - >> - -\" - << - NLA = 80; - zzmode(STRINGS); zzmore(); - >> - -/\* - << - NLA = 81; - zzmode(COMMENTS); zzskip(); - >> - -\*/ - << - NLA = 82; - warn("Missing /*; found dangling */"); zzskip(); - >> - -// - << - NLA = 83; - zzmode(CPP_COMMENTS); zzskip(); - >> - -#line[\ \t]* [0-9]+ {[\ \t]* \"~[\"]+\" ([\ \t]* [0-9]*)* } (\n|\r|\r\n) - << - NLA = 84; - - zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore(); - getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr); - >> - -#line ~[\n\r]* (\n|\r|\r\n) - << - NLA = 85; - - zzline++; zzmore(); - >> - -\>\> - << - NLA = 86; - warn("Missing <<; found dangling \>\>"); zzskip(); - >> - -. - << - NLA = WildCard; - >> - -\@ - << - NLA = 88; - FoundException = 1; /* MR6 */ - FoundAtOperator = 1; - >> - -{\\}#pragma - << - NLA = Pragma; - >> - -{\\}#FirstSetSymbol - << - NLA = FirstSetSymbol; - >> - -{\\}#header - << - NLA = 94; - >> - -{\\}#first - << - NLA = 95; - >> - -{\\}#parser - << - NLA = 96; - >> - -{\\}#tokdefs - << - NLA = 97; - >> - -\} - << - NLA = 98; - >> - -class - << - NLA = 99; - >> - -\{ - << - NLA = 102; - >> - -! - << - NLA = 103; - >> - -\< - << - NLA = 104; - >> - -\> - << - NLA = 105; - >> - -: - << - NLA = 106; - >> - -; - << - NLA = 107; - >> - -{\\}#lexaction - << - NLA = 108; - >> - -{\\}#lexmember - << - NLA = 109; - >> - -{\\}#lexprefix - << - NLA = 110; - >> - -{\\}#pred - << - NLA = 111; - >> - -\|\| - << - NLA = 112; - >> - -&& - << - NLA = 113; - >> - -\( - << - NLA = 114; - >> - -\) - << - NLA = 115; - >> - -{\\}#lexclass - << - NLA = 116; - >> - -{\\}#errclass - << - NLA = 117; - >> - -{\\}#tokclass - << - NLA = 118; - >> - -.. - << - NLA = 119; - >> - -{\\}#token - << - NLA = 120; - >> - -= - << - NLA = 121; - >> - -[0-9]+ - << - NLA = 122; - >> - -\| - << - NLA = 123; - >> - -\~ - << - NLA = 124; - >> - -^ - << - NLA = 125; - >> - -approx - << - NLA = 126; - >> - -LL\(1\) - << - NLA = 127; - >> - -LL\(2\) - << - NLA = 128; - >> - -\* - << - NLA = 129; - >> - -\+ - << - NLA = 130; - >> - -? - << - NLA = 131; - >> - -=> - << - NLA = 132; - >> - -exception - << - NLA = 133; - >> - -default - << - NLA = 134; - >> - -catch - << - NLA = 135; - >> - -[a-z] [A-Za-z0-9_]* - << - NLA = NonTerminal; - - while ( zzchar==' ' || zzchar=='\t' ) { - zzadvance(); - } - if ( zzchar == ':' && inAlt ) NLA = LABEL; - >> - -[A-Z] [A-Za-z0-9_]* - << - NLA = TokenTerm; - - while ( zzchar==' ' || zzchar=='\t' ) { - zzadvance(); - } - if ( zzchar == ':' && inAlt ) NLA = LABEL; - >> - -{\\}#[A-Za-z0-9_]* - << - NLA = 136; - warn(eMsg1("unknown meta-op: %s",LATEXT(1))); zzskip(); - >> - - -%%STRINGS - -@ - << - NLA = Eof; - >> - -\" - << - NLA = QuotedTerm; - zzmode(START); - >> - -\n|\r|\r\n - << - NLA = 3; - - zzline++; - warn("eoln found in string"); - zzskip(); - >> - -\\(\n|\r|\r\n) - << - NLA = 4; - zzline++; zzmore(); - >> - -\\~[] - << - NLA = 5; - zzmore(); - >> - -~[\n\r\"\\]+ - << - NLA = 6; - zzmore(); - >> - - -%%ACTION_STRINGS - -@ - << - NLA = Eof; - >> - -\" - << - NLA = 7; - zzmode(ACTIONS); zzmore(); - >> - -\n|\r|\r\n - << - NLA = 8; - - zzline++; - warn("eoln found in string (in user action)"); - zzskip(); - >> - -\\(\n|\r|\r\n) - << - NLA = 9; - zzline++; zzmore(); - >> - -\\~[] - << - NLA = 10; - zzmore(); - >> - -~[\n\r\"\\]+ - << - NLA = 11; - zzmore(); - >> - - -%%ACTION_CHARS - -@ - << - NLA = Eof; - >> - -' - << - NLA = 12; - zzmode(ACTIONS); zzmore(); - >> - -\n|\r|\r\n - << - NLA = 13; - - zzline++; - warn("eoln found in char literal (in user action)"); - zzskip(); - >> - -\\~[] - << - NLA = 14; - zzmore(); - >> - -~[\n\r'\\]+ - << - NLA = 15; - zzmore(); - >> - - -%%ACTION_COMMENTS - -@ - << - NLA = Eof; - >> - -\*/ - << - NLA = 16; - zzmode(ACTIONS); zzmore(); - >> - -\* - << - NLA = 17; - zzmore(); - >> - -\n|\r|\r\n - << - NLA = 18; - zzline++; zzmore(); DAWDLE; - >> - -~[\n\r\*]+ - << - NLA = 19; - zzmore(); - >> - - -%%TOK_DEF_COMMENTS - -@ - << - NLA = Eof; - >> - -\*/ - << - NLA = 20; - zzmode(PARSE_ENUM_FILE); - zzmore(); - >> - -\* - << - NLA = 21; - zzmore(); - >> - -\n|\r|\r\n - << - NLA = 22; - zzline++; zzmore(); DAWDLE; - >> - -~[\n\r\*]+ - << - NLA = 23; - zzmore(); - >> - - -%%TOK_DEF_CPP_COMMENTS - -@ - << - NLA = Eof; - >> - -\n|\r|\r\n - << - NLA = 24; - zzline++; zzmode(PARSE_ENUM_FILE); zzskip(); DAWDLE; - >> - -~[\n\r]+ - << - NLA = 25; - zzskip(); - >> - - -%%ACTION_CPP_COMMENTS - -@ - << - NLA = Eof; - >> - -\n|\r|\r\n - << - NLA = 26; - zzline++; zzmode(ACTIONS); zzmore(); DAWDLE; - >> - -~[\n\r]+ - << - NLA = 27; - zzmore(); - >> - - -%%CPP_COMMENTS - -@ - << - NLA = Eof; - >> - -\n|\r|\r\n - << - NLA = 28; - zzline++; zzmode(START); zzskip(); DAWDLE; - >> - -~[\n\r]+ - << - NLA = 29; - zzskip(); - >> - - -%%COMMENTS - -@ - << - NLA = Eof; - >> - -\*/ - << - NLA = 30; - zzmode(START); zzskip(); - >> - -\* - << - NLA = 31; - zzskip(); - >> - -\n|\r|\r\n - << - NLA = 32; - zzline++; zzskip(); DAWDLE; - >> - -~[\n\r\*]+ - << - NLA = 33; - zzskip(); - >> - - -%%ACTIONS - -@ - << - NLA = Eof; - >> - -\>\> - << - NLA = Action; - /* these do not nest */ - zzmode(START); - NLATEXT[0] = ' '; - NLATEXT[1] = ' '; - zzbegexpr[0] = ' '; - zzbegexpr[1] = ' '; - if ( zzbufovf ) { - err( eMsgd("action buffer overflow; size %d",ZZLEXBUFSIZE)); - } - -/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */ - /* MR1 in DLG action */ - /* MR1 Doesn't matter what kind of action it is - reset*/ - - tokenActionActive=0; /* MR1 */ - >> - -\>\>? - << - NLA = Pred; - /* these do not nest */ - zzmode(START); - NLATEXT[0] = ' '; - NLATEXT[1] = ' '; - zzbegexpr[0] = '\0'; - if ( zzbufovf ) { - err( eMsgd("predicate buffer overflow; size %d",ZZLEXBUFSIZE)); - }; -#ifdef __cplusplus__ - /* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); -#else -#ifdef __STDC__ - /* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); -#else -#ifdef __USE_PROTOS - /* MRxx */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); -#else - /* MR10 */ list_apply(CurActionLabels,mark_label_used_in_sem_pred); -#endif -#endif -#endif - >> - -\] - << - NLA = PassAction; - if ( topint() == ']' ) { - popint(); - if ( istackempty() ) /* terminate action */ - { - zzmode(START); - NLATEXT[0] = ' '; - zzbegexpr[0] = ' '; - if ( zzbufovf ) { - err( eMsgd("parameter buffer overflow; size %d",ZZLEXBUFSIZE)); - } - } - else { - /* terminate $[..] and #[..] */ - if ( GenCC ) zzreplstr("))"); - else zzreplstr(")"); - zzmore(); - } - } - else if ( topint() == '|' ) { /* end of simple [...] */ - popint(); - zzmore(); - } - else zzmore(); - >> - -consumeUntil\( [\ \t]* \{~[\}]+\} [\ \t]* \) - << - NLA = 37; - - zzmore(); - zzreplstr(inline_set(zzbegexpr+ - strlen("consumeUntil("))); - >> - -consumeUntil\( ~[\)]+ \) - << - NLA = 38; - zzmore(); - >> - -\n|\r|\r\n - << - NLA = 39; - zzline++; zzmore(); DAWDLE; - >> - -\> - << - NLA = 40; - zzmore(); - >> - -$ - << - NLA = 41; - zzmore(); - >> - -$$ - << - NLA = 42; - if ( !GenCC ) {zzreplstr("zzaRet"); zzmore();} - else err("$$ use invalid in C++ mode"); - >> - -$\[\] - << - NLA = 43; - if ( !GenCC ) {zzreplstr("zzempty_attr"); zzmore();} - else err("$[] use invalid in C++ mode"); - >> - -$\[ - << - NLA = 44; - - pushint(']'); - if ( !GenCC ) zzreplstr("zzconstr_attr("); - else err("$[..] use invalid in C++ mode"); - zzmore(); - >> - -$[0-9]+ - << - NLA = 45; - { - static char buf[100]; - numericActionLabel=1; /* MR10 */ - if ( strlen(zzbegexpr)>(size_t)85 ) - fatal("$i attrib ref too big"); - set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction); - if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s)", - BlkLevel-1,zzbegexpr+1); - else sprintf(buf,"_t%d%s", - BlkLevel-1,zzbegexpr+1); - zzreplstr(buf); - zzmore(); - UsedOldStyleAttrib = 1; - if ( UsedNewStyleLabel ) - err("cannot mix old-style $i with new-style labels"); - } - >> - -$[0-9]+. - << - NLA = 46; - { - static char buf[100]; - numericActionLabel=1; /* MR10 */ - if ( strlen(zzbegexpr)>(size_t)85 ) - fatal("$i.field attrib ref too big"); - zzbegexpr[strlen(zzbegexpr)-1] = ' '; - set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction); - if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s).", - BlkLevel-1,zzbegexpr+1); - else sprintf(buf,"_t%d%s.", - BlkLevel-1,zzbegexpr+1); - zzreplstr(buf); - zzmore(); - UsedOldStyleAttrib = 1; - if ( UsedNewStyleLabel ) - err("cannot mix old-style $i with new-style labels"); - } - >> - -$[0-9]+.[0-9]+ - << - NLA = 47; - { - static char buf[100]; - static char i[20], j[20]; - char *p,*q; - numericActionLabel=1; /* MR10 */ - if (strlen(zzbegexpr)>(size_t)85) fatal("$i.j attrib ref too big"); - for (p=zzbegexpr+1,q= &i[0]; *p!='.'; p++) { - if ( q == &i[20] ) - fatalFL("i of $i.j attrib ref too big", - FileStr[CurFile], zzline ); - *q++ = *p; - } - *q = '\0'; - for (p++, q= &j[0]; *p!='\0'; p++) { - if ( q == &j[20] ) - fatalFL("j of $i.j attrib ref too big", - FileStr[CurFile], zzline ); - *q++ = *p; - } - *q = '\0'; - if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%s,%s)",i,j); - else sprintf(buf,"_t%s%s",i,j); - zzreplstr(buf); - zzmore(); - UsedOldStyleAttrib = 1; - if ( UsedNewStyleLabel ) - err("cannot mix old-style $i with new-style labels"); - } - >> - -$[_a-zA-Z][_a-zA-Z0-9]* - << - NLA = 48; - { static char buf[300]; LabelEntry *el; - zzbegexpr[0] = ' '; - if ( CurRule != NULL && - strcmp(CurRule, &zzbegexpr[1])==0 ) { - if ( !GenCC ) zzreplstr("zzaRet"); - } - else if ( CurRetDef != NULL && - strmember(CurRetDef, &zzbegexpr[1])) { - if ( hasMultipleOperands( CurRetDef ) ) { - require (strlen(zzbegexpr)<=(size_t)285, - "$retval attrib ref too big"); - sprintf(buf,"_retv.%s",&zzbegexpr[1]); - zzreplstr(buf); - } - else zzreplstr("_retv"); - } - else if ( CurParmDef != NULL && - strmember(CurParmDef, &zzbegexpr[1])) { - ; - } - else if ( Elabel==NULL ) { - { err("$-variables in actions outside of rules are not allowed"); } - } else if ( (el=(LabelEntry *)hash_get(Elabel, &zzbegexpr[1]))!=NULL ) { - /* MR10 */ - /* MR10 */ /* element labels might exist without an elem when */ - /* MR10 */ /* it is a forward reference (to a rule) */ - /* MR10 */ - /* MR10 */ if ( GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) ) - /* MR10 */ { err(eMsg1("There are no token ptrs for rule references: '$%s'",&zzbegexpr[1])); } - /* MR10 */ - /* MR10 */ if ( !GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) && GenAST) { - /* MR10 */ err("You can no longer use attributes returned by rules when also using ASTs"); - /* MR10 */ err(" Use upward inheritance (\"rule >[Attrib a] : ... <<$a=...\>\>\")"); - /* MR10 */ }; - /* MR10 */ - /* MR10 */ /* keep track of <<... $label ...>> for semantic predicates in guess mode */ - /* MR10 */ /* element labels contain pointer to the owners node */ - /* MR10 */ - /* MR10 */ if (el->elem != NULL && el->elem->ntype == nToken) { - /* MR10 */ list_add(&CurActionLabels,el); - /* MR10 */ }; -} -else -warn(eMsg1("$%s not parameter, return value, (defined) element label",&zzbegexpr[1])); -} -zzmore(); - >> - -#0 - << - NLA = 49; - zzreplstr("(*_root)"); zzmore(); chkGTFlag(); - >> - -#\[\] - << - NLA = 50; - if ( GenCC ) { - if (NewAST) zzreplstr("(newAST)"); - else zzreplstr("(new AST)");} - else {zzreplstr("zzastnew()");} zzmore(); - chkGTFlag(); - >> - -#\(\) - << - NLA = 51; - zzreplstr("NULL"); zzmore(); chkGTFlag(); - >> - -#[0-9]+ - << - NLA = 52; - { - static char buf[100]; - if ( strlen(zzbegexpr)>(size_t)85 ) - fatal("#i AST ref too big"); - if ( GenCC ) sprintf(buf,"_ast%d%s",BlkLevel-1,zzbegexpr+1); - else sprintf(buf,"zzastArg(%s)",zzbegexpr+1); - zzreplstr(buf); - zzmore(); - set_orel(atoi(zzbegexpr+1), &AST_nodes_refd_in_actions); - chkGTFlag(); - } - >> - -#line[\ \t]* [0-9]+ {[\ \t]* \"~[\"]+\" ([\ \t]* [0-9]*)* } (\n|\r|\r\n) - << - NLA = 53; - - zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore(); - getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr); - >> - -#line ~[\n\r]* (\n|\r|\r\n) - << - NLA = 54; - - zzline++; zzmore(); - >> - -#[_a-zA-Z][_a-zA-Z0-9]* - << - NLA = 55; - - if ( !(strcmp(zzbegexpr, "#ifdef")==0 || - strcmp(zzbegexpr, "#if")==0 || - strcmp(zzbegexpr, "#else")==0 || - strcmp(zzbegexpr, "#endif")==0 || - strcmp(zzbegexpr, "#ifndef")==0 || - strcmp(zzbegexpr, "#define")==0 || - strcmp(zzbegexpr, "#pragma")==0 || - strcmp(zzbegexpr, "#undef")==0 || - strcmp(zzbegexpr, "#import")==0 || - strcmp(zzbegexpr, "#line")==0 || - strcmp(zzbegexpr, "#include")==0 || - strcmp(zzbegexpr, "#error")==0) ) - { - static char buf[100]; - sprintf(buf, "%s_ast", zzbegexpr+1); - /* MR27 */ list_add(&CurAstLabelsInActions, mystrdup(zzbegexpr+1)); - zzreplstr(buf); - chkGTFlag(); - } - zzmore(); - >> - -#\[ - << - NLA = 56; - - pushint(']'); - if ( GenCC ) { - if (NewAST) zzreplstr("(newAST("); - else zzreplstr("(new AST("); } - else zzreplstr("zzmk_ast(zzastnew(),"); - zzmore(); - chkGTFlag(); - >> - -#\( - << - NLA = 57; - - pushint('}'); - if ( GenCC ) { - if (tmakeInParser) { - zzreplstr("tmake("); - } - else { - zzreplstr("ASTBase::tmake("); - } - } - else { - zzreplstr("zztmake("); - } - zzmore(); - chkGTFlag(); - >> - -# - << - NLA = 58; - zzmore(); - >> - -\) - << - NLA = 59; - - if ( istackempty() ) - zzmore(); - else if ( topint()==')' ) { - popint(); - } - else if ( topint()=='}' ) { - popint(); - /* terminate #(..) */ - zzreplstr(", NULL)"); - } - zzmore(); - >> - -\[ - << - NLA = 60; - - pushint('|'); /* look for '|' to terminate simple [...] */ - zzmore(); - >> - -\( - << - NLA = 61; - - pushint(')'); - zzmore(); - >> - -\\\] - << - NLA = 62; - zzreplstr("]"); zzmore(); - >> - -\\\) - << - NLA = 63; - zzreplstr(")"); zzmore(); - >> - -\\> - << - NLA = 64; - if (! tokenActionActive) zzreplstr(">"); /* MR1 */ - zzmore(); /* MR1 */ - >> - -' - << - NLA = 65; - zzmode(ACTION_CHARS); zzmore(); - >> - -\" - << - NLA = 66; - zzmode(ACTION_STRINGS); zzmore(); - >> - -\\$ - << - NLA = 67; - zzreplstr("$"); zzmore(); - >> - -\\# - << - NLA = 68; - zzreplstr("#"); zzmore(); - >> - -\\(\n|\r|\r\n) - << - NLA = 69; - zzline++; zzmore(); - >> - -\\~[\]\)>$#] - << - NLA = 70; - zzmore(); - >> - -/ - << - NLA = 71; - zzmore(); - >> - -/\* - << - NLA = 72; - zzmode(ACTION_COMMENTS); zzmore(); - >> - -\*/ - << - NLA = 73; - warn("Missing /*; found dangling */ in action"); zzmore(); - >> - -// - << - NLA = 74; - zzmode(ACTION_CPP_COMMENTS); zzmore(); - >> - -~[\n\r\)\(\\$#\>\]\[\"'/]+ - << - NLA = 75; - zzmore(); - >> - - -%%PARSE_ENUM_FILE - -@ - << - NLA = Eof; - ; - >> - -[\t\ ]+ - << - NLA = 137; - zzskip(); - >> - -\n|\r|\r\n - << - NLA = 138; - zzline++; zzskip(); - >> - -// - << - NLA = 139; - zzmode(TOK_DEF_CPP_COMMENTS); zzmore(); - >> - -/\* - << - NLA = 140; - zzmode(TOK_DEF_COMMENTS); zzskip(); - >> - -#ifdef - << - NLA = 141; - zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); - >> - -#if - << - NLA = 142; - zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); - >> - -#ifndef - << - NLA = 143; - ; - >> - -#else - << - NLA = 144; - zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); - >> - -#endif - << - NLA = 145; - zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); - >> - -#undef - << - NLA = 146; - zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); - >> - -#import - << - NLA = 147; - zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); - >> - -#define - << - NLA = 149; - >> - -enum - << - NLA = 151; - >> - -\{ - << - NLA = 152; - >> - -= - << - NLA = 153; - >> - -, - << - NLA = 154; - >> - -\} - << - NLA = 155; - >> - -; - << - NLA = 156; - >> - -[0-9]+ - << - NLA = INT; - >> - -[a-zA-Z_][_a-zA-Z0-9]* - << - NLA = ID; - >> - -%% diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/pred.c b/Tools/CodeTools/TianoTools/Pccts/antlr/pred.c deleted file mode 100644 index eb11c4d950..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/pred.c +++ /dev/null @@ -1,821 +0,0 @@ -/* - * pred.c -- source for predicate detection, manipulation - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2001 - */ - -#include -#include "pcctscfg.h" -#include "set.h" -#include "syn.h" -#include "hash.h" -#include "generic.h" -#include "dlgdef.h" -#include - -#ifdef __USE_PROTOS -static void complete_context_sets(RuleRefNode *, Predicate *); -static void complete_context_trees(RuleRefNode *, Predicate *); -#else -static void complete_context_sets(); -static void complete_context_trees(); -#endif - -char *PRED_AND_LIST = "AND"; -char *PRED_OR_LIST = "OR"; - -/* - * In C mode, return the largest constant integer found as the - * sole argument to LATEXT(i). - * - * In C++ mode, return the largest constant integer found as the - * sole argument to LT(i) given that the char before is nonalpha. - */ - -int -#ifdef __USE_PROTOS -predicateLookaheadDepth(ActionNode *a) -#else -predicateLookaheadDepth(a) -ActionNode *a; -#endif -{ - int max_k=0; - - if (a->predEntry != NULL) { - MR_pred_depth(a->predEntry->pred,&max_k); - goto PREDENTRY_EXIT; - } - - if ( GenCC ) - { - /* scan for LT(i) */ - int k = 0; - char *p = a->action; - while ( p!=NULL ) - { - p = strstr(p, "LT("); - if ( p!=NULL ) - { - if ( p>=a->action && !isalpha(*(p-1)) ) - { - k = atoi(p+strlen("LT(")); - if ( k>max_k ) max_k=k; - } - p += strlen("LT("); - } - } - } - else { - /* scan for LATEXT(i) */ - int k = 0; - char *p = a->action; - while ( p!=NULL ) - { - p = strstr(p, "LATEXT("); - if ( p!=NULL ) - { - p += strlen("LATEXT("); - k = atoi(p); - if ( k>max_k ) max_k=k; - } - } - } - - if (max_k==0) { - max_k = 1; /* MR33 Badly designed if didn't set max_k when CLL_k = 1 */ - if (CLL_k > 1) /* MR27 Don't warn if max(k,ck) == 1 */ - { - if ( !a->frmwarned ) - { - a->frmwarned = 1; - warnFL(eMsg1("predicate: %s missing, bad, or with i=0; assuming i=1", - GenCC?"LT(i)":"LATEXT(i)"), - FileStr[a->file], a->line); - } - } - } - -/* MR10 */ if ( max_k > CLL_k) { -/* MR10 */ if ( !a->frmwarned ) -/* MR10 */ { -/* MR10 */ a->frmwarned = 1; -/* MR11 */ errFL(eMsgd2("predicate refers to lookahead token %d. Semantic lookahead is limited to max(k,ck)==%d", -/* MR10 */ max_k,CLL_k), -/* MR10 */ FileStr[a->file],a->line); -/* MR10 */ if (max_k >= OutputLL_k) { -/* MR10 */ if (!GenCC) { -/* MR10 */ errFL(eMsgd(" the lookahead buffer size in C mode is %d token(s) (including the one just recognized)", -/* MR10 */ OutputLL_k), -/* MR10 */ FileStr[a->file],a->line); -/* MR10 */ }; -/* MR10 */ }; -/* MR10 */ }; -/* MR10 */ max_k= CLL_k; -/* MR10 */ }; - -PREDENTRY_EXIT: - return max_k; -} - -/* Find all predicates in a block of alternatives. DO NOT find predicates - * behind the block because that predicate could depend on things set in - * one of the nonoptional blocks - */ - -Predicate * -#ifdef __USE_PROTOS -find_in_aSubBlk( Junction *alt ) -#else -find_in_aSubBlk( alt ) -Junction *alt; -#endif -{ - Predicate *a, *head=NULL, *tail=NULL, *root=NULL; - Junction *p = alt; - - if (MRhoisting) { - return MR_find_in_aSubBlk(alt); - }; - for (; p!=NULL; p=(Junction *)p->p2) - { - /* ignore empty alts */ - if ( p->p1->ntype != nJunction || - ((Junction *)p->p1)->jtype != EndBlk ) - { - a = find_predicates(p->p1); /* get preds for this alt */ - if ( a==NULL ) continue; - - /* make an OR list of predicates */ - if ( head==NULL ) - { - root = new_pred(); - root->expr = PRED_OR_LIST; - head = tail = a; - root->down = head; - } - else { - tail->right = a; - a->left = tail; - a->up = tail->up; - tail = a; - } - } - } - - /* if just one pred, remove OR root */ - if ( root!=NULL && root->down->right == NULL ) - { - Predicate *d = root->down; - free( (char *) root); - return d; - } - - return root; -} - -Predicate * -#ifdef __USE_PROTOS -find_in_aOptBlk( Junction *alt ) -#else -find_in_aOptBlk( alt ) -Junction *alt; -#endif -{ - return find_in_aSubBlk( alt ); -} - -Predicate * -#ifdef __USE_PROTOS -find_in_aLoopBegin( Junction *alt ) -#else -find_in_aLoopBegin( alt ) -Junction *alt; -#endif -{ - return find_in_aSubBlk( (Junction *) alt->p1 ); /* get preds in alts */ -} - -Predicate * -#ifdef __USE_PROTOS -find_in_aPlusBlk( Junction *alt ) -#else -find_in_aPlusBlk( alt ) -Junction *alt; -#endif -{ - require(alt!=NULL&&alt->p2!=NULL, "invalid aPlusBlk"); - return find_in_aSubBlk( alt ); -} - -/* Look for a predicate; - * - * Do not pass anything but Junction nodes; no Actions, Tokens, RuleRefs. - * This means that a "hoisting distance" of zero is the only distance - * allowable. Init actions are ignored. - * - * WARNING: - * Assumes no (..)? block after predicate for the moment. - * Does not check to see if pred is in production that can generate - * a sequence contained in the set of ambiguous tuples. - * - * Return the predicate found if any. - */ - - -Predicate * -#ifdef __USE_PROTOS -find_predicates( Node *alt ) -#else -find_predicates( alt ) -Node *alt; -#endif -{ -#ifdef DBG_PRED - Junction *j; - RuleRefNode *r; - TokNode *t; -#endif - Predicate *pred; - - if ( alt==NULL ) return NULL; - -#ifdef DBG_PRED - switch ( alt->ntype ) - { - case nJunction : - j = (Junction *) alt; - fprintf(stderr, "Junction(in %s)", j->rname); - switch ( j->jtype ) - { - case aSubBlk : - fprintf(stderr,"aSubBlk\n"); - break; - case aOptBlk : - fprintf(stderr,"aOptBlk\n"); - break; - case aLoopBegin : - fprintf(stderr,"aLoopBeginBlk\n"); - break; - case aLoopBlk : - fprintf(stderr,"aLoopBlk\n"); - break; - case aPlusBlk : - fprintf(stderr,"aPlusBlk\n"); - break; - case EndBlk : - fprintf(stderr,"EndBlk\n"); - break; - case RuleBlk : - fprintf(stderr,"RuleBlk\n"); - break; - case Generic : - fprintf(stderr,"Generic\n"); - break; - case EndRule : - fprintf(stderr,"EndRule\n"); - break; - } - break; - case nRuleRef : - r = (RuleRefNode *) alt; - fprintf(stderr, "RuleRef(in %s)\n", r->rname); - break; - case nToken : - t = (TokNode *) alt; - fprintf(stderr, "TokenNode(in %s)%s\n", t->rname, TokenString(t->token)); - break; - case nAction : - fprintf(stderr, "Action\n"); - break; - } -#endif - - switch ( alt->ntype ) - { - case nJunction : - { - Predicate *a, *b; - Junction *p = (Junction *) alt; - - /* lock nodes */ - if ( p->jtype==aLoopBlk || p->jtype==RuleBlk || - p->jtype==aPlusBlk || p->jtype==EndRule ) - { - require(p->pred_lock!=NULL, "rJunc: lock array is NULL"); - if ( p->pred_lock[1] ) - { - return NULL; - } - p->pred_lock[1] = TRUE; - } - - switch ( p->jtype ) - { - case aSubBlk : - a = find_in_aSubBlk(p); - return a; /* nothing is visible past this guy */ - case aOptBlk : - a = find_in_aOptBlk(p); - return a; - case aLoopBegin : - a = find_in_aLoopBegin(p); - return a; - case aLoopBlk : - a = find_in_aSubBlk(p); - p->pred_lock[1] = FALSE; - return a; - case aPlusBlk : - a = find_in_aPlusBlk(p); - p->pred_lock[1] = FALSE; - return a; /* nothing is visible past this guy */ - case RuleBlk : - a = find_predicates(p->p1); - p->pred_lock[1] = FALSE; - return a; - case Generic : - a = find_predicates(p->p1); - b = find_predicates(p->p2); - if ( p->pred_lock!=NULL ) p->pred_lock[1] = FALSE; - if ( a==NULL ) return b; - if ( b==NULL ) return a; - /* otherwise OR the two preds together */ - { - fatal_internal("hit unknown situation during predicate hoisting"); - } - case EndBlk : - case EndRule : /* Find no predicates after a rule ref */ - return NULL; - default: - fatal_internal("this cannot be printed\n"); - break; - } - } - case nAction : - { - ActionNode *p = (ActionNode *) alt; - if ( p->noHoist) return NULL; /* MR12c */ - if ( p->init_action ) return find_predicates(p->next); - if ( p->is_predicate ) - { - Tree *t=NULL; -#ifdef DBG_PRED - fprintf(stderr, "predicate: <<%s>>?\n", p->action); -#endif - if ( p->guardpred!=NULL ) - { - pred = predicate_dup(p->guardpred); - MR_guardPred_plainSet(p,pred); /* MR12c */ - } - else - { - pred = new_pred(); - pred->k = predicateLookaheadDepth(p); - pred->source = p; - pred->expr = p->action; - if ( HoistPredicateContext && pred->k > 1 ) - { - /* MR30 No need to use first_item_is_guess_block_extra - since we know this is an action, not a (...)* or - (...)+ block. - */ - - if ( first_item_is_guess_block((Junction *)p->next) ) - { - warnFL("cannot compute context of predicate in front of (..)? block", - FileStr[p->file], p->line); - } - else - { - ConstrainSearch = 0; -/* MR11 */ if (p->ampersandPred != NULL) { -/* MR11 */ TRAV(p, -/* MR11 */ pred->k, -/* MR11 */ &(pred->completionTree), t); -/* MR11 */ } else { - TRAV(p->next, - pred->k, - &(pred->completionTree), t); - }; - pred->tcontext = t; - MR_check_pred_too_long(pred,pred->completionTree); -#ifdef DBG_PRED - fprintf(stderr, "LL(%d) context:", pred->k); - preorder(t); - fprintf(stderr, "\n"); -#endif - } - } - else if ( HoistPredicateContext && pred->k == 1 ) - { - pred->scontext[1] = empty; - /* MR30 No need to use first_item_is_guess_block_extra - since we know this is an action. - */ - if ( first_item_is_guess_block((Junction *)p->next) ) - { - warnFL("cannot compute context of predicate in front of (..)? block", - FileStr[p->file], p->line); - } - else - { - REACH((Junction *)p->next, - 1, - &(pred->completionSet), - pred->scontext[1]); - MR_check_pred_too_long(pred,pred->completionSet); -#ifdef DBG_PRED - fprintf(stderr, "LL(1) context:"); - s_fprT(stderr, pred->scontext[1]); - fprintf(stderr, "\n"); -#endif - } - } - } - { - Predicate *d = find_predicates(p->next); - Predicate *root; - -/* Warning: Doesn't seem like the up pointers will all be set correctly; - * TJP: that's ok, we're not using them now. - */ - if ( d!=NULL ) - { - root = new_pred(); - root->expr = PRED_AND_LIST; - root->down = pred; - pred->right = d; - pred->up = root; - d->left = pred; - d->up = pred->up; - return root; - } - } - return pred; - } - return NULL; - } - case nRuleRef : - { - Predicate *a; - RuleRefNode *p = (RuleRefNode *) alt; - Junction *r; - Junction *save_MR_RuleBlkWithHalt; - - RuleEntry *q = (RuleEntry *) hash_get(Rname, p->text); - if ( q == NULL ) - { - warnFL( eMsg1("rule %s not defined",p->text), FileStr[p->file], p->line ); - return NULL; - } - r = RulePtr[q->rulenum]; - if ( r->pred_lock[1] ) - { - /* infinite left-recursion; ignore 'cause LL sup 1 (k) analysis - * must have seen it earlier. - */ - return NULL; - } - - /* MR10 There should only be one halt set at a time. */ - /* MR10 Life would have been easier with a global variable */ - /* MR10 (at least for this particular need) */ - /* MR10 Unset the old one and set the new one, later undo. */ - - require(r->end->halt == FALSE,"should only have one halt at a time"); - -/* MR10 */ require(MR_RuleBlkWithHalt == NULL || -/* MR10 */ (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == TRUE), -/* MR10 */ "RuleBlkWithHalt->end not RuleBlk or does not have halt set"); -/* MR10 */ if (MR_RuleBlkWithHalt != NULL) { -/* MR10 */ MR_RuleBlkWithHalt->end->halt=FALSE; -/* MR10 */ }; - -/*** fprintf(stderr,"\nSetting halt on junction #%d\n",r->end->seq); ***/ - - require(r->end->halt == FALSE,"rule->end->halt already set"); - - save_MR_RuleBlkWithHalt=MR_RuleBlkWithHalt; - -/* MR10 */ MR_pointerStackPush(&MR_RuleBlkWithHaltStack,MR_RuleBlkWithHalt); -/* MR10 */ MR_pointerStackPush(&MR_PredRuleRefStack,p); - - r->end->halt = TRUE; -/* MR10 */ MR_RuleBlkWithHalt=r; - - a = find_predicates((Node *)r); - - require(r->end->halt == TRUE,"rule->end->halt not set"); - r->end->halt = FALSE; - -/* MR10 */ MR_pointerStackPop(&MR_PredRuleRefStack); -/* MR10 */ MR_RuleBlkWithHalt=(Junction *) MR_pointerStackPop(&MR_RuleBlkWithHaltStack); - - require (MR_RuleBlkWithHalt==save_MR_RuleBlkWithHalt, - "RuleBlkWithHaltStack not consistent"); - -/* MR10 */ require(MR_RuleBlkWithHalt == NULL || -/* MR10 */ (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == FALSE), -/* MR10 */ "RuleBlkWithHalt->end not RuleBlk or has no halt set"); -/* MR10 */ if (MR_RuleBlkWithHalt != NULL) { -/* MR10 */ MR_RuleBlkWithHalt->end->halt=TRUE; -/* MR10 */ }; - -/*** fprintf(stderr,"\nRestoring halt on junction #%d\n",r->end->seq); ***/ - - if ( a==NULL ) return NULL; - - /* attempt to compute the "local" FOLLOW just like in normal lookahead - * computation if needed - */ - - complete_context_sets(p,a); - complete_context_trees(p,a); - -/* MR10 */ MR_cleanup_pred_trees(a); - - return a; - } - case nToken : - break; - } - - return NULL; -} - -#ifdef __USE_PROTOS -Predicate *MR_find_predicates_and_supp(Node *alt) -#else -Predicate *MR_find_predicates_and_supp(alt) - Node *alt; -#endif -{ - Predicate *p; - - p=find_predicates(alt); - p=MR_suppressK(alt,p); - return p; -} - -Predicate * -#ifdef __USE_PROTOS -new_pred( void ) -#else -new_pred( ) -#endif -{ - Predicate *p = (Predicate *) calloc(1,sizeof(Predicate)); /* MR10 */ - require(p!=NULL, "new_pred: cannot alloc predicate"); - p->scontext[0]=empty; - p->scontext[1]=empty; - p->completionTree=empty; - p->completionSet=empty; - p->plainSet=empty; - return p; -} - -static void -#ifdef __USE_PROTOS -complete_context_sets( RuleRefNode *p, Predicate *a ) -#else -complete_context_sets( p, a ) -RuleRefNode *p; -Predicate *a; -#endif -{ - set rk2, b; - int k2; - -#ifdef DBG_PRED - fprintf(stderr, "enter complete_context_sets\n"); -#endif - for (; a!=NULL; a=a->right) - { - if ( a->expr == PRED_AND_LIST || a->expr == PRED_OR_LIST ) - { - complete_context_sets(p,a->down); - continue; - } - rk2 = b = empty; - while ( !set_nil(a->completionSet) ) - { - k2 = set_int(a->completionSet); - set_rm(k2, a->completionSet); - - REACH(p->next, k2, &rk2, b); - set_orin(&(a->scontext[1]), b); - set_free(b); - } - - set_orin(&(a->completionSet), rk2);/* remember what we couldn't do */ - set_free(rk2); -#ifdef DBG_PRED - fprintf(stderr, "LL(1) context for %s(addr 0x%x) after ruleref:", a->expr, a); - s_fprT(stderr, a->scontext[1]); - fprintf(stderr, "\n"); -#endif -/* complete_context_sets(p, a->down);*/ - } -#ifdef DBG_PRED - fprintf(stderr, "exit complete_context_sets\n"); -#endif -} - -static void -#ifdef __USE_PROTOS -complete_context_trees( RuleRefNode *p, Predicate *a ) -#else -complete_context_trees( p, a ) -RuleRefNode *p; -Predicate *a; -#endif -{ - set rk2; - int k2; - Tree *u; - -#ifdef DBG_PRED - fprintf(stderr, "enter complete_context_trees\n"); -#endif - for (; a!=NULL; a=a->right) - { - if ( a->expr == PRED_AND_LIST || a->expr == PRED_OR_LIST ) - { - complete_context_trees(p, a->down); - continue; - } - rk2 = empty; - - /* any k left to do? if so, link onto tree */ - while ( !set_nil(a->completionTree) ) - { - k2 = set_int(a->completionTree); - set_rm(k2, a->completionTree); - u = NULL; - - TRAV(p->next, k2, &rk2, u); - - /* any subtrees missing k2 tokens, add u onto end */ - a->tcontext = tlink(a->tcontext, u, k2); - Tfree(u); /* MR10 */ - } - set_orin(&(a->completionTree), rk2);/* remember what we couldn't do */ - set_free(rk2); -#ifdef DBG_PRED - fprintf(stderr, "LL(i<%d) context after ruleref:", LL_k); - preorder(a->tcontext); - fprintf(stderr, "\n"); -#endif -/* complete_context_trees(p, a->down);*/ - } -#ifdef DBG_PRED - fprintf(stderr, "exit complete_context_trees\n"); -#endif -} - -/* Walk a list of predicates and return the set of all tokens in scontext[1]'s */ -set -#ifdef __USE_PROTOS -covered_set( Predicate *p ) -#else -covered_set( p ) -Predicate *p; -#endif -{ - set a; - - a = empty; - for (; p!=NULL; p=p->right) - { - if ( p->expr == PRED_AND_LIST || p->expr == PRED_OR_LIST ) - { - set_orin(&a, covered_set(p->down)); - continue; - } - set_orin(&a, p->scontext[1]); - set_orin(&a, covered_set(p->down)); - } - return a; -} - -/* MR10 predicate_free() - MR10 Don't free the leaf nodes since they are part of the action node -*/ - -#ifdef __USE_PROTOS -void predicate_free(Predicate *p) -#else -void predicate_free(p) - Predicate *p; -#endif -{ - if (p == NULL) return; - predicate_free(p->right); - predicate_free(p->down); - if (p->cloned || - p->source == NULL || - p->source->guardpred == NULL || - p->expr == PRED_AND_LIST || - p->expr == PRED_OR_LIST) { - set_free(p->scontext[1]); - set_free(p->completionSet); - set_free(p->completionTree); - set_free(p->plainSet); - Tfree(p->tcontext); - free( (char *) p); - } else { - p->right=NULL; - p->down=NULL; /* MR13 *** debug */ - }; -} - -/* MR10 predicate_dup() */ - -#ifdef __USE_PROTOS -Predicate * predicate_dup_xxx(Predicate *p,int contextToo) -#else -Predicate * predicate_dup_xxx(p,contextToo) - Predicate *p; - int contextToo; -#endif -{ - Predicate *q; - - if (p == NULL) return NULL; - q=new_pred(); - q->down=predicate_dup(p->down); - q->right=predicate_dup(p->right); - - /* - don't replicate expr - it is read-only - and address comparison is used to look - for identical predicates. - */ - - q->expr=p->expr; - q->k=p->k; - q->source=p->source; - q->cloned=1; - q->ampersandStyle=p->ampersandStyle; - q->inverted=p->inverted; - q->predEntry=p->predEntry; - q->plainSet=set_dup(p->plainSet); - - if (contextToo) { - q->tcontext=tdup(p->tcontext); - q->scontext[0]=set_dup(p->scontext[0]); - q->scontext[1]=set_dup(p->scontext[1]); - q->completionTree=set_dup(p->completionTree); - q->completionSet=set_dup(p->completionSet); - }; - - /* don't need to dup "redundant" */ - - return q; - -} - -#ifdef __USE_PROTOS -Predicate * predicate_dup_without_context(Predicate *p) -#else -Predicate * predicate_dup_without_context(p) - Predicate *p; -#endif -{ - return predicate_dup_xxx(p,0); -} - -#ifdef __USE_PROTOS -Predicate * predicate_dup(Predicate *p) -#else -Predicate * predicate_dup(p) - Predicate *p; -#endif -{ - return predicate_dup_xxx(p,1); -} - diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/proto.h b/Tools/CodeTools/TianoTools/Pccts/antlr/proto.h deleted file mode 100644 index 53035e720e..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/proto.h +++ /dev/null @@ -1,852 +0,0 @@ -/* - * proto.h -- function prototypes - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2001 - */ - - /* V a r i a b l e s */ - -extern int tp; -extern Junction *SynDiag; -extern char Version[]; -extern char VersionDef[]; -#ifdef __cplusplus -extern void (*fpPrint[])(...); -#else -extern void (*fpPrint[])(); -#endif -#ifdef __cplusplus -extern struct _set (*fpReach[])(...); -#else -extern struct _set (*fpReach[])(); -#endif -#ifdef __cplusplus -extern struct _tree *(*fpTraverse[])(...); -#else -extern struct _tree *(*fpTraverse[])(); -#endif -#ifdef __cplusplus -extern void (**fpTrans)(...); -#else -extern void (**fpTrans)(); -#endif -#ifdef __cplusplus -extern void (**fpJTrans)(...); -#else -extern void (**fpJTrans)(); -#endif -#ifdef __cplusplus -extern void (*C_Trans[NumNodeTypes+1])(...); -#else -extern void (*C_Trans[])(); -#endif -#ifdef __cplusplus -extern void (*C_JTrans[NumJuncTypes+1])(...); -#else -extern void (*C_JTrans[])(); -#endif -extern int BlkLevel; -extern int CurFile; -extern char *CurPredName; -extern char *CurRule; -extern int CurRuleDebug; /* MR13 */ -extern Junction *CurRuleBlk; -extern RuleEntry *CurRuleNode; -extern ListNode *CurElementLabels; -extern ListNode *CurAstLabelsInActions; /* MR27 */ -extern ListNode *ContextGuardPredicateList; /* MR13 */ -extern ListNode *CurActionLabels; -extern int numericActionLabel; /* MR10 << ... $1 ... >> or << ... $1 ... >>? */ -extern ListNode *NumericPredLabels; /* MR10 << ... $1 ... >>? ONLY */ -extern char *FileStr[]; -extern int NumFiles; -extern int EpToken; -extern int WildCardToken; -extern Entry **Tname, - **Texpr, - **Rname, - **Fcache, - **Tcache, - **Elabel, - **Sname, - **Pname; /* MR11 */ -extern ListNode *ExprOrder; -extern ListNode **Cycles; -extern int TokenNum; -extern int LastTokenCounted; -extern ListNode *BeforeActions, *AfterActions, *LexActions; - -/* MR1 */ -/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ -/* MR1 via #lexmember <<....>> & #lexprefix <<...>> */ -/* MR1 */ - -extern ListNode *LexMemberActions; /* MR1 */ -extern ListNode *LexPrefixActions; /* MR1 */ - -extern set *fset; /* for constrained search */ /* MR11 */ -extern int maxk; /* for constrained search */ /* MR11 */ -extern int Save_argc; /* MR10 */ -extern char **Save_argv; /* MR10 */ -extern ListNode *eclasses, *tclasses; -extern char *HdrAction; -extern char *FirstAction; /* MR11 */ -extern FILE *ErrFile; -extern char *RemapFileName; -extern char *ErrFileName; -extern char *DlgFileName; -extern char *DefFileName; -extern char *ModeFileName; -extern char *StdMsgName; -extern int NumRules; -extern Junction **RulePtr; -extern int LL_k; -extern int CLL_k; -extern char *decodeJType[]; -extern int PrintOut; -extern int PrintAnnotate; -extern int CodeGen; -extern int LexGen; -extern int esetnum; -extern int setnum; -extern int wordnum; -extern int GenAST; -extern int GenANSI; -extern int **FoStack; -extern int **FoTOS; -extern int GenExprSetsOpt; -extern FILE *DefFile; -extern int CannotContinue; -extern int GenCR; -extern int GenLineInfo; -extern int GenLineInfoMS; -extern int action_file, action_line; -extern int TraceGen; -extern int CurAmbigAlt1, CurAmbigAlt2, CurAmbigline, CurAmbigfile; -extern char *CurAmbigbtype; -extern int elevel; -extern int GenEClasseForRules; -extern FILE *input, *output; -extern char **TokenStr, **ExprStr; -extern int CurrentLexClass, NumLexClasses; -extern LClass lclass[]; -extern char LexStartSymbol[]; -extern char *CurRetDef; -extern char *CurParmDef; -extern int OutputLL_k; -extern int TreeResourceLimit; -extern int DemandLookahead; -extern char *RulePrefix; -extern int GenStdPccts; -extern char *stdpccts; -extern int ParseWithPredicates; -extern int ConstrainSearch; -extern int PURIFY; /* MR23 */ - -extern set MR_CompromisedRules; /* MR14 */ -extern int MR_AmbSourceSearch; /* MR11 */ -extern int MR_SuppressSearch; /* MR13 */ -extern int MR_AmbSourceSearchGroup; /* MR11 */ -extern int MR_AmbSourceSearchChoice; /* MR11 */ -extern int MR_AmbSourceSearchLimit; /* MR11 */ -extern int MR_usingPredNames; /* MR11 */ -extern int MR_ErrorSetComputationActive; /* MR14 */ -extern char *MR_AmbAidRule; /* MR11 */ -extern int MR_AmbAidLine; /* MR11 */ -extern int MR_AmbAidMultiple; /* MR11 */ -extern int MR_AmbAidDepth; /* MR11 */ -extern int MR_skipped_e3_report; /* MR11 */ -extern int MR_matched_AmbAidRule; /* MR11 */ -extern int MR_Inhibit_Tokens_h_Gen; /* MR13 */ -extern int NewAST; /* MR13 */ -extern int tmakeInParser; /* MR23 */ -extern int AlphaBetaTrace; /* MR14 */ -extern int MR_BlkErr; /* MR21 */ -extern int MR_AlphaBetaWarning; /* MR14 */ -extern int MR_AlphaBetaMessageCount; /* MR14 */ -extern int MR_MaintainBackTrace; /* MR14 */ -extern int MR_BadExprSets; /* MR13 */ -extern int FoundGuessBlk; -extern int FoundException; -extern int FoundAtOperator; /* MR6 */ -extern int FoundExceptionGroup; /* MR6 */ -extern int WarningLevel; -extern int UseStdout; /* MR6 */ -extern int TabWidth; /* MR6 */ -extern int pLevel; -extern int pAlt1; -extern int pAlt2; -extern int AImode; -extern int HoistPredicateContext; -extern int MRhoisting; /* MR9 */ -extern int MRhoistingk; /* MR13 */ -extern int MR_debugGenRule; /* MR11 */ -extern int GenCC; -extern char *ParserName; -extern char *StandardSymbols[]; -extern char *ASTSymbols[]; -extern set reserved_positions; -extern set all_tokens; -extern set imag_tokens; -extern set tokclasses; -extern ListNode *ForcedTokens; -extern int *TokenInd; -extern FILE *Parser_h, *Parser_c; -extern char CurrentClassName[]; -extern int no_classes_found; -extern char Parser_h_Name[]; -extern char Parser_c_Name[]; -extern char MRinfoFile_Name[]; /* MR10 */ -extern FILE *MRinfoFile; /* MR10 */ -extern int MRinfo; /* MR10 */ -extern int MRinfoSeq; /* MR10 */ -extern int InfoP; /* MR10 */ -extern int InfoT; /* MR10 */ -extern int InfoF; /* MR10 */ -extern int InfoM; /* MR10 */ -extern int InfoO; /* MR12 */ -extern int PotentialSuppression; /* MR10 */ -extern int PotentialDummy; /* MR10 */ -extern int TnodesInUse; /* MR10 */ -extern int TnodesPeak; /* MR10 */ -extern int TnodesReportThreshold; /* MR11 */ -extern int TnodesAllocated; /* MR10 */ -extern char *ClassDeclStuff; /* MR10 */ -extern char *BaseClassName; /* MR22 */ -extern ListNode *class_before_actions, *class_after_actions; -extern char *UserTokenDefsFile; -extern int UserDefdTokens; -extern ListNode *MetaTokenNodes; -extern char *OutputDirectory; -extern int DontCopyTokens; -extern int LTinTokenAction; /* MR23 */ -extern set AST_nodes_refd_in_actions; -extern ListNode *CurExGroups; -extern int CurBlockID; -extern int CurAltNum; -extern Junction *CurAltStart; -extern Junction *OuterAltStart; /* chain exception groups MR7 */ -extern ExceptionGroup *DefaultExGroup; -extern int NumSignals; -extern int ContextGuardTRAV; -extern Junction *MR_RuleBlkWithHalt; /* MR10 */ -extern PointerStack MR_BackTraceStack; /* MR10 */ -extern PointerStack MR_PredRuleRefStack; /* MR10 */ -extern PointerStack MR_RuleBlkWithHaltStack; /* MR10 */ - -/* */ -/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */ -/* MR1 in DLG action */ -/* */ -extern int tokenActionActive; /* MR1 */ - -extern char *PRED_OR_LIST; /* MR10 */ -extern char *PRED_AND_LIST; /* MR10 */ - -#ifdef __VMS -#define STRICMP strcasecmp /* MR21 */ -#else -#define STRICMP stricmp /* MR21 */ -#endif - -/* MR26 */ -#ifdef PCCTS_USE_STDARG -extern Tree *tmake(Tree *root, ...); -#else -extern Tree *tmake(); -#endif - -#ifdef __USE_PROTOS -extern int STRICMP(const char*, const char*); -extern void istackreset(void); -extern int istacksize(void); -extern void pushint(int); -extern int popint( void ); -extern int istackempty( void ); -extern int topint( void ); -extern void NewSetWd( void ); -extern void DumpSetWd( void ); -extern void DumpSetWdForC( void ); -extern void DumpSetWdForCC( void ); -extern void NewSet( void ); -extern void FillSet( set ); -extern void ComputeErrorSets( void ); -extern void ComputeTokSets( void ); -extern void SubstErrorClass( set * ); -extern int DefErrSet( set *, int, char * ); -extern int DefErrSetForC( set *, int, char * ); -extern int DefErrSetForCC( set *, int, char * ); -extern int DefErrSet1(int, set *, int, char *); /* MR21 */ -extern int DefErrSetForC1(int, set *, int, char *, const char* ); /* MR21 */ -extern int DefErrSetForCC1(int, set *, int, char *, const char* ); /* MR21 */ -extern int DefErrSetWithSuffix(int, set *, int, char *, const char *); /* MR21 */ -extern void GenErrHdr( void ); -extern void dumpExpr( FILE *, char * ); -extern void addParm( Node *, char * ); -extern Graph buildAction( char *, int, int, int ); -extern Graph buildToken( char * ); -extern Graph buildWildCard( char * ); -extern Graph buildRuleRef( char * ); -extern Graph Or( Graph, Graph ); -extern Graph Cat( Graph, Graph ); -extern Graph makeOpt( Graph, int, char *); -extern Graph makeBlk( Graph, int, char *); -extern Graph makeLoop( Graph, int, char *); -extern Graph makePlus( Graph, int, char *); -extern Graph emptyAlt( void ); -extern Graph emptyAlt3( void ); -extern TokNode * newTokNode( void ); -extern RuleRefNode * newRNode( void ); -extern Junction * newJunction( void ); -extern ActionNode * newActionNode( void ); -extern char * makelocks( void ); -extern void preorder( Tree * ); -extern Tree * tnode( int ); -extern void _Tfree( Tree * ); -extern Tree * tdup( Tree * ); -extern int is_single_tuple( Tree * ); -extern Tree * tappend( Tree *, Tree * ); -extern void Tfree( Tree * ); -extern Tree * tlink( Tree *, Tree *, int ); -extern Tree * tshrink( Tree * ); -extern Tree * tflatten( Tree * ); -extern Tree * tJunc( Junction *, int, set * ); -extern Tree * tRuleRef( RuleRefNode *, int, set * ); -extern Tree * tToken( TokNode *, int, set * ); -extern Tree * tAction( ActionNode *, int, set * ); -extern int tmember( Tree *, Tree * ); -extern int tmember_constrained( Tree *, Tree * ); -extern Tree * tleft_factor( Tree * ); -extern Tree * trm_perm( Tree *, Tree * ); -extern void tcvt( set *, Tree * ); -extern Tree * permute( int, int ); -extern Tree * VerifyAmbig( Junction *, Junction *, unsigned **, set *, Tree **, Tree **, int * ); -extern set rJunc( Junction *, int, set * ); -extern set rRuleRef( RuleRefNode *, int, set * ); -extern set rToken( TokNode *, int, set * ); -extern set rAction( ActionNode *, int, set * ); -extern void HandleAmbiguity( Junction *, Junction *, Junction *, int ); -extern set First( Junction *, int, int, int * ); -extern void freeBlkFsets( Junction * ); -extern void genAction( ActionNode * ); -extern void genRuleRef( RuleRefNode * ); -extern void genToken( TokNode * ); -extern void genOptBlk( Junction * ); -extern void genLoopBlk( Junction *, Junction *, Junction *, int ); -extern void genLoopBegin( Junction * ); -extern void genPlusBlk( Junction * ); -extern void genSubBlk( Junction * ); -extern void genRule( Junction * ); -extern void genJunction( Junction * ); -extern void genEndBlk( Junction * ); -extern void genEndRule( Junction * ); -extern void genHdr( int ); -extern void genHdr1( int ); -extern void dumpAction( char *, FILE *, int, int, int, int ); -extern void dumpActionPlus(ActionNode*, char *, FILE *, int, int, int, int ); /* MR21 */ -extern Entry ** newHashTable( void ); -extern Entry * hash_add( Entry **, char *, Entry * ); -extern Entry * hash_get( Entry **, char * ); -extern void hashStat( Entry ** ); -extern char * mystrdup( char * ); -extern void genLexDescr( void ); -extern void dumpLexClasses( FILE * ); -extern void genDefFile( void ); -extern void DumpListOfParmNames( char *, FILE *, int ); /* MR5 janm 26-May-97 */ -extern int DumpNextNameInDef( char **, FILE * ); -extern void DumpOldStyleParms( char *, FILE * ); -extern void DumpType( char *, FILE * ); -extern int strmember( char *, char * ); -/* extern int HasComma( char * ); MR23 Replaced by hasMultipleOperands() */ -extern void DumpRetValStruct( FILE *, char *, int ); -extern char * StripQuotes( char * ); -extern int main( int, char *[] ); -extern void readDescr( void ); -extern FILE * NextFile( void ); -extern char * outnameX( char *, char *); -extern char * outname( char * ); -extern void fatalFL( char *, char *, int ); -extern void fatal_intern( char *, char *, int ); -extern void cleanUp( void ); -extern char * eMsg3( char *, char *, char *, char * ); -extern char * eMsgd( char *, int ); -extern char * eMsgd2( char *, int, int ); -extern void s_fprT( FILE *, set ); -extern char * TerminalString( int ); -extern void lexclass( char * ); -extern void lexmode( int ); -extern int LexClassIndex( char * ); -extern int hasAction( char * ); -extern void setHasAction( char *, char * ); -extern int addTname( char * ); -extern int addTexpr( char * ); -extern int Tnum( char * ); -extern void Tklink( char *, char * ); -extern Entry * newEntry( char *, int ); -extern void list_add( ListNode **, void * ); -extern void list_free( ListNode **, int freeData ); /* MR10 */ -extern void list_apply( ListNode *, void (*)(void *) ); -extern int list_search_cstring (ListNode *, char *); /* MR27 */ -extern char * Fkey( char *, int, int ); -extern void FoPush( char *, int ); -extern void FoPop( int ); -extern void RegisterCycle( char *, int ); -extern void ResolveFoCycles( int ); -extern void pJunc( Junction * ); -extern void pRuleRef( RuleRefNode * ); -extern void pToken( TokNode * ); -extern void pAction( ActionNode * ); -extern void FoLink( Node * ); -extern void addFoLink( Node *, char *, Junction * ); -extern void GenCrossRef( Junction * ); -extern void defErr( char *, long, long, long, long, long, long ); -extern void genStdPCCTSIncludeFile(FILE *,char *); /* MR10 */ -extern char * pcctsBaseName(char *); /* MR32 */ -extern Predicate *find_predicates(Node *); /* MR10 */ -extern Predicate *MR_find_predicates_and_supp(Node *); /* MR13 */ -extern int predicateLookaheadDepth(ActionNode *); /* MR10 */ -extern void predicate_free(Predicate *); /* MR10 */ -extern Predicate * predicate_dup(Predicate *); /* MR10 */ -extern Predicate * predicate_dup_without_context(Predicate *); /* MR11 */ -extern void GenRulePrototypes(FILE *, Junction *); -extern Junction *first_item_is_guess_block(Junction *); -extern Junction *first_item_is_guess_block_extra(Junction * q); /* MR30 */ -extern Junction *analysis_point(Junction *); -extern Tree *make_tree_from_sets(set *, set *); -extern Tree *tdup_chain(Tree *); -extern Tree *tdif(Tree *, Predicate *, set *, set *); -extern set covered_set(Predicate *); -extern void AmbiguityDialog(Junction *, int, Junction *, Junction *, int *, int *); -extern void dumpAmbigMsg(set *, FILE *, int); -extern void GenRuleFuncRedefs(FILE *, Junction *); -extern void GenPredefinedSymbolRedefs(FILE *); -extern void GenASTSymbolRedefs(FILE *); -extern void GenRemapFile(void); -extern void GenSetRedefs(FILE *); -extern ForcedToken *newForcedToken(char *, int); -extern void RemapForcedTokens(void); -extern char *TokenOrExpr(int); -extern void setUpperRange(TokNode *, char *); -extern void GenParser_c_Hdr(void); -extern void GenParser_h_Hdr(void); -extern void GenRuleMemberDeclarationsForCC(FILE *, Junction *); -extern int addForcedTname( char *, int ); -extern char *OutMetaName(char *); -extern void OutFirstSetSymbol(Junction *q, char *); /* MR21 */ -extern void warnNoFL(char *err); -extern void warnFL(char *err,char *f,int l); -extern void warn(char *err); -extern void warnNoCR( char *err ); -extern void errNoFL(char *err); -extern void errFL(char *err,char *f,int l); -extern void err(char *err); -extern void errNoCR( char *err ); -extern void genPredTree( Predicate *p, Node *j, int ,int); -extern UserAction *newUserAction(char *); -extern char *gate_symbol(char *name); -extern char *makeAltID(int blockid, int altnum); -extern void DumpRemainingTokSets(void); -extern void DumpANSIFunctionArgDef(FILE *f, Junction *q, int bInit); /* MR23 */ -extern void DumpFormals(FILE *, char *, int bInit); /* MR23 */ -extern char* hideDefaultArgs(const char* pdecl); /* MR22 VHS */ -extern Predicate *computePredFromContextGuard(Graph,int *msgDone); /* MR21 */ -extern void recomputeContextGuard(Predicate *); /* MR13 */ -extern Predicate *new_pred(void); -extern void chkGTFlag(void); -extern void leAdd(LabelEntry *); /* MR7 */ -extern void leFixup(void); /* MR7 */ -extern void egAdd(ExceptionGroup *); /* MR7 */ -extern void egFixup(void); /* MR7 */ -extern void altAdd(Junction *); /* MR7 */ -extern void altFixup(void); /* MR7 */ -extern Predicate * MR_find_in_aSubBlk(Junction *alt); /* MR10 */ -extern Predicate * MR_predFlatten(Predicate *p); /* MR10 */ -extern Predicate * MR_predSimplifyALL(Predicate *p); /* MR10 */ -extern Predicate * MR_predSimplifyALLX(Predicate *p,int skipPass3); /* MR10 */ -extern int MR_allPredLeaves(Predicate *p); /* MR10 */ -extern void MR_cleanup_pred_trees(Predicate *p); /* MR10 */ -extern int MR_predicate_context_completed(Predicate *p); /* MR10 */ -extern void MR_check_pred_too_long(Predicate *p,set completion); /* MR10 */ -extern Tree * MR_remove_epsilon_from_tree(Tree *t); /* MR10 */ -extern Tree * MR_computeTreeAND(Tree *l,Tree *r); /* MR10 */ -extern int MR_tree_equ(Tree *big, Tree *small); /* MR10 */ -extern set MR_First(int ck,Junction *j,set *incomplete); /* MR10 */ -extern set MR_compute_pred_set(Predicate *p); /* MR10 */ -extern Tree * MR_compute_pred_tree_context(Predicate *p); /* MR10 */ -extern int MR_pointerStackPush(PointerStack *,void *); /* MR10 */ -extern void * MR_pointerStackPop(PointerStack *); /* MR10 */ -extern void * MR_pointerStackTop(PointerStack *); /* MR10 */ -extern void MR_pointerStackReset(PointerStack *); /* MR10 */ -extern void MR_backTraceReport(void); /* MR10 */ -extern void MR_alphaBetaTraceReport(void); /* MR14 */ -extern void MR_dumpRuleSet(set); /* MR14 */ -extern void MR_predContextPresent(Predicate *p,int *,int *); /* MR10 */ -extern void MR_dumpPred(Predicate *p,int withContext); /* MR10 */ -extern void MR_dumpPred1(int,Predicate *p,int withContext); /* MR10 */ -extern void MR_xxxIndent(FILE *f,int depth); /* MR11 */ -extern void MR_outputIndent(int depth); /* MR11 */ -extern void MR_stderrIndent(int depth); /* MR11 */ -extern Junction * MR_ruleReferenced(RuleRefNode *rrn); /* MR10 */ -extern Junction * MR_nameToRuleBlk(char *); /* MR10 */ -extern void MR_releaseResourcesUsedInRule(Node *); /* MR10 */ -extern void MR_dumpTreeX(int depth,Tree *t,int across); /* MR10 */ -extern void MR_dumpTreeF(FILE *f,int depth,Tree *t,int across); /* MR10 */ -extern void DumpFcache(void); /* MR10 */ -extern void MR_dumpTokenSet(FILE *f,int depth,set s); /* MR10 */ -extern void MR_traceAmbSource(set *,Junction *,Junction *); /* MR11 */ -extern void MR_traceAmbSourceK(Tree *,Junction *a1,Junction *a2); /* MR11 */ -extern void MR_traceAmbSourceKclient(void); /* MR20 */ -extern Node *MR_advance(Node *); /* MR11 */ -extern int MR_offsetFromRule(Node *); /* MR11 */ -extern char *MR_ruleNamePlusOffset(Node *); /* MR11 */ -extern int MR_max_height_of_tree(Tree *); /* MR11 */ -extern int MR_all_leaves_same_height(Tree *,int); /* MR11 */ -extern void MR_projectTreeOntoSet(Tree *t,int k,set *); /* MR11 */ -extern Tree *MR_make_tree_from_set(set); /* MR11 */ -extern Predicate *MR_removeRedundantPredPass3(Predicate *); /* MR11 */ -extern void MR_pred_depth(Predicate *,int *); /* MR11 */ -extern int MR_comparePredicates(Predicate *,Predicate *); /* MR11 */ -extern Predicate * MR_unfold(Predicate *); /* MR11 */ -extern void MR_simplifyInverted(Predicate *,int); /* MR11 */ -extern int MR_secondPredicateUnreachable /* MR11 */ - (Predicate *first,Predicate *second); /* MR11 */ -extern void MR_clearPredEntry(Predicate *); /* MR11 */ -extern void MR_orphanRules(FILE *); /* MR12 */ -extern void MR_merge_contexts(Tree *); /* MR12 */ -extern int ci_strequ(char *,char *); /* MR12 */ -extern void MR_guardPred_plainSet(ActionNode *anode,Predicate *); /* MR12c */ -extern void MR_suppressSearchReport(void); /* MR12c */ -extern Predicate * MR_suppressK(Node *,Predicate *); /* MR13 */ -extern void MR_backTraceDumpItem(FILE *,int skip,Node *n); /* MR13 */ -extern void MR_backTraceDumpItemReset(void); /* MR13 */ -extern Junction * MR_junctionWithoutP2(Junction *); /* MR13 */ -extern void MR_setConstrainPointer(set *); /* MR18 */ -extern void BlockPreambleOption(Junction *q, char * pSymbol); /* MR23 */ -extern char* getInitializer(char *); /* MR23 */ -extern char *endFormal(char *pStart, /* MR23 */ - char **ppDataType, /* MR23 */ - char **ppSymbol, /* MR23 */ - char **ppEqualSign, /* MR23 */ - char **ppValue, /* MR23 */ - char **ppSeparator, /* MR23 */ - int *pNext); /* MR23 */ -extern char *strBetween(char *pStart, /* MR23 */ - char *pNext, /* MR23 */ - char *pStop); /* MR23 */ -extern int hasMultipleOperands(char *); /* MR23 */ -extern void DumpInitializers(FILE*, RuleEntry*, char*); /* MR23 */ -extern int isTermEntryTokClass(TermEntry *); /* MR23 */ -extern int isEmptyAlt(Node *, Node *); /* MR23 */ -#else -extern int STRICMP(); -extern void istackreset(); -extern int istacksize(); -extern void pushint(); -extern int popint(); -extern int istackempty(); -extern int topint(); -extern void NewSetWd(); -extern void DumpSetWd(); -extern void DumpSetWdForC(); -extern void DumpSetWdForCC(); -extern void NewSet(); -extern void FillSet(); -extern void ComputeErrorSets(); -extern void ComputeTokSets(); -extern void SubstErrorClass(); -extern int DefErrSet(); -extern int DefErrSetForC(); -extern int DefErrSetForCC(); -extern int DefErrSet1(); -extern int DefErrSetForC1(); -extern int DefErrSetForCC1(); -extern int DefErrSetWithSuffix(); /* MR21 */ -extern void GenErrHdr(); -extern void dumpExpr(); -extern void addParm(); -extern Graph buildAction(); -extern Graph buildToken(); -extern Graph buildWildCard(); -extern Graph buildRuleRef(); -extern Graph Or(); -extern Graph Cat(); -extern Graph makeOpt(); -extern Graph makeBlk(); -extern Graph makeLoop(); -extern Graph makePlus(); -extern Graph emptyAlt(); -extern Graph emptyAlt3(); -extern TokNode * newTokNode(); -extern RuleRefNode * newRNode(); -extern Junction * newJunction(); -extern ActionNode * newActionNode(); -extern char * makelocks(); -extern void preorder(); -extern Tree * tnode(); -extern void _Tfree(); -extern Tree * tdup(); -extern int is_single_tuple(); -extern Tree * tappend(); -extern void Tfree(); -extern Tree * tlink(); -extern Tree * tshrink(); -extern Tree * tflatten(); -extern Tree * tJunc(); -extern Tree * tRuleRef(); -extern Tree * tToken(); -extern Tree * tAction(); -extern int tmember(); -extern int tmember_constrained(); -extern Tree * tleft_factor(); -extern Tree * trm_perm(); -extern void tcvt(); -extern Tree * permute(); -extern Tree * VerifyAmbig(); -extern set rJunc(); -extern set rRuleRef(); -extern set rToken(); -extern set rAction(); -extern void HandleAmbiguity(); -extern set First(); -extern void freeBlkFsets(); -extern void genAction(); -extern void genRuleRef(); -extern void genToken(); -extern void genOptBlk(); -extern void genLoopBlk(); -extern void genLoopBegin(); -extern void genPlusBlk(); -extern void genSubBlk(); -extern void genRule(); -extern void genJunction(); -extern void genEndBlk(); -extern void genEndRule(); -extern void genHdr(); -extern void genHdr1(); -extern void dumpAction(); -extern void dumpActionPlus(); /* MR21 */ -extern Entry ** newHashTable(); -extern Entry * hash_add(); -extern Entry * hash_get(); -extern void hashStat(); -extern char * mystrdup(); -extern void genLexDescr(); -extern void dumpLexClasses(); -extern void genDefFile(); -extern void DumpListOfParmNames(); /* MR5 janm 26-May-97 */ -extern int DumpNextNameInDef(); -extern void DumpOldStyleParms(); -extern void DumpType(); -extern int strmember(); -/* extern int HasComma(); MR23 Replaced by hasMultipleOperands() */ -extern void DumpRetValStruct(); -extern char * StripQuotes(); -extern int main(); -extern void readDescr(); -extern FILE * NextFile(); -extern char * outnameX(); -extern char * outname(); -extern void fatalFL(); -extern void fatal_intern(); -extern void cleanUp(); -extern char * eMsg3(); -extern char * eMsgd(); -extern char * eMsgd2(); -extern void s_fprT(); -extern char * TerminalString(); -extern void lexclass(); -extern void lexmode(); -extern int LexClassIndex(); -extern int hasAction(); -extern void setHasAction(); -extern int addTname(); -extern int addTexpr(); -extern int Tnum(); -extern void Tklink(); -extern Entry * newEntry(); -extern void list_add(); -extern void list_free(); /* MR10 */ -extern void list_apply(); -extern int list_search_cstring (); /* MR27 */ -extern char * Fkey(); -extern void FoPush(); -extern void FoPop(); -extern void RegisterCycle(); -extern void ResolveFoCycles(); -extern void pJunc(); -extern void pRuleRef(); -extern void pToken(); -extern void pAction(); -extern void FoLink(); -extern void addFoLink(); -extern void GenCrossRef(); -extern void defErr(); -extern void genStdPCCTSIncludeFile(); -extern char * pcctsBaseName(); /* MR32 */ -extern Predicate *find_predicates(); -extern Predicate *MR_find_predicates_and_supp(); /* MR13 */ -extern int predicateLookaheadDepth(); /* MR10 */ -extern void predicate_free(); /* MR10 */ -extern Predicate * predicate_dup(); /* MR10 */ -extern Predicate * predicate_dup_without_context(); /* MR11 */ -extern void GenRulePrototypes(); -extern Junction *first_item_is_guess_block(); -extern Junction *first_item_is_guess_block_extra(); /* MR30 */ -extern Junction *analysis_point(); -extern Tree *make_tree_from_sets(); -extern Tree *tdup_chain(); -extern Tree *tdif(); -extern set covered_set(); -extern void AmbiguityDialog(); -extern void dumpAmbigMsg(); -extern void GenRuleFuncRedefs(); -extern void GenPredefinedSymbolRedefs(); -extern void GenASTSymbolRedefs(); -extern void GenRemapFile(); -extern void GenSetRedefs(); -extern ForcedToken *newForcedToken(); -extern void RemapForcedTokens(); -extern char *TokenOrExpr(); -extern void setUpperRange(); -extern void GenParser_c_Hdr(); -extern void GenParser_h_Hdr(); -extern void GenRuleMemberDeclarationsForCC(); -extern int addForcedTname(); -extern char *OutMetaName(); -extern void OutFirstSetSymbol(); /* MR21 */ -extern void warnNoFL(); -extern void warnFL(); -extern void warn(); -extern void warnNoCR(); -extern void errNoFL(); -extern void errFL(); -extern void err(); -extern void errNoCR(); -extern void genPredTree(); -extern UserAction *newUserAction(); -extern char *gate_symbol(); -extern char *makeAltID(); -extern void DumpRemainingTokSets(); -extern void DumpANSIFunctionArgDef(); -extern void DumpFormals(); /* MR23 */ -extern char* hideDefaultArgs(); /* MR22 VHS */ -extern Predicate *computePredFromContextGuard(); -extern void recomputeContextGuard(); /* MR13 */ -extern Predicate *new_pred(); -extern void chkGTFlag(); -extern void leAdd(); /* MR7 */ -extern void leFixup(); /* MR7 */ -extern void egAdd(); /* MR7 */ -extern void egFixup(); /* MR7 */ -extern void altAdd(); /* MR7 */ -extern void altFixup(); /* MR7 */ -extern Predicate * MR_find_in_aSubBlk(); /* MR10 */ -extern Predicate * MR_predFlatten(); /* MR10 */ -extern Predicate * MR_predSimplifyALL(); /* MR10 */ -extern Predicate * MR_predSimplifyALLX(); /* MR10 */ -extern void MR_cleanup_pred_trees(); /* MR10 */ -extern int MR_allPredLeaves(); /* MR10 */ -extern int MR_predicate_context_completed(); /* MR10 */ -extern void MR_check_pred_too_long(); /* MR10 */ -extern Tree * MR_remove_epsilon_from_tree(); /* MR10 */ -extern Tree * MR_computeTreeAND(); /* MR10 */ -extern int MR_tree_equ(); /* MR10 */ -extern set MR_First(); /* MR10 */ -extern set MR_compute_pred_set(); /* MR10 */ -extern Tree * MR_compute_pred_tree_context(); /* MR10 */ -extern int MR_pointerStackPush(); /* MR10 */ -extern void * MR_pointerStackPop(); /* MR10 */ -extern void * MR_pointerStackTop(); /* MR10 */ -extern void MR_pointerStackReset(); /* MR10 */ -extern void MR_backTraceReport(); /* MR10 */ -extern void MR_alphaBetaTraceReport(); /* MR14 */ -extern void MR_dumpRuleSet(); /* MR14 */ -extern void MR_predContextPresent(); /* MR10 */ -extern void MR_dumpPred(); /* MR10 */ -extern void MR_dumpPred1(); /* MR10 */ -extern void MR_xxxIndent(); /* MR11 */ -extern void MR_stderrIndent(); /* MR11 */ -extern void MR_outputIndent(); /* MR11 */ -extern Junction * MR_ruleReferenced(); /* MR10 */ -extern void MR_releaseResourcesUsedInRule(); /* MR10 */ -extern void MR_dumpTreeX(); /* MR10 */ -extern void MR_dumpTreeF(); /* MR10 */ -extern void DumpFcache(); /* MR10 */ -extern void MR_dumpTokenSet(); /* MR10 */ -extern void MR_traceAmbSource(); /* MR11 */ -extern Node *MR_advance(); /* MR11 */ -extern int MR_offsetFromRule(); /* MR11 */ -extern char *MR_ruleNamePlusOffset(); /* MR11 */ -extern void MR_traceAmbSourceK(); /* MR11 */ -extern void MR_traceAmbSourceKclient(); /* [i_a] added */ -extern int MR_max_height_of_tree(); /* MR11 */ -extern int MR_all_leaves_same_height(); /* MR11 */ -extern void MR_projectTreeOntoSet(); /* MR11 */ -extern Tree *MR_make_tree_from_set(); /* MR11 */ -extern Predicate *MR_removeRedundantPredPass3(); /* MR11 */ -extern void MR_pred_depth(); /* MR11 */ -extern int MR_comparePredicates(); /* MR11 */ -extern Predicate * MR_unfold(); /* MR11 */ -extern void MR_simplifyInverted(); /* MR11 */ -extern int MR_secondPredicateUnreachable(); /* MR11 */ -extern Junction * MR_nameToRuleBlk(); /* MR10 */ -extern void MR_clearPredEntry(); /* MR11 */ -extern void MR_orphanRules(); /* MR12 */ -extern void MR_merge_contexts(); /* MR12 */ -extern int ci_strequ(); /* MR12 */ -extern void MR_guardPred_plainSet(); /* MR12c */ -extern void MR_suppressSearchReport(); /* MR12c */ -extern Predicate * MR_suppressK(); /* MR13 */ -extern void MR_backTraceDumpItem(); /* MR13 */ -extern void MR_backTraceDumpItemReset(); /* MR13 */ -extern Junction * MR_junctionWithoutP2(); /* MR13 */ -extern void MR_setConstrainPointer(); /* MR18 */ -extern void BlockPreambleOption(); /* MR23 */ -extern char* getInitializer(); /* MR23 */ -extern int hasMultipleOperands(); /* MR23 */ -extern char *endFormal(); /* MR23 */ -extern char *strBetween(); /* MR23 */ -extern void DumpInitializers(); /* MR23 */ -extern int isTermEntryTokClass(); /* MR23 */ -extern int isEmptyAlt(); - -#endif - -#ifdef __USE_PROTOS -#include -#endif - -/* MR20 G. Hobbelt Create proper externs for dlg variables */ - -extern set attribsRefdFromAction; -extern int inAlt; -extern int UsedOldStyleAttrib; -extern int UsedNewStyleLabel; - -#define MAX_BLK_LEVEL 100 /* MR23 */ -extern int CurBlockID_array[MAX_BLK_LEVEL]; /* MR23 */ -extern int CurAltNum_array[MAX_BLK_LEVEL]; /* MR23 */ diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/scan.c b/Tools/CodeTools/TianoTools/Pccts/antlr/scan.c deleted file mode 100644 index 9b4bde08e6..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/scan.c +++ /dev/null @@ -1,5735 +0,0 @@ - -/* parser.dlg -- DLG Description of scanner - * - * Generated from: antlr.g - * - * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001 - * Purdue University Electrical Engineering - * With AHPCRC, University of Minnesota - * ANTLR Version 1.33MR33 - */ - -#define ANTLR_VERSION 13333 -#include "pcctscfg.h" -#include "pccts_stdio.h" - -#include "pcctscfg.h" -#include "set.h" -#include -#include "syn.h" -#include "hash.h" -#include "generic.h" -#define zzcr_attr(attr,tok,t) -#include "antlr.h" -#include "tokens.h" -#include "dlgdef.h" -LOOKAHEAD - -void -#ifdef __USE_PROTOS -zzerraction(void) -#else -zzerraction() -#endif -{ - (*zzerr)("invalid token"); - zzadvance(); - zzskip(); -} -/* - * D L G tables - * - * Generated from: parser.dlg - * - * 1989-2001 by Will Cohen, Terence Parr, and Hank Dietz - * Purdue University Electrical Engineering - * DLG Version 1.33MR33 - */ - -#include "mode.h" - - - - -/* maintained, but not used for now */ -set AST_nodes_refd_in_actions = set_init; -int inAlt = 0; -set attribsRefdFromAction = set_init; /* MR20 */ -int UsedOldStyleAttrib = 0; -int UsedNewStyleLabel = 0; -#ifdef __USE_PROTOS -char *inline_set(char *); -#else -char *inline_set(); -#endif - -/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */ -/* MR1 in DLG action */ - -int tokenActionActive=0; /* MR1 */ - - - - - -static char * -#ifdef __USE_PROTOS -getFileNameFromTheLineInfo(char *toStr, char *fromStr) -#else -getFileNameFromTheLineInfo(toStr, fromStr) -char *toStr, *fromStr; -#endif -{ - int i, j, k; - - if (!fromStr || !toStr) return toStr; - - /* find the first " */ - - for (i=0; - (ielem->ntype == nToken,"mark_label_used... ntype != nToken"); - tn=(TokNode *)le->elem; - require (tn->label != 0,"mark_label_used... TokNode has no label"); - tn->label_used_in_semantic_pred=1; -} - -static void act1() -{ - NLA = Eof; - /* L o o k F o r A n o t h e r F i l e */ - { - FILE *new_input; - new_input = NextFile(); - if ( new_input == NULL ) { NLA=Eof; return; } - fclose( input ); - input = new_input; - zzrdstream( input ); - zzskip(); /* Skip the Eof (@) char i.e continue */ - } - } - - -static void act2() -{ - NLA = 76; - zzskip(); - } - - -static void act3() -{ - NLA = 77; - zzline++; zzskip(); - } - - -static void act4() -{ - NLA = 78; - zzmode(ACTIONS); zzmore(); - istackreset(); - pushint(']'); - } - - -static void act5() -{ - NLA = 79; - action_file=CurFile; action_line=zzline; - zzmode(ACTIONS); zzmore(); - list_free(&CurActionLabels,0); /* MR10 */ - numericActionLabel=0; /* MR10 */ - istackreset(); - pushint('>'); - } - - -static void act6() -{ - NLA = 80; - zzmode(STRINGS); zzmore(); - } - - -static void act7() -{ - NLA = 81; - zzmode(COMMENTS); zzskip(); - } - - -static void act8() -{ - NLA = 82; - warn("Missing /*; found dangling */"); zzskip(); - } - - -static void act9() -{ - NLA = 83; - zzmode(CPP_COMMENTS); zzskip(); - } - - -static void act10() -{ - NLA = 84; - - zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore(); - getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr); - } - - -static void act11() -{ - NLA = 85; - - zzline++; zzmore(); - } - - -static void act12() -{ - NLA = 86; - warn("Missing <<; found dangling >>"); zzskip(); - } - - -static void act13() -{ - NLA = WildCard; - } - - -static void act14() -{ - NLA = 88; - FoundException = 1; /* MR6 */ - FoundAtOperator = 1; - } - - -static void act15() -{ - NLA = Pragma; - } - - -static void act16() -{ - NLA = FirstSetSymbol; - } - - -static void act17() -{ - NLA = 94; - } - - -static void act18() -{ - NLA = 95; - } - - -static void act19() -{ - NLA = 96; - } - - -static void act20() -{ - NLA = 97; - } - - -static void act21() -{ - NLA = 98; - } - - -static void act22() -{ - NLA = 99; - } - - -static void act23() -{ - NLA = 102; - } - - -static void act24() -{ - NLA = 103; - } - - -static void act25() -{ - NLA = 104; - } - - -static void act26() -{ - NLA = 105; - } - - -static void act27() -{ - NLA = 106; - } - - -static void act28() -{ - NLA = 107; - } - - -static void act29() -{ - NLA = 108; - } - - -static void act30() -{ - NLA = 109; - } - - -static void act31() -{ - NLA = 110; - } - - -static void act32() -{ - NLA = 111; - } - - -static void act33() -{ - NLA = 112; - } - - -static void act34() -{ - NLA = 113; - } - - -static void act35() -{ - NLA = 114; - } - - -static void act36() -{ - NLA = 115; - } - - -static void act37() -{ - NLA = 116; - } - - -static void act38() -{ - NLA = 117; - } - - -static void act39() -{ - NLA = 118; - } - - -static void act40() -{ - NLA = 119; - } - - -static void act41() -{ - NLA = 120; - } - - -static void act42() -{ - NLA = 121; - } - - -static void act43() -{ - NLA = 122; - } - - -static void act44() -{ - NLA = 123; - } - - -static void act45() -{ - NLA = 124; - } - - -static void act46() -{ - NLA = 125; - } - - -static void act47() -{ - NLA = 126; - } - - -static void act48() -{ - NLA = 127; - } - - -static void act49() -{ - NLA = 128; - } - - -static void act50() -{ - NLA = 129; - } - - -static void act51() -{ - NLA = 130; - } - - -static void act52() -{ - NLA = 131; - } - - -static void act53() -{ - NLA = 132; - } - - -static void act54() -{ - NLA = 133; - } - - -static void act55() -{ - NLA = 134; - } - - -static void act56() -{ - NLA = 135; - } - - -static void act57() -{ - NLA = NonTerminal; - - while ( zzchar==' ' || zzchar=='\t' ) { - zzadvance(); - } - if ( zzchar == ':' && inAlt ) NLA = LABEL; - } - - -static void act58() -{ - NLA = TokenTerm; - - while ( zzchar==' ' || zzchar=='\t' ) { - zzadvance(); - } - if ( zzchar == ':' && inAlt ) NLA = LABEL; - } - - -static void act59() -{ - NLA = 136; - warn(eMsg1("unknown meta-op: %s",LATEXT(1))); zzskip(); - } - -static unsigned char shift0[257] = { - 0, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 1, 2, 58, 58, 3, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 1, 40, 6, 9, 58, 58, 45, - 58, 46, 47, 8, 52, 58, 58, 18, 7, 16, - 14, 15, 16, 16, 16, 16, 16, 16, 16, 41, - 42, 5, 48, 17, 53, 19, 56, 56, 56, 56, - 56, 26, 56, 56, 56, 56, 56, 51, 56, 56, - 56, 56, 56, 56, 29, 56, 56, 56, 56, 56, - 56, 56, 4, 20, 58, 50, 57, 58, 23, 31, - 38, 34, 13, 35, 24, 33, 11, 55, 36, 10, - 25, 12, 32, 21, 55, 22, 27, 28, 54, 55, - 55, 43, 30, 55, 39, 44, 37, 49, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58 -}; - - -static void act60() -{ - NLA = Eof; - } - - -static void act61() -{ - NLA = QuotedTerm; - zzmode(START); - } - - -static void act62() -{ - NLA = 3; - - zzline++; - warn("eoln found in string"); - zzskip(); - } - - -static void act63() -{ - NLA = 4; - zzline++; zzmore(); - } - - -static void act64() -{ - NLA = 5; - zzmore(); - } - - -static void act65() -{ - NLA = 6; - zzmore(); - } - -static unsigned char shift1[257] = { - 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 2, 5, 5, 3, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 1, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5 -}; - - -static void act66() -{ - NLA = Eof; - } - - -static void act67() -{ - NLA = 7; - zzmode(ACTIONS); zzmore(); - } - - -static void act68() -{ - NLA = 8; - - zzline++; - warn("eoln found in string (in user action)"); - zzskip(); - } - - -static void act69() -{ - NLA = 9; - zzline++; zzmore(); - } - - -static void act70() -{ - NLA = 10; - zzmore(); - } - - -static void act71() -{ - NLA = 11; - zzmore(); - } - -static unsigned char shift2[257] = { - 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 2, 5, 5, 3, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 1, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5 -}; - - -static void act72() -{ - NLA = Eof; - } - - -static void act73() -{ - NLA = 12; - zzmode(ACTIONS); zzmore(); - } - - -static void act74() -{ - NLA = 13; - - zzline++; - warn("eoln found in char literal (in user action)"); - zzskip(); - } - - -static void act75() -{ - NLA = 14; - zzmore(); - } - - -static void act76() -{ - NLA = 15; - zzmore(); - } - -static unsigned char shift3[257] = { - 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 2, 5, 5, 3, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5 -}; - - -static void act77() -{ - NLA = Eof; - } - - -static void act78() -{ - NLA = 16; - zzmode(ACTIONS); zzmore(); - } - - -static void act79() -{ - NLA = 17; - zzmore(); - } - - -static void act80() -{ - NLA = 18; - zzline++; zzmore(); DAWDLE; - } - - -static void act81() -{ - NLA = 19; - zzmore(); - } - -static unsigned char shift4[257] = { - 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 3, 5, 5, 4, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 1, 5, 5, 5, 5, 2, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5 -}; - - -static void act82() -{ - NLA = Eof; - } - - -static void act83() -{ - NLA = 20; - zzmode(PARSE_ENUM_FILE); - zzmore(); - } - - -static void act84() -{ - NLA = 21; - zzmore(); - } - - -static void act85() -{ - NLA = 22; - zzline++; zzmore(); DAWDLE; - } - - -static void act86() -{ - NLA = 23; - zzmore(); - } - -static unsigned char shift5[257] = { - 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 3, 5, 5, 4, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 1, 5, 5, 5, 5, 2, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5 -}; - - -static void act87() -{ - NLA = Eof; - } - - -static void act88() -{ - NLA = 24; - zzline++; zzmode(PARSE_ENUM_FILE); zzskip(); DAWDLE; - } - - -static void act89() -{ - NLA = 25; - zzskip(); - } - -static unsigned char shift6[257] = { - 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 1, 3, 3, 2, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3 -}; - - -static void act90() -{ - NLA = Eof; - } - - -static void act91() -{ - NLA = 26; - zzline++; zzmode(ACTIONS); zzmore(); DAWDLE; - } - - -static void act92() -{ - NLA = 27; - zzmore(); - } - -static unsigned char shift7[257] = { - 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 1, 3, 3, 2, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3 -}; - - -static void act93() -{ - NLA = Eof; - } - - -static void act94() -{ - NLA = 28; - zzline++; zzmode(START); zzskip(); DAWDLE; - } - - -static void act95() -{ - NLA = 29; - zzskip(); - } - -static unsigned char shift8[257] = { - 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 1, 3, 3, 2, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3 -}; - - -static void act96() -{ - NLA = Eof; - } - - -static void act97() -{ - NLA = 30; - zzmode(START); zzskip(); - } - - -static void act98() -{ - NLA = 31; - zzskip(); - } - - -static void act99() -{ - NLA = 32; - zzline++; zzskip(); DAWDLE; - } - - -static void act100() -{ - NLA = 33; - zzskip(); - } - -static unsigned char shift9[257] = { - 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 3, 5, 5, 4, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 1, 5, 5, 5, 5, 2, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5 -}; - - -static void act101() -{ - NLA = Eof; - } - - -static void act102() -{ - NLA = Action; - /* these do not nest */ - zzmode(START); - NLATEXT[0] = ' '; - NLATEXT[1] = ' '; - zzbegexpr[0] = ' '; - zzbegexpr[1] = ' '; - if ( zzbufovf ) { - err( eMsgd("action buffer overflow; size %d",ZZLEXBUFSIZE)); - } - -/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */ - /* MR1 in DLG action */ - /* MR1 Doesn't matter what kind of action it is - reset*/ - - tokenActionActive=0; /* MR1 */ - } - - -static void act103() -{ - NLA = Pred; - /* these do not nest */ - zzmode(START); - NLATEXT[0] = ' '; - NLATEXT[1] = ' '; - zzbegexpr[0] = '\0'; - if ( zzbufovf ) { - err( eMsgd("predicate buffer overflow; size %d",ZZLEXBUFSIZE)); - }; -#ifdef __cplusplus__ - /* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); -#else -#ifdef __STDC__ - /* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); -#else -#ifdef __USE_PROTOS - /* MRxx */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred); -#else - /* MR10 */ list_apply(CurActionLabels,mark_label_used_in_sem_pred); -#endif -#endif -#endif - } - - -static void act104() -{ - NLA = PassAction; - if ( topint() == ']' ) { - popint(); - if ( istackempty() ) /* terminate action */ - { - zzmode(START); - NLATEXT[0] = ' '; - zzbegexpr[0] = ' '; - if ( zzbufovf ) { - err( eMsgd("parameter buffer overflow; size %d",ZZLEXBUFSIZE)); - } - } - else { - /* terminate $[..] and #[..] */ - if ( GenCC ) zzreplstr("))"); - else zzreplstr(")"); - zzmore(); - } - } - else if ( topint() == '|' ) { /* end of simple [...] */ - popint(); - zzmore(); - } - else zzmore(); - } - - -static void act105() -{ - NLA = 37; - - zzmore(); - zzreplstr(inline_set(zzbegexpr+ - strlen("consumeUntil("))); - } - - -static void act106() -{ - NLA = 38; - zzmore(); - } - - -static void act107() -{ - NLA = 39; - zzline++; zzmore(); DAWDLE; - } - - -static void act108() -{ - NLA = 40; - zzmore(); - } - - -static void act109() -{ - NLA = 41; - zzmore(); - } - - -static void act110() -{ - NLA = 42; - if ( !GenCC ) {zzreplstr("zzaRet"); zzmore();} - else err("$$ use invalid in C++ mode"); - } - - -static void act111() -{ - NLA = 43; - if ( !GenCC ) {zzreplstr("zzempty_attr"); zzmore();} - else err("$[] use invalid in C++ mode"); - } - - -static void act112() -{ - NLA = 44; - - pushint(']'); - if ( !GenCC ) zzreplstr("zzconstr_attr("); - else err("$[..] use invalid in C++ mode"); - zzmore(); - } - - -static void act113() -{ - NLA = 45; - { - static char buf[100]; - numericActionLabel=1; /* MR10 */ - if ( strlen(zzbegexpr)>(size_t)85 ) - fatal("$i attrib ref too big"); - set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction); - if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s)", - BlkLevel-1,zzbegexpr+1); - else sprintf(buf,"_t%d%s", - BlkLevel-1,zzbegexpr+1); - zzreplstr(buf); - zzmore(); - UsedOldStyleAttrib = 1; - if ( UsedNewStyleLabel ) - err("cannot mix old-style $i with new-style labels"); - } - } - - -static void act114() -{ - NLA = 46; - { - static char buf[100]; - numericActionLabel=1; /* MR10 */ - if ( strlen(zzbegexpr)>(size_t)85 ) - fatal("$i.field attrib ref too big"); - zzbegexpr[strlen(zzbegexpr)-1] = ' '; - set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction); - if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s).", - BlkLevel-1,zzbegexpr+1); - else sprintf(buf,"_t%d%s.", - BlkLevel-1,zzbegexpr+1); - zzreplstr(buf); - zzmore(); - UsedOldStyleAttrib = 1; - if ( UsedNewStyleLabel ) - err("cannot mix old-style $i with new-style labels"); - } - } - - -static void act115() -{ - NLA = 47; - { - static char buf[100]; - static char i[20], j[20]; - char *p,*q; - numericActionLabel=1; /* MR10 */ - if (strlen(zzbegexpr)>(size_t)85) fatal("$i.j attrib ref too big"); - for (p=zzbegexpr+1,q= &i[0]; *p!='.'; p++) { - if ( q == &i[20] ) - fatalFL("i of $i.j attrib ref too big", - FileStr[CurFile], zzline ); - *q++ = *p; - } - *q = '\0'; - for (p++, q= &j[0]; *p!='\0'; p++) { - if ( q == &j[20] ) - fatalFL("j of $i.j attrib ref too big", - FileStr[CurFile], zzline ); - *q++ = *p; - } - *q = '\0'; - if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%s,%s)",i,j); - else sprintf(buf,"_t%s%s",i,j); - zzreplstr(buf); - zzmore(); - UsedOldStyleAttrib = 1; - if ( UsedNewStyleLabel ) - err("cannot mix old-style $i with new-style labels"); - } - } - - -static void act116() -{ - NLA = 48; - { static char buf[300]; LabelEntry *el; - zzbegexpr[0] = ' '; - if ( CurRule != NULL && - strcmp(CurRule, &zzbegexpr[1])==0 ) { - if ( !GenCC ) zzreplstr("zzaRet"); - } - else if ( CurRetDef != NULL && - strmember(CurRetDef, &zzbegexpr[1])) { - if ( hasMultipleOperands( CurRetDef ) ) { - require (strlen(zzbegexpr)<=(size_t)285, - "$retval attrib ref too big"); - sprintf(buf,"_retv.%s",&zzbegexpr[1]); - zzreplstr(buf); - } - else zzreplstr("_retv"); - } - else if ( CurParmDef != NULL && - strmember(CurParmDef, &zzbegexpr[1])) { - ; - } - else if ( Elabel==NULL ) { - { err("$-variables in actions outside of rules are not allowed"); } - } else if ( (el=(LabelEntry *)hash_get(Elabel, &zzbegexpr[1]))!=NULL ) { - /* MR10 */ - /* MR10 */ /* element labels might exist without an elem when */ - /* MR10 */ /* it is a forward reference (to a rule) */ - /* MR10 */ - /* MR10 */ if ( GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) ) - /* MR10 */ { err(eMsg1("There are no token ptrs for rule references: '$%s'",&zzbegexpr[1])); } - /* MR10 */ - /* MR10 */ if ( !GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) && GenAST) { - /* MR10 */ err("You can no longer use attributes returned by rules when also using ASTs"); - /* MR10 */ err(" Use upward inheritance (\"rule >[Attrib a] : ... <<$a=...>>\")"); - /* MR10 */ }; - /* MR10 */ - /* MR10 */ /* keep track of <<... $label ...>> for semantic predicates in guess mode */ - /* MR10 */ /* element labels contain pointer to the owners node */ - /* MR10 */ - /* MR10 */ if (el->elem != NULL && el->elem->ntype == nToken) { - /* MR10 */ list_add(&CurActionLabels,el); - /* MR10 */ }; -} -else -warn(eMsg1("$%s not parameter, return value, (defined) element label",&zzbegexpr[1])); -} -zzmore(); - } - - -static void act117() -{ - NLA = 49; - zzreplstr("(*_root)"); zzmore(); chkGTFlag(); - } - - -static void act118() -{ - NLA = 50; - if ( GenCC ) { - if (NewAST) zzreplstr("(newAST)"); - else zzreplstr("(new AST)");} - else {zzreplstr("zzastnew()");} zzmore(); - chkGTFlag(); - } - - -static void act119() -{ - NLA = 51; - zzreplstr("NULL"); zzmore(); chkGTFlag(); - } - - -static void act120() -{ - NLA = 52; - { - static char buf[100]; - if ( strlen(zzbegexpr)>(size_t)85 ) - fatal("#i AST ref too big"); - if ( GenCC ) sprintf(buf,"_ast%d%s",BlkLevel-1,zzbegexpr+1); - else sprintf(buf,"zzastArg(%s)",zzbegexpr+1); - zzreplstr(buf); - zzmore(); - set_orel(atoi(zzbegexpr+1), &AST_nodes_refd_in_actions); - chkGTFlag(); - } - } - - -static void act121() -{ - NLA = 53; - - zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore(); - getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr); - } - - -static void act122() -{ - NLA = 54; - - zzline++; zzmore(); - } - - -static void act123() -{ - NLA = 55; - - if ( !(strcmp(zzbegexpr, "#ifdef")==0 || - strcmp(zzbegexpr, "#if")==0 || - strcmp(zzbegexpr, "#else")==0 || - strcmp(zzbegexpr, "#endif")==0 || - strcmp(zzbegexpr, "#ifndef")==0 || - strcmp(zzbegexpr, "#define")==0 || - strcmp(zzbegexpr, "#pragma")==0 || - strcmp(zzbegexpr, "#undef")==0 || - strcmp(zzbegexpr, "#import")==0 || - strcmp(zzbegexpr, "#line")==0 || - strcmp(zzbegexpr, "#include")==0 || - strcmp(zzbegexpr, "#error")==0) ) - { - static char buf[100]; - sprintf(buf, "%s_ast", zzbegexpr+1); - /* MR27 */ list_add(&CurAstLabelsInActions, mystrdup(zzbegexpr+1)); - zzreplstr(buf); - chkGTFlag(); - } - zzmore(); - } - - -static void act124() -{ - NLA = 56; - - pushint(']'); - if ( GenCC ) { - if (NewAST) zzreplstr("(newAST("); - else zzreplstr("(new AST("); } - else zzreplstr("zzmk_ast(zzastnew(),"); - zzmore(); - chkGTFlag(); - } - - -static void act125() -{ - NLA = 57; - - pushint('}'); - if ( GenCC ) { - if (tmakeInParser) { - zzreplstr("tmake("); - } - else { - zzreplstr("ASTBase::tmake("); - } - } - else { - zzreplstr("zztmake("); - } - zzmore(); - chkGTFlag(); - } - - -static void act126() -{ - NLA = 58; - zzmore(); - } - - -static void act127() -{ - NLA = 59; - - if ( istackempty() ) - zzmore(); - else if ( topint()==')' ) { - popint(); - } - else if ( topint()=='}' ) { - popint(); - /* terminate #(..) */ - zzreplstr(", NULL)"); - } - zzmore(); - } - - -static void act128() -{ - NLA = 60; - - pushint('|'); /* look for '|' to terminate simple [...] */ - zzmore(); - } - - -static void act129() -{ - NLA = 61; - - pushint(')'); - zzmore(); - } - - -static void act130() -{ - NLA = 62; - zzreplstr("]"); zzmore(); - } - - -static void act131() -{ - NLA = 63; - zzreplstr(")"); zzmore(); - } - - -static void act132() -{ - NLA = 64; - if (! tokenActionActive) zzreplstr(">"); /* MR1 */ - zzmore(); /* MR1 */ - } - - -static void act133() -{ - NLA = 65; - zzmode(ACTION_CHARS); zzmore(); - } - - -static void act134() -{ - NLA = 66; - zzmode(ACTION_STRINGS); zzmore(); - } - - -static void act135() -{ - NLA = 67; - zzreplstr("$"); zzmore(); - } - - -static void act136() -{ - NLA = 68; - zzreplstr("#"); zzmore(); - } - - -static void act137() -{ - NLA = 69; - zzline++; zzmore(); - } - - -static void act138() -{ - NLA = 70; - zzmore(); - } - - -static void act139() -{ - NLA = 71; - zzmore(); - } - - -static void act140() -{ - NLA = 72; - zzmode(ACTION_COMMENTS); zzmore(); - } - - -static void act141() -{ - NLA = 73; - warn("Missing /*; found dangling */ in action"); zzmore(); - } - - -static void act142() -{ - NLA = 74; - zzmode(ACTION_CPP_COMMENTS); zzmore(); - } - - -static void act143() -{ - NLA = 75; - zzmore(); - } - -static unsigned char shift10[257] = { - 0, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 16, 19, 33, 33, 20, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 16, 33, 28, 27, 21, 33, 33, - 30, 15, 18, 32, 33, 33, 33, 25, 31, 23, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 33, - 33, 33, 33, 1, 2, 33, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 11, 26, 26, 26, - 26, 26, 22, 29, 3, 33, 26, 33, 26, 26, - 4, 26, 10, 26, 26, 26, 13, 26, 26, 14, - 9, 6, 5, 26, 26, 26, 7, 12, 8, 26, - 26, 26, 26, 26, 17, 33, 34, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33 -}; - - -static void act144() -{ - NLA = Eof; - ; - } - - -static void act145() -{ - NLA = 137; - zzskip(); - } - - -static void act146() -{ - NLA = 138; - zzline++; zzskip(); - } - - -static void act147() -{ - NLA = 139; - zzmode(TOK_DEF_CPP_COMMENTS); zzmore(); - } - - -static void act148() -{ - NLA = 140; - zzmode(TOK_DEF_COMMENTS); zzskip(); - } - - -static void act149() -{ - NLA = 141; - zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); - } - - -static void act150() -{ - NLA = 142; - zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); - } - - -static void act151() -{ - NLA = 143; - ; - } - - -static void act152() -{ - NLA = 144; - zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); - } - - -static void act153() -{ - NLA = 145; - zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); - } - - -static void act154() -{ - NLA = 146; - zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); - } - - -static void act155() -{ - NLA = 147; - zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); - } - - -static void act156() -{ - NLA = 149; - } - - -static void act157() -{ - NLA = 151; - } - - -static void act158() -{ - NLA = 152; - } - - -static void act159() -{ - NLA = 153; - } - - -static void act160() -{ - NLA = 154; - } - - -static void act161() -{ - NLA = 155; - } - - -static void act162() -{ - NLA = 156; - } - - -static void act163() -{ - NLA = INT; - } - - -static void act164() -{ - NLA = ID; - } - -static unsigned char shift11[257] = { - 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 1, 2, 27, 27, 3, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 1, 27, 27, 6, 27, 27, 27, - 27, 27, 27, 5, 27, 22, 27, 27, 4, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 27, - 24, 27, 21, 27, 27, 27, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 27, 27, 27, 27, 26, 27, 26, 26, - 26, 9, 10, 8, 26, 26, 7, 26, 26, 12, - 15, 11, 17, 16, 26, 18, 13, 19, 14, 26, - 26, 26, 26, 26, 20, 27, 23, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27 -}; - -#define DfaStates 436 -typedef unsigned short DfaState; - -static DfaState st0[60] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 11, 11, 12, 13, 13, 13, 14, 15, 16, - 17, 11, 11, 18, 11, 11, 19, 11, 11, 19, - 11, 11, 11, 11, 20, 11, 11, 21, 22, 23, - 24, 25, 26, 11, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 11, 11, 19, 436, 436, 436 -}; - -static DfaState st1[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st2[60] = { - 436, 2, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st3[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st4[60] = { - 436, 436, 37, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st5[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st6[60] = { - 436, 436, 436, 436, 436, 38, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st7[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st8[60] = { - 436, 436, 436, 436, 436, 436, 436, 39, 40, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st9[60] = { - 436, 436, 436, 436, 436, 436, 436, 41, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st10[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 42, 43, 43, 44, 43, 43, 43, 436, 436, 436, - 436, 45, 43, 43, 43, 43, 46, 43, 47, 43, - 43, 43, 43, 48, 43, 49, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st11[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st12[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 51, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st13[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 13, 13, 13, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st14[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 52, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st15[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 53, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st16[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st17[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 54, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st18[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 55, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st19[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 56, 56, 56, 56, 56, 56, 56, 436, 436, 436, - 436, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 436, 56, 436, - 436, 436, 436, 56, 436, 436, 436, 436, 436, 436, - 436, 56, 436, 436, 56, 56, 56, 56, 436, 436 -}; - -static DfaState st20[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 57, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st21[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st22[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 58, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 59, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st23[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st24[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st25[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st26[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st27[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 60, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st28[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 61, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st29[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st30[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st31[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 62, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st32[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st33[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st34[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 56, 56, 56, 56, 56, 56, 56, 436, 436, 436, - 436, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 436, 56, 436, - 436, 436, 436, 56, 436, 436, 436, 436, 436, 436, - 436, 63, 436, 436, 56, 56, 56, 56, 436, 436 -}; - -static DfaState st35[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st36[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st37[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st38[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st39[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st40[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st41[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st42[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 64, 43, 65, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st43[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st44[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 66, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st45[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 67, 68, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st46[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 69, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st47[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 70, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st48[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 71, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st49[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 72, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st50[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st51[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 73, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st52[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st53[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st54[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 74, 43, 43, 44, 43, 43, 43, 436, 436, 436, - 436, 45, 43, 43, 43, 43, 46, 43, 47, 43, - 43, 43, 43, 48, 43, 49, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st55[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 75, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st56[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 56, 56, 56, 56, 56, 56, 56, 436, 436, 436, - 436, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 436, 56, 436, - 436, 436, 436, 56, 436, 436, 436, 436, 436, 436, - 436, 56, 436, 436, 56, 56, 56, 56, 436, 436 -}; - -static DfaState st57[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 76, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st58[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 77, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st59[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 78, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st60[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st61[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st62[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st63[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 56, 56, 56, 56, 56, 56, 56, 436, 436, 436, - 436, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 436, 56, 436, - 436, 436, 436, 56, 436, 436, 79, 436, 436, 436, - 436, 56, 436, 436, 56, 56, 56, 56, 436, 436 -}; - -static DfaState st64[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 80, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st65[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 81, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st66[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 82, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st67[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 83, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 84, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st68[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 85, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st69[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 86, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st70[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 87, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st71[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 88, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st72[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 89, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st73[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 90, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st74[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 65, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st75[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 91, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st76[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 92, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st77[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 93, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st78[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 94, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st79[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 95, 96, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st80[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 97, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st81[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 98, 43, 99, 43, 100, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 101, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st82[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 102, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st83[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 103, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st84[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 104, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st85[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 105, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st86[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 106, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st87[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 107, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 108, 43, 43, 436, 109, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st88[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 110, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st89[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 111, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st90[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 112, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st91[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 113, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st92[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 114, 50, 50, 50, 436, 436 -}; - -static DfaState st93[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 115, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st94[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 116, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st95[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 117, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st96[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 118, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st97[60] = { - 436, 119, 120, 121, 122, 122, 122, 122, 122, 122, - 123, 123, 123, 123, 124, 124, 124, 122, 122, 122, - 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 122, 123, 122, - 122, 122, 122, 123, 122, 122, 122, 122, 122, 122, - 122, 123, 122, 122, 123, 123, 123, 123, 122, 436 -}; - -static DfaState st98[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 125, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st99[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 126, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st100[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 127, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st101[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 128, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st102[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 129, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st103[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st104[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 130, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st105[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 131, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st106[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 132, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st107[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 133, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st108[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 134, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st109[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 135, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st110[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 136, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st111[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 137, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st112[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 138, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st113[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 139, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st114[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 140, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st115[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st116[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st117[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st118[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st119[60] = { - 436, 119, 120, 121, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 141, 141, 141, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 436 -}; - -static DfaState st120[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st121[60] = { - 436, 436, 142, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st122[60] = { - 436, 122, 120, 121, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 436 -}; - -static DfaState st123[60] = { - 436, 122, 120, 121, 122, 122, 122, 122, 122, 122, - 123, 123, 123, 123, 123, 123, 123, 122, 122, 122, - 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 122, 123, 122, - 122, 122, 122, 123, 122, 122, 122, 122, 122, 122, - 122, 123, 122, 122, 123, 123, 123, 123, 122, 436 -}; - -static DfaState st124[60] = { - 436, 143, 144, 145, 122, 122, 146, 122, 122, 122, - 123, 123, 123, 123, 124, 124, 124, 122, 122, 122, - 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 122, 123, 122, - 122, 122, 122, 123, 122, 122, 122, 122, 122, 122, - 122, 123, 122, 122, 123, 123, 123, 123, 122, 436 -}; - -static DfaState st125[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 147, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st126[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 148, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st127[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 149, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st128[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 150, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st129[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 151, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st130[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 152, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st131[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 153, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st132[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 154, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st133[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st134[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 155, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st135[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 156, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st136[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 157, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st137[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st138[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 158, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st139[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st140[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 159, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st141[60] = { - 436, 143, 144, 145, 122, 122, 146, 122, 122, 122, - 122, 122, 122, 122, 141, 141, 141, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 436 -}; - -static DfaState st142[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st143[60] = { - 436, 143, 120, 121, 122, 122, 146, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 436 -}; - -static DfaState st144[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st145[60] = { - 436, 436, 160, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st146[60] = { - 436, 161, 162, 163, 161, 161, 122, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 436 -}; - -static DfaState st147[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 164, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st148[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 165, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st149[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 166, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st150[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 167, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st151[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 168, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st152[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st153[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st154[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 169, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st155[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 170, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st156[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 171, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st157[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st158[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 172, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st159[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st160[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st161[60] = { - 436, 161, 162, 163, 161, 161, 173, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 436 -}; - -static DfaState st162[60] = { - 436, 174, 174, 174, 174, 174, 175, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 436 -}; - -static DfaState st163[60] = { - 436, 174, 176, 174, 174, 174, 175, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 436 -}; - -static DfaState st164[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 177, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st165[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 178, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st166[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 179, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st167[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 180, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st168[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 181, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st169[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 182, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st170[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st171[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 183, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st172[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 184, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st173[60] = { - 436, 185, 144, 145, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 186, 186, 186, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 436 -}; - -static DfaState st174[60] = { - 436, 174, 174, 174, 174, 174, 175, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 436 -}; - -static DfaState st175[60] = { - 436, 187, 188, 189, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 190, 190, 190, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st176[60] = { - 436, 174, 174, 174, 174, 174, 175, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 436 -}; - -static DfaState st177[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 191, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st178[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 192, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st179[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 193, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st180[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st181[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st182[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 194, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st183[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st184[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 50, 50, 50, 50, 50, 50, 50, 436, 436, 436, - 436, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 436, 50, 436, - 436, 436, 436, 50, 436, 436, 436, 436, 436, 436, - 436, 50, 436, 436, 50, 50, 50, 50, 436, 436 -}; - -static DfaState st185[60] = { - 436, 185, 144, 145, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 186, 186, 186, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 436 -}; - -static DfaState st186[60] = { - 436, 185, 144, 145, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 186, 186, 186, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 436 -}; - -static DfaState st187[60] = { - 436, 187, 188, 189, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 190, 190, 190, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st188[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st189[60] = { - 436, 436, 195, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st190[60] = { - 436, 187, 188, 189, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 190, 190, 190, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st191[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st192[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st193[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st194[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 196, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st195[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st196[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 197, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st197[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 198, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st198[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 199, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st199[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 200, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st200[60] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 43, 43, 43, 43, 43, 43, 43, 436, 436, 436, - 436, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 436, 43, 436, - 436, 436, 436, 43, 436, 436, 436, 436, 436, 436, - 436, 43, 436, 436, 43, 43, 43, 43, 436, 436 -}; - -static DfaState st201[7] = { - 202, 203, 204, 205, 206, 207, 436 -}; - -static DfaState st202[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st203[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st204[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st205[7] = { - 436, 436, 208, 436, 436, 436, 436 -}; - -static DfaState st206[7] = { - 436, 209, 210, 211, 209, 209, 436 -}; - -static DfaState st207[7] = { - 436, 436, 436, 436, 436, 207, 436 -}; - -static DfaState st208[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st209[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st210[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st211[7] = { - 436, 436, 212, 436, 436, 436, 436 -}; - -static DfaState st212[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st213[7] = { - 214, 215, 216, 217, 218, 219, 436 -}; - -static DfaState st214[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st215[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st216[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st217[7] = { - 436, 436, 220, 436, 436, 436, 436 -}; - -static DfaState st218[7] = { - 436, 221, 222, 223, 221, 221, 436 -}; - -static DfaState st219[7] = { - 436, 436, 436, 436, 436, 219, 436 -}; - -static DfaState st220[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st221[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st222[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st223[7] = { - 436, 436, 224, 436, 436, 436, 436 -}; - -static DfaState st224[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st225[7] = { - 226, 227, 228, 229, 230, 231, 436 -}; - -static DfaState st226[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st227[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st228[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st229[7] = { - 436, 436, 232, 436, 436, 436, 436 -}; - -static DfaState st230[7] = { - 436, 233, 233, 233, 233, 233, 436 -}; - -static DfaState st231[7] = { - 436, 436, 436, 436, 436, 231, 436 -}; - -static DfaState st232[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st233[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st234[7] = { - 235, 236, 237, 238, 239, 237, 436 -}; - -static DfaState st235[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st236[7] = { - 436, 436, 240, 436, 436, 436, 436 -}; - -static DfaState st237[7] = { - 436, 436, 237, 436, 436, 237, 436 -}; - -static DfaState st238[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st239[7] = { - 436, 436, 436, 241, 436, 436, 436 -}; - -static DfaState st240[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st241[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st242[7] = { - 243, 244, 245, 246, 247, 245, 436 -}; - -static DfaState st243[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st244[7] = { - 436, 436, 248, 436, 436, 436, 436 -}; - -static DfaState st245[7] = { - 436, 436, 245, 436, 436, 245, 436 -}; - -static DfaState st246[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st247[7] = { - 436, 436, 436, 249, 436, 436, 436 -}; - -static DfaState st248[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st249[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st250[5] = { - 251, 252, 253, 254, 436 -}; - -static DfaState st251[5] = { - 436, 436, 436, 436, 436 -}; - -static DfaState st252[5] = { - 436, 436, 436, 436, 436 -}; - -static DfaState st253[5] = { - 436, 255, 436, 436, 436 -}; - -static DfaState st254[5] = { - 436, 436, 436, 254, 436 -}; - -static DfaState st255[5] = { - 436, 436, 436, 436, 436 -}; - -static DfaState st256[5] = { - 257, 258, 259, 260, 436 -}; - -static DfaState st257[5] = { - 436, 436, 436, 436, 436 -}; - -static DfaState st258[5] = { - 436, 436, 436, 436, 436 -}; - -static DfaState st259[5] = { - 436, 261, 436, 436, 436 -}; - -static DfaState st260[5] = { - 436, 436, 436, 260, 436 -}; - -static DfaState st261[5] = { - 436, 436, 436, 436, 436 -}; - -static DfaState st262[5] = { - 263, 264, 265, 266, 436 -}; - -static DfaState st263[5] = { - 436, 436, 436, 436, 436 -}; - -static DfaState st264[5] = { - 436, 436, 436, 436, 436 -}; - -static DfaState st265[5] = { - 436, 267, 436, 436, 436 -}; - -static DfaState st266[5] = { - 436, 436, 436, 266, 436 -}; - -static DfaState st267[5] = { - 436, 436, 436, 436, 436 -}; - -static DfaState st268[7] = { - 269, 270, 271, 272, 273, 271, 436 -}; - -static DfaState st269[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st270[7] = { - 436, 436, 274, 436, 436, 436, 436 -}; - -static DfaState st271[7] = { - 436, 436, 271, 436, 436, 271, 436 -}; - -static DfaState st272[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st273[7] = { - 436, 436, 436, 275, 436, 436, 436 -}; - -static DfaState st274[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st275[7] = { - 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st276[36] = { - 277, 278, 279, 280, 281, 279, 279, 279, 279, 279, - 279, 279, 279, 279, 279, 282, 279, 279, 283, 284, - 285, 286, 287, 279, 279, 279, 279, 288, 289, 290, - 291, 292, 293, 279, 279, 436 -}; - -static DfaState st277[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st278[36] = { - 436, 294, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st279[36] = { - 436, 436, 279, 436, 279, 279, 279, 279, 279, 279, - 279, 279, 279, 279, 279, 436, 279, 279, 436, 436, - 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, - 436, 436, 279, 279, 279, 436 -}; - -static DfaState st280[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st281[36] = { - 436, 436, 279, 436, 279, 295, 279, 279, 279, 279, - 279, 279, 279, 279, 279, 436, 279, 279, 436, 436, - 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, - 436, 436, 279, 279, 279, 436 -}; - -static DfaState st282[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st283[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st284[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st285[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 296, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st286[36] = { - 436, 436, 436, 436, 297, 297, 297, 297, 297, 297, - 297, 297, 297, 297, 297, 436, 436, 436, 436, 436, - 436, 298, 299, 300, 300, 436, 297, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st287[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st288[36] = { - 436, 436, 436, 436, 301, 301, 301, 301, 301, 301, - 301, 301, 301, 301, 302, 303, 436, 436, 436, 436, - 436, 436, 304, 305, 306, 436, 301, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st289[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st290[36] = { - 436, 307, 308, 309, 308, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 308, 308, 308, 308, 310, 311, - 312, 313, 308, 308, 308, 308, 308, 314, 308, 308, - 308, 308, 308, 308, 308, 436 -}; - -static DfaState st291[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st292[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 315, 316, 436, 436, 436 -}; - -static DfaState st293[36] = { - 436, 436, 279, 436, 279, 279, 279, 279, 279, 279, - 279, 279, 279, 279, 279, 436, 279, 279, 436, 436, - 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, - 436, 317, 279, 279, 279, 436 -}; - -static DfaState st294[36] = { - 436, 436, 318, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st295[36] = { - 436, 436, 279, 436, 279, 279, 319, 279, 279, 279, - 279, 279, 279, 279, 279, 436, 279, 279, 436, 436, - 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, - 436, 436, 279, 279, 279, 436 -}; - -static DfaState st296[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st297[36] = { - 436, 436, 436, 436, 320, 320, 320, 320, 320, 320, - 320, 320, 320, 320, 320, 436, 436, 436, 436, 436, - 436, 436, 436, 320, 320, 436, 320, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st298[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st299[36] = { - 436, 436, 436, 321, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st300[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 300, 300, 322, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st301[36] = { - 436, 436, 436, 436, 323, 323, 323, 323, 323, 323, - 323, 323, 323, 323, 323, 436, 436, 436, 436, 436, - 436, 436, 436, 323, 323, 436, 323, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st302[36] = { - 436, 436, 436, 436, 323, 323, 323, 323, 323, 323, - 323, 323, 323, 324, 323, 436, 436, 436, 436, 436, - 436, 436, 436, 323, 323, 436, 323, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st303[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 325, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st304[36] = { - 436, 436, 436, 326, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st305[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 306, 306, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st306[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 306, 306, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st307[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st308[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st309[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st310[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st311[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st312[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 327, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st313[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st314[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st315[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st316[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st317[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st318[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st319[36] = { - 436, 436, 279, 436, 279, 279, 279, 328, 279, 279, - 279, 279, 279, 279, 279, 436, 279, 279, 436, 436, - 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, - 436, 436, 279, 279, 279, 436 -}; - -static DfaState st320[36] = { - 436, 436, 436, 436, 320, 320, 320, 320, 320, 320, - 320, 320, 320, 320, 320, 436, 436, 436, 436, 436, - 436, 436, 436, 320, 320, 436, 320, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st321[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st322[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 329, 329, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st323[36] = { - 436, 436, 436, 436, 323, 323, 323, 323, 323, 323, - 323, 323, 323, 323, 323, 436, 436, 436, 436, 436, - 436, 436, 436, 323, 323, 436, 323, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st324[36] = { - 436, 436, 436, 436, 323, 323, 330, 323, 323, 323, - 323, 323, 323, 323, 323, 436, 436, 436, 436, 436, - 436, 436, 436, 323, 323, 436, 323, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st325[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st326[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st327[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st328[36] = { - 436, 436, 279, 436, 279, 279, 279, 279, 331, 279, - 279, 279, 279, 279, 279, 436, 279, 279, 436, 436, - 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, - 436, 436, 279, 279, 279, 436 -}; - -static DfaState st329[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 329, 329, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st330[36] = { - 436, 436, 436, 436, 323, 323, 323, 323, 323, 323, - 332, 323, 323, 323, 323, 436, 436, 436, 436, 436, - 436, 436, 436, 323, 323, 436, 323, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st331[36] = { - 436, 436, 279, 436, 279, 279, 279, 279, 279, 333, - 279, 279, 279, 279, 279, 436, 279, 279, 436, 436, - 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, - 436, 436, 279, 279, 279, 436 -}; - -static DfaState st332[36] = { - 436, 334, 334, 334, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 334, 336, 334, 334, 337, - 338, 334, 334, 339, 339, 334, 335, 334, 334, 334, - 334, 334, 334, 334, 334, 436 -}; - -static DfaState st333[36] = { - 436, 436, 279, 436, 279, 279, 279, 279, 279, 279, - 340, 279, 279, 279, 279, 436, 279, 279, 436, 436, - 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, - 436, 436, 279, 279, 279, 436 -}; - -static DfaState st334[36] = { - 436, 334, 334, 334, 334, 334, 334, 334, 334, 334, - 334, 334, 334, 334, 334, 334, 334, 334, 334, 337, - 338, 334, 334, 334, 334, 334, 334, 334, 334, 334, - 334, 334, 334, 334, 334, 436 -}; - -static DfaState st335[36] = { - 436, 334, 334, 334, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 334, 334, 334, 334, 337, - 338, 334, 334, 335, 335, 334, 335, 334, 334, 334, - 334, 334, 334, 334, 334, 436 -}; - -static DfaState st336[36] = { - 436, 334, 334, 334, 334, 334, 334, 334, 334, 334, - 334, 334, 334, 334, 334, 334, 336, 334, 334, 337, - 338, 334, 334, 341, 341, 334, 334, 334, 334, 334, - 334, 334, 334, 334, 334, 436 -}; - -static DfaState st337[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st338[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 342, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st339[36] = { - 436, 334, 334, 334, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 334, 343, 334, 334, 344, - 345, 334, 334, 339, 339, 334, 335, 334, 346, 334, - 334, 334, 334, 334, 334, 436 -}; - -static DfaState st340[36] = { - 436, 436, 279, 436, 279, 279, 279, 279, 279, 279, - 279, 347, 279, 279, 279, 436, 279, 279, 436, 436, - 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, - 436, 436, 279, 279, 279, 436 -}; - -static DfaState st341[36] = { - 436, 334, 334, 334, 334, 334, 334, 334, 334, 334, - 334, 334, 334, 334, 334, 334, 343, 334, 334, 344, - 345, 334, 334, 341, 341, 334, 334, 334, 346, 334, - 334, 334, 334, 334, 334, 436 -}; - -static DfaState st342[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st343[36] = { - 436, 334, 334, 334, 334, 334, 334, 334, 334, 334, - 334, 334, 334, 334, 334, 334, 343, 334, 334, 337, - 338, 334, 334, 334, 334, 334, 334, 334, 346, 334, - 334, 334, 334, 334, 334, 436 -}; - -static DfaState st344[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st345[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 348, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st346[36] = { - 436, 349, 349, 349, 349, 349, 349, 349, 349, 349, - 349, 349, 349, 349, 349, 349, 349, 349, 349, 350, - 351, 349, 349, 349, 349, 349, 349, 349, 334, 349, - 349, 349, 349, 349, 349, 436 -}; - -static DfaState st347[36] = { - 436, 436, 279, 436, 279, 279, 352, 279, 279, 279, - 279, 279, 279, 279, 279, 436, 279, 279, 436, 436, - 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, - 436, 436, 279, 279, 279, 436 -}; - -static DfaState st348[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st349[36] = { - 436, 349, 349, 349, 349, 349, 349, 349, 349, 349, - 349, 349, 349, 349, 349, 349, 349, 349, 349, 350, - 351, 349, 349, 349, 349, 349, 349, 349, 353, 349, - 349, 349, 349, 349, 349, 436 -}; - -static DfaState st350[36] = { - 436, 354, 354, 354, 354, 354, 354, 354, 354, 354, - 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, - 354, 354, 354, 354, 354, 354, 354, 354, 355, 354, - 354, 354, 354, 354, 354, 436 -}; - -static DfaState st351[36] = { - 436, 354, 354, 354, 354, 354, 354, 354, 354, 354, - 354, 354, 354, 354, 354, 354, 354, 354, 354, 356, - 354, 354, 354, 354, 354, 354, 354, 354, 355, 354, - 354, 354, 354, 354, 354, 436 -}; - -static DfaState st352[36] = { - 436, 436, 279, 436, 279, 279, 279, 279, 279, 279, - 279, 279, 357, 279, 279, 436, 279, 279, 436, 436, - 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, - 436, 436, 279, 279, 279, 436 -}; - -static DfaState st353[36] = { - 436, 334, 334, 334, 334, 334, 334, 334, 334, 334, - 334, 334, 334, 334, 334, 334, 358, 334, 334, 344, - 345, 334, 334, 359, 359, 334, 334, 334, 334, 334, - 334, 334, 334, 334, 334, 436 -}; - -static DfaState st354[36] = { - 436, 354, 354, 354, 354, 354, 354, 354, 354, 354, - 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, - 354, 354, 354, 354, 354, 354, 354, 354, 355, 354, - 354, 354, 354, 354, 354, 436 -}; - -static DfaState st355[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 360, 436, 436, 361, - 362, 436, 436, 363, 363, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st356[36] = { - 436, 354, 354, 354, 354, 354, 354, 354, 354, 354, - 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, - 354, 354, 354, 354, 354, 354, 354, 354, 355, 354, - 354, 354, 354, 354, 354, 436 -}; - -static DfaState st357[36] = { - 436, 436, 279, 436, 279, 279, 279, 279, 279, 279, - 279, 279, 279, 364, 279, 436, 279, 279, 436, 436, - 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, - 436, 436, 279, 279, 279, 436 -}; - -static DfaState st358[36] = { - 436, 334, 334, 334, 334, 334, 334, 334, 334, 334, - 334, 334, 334, 334, 334, 334, 358, 334, 334, 344, - 345, 334, 334, 359, 359, 334, 334, 334, 334, 334, - 334, 334, 334, 334, 334, 436 -}; - -static DfaState st359[36] = { - 436, 334, 334, 334, 334, 334, 334, 334, 334, 334, - 334, 334, 334, 334, 334, 334, 358, 334, 334, 344, - 345, 334, 334, 359, 359, 334, 334, 334, 334, 334, - 334, 334, 334, 334, 334, 436 -}; - -static DfaState st360[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 360, 436, 436, 361, - 362, 436, 436, 363, 363, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st361[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st362[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 365, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st363[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 360, 436, 436, 361, - 362, 436, 436, 363, 363, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st364[36] = { - 436, 436, 279, 436, 279, 279, 279, 279, 279, 279, - 279, 279, 279, 279, 366, 436, 279, 279, 436, 436, - 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, - 436, 436, 279, 279, 279, 436 -}; - -static DfaState st365[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st366[36] = { - 436, 436, 279, 436, 279, 279, 279, 279, 279, 279, - 279, 279, 279, 279, 279, 367, 279, 279, 436, 436, - 436, 436, 436, 279, 279, 279, 279, 436, 436, 436, - 436, 436, 279, 279, 279, 436 -}; - -static DfaState st367[36] = { - 436, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 369, 370, 436, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 436 -}; - -static DfaState st368[36] = { - 436, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 371, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 436 -}; - -static DfaState st369[36] = { - 436, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 369, 370, 371, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 436 -}; - -static DfaState st370[36] = { - 436, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 373, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 368, 436 -}; - -static DfaState st371[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st372[36] = { - 436, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 373, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 374, 436 -}; - -static DfaState st373[36] = { - 436, 375, 375, 375, 375, 375, 375, 375, 375, 375, - 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, - 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, - 375, 375, 375, 375, 376, 436 -}; - -static DfaState st374[36] = { - 436, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 377, 368, 378, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 436 -}; - -static DfaState st375[36] = { - 436, 375, 375, 375, 375, 375, 375, 375, 375, 375, - 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, - 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, - 375, 375, 375, 375, 376, 436 -}; - -static DfaState st376[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 379, 436, 380, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st377[36] = { - 436, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 368, 377, 368, 378, 368, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, - 368, 368, 368, 368, 368, 436 -}; - -static DfaState st378[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st379[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 379, 436, 380, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st380[36] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436 -}; - -static DfaState st381[28] = { - 382, 383, 384, 385, 386, 436, 387, 388, 388, 388, - 389, 388, 388, 388, 388, 388, 388, 388, 388, 388, - 390, 391, 392, 393, 394, 395, 388, 436 -}; - -static DfaState st382[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st383[28] = { - 436, 383, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st384[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st385[28] = { - 436, 436, 396, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st386[28] = { - 436, 436, 436, 436, 397, 398, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st387[28] = { - 436, 436, 436, 436, 436, 436, 436, 399, 436, 400, - 401, 436, 436, 436, 402, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st388[28] = { - 436, 436, 436, 436, 436, 436, 436, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, - 436, 436, 436, 436, 436, 403, 403, 436 -}; - -static DfaState st389[28] = { - 436, 436, 436, 436, 436, 436, 436, 403, 403, 403, - 403, 404, 403, 403, 403, 403, 403, 403, 403, 403, - 436, 436, 436, 436, 436, 403, 403, 436 -}; - -static DfaState st390[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st391[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st392[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st393[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st394[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st395[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 395, 436, 436 -}; - -static DfaState st396[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st397[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st398[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st399[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 405, 436, - 436, 436, 436, 436, 436, 406, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st400[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 407, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st401[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 408, 409, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st402[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 410, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st403[28] = { - 436, 436, 436, 436, 436, 436, 436, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, - 436, 436, 436, 436, 436, 403, 403, 436 -}; - -static DfaState st404[28] = { - 436, 436, 436, 436, 436, 436, 436, 403, 403, 403, - 403, 403, 403, 403, 411, 403, 403, 403, 403, 403, - 436, 436, 436, 436, 436, 403, 403, 436 -}; - -static DfaState st405[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 412, - 436, 413, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st406[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 414, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st407[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 415, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st408[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 416, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st409[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 417, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st410[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 418, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st411[28] = { - 436, 436, 436, 436, 436, 436, 436, 403, 403, 403, - 403, 403, 403, 403, 403, 419, 403, 403, 403, 403, - 436, 436, 436, 436, 436, 403, 403, 436 -}; - -static DfaState st412[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 420, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st413[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 421, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st414[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 422, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st415[28] = { - 436, 436, 436, 436, 436, 436, 436, 423, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st416[28] = { - 436, 436, 436, 436, 436, 436, 436, 424, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st417[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 425, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st418[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 426, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st419[28] = { - 436, 436, 436, 436, 436, 436, 436, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, - 436, 436, 436, 436, 436, 403, 403, 436 -}; - -static DfaState st420[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 427, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st421[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 428, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st422[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 429, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st423[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 430, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st424[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 431, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st425[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st426[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 432, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st427[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st428[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 433, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st429[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 434, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st430[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 435, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st431[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st432[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st433[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st434[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - -static DfaState st435[28] = { - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436 -}; - - -DfaState *dfa[436] = { - st0, - st1, - st2, - st3, - st4, - st5, - st6, - st7, - st8, - st9, - st10, - st11, - st12, - st13, - st14, - st15, - st16, - st17, - st18, - st19, - st20, - st21, - st22, - st23, - st24, - st25, - st26, - st27, - st28, - st29, - st30, - st31, - st32, - st33, - st34, - st35, - st36, - st37, - st38, - st39, - st40, - st41, - st42, - st43, - st44, - st45, - st46, - st47, - st48, - st49, - st50, - st51, - st52, - st53, - st54, - st55, - st56, - st57, - st58, - st59, - st60, - st61, - st62, - st63, - st64, - st65, - st66, - st67, - st68, - st69, - st70, - st71, - st72, - st73, - st74, - st75, - st76, - st77, - st78, - st79, - st80, - st81, - st82, - st83, - st84, - st85, - st86, - st87, - st88, - st89, - st90, - st91, - st92, - st93, - st94, - st95, - st96, - st97, - st98, - st99, - st100, - st101, - st102, - st103, - st104, - st105, - st106, - st107, - st108, - st109, - st110, - st111, - st112, - st113, - st114, - st115, - st116, - st117, - st118, - st119, - st120, - st121, - st122, - st123, - st124, - st125, - st126, - st127, - st128, - st129, - st130, - st131, - st132, - st133, - st134, - st135, - st136, - st137, - st138, - st139, - st140, - st141, - st142, - st143, - st144, - st145, - st146, - st147, - st148, - st149, - st150, - st151, - st152, - st153, - st154, - st155, - st156, - st157, - st158, - st159, - st160, - st161, - st162, - st163, - st164, - st165, - st166, - st167, - st168, - st169, - st170, - st171, - st172, - st173, - st174, - st175, - st176, - st177, - st178, - st179, - st180, - st181, - st182, - st183, - st184, - st185, - st186, - st187, - st188, - st189, - st190, - st191, - st192, - st193, - st194, - st195, - st196, - st197, - st198, - st199, - st200, - st201, - st202, - st203, - st204, - st205, - st206, - st207, - st208, - st209, - st210, - st211, - st212, - st213, - st214, - st215, - st216, - st217, - st218, - st219, - st220, - st221, - st222, - st223, - st224, - st225, - st226, - st227, - st228, - st229, - st230, - st231, - st232, - st233, - st234, - st235, - st236, - st237, - st238, - st239, - st240, - st241, - st242, - st243, - st244, - st245, - st246, - st247, - st248, - st249, - st250, - st251, - st252, - st253, - st254, - st255, - st256, - st257, - st258, - st259, - st260, - st261, - st262, - st263, - st264, - st265, - st266, - st267, - st268, - st269, - st270, - st271, - st272, - st273, - st274, - st275, - st276, - st277, - st278, - st279, - st280, - st281, - st282, - st283, - st284, - st285, - st286, - st287, - st288, - st289, - st290, - st291, - st292, - st293, - st294, - st295, - st296, - st297, - st298, - st299, - st300, - st301, - st302, - st303, - st304, - st305, - st306, - st307, - st308, - st309, - st310, - st311, - st312, - st313, - st314, - st315, - st316, - st317, - st318, - st319, - st320, - st321, - st322, - st323, - st324, - st325, - st326, - st327, - st328, - st329, - st330, - st331, - st332, - st333, - st334, - st335, - st336, - st337, - st338, - st339, - st340, - st341, - st342, - st343, - st344, - st345, - st346, - st347, - st348, - st349, - st350, - st351, - st352, - st353, - st354, - st355, - st356, - st357, - st358, - st359, - st360, - st361, - st362, - st363, - st364, - st365, - st366, - st367, - st368, - st369, - st370, - st371, - st372, - st373, - st374, - st375, - st376, - st377, - st378, - st379, - st380, - st381, - st382, - st383, - st384, - st385, - st386, - st387, - st388, - st389, - st390, - st391, - st392, - st393, - st394, - st395, - st396, - st397, - st398, - st399, - st400, - st401, - st402, - st403, - st404, - st405, - st406, - st407, - st408, - st409, - st410, - st411, - st412, - st413, - st414, - st415, - st416, - st417, - st418, - st419, - st420, - st421, - st422, - st423, - st424, - st425, - st426, - st427, - st428, - st429, - st430, - st431, - st432, - st433, - st434, - st435 -}; - - -DfaState accepts[437] = { - 0, 1, 2, 3, 3, 4, 25, 6, 0, 50, - 59, 57, 57, 43, 26, 13, 14, 0, 57, 58, - 57, 21, 57, 23, 24, 27, 28, 44, 0, 35, - 36, 42, 45, 46, 58, 51, 52, 3, 5, 9, - 7, 8, 59, 59, 59, 59, 59, 59, 59, 59, - 57, 57, 12, 40, 59, 57, 58, 57, 57, 57, - 33, 34, 53, 58, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 57, 59, 57, 57, 57, 57, 0, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 57, 57, 57, 57, 57, 0, 0, 59, 59, 59, - 59, 59, 59, 32, 59, 59, 59, 59, 59, 59, - 59, 59, 57, 57, 57, 22, 56, 48, 49, 0, - 11, 11, 0, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 41, 59, 59, 59, 18, 57, 47, - 57, 0, 11, 0, 10, 10, 0, 59, 59, 59, - 59, 59, 15, 19, 59, 59, 59, 17, 57, 55, - 10, 0, 11, 11, 59, 59, 59, 59, 59, 59, - 20, 59, 57, 0, 0, 0, 11, 59, 59, 59, - 37, 38, 59, 39, 54, 0, 0, 0, 10, 10, - 0, 31, 29, 30, 59, 10, 59, 59, 59, 59, - 16, 0, 60, 61, 62, 62, 0, 65, 62, 64, - 63, 63, 63, 0, 66, 67, 68, 68, 0, 71, - 68, 70, 69, 69, 69, 0, 72, 73, 74, 74, - 0, 76, 74, 75, 0, 77, 79, 81, 80, 80, - 78, 80, 0, 82, 84, 86, 85, 85, 83, 85, - 0, 87, 88, 88, 89, 88, 0, 90, 91, 91, - 92, 91, 0, 93, 94, 94, 95, 94, 0, 96, - 98, 100, 99, 99, 97, 99, 0, 101, 108, 143, - 104, 143, 129, 127, 107, 107, 109, 128, 126, 134, - 0, 133, 139, 143, 102, 143, 107, 116, 110, 112, - 113, 123, 123, 125, 124, 117, 120, 132, 138, 130, - 131, 137, 137, 135, 136, 142, 140, 141, 103, 143, - 116, 111, 114, 123, 123, 119, 118, 137, 143, 115, - 123, 143, 123, 143, 0, 123, 0, 122, 122, 123, - 143, 0, 122, 0, 121, 121, 0, 143, 121, 0, - 122, 122, 143, 0, 0, 0, 122, 143, 0, 0, - 0, 121, 121, 0, 143, 121, 143, 0, 0, 0, - 0, 106, 0, 106, 0, 0, 0, 0, 105, 0, - 105, 0, 144, 145, 146, 146, 0, 0, 164, 164, - 158, 159, 160, 161, 162, 163, 146, 147, 148, 0, - 0, 0, 0, 164, 164, 150, 0, 0, 0, 0, - 0, 164, 0, 0, 0, 0, 0, 0, 0, 157, - 0, 0, 0, 0, 0, 152, 0, 149, 0, 0, - 0, 153, 154, 151, 155, 156, 0 -}; - -void (*actions[165])() = { - zzerraction, - act1, - act2, - act3, - act4, - act5, - act6, - act7, - act8, - act9, - act10, - act11, - act12, - act13, - act14, - act15, - act16, - act17, - act18, - act19, - act20, - act21, - act22, - act23, - act24, - act25, - act26, - act27, - act28, - act29, - act30, - act31, - act32, - act33, - act34, - act35, - act36, - act37, - act38, - act39, - act40, - act41, - act42, - act43, - act44, - act45, - act46, - act47, - act48, - act49, - act50, - act51, - act52, - act53, - act54, - act55, - act56, - act57, - act58, - act59, - act60, - act61, - act62, - act63, - act64, - act65, - act66, - act67, - act68, - act69, - act70, - act71, - act72, - act73, - act74, - act75, - act76, - act77, - act78, - act79, - act80, - act81, - act82, - act83, - act84, - act85, - act86, - act87, - act88, - act89, - act90, - act91, - act92, - act93, - act94, - act95, - act96, - act97, - act98, - act99, - act100, - act101, - act102, - act103, - act104, - act105, - act106, - act107, - act108, - act109, - act110, - act111, - act112, - act113, - act114, - act115, - act116, - act117, - act118, - act119, - act120, - act121, - act122, - act123, - act124, - act125, - act126, - act127, - act128, - act129, - act130, - act131, - act132, - act133, - act134, - act135, - act136, - act137, - act138, - act139, - act140, - act141, - act142, - act143, - act144, - act145, - act146, - act147, - act148, - act149, - act150, - act151, - act152, - act153, - act154, - act155, - act156, - act157, - act158, - act159, - act160, - act161, - act162, - act163, - act164 -}; - -static DfaState dfa_base[] = { - 0, - 201, - 213, - 225, - 234, - 242, - 250, - 256, - 262, - 268, - 276, - 381 -}; - -static unsigned char *b_class_no[] = { - shift0, - shift1, - shift2, - shift3, - shift4, - shift5, - shift6, - shift7, - shift8, - shift9, - shift10, - shift11 -}; - - - -#define ZZSHIFT(c) (b_class_no[zzauto][1+c]) -#define MAX_MODE 12 -#include "dlgauto.h" diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/stdpccts.h b/Tools/CodeTools/TianoTools/Pccts/antlr/stdpccts.h deleted file mode 100644 index ccdc21c3c9..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/stdpccts.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef STDPCCTS_H -#define STDPCCTS_H -/* - * stdpccts.h -- P C C T S I n c l u d e - * - * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001 - * Purdue University Electrical Engineering - * With AHPCRC, University of Minnesota - * ANTLR Version 1.33MR33 - */ - -#ifndef ANTLR_VERSION -#define ANTLR_VERSION 13333 -#endif - -#include "pcctscfg.h" -#include "pccts_stdio.h" - -#include "pcctscfg.h" -#include "set.h" -#include -#include "syn.h" -#include "hash.h" -#include "generic.h" -#define zzcr_attr(attr,tok,t) -#define zzSET_SIZE 20 -#include "antlr.h" -#include "tokens.h" -#include "dlgdef.h" -#include "mode.h" -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/syn.h b/Tools/CodeTools/TianoTools/Pccts/antlr/syn.h deleted file mode 100644 index a23d196d77..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/syn.h +++ /dev/null @@ -1,390 +0,0 @@ -/* - * syn.h - * - * This file includes definitions and macros associated with syntax diagrams - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2001 - */ - -#include "set.h" - -#define NumNodeTypes 4 -#define NumJuncTypes 9 - -/* List the different node types */ -#define nJunction 1 -#define nRuleRef 2 -#define nToken 3 -#define nAction 4 - -/* Different types of junctions */ -#define aSubBlk 1 -#define aOptBlk 2 -#define aLoopBlk 3 -#define EndBlk 4 -#define RuleBlk 5 -#define Generic 6 /* just a junction--no unusual characteristics */ -#define EndRule 7 -#define aPlusBlk 8 -#define aLoopBegin 9 - -typedef int NodeType; - -#define TreeBlockAllocSize 500 -#define JunctionBlockAllocSize 200 -#define ActionBlockAllocSize 50 -#define RRefBlockAllocSize 100 -#define TokenBlockAllocSize 100 - -#ifdef __cplusplus -class ActionNode; -class Junction; -#endif - -/* note that 'right' is used by the tree node allocator as a ptr for linked list */ -typedef struct _tree { - struct _tree *down, *right; - int token; - union { - int rk; /* if token==EpToken, => how many more tokens req'd */ - struct _tree *tref; /* if token==TREE_REF */ - set sref; /* if token==SET */ - } v; -#ifdef TREE_DEBUG - int in_use; - int seq; -#endif - } Tree; - - -/* a predicate is defined to be a predicate action and a token tree with - * context info (if used); later, this struct may include the - * "hoisting distance" when we hoist past tokens. - * - * A tree is used to indicate && vs || - * - * p - * | - * q--r - * - * indicates p && (q||r). - * - * If expr is PRED_AND_LIST or PRED_OR_LIST, then it's an operation node - * and indicates the start of an && or || list. - */ - -typedef struct _Predicate { - struct _Predicate *down, *right; /* these have to be first */ - struct _Predicate *up, *left; /* doubly-link me */ - char *expr; - Tree *tcontext; /* used if lookahead depth of > one is needed (tree) */ - int k; /* lookahead depth for this tcontext */ - set scontext[2];/* used if lookahead depth of one is needed (set) */ - /* scontext[0] is not used; only needed so genExprSets() - routine works (it expects an array) - */ - set completionTree; /* which lookahead depths are required to complete tcontext? */ - set completionSet; /* MR10 separate completion set for sets and trees */ - struct _PredEntry *predEntry; /* MR11 */ - -#ifdef __cplusplus - ActionNode *source; /* where did this predicate come from? */ -#else - struct _anode *source; /* where did this predicate come from? */ -#endif - - char cloned; /* MR10 don't want to free original guard pred */ - char redundant; /* MR10 predicate tree simplification */ - char ampersandStyle; /* MR10 (g)? && <

>? */ - char inverted; /* MR11 ! predName */ - char isConst; /* MR11 */ - char constValue; /* MR11 */ - char conflictReported; /* MR11 */ - - set plainSet; /* MR12b */ - - /*** remember to change new_predicate() and predicate_dup() when changing this ***/ - -} Predicate; - -typedef struct _ExceptionHandler { - char *signalname; - char *action; - } ExceptionHandler; - -typedef struct _ExceptionGroup { - struct _ListNode *handlers; /* list of ExceptionHandler's */ - char *label; /* label==""; implies not attached to any - * particular rule ref. - */ - char *altID; /* which alt did it come from (blk#:alt#) */ - - struct _ExceptionGroup *pendingLink; /* for alternative EG MR7 */ - struct _ExceptionGroup *outerEG; /* for alternative EG MR7 */ - struct _LabelEntry *labelEntry; /* for alternative EG MR7 */ - int forRule; /* MR7 */ - int used; /* MR7 */ - } ExceptionGroup ; - - -#define TokenString(_i) ((TokenInd!=NULL)?TokenStr[TokenInd[_i]]:TokenStr[_i]) -#define ExprString(_i) ((TokenInd!=NULL)?ExprStr[TokenInd[_i]]:ExprStr[_i]) - - - /* M e s s a g e P a s s i n g T o N o d e s */ - -/* - * assumes a 'Junction *r' exists. This macro calls a function with - * the pointer to the node to operate on and a pointer to the rule - * in which it is enclosed. - */ -#define TRANS(p) {if ( (p)==NULL ) fatal("TRANS: NULL object"); \ - if ( (p)->ntype == nJunction ) (*(fpJTrans[((Junction *)(p))->jtype]))( p );\ - else (*(fpTrans[(p)->ntype]))( p );} - -#define PRINT(p) {if ( (p)==NULL ) fatal("PRINT: NULL object");\ - (*(fpPrint[(p)->ntype]))( p );} - -#define REACH(p,k,rk,a) {if ( (p)==NULL ) fatal("REACH: NULL object");\ - (a) = (*(fpReach[(p)->ntype]))( p, k, rk );} - -#define TRAV(p,k,rk,a) {if ( (p)==NULL ) {\ - if ( ContextGuardTRAV ) (a)=NULL; \ - else fatal("TRAV: NULL object");\ - } \ - else (a) = (*(fpTraverse[(p)->ntype]))( p, k, rk );} - -/** -*** #define TRAV(p,k,rk,a) {if ( (p)==NULL ) fatal("TRAV: NULL object");\ -*** (a) = (*(fpTraverse[(p)->ntype]))( p, k, rk );} -**/ - -/* All syntax diagram nodes derive from Node -- superclass - */ -#ifdef __cplusplus -class Node { -public: - NodeType ntype; - char *rname; /* what rule does this element live in? */ - int file; /* index in FileStr */ - int line; /* line number that element occurs on */ - }; -#else -typedef struct _node { - NodeType ntype; - char *rname; /* what rule does this element live in? */ - int file; /* index in FileStr */ - int line; /* line number that element occurs on */ - } Node; -#endif - -#ifdef __cplusplus -class ActionNode : public Node { -public: -#else -typedef struct _anode { - NodeType ntype; - char *rname; /* what rule does this action live in? */ - int file; /* index in FileStr (name of file with action) */ - int line; /* line number that action occurs on */ -#endif - Node *next; - char *action; - int is_predicate; /* true if action is a <<...>>? predicate action */ - int done; /* don't dump if action dumped (used for predicates) */ - int init_action; /* is this the 1st action of 1st prod of block? */ - char *pred_fail; /* what to do/print when predicate fails */ - Predicate *guardpred; /* if '(context)? =>' was present, already done */ - unsigned char frmwarned;/* have we dumped a warning for pred yet? */ - unsigned char ctxwarned;/* have we dumped a warning for pred yet? */ - unsigned char predTooLong; /* MR10 have we dumped warning for pred yet */ - unsigned char noHoist; /* MR12 literally "noHoist" */ - Predicate *ampersandPred; /* MR10 (g)? && <

>? expr */ -#ifdef __cplusplus - Junction *guardNodes; /* MR11 */ -#else - struct _junct *guardNodes; /* MR11 */ -#endif - struct _PredEntry *predEntry; /* MR11 */ - int inverted; /* MR11 <>? */ -#ifdef __cplusplus - }; -#else - } ActionNode; -#endif - -#ifdef __cplusplus -class TokNode : public Node { -public: -#else -typedef struct _toknode { - NodeType ntype; - char *rname; /* name of rule it's in */ - int file; /* index in FileStr (name of file with rule) */ - int line; /* line number that token occurs on */ -#endif - Node *next; - int token; - int astnode; /* leaf/root/excluded (used to build AST's) */ - unsigned char label;/* token label or expression ? */ - unsigned char remapped; - /* used if token id's are forced to certain positions; - * a function walks the tree reassigning token numbers */ - int upper_range; /* MR13 - was char */ - /* used only if Token is of type T1..T2; in this case, - * use token..upper_range as the range; else - * upper_range must be 0 */ - unsigned char wild_card; - /* indicates that the token is the "." wild-card; - * field token is ignored if wild_card is set - */ - unsigned int elnum; /* element number within the alternative */ -#ifdef __cplusplus - Junction *altstart; /* pointer to node that starts alt */ -#else - struct _junct *altstart; /* pointer to node that starts alt */ -#endif - struct _TCnode *tclass; /* token class if tokclass ref */ - set tset; /* set of tokens represented by meta token */ - char *el_label; /* el_label:toknode */ - unsigned char complement; /* complement the set? */ - ExceptionGroup *ex_group; /* any exception[el_label] attached? */ - unsigned char use_def_MT_handler; - unsigned char label_used_in_semantic_pred; /* MR10 */ -#ifdef __cplusplus - }; -#else - } TokNode; -#endif - -#ifdef __cplusplus -class RuleRefNode : public Node { -public: -#else -typedef struct _rrnode { - NodeType ntype; - char *rname; /* name of rule it's in */ - int file; /* index in FileStr (name of file with rule) - it's in */ - int line; /* line number that rule ref occurs on */ -#endif - Node *next; - char *text; /* reference to which rule */ - char *parms; /* point to parameters of rule invocation - (if present) */ - char *assign; /* point to left-hand-side of assignment - (if any) */ - int linked; /* Has a FoLink already been established? */ - int astnode; /* excluded? (used to build AST's) */ - unsigned int elnum; /* element number within the alternative */ -#ifdef __cplusplus - Junction *altstart; -#else - struct _junct *altstart; -#endif - char *el_label; /* el_label:rrnode */ - ExceptionGroup *ex_group; /* any exception[el_label] attached? */ -#ifdef __cplusplus - }; -#else - } RuleRefNode; -#endif - -#ifdef __cplusplus -class Junction : public Node { -public: -#else -typedef struct _junct { - NodeType ntype; - char *rname; /* name of rule junction is in */ - int file; /* index in FileStr (name of file with rule) - if blk == RuleBlk */ - int line; /* line number that rule occurs on */ -#endif - int seq; /* MR10 sequence number */ - char ignore; /* used by FIRST computation to ignore - empty alt added for the (...)+ blks */ - char visited; /* used by recursive routines to avoid - infinite recursion */ - char pvisited; /* used by print routines to avoid - infinite recursion */ - char fvisited; /* used by FoLink() to avoid - infinite recursion */ - char *lock; /* used by REACH to track infinite recursion */ - char *pred_lock; /* used by find_predicates to track infinite recursion */ - int altnum; /* used in subblocks. altnum==0 means not an - alt of subrule */ - int jtype; /* annotation for code-gen/FIRST/FOLLOW. - Junction type */ -#ifdef __cplusplus - Junction *end; /* pointer to node with EndBlk in it - if blk == a block type */ -#else - struct _junct *end; /* pointer to node with EndBlk in it - if blk == a block type */ -#endif - Node *p1, *p2; - char halt; /* never move past a junction with halt==TRUE */ /* MR10 was int */ - char *pdecl; /* point to declaration of parameters on rule - (if present) */ - char *parm; /* point to parameter of block invocation - (if present) */ - char predparm; /* indicates that the 'parm' is a predicate - * to be used in the while loop generated - * for blocks */ /* MR10 was int */ - char *ret; /* point to return type of rule (if present) */ - char *erraction; /* point to error action (if present) */ - int blockid; /* this is a unique ID */ - char *exception_label; /* goto label for this alt */ - set *fset; /* used for code generation */ - Tree *ftree; /* used for code generation */ - Predicate *predicate;/* predicate that can be used to disambiguate */ - char guess; /* true if (...)? block */ - char alpha_beta_guess_end; /* MR14 1 => end block of guess sub block */ - Node *guess_analysis_point; /* MR14 */ - char approx; /* limit block to use linear approx lookahead? */ - set tokrefs; /* if ith element of alt is tokref then i is member */ - set rulerefs; /* if ith element of alt is rule ref then i is member */ - struct _ListNode *exceptions; /* list of exceptions groups for rule */ - struct _ListNode *el_labels; /* list of element labels for rule */ - ExceptionGroup *outerEG; /* MR7 */ - int curAltNum; /* MR7 */ - char* pFirstSetSymbol; /* #pragma FirstSetSymbol(Foo) MR21 */ -#ifdef __cplusplus - Junction *pendingLink; /* MR7 */ -#else - struct _junct *pendingLink; /* MR7 */ -#endif - char overlap_warning; /* MR10 */ -#ifdef __cplusplus - }; -#else - } Junction; -#endif - -typedef struct { Node *left, *right;} Graph; - diff --git a/Tools/CodeTools/TianoTools/Pccts/antlr/tokens.h b/Tools/CodeTools/TianoTools/Pccts/antlr/tokens.h deleted file mode 100644 index 91a53a8471..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/antlr/tokens.h +++ /dev/null @@ -1,246 +0,0 @@ -#ifndef tokens_h -#define tokens_h -/* tokens.h -- List of labelled tokens and stuff - * - * Generated from: antlr.g - * - * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001 - * Purdue University Electrical Engineering - * ANTLR Version 1.33MR33 - */ -#define zzEOF_TOKEN 1 -#define Eof 1 -#define QuotedTerm 2 -#define Action 34 -#define Pred 35 -#define PassAction 36 -#define WildCard 87 -#define LABEL 89 -#define Pragma 92 -#define FirstSetSymbol 93 -#define NonTerminal 100 -#define TokenTerm 101 -#define ID 148 -#define INT 150 - -#ifdef __USE_PROTOS -void grammar(void); -#else -extern void grammar(); -#endif - -#ifdef __USE_PROTOS -void class_def(void); -#else -extern void class_def(); -#endif - -#ifdef __USE_PROTOS -void rule(void); -#else -extern void rule(); -#endif - -#ifdef __USE_PROTOS -void laction(void); -#else -extern void laction(); -#endif - -#ifdef __USE_PROTOS -void lmember(void); -#else -extern void lmember(); -#endif - -#ifdef __USE_PROTOS -void lprefix(void); -#else -extern void lprefix(); -#endif - -#ifdef __USE_PROTOS -void aPred(void); -#else -extern void aPred(); -#endif - -#ifdef __USE_PROTOS -extern Predicate * predOrExpr(void); -#else -extern Predicate * predOrExpr(); -#endif - -#ifdef __USE_PROTOS -extern Predicate * predAndExpr(void); -#else -extern Predicate * predAndExpr(); -#endif - -#ifdef __USE_PROTOS -extern Predicate * predPrimary(void); -#else -extern Predicate * predPrimary(); -#endif - -#ifdef __USE_PROTOS -void aLexclass(void); -#else -extern void aLexclass(); -#endif - -#ifdef __USE_PROTOS -void error(void); -#else -extern void error(); -#endif - -#ifdef __USE_PROTOS -void tclass(void); -#else -extern void tclass(); -#endif - -#ifdef __USE_PROTOS -void token(void); -#else -extern void token(); -#endif - -#ifdef __USE_PROTOS -void block(set * toksrefd,set * rulesrefd); -#else -extern void block(); -#endif - -#ifdef __USE_PROTOS -void alt(set * toksrefd,set * rulesrefd); -#else -extern void alt(); -#endif - -#ifdef __USE_PROTOS -extern LabelEntry * element_label(void); -#else -extern LabelEntry * element_label(); -#endif - -#ifdef __USE_PROTOS -extern Node * element(int old_not,int first_on_line,int use_def_MT_handler); -#else -extern Node * element(); -#endif - -#ifdef __USE_PROTOS -void default_exception_handler(void); -#else -extern void default_exception_handler(); -#endif - -#ifdef __USE_PROTOS -extern ExceptionGroup * exception_group(void); -#else -extern ExceptionGroup * exception_group(); -#endif - -#ifdef __USE_PROTOS -extern ExceptionHandler * exception_handler(void); -#else -extern ExceptionHandler * exception_handler(); -#endif - -#ifdef __USE_PROTOS -void enum_file(char * fname); -#else -extern void enum_file(); -#endif - -#ifdef __USE_PROTOS -void defines(char * fname); -#else -extern void defines(); -#endif - -#ifdef __USE_PROTOS -void enum_def(char * fname); -#else -extern void enum_def(); -#endif - -#endif -extern SetWordType zzerr1[]; -extern SetWordType zzerr2[]; -extern SetWordType zzerr3[]; -extern SetWordType zzerr4[]; -extern SetWordType setwd1[]; -extern SetWordType zzerr5[]; -extern SetWordType zzerr6[]; -extern SetWordType zzerr7[]; -extern SetWordType zzerr8[]; -extern SetWordType zzerr9[]; -extern SetWordType setwd2[]; -extern SetWordType zzerr10[]; -extern SetWordType zzerr11[]; -extern SetWordType zzerr12[]; -extern SetWordType zzerr13[]; -extern SetWordType setwd3[]; -extern SetWordType zzerr14[]; -extern SetWordType zzerr15[]; -extern SetWordType zzerr16[]; -extern SetWordType zzerr17[]; -extern SetWordType zzerr18[]; -extern SetWordType zzerr19[]; -extern SetWordType zzerr20[]; -extern SetWordType zzerr21[]; -extern SetWordType setwd4[]; -extern SetWordType zzerr22[]; -extern SetWordType zzerr23[]; -extern SetWordType zzerr24[]; -extern SetWordType zzerr25[]; -extern SetWordType zzerr26[]; -extern SetWordType setwd5[]; -extern SetWordType zzerr27[]; -extern SetWordType zzerr28[]; -extern SetWordType zzerr29[]; -extern SetWordType zzerr30[]; -extern SetWordType zzerr31[]; -extern SetWordType zzerr32[]; -extern SetWordType zzerr33[]; -extern SetWordType setwd6[]; -extern SetWordType zzerr34[]; -extern SetWordType zzerr35[]; -extern SetWordType zzerr36[]; -extern SetWordType zzerr37[]; -extern SetWordType zzerr38[]; -extern SetWordType zzerr39[]; -extern SetWordType zzerr40[]; -extern SetWordType zzerr41[]; -extern SetWordType zzerr42[]; -extern SetWordType setwd7[]; -extern SetWordType zzerr43[]; -extern SetWordType zzerr44[]; -extern SetWordType zzerr45[]; -extern SetWordType zzerr46[]; -extern SetWordType zzerr47[]; -extern SetWordType zzerr48[]; -extern SetWordType zzerr49[]; -extern SetWordType zzerr50[]; -extern SetWordType zzerr51[]; -extern SetWordType zzerr52[]; -extern SetWordType zzerr53[]; -extern SetWordType setwd8[]; -extern SetWordType zzerr54[]; -extern SetWordType zzerr55[]; -extern SetWordType zzerr56[]; -extern SetWordType zzerr57[]; -extern SetWordType setwd9[]; -extern SetWordType zzerr58[]; -extern SetWordType zzerr59[]; -extern SetWordType zzerr60[]; -extern SetWordType zzerr61[]; -extern SetWordType zzerr62[]; -extern SetWordType zzerr63[]; -extern SetWordType zzerr64[]; -extern SetWordType zzerr65[]; -extern SetWordType setwd10[]; -extern SetWordType setwd11[]; diff --git a/Tools/CodeTools/TianoTools/Pccts/build.xml b/Tools/CodeTools/TianoTools/Pccts/build.xml deleted file mode 100644 index 4f4e0a9e7c..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/build.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/Pccts/dlg/DlgMS.mak b/Tools/CodeTools/TianoTools/Pccts/dlg/DlgMS.mak deleted file mode 100644 index 4a9019b1c6..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/dlg/DlgMS.mak +++ /dev/null @@ -1,121 +0,0 @@ -# PCCTS directory - -# You will need to set the LIB variable similar to this. -# LIB="C:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/lib;c:/Microsoft Visual Studio .NET 2003/Vc7/PlatformSDK/Lib" - -# PCCTS_HOME= -PCCTS_HOME=$(WORKSPACE)\Tools\Source\TianoTools\Pccts -DLG_SRC=$(PCCTS_HOME)\dlg -PCCTS_H=$(PCCTS_HOME)\h - - -# Support directories -SET=$(PCCTS_HOME)\support\set - - -# Compiler stuff -CC = cl -CFLAGS = /nologo -I "." -I "$(PCCTS_H)" -I "$(SET)" -D "USER_ZZSYN" -D "PC" \ - -D "ZZLEXBUFSIZE=65536" /D "LONGFILENAMES" /W3 /Zi - -DLG_OBJS = dlg_p.obj dlg_a.obj main.obj err.obj support.obj \ - output.obj relabel.obj automata.obj - -SUPPORT_OBJS = set.obj - -# Dependencies - -dlg.exe: $(DLG_OBJS) $(SUPPORT_OBJS) - $(CC) $(CFLAGS) -o dlg.exe $(DLG_OBJS) $(SUPPORT_OBJS) - del *.obj - del *.ilk - del *.pdb - move dlg.exe $(WORKSPACE)\Tools\bin\. - -dlg_p.obj: $(DLG_SRC)\dlg_p.c \ - $(PCCTS_H)\antlr.h \ - $(PCCTS_H)\config.h \ - $(PCCTS_H)\dlgdef.h \ - $(SET)\set.h \ - $(DLG_SRC)\dlg.h \ - $(DLG_SRC)\mode.h \ - $(DLG_SRC)\tokens.h \ - - $(CC) -c $(CFLAGS) $(DLG_SRC)\dlg_p.c - -dlg_a.obj: $(DLG_SRC)\dlg_a.c \ - $(PCCTS_H)\antlr.h \ - $(PCCTS_H)\config.h \ - $(PCCTS_H)\dlgauto.h \ - $(PCCTS_H)\dlgdef.h \ - $(SET)\set.h \ - $(DLG_SRC)\dlg.h \ - $(DLG_SRC)\mode.h \ - $(DLG_SRC)\tokens.h \ - - $(CC) -c $(CFLAGS) $(DLG_SRC)\dlg_a.c - -main.obj: $(DLG_SRC)\main.c \ - $(PCCTS_H)\antlr.h \ - $(PCCTS_H)\config.h \ - $(PCCTS_H)\dlgdef.h \ - $(SET)\set.h \ - $(DLG_SRC)\dlg.h \ - $(DLG_SRC)\mode.h \ - $(DLG_SRC)\stdpccts.h \ - $(DLG_SRC)\tokens.h \ - - $(CC) -c $(CFLAGS) $(DLG_SRC)\main.c - -err.obj: $(DLG_SRC)\err.c \ - $(PCCTS_H)\antlr.h \ - $(PCCTS_H)\config.h \ - $(PCCTS_H)\dlgdef.h \ - $(PCCTS_H)\err.h \ - $(SET)\set.h \ - $(DLG_SRC)\dlg.h \ - $(DLG_SRC)\tokens.h \ - - $(CC) -c $(CFLAGS) $(DLG_SRC)\err.c - -support.obj: $(DLG_SRC)\support.c \ - $(PCCTS_H)\config.h \ - $(SET)\set.h \ - $(DLG_SRC)\dlg.h \ - - $(CC) -c $(CFLAGS) $(DLG_SRC)\support.c - -output.obj: $(DLG_SRC)\output.c \ - $(PCCTS_H)\config.h \ - $(SET)\set.h \ - $(DLG_SRC)\dlg.h \ - - $(CC) -c $(CFLAGS) $(DLG_SRC)\output.c - -relabel.obj: $(DLG_SRC)\relabel.c \ - $(PCCTS_H)\config.h \ - $(SET)\set.h \ - $(DLG_SRC)\dlg.h \ - - $(CC) -c $(CFLAGS) $(DLG_SRC)\relabel.c - -automata.obj: $(DLG_SRC)\automata.c \ - $(PCCTS_H)\config.h \ - $(SET)\set.h \ - $(DLG_SRC)\dlg.h \ - - $(CC) -c $(CFLAGS) $(DLG_SRC)\automata.c - - -set.obj: $(SET)\set.c \ - $(PCCTS_H)\config.h \ - $(SET)\set.h \ - - $(CC) -c $(CFLAGS) $(SET)\set.c - -clean: - del *.obj - -distclean: - del *.obj - del $(WORKSPACE)\Tools\bin\dlg.exe diff --git a/Tools/CodeTools/TianoTools/Pccts/dlg/DlgPPC.mak b/Tools/CodeTools/TianoTools/Pccts/dlg/DlgPPC.mak deleted file mode 100644 index 55b643ad88..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/dlg/DlgPPC.mak +++ /dev/null @@ -1,84 +0,0 @@ -# File: dlgPPC.make -# Target: dlgPPC -# Sources: automata.c -# dlg_a.c -# dlg_p.c -# err.c -# main.c -# output.c -# relabel.c -# support.c -# ::support:set:set.c -# Created: Sunday, May 17, 1998 11:34:20 PM -# Author: Kenji Tanaka - - -MAKEFILE = dlgPPC.make -Â¥MondoBuildÂ¥ = {MAKEFILE} # Make blank to avoid rebuilds when makefile is modified -Includes = ¶ - -i "::h:" ¶ - -i "::support:set:" -SymÂ¥PPC = -ObjDirÂ¥PPC = ":Obj:" - -PPCCOptions = {Includes} {SymÂ¥PPC} -w off -d MPW -d __STDC__=1 -d USER_ZZSYN - -ObjectsÂ¥PPC = ¶ - "{ObjDirÂ¥PPC}automata.c.x" ¶ - "{ObjDirÂ¥PPC}dlg_a.c.x" ¶ - "{ObjDirÂ¥PPC}dlg_p.c.x" ¶ - "{ObjDirÂ¥PPC}err.c.x" ¶ - "{ObjDirÂ¥PPC}main.c.x" ¶ - "{ObjDirÂ¥PPC}output.c.x" ¶ - "{ObjDirÂ¥PPC}relabel.c.x" ¶ - "{ObjDirÂ¥PPC}support.c.x" ¶ - "{ObjDirÂ¥PPC}set.c.x" - - -dlgPPC ÄÄ {Â¥MondoBuildÂ¥} {ObjectsÂ¥PPC} - PPCLink ¶ - -o {Targ} {SymÂ¥PPC} ¶ - {ObjectsÂ¥PPC} ¶ - -t 'MPST' ¶ - -c 'MPS ' ¶ - "{SharedLibraries}InterfaceLib" ¶ - "{SharedLibraries}StdCLib" ¶ - "{SharedLibraries}MathLib" ¶ - "{PPCLibraries}StdCRuntime.o" ¶ - "{PPCLibraries}PPCCRuntime.o" ¶ - "{PPCLibraries}PPCToolLibs.o" - - -"{ObjDirÂ¥PPC}automata.c.x" Ä {Â¥MondoBuildÂ¥} automata.c - {PPCC} automata.c -o {Targ} {PPCCOptions} - -"{ObjDirÂ¥PPC}dlg_a.c.x" Ä {Â¥MondoBuildÂ¥} dlg_a.c - {PPCC} dlg_a.c -o {Targ} {PPCCOptions} - -"{ObjDirÂ¥PPC}dlg_p.c.x" Ä {Â¥MondoBuildÂ¥} dlg_p.c - {PPCC} dlg_p.c -o {Targ} {PPCCOptions} - -"{ObjDirÂ¥PPC}err.c.x" Ä {Â¥MondoBuildÂ¥} err.c - {PPCC} err.c -o {Targ} {PPCCOptions} - -"{ObjDirÂ¥PPC}main.c.x" Ä {Â¥MondoBuildÂ¥} main.c - {PPCC} main.c -o {Targ} {PPCCOptions} - -"{ObjDirÂ¥PPC}output.c.x" Ä {Â¥MondoBuildÂ¥} output.c - {PPCC} output.c -o {Targ} {PPCCOptions} - -"{ObjDirÂ¥PPC}relabel.c.x" Ä {Â¥MondoBuildÂ¥} relabel.c - {PPCC} relabel.c -o {Targ} {PPCCOptions} - -"{ObjDirÂ¥PPC}support.c.x" Ä {Â¥MondoBuildÂ¥} support.c - {PPCC} support.c -o {Targ} {PPCCOptions} - -"{ObjDirÂ¥PPC}set.c.x" Ä {Â¥MondoBuildÂ¥} "::support:set:set.c" - {PPCC} "::support:set:set.c" -o {Targ} {PPCCOptions} - - -dlgPPC ÄÄ dlg.r - Rez dlg.r -o dlgPPC -a - -Install Ä dlgPPC - Duplicate -y dlgPPC "{MPW}"Tools:dlg diff --git a/Tools/CodeTools/TianoTools/Pccts/dlg/automata.c b/Tools/CodeTools/TianoTools/Pccts/dlg/automata.c deleted file mode 100644 index d6d5d7809d..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/dlg/automata.c +++ /dev/null @@ -1,353 +0,0 @@ -/* Automata conversion functions for DLG - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * DLG 1.33 - * Will Cohen - * With mods by Terence Parr; AHPCRC, University of Minnesota - * 1989-2001 - */ - -#include -#include "pcctscfg.h" -#include "dlg.h" -#ifdef MEMCHK -#include "trax.h" -#else -#ifdef __STDC__ -#include -#else -#include -#endif /* __STDC__ */ -#endif - -#define hash_list struct _hash_list_ -hash_list{ - hash_list *next; /* next thing in list */ - dfa_node *node; - }; - -int dfa_allocated = 0; /* keeps track of number of dfa nodes */ -dfa_node **dfa_array; /* root of binary tree that stores dfa array */ -dfa_node *dfa_model_node; -hash_list *dfa_hash[HASH_SIZE]; /* used to quickly find */ - /* desired dfa node */ - -void -#ifdef __USE_PROTOS -make_dfa_model_node(int width) -#else -make_dfa_model_node(width) -int width; -#endif -{ - register int i; - dfa_model_node = (dfa_node*) malloc(sizeof(dfa_node) - + sizeof(int)*width); - dfa_model_node->node_no = -1; /* impossible value for real dfa node */ - dfa_model_node->dfa_set = 0; - dfa_model_node->alternatives = FALSE; - dfa_model_node->done = FALSE; - dfa_model_node->nfa_states = empty; - for(i = 0; itrans[i] = NIL_INDEX; - } -} - - -/* adds a new nfa to the binary tree and returns a pointer to it */ -dfa_node * -#ifdef __USE_PROTOS -new_dfa_node(set nfa_states) -#else -new_dfa_node(nfa_states) -set nfa_states; -#endif -{ - register int j; - register dfa_node *t; - static int dfa_size=0; /* elements dfa_array[] can hold */ - - ++dfa_allocated; - if (dfa_size<=dfa_allocated){ - /* need to redo array */ - if (!dfa_array){ - /* need some to do inital allocation */ - dfa_size=dfa_allocated+DFA_MIN; - dfa_array=(dfa_node **) malloc(sizeof(dfa_node*)* - dfa_size); - }else{ - /* need more space */ - dfa_size=2*(dfa_allocated+1); - dfa_array=(dfa_node **) realloc(dfa_array, - sizeof(dfa_node*)*dfa_size); - } - } - /* fill out entry in array */ - t = (dfa_node*) malloc(sizeof(nfa_node)+sizeof(int)*class_no); - *t = *dfa_model_node; - for (j=0; jtrans[j] = NIL_INDEX; - t->node_no = dfa_allocated; - t->nfa_states = set_dup(nfa_states); - dfa_array[dfa_allocated] = t; - return t; -} - - -/* past a pointer to the start start of the nfa graph - * nfa_to_dfa convers this graph to dfa. The function returns - * a pointer to the first dfa state. - * NOTE: The function that prints out the table will have to figure out how - * to find the other dfa states given the first dfa_state and the number of dfa - * nodes allocated - */ -dfa_node ** -#ifdef __USE_PROTOS -nfa_to_dfa(nfa_node *start) -#else -nfa_to_dfa(start) -nfa_node *start; -#endif -{ - register dfa_node *d_state, *trans_d_state; - register int a; - set t; - int last_done; - unsigned *nfa_list; - unsigned *reach_list; - - reach_list = (unsigned *) malloc((2+nfa_allocated)*sizeof(unsigned)); - if (!start) return NULL; - t = set_of(NFA_NO(start)); - _set_pdq(t,reach_list); - closure(&t,reach_list); - /* Make t a dfa state */ - d_state = dfastate(t); - last_done = DFA_NO(d_state); - - do { - /* Mark dfa state x as "done" */ - d_state->done = TRUE; - nfa_list = set_pdq(d_state->nfa_states); - for (a = 0; at, labeled with a */ - d_state->trans[a] = DFA_NO(trans_d_state); - d_state->alternatives = TRUE; - } - } - free(nfa_list); - ++last_done; /* move forward in queue */ - /* And so forth until nothing isn't done */ - d_state = DFA(last_done); - } while (last_done<=dfa_allocated); - - free(reach_list); - set_free(t); - - /* returns pointer to the array that holds the automaton */ - return dfa_array; -} - -void -#ifdef __USE_PROTOS -clear_hash(void) -#else -clear_hash() -#endif -{ - register int i; - - for(i=0; inext; - } - total+=j; - fprintf(f,"bin[%d] has %d\n",i,j); - } - fprintf(f,"total = %d\n",total); -} -#endif - -/* Returns a pointer to a dfa node that has the same nfa nodes in it. - * This may or maynot be a newly created node. - */ -dfa_node * -#ifdef __USE_PROTOS -dfastate(set nfa_states) -#else -dfastate(nfa_states) -set nfa_states; -#endif -{ - register hash_list *p; - int bin; - - /* hash using set and see if it exists */ - bin = set_hash(nfa_states,HASH_SIZE); - p = dfa_hash[bin]; - while(p && !set_equ(nfa_states,(p->node)->nfa_states)){ - p = p->next; - } - if(!p){ - /* next state to add to hash table */ - p = (hash_list*)malloc(sizeof(hash_list)); - p->node = new_dfa_node(nfa_states); - p->next = dfa_hash[bin]; - dfa_hash[bin] = p; - } - return (p->node); -} - - -/* this reach assumes the closure has been done already on set */ -int -#ifdef __USE_PROTOS -reach(unsigned *nfa_list, register int a, unsigned *reach_list) -#else -reach(nfa_list, a, reach_list) -unsigned *nfa_list; -register int a; -unsigned *reach_list; -#endif -{ - register unsigned *e; - register nfa_node *node; - int t=0; - - e = nfa_list; - if (e){ - while (*e != nil){ - node = NFA(*e); - if (set_el(a,node->label)){ - t=1; - *reach_list=NFA_NO(node->trans[0]); - ++reach_list; - } - ++e; - } - } - *reach_list=nil; - return t; -} - -/* finds all the nodes that can be reached by epsilon transitions - from the set of a nodes and returns puts them back in set b */ -set -#ifdef __USE_PROTOS -closure(set *b, unsigned *reach_list) -#else -closure(b, reach_list) -set *b; -unsigned *reach_list; -#endif -{ - register nfa_node *node,*n; /* current node being examined */ - register unsigned *e; - - ++operation_no; -#if 0 - t = e = set_pdq(*b); -#else - e=reach_list; -#endif - while (*e != nil){ - node = NFA(*e); - set_orel(NFA_NO(node),b); - /* mark it done */ - node->nfa_set = operation_no; - if ((n=node->trans[0]) != NIL_INDEX && set_nil(node->label) && - (n->nfa_set != operation_no)){ - /* put in b */ - set_orel(NFA_NO(n),b); - close1(n,operation_no,b); - } - if ((n=node->trans[1]) != NIL_INDEX && - (n->nfa_set != operation_no)){ - /* put in b */ - set_orel(NFA_NO(node->trans[1]),b); - close1(n,operation_no,b); - } - ++e; - } -#if 0 - free(t); -#endif - return *b; -} - -#ifdef __USE_PROTOS -void close1(nfa_node *node, int o, set *b) -#else -void close1(node,o,b) -nfa_node *node; -int o; /* marker to avoid cycles */ -set *b; -#endif -{ - register nfa_node *n; /* current node being examined */ - - /* mark it done */ - node->nfa_set = o; - if ((n=node->trans[0]) != NIL_INDEX && set_nil(node->label) && - (n->nfa_set != o)){ - /* put in b */ - set_orel(NFA_NO(n),b); - close1(n,o,b); - } - if ((n=node->trans[1]) != NIL_INDEX && - (n->nfa_set != o)){ - /* put in b */ - set_orel(NFA_NO(node->trans[1]),b); - close1(n,o,b); - } -} diff --git a/Tools/CodeTools/TianoTools/Pccts/dlg/build.xml b/Tools/CodeTools/TianoTools/Pccts/dlg/build.xml deleted file mode 100644 index 4195950c7b..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/dlg/build.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/Pccts/dlg/dlg.1 b/Tools/CodeTools/TianoTools/Pccts/dlg/dlg.1 deleted file mode 100644 index f68e3ae8a7..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/dlg/dlg.1 +++ /dev/null @@ -1,79 +0,0 @@ -.TH dlg 1 "April 1994" "DLG" "PCCTS Manual Pages" -.SH NAME -dlg \- DFA Lexical Analyzer Generator -.SH SYNTAX -.LP -\fBdlg\fR [\fIoptions\fR] \fIlexical_spec\fR [\fIoutput_file\fR] -.SH DESCRIPTION -.B dlg -is a tool that produces fast deterministic finite automata for recognizing -regular expressions in input. -.SH OPTIONS -.IP "\fB-CC\fR" -Generate C++ output. The \fIoutput_file\fP is not specified in this -case. -.IP "\fB-C\fR[\fP level\fR] -Where \fPlevel\fR is the compression level used. 0 indications no -compression, 1 removes all unused characters from the transition from table, -and 2 maps equivalent characters into the same character classes. It is -suggested that level -C2 is used, since it will significantly reduce the size -of the dfa produced for lexical analyzer. -.IP "\fB-m\fP -Produces the header file for the lexical mode with a name other than -the default name of "mode.h". -.IP \fB-i\fP -An interactive, or as interactive as possible, parser is produced. A character -is only obtained when required to decide which state to go to. Some care -must be taken to obtain accept states that do not require look ahead at the -next character to determine if that is the stop state. Any regular expression -with a Kleene closure at the end is guaranteed to require another character -of look ahead. -.IP "\fB-cl\fP class -Specify a class name for DLG to generate. The default is DLGLexer. -'class' will be a subclass of DLGLexerBase; only used for -CC. -.IP \fB-ci\fP -The automaton will treat upper and lower case characters identically. -This is accomplished in the automaton; the characters in the lexical -buffer are unmodified. -.IP \fB-cs\fP -Upper and lower case characters are treated as distinct. This is the -default. -.IP "\fB-o\fP dir -Directory where output files should go (default="."). This is very -nice for keeping the source directory clear of ANTLR and DLG spawn. -.IP \fB-Wambiguity\fP -Warns if more than one regular expression could match the same character -sequence. The warnings give the numbers of the expressions in the dlg -lexical specification file. The numbering of the expressions starts at one. -Multiple warnings may be print for the same expressions. -.IP \- -Used in place of file names to get input from standard in or send output -to standard out. -.SH "SPECIAL CONSIDERATIONS" -.PP -\fIDlg\fP works... we think. There is no implicit guarantee of -anything. We reserve no \fBlegal\fP rights to the software known as -the Purdue Compiler Construction Tool Set (PCCTS) \(em PCCTS is in the -public domain. An individual or company may do whatever they wish -with source code distributed with PCCTS or the code generated by -PCCTS, including the incorporation of PCCTS, or its output, into -commercial software. We encourage users to develop software with -PCCTS. However, we do ask that credit is given to us for developing -PCCTS. By "credit", we mean that if you incorporate our source code -into one of your programs (commercial product, research project, or -otherwise) that you acknowledge this fact somewhere in the -documentation, research report, etc... If you like PCCTS and have -developed a nice tool with the output, please mention that you -developed it using PCCTS. As long as these guidelines are followed, we -expect to continue enhancing this system and expect to make other -tools available as they are completed. -.SH FILES -.B mode.h -, -.B dlgauto.h -, -.B dlgdef.h -.SH SEE ALSO -.BR antlr (1), -.BR pccts (1) -.SH BUGS diff --git a/Tools/CodeTools/TianoTools/Pccts/dlg/dlg.h b/Tools/CodeTools/TianoTools/Pccts/dlg/dlg.h deleted file mode 100644 index 9f387c0a1c..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/dlg/dlg.h +++ /dev/null @@ -1,250 +0,0 @@ -/* dlg header file - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * DLG 1.33 - * Will Cohen - * With mods by Terence Parr; AHPCRC, University of Minnesota - * 1989-2001 - */ - -/* MR1 Move pcctscfg.h to top of file */ - -#include "pcctscfg.h" - -/* turn off warnings for unreferenced labels */ - -#ifdef _MSC_VER -#pragma warning(disable:4102) -#endif - -#include "set.h" - -#define TRUE 1 -#define FALSE 0 - -/***** output related stuff *******************/ -#define IN input_stream -#define OUT output_stream - -#define MAX_MODES 50 /* number of %%names allowed */ -#define MAX_ON_LINE 10 - -#define NFA_MIN 64 /* minimum nfa_array size */ -#define DFA_MIN 64 /* minimum dfa_array size */ - -#define DEFAULT_CLASSNAME "DLGLexer" - -/* these macros allow the size of the character set to be easily changed */ -/* NOTE: do NOT change MIN_CHAR since EOF is the lowest char, -1 */ -#define MIN_CHAR (-1) /* lowest possible character possible on input */ -#define MAX_CHAR 255 /* highest possible character possible on input */ -#define CHAR_RANGE (1+(MAX_CHAR) - (MIN_CHAR)) - -/* indicates that the not an "array" reference */ -#define NIL_INDEX 0 - -/* size of hash table used to find dfa_states quickly */ -#define HASH_SIZE 211 - -#define nfa_node struct _nfa_node -nfa_node { - int node_no; - int nfa_set; - int accept; /* what case to use */ - nfa_node *trans[2]; - set label; /* one arc always labelled with epsilon */ -}; - -#define dfa_node struct _dfa_node -dfa_node { - int node_no; - int dfa_set; - int alternatives; /* used for interactive mode */ - /* are more characters needed */ - int done; - set nfa_states; - int trans[1];/* size of transition table depends on - * number of classes required for automata. - */ - - -}; - -/******** macros for accessing the NFA and DFA nodes ****/ -#define NFA(x) (nfa_array[x]) -#define DFA(x) (dfa_array[x]) -#define DFA_NO(x) ( (x) ? (x)->node_no : NIL_INDEX) -#define NFA_NO(x) ( (x) ? (x)->node_no : NIL_INDEX) - -/******** wrapper for memory checking ***/ -/*#define malloc(x) dlg_malloc((x),__FILE__,__LINE__)*/ - -/*#define calloc(x,y) dlg_calloc((x),(y),__FILE__,__LINE__)*/ - -/******** antlr attributes *************/ -typedef struct { - unsigned char letter; - nfa_node *l,*r; - set label; - } Attrib; - -#define zzcr_attr(attr, token, text) { \ - (attr)->letter = text[0]; (attr)->l = NULL; \ - (attr)->r = NULL; (attr)->label = empty; \ -} -#define zzd_attr(a) set_free((a)->label); - -/******************** Variable ******************************/ -extern char program[]; /* tells what program this is */ -extern char version[]; /* tells what version this is */ -extern char *file_str[]; /* file names being used */ -extern int err_found; /* flag to indicate error occured */ -extern int action_no; /* last action function printed */ -extern int func_action; /* should actions be turned into functions?*/ -extern set used_chars; /* used to label trans. arcs */ -extern set used_classes; /* classes or chars used to label trans. arcs */ -extern int class_no; /* number of classes used */ -extern set class_sets[]; /* shows char. in each class */ -extern set normal_chars; /* mask off unused portion of set */ -extern int comp_level; /* what compression level to use */ -extern int interactive; /* interactive scanner (avoid lookahead)*/ -extern int mode_counter; /* keeps track of the number of %%name */ -extern int dfa_basep[]; /* start of each group of dfa */ -extern int dfa_class_nop[];/* number of transistion arcs in */ - /* each dfa in each mode */ -extern int nfa_allocated; -extern int dfa_allocated; -extern nfa_node **nfa_array; /* start of nfa "array" */ -extern dfa_node **dfa_array; /* start of dfa "array" */ -extern int operation_no; /* unique number for each operation */ -extern FILE *input_stream; /* where description read from */ -extern FILE *output_stream; /* where to put the output */ -extern FILE *mode_stream; /* where to put the mode output */ -extern FILE *class_stream; -extern char *mode_file; /* name of file for mode output */ -extern int gen_ansi; /* produce ansi compatible code */ -extern int case_insensitive;/* ignore case of input spec. */ -extern int warn_ambig; /* show if regular expressions ambiguous */ -extern int gen_cpp; -extern char *cl_file_str; -extern int firstLexMember; /* MR1 */ -extern char *OutputDirectory; -extern char *class_name; - -/******************** Functions ******************************/ -#ifdef __USE_PROTOS -extern char *dlg_malloc(int, char *, int); /* wrapper malloc */ -extern char *dlg_calloc(int, int, char *, int); /* wrapper calloc */ -extern int reach(unsigned *, register int, unsigned *); -extern set closure(set *, unsigned *); -extern dfa_node *new_dfa_node(set); -extern nfa_node *new_nfa_node(void); -extern dfa_node *dfastate(set); -extern dfa_node **nfa_to_dfa(nfa_node *); -extern void internal_error(char *, char *, int); /* MR9 23-Sep-97 */ -extern FILE *read_stream(char *); /* opens file for reading */ -extern FILE *write_stream(char *); /* opens file for writing */ -extern void make_nfa_model_node(void); -extern void make_dfa_model_node(int); -extern char *ClassName(char *); -extern char *OutMetaName(char *); -extern void error(char*, int); -extern void warning(char*, int); -extern void p_head(void); -extern void p_class_hdr(void); -extern void p_includes(void); -extern void p_tables(void); -extern void p_tail(void); /* MR1 */ -extern void p_class_def1(void); /* MR1 */ -extern void new_automaton_mode(void); /* MR1 */ -extern int relabel(nfa_node *,int); /* MR1 */ -extern void p_shift_table(int); /* MR1 */ -extern void p_bshift_table(void); /* MR1 */ -extern void p_class_table(void); /* MR1 */ -extern void p_mode_def(char *,int); /* MR1 */ -extern void init(void); /* MR1 */ -extern void p_class_def2(void); /* MR1 */ -extern void clear_hash(void); /* MR1 */ -extern void p_alternative_table(void); /* MR1 */ -extern void p_node_table(void); /* MR1 */ -extern void p_dfa_table(void); /* MR1 */ -extern void p_accept_table(void); /* MR1 */ -extern void p_action_table(void); /* MR1 */ -extern void p_base_table(void); /* MR1 */ -extern void p_single_node(int,int); /* MR1 */ -extern char * minsize(int); /* MR1 */ -extern void close1(nfa_node *,int,set *); /* MR1 */ -extern void partition(nfa_node *,int); /* MR1 */ -extern void intersect_nfa_labels(nfa_node *,set *); /* MR1 */ -extern void r_intersect(nfa_node *,set *); /* MR1 */ -extern void label_node(nfa_node *); /* MR1 */ -extern void label_with_classes(nfa_node *); /* MR1 */ - -#else -extern char *dlg_malloc(); /* wrapper malloc */ -extern char *dlg_calloc(); /* wrapper calloc */ -extern int reach(); -extern set closure(); -extern dfa_node *new_dfa_node(); -extern nfa_node *new_nfa_node(); -extern dfa_node *dfastate(); -extern dfa_node **nfa_to_dfa(); -extern void internal_error(); /* MR9 23-Sep-97 */ -extern FILE *read_stream(); /* opens file for reading */ -extern FILE *write_stream(); /* opens file for writing */ -extern void make_nfa_model_node(); -extern void make_dfa_model_node(); -extern char *ClassName(); -extern char *OutMetaName(); -extern void error(); -extern void warning(); -extern void p_head(); /* MR9 */ -extern void p_class_hdr(); /* MR9 */ -extern void p_includes(); /* MR9 */ -extern void p_tables(); /* MR9 */ -extern void p_tail(); /* MR1 */ -extern void p_class_def1(); /* MR1 */ -extern void new_automaton_mode(); /* MR1 */ -extern int relabel(); /* MR1 */ -extern void p_shift_table(); /* MR1 */ -extern void p_bshift_table(); /* MR1 */ -extern void p_class_table(); /* MR1 */ -extern void p_mode_def(); /* MR1 */ -extern void init(); /* MR1 */ -extern void p_class_def2(); /* MR1 */ -extern void clear_hash(); /* MR1 */ -extern void p_alternative_table(); /* MR1 */ -extern void p_node_table(); /* MR1 */ -extern void p_dfa_table(); /* MR1 */ -extern void p_accept_table(); /* MR1 */ -extern void p_action_table(); /* MR1 */ -extern void p_base_table(); /* MR1 */ -extern void p_single_node(); /* MR1 */ -extern char * minsize(); /* MR1 */ -extern void close1(); /* MR1 */ -extern void partition(); /* MR1 */ -extern void intersect_nfa_labels(); /* MR1 */ -extern void r_intersect(); /* MR1 */ -extern void label_node(); /* MR1 */ -extern void label_with_classes(); /* MR1 */ - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/dlg/dlg.r b/Tools/CodeTools/TianoTools/Pccts/dlg/dlg.r deleted file mode 100644 index c5311fa1b8..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/dlg/dlg.r +++ /dev/null @@ -1,275 +0,0 @@ -/* - File: dlgMPW.r - Target: dlg 133MR - Created: Monday, June 15, 1998 4:44:11 AM - Author: Kenji Tanaka (kentar@osa.att.ne.jp) -*/ - -#include "cmdo.r" - -resource 'cmdo' (128, "Dlg") { - { /* array dialogs: 1 elements */ - /* [1] */ - 295, - "DLG -- Purdue Compiler Construction Tool" - " Set (PCCTS) lexical analyzer generator.", - { /* array itemArray: 18 elements */ - /* [1] */ - NotDependent { - - }, - CheckOption { - NotSet, - {35, 175, 50, 225}, - "On", - "-CC", - "When this control is checked, DLG genera" - "tes a scanner using C++ classes rather t" - "han C functions." - }, - /* [2] */ - Or { - { /* array OrArray: 1 elements */ - /* [1] */ - 1 - } - }, - RegularEntry { - "Lexer Class Name:", - {35, 225, 50, 355}, - {35, 355, 51, 450}, - "DLGLexer", - keepCase, - "-cl", - "This entry specifies the name DLG uses f" - "or the C++ lexer class." - }, - /* [3] */ - NotDependent { - - }, - TextBox { - gray, - {25, 165, 60, 460}, - "C++ Code Generation" - }, - /* [4] */ - NotDependent { - - }, - Files { - InputFile, - RequiredFile { - {37, 25, 56, 135}, - "Input File", - "", - "Choose the lexical description file for " - "DLG to process." - }, - Additional { - "", - "", - "", - "", - { /* array TypesArray: 1 elements */ - /* [1] */ - text - } - } - }, - /* [5] */ - Or { - { /* array OrArray: 1 elements */ - /* [1] */ - -1 - } - }, - Files { - OutputFile, - RequiredFile { - {66, 25, 85, 135}, - "Output File", - "", - "Choose the name of the file that will ho" - "ld the DLG-produced scanner." - }, - NoMore { - - } - }, - /* [6] */ - Or { - { /* array OrArray: 2 elements */ - /* [1] */ - 1, - /* [2] */ - 5 - } - }, - Dummy { - - }, - /* [7] */ - NotDependent { - - }, - Redirection { - DiagnosticOutput, - {90, 25} - }, - /* [8] */ - NotDependent { - - }, - TextBox { - gray, - {25, 20, 132, 145}, - "Files" - }, - /* [9] */ - NotDependent { - - }, - Files { - DirOnly, - OptionalFile { - {68, 175, 84, 305}, - {88, 175, 107, 305}, - "Output Directory", - ":", - "-o", - "", - "Choose the directory where DLG will put " - "its output.", - dim, - "Output DirectoryI", - "", - "" - }, - NoMore { - - } - }, - /* [10] */ - NotDependent { - - }, - RegularEntry { - "Mode File Name:", - {68, 315, 83, 450}, - {88, 315, 104, 450}, - "mode.h", - keepCase, - "-m", - "This entry specifies the name DLG uses f" - "or its lexical mode output file." - }, - /* [11] */ - NotDependent { - - }, - RadioButtons { - { /* array radioArray: 3 elements */ - /* [1] */ - {134, 175, 149, 255}, "None", "", Set, "When this option is selected, DLG will n" - "ot compress its tables.", - /* [2] */ - {134, 265, 149, 345}, "Level 1", "-C1", NotSet, "When this option is selected, DLG will r" - "emove all unused characters from the tra" - "nsition-from table.", - /* [3] */ - {134, 360, 149, 450}, "Level 2", "-C2", NotSet, "When this option is selected, DLG will p" - "erform level 1 compression plus it will " - "map equivalent characters into the same " - "character classes." - } - }, - /* [12] */ - NotDependent { - - }, - TextBox { - gray, - {124, 165, 156, 460}, - "Table Compression" - }, - /* [13] */ - NotDependent { - - }, - CheckOption { - Set, - {165, 20, 180, 145}, - "Case Sensitive", - "-ci", - "When this control is checked, the DLG au" - "tomaton will treat upper and lower case " - "characters identically." - }, - /* [14] */ - NotDependent { - - }, - CheckOption { - NotSet, - {165, 150, 180, 300}, - "Interactive Scanner", - "-i", - "When this control is checked, DLG will g" - "enerate as interactive a scanner as poss" - "ible." - }, - /* [15] */ - NotDependent { - - }, - CheckOption { - NotSet, - {165, 310, 180, 460}, - "Ambiguity Warnings", - "-Wambiguity", - "When this control is checked, DLG warns " - "if more than one regular expression coul" - "d match the same character sequence." - }, - /* [16] */ - NotDependent { - - }, - VersionDialog { - VersionString { - "1.33MR" - }, - "PCCTS was written by Terence Parr, Russe" - "ll Quong, Will Cohen, and Hank Dietz: 19" - "89-1998. MPW port by Scott Haney.", - noDialog - }, - /* [17] */ - And { - { /* array AndArray: 2 elements */ - /* [1] */ - 4, - /* [2] */ - 6 - } - }, - DoItButton { - - }, - /* [18] */ - NotDependent { - - }, - CheckOption { - NotSet, - {142, 20, 157, 148}, - "Generate ANSI C", - "-ga", - "When this control is checked, DLG genera" - "tes ANSI C compatible code." - } - } - } -}; - diff --git a/Tools/CodeTools/TianoTools/Pccts/dlg/dlg1.txt b/Tools/CodeTools/TianoTools/Pccts/dlg/dlg1.txt deleted file mode 100644 index 06b320de2a..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/dlg/dlg1.txt +++ /dev/null @@ -1,132 +0,0 @@ - - - -dlg(1) PCCTS Manual Pages dlg(1) - - - -NAME - dlg - DFA Lexical Analyzer Generator - -SYNTAX - dlg [_o_p_t_i_o_n_s] _l_e_x_i_c_a_l__s_p_e_c [_o_u_t_p_u_t__f_i_l_e] - -DESCRIPTION - dlg is a tool that produces fast deterministic finite auto- - mata for recognizing regular expressions in input. - -OPTIONS - -CC Generate C++ output. The _o_u_t_p_u_t__f_i_l_e is not specified - in this case. - - -C[ level] - Where level is the compression level used. 0 indica- - tions no compression, 1 removes all unused characters - from the transition from table, and 2 maps equivalent - characters into the same character classes. It is sug- - gested that level -C2 is used, since it will signifi- - cantly reduce the size of the dfa produced for lexical - analyzer. - - -m Produces the header file for the lexical mode with a - name other than the default name of "mode.h". - - -i An interactive, or as interactive as possible, parser - is produced. A character is only obtained when - required to decide which state to go to. Some care - must be taken to obtain accept states that do not - require look ahead at the next character to determine - if that is the stop state. Any regular expression with - a Kleene closure at the end is guaranteed to require - another character of look ahead. - - -cl class - Specify a class name for DLG to generate. The default - is DLGLexer. - - -ci The automaton will treat upper and lower case charac- - ters identically. This is accomplished in the automa- - ton; the characters in the lexical buffer are unmodi- - fied. - - -cs Upper and lower case characters are treated as dis- - tinct. This is the default. - - -o dir - Directory where output files should go (default="."). - This is very nice for keeping the source directory - clear of ANTLR and DLG spawn. - - -Wambiguity - Warns if more than one regular expression could match - the same character sequence. The warnings give the - numbers of the expressions in the dlg lexical specifi- - cation file. The numbering of the expressions starts - at one. Multiple warnings may be print for the same - expressions. - - - Used in place of file names to get input from standard - in or send output to standard out. - -SPECIAL CONSIDERATIONS - _D_l_g works... we think. There is no implicit guarantee of - anything. We reserve no legal rights to the software known - as the Purdue Compiler Construction Tool Set (PCCTS) - PCCTS - is in the public domain. An individual or company may do - whatever they wish with source code distributed with PCCTS - or the code generated by PCCTS, including the incorporation - of PCCTS, or its output, into commercial software. We - encourage users to develop software with PCCTS. However, we - do ask that credit is given to us for developing PCCTS. By - "credit", we mean that if you incorporate our source code - into one of your programs (commercial product, research pro- - ject, or otherwise) that you acknowledge this fact somewhere - in the documentation, research report, etc... If you like - PCCTS and have developed a nice tool with the output, please - mention that you developed it using PCCTS. As long as these - guidelines are followed, we expect to continue enhancing - this system and expect to make other tools available as they - are completed. - -FILES - mode.h , dlgauto.h , dlgdef.h - -SEE ALSO - antlr(1), pccts(1) - -BUGS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/Pccts/dlg/dlg_a.c b/Tools/CodeTools/TianoTools/Pccts/dlg/dlg_a.c deleted file mode 100644 index 0b8982cf2a..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/dlg/dlg_a.c +++ /dev/null @@ -1,1414 +0,0 @@ - -/* parser.dlg -- DLG Description of scanner - * - * Generated from: dlg_p.g - * - * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001 - * Purdue University Electrical Engineering - * With AHPCRC, University of Minnesota - * ANTLR Version 1.33MR33 - */ - -#define ANTLR_VERSION 13333 -#include "pcctscfg.h" -#include "pccts_stdio.h" - -#include -#include "dlg.h" -#include "antlr.h" -#include "tokens.h" -#include "dlgdef.h" -LOOKAHEAD - -void -#ifdef __USE_PROTOS -zzerraction(void) -#else -zzerraction() -#endif -{ - (*zzerr)("invalid token"); - zzadvance(); - zzskip(); -} -/* - * D L G tables - * - * Generated from: parser.dlg - * - * 1989-2001 by Will Cohen, Terence Parr, and Hank Dietz - * Purdue University Electrical Engineering - * DLG Version 1.33MR33 - */ - -#include "mode.h" - - - - -int func_action; /* should actions be turned into functions?*/ -int lex_mode_counter = 0; /* keeps track of the number of %%names */ -/* MR1 */ -/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ -/* MR1 via <<%%lexmember...>> */ -/* MR1 */ -int lexMember = 0; /* <<%%lexmemeber ...>> MR1 */ -int lexAction = 0; /* <<%%lexaction ...>> MR1 */ -int parserClass = 0; /* <<%%parserclass ...>> MR1 */ -int lexPrefix = 0; /* <<%%lexprefix ...>> MR1 */ -char theClassName[100]; /* MR11 */ -char *pClassName=theClassName; /* MR11 */ -int firstLexMember=1; /* MR1 */ - -#ifdef __USE_PROTOS -void xxputc(int c) { /* MR1 */ -#else - void xxputc(c) /* MR1 */ - int c; /* MR1 */ - { /* MR1 */ -#endif - if (parserClass) { /* MR1 */ - *pClassName++=c; /* MR1 */ - *pClassName=0; /* MR1 */ - } else if (lexMember || lexPrefix) { /* MR1 */ - if (class_stream != NULL) fputc(c,class_stream); /* MR1 */ - } else { /* MR1 */ - fputc(c,OUT); /* MR1 */ - }; /* MR1 */ - } /* MR1 */ - -#ifdef __USE_PROTOS - void xxprintf(char *format,char *string) { /* MR1 */ -#else - void xxprintf(format,string) /* MR1 */ - char *format; /* MR1 */ - char *string; /* MR1 */ - { /* MR1 */ -#endif - if (lexMember || lexPrefix || parserClass) { /* MR1 */ - if (class_stream != NULL) /* MR1 */ - fprintf(class_stream,format,string); /* MR1 */ - } else { /* MR1 */ - fprintf(OUT,format,string); /* MR1 */ - }; /* MR1 */ - } /* MR1 */ - -static void act1() -{ - NLA = 1; - } - - -static void act2() -{ - NLA = 2; - zzskip(); - } - - -static void act3() -{ - NLA = 3; - zzline++; zzskip(); DAWDLE; - } - - -static void act4() -{ - NLA = L_EOF; - } - - -static void act5() -{ - NLA = PER_PER; - } - - -static void act6() -{ - NLA = NAME_PER_PER; - p_mode_def(&zzlextext[2],lex_mode_counter++); - } - - -static void act7() -{ - NLA = LEXMEMBER; - lexMember=1; /* MR1 */ - if (firstLexMember != 0) { /* MR1 */ - firstLexMember=0; /* MR1 */ - p_class_def1(); /* MR1 */ - }; /* MR1 */ - zzmode(ACT); /* MR1 */ - } - - -static void act8() -{ - NLA = LEXACTION; - lexAction=1;zzmode(ACT); - } - - -static void act9() -{ - NLA = PARSERCLASS; - parserClass=1; /* MR1 */ - zzmode(ACT); /* MR1 */ - } - - -static void act10() -{ - NLA = LEXPREFIX; - lexPrefix=1;zzmode(ACT); - } - - -static void act11() -{ - NLA = ACTION; - if (func_action) - fprintf(OUT,"\n%s %sact%d()\n{ ", - gen_cpp?"ANTLRTokenType":"static void", - gen_cpp?ClassName("::"):"", ++action_no); - zzmode(ACT); zzskip(); - } - - -static void act12() -{ - NLA = GREAT_GREAT; - } - - -static void act13() -{ - NLA = L_BRACE; - } - - -static void act14() -{ - NLA = R_BRACE; - } - - -static void act15() -{ - NLA = L_PAR; - } - - -static void act16() -{ - NLA = R_PAR; - } - - -static void act17() -{ - NLA = L_BRACK; - } - - -static void act18() -{ - NLA = R_BRACK; - } - - -static void act19() -{ - NLA = ZERO_MORE; - } - - -static void act20() -{ - NLA = ONE_MORE; - } - - -static void act21() -{ - NLA = OR; - } - - -static void act22() -{ - NLA = RANGE; - } - - -static void act23() -{ - NLA = NOT; - } - - -static void act24() -{ - NLA = OCTAL_VALUE; - {int t; sscanf(&zzlextext[1],"%o",&t); zzlextext[0] = t;} - } - - -static void act25() -{ - NLA = HEX_VALUE; - {int t; sscanf(&zzlextext[3],"%x",&t); zzlextext[0] = t;} - } - - -static void act26() -{ - NLA = DEC_VALUE; - {int t; sscanf(&zzlextext[1],"%d",&t); zzlextext[0] = t;} - } - - -static void act27() -{ - NLA = TAB; - zzlextext[0] = '\t'; - } - - -static void act28() -{ - NLA = NL; - zzlextext[0] = '\n'; - } - - -static void act29() -{ - NLA = CR; - zzlextext[0] = '\r'; - } - - -static void act30() -{ - NLA = BS; - zzlextext[0] = '\b'; - } - - -static void act31() -{ - NLA = CONTINUATION; - zzline++; zzskip(); - } - - -static void act32() -{ - NLA = LIT; - zzlextext[0] = zzlextext[1]; - } - - -static void act33() -{ - NLA = REGCHAR; - } - -static unsigned char shift0[257] = { - 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 1, 2, 40, 40, 1, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 1, 40, 40, 40, 40, 4, 40, - 40, 30, 31, 34, 35, 40, 37, 40, 40, 23, - 24, 24, 24, 24, 24, 24, 24, 25, 25, 40, - 40, 26, 40, 27, 40, 3, 21, 21, 21, 21, - 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 20, - 22, 22, 32, 39, 33, 40, 22, 40, 11, 9, - 12, 21, 6, 19, 22, 22, 14, 22, 22, 5, - 8, 16, 15, 17, 22, 10, 18, 13, 22, 22, - 22, 7, 22, 22, 28, 36, 29, 38, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40 -}; - - -static void act34() -{ - NLA = 1; - error("unterminated action", zzline); zzmode(START); - } - - -static void act35() -{ - NLA = ACTION; - if (func_action) fprintf(OUT,"}\n\n"); - zzmode(START); - /* MR1 */ - /* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ - /* MR1 via <<%%lexmember ...>> */ - /* MR1 This is a consequence of not saving actions */ - /* MR1 */ - /* MR1 */ parserClass=0; - /* MR1 */ lexPrefix=0; - /* MR1 */ lexAction=0; - /* MR1 */ lexMember=0; - } - - -static void act36() -{ - NLA = 34; - xxputc(zzlextext[0]); zzskip(); - } - - -static void act37() -{ - NLA = 35; - xxputc('>'); zzskip(); - } - - -static void act38() -{ - NLA = 36; - xxputc('\\'); zzskip(); - } - - -static void act39() -{ - NLA = 37; - xxputc(zzlextext[0]); ++zzline; zzskip(); - } - - -static void act40() -{ - NLA = 38; - zzmode(ACTION_COMMENTS); /* MR1 */ - xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ - } - - -static void act41() -{ - NLA = 39; - zzmode(ACTION_CPP_COMMENTS); /* MR1 */ - xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ - } - - -static void act42() -{ - NLA = 40; - xxputc(zzlextext[0]); zzskip(); - } - -static unsigned char shift1[257] = { - 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 3, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 5, 6, 6, 6, 6, 4, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 1, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 2, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6 -}; - - -static void act43() -{ - NLA = 1; - } - - -static void act44() -{ - NLA = 41; - zzmode(ACT); /* MR1 */ - xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ - } - - -static void act45() -{ - NLA = 42; - zzline++; xxputc(zzlextext[0]); zzskip(); - } - - -static void act46() -{ - NLA = 43; - xxputc(zzlextext[0]); zzskip(); - } - -static unsigned char shift2[257] = { - 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 3, 4, 4, 3, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 1, 4, 4, 4, 4, 2, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4 -}; - - -static void act47() -{ - NLA = 1; - } - - -static void act48() -{ - NLA = 44; - zzmode(ACT); zzline++; /* MR1 */ - xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ - } - - -static void act49() -{ - NLA = 45; - xxputc(zzlextext[0]); zzskip(); - } - -static unsigned char shift3[257] = { - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2 -}; - -#define DfaStates 94 -typedef unsigned char DfaState; - -static DfaState st0[42] = { - 1, 2, 3, 4, 5, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 6, 94 -}; - -static DfaState st1[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st2[42] = { - 94, 21, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st3[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st4[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st5[42] = { - 94, 94, 94, 94, 22, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st6[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st7[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 23, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st8[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 24, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st9[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st10[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st11[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st12[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st13[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st14[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st15[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st16[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st17[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st18[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st19[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st20[42] = { - 94, 25, 26, 25, 25, 25, 25, 25, 25, 27, - 28, 25, 25, 29, 25, 25, 30, 25, 25, 25, - 25, 25, 25, 31, 32, 32, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 94 -}; - -static DfaState st21[42] = { - 94, 21, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st22[42] = { - 94, 94, 94, 94, 94, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st23[42] = { - 94, 94, 94, 94, 34, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st24[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st25[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st26[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st27[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st28[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st29[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st30[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st31[42] = { - 94, 94, 94, 94, 94, 94, 94, 35, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 35, 94, 94, 36, 36, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st32[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 37, 37, 37, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st33[42] = { - 94, 94, 94, 94, 94, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st34[42] = { - 94, 94, 94, 94, 39, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st35[42] = { - 94, 94, 94, 94, 94, 94, 40, 94, 94, 40, - 94, 40, 40, 94, 94, 94, 94, 94, 94, 40, - 94, 40, 94, 40, 40, 40, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st36[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 36, 36, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st37[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 37, 37, 37, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st38[42] = { - 94, 94, 94, 94, 94, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st39[42] = { - 94, 94, 94, 94, 94, 41, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 42, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st40[42] = { - 94, 94, 94, 94, 94, 94, 40, 94, 94, 40, - 94, 40, 40, 94, 94, 94, 94, 94, 94, 40, - 94, 40, 94, 40, 40, 40, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st41[42] = { - 94, 94, 94, 94, 94, 94, 43, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st42[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 44, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st43[42] = { - 94, 94, 94, 94, 94, 94, 94, 45, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st44[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 46, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st45[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 47, 94, - 94, 48, 94, 94, 94, 94, 94, 49, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st46[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 50, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st47[42] = { - 94, 94, 94, 94, 94, 94, 51, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st48[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 52, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st49[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 53, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st50[42] = { - 94, 94, 94, 94, 94, 94, 54, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st51[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 55, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st52[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 56, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st53[42] = { - 94, 94, 94, 94, 94, 94, 57, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st54[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 58, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st55[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 59, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st56[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 60, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st57[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 61, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st58[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 62, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st59[42] = { - 94, 94, 94, 94, 94, 94, 63, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st60[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 64, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st61[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 65, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st62[42] = { - 94, 94, 94, 94, 94, 66, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st63[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 67, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st64[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 68, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st65[42] = { - 94, 94, 94, 94, 94, 94, 94, 69, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st66[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 70, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st67[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st68[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st69[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st70[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 71, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st71[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 72, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st72[42] = { - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94 -}; - -static DfaState st73[8] = { - 74, 75, 76, 77, 78, 79, 79, 94 -}; - -static DfaState st74[8] = { - 94, 94, 94, 94, 94, 94, 94, 94 -}; - -static DfaState st75[8] = { - 94, 80, 94, 94, 94, 94, 94, 94 -}; - -static DfaState st76[8] = { - 94, 81, 94, 94, 94, 94, 94, 94 -}; - -static DfaState st77[8] = { - 94, 94, 94, 94, 94, 94, 94, 94 -}; - -static DfaState st78[8] = { - 94, 94, 94, 94, 82, 83, 94, 94 -}; - -static DfaState st79[8] = { - 94, 94, 94, 94, 94, 94, 94, 94 -}; - -static DfaState st80[8] = { - 94, 94, 94, 94, 94, 94, 94, 94 -}; - -static DfaState st81[8] = { - 94, 94, 94, 94, 94, 94, 94, 94 -}; - -static DfaState st82[8] = { - 94, 94, 94, 94, 94, 94, 94, 94 -}; - -static DfaState st83[8] = { - 94, 94, 94, 94, 94, 94, 94, 94 -}; - -static DfaState st84[6] = { - 85, 86, 87, 88, 87, 94 -}; - -static DfaState st85[6] = { - 94, 94, 94, 94, 94, 94 -}; - -static DfaState st86[6] = { - 94, 94, 89, 94, 94, 94 -}; - -static DfaState st87[6] = { - 94, 94, 94, 94, 94, 94 -}; - -static DfaState st88[6] = { - 94, 94, 94, 94, 94, 94 -}; - -static DfaState st89[6] = { - 94, 94, 94, 94, 94, 94 -}; - -static DfaState st90[4] = { - 91, 92, 93, 94 -}; - -static DfaState st91[4] = { - 94, 94, 94, 94 -}; - -static DfaState st92[4] = { - 94, 94, 94, 94 -}; - -static DfaState st93[4] = { - 94, 94, 94, 94 -}; - - -DfaState *dfa[94] = { - st0, - st1, - st2, - st3, - st4, - st5, - st6, - st7, - st8, - st9, - st10, - st11, - st12, - st13, - st14, - st15, - st16, - st17, - st18, - st19, - st20, - st21, - st22, - st23, - st24, - st25, - st26, - st27, - st28, - st29, - st30, - st31, - st32, - st33, - st34, - st35, - st36, - st37, - st38, - st39, - st40, - st41, - st42, - st43, - st44, - st45, - st46, - st47, - st48, - st49, - st50, - st51, - st52, - st53, - st54, - st55, - st56, - st57, - st58, - st59, - st60, - st61, - st62, - st63, - st64, - st65, - st66, - st67, - st68, - st69, - st70, - st71, - st72, - st73, - st74, - st75, - st76, - st77, - st78, - st79, - st80, - st81, - st82, - st83, - st84, - st85, - st86, - st87, - st88, - st89, - st90, - st91, - st92, - st93 -}; - - -DfaState accepts[95] = { - 0, 1, 2, 3, 4, 33, 33, 33, 33, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 0, 2, 5, 11, 12, 32, 31, 30, 29, 27, - 28, 24, 26, 6, 0, 0, 24, 26, 6, 0, - 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 7, 8, 10, - 0, 0, 9, 0, 34, 36, 38, 39, 42, 42, - 35, 37, 41, 40, 0, 43, 46, 46, 45, 44, - 0, 47, 48, 49, 0 -}; - -void (*actions[50])() = { - zzerraction, - act1, - act2, - act3, - act4, - act5, - act6, - act7, - act8, - act9, - act10, - act11, - act12, - act13, - act14, - act15, - act16, - act17, - act18, - act19, - act20, - act21, - act22, - act23, - act24, - act25, - act26, - act27, - act28, - act29, - act30, - act31, - act32, - act33, - act34, - act35, - act36, - act37, - act38, - act39, - act40, - act41, - act42, - act43, - act44, - act45, - act46, - act47, - act48, - act49 -}; - -static DfaState dfa_base[] = { - 0, - 73, - 84, - 90 -}; - -static unsigned char *b_class_no[] = { - shift0, - shift1, - shift2, - shift3 -}; - - - -#define ZZSHIFT(c) (b_class_no[zzauto][1+c]) -#define MAX_MODE 4 -#include "dlgauto.h" diff --git a/Tools/CodeTools/TianoTools/Pccts/dlg/dlg_p.c b/Tools/CodeTools/TianoTools/Pccts/dlg/dlg_p.c deleted file mode 100644 index e726ae3983..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/dlg/dlg_p.c +++ /dev/null @@ -1,959 +0,0 @@ -/* - * A n t l r T r a n s l a t i o n H e a d e r - * - * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001 - * Purdue University Electrical Engineering - * With AHPCRC, University of Minnesota - * ANTLR Version 1.33MR33 - * - * ..\bin\antlr dlg_p.g -gh - * - */ - -#define ANTLR_VERSION 13333 -#include "pcctscfg.h" -#include "pccts_stdio.h" - -#include -#include "dlg.h" -#define zzSET_SIZE 8 -#include "antlr.h" -#include "tokens.h" -#include "dlgdef.h" -#include "mode.h" - -/* MR23 In order to remove calls to PURIFY use the antlr -nopurify option */ - -#ifndef PCCTS_PURIFY -#define PCCTS_PURIFY(r,s) memset((char *) &(r),'\0',(s)); -#endif - -ANTLR_INFO - - -/* MR20 G. Hobbelt -Fix for Borland C++ 4.x & 5.x compiling with ALL warnings enabled -*/ - -#ifdef __TURBOC__ -#pragma warn -aus /* unused assignment of 'xxx' */ -#endif - -int action_no = 0; /* keep track of actions outputed */ -int nfa_allocated = 0; /* keeps track of number of nfa nodes */ -nfa_node **nfa_array = NULL;/* root of binary tree that stores nfa array */ -nfa_node nfa_model_node; /* model to initialize new nodes */ -set used_chars; /* used to label trans. arcs */ -set used_classes; /* classes or chars used to label trans. arcs */ -set normal_chars; /* mask to get rid elements that aren't used -in set */ -int flag_paren = FALSE; -int flag_brace = FALSE; -int mode_counter = 0; /* keep track of number of %%names */ - - - -void -#ifdef __USE_PROTOS -grammar(void) -#else -grammar() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - p_head(); p_class_hdr(); func_action = FALSE; - { - zzBLOCK(zztasp2); - zzMake0; - { - while ( (setwd1[LA(1)]&0x1) ) { - { - zzBLOCK(zztasp3); - zzMake0; - { - if ( (LA(1)==LEXACTION) ) { - zzmatch(LEXACTION); zzCONSUME; - } - else { - if ( (LA(1)==LEXMEMBER) ) { - zzmatch(LEXMEMBER); zzCONSUME; - } - else { - if ( (LA(1)==LEXPREFIX) ) { - zzmatch(LEXPREFIX); zzCONSUME; - } - else { - if ( (LA(1)==PARSERCLASS) ) { - zzmatch(PARSERCLASS); zzCONSUME; - } - else { - if ( (LA(1)==ACTION) ) { - } - else {zzFAIL(1,zzerr1,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - } - } - } - zzEXIT(zztasp3); - } - } - zzmatch(ACTION); zzCONSUME; - zzLOOP(zztasp2); - } - zzEXIT(zztasp2); - } - } - if ( gen_cpp ) p_includes(); - start_states(); - func_action = FALSE; p_tables(); p_tail(); - { - zzBLOCK(zztasp2); - zzMake0; - { - while ( (LA(1)==ACTION) ) { - zzmatch(ACTION); zzCONSUME; - zzLOOP(zztasp2); - } - zzEXIT(zztasp2); - } - } - zzmatch(1); - if (firstLexMember != 0) p_class_def1(); - zzCONSUME; - - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd1, 0x2); - } -} - -void -#ifdef __USE_PROTOS -start_states(void) -#else -start_states() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==PER_PER) ) { - zzmatch(PER_PER); zzCONSUME; - do_conversion(); - } - else { - if ( (LA(1)==NAME_PER_PER) ) { - zzmatch(NAME_PER_PER); zzCONSUME; - do_conversion(); - { - zzBLOCK(zztasp3); - zzMake0; - { - while ( (LA(1)==NAME_PER_PER) ) { - zzmatch(NAME_PER_PER); zzCONSUME; - do_conversion(); - zzLOOP(zztasp3); - } - zzEXIT(zztasp3); - } - } - } - else {zzFAIL(1,zzerr2,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - zzmatch(PER_PER); zzCONSUME; - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd1, 0x4); - } -} - -void -#ifdef __USE_PROTOS -do_conversion(void) -#else -do_conversion() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - new_automaton_mode(); func_action = TRUE; - rule_list(); - - dfa_class_nop[mode_counter] = - relabel(zzaArg(zztasp1,1 ).l,comp_level); - if (comp_level) - p_shift_table(mode_counter); - dfa_basep[mode_counter] = dfa_allocated+1; - make_dfa_model_node(dfa_class_nop[mode_counter]); - nfa_to_dfa(zzaArg(zztasp1,1 ).l); - ++mode_counter; - func_action = FALSE; -#ifdef HASH_STAT - fprint_hash_stats(stderr); -#endif - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd1, 0x8); - } -} - -void -#ifdef __USE_PROTOS -rule_list(void) -#else -rule_list() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - if ( (setwd1[LA(1)]&0x10) ) { - rule(); - zzaRet.l=zzaArg(zztasp1,1 ).l; zzaRet.r=zzaArg(zztasp1,1 ).r; - { - zzBLOCK(zztasp2); - zzMake0; - { - while ( (setwd1[LA(1)]&0x20) ) { - rule(); - {nfa_node *t1; - t1 = new_nfa_node(); - (t1)->trans[0]=zzaRet.l; - (t1)->trans[1]=zzaArg(zztasp2,1 ).l; - /* all accept nodes "dead ends" */ - zzaRet.l=t1; zzaRet.r=NULL; - } - zzLOOP(zztasp2); - } - zzEXIT(zztasp2); - } - } - } - else { - if ( (setwd1[LA(1)]&0x40) ) { - zzaRet.l = new_nfa_node(); zzaRet.r = NULL; - warning("no regular expressions", zzline); - } - else {zzFAIL(1,zzerr3,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd1, 0x80); - } -} - -void -#ifdef __USE_PROTOS -rule(void) -#else -rule() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - if ( (setwd2[LA(1)]&0x1) ) { - reg_expr(); - zzmatch(ACTION); - if (zzaArg(zztasp1,1 ).r != NULL) { - zzaRet.l=zzaArg(zztasp1,1 ).l; zzaRet.r=zzaArg(zztasp1,1 ).r; (zzaArg(zztasp1,1 ).r)->accept=action_no; - } - zzCONSUME; - - } - else { - if ( (LA(1)==ACTION) ) { - zzmatch(ACTION); - zzaRet.l = NULL; zzaRet.r = NULL; - error("no expression for action ", zzline); - zzCONSUME; - - } - else {zzFAIL(1,zzerr4,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd2, 0x2); - } -} - -void -#ifdef __USE_PROTOS -reg_expr(void) -#else -reg_expr() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - and_expr(); - zzaRet.l=zzaArg(zztasp1,1 ).l; zzaRet.r=zzaArg(zztasp1,1 ).r; - { - zzBLOCK(zztasp2); - zzMake0; - { - while ( (LA(1)==OR) ) { - zzmatch(OR); zzCONSUME; - and_expr(); - {nfa_node *t1, *t2; - t1 = new_nfa_node(); t2 = new_nfa_node(); - (t1)->trans[0]=zzaRet.l; - (t1)->trans[1]=zzaArg(zztasp2,2 ).l; - /* MR23 */ if (zzaRet.r != NULL) (zzaRet.r)->trans[1]=t2; - if (zzaArg(zztasp2,2 ).r) { - (zzaArg(zztasp2,2 ).r)->trans[1]=t2; /* MR20 */ - } - zzaRet.l=t1; zzaRet.r=t2; - } - zzLOOP(zztasp2); - } - zzEXIT(zztasp2); - } - } - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd2, 0x4); - } -} - -void -#ifdef __USE_PROTOS -and_expr(void) -#else -and_expr() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - repeat_expr(); - - zzaRet.l=zzaArg(zztasp1,1 ).l; zzaRet.r=zzaArg(zztasp1,1 ).r; - { - zzBLOCK(zztasp2); - zzMake0; - { - while ( (setwd2[LA(1)]&0x8) ) { - repeat_expr(); - if (zzaRet.r != NULL) { - (zzaRet.r)->trans[1]=zzaArg(zztasp2,1 ).l; - zzaRet.r=zzaArg(zztasp2,1 ).r; - } - zzLOOP(zztasp2); - } - zzEXIT(zztasp2); - } - } - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd2, 0x10); - } -} - -void -#ifdef __USE_PROTOS -repeat_expr(void) -#else -repeat_expr() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - if ( (setwd2[LA(1)]&0x20) ) { - expr(); - zzaRet.l=zzaArg(zztasp1,1 ).l; zzaRet.r=zzaArg(zztasp1,1 ).r; - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==ZERO_MORE) ) { - zzmatch(ZERO_MORE); - { nfa_node *t1,*t2; - /* MR23 */ if (zzaRet.r != NULL) (zzaRet.r)->trans[0] = zzaRet.l; - t1 = new_nfa_node(); t2 = new_nfa_node(); - t1->trans[0]=zzaRet.l; - t1->trans[1]=t2; - /* MR23 */ if (zzaRet.r != NULL) (zzaRet.r)->trans[1]=t2; - zzaRet.l=t1;zzaRet.r=t2; - } - zzCONSUME; - - } - else { - if ( (LA(1)==ONE_MORE) ) { - zzmatch(ONE_MORE); - if (zzaRet.r != NULL) (zzaRet.r)->trans[0] = zzaRet.l; - zzCONSUME; - - } - else { - if ( (setwd2[LA(1)]&0x40) ) { - } - else {zzFAIL(1,zzerr5,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - } - zzEXIT(zztasp2); - } - } - } - else { - if ( (LA(1)==ZERO_MORE) ) { - zzmatch(ZERO_MORE); - error("no expression for *", zzline); - zzCONSUME; - - } - else { - if ( (LA(1)==ONE_MORE) ) { - zzmatch(ONE_MORE); - error("no expression for +", zzline); - zzCONSUME; - - } - else {zzFAIL(1,zzerr6,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - } - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd2, 0x80); - } -} - -void -#ifdef __USE_PROTOS -expr(void) -#else -expr() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - zzaRet.l = new_nfa_node(); - zzaRet.r = new_nfa_node(); - if ( (LA(1)==L_BRACK) ) { - zzmatch(L_BRACK); zzCONSUME; - atom_list(); - zzmatch(R_BRACK); - - /* MR23 */ if (zzaRet.l != NULL) { - (zzaRet.l)->trans[0] = zzaRet.r; - (zzaRet.l)->label = set_dup(zzaArg(zztasp1,2 ).label); - set_orin(&used_chars,(zzaRet.l)->label); - } - zzCONSUME; - - } - else { - if ( (LA(1)==NOT) ) { - zzmatch(NOT); zzCONSUME; - zzmatch(L_BRACK); zzCONSUME; - atom_list(); - zzmatch(R_BRACK); - - /* MR23 */ if (zzaRet.l != NULL) { - (zzaRet.l)->trans[0] = zzaRet.r; - (zzaRet.l)->label = set_dif(normal_chars,zzaArg(zztasp1,3 ).label); - set_orin(&used_chars,(zzaRet.l)->label); - } - zzCONSUME; - - } - else { - if ( (LA(1)==L_PAR) ) { - zzmatch(L_PAR); zzCONSUME; - reg_expr(); - zzmatch(R_PAR); - - /* MR23 */ if (zzaRet.l != NULL) { - (zzaRet.l)->trans[0] = zzaArg(zztasp1,2 ).l; - if (zzaArg(zztasp1,2 ).r) { - (zzaArg(zztasp1,2 ).r)->trans[1] = zzaRet.r; /* MR20 */ - } - } - zzCONSUME; - - } - else { - if ( (LA(1)==L_BRACE) ) { - zzmatch(L_BRACE); zzCONSUME; - reg_expr(); - zzmatch(R_BRACE); - - /* MR23 */ if (zzaRet.l != NULL) { - (zzaRet.l)->trans[0] = zzaArg(zztasp1,2 ).l; - (zzaRet.l)->trans[1] = zzaRet.r; - if (zzaArg(zztasp1,2 ).r) { - (zzaArg(zztasp1,2 ).r)->trans[1] = zzaRet.r; /* MR20 */ - } - } - zzCONSUME; - - } - else { - if ( (setwd3[LA(1)]&0x1) ) { - atom(); - - /* MR23 */ if (zzaRet.l != NULL) { - (zzaRet.l)->trans[0] = zzaRet.r; - (zzaRet.l)->label = set_dup(zzaArg(zztasp1,1 ).label); - set_orin(&used_chars,(zzaRet.l)->label); - } - } - else {zzFAIL(1,zzerr7,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - } - } - } - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd3, 0x2); - } -} - -void -#ifdef __USE_PROTOS -atom_list(void) -#else -atom_list() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - set_free(zzaRet.label); - { - zzBLOCK(zztasp2); - zzMake0; - { - while ( (setwd3[LA(1)]&0x4) ) { - near_atom(); - set_orin(&(zzaRet.label),zzaArg(zztasp2,1 ).label); - zzLOOP(zztasp2); - } - zzEXIT(zztasp2); - } - } - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd3, 0x8); - } -} - -void -#ifdef __USE_PROTOS -near_atom(void) -#else -near_atom() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - register int i; - register int i_prime; - anychar(); - zzaRet.letter=zzaArg(zztasp1,1 ).letter; zzaRet.label=set_of(zzaArg(zztasp1,1 ).letter); - i_prime = zzaArg(zztasp1,1 ).letter + MIN_CHAR; - if (case_insensitive && islower(i_prime)) - set_orel(toupper(i_prime)-MIN_CHAR, - &(zzaRet.label)); - if (case_insensitive && isupper(i_prime)) - set_orel(tolower(i_prime)-MIN_CHAR, - &(zzaRet.label)); - { - zzBLOCK(zztasp2); - zzMake0; - { - if ( (LA(1)==RANGE) ) { - zzmatch(RANGE); zzCONSUME; - anychar(); - if (case_insensitive){ - i_prime = zzaRet.letter+MIN_CHAR; - zzaRet.letter = (islower(i_prime) ? - toupper(i_prime) : i_prime)-MIN_CHAR; - i_prime = zzaArg(zztasp2,2 ).letter+MIN_CHAR; - zzaArg(zztasp2,2 ).letter = (islower(i_prime) ? - toupper(i_prime) : i_prime)-MIN_CHAR; - } - /* check to see if range okay */ - { - int debugLetter1 = zzaRet.letter; - int debugLetter2 = zzaArg(zztasp2,2 ).letter; - } - if (zzaRet.letter > zzaArg(zztasp2,2 ).letter - && zzaArg(zztasp2,2 ).letter != 0xff){ /* MR16 */ - error("invalid range ", zzline); - } - for (i=zzaRet.letter; i<= (int)zzaArg(zztasp2,2 ).letter; ++i){ - set_orel(i,&(zzaRet.label)); - i_prime = i+MIN_CHAR; - if (case_insensitive && islower(i_prime)) - set_orel(toupper(i_prime)-MIN_CHAR, - &(zzaRet.label)); - if (case_insensitive && isupper(i_prime)) - set_orel(tolower(i_prime)-MIN_CHAR, - &(zzaRet.label)); - } - } - else { - if ( (setwd3[LA(1)]&0x10) ) { - } - else {zzFAIL(1,zzerr8,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - zzEXIT(zztasp2); - } - } - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd3, 0x20); - } -} - -void -#ifdef __USE_PROTOS -atom(void) -#else -atom() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - register int i_prime; - anychar(); - zzaRet.label = set_of(zzaArg(zztasp1,1 ).letter); - i_prime = zzaArg(zztasp1,1 ).letter + MIN_CHAR; - if (case_insensitive && islower(i_prime)) - set_orel(toupper(i_prime)-MIN_CHAR, - &(zzaRet.label)); - if (case_insensitive && isupper(i_prime)) - set_orel(tolower(i_prime)-MIN_CHAR, - &(zzaRet.label)); - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd3, 0x40); - } -} - -void -#ifdef __USE_PROTOS -anychar(void) -#else -anychar() -#endif -{ - zzRULE; - zzBLOCK(zztasp1); - zzMake0; - { - if ( (LA(1)==REGCHAR) ) { - zzmatch(REGCHAR); - zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR; - zzCONSUME; - - } - else { - if ( (LA(1)==OCTAL_VALUE) ) { - zzmatch(OCTAL_VALUE); - zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR; - zzCONSUME; - - } - else { - if ( (LA(1)==HEX_VALUE) ) { - zzmatch(HEX_VALUE); - zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR; - zzCONSUME; - - } - else { - if ( (LA(1)==DEC_VALUE) ) { - zzmatch(DEC_VALUE); - zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR; - zzCONSUME; - - } - else { - if ( (LA(1)==TAB) ) { - zzmatch(TAB); - zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR; - zzCONSUME; - - } - else { - if ( (LA(1)==NL) ) { - zzmatch(NL); - zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR; - zzCONSUME; - - } - else { - if ( (LA(1)==CR) ) { - zzmatch(CR); - zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR; - zzCONSUME; - - } - else { - if ( (LA(1)==BS) ) { - zzmatch(BS); - zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR; - zzCONSUME; - - } - else { - if ( (LA(1)==LIT) ) { - zzmatch(LIT); - zzaRet.letter = zzaArg(zztasp1,1 ).letter - MIN_CHAR; - zzCONSUME; - - } - else { - if ( (LA(1)==L_EOF) ) { - zzmatch(L_EOF); - zzaRet.letter = 0; - zzCONSUME; - - } - else {zzFAIL(1,zzerr9,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk); goto fail;} - } - } - } - } - } - } - } - } - } - zzEXIT(zztasp1); - return; -fail: - zzEXIT(zztasp1); - /* empty action */ - zzsyn(zzMissText, zzBadTok, (ANTLRChar *)"", zzMissSet, zzMissTok, zzErrk, zzBadText); - zzresynch(setwd3, 0x80); - } -} - -/* adds a new nfa to the binary tree and returns a pointer to it */ -nfa_node * -#ifdef __USE_PROTOS -new_nfa_node(void) -#else -new_nfa_node() -#endif -{ - register nfa_node *t; - static int nfa_size=0; /* elements nfa_array[] can hold */ - - ++nfa_allocated; - if (nfa_size<=nfa_allocated){ - /* need to redo array */ - if (!nfa_array){ - /* need some to do inital allocation */ - nfa_size=nfa_allocated+NFA_MIN; - nfa_array=(nfa_node **) malloc(sizeof(nfa_node*)* - nfa_size); - }else{ - /* need more space */ - nfa_size=2*(nfa_allocated+1); - nfa_array=(nfa_node **) realloc(nfa_array, - sizeof(nfa_node*)*nfa_size); - } - } - /* fill out entry in array */ - t = (nfa_node*) malloc(sizeof(nfa_node)); - nfa_array[nfa_allocated] = t; - *t = nfa_model_node; - t->node_no = nfa_allocated; - return t; -} - - -/* initialize the model node used to fill in newly made nfa_nodes */ -void -#ifdef __USE_PROTOS -make_nfa_model_node(void) -#else -make_nfa_model_node() -#endif -{ - nfa_model_node.node_no = -1; /* impossible value for real nfa node */ - nfa_model_node.nfa_set = 0; - nfa_model_node.accept = 0; /* error state default*/ - nfa_model_node.trans[0] = NULL; - nfa_model_node.trans[1] = NULL; - nfa_model_node.label = empty; -} - -#if defined(DEBUG) || defined(_DEBUG) - -/* print out the pointer value and the node_number */ -void -#ifdef __USE_PROTOS -fprint_dfa_pair(FILE *f, nfa_node *p) -#else -fprint_dfa_pair(f, p) -FILE *f; -nfa_node *p; -#endif -{ - if (p){ - fprintf(f, "%x (%d)", p, p->node_no); - }else{ - fprintf(f, "(nil)"); - } -} - -/* print out interest information on a set */ -void -#ifdef __USE_PROTOS -fprint_set(FILE *f, set s) -#else -fprint_set(f,s) -FILE *f; -set s; -#endif -{ - unsigned int *x; - - fprintf(f, "n = %d,", s.n); - if (s.setword){ - fprintf(f, "setword = %x, ", s.setword); - /* print out all the elements in the set */ - x = set_pdq(s); - while (*x!=nil){ - fprintf(f, "%d ", *x); - ++x; - } - }else{ - fprintf(f, "setword = (nil)"); - } -} - -/* code to be able to dump out the nfas -return 0 if okay dump -return 1 if screwed up -*/ -int -#ifdef __USE_PROTOS -dump_nfas(int first_node, int last_node) -#else -dump_nfas(first_node, last_node) -int first_node; -int last_node; -#endif -{ - register int i; - nfa_node *t; - - for (i=first_node; i<=last_node; ++i){ - t = NFA(i); - if (!t) break; - fprintf(stderr, "nfa_node %d {\n", t->node_no); - fprintf(stderr, "\n\tnfa_set = %d\n", t->nfa_set); - fprintf(stderr, "\taccept\t=\t%d\n", t->accept); - fprintf(stderr, "\ttrans\t=\t("); - fprint_dfa_pair(stderr, t->trans[0]); - fprintf(stderr, ","); - fprint_dfa_pair(stderr, t->trans[1]); - fprintf(stderr, ")\n"); - fprintf(stderr, "\tlabel\t=\t{ "); - fprint_set(stderr, t->label); - fprintf(stderr, "\t}\n"); - fprintf(stderr, "}\n\n"); - } - return 0; -} -#endif - -/* DLG-specific syntax error message generator -* (define USER_ZZSYN when compiling so don't get 2 definitions) -*/ -void -#ifdef __USE_PROTOS -zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, int k, char *bad_text) -#else -zzsyn(text, tok, egroup, eset, etok, k, bad_text) -char *text, *egroup, *bad_text; -int tok; -int etok; -int k; -SetWordType *eset; -#endif -{ -fprintf(stderr, ErrHdr, file_str[0]!=NULL?file_str[0]:"stdin", zzline); -fprintf(stderr, " syntax error at \"%s\"", (tok==zzEOF_TOKEN)?"EOF":text); -if ( !etok && !eset ) {fprintf(stderr, "\n"); return;} -if ( k==1 ) fprintf(stderr, " missing"); -else -{ -fprintf(stderr, "; \"%s\" not", bad_text); -if ( zzset_deg(eset)>1 ) fprintf(stderr, " in"); -} -if ( zzset_deg(eset)>0 ) zzedecode(eset); -else fprintf(stderr, " %s", zztokens[etok]); -if ( strlen(egroup) > (size_t)0 ) fprintf(stderr, " in %s", egroup); -fprintf(stderr, "\n"); -} diff --git a/Tools/CodeTools/TianoTools/Pccts/dlg/dlg_p.g b/Tools/CodeTools/TianoTools/Pccts/dlg/dlg_p.g deleted file mode 100644 index 58ca110693..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/dlg/dlg_p.g +++ /dev/null @@ -1,614 +0,0 @@ -/* This is the parser for the dlg - * This is a part of the Purdue Compiler Construction Tool Set - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * DLG 1.33 - * Will Cohen - * With mods by Terence Parr; AHPCRC, University of Minnesota - * 1989-1995 - */ - -#header << -#include -#include "dlg.h" ->> - -<< - -/* MR20 G. Hobbelt - Fix for Borland C++ 4.x & 5.x compiling with ALL warnings enabled -*/ - -#ifdef __TURBOC__ -#pragma warn -aus /* unused assignment of 'xxx' */ -#endif - -int action_no = 0; /* keep track of actions outputed */ -int nfa_allocated = 0; /* keeps track of number of nfa nodes */ -nfa_node **nfa_array = NULL;/* root of binary tree that stores nfa array */ -nfa_node nfa_model_node; /* model to initialize new nodes */ -set used_chars; /* used to label trans. arcs */ -set used_classes; /* classes or chars used to label trans. arcs */ -set normal_chars; /* mask to get rid elements that aren't used - in set */ -int flag_paren = FALSE; -int flag_brace = FALSE; -int mode_counter = 0; /* keep track of number of %%names */ - ->> - -#lexaction << -int func_action; /* should actions be turned into functions?*/ -int lex_mode_counter = 0; /* keeps track of the number of %%names */ -/* MR1 */ -/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ -/* MR1 via <<%%lexmember...>> */ -/* MR1 */ -int lexMember = 0; /* <<%%lexmemeber ...>> MR1 */ -int lexAction = 0; /* <<%%lexaction ...>> MR1 */ -int parserClass = 0; /* <<%%parserclass ...>> MR1 */ -int lexPrefix = 0; /* <<%%lexprefix ...>> MR1 */ -char theClassName[100]; /* MR11 */ -char *pClassName=theClassName; /* MR11 */ -int firstLexMember=1; /* MR1 */ - -#ifdef __USE_PROTOS -void xxputc(int c) { /* MR1 */ -#else -void xxputc(c) /* MR1 */ - int c; /* MR1 */ -{ /* MR1 */ -#endif - if (parserClass) { /* MR1 */ - *pClassName++=c; /* MR1 */ - *pClassName=0; /* MR1 */ - } else if (lexMember || lexPrefix) { /* MR1 */ - if (class_stream != NULL) fputc(c,class_stream); /* MR1 */ - } else { /* MR1 */ - fputc(c,OUT); /* MR1 */ - }; /* MR1 */ -} /* MR1 */ - -#ifdef __USE_PROTOS -void xxprintf(char *format,char *string) { /* MR1 */ -#else -void xxprintf(format,string) /* MR1 */ - char *format; /* MR1 */ - char *string; /* MR1 */ -{ /* MR1 */ -#endif - if (lexMember || lexPrefix || parserClass) { /* MR1 */ - if (class_stream != NULL) /* MR1 */ - fprintf(class_stream,format,string); /* MR1 */ - } else { /* MR1 */ - fprintf(OUT,format,string); /* MR1 */ - }; /* MR1 */ -} /* MR1 */ ->> - -#token "[\r\t\ ]+" << zzskip(); >> /* Ignore white */ -#token "\n" << zzline++; zzskip(); DAWDLE; >> /* Track Line # */ -#token L_EOF "\@" -#token PER_PER "\%\%" -#token NAME_PER_PER "\%\%[a-zA-Z_][a-zA-Z0-9_]*" - << p_mode_def(&zzlextext[2],lex_mode_counter++); >> - -#token LEXMEMBER "\<\<\%\%lexmember" /* MR1 */ - <> /* MR1 */ -#token LEXACTION "\<\<\%\%lexaction" /* MR1 */ - <> /* MR1 */ -#token PARSERCLASS "\<\<\%\%parserclass" /* MR1 */ - <> /* MR1 */ -#token LEXPREFIX "\<\<\%\%lexprefix" /* MR1 */ - <> /* MR1 */ - -#token ACTION "\<\<" - << if (func_action) - fprintf(OUT,"\n%s %sact%d()\n{ ", - gen_cpp?"ANTLRTokenType":"static void", - gen_cpp?ClassName("::"):"", ++action_no); - zzmode(ACT); zzskip(); - >> -#token GREAT_GREAT "\>\>" -#token L_BRACE "\{" -#token R_BRACE "\}" -#token L_PAR "\(" -#token R_PAR "\)" -#token L_BRACK "\[" -#token R_BRACK "\]" -#token ZERO_MORE "\*" -#token ONE_MORE "\+" -#token OR "\|" -#token RANGE "\-" -#token NOT "\~" -#token OCTAL_VALUE "\\0[0-7]*" - << {int t; sscanf(&zzlextext[1],"%o",&t); zzlextext[0] = t;}>> -#token HEX_VALUE "\\0[Xx][0-9a-fA-F]+" - << {int t; sscanf(&zzlextext[3],"%x",&t); zzlextext[0] = t;}>> -#token DEC_VALUE "\\[1-9][0-9]*" - << {int t; sscanf(&zzlextext[1],"%d",&t); zzlextext[0] = t;}>> -#token TAB "\\t" << zzlextext[0] = '\t';>> -#token NL "\\n" << zzlextext[0] = '\n';>> -#token CR "\\r" << zzlextext[0] = '\r';>> -#token BS "\\b" << zzlextext[0] = '\b';>> - -/* MR1 */ -/* MR1 10-Apr-97 MR1 Allow #token regular expressions to cross lines */ -/* MR1 */ -#token CONTINUATION "\\ \n" << zzline++; zzskip();>> /* MR1 */ - -/* NOTE: this takes ANYTHING after the \ */ -#token LIT "\\~[tnrb]" << zzlextext[0] = zzlextext[1];>> - -/* NOTE: this takes ANYTHING that doesn't match the other tokens */ -#token REGCHAR "~[\\]" - - -grammar : << p_head(); p_class_hdr(); func_action = FALSE;>> - ( {LEXACTION | LEXMEMBER | LEXPREFIX | PARSERCLASS } ACTION)* /* MR1 */ - <> - start_states - << func_action = FALSE; p_tables(); p_tail(); >> - (ACTION)* "@" - << if (firstLexMember != 0) p_class_def1(); >> /* MR1 */ - ; - -start_states : ( PER_PER do_conversion - | NAME_PER_PER do_conversion (NAME_PER_PER do_conversion)*) - PER_PER - ; - -do_conversion : <> - rule_list - << - dfa_class_nop[mode_counter] = - relabel($1.l,comp_level); - if (comp_level) - p_shift_table(mode_counter); - dfa_basep[mode_counter] = dfa_allocated+1; - make_dfa_model_node(dfa_class_nop[mode_counter]); - nfa_to_dfa($1.l); - ++mode_counter; - func_action = FALSE; -#ifdef HASH_STAT - fprint_hash_stats(stderr); -#endif - >> - ; - -rule_list : rule <<$$.l=$1.l; $$.r=$1.r;>> - (rule - <<{nfa_node *t1; - t1 = new_nfa_node(); - (t1)->trans[0]=$$.l; - (t1)->trans[1]=$1.l; - /* all accept nodes "dead ends" */ - $$.l=t1; $$.r=NULL; - } - >> - )* - | /* empty */ - <<$$.l = new_nfa_node(); $$.r = NULL; - warning("no regular expressions", zzline); - >> - ; - -rule : reg_expr ACTION -/* MR23 */ << if ($1.r != NULL) { - $$.l=$1.l; $$.r=$1.r; ($1.r)->accept=action_no; - } - >> - | ACTION - <<$$.l = NULL; $$.r = NULL; - error("no expression for action ", zzline); - >> - ; - -reg_expr : and_expr <<$$.l=$1.l; $$.r=$1.r;>> - (OR and_expr - <<{nfa_node *t1, *t2; - t1 = new_nfa_node(); t2 = new_nfa_node(); - (t1)->trans[0]=$$.l; - (t1)->trans[1]=$2.l; -/* MR23 */ if ($$.r != NULL) ($$.r)->trans[1]=t2; - if ($2.r) { - ($2.r)->trans[1]=t2; /* MR20 */ - } - $$.l=t1; $$.r=t2; - } - >> - )* - ; - -and_expr : repeat_expr - << - $$.l=$1.l; $$.r=$1.r; - >> - (repeat_expr -/* MR23 */ << if ($$.r != NULL) { - ($$.r)->trans[1]=$1.l; - $$.r=$1.r; - } - >> - )* - ; - -repeat_expr : expr <<$$.l=$1.l; $$.r=$1.r;>> - { ZERO_MORE - <<{ nfa_node *t1,*t2; -/* MR23 */ if ($$.r != NULL) ($$.r)->trans[0] = $$.l; - t1 = new_nfa_node(); t2 = new_nfa_node(); - t1->trans[0]=$$.l; - t1->trans[1]=t2; -/* MR23 */ if ($$.r != NULL) ($$.r)->trans[1]=t2; - $$.l=t1;$$.r=t2; - } - >> - | ONE_MORE -/* MR23 */ <trans[0] = $$.l;>> - } - | ZERO_MORE - << error("no expression for *", zzline);>> - | ONE_MORE - << error("no expression for +", zzline);>> - ; - -expr : << $$.l = new_nfa_node(); - $$.r = new_nfa_node(); - >> - L_BRACK atom_list R_BRACK - << -/* MR23 */ if ($$.l != NULL) { - ($$.l)->trans[0] = $$.r; - ($$.l)->label = set_dup($2.label); - set_orin(&used_chars,($$.l)->label); - } - >> - | NOT L_BRACK atom_list R_BRACK - << -/* MR23 */ if ($$.l != NULL) { - ($$.l)->trans[0] = $$.r; - ($$.l)->label = set_dif(normal_chars,$3.label); - set_orin(&used_chars,($$.l)->label); - } - >> - | L_PAR reg_expr R_PAR - << -/* MR23 */ if ($$.l != NULL) { - ($$.l)->trans[0] = $2.l; - if ($2.r) { - ($2.r)->trans[1] = $$.r; /* MR20 */ - } - } - >> - | L_BRACE reg_expr R_BRACE - << -/* MR23 */ if ($$.l != NULL) { - ($$.l)->trans[0] = $2.l; - ($$.l)->trans[1] = $$.r; - if ($2.r) { - ($2.r)->trans[1] = $$.r; /* MR20 */ - } - } - >> - | atom - << -/* MR23 */ if ($$.l != NULL) { - ($$.l)->trans[0] = $$.r; - ($$.l)->label = set_dup($1.label); - set_orin(&used_chars,($$.l)->label); - } - >> - ; - -atom_list : << set_free($$.label); >> - (near_atom <>)* - ; - -near_atom : << register int i; - register int i_prime; - >> - anychar - <<$$.letter=$1.letter; $$.label=set_of($1.letter); - i_prime = $1.letter + MIN_CHAR; - if (case_insensitive && islower(i_prime)) - set_orel(toupper(i_prime)-MIN_CHAR, - &($$.label)); - if (case_insensitive && isupper(i_prime)) - set_orel(tolower(i_prime)-MIN_CHAR, - &($$.label)); - >> - { RANGE anychar - << if (case_insensitive){ - i_prime = $$.letter+MIN_CHAR; - $$.letter = (islower(i_prime) ? - toupper(i_prime) : i_prime)-MIN_CHAR; - i_prime = $2.letter+MIN_CHAR; - $2.letter = (islower(i_prime) ? - toupper(i_prime) : i_prime)-MIN_CHAR; - } - /* check to see if range okay */ - { - int debugLetter1 = $$.letter; - int debugLetter2 = $2.letter; - } - if ($$.letter > $2.letter - && $2.letter != 0xff){ /* MR16 */ - error("invalid range ", zzline); - } - for (i=$$.letter; i<= (int)$2.letter; ++i){ - set_orel(i,&($$.label)); - i_prime = i+MIN_CHAR; - if (case_insensitive && islower(i_prime)) - set_orel(toupper(i_prime)-MIN_CHAR, - &($$.label)); - if (case_insensitive && isupper(i_prime)) - set_orel(tolower(i_prime)-MIN_CHAR, - &($$.label)); - } - >> - } - ; - -atom : << register int i_prime;>> - anychar - <<$$.label = set_of($1.letter); - i_prime = $1.letter + MIN_CHAR; - if (case_insensitive && islower(i_prime)) - set_orel(toupper(i_prime)-MIN_CHAR, - &($$.label)); - if (case_insensitive && isupper(i_prime)) - set_orel(tolower(i_prime)-MIN_CHAR, - &($$.label)); - >> - ; - -anychar : REGCHAR <<$$.letter = $1.letter - MIN_CHAR;>> - | OCTAL_VALUE <<$$.letter = $1.letter - MIN_CHAR;>> - | HEX_VALUE <<$$.letter = $1.letter - MIN_CHAR;>> - | DEC_VALUE <<$$.letter = $1.letter - MIN_CHAR;>> - | TAB <<$$.letter = $1.letter - MIN_CHAR;>> - | NL <<$$.letter = $1.letter - MIN_CHAR;>> - | CR <<$$.letter = $1.letter - MIN_CHAR;>> - | BS <<$$.letter = $1.letter - MIN_CHAR;>> - | LIT <<$$.letter = $1.letter - MIN_CHAR;>> - /* NOTE: LEX_EOF is ALWAYS shifted to 0 = MIN_CHAR - MIN_CHAR*/ - | L_EOF <<$$.letter = 0;>> - ; - -<> - -#lexclass ACT -#token "@" << error("unterminated action", zzline); zzmode(START); >> -#token ACTION "\>\>" - << if (func_action) fprintf(OUT,"}\n\n"); - zzmode(START); -/* MR1 */ -/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ -/* MR1 via <<%%lexmember ...>> */ -/* MR1 This is a consequence of not saving actions */ -/* MR1 */ -/* MR1 */ parserClass=0; -/* MR1 */ lexPrefix=0; -/* MR1 */ lexAction=0; -/* MR1 */ lexMember=0; - >> -#token "\>" << xxputc(zzlextext[0]); zzskip(); >> /* MR1 */ -#token "\\\>" << xxputc('>'); zzskip(); >> /* MR1 */ -#token "\\" << xxputc('\\'); zzskip(); >> /* MR1 */ -#token "\n" << xxputc(zzlextext[0]); ++zzline; zzskip(); >> /* MR1 */ -#token "/\*" << zzmode(ACTION_COMMENTS); /* MR1 */ - xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ - >> /* MR1 */ -#token "//" << zzmode(ACTION_CPP_COMMENTS); /* MR1 */ - xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ - >> /* MR1 */ -#token "~[]" << xxputc(zzlextext[0]); zzskip(); >> /* MR1 */ - /* MR1 */ -#lexclass ACTION_COMMENTS /* MR1 */ -#token "\*/" << zzmode(ACT); /* MR1 */ - xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ - >> /* MR1 */ -#token "[\n\r]" << zzline++; xxputc(zzlextext[0]); zzskip();>> /* MR1 */ -#token "~[]" << xxputc(zzlextext[0]); zzskip();>> /* MR1 */ - /* MR1 */ -#lexclass ACTION_CPP_COMMENTS /* MR1 */ -#token "[\n\r]" << zzmode(ACT); zzline++; /* MR1 */ - xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ - >> /* MR1 */ -#token "~[]" << xxputc(zzlextext[0]); zzskip();>> /* MR1 */ - -<< -/* adds a new nfa to the binary tree and returns a pointer to it */ -nfa_node * -#ifdef __USE_PROTOS -new_nfa_node(void) -#else -new_nfa_node() -#endif -{ - register nfa_node *t; - static int nfa_size=0; /* elements nfa_array[] can hold */ - - ++nfa_allocated; - if (nfa_size<=nfa_allocated){ - /* need to redo array */ - if (!nfa_array){ - /* need some to do inital allocation */ - nfa_size=nfa_allocated+NFA_MIN; - nfa_array=(nfa_node **) malloc(sizeof(nfa_node*)* - nfa_size); - }else{ - /* need more space */ - nfa_size=2*(nfa_allocated+1); - nfa_array=(nfa_node **) realloc(nfa_array, - sizeof(nfa_node*)*nfa_size); - } - } - /* fill out entry in array */ - t = (nfa_node*) malloc(sizeof(nfa_node)); - nfa_array[nfa_allocated] = t; - *t = nfa_model_node; - t->node_no = nfa_allocated; - return t; -} - - -/* initialize the model node used to fill in newly made nfa_nodes */ -void -#ifdef __USE_PROTOS -make_nfa_model_node(void) -#else -make_nfa_model_node() -#endif -{ - nfa_model_node.node_no = -1; /* impossible value for real nfa node */ - nfa_model_node.nfa_set = 0; - nfa_model_node.accept = 0; /* error state default*/ - nfa_model_node.trans[0] = NULL; - nfa_model_node.trans[1] = NULL; - nfa_model_node.label = empty; -} ->> - -<< -#if defined(DEBUG) || defined(_DEBUG) - -/* print out the pointer value and the node_number */ -void -#ifdef __USE_PROTOS -fprint_dfa_pair(FILE *f, nfa_node *p) -#else -fprint_dfa_pair(f, p) -FILE *f; -nfa_node *p; -#endif -{ - if (p){ - fprintf(f, "%x (%d)", p, p->node_no); - }else{ - fprintf(f, "(nil)"); - } -} - -/* print out interest information on a set */ -void -#ifdef __USE_PROTOS -fprint_set(FILE *f, set s) -#else -fprint_set(f,s) -FILE *f; -set s; -#endif -{ - unsigned int *x; - - fprintf(f, "n = %d,", s.n); - if (s.setword){ - fprintf(f, "setword = %x, ", s.setword); - /* print out all the elements in the set */ - x = set_pdq(s); - while (*x!=nil){ - fprintf(f, "%d ", *x); - ++x; - } - }else{ - fprintf(f, "setword = (nil)"); - } -} - -/* code to be able to dump out the nfas - return 0 if okay dump - return 1 if screwed up - */ -int -#ifdef __USE_PROTOS -dump_nfas(int first_node, int last_node) -#else -dump_nfas(first_node, last_node) -int first_node; -int last_node; -#endif -{ - register int i; - nfa_node *t; - - for (i=first_node; i<=last_node; ++i){ - t = NFA(i); - if (!t) break; - fprintf(stderr, "nfa_node %d {\n", t->node_no); - fprintf(stderr, "\n\tnfa_set = %d\n", t->nfa_set); - fprintf(stderr, "\taccept\t=\t%d\n", t->accept); - fprintf(stderr, "\ttrans\t=\t("); - fprint_dfa_pair(stderr, t->trans[0]); - fprintf(stderr, ","); - fprint_dfa_pair(stderr, t->trans[1]); - fprintf(stderr, ")\n"); - fprintf(stderr, "\tlabel\t=\t{ "); - fprint_set(stderr, t->label); - fprintf(stderr, "\t}\n"); - fprintf(stderr, "}\n\n"); - } - return 0; -} -#endif ->> - -<< -/* DLG-specific syntax error message generator - * (define USER_ZZSYN when compiling so don't get 2 definitions) - */ -void -#ifdef __USE_PROTOS -zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, int k, char *bad_text) -#else -zzsyn(text, tok, egroup, eset, etok, k, bad_text) -char *text, *egroup, *bad_text; -int tok; -int etok; -int k; -SetWordType *eset; -#endif -{ - fprintf(stderr, ErrHdr, file_str[0]!=NULL?file_str[0]:"stdin", zzline); - fprintf(stderr, " syntax error at \"%s\"", (tok==zzEOF_TOKEN)?"EOF":text); - if ( !etok && !eset ) {fprintf(stderr, "\n"); return;} - if ( k==1 ) fprintf(stderr, " missing"); - else - { - fprintf(stderr, "; \"%s\" not", bad_text); - if ( zzset_deg(eset)>1 ) fprintf(stderr, " in"); - } - if ( zzset_deg(eset)>0 ) zzedecode(eset); - else fprintf(stderr, " %s", zztokens[etok]); - if ( strlen(egroup) > (size_t)0 ) fprintf(stderr, " in %s", egroup); - fprintf(stderr, "\n"); -} ->> diff --git a/Tools/CodeTools/TianoTools/Pccts/dlg/err.c b/Tools/CodeTools/TianoTools/Pccts/dlg/err.c deleted file mode 100644 index c3eaeae6d1..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/dlg/err.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * A n t l r S e t s / E r r o r F i l e H e a d e r - * - * Generated from: dlg_p.g - * - * Terence Parr, Russell Quong, Will Cohen, and Hank Dietz: 1989-2001 - * Parr Research Corporation - * with Purdue University Electrical Engineering - * With AHPCRC, University of Minnesota - * ANTLR Version 1.33MR33 - */ - -#define ANTLR_VERSION 13333 -#include "pcctscfg.h" -#include "pccts_stdio.h" - -#include -#include "dlg.h" -#define zzSET_SIZE 8 -#include "antlr.h" -#include "tokens.h" -#include "dlgdef.h" -#include "err.h" - -ANTLRChar *zztokens[46]={ - /* 00 */ "Invalid", - /* 01 */ "@", - /* 02 */ "[\\r\\t\\ ]+", - /* 03 */ "\\n", - /* 04 */ "L_EOF", - /* 05 */ "PER_PER", - /* 06 */ "NAME_PER_PER", - /* 07 */ "LEXMEMBER", - /* 08 */ "LEXACTION", - /* 09 */ "PARSERCLASS", - /* 10 */ "LEXPREFIX", - /* 11 */ "ACTION", - /* 12 */ "GREAT_GREAT", - /* 13 */ "L_BRACE", - /* 14 */ "R_BRACE", - /* 15 */ "L_PAR", - /* 16 */ "R_PAR", - /* 17 */ "L_BRACK", - /* 18 */ "R_BRACK", - /* 19 */ "ZERO_MORE", - /* 20 */ "ONE_MORE", - /* 21 */ "OR", - /* 22 */ "RANGE", - /* 23 */ "NOT", - /* 24 */ "OCTAL_VALUE", - /* 25 */ "HEX_VALUE", - /* 26 */ "DEC_VALUE", - /* 27 */ "TAB", - /* 28 */ "NL", - /* 29 */ "CR", - /* 30 */ "BS", - /* 31 */ "CONTINUATION", - /* 32 */ "LIT", - /* 33 */ "REGCHAR", - /* 34 */ "\\>", - /* 35 */ "\\\\>", - /* 36 */ "\\", - /* 37 */ "\\n", - /* 38 */ "/\\*", - /* 39 */ "//", - /* 40 */ "~[]", - /* 41 */ "\\*/", - /* 42 */ "[\\n\\r]", - /* 43 */ "~[]", - /* 44 */ "[\\n\\r]", - /* 45 */ "~[]" -}; -SetWordType zzerr1[8] = {0x80,0xf,0x0,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr2[8] = {0x60,0x0,0x0,0x0, 0x0,0x0,0x0,0x0}; -SetWordType zzerr3[8] = {0x70,0xa8,0x9a,0x7f, 0x3,0x0,0x0,0x0}; -SetWordType setwd1[46] = {0x0,0x6,0x0,0x0,0x30,0xc8,0xc8, - 0x1,0x1,0x1,0x1,0x35,0x0,0x30,0x0, - 0x30,0x0,0x30,0x0,0x30,0x30,0x0,0x0, - 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30, - 0x0,0x30,0x30,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0}; -SetWordType zzerr4[8] = {0x10,0xa8,0x9a,0x7f, 0x3,0x0,0x0,0x0}; -SetWordType zzerr5[8] = {0x10,0xe8,0xbb,0x7f, 0x3,0x0,0x0,0x0}; -SetWordType zzerr6[8] = {0x10,0xa0,0x9a,0x7f, 0x3,0x0,0x0,0x0}; -SetWordType setwd2[46] = {0x0,0x0,0x0,0x0,0xeb,0x2,0x2, - 0x0,0x0,0x0,0x0,0xd6,0x0,0xeb,0xd4, - 0xeb,0xd4,0xeb,0x0,0xcb,0xcb,0xd0,0x0, - 0xeb,0xeb,0xeb,0xeb,0xeb,0xeb,0xeb,0xeb, - 0x0,0xeb,0xeb,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0}; -SetWordType zzerr7[8] = {0x10,0xa0,0x82,0x7f, 0x3,0x0,0x0,0x0}; -SetWordType zzerr8[8] = {0x10,0x0,0x44,0x7f, 0x3,0x0,0x0,0x0}; -SetWordType zzerr9[8] = {0x10,0x0,0x0,0x7f, 0x3,0x0,0x0,0x0}; -SetWordType setwd3[46] = {0x0,0x0,0x0,0x0,0xf7,0x0,0x0, - 0x0,0x0,0x0,0x0,0xc2,0x0,0xc2,0xc2, - 0xc2,0xc2,0xc2,0xb8,0xc2,0xc2,0xc2,0x80, - 0xc2,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7, - 0x0,0xf7,0xf7,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0}; diff --git a/Tools/CodeTools/TianoTools/Pccts/dlg/main.c b/Tools/CodeTools/TianoTools/Pccts/dlg/main.c deleted file mode 100644 index 35bd827f8c..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/dlg/main.c +++ /dev/null @@ -1,281 +0,0 @@ -/* Main function for dlg version - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * DLG 1.33 - * Will Cohen - * With mods by Terence Parr; AHPCRC, University of Minnesota - * 1989-2001 - */ - -#include -#include "stdpccts.h" - -char program[] = "dlg"; -char version[] = "1.33MR33"; /* MRXXX */ -int numfiles = 0; -char *file_str[2] = {NULL, NULL}; -char *mode_file = "mode.h"; -char *class_name = DEFAULT_CLASSNAME; -char *OutputDirectory = TopDirectory; - -/* Option variables */ -int comp_level = 0; -int interactive = FALSE; -int case_insensitive = FALSE; -int warn_ambig = FALSE; -int gen_cpp = FALSE; - -#ifdef __USE_PROTOS -static int ci_strequ(char *a,char *b) -#else -static int ci_strequ(a,b) - char *a; - char *b; -#endif -{ - for ( ;*a != 0 && *b != 0; a++, b++) { - if (toupper(*a) != toupper(*b)) return 0; - } - return (*a == *b); -} - -/* Option List Stuff */ -#ifdef __USE_PROTOS -void p_comp0(void) {comp_level = 0;} -void p_comp1(void) {comp_level = 1;} -void p_comp2(void) {comp_level = 2;} -void p_stdio(void) { file_str[numfiles++] = NULL;} -void p_file(char *s) { file_str[numfiles++] = s;} -void p_cl_name(char *s, char *t) - { - if ( gen_cpp ) { - class_name = t; - } - else { - warning("-cl only valid in C++ mode; -cl ignored...",0); - } - } -void p_mode_file(char *s, char *t){mode_file=t;} -void p_outdir(char *s,char *t) {OutputDirectory=t;} -void p_ansi(void) {gen_ansi = TRUE;} -void p_interactive(void) {interactive = TRUE;} -void p_case_s(void) { case_insensitive = FALSE; } -void p_case_i(void) { case_insensitive = TRUE; } -void p_warn_ambig(void) { warn_ambig = TRUE; } -void p_cpp(void) { gen_cpp = TRUE; } -#else -void p_comp0() {comp_level = 0;} -void p_comp1() {comp_level = 1;} -void p_comp2() {comp_level = 2;} -void p_stdio() { file_str[numfiles++] = NULL;} -void p_file(s) char *s; { file_str[numfiles++] = s;} -void p_cl_name(s,t) - char *s, *t; - { - if ( gen_cpp ) { - class_name = t; - } - else { - warning("-cl only valid in C++ mode; -cl ignored...",0); - } - } -void p_mode_file(s,t) char *s,*t;{mode_file=t;} -void p_outdir(s,t) char *s,*t;{OutputDirectory=t;} -void p_ansi() {gen_ansi = TRUE;} -void p_interactive() {interactive = TRUE;} -void p_case_s() { case_insensitive = FALSE; } -void p_case_i() { case_insensitive = TRUE; } -void p_warn_ambig() { warn_ambig = TRUE; } -void p_cpp() { gen_cpp = TRUE; } -#endif - -#ifdef __cplusplus -typedef void (*WildFunc)(...); -#else -typedef void (*WildFunc)(); -#endif - -typedef struct { - char *option; - int arg; - WildFunc process; - char *descr; - } Opt; - -Opt options[] = { - { "-CC", 0, (WildFunc)p_cpp, "Generate C++ output" }, - { "-C0", 0, (WildFunc)p_comp0, "No compression (default)" }, - { "-C1", 0, (WildFunc)p_comp1, "Compression level 1" }, - { "-C2", 0, (WildFunc)p_comp2, "Compression level 2" }, - { "-ga", 0, (WildFunc)p_ansi, "Generate ansi C"}, - { "-Wambiguity", 0, (WildFunc)p_warn_ambig, "Warn if expressions ambiguous"}, - { "-m", 1, (WildFunc)p_mode_file, "Rename lexical mode output file"}, - { "-i", 0, (WildFunc)p_interactive, "Build interactive scanner (not valid for C++ mode)"}, - { "-ci", 0, (WildFunc)p_case_i, "Make lexical analyzer case insensitive"}, - { "-cl", 1, (WildFunc)p_cl_name, "Rename lexer class (DLGLexer); only used for -CC"}, - { "-cs", 0, (WildFunc)p_case_s, "Make lexical analyzer case sensitive (default)"}, - { "-o", 1, (WildFunc)p_outdir, OutputDirectoryOption}, - { "-", 0, (WildFunc)p_stdio, "Use standard i/o rather than file"}, - { "*", 0, (WildFunc)p_file, ""}, /* anything else is a file */ - { NULL, 0, NULL } - }; - -#ifdef __USE_PROTOS -void ProcessArgs(int argc, char **argv, Opt *options) -#else -void ProcessArgs(argc, argv, options) -int argc; -char **argv; -Opt *options; -#endif -{ - Opt *p; - - while ( argc-- > 0 ) - { - p = options; - while ( p->option != NULL ) - { - if ( strcmp(p->option, "*") == 0 || - ci_strequ(p->option,*argv) ) - { - if ( p->arg ) - { - (*p->process)( *argv, *(argv+1) ); - argv++; - argc--; - } - else - (*p->process)( *argv ); - break; - } - p++; - } - argv++; - } -} - -#ifdef __USE_PROTOS -int main(int argc, char *argv[]) -#else -int main(argc, argv) -int argc; -char *argv[]; -#endif -{ - init(); - fprintf(stderr, "%s Version %s 1989-2001\n", &(program[0]), - &(version[0])); - if ( argc == 1 ) - { - Opt *p = options; - fprintf(stderr, "%s [options] f1 f2 ... fn\n",argv[0]); - while ( *(p->option) != '*' ) - { - fprintf(stderr, "\t%s %s\t%s\n", - p->option, - (p->arg)?"___":" ", - p->descr); - p++; - } - }else{ - ProcessArgs(argc-1, &(argv[1]), options); - if (interactive && gen_cpp) { - fprintf(stderr,"\n"); -/*** MR21a This statement is wrong ! ***/ -#if 0 -*** fprintf(stderr,"Interactive lexer option (\"-i\") has no effect when in C++ mode\n"); -*** fprintf(stderr,"because of extra buffering provided by ANTLRTokenBuffer class.\n"); -*** fprintf(stderr,"\n"); -#endif - } - input_stream = read_stream(file_str[0]); - if (input_stream) { - /* don't overwrite unless input okay */ - if ( gen_cpp ) { - output_stream = write_stream(ClassName(CPP_FILE_SUFFIX)); - if ( file_str[1]!=NULL ) { - warning("output file implicit in C++ mode; ignored...",0); - } - class_stream = write_stream(ClassName(".h")); - mode_stream = class_stream; - } - else { - output_stream = write_stream(file_str[1]); - mode_stream = write_stream(mode_file); - } - } - /* make sure that error reporting routines in grammar - know what the file really is */ - /* make sure that reading and writing somewhere */ - if (input_stream && output_stream && mode_stream){ - ANTLR(grammar(), input_stream); - } - p_class_def2(); /* MR1 */ - } - if ( output_stream!=NULL ) fclose(output_stream); - if ( !gen_cpp && mode_stream!=NULL ) fclose(mode_stream); - if ( class_stream!=NULL ) fclose(class_stream); - exit(PCCTS_EXIT_SUCCESS); - return 0; /* get rid of warning message MR1 */ -} - -/* initialize all the variables */ -void -#ifdef __USE_PROTOS -init(void) -#else -init() -#endif -{ - register int i; - -#ifdef SPECIAL_INITS - special_inits(); /* MR1 */ -#endif - used_chars = empty; - used_classes = empty; - /* make the valid character set */ - normal_chars = empty; - /* NOTE: MIN_CHAR is EOF */ - /* NOTE: EOF is not quite a valid char, it is special. Skip it*/ - for (i = 1; i -#include -#include "dlg.h" -#ifdef MEMCHK -#include "trax.h" -#else -#ifdef __STDC__ -#include -#else -#include -#endif /* __STDC__ */ -#endif - -static char *mode_name[MAX_MODES]; -static int mode_number[MAX_MODES]; -static int cur_mode=0; - -int operation_no = 0; /* used to mark nodes so that infinite loops avoided */ -int dfa_basep[MAX_MODES]; /* start of each group of states */ -int dfa_class_nop[MAX_MODES]; /* number of elements in each group of states*/ - -int gen_ansi = FALSE; /* allows ansi code to be generated */ - -FILE *input_stream; /* where to read description from */ -FILE *output_stream; /* where to put the output */ -FILE *mode_stream; /* where to put the mode.h stuff */ -FILE *class_stream; /* where to put the scan.h stuff (if gen_cpp) */ - -/* NOTE: This section is MACHINE DEPENDENT */ -#define DIF_SIZE 4 -#if defined(PC) && !defined(PC32) -unsigned long typesize[DIF_SIZE] = { 0x7f, 0x7fff, 0x7ffful, 0x7ffffffful }; /* MR20 */ -char t0[] = "unsigned char"; -char t1[] = "unsigned short"; -char t2[] = "unsigned int"; -char t3[] = "unsigned long"; -char *typevar[DIF_SIZE] = { t0, t1, t2, t3}; -#else -unsigned long typesize[DIF_SIZE] = { 0x7f, 0x7fff, 0x7ffffffful, 0x7ffffffful }; /* MR20 */ -char t0[] = "unsigned char"; -char t1[] = "unsigned short"; -char t2[] = "unsigned int"; -char t3[] = "unsigned long"; -char *typevar[DIF_SIZE] = { t0, t1, t2, t3}; -#endif - -/* Added by TJP August 1994 */ -/* Take in MyLexer and return MyLexer_h */ - -static char * -#ifdef __USE_PROTOS -gate_symbol(char *name) -#else -gate_symbol(name) -char *name; -#endif -{ - static char buf[100]; - sprintf(buf, "%s_h", name); - return buf; -} - -/* Added by TJP August 1994 */ -static char * -#ifdef __USE_PROTOS -mystrdup(char *s) -#else -mystrdup(s) -char *s; -#endif -{ - char *p = (char *)malloc(strlen(s)+1); - strcpy(p, s); - return p; -} - -#ifdef __USE_PROTOS -void p_class_hdr(void) -#else -void p_class_hdr() -#endif -{ - if ( class_stream == NULL ) return; - fprintf(class_stream, "#ifndef %s\n", gate_symbol(ClassName(""))); - fprintf(class_stream, "#define %s\n", gate_symbol(ClassName(""))); - fprintf(class_stream, "/*\n"); - fprintf(class_stream, " * D L G L e x e r C l a s s D e f i n i t i o n\n"); - fprintf(class_stream, " *\n"); - fprintf(class_stream, " * Generated from:"); - fprintf(class_stream, " %s", file_str[0]); - fprintf(class_stream, "\n"); - fprintf(class_stream, " *\n"); - fprintf(class_stream, " * 1989-2001 by Will Cohen, Terence Parr, and Hank Dietz\n"); - fprintf(class_stream, " * Purdue University Electrical Engineering\n"); - fprintf(class_stream, " * DLG Version %s\n", version); - fprintf(class_stream, " */\n\n"); - fprintf(class_stream, "\n"); - fprintf(class_stream, "#include \"%s\"\n", DLEXERBASE_H); -} - -/* MR1 */ -/* MR1 16-Apr-97 Split printing of class header up into several parts */ -/* MR1 so that #lexprefix <<...>>and #lexmember <<...>> */ -/* MR1 can be inserted in the appropriate spots */ -/* MR1 */ - -#ifdef __USE_PROTOS -void p_class_def1(void) -#else -void p_class_def1() -#endif -{ - if ( class_stream == NULL ) return; - fprintf(class_stream, "\nclass %s : public DLGLexerBase {\n", ClassName("")); - fprintf(class_stream, "public:\n"); -} - -#ifdef __USE_PROTOS -void p_class_def2(void) -#else -void p_class_def2() -#endif -{ - int i, m; - if ( class_stream == NULL ) return; - fprintf(class_stream, "public:\n"); - fprintf(class_stream, "\tstatic const int MAX_MODE;\n"); - fprintf(class_stream, "\tstatic const int DfaStates;\n"); - for (i=0; i> */ -/* MR1 */ -/* MR1 */ fprintf(class_stream,"//\n"); -/* MR1 */ fprintf(class_stream, -/* MR1 */ "// 133MR1 Deprecated feature to allow inclusion of "); -/* MR1 */ fprintf(class_stream, -/* MR1 */ "user-defined code in DLG class header\n"); -/* MR1 */ fprintf(class_stream,"//\n"); -/* MR1 */ -/* MR1 */ fprintf(class_stream,"#ifdef DLGLexerIncludeFile\n"); -/* MR1 */ fprintf(class_stream,"#include DLGLexerIncludeFile\n"); -/* MR1 */ fprintf(class_stream,"#endif\n"); - - fprintf(class_stream, "};\n"); - - fprintf(class_stream, "typedef ANTLRTokenType (%s::*Ptr%sMemberFunc)();\n", - ClassName(""), ClassName("")); - - fprintf(class_stream, "#endif\n"); -} - -/* generate required header on output */ - -#ifdef __USE_PROTOS -void p_head(void) -#else -void p_head() -#endif -{ - fprintf(OUT, "/*\n"); - fprintf(OUT, " * D L G tables\n"); - fprintf(OUT, " *\n"); - fprintf(OUT, " * Generated from:"); - fprintf(OUT, " %s", file_str[0]); - fprintf(OUT, "\n"); - fprintf(OUT, " *\n"); - fprintf(OUT, " * 1989-2001 by Will Cohen, Terence Parr, and Hank Dietz\n"); - fprintf(OUT, " * Purdue University Electrical Engineering\n"); - fprintf(OUT, " * DLG Version %s\n", version); - fprintf(OUT, " */\n\n"); - if ( gen_cpp) fprintf(OUT, "#include \"pcctscfg.h\"\n"); - if ( gen_cpp ) fprintf(OUT, "#include \"pccts_stdio.h\"\n"); - if ( !gen_cpp ) fprintf(OUT, "#include \"%s\"\n\n", mode_file); - fprintf(OUT,"\n"); -} - -#ifdef __USE_PROTOS -void p_includes(void) -#else -void p_includes() -#endif -{ - fprintf(OUT, "#include \"%s\"\n", APARSER_H); - fprintf(OUT, "#include \"%s\"\n", DLEXERBASE_H); - fprintf(OUT, "#include \"%s\"\n", ClassName(".h")); -} - -/* generate code to tie up any loose ends */ - -#ifdef __USE_PROTOS -void p_tail(void) /* MR1 */ -#else -void p_tail() /* MR1 */ -#endif -{ - if ( gen_cpp ) { - if ( strcmp(ClassName(""), DEFAULT_CLASSNAME)!=0 ) - fprintf(OUT, "#define DLGLexer %s\n", ClassName("")); - fprintf(OUT, "#include \"%s\"\n", DLEXER_H); /* MR23 Rename DLexer.cpp to DLexer.h */ - return; - } - fprintf(OUT, "\n"); - fprintf(OUT, "\n"); - if (comp_level) - fprintf(OUT, "#define ZZSHIFT(c) (b_class_no[zzauto][1+c])\n"); - else - fprintf(OUT, "#define ZZSHIFT(c) (1+c)\n"); - if ( !gen_cpp ) fprintf(OUT, "#define MAX_MODE %d\n",mode_counter); - fprintf(OUT, "#include \"dlgauto.h\"\n"); -} - - -/* output the table of DFA for general use */ - -#ifdef __USE_PROTOS -void p_tables() -#else -void p_tables() -#endif -{ - if ( !gen_cpp ) { - fprintf(OUT, "#define DfaStates\t%d\n", dfa_allocated); - fprintf(OUT, "typedef %s DfaState;\n\n", minsize(dfa_allocated)); - } - - if ( gen_cpp ) { - int i; - fprintf(OUT, "\n"); - fprintf(OUT, "const int %s::MAX_MODE=%d;\n", - ClassName(""), - mode_counter); - fprintf(OUT, "const int %s::DfaStates=%d;\n", - ClassName(""), - dfa_allocated); - for (i=0; i typesize[i]) /* MR20 */ - ++i; - return typevar[i]; -} - - -#ifdef __USE_PROTOS -void p_node_table(void) -#else -void p_node_table() -#endif -{ - register int i; - register int m = 0; - - for(m=0; m<(mode_counter-1); ++m){ - for(i=dfa_basep[m]; itrans[j]; - if (trans == NIL_INDEX) - trans = dfa_allocated+1; - /* all of DFA moved down one in array */ - fprintf(OUT, "%d", trans-1); - fprintf(OUT, ", "); - if (!(--items_on_line)){ - fprintf(OUT, "\n "); - items_on_line = MAX_ON_LINE; - } - } -#if 1 - /* put in jump to error state */ - fprintf(OUT, "%d\n};\n\n", dfa_allocated); -#else - fprintf(OUT, "\n};\n\n"); -#endif -} - - -#ifdef __USE_PROTOS -void p_dfa_table(void) -#else -void p_dfa_table() -#endif -{ - register int i; - - fprintf(OUT, "\n%sDfaState *%sdfa[%d] = {\n", - gen_cpp?ClassName("::"):"",gen_cpp?ClassName("::"):"", dfa_allocated); - for (i=0; i<(dfa_allocated-1); ++i){ - fprintf(OUT, "\tst%d,\n", i); - } - fprintf(OUT, "\tst%d\n", i); - fprintf(OUT, "};\n\n"); -} - - -#ifdef __USE_PROTOS -void p_accept_table(void) -#else -void p_accept_table() -#endif -{ - register int i = 1; - register int items_on_line = 0; - int true_interactive = TRUE; - - /* make sure element for one past (zzerraction) -WEC 12/16/92 */ - fprintf(OUT,"\n%sDfaState %saccepts[%d] = {\n ", - gen_cpp?ClassName("::"):"", - gen_cpp?ClassName("::"):"", - dfa_allocated+1); - /* don't do anything if no dfa nodes */ - if (i>dfa_allocated) goto skip_accepts; - for (;;) { - int accept=0; /* MR14a - Manuel Kessler (mlkessle@cip.physik.uni-wuerzburg.de) */ - set accept_set; - set nfa_states; - unsigned int *t, *nfa_i; - unsigned int *q, *regular_expr; - - accept_set = empty; - nfa_states = DFA(i)->nfa_states; - t = nfa_i = set_pdq(nfa_states); - /* NOTE: picks lowest accept because accepts monotonic */ - /* with respect to nfa node numbers and set_pdq */ - /* returns in that order */ - while((*nfa_i != nil) && (!(accept = NFA(*nfa_i)->accept))){ - nfa_i++; - } - - /* figure out if more than one accept state there */ - if (warn_ambig ){ - set_orel(accept, &accept_set); - while(*nfa_i != nil){ - set_orel(NFA(*nfa_i)->accept, &accept_set); - nfa_i++; - } - /* remove error action from consideration */ - set_rm(0, accept_set); - - if( set_deg(accept_set)>1){ - fprintf(stderr, "dlg warning: ambiguous regular expression "); - q = regular_expr = set_pdq(accept_set); - while(*regular_expr != nil){ - fprintf(stderr," %d ", *regular_expr); - ++regular_expr; - } - fprintf(stderr, "\n"); - free(q); - } - } - - if ((DFA(i)->alternatives) && (accept != 0)){ - true_interactive = FALSE; - } - fprintf(OUT, "%d, ", accept); - - /* free up memory before we "break" below -ATG 4/6/95 */ - free(t); - set_free(accept_set); - - if ((++i)>dfa_allocated) - break; - if ((++items_on_line)>=MAX_ON_LINE){ - fprintf(OUT,"\n "); - items_on_line = 0; - } -/* - free(t); - set_free(accept_set); -*/ - } - /* make sure element for one past (zzerraction) -WEC 12/16/92 */ -skip_accepts: - fprintf(OUT, "0\n};\n\n"); -} - - -#ifdef __USE_PROTOS -void p_action_table(void) -#else -void p_action_table() -#endif -{ - register int i; - char* theClassName = ClassName(""); - - if ( gen_cpp ) - fprintf(OUT, "Ptr%sMemberFunc %s::actions[%d] = {\n", theClassName, - theClassName, action_no+1); - else - fprintf(OUT, "void (*actions[%d])() = {\n", action_no+1); - if ( gen_cpp ) -/* fprintf(OUT, "\t(Ptr%sMemberFunc)&%s::erraction,\n", theClassName, theClassName);*/ - fprintf(OUT, "\t&%s::erraction,\n", theClassName); - else - fprintf(OUT, "\tzzerraction,\n"); - for (i=1; i=CHAR_RANGE) - break; - fprintf(OUT,", "); - if ((++items_on_line)>=MAX_ON_LINE){ - fprintf(OUT,"\n "); - items_on_line = 0; - } - } - fprintf(OUT, "\n};\n\n"); -} - - -#ifdef __USE_PROTOS -void p_base_table(void) -#else -void p_base_table() -#endif -{ - register int m; - - fprintf(OUT, "%sDfaState %sdfa_base[] = {\n", - gen_cpp?ClassName("::"):"static ", - gen_cpp?ClassName("::"):""); - for(m=0; m<(mode_counter-1); ++m) - fprintf(OUT, "\t%d,\n", dfa_basep[m]-1); - fprintf(OUT, "\t%d\n};\n\n", dfa_basep[m]-1); -} - - -#ifdef __USE_PROTOS -void p_class_table(void) /* MR1 */ -#else -void p_class_table() /* MR1 */ -#endif -{ -#if 0 - register int m; - - fprintf(OUT,"%s int %sdfa_class_no[] = {\n", - gen_cpp?"":"static", - gen_cpp?ClassName("::"):""); - for(m=0; m<(mode_counter-1); ++m) - fprintf(OUT,"\t%d,\n", dfa_class_nop[m]); - fprintf(OUT,"\t%d\n};\n\n", dfa_class_nop[m]); -#endif -} - - -#ifdef __USE_PROTOS -void p_bshift_table(void) /* MR1 */ -#else -void p_bshift_table() /* MR1 */ -#endif -{ - register int m; - - fprintf(OUT,"%s unsigned char *%sb_class_no[] = {\n", - gen_cpp?"":"static", - gen_cpp?ClassName("::"):""); - for(m=0; m<(mode_counter-1); ++m) - fprintf(OUT, "\tshift%d,\n", m); - fprintf(OUT, "\tshift%d\n};\n\n", m); -} - - -#ifdef __USE_PROTOS -void p_alternative_table(void) /* MR1 */ -#else -void p_alternative_table() /* MR1 */ -#endif -{ - register int i; - - if ( !gen_cpp ) fprintf(OUT, "#define ZZINTERACTIVE\n\n"); - if ( gen_cpp ) - fprintf(OUT, "DLGChar %salternatives[%d] = {\n", /* mr23 vhs %sDfaStates+1 */ - ClassName("::"), - dfa_allocated+1); /* vhs ClassName("::")); */ - else - fprintf(OUT, "static %s zzalternatives[DfaStates+1] = {\n", - minsize(dfa_allocated)); - - for(i=1; i<=dfa_allocated; ++i) - fprintf(OUT, "\t%d,\n", DFA(i)->alternatives); - fprintf(OUT, "/* must have 0 for zzalternatives[DfaStates] */\n"); - fprintf(OUT, "\t0\n};\n\n"); -} - - -#ifdef __USE_PROTOS -void p_mode_def(char *s,int m) /* MR1 */ -#else -void p_mode_def(s,m) /* MR1 */ -char *s; -int m; -#endif -{ - if ( gen_cpp ) - { - mode_name[cur_mode] = mystrdup(s); - mode_number[cur_mode] = m; - cur_mode++; - } - else - fprintf(mode_stream, "#define %s %d\n", s, m); -} - -#ifdef __USE_PROTOS -char * ClassName(char *suffix) -#else -char * ClassName(suffix) -char *suffix; -#endif -{ - static char buf[200]; - extern char *class_name; - - sprintf(buf, "%s%s", class_name, suffix); - return buf; -} - -#ifdef DEBUG - -/* print out a particular nfa node that is pointed to by p */ - -#ifdef __USE_PROTOS -void p_nfa_node(nfa_node *p) -#else -void p_nfa_node(p) -nfa_node *p; -#endif -{ - register nfa_node *t; - - if (p != NIL_INDEX){ - printf("NFA state : %d\naccept state : %d\n", - NFA_NO(p),p->accept); - if (p->trans[0] != NIL_INDEX){ - printf("trans[0] => %d on ", NFA_NO(p->trans[0])); - p_set(p->label); - printf("\n"); - } - else - printf("trans[0] => nil\n"); - if (p->trans[1] != NIL_INDEX) - printf("trans[1] => %d on epsilon\n", - NFA_NO(p->trans[1])); - else - printf("trans[1] => nil\n"); - printf("\n"); - } -} -#endif - -#ifdef DEBUG - -/* code to print out special structures when using a debugger */ - -#ifdef __USE_PROTOS -void p_nfa(p) -#else -void p_nfa(nfa_node *p) -nfa_node *p; /* state number also index into array */ -#endif -{ -/* each node has a marker on it so it only gets printed once */ - - operation_no++; /* get new number */ - s_p_nfa(p); -} - -#ifdef __USE_PROTOS -void s_p_nfa(nfa_node *p) -#else -void s_p_nfa(p) -nfa_node *p; /* state number also index into array */ -#endif -{ - if ((p != NIL_INDEX) && (p->nfa_set != operation_no)){ - /* so it is only printed once */ - p->nfa_set = operation_no; - p_nfa_node(p); - s_p_nfa(p->trans[0]); - s_p_nfa(p->trans[1]); - } -} - -#ifdef __USE_PROTOS -void p_dfa_node(dfa_node *p) -#else -void p_dfa_node(p) -dfa_node *p; -#endif -{ - int i; - - if (p != NIL_INDEX){ - printf("DFA state :%d\n",NFA_NO(p)); - if (p->done) - printf("done\n"); - else - printf("undone\n"); - printf("from nfa states : "); - p_set(p->nfa_states); - printf("\n"); - /* NOTE: trans arcs stored as ints rather than pointer*/ - for (i=0; itrans[i]); - } - printf("\n\n"); - } -} - -#ifdef __USE_PROTOS -void p_dfa(void) -#else -void p_dfa() -#endif -{ -/* prints out all the dfa nodes actually allocated */ - - int i; - - for (i = 1; i<=dfa_allocated; i++) - p_dfa_node(NFA(i)); -} - - -/* print out numbers in the set label */ - -#ifdef __USE_PROTOS -void p_set(set label) -#else -void p_set(label) -set label; -#endif -{ - unsigned *t, *e; - - if (set_nil(label)){ - printf("epsilon\n"); - }else{ - t = e = set_pdq(label); - while(*e != nil){ - printf("%d ", (*e+MIN_CHAR)); - e++; - } - printf("\n"); - free(t); - } - -} -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/dlg/parser.dlg b/Tools/CodeTools/TianoTools/Pccts/dlg/parser.dlg deleted file mode 100644 index df9a637f9e..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/dlg/parser.dlg +++ /dev/null @@ -1,398 +0,0 @@ -<< -/* parser.dlg -- DLG Description of scanner - * - * Generated from: dlg_p.g - * - * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001 - * Purdue University Electrical Engineering - * With AHPCRC, University of Minnesota - * ANTLR Version 1.33MR33 - */ - -#define ANTLR_VERSION 13333 -#include "pcctscfg.h" -#include "pccts_stdio.h" - -#include -#include "dlg.h" -#include "antlr.h" -#include "tokens.h" -#include "dlgdef.h" -LOOKAHEAD - -void -#ifdef __USE_PROTOS -zzerraction(void) -#else -zzerraction() -#endif -{ - (*zzerr)("invalid token"); - zzadvance(); - zzskip(); -} ->> - -<<%%lexaction - -int func_action; /* should actions be turned into functions?*/ -int lex_mode_counter = 0; /* keeps track of the number of %%names */ -/* MR1 */ -/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ -/* MR1 via <<%%lexmember...>> */ -/* MR1 */ -int lexMember = 0; /* <<%%lexmemeber ...>> MR1 */ -int lexAction = 0; /* <<%%lexaction ...>> MR1 */ -int parserClass = 0; /* <<%%parserclass ...>> MR1 */ -int lexPrefix = 0; /* <<%%lexprefix ...>> MR1 */ -char theClassName[100]; /* MR11 */ -char *pClassName=theClassName; /* MR11 */ -int firstLexMember=1; /* MR1 */ - -#ifdef __USE_PROTOS -void xxputc(int c) { /* MR1 */ -#else - void xxputc(c) /* MR1 */ - int c; /* MR1 */ - { /* MR1 */ -#endif - if (parserClass) { /* MR1 */ - *pClassName++=c; /* MR1 */ - *pClassName=0; /* MR1 */ - } else if (lexMember || lexPrefix) { /* MR1 */ - if (class_stream != NULL) fputc(c,class_stream); /* MR1 */ - } else { /* MR1 */ - fputc(c,OUT); /* MR1 */ - }; /* MR1 */ - } /* MR1 */ - -#ifdef __USE_PROTOS - void xxprintf(char *format,char *string) { /* MR1 */ -#else - void xxprintf(format,string) /* MR1 */ - char *format; /* MR1 */ - char *string; /* MR1 */ - { /* MR1 */ -#endif - if (lexMember || lexPrefix || parserClass) { /* MR1 */ - if (class_stream != NULL) /* MR1 */ - fprintf(class_stream,format,string); /* MR1 */ - } else { /* MR1 */ - fprintf(OUT,format,string); /* MR1 */ - }; /* MR1 */ - } /* MR1 */ ->> - - -%%START - -@ - << - NLA = 1; - >> - -[\r\t\ ]+ - << - NLA = 2; - zzskip(); - >> - -\n - << - NLA = 3; - zzline++; zzskip(); DAWDLE; - >> - -\@ - << - NLA = L_EOF; - >> - -\%\% - << - NLA = PER_PER; - >> - -\%\%[a-zA-Z_][a-zA-Z0-9_]* - << - NLA = NAME_PER_PER; - p_mode_def(&zzlextext[2],lex_mode_counter++); - >> - -\<\<\%\%lexmember - << - NLA = LEXMEMBER; - lexMember=1; /* MR1 */ - if (firstLexMember != 0) { /* MR1 */ - firstLexMember=0; /* MR1 */ - p_class_def1(); /* MR1 */ - }; /* MR1 */ - zzmode(ACT); /* MR1 */ - >> - -\<\<\%\%lexaction - << - NLA = LEXACTION; - lexAction=1;zzmode(ACT); - >> - -\<\<\%\%parserclass - << - NLA = PARSERCLASS; - parserClass=1; /* MR1 */ - zzmode(ACT); /* MR1 */ - >> - -\<\<\%\%lexprefix - << - NLA = LEXPREFIX; - lexPrefix=1;zzmode(ACT); - >> - -\<\< - << - NLA = ACTION; - if (func_action) - fprintf(OUT,"\n%s %sact%d()\n{ ", - gen_cpp?"ANTLRTokenType":"static void", - gen_cpp?ClassName("::"):"", ++action_no); - zzmode(ACT); zzskip(); - >> - -\>\> - << - NLA = GREAT_GREAT; - >> - -\{ - << - NLA = L_BRACE; - >> - -\} - << - NLA = R_BRACE; - >> - -\( - << - NLA = L_PAR; - >> - -\) - << - NLA = R_PAR; - >> - -\[ - << - NLA = L_BRACK; - >> - -\] - << - NLA = R_BRACK; - >> - -\* - << - NLA = ZERO_MORE; - >> - -\+ - << - NLA = ONE_MORE; - >> - -\| - << - NLA = OR; - >> - -\- - << - NLA = RANGE; - >> - -\~ - << - NLA = NOT; - >> - -\\0[0-7]* - << - NLA = OCTAL_VALUE; - {int t; sscanf(&zzlextext[1],"%o",&t); zzlextext[0] = t;} - >> - -\\0[Xx][0-9a-fA-F]+ - << - NLA = HEX_VALUE; - {int t; sscanf(&zzlextext[3],"%x",&t); zzlextext[0] = t;} - >> - -\\[1-9][0-9]* - << - NLA = DEC_VALUE; - {int t; sscanf(&zzlextext[1],"%d",&t); zzlextext[0] = t;} - >> - -\\t - << - NLA = TAB; - zzlextext[0] = '\t'; - >> - -\\n - << - NLA = NL; - zzlextext[0] = '\n'; - >> - -\\r - << - NLA = CR; - zzlextext[0] = '\r'; - >> - -\\b - << - NLA = BS; - zzlextext[0] = '\b'; - >> - -\\ \n - << - NLA = CONTINUATION; - zzline++; zzskip(); - >> - -\\~[tnrb] - << - NLA = LIT; - zzlextext[0] = zzlextext[1]; - >> - -~[\\] - << - NLA = REGCHAR; - >> - - -%%ACT - -@ - << - NLA = 1; - error("unterminated action", zzline); zzmode(START); - >> - -\>\> - << - NLA = ACTION; - if (func_action) fprintf(OUT,"}\n\n"); - zzmode(START); - /* MR1 */ - /* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */ - /* MR1 via <<%%lexmember ...>> */ - /* MR1 This is a consequence of not saving actions */ - /* MR1 */ - /* MR1 */ parserClass=0; - /* MR1 */ lexPrefix=0; - /* MR1 */ lexAction=0; - /* MR1 */ lexMember=0; - >> - -\> - << - NLA = 34; - xxputc(zzlextext[0]); zzskip(); - >> - -\\\> - << - NLA = 35; - xxputc('>'); zzskip(); - >> - -\\ - << - NLA = 36; - xxputc('\\'); zzskip(); - >> - -\n - << - NLA = 37; - xxputc(zzlextext[0]); ++zzline; zzskip(); - >> - -/\* - << - NLA = 38; - zzmode(ACTION_COMMENTS); /* MR1 */ - xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ - >> - -// - << - NLA = 39; - zzmode(ACTION_CPP_COMMENTS); /* MR1 */ - xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ - >> - -~[] - << - NLA = 40; - xxputc(zzlextext[0]); zzskip(); - >> - - -%%ACTION_COMMENTS - -@ - << - NLA = 1; - >> - -\*/ - << - NLA = 41; - zzmode(ACT); /* MR1 */ - xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ - >> - -[\n\r] - << - NLA = 42; - zzline++; xxputc(zzlextext[0]); zzskip(); - >> - -~[] - << - NLA = 43; - xxputc(zzlextext[0]); zzskip(); - >> - - -%%ACTION_CPP_COMMENTS - -@ - << - NLA = 1; - >> - -[\n\r] - << - NLA = 44; - zzmode(ACT); zzline++; /* MR1 */ - xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */ - >> - -~[] - << - NLA = 45; - xxputc(zzlextext[0]); zzskip(); - >> - -%% diff --git a/Tools/CodeTools/TianoTools/Pccts/dlg/relabel.c b/Tools/CodeTools/TianoTools/Pccts/dlg/relabel.c deleted file mode 100644 index 0b8bc163d1..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/dlg/relabel.c +++ /dev/null @@ -1,217 +0,0 @@ -/* This group of functions does the character class compression. - It goes over the dfa and relabels the arcs with the partitions - of characters in the NFA. The partitions are stored in the - array class. - - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * DLG 1.33 - * Will Cohen - * With mods by Terence Parr; AHPCRC, University of Minnesota - * 1989-2001 - */ - -#include -#include "dlg.h" -#ifdef MEMCHK -#include "trax.h" -#else -#ifdef __STDC__ -#include -#else -#include -#endif /* __STDC__ */ -#endif - -int class_no = CHAR_RANGE; /* number of classes for labels */ -int first_el[CHAR_RANGE]; /* first element in each class partition */ -set class_sets[CHAR_RANGE]; /* array holds partitions from class */ - /* compression */ - -/* goes through labels on NFA graph and partitions the characters into - * character classes. This reduces the amount of space required for each - * dfa node, since only one arc is required each class instead of one arc - * for each character - * level: - * 0 no compression done - * 1 remove unused characters from classes - * 2 compress equivalent characters into same class - * - * returns the number of character classes required - */ -#ifdef __USE_PROTOS -int relabel(nfa_node* start,int level) -#else -int relabel(start,level) -int level; -nfa_node *start; -#endif -{ - if (level){ - set_free(used_classes); - partition(start,level); - label_with_classes(start); - }else{ - /* classes equivalent to all characters in alphabet */ - class_no = CHAR_RANGE; - } - return class_no; -} - -/* makes character class sets for new labels */ -#ifdef __USE_PROTOS -void partition(nfa_node* start,int level) -#else -void partition(start,level) -nfa_node *start; /* beginning of nfa graph */ -int level; /* compression level to uses */ -#endif -{ - set current_class; - set unpart_chars; - set temp; - - unpart_chars = set_dup(used_chars); -#if 0 - /* EOF (-1+1) alway in class 0 */ - class_sets[0] = set_of(0); - first_el[0] = 0; - used_classes = set_of(0); - temp = set_dif(unpart_chars, class_sets[0]); - set_free(unpart_chars); - unpart_chars = temp; - class_no = 1; -#else - class_no = 0; -#endif - while (!set_nil(unpart_chars)){ - /* don't look for equivalent labels if c <= 1 */ - if (level <= 1){ - current_class = set_of(set_int(unpart_chars)); - }else{ - current_class = set_dup(unpart_chars); - intersect_nfa_labels(start,¤t_class); - } - set_orel(class_no,&used_classes); - first_el[class_no] = set_int(current_class); - class_sets[class_no] = current_class; - temp = set_dif(unpart_chars,current_class); - set_free(unpart_chars); - unpart_chars = temp; - ++class_no; - } - - /* free unpart_chars -ATG 5/6/95 */ - set_free(unpart_chars); - -#if 0 - /* group all the other unused characters into a class */ - set_orel(class_no,&used_classes); - first_el[class_no] = set_int(current_class); - class_sets[class_no] = set_dif(normal_chars,used_chars); - ++class_no; -#endif -} - - -/* given pointer to beginning of graph and recursively walks it trying - * to find a maximal partition. This partion in returned in maximal_class - */ -#ifdef __USE_PROTOS -void intersect_nfa_labels(nfa_node* start,set* maximal_class) -#else -void intersect_nfa_labels(start,maximal_class) -nfa_node *start; -set *maximal_class; -#endif -{ - /* pick a new operation number */ - ++operation_no; - r_intersect(start,maximal_class); -} - -#ifdef __USE_PROTOS -void r_intersect(nfa_node* start,set* maximal_class) -#else -void r_intersect(start,maximal_class) -nfa_node *start; -set * maximal_class; -#endif -{ - set temp; - - if(start && start->nfa_set != operation_no) - { - start->nfa_set = operation_no; - temp = set_and(*maximal_class,start->label); - if (!set_nil(temp)) - { - set_free(*maximal_class); - *maximal_class = temp; - }else{ - set_free(temp); - } - r_intersect(start->trans[0],maximal_class); - r_intersect(start->trans[1],maximal_class); - } -} - - -/* puts class labels in place of old character labels */ -#ifdef __USE_PROTOS -void label_with_classes(nfa_node* start) -#else -void label_with_classes(start) -nfa_node *start; -#endif -{ - ++operation_no; - label_node(start); -} - -#ifdef __USE_PROTOS -void label_node(nfa_node *start) -#else -void label_node(start) -nfa_node *start; -#endif -{ - set new_label; - register int i; - - /* only do node if it hasn't been done before */ - if (start && start->nfa_set != operation_no){ - start->nfa_set = operation_no; - new_label = empty; - for (i = 0; ilabel)) - set_orel(i,&new_label); - } - set_free(start->label); - start->label = new_label; - /* do any nodes that can be reached from this one */ - label_node(start->trans[0]); - label_node(start->trans[1]); - } -} diff --git a/Tools/CodeTools/TianoTools/Pccts/dlg/stdpccts.h b/Tools/CodeTools/TianoTools/Pccts/dlg/stdpccts.h deleted file mode 100644 index 06ec67e44d..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/dlg/stdpccts.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef STDPCCTS_H -#define STDPCCTS_H -/* - * stdpccts.h -- P C C T S I n c l u d e - * - * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001 - * Purdue University Electrical Engineering - * With AHPCRC, University of Minnesota - * ANTLR Version 1.33MR33 - */ - -#ifndef ANTLR_VERSION -#define ANTLR_VERSION 13333 -#endif - -#include "pcctscfg.h" -#include "pccts_stdio.h" - -#include -#include "dlg.h" -#define zzSET_SIZE 8 -#include "antlr.h" -#include "tokens.h" -#include "dlgdef.h" -#include "mode.h" -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/dlg/support.c b/Tools/CodeTools/TianoTools/Pccts/dlg/support.c deleted file mode 100644 index 84fe99d69c..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/dlg/support.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * DLG 1.33 - * Will Cohen - * With mods by Terence Parr; AHPCRC, University of Minnesota - * 1989-2001 - */ - -#include -#include -#include "dlg.h" -#ifdef MEMCHK -#include "trax.h" -#else -#ifdef __STDC__ -#include -#else -#include -#endif /* __STDC__ */ -#endif - -int err_found = 0; /* indicates whether problem found */ - -#ifdef __USE_PROTOS -void internal_error(char *s, char *file,int line) /* MR9 23-Sep-97 */ -#else -void internal_error(s,file,line) /* MR9 23-Sep-97 */ -char *s,*file; -int line; -#endif -{ - fprintf(stderr,s,file,line); - exit(PCCTS_EXIT_FAILURE); -} - -#ifdef __USE_PROTOS -char *dlg_malloc(int bytes,char *file,int line) -#else -char *dlg_malloc(bytes,file,line) -int bytes; -char *file; -int line; -#endif -{ - char *t; - - t = (char *) malloc(bytes); - if (!t){ - /* error */ - internal_error("%s(%d): unable to allocate memory\n", - file,line); - } - return t; -} - - -#ifdef __USE_PROTOS -char *dlg_calloc(int n,int bytes,char *file,int line) -#else -char *dlg_calloc(n,bytes,file,line) -int n,bytes; -char *file; -int line; -#endif -{ - char *t; - - t = (char *) calloc(n,bytes); - if (!t){ - /* error */ - internal_error("%s(%d): unable to allocate memory\n", - file,line); - } - return t; -} - - -#ifdef __USE_PROTOS -FILE *read_stream(char *name) -#else -FILE *read_stream(name) -char *name; -#endif -{ - FILE *f; - - if (name){ - if (name[0] == '-') { - fprintf(stderr, "dlg: invalid option: '%s'\n", name); - f = NULL; - }else{ - f = fopen(name, "r"); - if (f == NULL){ - /* couldn't open file */ - fprintf(stderr, - "dlg: Warning: Can't read file %s.\n", - name); - } - } - }else{ - /* open stdin if nothing there */ - f = stdin; - } - return f; -} - -#ifdef __USE_PROTOS -FILE *write_stream(char *name) -#else -FILE *write_stream(name) -char *name; -#endif -{ - FILE *f; - - if (name){ - if (name[0] == '-') { - fprintf(stderr, "dlg: invalid option: '%s'\n", name); - f = NULL; - }else{ - f = fopen(OutMetaName(name), "w"); - if (f == NULL){ - /* couldn't open file */ - fprintf(stderr, - "dlg: Warning: Can't write to file %s.\n", - name); - } - else -#ifdef SPECIAL_FOPEN - special_fopen_actions(OutMetaName(name)); /* MR1 */ -#else - ; /* MR1 */ -#endif - } - }else{ - /* open stdout if nothing there */ - f = stdout; - } - return f; -} - - -#ifdef __USE_PROTOS -void fatal(char *message,int line_no) -#else -void fatal(message,line_no) -char *message; -int line_no; -#endif -{ - fprintf(stderr,ErrHdr, - (file_str[0] ? file_str[0] : "stdin"), line_no); - fprintf(stderr, " Fatal: %s\n", message); - exit(PCCTS_EXIT_FAILURE); -} - -#ifdef __USE_PROTOS -void error(char *message,int line_no) -#else -void error(message,line_no) -char *message; -int line_no; -#endif -{ - fprintf(stderr,ErrHdr, - (file_str[0] ? file_str[0] : "stdin"), line_no); - fprintf(stderr, " Error: %s\n", message); - err_found = 1; -} - -#ifdef __USE_PROTOS -void warning(char *message,int line_no) -#else -void warning(message,line_no) -char *message; -int line_no; -#endif -{ - fprintf(stderr,ErrHdr, - (file_str[0] ? file_str[0] : "stdin"), line_no); - fprintf(stderr, " Warning: %s\n", message); -} - -/* MR10: Jeff Vincent - MR10: Changed to remove directory information from n only if - MR10: if OutputDirectory was changed by user (-o option) -*/ - -#ifdef __USE_PROTOS -char *OutMetaName(char *n) -#else -char *OutMetaName(n) -char *n; -#endif -{ - static char *dir_sym = DirectorySymbol; - static char newname[MaxFileName+1]; - char *p; - - /* If OutputDirectory is same as TopDirectory (platform default) then leave n alone. */ - if (strcmp(OutputDirectory, TopDirectory) == 0) - return n; - - /* p will point to filename without path information */ - if ((p = strrchr(n, *dir_sym)) != NULL) - p++; - else - p = n; - - /* Copy new output directory into newname[] */ - strcpy(newname, OutputDirectory); - - /* if new output directory does not have trailing dir_sym, add it! */ - if (newname[strlen(newname)-1] != *dir_sym) - strcat(newname, dir_sym); - - /* contatenate FILE NAME ONLY to new output directory */ - strcat(newname, p); - - return newname; -} diff --git a/Tools/CodeTools/TianoTools/Pccts/dlg/tokens.h b/Tools/CodeTools/TianoTools/Pccts/dlg/tokens.h deleted file mode 100644 index 73e502b7e1..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/dlg/tokens.h +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef tokens_h -#define tokens_h -/* tokens.h -- List of labelled tokens and stuff - * - * Generated from: dlg_p.g - * - * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001 - * Purdue University Electrical Engineering - * ANTLR Version 1.33MR33 - */ -#define zzEOF_TOKEN 1 -#define L_EOF 4 -#define PER_PER 5 -#define NAME_PER_PER 6 -#define LEXMEMBER 7 -#define LEXACTION 8 -#define PARSERCLASS 9 -#define LEXPREFIX 10 -#define ACTION 11 -#define GREAT_GREAT 12 -#define L_BRACE 13 -#define R_BRACE 14 -#define L_PAR 15 -#define R_PAR 16 -#define L_BRACK 17 -#define R_BRACK 18 -#define ZERO_MORE 19 -#define ONE_MORE 20 -#define OR 21 -#define RANGE 22 -#define NOT 23 -#define OCTAL_VALUE 24 -#define HEX_VALUE 25 -#define DEC_VALUE 26 -#define TAB 27 -#define NL 28 -#define CR 29 -#define BS 30 -#define CONTINUATION 31 -#define LIT 32 -#define REGCHAR 33 - -#ifdef __USE_PROTOS -void grammar(void); -#else -extern void grammar(); -#endif - -#ifdef __USE_PROTOS -void start_states(void); -#else -extern void start_states(); -#endif - -#ifdef __USE_PROTOS -void do_conversion(void); -#else -extern void do_conversion(); -#endif - -#ifdef __USE_PROTOS -void rule_list(void); -#else -extern void rule_list(); -#endif - -#ifdef __USE_PROTOS -void rule(void); -#else -extern void rule(); -#endif - -#ifdef __USE_PROTOS -void reg_expr(void); -#else -extern void reg_expr(); -#endif - -#ifdef __USE_PROTOS -void and_expr(void); -#else -extern void and_expr(); -#endif - -#ifdef __USE_PROTOS -void repeat_expr(void); -#else -extern void repeat_expr(); -#endif - -#ifdef __USE_PROTOS -void expr(void); -#else -extern void expr(); -#endif - -#ifdef __USE_PROTOS -void atom_list(void); -#else -extern void atom_list(); -#endif - -#ifdef __USE_PROTOS -void near_atom(void); -#else -extern void near_atom(); -#endif - -#ifdef __USE_PROTOS -void atom(void); -#else -extern void atom(); -#endif - -#ifdef __USE_PROTOS -void anychar(void); -#else -extern void anychar(); -#endif - -#endif -extern SetWordType zzerr1[]; -extern SetWordType zzerr2[]; -extern SetWordType zzerr3[]; -extern SetWordType setwd1[]; -extern SetWordType zzerr4[]; -extern SetWordType zzerr5[]; -extern SetWordType zzerr6[]; -extern SetWordType setwd2[]; -extern SetWordType zzerr7[]; -extern SetWordType zzerr8[]; -extern SetWordType zzerr9[]; -extern SetWordType setwd3[]; diff --git a/Tools/CodeTools/TianoTools/Pccts/h/AParser.cpp b/Tools/CodeTools/TianoTools/Pccts/h/AParser.cpp deleted file mode 100644 index 720fe75af1..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/AParser.cpp +++ /dev/null @@ -1,871 +0,0 @@ -/* ANTLRParser.C - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -#include "pcctscfg.h" - -#include "pccts_stdlib.h" -#include "pccts_stdarg.h" -#include "pccts_string.h" -#include "pccts_stdio.h" - -PCCTS_NAMESPACE_STD - -/* I have to put this here due to C++ limitation - * that you can't have a 'forward' decl for enums. - * I hate C++!!!!!!!!!!!!!!! - * Of course, if I could use real templates, this would go away. - */ -// MR1 -// MR1 10-Apr-97 133MR1 Prevent use of varying sizes for the -// MR1 ANTLRTokenType enum -// MR1 - -enum ANTLRTokenType { TER_HATES_CPP=0, ITS_TOO_COMPLICATED=9999}; // MR1 - -#define ANTLR_SUPPORT_CODE - -#include ATOKEN_H -#include ATOKENBUFFER_H -#include APARSER_H - -static const int zzINF_DEF_TOKEN_BUFFER_SIZE = 2000; /* MR14 */ -static const int zzINF_BUFFER_TOKEN_CHUNK_SIZE = 1000; /* MR14 */ - - /* L o o k a h e a d M a c r o s */ - -/* maximum of 32 bits/unsigned int and must be 8 bits/byte; - * we only use 8 bits of it. - */ -SetWordType ANTLRParser::bitmask[sizeof(SetWordType)*8] = { - 0x00000001, 0x00000002, 0x00000004, 0x00000008, - 0x00000010, 0x00000020, 0x00000040, 0x00000080 -}; - -char ANTLRParser::eMsgBuffer[500] = ""; - -ANTLRParser:: -~ANTLRParser() -{ - delete [] token_type; - delete [] zzFAILtext; // MR16 Manfred Kogler -} - -ANTLRParser:: -ANTLRParser(ANTLRTokenBuffer *_inputTokens, - int k, - int use_inf_look, - int dlook, - int ssize) -{ - LLk = k; - can_use_inf_look = use_inf_look; -/* MR14 */ if (dlook != 0) { -/* MR14 */ panic("ANTLRParser::ANTLRParser - Demand lookahead not supported in C++ mode"); -/* MR14 */ -/* MR14 */ }; - demand_look = 0; /* demand_look = dlook; */ - bsetsize = ssize; - guessing = 0; - token_tbl = NULL; - eofToken = (ANTLRTokenType)1; - - // allocate lookahead buffer - token_type = new ANTLRTokenType[LLk]; - lap = 0; - labase = 0; -#ifdef ZZDEFER_FETCH - stillToFetch = 0; // MR19 -#endif - dirty = 0; - inf_labase = 0; // MR7 - inf_last = 0; // MR7 - /* prime lookahead buffer, point to inputTokens */ - this->inputTokens = _inputTokens; - this->inputTokens->setMinTokens(k); - _inputTokens->setParser(this); // MR1 - resynchConsumed=1; // MR8 - zzFAILtext=NULL; // MR9 - traceOptionValueDefault=0; // MR10 - traceReset(); // MR10 - zzGuessSeq=0; // MR10 - syntaxErrCount=0; // MR11 -} - -void ANTLRParser::init() -{ - prime_lookahead(); - resynchConsumed=1; // MR8 - traceReset(); // MR10 -} - -void ANTLRParser::traceReset() -{ - traceOptionValue=traceOptionValueDefault; - traceGuessOptionValue=1; - traceCurrentRuleName=NULL; - traceDepth=0; -} - - -#ifdef _MSC_VER // MR23 -//Turn off warning: -//interaction between '_setjmp' and C++ object destruction is non-portable -#pragma warning(disable : 4611) -#endif -int ANTLRParser:: -guess(ANTLRParserState *st) -{ - saveState(st); - guessing = 1; - return setjmp(guess_start.state); -} -#ifdef _MSC_VER // MR23 -#pragma warning(default: 4611) -#endif - -void ANTLRParser:: -saveState(ANTLRParserState *buf) -{ - buf->guess_start = guess_start; - buf->guessing = guessing; - buf->inf_labase = inf_labase; - buf->inf_last = inf_last; - buf->dirty = dirty; - buf->traceOptionValue=traceOptionValue; /* MR10 */ - buf->traceGuessOptionValue=traceGuessOptionValue; /* MR10 */ - buf->traceCurrentRuleName=traceCurrentRuleName; /* MR10 */ - buf->traceDepth=traceDepth; /* MR10 */ -} - -void ANTLRParser:: -restoreState(ANTLRParserState *buf) -{ - int i; - int prevTraceOptionValue; - - guess_start = buf->guess_start; - guessing = buf->guessing; - inf_labase = buf->inf_labase; - inf_last = buf->inf_last; - dirty = buf->dirty; - - // restore lookahead buffer from k tokens before restored TokenBuffer position - // if demand_look, then I guess we don't look backwards for these tokens. - for (i=1; i<=LLk; i++) token_type[i-1] = - inputTokens->bufferedToken(i-LLk)->getType(); - lap = 0; - labase = 0; - - /* MR10 */ - - prevTraceOptionValue=traceOptionValue; - traceOptionValue=buf->traceOptionValue; - if ( (prevTraceOptionValue > 0) != - (traceOptionValue > 0)) { - if (traceCurrentRuleName != NULL) { /* MR21 */ - if (traceOptionValue > 0) { - /* MR23 */ printMessage(stderr, - "trace enable restored in rule %s depth %d\n", - traceCurrentRuleName, - traceDepth); - }; - if (traceOptionValue <= 0) { - /* MR23 */ printMessage(stderr, - "trace disable restored in rule %s depth %d\n", - traceCurrentRuleName, /* MR21 */ - traceDepth); - }; - } - }; - traceGuessOptionValue=buf->traceGuessOptionValue; - traceCurrentRuleName=buf->traceCurrentRuleName; - traceDepth=buf->traceDepth; - traceGuessDone(buf); -} - -/* Get the next symbol from the input stream; put it into lookahead buffer; - * fill token_type[] fast reference cache also. NLA is the next place where - * a lookahead ANTLRAbstractToken should go. - */ -void ANTLRParser:: -consume() -{ - -#ifdef ZZDEBUG_CONSUME_ACTION - zzdebug_consume_action(); -#endif - -// MR19 V.H. Simonis -// Defer Fetch feature -// Moves action of consume() into LA() function - -#ifdef ZZDEFER_FETCH - stillToFetch++; -#else - NLA = inputTokens->getToken()->getType(); - dirty--; - lap = (lap+1)&(LLk-1); -#endif - -} - -_ANTLRTokenPtr ANTLRParser:: -LT(int i) -{ - -// MR19 V.H. Simonis -// Defer Fetch feature -// Moves action of consume() into LA() function - -#ifdef ZZDEFER_FETCH - undeferFetch(); -#endif - -#ifdef DEBUG_TOKENBUFFER - if ( i >= inputTokens->bufferSize() || inputTokens->minTokens() < LLk ) /* MR20 Was "<=" */ - { - char buf[2000]; /* MR20 Was "static" */ - sprintf(buf, "The minimum number of tokens you requested that the\nANTLRTokenBuffer buffer is not enough to satisfy your\nLT(%d) request; increase 'k' argument to constructor for ANTLRTokenBuffer\n", i); - panic(buf); - } -#endif - return inputTokens->bufferedToken(i-LLk); -} - -void -ANTLRParser:: -look(int k) -{ - int i, c = k - (LLk-dirty); - for (i=1; i<=c; i++) consume(); -} - -/* fill the lookahead buffer up with k symbols (even if DEMAND_LOOK); - */ -void -ANTLRParser:: -prime_lookahead() -{ - int i; - for(i=1;i<=LLk; i++) consume(); - dirty=0; - // lap = 0; // MR14 Sinan Karasu (sinan.karasu@boeing.com) - // labase = 0; // MR14 - labase=lap; // MR14 -} - -/* check to see if the current input symbol matches '_t'. - * During NON demand lookahead mode, dirty will always be 0 and - * hence the extra code for consuming tokens in _match is never - * executed; the same routine can be used for both modes. - */ -int ANTLRParser:: -_match(ANTLRTokenType _t, ANTLRChar **MissText, - ANTLRTokenType *MissTok, _ANTLRTokenPtr *BadTok, - SetWordType **MissSet) -{ - if ( dirty==LLk ) { - consume(); - } - if ( LA(1)!=_t ) { - *MissText=NULL; - *MissTok= _t; - *BadTok = LT(1); - *MissSet=NULL; - return 0; - } - dirty++; - labase = (labase+1)&(LLk-1); // labase maintained even if !demand look - return 1; -} - -/* check to see if the current input symbol matches '_t'. - * Used during exception handling. - */ -int ANTLRParser:: -_match_wsig(ANTLRTokenType _t) -{ - if ( dirty==LLk ) { - consume(); - } - if ( LA(1)!=_t ) return 0; - dirty++; - labase = (labase+1)&(LLk-1); // labase maintained even if !demand look - return 1; -} - -/* check to see if the current input symbol matches any token in a set. - * During NON demand lookahead mode, dirty will always be 0 and - * hence the extra code for consuming tokens in _match is never - * executed; the same routine can be used for both modes. - */ -int ANTLRParser:: -_setmatch(SetWordType *tset, ANTLRChar **MissText, - ANTLRTokenType *MissTok, _ANTLRTokenPtr *BadTok, - SetWordType **MissSet, SetWordType *tokclassErrset) -{ - if ( dirty==LLk ) { - consume(); - } - if ( !set_el(LA(1), tset) ) { - *MissText=NULL; /* MR23 */ - *MissTok=(ANTLRTokenType) 0; /* MR23 */ - *BadTok=LT(1); /* MR23 */ - *MissSet=tokclassErrset; /* MR23 */ - return 0; - } - dirty++; - labase = (labase+1)&(LLk-1); // labase maintained even if !demand look - return 1; -} - -int ANTLRParser:: -_setmatch_wsig(SetWordType *tset) -{ - if ( dirty==LLk ) { - consume(); - } - if ( !set_el(LA(1), tset) ) return 0; - dirty++; - labase = (labase+1)&(LLk-1); // labase maintained even if !demand look - return 1; -} - - /* Exception handling routines */ -// -// 7-Apr-97 133MR1 -// Change suggested by Eli Sternheim (eli@interhdl.com) -// -void ANTLRParser:: -consumeUntil(SetWordType *st) -{ - ANTLRTokenType tmp; // MR1 - const int Eof=1; // MR1 - while ( !set_el( (tmp=LA(1)), st) && tmp!=Eof) { consume(); } // MR1 -} - -// -// 7-Apr-97 133MR1 -// Change suggested by Eli Sternheim (eli@interhdl.com) -// -void ANTLRParser:: -consumeUntilToken(int t) -{ - int tmp; // MR1 - const int Eof=1; // MR1 - while ( (tmp=LA(1)) !=t && tmp!=Eof) { consume(); } // MR1 -} - - - /* Old error stuff */ - -void ANTLRParser:: -resynch(SetWordType *wd,SetWordType mask) -{ - -/* MR8 S.Bochnak@microtool.com.pl */ -/* MR8 Change file scope static "consumed" to instance var */ - - /* if you enter here without having consumed a token from last resynch - * force a token consumption. - */ -/* MR8 */ if ( !resynchConsumed ) {consume(); resynchConsumed=1; return;} - - /* if current token is in resynch set, we've got what we wanted */ - -/* MR8 */ if ( wd[LA(1)]&mask || LA(1) == eofToken ) {resynchConsumed=0; return;} - - /* scan until we find something in the resynch set */ - - while ( !(wd[LA(1)]&mask) && LA(1) != eofToken ) {consume();} - -/* MR8 */ resynchConsumed=1; -} - -/* standard error reporting function that assumes DLG-based scanners; - * you should redefine in subclass to change it or if you use your - * own scanner. - */ - -/* MR23 THM There appears to be a parameter "badText" passed to syn() - which is not present in the parameter list. This may be - because in C mode there is no attribute function which - returns the text, so the text representation of the token - must be passed explicitly. I think. -*/ - -void ANTLRParser:: -syn(_ANTLRTokenPtr /*tok MR23*/, ANTLRChar *egroup, SetWordType *eset, - ANTLRTokenType etok, int k) -{ - int line; - - line = LT(1)->getLine(); - - syntaxErrCount++; /* MR11 */ - - /* MR23 If the token is not an EOF token, then use the ->getText() value. - - If the token is the EOF token the text returned by ->getText() - may be garbage. If the text from the token table is "@" use - "" instead, because end-users don't know what "@" means. - If the text is not "@" then use that text, which must have been - supplied by the grammar writer. - */ - const char * errorAt = LT(1)->getText(); - if (LA(1) == eofToken) { - errorAt = parserTokenName(LA(1)); - if (errorAt[0] == '@') errorAt = ""; - } - /* MR23 */ printMessage(stderr, "line %d: syntax error at \"%s\"", - line, errorAt); - if ( !etok && !eset ) {/* MR23 */ printMessage(stderr, "\n"); return;} - if ( k==1 ) /* MR23 */ printMessage(stderr, " missing"); - else - { - /* MR23 */ printMessage(stderr, "; \"%s\" not", LT(k)->getText()); // MR23 use LT(k) since k>1 - if ( set_deg(eset)>1 ) /* MR23 */ printMessage(stderr, " in"); - } - if ( set_deg(eset)>0 ) edecode(eset); - else /* MR23 */ printMessage(stderr, " %s", token_tbl[etok]); - if ( strlen(egroup) > 0 ) /* MR23 */ printMessage(stderr, " in %s", egroup); - /* MR23 */ printMessage(stderr, "\n"); -} - -/* is b an element of set p? */ -int ANTLRParser:: -set_el(ANTLRTokenType b, SetWordType *p) -{ - return( p[DIVWORD(b)] & bitmask[MODWORD(b)] ); -} - -int ANTLRParser:: -set_deg(SetWordType *a) -{ - /* Fast compute degree of a set... the number - of elements present in the set. Assumes - that all word bits are used in the set - */ - register SetWordType *p = a; - register SetWordType *endp = &(a[bsetsize]); - register int degree = 0; - - if ( a == NULL ) return 0; - while ( p < endp ) - { - register SetWordType t = *p; - register SetWordType *b = &(bitmask[0]); - do { - if (t & *b) ++degree; - } while (++b < &(bitmask[sizeof(SetWordType)*8])); - p++; - } - - return(degree); -} - -void ANTLRParser:: -edecode(SetWordType *a) -{ - register SetWordType *p = a; - register SetWordType *endp = &(p[bsetsize]); - register unsigned e = 0; - - if ( set_deg(a)>1 ) /* MR23 */ printMessage(stderr, " {"); - do { - register SetWordType t = *p; - register SetWordType *b = &(bitmask[0]); - do { - if ( t & *b ) /* MR23 */ printMessage(stderr, " %s", token_tbl[e]); - e++; - } while (++b < &(bitmask[sizeof(SetWordType)*8])); - } while (++p < endp); - if ( set_deg(a)>1 ) /* MR23 */ printMessage(stderr, " }"); -} - -/* input looks like: - * zzFAIL(k, e1, e2, ...,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText,&zzErrk) - * where the zzMiss stuff is set here to the token that did not match - * (and which set wasn't it a member of). - */ - -// MR9 29-Sep-97 Stan Bochnak (S.Bochnak@microTool.com.pl) -// MR9 Original fix to static allocated text didn't -// MR9 work because a pointer to it was passed back -// MR9 to caller. Replace with instance variable. - -const int SETWORDCOUNT=20; - -void -ANTLRParser::FAIL(int k, ...) -{ -// -// MR1 10-Apr-97 -// - - if (zzFAILtext == NULL) zzFAILtext=new char [1000]; // MR9 - SetWordType **f=new SetWordType *[SETWORDCOUNT]; // MR1 // MR9 - SetWordType **miss_set; - ANTLRChar **miss_text; - _ANTLRTokenPtr *bad_tok; - ANTLRChar **bad_text; -// -// 7-Apr-97 133MR1 -// err_k is passed as a "int *", not "unsigned *" -// - int *err_k; // MR1 - int i; - va_list ap; - - va_start(ap, k); - - zzFAILtext[0] = '\0'; - if ( k > SETWORDCOUNT ) panic("FAIL: overflowed buffer"); - for (i=1; i<=k; i++) /* collect all lookahead sets */ - { - f[i-1] = va_arg(ap, SetWordType *); - } - for (i=1; i<=k; i++) /* look for offending token */ - { - if ( i>1 ) strcat(zzFAILtext, " "); - strcat(zzFAILtext, LT(i)->getText()); - if ( !set_el(LA(i), f[i-1]) ) break; - } - miss_set = va_arg(ap, SetWordType **); - miss_text = va_arg(ap, ANTLRChar **); - bad_tok = va_arg(ap, _ANTLRTokenPtr *); - bad_text = va_arg(ap, ANTLRChar **); - err_k = va_arg(ap, int *); // MR1 - if ( i>k ) - { - /* bad; lookahead is permutation that cannot be matched, - * but, the ith token of lookahead is valid at the ith position - * (The old LL sub 1 (k) versus LL(k) parsing technique) - */ - *miss_set = NULL; - *miss_text = LT(1)->getText(); - *bad_tok = LT(1); - *bad_text = (*bad_tok)->getText(); - *err_k = k; -// -// MR4 20-May-97 erroneously deleted contents of f[] -// MR4 reported by Bruce Guenter (bruceg@qcc.sk.ca) -// MR1 10-Apr-97 release temporary storage -// - delete [] f; // MR1 - return; // MR1 - } -/* MR23 printMessage(stderr, "%s not in %dth set\n", zztokens[LA(i)], i);*/ - *miss_set = f[i-1]; - *miss_text = zzFAILtext; - *bad_tok = LT(i); - *bad_text = (*bad_tok)->getText(); - if ( i==1 ) *err_k = 1; - else *err_k = k; -// -// MR4 20-May-97 erroneously deleted contents of f[] -// MR4 reported by Bruce Guenter (bruceg@qcc.sk.ca) -// MR1 10-Apr-97 release temporary storage -// - delete [] f; // MR1 - return; // MR1 -} - -int ANTLRParser:: -_match_wdfltsig(ANTLRTokenType tokenWanted, SetWordType *whatFollows) -{ - if ( dirty==LLk ) consume(); - - if ( LA(1)!=tokenWanted ) - { - syntaxErrCount++; /* MR11 */ - /* MR23 */ printMessage(stderr, - "line %d: syntax error at \"%s\" missing %s\n", - LT(1)->getLine(), - (LA(1)==eofToken && LT(1)->getText()[0] == '@')?"":LT(1)->getText(), /* MR21a */ - token_tbl[tokenWanted]); - consumeUntil( whatFollows ); - return 0; - } - else { - dirty++; - labase = (labase+1)&(LLk-1); // labase maintained even if !demand look -/* if ( !demand_look ) consume(); */ - return 1; - } -} - - -int ANTLRParser:: -_setmatch_wdfltsig(SetWordType *tokensWanted, - ANTLRTokenType tokenTypeOfSet, - SetWordType *whatFollows) -{ - if ( dirty==LLk ) consume(); - if ( !set_el(LA(1), tokensWanted) ) - { - syntaxErrCount++; /* MR11 */ - /* MR23 */ printMessage(stderr, - "line %d: syntax error at \"%s\" missing %s\n", - LT(1)->getLine(), - (LA(1)==eofToken && LT(1)->getText()[0] == '@')?"":LT(1)->getText(), /* MR21a */ - token_tbl[tokenTypeOfSet]); - consumeUntil( whatFollows ); - return 0; - } - else { - dirty++; - labase = (labase+1)&(LLk-1); // labase maintained even if !demand look -/* if ( !demand_look ) consume(); */ - return 1; - } -} - -char *ANTLRParser:: -eMsgd(char *err,int d) -{ - sprintf(eMsgBuffer, err, d); // dangerous, but I don't care - return eMsgBuffer; -} - -char *ANTLRParser:: -eMsg(char *err, char *s) -{ - sprintf(eMsgBuffer, err, s); - return eMsgBuffer; -} - -char *ANTLRParser:: -eMsg2(char *err,char *s, char *t) -{ - sprintf(eMsgBuffer, err, s, t); - return eMsgBuffer; -} - -void ANTLRParser:: -panic(const char *msg) // MR20 const -{ - /* MR23 */ printMessage(stderr, "ANTLR panic: %s\n", msg); - exit(PCCTS_EXIT_FAILURE); // MR1 -} - -const ANTLRChar *ANTLRParser:: // MR1 -parserTokenName(int tok) { // MR1 - return token_tbl[tok]; // MR1 -} // MR1 - -void ANTLRParser::traceGuessDone(const ANTLRParserState *state) { - - int doIt=0; - - if (traceCurrentRuleName == NULL) return; - - if (traceOptionValue <= 0) { - doIt=0; - } else if (traceGuessOptionValue <= 0) { - doIt=0; - } else { - doIt=1; - }; - - if (doIt) { - /* MR23 */ printMessage(stderr,"guess done - returning to rule %s {\"%s\"} at depth %d", - state->traceCurrentRuleName, - LT(1)->getType() == eofToken ? "@" : LT(1)->getText(), - state->traceDepth); - if (state->guessing != 0) { - /* MR23 */ printMessage(stderr," (guess mode continues - an enclosing guess is still active)"); - } else { - /* MR23 */ printMessage(stderr," (guess mode ends)"); - }; - /* MR23 */ printMessage(stderr,"\n"); - }; -} - -void ANTLRParser::traceGuessFail() { - - int doIt=0; - - if (traceCurrentRuleName == NULL) return; /* MR21 */ - - if (traceOptionValue <= 0) { - doIt=0; - } else if (guessing && traceGuessOptionValue <= 0) { - doIt=0; - } else { - doIt=1; - }; - - if (doIt) { - /* MR23 */ printMessage(stderr,"guess failed in %s\n",traceCurrentRuleName); - }; -} - -/* traceOption: - zero value turns off trace -*/ - -void ANTLRParser::tracein(const ANTLRChar * rule) { - - int doIt=0; - - traceDepth++; - traceCurrentRuleName=rule; - - if (traceOptionValue <= 0) { - doIt=0; - } else if (guessing && traceGuessOptionValue <= 0) { - doIt=0; - } else { - doIt=1; - }; - - if (doIt) { - /* MR23 */ printMessage(stderr,"enter rule %s {\"%s\"} depth %d", - rule, - LT(1)->getType() == eofToken ? "@" : LT(1)->getText(), - traceDepth); - if (guessing) /* MR23 */ printMessage(stderr," guessing"); - /* MR23 */ printMessage(stderr,"\n"); - }; - return; -} - -void ANTLRParser::traceout(const ANTLRChar * rule) { - - int doIt=0; - - traceDepth--; - - if (traceOptionValue <= 0) { - doIt=0; - } else if (guessing && traceGuessOptionValue <= 0) { - doIt=0; - } else { - doIt=1; - }; - - if (doIt) { - /* MR23 */ printMessage(stderr,"exit rule %s {\"%s\"} depth %d", - rule, - LT(1)->getType() == eofToken ? "@" : LT(1)->getText(), - traceDepth+1); - if (guessing) /* MR23 */ printMessage(stderr," guessing"); - /* MR23 */ printMessage(stderr,"\n"); - }; -} - -int ANTLRParser::traceOption(int delta) { - - int prevValue=traceOptionValue; - - traceOptionValue=traceOptionValue+delta; - - if (traceCurrentRuleName != NULL) { - if (prevValue <= 0 && traceOptionValue > 0) { - /* MR23 */ printMessage(stderr,"trace enabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth); - }; - if (prevValue > 0 && traceOptionValue <= 0) { - /* MR23 */ printMessage(stderr,"trace disabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth); - }; - }; - - return prevValue; -} - -int ANTLRParser::traceGuessOption(int delta) { - - int prevValue=traceGuessOptionValue; - - traceGuessOptionValue=traceGuessOptionValue+delta; - - if (traceCurrentRuleName != NULL) { - if (prevValue <= 0 && traceGuessOptionValue > 0) { - /* MR23 */ printMessage(stderr,"guess trace enabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth); - }; - if (prevValue > 0 && traceGuessOptionValue <= 0) { - /* MR23 */ printMessage(stderr,"guess trace disabled in rule %s depth %d\n",traceCurrentRuleName,traceDepth); - }; - }; - return prevValue; -} - -// MR19 V.H. Simonis Defer Fetch feature - -void ANTLRParser::undeferFetch() -{ - -#ifdef ZZDEFER_FETCH - if (stillToFetch) { - for (int stillToFetch_x = 0; stillToFetch_x < stillToFetch; ++stillToFetch_x) { - NLA = inputTokens->getToken()->getType(); - dirty--; - lap = (lap+1)&(LLk-1); - } - stillToFetch = 0; - } -#else - return; -#endif - -} - -int ANTLRParser::isDeferFetchEnabled() -{ -#ifdef ZZDEFER_FETCH - return 1; -#else - return 0; -#endif -} - -//MR23 -int ANTLRParser::printMessage(FILE* pFile, const char* pFormat, ...) -{ - va_list marker; - va_start( marker, pFormat ); - int iRet = printMessageV(pFile, pFormat, marker); - va_end( marker ); - return iRet; -} - -int ANTLRParser::printMessageV(FILE* pFile, const char* pFormat, va_list arglist) // MR23 -{ - return vfprintf(pFile, pFormat, arglist); -} - -// MR23 Move semantic predicate error handling from macro to virtual function -// -// Called by the zzfailed_pred - -void ANTLRParser::failedSemanticPredicate(const char* predicate) -{ - printMessage(stdout,"line %d: semantic error; failed predicate: '%s'\n", - LT(1)->getLine(), predicate); -} diff --git a/Tools/CodeTools/TianoTools/Pccts/h/AParser.h b/Tools/CodeTools/TianoTools/Pccts/h/AParser.h deleted file mode 100644 index fe405f4167..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/AParser.h +++ /dev/null @@ -1,376 +0,0 @@ -/* ANTLRParser.h - * - * Define the generic ANTLRParser superclass, which is subclassed to - * define an actual parser. - * - * Before entry into this file: ANTLRTokenType must be set. - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -#ifndef APARSER_H_GATE -#define APARSER_H_GATE - -#include "pcctscfg.h" - -#include "pccts_stdio.h" -#include "pccts_setjmp.h" - -PCCTS_NAMESPACE_STD - -#include ATOKEN_H -#include ATOKENBUFFER_H - -#ifdef ZZCAN_GUESS -#ifndef ZZINF_LOOK -#define ZZINF_LOOK -#endif -#endif - - -#define NLA (token_type[lap&(LLk-1)])/* --> next LA */ - -typedef unsigned char SetWordType; - -/* Define external bit set stuff (for SetWordType) */ -#define EXT_WORDSIZE (sizeof(char)*8) -#define EXT_LOGWORDSIZE 3 - - /* s y n t a c t i c p r e d i c a t e s t u f f */ - -#ifndef zzUSER_GUESS_HOOK -#define zzUSER_GUESS_HOOK(seqFrozen,zzrv) -#endif - -#ifndef zzUSER_GUESS_DONE_HOOK -#define zzUSER_GUESS_DONE_HOOK(seqFrozen) -#endif - -/* MR14 Add zzUSER_GUESS_FAIL_HOOK and related code */ - -#define zzUSER_GUESS_FAIL_HOOK_INTERNAL zzUSER_GUESS_FAIL_HOOK(SeqFrozen) -#ifndef zzUSER_GUESS_FAIL_HOOK -#define zzUSER_GUESS_FAIL_HOOK(zzGuessSeq) -#endif - - -typedef struct _zzjmp_buf { - jmp_buf state; - } zzjmp_buf; - -/* these need to be macros not member functions */ -#define zzGUESS_BLOCK ANTLRParserState zzst; int zzrv; int _marker; int zzGuessSeqFrozen; -#define zzNON_GUESS_MODE if ( !guessing ) -#define zzGUESS_FAIL guess_fail(); - -/* Note: zzGUESS_DONE does not execute longjmp() */ - -#define zzGUESS_DONE {zzrv=1; inputTokens->rewind(_marker); guess_done(&zzst);zzUSER_GUESS_DONE_HOOK(zzGuessSeqFrozen) } -#define zzGUESS saveState(&zzst); \ - guessing = 1; \ - zzGuessSeqFrozen = ++zzGuessSeq; \ - _marker = inputTokens->mark(); \ - zzrv = setjmp(guess_start.state); \ - zzUSER_GUESS_HOOK(zzGuessSeqFrozen,zzrv) \ - if ( zzrv ) zzGUESS_DONE - -#define zzTRACEdata const ANTLRChar *zzTracePrevRuleName = NULL; - -#ifndef zzTRACEIN -#define zzTRACEIN(r) zzTracePrevRuleName=traceCurrentRuleName;tracein(r); -#endif -#ifndef zzTRACEOUT -#define zzTRACEOUT(r) traceout(r);traceCurrentRuleName=zzTracePrevRuleName; -#endif - - /* a n t l r p a r s e r d e f */ - -struct ANTLRParserState { - /* class variables */ - zzjmp_buf guess_start; - int guessing; - - int inf_labase; - int inf_last; - - int dirty; - - int traceOptionValue; // MR10 - int traceGuessOptionValue; // MR10 - const ANTLRChar *traceCurrentRuleName; // MR10 - int traceDepth; // MR10 - -}; - -/* notes: - * - * multiple inheritance is a cool way to include what stuff is needed - * in this structure (like guess stuff). however, i'm not convinced that - * multiple inheritance works correctly on all platforms. not that - * much space is used--just include all possibly useful members. - * - * the class should also be a template with arguments for the lookahead - * depth and so on. that way, more than one parser can be defined (as - * each will probably have different lookahead requirements). however, - * am i sure that templates work? no, i'm not sure. - * - * no attributes are maintained and, hence, the 'asp' variable is not - * needed. $i can still be referenced, but it refers to the token - * associated with that rule element. question: where are the token's - * stored if not on the software stack? in local variables created - * and assigned to by antlr. - */ -class ANTLRParser { -protected: - /* class variables */ - static SetWordType bitmask[sizeof(SetWordType)*8]; - static char eMsgBuffer[500]; - -protected: - int LLk; // number of lookahead symbols (old LL_K) - int demand_look; - ANTLRTokenType eofToken; // when do I stop during resynch()s - int bsetsize; // size of bitsets created by ANTLR in - // units of SetWordType - - ANTLRTokenBuffer *inputTokens; //place to get input tokens - - zzjmp_buf guess_start; // where to jump back to upon failure - int guessing; // if guessing (using (...)? predicate) - - // infinite lookahead stuff - int can_use_inf_look; // set by subclass (generated by ANTLR) - int inf_lap; - int inf_labase; - int inf_last; - int *_inf_line; - - const ANTLRChar **token_tbl; // pointer to table of token type strings MR20 const - - int dirty; // used during demand lookahead - - ANTLRTokenType *token_type; // fast reference cache of token.getType() -// ANTLRLightweightToken **token; // the token with all its attributes - int lap; - int labase; -#ifdef ZZDEFER_FETCH - int stillToFetch; // MR19 V.H. Simonis -#endif - -private: - void fill_inf_look(); - -protected: - virtual void guess_fail() { // MR9 27-Sep-97 make virtual - traceGuessFail(); // MR10 - longjmp(guess_start.state, 1); } // MR9 - virtual void guess_done(ANTLRParserState *st) { // MR9 27-Sep-97 make virtual - restoreState(st); } // MR9 - virtual int guess(ANTLRParserState *); // MR9 27-Sep-97 make virtual - void look(int); - int _match(ANTLRTokenType, ANTLRChar **, ANTLRTokenType *, - _ANTLRTokenPtr *, SetWordType **); - int _setmatch(SetWordType *, ANTLRChar **, ANTLRTokenType *, - _ANTLRTokenPtr *, SetWordType **, - SetWordType * tokclassErrset /* MR23 */); - int _match_wsig(ANTLRTokenType); - int _setmatch_wsig(SetWordType *); - virtual void consume(); - virtual void resynch(SetWordType *wd,SetWordType mask); // MR21 - void prime_lookahead(); - virtual void tracein(const ANTLRChar *r); // MR10 - virtual void traceout(const ANTLRChar *r); // MR10 - static unsigned MODWORD(unsigned x) {return x & (EXT_WORDSIZE-1);} // x % EXT_WORDSIZE // MR9 - static unsigned DIVWORD(unsigned x) {return x >> EXT_LOGWORDSIZE;} // x / EXT_WORDSIZE // MR9 - int set_deg(SetWordType *); - int set_el(ANTLRTokenType, SetWordType *); - virtual void edecode(SetWordType *); // MR1 - virtual void FAIL(int k, ...); // MR1 - int traceOptionValue; // MR10 - int traceGuessOptionValue; // MR10 - const ANTLRChar *traceCurrentRuleName; // MR10 - int traceDepth; // MR10 - void traceReset(); // MR10 - virtual void traceGuessFail(); // MR10 - virtual void traceGuessDone(const ANTLRParserState *); // MR10 - int zzGuessSeq; // MR10 - -public: - ANTLRParser(ANTLRTokenBuffer *, - int k=1, - int use_inf_look=0, - int demand_look=0, - int bsetsize=1); - virtual ~ANTLRParser(); - - virtual void init(); - - ANTLRTokenType LA(int i) - { -// -// MR14 demand look will always be 0 for C++ mode -// -//// return demand_look ? token_type[(labase+(i)-1)&(LLk-1)] : -//// token_type[(lap+(i)-1)&(LLk-1)]; - -// MR19 V.H. Simonis Defer fetch feature - -#ifdef ZZDEFER_FETCH - undeferFetch(); -#endif - return token_type[(lap+(i)-1)&(LLk-1)]; - } - _ANTLRTokenPtr LT(int i); - - void setEofToken(ANTLRTokenType t) { eofToken = t; } - ANTLRTokenType getEofToken() const { return eofToken; } // MR14 - - void noGarbageCollectTokens() { inputTokens->noGarbageCollectTokens(); } - void garbageCollectTokens() { inputTokens->garbageCollectTokens(); } - - virtual void syn(_ANTLRTokenPtr tok, ANTLRChar *egroup, - SetWordType *eset, ANTLRTokenType etok, int k); - virtual void saveState(ANTLRParserState *); // MR9 27-Sep-97 make virtual - virtual void restoreState(ANTLRParserState *); // MR9 27-Sep-97 make virtual - - virtual void panic(const char *msg); // MR20 const - - static char *eMsgd(char *,int); - static char *eMsg(char *,char *); - static char *eMsg2(char *,char *,char *); - - virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23 - virtual int printMessageV(FILE* pFile, const char* pFormat, va_list arglist); // MR23 - - void consumeUntil(SetWordType *st); - void consumeUntilToken(int t); - - virtual int _setmatch_wdfltsig(SetWordType *tokensWanted, - ANTLRTokenType tokenTypeOfSet, - SetWordType *whatFollows); - virtual int _match_wdfltsig(ANTLRTokenType tokenWanted, - SetWordType *whatFollows); - - const ANTLRChar * parserTokenName(int tok); // MR1 - - int traceOptionValueDefault; // MR11 - int traceOption(int delta); // MR11 - int traceGuessOption(int delta); // MR11 - -// MR8 5-Aug-97 S.Bochnak@microtool.com.pl -// MR8 Move resynch static local variable -// MR8 to class instance - - int syntaxErrCount; // MR12 - ANTLRTokenStream *getLexer() const { // MR12 - return inputTokens ? inputTokens->getLexer() : 0; } // MR12 -protected: // MR8 - int resynchConsumed; // MR8 - char *zzFAILtext; // workarea required by zzFAIL // MR9 - void undeferFetch(); // MR19 V.H. Simonis - int isDeferFetchEnabled(); // MR19 V.H. Simonis - virtual void failedSemanticPredicate(const char* predicate); /* MR23 */ -}; - -#define zzmatch(_t) \ - if ( !_match((ANTLRTokenType)_t, &zzMissText, &zzMissTok, \ - (_ANTLRTokenPtr *) &zzBadTok, &zzMissSet) ) goto fail; - -#define zzmatch_wsig(_t,handler) \ - if ( !_match_wsig((ANTLRTokenType)_t) ) if ( guessing ) zzGUESS_FAIL else {_signal=MismatchedToken; goto handler;} - -#define zzsetmatch(_ts,_tokclassErrset) \ - if ( !_setmatch(_ts, &zzMissText, &zzMissTok, \ - (_ANTLRTokenPtr *) &zzBadTok, &zzMissSet, _tokclassErrset) ) goto fail; - -#define zzsetmatch_wsig(_ts, handler) \ - if ( !_setmatch_wsig(_ts) ) if ( guessing ) zzGUESS_FAIL else {_signal=MismatchedToken; goto handler;} - -/* For the dflt signal matchers, a FALSE indicates that an error occurred - * just like the other matchers, but in this case, the routine has already - * recovered--we do NOT want to consume another token. However, when - * the match was successful, we do want to consume hence _signal=0 so that - * a token is consumed by the "if (!_signal) consume(); _signal=NoSignal;" - * preamble. - */ -#define zzsetmatch_wdfltsig(tokensWanted, tokenTypeOfSet, whatFollows) \ - if ( !_setmatch_wdfltsig(tokensWanted, tokenTypeOfSet, whatFollows) ) \ - _signal = MismatchedToken; - -#define zzmatch_wdfltsig(tokenWanted, whatFollows) \ - if ( !_match_wdfltsig(tokenWanted, whatFollows) ) _signal = MismatchedToken; - - -// MR1 10-Apr-97 zzfailed_pred() macro does not backtrack in guess mode. -// MR1 Identification and correction due to J. Lilley -// -// MR23 Call virtual method to report error. -// MR23 Provide more control over failed predicate action -// without any need for user to worry about guessing internals. - -#ifndef zzfailed_pred -#define zzfailed_pred(_p,_hasuseraction,_useraction) \ - if (guessing) { \ - zzGUESS_FAIL; \ - } else { \ - zzfailed_pred_action(_p,_hasuseraction,_useraction) \ - } -#endif - -// MR23 Provide more control over failed predicate action -// without any need for user to worry about guessing internals. -// _hasuseraction == 0 => no user specified error action -// _hasuseraction == 1 => user specified error action - -#ifndef zzfailed_pred_action -#define zzfailed_pred_action(_p,_hasuseraction,_useraction) \ - if (_hasuseraction) { _useraction } else { failedSemanticPredicate(_p); } -#endif - -#define zzRULE \ - SetWordType *zzMissSet=NULL; ANTLRTokenType zzMissTok=(ANTLRTokenType)0; \ - _ANTLRTokenPtr zzBadTok=NULL; ANTLRChar *zzBadText=(ANTLRChar *)""; \ - int zzErrk=1,zzpf=0; \ - zzTRACEdata \ - ANTLRChar *zzMissText=(ANTLRChar *)""; - -#endif - - /* S t a n d a r d E x c e p t i o n S i g n a l s */ - -#define NoSignal 0 -#define MismatchedToken 1 -#define NoViableAlt 2 -#define NoSemViableAlt 3 - -/* MR7 Allow more control over signalling */ -/* by adding "Unwind" and "SetSignal" */ - -#define Unwind 4 -#define setSignal(newValue) *_retsignal=_signal=(newValue) -#define suppressSignal *_retsignal=_signal=0 -#define exportSignal *_retsignal=_signal diff --git a/Tools/CodeTools/TianoTools/Pccts/h/ASTBase.cpp b/Tools/CodeTools/TianoTools/Pccts/h/ASTBase.cpp deleted file mode 100644 index a94f080c86..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/ASTBase.cpp +++ /dev/null @@ -1,256 +0,0 @@ -/* Abstract syntax tree manipulation functions - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -#include "pcctscfg.h" - -#include "pccts_stdio.h" -#include "pccts_stdarg.h" - -PCCTS_NAMESPACE_STD - -#define ANTLR_SUPPORT_CODE - -#include "ASTBase.h" - -/* ensure that tree manipulation variables are current after a rule - * reference - */ -void -ASTBase::link(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail) -{ - if ( *_sibling == NULL ) return; - if ( *_root == NULL ) *_root = *_sibling; - else if ( *_root != *_sibling ) (*_root)->_down = *_sibling; - if ( *_tail==NULL ) *_tail = *_sibling; - while ( (*_tail)->_right != NULL ) *_tail = (*_tail)->_right; -} - -/* add a child node to the current sibling list */ -void -ASTBase::subchild(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail) -{ - if ( *_tail != NULL ) (*_tail)->_right = this; - else { - *_sibling = this; - if ( *_root != NULL ) (*_root)->_down = *_sibling; - } - *_tail = this; - if ( *_root == NULL ) *_root = *_sibling; -} - -/* make a new AST node. Make the newly-created - * node the root for the current sibling list. If a root node already - * exists, make the newly-created node the root of the current root. - */ -void -ASTBase::subroot(ASTBase **_root, ASTBase **_sibling, ASTBase **_tail) -{ - if ( *_root != NULL ) - if ( (*_root)->_down == *_sibling ) *_sibling = *_tail = *_root; - *_root = this; - (*_root)->_down = *_sibling; -} - -/* Apply preorder_action(), etc.. to root then each sibling */ -// -// 7-Apr-97 133MR1 -// Fix suggested by Ron House (house@helios.usq.edu.au) -// -void -ASTBase::preorder(void* pData /*= NULL*/ /* MR23 */) -{ - ASTBase *tree = this; - - while ( tree!= NULL ) - { - if ( tree->_down != NULL ) { - tree->preorder_before_action(pData); // MR1 - }; - tree->preorder_action(pData); - if ( tree->_down!=NULL ) - { - tree->_down->preorder(pData); - tree->preorder_after_action(pData); // MR1 - } - tree = tree->_right; - } -} - -/* free all AST nodes in tree; apply func to each before freeing */ -void -ASTBase::destroy() -{ - ASTBase* tree = this; - while (tree) { - if (tree->_down) tree->_down->destroy(); - - ASTBase* cur = tree; - tree = tree->_right; - delete cur; - } -} - -/* build a tree (root child1 child2 ... NULL) - * If root is NULL, simply make the children siblings and return ptr - * to 1st sibling (child1). If root is not single node, return NULL. - * - * Siblings that are actually siblins lists themselves are handled - * correctly. For example #( NULL, #( NULL, A, B, C), D) results - * in the tree ( NULL A B C D ). - * - * Requires at least two parameters with the last one being NULL. If - * both are NULL, return NULL. - */ -ASTBase * -ASTBase::tmake(ASTBase *root, ...) -{ - va_list ap; - register ASTBase *child, *sibling=NULL, *tail=NULL /*MR23*/, *w; - - va_start(ap, root); - - if ( root != NULL ) - if ( root->_down != NULL ) { - root->reportOverwriteOfDownPointer(); /* MR21 Report problem which almost always an error */ - return NULL; - } - child = va_arg(ap, ASTBase *); - while ( child != NULL ) - { - for (w=child; w->_right!=NULL; w=w->_right) {;} /* find end of child */ - if ( sibling == NULL ) {sibling = child; tail = w;} - else {tail->_right = child; tail = w;} - child = va_arg(ap, ASTBase *); - } - if ( root==NULL ) root = sibling; - else root->_down = sibling; - va_end(ap); - return root; -} - -#ifndef PCCTS_NOT_USING_SOR - -/* tree duplicate */ -// forgot to check for NULL this (TJP July 23,1995) -ASTBase * -ASTBase::dup() -{ - ASTBase *u, *t=this; - - if ( t == NULL ) return NULL; -/* - u = new ASTBase; - *u = *t; -*/ - u = (ASTBase *)this->shallowCopy(); - if ( t->_right!=NULL ) u->_right = t->_right->dup(); - else u->_right = NULL; - if ( t->_down!=NULL ) u->_down = t->_down->dup(); - else u->_down = NULL; - return u; -} -#endif - -// -// 7-Apr-97 133MR1 -// Fix suggested by Asgeir Olafsson (olafsson@cstar.ac.com) -// -/* tree duplicate */ - -#ifndef PCCTS_NOT_USING_SOR - -ASTBase * -ASTDoublyLinkedBase::dup() -{ - ASTDoublyLinkedBase *u, *t=this; - - if ( t == NULL ) return NULL; - u = (ASTDoublyLinkedBase *)this->shallowCopy(); - u->_up = NULL; /* set by calling invocation */ - u->_left = NULL; - if (t->_right!=NULL) { // MR1 - u->_right=t->_right->dup(); // MR1 - ((ASTDoublyLinkedBase *)u->_right)->_left = u; // MR1 - } else { // MR1 - u->_right = NULL; // MR1 - }; // MR1 - if (t->_down!=NULL) { // MR1 - u->_down = t->_down->dup(); // MR1 - ((ASTDoublyLinkedBase *)u->_down)->_up = u; // MR1 - } else { // MR1 - u->_down = NULL; // MR1 - }; // MR1 - return u; -} - -#endif - -/* - * Set the 'up', and 'left' pointers of all nodes in 't'. - * Initial call is double_link(your_tree, NULL, NULL). - */ -void -ASTDoublyLinkedBase::double_link(ASTBase *left, ASTBase *up) -{ - ASTDoublyLinkedBase *t = this; - - t->_left = (ASTDoublyLinkedBase *) left; - t->_up = (ASTDoublyLinkedBase *) up; - if (t->_down != NULL) - ((ASTDoublyLinkedBase *)t->_down)->double_link(NULL, t); - if (t->_right != NULL) - ((ASTDoublyLinkedBase *)t->_right)->double_link(t, up); -} - -// MR21 ASTBase::reportOverwriteOfDownPointer - -void ASTBase::reportOverwriteOfDownPointer() -{ - panic("Attempt to overwrite down pointer in ASTBase::tmake"); -} - -// MR21 ASTBase::panic - -void ASTBase::panic(const char *msg) -{ - /* MR23 */ printMessage(stderr,"ASTBase panic: %s\n", msg); - exit(PCCTS_EXIT_FAILURE); -} - -#ifdef PCCTS_NOT_USING_SOR -//MR23 -int ASTBase::printMessage(FILE* pFile, const char* pFormat, ...) -{ - va_list marker; - va_start( marker, pFormat ); - int iRet = vfprintf(pFile, pFormat, marker); - va_end( marker ); - return iRet; -} -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/ASTBase.h b/Tools/CodeTools/TianoTools/Pccts/h/ASTBase.h deleted file mode 100644 index 912f4b8482..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/ASTBase.h +++ /dev/null @@ -1,122 +0,0 @@ -/* Abstract syntax tree - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -#ifndef ASTBase_H -#define ASTBase_H - -#include "pcctscfg.h" - -#include "pccts_stdio.h" -#include "pccts_stdlib.h" - -PCCTS_NAMESPACE_STD - -#ifndef PCCTS_NOT_USING_SOR -#include "PCCTSAST.h" -#endif - -/* - * Notes: - * - * To specify a copy constructor, subclass one of these classes and - * give the copy constructor. To use dup(), you must define shallowCopy(). - * shallowCopy() can use either a copy constructor or just copy the node - * itself. - */ - -#ifdef PCCTS_NOT_USING_SOR -class DllExportPCCTS ASTBase { -#else -class DllExportPCCTS ASTBase : public PCCTS_AST { -#endif - -protected: - ASTBase *_right, *_down; - -public: - -#ifdef PCCTS_NOT_USING_SOR - ASTBase *right() { return _right; } - ASTBase *down() { return _down; } - void setRight(ASTBase *t) { _right = (ASTBase *)t; } - void setDown(ASTBase *t) { _down = (ASTBase *)t; } -#else - PCCTS_AST *right() { return _right; } // define the SORCERER interface - PCCTS_AST *down() { return _down; } - void setRight(PCCTS_AST *t) { _right = (ASTBase *)t; } - void setDown(PCCTS_AST *t) { _down = (ASTBase *)t; } -#endif - ASTBase() { _right = _down = NULL; } - virtual ~ASTBase() { ; } -#ifndef PCCTS_NOT_USING_SOR - virtual ASTBase *dup(); -#endif - void destroy(); - void preorder(void* pData = NULL /* MR23 */); - static ASTBase *tmake(ASTBase *, ...); - static void link(ASTBase **, ASTBase **, ASTBase **); - void subchild(ASTBase **, ASTBase **, ASTBase **); - void subroot(ASTBase **, ASTBase **, ASTBase **); - virtual void preorder_action(void* /*pData*/ = NULL /* MR23 */) { ; } - virtual void preorder_before_action(void* /*pData*/ = NULL /* MR23 */) { /* MR23 */ printMessage(stdout, " ("); } - virtual void preorder_after_action(void* /*pData*/ = NULL /* MR23 */) { /* MR23 */ printMessage(stdout, " )"); } - virtual void panic(const char *msg); /* MR21 */ - virtual void reportOverwriteOfDownPointer(); /* MR21 */ -#ifdef PCCTS_NOT_USING_SOR - virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23 -#endif -}; - -class DllExportPCCTS ASTDoublyLinkedBase : public ASTBase { -protected: - ASTDoublyLinkedBase *_left, *_up; - -public: - void double_link(ASTBase *left, ASTBase *up); - -#ifndef PCCTS_NOT_USING_SOR - virtual ASTBase *dup(); -#endif - -#ifdef PCCTS_NOT_USING_SOR - ASTBase *left() { return _left; } - ASTBase *up() { return _up; } - void setLeft(ASTBase *t) { _left = (ASTDoublyLinkedBase *)t; } // MR6 - void setUp(ASTBase *t) { _up = (ASTDoublyLinkedBase *)t; } // MR6 -#else - PCCTS_AST *left() { return _left; } - PCCTS_AST *up() { return _up; } - void setLeft(PCCTS_AST *t) { _left = (ASTDoublyLinkedBase *)t; } // MR6 - void setUp(PCCTS_AST *t) { _up = (ASTDoublyLinkedBase *)t; } // MR6 -#endif - -}; - -class AST; // announce that this class will be coming along shortly -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/ATokPtr.h b/Tools/CodeTools/TianoTools/Pccts/h/ATokPtr.h deleted file mode 100644 index 75b4c86cbf..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/ATokPtr.h +++ /dev/null @@ -1,88 +0,0 @@ -/* ATokPtr.h - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Written by Russell Quong June 30, 1995 - * Adapted by Terence Parr to ANTLR stuff - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -#ifndef ATokPtr_h -#define ATokPtr_h - -#include "pcctscfg.h" - -#include "pccts_stdio.h" - -PCCTS_NAMESPACE_STD - -// pointer to a reference counted object -// robust in that an unused ANTLRTokenPtr can point to NULL. - -class ANTLRAbstractToken; - -class DllExportPCCTS ANTLRTokenPtr { -public: - ANTLRTokenPtr(ANTLRAbstractToken *addr=NULL){ptr_ = addr; ref();} - ANTLRTokenPtr(const ANTLRTokenPtr &lhs) {ptr_ = lhs.ptr_; lhs.ref();} - ~ANTLRTokenPtr(); - - // use ANTLRTokenPtr as a pointer to ANTLRToken -// -// 8-Apr-97 MR1 Make operator -> a const member function -// as well as some other member functions -// - ANTLRAbstractToken *operator-> () const { return ptr_; } // MR1 -// -// 7-Apr-97 133MR1 -// Fix suggested by Andreas Magnusson -// (Andreas.Magnusson@mailbox.swipnet.se) - void operator = (const ANTLRTokenPtr & lhs); // MR1 - void operator = (ANTLRAbstractToken *addr); - int operator != (const ANTLRTokenPtr &q) const // MR1 // MR11 unsigned -> int - { return this->ptr_ != q.ptr_; } - int operator == (const ANTLRTokenPtr &q) const // MR1 // MR11 unsigned -> int - { return this->ptr_ == q.ptr_; } - int operator == (const ANTLRAbstractToken *addr) const // MR11 - { return this->ptr_ == addr; } - int operator != (const ANTLRAbstractToken *addr) const // MR11 - { return this->ptr_ != addr; } - - void ref() const; - void deref(); - -protected: - ANTLRAbstractToken *ptr_; -}; - -//typedef ANTLRTokenPtr _ANTLRTokenPtr; - -/* - * Since you cannot redefine operator->() to return one of the user's - * token object types, we must down cast. This is a drag. Here's - * a macro that helps. template: "mytoken(a-smart-ptr)->myfield". - */ -#define mytoken(tk) ((ANTLRToken *)(tk.operator->())) - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/ATokPtrImpl.h b/Tools/CodeTools/TianoTools/Pccts/h/ATokPtrImpl.h deleted file mode 100644 index 9c07cf52a9..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/ATokPtrImpl.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * ATokPtrImpl.h (formerly ATokPtr.cpp) - * - * This is #included in ATokBuffer.cpp for historical reasons. - * It has been renamed because of problems with the .cpp extension - * when used with IDE. - * - * - * ANTLRToken MUST be defined before entry to this file. - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Written by Russell Quong June 30, 1995 - * Adapted by Terence Parr to ANTLR stuff - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -#include "pcctscfg.h" - -PCCTS_NAMESPACE_STD - -#include "ATokPtr.h" - -void ANTLRTokenPtr::ref() const -{ - if (ptr_ != NULL) { - ptr_->ref(); - } -} - -void ANTLRTokenPtr::deref() -{ - if (ptr_ != NULL) - { - ptr_->deref(); - if ( ptr_->nref()==0 ) - { - delete ptr_; - ptr_ = NULL; - } - } -} - -ANTLRTokenPtr::~ANTLRTokenPtr() -{ - deref(); -} - -// -// 8-Apr-97 MR1 Make operator -> a const member function -// as weall as some other member functions -// -void ANTLRTokenPtr::operator = (const ANTLRTokenPtr & lhs) // MR1 -{ - lhs.ref(); // protect against "xp = xp"; ie same underlying object - deref(); - ptr_ = lhs.ptr_; -} - -void ANTLRTokenPtr::operator = (ANTLRAbstractToken *addr) -{ - if (addr != NULL) { - addr->ref(); - } - deref(); - ptr_ = addr; -} diff --git a/Tools/CodeTools/TianoTools/Pccts/h/AToken.h b/Tools/CodeTools/TianoTools/Pccts/h/AToken.h deleted file mode 100644 index 6167c21ef5..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/AToken.h +++ /dev/null @@ -1,325 +0,0 @@ -/* ANTLRToken.h - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -#ifndef ATOKEN_H_GATE -#define ATOKEN_H_GATE - -#include "pcctscfg.h" - -#include "pccts_string.h" -#include "pccts_stdio.h" -#include "pccts_stdlib.h" -#include "pccts_stdarg.h" // MR23 - -PCCTS_NAMESPACE_STD - -// MR9 RJV (JVincent@novell.com) Not needed for variable length strings - -//// MR9 #ifndef ANTLRCommonTokenTEXTSIZE -//// MR9 #define ANTLRCommonTokenTEXTSIZE 100 -//// MR9 #endif - - -/* must define what a char looks like; can make this a class too */ -typedef char ANTLRChar; - -/* D E F I N E S M A R T P O I N T E R S */ - -//#include ATOKPTR_H not tested yet, leave out -class ANTLRAbstractToken; -typedef ANTLRAbstractToken *_ANTLRTokenPtr; - -class ANTLRAbstractToken { -public: - virtual ~ANTLRAbstractToken() {;} - virtual ANTLRTokenType getType() const = 0; - virtual void setType(ANTLRTokenType t) = 0; - virtual int getLine() const = 0; - virtual void setLine(int line) = 0; - virtual ANTLRChar *getText() const = 0; - virtual void setText(const ANTLRChar *) = 0; - - /* This function will disappear when I can use templates */ - virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt, - ANTLRChar *text, - int line) = 0; - - /* define to satisfy ANTLRTokenBuffer's need to determine whether or - not a token object can be destroyed. If nref()==0, no one has - a reference, and the object may be destroyed. This function defaults - to 1, hence, if you use deleteTokens() message with a token object - not derived from ANTLRCommonRefCountToken, the parser will compile - but will not delete objects after they leave the token buffer. - */ - - virtual unsigned nref() const { return 1; } // MR11 - virtual void ref() {;} - virtual void deref() {;} - - virtual void panic(const char *msg) // MR20 const - { - /* MR23 */ printMessage(stderr, "ANTLRAbstractToken panic: %s\n", msg); - exit(PCCTS_EXIT_FAILURE); - } - - virtual int printMessage(FILE* pFile, const char* pFormat, ...) // MR23 - { - va_list marker; - va_start( marker, pFormat ); - int iRet = vfprintf(pFile, pFormat, marker); - va_end( marker ); - return iRet; - } -}; - -/* This class should be subclassed. It cannot store token type or text */ - -class ANTLRRefCountToken : public ANTLRAbstractToken { -public: -#ifdef DBG_REFCOUNTTOKEN - static int ctor; - static int dtor; -#endif -protected: - unsigned refcnt_; -#ifdef DBG_REFCOUNTTOKEN - char object[200]; -#endif - -public: - - // MR23 - No matter what you do, you're hammered. - // Don't give names to formals something breaks. - // Give names to formals and don't use them it breaks. - -#ifndef DBG_REFCOUNTTOKEN - ANTLRRefCountToken(ANTLRTokenType /* t MR23 */, const ANTLRChar * /* s MR23 */) -#else - ANTLRRefCountToken(ANTLRTokenType t, const ANTLRChar * s) -#endif - -#ifndef DBG_REFCOUNTTOKEN - { - refcnt_ = 0; - } -#else - { - ctor++; - refcnt_ = 0; - if ( t==1 ) sprintf(object,"tok_EOF"); - else sprintf(object,"tok_%s",s); - /* MR23 */ printMessage(stderr, "ctor %s #%d\n",object,ctor); - } -#endif - ANTLRRefCountToken() -#ifndef DBG_REFCOUNTTOKEN - { refcnt_ = 0; } -#else - { - ctor++; - refcnt_ = 0; - sprintf(object,"tok_blank"); - /* MR23 */ printMessage(stderr, "ctor %s #%d\n",object,ctor); - } - virtual ~ANTLRRefCountToken() - { - dtor++; - if ( dtor>ctor ) /* MR23 */ printMessage(stderr, "WARNING: dtor>ctor\n"); - /* MR23 */ printMessage(stderr, "dtor %s #%d\n", object, dtor); - object[0]='\0'; - } -#endif - - // reference counting stuff needed by ANTLRTokenPtr. - // User should not access these; for C++ language reasons, we had - // to make these public. Yuck. - - void ref() { refcnt_++; } - void deref() { refcnt_--; } - unsigned nref() const { return refcnt_; } // MR11 - - virtual ANTLRAbstractToken *makeToken(ANTLRTokenType /*tt MR23*/, - ANTLRChar * /*txt MR23*/, - int /*line MR23*/) - { - panic("call to ANTLRRefCountToken::makeToken()\n"); - return NULL; - } -}; - -class ANTLRCommonNoRefCountToken : public ANTLRAbstractToken { -protected: - ANTLRTokenType _type; - int _line; - ANTLRChar *_text; // MR9 RJV - -public: - ANTLRCommonNoRefCountToken(ANTLRTokenType t, const ANTLRChar *s) - { setType(t); _line = 0; _text = NULL; setText(s); } - ANTLRCommonNoRefCountToken() - { setType((ANTLRTokenType)0); _line = 0; _text = NULL; setText(""); } - - ~ANTLRCommonNoRefCountToken() { if (_text) delete [] _text; } // MR9 RJV: Added Destructor to remove string - - ANTLRTokenType getType() const { return _type; } - void setType(ANTLRTokenType t) { _type = t; } - virtual int getLine() const { return _line; } - void setLine(int line) { _line = line; } - ANTLRChar *getText() const { return _text; } - int getLength() const { return strlen(getText()); } // MR11 - -// MR9 RJV: Added code for variable length strings to setText() - - void setText(const ANTLRChar *s) - { if (s != _text) { - if (_text) delete [] _text; - if (s != NULL) { - _text = new ANTLRChar[strlen(s)+1]; - if (_text == NULL) panic("ANTLRCommonNoRefCountToken::setText new failed"); - strcpy(_text,s); - } else { - _text = new ANTLRChar[1]; - if (_text == NULL) panic("ANTLRCommonNoRefCountToken::setText new failed"); - strcpy(_text,""); - }; - }; - } - - virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt, - ANTLRChar *txt, - int line) - { - ANTLRAbstractToken *t = new ANTLRCommonNoRefCountToken; - t->setType(tt); t->setText(txt); t->setLine(line); - return t; - } - -// MR9 THM Copy constructor required when heap allocated string is used with copy semantics - - ANTLRCommonNoRefCountToken (const ANTLRCommonNoRefCountToken& from) : - ANTLRAbstractToken(from) { - setType(from._type); - setLine(from._line); - _text=NULL; - setText(from._text); - }; - -// MR9 THM operator =() required when heap allocated string is used with copy semantics - - virtual ANTLRCommonNoRefCountToken& operator =(const ANTLRCommonNoRefCountToken& rhs) { - -////// MR15 WatCom can't hack use of operator =() -////// Use this: *( (ANTRLAbstractToken *) this)=rhs; - - *( (ANTLRAbstractToken *) this ) = rhs; - - setType(rhs._type); - setLine(rhs._line); - setText(rhs._text); - return *this; - }; -}; - -class ANTLRCommonToken : public ANTLRRefCountToken { -protected: - ANTLRTokenType _type; - int _line; - ANTLRChar *_text; // MR9 RJV:Added - -public: - ANTLRCommonToken(ANTLRTokenType t, const ANTLRChar *s) : ANTLRRefCountToken(t,s) - { setType(t); _line = 0; _text = NULL; setText(s); } // MR9 - ANTLRCommonToken() - { setType((ANTLRTokenType)0); _line = 0; _text = NULL; setText(""); } // MR9 - - virtual ~ANTLRCommonToken() { if (_text) delete [] _text; } // MR9 RJV: Added Destructor to remove string - - ANTLRTokenType getType() const { return _type; } - void setType(ANTLRTokenType t) { _type = t; } - virtual int getLine() const { return _line; } - void setLine(int line) { _line = line; } - ANTLRChar *getText() const { return _text; } - int getLength() const { return strlen(getText()); } // MR11 - -// MR9 RJV: Added code for variable length strings to setText() - - void setText(const ANTLRChar *s) - { if (s != _text) { - if (_text) delete [] _text; - if (s != NULL) { - _text = new ANTLRChar[strlen(s)+1]; - if (_text == NULL) panic("ANTLRCommonToken::setText new failed"); - strcpy(_text,s); - } else { - _text = new ANTLRChar[1]; - if (_text == NULL) panic("ANTLRCommonToken::setText new failed"); - strcpy(_text,""); - }; - }; - } - - virtual ANTLRAbstractToken *makeToken(ANTLRTokenType tt, - ANTLRChar *txt, - int line) - { - ANTLRAbstractToken *t = new ANTLRCommonToken(tt,txt); - t->setLine(line); - return t; - } - -// MR9 THM Copy constructor required when heap allocated string is used with copy semantics - - ANTLRCommonToken (const ANTLRCommonToken& from) : - ANTLRRefCountToken(from) { - setType(from._type); - setLine(from._line); - _text=NULL; - setText(from._text); - }; - -// MR9 THM operator =() required when heap allocated string is used with copy semantics - - virtual ANTLRCommonToken& operator =(const ANTLRCommonToken& rhs) { - -////// MR15 WatCom can't hack use of operator =() -////// Use this instead: *( (ANTRLRRefCountToken *) this)=rhs; - - *( (ANTLRRefCountToken *) this) = rhs; - - setType(rhs._type); - setLine(rhs._line); - setText(rhs._text); - return *this; - }; -}; - -// used for backward compatibility -typedef ANTLRCommonToken ANTLRCommonBacktrackingToken; - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/ATokenBuffer.cpp b/Tools/CodeTools/TianoTools/Pccts/h/ATokenBuffer.cpp deleted file mode 100644 index 9a2f2fc88b..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/ATokenBuffer.cpp +++ /dev/null @@ -1,374 +0,0 @@ -/* ANTLRTokenBuffer.cpp - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -typedef int ANTLRTokenType; // fool AToken.h into compiling - -class ANTLRParser; /* MR1 */ - -#define ANTLR_SUPPORT_CODE - -#include "pcctscfg.h" - -#include ATOKENBUFFER_H -#include APARSER_H // MR23 - -typedef ANTLRAbstractToken *_ANTLRTokenPtr; - -#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW) -static unsigned char test[1000]; -#endif - -#ifdef DBG_REFCOUNTTOKEN -int ANTLRRefCountToken::ctor = 0; /* MR23 */ -int ANTLRRefCountToken::dtor = 0; /* MR23 */ -#endif - -ANTLRTokenBuffer:: -ANTLRTokenBuffer(ANTLRTokenStream *_input, int _k, int _chunk_size_formal) /* MR14 */ -{ - this->input = _input; - this->k = _k; - buffer_size = chunk_size = _chunk_size_formal; - buffer = (_ANTLRTokenPtr *) - calloc(chunk_size+1,sizeof(_ANTLRTokenPtr )); - if ( buffer == NULL ) { - panic("cannot alloc token buffer"); - } - buffer++; // leave the first elem empty so tp-1 is valid ptr - - tp = &buffer[0]; - last = tp-1; - next = &buffer[0]; - num_markers = 0; - end_of_buffer = &buffer[buffer_size-1]; - threshold = &buffer[(int)(buffer_size/2)]; // MR23 - Used to be 1.0/2.0 ! - _deleteTokens = 1; // assume we delete tokens - parser=NULL; // MR5 - uninitialized reference -} - -static void f() {;} -ANTLRTokenBuffer:: -~ANTLRTokenBuffer() -{ - f(); - // Delete all remaining tokens (from 0..last inclusive) - if ( _deleteTokens ) - { - _ANTLRTokenPtr *z; - for (z=buffer; z<=last; z++) - { - (*z)->deref(); -// z->deref(); -#ifdef DBG_REFCOUNTTOKEN - /* MR23 */ printMessage(stderr, "##########dtor: deleting token '%s' (ref %d)\n", - ((ANTLRCommonToken *)*z)->getText(), (*z)->nref()); -#endif - if ( (*z)->nref()==0 ) - { - delete (*z); - } - } - } - - if ( buffer!=NULL ) free((char *)(buffer-1)); -} - -#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW) -#include "pccts_stdio.h" -PCCTS_NAMESPACE_STD -#endif - -_ANTLRTokenPtr ANTLRTokenBuffer:: -getToken() -{ - if ( tp <= last ) // is there any buffered lookahead still to be read? - { - return *tp++; // read buffered lookahead - } - // out of buffered lookahead, get some more "real" - // input from getANTLRToken() - if ( num_markers==0 ) - { - if( next > threshold ) - { -#ifdef DBG_TBUF -/* MR23 */ printMessage(stderr,"getToken: next > threshold (high water is %d)\n", threshold-buffer); -#endif - makeRoom(); - } - } - else { - if ( next > end_of_buffer ) - { -#ifdef DBG_TBUF -/* MR23 */ printMessage(stderr,"getToken: next > end_of_buffer (size is %d)\n", buffer_size); -#endif - extendBuffer(); - } - } - *next = getANTLRToken(); - (*next)->ref(); // say we have a copy of this pointer in buffer - last = next; - next++; - tp = last; - return *tp++; -} - -void ANTLRTokenBuffer:: -rewind(int pos) -{ -#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW) - /* MR23 */ printMessage(stderr, "rewind(%d)[nm=%d,from=%d,%d.n=%d]\n", pos, num_markers, tp-buffer,pos,test[pos]); - test[pos]--; -#endif - tp = &buffer[pos]; - num_markers--; -} - -/* - * This function is used to specify that the token pointers read - * by the ANTLRTokenBuffer should be buffered up (to be reused later). - */ -int ANTLRTokenBuffer:: -mark() -{ -#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW) - test[tp-buffer]++; - /* MR23 */ printMessage(stderr,"mark(%d)[nm=%d,%d.n=%d]\n",tp-buffer,num_markers+1,tp-buffer,test[tp-buffer]); -#endif - num_markers++; - return tp - buffer; -} - -/* - * returns the token pointer n positions ahead. - * This implies that bufferedToken(1) gets the NEXT symbol of lookahead. - * This is used in conjunction with the ANTLRParser lookahead buffer. - * - * No markers are set or anything. A bunch of input is buffered--that's all. - * The tp pointer is left alone as the lookahead has not been advanced - * with getToken(). The next call to getToken() will find a token - * in the buffer and won't have to call getANTLRToken(). - * - * If this is called before a consume() is done, how_many_more_i_need is - * set to 'n'. - */ -_ANTLRTokenPtr ANTLRTokenBuffer:: -bufferedToken(int n) -{ -// int how_many_more_i_need = (last-tp < 0) ? n : n-(last-tp)-1; - int how_many_more_i_need = (tp > last) ? n : n-(last-tp)-1; - // Make sure that at least n tokens are available in the buffer -#ifdef DBG_TBUF - /* MR23 */ printMessage(stderr, "bufferedToken(%d)\n", n); -#endif - for (int i=1; i<=how_many_more_i_need; i++) - { - if ( next > end_of_buffer ) // buffer overflow? - { - extendBuffer(); - } - *next = getANTLRToken(); - (*next)->ref(); // say we have a copy of this pointer in buffer - last = next; - next++; - } - return tp[n - 1]; -} - -/* If no markers are set, the none of the input needs to be saved (except - * for the lookahead Token pointers). We save only k-1 token pointers as - * we are guaranteed to do a getANTLRToken() right after this because otherwise - * we wouldn't have needed to extend the buffer. - * - * If there are markers in the buffer, we need to save things and so - * extendBuffer() is called. - */ -void ANTLRTokenBuffer:: -makeRoom() -{ -#ifdef DBG_TBUF - /* MR23 */ printMessage(stderr, "in makeRoom.................\n"); - /* MR23 */ printMessage(stderr, "num_markers==%d\n", num_markers); -#endif -/* - if ( num_markers == 0 ) - { -*/ -#ifdef DBG_TBUF - /* MR23 */ printMessage(stderr, "moving lookahead and resetting next\n"); - - _ANTLRTokenPtr *r; - /* MR23 */ printMessage(stderr, "tbuf = ["); - for (r=buffer; r<=last; r++) - { - if ( *r==NULL ) /* MR23 */ printMessage(stderr, " xxx"); - else /* MR23 */ printMessage(stderr, " '%s'", ((ANTLRCommonToken *)*r)->getText()); - } - /* MR23 */ printMessage(stderr, " ]\n"); - - /* MR23 */ printMessage(stderr, - "before: tp=%d, last=%d, next=%d, threshold=%d\n",tp-buffer,last-buffer,next-buffer,threshold-buffer); -#endif - - // Delete all tokens from 0..last-(k-1) inclusive - if ( _deleteTokens ) - { - _ANTLRTokenPtr *z; - for (z=buffer; z<=last-(k-1); z++) - { - (*z)->deref(); -// z->deref(); -#ifdef DBG_REFCOUNTTOKEN - /* MR23 */ printMessage(stderr, "##########makeRoom: deleting token '%s' (ref %d)\n", - ((ANTLRCommonToken *)*z)->getText(), (*z)->nref()); -#endif - if ( (*z)->nref()==0 ) - { - delete (*z); - } - } - } - - // reset the buffer to initial conditions, but move k-1 symbols - // to the beginning of buffer and put new input symbol at k - _ANTLRTokenPtr *p = buffer, *q = last-(k-1)+1; -// ANTLRAbstractToken **p = buffer, **q = end_of_buffer-(k-1)+1; -#ifdef DBG_TBUF - /* MR23 */ printMessage(stderr, "lookahead buffer = ["); -#endif - for (int i=1; i<=(k-1); i++) - { - *p++ = *q++; -#ifdef DBG_TBUF - /* MR23 */ printMessage(stderr, - " '%s'", ((ANTLRCommonToken *)buffer[i-1])->getText()); -#endif - } -#ifdef DBG_TBUF - /* MR23 */ printMessage(stderr, " ]\n"); -#endif - next = &buffer[k-1]; - tp = &buffer[k-1]; // tp points to what will be filled in next - last = tp-1; -#ifdef DBG_TBUF - /* MR23 */ printMessage(stderr, - "after: tp=%d, last=%d, next=%d\n", - tp-buffer, last-buffer, next-buffer); -#endif -/* - } - else { - extendBuffer(); - } -*/ -} - -/* This function extends 'buffer' by chunk_size and returns with all - * pointers at the same relative positions in the buffer (the buffer base - * address could have changed in realloc()) except that 'next' comes - * back set to where the next token should be stored. All other pointers - * are untouched. - */ -void -ANTLRTokenBuffer:: -extendBuffer() -{ - int save_last = last-buffer, save_tp = tp-buffer, save_next = next-buffer; -#ifdef DBG_TBUF - /* MR23 */ printMessage(stderr, "extending physical buffer\n"); -#endif - buffer_size += chunk_size; - buffer = (_ANTLRTokenPtr *) - realloc((char *)(buffer-1), - (buffer_size+1)*sizeof(_ANTLRTokenPtr )); - if ( buffer == NULL ) { - panic("cannot alloc token buffer"); - } - buffer++; // leave the first elem empty so tp-1 is valid ptr - - tp = buffer + save_tp; // put the pointers back to same relative position - last = buffer + save_last; - next = buffer + save_next; - end_of_buffer = &buffer[buffer_size-1]; - threshold = &buffer[(int)(buffer_size*(1.0/2.0))]; - -/* - // zero out new token ptrs so we'll know if something to delete in buffer - ANTLRAbstractToken **p = end_of_buffer-chunk_size+1; - for (; p<=end_of_buffer; p++) *p = NULL; -*/ -} - -ANTLRParser * ANTLRTokenBuffer:: // MR1 -setParser(ANTLRParser *p) { // MR1 - ANTLRParser *old=parser; // MR1 - parser=p; // MR1 - input->setParser(p); // MR1 - return old; // MR1 -} // MR1 - // MR1 -ANTLRParser * ANTLRTokenBuffer:: // MR1 -getParser() { // MR1 - return parser; // MR1 -} // MR1 - -void ANTLRTokenBuffer::panic(const char *msg) // MR23 -{ - if (parser) //MR23 - parser->panic(msg); //MR23 - else //MR23 - exit(PCCTS_EXIT_FAILURE); -} - -//MR23 -int ANTLRTokenBuffer::printMessage(FILE* pFile, const char* pFormat, ...) -{ - va_list marker; - va_start( marker, pFormat ); - - int iRet = 0; - if (parser) - parser->printMessageV(pFile, pFormat, marker); - else - iRet = vfprintf(pFile, pFormat, marker); - - va_end( marker ); - return iRet; -} - -/* to avoid having to link in another file just for the smart token ptr - * stuff, we include it here. Ugh. - * - * MR23 This causes nothing but problems for IDEs. - * Change from .cpp to .h - * - */ - -#include ATOKPTR_IMPL_H diff --git a/Tools/CodeTools/TianoTools/Pccts/h/ATokenBuffer.h b/Tools/CodeTools/TianoTools/Pccts/h/ATokenBuffer.h deleted file mode 100644 index 1c008fd59e..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/ATokenBuffer.h +++ /dev/null @@ -1,109 +0,0 @@ -/* ANTLRTokenBuffer.h - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -#ifndef ATOKENBUFFER_H_GATE -#define ATOKENBUFFER_H_GATE - -#include "pcctscfg.h" - -#include "pccts_stdlib.h" - -PCCTS_NAMESPACE_STD - -#include ATOKEN_H -#include ATOKENSTREAM_H - -/* - * The parser is "attached" to an ANTLRTokenBuffer via interface - * functions: getToken() and bufferedToken(). The object that actually - * consumes characters and constructs tokens is connected to the - * ANTLRTokenBuffer via interface function ANTLRTokenStream::getToken(); - * where ANTLRTokenStream is really just a behavior (class with no data). - * C++ does not have this abstraction and hence we simply have come up - * with a fancy name for "void *". See the note in ANTLRTokenStream.h on - * the "behavior" of ANTLRTokenStream. - */ - -class ANTLRParser; // MR1 - -class DllExportPCCTS ANTLRTokenBuffer { -protected: - ANTLRTokenStream *input; // where do I get tokens - int buffer_size; - int chunk_size; - int num_markers; - int k; // Need at least this many tokens in buffer - _ANTLRTokenPtr *buffer; // buffer used for arbitrary lookahead - _ANTLRTokenPtr *tp; // pts into buffer; current token ptr - _ANTLRTokenPtr *last; // pts to last valid token in buffer - _ANTLRTokenPtr *next; // place to put token from getANTLRToken() - _ANTLRTokenPtr *end_of_buffer; - /* when you try to write a token past this and there are no markers - set, then move k-1 tokens back to the beginning of the buffer. - We want to stay away from the end of the buffer because we have - to extend it if a marker is set and we reach the end (we cannot - move tokens to the beginning of the buffer in this case). - */ - _ANTLRTokenPtr *threshold; - unsigned char _deleteTokens; - - // This function is filled in by the subclass; it initiates fetch of input - virtual _ANTLRTokenPtr getANTLRToken() { return input->getToken(); } - void makeRoom(); - void extendBuffer(); - -public: - ANTLRTokenBuffer(ANTLRTokenStream *in, int k=1, int chksz=50); - virtual ~ANTLRTokenBuffer(); - virtual _ANTLRTokenPtr getToken(); - virtual void rewind(int pos); - virtual int mark(); - virtual _ANTLRTokenPtr bufferedToken(int i); - - void noGarbageCollectTokens() { _deleteTokens=0; } - void garbageCollectTokens() { _deleteTokens=1; } - - virtual int bufferSize() { return buffer_size; } - virtual int minTokens() { return k; } - virtual void setMinTokens(int k_new) { k = k_new; } - - virtual void panic(const char *msg); /* MR20 const */ - - virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23 - -protected: // MR1 - ANTLRParser *parser; // MR1 -public: // MR1 - ANTLRParser *setParser(ANTLRParser *p); // MR1 - ANTLRParser *getParser(); // MR1 - ANTLRTokenStream *getLexer() const { // MR12 - return input;} // MR12 -}; - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/ATokenStream.h b/Tools/CodeTools/TianoTools/Pccts/h/ATokenStream.h deleted file mode 100644 index 3dfea6ebff..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/ATokenStream.h +++ /dev/null @@ -1,51 +0,0 @@ -/* ANTLRTokenStream.h - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -#ifndef ATOKENSTREAM_H_GATE -#define ATOKENSTREAM_H_GATE - -#include "pcctscfg.h" - -/* This is really a behavior or protocol; it merely indicates the behavior - * required of the input and output of an ANTLRTokenBuffer. You could - * subclass it, but you can also just pass any old pointer to ANTLRTokenBuffer - * with a type cast (in which case, your getANTLRToken() would have to - * explicitly cast the input pointer to your REAL type (typically your lexer)). - */ - -class ANTLRParser; // MR1 - -class DllExportPCCTS ANTLRTokenStream { -public: - virtual _ANTLRTokenPtr getToken() = 0; - virtual ANTLRParser * setParser(ANTLRParser * /*p MR23*/) {return 0; }; // MR12 - virtual ANTLRParser * getParser() { return 0; }; // MR12 -}; - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/BufFileInput.cpp b/Tools/CodeTools/TianoTools/Pccts/h/BufFileInput.cpp deleted file mode 100644 index 99d08a42a4..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/BufFileInput.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// FILE: BufFileInput.cpp -// AUTHOR: Alexey Demakov (AVD) demakov@kazbek.ispras.ru -// CREATION: 26-JAN-1998 -// DESCRIPTION: File Input Stream with lookahead for Scanner. -// See file BufFileInput.h for details - -// Change History: -// -// 22-Jun-1998 assert.h -> PCCTS_ASSERT_H -// string.h -> PCCTS_STRING_H -// -// 28-May-1998 Add virtual destructor to release buffer. -// -// Add dummy definition for ANTLRTokenType -// to allow compilation without knowing -// token type codes. -// -// Manfred Kogler (km@cast.uni-linz.ac.at) -// (1.33MR14) -// -// 20-Jul-1998 MR14a - Reorder initialization list for ctor. -// - -enum ANTLRTokenType {TER_HATES_CPP=0, SO_DO_OTHERS=9999 }; - -#include "pcctscfg.h" -#include "pccts_assert.h" -#include "pccts_string.h" - -PCCTS_NAMESPACE_STD - -#include "BufFileInput.h" - -BufFileInput::BufFileInput( FILE *f, int buf_size ) -: input( f ), - buf( new int[buf_size] ), - size( buf_size ), - start( 0 ), - len( 0 ) -{ -} - -BufFileInput::~BufFileInput() -{ - delete [] buf; -} - -int BufFileInput::nextChar( void ) -{ - if( len > 0 ) - { - // get char from buffer - int c = buf[start]; - - if( c != EOF ) - { - start++; start %= size; - len--; - } - return c; - } else { - // get char from file - int c = getc( input ); - - if( c == EOF ) - { - // if EOF - put it in the buffer as indicator - buf[start] = EOF; - len++; - } - return c; - } -} - -int BufFileInput::lookahead( char* s ) -{ - int l = strlen( s ); - - assert( 0 < l && l <= size ); - - while( len < l ) - { - int c = getc( input ); - - buf[ (start+len) % size ] = c; - - len++; - - if( c == EOF ) return 0; - } - - for( int i = 0; i < l; i++ ) - { - if( s[i] != buf[ (start+i) % size ] ) return 0; - } - return 1; -} - -// End of file BufFileInput.cpp - diff --git a/Tools/CodeTools/TianoTools/Pccts/h/BufFileInput.h b/Tools/CodeTools/TianoTools/Pccts/h/BufFileInput.h deleted file mode 100644 index ea54c0ee26..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/BufFileInput.h +++ /dev/null @@ -1,53 +0,0 @@ -// FILE: BufFileInput.h -// AUTHOR: Alexey Demakov (AVD) demakov@kazbek.ispras.ru -// CREATION: 26-JAN-1998 -// DESCRIPTION: File Input Stream with lookahead for Scanner -// Tested under Win32 with ANTLR 1.33 MR10 and MSVC 5.0 - -// Change History: -// -// 28-May-1998 Add virtual destructor to release buffer -// Manfred Kogler (km@cast.uni-linz.ac.at) -// (1.33MR14) - -#ifndef BufFileInput_h -#define BufFileInput_h - -#include "pcctscfg.h" - -#include "pccts_stdio.h" - -PCCTS_NAMESPACE_STD - -#include "DLexerBase.h" - -class DllExportPCCTS BufFileInput : public DLGInputStream -{ -public: - // constructor - // f - input stream - // buf_size - size of buffer (maximal length for string in is_in) - - BufFileInput(FILE *f, int buf_size = 8 ); - - virtual ~BufFileInput(); - - // gets next char from stream - - virtual int nextChar( void ); - - // looks in stream and compares next l characters with s - // returns the result of comparision - - int lookahead( char* s ); - -private: - FILE *input; // input stream; - int* buf; // buffer - int size; // size of buffer - int start; // position of the first symbol in buffer - int len; // count of characters in buffers -}; - -#endif -// end of file BufFileInput.h diff --git a/Tools/CodeTools/TianoTools/Pccts/h/DLG_stream_input.h b/Tools/CodeTools/TianoTools/Pccts/h/DLG_stream_input.h deleted file mode 100644 index d2147f5217..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/DLG_stream_input.h +++ /dev/null @@ -1,98 +0,0 @@ - -/************************************************************/ -/* */ -/* Predefined char stream: Input from (c++) stream. */ -/* */ -/* By Hubert Holin (Hubert.Holin@Bigfoot.com), 1998. */ -/* */ -/* This is completely free stuff, do whatever you want with */ -/* it (but then, I will take no responsability for whatever */ -/* may happen if you do either... caveat emptor!). */ -/* */ -/************************************************************/ - -#ifndef _DLG_STREAM_INPUT_H -#define _DLG_STREAM_INPUT_H - -#include "pccts_istream.h" - -PCCTS_NAMESPACE_STD - -#ifndef DLGX_H -#include "DLexerBase.h" -#endif - - -// NOTES: The semantics of the copy constructor -// and the affectation operator may be unwaranted... -// and the stream may not be reset. -// -// It would have been so much nicer for nextChar() -// to throw (of for the DLGInputStream to change status) -// upon hiting EOF than to return an "int"... - -template < - class E, - class T = ::std::char_traits - > -class DLG_stream_input : public DLGInputStream -{ -public: - - DLG_stream_input(::std::basic_istream * p_input_stream) - : input(p_input_stream) - { - // nothing to do! - }; - - DLG_stream_input(const DLG_stream_input & a_recopier) - : input(a_recopier.input) - { - // nothing to do! - }; - - virtual ~DLG_stream_input() - { - this->purge(); // bloody templarized lookup... - }; - - DLG_stream_input operator = (const DLG_stream_input & a_affecter) - { - if (this != &a_affecter) - { - input = a_affecter.input; - } - - return(*this); - }; - - virtual int nextChar() - { - E extracted_stuff; - - input->get(extracted_stuff); - - if (*input) - { - return(int(extracted_stuff)); - } - else - { - return(EOF); - } - }; - -protected: - - ::std::basic_istream * input; - -private: - - void purge() - { - // nothing to do! - }; -}; - -#endif /* _DLG_STREAM_INPUT_H */ - diff --git a/Tools/CodeTools/TianoTools/Pccts/h/DLexer.h b/Tools/CodeTools/TianoTools/Pccts/h/DLexer.h deleted file mode 100644 index 37cac24f14..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/DLexer.h +++ /dev/null @@ -1,191 +0,0 @@ -/* DLexer.h (formerly DLexer.cpp) - * - * This was renamed because the use of the .cpp extension caused problems - * with IDEs. - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -#define ZZINC {if ( track_columns ) (++_endcol);} - -#define ZZGETC {ch = input->nextChar(); cl = ZZSHIFT(ch);} - -#define ZZNEWSTATE (newstate = dfa[state][cl]) - -#ifndef ZZCOPY -#define ZZCOPY \ - /* Truncate matching buffer to size (not an error) */ \ - if (nextpos < lastpos){ \ - *(nextpos++) = ch; \ - }else{ \ - bufovf = 1; \ - } -#endif - -void DLGLexer:: -mode( int m ) -{ - /* points to base of dfa table */ - if (m*actions[accepts[state]])(); - -// MR1 -// MR1 11-Apr-97 Help for tracking DLG results -// MR1 - -#ifdef DEBUG_LEXER - -/* MR1 */ if (debugLexerFlag) { -/* MR1 */ if (parser != NULL) { -/* MR1 */ /* MR23 */ printMessage(stdout, "\ntoken name=%s",parser->parserTokenName(tk)); -/* MR1 */ } else { -/* MR1 */ /* MR23 */ printMessage(stdout, "\ntoken nnumber=%d",tk); -/* MR1 */ }; -/* MR1 */ /* MR23 */ printMessage(stdout, " lextext=(%s) mode=%d", -/* MR1 */ (_lextext[0]=='\n' && _lextext[1]==0) ? -/* MR1 */ "newline" : _lextext, -/* MR1 */ automaton); -/* MR1 */ if (interactive && !charfull) { -/* MR1 */ /* MR23 */ printMessage(stdout, " char=empty"); -/* MR1 */ } else { -/* MR1 */ if (ch=='\n') { -/* MR1 */ /* MR23 */ printMessage(stdout, " char=newline"); -/* MR1 */ } else { -/* MR1 */ /* MR23 */ printMessage(stdout, " char=(%c)",ch); -/* MR1 */ }; -/* MR1 */ }; -/* MR1 */ /* MR23 */ printMessage(stdout, " %s\n", -/* MR1 */ (add_erase==1 ? "skip()" : -/* MR1 */ add_erase==2 ? "more()" : -/* MR1 */ "")); -/* MR1 */ }; - -#endif - - switch (add_erase) { - case 1: goto skip; - case 2: goto more; - } - return tk; -} - -void DLGLexer:: -advance() -{ - if ( input==NULL ) err_in(); - ZZGETC; charfull = 1; ZZINC; -} diff --git a/Tools/CodeTools/TianoTools/Pccts/h/DLexerBase.cpp b/Tools/CodeTools/TianoTools/Pccts/h/DLexerBase.cpp deleted file mode 100644 index b218afc038..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/DLexerBase.cpp +++ /dev/null @@ -1,302 +0,0 @@ -/* DLGLexerBase.c - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -#include "pcctscfg.h" - -#include "pccts_stdio.h" -#include "pccts_stdlib.h" - -PCCTS_NAMESPACE_STD - -/* I have to put this here due to C++ limitation - * that you can't have a 'forward' decl for enums. - * I hate C++!!!!!!!!!!!!!!! - */ - -// MR1 -// MR1 10-Apr-97 133MR1 Prevent use of varying sizes for the -// MR1 ANTLRTokenType enum -// MR1 - -enum ANTLRTokenType { TER_HATES_CPP=0, ITS_UTTER_GARBAGE, // MR1 - WITH_SOME_GOOD_IDEAS=9999}; // MR1 - -#define ANTLR_SUPPORT_CODE - -#include "pcctscfg.h" -#include DLEXERBASE_H -#include APARSER_H // MR23 - -DLGLexerBase:: -DLGLexerBase(DLGInputStream *in, - unsigned bufsize, - int _interactive, - int _track_columns) -{ - this->_bufsize = bufsize; - this->_lextext = new DLGChar[_bufsize]; - if ( this->_lextext==NULL ) { - panic("text buffer is NULL"); - } - this->_begexpr = this->_endexpr = NULL; - this->ch = this->bufovf = 0; - this->nextpos = NULL; - this->cl = 0; - this->add_erase = 0; - this->input = in; - this->_begcol = 0; - this->_endcol = 0; - this->_line = 1; - this->charfull = 0; - this->automaton = 0; - this->token_to_fill = NULL; - this->interactive = _interactive; - this->track_columns = _track_columns; - this->debugLexerFlag = 0; // MR1 - this->parser = NULL; // MR1 - this->lexErrCount=0; // MR11 -} - -// MR19 THM - -void DLGLexerBase::reset() -{ - this->charfull = 0; - this->_begcol = 0; - this->_endcol = 0; - this->automaton = 0; - this->_line=1; - this->lexErrCount=0; -} - -void DLGLexerBase:: -setInputStream( DLGInputStream *in ) -{ - this->input = in; - _line = 1; - charfull = 0; -} - -/* saves dlg state, but not what feeds dlg (such as file position) */ -void DLGLexerBase:: -saveState(DLGState *state) -{ - state->input = input; - state->interactive = interactive; - state->track_columns = track_columns; - state->auto_num = automaton; - state->add_erase = add_erase; - state->lookc = ch; - state->char_full = charfull; - state->begcol = _begcol; - state->endcol = _endcol; - state->line = _line; - state->lextext = _lextext; - state->begexpr = _begexpr; - state->endexpr = _endexpr; - state->bufsize = _bufsize; - state->bufovf = bufovf; - state->nextpos = nextpos; - state->class_num = cl; - state->debugLexerFlag = debugLexerFlag; // MR1 - state->parser = parser; // MR1 -} - -void DLGLexerBase:: -restoreState(DLGState *state) -{ - input = state->input; - interactive = state->interactive; - track_columns = state->track_columns; - automaton = state->auto_num; - add_erase = state->add_erase; - ch = state->lookc; - charfull = state->char_full; - _begcol = state->begcol; - _endcol = state->endcol; - _line = state->line; - _lextext = state->lextext; - _begexpr = state->begexpr; - _endexpr = state->endexpr; - _bufsize = state->bufsize; - bufovf = state->bufovf; - nextpos = state->nextpos; - cl = state->class_num; - debugLexerFlag = state->debugLexerFlag; // MR1 - parser = state->parser; // MR1 -} - -/* erase what is currently in the buffer, and get a new reg. expr */ -void DLGLexerBase:: -skip() -{ - add_erase = 1; -} - -/* don't erase what is in the lextext buffer, add on to it */ -void DLGLexerBase:: -more() -{ - add_erase = 2; -} - -/* substitute c for the reg. expr last matched and is in the buffer */ -void DLGLexerBase:: -replchar(DLGChar c) -{ - /* can't allow overwriting null at end of string */ - if (_begexpr < &_lextext[_bufsize-1]){ - *_begexpr = c; - *(_begexpr+1) = '\0'; - } - _endexpr = _begexpr; - if (c != '\0') { - nextpos = _begexpr + 1; - } - else { - nextpos = _begexpr; /* MR30 Zero terminates string. */ - } -} - -/* replace the string s for the reg. expr last matched and in the buffer */ - -#ifdef _MSC_VER // MR23 -//Turn off "assignment within conditional expression" warning -#pragma warning(disable : 4706) -#endif -void DLGLexerBase:: -replstr(const DLGChar *s) /* MR20 const */ -{ - register DLGChar *l= &_lextext[_bufsize -1]; - - nextpos = _begexpr; - if (s){ - while ((nextpos <= l) && (*(nextpos++) = *(s++))){ - /* empty */ - } - /* correct for NULL at end of string */ - nextpos--; - } - if ((nextpos <= l) && (*(--s) == 0)){ - bufovf = 0; - }else{ - bufovf = 1; - } - *(nextpos) = '\0'; - _endexpr = nextpos - 1; -} -#ifdef _MSC_VER // MR23 -#pragma warning(default: 4706) -#endif - -void DLGLexerBase:: -errstd(const char *s) /* MR20 const */ -{ - lexErrCount++; /* MR11 */ - /* MR23 */ printMessage(stderr, - "%s near line %d (text was '%s')\n", - ((s == NULL) ? "Lexical error" : s), - _line,_lextext); -} - -int DLGLexerBase:: -err_in() -{ - /* MR23 */ printMessage(stderr,"No input stream, function, or string\n"); - /* return eof to get out gracefully */ - return EOF; -} - -ANTLRTokenType DLGLexerBase:: -erraction() -{ - errstd("invalid token"); - advance(); - skip(); - return (ANTLRTokenType) 0; // bogus, but satisfies compiler -} - -_ANTLRTokenPtr DLGLexerBase:: -getToken() -{ - if ( token_to_fill==NULL ) panic("NULL token_to_fill"); - ANTLRTokenType tt = nextTokenType(); - _ANTLRTokenPtr tk = token_to_fill->makeToken(tt, _lextext,_line); - return tk; -} - -void DLGLexerBase:: -panic(const char *msg) /* MR20 const */ -{ - if (parser) //MR23 - parser->panic(msg); //MR23 - else //MR23 - { - /* MR23 */ printMessage(stderr, "DLG panic: %s\n", msg); - // - // 7-Apr-97 133MR1 - // - exit(PCCTS_EXIT_FAILURE); // MR1 - } -} - -ANTLRParser * DLGLexerBase:: // MR1 -setParser(ANTLRParser *p) { // MR1 - ANTLRParser *oldValue=parser; // MR1 - parser=p; // MR1 - return oldValue; // MR1 -} // MR1 - // MR1 -ANTLRParser * DLGLexerBase:: // MR1 -getParser() { // MR1 - return parser; // MR1 -} // MR1 - // MR1 -int DLGLexerBase:: // MR1 -debugLexer(int newValue) { // MR1 - int oldValue=debugLexerFlag; // MR1 - debugLexerFlag=newValue; // MR1 - return oldValue; // MR1 -} // MR1 - -//MR23 -int DLGLexerBase::printMessage(FILE* pFile, const char* pFormat, ...) -{ - va_list marker; - va_start( marker, pFormat ); - - int iRet = 0; - if (parser) - parser->printMessageV(pFile, pFormat, marker); - else - iRet = vfprintf(pFile, pFormat, marker); - - va_end( marker ); - return iRet; -} diff --git a/Tools/CodeTools/TianoTools/Pccts/h/DLexerBase.h b/Tools/CodeTools/TianoTools/Pccts/h/DLexerBase.h deleted file mode 100644 index db6cc1890c..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/DLexerBase.h +++ /dev/null @@ -1,198 +0,0 @@ -/* DLGLexerBase.h - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -#ifndef DLGX_H -#define DLGX_H - -#include "pcctscfg.h" -#include "pccts_stdio.h" - -PCCTS_NAMESPACE_STD - -#include ATOKEN_H -#include ATOKENSTREAM_H - -class ANTLRParser; // MR1 - -/* must define what a char looks like; can make this a class too */ -typedef char DLGChar; - -/* Can have it as a class too: (ack this looks weird; is it right?) -class DllExportPCCTS DLGChar { -private: - int c; -public: - DLGChar(int ch) { c = ch; } - int atom() { return c; } -}; -*/ - -/* user must subclass this */ -class DllExportPCCTS DLGInputStream { -public: - virtual int nextChar() = 0; -}; - -/* Predefined char stream: Input from FILE */ -class DllExportPCCTS DLGFileInput : public DLGInputStream { -private: - int found_eof; - FILE *input; -public: - DLGFileInput(FILE *f) { input = f; found_eof = 0; } - int nextChar() { - int c; - if ( found_eof ) return EOF; - else { - c=getc(input); - if ( c==EOF ) found_eof = 1; - return c; - } - } - void DLGFileReset(FILE *f) {input=f; found_eof = 0; }; // MR11 -}; - -// MR9 Suggested by Bruce Guenter (bruceg@qcc.sk.ca) -// MR9 Make DLGStringInput const correct - -/* Predefined char stream: Input from string */ -class DllExportPCCTS DLGStringInput : public DLGInputStream { -private: - const DLGChar *input; // MR9 - const DLGChar *p; // MR9 -public: - DLGStringInput(const DLGChar *s) { input = s; p = &input[0];} // MR9 - int nextChar() - { - if (*p) return (int) (unsigned char) *p++; // MR14 - else return EOF; - } - - void DLGStringReset(const DLGChar *s) {input=s; p= &input[0]; }; // MR11 // MR16 -}; - -class DllExportPCCTS DLGState { -public: - DLGInputStream *input; - int interactive; - int track_columns; - int auto_num; - int add_erase; - int lookc; - int char_full; - int begcol, endcol; - int line; - DLGChar *lextext, *begexpr, *endexpr; - int bufsize; - int bufovf; - DLGChar *nextpos; - int class_num; - int debugLexerFlag; // MR1 - ANTLRParser *parser; // MR1 -}; - -/* user must subclass this */ -class DllExportPCCTS DLGLexerBase : public ANTLRTokenStream { -public: - virtual ANTLRTokenType erraction(); - -protected: - DLGInputStream *input; - int interactive; - int track_columns; - DLGChar *_lextext; /* text of most recently matched token */ - DLGChar *_begexpr; /* beginning of last reg expr recogn. */ - DLGChar *_endexpr; /* beginning of last reg expr recogn. */ - int _bufsize; /* number of characters in lextext */ - int _begcol; /* column that first character of token is in*/ - int _endcol; /* column that last character of token is in */ - int _line; /* line current token is on */ - int ch; /* character to determine next state */ - int bufovf; /* indicates that buffer too small for text */ - int charfull; - DLGChar *nextpos; /* points to next available position in lextext*/ - int cl; - int automaton; - int add_erase; - DLGChar ebuf[70]; - _ANTLRTokenPtr token_to_fill; - - int debugLexerFlag; // MR1 - ANTLRParser *parser; // MR1 -public: - virtual _ANTLRTokenPtr getToken(); // MR12 public - virtual void advance(void) = 0; - void skip(void); /* erase lextext, look for antoher token */ - void more(void); /* keep lextext, look for another token */ - void mode(int k); /* switch to automaton 'k' */ - void saveState(DLGState *); - void restoreState(DLGState *); - virtual ANTLRTokenType nextTokenType(void)=0;/* get next token */ - void replchar(DLGChar c); /* replace last recognized reg. expr. with - a character */ - void replstr(const DLGChar *s); /* replace last recognized reg. expr. with - a string */ /* MR20 const */ - virtual int err_in(); // MR1 - virtual void errstd(const char *); // MR1 MR20 const - int line() { return _line; } - void set_line(int newValue) { _line=newValue; }; // MR1 - virtual void newline() { _line++; } - DLGChar *lextext() { return _lextext; } - - int begcol() { return _begcol; } - int endcol() { return _endcol; } - void set_begcol(int a) { _begcol=a; } - void set_endcol(int a) { _endcol=a; } - DLGChar *begexpr() { return _begexpr; } - DLGChar *endexpr() { return _endexpr; } - int bufsize() { return _bufsize; } - - void setToken(ANTLRAbstractToken *t) { token_to_fill = t; } - - void setInputStream(DLGInputStream *); - DLGLexerBase(DLGInputStream *in, - unsigned bufsize=2000, - int interactive=0, - int track_columns=0); - void reset(); // MR19 - virtual ~DLGLexerBase() { delete [] _lextext; } - virtual void panic(const char *msg); // MR1 MR20 const - void trackColumns() { - track_columns = 1; - this->_begcol = 0; - this->_endcol = 0; - }; - virtual ANTLRParser *setParser(ANTLRParser *p); // MR1 - virtual ANTLRParser *getParser(); // MR1 - virtual int debugLexer(int value); // MR1 - int lexErrCount; // MR12 - virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23 -}; - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/PBlackBox.h b/Tools/CodeTools/TianoTools/Pccts/h/PBlackBox.h deleted file mode 100644 index d25b8d6939..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/PBlackBox.h +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef PBLACKBOX_H -#define PBLACKBOX_H - -/* - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -/* Completely rewritten by Chris Uzdavinis (chris@atdesk.com) for MR23 */ - -#include "pcctscfg.h" - -#include "pccts_iostream.h" - -PCCTS_NAMESPACE_STD - -// MR20 Added #include for "DLexerBase.h" - -#include "DLexerBase.h" - -// -// The default buffer size of the lexer is given by the -// second argument of the lexer's ctor. It is optional -// and defaults to 2000 -// - -template -class DllExportPCCTS ParserBlackBox { -private: - // no copy construction allowed - ParserBlackBox(ParserBlackBox const &); - - // no copy assignment allowed - ParserBlackBox & operator=(ParserBlackBox const &); - -protected: - DLGFileInput *in; - Lexer *scan; - _ANTLRTokenPtr tok; - ANTLRTokenBuffer *pipe; - Parser *_parser; - FILE *file; - int openByBlackBox; /* MR21 Don't close what we haven't opened */ -public: - - ParserBlackBox(FILE *f) - : in(0) - , scan(0) - , tok(0) - , pipe(0) - , _parser(0) - , file(0) - , openByBlackBox(0) - { - if (f == NULL) - { - cerr << "invalid file pointer\n"; - } - else - { - openByBlackBox = 0; /* MR21a */ - file = f; - in = new DLGFileInput(f); - scan = new Lexer(in); - pipe = new ANTLRTokenBuffer(scan); - tok = new Token; - scan->setToken(tok); - _parser = new Parser(pipe); - _parser->init(); - } - } - ParserBlackBox(char *fname) - : in(0) - , scan(0) - , tok(0) - , pipe(0) - , _parser(0) - , file(0) - , openByBlackBox(0) - { - FILE *f = fopen(fname, "r"); - if ( f==NULL ) { - openByBlackBox = 0; - cerr << "cannot open " << fname << "\n"; return; - } - else { - openByBlackBox = 1; - file = f; - in = new DLGFileInput(f); - scan = new Lexer(in); - pipe = new ANTLRTokenBuffer(scan); - tok = new Token; - scan->setToken(tok); - _parser = new Parser(pipe); - _parser->init(); - } - } - - ~ParserBlackBox() - { - delete in; delete scan; delete pipe; delete _parser; delete tok; - if (1 == openByBlackBox) { - fclose(file); - } - } - - Parser *parser() { return _parser; } - Lexer *getLexer() { return scan; } -}; - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/PCCTSAST.cpp b/Tools/CodeTools/TianoTools/Pccts/h/PCCTSAST.cpp deleted file mode 100644 index a8249cdac0..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/PCCTSAST.cpp +++ /dev/null @@ -1,684 +0,0 @@ -/* - * PCCTSAST.C - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to SORCERER -- SORCERER is in the public - * domain. An individual or company may do whatever they wish with - * source code distributed with SORCERER or the code generated by - * SORCERER, including the incorporation of SORCERER, or its output, into - * commerical software. - * - * We encourage users to develop software with SORCERER. However, we do - * ask that credit is given to us for developing SORCERER. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like SORCERER and have developed a nice tool with the - * output, please mention that you developed it using SORCERER. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * SORCERER 1.00B14 and ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * AHPCRC, University of Minnesota - * 1992-2000 - */ - -#define ANTLR_SUPPORT_CODE - -#include "pcctscfg.h" - -#include "PCCTSAST.h" -#include "pccts_stdarg.h" - -PCCTS_NAMESPACE_STD - -#include - -//#include "SList.h" - - /* String Scanning/Parsing Stuff */ - -const char *PCCTS_AST::scan_token_tbl[] = { /* MR20 const */ - "invalid", /* 0 */ - "LPAREN", /* 1 */ - "RPAREN", /* 2 */ - "PERCENT", /* 3 */ - "INT", /* 4 */ - "COLON", /* 5 */ - "POUND", /* 6 */ - "PERIOD", /* 7 */ -}; - -void PCCTS_AST:: -addChild(PCCTS_AST *t) -{ - if ( t==NULL ) return; - PCCTS_AST *s = down(); - if ( s!=NULL ) - { - while ( s->right()!=NULL ) s = s->right(); - s->setRight(t); - } - else - this->setDown(t); -} - -void PCCTS_AST:: -lisp(FILE *f) -{ - if ( down() != NULL ) /* MR23 */ printMessage(f," ("); - lisp_action(f); - if ( down()!=NULL ) down()->lisp(f); - if ( down() != NULL ) /* MR23 */ printMessage(f," )"); - if ( right()!=NULL ) right()->lisp(f); -} - -/* build a tree (root child1 child2 ... NULL) - * If root is NULL, simply make the children siblings and return ptr - * to 1st sibling (child1). If root is not single node, return NULL. - * - * Siblings that are actually sibling lists themselves are handled - * correctly. For example #( NULL, #( NULL, A, B, C), D) results - * in the tree ( NULL A B C D ). - * - * Requires at least two parameters with the last one being NULL. If - * both are NULL, return NULL. - * - * The down() and right() down/right pointers are used to make the tree. - */ -PCCTS_AST *PCCTS_AST:: -make(PCCTS_AST *rt, ...) -{ - va_list ap; - register PCCTS_AST *child, *sibling=NULL, *tail=NULL /*MR23*/, *w; - PCCTS_AST *root; - - va_start(ap, rt); - root = rt; - - if ( root != NULL ) - if ( root->down() != NULL ) return NULL; - child = va_arg(ap, PCCTS_AST *); - while ( child != NULL ) - { - /* find end of child */ - for (w=child; w->right()!=NULL; w=w->right()) {;} - if ( sibling == NULL ) {sibling = child; tail = w;} - else {tail->setRight(child); tail = w;} - child = va_arg(ap, PCCTS_AST *); - } - if ( root==NULL ) root = sibling; - else root->setDown(sibling); - va_end(ap); - return root; -} - -/* The following push and pop routines are only used by ast_find_all() */ - -void PCCTS_AST:: -_push(PCCTS_AST **st, int *sp, PCCTS_AST *e) -{ - (*sp)--; - require((*sp)>=0, "stack overflow"); - st[(*sp)] = e; -} - -PCCTS_AST *PCCTS_AST:: -_pop(PCCTS_AST **st, int *sp) -{ - PCCTS_AST *e = st[*sp]; - (*sp)++; - require((*sp)<=MaxTreeStackDepth, "stack underflow"); - return e; -} - -/* Find all occurrences of u in t. - * 'cursor' must be initialized to 't'. It eventually - * returns NULL when no more occurrences of 'u' are found. - */ -PCCTS_AST *PCCTS_AST:: -ast_find_all(PCCTS_AST *u, PCCTS_AST **cursor) -{ - PCCTS_AST *sib; - /*** static ***/ PCCTS_AST *template_stack[MaxTreeStackDepth]; /* MR23 Remove "static" */ - /*** static ***/ int tsp = MaxTreeStackDepth; /* MR23 Remove "static" */ - -////static int nesting = 0; /* MR23 Not referenced */ - - if ( *cursor == NULL ) return NULL; - if ( *cursor!=this ) sib = *cursor; - else { - /* else, first time--start at top of template 't' */ - tsp = MaxTreeStackDepth; - sib = this; - /* bottom of stack is always a NULL--"cookie" indicates "done" */ - _push(template_stack, &tsp, NULL); - } - -keep_looking: - if ( sib==NULL ) /* hit end of sibling list */ - { - sib = _pop(template_stack, &tsp); - if ( sib == NULL ) { *cursor = NULL; return NULL; } - } - - if ( sib->type() != u->type() ) - { - /* look for another match */ - if ( sib->down()!=NULL ) - { - if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right()); - sib=sib->down(); - goto keep_looking; - } - /* nothing below to try, try next sibling */ - sib=sib->right(); - goto keep_looking; - } - - /* found a matching root node, try to match what's below */ - if ( match_partial(sib, u) ) - { - /* record sibling cursor so we can pick up next from there */ - if ( sib->down()!=NULL ) - { - if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right()); - *cursor = sib->down(); - } - else if ( sib->right()!=NULL ) *cursor = sib->right(); - else *cursor = _pop(template_stack, &tsp); - return sib; - } - - /* no match, keep searching */ - if ( sib->down()!=NULL ) - { - if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right()); - sib=sib->down(); - } - else sib = sib->right(); /* else, try to right if zip below */ - goto keep_looking; -} - -/* are two trees exactly alike? */ -int PCCTS_AST:: -match(PCCTS_AST *u) -{ - PCCTS_AST *t = this; - PCCTS_AST *sib; - - if ( u==NULL ) return 0; - - for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right()) - { - if ( sib->type() != u->type() ) return 0; - if ( sib->down()!=NULL ) - if ( !sib->down()->match(u->down()) ) return 0; - } - return 1; -} - -/* Is 'u' a subtree of 't' beginning at the root? */ -int PCCTS_AST:: -match_partial(PCCTS_AST *t, PCCTS_AST *u) -{ - PCCTS_AST *sib; - - if ( u==NULL ) return 1; - if ( t==NULL ) return 0; /* MR23 removed unreachable code */ - - for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right()) - { - if ( sib->type() != u->type() ) return 0; - if ( sib->down()!=NULL ) - if ( !match_partial(sib->down(), u->down()) ) return 0; - } - return 1; -} - -#ifdef _MSC_VER // MR23 -//Turn off "unreachable code" warning -#pragma warning(disable : 4702) -#endif -/* Walk the template tree 't' (matching against 'this'), filling in the - * 'labels' array, and setting 'n' according to how many labels were matched. - */ -int PCCTS_AST:: -scanmatch(ScanAST *t, PCCTS_AST **labels[], int *n) -{ - ScanAST *sib; - PCCTS_AST *u = this; - - if ( u==NULL ) return 0; - - for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right()) - { - /* make sure tokens match; token of '0' means wildcard match */ - if ( sib->type() != u->type() && sib->type()!=0 ) return 0; - /* we have a matched token here; set label pointers if exists */ - if ( sib->label_num>0 ) - { - require(labels!=NULL, "label found in template, but no array of labels"); - (*n)++; - *(labels[sib->label_num-1]) = u; - } - /* match what's below if something there and current node is not wildcard */ - if ( sib->down()!=NULL && sib->type()!=0 ) - { - if ( sib->down()==NULL ) - { - if ( u->down()!=NULL ) - return 0; - else - return 1; - } - if ( !u->down()->scanmatch(sib->down(), labels, n) ) return 0; - } - } - return 1; -} -#ifdef _MSC_VER // MR23 -#pragma warning(default : 4702) -#endif - -void PCCTS_AST:: -insert_after(PCCTS_AST *b) -{ - PCCTS_AST *end; - if ( b==NULL ) return; - /* find end of b's child list */ - for (end=b; end->right()!=NULL; end=end->right()) {;} - end->setRight(this->right()); - this->setRight(b); -} - -void PCCTS_AST:: -append(PCCTS_AST *b) -{ - PCCTS_AST *end; - require(b!=NULL, "append: NULL input tree"); - /* find end of child list */ - for (end=this; end->right()!=NULL; end=end->right()) {;} - end->setRight(b); -} - -PCCTS_AST *PCCTS_AST:: -tail() -{ - PCCTS_AST *end; - /* find end of child list */ - for (end=this; end->right()!=NULL; end=end->right()) {;} - return end; -} - -PCCTS_AST *PCCTS_AST:: -bottom() -{ - PCCTS_AST *end; - /* find end of child list */ - for (end=this; end->down()!=NULL; end=end->down()) {;} - return end; -} - -PCCTS_AST *PCCTS_AST:: -cut_between(PCCTS_AST *a, PCCTS_AST *b) -{ - PCCTS_AST *end, *ret; - if (a==NULL||b==NULL) return NULL; - /* find node pointing to b */ - for (end=a; end->right()!=NULL&&end->right()!=b; end=end->right()) - {;} - if (end->right()==NULL) return NULL; //ast_cut_between: a,b not connected - end->setRight(NULL); /* don't want it point to 'b' anymore */ - ret = a->right(); - a->setRight(b); - return ret; -} - -#ifdef NOT_YET -SList *PCCTS_AST:: -to_slist() -{ - SList *list = new SList; - PCCTS_AST *p; - - for (p=this; p!=NULL; p=p->right()) - { - list->add(p); - } - return list; -} -#endif - -void PCCTS_AST:: -tfree() -{ - PCCTS_AST *t = this; - if ( t->down()!=NULL ) t->down()->tfree(); - if ( t->right()!=NULL ) t->right()->tfree(); - delete t; -} - -int PCCTS_AST:: -nsiblings() -{ - PCCTS_AST *t = this; - int n=0; - - while ( t!=NULL ) - { - n++; - t = t->right(); - } - return n; -} - -PCCTS_AST *PCCTS_AST:: -sibling_index(int i) -{ - PCCTS_AST *t = this; - int j=1; - require(i>0, "sibling_index: i<=0"); - - while ( t!=NULL ) - { - if ( j==i ) return t; - j++; - t = t->right(); - } - return NULL; -} - -/* Assume this is a root node of a tree-- - * duplicate that node and what's below; ignore siblings of root node. - */ - -// MR9 23-Sep-97 RJV -// MR9 -// MR9 RJV: Original version only duplicated the node and down elements. -// MR9 Made copies of the pointers to sibling. -// MR9 Changed call "down()->deepCopy()" to "down()->deepCopyBushy()" -// MR9 - -PCCTS_AST *PCCTS_AST:: -deepCopy() -{ - PCCTS_AST *u = this->shallowCopy(); - if ( down()!=NULL ) u->setDown(down()->deepCopyBushy()); - u->setRight(NULL); - return u; -} - -/* Copy all nodes including siblings of root. */ -PCCTS_AST *PCCTS_AST:: -deepCopyBushy() -{ - PCCTS_AST *u = this->shallowCopy(); - /* copy the rest of the tree */ - if ( down()!=NULL ) u->setDown(down()->deepCopyBushy()); - if ( right()!=NULL ) u->setRight(right()->deepCopyBushy()); - return u; -} - -void PCCTS_AST:: -scanast_free(ScanAST *t) -{ - if ( t == NULL ) return; - scanast_free( t->down() ); - scanast_free( t->right() ); - free( (char *) t ); // MR1 -} - -/* - * scan - * - * This function is like scanf(): it attempts to match a template - * against an input tree. A variable number of tree pointers - * may be set according to the '%i' labels in the template string. - * For example: - * - * t->ast_scan("#( 6 #(5 %1:4 %2:3) #(1 %3:3 %4:3) )", - * &w, &x, &y, &z); - * - * Naturally, you'd want this converted from - * - * t->ast_scan("#( RangeOp #(Minus %1:IConst %2:Var) #(Plus %3:Var %4Var) )", - * &w, &x, &y, &z); - * - * by SORCERER. - * - * This function call must be done withing a SORCERER file because SORCERER - * must convert the token references to the associated token number. - * - * This functions parses the template and creates trees which are then - * matched against the input tree. The labels are set as they are - * encountered; hence, partial matches may leave some pointers set - * and some NULL. This routines initializes all argument pointers to NULL - * at the beginning. - * - * This function returns the number of labels matched. - */ -int PCCTS_AST:: -ast_scan(char *templ, ...) -{ - va_list ap; - ScanAST *tmpl; - int n, i, found=0; - PCCTS_AST ***label_ptrs=NULL; - - va_start(ap, templ); - - /* make a ScanAST tree out of the template */ - tmpl = stringparser_parse_scanast(templ, &n); - - /* make an array out of the labels */ - if ( n>0 ) - { - label_ptrs = (PCCTS_AST ***) calloc(n, sizeof(PCCTS_AST **)); - require(label_ptrs!=NULL, "scan: out of memory"); - for (i=1; i<=n; i++) - { - label_ptrs[i-1] = va_arg(ap, PCCTS_AST **); - *(label_ptrs[i-1]) = NULL; - } - } - - /* match the input tree against the template */ - scanmatch(tmpl, label_ptrs, &found); - - scanast_free(tmpl); - free( (char *) label_ptrs); // MR1 - - return found; -} - -ScanAST *PCCTS_AST:: -new_scanast(int tok) -{ - ScanAST *p = (ScanAST *) calloc(1, sizeof(ScanAST)); -// -// 7-Apr-97 133MR1 -// - if ( p == NULL ) - panic("out of memory\n"); // MR23 - p->_token = tok; - return p; -} - -ScanAST *PCCTS_AST:: -stringparser_parse_scanast(char *templ, int *num_labels) -{ - StringLexer lex; - StringParser parser; - ScanAST *t; - - stringlexer_init(&lex, templ); - stringparser_init(&parser, &lex); - t = stringparser_parse_tree(&parser); - *num_labels = parser.num_labels; - return t; -} - -void PCCTS_AST:: -stringparser_match(StringParser *parser, int token) -{ - if ( parser->token != token ) panic("bad tree in scan()"); -} - -/* - * Match a tree of the form: - * (root child1 child2 ... childn) - * or, - * node - * - * where the elements are integers or labeled integers. - */ -ScanAST *PCCTS_AST:: -stringparser_parse_tree(StringParser *parser) -{ - ScanAST *t=NULL, *root, *child, *last=NULL /*MR23*/; - - if ( parser->token != __POUND ) - { - return stringparser_parse_element(parser); - } - stringparser_match(parser,__POUND); - parser->token = stringscan_gettok(parser->lexer); - stringparser_match(parser,__LPAREN); - parser->token = stringscan_gettok(parser->lexer); - root = stringparser_parse_element(parser); - while ( parser->token != __RPAREN ) - { - child = stringparser_parse_element(parser); - if ( t==NULL ) { t = child; last = t; } - else { last->_right = child; last = child; } - } - stringparser_match(parser,__RPAREN); - parser->token = stringscan_gettok(parser->lexer); - root->_down = t; - return root; -} - -ScanAST *PCCTS_AST:: -stringparser_parse_element(StringParser *parser) -{ - char ebuf[100]; - int label = 0; - - if ( parser->token == __POUND ) - { - return stringparser_parse_tree(parser); - } - if ( parser->token == __PERCENT ) - { - parser->token = stringscan_gettok(parser->lexer); - stringparser_match(parser,__INT); - label = atoi(parser->lexer->text); - parser->num_labels++; - if ( label==0 ) panic("%%0 is an invalid label"); - parser->token = stringscan_gettok(parser->lexer); - stringparser_match(parser,__COLON); - parser->token = stringscan_gettok(parser->lexer); - /* can label tokens and wildcards */ - if ( parser->token != __INT && parser->token != __PERIOD ) - panic("can only label tokens"); - } - if ( parser->token == __INT ) - { - ScanAST *p = new_scanast(atoi(parser->lexer->text)); - parser->token = stringscan_gettok(parser->lexer); - p->label_num = label; - return p; - } - if ( parser->token == __PERIOD ) - { - ScanAST *p = new_scanast(0); /* token of 0 is wildcard */ - parser->token = stringscan_gettok(parser->lexer); - p->label_num = label; - return p; - } - sprintf(ebuf, "mismatch token in scan(): %s", scan_token_str(parser->token)); - panic(ebuf); - return NULL; -} - -void PCCTS_AST:: -stringparser_init(StringParser *parser, StringLexer *input) -{ - parser->lexer = input; - parser->token = stringscan_gettok(parser->lexer); - parser->num_labels = 0; -} - -void PCCTS_AST:: -stringlexer_init(StringLexer *scanner, char *input) -{ - scanner->text[0]='\0'; - scanner->input = input; - scanner->p = input; - stringscan_advance(scanner); -} - -void PCCTS_AST:: -stringscan_advance(StringLexer *scanner) -{ - if ( *(scanner->p) == '\0' ) scanner->c = __StringScanEOF; - scanner->c = *(scanner->p)++; -} - -int PCCTS_AST:: -stringscan_gettok(StringLexer *scanner) -{ - char *index = &scanner->text[0]; - char ebuf[100]; /* MR23 Remove static */ - - while ( isspace(scanner->c) ) { stringscan_advance(scanner); } - if ( isdigit(scanner->c) ) - { - int tok = __INT; - while ( isdigit(scanner->c) ) { - *index++ = (char) /* static_cast */ (scanner->c); // MR23 - stringscan_advance(scanner); - } - *index = '\0'; - return tok; - } - switch ( scanner->c ) - { - case '#' : stringscan_advance(scanner); return __POUND; - case '(' : stringscan_advance(scanner); return __LPAREN; - case ')' : stringscan_advance(scanner); return __RPAREN; - case '%' : stringscan_advance(scanner); return __PERCENT; - case ':' : stringscan_advance(scanner); return __COLON; - case '.' : stringscan_advance(scanner); return __PERIOD; - case '\0' : return __StringScanEOF; - case __StringScanEOF : return __StringScanEOF; - default : - sprintf(ebuf, "invalid char in scan: '%c'", scanner->c); - panic(ebuf); - } - return __StringScanEOF; // never reached -} - -const char *PCCTS_AST:: /* MR20 const */ -scan_token_str(int t) -{ - if ( VALID_SCAN_TOKEN(t) ) return scan_token_tbl[t]; - else if ( t==__StringScanEOF ) return ""; - else return ""; -} - -//MR23 -int PCCTS_AST::printMessage(FILE* pFile, const char* pFormat, ...) -{ - va_list marker; - va_start( marker, pFormat ); - int iRet = vfprintf(pFile, pFormat, marker); - va_end( marker ); - return iRet; -} diff --git a/Tools/CodeTools/TianoTools/Pccts/h/PCCTSAST.h b/Tools/CodeTools/TianoTools/Pccts/h/PCCTSAST.h deleted file mode 100644 index 3485da7d1b..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/PCCTSAST.h +++ /dev/null @@ -1,143 +0,0 @@ -/* Abstract syntax tree - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -#ifndef PCCTSAST_H -#define PCCTSAST_H - -#include "pcctscfg.h" - -#include "pccts_stdio.h" -#include "pccts_stdlib.h" - -PCCTS_NAMESPACE_STD - -//class SList; - -#define StringScanMaxText 50 -#define MaxTreeStackDepth 400 - -// -// 7-Apr-97 133MR1 signed int not accepted by AT&T cfront -// -typedef struct stringlexer { - int c; // MR1 - char *input; - char *p; - char text[StringScanMaxText]; - } StringLexer; - -/* Define the structures needed for ast_scan() */ -typedef struct stringparser { - int token; - StringLexer *lexer; - int num_labels; - } StringParser; - -typedef struct _scanast { - struct _scanast *_right, *_down; - int _token; - int label_num; - int type() { return _token; } - struct _scanast *right() { return _right; } - struct _scanast *down() { return _down; } - } ScanAST; - -#define VALID_SCAN_TOKEN(t) (t>=__LPAREN && t<=__PERIOD) - -class DllExportPCCTS PCCTS_AST { -protected: - static const char *scan_token_tbl[]; /* MR20 const */ - enum { - __LPAREN=1, - __RPAREN=2, - __PERCENT=3, - __INT=4, - __COLON=5, - __POUND=6, - __PERIOD=7, - __StringScanEOF=-1}; - -protected: - const char *scan_token_str(int t); /* MR20 const */ - void stringlexer_init(StringLexer *scanner, char *input); - void stringparser_init(StringParser *, StringLexer *); - ScanAST *stringparser_parse_scanast(char *templ, int *n); - ScanAST *stringparser_parse_tree(StringParser *parser); - ScanAST *stringparser_parse_element(StringParser *parser); - void stringscan_advance(StringLexer *scanner); - int stringscan_gettok(StringLexer *scanner); - void _push(PCCTS_AST **st, int *sp, PCCTS_AST *e); - PCCTS_AST *_pop(PCCTS_AST **st, int *sp); - int match_partial(PCCTS_AST *t, PCCTS_AST *u); - int scanmatch(ScanAST *t, PCCTS_AST **labels[], int *n); - void scanast_free(ScanAST *t); - ScanAST *new_scanast(int tok); - void stringparser_match(StringParser *parser, int type); - virtual PCCTS_AST *deepCopyBushy(); - -public: - PCCTS_AST() {;} - virtual ~PCCTS_AST() {;} - - /* This group must be defined for SORCERER to work correctly */ - virtual PCCTS_AST *right() = 0; - virtual PCCTS_AST *down() = 0; - virtual void setRight(PCCTS_AST *t) = 0; - virtual void setDown(PCCTS_AST *t) = 0; -// we define these so ANTLR doesn't have to - virtual int type() { return 0; } - virtual void setType(int /*t MR23 */) {;} - virtual PCCTS_AST *shallowCopy() {panic("no shallowCopy() defined"); return NULL;} - - /* These are not needed by ANTLR, but are support functions */ - virtual PCCTS_AST *deepCopy(); // used by SORCERER in transform mode - virtual void addChild(PCCTS_AST *t); - virtual void lisp_action(FILE * /*f MR23 */) {;} - virtual void lisp(FILE *f); - static PCCTS_AST *make(PCCTS_AST *rt, ...); - virtual PCCTS_AST *ast_find_all(PCCTS_AST *u, PCCTS_AST **cursor); - virtual int match(PCCTS_AST *u); - virtual void insert_after(PCCTS_AST *b); - virtual void append(PCCTS_AST *b); - virtual PCCTS_AST *tail(); - virtual PCCTS_AST *bottom(); - static PCCTS_AST *cut_between(PCCTS_AST *a, PCCTS_AST *b); -// virtual SList *to_slist(); - virtual void tfree(); - int ast_scan(char *templ, ...); - virtual int nsiblings(); - virtual PCCTS_AST *sibling_index(int i); - - void require(int e,const char *err){ if ( !e ) panic(err); } /* MR20 const */ - virtual void panic(const char *err) // MR20 const - { /* MR23 */ printMessage(stderr, "PCCTS_AST: %s\n", err); exit(PCCTS_EXIT_FAILURE); } - virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23 -}; - -#endif /* PCCTSAST_H */ diff --git a/Tools/CodeTools/TianoTools/Pccts/h/SList.h b/Tools/CodeTools/TianoTools/Pccts/h/SList.h deleted file mode 100644 index 5b8bf97427..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/SList.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef SList_h -#define SList_h - -/* - * SList.h - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to SORCERER -- SORCERER is in the public - * domain. An individual or company may do whatever they wish with - * source code distributed with SORCERER or the code generated by - * SORCERER, including the incorporation of SORCERER, or its output, into - * commerical software. - * - * We encourage users to develop software with SORCERER. However, we do - * ask that credit is given to us for developing SORCERER. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like SORCERER and have developed a nice tool with the - * output, please mention that you developed it using SORCERER. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * PCCTS 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1992-2000 - */ - -#include "pcctscfg.h" - -#include "pccts_stdio.h" -#include "pccts_stdlib.h" - -PCCTS_NAMESPACE_STD - -#include "PCCTSAST.h" - -class PCCTS_AST; - -class SListNode { -protected: - void *_elem; /* pointer to any kind of element */ - SListNode *_next; -public: - SListNode() {_elem=_next=NULL;} - virtual ~SListNode() {_elem=_next=NULL;} - void *elem() { return _elem; } - void setElem(void *e) { _elem = e; } - void setNext(SListNode *t) { _next = t; } - SListNode *next() { return _next; } -}; - -class SList { - SListNode *head, *tail; -public: - SList() {head=tail=NULL;} - virtual ~SList() {head=tail=NULL;} - virtual void *iterate(SListNode **); - virtual void add(void *e); - virtual void lfree(); - virtual PCCTS_AST *to_ast(SList list); - virtual void require(int e,char *err){ if ( !e ) panic(err); } - virtual void panic(char *err){ /* MR23 */ printMessage(stderr, "SList panic: %s\n", err); exit(PCCTS_EXIT_FAILURE); } - virtual int printMessage(FILE* pFile, const char* pFormat, ...); // MR23 -}; - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/antlr.h b/Tools/CodeTools/TianoTools/Pccts/h/antlr.h deleted file mode 100644 index 80664535d3..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/antlr.h +++ /dev/null @@ -1,807 +0,0 @@ -/* antlr.h - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -#ifndef ANTLR_H -#define ANTLR_H - -#include "pcctscfg.h" - -#include "pccts_stdio.h" - -/* turn off warnings for unreferenced labels */ - -#ifdef _MSC_VER -#pragma warning(disable:4102) -#endif - -/* - * Define all of the stack setup and manipulation of $i, #i variables. - * - * Notes: - * The type 'Attrib' must be defined before entry into this .h file. - */ - - -#ifdef __USE_PROTOS -#include "pccts_stdlib.h" -#else -#ifdef VAXC -#include -#else -#include -#endif -#endif -#include "pccts_string.h" - -#if 0 -#include "set.h" -#endif - - -typedef int ANTLRTokenType; -typedef unsigned char SetWordType; - -typedef char ANTLRChar; - - /* G u e s s S t u f f */ - -#ifdef ZZCAN_GUESS -#ifndef ZZINF_LOOK -#define ZZINF_LOOK -#endif -#endif - -#ifdef ZZCAN_GUESS -typedef struct _zzjmp_buf { - jmp_buf state; - } zzjmp_buf; -#endif - - -/* can make this a power of 2 for more efficient lookup */ - -#ifndef ZZLEXBUFSIZE -#define ZZLEXBUFSIZE 8000 /* MR22 raise from 2k to 8k */ -#endif - -#define zzOvfChk \ - if ( zzasp <= 0 ) \ - { \ - fprintf(stderr, zzStackOvfMsg, __FILE__, __LINE__); \ - exit(PCCTS_EXIT_FAILURE); \ - } - -#ifndef ZZA_STACKSIZE -#define ZZA_STACKSIZE 400 -#endif -#ifndef ZZAST_STACKSIZE -#define ZZAST_STACKSIZE 400 -#endif - -#ifndef zzfailed_pred -#ifdef ZZCAN_GUESS -#define zzfailed_pred(_p,_hasuseraction,_useraction) \ - if (zzguessing) { \ - zzGUESS_FAIL; \ - } else { \ - zzfailed_pred_action(_p,_hasuseraction,_useraction); \ - } -#else -#define zzfailed_pred(_p,_hasuseraction,_useraction) \ - zzfailed_pred_action(_p,_hasuseraction,_useraction); -#endif -#endif - -/* MR23 Provide more control over failed predicate action - without any need for user to worry about guessing internals. - _hasuseraction == 0 => no user specified error action - _hasuseraction == 1 => user specified error action -*/ - -#ifndef zzfailed_pred_action -#define zzfailed_pred_action(_p,_hasuseraction,_useraction) \ - if (_hasuseraction) { _useraction } \ - else { fprintf(stderr, "semantic error; failed predicate: '%s'\n",_p); } -#endif - -/* MR19 zzchar_t additions */ - -#ifdef LL_K -#define LOOKAHEAD \ - int zztokenLA[LL_K]; \ - zzchar_t zztextLA[LL_K][ZZLEXBUFSIZE]; \ - int zzlap = 0, zzlabase=0; /* labase only used for DEMAND_LOOK */ -#else -#define LOOKAHEAD \ - int zztoken; -#endif - -#ifndef zzcr_ast -#define zzcr_ast(ast,attr,tok,text) -#endif - -#ifdef DEMAND_LOOK -#define DemandLookData int zzdirty=1; -#else -#define DemandLookData -#endif - -#ifndef zzUSER_GUESS_HOOK -#define zzUSER_GUESS_HOOK(seqFrozen,zzrv) -#endif - -#ifndef zzUSER_GUESS_DONE_HOOK -#define zzUSER_GUESS_DONE_HOOK(seqFrozen) -#endif - - /* S t a t e S t u f f */ - -#ifdef ZZCAN_GUESS -#define zzGUESS_BLOCK zzantlr_state zzst; int zzrv; int zzGuessSeqFrozen; - -/* MR10 change zzGUESS: do zzGUESS_DONE when zzrv==1 after longjmp as in C++ mode */ - -#define zzGUESS zzsave_antlr_state(&zzst); \ - zzguessing = 1; \ - zzGuessSeqFrozen=++zzGuessSeq; \ - zzrv = setjmp(zzguess_start.state); \ - zzUSER_GUESS_HOOK(zzGuessSeqFrozen,zzrv) \ - if (zzrv) zzGUESS_DONE; -#ifdef zzTRACE_RULES -#define zzGUESS_FAIL { zzTraceGuessFail(); longjmp(zzguess_start.state, 1); } -#else -#define zzGUESS_FAIL longjmp(zzguess_start.state, 1) -#endif - -/* MR10 change zzGUESS_DONE: zzrv=1 to simulate longjmp() return value as in C++ mode */ - -#define zzGUESS_DONE { zzrestore_antlr_state(&zzst); zzrv=1; zzUSER_GUESS_DONE_HOOK(zzGuessSeqFrozen) } -#define zzNON_GUESS_MODE if ( !zzguessing ) -#define zzGuessData \ - zzjmp_buf zzguess_start; \ - int zzguessing; -#else -#define zzGUESS_BLOCK -#define zzGUESS -#define zzGUESS_FAIL -#define zzGUESS_DONE -#define zzNON_GUESS_MODE -#define zzGuessData -#endif - -typedef struct _zzantlr_state { -#ifdef ZZCAN_GUESS - zzjmp_buf guess_start; - int guessing; -#endif - int asp; - int ast_sp; -#ifdef ZZINF_LOOK - int inf_lap; /* not sure we need to save this one */ - int inf_labase; - int inf_last; - -/* MR6 Gunnar Rxnning (gunnar@candleweb.no) */ -/* MR6 Additional state needs to be saved/restored */ -/* MR6 Matching changes in err.h */ - - int *inf_tokens; /* MR6 */ - char **inf_text; /* MR6 */ - char *inf_text_buffer; /* MR6 */ - int *inf_line; /* MR6 */ -#endif -#ifdef DEMAND_LOOK - int dirty; -#endif - -#ifdef LL_K - int tokenLA[LL_K]; - char textLA[LL_K][ZZLEXBUFSIZE]; - int lap; - int labase; -#else - int token; - char text[ZZLEXBUFSIZE]; -#endif -#ifdef zzTRACE_RULES - int traceOptionValue; /* MR10 */ - int traceGuessOptionValue; /* MR10 */ - char *traceCurrentRuleName; /* MR10 */ - int traceDepth; /* MR10 */ -#endif - - } zzantlr_state; - -#ifdef zzTRACE_RULES -extern int zzTraceOptionValueDefault; -extern int zzTraceOptionValue; -extern int zzTraceGuessOptionValue; -extern char *zzTraceCurrentRuleName; -extern int zzTraceDepth; -#endif - -extern int zzGuessSeq; /* MR10 */ -extern int zzSyntaxErrCount; /* MR11 */ -extern int zzLexErrCount; /* MR11 */ - - /* I n f i n i t e L o o k a h e a d */ - - -#ifdef ZZINF_LOOK -#define InfLookData \ - int *zzinf_tokens; \ - char **zzinf_text; \ - char *zzinf_text_buffer; \ - int *zzinf_line; \ - int zzinf_labase; \ - int zzinf_last; -#else -#define InfLookData -#endif - -#ifdef ZZINF_LOOK - -#ifndef ZZINF_DEF_TEXT_BUFFER_SIZE -#define ZZINF_DEF_TEXT_BUFFER_SIZE 20000 -#endif -#ifndef ZZINF_DEF_TOKEN_BUFFER_SIZE -#define ZZINF_DEF_TOKEN_BUFFER_SIZE 2000 -#endif -/* WARNING!!!!!! - * ZZINF_BUFFER_TEXT_CHUNK_SIZE must be > sizeof(text) largest possible token. - */ -#ifndef ZZINF_BUFFER_TEXT_CHUNK_SIZE -#define ZZINF_BUFFER_TEXT_CHUNK_SIZE 5000 -#endif -#ifndef ZZINF_BUFFER_TOKEN_CHUNK_SIZE -#define ZZINF_BUFFER_TOKEN_CHUNK_SIZE 1000 -#endif - -#if ZZLEXBUFSIZE > ZZINF_BUFFER_TEXT_CHUNK_SIZE -#define ZZINF_BUFFER_TEXT_CHUNK_SIZE ZZLEXBUFSIZE+5 -#endif - -/* make inf_look user-access macros */ -#ifdef LL_K -#define ZZINF_LA_VALID(i) (((zzinf_labase+i-1)-LL_K+1) <= zzinf_last) -#define ZZINF_LA(i) zzinf_tokens[(zzinf_labase+i-1)-LL_K+1] -#define ZZINF_LATEXT(i) zzinf_text[(zzinf_labase+i-1)-LL_K+1] -/* MR6 In 1.33 vanilla the #define ZZINF_LINE(i) is was commented out */ -#define ZZINF_LINE(i) zzinf_line[(zzinf_labase+i-1)-LL_K+1] -#else -#define ZZINF_LA_VALID(i) (((zzinf_labase+i-1)) <= zzinf_last) -#define ZZINF_LA(i) zzinf_tokens[(zzinf_labase+i-1)] -#define ZZINF_LATEXT(i) zzinf_text[(zzinf_labase+i-1)] -#endif - -#define inf_zzgettok _inf_zzgettok() -extern void _inf_zzgettok(); - -#endif /* ZZINF_LOOK */ - - -#ifdef LL_K - -#ifdef __USE_PROTOS -#define ANTLR_INFO \ - Attrib zzempty_attr(void) {static Attrib a; return a;} \ - Attrib zzconstr_attr(int _tok, char *_text) \ - {Attrib a; zzcr_attr((&a),_tok,_text); return a;} \ - int zzasp=ZZA_STACKSIZE; \ - char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n"; \ - Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData \ - InfLookData \ - zzGuessData -#else -#define ANTLR_INFO \ - Attrib zzempty_attr() {static Attrib a; return a;} \ - Attrib zzconstr_attr(_tok, _text) int _tok; char *_text; \ - {Attrib a; zzcr_attr((&a),_tok,_text); return a;} \ - int zzasp=ZZA_STACKSIZE; \ - char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n"; \ - Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData \ - InfLookData \ - zzGuessData -#endif - -#else - -#ifdef __USE_PROTOS -#define ANTLR_INFO \ - Attrib zzempty_attr(void) {static Attrib a; return a;} \ - Attrib zzconstr_attr(int _tok, char *_text) \ - {Attrib a; zzcr_attr((&a),_tok,_text); return a;} \ - int zzasp=ZZA_STACKSIZE; \ - char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n"; \ - Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData \ - InfLookData \ - zzGuessData -#else -#define ANTLR_INFO \ - Attrib zzempty_attr() {static Attrib a; return a;} \ - Attrib zzconstr_attr(_tok, _text) int _tok; char *_text; \ - {Attrib a; zzcr_attr((&a),_tok,_text); return a;} \ - int zzasp=ZZA_STACKSIZE; \ - char zzStackOvfMsg[]="fatal: attrib/AST stack overflow %s(%d)!\n"; \ - Attrib zzaStack[ZZA_STACKSIZE]; DemandLookData \ - InfLookData \ - zzGuessData -#endif - -#endif /* LL_k */ - - -#ifdef ZZINF_LOOK - -#ifdef LL_K -#ifdef DEMAND_LOOK -#define zzPrimeLookAhead {zzdirty=LL_K; zzlap = zzlabase = 0;} -#else -#define zzPrimeLookAhead {zzlap = zzlabase = 0; zzfill_inf_look();\ - {int _i; for(_i=1;_i<=LL_K; _i++) \ - {zzCONSUME;} zzlap = zzlabase = 0;}} -#endif - -#else /* LL_K */ - -#ifdef DEMAND_LOOK -#define zzPrimeLookAhead zzfill_inf_look(); zzdirty=1 -#else -#define zzPrimeLookAhead zzfill_inf_look(); inf_zzgettok - -#endif -#endif /* LL_K */ - -#else /* ZZINF_LOOK */ - -#ifdef LL_K -#ifdef DEMAND_LOOK -#define zzPrimeLookAhead {zzdirty=LL_K; zzlap = zzlabase = 0;} -#else -#define zzPrimeLookAhead {int _i; zzlap = 0; for(_i=1;_i<=LL_K; _i++) \ - {zzCONSUME;} zzlap = 0;} -#endif - -#else - -#ifdef DEMAND_LOOK -#define zzPrimeLookAhead zzdirty=1 -#else -#define zzPrimeLookAhead zzgettok() -#endif -#endif /* LL_K */ - -#endif /* ZZINF_LOOK */ - - -#ifdef LL_K -#define zzenterANTLRs(s) \ - zzlextext = &(zztextLA[0][0]); zzrdstr( s ); zzPrimeLookAhead; -#define zzenterANTLRf(f) \ - zzlextext = &(zztextLA[0][0]); zzrdfunc( f ); zzPrimeLookAhead; -#define zzenterANTLR(f) \ - zzlextext = &(zztextLA[0][0]); zzrdstream( f ); zzPrimeLookAhead; -#ifdef ZZINF_LOOK -#define zzleaveANTLR(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line); -#define zzleaveANTLRf(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line); -#define zzleaveANTLRs(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line); -#else -#define zzleaveANTLR(f) -#define zzleaveANTLRf(f) -#define zzleaveANTLRs(f) -#endif - -#else - -#define zzenterANTLRs(s) \ - {static char zztoktext[ZZLEXBUFSIZE]; \ - zzlextext = zztoktext; zzrdstr( s ); zzPrimeLookAhead;} -#define zzenterANTLRf(f) \ - {static char zztoktext[ZZLEXBUFSIZE]; \ - zzlextext = zztoktext; zzrdfunc( f ); zzPrimeLookAhead;} -#define zzenterANTLR(f) \ - {static char zztoktext[ZZLEXBUFSIZE]; \ - zzlextext = zztoktext; zzrdstream( f ); zzPrimeLookAhead;} -#ifdef ZZINF_LOOK -#define zzleaveANTLR(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line); -#define zzleaveANTLRf(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line); -#define zzleaveANTLRs(f) free(zzinf_text_buffer); free(zzinf_text); free(zzinf_tokens); free(zzinf_line); -#else -#define zzleaveANTLR(f) -#define zzleaveANTLRf(f) -#define zzleaveANTLRs(f) -#endif - -#endif - -/* MR19 Paul D. Smith (psmith@baynetworks.com) - Need to adjust AST stack pointer at exit. - Referenced in ANTLRx macros. -*/ - -#ifdef GENAST -#define ZZAST_ADJUST ++zzast_sp; -#else -#define ZZAST_ADJUST -#endif - -#define ANTLR(st, f) zzbufsize = ZZLEXBUFSIZE; \ - zzenterANTLR(f); \ - { \ - zzBLOCK(zztasp1); \ - st; /* ++zzasp; Removed MR20 G. Hobbelt */ \ - /* ZZAST_ADJUST Removed MR20 G. Hobbelt */ \ - /* MR20 G. Hobbelt. Kill the top' attribute (+AST stack corr.) */ \ - zzEXIT_ANTLR(zztasp1 + 1); \ - } \ - zzleaveANTLR(f); - -#define ANTLRm(st, f, _m) zzbufsize = ZZLEXBUFSIZE; \ - zzmode(_m); \ - zzenterANTLR(f); \ - { \ - zzBLOCK(zztasp1); \ - st; /* ++zzasp; Removed MR20 G. Hobbelt */ \ - /* ZZAST_ADJUST Removed MR20 G. Hobbelt */ \ - /* MR20 G. Hobbelt. Kill the top' attribute (+AST stack corr.) */ \ - zzEXIT_ANTLR(zztasp1 + 1); \ - } \ - zzleaveANTLR(f); - -#define ANTLRf(st, f) zzbufsize = ZZLEXBUFSIZE; \ - zzenterANTLRf(f); \ - { \ - zzBLOCK(zztasp1); \ - st; /* ++zzasp; Removed MR20 G. Hobbelt */ \ - /* ZZAST_ADJUST Removed MR20 G. Hobbelt */ \ - /* MR20 G. Hobbelt. Kill the top' attribute (+AST stack corr.) */ \ - zzEXIT_ANTLR(zztasp1 + 1); \ - } \ - zzleaveANTLRf(f); - -#define ANTLRs(st, s) zzbufsize = ZZLEXBUFSIZE; \ - zzenterANTLRs(s); \ - { \ - zzBLOCK(zztasp1); \ - st; /* ++zzasp; Removed MR20 G. Hobbelt */ \ - /* ZZAST_ADJUST Removed MR20 G. Hobbelt */ \ - /* MR20 G. Hobbelt. Kill the top' attribute (+AST stack corr.) */ \ - zzEXIT_ANTLR(zztasp1 + 1); \ - } \ - zzleaveANTLRs(s); - -#ifdef LL_K -#define zztext (&(zztextLA[zzlap][0])) -#else -#define zztext zzlextext -#endif - - - /* A r g u m e n t A c c e s s */ - -#define zzaCur (zzaStack[zzasp]) -#define zzaRet (*zzaRetPtr) -#define zzaArg(v,n) zzaStack[v-n] -#define zzMakeAttr { zzNON_GUESS_MODE {zzOvfChk; --zzasp; zzcr_attr(&(zzaStack[zzasp]),LA(1),LATEXT(1));}} -#ifdef zzdef0 -#define zzMake0 { zzOvfChk; --zzasp; zzdef0(&(zzaStack[zzasp]));} -#else -#define zzMake0 { zzOvfChk; --zzasp;} -#endif -#define zzaPush(_v) { zzOvfChk; zzaStack[--zzasp] = _v;} -#ifndef zzd_attr -#define zzREL(t) zzasp=(t); /* Restore state of stack */ -#else -#define zzREL(t) for (; zzasp<(t); zzasp++) \ - { zzd_attr(&(zzaStack[zzasp])); } -#endif - - -#define zzsetmatch(_es,_tokclassErrset) \ - if ( !_zzsetmatch(_es, &zzBadText, &zzMissText, &zzMissTok, &zzBadTok, &zzMissSet, _tokclassErrset) ) goto fail; /* MR23 */ - -#ifdef ZZCAN_GUESS -#define zzsetmatch_wsig(_es, handler) \ - if ( !_zzsetmatch_wsig(_es) ) if (zzguessing) { zzGUESS_FAIL; } else {_signal=MismatchedToken; goto handler;} -#else -#define zzsetmatch_wsig(_es, handler) \ - if ( !_zzsetmatch_wsig(_es) ) {_signal=MismatchedToken; goto handler;} -#endif - -#ifdef __USE_PROTOS -extern int _zzsetmatch(SetWordType *, char **, char **, int *, int *, SetWordType **, SetWordType * /* MR23 */); -extern int _zzsetmatch_wsig(SetWordType *); -#else -extern int _zzsetmatch(); -extern int _zzsetmatch_wsig(); -#endif - -#define zzmatch(_t) \ - if ( !_zzmatch(_t, &zzBadText, &zzMissText, &zzMissTok, &zzBadTok, &zzMissSet) ) goto fail; - -#ifdef ZZCAN_GUESS -#define zzmatch_wsig(_t,handler) \ - if ( !_zzmatch_wsig(_t) ) if (zzguessing) { zzGUESS_FAIL; } else {_signal=MismatchedToken; goto handler;} -#else -#define zzmatch_wsig(_t,handler) \ - if ( !_zzmatch_wsig(_t) ) {_signal=MismatchedToken; goto handler;} -#endif - -#ifdef __USE_PROTOS -extern int _zzmatch(int, char **, char **, int *, int *, SetWordType **); -extern int _zzmatch_wsig(int); -#else -extern int _zzmatch(); -extern int _zzmatch_wsig(); -#endif - -#define zzmatch_wdfltsig(_t,_f) \ - if ( !_zzmatch_wdfltsig(_t,_f) ) _signal=MismatchedToken; -#define zzsetmatch_wdfltsig(tw,tt,wf) \ - if ( !_zzsetmatch_wdfltsig(tw,tt,wf) ) _signal=MismatchedToken; - -#ifdef __USE_PROTOS -extern int _zzmatch_wdfltsig(int, SetWordType *); -extern int _zzsetmatch_wdfltsig(SetWordType *tokensWanted, - int tokenTypeOfSet, - SetWordType *whatFollows); -#else -extern int _zzmatch_wdfltsig(); -extern int _zzsetmatch_wdfltsig(); -#endif - -#ifdef GENAST -#define zzRULE Attrib *zzaRetPtr = &(zzaStack[zzasp-1]); \ - SetWordType *zzMissSet=NULL; int zzMissTok=0; \ - int zzBadTok=0; char *zzBadText=""; \ - int zzErrk=1,zzpf=0; \ - zzTRACEdata \ - char *zzMissText=""; zzASTVars -#else -#define zzRULE Attrib *zzaRetPtr = &(zzaStack[zzasp-1]); \ - int zzBadTok=0; char *zzBadText=""; \ - int zzErrk=1,zzpf=0; \ - zzTRACEdata \ - SetWordType *zzMissSet=NULL; int zzMissTok=0; char *zzMissText="" -#endif - -#ifdef GENAST -#define zzBLOCK(i) int i = zzasp - 1; int zztsp = zzast_sp -#define zzEXIT(i) zzREL(i); zzastREL; zzNON_GUESS_MODE { zzastPush(*_root); } -#define zzEXIT_ANTLR(i) zzREL(i); zzastREL /* [i_a] added as we want this for the ANTLRx() macros */ -#define zzLOOP(i) zzREL(i); zzastREL -#else -#define zzBLOCK(i) int i = zzasp - 1 -#define zzEXIT(i) zzREL(i) -#define zzEXIT_ANTLR(i) zzREL(i) /* [i_a] added as we want this for the ANTLRx() macros */ -#define zzLOOP(i) zzREL(i) -#endif - -#ifdef LL_K - -#ifdef DEMAND_LOOK -#define LOOK(_k) {int i,stop=_k-(LL_K-zzdirty); for (i=1; i<=stop; i++) \ - zzCONSUME;} -#define zzCONSUME {zzgettok(); zzdirty--; \ - zzlap = (zzlap+1)&(LL_K-1); \ - zzlextext = &(zztextLA[zzlap][0]);} -#else -#ifdef ZZINF_LOOK -#define zzCONSUME {inf_zzgettok; \ - zzlap = (zzlap+1)&(LL_K-1); \ - zzlextext = &(zztextLA[zzlap][0]); \ - } -#else -#define zzCONSUME {zzgettok(); \ - zzlap = (zzlap+1)&(LL_K-1); \ - zzlextext = &(zztextLA[zzlap][0]);} -#endif /* ZZINF_LOOK */ -#endif /* DEMAND_LOOK */ - -#else /* LL_K */ - -#ifdef DEMAND_LOOK -#define LOOK(_k) if ( zzdirty) zzCONSUME; -#ifdef ZZINF_LOOK -#define zzCONSUME inf_zzgettok; zzdirty=0; -#else -#define zzCONSUME zzgettok(); zzdirty=0; -#endif /* ZZINF_LOOK */ - -#else /* DEMAND_LOOK */ - -#ifdef ZZINF_LOOK -#define zzCONSUME inf_zzgettok -#else -#define zzCONSUME zzgettok(); -#endif - -#endif /* DEMAND_LOOK */ - -#endif /* LL_K */ - -#ifdef LL_K -#define NLA zztokenLA[zzlap&(LL_K-1)] /* --> next LA */ -#define NLATEXT zztextLA[zzlap&(LL_K-1)] /* --> next text of LA */ -#ifdef DEMAND_LOOK -#define LA(i) zztokenLA[(zzlabase+(i)-1)&(LL_K-1)] -#define LATEXT(i) (&(zztextLA[(zzlabase+(i)-1)&(LL_K-1)][0])) -#else -#define LA(i) zztokenLA[(zzlap+(i)-1)&(LL_K-1)] -#define LATEXT(i) (&(zztextLA[(zzlap+(i)-1)&(LL_K-1)][0])) -#endif -#else -#define NLA zztoken -#define NLATEXT zztext -#define LA(i) zztoken -#define LATEXT(i) zztext -#endif - - - /* S t a n d a r d S i g n a l s */ - -#define NoSignal 0 -#define MismatchedToken 1 -#define NoViableAlt 2 -#define NoSemViableAlt 3 - -/* MR7 Allow more control over signalling */ -/* by adding "Unwind" and "zzsetSignal" */ - -#define Unwind 4 -#define zzsetSignal(newValue) *_retsignal=_signal=(newValue) -#define zzsuppressSignal *_retsignal=_signal=0 -#define zzexportSignal *_retsignal=_signal - - /* F u n c t i o n T r a c i n g */ - -#ifndef zzTRACE_RULES -#define zzTRACEdata -#else -#ifndef zzTRACEdata -#define zzTRACEdata ANTLRChar *zzTracePrevRuleName = NULL; -#endif -#endif - -#ifndef zzTRACEIN -#define zzTRACEIN(r) zzTracePrevRuleName=zzTraceCurrentRuleName;zzTraceIn(r); -#endif -#ifndef zzTRACEOUT -#define zzTRACEOUT(r) zzTraceOut(r);zzTraceCurrentRuleName=zzTracePrevRuleName; -#endif - -/* MR19 zzchar_t additions */ - -#ifndef zzchar_t -#ifdef ZZWCHAR_T -#define zzchar_t wchar_t -#else -#define zzchar_t char -#endif -#endif - - -/* MR26 */ - -#ifdef PCCTS_USE_STDARG -extern void zzFAIL(int k, ...); -#else -extern void zzFAIL(); -#endif - /* E x t e r n D e f s */ - -#ifdef __USE_PROTOS -extern Attrib zzempty_attr(void); -extern Attrib zzconstr_attr(int, char *); -extern void zzsyn(char *, int, char *, SetWordType *, int, int, char *); -extern int zzset_el(unsigned, SetWordType *); -extern int zzset_deg(SetWordType *); -extern void zzedecode(SetWordType *); - -extern void zzresynch(SetWordType *, SetWordType); -extern void zzsave_antlr_state(zzantlr_state *); -extern void zzrestore_antlr_state(zzantlr_state *); -extern void zzfill_inf_look(void); -extern void zzconsumeUntil(SetWordType *st); /* MR7 */ -extern void zzconsumeUntilToken(int t); /* MR7 */ -extern void zzTraceIn(char * ruleName); /* MR10 */ -extern void zzTraceOut(char * ruleName); /* MR10 */ -extern int zzTraceOption(int delta); /* MR10 */ -extern int zzTraceGuessOption(int delta); /* MR10 */ -extern void zzTraceReset(void); /* MR10 */ -extern void zzTraceGuessFail(void); /* MR10 */ -#ifdef EXCEPTION_HANDLING -extern void zzdflthandlers(int, int *); -#endif -#else -extern Attrib zzempty_attr(); -extern Attrib zzconstr_attr(); -extern void zzsyn(); -extern int zzset_el(); -extern int zzset_deg(); -extern void zzedecode(); -extern void zzresynch(); -extern void zzsave_antlr_state(); -extern void zzrestore_antlr_state(); -extern void zzfill_inf_look(); -extern void zzconsumeUntil(); /* MR7 */ -extern void zzconsumeUntilToken(); /* MR7 */ -extern void zzTraceIn(); /* MR10 */ -extern void zzTraceOut(); /* MR10 */ -extern int zzTraceOption(); /* MR10 */ -extern int zzTraceGuessOption(); /* MR10 */ -extern void zzTraceReset(); /* MR10 */ -extern void zzTraceGuessFail(); /* MR10 */ -#ifdef EXCEPTION_HANDLING -extern void zzdflthandlers(); -#endif -#endif - - /* G l o b a l V a r i a b l e s */ - -/* Define a parser; user should do a "#parser myname" in their grammar file */ -/*extern struct pccts_parser zzparser;*/ - -extern char *zztokens[]; -#ifdef LL_K -extern int zztokenLA[]; -extern zzchar_t zztextLA[][ZZLEXBUFSIZE]; -extern int zzlap; -extern int zzlabase; -#else -extern int zztoken; -#endif - -extern char zzStackOvfMsg[]; -extern int zzasp; -extern Attrib zzaStack[]; -#ifdef ZZINF_LOOK -extern int *zzinf_tokens; -extern char **zzinf_text; -extern char *zzinf_text_buffer; -extern int *zzinf_line; -extern int zzinf_labase; -extern int zzinf_last; -#endif -#ifdef DEMAND_LOOK -extern int zzdirty; -#endif -#ifdef ZZCAN_GUESS -extern int zzguessing; -extern zzjmp_buf zzguess_start; -#endif - -/* Define global veriables that refer to values exported by the scanner. - * These declarations duplicate those in dlgdef.h, but are needed - * if ANTLR is not to generate a .dlg file (-gx); PS, this is a hack. - */ -extern zzchar_t *zzlextext; /* text of most recently matched token */ -extern int zzbufsize; /* how long zzlextext is */ - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/ast.c b/Tools/CodeTools/TianoTools/Pccts/h/ast.c deleted file mode 100644 index 9326ae16ae..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/ast.c +++ /dev/null @@ -1,345 +0,0 @@ -/* Abstract syntax tree manipulation functions - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -#include "pcctscfg.h" - -#ifdef PCCTS_USE_STDARG -#include "pccts_stdarg.h" -#else -#include -#endif - -/* ensure that tree manipulation variables are current after a rule - * reference - */ - -void -#ifdef __USE_PROTOS -zzlink(AST **_root, AST **_sibling, AST **_tail) -#else -zzlink(_root, _sibling, _tail) -AST **_root, **_sibling, **_tail; -#endif -{ - if ( *_sibling == NULL ) return; - if ( *_root == NULL ) *_root = *_sibling; - else if ( *_root != *_sibling ) (*_root)->down = *_sibling; - if ( *_tail==NULL ) *_tail = *_sibling; - while ( (*_tail)->right != NULL ) *_tail = (*_tail)->right; -} - -AST * -#ifdef __USE_PROTOS -zzastnew(void) -#else -zzastnew() -#endif -{ - AST *p = (AST *) calloc(1, sizeof(AST)); - if ( p == NULL ) fprintf(stderr,"%s(%d): cannot allocate AST node\n",__FILE__,__LINE__); - return p; -} - -/* add a child node to the current sibling list */ -void -#ifdef __USE_PROTOS -zzsubchild(AST **_root, AST **_sibling, AST **_tail) -#else -zzsubchild(_root, _sibling, _tail) -AST **_root, **_sibling, **_tail; -#endif -{ - AST *n; - zzNON_GUESS_MODE { - n = zzastnew(); -#ifdef DEMAND_LOOK - zzcr_ast(n, &(zzaCur), LA(0), LATEXT(0)); -#else - zzcr_ast(n, &(zzaCur), LA(1), LATEXT(1)); -#endif - zzastPush( n ); - if ( *_tail != NULL ) (*_tail)->right = n; - else { - *_sibling = n; - if ( *_root != NULL ) (*_root)->down = *_sibling; - } - *_tail = n; - if ( *_root == NULL ) *_root = *_sibling; - } -} - -/* make a new AST node. Make the newly-created - * node the root for the current sibling list. If a root node already - * exists, make the newly-created node the root of the current root. - */ -void -#ifdef __USE_PROTOS -zzsubroot(AST **_root, AST **_sibling, AST **_tail) -#else -zzsubroot(_root, _sibling, _tail) -AST **_root, **_sibling, **_tail; -#endif -{ - AST *n; - zzNON_GUESS_MODE { - n = zzastnew(); -#ifdef DEMAND_LOOK - zzcr_ast(n, &(zzaCur), LA(0), LATEXT(0)); -#else - zzcr_ast(n, &(zzaCur), LA(1), LATEXT(1)); -#endif - zzastPush( n ); - if ( *_root != NULL ) - if ( (*_root)->down == *_sibling ) *_sibling = *_tail = *_root; - *_root = n; - (*_root)->down = *_sibling; - } -} - -/* Apply function to root then each sibling - * example: print tree in child-sibling LISP-format (AST has token field) - * - * void show(tree) - * AST *tree; - * { - * if ( tree == NULL ) return; - * printf(" %s", zztokens[tree->token]); - * } - * - * void before() { printf(" ("); } - * void after() { printf(" )"); } - * - * LISPdump() { zzpre_ast(tree, show, before, after); } - * - */ -void -#ifdef __USE_PROTOS -zzpre_ast( - AST *tree, - void (*func)(AST *), /* apply this to each tree node */ - void (*before)(AST *), /* apply this to root of subtree before preordering it */ - void (*after)(AST *)) /* apply this to root of subtree after preordering it */ -#else -zzpre_ast(tree, func, before, after) -AST *tree; -void (*func)(), /* apply this to each tree node */ - (*before)(), /* apply this to root of subtree before preordering it */ - (*after)(); /* apply this to root of subtree after preordering it */ -#endif -{ - while ( tree!= NULL ) - { - if ( tree->down != NULL ) (*before)(tree); - (*func)(tree); - zzpre_ast(tree->down, func, before, after); - if ( tree->down != NULL ) (*after)(tree); - tree = tree->right; - } -} - -/* free all AST nodes in tree; apply func to each before freeing */ - -#if 0 -////void -////#ifdef __USE_PROTOS -////zzfree_ast(AST *tree) -////#else -////zzfree_ast(tree) -////AST *tree; -////#endif -////{ -//// if ( tree == NULL ) return; -//// zzfree_ast( tree->down ); -//// zzfree_ast( tree->right ); -//// zztfree( tree ); -////} -#endif - -/* - MR19 Optimize freeing of the following structure to limit recursion - SAKAI Kiyotaka (ksakai@isr.co.jp) -*/ - -/* - NULL o - / \ - NULL o - / \ - NULL NULL -*/ - -/* - MR21 Another refinement to replace recursion with iteration - NAKAJIMA Mutsuki (muc@isr.co.jp). -*/ - -void -#ifdef __USE_PROTOS -zzfree_ast(AST *tree) -#else -zzfree_ast(tree) -AST *tree; -#endif -{ - - AST *otree; - - if (tree == NULL) return; - - while (tree->down == NULL || tree->right == NULL) { - - if (tree->down == NULL && tree->right == NULL) { - zztfree(tree); - return; - } - - otree = tree; - if (tree->down == NULL) { - tree = tree->right; - } else { - tree = tree->down; - } - zztfree( otree ); - } - - while (tree != NULL) { - zzfree_ast(tree->down); - otree = tree; - tree = otree->right; - zztfree(otree); - } -} - -/* build a tree (root child1 child2 ... NULL) - * If root is NULL, simply make the children siblings and return ptr - * to 1st sibling (child1). If root is not single node, return NULL. - * - * Siblings that are actually siblins lists themselves are handled - * correctly. For example #( NULL, #( NULL, A, B, C), D) results - * in the tree ( NULL A B C D ). - * - * Requires at least two parameters with the last one being NULL. If - * both are NULL, return NULL. - */ -#ifdef PCCTS_USE_STDARG -AST *zztmake(AST *rt, ...) -#else -AST *zztmake(va_alist) -va_dcl -#endif -{ - va_list ap; - register AST *child, *sibling=NULL, *tail=NULL /* MR20 */, *w; - AST *root; - -#ifdef PCCTS_USE_STDARG - va_start(ap, rt); - root = rt; -#else - va_start(ap); - root = va_arg(ap, AST *); -#endif - - if ( root != NULL ) - if ( root->down != NULL ) return NULL; - child = va_arg(ap, AST *); - while ( child != NULL ) - { - for (w=child; w->right!=NULL; w=w->right) {;} /* find end of child */ - if ( sibling == NULL ) {sibling = child; tail = w;} - else {tail->right = child; tail = w;} - child = va_arg(ap, AST *); - } - if ( root==NULL ) root = sibling; - else root->down = sibling; - va_end(ap); - return root; -} - -/* tree duplicate */ -AST * -#ifdef __USE_PROTOS -zzdup_ast(AST *t) -#else -zzdup_ast(t) -AST *t; -#endif -{ - AST *u; - - if ( t == NULL ) return NULL; - u = zzastnew(); - *u = *t; -#ifdef zzAST_DOUBLE - u->up = NULL; /* set by calling invocation */ - u->left = NULL; -#endif - u->right = zzdup_ast(t->right); - u->down = zzdup_ast(t->down); -#ifdef zzAST_DOUBLE - if ( u->right!=NULL ) u->right->left = u; - if ( u->down!=NULL ) u->down->up = u; -#endif - return u; -} - -void -#ifdef __USE_PROTOS -zztfree(AST *t) -#else -zztfree(t) -AST *t; -#endif -{ -#ifdef zzd_ast - zzd_ast( t ); -#endif - free( t ); -} - -#ifdef zzAST_DOUBLE -/* - * Set the 'up', and 'left' pointers of all nodes in 't'. - * Initial call is double_link(your_tree, NULL, NULL). - */ -void -#ifdef __USE_PROTOS -zzdouble_link(AST *t, AST *left, AST *up) -#else -zzdouble_link(t, left, up) -AST *t, *left, *up; -#endif -{ - if ( t==NULL ) return; - t->left = left; - t->up = up; - zzdouble_link(t->down, NULL, t); - zzdouble_link(t->right, t, up); -} -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/ast.h b/Tools/CodeTools/TianoTools/Pccts/h/ast.h deleted file mode 100644 index 5ff84bd76c..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/ast.h +++ /dev/null @@ -1,121 +0,0 @@ -/* Abstract syntax tree - * - * Macros, definitions - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -#ifndef ZZAST_H -#define ZZAST_H - -#define zzastOvfChk \ - if ( zzast_sp <= 0 ) \ - { \ - fprintf(stderr, zzStackOvfMsg, __FILE__, __LINE__); \ - exit(PCCTS_EXIT_FAILURE); \ - } - -#ifndef USER_DEFINED_AST -#ifndef AST_FIELDS -#define AST_FIELDS -#endif - -typedef struct _ast { - struct _ast *right, *down; -#ifdef zzAST_DOUBLE - struct _ast *left, *up; -#endif - AST_FIELDS -} AST; - -#else - -#ifdef zzAST_DOUBLE -#define AST_REQUIRED_FIELDS struct _ast *right, *down, *left, *up; -#else -#define AST_REQUIRED_FIELDS struct _ast *right, *down; -#endif - -#endif - - -/* N o d e a c c e s s m a c r o s */ -#define zzchild(t) (((t)==NULL)? (AST *) NULL:(t->down)) /* MR19 */ -#define zzsibling(t) (((t)==NULL)? (AST *) NULL:(t->right)) /* MR19 */ - - -/* define global variables needed by #i stack */ -#define zzASTgvars \ - AST *zzastStack[ZZAST_STACKSIZE]; \ - int zzast_sp = ZZAST_STACKSIZE; - -#define zzASTVars AST *_ast = NULL, *_sibling = NULL, *_tail = NULL -#define zzSTR ( (_tail==NULL)?(&_sibling):(&(_tail->right)) ) -#define zzastCur (zzastStack[zzast_sp]) -#define zzastArg(i) (zzastStack[zztsp-i]) -#define zzastPush(p) zzastOvfChk; zzastStack[--zzast_sp] = p; -#define zzastDPush --zzast_sp -#define zzastMARK zztsp=zzast_sp; /* Save state of stack */ -#define zzastREL zzast_sp=zztsp; /* Return state of stack */ -#define zzrm_ast {zzfree_ast(*_root); _tail = _sibling = (*_root)=NULL;} - -extern int zzast_sp; -extern AST *zzastStack[]; - -/* MR26 */ - -#ifdef PCCTS_USE_STDARG -AST *zztmake(AST *, ...); -#else -AST *zztmake(); -#endif - -#ifdef __USE_PROTOS -void zzlink(AST **, AST **, AST **); -void zzsubchild(AST **, AST **, AST **); -void zzsubroot(AST **, AST **, AST **); -void zzpre_ast(AST *, void (*)(AST *), void (*)(AST *), void (*)(AST *)); -void zzfree_ast(AST *); -AST *zzdup_ast(AST *); -void zztfree(AST *); -void zzdouble_link(AST *, AST *, AST *); -AST *zzastnew(void); - -#else - -void zzlink(); -AST *zzastnew(); -void zzsubchild(); -void zzsubroot(); -void zzpre_ast(); -void zzfree_ast(); -AST *zzdup_ast(); -void zztfree(); -void zzdouble_link(); -#endif - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/charbuf.h b/Tools/CodeTools/TianoTools/Pccts/h/charbuf.h deleted file mode 100644 index 5f01c8ba35..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/charbuf.h +++ /dev/null @@ -1,46 +0,0 @@ -/* ANTLR attribute definition -- constant width text - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -#ifndef ZZCHARBUF_H -#define ZZCHARBUF_H - -#include "pcctscfg.h" - -#include "pccts_string.h" - -#ifndef D_TextSize -#define D_TextSize 30 -#endif - -typedef struct { char text[D_TextSize]; } Attrib; - -#define zzcr_attr(a,tok,t) strncpy((a)->text, t, D_TextSize-1); \ - (a)->text[D_TextSize-1] = '\0'; - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/charptr.c b/Tools/CodeTools/TianoTools/Pccts/h/charptr.c deleted file mode 100644 index d3f80e60ba..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/charptr.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -#include "pcctscfg.h" - -#ifdef __STDC__ -#include "pccts_stdlib.h" -#else -#include -#endif -#include "pccts_string.h" - -/* 133MR1 include stdio.h for fprintf in charptr.c */ - -#include "pccts_stdio.h" - -/* 133MR1 include charptr.h for Attrib in charptr.c */ - -#include "charptr.h" - -#ifdef __USE_PROTOS -zzcr_attr(Attrib *a,int token,char *text) -#else -zzcr_attr(a,token,text) -Attrib *a; -int token; -char *text; -#endif -{ - *a = (char *) malloc(strlen(text)+1); /* MR6 */ - if ( *a == NULL ) {fprintf(stderr, "zzcr_attr: out of memory!\n"); exit(-1);} - strcpy(*a, text); -} diff --git a/Tools/CodeTools/TianoTools/Pccts/h/charptr.h b/Tools/CodeTools/TianoTools/Pccts/h/charptr.h deleted file mode 100644 index e73da681a4..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/charptr.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -/* - * WARNING!!!!: charptr.h does NOT make copies and the - * memory is freed after the attribute scope exits. - */ - -#ifndef ZZCHARPTR_H -#define ZZCHARPTR_H - -typedef char *Attrib; -#define zzdef0(a) {*(a)=NULL;} -/* MR8 Jens Tingleff (jensting@imaginet.fr) */ -/* Set memory pointer to null after free() */ -#define zzd_attr(a) {if ( *(a)!=NULL ) {free(*(a)); *(a)=NULL; }; } - -#ifdef __STDC__ -extern zzcr_attr(Attrib *,int,char *); -#endif - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/config.h b/Tools/CodeTools/TianoTools/Pccts/h/config.h deleted file mode 100644 index 8aa50ad618..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/config.h +++ /dev/null @@ -1 +0,0 @@ -#include "pcctscfg.h" diff --git a/Tools/CodeTools/TianoTools/Pccts/h/dlgauto.h b/Tools/CodeTools/TianoTools/Pccts/h/dlgauto.h deleted file mode 100644 index db94cefaca..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/dlgauto.h +++ /dev/null @@ -1,504 +0,0 @@ -/* dlgauto.h automaton - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Will Cohen and Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -#ifndef ZZDEFAUTO_H -#define ZZDEFAUTO_H - -/* 10-Apr-97 133MR1 Uses __USE_PROTOS show should #include pcctscfg.h */ - -#include "pcctscfg.h" - -zzchar_t *zzlextext; /* text of most recently matched token */ -zzchar_t *zzbegexpr; /* beginning of last reg expr recogn. */ -zzchar_t *zzendexpr; /* beginning of last reg expr recogn. */ -int zzbufsize = 0; /* number of characters in zzlextext */ /* MR7 */ -int zzbegcol = 0; /* column that first character of token is in*/ -int zzendcol = 0; /* column that last character of token is in */ -int zzline = 1; /* line current token is on */ -int zzreal_line=1; /* line of 1st portion of token that is not skipped */ -int zzchar; /* character to determine next state */ -int zzbufovf; /* indicates that buffer too small for text */ -int zzcharfull = 0; -static zzchar_t *zznextpos;/* points to next available position in zzlextext*/ -static int zzclass; - -#ifdef __USE_PROTOS -void zzerrstd(const char *); -void (*zzerr)(const char *)=zzerrstd;/* pointer to error reporting function */ -extern int zzerr_in(void); -static int (*zzfunc_in)(void) = zzerr_in; /* MR20 */ -#else -void zzerrstd(); -void (*zzerr)()=zzerrstd; /* pointer to error reporting function */ -extern int zzerr_in(); -static int (*zzfunc_in)() = zzerr_in; /* MR20 */ -#endif - -static FILE *zzstream_in=0; -static zzchar_t *zzstr_in=0; - -#ifdef USER_ZZMODE_STACK -int zzauto = 0; -#else -static int zzauto = 0; -#endif -static int zzadd_erase; -static char zzebuf[70]; - -#ifdef ZZCOL -#define ZZINC (++zzendcol) -#else -#define ZZINC -#endif - - -#define ZZGETC_STREAM {zzchar = getc(zzstream_in); zzclass = ZZSHIFT(zzchar);} -#define ZZGETC_FUNC {zzchar = (*zzfunc_in)(); zzclass = ZZSHIFT(zzchar);} -#define ZZGETC_STR { \ - if (*zzstr_in){ \ - zzchar = *zzstr_in; \ - ++zzstr_in; \ - }else{ \ - zzchar = EOF; \ - } \ - zzclass = ZZSHIFT(zzchar); \ -} - -#define ZZNEWSTATE (newstate = dfa[state][zzclass]) - -#ifndef ZZCOPY -#define ZZCOPY \ - /* Truncate matching buffer to size (not an error) */ \ - if (zznextpos < lastpos){ \ - *(zznextpos++) = zzchar; \ - }else{ \ - zzbufovf = 1; \ - } -#endif - -void -#ifdef __USE_PROTOS -zzrdstream( FILE *f ) -#else -zzrdstream( f ) -FILE *f; -#endif -{ - /* make sure that it is really set to something, otherwise just - leave it be. - */ - if (f){ - /* make sure that there is always someplace to get input - before closing zzstream_in - */ -#if 0 - if (zzstream_in && zzstream_in!=stdin) fclose( zzstream_in ); -#endif - zzline = 1; - zzstream_in = f; - zzfunc_in = NULL; - zzstr_in = 0; - zzcharfull = 0; - } -} - -void -#ifdef __USE_PROTOS -zzrdfunc( int (*f)(void) ) -#else -zzrdfunc( f ) -int (*f)(); -#endif -{ - /* make sure that it is really set to something, otherwise just - leave it be. - */ - if (f){ - /* make sure that there is always someplace to get input - before closing zzstream_in - */ -#if 0 - if (zzstream_in && zzstream_in!=stdin) fclose( zzstream_in ); -#endif - zzline = 1; - zzstream_in = NULL; - zzfunc_in = f; - zzstr_in = 0; - zzcharfull = 0; - } -} - - -void -#ifdef __USE_PROTOS -zzrdstr( zzchar_t *s ) -#else -zzrdstr( s ) -zzchar_t *s; -#endif -{ - /* make sure that it is really set to something, otherwise just - leave it be. - */ - if (s){ - /* make sure that there is always someplace to get input - before closing zzstream_in - */ -#if 0 - if (zzstream_in && zzstream_in!=stdin) fclose( zzstream_in ); -#endif - zzline = 1; - zzstream_in = NULL; - zzfunc_in = 0; - zzstr_in = s; - zzcharfull = 0; - } -} - - -#ifdef __USE_PROTOS -void zzclose_stream(void) -#else -void zzclose_stream() -#endif -{ -#if 0 - fclose( zzstream_in ); - zzstream_in = NULL; - zzfunc_in = NULL; -#endif -} - -/* saves dlg state, but not what feeds dlg (such as file position) */ -void -#ifdef __USE_PROTOS -zzsave_dlg_state(struct zzdlg_state *state) -#else -zzsave_dlg_state(state) -struct zzdlg_state *state; -#endif -{ - state->stream = zzstream_in; - state->func_ptr = zzfunc_in; - state->str = zzstr_in; - state->auto_num = zzauto; - state->add_erase = zzadd_erase; - state->lookc = zzchar; - state->char_full = zzcharfull; - state->begcol = zzbegcol; - state->endcol = zzendcol; - state->line = zzline; - state->lextext = zzlextext; - state->begexpr = zzbegexpr; - state->endexpr = zzendexpr; - state->bufsize = zzbufsize; - state->bufovf = zzbufovf; - state->nextpos = zznextpos; - state->class_num = zzclass; -} - -void -#ifdef __USE_PROTOS -zzrestore_dlg_state(struct zzdlg_state *state) -#else -zzrestore_dlg_state(state) -struct zzdlg_state *state; -#endif -{ - zzstream_in = state->stream; - zzfunc_in = state->func_ptr; - zzstr_in = state->str; - zzauto = state->auto_num; - zzadd_erase = state->add_erase; - zzchar = state->lookc; - zzcharfull = state->char_full; - zzbegcol = state->begcol; - zzendcol = state->endcol; - zzline = state->line; - zzlextext = state->lextext; - zzbegexpr = state->begexpr; - zzendexpr = state->endexpr; - zzbufsize = state->bufsize; - zzbufovf = state->bufovf; - zznextpos = state->nextpos; - zzclass = state->class_num; -} - -void -#ifdef __USE_PROTOS -zzmode( int m ) -#else -zzmode( m ) -int m; -#endif -{ - /* points to base of dfa table */ - if (m -#include - -/* */ -/* 7-Apr-97 133MR1 */ -/* Proper choice of STDC and cplusplus pre-processor symbols (?) */ -/* */ -#include "pccts_string.h" - -#ifdef PCCTS_USE_STDARG -#include "pccts_stdarg.h" -#else -#include -#endif - -#ifdef DUM -/* Define usable bits per unsigned int word (used for set stuff) */ -#ifdef PC -#define BSETWORDSIZE 16 -#define BSETLOGWORDSIZE 4 -#else -#define BSETWORDSIZE 32 -#define BSETLOGWORDSIZE 5 -#endif -#endif - -#define BSETWORDSIZE 8 -#define BSETLOGWORDSIZE 3 /* SetWordType is 8bits */ - -#define BSETMODWORD(x) ((x) & (BSETWORDSIZE-1)) /* x % BSETWORDSIZE */ -#define BSETDIVWORD(x) ((x) >> BSETLOGWORDSIZE) /* x / BSETWORDSIZE */ - -/* This is not put into the global pccts_parser structure because it is - * hidden and does not need to be saved during a "save state" operation - */ -/* maximum of 32 bits/unsigned int and must be 8 bits/byte */ -static SetWordType bitmask[] = { - 0x00000001, 0x00000002, 0x00000004, 0x00000008, - 0x00000010, 0x00000020, 0x00000040, 0x00000080 -}; - -#ifdef zzTRACE_RULES -int zzTraceOptionValueDefault=1; -int zzTraceOptionValue=1; -int zzTraceGuessOptionValue=1; -char *zzTraceCurrentRuleName=NULL; -int zzTraceDepth=0; -#endif - -int zzGuessSeq=0; /* MR10 */ -int zzSyntaxErrCount=0; /* MR11 */ -int zzLexErrCount=0; /* MR11 */ - -void -#ifdef __USE_PROTOS -zzresynch(SetWordType *wd,SetWordType mask) -#else -zzresynch(wd,mask) -SetWordType *wd, mask; -#endif -{ - static int consumed = 1; - - /* if you enter here without having consumed a token from last resynch - * force a token consumption. - */ - if ( !consumed ) {zzCONSUME; consumed=1; return;} /* MR10 */ - - /* if current token is in resynch set, we've got what we wanted */ - if ( wd[LA(1)]&mask || LA(1) == zzEOF_TOKEN ) {consumed=0; return;} - - /* scan until we find something in the resynch set */ - while ( !(wd[LA(1)]&mask) && LA(1) != zzEOF_TOKEN ) {zzCONSUME;} - consumed=1; -} - -/* */ -/* 7-Apr-97 133MR1 for C++ and MR7 for C */ -/* Change suggested by Eli Sternheim (eli@interhdl.com) */ -/* */ - -void -#ifdef __USE_PROTOS -zzconsumeUntil(SetWordType *st) -#else -zzconsumeUntil(st) -SetWordType *st; -#endif -{ - int tmp; /* MR7 */ - while ( !zzset_el( (tmp=LA(1)), st) && tmp!=1 /* Eof */) { /* MR7 */ - zzCONSUME; } /* MR7 */ -} - -/* */ -/* 7-Apr-97 133MR1 for C++ and MR7 for C */ -/* Change suggested by Eli Sternheim (eli@interhdl.com) */ -/* */ - -void -#ifdef __USE_PROTOS -zzconsumeUntilToken(int t) -#else -zzconsumeUntilToken(t) -int t; -#endif -{ - int tmp; /* MR7 */ - while ( (tmp=LA(1)) !=t && tmp!=1 /* Eof */) { zzCONSUME; } /* MR7 */ -} - -/* input looks like: - * zzFAIL(k, e1, e2, ...,&zzMissSet,&zzMissText,&zzBadTok,&zzBadText) - * where the zzMiss stuff is set here to the token that did not match - * (and which set wasn't it a member of). - */ - -#ifdef PCCTS_USE_STDARG -void zzFAIL(int k, ...) -#else -void zzFAIL(va_alist) -va_dcl -#endif -{ -#ifdef LL_K - static char text[LL_K*ZZLEXBUFSIZE+1]; - SetWordType *f[LL_K]; -#else - static char text[ZZLEXBUFSIZE+1]; - SetWordType *f[1]; -#endif - SetWordType **miss_set; - char **miss_text; - int *bad_tok; - char **bad_text; - int *err_k; - int i; - va_list ap; -#ifndef PCCTS_USE_STDARG /* MR20 */ - int k; -#endif -#ifdef PCCTS_USE_STDARG /* MR20 */ - va_start(ap, k); -#else - va_start(ap); - k = va_arg(ap, int); /* how many lookahead sets? */ -#endif - assert(k <= sizeof(f)/sizeof(f[0])); /* MR20 G. Hobbelt */ - text[0] = '\0'; - for (i=1; i<=k; i++) /* collect all lookahead sets */ - { - f[i-1] = va_arg(ap, SetWordType *); - } - for (i=1; i<=k; i++) /* look for offending token */ - { - if ( i>1 ) strcat(text, " "); - strcat(text, LATEXT(i)); - if ( !zzset_el((unsigned)LA(i), f[i-1]) ) break; - } - miss_set = va_arg(ap, SetWordType **); - miss_text = va_arg(ap, char **); - bad_tok = va_arg(ap, int *); - bad_text = va_arg(ap, char **); - err_k = va_arg(ap, int *); - if ( i>k ) - { - /* bad; lookahead is permutation that cannot be matched, - * but, the ith token of lookahead is valid at the ith position - * (The old LL sub 1 (k) versus LL(k) parsing technique) - */ - *miss_set = NULL; - *miss_text = zzlextext; - *bad_tok = LA(1); - *bad_text = LATEXT(1); - *err_k = k; - return; - } -/* fprintf(stderr, "%s not in %dth set\n", zztokens[LA(i)], i);*/ - *miss_set = f[i-1]; - *miss_text = text; - *bad_tok = LA(i); - *bad_text = LATEXT(i); - if ( i==1 ) *err_k = 1; - else *err_k = k; -} - -#ifdef __USE_PROTOS -void zzTraceGuessDone(zzantlr_state *state) -#else -void zzTraceGuessDone(state) - zzantlr_state *state; -#endif -{ -#ifdef zzTRACE_RULES -#ifdef ZZCAN_GUESS - - int doIt=0; - - if (zzTraceCurrentRuleName == NULL) return; - - if (zzTraceOptionValue <= 0) { - doIt=0; - } else if (zzTraceGuessOptionValue <= 0) { - doIt=0; - } else { - doIt=1; - }; - - if (doIt) { - fprintf(stderr,"guess done - returning to rule %s {\"%s\"} at depth %d", - state->traceCurrentRuleName, - LATEXT(1), - state->traceDepth); - if (state->guessing != 0) { - fprintf(stderr," (guess mode continues - an enclosing guess is still active)"); - } else { - fprintf(stderr," (guess mode ends)"); - }; - fprintf(stderr,"\n"); - }; -#endif -#endif -} - -void -#ifdef __USE_PROTOS -zzsave_antlr_state(zzantlr_state *buf) -#else -zzsave_antlr_state(buf) -zzantlr_state *buf; -#endif -{ -#ifdef LL_K - int i; -#endif - -#ifdef ZZCAN_GUESS - buf->guess_start = zzguess_start; - buf->guessing = zzguessing; -#endif - buf->asp = zzasp; -#ifdef GENAST - buf->ast_sp = zzast_sp; -#endif -#ifdef ZZINF_LOOK - buf->inf_labase = zzinf_labase; - buf->inf_last = zzinf_last; - -/* MR6 Gunnar Rxnning (gunnar@candleweb.no) */ -/* MR6 Additional state needs to be saved/restored */ - - buf->inf_tokens = zzinf_tokens; /* MR6 */ - buf->inf_text = zzinf_text; /* MR6 */ - buf->inf_text_buffer = zzinf_text_buffer; /* MR6 */ - buf->inf_line = zzinf_line; /* MR6 */ - -#endif -#ifdef DEMAND_LOOK - buf->dirty = zzdirty; -#endif -#ifdef LL_K - for (i=0; itokenLA[i] = zztokenLA[i]; - for (i=0; itextLA[i], zztextLA[i]); - buf->lap = zzlap; - buf->labase = zzlabase; -#else - buf->token = zztoken; - strcpy(buf->text, zzlextext); -#endif -#ifdef zzTRACE_RULES - - /* MR10 */ - - buf->traceOptionValue=zzTraceOptionValue; - buf->traceGuessOptionValue=zzTraceGuessOptionValue; - buf->traceCurrentRuleName=zzTraceCurrentRuleName; - buf->traceDepth=zzTraceDepth; -#endif -} - -void -#ifdef __USE_PROTOS -zzrestore_antlr_state(zzantlr_state *buf) -#else -zzrestore_antlr_state(buf) -zzantlr_state *buf; -#endif -{ - -#ifdef zzTRACE_RULES - int prevTraceOptionValue; -#endif - -#ifdef LL_K - int i; -#endif - -#ifdef ZZCAN_GUESS - zzguess_start = buf->guess_start; - zzguessing = buf->guessing; -#endif - zzasp = buf->asp; -#ifdef GENAST - zzast_sp = buf->ast_sp; -#endif -#ifdef ZZINF_LOOK - zzinf_labase = buf->inf_labase; - zzinf_last = buf->inf_last; - -/* MR6 Gunnar Rxnning (gunnar@candleweb.no) */ -/* MR6 Additional state needs to be saved/restored */ - - zzinf_tokens = buf->inf_tokens; /* MR6 */ - zzinf_text = buf->inf_text; /* MR6 */ - zzinf_text_buffer = buf->inf_text_buffer; /* MR6 */ - zzinf_line = buf->inf_line; /* MR6 */ -#endif -#ifdef DEMAND_LOOK - zzdirty = buf->dirty; -#endif -#ifdef LL_K - for (i=0; itokenLA[i]; - for (i=0; itextLA[i]); - zzlap = buf->lap; - zzlabase = buf->labase; -#else - zztoken = buf->token; - strcpy(zzlextext, buf->text); -#endif -#ifdef zzTRACE_RULES - - prevTraceOptionValue=zzTraceOptionValue; - zzTraceOptionValue=buf->traceOptionValue; - if ( (prevTraceOptionValue > 0) != - (zzTraceOptionValue > 0)) { - if (zzTraceOptionValue > 0) { - fprintf(stderr,"trace enable restored in rule %s depth %d\n", - zzTraceCurrentRuleName,zzTraceDepth); - }; - if (zzTraceOptionValue <= 0) { - fprintf(stderr,"trace disable restored in rule %s depth %d\n", - zzTraceCurrentRuleName,zzTraceDepth); - }; - }; - - zzTraceOptionValue=buf->traceOptionValue; /* MR10 */ - zzTraceGuessOptionValue=buf->traceGuessOptionValue; /* MR10 */ - zzTraceCurrentRuleName=buf->traceCurrentRuleName; /* MR10 */ - zzTraceDepth=buf->traceDepth; /* MR10 */ - zzTraceGuessDone(buf); /* MR10 */ -#endif -} - -void -#ifdef __USE_PROTOS -zzedecode(SetWordType *a) -#else -zzedecode(a) -SetWordType *a; -#endif -{ - register SetWordType *p = a; - register SetWordType *endp = &(p[zzSET_SIZE]); - register unsigned e = 0; - - if ( zzset_deg(a)>1 ) fprintf(stderr, " {"); - do { - register SetWordType t = *p; - register SetWordType *b = &(bitmask[0]); - do { - if ( t & *b ) fprintf(stderr, " %s", zztokens[e]); - e++; - } while (++b < &(bitmask[sizeof(SetWordType)*8])); - } while (++p < endp); - if ( zzset_deg(a)>1 ) fprintf(stderr, " }"); -} - -#ifndef USER_ZZSYN -/* standard error reporting function */ -void -#ifdef __USE_PROTOS -zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, int k, char *bad_text) -#else -zzsyn(text, tok, egroup, eset, etok, k, bad_text) -char *text, *egroup, *bad_text; -int tok; -int etok; -int k; -SetWordType *eset; -#endif -{ - - zzSyntaxErrCount++; /* MR11 */ - fprintf(stderr, "line %d: syntax error at \"%s\"", zzline, (tok==zzEOF_TOKEN)?"EOF":bad_text); - if ( !etok && !eset ) {fprintf(stderr, "\n"); return;} - if ( k==1 ) fprintf(stderr, " missing"); - else - { - fprintf(stderr, "; \"%s\" not", bad_text); - if ( zzset_deg(eset)>1 ) fprintf(stderr, " in"); - } - if ( zzset_deg(eset)>0 ) zzedecode(eset); - else fprintf(stderr, " %s", zztokens[etok]); - if ( strlen(egroup) > 0 ) fprintf(stderr, " in %s", egroup); - fprintf(stderr, "\n"); -} -#endif - -/* is b an element of set p? */ -int -#ifdef __USE_PROTOS -zzset_el(unsigned b, SetWordType *p) -#else -zzset_el(b,p) -unsigned b; -SetWordType *p; -#endif -{ - return( p[BSETDIVWORD(b)] & bitmask[BSETMODWORD(b)] ); -} - -int -#ifdef __USE_PROTOS -zzset_deg(SetWordType *a) -#else -zzset_deg(a) -SetWordType *a; -#endif -{ - /* Fast compute degree of a set... the number - of elements present in the set. Assumes - that all word bits are used in the set - */ - register SetWordType *p = a; - register SetWordType *endp = &(a[zzSET_SIZE]); - register int degree = 0; - - if ( a == NULL ) return 0; - while ( p < endp ) - { - register SetWordType t = *p; - register SetWordType *b = &(bitmask[0]); - do { - if (t & *b) ++degree; - } while (++b < &(bitmask[sizeof(SetWordType)*8])); - p++; - } - - return(degree); -} - -#ifdef DEMAND_LOOK - -#ifdef LL_K -int -#ifdef __USE_PROTOS -_zzmatch(int _t, char **zzBadText, char **zzMissText, - int *zzMissTok, int *zzBadTok, - SetWordType **zzMissSet) -#else -_zzmatch(_t, zzBadText, zzMissText, zzMissTok, zzBadTok, zzMissSet) -int _t; -char **zzBadText; -char **zzMissText; -int *zzMissTok, *zzBadTok; -SetWordType **zzMissSet; -#endif -{ - if ( zzdirty==LL_K ) { - zzCONSUME; - } - if ( LA(1)!=_t ) { - *zzBadText = *zzMissText=LATEXT(1); - *zzMissTok= _t; *zzBadTok=LA(1); - *zzMissSet=NULL; - return 0; - } - zzMakeAttr - zzdirty++; - zzlabase++; - return 1; -} - -int -#ifdef __USE_PROTOS -_zzmatch_wsig(int _t) -#else -_zzmatch_wsig(_t) -int _t; -#endif -{ - if ( zzdirty==LL_K ) { - zzCONSUME; - } - if ( LA(1)!=_t ) { - return 0; - } - zzMakeAttr - zzdirty++; - zzlabase++; - return 1; -} - -#else - -int -#ifdef __USE_PROTOS -_zzmatch(int _t, char **zzBadText, char **zzMissText, - int *zzMissTok, int *zzBadTok, SetWordType **zzMissSet) -#else -_zzmatch(_t, zzBadText, zzMissText, zzMissTok, zzBadTok, zzMissSet) -int _t; -char **zzBadText; -char **zzMissText; -int *zzMissTok, *zzBadTok; -SetWordType **zzMissSet; -#endif -{ - if ( zzdirty ) {zzCONSUME;} - if ( LA(1)!=_t ) { - *zzBadText = *zzMissText=LATEXT(1); - *zzMissTok= _t; *zzBadTok=LA(1); - *zzMissSet=NULL; - return 0; - } - zzdirty = 1; - zzMakeAttr - return 1; -} - -int -#ifdef __USE_PROTOS -_zzmatch_wsig(int _t) -#else -_zzmatch_wsig(_t) -int _t; -#endif -{ - if ( zzdirty ) {zzCONSUME;} - if ( LA(1)!=_t ) { - return 0; - } - zzdirty = 1; - zzMakeAttr - return 1; -} - -#endif /*LL_K*/ - -#else - -int -#ifdef __USE_PROTOS -_zzmatch(int _t, char **zzBadText, char **zzMissText, - int *zzMissTok, int *zzBadTok, - SetWordType **zzMissSet) -#else -_zzmatch(_t, zzBadText, zzMissText, zzMissTok, zzBadTok, zzMissSet) -int _t; -char **zzBadText; -char **zzMissText; -int *zzMissTok, *zzBadTok; -SetWordType **zzMissSet; -#endif -{ - if ( LA(1)!=_t ) { - *zzBadText = *zzMissText=LATEXT(1); - *zzMissTok= _t; *zzBadTok=LA(1); - *zzMissSet=NULL; - return 0; - } - zzMakeAttr - return 1; -} - -int -#ifdef __USE_PROTOS -_zzmatch_wsig(int _t) -#else -_zzmatch_wsig(_t) -int _t; -#endif -{ - if ( LA(1)!=_t ) return 0; - zzMakeAttr - return 1; -} - -#endif /*DEMAND_LOOK*/ - -#ifdef ZZINF_LOOK -void -#ifdef __USE_PROTOS -_inf_zzgettok(void) -#else -_inf_zzgettok() -#endif -{ - if ( zzinf_labase >= zzinf_last ) - {NLA = zzEOF_TOKEN; strcpy(NLATEXT, "");} - else { - NLA = zzinf_tokens[zzinf_labase]; - zzline = zzinf_line[zzinf_labase]; /* wrong in 1.21 */ - strcpy(NLATEXT, zzinf_text[zzinf_labase]); - zzinf_labase++; - } -} -#endif - -#ifdef ZZINF_LOOK -/* allocate default size text,token and line arrays; - * then, read all of the input reallocing the arrays as needed. - * Once the number of total tokens is known, the LATEXT(i) array (zzinf_text) - * is allocated and it's pointers are set to the tokens in zzinf_text_buffer. - */ -void -#ifdef __USE_PROTOS -zzfill_inf_look(void) -#else -zzfill_inf_look() -#endif -{ - int tok, line; - int zzinf_token_buffer_size = ZZINF_DEF_TOKEN_BUFFER_SIZE; - int zzinf_text_buffer_size = ZZINF_DEF_TEXT_BUFFER_SIZE; - int zzinf_text_buffer_index = 0; - int zzinf_lap = 0; - - /* allocate text/token buffers */ - zzinf_text_buffer = (char *) malloc(zzinf_text_buffer_size); - if ( zzinf_text_buffer == NULL ) - { - fprintf(stderr, "cannot allocate lookahead text buffer (%d bytes)\n", - zzinf_text_buffer_size); - exit(PCCTS_EXIT_FAILURE); - } - zzinf_tokens = (int *) calloc(zzinf_token_buffer_size,sizeof(int)); - if ( zzinf_tokens == NULL ) - { - fprintf(stderr, "cannot allocate token buffer (%d tokens)\n", - zzinf_token_buffer_size); - exit(PCCTS_EXIT_FAILURE); - } - zzinf_line = (int *) calloc(zzinf_token_buffer_size,sizeof(int)); - if ( zzinf_line == NULL ) - { - fprintf(stderr, "cannot allocate line buffer (%d ints)\n", - zzinf_token_buffer_size); - exit(PCCTS_EXIT_FAILURE); - } - - /* get tokens, copying text to text buffer */ - zzinf_text_buffer_index = 0; - do { - zzgettok(); - line = zzreal_line; - while ( zzinf_lap>=zzinf_token_buffer_size ) - { - zzinf_token_buffer_size += ZZINF_BUFFER_TOKEN_CHUNK_SIZE; - zzinf_tokens = (int *) realloc(zzinf_tokens, - zzinf_token_buffer_size*sizeof(int)); - if ( zzinf_tokens == NULL ) - { - fprintf(stderr, "cannot allocate lookahead token buffer (%d tokens)\n", - zzinf_token_buffer_size); - exit(PCCTS_EXIT_FAILURE); - } - zzinf_line = (int *) realloc(zzinf_line, - zzinf_token_buffer_size*sizeof(int)); - if ( zzinf_line == NULL ) - { - fprintf(stderr, "cannot allocate lookahead line buffer (%d ints)\n", - zzinf_token_buffer_size); - exit(PCCTS_EXIT_FAILURE); - } - - } - while ( (zzinf_text_buffer_index+strlen(NLATEXT)+1) >= zzinf_text_buffer_size ) - { - zzinf_text_buffer_size += ZZINF_BUFFER_TEXT_CHUNK_SIZE; - zzinf_text_buffer = (char *) realloc(zzinf_text_buffer, - zzinf_text_buffer_size); - if ( zzinf_text_buffer == NULL ) - { - fprintf(stderr, "cannot allocate lookahead text buffer (%d bytes)\n", - zzinf_text_buffer_size); - exit(PCCTS_EXIT_FAILURE); - } - } - /* record token and text and line of input symbol */ - tok = zzinf_tokens[zzinf_lap] = NLA; - strcpy(&zzinf_text_buffer[zzinf_text_buffer_index], NLATEXT); - zzinf_text_buffer_index += strlen(NLATEXT)+1; - zzinf_line[zzinf_lap] = line; - zzinf_lap++; - } while (tok!=zzEOF_TOKEN); - zzinf_labase = 0; - zzinf_last = zzinf_lap-1; - - /* allocate ptrs to text of ith token */ - zzinf_text = (char **) calloc(zzinf_last+1,sizeof(char *)); - if ( zzinf_text == NULL ) - { - fprintf(stderr, "cannot allocate lookahead text buffer (%d)\n", - zzinf_text_buffer_size); - exit(PCCTS_EXIT_FAILURE); - } - zzinf_text_buffer_index = 0; - zzinf_lap = 0; - /* set ptrs so that zzinf_text[i] is the text of the ith token found on input */ - while (zzinf_lap<=zzinf_last) - { - zzinf_text[zzinf_lap++] = &zzinf_text_buffer[zzinf_text_buffer_index]; - zzinf_text_buffer_index += strlen(&zzinf_text_buffer[zzinf_text_buffer_index])+1; - } -} -#endif - -int -#ifdef __USE_PROTOS -_zzsetmatch(SetWordType *e, char **zzBadText, char **zzMissText, - int *zzMissTok, int *zzBadTok, - SetWordType **zzMissSet, - SetWordType *zzTokclassErrset /* MR23 */) -#else -_zzsetmatch(e, zzBadText, zzMissText, zzMissTok, zzBadTok, zzMissSet, zzTokclassErrset /* MR23 */) -SetWordType *e; -char **zzBadText; -char **zzMissText; -int *zzMissTok, *zzBadTok; -SetWordType **zzMissSet; -SetWordType *zzTokclassErrset; -#endif -{ -#ifdef DEMAND_LOOK -#ifdef LL_K - if ( zzdirty==LL_K ) {zzCONSUME;} -#else - if ( zzdirty ) {zzCONSUME;} -#endif -#endif - if ( !zzset_el((unsigned)LA(1), e) ) { - *zzBadText = LATEXT(1); *zzMissText=NULL; - *zzMissTok= 0; *zzBadTok=LA(1); - *zzMissSet=zzTokclassErrset; /* MR23 */ - return 0; - } - zzMakeAttr /* MR14 Ger Hobbelt (hobbelt@axa.nl) */ -#ifdef DEMAND_LOOK -#ifdef LL_K - zzdirty++; - zzlabase++; /* MR14 Ger Hobbelt (hobbelt@axa.nl) */ -#else - zzdirty = 1; -#endif -#endif - return 1; -} - -int -#ifdef __USE_PROTOS -_zzmatch_wdfltsig(int tokenWanted, SetWordType *whatFollows) -#else -_zzmatch_wdfltsig(tokenWanted, whatFollows) -int tokenWanted; -SetWordType *whatFollows; -#endif -{ -#ifdef DEMAND_LOOK -#ifdef LL_K - if ( zzdirty==LL_K ) { - zzCONSUME; - } -#else - if ( zzdirty ) {zzCONSUME;} -#endif -#endif - - if ( LA(1)!=tokenWanted ) - { - zzSyntaxErrCount++; /* MR11 */ - fprintf(stderr, - "line %d: syntax error at \"%s\" missing %s\n", - zzline, - (LA(1)==zzEOF_TOKEN)?"":(char *)LATEXT(1), - zztokens[tokenWanted]); - zzconsumeUntil( whatFollows ); - return 0; - } - else { - zzMakeAttr -#ifdef DEMAND_LOOK -#ifdef LL_K - zzdirty++; - zzlabase++; -#else - zzdirty = 1; -#endif -#else -/* zzCONSUME; consume if not demand lookahead */ -#endif - return 1; - } -} - -int -#ifdef __USE_PROTOS -_zzsetmatch_wdfltsig(SetWordType *tokensWanted, - int tokenTypeOfSet, - SetWordType *whatFollows) -#else -_zzsetmatch_wdfltsig(tokensWanted, tokenTypeOfSet, whatFollows) -SetWordType *tokensWanted; -int tokenTypeOfSet; -SetWordType *whatFollows; -#endif -{ -#ifdef DEMAND_LOOK -#ifdef LL_K - if ( zzdirty==LL_K ) {zzCONSUME;} -#else - if ( zzdirty ) {zzCONSUME;} -#endif -#endif - if ( !zzset_el((unsigned)LA(1), tokensWanted) ) - { - zzSyntaxErrCount++; /* MR11 */ - fprintf(stderr, - "line %d: syntax error at \"%s\" missing %s\n", - zzline, - (LA(1)==zzEOF_TOKEN)?"":(char *)LATEXT(1), - zztokens[tokenTypeOfSet]); - zzconsumeUntil( whatFollows ); - return 0; - } - else { - zzMakeAttr -#ifdef DEMAND_LOOK -#ifdef LL_K - zzdirty++; - zzlabase++; -#else - zzdirty = 1; -#endif -#else -/* zzCONSUME; consume if not demand lookahead */ -#endif - return 1; - } -} - -int -#ifdef __USE_PROTOS -_zzsetmatch_wsig(SetWordType *e) -#else -_zzsetmatch_wsig(e) -SetWordType *e; -#endif -{ -#ifdef DEMAND_LOOK -#ifdef LL_K - if ( zzdirty==LL_K ) {zzCONSUME;} -#else - if ( zzdirty ) {zzCONSUME;} -#endif -#endif - if ( !zzset_el((unsigned)LA(1), e) ) return 0; - zzMakeAttr /* MR14 Ger Hobbelt (hobbelt@axa.nl) */ -#ifdef DEMAND_LOOK -#ifdef LL_K - zzdirty++; - zzlabase++; /* MR14 Ger Hobbelt (hobbelt@axa.nl) */ -#else - zzdirty = 1; -#endif -#endif - return 1; -} - -#ifdef USER_ZZMODE_STACK -static int zzmstk[ZZMAXSTK] = { -1 }; -static int zzmdep = 0; -static char zzmbuf[70]; - -void -#ifdef __USE_PROTOS -zzmpush( int m ) -#else -zzmpush( m ) -int m; -#endif -{ - if(zzmdep == ZZMAXSTK - 1) { - sprintf(zzmbuf, "Mode stack overflow "); - zzerr(zzmbuf); - } else { - zzmstk[zzmdep++] = zzauto; - zzmode(m); - } -} - -void -#ifdef __USE_PROTOS -zzmpop( void ) -#else -zzmpop( ) -#endif -{ - if(zzmdep == 0) - { sprintf(zzmbuf, "Mode stack underflow "); - zzerr(zzmbuf); - } - else - { zzmdep--; - zzmode(zzmstk[zzmdep]); - } -} - -void -#ifdef __USE_PROTOS -zzsave_mode_stack( int modeStack[], int *modeLevel ) -#else -zzsave_mode_stack( modeStack, modeLevel ) -int modeStack[]; -int *modeLevel; -#endif -{ - int i; - memcpy(modeStack, zzmstk, sizeof(zzmstk)); - *modeLevel = zzmdep; - zzmdep = 0; - - return; -} - -void -#ifdef __USE_PROTOS -zzrestore_mode_stack( int modeStack[], int *modeLevel ) -#else -zzrestore_mode_stack( modeStack, modeLevel ) -int modeStack[]; -int *modeLevel; -#endif -{ - int i; - - memcpy(zzmstk, modeStack, sizeof(zzmstk)); - zzmdep = *modeLevel; - - return; -} -#endif /* USER_ZZMODE_STACK */ - -#ifdef __USE_PROTOS -void zzTraceReset(void) -#else -void zzTraceReset() -#endif -{ -#ifdef zzTRACE_RULES - zzTraceOptionValue=zzTraceOptionValueDefault; - zzTraceGuessOptionValue=1; - zzTraceCurrentRuleName=NULL; - zzTraceDepth=0; -#endif -} - -#ifdef __USE_PROTOS -void zzTraceGuessFail(void) -#else -void zzTraceGuessFail() -#endif -{ - -#ifdef zzTRACE_RULES -#ifdef ZZCAN_GUESS - - int doIt=0; - - if (zzTraceOptionValue <= 0) { - doIt=0; - } else if (zzguessing && zzTraceGuessOptionValue <= 0) { - doIt=0; - } else { - doIt=1; - }; - - if (doIt) { - fprintf(stderr,"guess failed\n"); - }; -#endif -#endif -} - -/* zzTraceOption: - zero value turns off trace -*/ - -#ifdef __USE_PROTOS -void zzTraceIn(char * rule) -#else -void zzTraceIn(rule) - char *rule; -#endif -{ -#ifdef zzTRACE_RULES - - int doIt=0; - - zzTraceDepth++; - zzTraceCurrentRuleName=rule; - - if (zzTraceOptionValue <= 0) { - doIt=0; -#ifdef ZZCAN_GUESS - } else if (zzguessing && zzTraceGuessOptionValue <= 0) { - doIt=0; -#endif - } else { - doIt=1; - }; - - if (doIt) { - fprintf(stderr,"enter rule %s {\"%s\"} depth %d", - rule, - LA(1)==1 ? "@" : (char *) LATEXT(1), /* MR19 */ - zzTraceDepth); -#ifdef ZZCAN_GUESS - if (zzguessing) fprintf(stderr," guessing"); -#endif - fprintf(stderr,"\n"); - }; -#endif - return; -} - -#ifdef __USE_PROTOS -void zzTraceOut(char * rule) -#else -void zzTraceOut(rule) - char *rule; -#endif -{ -#ifdef zzTRACE_RULES - int doIt=0; - - zzTraceDepth--; - - if (zzTraceOptionValue <= 0) { - doIt=0; -#ifdef ZZCAN_GUESS - } else if (zzguessing && zzTraceGuessOptionValue <= 0) { - doIt=0; -#endif - } else { - doIt=1; - }; - - if (doIt) { - fprintf(stderr,"exit rule %s {\"%s\"} depth %d", - rule, - LA(1)==1 ? "@" : (char *) LATEXT(1), /* MR19 */ - zzTraceDepth+1); -#ifdef ZZCAN_GUESS - if (zzguessing) fprintf(stderr," guessing"); -#endif - fprintf(stderr,"\n"); - }; -#endif -} - -#ifdef __USE_PROTOS -int zzTraceOption(int delta) -#else -int zzTraceOption(delta) - int delta; -#endif -{ -#ifdef zzTRACE_RULES - int prevValue=zzTraceOptionValue; - - zzTraceOptionValue=zzTraceOptionValue+delta; - - if (zzTraceCurrentRuleName != NULL) { - if (prevValue <= 0 && zzTraceOptionValue > 0) { - fprintf(stderr,"trace enabled in rule %s depth %d\n", - zzTraceCurrentRuleName,zzTraceDepth); - }; - if (prevValue > 0 && zzTraceOptionValue <= 0) { - fprintf(stderr,"trace disabled in rule %s depth %d\n", - zzTraceCurrentRuleName,zzTraceDepth); - }; - }; - return prevValue; -#else - return 0; -#endif -} - -#ifdef __USE_PROTOS -int zzTraceGuessOption(int delta) -#else -int zzTraceGuessOption(delta) - int delta; -#endif -{ -#ifdef zzTRACE_RULES -#ifdef ZZCAN_GUESS - int prevValue=zzTraceGuessOptionValue; - - zzTraceGuessOptionValue=zzTraceGuessOptionValue+delta; - - if (zzTraceCurrentRuleName != NULL) { - if (prevValue <= 0 && zzTraceGuessOptionValue > 0) { - fprintf(stderr,"guess trace enabled in rule %s depth %d\n", - zzTraceCurrentRuleName,zzTraceDepth); - }; - if (prevValue > 0 && zzTraceGuessOptionValue <= 0) { - fprintf(stderr,"guess trace disabled in rule %s depth %d\n", - zzTraceCurrentRuleName,zzTraceDepth); - }; - }; - return prevValue; -#else - return 0; -#endif -#else - return 0; -#endif -} - -#endif /* ERR_H */ diff --git a/Tools/CodeTools/TianoTools/Pccts/h/int.h b/Tools/CodeTools/TianoTools/Pccts/h/int.h deleted file mode 100644 index cdcaa92426..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/int.h +++ /dev/null @@ -1,37 +0,0 @@ -/* ANTLR attribute definition -- long integers - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * ANTLR 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -#ifndef ZZINT_H -#define ZZINT_H - -typedef long Attrib; - -#define zzcr_attr(a,tok,t) *(a) = atol(t); - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/pccts_assert.h b/Tools/CodeTools/TianoTools/Pccts/h/pccts_assert.h deleted file mode 100644 index ff0dfb5126..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/pccts_assert.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __PCCTS_ASSERT_H__ -#define __PCCTS_ASSERT_H__ - -#ifdef PCCTS_USE_NAMESPACE_STD -#include -#else -#include -#endif - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/pccts_iostream.h b/Tools/CodeTools/TianoTools/Pccts/h/pccts_iostream.h deleted file mode 100644 index 972b32cbd1..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/pccts_iostream.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __PCCTS_IOSTREAM_H__ -#define __PCCTS_IOSTREAM_H__ - -#ifdef PCCTS_USE_NAMESPACE_STD -#include -#else -#include -#endif - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/pccts_istream.h b/Tools/CodeTools/TianoTools/Pccts/h/pccts_istream.h deleted file mode 100644 index e25cb8c483..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/pccts_istream.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __PCCTS_ISTREAM_H__ -#define __PCCTS_ISTREAM_H__ - -#ifdef PCCTS_USE_NAMESPACE_STD -#include -#else -#include -#endif - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/pccts_setjmp.h b/Tools/CodeTools/TianoTools/Pccts/h/pccts_setjmp.h deleted file mode 100644 index 9ea185ca73..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/pccts_setjmp.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __PCCTS_SETJMP_H__ -#define __PCCTS_SETJMP_H__ - -#ifdef PCCTS_USE_NAMESPACE_STD -#include -#else -#include -#endif - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/pccts_stdarg.h b/Tools/CodeTools/TianoTools/Pccts/h/pccts_stdarg.h deleted file mode 100644 index e957430c32..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/pccts_stdarg.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __PCCTS_STDARG_H__ -#define __PCCTS_STDARG_H__ - -#ifdef PCCTS_USE_NAMESPACE_STD -#include -#else -#include -#endif - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/pccts_stdio.h b/Tools/CodeTools/TianoTools/Pccts/h/pccts_stdio.h deleted file mode 100644 index ac34d1086d..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/pccts_stdio.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __PCCTS_STDIO_H__ -#define __PCCTS_STDIO_H__ - -#ifdef PCCTS_USE_NAMESPACE_STD -#include -#else -#include -#endif - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/pccts_stdlib.h b/Tools/CodeTools/TianoTools/Pccts/h/pccts_stdlib.h deleted file mode 100644 index f0b344e8dc..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/pccts_stdlib.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __PCCTS_STDLIB_H__ -#define __PCCTS_STDLIB_H__ - -#ifdef PCCTS_USE_NAMESPACE_STD -#include -#else -#include -#endif - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/pccts_string.h b/Tools/CodeTools/TianoTools/Pccts/h/pccts_string.h deleted file mode 100644 index 458a08a94b..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/pccts_string.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __PCCTS_STRING_H__ -#define __PCCTS_STRING_H__ - -#ifdef PCCTS_USE_NAMESPACE_STD -#include -#else -#include -#endif - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/pcctscfg.h b/Tools/CodeTools/TianoTools/Pccts/h/pcctscfg.h deleted file mode 100644 index 0c3c5ba6fd..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/pcctscfg.h +++ /dev/null @@ -1,359 +0,0 @@ -#ifndef PCCTS_CONFIG_H -#define PCCTS_CONFIG_H -/* - * pcctscfg.h (formerly config.h) (for ANTLR, DLG, and SORCERER) - * - * This is a simple configuration file that doesn't have config stuff - * in it, but it's a start. - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to the Purdue Compiler Construction Tool - * Set (PCCTS) -- PCCTS is in the public domain. An individual or - * company may do whatever they wish with source code distributed with - * PCCTS or the code generated by PCCTS, including the incorporation of - * PCCTS, or its output, into commerical software. - * - * We encourage users to develop software with PCCTS. However, we do ask - * that credit is given to us for developing PCCTS. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like PCCTS and have developed a nice tool with the - * output, please mention that you developed it using PCCTS. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * Used by PCCTS 1.33 (SORCERER 1.00B11 and up) - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1989-2000 - */ - -/* This file knows about the following ``environments'' - UNIX (default) - DOS (use #define PC) - MAC (use #define MPW; has a few things for THINK C, Metrowerks) - MS/C++ (MR14 Microsoft Visual C++ environment uses symbol _MSC_VER) - - */ - -/* should test __STDC__ for 1, but some compilers don't set value, just def */ - -#ifndef __USE_PROTOS -#ifdef __STDC__ -#define __USE_PROTOS -#endif -#ifdef __cplusplus -#define __USE_PROTOS -#endif -#endif - -#ifdef PCCTS_USE_NAMESPACE_STD -#define PCCTS_NAMESPACE_STD namespace std {}; using namespace std; -#else -#define PCCTS_NAMESPACE_STD -#endif - -#include "pccts_stdio.h" -#include "pccts_stdlib.h" - -/* largest file name size */ - -#ifdef _MAX_PATH -#define MaxFileName _MAX_PATH /* MR9 RJV: MAX_PATH defined in stdlib.h (MSVC++ 5.0) */ -#else -#define MaxFileName 300 -#endif - -/* -* Define PC32 if in a 32-bit PC environment (e.g. extended DOS or Win32). -* The macros tested here are defined by Watcom, Microsoft, Borland, -* and djgpp, respectively, when they are used as 32-bit compilers. -* Users of these compilers *must* be sure to define PC in their -* makefiles for this to work correctly. -*/ -#ifdef PC -# if (defined(__WATCOMC__) || defined(_WIN32) || defined(__WIN32__) || \ - defined(__GNUC__) || defined(__GNUG__)) -# ifndef PC32 -# define PC32 -# endif -# endif -#endif - -/* MR1 10-Apr-97 Default for PC is short file names */ -/* MR1 Default for non-PC is long file names */ -/* MR1 Can override via command line option LONGFILENAMES */ - -#ifndef LONGFILENAMES -#ifndef PC -#define LONGFILENAMES -#endif -#endif - -#ifndef LONGFILENAMES -#define ATOKEN_H "AToken.h" -#define ATOKPTR_H "ATokPtr.h" -#define ATOKPTR_IMPL_H "ATokPtrIm.h" -#define ATOKENBUFFER_H "ATokBuf.h" -#define ATOKENBUFFER_C "ATokBuf.cpp" -#define ATOKENSTREAM_H "ATokStr.h" -#define APARSER_H "AParser.h" -#define APARSER_C "AParser.cpp" -#define ASTBASE_H "ASTBase.h" -#define ASTBASE_C "ASTBase.cpp" -#define PCCTSAST_C "PCCTSAST.cpp" -#define LIST_C "List.cpp" -#define DLEXERBASE_H "DLexBase.h" -#define DLEXERBASE_C "DLexBase.cpp" -#define DLEXER_H "DLexer.h" -#define STREESUPPORT_C "STreeSup.C" -#else -#define ATOKEN_H "AToken.h" -#define ATOKPTR_H "ATokPtr.h" -#define ATOKPTR_IMPL_H "ATokPtrImpl.h" -#define ATOKENBUFFER_H "ATokenBuffer.h" -#define ATOKENBUFFER_C "ATokenBuffer.cpp" -#define ATOKENSTREAM_H "ATokenStream.h" -#define APARSER_H "AParser.h" -#define APARSER_C "AParser.cpp" -#define ASTBASE_H "ASTBase.h" -#define ASTBASE_C "ASTBase.cpp" -#define PCCTSAST_C "PCCTSAST.cpp" -#define LIST_C "List.cpp" -#define DLEXERBASE_H "DLexerBase.h" -#define DLEXERBASE_C "DLexerBase.cpp" -#define DLEXER_H "DLexer.h" -#define STREESUPPORT_C "STreeSupport.cpp" -#endif - -/* SORCERER Stuff */ - -/* MR8 6-Aug-97 Change from ifdef PC to ifndef LONGFILENAMES */ - -#ifndef LONGFILENAMES -#define STPARSER_H "STreePar.h" -#define STPARSER_C "STreePar.C" -#else -#define STPARSER_H "STreeParser.h" -#define STPARSER_C "STreeParser.cpp" -#endif - -#ifdef MPW -#define CPP_FILE_SUFFIX ".cp" -#define CPP_FILE_SUFFIX_NO_DOT "cp" -#define OBJ_FILE_SUFFIX ".o" -#else -#ifdef PC -#define CPP_FILE_SUFFIX ".cpp" -#define CPP_FILE_SUFFIX_NO_DOT "cpp" -#define OBJ_FILE_SUFFIX ".obj" -#else -#ifdef __VMS -#define CPP_FILE_SUFFIX ".cpp" -#define CPP_FILE_SUFFIX_NO_DOT "cpp" -#define OBJ_FILE_SUFFIX ".obj" -#else -#define CPP_FILE_SUFFIX ".cpp" -#define CPP_FILE_SUFFIX_NO_DOT "cpp" -#define OBJ_FILE_SUFFIX ".o" -#endif -#endif -#endif - -/* User may redefine how line information looks */ /* make it #line MR7 */ -/* MR21 Use #ifndef */ - -#ifndef LineInfoFormatStr -#define LineInfoFormatStr "#line %d \"%s\"\n" -#endif - -#ifdef MPW /* Macintosh Programmer's Workshop */ -#define ErrHdr "File \"%s\"; Line %d #" -#else -#ifdef _MSC_VER /* MR14 Microsoft Visual C++ environment */ -#define ErrHdr "%s(%d) :" -#else -#define ErrHdr "%s, line %d:" /* default */ -#endif -#endif - -/* must assume old K&R cpp here, can't use #if defined(..)... */ - -#ifdef MPW -#define TopDirectory ":" -#define DirectorySymbol ":" -#define OutputDirectoryOption "Directory where all output files should go (default=\":\")" -#else -#ifdef PC -#define TopDirectory "." -#define DirectorySymbol "\\" -#define OutputDirectoryOption "Directory where all output files should go (default=\".\")" -#else -#ifdef __VMS -#define TopDirectory "[000000]" -#define DirectorySymbol "]" -#define OutputDirectoryOption "Directory where all output files should go (default=\"[]\")" -#else -#define TopDirectory "." -#define DirectorySymbol "/" -#define OutputDirectoryOption "Directory where all output files should go (default=\".\")" -#endif -#endif -#endif - -#ifdef MPW - -/* Make sure we have prototypes for all functions under MPW */ - -#include "pccts_string.h" -#include "pccts_stdlib.h" - -/* MR6 2-Jun-97 Fixes false dependency caused by VC++ #include scanner */ -/* MR6 Reported by Brad Schick (schick@interaccess.com) */ -#define MPW_CursorCtl_Header -#include MPW_CursorCtl_Header -#ifdef __cplusplus -extern "C" { -#endif -extern void fsetfileinfo (const char *filename, unsigned long newcreator, unsigned long newtype); -#ifdef __cplusplus -} -#endif - -/* File creators for various popular development environments */ - -#define MAC_FILE_CREATOR 'MPS ' /* MPW Text files */ -#if 0 -#define MAC_FILE_CREATOR 'KAHL' /* THINK C/Symantec C++ Text files */ -#endif -#if 0 -#define MAC_FILE_CREATOR 'CWIE' /* Metrowerks C/C++ Text files */ -#endif - -#endif - -#ifdef MPW -#define DAWDLE SpinCursor(1) -#else -#define DAWDLE -#endif - -#ifdef MPW -#define SPECIAL_INITS -#define SPECIAL_FOPEN -#endif - -#ifdef MPW -#ifdef __cplusplus -inline -#else -static -#endif -void special_inits() -{ - InitCursorCtl((acurHandle) 0); -} -#endif - -#ifdef MPW -#ifdef __cplusplus -inline -#else -static -#endif -void special_fopen_actions(char * s) -{ - fsetfileinfo (s, MAC_FILE_CREATOR, 'TEXT'); -} -#endif - -/* Define usable bits for set.c stuff */ -#define BytesPerWord sizeof(unsigned) -#define WORDSIZE (sizeof(unsigned)*8) -#define LogWordSize (WORDSIZE==16?4:5) - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -#if defined(VAXC) || defined(__VMS) -#include -#define PCCTS_EXIT_SUCCESS 1 -#define PCCTS_EXIT_FAILURE SS$_ABORT -#define zzDIE return SS$_ABORT; -#define zzDONE return 1; - -#else /* !VAXC and !__VMS */ - -#define PCCTS_EXIT_SUCCESS 0 -#define PCCTS_EXIT_FAILURE 1 -#define zzDIE return 1; -#define zzDONE return 0; - -#endif - -#ifdef USER_ZZMODE_STACK -# ifndef ZZSTACK_MAX_MODE -# define ZZSTACK_MAX_MODE 32 -# endif -# define ZZMAXSTK (ZZSTACK_MAX_MODE * 2) -#endif - -#ifndef DllExportPCCTS -#define DllExportPCCTS -#endif - -#ifdef PC -#ifndef PCCTS_CASE_INSENSITIVE_FILE_NAME -#define PCCTS_CASE_INSENSITIVE_FILE_NAME -#endif -#endif - -#ifdef PC32 -#ifndef PCCTS_CASE_INSENSITIVE_FILE_NAME -#define PCCTS_CASE_INSENSITIVE_FILE_NAME -#endif -#endif - -#ifdef __VMS -#ifndef PCCTS_CASE_INSENSITIVE_FILE_NAME -#define PCCTS_CASE_INSENSITIVE_FILE_NAME -#endif -#endif - -#ifdef __USE_PROTOS -#ifndef PCCTS_USE_STDARG -#define PCCTS_USE_STDARG -#endif -#endif - -#ifdef __STDC__ -#ifndef PCCTS_USE_STDARG -#define PCCTS_USE_STDARG -#endif -#endif - -#ifdef __cplusplus -#ifndef PCCTS_USE_STDARG -#define PCCTS_USE_STDARG -#endif -#endif - -#ifdef _MSC_VER -/*Turn off the warnings for: - unreferenced inline/local function has been removed -*/ -#pragma warning(disable : 4514) -/* function not expanded */ -#pragma warning(disable : 4710) -#endif - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/h/pcnames.bat b/Tools/CodeTools/TianoTools/Pccts/h/pcnames.bat deleted file mode 100644 index 8784aee9ab..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/pcnames.bat +++ /dev/null @@ -1,11 +0,0 @@ -ren aparser.c aparser.cpp -ren astbase.c astbase.cpp -ren atokenbu.c atokbuf.cpp -ren atokenbu.h atokbuf.h -ren atokenst.h atokstr.h -ren dlexerba.c dlexbase.cpp -ren dlexerba.h dlexbase.h -ren dlexer.c dlexer.cpp -ren list.c list.cpp -ren pblackbo.h pblckbox.h -ren pcctsast.c pcctsast.cpp diff --git a/Tools/CodeTools/TianoTools/Pccts/h/slist.cpp b/Tools/CodeTools/TianoTools/Pccts/h/slist.cpp deleted file mode 100644 index faf2fe4967..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/h/slist.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - * SList.C - * - * SOFTWARE RIGHTS - * - * We reserve no LEGAL rights to SORCERER -- SORCERER is in the public - * domain. An individual or company may do whatever they wish with - * source code distributed with SORCERER or the code generated by - * SORCERER, including the incorporation of SORCERER, or its output, into - * commerical software. - * - * We encourage users to develop software with SORCERER. However, we do - * ask that credit is given to us for developing SORCERER. By "credit", - * we mean that if you incorporate our source code into one of your - * programs (commercial product, research project, or otherwise) that you - * acknowledge this fact somewhere in the documentation, research report, - * etc... If you like SORCERER and have developed a nice tool with the - * output, please mention that you developed it using SORCERER. In - * addition, we ask that this header remain intact in our source code. - * As long as these guidelines are kept, we expect to continue enhancing - * this system and expect to make other tools available as they are - * completed. - * - * PCCTS 1.33 - * Terence Parr - * Parr Research Corporation - * with Purdue University and AHPCRC, University of Minnesota - * 1992-2000 - */ - -#define ANTLR_SUPPORT_CODE - -#include "SList.h" -#include "pccts_stdarg.h" // MR23 - -/* Iterate over a list of elements; returns ptr to a new element - * in list upon every call and NULL when no more are left. - * Very useful like this: - * - * cursor = mylist; - * while ( (p=mylist->iterate(&cursor)) ) { - * // place with element p - * } - * - * The cursor must be initialized to point to the list to iterate over. - */ -void *SList:: -iterate(SListNode **cursor) -{ - void *e; - - if ( cursor == NULL || *cursor==NULL ) return NULL; - if ( head == *cursor ) { *cursor = (*cursor)->next(); } - e = (*cursor)->elem(); - (*cursor) = (*cursor)->next(); - return e; -} - -/* add an element to end of list. */ -void SList:: -add(void *e) -{ - SListNode *p, *tail=NULL; - require(e!=NULL, "slist_add: attempting to add NULL list element"); - - p = new SListNode; - require(p!=NULL, "add: cannot alloc new list node"); - p->setElem(e); - if ( head == NULL ) - { - head = tail = p; - } - else /* find end of list */ - { - tail->setNext(p); - tail = p; - } -} - -void SList:: -lfree() -{ - SListNode *p,*q; - - if ( head==NULL ) return; /* empty list */ - for (p = head; p!=NULL; p=q) - { - q = p->next(); - free(p); - } -} - -PCCTS_AST *SList:: -to_ast(SList list) -{ - PCCTS_AST *t=NULL, *last=NULL; - SListNode *p; - - for (p = head; p!=NULL; p=p->next()) - { - PCCTS_AST *u = (PCCTS_AST *)p->elem(); - if ( last==NULL ) last = t = u; - else { last->setRight(u); last = u; } - } - return t; -} - -// MR23 -int SList::printMessage(FILE* pFile, const char* pFormat, ...) -{ - va_list marker; - va_start( marker, pFormat ); - int iRet = vfprintf(pFile, pFormat, marker); - va_end( marker ); - return iRet; -} diff --git a/Tools/CodeTools/TianoTools/Pccts/history.ps b/Tools/CodeTools/TianoTools/Pccts/history.ps deleted file mode 100644 index e2600d5129..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/history.ps +++ /dev/null @@ -1,473 +0,0 @@ -%!PS-Adobe-3.0 -%%Creator: groff version 1.06 -%%DocumentNeededResources: font Times-Roman -%%+ font Times-Italic -%%+ font Courier -%%DocumentSuppliedResources: procset grops 1.06 0 -%%Pages: 3 -%%PageOrder: Ascend -%%Orientation: Portrait -%%EndComments -%%BeginProlog -%%BeginResource: procset grops 1.06 0 - -/setpacking where { - pop - currentpacking - true setpacking -} if - -/grops 120 dict dup begin - -% The ASCII code of the space character. -/SC 32 def - -/A /show load def -/B { 0 SC 3 -1 roll widthshow } bind def -/C { 0 exch ashow } bind def -/D { 0 exch 0 SC 5 2 roll awidthshow } bind def -/E { 0 rmoveto show } bind def -/F { 0 rmoveto 0 SC 3 -1 roll widthshow } bind def -/G { 0 rmoveto 0 exch ashow } bind def -/H { 0 rmoveto 0 exch 0 SC 5 2 roll awidthshow } bind def -/I { 0 exch rmoveto show } bind def -/J { 0 exch rmoveto 0 SC 3 -1 roll widthshow } bind def -/K { 0 exch rmoveto 0 exch ashow } bind def -/L { 0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow } bind def -/M { rmoveto show } bind def -/N { rmoveto 0 SC 3 -1 roll widthshow } bind def -/O { rmoveto 0 exch ashow } bind def -/P { rmoveto 0 exch 0 SC 5 2 roll awidthshow } bind def -/Q { moveto show } bind def -/R { moveto 0 SC 3 -1 roll widthshow } bind def -/S { moveto 0 exch ashow } bind def -/T { moveto 0 exch 0 SC 5 2 roll awidthshow } bind def - -% name size font SF - - -/SF { - findfont exch - [ exch dup 0 exch 0 exch neg 0 0 ] makefont - dup setfont - [ exch /setfont cvx ] cvx bind def -} bind def - -% name a c d font MF - - -/MF { - findfont - [ 5 2 roll - 0 3 1 roll % b - neg 0 0 ] makefont - dup setfont - [ exch /setfont cvx ] cvx bind def -} bind def - -/level0 0 def -/RES 0 def -/PL 0 def -/LS 0 def - -% Guess the page length. -% This assumes that the imageable area is vertically centered on the page. -% PLG - length - -/PLG { - gsave newpath clippath pathbbox grestore - exch pop add exch pop -} bind def - -% BP - - -/BP { - /level0 save def - 1 setlinecap - 1 setlinejoin - 72 RES div dup scale - LS { - 90 rotate - } { - 0 PL translate - } ifelse - 1 -1 scale -} bind def - -/EP { - level0 restore - showpage -} bind def - - -% centerx centery radius startangle endangle DA - - -/DA { - newpath arcn stroke -} bind def - -% x y SN - x' y' -% round a position to nearest (pixel + (.25,.25)) - -/SN { - transform - .25 sub exch .25 sub exch - round .25 add exch round .25 add exch - itransform -} bind def - -% endx endy startx starty DL - -% we round the endpoints of the line, so that parallel horizontal -% and vertical lines will appear even - -/DL { - SN - moveto - SN - lineto stroke -} bind def - -% centerx centery radius DC - - -/DC { - newpath 0 360 arc closepath -} bind def - - -/TM matrix def - -% width height centerx centery DE - - -/DE { - TM currentmatrix pop - translate scale newpath 0 0 .5 0 360 arc closepath - TM setmatrix -} bind def - -% these are for splines - -/RC /rcurveto load def -/RL /rlineto load def -/ST /stroke load def -/MT /moveto load def -/CL /closepath load def - -% fill the last path - -% amount FL - - -/FL { - currentgray exch setgray fill setgray -} bind def - -% fill with the ``current color'' - -/BL /fill load def - -/LW /setlinewidth load def -% new_font_name encoding_vector old_font_name RE - - -/RE { - findfont - dup maxlength dict begin - { - 1 index /FID ne { def } { pop pop } ifelse - } forall - /Encoding exch def - dup /FontName exch def - currentdict end definefont pop -} bind def - -/DEFS 0 def - -% hpos vpos EBEGIN - - -/EBEGIN { - moveto - DEFS begin -} bind def - -/EEND /end load def - -/CNT 0 def -/level1 0 def - -% llx lly newwid wid newht ht newllx newlly PBEGIN - - -/PBEGIN { - /level1 save def - translate - div 3 1 roll div exch scale - neg exch neg exch translate - % set the graphics state to default values - 0 setgray - 0 setlinecap - 1 setlinewidth - 0 setlinejoin - 10 setmiterlimit - [] 0 setdash - /setstrokeadjust where { - pop - false setstrokeadjust - } if - /setoverprint where { - pop - false setoverprint - } if - newpath - /CNT countdictstack def - userdict begin - /showpage {} def -} bind def - -/PEND { - clear - countdictstack CNT sub { end } repeat - level1 restore -} bind def - -end def - -/setpacking where { - pop - setpacking -} if -%%EndResource -%%IncludeResource: font Times-Roman -%%IncludeResource: font Times-Italic -%%IncludeResource: font Courier -grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL -792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron -/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef -/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef -/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space -/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft -/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four -/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C -/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash -/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q -/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase -/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger -/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut -/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash -/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar -/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus -/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu -/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright -/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde -/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute -/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis -/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls -/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute -/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve -/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex -/udieresis/yacute/thorn/ydieresis]def/Courier@0 ENC0/Courier RE/Times-Italic@0 -ENC0/Times-Italic RE/Times-Roman@0 ENC0/Times-Roman RE -%%EndProlog -%%Page: 1 1 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 13/Times-Roman@0 SF(The History of PCCTS)228.232 84 Q/F1 11/Times-Roman@0 -SF(The Purdue Compiler)190.468 108 Q(-Construction T)-.22 E(ool Set)-.88 E/F2 -10/Times-Italic@0 SF -.92(Te)262.245 144 S -.37(re).92 G(nce P).37 E(arr)-.8 E -/F3 10/Times-Roman@0 SF -.15(Pa)234.755 156 S(rr Research Corporation).15 E -(Minneapolis, Minnesota)239.39 168 Q(and)280.78 180 Q(Uni)239.315 192 Q -.15 -(ve)-.25 G(rsity of Minnesota).15 E -(Army High Performance Computing Research Center)180.38 204 Q F2 -([Updated 8-7-94])252.31 228 Q F1 .084(The PCCTS project be)97 259.6 R -.055 -(ga)-.165 G 2.834(na).055 G 2.833(sap)220.547 259.6 S(arser)240.876 259.6 Q -.083(-generator project for a graduate course at Purdue Uni-)-.22 F -.165(ve)72 -275.6 S 1.085(rsity in the F).165 F 1.086 -(all of 1988 taught by Hank Dietz\212 translator)-.165 F 1.086 -(-writing systems.)-.22 F 1.086(Under the guid-)6.586 F .627 -(ance of Professor Dietz, the parser generator)72 291.6 R 3.377(,A)-.44 G .626 -(NTLR \(originally called YUCC\), continued after)285.18 291.6 R .253 -(the termination of the course and e)72 307.6 R -.165(ve)-.275 G .254 -(ntually became the subject of T).165 F .254(erence P)-.77 F(arr')-.165 E 3.004 -(sM)-.605 G(aster')445.083 307.6 Q 3.004(st)-.605 G(hesis.)479.25 307.6 Q -(Originally)72 323.6 Q 4.092(,l)-.715 G -.165(ex)126.406 323.6 S 1.342 -(ical analysis w).165 F 1.342(as performed via ALX which w)-.11 F 1.342 -(as soon replaced by W)-.11 F 1.341(ill Cohen')-.44 F(s)-.605 E .594 -(DLG in the F)72 339.6 R .594(all of 1989 \(DF)-.165 F .595(A-based le)-.814 F -.595(xical-analyzer generator)-.165 F 3.345(,a)-.44 G .595(lso an of)367.188 -339.6 R .595(fshoot of the graduate)-.275 F(translation course\).)72 355.6 Q -.877(The alpha v)97 375.2 R .877(ersion of ANTLR w)-.165 F .877(as totally re) --.11 F .876(written resulting in 1.00B.)-.275 F -1.221(Ve)6.376 G .876 -(rsion 1.00B w)1.221 F(as)-.11 E 1.577(released via an internet ne)72 391.2 R -1.577(wsgroup \(comp.compilers\) posting in February of 1990 and quickly)-.275 -F -.055(ga)72 407.2 S .356(thered a lar).055 F .356(ge follo)-.198 F 3.106 -(wing. 1.00B)-.275 F .356(generated only LL\(1\) parsers, b)3.106 F .356 -(ut allo)-.22 F .356(wed the mer)-.275 F .356(ged descrip-)-.198 F 1.859 -(tion of le)72 423.2 R 1.859(xical and syntactic analysis.)-.165 F 1.86 -(It had rudimentary attrib)7.359 F 1.86(ute handling similar to that of)-.22 F --.55 -1.32(YA C)72 439.2 T 3.549(Ca)1.32 G .799 -(nd did not incorporate rule parameters or return v)109.231 439.2 R .798 -(alues; do)-.275 F(wnw)-.275 E .798(ard inheritance w)-.11 F .798(as v)-.11 F -(ery)-.165 E -.165(aw)72 455.2 S(kw).165 E 6.433(ard. 1.00B-generated)-.11 F -3.684(parsers terminated upon the \214rst syntax error)6.433 F 9.184(.L)-.605 G --.165(ex)440.916 455.2 S 3.684(ical classes).165 F(\(modes\) were not allo)72 -471.2 Q(wed and DLG did not ha)-.275 E .33 -.165(ve a)-.22 H 2.75(ni).165 G -(nteracti)305.959 471.2 Q .33 -.165(ve m)-.275 H(ode.).165 E .831 -(Upon starting his Ph.D. at Purdue in the F)97 490.8 R .83(all of 1990, T)-.165 -F .83(erence P)-.77 F .83(arr be)-.165 F -.055(ga)-.165 G 3.58(nt).055 G .83 -(he second total)436.351 490.8 R(re)72 506.8 Q 1.646(write of ANTLR.)-.275 F -1.646(The method by which grammars may be practically analyzed to generate) -7.146 F/F4 11/Times-Italic@0 SF(LL)72.638 522.8 Q F1(\().583 E F4(k).396 E F1 -3.849(\)l).737 G 1.099(ookahead information w)105.703 522.8 R 1.099(as disco) --.11 F -.165(ve)-.165 G 1.099(red in August of 1990 just before his return.) -.165 F -1.221(Ve)6.598 G(rsion)1.221 E .626 -(1.00 incorporated this algorithm and included the AST mechanism, le)72 538.8 R -.626(xical classes, error classes,)-.165 F .354(and automatic error reco)72 -554.8 R -.165(ve)-.165 G .353(ry; code quality and portability were higher).165 -F 5.853(.I)-.605 G 3.103(nF)395.965 554.8 S .353(ebruary of 1992 1.00)410.684 -554.8 R -.11(wa)72 570.8 S 2.76(sr).11 G .01 -(eleased via an article in SIGPLAN Notices.)95.418 570.8 R .01 -(Peter Dahl, Ph.D. candidate, and Professor Matt)5.51 F(O'K)72 586.8 Q 2.074 -(eefe \(both at the Uni)-.275 F -.165(ve)-.275 G 2.073 -(rsity of Minnesota\) tested this v).165 F 2.073(ersion e)-.165 F(xtensi)-.165 -E -.165(ve)-.275 G(ly).165 E 7.573(.D)-.715 G 2.073(ana Hogg)448.522 586.8 R -(att)-.055 E .078(\(Micro Data Base Systems, Inc.\) came up with the idea of e\ -rror grouping \(strings attached to non-)72 602.8 R -(terminals\) and tested 1.00 hea)72 618.8 Q(vily)-.22 E(.)-.715 E -1.221(Ve)97 -638.4 S .878(rsion 1.06 w)1.221 F .877 -(as released in December 1992 and represented a lar)-.11 F .877 -(ge feature enhancement)-.198 F -.165(ove)72 654.4 S 3.648(r1).165 G 3.648 -(.00. F)100.365 654.4 R .898(or e)-.165 F .899 -(xample, rudimentary semantic predicates were introduced, error messages were) --.165 F 2.281(signi\214cantly impro)72 670.4 R -.165(ve)-.165 G 5.031(df).165 G -(or)181.953 670.4 Q F4(k)5.427 E F1 2.281 -(>1 lookahead and ANTLR parsers could indicate that lookahead).737 F 1.381 -(fetches were to occur only when necessary for the parse \(normally)72 686.4 R -4.131(,t)-.715 G 1.381(he lookahead `)387.051 686.4 R(`pipe')-.814 E 4.132('w) --.814 G(as)494.837 686.4 Q 1.182(constantly full\).)72 702.4 R 1.182 -(Russell Quong joined the project in the Spring of 1992 to aid in the semantic) -6.682 F .681(predicate design.)72 718.4 R(Be)6.181 E .681(ginning and adv)-.165 -F .682(anced tutorials were created and released as well.)-.275 F 3.432(Am) -6.182 G(ak)485.179 718.4 Q(e-)-.11 E .993(\214le generator w)72 734.4 R .993 -(as included that sets up dependencies and such correctly for ANTLR and DLG.) --.11 F EP -%%Page: 2 2 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 11/Times-Roman@0 SF 2.75(-2-)278.837 52 S -1.221(Ve)72 88 S 1.414(ry fe) -1.221 F 4.164(w1)-.275 G 1.414(.00 incompatibilities were introduced \(1.00 w) -122.81 88 R 1.415(as quite dif)-.11 F 1.415(ferent from 1.00B in some)-.275 F -(areas\).)72 104 Q 1.089(1.10 w)97 123.6 R 1.088 -(as released on August 31, 1993 and incorporated b)-.11 F 1.088(ug \214x)-.22 F -1.088(es, a fe)-.165 F 3.838(wf)-.275 G 1.088(eature enhance-)433.59 123.6 R -3.112(ments and a major ne)72 139.6 R 5.863(wc)-.275 G(apability \212)196.957 -139.6 Q 3.113(an arbitrary lookahead operator \(syntactic predicate\),)5.863 F -/F1 11/Courier@0 SF(\(alpha\)?beta)72 155.6 Q F0 6.754(.T)C 1.254 -(his feature w)167.425 155.6 R 1.254 -(as co-designed with Professor Russell Quong also at Purdue.)-.11 F 3.297 -.88 -(To s)72 171.6 T 1.537 -(upport in\214nite lookahead, a preprocessor \215ag, ZZINF_LOOK, w).88 F 1.537 -(as created that forced the)-.11 F .21(ANTLR\(\) macro to tok)72 187.6 R .21 -(enize all input prior to parsing.)-.11 F .209(Hence, at an)5.709 F 2.959(ym) --.165 G .209(oment, an action or predi-)389.215 187.6 R .936 -(cate can see the entire input sentence.)72 203.6 R .936 -(The predicate mechanism of 1.06 w)6.436 F .937(as e)-.11 F .937 -(xtended to allo)-.165 F(w)-.275 E .55 -(multiple predicates to be hoisted; the syntactic conte)72 219.6 R .55 -(xt of a predicate w)-.165 F .55(as also mo)-.11 F -.165(ve)-.165 G 3.299(da) -.165 G .549(long with)461.585 219.6 R(the predicate.)72 235.6 Q .754 -(In February of 1994, SORCERER \(a simple tree-parser generator\) w)97 255.2 R -.755(as released.)-.11 F .755(This tool)6.255 F(allo)72 271.2 Q .6(ws the user\ - to parse child-sibling trees by specifying a grammar rather than b)-.275 F -.599(uilding a recur)-.22 F(-)-.22 E(si)72 287.2 Q -.165(ve)-.275 G 1.39 -(-descent tree w).165 F(alk)-.11 E 1.391(er by hand.)-.11 F -.88(Wo)6.891 G -1.391(rk to).88 F -.11(wa)-.275 G 1.391 -(rds a library of tree transformations is underw).11 F(ay)-.11 E(.)-.715 E .581 -(Aaron Sa)72 303.2 R(wde)-.165 E 3.331(ya)-.165 G 3.331(tT)145.531 303.2 S .581 -(he Uni)158.641 303.2 R -.165(ve)-.275 G .58 -(rsity of Minnesota became a second author of SORCERER after the).165 F -(initial release.)72 319.2 Q .627(On April 1, 1994, PCCTS 1.20 w)97 338.8 R -.627(as released.)-.11 F .627(This w)6.127 F .627(as the \214rst v)-.11 F .627 -(ersion to acti)-.165 F -.165(ve)-.275 G .627(ly support).165 F 1.664 -(C++ output.)72 354.8 R 1.664(It also included important \214x)7.164 F 1.663 -(es re)-.165 F -.055(ga)-.165 G 1.663 -(rding semantic predicates and \(..\)+ subrules.).055 F(This v)72 370.8 Q -(ersion also introduced tok)-.165 E(en classes, the `)-.11 E(`)-.814 E/F2 11 -/Times-Italic@0 SF(not)A F0 1.628 -.814('' o)D(perator).814 E 2.75(,a)-.44 G -(nd tok)355.294 370.8 Q(en ranges.)-.11 E .764 -(On June 19, 1994, SORCERER 1.00B9 w)97 390.4 R .765(as released.)-.11 F .765 -(Gary Funck of Intrepid T)6.265 F(echnology)-.77 E .807 -(joined the SORCERER team and pro)72 406.4 R .807(vided v)-.165 F .807(ery v) --.165 F .807(aluable suggestions re)-.275 F -.055(ga)-.165 G .806(rding the `) -.055 F(`transform')-.814 E(')-.814 E(mode of SORCERER.)72 422.4 Q 1.137 -(On August 8, 1994, PCCTS 1.21 w)97 442 R 1.137(as released.)-.11 F 1.138 -(It mainly cleaned up the C++ output and)6.637 F(included a number of b)72 458 -Q(ug \214x)-.22 E(es.)-.165 E .316(From the 1.21 release forw)97 477.6 R .316 -(ard, the maintenance and support of all PCCTS tools will be pri-)-.11 F 1.557 -(marily pro)72 493.6 R 1.557(vided by P)-.165 F 1.557 -(arr Research Corporation, Minneapolis MN---an or)-.165 F -.055(ga)-.198 G -1.558(nization founded on).055 F 1.616(the principles of e)72 509.6 R 1.616 -(xcellence in research and inte)-.165 F 1.616(grity in b)-.165 F 1.616 -(usiness; we are de)-.22 F -.22(vo)-.275 G 1.616(ted to pro).22 F(viding)-.165 -E 1.202(really cool softw)72 525.6 R 1.202(are tools.)-.11 F 1.202 -(Please see \214le PCCTS.FUTURE for more information.)6.702 F 1.203(All PCCTS) -6.703 F(tools currently in the public domain will continue to be in the public\ - domain.)72 541.6 Q 1.198(Looking to)97 561.2 R -.11(wa)-.275 G 1.198 -(rds the future, a graphical user).11 F(-interf)-.22 E 1.197 -(ace is in the design phase.)-.11 F 1.197(This w)6.697 F(ould)-.11 E(allo)72 -577.2 Q 2.753(wu)-.275 G .003(sers to vie)104.42 577.2 R 2.753(wt)-.275 G .004 -(he syntax diagram representation of their grammars and w)162.509 577.2 R .004 -(ould highlight non-)-.11 F 1.181(deterministic productions.)72 593.2 R -.165 -(Pa)6.681 G 1.18(rsing can be traced graphically as well.).165 F 1.18 -(This system will be b)6.68 F(uilt)-.22 E .167(using a multiplatform windo)72 -609.2 R 2.917(wl)-.275 G(ibrary)211.73 609.2 Q 5.667(.W)-.715 G 2.917(ea) -255.204 609.2 S .168(lso anticipate the introduction of a sophisticated error) -267.889 609.2 R(handling mechanism called `)72 625.2 Q(`parser e)-.814 E -(xception handling')-.165 E 2.75('i)-.814 G 2.75(nan)327.431 625.2 S -(ear future release.)348.815 625.2 Q(Currently)97 644.8 Q 3.019(,P)-.715 G .269 -(CCTS is used at o)150.333 644.8 R -.165(ve)-.165 G 3.019(r1).165 G .269 -(000 kno)253.098 644.8 R .268(wn academic, go)-.275 F -.165(ve)-.165 G .268 -(rnment, and commercial sites).165 F .859(in 37 countries.)72 660.8 R .859 -(Of course, the true number of users is unkno)6.359 F .859(wn due to the lar) --.275 F .859(ge number of ftp)-.198 F(sites.)72 676.8 Q EP -%%Page: 3 3 -%%BeginPageSetup -BP -%%EndPageSetup -/F0 11/Times-Roman@0 SF 2.75(-3-)278.837 52 S(Credits)272.11 88 Q .44 LW -472.162 103.75 103.838 103.75 DL(Idea/T)134.236 117 Q 52.987(ool Coder)-.88 F -(Co-designer\(s\))345.436 117 Q 281.334 103.75 281.334 124.75 DL 209.273 103.75 -209.273 124.75 DL 209.273 124.75 103.838 124.75 DL 103.838 126.75 209.273 -126.75 DL 281.334 124.75 209.273 124.75 DL 209.273 126.75 281.334 126.75 DL -472.162 124.75 281.334 124.75 DL 281.334 126.75 472.162 126.75 DL(ANTLR 1.00A) -109.338 140 Q -.77(Te)217.523 140 S(rence P).77 E 13.75(arr Hank)-.165 F(Dietz) -2.75 E 82.83(ALX T)109.338 156 R(erence P)-.77 E 13.75(arr Hank)-.165 F(Dietz) -2.75 E(ANTLR 1.00B)109.338 172 Q -.77(Te)217.523 172 S(rence P).77 E 13.75 -(arr Hank)-.165 F(Dietz, W)2.75 E(ill Cohen)-.44 E(DLG 1.00B)109.338 188 Q -.44 -(Wi)217.523 188 S(ll Cohen).44 E -.77(Te)289.584 188 S(rence P).77 E(arr)-.165 -E 2.75(,H)-.44 G(ank Dietz)358.147 188 Q(NF)109.338 204 Q 2.75(AR)-.814 G -30.778(elabelling W)140.611 204 R(ill Cohen)-.44 E/F1 11/Times-Italic@0 SF(LL) -109.976 220 Q F0(\().583 E F1(k).396 E F0 2.75(\)a).737 G 40.447(nalysis T) -143.768 220 R(erence P)-.77 E 13.75(arr Hank)-.165 F(Dietz)2.75 E(ANTLR 1.00) -109.338 236 Q -.77(Te)217.523 236 S(rence P).77 E 13.75(arr Hank)-.165 F -(Dietz, W)2.75 E(ill Cohen)-.44 E(DLG 1.00)109.338 252 Q -.44(Wi)217.523 252 S -(ll Cohen).44 E -.77(Te)289.584 252 S(rence P).77 E(arr)-.165 E 2.75(,H)-.44 G -(ank Dietz)358.147 252 Q(ANTLR 1.06)109.338 268 Q -.77(Te)217.523 268 S -(rence P).77 E 13.75(arr W)-.165 F(ill Cohen, Russell Quong, Hank Dietz)-.44 E -(DLG 1.06)109.338 284 Q -.44(Wi)217.523 284 S(ll Cohen).44 E -.77(Te)289.584 -284 S(rence P).77 E(arr)-.165 E 2.75(,H)-.44 G(ank Dietz)358.147 284 Q -(ANTLR 1.10)109.338 300 Q -.77(Te)217.523 300 S(rence P).77 E 13.75(arr W)-.165 -F(ill Cohen, Russell Quong)-.44 E(ANTLR 1.20)109.338 316 Q -.77(Te)217.523 316 -S(rence P).77 E 13.75(arr W)-.165 F(ill Cohen, Russell Quong)-.44 E(ANTLR 1.21) -109.338 332 Q -.77(Te)217.523 332 S(rence P).77 E 13.75(arr Russell)-.165 F -(Quong)2.75 E(DLG 1.10)109.338 348 Q -.44(Wi)217.523 348 S(ll Cohen).44 E -.77 -(Te)289.584 348 S(rence P).77 E(arr)-.165 E(DLG 1.20)109.338 364 Q -.44(Wi) -217.523 364 S(ll Cohen).44 E -.77(Te)289.584 364 S(rence P).77 E(arr)-.165 E -(DLG 1.21)109.338 380 Q -.77(Te)217.523 380 S(rence P).77 E(arr)-.165 E -(Semantic predicates)109.338 396 Q -.77(Te)217.523 396 S(rence P).77 E 13.75 -(arr Russell)-.165 F(Quonq)2.75 E(Syntactic predicates)109.338 412 Q -.77(Te) -217.523 412 S(rence P).77 E 13.75(arr Russell)-.165 F(Quonq)2.75 E -(SORCERER 1.00A)109.338 428 Q -.77(Te)217.523 428 S(rence P).77 E(arr)-.165 E -(SORCERER 1.00B)109.338 444 Q -.77(Te)217.523 444 S(rence P).77 E 13.75 -(arr Aaron)-.165 F(Sa)2.75 E(wde)-.165 E(y)-.165 E(SORCERER 1.00B9)109.338 460 -Q -.77(Te)217.523 460 S(rence P).77 E 13.75(arr Aaron)-.165 F(Sa)2.75 E(wde) --.165 E 1.43 -.715(y, G)-.165 H(ary Funck).715 E 472.162 467.75 103.838 467.75 -DL 472.162 103.75 472.162 467.75 DL 103.838 103.75 103.838 467.75 DL EP -%%Trailer -end -%%EOF diff --git a/Tools/CodeTools/TianoTools/Pccts/history.txt b/Tools/CodeTools/TianoTools/Pccts/history.txt deleted file mode 100644 index 89ad8408c9..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/history.txt +++ /dev/null @@ -1,186 +0,0 @@ - - - - The History of PCCTS - - The Purdue Compiler-Construction Tool Set - - - Terence Parr - Parr Research Corporation - Minneapolis, Minnesota - and - University of Minnesota - Army High Performance Computing Research Center - - [Updated 8-7-94] - - - The PCCTS project began as a parser-generator project for a gra- -duate course at Purdue University in the Fall of 1988 taught by Hank -Dietz- translator-writing systems. Under the guidance of Professor -Dietz, the parser generator, ANTLR (originally called YUCC), continued -after the termination of the course and eventually became the subject -of Terence Parr's Master's thesis. Originally, lexical analysis was -performed via ALX which was soon replaced by Will Cohen's DLG in the -Fall of 1989 (DFA-based lexical-analyzer generator, also an offshoot -of the graduate translation course). - - The alpha version of ANTLR was totally rewritten resulting in -1.00B. Version 1.00B was released via an internet newsgroup -(comp.compilers) posting in February of 1990 and quickly gathered a -large following. 1.00B generated only LL(1) parsers, but allowed the -merged description of lexical and syntactic analysis. It had rudimen- -tary attribute handling similar to that of YACC and did not incor- -porate rule parameters or return values; downward inheritance was very -awkward. 1.00B-generated parsers terminated upon the first syntax -error. Lexical classes (modes) were not allowed and DLG did not have -an interactive mode. - - Upon starting his Ph.D. at Purdue in the Fall of 1990, Terence -Parr began the second total rewrite of ANTLR. The method by which -grammars may be practically analyzed to generate LL(k) lookahead -information was discovered in August of 1990 just before his return. -Version 1.00 incorporated this algorithm and included the AST mechan- -ism, lexical classes, error classes, and automatic error recovery; -code quality and portability were higher. In February of 1992 1.00 -was released via an article in SIGPLAN Notices. Peter Dahl, Ph.D. -candidate, and Professor Matt O'Keefe (both at the University of Min- -nesota) tested this version extensively. Dana Hoggatt (Micro Data -Base Systems, Inc.) came up with the idea of error grouping (strings -attached to non-terminals) and tested 1.00 heavily. - - Version 1.06 was released in December 1992 and represented a -large feature enhancement over 1.00. For example, rudimentary seman- -tic predicates were introduced, error messages were significantly -improved for k>1 lookahead and ANTLR parsers could indicate that loo- -kahead fetches were to occur only when necessary for the parse - - - - Page 1 - - PCCTS - - -(normally, the lookahead "pipe" was constantly full). Russell Quong -joined the project in the Spring of 1992 to aid in the semantic predi- -cate design. Beginning and advanced tutorials were created and -released as well. A makefile generator was included that sets up -dependencies and such correctly for ANTLR and DLG. Very few 1.00 -incompatibilities were introduced (1.00 was quite different from 1.00B -in some areas). - - 1.10 was released on August 31, 1993 and incorporated bug fixes, -a few feature enhancements and a major new capability - an arbitrary -lookahead operator (syntactic predicate), (alpha)?beta. This feature -was co-designed with Professor Russell Quong also at Purdue. To sup- -port infinite lookahead, a preprocessor flag, ZZINF_LOOK, was created -that forced the ANTLR() macro to tokenize all input prior to parsing. -Hence, at any moment, an action or predicate can see the entire input -sentence. The predicate mechanism of 1.06 was extended to allow mul- -tiple predicates to be hoisted; the syntactic context of a predicate -was also moved along with the predicate. - - In February of 1994, SORCERER (a simple tree-parser generator) -was released. This tool allows the user to parse child-sibling trees -by specifying a grammar rather than building a recursive-descent tree -walker by hand. Work towards a library of tree transformations is -underway. Aaron Sawdey at The University of Minnesota became a second -author of SORCERER after the initial release. - - On April 1, 1994, PCCTS 1.20 was released. This was the first -version to actively support C++ output. It also included important -fixes regarding semantic predicates and (..)+ subrules. This version -also introduced token classes, the "not" operator, and token ranges. - - On June 19, 1994, SORCERER 1.00B9 was released. Gary Funck of -Intrepid Technology joined the SORCERER team and provided very valu- -able suggestions regarding the "transform" mode of SORCERER. - - On August 8, 1994, PCCTS 1.21 was released. It mainly cleaned up -the C++ output and included a number of bug fixes. - - From the 1.21 release forward, the maintenance and support of all -PCCTS tools will be primarily provided by Parr Research Corporation, -Minneapolis MN---an organization founded on the principles of excel- -lence in research and integrity in business; we are devoted to provid- -ing really cool software tools. Please see file PCCTS.FUTURE for more -information. All PCCTS tools currently in the public domain will con- -tinue to be in the public domain. - - Looking towards the future, a graphical user-interface is in the -design phase. This would allow users to view the syntax diagram -representation of their grammars and would highlight nondeterministic -productions. Parsing can be traced graphically as well. This system -will be built using a multiplatform window library. We also antici- -pate the introduction of a sophisticated error handling mechanism -called "parser exception handling" in a near future release. - - - - - Page 2 - - PCCTS - - - Currently, PCCTS is used at over 1000 known academic, government, -and commercial sites in 37 countries. Of course, the true number of -users is unknown due to the large number of ftp sites. - Credits - -_____________________________________________________________________________ -_____________________________________________________________________________ -|ANTLR 1.00A Terence Parr Hank Dietz | -|ALX Terence Parr Hank Dietz | -|ANTLR 1.00B Terence Parr Hank Dietz, Will Cohen | -|DLG 1.00B Will Cohen Terence Parr, Hank Dietz | -|NFA Relabelling Will Cohen | -|LL(k) analysis Terence Parr Hank Dietz | -|ANTLR 1.00 Terence Parr Hank Dietz, Will Cohen | -|DLG 1.00 Will Cohen Terence Parr, Hank Dietz | -|ANTLR 1.06 Terence Parr Will Cohen, Russell Quong, Hank Dietz| -|DLG 1.06 Will Cohen Terence Parr, Hank Dietz | -|ANTLR 1.10 Terence Parr Will Cohen, Russell Quong | -|ANTLR 1.20 Terence Parr Will Cohen, Russell Quong | -|ANTLR 1.21 Terence Parr Russell Quong | -|DLG 1.10 Will Cohen Terence Parr | -|DLG 1.20 Will Cohen Terence Parr | -|DLG 1.21 Terence Parr | -|Semantic predicates Terence Parr Russell Quonq | -|Syntactic predicates Terence Parr Russell Quonq | -|SORCERER 1.00A Terence Parr | -|SORCERER 1.00B Terence Parr Aaron Sawdey | -|SORCERER 1.00B9 Terence Parr Aaron Sawdey, Gary Funck | -|___________________________________________________________________________| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Page 3 - diff --git a/Tools/CodeTools/TianoTools/Pccts/makefile b/Tools/CodeTools/TianoTools/Pccts/makefile deleted file mode 100644 index f9b2dd2b9b..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/makefile +++ /dev/null @@ -1,66 +0,0 @@ -# -# Main makefile for PCCTS 1.33MR33 /* MRXXX */ -# -# Terence Parr -# Parr Research Corporation -# -# verbosity versus silence... -PSss= -# -# this can be set to /user/local/bin etc... -BINDIR=bin -# This part added by Thomas Herter, M"unchen, Germany. See also manpages -# target. -MANDIR=$(HOME)/man -MANEXT=1 -MANFILES=dlg/dlg.1 antlr/antlr.1 - -#CC=cc -#CC=gcc -#COPT=-O2 - -pccts: - @echo " " - @echo " Welcome to PCCTS 1.33MR33 installation" - @echo " " - @echo " (Version 1.33 Maintenance Release #33)" # mrxxx - @echo " " - @echo " Released 19 April 2002" - @echo " " - @echo " Featuring" - @echo " ANTLR -- ANother Tool for Language Recognition" - @echo " DLG -- DFA-based Lexical Analyzer Generator" - @echo " SORCERER -- Source-to-source translator (tree walker)" - @echo " " - @echo " http://www.antlr.org" - @echo " " - @echo " Trouble reports to tmoog@polhode.com" - @echo " Additional PCCTS 1.33 information at" - @echo " http://www.polhode.com" - @echo - @echo - @echo "To substitute gcc for CC to invoke compiler: make CC=gcc" - @echo "If there are problems with cr and lf try: unzip -a ..." - @echo -# - @if [ ! -d $(BINDIR) ] ; then mkdir $(BINDIR) ; fi - @echo Making executables... - (cd ./antlr; $(MAKE) CC="$(CC)" COPT="$(COPT)") - @echo antlr executable now in $(BINDIR) - (cd ./dlg; $(MAKE) CC="$(CC)" COPT="$(COPT)") - @echo dlg executable now in $(BINDIR) - @echo - @echo " PCCTS 1.33MR33 installation complete" # MRXXX - -clean: - (cd ./antlr; $(MAKE) -s clean) - (cd ./dlg; $(MAKE) -s clean) - - -manpages: - # mkdir -p $(MANDIR)/man$(MANEXT) - if [ ! -d $(MANDIR) ] ; then \ - mkdir $(MANDIR) ; fi - if [ ! -d $(MANDIR)/man$(MANEXT) ] ; then \ - mkdir $(MANDIR)/man$(MANEXT); fi - cp -p $(MANFILES) $(MANDIR)/man$(MANEXT) diff --git a/Tools/CodeTools/TianoTools/Pccts/support/genmk/genmk.c b/Tools/CodeTools/TianoTools/Pccts/support/genmk/genmk.c deleted file mode 100644 index 4952a30b38..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/support/genmk/genmk.c +++ /dev/null @@ -1,1063 +0,0 @@ -/* - * genmk -- a program to make makefiles for PCCTS - * - * ANTLR 1.33MR23 - * Terence John Parr 1989 - 2000 - * Purdue University - * U of MN - */ - -#include -#include -#include "pcctscfg.h" /* be sensitive to what ANTLR/DLG call the files */ - -#ifdef VAXC -#define DIE return 0; -#define DONE return 1; -#else -#define DIE return 1; -#define DONE return 0; -#endif - -#ifndef require -#define require(expr, err) {if ( !(expr) ) fatal(err);} -#endif - -#define MAX_FILES 50 -#define MAX_CFILES 1600 -#define MAX_SFILES 50 -#define MAX_SORS 50 -#define MAX_CLASSES 50 - -char *RENAME_OBJ_FLAG="-o", - *RENAME_EXE_FLAG="-o"; - -char *dlg = "parser.dlg"; -char *err = "err.c"; -char *hdr = "stdpccts.h"; -char *tok = "tokens.h"; -char *mode = "mode.h"; -char *scan = "scan"; - -char ATOKENBUFFER_O[100]; -char APARSER_O[100]; -char ASTBASE_O[100]; -char PCCTSAST_O[100]; -char LIST_O[100]; -char DLEXERBASE_O[100]; - -/* Option flags */ -static char *project="t", *files[MAX_FILES], *classes[MAX_CLASSES]; -static char *cfiles[MAX_CFILES]; -static char *sfiles[MAX_SORS][MAX_SFILES],*sclasses[MAX_SORS]; -static int num_sfiles[MAX_SORS]; /*sorcerer files in group */ -static int num_sors = 0; /*sorcerer groups */ -static int num_files = 0; /* grammar files */ -static int num_cfiles = 0; /* additional C/C++ files */ -static int num_classes = 0; /* ANTLR classes */ -static int user_lexer = 0; -static char *user_token_types = NULL; -static int gen_CPP = 0; -static char *outdir="."; -static char *dlg_class = "DLGLexer"; -static int gen_trees = 0; -static int gen_hoist = 0; -static int nondef_comp = 0; /* 1=compiler is non default */ -static char *compilerCCC="CC"; -static char *compilerCC="cc"; -static char *pccts_path="/usr/local/pccts"; - -#ifdef __STDC__ -void help(void); -void mk(char *project, char **files, int n, int argc, char **argv); -void pfiles(char **files, int n, char *suffix); -void fatal(char *msg); -void warn(char *msg); -#else -void help(); -void mk(); -void pfiles(); -void fatal(); -void warn(); -#endif - -typedef struct _Opt { - char *option; - int arg; -#ifdef __cplusplus - void (*process)(...); -#else - void (*process)(); -#endif - char *descr; - } Opt; - -#ifdef __STDC__ -static void ProcessArgs(int, char **, Opt *); -#else -static void ProcessArgs(); -#endif - -static void -#ifdef __STDC__ -pProj(char *s, char *t ) -#else -pProj( s, t ) -char *s; -char *t; -#endif -{ - project = t; -} - -static void -#ifdef __STDC__ -pUL( char *s ) -#else -pUL( s ) -char *s; -#endif -{ - user_lexer = 1; -} - -static void -#ifdef __STDC__ -pCPP( char *s ) -#else -pCPP( s ) -char *s; -#endif -{ - gen_CPP = 1; -} - -static void -#ifdef __STDC__ -pUT( char *s, char *t ) -#else -pUT( s, t ) -char *s; -char *t; -#endif -{ - user_token_types = t; -} - -static void -#ifdef __STDC__ -pTrees( char *s ) -#else -pTrees( s ) -char *s; -#endif -{ - gen_trees = 1; -} - -static void -#ifdef __STDC__ -pHoist( char *s ) -#else -pHoist( s ) -char *s; -#endif -{ - gen_hoist = 1; -} - -static void -#ifdef __STDC__ -pSor( char *s ) -#else -pSor( s ) -char *s; -#endif -{ - require(num_sors0 ) { - warn("can't define classes w/o C++ mode; turning on C++ mode...\n"); - gen_CPP=1; - } - if (!gen_CPP && num_sors) { - warn("can't define sorcerer group in C mode (yet); turning on C++ mode...\n"); - gen_CPP=1; - } - if ( gen_CPP && num_classes==0 ) { - fatal("must define classes >0 grammar classes in C++ mode\n"); - } - - mk(project, files, num_files, argc, argv); - DONE; -} - -#ifdef __STDC__ -void help(void) -#else -void help() -#endif -{ - Opt *p = options; - static char buf[1000+1]; - - fprintf(stderr, "genmk [options] f1.g ... fn.g\n"); - while ( p->option!=NULL && *(p->option) != '*' ) - { - buf[0]='\0'; - if ( p->arg ) sprintf(buf, "%s ___", p->option); - else strcpy(buf, p->option); - fprintf(stderr, "\t%-16s %s\n", buf, p->descr); - p++; - } -} - -#ifdef __STDC__ -void mk(char *project, char **files, int n, int argc, char **argv) -#else -void mk(project, files, n, argc, argv) -char *project; -char **files; -int n; -int argc; -char **argv; -#endif -{ - int i,j; - - printf("#\n"); - printf("# PCCTS makefile for: "); - pfiles(files, n, NULL); - printf("\n"); - printf("#\n"); - printf("# Created from:"); - for (i=0; i0) { - printf("SOR_H = $(PCCTS)%ssorcerer%sh\n", DirectorySymbol, DirectorySymbol); - printf("SOR_LIB = $(PCCTS)%ssorcerer%slib\n", - DirectorySymbol, DirectorySymbol); - } - printf("BIN = $(PCCTS)%sbin\n", DirectorySymbol); - printf("ANTLR = $(BIN)%santlr\n", DirectorySymbol); - printf("DLG = $(BIN)%sdlg\n", DirectorySymbol); - if (num_sors>0) printf("SOR = $(BIN)%ssor\n", DirectorySymbol); - printf("CFLAGS = -I. -I$(ANTLR_H)"); - if (num_sors>0) printf(" -I$(SOR_H)"); - if ( strcmp(outdir, ".")!=0 ) printf(" -I%s", outdir); - printf(" $(COTHER)"); - printf("\n"); - printf("AFLAGS ="); - if ( strcmp(outdir,".")!=0 ) printf(" -o %s", outdir); - if ( user_lexer ) printf(" -gx"); - if ( gen_CPP ) printf(" -CC"); - if ( strcmp(hdr,"stdpccts.h")!=0 ) printf(" -gh %s", hdr); - if ( gen_trees ) printf(" -gt"); - if ( gen_hoist ) { - printf(" -mrhoist on") ; - } else { - printf(" -mrhoist off"); - }; - printf(" $(AOTHER)"); - printf("\n"); - printf("DFLAGS = -C2 -i"); - if ( gen_CPP ) printf(" -CC"); - if ( strcmp(dlg_class,"DLGLexer")!=0 ) printf(" -cl %s", dlg_class); - if ( strcmp(outdir,".")!=0 ) printf(" -o %s", outdir); - printf(" $(DOTHER)"); - printf("\n"); - if (num_sors>0) - { - printf("SFLAGS = -CPP"); - if ( strcmp(outdir,".")!=0 ) printf(" -out-dir %s", outdir); - printf(" $(SOTHER)\n"); - } - printf("GRM = "); - pfiles(files, n, NULL); - printf("\n"); - printf("SRC = "); - if ( gen_CPP ) pfiles(files, n, CPP_FILE_SUFFIX_NO_DOT); - else pfiles(files, n, "c"); - if ( gen_CPP ) { - printf(" \\\n\t"); - pclasses(classes, num_classes, CPP_FILE_SUFFIX_NO_DOT); - printf(" \\\n\t"); - printf("$(ANTLR_H)%s%s", DirectorySymbol, APARSER_C); - if ( !user_lexer ) printf(" $(ANTLR_H)%s%s", DirectorySymbol, DLEXERBASE_C); - if ( gen_trees ) { - printf(" \\\n\t"); - printf("$(ANTLR_H)%s%s", DirectorySymbol, ASTBASE_C); - printf(" $(ANTLR_H)%s%s", DirectorySymbol, PCCTSAST_C); -/* printf(" $(ANTLR_H)%s%s", DirectorySymbol, LIST_C); */ - printf(" \\\n\t"); - } - printf(" $(ANTLR_H)%s%s", DirectorySymbol, ATOKENBUFFER_C); - } - if ( !user_lexer ) { - if ( gen_CPP ) printf(" $(SCAN)%s", CPP_FILE_SUFFIX); - else printf(" %s$(SCAN).c", DIR()); - } - if ( !gen_CPP ) printf(" $(ERR).c"); - for (i=0;i0) - printf(" \\\n\t$(SOR_LIB)%sSTreeParser.cpp", DirectorySymbol); - if (num_cfiles>0) - { - printf(" \\\n\t"); - pfiles(cfiles,num_cfiles,NULL); - } - printf("\n\n"); - printf("OBJ = "); - pfiles(files, n, "o"); - if ( gen_CPP ) { - printf(" \\\n\t"); - pclasses(classes, num_classes, "o"); - printf(" \\\n\t"); - printf("%s%s", DIR(), APARSER_O); - if ( !user_lexer ) { - printf(" %s%s", DIR(), DLEXERBASE_O); - } - if ( gen_trees ) { - printf(" \\\n\t"); - printf("%s%s", DIR(), ASTBASE_O); - printf(" %s%s", DIR(), PCCTSAST_O); -/* printf(" %s%s", DIR(), LIST_O); */ - printf(" \\\n\t"); - } - printf(" %s%s", DIR(), ATOKENBUFFER_O); - } - if ( !user_lexer ) { - if ( gen_CPP ) printf(" $(SCAN)%s", OBJ_FILE_SUFFIX); - else printf(" %s$(SCAN)%s", DIR(), OBJ_FILE_SUFFIX); - } - if ( !gen_CPP ) printf(" $(ERR)%s", OBJ_FILE_SUFFIX); - for (i=0;i0) printf(" \\\n\tSTreeParser.o"); - if (num_cfiles>0) - { - printf(" \\\n\t"); - pfiles(cfiles,num_cfiles,"o"); - } - printf("\n\n"); - - printf("ANTLR_SPAWN = "); - if ( gen_CPP ) pfiles(files, n, CPP_FILE_SUFFIX_NO_DOT); - else pfiles(files, n, "c"); - if ( gen_CPP ) { - printf(" "); - pclasses(classes, num_classes, CPP_FILE_SUFFIX_NO_DOT); - printf(" \\\n\t\t"); - pclasses(classes, num_classes, "h"); - if ( strcmp(hdr,"stdpccts.h")!=0 ) { - printf(" \\\n\t\t"); - printf("$(HDR_FILE) stdpccts.h"); - } - } - if ( user_lexer ) { - if ( !user_token_types ) printf(" $(TOKENS)"); - } - else { - printf(" $(DLG_FILE)"); - if ( !user_token_types ) printf(" $(TOKENS)"); - } - if ( !gen_CPP ) printf(" $(ERR).c"); - printf("\n"); - - if ( !user_lexer ) { - if ( gen_CPP ) printf("DLG_SPAWN = $(SCAN)%s", CPP_FILE_SUFFIX); - else printf("DLG_SPAWN = %s$(SCAN).c", DIR()); - if ( gen_CPP ) printf(" $(SCAN).h"); - if ( !gen_CPP ) printf(" $(MOD_FILE)"); - printf("\n"); - } - - if ( gen_CPP ) { - if ( !nondef_comp ) - printf("ifdef CXX\nCCC = $(CXX)\nendif\n\nifndef CCC\n"); - printf("CCC = %s\n",compilerCCC); - if ( !nondef_comp ) printf("endif\n\n"); - } - else - { - if ( !nondef_comp ) printf("ifndef CC\n"); - printf("CC = %s\n",compilerCC); - if ( !nondef_comp ) printf("endif\n\n"); - } - - /* set up dependencies */ - printf("\n%s : $(SRC) $(OBJ)\n", project); - printf("\t%s %s %s $(CFLAGS) $(OBJ)\n", - gen_CPP?"$(CCC)":"$(CC)", - RENAME_EXE_FLAG, - project); - printf("\n"); - - /* implicit rules */ - -/* if(gen_CPP) - printf("%%.o : %%.cpp\n\t$(CCC) -c $(CFLAGS) $<\n\n"); - - printf("%%.o : %%.c\n\t%s -c $(CFLAGS) $<\n\n", - gen_CPP?"$(CCC)":"$(CC)"); -*/ - /* how to compile parser files */ - - for (i=0; i0) - { - printf("STreeParser%s : $(SOR_LIB)%sSTreeParser.cpp\n", - OBJ_FILE_SUFFIX,DirectorySymbol); - printf("\t%s -c $(CFLAGS) %s ", - gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG); - printf("STreeParser%s ",OBJ_FILE_SUFFIX); - printf("$(SOR_LIB)%sSTreeParser.cpp\n\n",DirectorySymbol); - } - - printf("$(ANTLR_SPAWN) : $(GRM)\n"); - printf("\t$(ANTLR) $(AFLAGS) $(GRM)\n"); - - if ( !user_lexer ) - { - printf("\n"); - printf("$(DLG_SPAWN) : $(DLG_FILE)\n"); - if ( gen_CPP ) printf("\t$(DLG) $(DFLAGS) $(DLG_FILE)\n"); - else printf("\t$(DLG) $(DFLAGS) $(DLG_FILE) $(SCAN).c\n"); - } - - /* do the makes for ANTLR/DLG support */ - if ( gen_CPP ) { - printf("\n"); - printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), APARSER_O, DirectorySymbol, APARSER_C); - printf("\t%s -c $(CFLAGS) %s ", - gen_CPP?"$(CCC)":"$(CC)", - RENAME_OBJ_FLAG); - printf("%s%s $(ANTLR_H)%s%s\n", DIR(), APARSER_O, DirectorySymbol, APARSER_C); - printf("\n"); - printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), ATOKENBUFFER_O, DirectorySymbol, ATOKENBUFFER_C); - printf("\t%s -c $(CFLAGS) %s ", - gen_CPP?"$(CCC)":"$(CC)", - RENAME_OBJ_FLAG); - printf("%s%s $(ANTLR_H)%s%s\n", DIR(), ATOKENBUFFER_O, DirectorySymbol, ATOKENBUFFER_C); - if ( !user_lexer ) { - printf("\n"); - printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), DLEXERBASE_O, DirectorySymbol, DLEXERBASE_C); - printf("\t%s -c $(CFLAGS) %s ", - gen_CPP?"$(CCC)":"$(CC)", - RENAME_OBJ_FLAG); - printf("%s%s $(ANTLR_H)%s%s\n", DIR(), DLEXERBASE_O, DirectorySymbol, DLEXERBASE_C); - } - if ( gen_trees ) { - printf("\n"); - printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), ASTBASE_O, DirectorySymbol, ASTBASE_C); - printf("\t%s -c $(CFLAGS) %s ", - gen_CPP?"$(CCC)":"$(CC)", - RENAME_OBJ_FLAG); - printf("%s%s $(ANTLR_H)%s%s\n", DIR(), ASTBASE_O, DirectorySymbol, ASTBASE_C); - printf("\n"); - printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), PCCTSAST_O, DirectorySymbol, PCCTSAST_C); - printf("\t%s -c $(CFLAGS) %s ", - gen_CPP?"$(CCC)":"$(CC)", - RENAME_OBJ_FLAG); - printf("%s%s $(ANTLR_H)%s%s\n", DIR(), PCCTSAST_O, DirectorySymbol, PCCTSAST_C); - printf("\n"); -/* - printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), LIST_O, DirectorySymbol, LIST_C); - printf("\t%s -c $(CFLAGS) %s ", - gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG); - printf("%s%s $(ANTLR_H)%s%s\n", DIR(), LIST_O, DirectorySymbol, LIST_C); -*/ - } - } - - /* clean and scrub targets */ - - printf("\nclean:\n"); - printf("\trm -f *%s core %s", OBJ_FILE_SUFFIX, project); - if ( strcmp(outdir, ".")!=0 ) printf(" %s*%s", DIR(), OBJ_FILE_SUFFIX); - printf("\n"); - - printf("\nscrub: clean\n"); -/* printf("\trm -f *%s core %s", OBJ_FILE_SUFFIX, project); */ -/* if ( strcmp(outdir, ".")!=0 ) printf(" %s*%s", DIR(), OBJ_FILE_SUFFIX); */ - printf("\trm -f $(ANTLR_SPAWN)"); - if ( !user_lexer ) printf(" $(DLG_SPAWN)"); - for (i=0;i0 ) - { - char *p = &(*files)[strlen(*files)-1]; - if ( !first ) putchar(' '); - first=0; - while ( p > *files && *p != '.' ) --p; - if ( p == *files ) - { - fprintf(stderr, - "genmk: filenames must be file.suffix format: %s\n", - *files); - exit(-1); - } - if ( suffix == NULL ) printf("%s", *files); - else - { - *p = '\0'; - printf("%s", DIR()); - if ( strcmp(suffix, "o")==0 ) printf("%s%s", *files, OBJ_FILE_SUFFIX); - else printf("%s.%s", *files, suffix); - *p = '.'; - } - files++; - --n; - } -} - -#ifdef __STDC__ -pclasses(char **classes, int n, char *suffix) -#else -pclasses(classes, n, suffix) -char **classes; -int n; -char *suffix; -#endif -{ - int first=1; - - while ( n>0 ) - { - if ( !first ) putchar(' '); - first=0; - if ( suffix == NULL ) printf("%s", *classes); - else { - printf("%s", DIR()); - if ( strcmp(suffix, "o")==0 ) printf("%s%s", *classes, OBJ_FILE_SUFFIX); - else printf("%s.%s", *classes, suffix); - } - classes++; - --n; - } -} - -static void -#ifdef __STDC__ -ProcessArgs( int argc, char **argv, Opt *options ) -#else -ProcessArgs( argc, argv, options ) -int argc; -char **argv; -Opt *options; -#endif -{ - Opt *p; - require(argv!=NULL, "ProcessArgs: command line NULL"); - - while ( argc-- > 0 ) - { - p = options; - while ( p->option != NULL ) - { - if ( strcmp(p->option, "*") == 0 || - strcmp(p->option, *argv) == 0 ) - { - if ( p->arg ) - { - (*p->process)( *argv, *(argv+1) ); - argv++; - argc--; - } - else - (*p->process)( *argv ); - break; - } - p++; - } - argv++; - } -} - -#ifdef __STDC__ -void fatal( char *err_) -#else -void fatal( err_) -char *err_; -#endif -{ - fprintf(stderr, "genmk: %s\n", err_); - exit(1); -} - -#ifdef __STDC__ -void warn( char *err_) -#else -void warn( err_) -char *err_; -#endif -{ - fprintf(stderr, "genmk: %s\n", err_); -} - -#ifdef __STDC__ -char *DIR(void) -#else -char *DIR() -#endif -{ - static char buf[200+1]; - - if ( strcmp(outdir,TopDirectory)==0 ) return ""; - sprintf(buf, "%s%s", outdir, DirectorySymbol); - return buf; -} diff --git a/Tools/CodeTools/TianoTools/Pccts/support/genmk/genmk_old.c b/Tools/CodeTools/TianoTools/Pccts/support/genmk/genmk_old.c deleted file mode 100644 index 2cf9fad727..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/support/genmk/genmk_old.c +++ /dev/null @@ -1,762 +0,0 @@ -/* - * genmk -- a program to make makefiles for PCCTS - * - * ANTLR 1.33MR10 - * Terence John Parr 1989 - 1998 - * Purdue University - * U of MN - */ - -#include -#include "pcctscfg.h" /* be sensitive to what ANTLR/DLG call the files */ - -#ifdef VAXC -#define DIE return 0; -#define DONE return 1; -#else -#define DIE return 1; -#define DONE return 0; -#endif - -#ifndef require -#define require(expr, err) {if ( !(expr) ) fatal(err);} -#endif - -#define MAX_FILES 50 -#define MAX_CLASSES 50 - -char *RENAME_OBJ_FLAG="-o", - *RENAME_EXE_FLAG="-o"; - -char *dlg = "parser.dlg"; -char *err = "err.c"; -char *hdr = "stdpccts.h"; -char *tok = "tokens.h"; -char *mode = "mode.h"; -char *scan = "scan"; - -char ATOKENBUFFER_O[100]; -char APARSER_O[100]; -char ASTBASE_O[100]; -char PCCTSAST_O[100]; -char LIST_O[100]; -char DLEXERBASE_O[100]; - -/* Option flags */ -static char *project="t", *files[MAX_FILES], *classes[MAX_CLASSES]; -static int num_files = 0; -static int num_classes = 0; -static int user_lexer = 0; -static char *user_token_types = NULL; -static int gen_CPP = 0; -static char *outdir="."; -static char *dlg_class = "DLGLexer"; -static int gen_trees = 0; -static int gen_hoist = 0; -static char cfiles[1600]=""; -static char *compilerCCC="CC"; -static char *compilerCC="cc"; -static char *pccts_path="/usr/local/pccts"; - -void help(); -void mk(); -void pfiles(); -void pclasses(); -void fatal(); -void warn(); - -typedef struct _Opt { - char *option; - int arg; -#ifdef __cplusplus - void (*process)(...); -#else - void (*process)(); -#endif - char *descr; - } Opt; - -#ifdef __STDC__ -static void ProcessArgs(int, char **, Opt *); -#else -static void ProcessArgs(); -#endif - -static void -pProj( s, t ) -char *s; -char *t; -{ - project = t; -} - -static void -pUL( s ) -char *s; -{ - user_lexer = 1; -} - -static void -pCPP( s ) -char *s; -{ - gen_CPP = 1; -} - -static void -pUT( s, t ) -char *s; -char *t; -{ - user_token_types = t; -} - -static void -pTrees( s ) -char *s; -{ - gen_trees = 1; -} - -static void -pHoist( s ) -char *s; -{ - gen_hoist = 1; -} - -static void -#ifdef __STDC__ -pFile( char *s ) -#else -pFile( s ) -char *s; -#endif -{ - if ( *s=='-' ) - { - fprintf(stderr, "invalid option: '%s'; ignored...",s); - return; - } - - require(num_files0 ) { - warn("can't define classes w/o C++ mode; turning on C++ mode...\n"); - gen_CPP=1; - } - if ( gen_CPP && num_classes==0 ) { - fatal("must define classes >0 grammar classes in C++ mode\n"); - } - - mk(project, files, num_files, argc, argv); - DONE; -} - -void help() -{ - Opt *p = options; - static char buf[1000+1]; - - fprintf(stderr, "genmk [options] f1.g ... fn.g\n"); - while ( p->option!=NULL && *(p->option) != '*' ) - { - buf[0]='\0'; - if ( p->arg ) sprintf(buf, "%s ___", p->option); - else strcpy(buf, p->option); - fprintf(stderr, "\t%-16s %s\n", buf, p->descr); - p++; - } -} - -void mk(project, files, n, argc, argv) -char *project; -char **files; -int n; -int argc; -char **argv; -{ - int i; - - printf("#\n"); - printf("# PCCTS makefile for: "); - pfiles(files, n, NULL); - printf("\n"); - printf("#\n"); - printf("# Created from:"); - for (i=0; i0 ) - { - char *p = &(*files)[strlen(*files)-1]; - if ( !first ) putchar(' '); - first=0; - while ( p > *files && *p != '.' ) --p; - if ( p == *files ) - { - fprintf(stderr, - "genmk: filenames must be file.suffix format: %s\n", - *files); - exit(-1); - } - if ( suffix == NULL ) printf("%s", *files); - else - { - *p = '\0'; - printf("%s", DIR()); - if ( strcmp(suffix, "o")==0 ) printf("%s%s", *files, OBJ_FILE_SUFFIX); - else printf("%s.%s", *files, suffix); - *p = '.'; - } - files++; - --n; - } -} - -void pclasses(classes, n, suffix) -char **classes; -int n; -char *suffix; -{ - int first=1; - - while ( n>0 ) - { - if ( !first ) putchar(' '); - first=0; - if ( suffix == NULL ) printf("%s", *classes); - else { - printf("%s", DIR()); - if ( strcmp(suffix, "o")==0 ) printf("%s%s", *classes, OBJ_FILE_SUFFIX); - else printf("%s.%s", *classes, suffix); - } - classes++; - --n; - } -} - -static void -#ifdef __STDC__ -ProcessArgs( int argc, char **argv, Opt *options ) -#else -ProcessArgs( argc, argv, options ) -int argc; -char **argv; -Opt *options; -#endif -{ - Opt *p; - require(argv!=NULL, "ProcessArgs: command line NULL"); - - while ( argc-- > 0 ) - { - p = options; - while ( p->option != NULL ) - { - if ( strcmp(p->option, "*") == 0 || - strcmp(p->option, *argv) == 0 ) - { - if ( p->arg ) - { - (*p->process)( *argv, *(argv+1) ); - argv++; - argc--; - } - else - (*p->process)( *argv ); - break; - } - p++; - } - argv++; - } -} - -void fatal( err_) -char *err_; -{ - fprintf(stderr, "genmk: %s\n", err_); - exit(1); -} - -void warn( err_) -char *err_; -{ - fprintf(stderr, "genmk: %s\n", err_); -} - -char *DIR() -{ - static char buf[200+1]; - - if ( strcmp(outdir,TopDirectory)==0 ) return ""; - sprintf(buf, "%s%s", outdir, DirectorySymbol); - return buf; -} diff --git a/Tools/CodeTools/TianoTools/Pccts/support/genmk/makefile b/Tools/CodeTools/TianoTools/Pccts/support/genmk/makefile deleted file mode 100644 index a003c2f321..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/support/genmk/makefile +++ /dev/null @@ -1,29 +0,0 @@ -## -## 7-Apr-97 -## added support/genmk/makefile to pccts 1.33MR1 distribution kit -## (support/genmk/makefile" omitted from 1.33 distribution kit) -## -SRC=genmk.c -OBJ=genmk.o -# Define PC if you use a PC OS (changes directory symbol and object file extension) -# see pccts/h/pcctscfg.h -CC=cc -COPT=-O -#CFLAGS=-I../../h -DPC -CFLAGS=$(COPT) -I../../h -BAG=../../bin/bag - -genmk: $(OBJ) $(SRC) ../../h/pcctscfg.h - $(CC) -o genmk $(OBJ) - -clean: - rm -rf core *.o - -scrub: - rm -rf genmk core *.o - -shar: - shar genmk.c makefile > genmk.shar - -archive: - $(BAG) genmk.c makefile > genmk.bag diff --git a/Tools/CodeTools/TianoTools/Pccts/support/rexpr/makefile b/Tools/CodeTools/TianoTools/Pccts/support/rexpr/makefile deleted file mode 100644 index 44caef1aa5..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/support/rexpr/makefile +++ /dev/null @@ -1,19 +0,0 @@ -BAG=../../bin/bag -SRC=test.c rexpr.c -OBJ=test.o rexpr.o -CFLAGS = -g - -test: $(OBJ) $(SRC) - cc -g -o texpr $(OBJ) - -shar: - shar makefile test.c rexpr.c rexpr.h > rexpr.shar - -archive: - $(BAG) makefile test.c rexpr.c rexpr.h > rexpr.bag - -clean: - rm -rf *.o core texpr - -scrub: - rm -rf *.o core texpr diff --git a/Tools/CodeTools/TianoTools/Pccts/support/rexpr/rexpr.c b/Tools/CodeTools/TianoTools/Pccts/support/rexpr/rexpr.c deleted file mode 100644 index 805bf65533..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/support/rexpr/rexpr.c +++ /dev/null @@ -1,586 +0,0 @@ -/* - * This file contains code for - * - * int rexpr(char *expr, char *s); - * - * which answers - * - * 1 if 's' is in the language described by the regular expression 'expr' - * 0 if it is not - * -1 if the regular expression is invalid - * - * Language membership is determined by constructing a non-deterministic - * finite automata (NFA) from the regular expression. A depth- - * first-search is performed on the NFA (graph) to check for a match of 's'. - * Each non-epsilon arc consumes one character from 's'. Backtracking is - * performed to check all possible paths through the NFA. - * - * Regular expressions follow the meta-language: - * - * ::= ( '|' )* - * - * ::= ( )* - * - * ::= {'~'} '[' ']' - * | '(' ')' - * | '{' '}' - * | - * - * ::= { '*' | '+' } - * - * ::= ( )* - * | { } '-' { } - * - * ::= Token[Atom] - * - * Notes: - * ~ means complement the set in [..]. i.e. all characters not listed - * * means match 0 or more times (can be on expression or atom) - * + means match 1 or more times (can be on expression or atom) - * {} optional - * () grouping - * [] set of atoms - * x-y all characters from x to y (found only in [..]) - * \xx the character with value xx - * - * Examples: - * [a-z]+ - * match 1 or more lower-case letters (e.g. variable) - * - * 0x[0-9A-Fa-f]+ - * match a hex number with 0x on front (e.g. 0xA1FF) - * - * [0-9]+.[0-9]+{e[0-9]+} - * match a floating point number (e.g. 3.14e21) - * - * Code example: - * if ( rexpr("[a-zA-Z][a-zA-Z0-9]+", str) ) then str is keyword - * - * Terence Parr - * Purdue University - * April 1991 - */ - -#include -#include -#ifdef __STDC__ -#include -#else -#include -#endif -#include "rexpr.h" - -#ifdef __USE_PROTOS -static int regExpr( GraphPtr g ); -static int andExpr( GraphPtr g ); -static int expr( GraphPtr g ); -static int repeatSymbol( GraphPtr g ); -static int atomList( char *p, int complement ); -static void next( void ); -static ArcPtr newGraphArc( void ); -static NodePtr newNode( void ); -static int ArcBetweenGraphNode( NodePtr i, NodePtr j, int label ); -static Graph BuildNFA_atom( int label ); -static Graph BuildNFA_AB( Graph A, Graph B ); -static Graph BuildNFA_AorB( Graph A, Graph B ); -static Graph BuildNFA_set( char *s ); -static Graph BuildNFA_Astar( Graph A ); -static Graph BuildNFA_Aplus( Graph A ); -static Graph BuildNFA_Aoptional( Graph A ); -#else -static int regExpr(); -static int andExpr(); -static int expr(); -static int repeatSymbol(); -static int atomList(); -static void next(); -static ArcPtr newGraphArc(); -static NodePtr newNode(); -static int ArcBetweenGraphNode(); -static Graph BuildNFA_atom(); -static Graph BuildNFA_AB(); -static Graph BuildNFA_AorB(); -static Graph BuildNFA_set(); -static Graph BuildNFA_Astar(); -static Graph BuildNFA_Aplus(); -static Graph BuildNFA_Aoptional(); -#endif - -static char *_c; -static int token, tokchar; -static NodePtr accept; -static NodePtr freelist = NULL; - -/* - * return 1 if s in language described by expr - * 0 if s is not - * -1 if expr is an invalid regular expression - */ -#ifdef __USE_PROTOS -static int rexpr(char *expr,char *s) -#else -static int rexpr(expr, s) -char *expr, *s; -#endif -{ - NodePtr p,q; - Graph nfa; - int result; - - fprintf(stderr, "rexpr(%s,%s);\n", expr,s); - freelist = NULL; - _c = expr; - next(); - if ( regExpr(&nfa) == -1 ) return -1; - accept = nfa.right; - result = match(nfa.left, s); - /* free all your memory */ - p = q = freelist; - while ( p!=NULL ) { q = p->track; free(p); p = q; } - return result; -} - -/* - * do a depth-first-search on the NFA looking for a path from start to - * accept state labelled with the characters of 's'. - */ - -#ifdef __USE_PROTOS -static int match(NodePtr automaton,char *s) -#else -static int match(automaton, s) -NodePtr automaton; -char *s; -#endif -{ - ArcPtr p; - - if ( automaton == accept && *s == '\0' ) return 1; /* match */ - - for (p=automaton->arcs; p!=NULL; p=p->next) /* try all arcs */ - { - if ( p->label == Epsilon ) - { - if ( match(p->target, s) ) return 1; - } - else if ( p->label == *s ) - if ( match(p->target, s+1) ) return 1; - } - return 0; -} - -/* - * ::= ( '|' {} )* - * - * Return -1 if syntax error - * Return 0 if none found - * Return 1 if a regExrp was found - */ - -#ifdef __USE_PROTOS -static int regExpr(GraphPtr g) -#else -static int regExpr(g) -GraphPtr g; -#endif -{ - Graph g1, g2; - - if ( andExpr(&g1) == -1 ) - { - return -1; - } - - while ( token == '|' ) - { - int a; - next(); - a = andExpr(&g2); - if ( a == -1 ) return -1; /* syntax error below */ - else if ( !a ) return 1; /* empty alternative */ - g1 = BuildNFA_AorB(g1, g2); - } - - if ( token!='\0' ) return -1; - - *g = g1; - return 1; -} - -/* - * ::= ( )* - */ - -#ifdef __USE_PROTOS -static int andExpr(GraphPtr g) -#else -static int andExpr(g) -GraphPtr g; -#endif -{ - Graph g1, g2; - - if ( expr(&g1) == -1 ) - { - return -1; - } - - while ( token==Atom || token=='{' || token=='(' || token=='~' || token=='[' ) - { - if (expr(&g2) == -1) return -1; - g1 = BuildNFA_AB(g1, g2); - } - - *g = g1; - return 1; -} - -/* - * ::= {'~'} '[' ']' - * | '(' ')' - * | '{' '}' - * | - */ - -#ifdef __USE_PROTOS -static int expr(GraphPtr g) -#else -static int expr(g) -GraphPtr g; -#endif -{ - int complement = 0; - char s[257]; /* alloc space for string of char in [] */ - - if ( token == '~' || token == '[' ) - { - if ( token == '~' ) {complement = 1; next();} - if ( token != '[' ) return -1; - next(); - if ( atomList( s, complement ) == -1 ) return -1; - *g = BuildNFA_set( s ); - if ( token != ']' ) return -1; - next(); - repeatSymbol( g ); - return 1; - } - if ( token == '(' ) - { - next(); - if ( regExpr( g ) == -1 ) return -1; - if ( token != ')' ) return -1; - next(); - repeatSymbol( g ); - return 1; - } - if ( token == '{' ) - { - next(); - if ( regExpr( g ) == -1 ) return -1; - if ( token != '}' ) return -1; - next(); - /* S p e c i a l C a s e O p t i o n a l { } */ - if ( token != '*' && token != '+' ) - { - *g = BuildNFA_Aoptional( *g ); - } - repeatSymbol( g ); - return 1; - } - if ( token == Atom ) - { - *g = BuildNFA_atom( tokchar ); - next(); - repeatSymbol( g ); - return 1; - } - - return -1; -} - -/* - * ::= { '*' | '+' } - */ -#ifdef __USE_PROTOS -static int repeatSymbol(GraphPtr g) -#else -static int repeatSymbol(g) -GraphPtr g; -#endif -{ - switch ( token ) - { - case '*' : *g = BuildNFA_Astar( *g ); next(); break; - case '+' : *g = BuildNFA_Aplus( *g ); next(); break; - } - return 1; -} - -/* - * ::= { }* - * { } '-' { } - * - * a-b is same as ab - * q-a is same as q - */ - -#ifdef __USE_PROTOS -static int atomList(char *p, int complement) -#else -static int atomList(p, complement) -char *p; -int complement; -#endif -{ - static unsigned char set[256]; /* no duplicates */ - int first, last, i; - char *s = p; - - if ( token != Atom ) return -1; - - for (i=0; i<256; i++) set[i] = 0; - while ( token == Atom ) - { - if ( !set[tokchar] ) *s++ = tokchar; - set[tokchar] = 1; /* Add atom to set */ - next(); - if ( token == '-' ) /* have we found '-' */ - { - first = *(s-1); /* Get last char */ - next(); - if ( token != Atom ) return -1; - else - { - last = tokchar; - } - for (i = first+1; i <= last; i++) - { - if ( !set[tokchar] ) *s++ = i; - set[i] = 1; /* Add atom to set */ - } - next(); - } - } - *s = '\0'; - if ( complement ) - { - for (i=0; i<256; i++) set[i] = !set[i]; - for (i=1,s=p; i<256; i++) if ( set[i] ) *s++ = i; - *s = '\0'; - } - return 1; -} - -/* a somewhat stupid lexical analyzer */ - -#ifdef __USE_PROTOS -static void next(void) -#else -static void next() -#endif -{ - while ( *_c==' ' || *_c=='\t' || *_c=='\n' ) _c++; - if ( *_c=='\\' ) - { - _c++; - if ( isdigit(*_c) ) - { - int n=0; - while ( isdigit(*_c) ) - { - n = n*10 + (*_c++ - '0'); - } - if ( n>255 ) n=255; - tokchar = n; - } - else - { - switch (*_c) - { - case 'n' : tokchar = '\n'; break; - case 't' : tokchar = '\t'; break; - case 'r' : tokchar = '\r'; break; - default : tokchar = *_c; - } - _c++; - } - token = Atom; - } - else if ( isgraph(*_c) && *_c!='[' && *_c!='(' && *_c!='{' && - *_c!='-' && *_c!='}' && *_c!=')' && *_c!=']' && - *_c!='+' && *_c!='*' && *_c!='~' && *_c!='|' ) - { - token = Atom; - tokchar = *_c++; - } - else - { - token = tokchar = *_c++; - } -} - -/* N F A B u i l d i n g R o u t i n e s */ - -#ifdef __USE_PROTOS -static ArcPtr newGraphArc(void) -#else -static ArcPtr newGraphArc() -#endif -{ - ArcPtr p; - p = (ArcPtr) calloc(1, sizeof(Arc)); - if ( p==NULL ) {fprintf(stderr,"rexpr: out of memory\n"); exit(-1);} - if ( freelist != NULL ) p->track = (ArcPtr) freelist; - freelist = (NodePtr) p; - return p; -} - -#ifdef __USE_PROTOS -static NodePtr newNode(void) -#else -static NodePtr newNode() -#endif -{ - NodePtr p; - p = (NodePtr) calloc(1, sizeof(Node)); - if ( p==NULL ) {fprintf(stderr,"rexpr: out of memory\n"); exit(-1);} - if ( freelist != NULL ) p->track = freelist; - freelist = p; - return p; -} - -#ifdef __USE_PROTOS -static void ArcBetweenGraphNodes(NodePtr i,NodePtr j,int label) -#else -static void ArcBetweenGraphNodes(i, j, label) -NodePtr i, j; -int label; -#endif -{ - ArcPtr a; - - a = newGraphArc(); - if ( i->arcs == NULL ) i->arctail = i->arcs = a; - else {(i->arctail)->next = a; i->arctail = a;} - a->label = label; - a->target = j; -} - -#ifdef __USE_PROTOS -static Graph BuildNFA_atom(int label) -#else -static Graph BuildNFA_atom(label) -int label; -#endif -{ - Graph g; - - g.left = newNode(); - g.right = newNode(); - ArcBetweenGraphNodes(g.left, g.right, label); - return( g ); -} - -#ifdef __USE_PROTOS -static Graph BuildNFA_AB(Graph A,Graph B) -#else -static Graph BuildNFA_AB(A, B) -Graph A, B; -#endif -{ - Graph g; - - ArcBetweenGraphNodes(A.right, B.left, Epsilon); - g.left = A.left; - g.right = B.right; - return( g ); -} - -#ifdef __USE_PROTOS -static Graph BuildNFA_AorB(Graph A,Graph B) -#else -static Graph BuildNFA_AorB(A, B) -Graph A, B; -#endif -{ - Graph g; - - g.left = newNode(); - ArcBetweenGraphNodes(g.left, A.left, Epsilon); - ArcBetweenGraphNodes(g.left, B.left, Epsilon); - g.right = newNode(); - ArcBetweenGraphNodes(A.right, g.right, Epsilon); - ArcBetweenGraphNodes(B.right, g.right, Epsilon); - return( g ); -} - -#ifdef __USE_PROTOS -static Graph BuildNFA_set(char *s) -#else -static Graph BuildNFA_set( s ) -char *s; -#endif -{ - Graph g; - - if ( s == NULL ) return g; - - g.left = newNode(); - g.right = newNode(); - while ( *s != '\0' ) - { - ArcBetweenGraphNodes(g.left, g.right, *s++); - } - return g; -} - -#ifdef __USE_PROTOS -static Graph BuildNFA_Astar(Graph A) -#else -static Graph BuildNFA_Astar( A ) -Graph A; -#endif -{ - Graph g; - - g.left = newNode(); - g.right = newNode(); - - ArcBetweenGraphNodes(g.left, A.left, Epsilon); - ArcBetweenGraphNodes(g.left, g.right, Epsilon); - ArcBetweenGraphNodes(A.right, g.right, Epsilon); - ArcBetweenGraphNodes(A.right, A.left, Epsilon); - - return( g ); -} - -#ifdef __USE_PROTOS -static Graph BuildNFA_Aplus(Graph A) -#else -static Graph BuildNFA_Aplus( A ) -Graph A; -#endif -{ - ArcBetweenGraphNodes(A.right, A.left, Epsilon); - - return( A ); -} - -#ifdef __USE_PROTOS -static Graph BuildNFA_Aoptional(Graph A) -#else -static Graph BuildNFA_Aoptional( A ) -Graph A; -#endif -{ - Graph g; - - g.left = newNode(); - g.right = newNode(); - - ArcBetweenGraphNodes(g.left, A.left, Epsilon); - ArcBetweenGraphNodes(g.left, g.right, Epsilon); - ArcBetweenGraphNodes(A.right, g.right, Epsilon); - - return( g ); -} diff --git a/Tools/CodeTools/TianoTools/Pccts/support/rexpr/rexpr.h b/Tools/CodeTools/TianoTools/Pccts/support/rexpr/rexpr.h deleted file mode 100644 index e67a9652fb..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/support/rexpr/rexpr.h +++ /dev/null @@ -1,30 +0,0 @@ -#define Atom 256 /* token Atom (an impossible char value) */ -#define Epsilon 257 /* epsilon arc (an impossible char value) */ - -/* track field must be same for all node types */ -typedef struct _a { - struct _a *track; /* track mem allocation */ - int label; - struct _a *next; - struct _n *target; - } Arc, *ArcPtr; - -typedef struct _n { - struct _n *track; - ArcPtr arcs, arctail; - } Node, *NodePtr; - -typedef struct { - NodePtr left, - right; - } Graph, *GraphPtr; - -#ifdef __USE_PROTOS -int rexpr( char *expr, char *s ); -int match( NodePtr automaton, char *s ); -#else -int rexpr(); -int match(); -#endif - - diff --git a/Tools/CodeTools/TianoTools/Pccts/support/rexpr/test.c b/Tools/CodeTools/TianoTools/Pccts/support/rexpr/test.c deleted file mode 100644 index 2619539e4b..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/support/rexpr/test.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include "rexpr.h" - -/* - * test for rexpr(). - * To make this test: - * cc -o rexpr test.c rexpr.c - * Then from command line type: - * rexpr r string - * where r is the regular expression that decribes a language - * and string is the string to verify. - */ -main(argc,argv) -int argc; -char *argv[]; -{ - if ( argc!=3 ) fprintf(stderr,"rexpr: expr s\n"); - else printf("%d\n", rexpr(argv[1], argv[2])); -} diff --git a/Tools/CodeTools/TianoTools/Pccts/support/set/set.c b/Tools/CodeTools/TianoTools/Pccts/support/set/set.c deleted file mode 100644 index eb6fba7393..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/support/set/set.c +++ /dev/null @@ -1,816 +0,0 @@ -/* set.c - - The following is a general-purpose set library originally developed - by Hank Dietz and enhanced by Terence Parr to allow dynamic sets. - - Sets are now structs containing the #words in the set and - a pointer to the actual set words. - - Generally, sets need not be explicitly allocated. They are - created/extended/shrunk when appropriate (e.g. in set_of()). - HOWEVER, sets need to be destroyed (free()ed) when they go out of scope - or are otherwise no longer needed. A routine is provided to - free a set. - - Sets can be explicitly created with set_new(s, max_elem). - - Sets can be declared to have minimum size to reduce realloc traffic. - Default minimum size = 1. - - Sets can be explicitly initialized to have no elements (set.n == 0) - by using the 'empty' initializer: - - Examples: - set a = empty; -- set_deg(a) == 0 - - return( empty ); - - Example set creation and destruction: - - set - set_of2(e,g) - unsigned e,g; - { - set a,b,c; - - b = set_of(e); -- Creates space for b and sticks in e - set_new(c, g); -- set_new(); set_orel() ==> set_of() - set_orel(g, &c); - a = set_or(b, c); - . - . - . - set_free(b); - set_free(c); - return( a ); - } - - 1987 by Hank Dietz - - Modified by: - Terence Parr - Purdue University - October 1989 - - Made it smell less bad to C++ 7/31/93 -- TJP -*/ - -#include -#include "pcctscfg.h" -#ifdef __STDC__ -#include -#else -#include -#endif -#include - -#include "set.h" - -#define MIN(i,j) ( (i) > (j) ? (j) : (i)) -#define MAX(i,j) ( (i) < (j) ? (j) : (i)) - -/* elems can be a maximum of 32 bits */ -static unsigned bitmask[] = { - 0x00000001, 0x00000002, 0x00000004, 0x00000008, - 0x00000010, 0x00000020, 0x00000040, 0x00000080, - 0x00000100, 0x00000200, 0x00000400, 0x00000800, - 0x00001000, 0x00002000, 0x00004000, 0x00008000, -#if !defined(PC) || defined(PC32) - 0x00010000, 0x00020000, 0x00040000, 0x00080000, - 0x00100000, 0x00200000, 0x00400000, 0x00800000, - 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000, 0x40000000, 0x80000000 -#endif -}; - -set empty = set_init; -static unsigned min=1; - -#define StrSize 200 - -#ifdef MEMCHK -#define CHK(a) \ - if ( a.setword != NULL ) \ - if ( !valid(a.setword) ) \ - {fprintf(stderr, "%s(%d): invalid set\n",__FILE__,__LINE__); exit(-1);} -#else -#define CHK(a) -#endif - -/* - * Set the minimum size (in words) of a set to reduce realloc calls - */ -void -#ifdef __USE_PROTOS -set_size( unsigned n ) -#else -set_size( n ) -unsigned n; -#endif -{ - min = n; -} - -unsigned int -#ifdef __USE_PROTOS -set_deg( set a ) -#else -set_deg( a ) -set a; -#endif -{ - /* Fast compute degree of a set... the number - of elements present in the set. Assumes - that all word bits are used in the set - and that SETSIZE(a) is a multiple of WORDSIZE. - */ - register unsigned *p = &(a.setword[0]); - register unsigned *endp = NULL; /* MR27 Avoid false memory check report */ - register unsigned degree = 0; - - CHK(a); - if ( a.n == 0 ) return(0); - endp = &(a.setword[a.n]); - while ( p < endp ) - { - register unsigned t = *p; - register unsigned *b = &(bitmask[0]); - do { - if (t & *b) ++degree; - } while (++b < &(bitmask[WORDSIZE])); - p++; - } - - return(degree); -} - -set -#ifdef __USE_PROTOS -set_or( set b, set c ) -#else -set_or( b, c ) -set b; -set c; -#endif -{ - /* Fast set union operation */ - /* resultant set size is max(b, c); */ - set *big; - set t; - unsigned int m,n; - register unsigned *r, *p, *q, *endp; - - CHK(b); CHK(c); - t = empty; - if (b.n > c.n) {big= &b; m=b.n; n=c.n;} else {big= &c; m=c.n; n=b.n;} - set_ext(&t, m); - r = t.setword; - - /* Or b,c until max of smaller set */ - q = c.setword; - p = b.setword; - endp = &(b.setword[n]); - while ( p < endp ) *r++ = *p++ | *q++; - - /* Copy rest of bigger set into result */ - p = &(big->setword[n]); - endp = &(big->setword[m]); - while ( p < endp ) *r++ = *p++; - - return(t); -} - -set -#ifdef __USE_PROTOS -set_and( set b, set c ) -#else -set_and( b, c ) -set b; -set c; -#endif -{ - /* Fast set intersection operation */ - /* resultant set size is min(b, c); */ - set t; - unsigned int n; - register unsigned *r, *p, *q, *endp; - - CHK(b); CHK(c); - t = empty; - n = (b.n > c.n) ? c.n : b.n; - if ( n == 0 ) return t; /* TJP 4-27-92 fixed for empty set */ - set_ext(&t, n); - r = t.setword; - - /* & b,c until max of smaller set */ - q = c.setword; - p = b.setword; - endp = &(b.setword[n]); - while ( p < endp ) *r++ = *p++ & *q++; - - return(t); -} - -set -#ifdef __USE_PROTOS -set_dif( set b, set c ) -#else -set_dif( b, c ) -set b; -set c; -#endif -{ - /* Fast set difference operation b - c */ - /* resultant set size is size(b) */ - set t; - unsigned int n; - register unsigned *r, *p, *q, *endp; - - CHK(b); CHK(c); - t = empty; - n = (b.n <= c.n) ? b.n : c.n ; - if ( b.n == 0 ) return t; /* TJP 4-27-92 fixed for empty set */ - /* WEC 12-1-92 fixed for c.n = 0 */ - set_ext(&t, b.n); - r = t.setword; - - /* Dif b,c until smaller set size */ - q = c.setword; - p = b.setword; - endp = &(b.setword[n]); - while ( p < endp ) *r++ = *p++ & (~ *q++); - - /* Copy rest of b into result if size(b) > c */ - if ( b.n > n ) - { - p = &(b.setword[n]); - endp = &(b.setword[b.n]); - while ( p < endp ) *r++ = *p++; - } - - return(t); -} - -set -#ifdef __USE_PROTOS -set_of( unsigned b ) -#else -set_of( b ) -unsigned b; -#endif -{ - /* Fast singleton set constructor operation */ - static set a; - - if ( b == nil ) return( empty ); - set_new(a, b); - a.setword[DIVWORD(b)] = bitmask[MODWORD(b)]; - - return(a); -} - -/* - * Extend (or shrink) the set passed in to have n words. - * - * if n is smaller than the minimum, boost n to have the minimum. - * if the new set size is the same as the old one, do nothing. - * - * TJP 4-27-92 Fixed so won't try to alloc 0 bytes - */ -void -#ifdef __USE_PROTOS -set_ext( set *a, unsigned int n ) -#else -set_ext( a, n ) -set *a; -unsigned int n; -#endif -{ - register unsigned *p; - register unsigned *endp; - unsigned int size; - - CHK((*a)); - if ( a->n == 0 ) - { - if ( n == 0 ) return; - if (a->setword != NULL) { - free (a->setword); /* MR20 */ - } - a->setword = (unsigned *) calloc(n, BytesPerWord); - if ( a->setword == NULL ) - { - fprintf(stderr, "set_ext(%d words): cannot allocate set\n", n); - exit(-1); - } - a->n = n; - return; - } - if ( n < min ) n = min; - if ( a->n == n || n == 0 ) return; - size = a->n; - a->n = n; - a->setword = (unsigned *) realloc( (char *)a->setword, (n*BytesPerWord) ); - if ( a->setword == NULL ) - { - fprintf(stderr, "set_ext(%d words): cannot allocate set\n", n); - exit(-1); - } - - p = &(a->setword[size]); /* clear from old size to new size */ - endp = &(a->setword[a->n]); - do { - *p++ = 0; - } while ( p < endp ); -} - -set -#ifdef __USE_PROTOS -set_not( set a ) -#else -set_not( a ) -set a; -#endif -{ - /* Fast not of set a (assumes all bits used) */ - /* size of resultant set is size(a) */ - /* ~empty = empty cause we don't know how bit to make set */ - set t; - register unsigned *r; - register unsigned *p = a.setword; - register unsigned *endp = &(a.setword[a.n]); - - CHK(a); - t = empty; - if ( a.n == 0 ) return( empty ); - set_ext(&t, a.n); - r = t.setword; - - do { - *r++ = (~ *p++); - } while ( p < endp ); - - return(t); -} - -int -#ifdef __USE_PROTOS -set_equ( set a, set b ) -#else -set_equ( a, b ) -set a; -set b; -#endif -{ -/* 8-Nov-97 Make it work with sets of different sizes */ -/* Easy to understand, too. Probably faster. */ -/* Check for a equal to b */ - - unsigned int count; /* MR11 */ - unsigned int i; /* MR11 */ - - CHK(a); CHK(b); - - count=MIN(a.n,b.n); - if (count == 0) return 1; - for (i=0; i < count; i++) { - if (a.setword[i] != b.setword[i]) return 0; - }; - if (a.n < b.n) { - for (i=count; i < b.n; i++) { - if (b.setword[i] != 0) return 0; - } - return 1; - } else if (a.n > b.n) { - for (i=count; i < a.n; i++) { - if (a.setword[i] != 0) return 0; - } - return 1; - } else { - return 1; - }; -} - -int -#ifdef __USE_PROTOS -set_sub( set a, set b ) -#else -set_sub( a, b ) -set a; -set b; -#endif -{ - -/* 8-Nov-97 Make it work with sets of different sizes */ -/* Easy to understand, too. Probably faster. */ -/* Check for a is a PROPER subset of b */ - - unsigned int count; - unsigned int i; - - CHK(a); CHK(b); - - if (a.n == 0) return 1; - count=MIN(a.n,b.n); - for (i=0; i < count; i++) { - if (a.setword[i] & ~b.setword[i]) return 0; - }; - if (a.n <= b.n) { - return 1; - } else { - for (i=count; i a.n ) return(0); - - /* Otherwise, we have to check */ - return( a.setword[DIVWORD(b)] & bitmask[MODWORD(b)] ); -} - -int -#ifdef __USE_PROTOS -set_nil( set a ) -#else -set_nil( a ) -set a; -#endif -{ - /* Fast check for nil set */ - register unsigned *p = a.setword; - register unsigned *endp; - - CHK(a); - if ( a.n == 0 ) return(1); - endp = &(a.setword[a.n]); - - /* The set is not empty if any word used to store - the set is non-zero. This means one must be a - bit careful about doing things like negation. - */ - do { - if (*p) return(0); - } while (++p < endp); - - return(1); -} - -char * -#ifdef __USE_PROTOS -set_str( set a ) -#else -set_str( a ) -set a; -#endif -{ - /* Fast convert set a into ASCII char string... - assumes that all word bits are used in the set - and that SETSIZE is a multiple of WORDSIZE. - Trailing 0 bits are removed from the string. - if no bits are on or set is empty, "" is returned. - */ - register unsigned *p = a.setword; - register unsigned *endp = &(a.setword[a.n]); - static char str_tmp[StrSize+1]; - register char *q = &(str_tmp[0]); - - CHK(a); - if ( a.n==0 ) {*q=0; return( &(str_tmp[0]) );} - do { - register unsigned t = *p; - register unsigned *b = &(bitmask[0]); - do { - *(q++) = (char) ((t & *b) ? '1' : '0'); - } while (++b < &(bitmask[WORDSIZE])); - } while (++p < endp); - - /* Trim trailing 0s & NULL terminate the string */ - while ((q > &(str_tmp[0])) && (*(q-1) != '1')) --q; - *q = 0; - - return(&(str_tmp[0])); -} - -set -#ifdef __USE_PROTOS -set_val( register char *s ) -#else -set_val( s ) -register char *s; -#endif -{ - /* Fast convert set ASCII char string into a set. - If the string ends early, the remaining set bits - are all made zero. - The resulting set size is just big enough to hold all elements. - */ - static set a; - register unsigned *p, *endp; - - set_new(a, strlen(s)); - p = a.setword; - endp = &(a.setword[a.n]); - do { - register unsigned *b = &(bitmask[0]); - /* Start with a word with no bits on */ - *p = 0; - do { - if (*s) { - if (*s == '1') { - /* Turn-on this bit */ - *p |= *b; - } - ++s; - } - } while (++b < &(bitmask[WORDSIZE])); - } while (++p < endp); - - return(a); -} - -/* - * Or element e into set a. a can be empty. - */ -void -#ifdef __USE_PROTOS -set_orel( unsigned e, set *a ) -#else -set_orel( e, a ) -unsigned e; -set *a; -#endif -{ - CHK((*a)); - if ( e == nil ) return; - if ( NumWords(e) > a->n ) set_ext(a, NumWords(e)); - a->setword[DIVWORD(e)] |= bitmask[MODWORD(e)]; -} - -/* - * Or set b into set a. a can be empty. does nothing if b empty. - */ -void -#ifdef __USE_PROTOS -set_orin( set *a, set b ) -#else -set_orin( a, b ) -set *a; -set b; -#endif -{ - /* Fast set union operation */ - /* size(a) is max(a, b); */ - unsigned int m; - register unsigned *p, - *q = b.setword, - *endq; /* MR20 */ - - CHK((*a)); CHK(b); - if ( b.n == 0 ) return; - endq = &(b.setword[b.n]); /* MR20 */ - m = (a->n > b.n) ? a->n : b.n; - set_ext(a, m); - p = a->setword; - do { - *p++ |= *q++; - } while ( q < endq ); -} - -/* - * And set b into set a. a can be empty. does nothing if b empty. - */ -void -#ifdef __USE_PROTOS -set_andin( set *a, set b ) -#else -set_andin( a, b ) -set *a; -set b; -#endif -{ - /* Fast set intersection operation */ - /* size(a) is max(a, b); */ - unsigned int m; - register unsigned *p, - *q = b.setword, - *endq = &(b.setword[b.n]); - - CHK((*a)); CHK(b); - if ( b.n == 0 ) return; - m = (a->n > b.n) ? a->n : b.n; - set_ext(a, m); - p = a->setword; - do { - *p++ &= *q++; - } while ( q < endq ); -} - -void -#ifdef __USE_PROTOS -set_rm( unsigned e, set a ) -#else -set_rm( e, a ) -unsigned e; -set a; -#endif -{ - /* Does not effect size of set */ - CHK(a); - if ( (e == nil) || (NumWords(e) > a.n) ) return; - a.setword[DIVWORD(e)] ^= (a.setword[DIVWORD(e)]&bitmask[MODWORD(e)]); -} - -void -#ifdef __USE_PROTOS -set_clr( set a ) -#else -set_clr( a ) -set a; -#endif -{ - /* Does not effect size of set */ - register unsigned *p = a.setword; - register unsigned *endp; - - CHK(a); - if ( a.n == 0 ) return; - endp = &(a.setword[a.n]); - do { - *p++ = 0; - } while ( p < endp ); -} - -set -#ifdef __USE_PROTOS -set_dup( set a ) -#else -set_dup( a ) -set a; -#endif -{ - set b; - register unsigned *p, - *q = a.setword, - *endq; /* MR20 */ - - CHK(a); - b = empty; - if ( a.n == 0 ) return( empty ); - endq = &(a.setword[a.n]); /* MR20 */ - set_ext(&b, a.n); - p = b.setword; - do { - *p++ = *q++; - } while ( q < endq ); - - return(b); -} - -/* - * Return a nil terminated list of unsigned ints that represents all - * "on" bits in the bit set. - * - * e.g. {011011} --> {1, 2, 4, 5, nil} - * - * _set_pdq and set_pdq are useful when an operation is required on each element - * of a set. Normally, the sequence is: - * - * while ( set_deg(a) > 0 ) { - * e = set_int(a); - * set_rm(e, a); - * ...process e... - * } - * Now, - * - * t = e = set_pdq(a); - * while ( *e != nil ) { - * ...process *e... - * e++; - * } - * free( t ); - * - * We have saved many set calls and have not destroyed set a. - */ -void -#ifdef __USE_PROTOS -_set_pdq( set a, register unsigned *q ) -#else -_set_pdq( a, q ) -set a; -register unsigned *q; -#endif -{ - register unsigned *p = a.setword, - *endp = &(a.setword[a.n]); - register unsigned e=0; - - CHK(a); - /* are there any space (possibility of elements)? */ - if ( a.n == 0 ) return; - do { - register unsigned t = *p; - register unsigned *b = &(bitmask[0]); - do { - if ( t & *b ) *q++ = e; - ++e; - } while (++b < &(bitmask[WORDSIZE])); - } while (++p < endp); - *q = nil; -} - -/* - * Same as _set_pdq except allocate memory. set_pdq is the natural function - * to use. - */ -unsigned * -#ifdef __USE_PROTOS -set_pdq( set a ) -#else -set_pdq( a ) -set a; -#endif -{ - unsigned *q; - int max_deg; - - CHK(a); - max_deg = WORDSIZE*a.n; - /* assume a.n!=0 & no elements is rare, but still ok */ - if ( a.n == 0 ) return(NULL); - q = (unsigned *) malloc((max_deg+1)*BytesPerWord); - if ( q == NULL ) return( NULL ); - _set_pdq(a, q); - return( q ); -} - -/* a function that produces a hash number for the set - */ -unsigned int -#ifdef __USE_PROTOS -set_hash( set a, register unsigned int mod ) -#else -set_hash( a, mod ) -set a; -register unsigned int mod; -#endif -{ - /* Fast hash of set a (assumes all bits used) */ - register unsigned *p = &(a.setword[0]); - register unsigned *endp = &(a.setword[a.n]); - register unsigned i = 0; - - CHK(a); - while (p> LogWordSize) /* x / WORDSIZE */ -#define nil (~((unsigned) 0)) /* An impossible set member all bits on (big!) */ - -typedef struct _set { - unsigned int n; /* Number of words in set */ - unsigned *setword; - } set; - -#define set_init {0, NULL} -#define set_null(a) ((a).setword==NULL) - -#define NumBytes(x) (((x)>>3)+1) /* Num bytes to hold x */ -#define NumWords(x) ((((unsigned)(x))>>LogWordSize)+1) /* Num words to hold x */ - - -/* M a c r o s */ - -/* make arg1 a set big enough to hold max elem # of arg2 */ -#define set_new(a,_max) \ -if (((a).setword=(unsigned *)calloc(NumWords(_max),BytesPerWord))==NULL) \ - fprintf(stderr, "set_new: Cannot allocate set with max of %d\n", _max); \ - (a).n = NumWords(_max); - -#define set_free(a) \ - {if ( (a).setword != NULL ) free((char *)((a).setword)); \ - (a) = empty;} - -#ifdef __USE_PROTOS -extern void set_size( unsigned ); -extern unsigned int set_deg( set ); -extern set set_or( set, set ); -extern set set_and( set, set ); -extern set set_dif( set, set ); -extern set set_of( unsigned ); -extern void set_ext( set *, unsigned int ); -extern set set_not( set ); -extern int set_equ( set, set ); -extern int set_sub( set, set ); -extern unsigned set_int( set ); -extern int set_el( unsigned, set ); -extern int set_nil( set ); -extern char * set_str( set ); -extern set set_val( register char * ); -extern void set_orel( unsigned, set * ); -extern void set_orin( set *, set ); -extern void set_andin( set *, set ); -extern void set_rm( unsigned, set ); -extern void set_clr( set ); -extern set set_dup( set ); -extern void set_PDQ( set, register unsigned * ); -extern unsigned *set_pdq( set ); -extern void _set_pdq( set a, register unsigned *q ); -extern unsigned int set_hash( set, register unsigned int ); -#else -extern void set_size(); -extern unsigned int set_deg(); -extern set set_or(); -extern set set_and(); -extern set set_dif(); -extern set set_of(); -extern void set_ext(); -extern set set_not(); -extern int set_equ(); -extern int set_sub(); -extern unsigned set_int(); -extern int set_el(); -extern int set_nil(); -extern char * set_str(); -extern set set_val(); -extern void set_orel(); -extern void set_orin(); -extern void set_andin(); -extern void set_rm(); -extern void set_clr(); -extern set set_dup(); -extern void set_PDQ(); -extern unsigned *set_pdq(); -extern void _set_pdq(); -extern unsigned int set_hash(); -#endif - -extern set empty; - -#endif diff --git a/Tools/CodeTools/TianoTools/Pccts/support/sym/sym.c b/Tools/CodeTools/TianoTools/Pccts/support/sym/sym.c deleted file mode 100644 index eccce059bb..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/support/sym/sym.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Simple symbol table manager using coalesced chaining to resolve collisions - * - * Doubly-linked lists are used for fast removal of entries. - * - * 'sym.h' must have a definition for typedef "Sym". Sym must include at - * minimum the following fields: - * - * ... - * char *symbol; - * struct ... *next, *prev, **head, *scope; - * unsigned int hash; - * ... - * - * 'template.h' can be used as a template to create a 'sym.h'. - * - * 'head' is &(table[hash(itself)]). - * The hash table is not resizable at run-time. - * The scope field is used to link all symbols of a current scope together. - * Scope() sets the current scope (linked list) to add symbols to. - * Any number of scopes can be handled. The user passes the address of - * a pointer to a symbol table - * entry (INITIALIZED TO NULL first time). - * - * Available Functions: - * - * zzs_init(s1,s2) -- Create hash table with size s1, string table size s2. - * zzs_done() -- Free hash and string table created with zzs_init(). - * zzs_add(key,rec)-- Add 'rec' with key 'key' to the symbol table. - * zzs_newadd(key) -- create entry; add using 'key' to the symbol table. - * zzs_get(key) -- Return pointer to last record entered under 'key' - * Else return NULL - * zzs_del(p) -- Unlink the entry associated with p. This does - * NOT free 'p' and DOES NOT remove it from a scope - * list. If it was a part of your intermediate code - * tree or another structure. It will still be there. - * It is only removed from further consideration - * by the symbol table. - * zzs_keydel(s) -- Unlink the entry associated with key s. - * Calls zzs_del(p) to unlink. - * zzs_scope(sc) -- Specifies that everything added to the symbol - * table with zzs_add() is added to the list (scope) - * 'sc'. 'sc' is of 'Sym **sc' type and must be - * initialized to NULL before trying to add anything - * to it (passing it to zzs_scope()). Scopes can be - * switched at any time and merely links a set of - * symbol table entries. If a NULL pointer is - * passed, the current scope is returned. - * zzs_rmscope(sc) -- Remove (zzs_del()) all elements of scope 'sc' - * from the symbol table. The entries are NOT - * free()'d. A pointer to the first - * element in the "scope" is returned. The user - * can then manipulate the list as he/she chooses - * (such as freeing them all). NOTE that this - * function sets your scope pointer to NULL, - * but returns a pointer to the list for you to use. - * zzs_stat() -- Print out the symbol table and some relevant stats. - * zzs_new(key) -- Create a new record with calloc() of type Sym. - * Add 'key' to the string table and make the new - * records 'symbol' pointer point to it. - * zzs_strdup(s) -- Add s to the string table and return a pointer - * to it. Very fast allocation routine - * and does not require strlen() nor calloc(). - * - * Example: - * - * #include - * #include "sym.h" - * - * main() - * { - * Sym *scope1=NULL, *scope2=NULL, *a, *p; - * - * zzs_init(101, 100); - * - * a = zzs_new("Apple"); zzs_add(a->symbol, a); -- No scope - * zzs_scope( &scope1 ); -- enter scope 1 - * a = zzs_new("Plum"); zzs_add(a->symbol, a); - * zzs_scope( &scope2 ); -- enter scope 2 - * a = zzs_new("Truck"); zzs_add(a->symbol, a); - * - * p = zzs_get("Plum"); - * if ( p == NULL ) fprintf(stderr, "Hmmm...Can't find 'Plum'\n"); - * - * p = zzs_rmscope(&scope1) - * for (; p!=NULL; p=p->scope) {printf("Scope1: %s\n", p->symbol);} - * p = zzs_rmscope(&scope2) - * for (; p!=NULL; p=p->scope) {printf("Scope2: %s\n", p->symbol);} - * } - * - * Terence Parr - * Purdue University - * February 1990 - * - * CHANGES - * - * Terence Parr - * May 1991 - * Renamed functions to be consistent with ANTLR - * Made HASH macro - * Added zzs_keydel() - * Added zzs_newadd() - * Fixed up zzs_stat() - * - * July 1991 - * Made symbol table entry save its hash code for fast comparison - * during searching etc... - */ - -#include -#if defined(__STDC__) || defined(__USE_PROTOS) -#include -#include -#else -#include -#endif -#include "sym.h" - -#define StrSame 0 - -static Sym **CurScope = NULL; -static unsigned size = 0; -static Sym **table=NULL; -static char *strings; -static char *strp; -static int strsize = 0; - -#ifdef __USE_PROTOS -void zzs_init(int sz,int strs) -#else -void zzs_init(sz, strs) -int sz, strs; -#endif -{ - if ( sz <= 0 || strs <= 0 ) return; - table = (Sym **) calloc(sz, sizeof(Sym *)); - if ( table == NULL ) - { - fprintf(stderr, "Cannot allocate table of size %d\n", sz); - exit(1); - } - strings = (char *) calloc(strs, sizeof(char)); - if ( strings == NULL ) - { - fprintf(stderr, "Cannot allocate string table of size %d\n", strs); - exit(1); - } - size = sz; - strsize = strs; - strp = strings; -} - -#ifdef __USE_PROTOS -void zzs_done(void) -#else -void zzs_done() -#endif -{ - if ( table != NULL ) free( table ); - if ( strings != NULL ) free( strings ); -} - -#ifdef __USE_PROTOS -void zzs_add(char *key,Sym rec) -#else -void zzs_add(key, rec) -char *key; -register Sym *rec; -#endif -{ - register unsigned int h=0; - register char *p=key; - - HASH(p, h); - rec->hash = h; /* save hash code for fast comp later */ - h %= size; - - if ( CurScope != NULL ) {rec->scope = *CurScope; *CurScope = rec;} - rec->next = table[h]; /* Add to doubly-linked list */ - rec->prev = NULL; - if ( rec->next != NULL ) (rec->next)->prev = rec; - table[h] = rec; - rec->head = &(table[h]); -} - -#ifdef __USE_PROTOS -Sym * zzs_get(char *key) -#else -Sym * zzs_get(key) -char *key; -#endif -{ - register unsigned int h=0; - register char *p=key; - register Sym *q; - - HASH(p, h); - - for (q = table[h%size]; q != NULL; q = q->next) - { - if ( q->hash == h ) /* do we even have a chance of matching? */ - if ( strcmp(key, q->symbol) == StrSame ) return( q ); - } - return( NULL ); -} - -/* - * Unlink p from the symbol table. Hopefully, it's actually in the - * symbol table. - * - * If p is not part of a bucket chain of the symbol table, bad things - * will happen. - * - * Will do nothing if all list pointers are NULL - */ -#ifdef __USE_PROTOS -void zzs_del(Sym *p) -#else -void zzs_del(p) -register Sym *p; -#endif -{ - if ( p == NULL ) {fprintf(stderr, "zzs_del(NULL)\n"); exit(1);} - if ( p->prev == NULL ) /* Head of list */ - { - register Sym **t = p->head; - - if ( t == NULL ) return; /* not part of symbol table */ - (*t) = p->next; - if ( (*t) != NULL ) (*t)->prev = NULL; - } - else - { - (p->prev)->next = p->next; - if ( p->next != NULL ) (p->next)->prev = p->prev; - } - p->next = p->prev = NULL; /* not part of symbol table anymore */ - p->head = NULL; -} - -#ifdef __USE_PROTOS -void zzs_keydel(char *key) -#else -void zzs_keydel(key) -char *key; -#endif -{ - Sym *p = zzs_get(key); - - if ( p != NULL ) zzs_del( p ); -} - -/* S c o p e S t u f f */ - -/* Set current scope to 'scope'; return current scope if 'scope' == NULL */ - -#ifdef __USE_PROTOS -Sym ** zzs_scope(Sym **scope) -#else -Sym ** zzs_scope(scope) -Sym **scope; -#endif -{ - if ( scope == NULL ) return( CurScope ); - CurScope = scope; - return( scope ); -} - -/* Remove a scope described by 'scope'. Return pointer to 1st element in scope */ - -#ifdef __USE_PROTOS -Sym * zzs_rmscope(Sym **scope) -#else -Sym * zzs_rmscope(scope) -register Sym **scope; -#endif -{ - register Sym *p; - Sym *start; - - if ( scope == NULL ) return(NULL); - start = p = *scope; - for (; p != NULL; p=p->scope) { zzs_del( p ); } - *scope = NULL; - return( start ); -} - -#ifdef __USE_PROTOS -void zzs_stat(void) -#else -void zzs_stat() -#endif -{ - static unsigned short count[20]; - unsigned int i,n=0,low=0, hi=0; - register Sym **p; - float avg=0.0; - - for (i=0; i<20; i++) count[i] = 0; - for (p=table; p<&(table[size]); p++) - { - register Sym *q = *p; - unsigned int len; - - if ( q != NULL && low==0 ) low = p-table; - len = 0; - if ( q != NULL ) printf("[%d]", p-table); - while ( q != NULL ) - { - len++; - n++; - printf(" %s", q->symbol); - q = q->next; - if ( q == NULL ) printf("\n"); - } - if ( len>=20 ) printf("zzs_stat: count table too small\n"); - else count[len]++; - if ( *p != NULL ) hi = p-table; - } - - printf("Storing %d recs used %d hash positions out of %d\n", - n, size-count[0], size); - printf("%f %% utilization\n", - ((float)(size-count[0]))/((float)size)); - for (i=0; i<20; i++) - { - if ( count[i] != 0 ) - { - avg += (((float)(i*count[i]))/((float)n)) * i; - printf("Buckets of len %d == %d (%f %% of recs)\n", - i, count[i], 100.0*((float)(i*count[i]))/((float)n)); - } - } - printf("Avg bucket length %f\n", avg); - printf("Range of hash function: %d..%d\n", low, hi); -} - -/* - * Given a string, this function allocates and returns a pointer to a - * symbol table record whose "symbol" pointer is reset to a position - * in the string table. - */ - -#ifdef __USE_PROTOS -Sym * zzs_new(char *text) -#else -Sym * zzs_new(text) -char *text; -#endif -{ - Sym *p; - - if ( (p = (Sym *) calloc(1,sizeof(Sym))) == 0 ) - { - fprintf(stderr,"Out of memory\n"); - exit(1); - } - p->symbol = zzs_strdup(text); - - return p; -} - -/* create a new symbol table entry and add it to the symbol table */ - -#ifdef __USE_PROTOS -Sym * zzs_newadd(char *text) -#else -Sym * zzs_newadd(text) -char *text; -#endif -{ - Sym *p = zzs_new(text); - if ( p != NULL ) zzs_add(text, p); - return p; -} - -/* Add a string to the string table and return a pointer to it. - * Bump the pointer into the string table to next avail position. - */ - -#ifdef __USE_PROTOS -char * zzs_strdup(char *s) -#else -char * zzs_strdup(s) -register char *s; -#endif -{ - register char *start=strp; - - while ( *s != '\0' ) - { - if ( strp >= &(strings[strsize-2]) ) - { - fprintf(stderr, "sym: string table overflow (%d chars)\n", strsize); - exit(-1); - } - *strp++ = *s++; - } - *strp++ = '\0'; - - return( start ); -} diff --git a/Tools/CodeTools/TianoTools/Pccts/support/sym/template.h b/Tools/CodeTools/TianoTools/Pccts/support/sym/template.h deleted file mode 100644 index ee6e665e34..0000000000 --- a/Tools/CodeTools/TianoTools/Pccts/support/sym/template.h +++ /dev/null @@ -1,41 +0,0 @@ -/* T e m p l a t e F o r S y m b o l T a b l e M a n a g e r */ - -/* define some hash function */ -#ifndef HASH -#define HASH(p, h) while ( *p != '\0' ) h = (h<<1) + *p++; -#endif - -/* minimum symbol table record */ -typedef struct _sym { - char *symbol; - struct _sym *next, *prev, **head, *scope; - unsigned int hash; - } Sym, *SymPtr; - -#ifdef __USE_PROTOS -void zzs_init(int, int); -void zzs_done(void); -void zzs_add(char *, Sym *); -Sym *zzs_get(char *); -void zzs_del(Sym *); -void zzs_keydel(char *); -Sym **zzs_scope(Sym **); -Sym *zzs_rmscope(Sym **); -void zzs_stat(void); -Sym *zzs_new(char *); -Sym *zzs_newadd(char *); -char *zzs_strdup(char *); -#else -void zzs_init(); -void zzs_done(); -void zzs_add(); -Sym *zzs_get(); -void zzs_del(); -void zzs_keydel(); -Sym **zzs_scope(); -Sym *zzs_rmscope(); -void zzs_stat(); -Sym *zzs_new(); -Sym *zzs_newadd(); -char *zzs_strdup(); -#endif diff --git a/Tools/CodeTools/TianoTools/PeCoffLoader/BasePeCoff.c b/Tools/CodeTools/TianoTools/PeCoffLoader/BasePeCoff.c deleted file mode 100644 index 9c25e1f4b8..0000000000 --- a/Tools/CodeTools/TianoTools/PeCoffLoader/BasePeCoff.c +++ /dev/null @@ -1,1060 +0,0 @@ -/*++ - -Copyright (c) 2004 - 2005, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PeCoffLoader.c - -Abstract: - - Tiano PE/COFF loader - -Revision History - ---*/ - - -#include -#include -#include - -STATIC -RETURN_STATUS -PeCoffLoaderGetPeHeader ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - OUT EFI_IMAGE_NT_HEADERS *PeHdr, - OUT EFI_TE_IMAGE_HEADER *TeHdr - ); - -STATIC -RETURN_STATUS -PeCoffLoaderCheckImageType ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - IN EFI_IMAGE_NT_HEADERS *PeHdr, - IN EFI_TE_IMAGE_HEADER *TeHdr - ); - -STATIC -VOID * -PeCoffLoaderImageAddress ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - IN UINTN Address - ); - - -STATIC -RETURN_STATUS -PeCoffLoaderGetPeHeader ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - OUT EFI_IMAGE_NT_HEADERS *PeHdr, - OUT EFI_TE_IMAGE_HEADER *TeHdr - ) -/*++ - -Routine Description: - - Retrieves the PE or TE Header from a PE/COFF or TE image - -Arguments: - - ImageContext - The context of the image being loaded - - PeHdr - The buffer in which to return the PE header - - TeHdr - The buffer in which to return the TE header - -Returns: - - RETURN_SUCCESS if the PE or TE Header is read, - Otherwise, the error status from reading the PE/COFF or TE image using the ImageRead function. - ---*/ -{ - RETURN_STATUS Status; - EFI_IMAGE_DOS_HEADER DosHdr; - UINTN Size; - - ImageContext->IsTeImage = FALSE; - // - // Read the DOS image headers - // - Size = sizeof (EFI_IMAGE_DOS_HEADER); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - 0, - &Size, - &DosHdr - ); - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return Status; - } - - ImageContext->PeCoffHeaderOffset = 0; - if (DosHdr.e_magic == EFI_IMAGE_DOS_SIGNATURE) { - // - // DOS image header is present, so read the PE header after the DOS image header - // - ImageContext->PeCoffHeaderOffset = DosHdr.e_lfanew; - } - // - // Read the PE/COFF Header - // - Size = sizeof (EFI_IMAGE_NT_HEADERS); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - ImageContext->PeCoffHeaderOffset, - &Size, - PeHdr - ); - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return Status; - } - // - // Check the PE/COFF Header Signature. If not, then try to read a TE header - // - if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) { - Size = sizeof (EFI_TE_IMAGE_HEADER); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - 0, - &Size, - TeHdr - ); - if (TeHdr->Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) { - return RETURN_UNSUPPORTED; - } - - ImageContext->IsTeImage = TRUE; - } - - return RETURN_SUCCESS; -} - -STATIC -RETURN_STATUS -PeCoffLoaderCheckImageType ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - IN EFI_IMAGE_NT_HEADERS *PeHdr, - IN EFI_TE_IMAGE_HEADER *TeHdr - ) -/*++ - -Routine Description: - - Checks the PE or TE header of a PE/COFF or TE image to determine if it supported - -Arguments: - - ImageContext - The context of the image being loaded - - PeHdr - The buffer in which to return the PE header - - TeHdr - The buffer in which to return the TE header - -Returns: - - RETURN_SUCCESS if the PE/COFF or TE image is supported - RETURN_UNSUPPORTED of the PE/COFF or TE image is not supported. - ---*/ -{ - // - // See if the machine type is supported. We support a native machine type (IA-32/Itanium-based) - // and the machine type for the Virtual Machine. - // - if (ImageContext->IsTeImage == FALSE) { - ImageContext->Machine = PeHdr->FileHeader.Machine; - } else { - ImageContext->Machine = TeHdr->Machine; - } - - if (!(EFI_IMAGE_MACHINE_TYPE_SUPPORTED (ImageContext->Machine))) { - ImageContext->ImageError = IMAGE_ERROR_INVALID_MACHINE_TYPE; - return RETURN_UNSUPPORTED; - } - - // - // See if the image type is supported. We support EFI Applications, - // EFI Boot Service Drivers, and EFI Runtime Drivers. - // - if (ImageContext->IsTeImage == FALSE) { - ImageContext->ImageType = PeHdr->OptionalHeader.Subsystem; - } else { - ImageContext->ImageType = (UINT16) (TeHdr->Subsystem); - } - - - return RETURN_SUCCESS; -} - -RETURN_STATUS -EFIAPI -PeCoffLoaderGetImageInfo ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -/*++ - -Routine Description: - - Retrieves information on a PE/COFF image - -Arguments: - - This - Calling context - ImageContext - The context of the image being loaded - -Returns: - - RETURN_SUCCESS - The information on the PE/COFF image was collected. - RETURN_INVALID_PARAMETER - ImageContext is NULL. - RETURN_UNSUPPORTED - The PE/COFF image is not supported. - Otherwise - The error status from reading the PE/COFF image using the - ImageContext->ImageRead() function - ---*/ -{ - RETURN_STATUS Status; - EFI_IMAGE_NT_HEADERS PeHdr; - EFI_TE_IMAGE_HEADER TeHdr; - EFI_IMAGE_DATA_DIRECTORY *DebugDirectoryEntry; - UINTN Size; - UINTN Index; - UINTN DebugDirectoryEntryRva; - UINTN DebugDirectoryEntryFileOffset; - UINTN SectionHeaderOffset; - EFI_IMAGE_SECTION_HEADER SectionHeader; - EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry; - - if (NULL == ImageContext) { - return RETURN_INVALID_PARAMETER; - } - // - // Assume success - // - ImageContext->ImageError = IMAGE_ERROR_SUCCESS; - - Status = PeCoffLoaderGetPeHeader (ImageContext, &PeHdr, &TeHdr); - if (RETURN_ERROR (Status)) { - return Status; - } - // - // Verify machine type - // - Status = PeCoffLoaderCheckImageType (ImageContext, &PeHdr, &TeHdr); - if (RETURN_ERROR (Status)) { - return Status; - } - // - // Retrieve the base address of the image - // - if (!(ImageContext->IsTeImage)) { - ImageContext->ImageAddress = PeHdr.OptionalHeader.ImageBase; - } else { - ImageContext->ImageAddress = (PHYSICAL_ADDRESS) (TeHdr.ImageBase); - } - // - // Initialize the alternate destination address to 0 indicating that it - // should not be used. - // - ImageContext->DestinationAddress = 0; - - // - // Initialize the codeview pointer. - // - ImageContext->CodeView = NULL; - ImageContext->PdbPointer = NULL; - - // - // Three cases with regards to relocations: - // - Image has base relocs, RELOCS_STRIPPED==0 => image is relocatable - // - Image has no base relocs, RELOCS_STRIPPED==1 => Image is not relocatable - // - Image has no base relocs, RELOCS_STRIPPED==0 => Image is relocatable but - // has no base relocs to apply - // Obviously having base relocations with RELOCS_STRIPPED==1 is invalid. - // - // Look at the file header to determine if relocations have been stripped, and - // save this info in the image context for later use. - // - if ((!(ImageContext->IsTeImage)) && ((PeHdr.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0)) { - ImageContext->RelocationsStripped = TRUE; - } else { - ImageContext->RelocationsStripped = FALSE; - } - - if (!(ImageContext->IsTeImage)) { - ImageContext->ImageSize = (UINT64) PeHdr.OptionalHeader.SizeOfImage; - ImageContext->SectionAlignment = PeHdr.OptionalHeader.SectionAlignment; - ImageContext->SizeOfHeaders = PeHdr.OptionalHeader.SizeOfHeaders; - - // - // Modify ImageSize to contain .PDB file name if required and initialize - // PdbRVA field... - // - if (PeHdr.OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { - DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); - - DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress; - - // - // Determine the file offset of the debug directory... This means we walk - // the sections to find which section contains the RVA of the debug - // directory - // - DebugDirectoryEntryFileOffset = 0; - - SectionHeaderOffset = (UINTN)( - ImageContext->PeCoffHeaderOffset + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - PeHdr.FileHeader.SizeOfOptionalHeader - ); - - for (Index = 0; Index < PeHdr.FileHeader.NumberOfSections; Index++) { - // - // Read section header from file - // - Size = sizeof (EFI_IMAGE_SECTION_HEADER); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - SectionHeaderOffset, - &Size, - &SectionHeader - ); - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return Status; - } - - if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress && - DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) { - DebugDirectoryEntryFileOffset = - DebugDirectoryEntryRva - SectionHeader.VirtualAddress + SectionHeader.PointerToRawData; - break; - } - - SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER); - } - - if (DebugDirectoryEntryFileOffset != 0) { - for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) { - // - // Read next debug directory entry - // - Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - DebugDirectoryEntryFileOffset, - &Size, - &DebugEntry - ); - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return Status; - } - - if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { - ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)); - if (DebugEntry.RVA == 0 && DebugEntry.FileOffset != 0) { - ImageContext->ImageSize += DebugEntry.SizeOfData; - } - - return RETURN_SUCCESS; - } - } - } - } - } else { - ImageContext->ImageSize = 0; - ImageContext->SectionAlignment = 4096; - ImageContext->SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN) TeHdr.BaseOfCode - (UINTN) TeHdr.StrippedSize; - - DebugDirectoryEntry = &TeHdr.DataDirectory[1]; - DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress; - SectionHeaderOffset = (UINTN) (sizeof (EFI_TE_IMAGE_HEADER)); - - DebugDirectoryEntryFileOffset = 0; - - for (Index = 0; Index < TeHdr.NumberOfSections;) { - // - // Read section header from file - // - Size = sizeof (EFI_IMAGE_SECTION_HEADER); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - SectionHeaderOffset, - &Size, - &SectionHeader - ); - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return Status; - } - - if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress && - DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) { - DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva - - SectionHeader.VirtualAddress + - SectionHeader.PointerToRawData + - sizeof (EFI_TE_IMAGE_HEADER) - - TeHdr.StrippedSize; - - // - // File offset of the debug directory was found, if this is not the last - // section, then skip to the last section for calculating the image size. - // - if (Index < (UINTN) TeHdr.NumberOfSections - 1) { - SectionHeaderOffset += (TeHdr.NumberOfSections - 1 - Index) * sizeof (EFI_IMAGE_SECTION_HEADER); - Index = TeHdr.NumberOfSections - 1; - continue; - } - } - - // - // In Te image header there is not a field to describe the ImageSize. - // Actually, the ImageSize equals the RVA plus the VirtualSize of - // the last section mapped into memory (Must be rounded up to - // a mulitple of Section Alignment). Per the PE/COFF specification, the - // section headers in the Section Table must appear in order of the RVA - // values for the corresponding sections. So the ImageSize can be determined - // by the RVA and the VirtualSize of the last section header in the - // Section Table. - // - if ((++Index) == (UINTN) TeHdr.NumberOfSections) { - ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize + - ImageContext->SectionAlignment - 1) & ~(ImageContext->SectionAlignment - 1); - } - - SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER); - } - - if (DebugDirectoryEntryFileOffset != 0) { - for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) { - // - // Read next debug directory entry - // - Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - DebugDirectoryEntryFileOffset, - &Size, - &DebugEntry - ); - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return Status; - } - - if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { - ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)); - return RETURN_SUCCESS; - } - } - } - } - - return RETURN_SUCCESS; -} - -STATIC -VOID * -PeCoffLoaderImageAddress ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - IN UINTN Address - ) -/*++ - -Routine Description: - - Converts an image address to the loaded address - -Arguments: - - ImageContext - The context of the image being loaded - - Address - The address to be converted to the loaded address - -Returns: - - NULL if the address can not be converted, otherwise, the converted address - ---*/ -{ - if (Address >= ImageContext->ImageSize) { - ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS; - return NULL; - } - - return (CHAR8 *) ((UINTN) ImageContext->ImageAddress + Address); -} - -RETURN_STATUS -EFIAPI -PeCoffLoaderRelocateImage ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -/*++ - -Routine Description: - - Relocates a PE/COFF image in memory - -Arguments: - - This - Calling context - - ImageContext - Contains information on the loaded image to relocate - -Returns: - - RETURN_SUCCESS if the PE/COFF image was relocated - RETURN_LOAD_ERROR if the image is not a valid PE/COFF image - RETURN_UNSUPPORTED not support - ---*/ -{ - RETURN_STATUS Status; - EFI_IMAGE_NT_HEADERS *PeHdr; - EFI_TE_IMAGE_HEADER *TeHdr; - EFI_IMAGE_DATA_DIRECTORY *RelocDir; - UINT64 Adjust; - EFI_IMAGE_BASE_RELOCATION *RelocBase; - EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd; - UINT16 *Reloc; - UINT16 *RelocEnd; - CHAR8 *Fixup; - CHAR8 *FixupBase; - UINT16 *F16; - UINT32 *F32; - CHAR8 *FixupData; - PHYSICAL_ADDRESS BaseAddress; - - PeHdr = NULL; - TeHdr = NULL; - // - // Assume success - // - ImageContext->ImageError = IMAGE_ERROR_SUCCESS; - - // - // If there are no relocation entries, then we are done - // - if (ImageContext->RelocationsStripped) { - return RETURN_SUCCESS; - } - - // - // If the destination address is not 0, use that rather than the - // image address as the relocation target. - // - if (ImageContext->DestinationAddress) { - BaseAddress = ImageContext->DestinationAddress; - } else { - BaseAddress = ImageContext->ImageAddress; - } - - if (!(ImageContext->IsTeImage)) { - PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN)ImageContext->ImageAddress + - ImageContext->PeCoffHeaderOffset); - Adjust = (UINT64) BaseAddress - PeHdr->OptionalHeader.ImageBase; - PeHdr->OptionalHeader.ImageBase = (UINTN) BaseAddress; - - // - // Find the relocation block - // - // Per the PE/COFF spec, you can't assume that a given data directory - // is present in the image. You have to check the NumberOfRvaAndSizes in - // the optional header to verify a desired directory entry is there. - // - if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { - RelocDir = &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]; - RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress); - RelocBaseEnd = PeCoffLoaderImageAddress ( - ImageContext, - RelocDir->VirtualAddress + RelocDir->Size - 1 - ); - } else { - // - // Set base and end to bypass processing below. - // - RelocBase = RelocBaseEnd = 0; - } - } else { - TeHdr = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress); - Adjust = (UINT64) (BaseAddress - TeHdr->ImageBase); - TeHdr->ImageBase = (UINT64) (BaseAddress); - - // - // Find the relocation block - // - RelocDir = &TeHdr->DataDirectory[0]; - RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)( - ImageContext->ImageAddress + - RelocDir->VirtualAddress + - sizeof(EFI_TE_IMAGE_HEADER) - - TeHdr->StrippedSize - ); - RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1); - } - - // - // Run the relocation information and apply the fixups - // - FixupData = ImageContext->FixupData; - while (RelocBase < RelocBaseEnd) { - - Reloc = (UINT16 *) ((CHAR8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION)); - RelocEnd = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock); - if (!(ImageContext->IsTeImage)) { - FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress); - } else { - FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress + - RelocBase->VirtualAddress + - sizeof(EFI_TE_IMAGE_HEADER) - - TeHdr->StrippedSize - ); - } - - if ((CHAR8 *) RelocEnd < (CHAR8 *) ((UINTN) ImageContext->ImageAddress) || - (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress + - (UINTN)ImageContext->ImageSize)) { - ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; - return RETURN_LOAD_ERROR; - } - - // - // Run this relocation record - // - while (Reloc < RelocEnd) { - - Fixup = FixupBase + (*Reloc & 0xFFF); - switch ((*Reloc) >> 12) { - case EFI_IMAGE_REL_BASED_ABSOLUTE: - break; - - case EFI_IMAGE_REL_BASED_HIGH: - F16 = (UINT16 *) Fixup; - *F16 = (UINT16) (*F16 + ((UINT16) ((UINT32) Adjust >> 16))); - if (FixupData != NULL) { - *(UINT16 *) FixupData = *F16; - FixupData = FixupData + sizeof (UINT16); - } - break; - - case EFI_IMAGE_REL_BASED_LOW: - F16 = (UINT16 *) Fixup; - *F16 = (UINT16) (*F16 + (UINT16) Adjust); - if (FixupData != NULL) { - *(UINT16 *) FixupData = *F16; - FixupData = FixupData + sizeof (UINT16); - } - break; - - case EFI_IMAGE_REL_BASED_HIGHLOW: - F32 = (UINT32 *) Fixup; - *F32 = *F32 + (UINT32) Adjust; - if (FixupData != NULL) { - FixupData = ALIGN_POINTER (FixupData, sizeof (UINT32)); - *(UINT32 *) FixupData = *F32; - FixupData = FixupData + sizeof (UINT32); - } - break; - - case EFI_IMAGE_REL_BASED_HIGHADJ: - // - // Return the same EFI_UNSUPPORTED return code as - // PeCoffLoaderRelocateImageEx() returns if it does not recognize - // the relocation type. - // - ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; - return RETURN_UNSUPPORTED; - - default: - Status = PeCoffLoaderRelocateImageEx (Reloc, Fixup, &FixupData, Adjust); - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; - return Status; - } - } - - // - // Next relocation record - // - Reloc += 1; - } - - // - // Next reloc block - // - RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd; - } - - return RETURN_SUCCESS; -} - -RETURN_STATUS -EFIAPI -PeCoffLoaderLoadImage ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -/*++ - -Routine Description: - - Loads a PE/COFF image into memory - -Arguments: - - This - Calling context - - ImageContext - Contains information on image to load into memory - -Returns: - - RETURN_SUCCESS if the PE/COFF image was loaded - RETURN_BUFFER_TOO_SMALL if the caller did not provide a large enough buffer - RETURN_LOAD_ERROR if the image is a runtime driver with no relocations - RETURN_INVALID_PARAMETER if the image address is invalid - ---*/ -{ - RETURN_STATUS Status; - EFI_IMAGE_NT_HEADERS *PeHdr; - EFI_TE_IMAGE_HEADER *TeHdr; - PE_COFF_LOADER_IMAGE_CONTEXT CheckContext; - EFI_IMAGE_SECTION_HEADER *FirstSection; - EFI_IMAGE_SECTION_HEADER *Section; - UINTN NumberOfSections; - UINTN Index; - CHAR8 *Base; - CHAR8 *End; - CHAR8 *MaxEnd; - EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry; - EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry; - UINTN Size; - UINT32 TempDebugEntryRva; - - PeHdr = NULL; - TeHdr = NULL; - // - // Assume success - // - ImageContext->ImageError = IMAGE_ERROR_SUCCESS; - - // - // Copy the provided context info into our local version, get what we - // can from the original image, and then use that to make sure everything - // is legit. - // - CopyMem (&CheckContext, ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)); - - Status = PeCoffLoaderGetImageInfo (&CheckContext); - if (RETURN_ERROR (Status)) { - return Status; - } - - // - // Make sure there is enough allocated space for the image being loaded - // - if (ImageContext->ImageSize < CheckContext.ImageSize) { - ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_SIZE; - return RETURN_BUFFER_TOO_SMALL; - } - - // - // If there's no relocations, then make sure it's not a runtime driver, - // and that it's being loaded at the linked address. - // - if (CheckContext.RelocationsStripped) { - // - // If the image does not contain relocations and it is a runtime driver - // then return an error. - // - if (CheckContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) { - ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM; - return RETURN_LOAD_ERROR; - } - // - // If the image does not contain relocations, and the requested load address - // is not the linked address, then return an error. - // - if (CheckContext.ImageAddress != ImageContext->ImageAddress) { - ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS; - return RETURN_INVALID_PARAMETER; - } - } - // - // Make sure the allocated space has the proper section alignment - // - if (!(ImageContext->IsTeImage)) { - if ((ImageContext->ImageAddress & (CheckContext.SectionAlignment - 1)) != 0) { - ImageContext->ImageError = IMAGE_ERROR_INVALID_SECTION_ALIGNMENT; - return RETURN_INVALID_PARAMETER; - } - } - // - // Read the entire PE/COFF or TE header into memory - // - if (!(ImageContext->IsTeImage)) { - Status = ImageContext->ImageRead ( - ImageContext->Handle, - 0, - &ImageContext->SizeOfHeaders, - (VOID *) (UINTN) ImageContext->ImageAddress - ); - - PeHdr = (EFI_IMAGE_NT_HEADERS *) - ((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset); - - FirstSection = (EFI_IMAGE_SECTION_HEADER *) ( - (UINTN)ImageContext->ImageAddress + - ImageContext->PeCoffHeaderOffset + - sizeof(UINT32) + - sizeof(EFI_IMAGE_FILE_HEADER) + - PeHdr->FileHeader.SizeOfOptionalHeader - ); - NumberOfSections = (UINTN) (PeHdr->FileHeader.NumberOfSections); - } else { - Status = ImageContext->ImageRead ( - ImageContext->Handle, - 0, - &ImageContext->SizeOfHeaders, - (void *) (UINTN) ImageContext->ImageAddress - ); - - TeHdr = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress); - - FirstSection = (EFI_IMAGE_SECTION_HEADER *) ( - (UINTN)ImageContext->ImageAddress + - sizeof(EFI_TE_IMAGE_HEADER) - ); - NumberOfSections = (UINTN) (TeHdr->NumberOfSections); - - } - - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return RETURN_LOAD_ERROR; - } - - // - // Load each section of the image - // - Section = FirstSection; - for (Index = 0, MaxEnd = NULL; Index < NumberOfSections; Index++) { - - // - // Compute sections address - // - Base = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress); - End = PeCoffLoaderImageAddress ( - ImageContext, - Section->VirtualAddress + Section->Misc.VirtualSize - 1 - ); - if (ImageContext->IsTeImage) { - Base = (CHAR8 *) ((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize); - End = (CHAR8 *) ((UINTN) End + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize); - } - - if (End > MaxEnd) { - MaxEnd = End; - } - // - // If the base start or end address resolved to 0, then fail. - // - if ((Base == NULL) || (End == NULL)) { - ImageContext->ImageError = IMAGE_ERROR_SECTION_NOT_LOADED; - return RETURN_LOAD_ERROR; - } - - // - // Read the section - // - Size = (UINTN) Section->Misc.VirtualSize; - if ((Size == 0) || (Size > Section->SizeOfRawData)) { - Size = (UINTN) Section->SizeOfRawData; - } - - if (Section->SizeOfRawData) { - if (!(ImageContext->IsTeImage)) { - Status = ImageContext->ImageRead ( - ImageContext->Handle, - Section->PointerToRawData, - &Size, - Base - ); - } else { - Status = ImageContext->ImageRead ( - ImageContext->Handle, - Section->PointerToRawData + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize, - &Size, - Base - ); - } - - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return Status; - } - } - - // - // If raw size is less then virt size, zero fill the remaining - // - - if (Size < Section->Misc.VirtualSize) { - ZeroMem (Base + Size, Section->Misc.VirtualSize - Size); - } - - // - // Next Section - // - Section += 1; - } - - // - // Get image's entry point - // - if (!(ImageContext->IsTeImage)) { - ImageContext->EntryPoint = (PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress ( - ImageContext, - PeHdr->OptionalHeader.AddressOfEntryPoint - ); - } else { - ImageContext->EntryPoint = (PHYSICAL_ADDRESS) ( - (UINTN)ImageContext->ImageAddress + - (UINTN)TeHdr->AddressOfEntryPoint + - (UINTN)sizeof(EFI_TE_IMAGE_HEADER) - - (UINTN) TeHdr->StrippedSize - ); - } - - // - // Determine the size of the fixup data - // - // Per the PE/COFF spec, you can't assume that a given data directory - // is present in the image. You have to check the NumberOfRvaAndSizes in - // the optional header to verify a desired directory entry is there. - // - if (!(ImageContext->IsTeImage)) { - if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { - DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) - &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]; - ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN); - } else { - ImageContext->FixupDataSize = 0; - } - } else { - DirectoryEntry = &TeHdr->DataDirectory[0]; - ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN); - } - // - // Consumer must allocate a buffer for the relocation fixup log. - // Only used for runtime drivers. - // - ImageContext->FixupData = NULL; - - // - // Load the Codeview info if present - // - if (ImageContext->DebugDirectoryEntryRva != 0) { - if (!(ImageContext->IsTeImage)) { - DebugEntry = PeCoffLoaderImageAddress ( - ImageContext, - ImageContext->DebugDirectoryEntryRva - ); - } else { - DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)( - ImageContext->ImageAddress + - ImageContext->DebugDirectoryEntryRva + - sizeof(EFI_TE_IMAGE_HEADER) - - TeHdr->StrippedSize - ); - } - - if (DebugEntry != NULL) { - TempDebugEntryRva = DebugEntry->RVA; - if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) { - Section--; - if ((UINTN) Section->SizeOfRawData < Section->Misc.VirtualSize) { - TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize; - } else { - TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData; - } - } - - if (TempDebugEntryRva != 0) { - if (!(ImageContext->IsTeImage)) { - ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva); - } else { - ImageContext->CodeView = (VOID *)( - (UINTN)ImageContext->ImageAddress + - (UINTN)TempDebugEntryRva + - (UINTN)sizeof(EFI_TE_IMAGE_HEADER) - - (UINTN) TeHdr->StrippedSize - ); - } - - if (ImageContext->CodeView == NULL) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return RETURN_LOAD_ERROR; - } - - if (DebugEntry->RVA == 0) { - Size = DebugEntry->SizeOfData; - if (!(ImageContext->IsTeImage)) { - Status = ImageContext->ImageRead ( - ImageContext->Handle, - DebugEntry->FileOffset, - &Size, - ImageContext->CodeView - ); - } else { - Status = ImageContext->ImageRead ( - ImageContext->Handle, - DebugEntry->FileOffset + sizeof (EFI_TE_IMAGE_HEADER) - TeHdr->StrippedSize, - &Size, - ImageContext->CodeView - ); - // - // Should we apply fix up to this field according to the size difference between PE and TE? - // Because now we maintain TE header fields unfixed, this field will also remain as they are - // in original PE image. - // - } - - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return RETURN_LOAD_ERROR; - } - - DebugEntry->RVA = TempDebugEntryRva; - } - - switch (*(UINT32 *) ImageContext->CodeView) { - case CODEVIEW_SIGNATURE_NB10: - ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY); - break; - - case CODEVIEW_SIGNATURE_RSDS: - ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY); - break; - - default: - break; - } - } - } - } - - return Status; -} diff --git a/Tools/CodeTools/TianoTools/PeCoffLoader/Common/EfiImage.h b/Tools/CodeTools/TianoTools/PeCoffLoader/Common/EfiImage.h deleted file mode 100644 index 9528e6bff5..0000000000 --- a/Tools/CodeTools/TianoTools/PeCoffLoader/Common/EfiImage.h +++ /dev/null @@ -1,701 +0,0 @@ -/** @file - EFI image format for PE32+. Please note some data structures are different - for IA-32 and Itanium-based images, look for UINTN and the #ifdef EFI_IA64 - - @bug Fix text - doc as defined in MSFT EFI specification. - - Copyright (c) 2006, Intel Corporation - All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - Module Name: EfiImage.h - -**/ - -#ifndef __EFI_IMAGE_H__ -#define __EFI_IMAGE_H__ - -// -// PE32+ Subsystem type for EFI images -// -#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION 10 -#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 -#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 -#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13 - -// -// BugBug: Need to get a real answer for this problem. This is not in the -// PE specification. -// -// A SAL runtime driver does not get fixed up when a transition to -// virtual mode is made. In all other cases it should be treated -// like a EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER image -// -#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13 - -// -// PE32+ Machine type for EFI images -// -#define IMAGE_FILE_MACHINE_I386 0x014c -#define IMAGE_FILE_MACHINE_IA64 0x0200 -#define IMAGE_FILE_MACHINE_EBC 0x0EBC -#define IMAGE_FILE_MACHINE_X64 0x8664 -// -// Support old names for backward compatible -// -#define EFI_IMAGE_MACHINE_IA32 IMAGE_FILE_MACHINE_I386 -#define EFI_IMAGE_MACHINE_IA64 IMAGE_FILE_MACHINE_IA64 -#define EFI_IMAGE_MACHINE_IPF IMAGE_FILE_MACHINE_IA64 -#define EFI_IMAGE_MACHINE_EBC IMAGE_FILE_MACHINE_EBC -#define EFI_IMAGE_MACHINE_X64 IMAGE_FILE_MACHINE_X64 - -#define EFI_IMAGE_DOS_SIGNATURE 0x5A4D // MZ -#define EFI_IMAGE_OS2_SIGNATURE 0x454E // NE -#define EFI_IMAGE_OS2_SIGNATURE_LE 0x454C // LE -#define EFI_IMAGE_NT_SIGNATURE 0x00004550 // PE00 -#define EFI_IMAGE_EDOS_SIGNATURE 0x44454550 // PEED - -/// -/// PE images can start with an optional DOS header, so if an image is run -/// under DOS it can print an error message. -/// -typedef struct { - UINT16 e_magic; // Magic number - UINT16 e_cblp; // Bytes on last page of file - UINT16 e_cp; // Pages in file - UINT16 e_crlc; // Relocations - UINT16 e_cparhdr; // Size of header in paragraphs - UINT16 e_minalloc; // Minimum extra paragraphs needed - UINT16 e_maxalloc; // Maximum extra paragraphs needed - UINT16 e_ss; // Initial (relative) SS value - UINT16 e_sp; // Initial SP value - UINT16 e_csum; // Checksum - UINT16 e_ip; // Initial IP value - UINT16 e_cs; // Initial (relative) CS value - UINT16 e_lfarlc; // File address of relocation table - UINT16 e_ovno; // Overlay number - UINT16 e_res[4]; // Reserved words - UINT16 e_oemid; // OEM identifier (for e_oeminfo) - UINT16 e_oeminfo; // OEM information; e_oemid specific - UINT16 e_res2[10]; // Reserved words - UINT32 e_lfanew; // File address of new exe header -} EFI_IMAGE_DOS_HEADER; - -/// -/// File header format. -/// -typedef struct { - UINT16 Machine; - UINT16 NumberOfSections; - UINT32 TimeDateStamp; - UINT32 PointerToSymbolTable; - UINT32 NumberOfSymbols; - UINT16 SizeOfOptionalHeader; - UINT16 Characteristics; -} EFI_IMAGE_FILE_HEADER; - -#define EFI_IMAGE_SIZEOF_FILE_HEADER 20 - -#define EFI_IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file. -#define EFI_IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references). -#define EFI_IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file. -#define EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file. -#define EFI_IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed. -#define EFI_IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine. -#define EFI_IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file -#define EFI_IMAGE_FILE_SYSTEM 0x1000 // System File. -#define EFI_IMAGE_FILE_DLL 0x2000 // File is a DLL. -#define EFI_IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed. -#define EFI_IMAGE_FILE_MACHINE_UNKNOWN 0 -#define EFI_IMAGE_FILE_MACHINE_I386 0x14c // Intel 386. -#define EFI_IMAGE_FILE_MACHINE_R3000 0x162 // MIPS* little-endian, 0540 big-endian -#define EFI_IMAGE_FILE_MACHINE_R4000 0x166 // MIPS* little-endian -#define EFI_IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP* -#define EFI_IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM* PowerPC Little-Endian -#define EFI_IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine -// -// * Other names and brands may be claimed as the property of others. -// - -/// -/// Directory format. -/// -typedef struct { - UINT32 VirtualAddress; - UINT32 Size; -} EFI_IMAGE_DATA_DIRECTORY; - -#define EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16 - -typedef struct { - UINT16 Magic; - UINT8 MajorLinkerVersion; - UINT8 MinorLinkerVersion; - UINT32 SizeOfCode; - UINT32 SizeOfInitializedData; - UINT32 SizeOfUninitializedData; - UINT32 AddressOfEntryPoint; - UINT32 BaseOfCode; - UINT32 BaseOfData; - UINT32 BaseOfBss; - UINT32 GprMask; - UINT32 CprMask[4]; - UINT32 GpValue; -} EFI_IMAGE_ROM_OPTIONAL_HEADER; - -#define EFI_IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 -#define EFI_IMAGE_SIZEOF_ROM_OPTIONAL_HEADER sizeof (EFI_IMAGE_ROM_OPTIONAL_HEADER) - -typedef struct { - EFI_IMAGE_FILE_HEADER FileHeader; - EFI_IMAGE_ROM_OPTIONAL_HEADER OptionalHeader; -} EFI_IMAGE_ROM_HEADERS; - -/// -/// @attention -/// EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64 -/// are for use ONLY by tools. All proper EFI code MUST use -/// EFI_IMAGE_OPTIONAL_HEADER ONLY!!! -/// -#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b - -typedef struct { - // - // Standard fields. - // - UINT16 Magic; - UINT8 MajorLinkerVersion; - UINT8 MinorLinkerVersion; - UINT32 SizeOfCode; - UINT32 SizeOfInitializedData; - UINT32 SizeOfUninitializedData; - UINT32 AddressOfEntryPoint; - UINT32 BaseOfCode; - UINT32 BaseOfData; - // - // NT additional fields. - // - UINT32 ImageBase; - UINT32 SectionAlignment; - UINT32 FileAlignment; - UINT16 MajorOperatingSystemVersion; - UINT16 MinorOperatingSystemVersion; - UINT16 MajorImageVersion; - UINT16 MinorImageVersion; - UINT16 MajorSubsystemVersion; - UINT16 MinorSubsystemVersion; - UINT32 Win32VersionValue; - UINT32 SizeOfImage; - UINT32 SizeOfHeaders; - UINT32 CheckSum; - UINT16 Subsystem; - UINT16 DllCharacteristics; - UINT32 SizeOfStackReserve; - UINT32 SizeOfStackCommit; - UINT32 SizeOfHeapReserve; - UINT32 SizeOfHeapCommit; - UINT32 LoaderFlags; - UINT32 NumberOfRvaAndSizes; - EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES]; -} EFI_IMAGE_OPTIONAL_HEADER32; - -/// -/// @attention -/// EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64 -/// are for use ONLY by tools. All proper EFI code MUST use -/// EFI_IMAGE_OPTIONAL_HEADER ONLY!!! -/// -#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b - -typedef struct { - // - // Standard fields. - // - UINT16 Magic; - UINT8 MajorLinkerVersion; - UINT8 MinorLinkerVersion; - UINT32 SizeOfCode; - UINT32 SizeOfInitializedData; - UINT32 SizeOfUninitializedData; - UINT32 AddressOfEntryPoint; - UINT32 BaseOfCode; - // - // NT additional fields. - // - UINT64 ImageBase; - UINT32 SectionAlignment; - UINT32 FileAlignment; - UINT16 MajorOperatingSystemVersion; - UINT16 MinorOperatingSystemVersion; - UINT16 MajorImageVersion; - UINT16 MinorImageVersion; - UINT16 MajorSubsystemVersion; - UINT16 MinorSubsystemVersion; - UINT32 Win32VersionValue; - UINT32 SizeOfImage; - UINT32 SizeOfHeaders; - UINT32 CheckSum; - UINT16 Subsystem; - UINT16 DllCharacteristics; - UINT64 SizeOfStackReserve; - UINT64 SizeOfStackCommit; - UINT64 SizeOfHeapReserve; - UINT64 SizeOfHeapCommit; - UINT32 LoaderFlags; - UINT32 NumberOfRvaAndSizes; - EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES]; -} EFI_IMAGE_OPTIONAL_HEADER64; - -/// -/// @attention -/// EFI_IMAGE_NT_HEADERS32 and EFI_IMAGE_HEADERS64 are for use ONLY -/// by tools. All proper EFI code MUST use EFI_IMAGE_NT_HEADERS ONLY!!! -/// -typedef struct { - UINT32 Signature; - EFI_IMAGE_FILE_HEADER FileHeader; - EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader; -} EFI_IMAGE_NT_HEADERS32; - -#define EFI_IMAGE_SIZEOF_NT_OPTIONAL32_HEADER sizeof (EFI_IMAGE_NT_HEADERS32) - -typedef struct { - UINT32 Signature; - EFI_IMAGE_FILE_HEADER FileHeader; - EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader; -} EFI_IMAGE_NT_HEADERS64; - -#define EFI_IMAGE_SIZEOF_NT_OPTIONAL64_HEADER sizeof (EFI_IMAGE_NT_HEADERS64) - -// -// Processor specific definition of EFI_IMAGE_OPTIONAL_HEADER so the -// type name EFI_IMAGE_OPTIONAL_HEADER is appropriate to the build. Same for -// EFI_IMAGE_NT_HEADERS. These definitions MUST be used by ALL EFI code. -// -#if defined (MDE_CPU_IA32) && !defined (BUILDING_TOOLS) || \ - defined (BUILDING_TOOLS) && defined (TOOL_BUILD_IA32_TARGET) - -// typedef EFI_IMAGE_OPTIONAL_HEADER32 EFI_IMAGE_OPTIONAL_HEADER; -typedef EFI_IMAGE_NT_HEADERS32 EFI_IMAGE_NT_HEADERS; - -#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC -#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \ - (((Machine) == EFI_IMAGE_MACHINE_IA32) || ((Machine) == EFI_IMAGE_MACHINE_EBC)) - -#elif defined (MDE_CPU_IPF) && !defined (BUILDING_TOOLS) || \ - defined (BUILDING_TOOLS) && defined (TOOL_BUILD_IPF_TARGET) - -typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER; -typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS; - -#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC -#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \ - (((Machine) == EFI_IMAGE_MACHINE_IPF) || ((Machine) == EFI_IMAGE_MACHINE_EBC)) - -#elif defined (MDE_CPU_X64) && !defined (BUILDING_TOOLS) || \ - defined (BUILDING_TOOLS) && defined (TOOL_BUILD_X64_TARGET) - -typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER; -typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS; - -#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC -#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \ - (((Machine) == EFI_IMAGE_MACHINE_X64) || ((Machine) == EFI_IMAGE_MACHINE_EBC)) - -#elif defined (MDE_CPU_EBC) - -// -// This is just to make sure you can cross compile with the EBC compiiler. -// It does not make sense to have a PE loader coded in EBC. You need to -// understand the basic -// -typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER; -typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS; - -#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC -#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_EBC) - -#else -#error Unknown Processor Type -#endif - - -#define EFI_IMAGE_FIRST_SECTION(ntheader) \ - ( \ - (EFI_IMAGE_SECTION_HEADER *) \ - ( \ - (UINT32) ntheader + \ - FIELD_OFFSET (EFI_IMAGE_NT_HEADERS, OptionalHeader) + \ - ((EFI_IMAGE_NT_HEADERS *) (ntheader))->FileHeader.SizeOfOptionalHeader \ - ) \ - ) - -// -// Subsystem Values -// -#define EFI_IMAGE_SUBSYSTEM_UNKNOWN 0 -#define EFI_IMAGE_SUBSYSTEM_NATIVE 1 -#define EFI_IMAGE_SUBSYSTEM_WINDOWS_GUI 2 -#define EFI_IMAGE_SUBSYSTEM_WINDOWS_CUI 3. -#define EFI_IMAGE_SUBSYSTEM_OS2_CUI 5 -#define EFI_IMAGE_SUBSYSTEM_POSIX_CUI 7 - -// -// Directory Entries -// -#define EFI_IMAGE_DIRECTORY_ENTRY_EXPORT 0 -#define EFI_IMAGE_DIRECTORY_ENTRY_IMPORT 1 -#define EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE 2 -#define EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 -#define EFI_IMAGE_DIRECTORY_ENTRY_SECURITY 4 -#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC 5 -#define EFI_IMAGE_DIRECTORY_ENTRY_DEBUG 6 -#define EFI_IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 -#define EFI_IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 -#define EFI_IMAGE_DIRECTORY_ENTRY_TLS 9 -#define EFI_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 - -// -// Section header format. -// -#define EFI_IMAGE_SIZEOF_SHORT_NAME 8 - -typedef struct { - UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME]; - union { - UINT32 PhysicalAddress; - UINT32 VirtualSize; - } Misc; - UINT32 VirtualAddress; - UINT32 SizeOfRawData; - UINT32 PointerToRawData; - UINT32 PointerToRelocations; - UINT32 PointerToLinenumbers; - UINT16 NumberOfRelocations; - UINT16 NumberOfLinenumbers; - UINT32 Characteristics; -} EFI_IMAGE_SECTION_HEADER; - -#define EFI_IMAGE_SIZEOF_SECTION_HEADER 40 - -#define EFI_IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved. -#define EFI_IMAGE_SCN_CNT_CODE 0x00000020 -#define EFI_IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 -#define EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 - -#define EFI_IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved. -#define EFI_IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information. -#define EFI_IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image. -#define EFI_IMAGE_SCN_LNK_COMDAT 0x00001000 - -#define EFI_IMAGE_SCN_ALIGN_1BYTES 0x00100000 -#define EFI_IMAGE_SCN_ALIGN_2BYTES 0x00200000 -#define EFI_IMAGE_SCN_ALIGN_4BYTES 0x00300000 -#define EFI_IMAGE_SCN_ALIGN_8BYTES 0x00400000 -#define EFI_IMAGE_SCN_ALIGN_16BYTES 0x00500000 -#define EFI_IMAGE_SCN_ALIGN_32BYTES 0x00600000 -#define EFI_IMAGE_SCN_ALIGN_64BYTES 0x00700000 - -#define EFI_IMAGE_SCN_MEM_DISCARDABLE 0x02000000 -#define EFI_IMAGE_SCN_MEM_NOT_CACHED 0x04000000 -#define EFI_IMAGE_SCN_MEM_NOT_PAGED 0x08000000 -#define EFI_IMAGE_SCN_MEM_SHARED 0x10000000 -#define EFI_IMAGE_SCN_MEM_EXECUTE 0x20000000 -#define EFI_IMAGE_SCN_MEM_READ 0x40000000 -#define EFI_IMAGE_SCN_MEM_WRITE 0x80000000 - -/// -/// Symbol format. -/// -#define EFI_IMAGE_SIZEOF_SYMBOL 18 - -// -// Section values. -// -// Symbols have a section number of the section in which they are -// defined. Otherwise, section numbers have the following meanings: -// -#define EFI_IMAGE_SYM_UNDEFINED (UINT16) 0 // Symbol is undefined or is common. -#define EFI_IMAGE_SYM_ABSOLUTE (UINT16) -1 // Symbol is an absolute value. -#define EFI_IMAGE_SYM_DEBUG (UINT16) -2 // Symbol is a special debug item. -// -// Type (fundamental) values. -// -#define EFI_IMAGE_SYM_TYPE_NULL 0 // no type. -#define EFI_IMAGE_SYM_TYPE_VOID 1 // -#define EFI_IMAGE_SYM_TYPE_CHAR 2 // type character. -#define EFI_IMAGE_SYM_TYPE_SHORT 3 // type short integer. -#define EFI_IMAGE_SYM_TYPE_INT 4 -#define EFI_IMAGE_SYM_TYPE_LONG 5 -#define EFI_IMAGE_SYM_TYPE_FLOAT 6 -#define EFI_IMAGE_SYM_TYPE_DOUBLE 7 -#define EFI_IMAGE_SYM_TYPE_STRUCT 8 -#define EFI_IMAGE_SYM_TYPE_UNION 9 -#define EFI_IMAGE_SYM_TYPE_ENUM 10 // enumeration. -#define EFI_IMAGE_SYM_TYPE_MOE 11 // member of enumeration. -#define EFI_IMAGE_SYM_TYPE_BYTE 12 -#define EFI_IMAGE_SYM_TYPE_WORD 13 -#define EFI_IMAGE_SYM_TYPE_UINT 14 -#define EFI_IMAGE_SYM_TYPE_DWORD 15 - -// -// Type (derived) values. -// -#define EFI_IMAGE_SYM_DTYPE_NULL 0 // no derived type. -#define EFI_IMAGE_SYM_DTYPE_POINTER 1 -#define EFI_IMAGE_SYM_DTYPE_FUNCTION 2 -#define EFI_IMAGE_SYM_DTYPE_ARRAY 3 - -// -// Storage classes. -// -#define EFI_IMAGE_SYM_CLASS_END_OF_FUNCTION (UINT8) -1 -#define EFI_IMAGE_SYM_CLASS_NULL 0 -#define EFI_IMAGE_SYM_CLASS_AUTOMATIC 1 -#define EFI_IMAGE_SYM_CLASS_EXTERNAL 2 -#define EFI_IMAGE_SYM_CLASS_STATIC 3 -#define EFI_IMAGE_SYM_CLASS_REGISTER 4 -#define EFI_IMAGE_SYM_CLASS_EXTERNAL_DEF 5 -#define EFI_IMAGE_SYM_CLASS_LABEL 6 -#define EFI_IMAGE_SYM_CLASS_UNDEFINED_LABEL 7 -#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8 -#define EFI_IMAGE_SYM_CLASS_ARGUMENT 9 -#define EFI_IMAGE_SYM_CLASS_STRUCT_TAG 10 -#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_UNION 11 -#define EFI_IMAGE_SYM_CLASS_UNION_TAG 12 -#define EFI_IMAGE_SYM_CLASS_TYPE_DEFINITION 13 -#define EFI_IMAGE_SYM_CLASS_UNDEFINED_STATIC 14 -#define EFI_IMAGE_SYM_CLASS_ENUM_TAG 15 -#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16 -#define EFI_IMAGE_SYM_CLASS_REGISTER_PARAM 17 -#define EFI_IMAGE_SYM_CLASS_BIT_FIELD 18 -#define EFI_IMAGE_SYM_CLASS_BLOCK 100 -#define EFI_IMAGE_SYM_CLASS_FUNCTION 101 -#define EFI_IMAGE_SYM_CLASS_END_OF_STRUCT 102 -#define EFI_IMAGE_SYM_CLASS_FILE 103 -#define EFI_IMAGE_SYM_CLASS_SECTION 104 -#define EFI_IMAGE_SYM_CLASS_WEAK_EXTERNAL 105 - -// -// type packing constants -// -#define EFI_IMAGE_N_BTMASK 017 -#define EFI_IMAGE_N_TMASK 060 -#define EFI_IMAGE_N_TMASK1 0300 -#define EFI_IMAGE_N_TMASK2 0360 -#define EFI_IMAGE_N_BTSHFT 4 -#define EFI_IMAGE_N_TSHIFT 2 - -// -// Communal selection types. -// -#define EFI_IMAGE_COMDAT_SELECT_NODUPLICATES 1 -#define EFI_IMAGE_COMDAT_SELECT_ANY 2 -#define EFI_IMAGE_COMDAT_SELECT_SAME_SIZE 3 -#define EFI_IMAGE_COMDAT_SELECT_EXACT_MATCH 4 -#define EFI_IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 - -#define EFI_IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 -#define EFI_IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 -#define EFI_IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 - -/// -/// Relocation format. -/// -typedef struct { - UINT32 VirtualAddress; - UINT32 SymbolTableIndex; - UINT16 Type; -} EFI_IMAGE_RELOCATION; - -#define EFI_IMAGE_SIZEOF_RELOCATION 10 - -// -// I386 relocation types. -// -#define EFI_IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary -#define EFI_IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address -#define EFI_IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address -#define EFI_IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address -#define EFI_IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included -#define EFI_IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address -#define EFI_IMAGE_REL_I386_SECTION 012 -#define EFI_IMAGE_REL_I386_SECREL 013 -#define EFI_IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address - -/// -/// Based relocation format. -/// -typedef struct { - UINT32 VirtualAddress; - UINT32 SizeOfBlock; -} EFI_IMAGE_BASE_RELOCATION; - -#define EFI_IMAGE_SIZEOF_BASE_RELOCATION 8 - -// -// Based relocation types. -// -#define EFI_IMAGE_REL_BASED_ABSOLUTE 0 -#define EFI_IMAGE_REL_BASED_HIGH 1 -#define EFI_IMAGE_REL_BASED_LOW 2 -#define EFI_IMAGE_REL_BASED_HIGHLOW 3 -#define EFI_IMAGE_REL_BASED_HIGHADJ 4 -#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5 -#define EFI_IMAGE_REL_BASED_IA64_IMM64 9 -#define EFI_IMAGE_REL_BASED_DIR64 10 - -/// -/// Line number format. -/// -typedef struct { - union { - UINT32 SymbolTableIndex; // Symbol table index of function name if Linenumber is 0. - UINT32 VirtualAddress; // Virtual address of line number. - } Type; - UINT16 Linenumber; // Line number. -} EFI_IMAGE_LINENUMBER; - -#define EFI_IMAGE_SIZEOF_LINENUMBER 6 - -// -// Archive format. -// -#define EFI_IMAGE_ARCHIVE_START_SIZE 8 -#define EFI_IMAGE_ARCHIVE_START "!\n" -#define EFI_IMAGE_ARCHIVE_END "`\n" -#define EFI_IMAGE_ARCHIVE_PAD "\n" -#define EFI_IMAGE_ARCHIVE_LINKER_MEMBER "/ " -#define EFI_IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " - -typedef struct { - UINT8 Name[16]; // File member name - `/' terminated. - UINT8 Date[12]; // File member date - decimal. - UINT8 UserID[6]; // File member user id - decimal. - UINT8 GroupID[6]; // File member group id - decimal. - UINT8 Mode[8]; // File member mode - octal. - UINT8 Size[10]; // File member size - decimal. - UINT8 EndHeader[2]; // String to end header. -} EFI_IMAGE_ARCHIVE_MEMBER_HEADER; - -#define EFI_IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 - -// -// DLL support. -// - -/// -/// DLL Export Format -/// -typedef struct { - UINT32 Characteristics; - UINT32 TimeDateStamp; - UINT16 MajorVersion; - UINT16 MinorVersion; - UINT32 Name; - UINT32 Base; - UINT32 NumberOfFunctions; - UINT32 NumberOfNames; - UINT32 AddressOfFunctions; - UINT32 AddressOfNames; - UINT32 AddressOfNameOrdinals; -} EFI_IMAGE_EXPORT_DIRECTORY; - -/// -/// DLL support. -/// Import Format -/// -typedef struct { - UINT16 Hint; - UINT8 Name[1]; -} EFI_IMAGE_IMPORT_BY_NAME; - -typedef struct { - union { - UINT32 Function; - UINT32 Ordinal; - EFI_IMAGE_IMPORT_BY_NAME *AddressOfData; - } u1; -} EFI_IMAGE_THUNK_DATA; - -#define EFI_IMAGE_ORDINAL_FLAG 0x80000000 -#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0) -#define EFI_IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) - -typedef struct { - UINT32 Characteristics; - UINT32 TimeDateStamp; - UINT32 ForwarderChain; - UINT32 Name; - EFI_IMAGE_THUNK_DATA *FirstThunk; -} EFI_IMAGE_IMPORT_DESCRIPTOR; - -/// -/// Debug Format -/// -#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2 - -typedef struct { - UINT32 Characteristics; - UINT32 TimeDateStamp; - UINT16 MajorVersion; - UINT16 MinorVersion; - UINT32 Type; - UINT32 SizeOfData; - UINT32 RVA; - UINT32 FileOffset; -} EFI_IMAGE_DEBUG_DIRECTORY_ENTRY; - -#define CODEVIEW_SIGNATURE_NB10 0x3031424E // "NB10" -typedef struct { - UINT32 Signature; // "NB10" - UINT32 Unknown; - UINT32 Unknown2; - UINT32 Unknown3; - // - // Filename of .PDB goes here - // -} EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY; - -#define CODEVIEW_SIGNATURE_RSDS 0x53445352 // "RSDS" -typedef struct { - UINT32 Signature; // "RSDS" - UINT32 Unknown; - UINT32 Unknown2; - UINT32 Unknown3; - UINT32 Unknown4; - UINT32 Unknown5; - // - // Filename of .PDB goes here - // -} EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY; - -/// -/// Header format for TE images -/// -typedef struct { - UINT16 Signature; // signature for TE format = "VZ" - UINT16 Machine; // from the original file header - UINT8 NumberOfSections; // from the original file header - UINT8 Subsystem; // from original optional header - UINT16 StrippedSize; // how many bytes we removed from the header - UINT32 AddressOfEntryPoint; // offset to entry point -- from original optional header - UINT32 BaseOfCode; // from original image -- required for ITP debug - UINT64 ImageBase; // from original file header - EFI_IMAGE_DATA_DIRECTORY DataDirectory[2]; // only base relocation and debug directory -} EFI_TE_IMAGE_HEADER; - -#define EFI_TE_IMAGE_HEADER_SIGNATURE 0x5A56 // "VZ" - -// -// Data directory indexes in our TE image header -// -#define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC 0 -#define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG 1 - -#endif diff --git a/Tools/CodeTools/TianoTools/PeCoffLoader/Ia32/PeCoffLoaderEx.c b/Tools/CodeTools/TianoTools/PeCoffLoader/Ia32/PeCoffLoaderEx.c deleted file mode 100644 index f58e8d0364..0000000000 --- a/Tools/CodeTools/TianoTools/PeCoffLoader/Ia32/PeCoffLoaderEx.c +++ /dev/null @@ -1,56 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PeCoffLoaderEx.c - -Abstract: - - IA-32 Specific relocation fixups - -Revision History - ---*/ - -#include - -RETURN_STATUS -PeCoffLoaderRelocateImageEx ( - IN UINT16 *Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust - ) -/*++ - -Routine Description: - - Performs an IA-32 specific relocation fixup - -Arguments: - - Reloc - Pointer to the relocation record - - Fixup - Pointer to the address to fix up - - FixupData - Pointer to a buffer to log the fixups - - Adjust - The offset to adjust the fixup - -Returns: - - EFI_UNSUPPORTED - Unsupported now - ---*/ -{ - return RETURN_UNSUPPORTED; -} diff --git a/Tools/CodeTools/TianoTools/PeCoffLoader/Ipf/PeCoffLoaderEx.c b/Tools/CodeTools/TianoTools/PeCoffLoader/Ipf/PeCoffLoaderEx.c deleted file mode 100644 index 3f3989908d..0000000000 --- a/Tools/CodeTools/TianoTools/PeCoffLoader/Ipf/PeCoffLoaderEx.c +++ /dev/null @@ -1,249 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - PeCoffLoaderEx.c - -Abstract: - - Fixes Intel Itanium(TM) specific relocation types - - -Revision History - ---*/ - -#include -#include -#include - - - - - -#define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \ - Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos) - -#define INS_IMM64(Value, Address, Size, InstPos, ValPos) \ - *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \ - ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos) - -#define IMM64_IMM7B_INST_WORD_X 3 -#define IMM64_IMM7B_SIZE_X 7 -#define IMM64_IMM7B_INST_WORD_POS_X 4 -#define IMM64_IMM7B_VAL_POS_X 0 - -#define IMM64_IMM9D_INST_WORD_X 3 -#define IMM64_IMM9D_SIZE_X 9 -#define IMM64_IMM9D_INST_WORD_POS_X 18 -#define IMM64_IMM9D_VAL_POS_X 7 - -#define IMM64_IMM5C_INST_WORD_X 3 -#define IMM64_IMM5C_SIZE_X 5 -#define IMM64_IMM5C_INST_WORD_POS_X 13 -#define IMM64_IMM5C_VAL_POS_X 16 - -#define IMM64_IC_INST_WORD_X 3 -#define IMM64_IC_SIZE_X 1 -#define IMM64_IC_INST_WORD_POS_X 12 -#define IMM64_IC_VAL_POS_X 21 - -#define IMM64_IMM41a_INST_WORD_X 1 -#define IMM64_IMM41a_SIZE_X 10 -#define IMM64_IMM41a_INST_WORD_POS_X 14 -#define IMM64_IMM41a_VAL_POS_X 22 - -#define IMM64_IMM41b_INST_WORD_X 1 -#define IMM64_IMM41b_SIZE_X 8 -#define IMM64_IMM41b_INST_WORD_POS_X 24 -#define IMM64_IMM41b_VAL_POS_X 32 - -#define IMM64_IMM41c_INST_WORD_X 2 -#define IMM64_IMM41c_SIZE_X 23 -#define IMM64_IMM41c_INST_WORD_POS_X 0 -#define IMM64_IMM41c_VAL_POS_X 40 - -#define IMM64_SIGN_INST_WORD_X 3 -#define IMM64_SIGN_SIZE_X 1 -#define IMM64_SIGN_INST_WORD_POS_X 27 -#define IMM64_SIGN_VAL_POS_X 63 - -RETURN_STATUS -PeCoffLoaderRelocateImageEx ( - IN UINT16 *Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust - ) -/*++ - -Routine Description: - - Performs an Itanium-based specific relocation fixup - -Arguments: - - Reloc - Pointer to the relocation record - - Fixup - Pointer to the address to fix up - - FixupData - Pointer to a buffer to log the fixups - - Adjust - The offset to adjust the fixup - -Returns: - - Status code - ---*/ -{ - UINT64 *F64; - UINT64 FixupVal; - - switch ((*Reloc) >> 12) { - - case EFI_IMAGE_REL_BASED_DIR64: - F64 = (UINT64 *) Fixup; - *F64 = *F64 + (UINT64) Adjust; - if (*FixupData != NULL) { - *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64)); - *(UINT64 *)(*FixupData) = *F64; - *FixupData = *FixupData + sizeof(UINT64); - } - break; - - case EFI_IMAGE_REL_BASED_IA64_IMM64: - - // - // Align it to bundle address before fixing up the - // 64-bit immediate value of the movl instruction. - // - - Fixup = (CHAR8 *)((UINTN) Fixup & (UINTN) ~(15)); - FixupVal = (UINT64)0; - - // - // Extract the lower 32 bits of IMM64 from bundle - // - EXT_IMM64(FixupVal, - (UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X, - IMM64_IMM7B_SIZE_X, - IMM64_IMM7B_INST_WORD_POS_X, - IMM64_IMM7B_VAL_POS_X - ); - - EXT_IMM64(FixupVal, - (UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X, - IMM64_IMM9D_SIZE_X, - IMM64_IMM9D_INST_WORD_POS_X, - IMM64_IMM9D_VAL_POS_X - ); - - EXT_IMM64(FixupVal, - (UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X, - IMM64_IMM5C_SIZE_X, - IMM64_IMM5C_INST_WORD_POS_X, - IMM64_IMM5C_VAL_POS_X - ); - - EXT_IMM64(FixupVal, - (UINT32 *)Fixup + IMM64_IC_INST_WORD_X, - IMM64_IC_SIZE_X, - IMM64_IC_INST_WORD_POS_X, - IMM64_IC_VAL_POS_X - ); - - EXT_IMM64(FixupVal, - (UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X, - IMM64_IMM41a_SIZE_X, - IMM64_IMM41a_INST_WORD_POS_X, - IMM64_IMM41a_VAL_POS_X - ); - - // - // Update 64-bit address - // - FixupVal += Adjust; - - // - // Insert IMM64 into bundle - // - INS_IMM64(FixupVal, - ((UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X), - IMM64_IMM7B_SIZE_X, - IMM64_IMM7B_INST_WORD_POS_X, - IMM64_IMM7B_VAL_POS_X - ); - - INS_IMM64(FixupVal, - ((UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X), - IMM64_IMM9D_SIZE_X, - IMM64_IMM9D_INST_WORD_POS_X, - IMM64_IMM9D_VAL_POS_X - ); - - INS_IMM64(FixupVal, - ((UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X), - IMM64_IMM5C_SIZE_X, - IMM64_IMM5C_INST_WORD_POS_X, - IMM64_IMM5C_VAL_POS_X - ); - - INS_IMM64(FixupVal, - ((UINT32 *)Fixup + IMM64_IC_INST_WORD_X), - IMM64_IC_SIZE_X, - IMM64_IC_INST_WORD_POS_X, - IMM64_IC_VAL_POS_X - ); - - INS_IMM64(FixupVal, - ((UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X), - IMM64_IMM41a_SIZE_X, - IMM64_IMM41a_INST_WORD_POS_X, - IMM64_IMM41a_VAL_POS_X - ); - - INS_IMM64(FixupVal, - ((UINT32 *)Fixup + IMM64_IMM41b_INST_WORD_X), - IMM64_IMM41b_SIZE_X, - IMM64_IMM41b_INST_WORD_POS_X, - IMM64_IMM41b_VAL_POS_X - ); - - INS_IMM64(FixupVal, - ((UINT32 *)Fixup + IMM64_IMM41c_INST_WORD_X), - IMM64_IMM41c_SIZE_X, - IMM64_IMM41c_INST_WORD_POS_X, - IMM64_IMM41c_VAL_POS_X - ); - - INS_IMM64(FixupVal, - ((UINT32 *)Fixup + IMM64_SIGN_INST_WORD_X), - IMM64_SIGN_SIZE_X, - IMM64_SIGN_INST_WORD_POS_X, - IMM64_SIGN_VAL_POS_X - ); - - F64 = (UINT64 *) Fixup; - if (*FixupData != NULL) { - *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64)); - *(UINT64 *)(*FixupData) = *F64; - *FixupData = *FixupData + sizeof(UINT64); - } - break; - - default: - return RETURN_UNSUPPORTED; - } - - return RETURN_SUCCESS; -} diff --git a/Tools/CodeTools/TianoTools/PeCoffLoader/X64/PeCoffLoaderEx.c b/Tools/CodeTools/TianoTools/PeCoffLoader/X64/PeCoffLoaderEx.c deleted file mode 100644 index 1e6cc34745..0000000000 --- a/Tools/CodeTools/TianoTools/PeCoffLoader/X64/PeCoffLoaderEx.c +++ /dev/null @@ -1,74 +0,0 @@ -/*++ - -Copyright 2005, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -Module Name: - - PeCoffLoaderEx.c - -Abstract: - - x64 Specific relocation fixups - -Revision History - ---*/ - -#include -#include -#include - - - - -RETURN_STATUS -PeCoffLoaderRelocateImageEx ( - IN UINT16 *Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust - ) -/*++ - -Routine Description: - Performs an x64 specific relocation fixup - -Arguments: - Reloc - Pointer to the relocation record - Fixup - Pointer to the address to fix up - FixupData - Pointer to a buffer to log the fixups - Adjust - The offset to adjust the fixup - -Returns: - None - ---*/ -{ - UINT64 *F64; - - switch ((*Reloc) >> 12) { - - case EFI_IMAGE_REL_BASED_DIR64: - F64 = (UINT64 *) Fixup; - *F64 = *F64 + (UINT64) Adjust; - if (*FixupData != NULL) { - *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64)); - *(UINT64 *)(*FixupData) = *F64; - *FixupData = *FixupData + sizeof(UINT64); - } - break; - - default: - return RETURN_UNSUPPORTED; - } - - return RETURN_SUCCESS; -} diff --git a/Tools/CodeTools/TianoTools/PeCoffLoader/build.xml b/Tools/CodeTools/TianoTools/PeCoffLoader/build.xml deleted file mode 100644 index db37829840..0000000000 --- a/Tools/CodeTools/TianoTools/PeCoffLoader/build.xml +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/PeiRebase/PeiRebaseExe.c b/Tools/CodeTools/TianoTools/PeiRebase/PeiRebaseExe.c deleted file mode 100644 index 27c646e486..0000000000 --- a/Tools/CodeTools/TianoTools/PeiRebase/PeiRebaseExe.c +++ /dev/null @@ -1,1059 +0,0 @@ -/*++ - -Copyright (c) 1999-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -Module Name: - - PeiRebaseExe.c - -Abstract: - - This contains all code necessary to build the PeiRebase.exe utility. - This utility relies heavily on the PeiRebase DLL. Definitions for both - can be found in the PEI Rebase Utility Specification, review draft. - ---*/ - -#include -#include -#include - -#include -#include -#include -#include - -#include "CommonLib.h" -#include "ParseInf.h" -#include "FvLib.h" -#include "EfiUtilityMsgs.h" -#include "PeiRebaseExe.h" - -EFI_STATUS -ReadHeader ( - IN FILE *InputFile, - OUT UINT32 *FvSize, - OUT BOOLEAN *ErasePolarity - ); - -int -main ( - int argc, - char **argv - ) -/*++ - -Routine Description: - - This utility relocates PEI XIP PE32s in a FV. - -Arguments: - - argc - Number of command line arguments - argv[]: - BaseAddress The base address to use for rebasing the FV. The correct - format is a hex number preceded by 0x. - InputFileName The name of the input FV file. - OutputFileName The name of the output FV file. - MapFileName The name of the map file of relocation info. - - Arguments come in pair in any order. - -I InputFileName - -O OutputFileName - -B BaseAddress - -M MapFileName - -Returns: - - 0 No error conditions detected. - 1 One or more of the input parameters is invalid. - 2 A resource required by the utility was unavailable. - Most commonly this will be memory allocation or file creation. - 3 PeiRebase.dll could not be loaded. - 4 Error executing the PEI rebase. - ---*/ -{ - UINT8 Index; - CHAR8 InputFileName[_MAX_PATH]; - CHAR8 OutputFileName[_MAX_PATH]; - CHAR8 MapFileName[_MAX_PATH]; - EFI_PHYSICAL_ADDRESS BaseAddress; - BOOLEAN BaseAddressSet; - EFI_STATUS Status; - FILE *InputFile; - FILE *OutputFile; - FILE *MapFile; - UINT64 FvOffset; - UINT32 FileCount; - int BytesRead; - EFI_FIRMWARE_VOLUME_HEADER *FvImage; - UINT32 FvSize; - EFI_FFS_FILE_HEADER *CurrentFile; - BOOLEAN ErasePolarity; - EFI_PHYSICAL_ADDRESS CurrentFileBaseAddress; - - ErasePolarity = FALSE; - // - // Set utility name for error/warning reporting purposes. - // - SetUtilityName (UTILITY_NAME); - // - // Verify the correct number of arguments - // - if (argc != MAX_ARGS) { - PrintUsage (); - return STATUS_ERROR; - } - - // - // Initialize variables - // - InputFileName[0] = 0; - OutputFileName[0] = 0; - MapFileName[0] = 0; - BaseAddress = 0; - BaseAddressSet = FALSE; - FvOffset = 0; - FileCount = 0; - ErasePolarity = FALSE; - InputFile = NULL; - OutputFile = NULL; - MapFile = NULL; - FvImage = NULL; - - // - // Parse the command line arguments - // - for (Index = 1; Index < MAX_ARGS; Index += 2) { - // - // Make sure argument pair begin with - or / - // - if (argv[Index][0] != '-' && argv[Index][0] != '/') { - PrintUsage (); - Error (NULL, 0, 0, argv[Index], "unrecognized option"); - return STATUS_ERROR; - } - // - // Make sure argument specifier is only one letter - // - if (argv[Index][2] != 0) { - PrintUsage (); - Error (NULL, 0, 0, argv[Index], "unrecognized option"); - return STATUS_ERROR; - } - // - // Determine argument to read - // - switch (argv[Index][1]) { - case 'I': - case 'i': - if (strlen (InputFileName) == 0) { - strcpy (InputFileName, argv[Index + 1]); - } else { - PrintUsage (); - Error (NULL, 0, 0, argv[Index + 1], "only one -i InputFileName may be specified"); - return STATUS_ERROR; - } - break; - - case 'O': - case 'o': - if (strlen (OutputFileName) == 0) { - strcpy (OutputFileName, argv[Index + 1]); - } else { - PrintUsage (); - Error (NULL, 0, 0, argv[Index + 1], "only one -o OutputFileName may be specified"); - return STATUS_ERROR; - } - break; - - case 'B': - case 'b': - if (!BaseAddressSet) { - Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &BaseAddress); - if (EFI_ERROR (Status)) { - PrintUsage (); - Error (NULL, 0, 0, argv[Index + 1], "invalid hex digit given for the base address"); - return STATUS_ERROR; - } - - BaseAddressSet = TRUE; - } else { - PrintUsage (); - Error (NULL, 0, 0, argv[Index + 1], "-b BaseAddress may only be specified once"); - return STATUS_ERROR; - } - break; - - case 'M': - case 'm': - if (strlen (MapFileName) == 0) { - strcpy (MapFileName, argv[Index + 1]); - } else { - PrintUsage (); - Error (NULL, 0, 0, argv[Index + 1], "only one -m MapFileName may be specified"); - return STATUS_ERROR; - } - break; - - default: - PrintUsage (); - Error (NULL, 0, 0, argv[Index], "unrecognized argument"); - return STATUS_ERROR; - break; - } - } - - // - // Create the Map file if we need it - // - if (strlen (MapFileName) != 0) { - MapFile = fopen (MapFileName, "w"); - if (MapFile == NULL) { - Error (NULL, 0, 0, MapFileName, "failed to open map file"); - goto Finish; - } - } - - // - // Open the file containing the FV - // - InputFile = fopen (InputFileName, "rb"); - if (InputFile == NULL) { - Error (NULL, 0, 0, InputFileName, "could not open input file for reading"); - return STATUS_ERROR; - } - // - // Determine size of FV - // - Status = ReadHeader (InputFile, &FvSize, &ErasePolarity); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "could not parse the FV header", NULL); - goto Finish; - } - // - // Allocate a buffer for the FV image - // - FvImage = malloc (FvSize); - if (FvImage == NULL) { - Error (NULL, 0, 0, "application error", "memory allocation failed"); - goto Finish; - } - // - // Read the entire FV to the buffer - // - BytesRead = fread (FvImage, 1, FvSize, InputFile); - fclose (InputFile); - InputFile = NULL; - if ((unsigned int) BytesRead != FvSize) { - Error (NULL, 0, 0, InputFileName, "failed to read from file"); - goto Finish; - } - // - // Prepare to walk the FV image - // - InitializeFvLib (FvImage, FvSize); - // - // Get the first file - // - Status = GetNextFile (NULL, &CurrentFile); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "cannot find the first file in the FV image", NULL); - goto Finish; - } - // - // Check if each file should be rebased - // - while (CurrentFile != NULL) { - // - // Rebase this file - // - CurrentFileBaseAddress = BaseAddress + ((UINTN) CurrentFile - (UINTN) FvImage); - Status = FfsRebase (CurrentFile, CurrentFileBaseAddress, MapFile); - - if (EFI_ERROR (Status)) { - switch (Status) { - - case EFI_INVALID_PARAMETER: - Error (NULL, 0, 0, "invalid parameter passed to FfsRebase", NULL); - break; - - case EFI_ABORTED: - Error (NULL, 0, 0, "error detected while rebasing -- aborted", NULL); - break; - - case EFI_OUT_OF_RESOURCES: - Error (NULL, 0, 0, "FfsRebase could not allocate required resources", NULL); - break; - - case EFI_NOT_FOUND: - Error (NULL, 0, 0, "FfsRebase could not locate a PE32 section", NULL); - break; - - default: - Error (NULL, 0, 0, "FfsRebase returned unknown status", "status=0x%08X", Status); - break; - } - - goto Finish; - } - - // - // Get the next file - // - Status = GetNextFile (CurrentFile, &CurrentFile); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "cannot find the next file in the FV image", NULL); - goto Finish; - } - } - // - // Open the output file - // - OutputFile = fopen (OutputFileName, "wb"); - if (OutputFile == NULL) { - Error (NULL, 0, 0, OutputFileName, "failed to open output file"); - goto Finish; - } - - if (fwrite (FvImage, 1, FvSize, OutputFile) != FvSize) { - Error (NULL, 0, 0, "failed to write to output file", 0); - goto Finish; - } - -Finish: - if (InputFile != NULL) { - fclose (InputFile); - } - // - // If we created an output file, and there was an error, remove it so - // subsequent builds will rebuild it. - // - if (OutputFile != NULL) { - if (GetUtilityStatus () == STATUS_ERROR) { - remove (OutputFileName); - } - - fclose (OutputFile); - } - - if (MapFile != NULL) { - fclose (MapFile); - } - - if (FvImage != NULL) { - free (FvImage); - } - - return GetUtilityStatus (); -} - -EFI_STATUS -ReadHeader ( - IN FILE *InputFile, - OUT UINT32 *FvSize, - OUT BOOLEAN *ErasePolarity - ) -/*++ - -Routine Description: - - This function determines the size of the FV and the erase polarity. The - erase polarity is the FALSE value for file state. - -Arguments: - - InputFile The file that contains the FV image. - FvSize The size of the FV. - ErasePolarity The FV erase polarity. - -Returns: - - EFI_SUCCESS Function completed successfully. - EFI_INVALID_PARAMETER A required parameter was NULL or is out of range. - EFI_ABORTED The function encountered an error. - ---*/ -{ - EFI_FIRMWARE_VOLUME_HEADER VolumeHeader; - EFI_FV_BLOCK_MAP_ENTRY BlockMap; - UINTN Signature[2]; - UINTN BytesRead; - UINT32 Size; - - BytesRead = 0; - Size = 0; - // - // Check input parameters - // - if ((InputFile == NULL) || (FvSize == NULL) || (ErasePolarity == NULL)) { - Error (NULL, 0, 0, "ReadHeader()", "invalid input parameter"); - return EFI_INVALID_PARAMETER; - } - // - // Read the header - // - fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile); - BytesRead = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY); - Signature[0] = VolumeHeader.Signature; - Signature[1] = 0; - - // - // Get erase polarity - // - if (VolumeHeader.Attributes & EFI_FVB_ERASE_POLARITY) { - *ErasePolarity = TRUE; - } - - do { - fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile); - BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY); - - if (BlockMap.NumBlocks != 0) { - Size += BlockMap.NumBlocks * BlockMap.BlockLength; - } - - } while (!(BlockMap.NumBlocks == 0 && BlockMap.BlockLength == 0)); - - if (VolumeHeader.FvLength != Size) { - Error (NULL, 0, 0, "volume size not consistant with block maps", NULL); - return EFI_ABORTED; - } - - *FvSize = Size; - - rewind (InputFile); - - return EFI_SUCCESS; -} - -VOID -PrintUtilityInfo ( - VOID - ) -/*++ - -Routine Description: - - Displays the standard utility information to SDTOUT - -Arguments: - - None - -Returns: - - None - ---*/ -{ - printf ( - "%s, PEI Rebase Utility. Version %i.%i, %s.\n\n", - UTILITY_NAME, - UTILITY_MAJOR_VERSION, - UTILITY_MINOR_VERSION, - UTILITY_DATE - ); -} - -VOID -PrintUsage ( - VOID - ) -/*++ - -Routine Description: - - Displays the utility usage syntax to STDOUT - -Arguments: - - None - -Returns: - - None - ---*/ -{ - printf ( - "Usage: %s -I InputFileName -O OutputFileName -B BaseAddress [-M MapFile]\n", - UTILITY_NAME - ); - printf (" Where:\n"); - printf (" InputFileName is the name of the EFI FV file to rebase.\n"); - printf (" OutputFileName is the desired output file name.\n"); - printf (" BaseAddress is the FV base address to rebase agains.\n"); - printf (" MapFileName is an optional map file of the relocations\n"); - printf (" Argument pair may be in any order.\n\n"); -} - -EFI_STATUS -FfsRebase ( - IN OUT EFI_FFS_FILE_HEADER *FfsFile, - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN FILE *MapFile OPTIONAL - ) -/*++ - -Routine Description: - - This function determines if a file is XIP and should be rebased. It will - rebase any PE32 sections found in the file using the base address. - -Arguments: - - FfsFile A pointer to Ffs file image. - BaseAddress The base address to use for rebasing the file image. - MapFile Optional file to dump relocation information into - -Returns: - - EFI_SUCCESS The image was properly rebased. - EFI_INVALID_PARAMETER An input parameter is invalid. - EFI_ABORTED An error occurred while rebasing the input file image. - EFI_OUT_OF_RESOURCES Could not allocate a required resource. - EFI_NOT_FOUND No compressed sections could be found. - ---*/ -{ - EFI_STATUS Status; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - UINTN MemoryImagePointer; - UINTN MemoryImagePointerAligned; - EFI_PHYSICAL_ADDRESS ImageAddress; - UINT64 ImageSize; - EFI_PHYSICAL_ADDRESS EntryPoint; - UINT32 Pe32ImageSize; - UINT32 NewPe32BaseAddress; - UINTN Index; - EFI_FILE_SECTION_POINTER CurrentPe32Section; - EFI_FFS_FILE_STATE SavedState; - EFI_IMAGE_NT_HEADERS *PeHdr; - UINT32 *PeHdrSizeOfImage; - UINT32 *PeHdrChecksum; - UINT32 FoundCount; - EFI_TE_IMAGE_HEADER *TEImageHeader; - UINT8 *TEBuffer; - EFI_IMAGE_DOS_HEADER *DosHeader; - UINT8 FileGuidString[80]; - UINT32 TailSize; - EFI_FFS_FILE_TAIL TailValue; - - // - // Verify input parameters - // - if (FfsFile == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Convert the GUID to a string so we can at least report which file - // if we find an error. - // - PrintGuidToBuffer (&FfsFile->Name, FileGuidString, sizeof (FileGuidString), TRUE); - if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) { - TailSize = sizeof (EFI_FFS_FILE_TAIL); - } else { - TailSize = 0; - } - - // - // Do some cursory checks on the FFS file contents - // - Status = VerifyFfsFile (FfsFile); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "file does not appear to be a valid FFS file, cannot be rebased", FileGuidString); - return EFI_INVALID_PARAMETER; - } - - memset (&ImageContext, 0, sizeof (ImageContext)); - - // - // Check if XIP file type. If not XIP, don't rebase. - // - if (FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE && - FfsFile->Type != EFI_FV_FILETYPE_PEIM && - FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE && - FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER - ) { - return EFI_SUCCESS; - } - - // - // Rebase each PE32 section - // - Status = EFI_SUCCESS; - FoundCount = 0; - for (Index = 1;; Index++) { - Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section); - if (EFI_ERROR (Status)) { - break; - } - - FoundCount++; - - // - // Calculate the PE32 base address, the FFS file base plus the offset of the PE32 section - // - NewPe32BaseAddress = ((UINT32) BaseAddress) + ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER) - (UINTN) FfsFile); - - // - // Initialize context - // - memset (&ImageContext, 0, sizeof (ImageContext)); - ImageContext.Handle = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION)); - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead; - - Status = PeCoffLoaderGetImageInfo (&ImageContext); - - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "GetImageInfo() call failed on rebase", FileGuidString); - return Status; - } - // - // Allocate a buffer for the image to be loaded into. - // - Pe32ImageSize = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION); - MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x1000)); - if (MemoryImagePointer == 0) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - return EFI_OUT_OF_RESOURCES; - } - memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000); - MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12); - - - ImageContext.ImageAddress = MemoryImagePointerAligned; - - Status = PeCoffLoaderLoadImage (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "LoadImage() call failed on rebase", FileGuidString); - free ((VOID *) MemoryImagePointer); - return Status; - } - - ImageContext.DestinationAddress = NewPe32BaseAddress; - Status = PeCoffLoaderRelocateImage (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "RelocateImage() call failed on rebase", FileGuidString); - free ((VOID *) MemoryImagePointer); - return Status; - } - - ImageAddress = ImageContext.ImageAddress; - ImageSize = ImageContext.ImageSize; - EntryPoint = ImageContext.EntryPoint; - - if (ImageSize > Pe32ImageSize) { - Error ( - NULL, - 0, - 0, - "rebased image is larger than original PE32 image", - "0x%X > 0x%X, file %s", - ImageSize, - Pe32ImageSize, - FileGuidString - ); - free ((VOID *) MemoryImagePointer); - return EFI_ABORTED; - } - // - // Since we may have updated the Codeview RVA, we need to insure the PE - // header indicates the image is large enough to contain the Codeview data - // so it will be loaded properly later if the PEIM is reloaded into memory... - // - PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset); - if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) { - PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage); - PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum); - } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) { - PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage); - PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum); - } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) { - PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage); - PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum); - } else { - Error ( - NULL, - 0, - 0, - "unknown machine type in PE32 image", - "machine type=0x%X, file=%s", - (UINT32) PeHdr->FileHeader.Machine, - FileGuidString - ); - free ((VOID *) MemoryImagePointer); - return EFI_ABORTED; - } - - if (*PeHdrSizeOfImage != ImageContext.ImageSize) { - *PeHdrSizeOfImage = (UINT32) ImageContext.ImageSize; - if (*PeHdrChecksum) { - *PeHdrChecksum = 0; - } - } - - memcpy (CurrentPe32Section.Pe32Section + 1, (VOID *) MemoryImagePointerAligned, (UINT32) ImageSize); - - // - // Get EntryPoint in Flash Region. - // - EntryPoint = NewPe32BaseAddress + EntryPoint - ImageAddress; - - // - // If a map file was selected output mapping information for any file that - // was rebased. - // - if (MapFile != NULL) { - fprintf (MapFile, "PE32 File: %s Base:%08lx", FileGuidString, BaseAddress); - fprintf (MapFile, " EntryPoint:%08lx", EntryPoint); - if (ImageContext.PdbPointer != NULL) { - fprintf (MapFile, " FileName: %s", ImageContext.PdbPointer); - } - fprintf (MapFile, "\n"); - } - - free ((VOID *) MemoryImagePointer); - - // - // Now update file checksum - // - if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) { - TailSize = sizeof (EFI_FFS_FILE_TAIL); - } else { - TailSize = 0; - } - - if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) { - SavedState = FfsFile->State; - FfsFile->IntegrityCheck.Checksum.File = 0; - FfsFile->State = 0; - if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) { - FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ( - (UINT8 *) FfsFile, - GetLength (FfsFile->Size) - TailSize - ); - } else { - FfsFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; - } - - FfsFile->State = SavedState; - } - // - // Update tail if present - // - if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) { - TailValue = (EFI_FFS_FILE_TAIL) (~(FfsFile->IntegrityCheck.TailReference)); - *(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue; - } - } - // - // Now process TE sections - // - for (Index = 1;; Index++) { - Status = GetSectionByType (FfsFile, EFI_SECTION_TE, Index, &CurrentPe32Section); - if (EFI_ERROR (Status)) { - break; - } - - FoundCount++; - - // - // Calculate the TE base address, the FFS file base plus the offset of the TE section less the size stripped off - // by GenTEImage - // - TEImageHeader = (EFI_TE_IMAGE_HEADER *) ((UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER)); - - NewPe32BaseAddress = ((UINT32) BaseAddress) + - ( - (UINTN) CurrentPe32Section.Pe32Section + - sizeof (EFI_COMMON_SECTION_HEADER) + - sizeof (EFI_TE_IMAGE_HEADER) - - TEImageHeader->StrippedSize - - (UINTN) FfsFile - ); - - // - // Allocate a buffer to unshrink the image into. - // - Pe32ImageSize = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) - - sizeof (EFI_TE_IMAGE_HEADER); - Pe32ImageSize += TEImageHeader->StrippedSize; - TEBuffer = (UINT8 *) malloc (Pe32ImageSize); - if (TEBuffer == NULL) { - Error (NULL, 0, 0, "failed to allocate memory", NULL); - return EFI_OUT_OF_RESOURCES; - } - // - // Expand the image into our buffer and fill in critical fields in the DOS header - // Fill in fields required by the loader. - // At offset 0x3C is the offset to the PE signature. We'll put it immediately following the offset value - // itself. - // - memset (TEBuffer, 0, Pe32ImageSize); - DosHeader = (EFI_IMAGE_DOS_HEADER *) TEBuffer; - DosHeader->e_magic = EFI_IMAGE_DOS_SIGNATURE; - *(UINT32 *) (TEBuffer + 0x3C) = 0x40; - PeHdr = (EFI_IMAGE_NT_HEADERS *) (TEBuffer + 0x40); - PeHdr->Signature = EFI_IMAGE_NT_SIGNATURE; - PeHdr->FileHeader.Machine = TEImageHeader->Machine; - PeHdr->FileHeader.NumberOfSections = TEImageHeader->NumberOfSections; - - // - // Say the size of the optional header is the total we stripped off less the size of a PE file header and PE signature and - // the 0x40 bytes for our DOS header. - // - PeHdr->FileHeader.SizeOfOptionalHeader = (UINT16) (TEImageHeader->StrippedSize - 0x40 - sizeof (UINT32) - sizeof (EFI_IMAGE_FILE_HEADER)); - PeHdr->OptionalHeader.ImageBase = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER)); - PeHdr->OptionalHeader.AddressOfEntryPoint = TEImageHeader->AddressOfEntryPoint; - PeHdr->OptionalHeader.BaseOfCode = TEImageHeader->BaseOfCode; - PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize; - PeHdr->OptionalHeader.Subsystem = TEImageHeader->Subsystem; - PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize; - PeHdr->OptionalHeader.SizeOfHeaders = TEImageHeader->StrippedSize + TEImageHeader->NumberOfSections * - sizeof (EFI_IMAGE_SECTION_HEADER) - 12; - - // - // Set NumberOfRvaAndSizes in the optional header to what we had available in the original image - // - if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) || - (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0) - ) { - PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC + 1; - PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; - PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; - } - - if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) || - (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0) - ) { - PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; - PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size; - if (PeHdr->OptionalHeader.NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1) { - PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1; - } - } - // - // NOTE: These values are defaults, and should be verified to be correct in the GenTE utility - // - PeHdr->OptionalHeader.SectionAlignment = 0x10; - - // - // Copy the rest of the image to its original offset - // - memcpy ( - TEBuffer + TEImageHeader->StrippedSize, - (UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) + sizeof (EFI_TE_IMAGE_HEADER), - GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) - - sizeof (EFI_TE_IMAGE_HEADER) - ); - - // - // Initialize context - // - memset (&ImageContext, 0, sizeof (ImageContext)); - ImageContext.Handle = (VOID *) TEBuffer; - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead; - - Status = PeCoffLoaderGetImageInfo (&ImageContext); - - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "GetImageInfo() call failed on rebase of TE image", FileGuidString); - free (TEBuffer); - return Status; - } - // - // Allocate a buffer for the image to be loaded into. - // - MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x1000)); - if (MemoryImagePointer == 0) { - Error (NULL, 0, 0, "memory allocation error on rebase of TE image", FileGuidString); - free (TEBuffer); - return EFI_OUT_OF_RESOURCES; - } - memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000); - MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12); - - - ImageContext.ImageAddress = MemoryImagePointerAligned; - Status = PeCoffLoaderLoadImage (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "LoadImage() call failed on rebase of TE image", FileGuidString); - free (TEBuffer); - free ((VOID *) MemoryImagePointer); - return Status; - } - - ImageContext.DestinationAddress = NewPe32BaseAddress; - Status = PeCoffLoaderRelocateImage (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "RelocateImage() call failed on rebase of TE image", FileGuidString); - free ((VOID *) MemoryImagePointer); - free (TEBuffer); - return Status; - } - - ImageAddress = ImageContext.ImageAddress; - ImageSize = ImageContext.ImageSize; - EntryPoint = ImageContext.EntryPoint; - - // - // Since we may have updated the Codeview RVA, we need to insure the PE - // header indicates the image is large enough to contain the Codeview data - // so it will be loaded properly later if the PEIM is reloaded into memory... - // - PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset); - if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) { - PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage); - PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum); - } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) { - PeHdrSizeOfImage = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage); - PeHdrChecksum = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum); - } else { - Error ( - NULL, - 0, - 0, - "unknown machine type in TE image", - "machine type=0x%X, file=%s", - (UINT32) PeHdr->FileHeader.Machine, - FileGuidString - ); - free ((VOID *) MemoryImagePointer); - free (TEBuffer); - return EFI_ABORTED; - } - - if (*PeHdrSizeOfImage != ImageContext.ImageSize) { - *PeHdrSizeOfImage = (UINT32) ImageContext.ImageSize; - if (*PeHdrChecksum) { - *PeHdrChecksum = 0; - } - } - - TEImageHeader->ImageBase = (UINT64) (NewPe32BaseAddress + TEImageHeader->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER)); - memcpy ( - (UINT8 *) (CurrentPe32Section.Pe32Section + 1) + sizeof (EFI_TE_IMAGE_HEADER), - (VOID *) ((UINT8 *) MemoryImagePointerAligned + TEImageHeader->StrippedSize), - GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) - - sizeof (EFI_TE_IMAGE_HEADER) - ); - - // - // Get EntryPoint in Flash Region. - // - EntryPoint = NewPe32BaseAddress + EntryPoint - ImageAddress; - - // - // If a map file was selected output mapping information for any file that - // was rebased. - // - if (MapFile != NULL) { - fprintf (MapFile, "TE File: %s Base:%08lx", FileGuidString, BaseAddress); - fprintf (MapFile, " EntryPoint:%08lx", EntryPoint); - if (ImageContext.PdbPointer != NULL) { - fprintf (MapFile, " FileName: %s", ImageContext.PdbPointer); - } - fprintf (MapFile, "\n"); - } - - free ((VOID *) MemoryImagePointer); - free (TEBuffer); - if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) { - TailSize = sizeof (EFI_FFS_FILE_TAIL); - } else { - TailSize = 0; - } - // - // Now update file checksum - // - if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) { - SavedState = FfsFile->State; - FfsFile->IntegrityCheck.Checksum.File = 0; - FfsFile->State = 0; - if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) { - FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ( - (UINT8 *) FfsFile, - GetLength (FfsFile->Size) - TailSize - ); - } else { - FfsFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; - } - - FfsFile->State = SavedState; - } - // - // Update tail if present - // - if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) { - TailValue = (EFI_FFS_FILE_TAIL) (~(FfsFile->IntegrityCheck.TailReference)); - *(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue; - } - } - // - // If we found no files, then emit an error if no compressed sections either - // - if (FoundCount == 0) { - Status = GetSectionByType (FfsFile, EFI_SECTION_COMPRESSION, Index, &CurrentPe32Section); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "no PE32, TE, nor compressed section found in FV file", FileGuidString); - return EFI_NOT_FOUND; - } - } - - return EFI_SUCCESS; -} - -EFI_STATUS -FfsRebaseImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINT32 *ReadSize, - OUT VOID *Buffer - ) -/*++ - -Routine Description: - - Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file - -Arguments: - - FileHandle - The handle to the PE/COFF file - - FileOffset - The offset, in bytes, into the file to read - - ReadSize - The number of bytes to read from the file starting at FileOffset - - Buffer - A pointer to the buffer to read the data into. - -Returns: - - EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset - ---*/ -{ - CHAR8 *Destination8; - CHAR8 *Source8; - UINT32 Length; - - Destination8 = Buffer; - Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset); - Length = *ReadSize; - while (Length--) { - *(Destination8++) = *(Source8++); - } - - return EFI_SUCCESS; -} diff --git a/Tools/CodeTools/TianoTools/PeiRebase/PeiRebaseExe.h b/Tools/CodeTools/TianoTools/PeiRebase/PeiRebaseExe.h deleted file mode 100644 index b05baefb59..0000000000 --- a/Tools/CodeTools/TianoTools/PeiRebase/PeiRebaseExe.h +++ /dev/null @@ -1,155 +0,0 @@ -/*++ - -Copyright (c) 1999-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -Module Name: - - PeiRebaseExe.h - -Abstract: - - Definitions for the PeiRebase exe utility. - ---*/ - -#ifndef _EFI_PEIM_FIXUP_EXE_H -#define _EFI_PEIM_FIXUP_EXE_H - -#include -#include -#include -#include - -// -// Utility Name -// -#define UTILITY_NAME "PeiRebase" - -// -// Utility version information -// -#define UTILITY_MAJOR_VERSION 0 -#define UTILITY_MINOR_VERSION 1 -#define UTILITY_DATE __DATE__ - -// -// The maximum number of arguments accepted from the command line. -// -#define MAX_ARGS 9 - -// -// The file copy buffer size -// -#define FILE_COPY_BUFFER_SIZE 512 - -// -// The function that displays general utility information -// -VOID -PrintUtilityInfo ( - VOID - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - None - -Returns: - - GC_TODO: add return values - ---*/ -; - -// -// The function that displays the utility usage message. -// -VOID -PrintUsage ( - VOID - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - None - -Returns: - - GC_TODO: add return values - ---*/ -; - -// -// Internal function declarations -// -EFI_STATUS -FfsRebaseImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINT32 *ReadSize, - OUT VOID *Buffer - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - FileHandle - GC_TODO: add argument description - FileOffset - GC_TODO: add argument description - ReadSize - GC_TODO: add argument description - Buffer - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -; - -EFI_STATUS -FfsRebase ( - IN OUT EFI_FFS_FILE_HEADER *FfsFile, - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN FILE *MapFile OPTIONAL - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - FfsFile - GC_TODO: add argument description - BaseAddress - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -; - -#endif diff --git a/Tools/CodeTools/TianoTools/PeiRebase/build.xml b/Tools/CodeTools/TianoTools/PeiRebase/build.xml deleted file mode 100644 index 7174441f3f..0000000000 --- a/Tools/CodeTools/TianoTools/PeiRebase/build.xml +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/SecApResetVectorFixup/SecApResetVectorFixup.c b/Tools/CodeTools/TianoTools/SecApResetVectorFixup/SecApResetVectorFixup.c deleted file mode 100644 index 442645720e..0000000000 --- a/Tools/CodeTools/TianoTools/SecApResetVectorFixup/SecApResetVectorFixup.c +++ /dev/null @@ -1,363 +0,0 @@ -/*++ - -Copyright (c) 2004-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -Module Name: - - SecApResetVectorFixup.c - -Abstract: - - This utility is part of build process for IA32 Fvrecovery.fv whose total size - is larger than 128kB so that we cannot use GenFvImage utility to put Ap reset - vector at the zero vector of Fv header. - - PEI FV after using the tool - - ------------------------- - |zzz | - | | - | | - | FFS | - | | - | | - | | - |---------------------- | - | PAD | - | | - |.......................| --- - | | | - |xxx | | 128K - |---------------------- | | - | VTF (SEC) | | - ------------------------- --- - - 1. zzz --> Zero vector, which is beyond the 128K limited address space - 2. xxx --> AP reset vector at 4K alignment below 128K and it is in the PAD - file area. - 3. After the build process ,the PAD guid is changed to a new GUID to avoid - the PAD definition confusing. If there is some problem, try to disable - UpdatePadFileGuid - - - ---*/ - -#include "SecApResetVectorFixup.h" - - -EFI_GUID DefaultFvPadFileNameGuid = { 0x78f54d4, 0xcc22, 0x4048, 0x9e, 0x94, 0x87, 0x9c, 0x21, 0x4d, 0x56, 0x2f }; -EFI_GUID NewFvPadFileNameGuid = { 0x145372bc, 0x66b9, 0x476d, 0x81, 0xbc, 0x21, 0x27, 0xc3, 0x76, 0xbb, 0x66 }; - -// -// jmp 0xf000:0xffd0 (0xFFFFFFD0) -// -UINT8 ApResetVector[5] = {0xEA, 0xD0, 0xFF, 0x00, 0xF0}; - -VOID -PrintUtilityInfo ( - VOID - ) -/*++ - -Routine Description: - - Displays the standard utility information to SDTOUT - -Arguments: - - None - -Returns: - - None - ---*/ -{ - printf ( - "%s - Tiano IA32 SEC Ap Reset Vector Fixup Utility."" Version %i.%i\n\n", - UTILITY_NAME, - UTILITY_MAJOR_VERSION, - UTILITY_MINOR_VERSION - ); -} - -VOID -PrintUsage ( - VOID - ) -/*++ - -Routine Description: - - Displays the utility usage syntax to STDOUT - -Arguments: - - None - -Returns: - - None - ---*/ -{ - printf ("Usage: %s InputFvrecoveryFile OutputFvrecoveryFile\n", UTILITY_NAME); - printf (" Where:\n"); - printf ("\tInputFvrecoveryFile - Name of the IA32 input Fvrecovery.fv file.\n"); - printf ("\tOutputFvrecoveryFile - Name of the IA32 output Fvrecovery.fv file.\n"); -} - - -VOID -UpdatePadFileGuid ( - IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader, - IN EFI_FFS_FILE_HEADER *FileHeader, - IN UINT32 FileLength, - IN OUT EFI_GUID *Guid - ) -/*++ - -Routine Description: - - Update the Pad File Guid to change it to other guid and update - the checksum - -Arguments: - FvHeader - EFI_FIRMWARE_VOLUME_HEADER - FileHeader - The FFS PAD file header. - FileLength - The FFS PAD file length. - Guid - The Guid to compare and if it is PAD Guid, update it to new Guid -Returns: - VOID ---*/ - -{ - if ((CompareGuid (Guid, (EFI_GUID *)&DefaultFvPadFileNameGuid)) == 0) { - // - // Set new Pad file guid - // - memcpy (Guid, &NewFvPadFileNameGuid, sizeof (EFI_GUID)); - - - - FileHeader->Type = EFI_FV_FILETYPE_FFS_PAD; - FileHeader->Attributes = 0; - // - // Fill in checksums and state, must be zero during checksum calculation. - // - FileHeader->IntegrityCheck.Checksum.Header = 0; - FileHeader->IntegrityCheck.Checksum.File = 0; - FileHeader->State = 0; - FileHeader->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER)); - if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) { - FileHeader->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) FileHeader, FileLength); - } else { - FileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; - } - - FileHeader->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID; - - if (FvHeader->Attributes & EFI_FVB_ERASE_POLARITY) { - FileHeader->State = (UINT8)~(FileHeader->State); - } - } - -} - - -STATUS -main ( - IN INTN argc, - IN CHAR8 **argv - ) -/*++ - -Routine Description: - - Main function. - -Arguments: - - argc - Number of command line parameters. - argv - Array of pointers to parameter strings. - -Returns: - STATUS_SUCCESS - Utility exits successfully. - STATUS_ERROR - Some error occurred during execution. - ---*/ -{ - FILE *FpIn; - FILE *FpOut; - UINT32 FvrecoveryFileSize; - UINT8 *FileBuffer; - UINT8 *FileBufferRaw; - UINT64 FvLength; - UINT32 Offset; - UINT32 FileLength; - UINT32 FileOccupiedSize; - EFI_FIRMWARE_VOLUME_HEADER *FvHeader; - EFI_FFS_FILE_HEADER *FileHeader; - EFI_GUID *TempGuid; - UINT8 *FixPoint; - UINT32 TempResult; - UINT32 Index; - UINT32 IpiVector; - - TempGuid = NULL; - SetUtilityName (UTILITY_NAME); - - // - // Display utility information - // - PrintUtilityInfo (); - - // - // Verify the correct number of arguments - // - if (argc != MAX_ARGS) { - Error (NULL, 0, 0, "invalid number of input parameters specified", NULL); - PrintUsage (); - return STATUS_ERROR; - } - // - // Open the Input Fvrecovery.fv file - // - if ((FpIn = fopen (argv[1], "rb")) == NULL) { - Error (NULL, 0, 0, "Unable to open file", argv[1]); - return STATUS_ERROR; - } - // - // Get the Input Fvrecovery.fv file size - // - fseek (FpIn, 0, SEEK_END); - FvrecoveryFileSize = ftell (FpIn); - // - // Read the contents of input file to memory buffer - // - FileBuffer = NULL; - FileBufferRaw = NULL; - FileBufferRaw = (UINT8 *) malloc (FvrecoveryFileSize + 0x10000); - if (NULL == FileBufferRaw) { - Error (NULL, 0, 0, "No sufficient memory to allocate!", NULL); - fclose (FpIn); - return STATUS_ERROR; - } - TempResult = 0x10000 - ((UINT32)FileBufferRaw & 0x0FFFF); - FileBuffer = (UINT8 *)((UINT32)FileBufferRaw + TempResult); - fseek (FpIn, 0, SEEK_SET); - TempResult = fread (FileBuffer, 1, FvrecoveryFileSize, FpIn); - if (TempResult != FvrecoveryFileSize) { - Error (NULL, 0, 0, "Read input file error!", NULL); - free ((VOID *)FileBufferRaw); - fclose (FpIn); - return STATUS_ERROR; - } - // - // Close the input Fvrecovery.fv file - // - fclose (FpIn); - // - // Find the pad FFS file - // - FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FileBuffer; - FvLength = FvHeader->FvLength; - FileHeader = (EFI_FFS_FILE_HEADER *)(FileBuffer + FvHeader->HeaderLength); - FileLength = (*(UINT32 *)(FileHeader->Size)) & 0x00FFFFFF; - FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8); - Offset = (UINT32)FileHeader - (UINT32)FileBuffer; - - while (Offset < FvLength) { - TempGuid = (EFI_GUID *)&(FileHeader->Name); - FileLength = (*(UINT32 *)(FileHeader->Size)) & 0x00FFFFFF; - FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8); - if ((CompareGuid (TempGuid, (EFI_GUID *)&DefaultFvPadFileNameGuid)) == 0) { - break; - } - FileHeader = (EFI_FFS_FILE_HEADER *)((UINT32)FileHeader + FileOccupiedSize); - Offset = (UINT32)FileHeader - (UINT32)FileBuffer; - } - - if (Offset >= FvLength) { - Error (NULL, 0, 0, "No pad file found!", NULL); - free ((VOID *)FileBufferRaw); - return STATUS_ERROR; - } - // - // Find the position to place Ap reset vector, the offset - // between the position and the end of Fvrecovery.fv file - // should not exceed 128kB to prevent Ap reset vector from - // outside legacy E and F segment - // - FixPoint = (UINT8 *)(FileHeader + sizeof(EFI_FFS_FILE_HEADER)); - TempResult = 0x1000 - ((UINT32)FixPoint & 0x0FFF); - FixPoint +=TempResult; - if (((UINT32)FixPoint - (UINT32)FileHeader + 5) > FileOccupiedSize) { - Error (NULL, 0, 0, "No appropriate space in pad file to add Ap reset vector!", NULL); - free ((VOID *)FileBufferRaw); - return STATUS_ERROR; - } - while (((UINT32)FixPoint - (UINT32)FileHeader + 5) <= FileOccupiedSize) { - FixPoint += 0x1000; - } - FixPoint -= 0x1000; - if ((UINT32)FvHeader + FvLength - (UINT32)FixPoint > 0x20000) { - Error (NULL, 0, 0, "The position to place Ap reset vector is not in E and F segment!", NULL); - free ((VOID *)FileBufferRaw); - return STATUS_ERROR; - } - // - // Fix up Ap reset vector and calculate the IPI vector - // - for (Index = 0; Index < 5; Index++) { - FixPoint[Index] = ApResetVector[Index]; - } - TempResult = 0x0FFFFFFFF - ((UINT32)FvHeader + (UINT32)FvLength - 1 - (UINT32)FixPoint); - TempResult >>= 12; - IpiVector = TempResult & 0x0FF; - - - UpdatePadFileGuid (FvHeader, FileHeader, FileLength, TempGuid); - - // - // Open the output Fvrecovery.fv file - // - if ((FpOut = fopen (argv[2], "w+b")) == NULL) { - Error (NULL, 0, 0, "Unable to open file", argv[2]); - free ((VOID *)FileBufferRaw); - return STATUS_ERROR; - } - // - // Write the output Fvrecovery.fv file - // - if ((fwrite (FileBuffer, 1, FvrecoveryFileSize, FpOut)) != FvrecoveryFileSize) { - Error (NULL, 0, 0, "Write output file error!", NULL); - free ((VOID *)FileBufferRaw); - return STATUS_ERROR; - } - // - // - // - fseek (FpOut, -8, SEEK_END); - if ((fwrite (&IpiVector, 1, sizeof(UINT32), FpOut)) != sizeof(UINT32)) { - Error (NULL, 0, 0, "Write output file error!", NULL); - free ((VOID *)FileBufferRaw); - return STATUS_ERROR; - } - // - // Close the output Fvrecovery.fv file - // - fclose (FpOut); - free ((VOID *)FileBufferRaw); - return STATUS_SUCCESS; -} - diff --git a/Tools/CodeTools/TianoTools/SecApResetVectorFixup/SecApResetVectorFixup.h b/Tools/CodeTools/TianoTools/SecApResetVectorFixup/SecApResetVectorFixup.h deleted file mode 100644 index 6d234e3a18..0000000000 --- a/Tools/CodeTools/TianoTools/SecApResetVectorFixup/SecApResetVectorFixup.h +++ /dev/null @@ -1,104 +0,0 @@ -/*++ - -Copyright (c) 1999-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -Module Name: - - SecApResetVectorFixup.h - -Abstract: - - Definitions for the SecApResetVectorFixup utility. - ---*/ - -#ifndef _SEC_AP_RESET_VECTOR_FIXUP_H -#define _SEC_AP_RESET_VECTOR_FIXUP_H - -#include -#include - -#include -#include -#include -#include -#include - -#include "EfiUtilityMsgs.c" -#include "CommonLib.h" - - -// -// Utility Name -// -#define UTILITY_NAME "SecApResetVectorFixup" - -// -// Utility version information -// -#define UTILITY_MAJOR_VERSION 0 -#define UTILITY_MINOR_VERSION 1 -#define UTILITY_DATE __DATE__ - -// -// The maximum number of arguments accepted from the command line. -// -#define MAX_ARGS 3 -#define BUF_SIZE (8 * 1024) - -#define GETOCCUPIEDSIZE(ActualSize, Alignment) \ - (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1)) - - -VOID -PrintUtilityInfo ( - VOID - ) -/*++ - -Routine Description: - - Displays the standard utility information to SDTOUT - -Arguments: - - None - -Returns: - - None - ---*/ -; - -VOID -PrintUsage ( - VOID - ) -/*++ - -Routine Description: - - Displays the utility usage syntax to STDOUT - -Arguments: - - None - -Returns: - - None - ---*/ -; - - -#endif diff --git a/Tools/CodeTools/TianoTools/SecApResetVectorFixup/build.xml b/Tools/CodeTools/TianoTools/SecApResetVectorFixup/build.xml deleted file mode 100644 index f615b2a602..0000000000 --- a/Tools/CodeTools/TianoTools/SecApResetVectorFixup/build.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/SecFixup/SecFixup.c b/Tools/CodeTools/TianoTools/SecFixup/SecFixup.c deleted file mode 100644 index c2d46a1d5c..0000000000 --- a/Tools/CodeTools/TianoTools/SecFixup/SecFixup.c +++ /dev/null @@ -1,362 +0,0 @@ -/*++ - -Copyright (c) 1999-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -Module Name: - - SecFixup.c - -Abstract: - - This utility is part of build process for IA32 SEC FFS file. - - It fixup the reset vector data. The reset vector data binary file - will be wrapped as a RAW section and be located immediately after - the PE/TE section. - - The SEC EXE file can be either PE or TE file. - ---*/ - -#include - -#include -#include -#include - -#include "EfiUtilityMsgs.c" -#include "SecFixup.h" - -VOID -PrintUtilityInfo ( - VOID - ) -/*++ - -Routine Description: - - Displays the standard utility information to SDTOUT - -Arguments: - - None - -Returns: - - None - ---*/ -{ - printf ( - "%s - Tiano IA32 SEC Fixup Utility."" Version %i.%i\n\n", - UTILITY_NAME, - UTILITY_MAJOR_VERSION, - UTILITY_MINOR_VERSION - ); -} - -VOID -PrintUsage ( - VOID - ) -/*++ - -Routine Description: - - Displays the utility usage syntax to STDOUT - -Arguments: - - None - -Returns: - - None - ---*/ -{ - printf ("Usage: %s SecExeFile ResetVectorDataFile OutputFile\n", UTILITY_NAME); - printf (" Where:\n"); - printf ("\tSecExeFile - Name of the IA32 SEC EXE file.\n"); - printf ("\tResetVectorDataFile - Name of the reset vector data binary file.\n"); - printf ("\tOutputFileName - Name of the output file.\n\n"); -} - -STATUS -main ( - IN INTN argc, - IN CHAR8 **argv - ) -/*++ - -Routine Description: - - Main function. - -Arguments: - - argc - Number of command line parameters. - argv - Array of pointers to parameter strings. - -Returns: - STATUS_SUCCESS - Utility exits successfully. - STATUS_ERROR - Some error occurred during execution. - ---*/ -{ - FILE *FpIn; - - FILE *FpOut; - UINT32 AddressOfEntryPoint; - INT32 DestRel; - STATUS Status; - UINT32 SecFileSize; - - SetUtilityName (UTILITY_NAME); - - // - // Display utility information - // - PrintUtilityInfo (); - - // - // Verify the correct number of arguments - // - if (argc != MAX_ARGS) { - Error (NULL, 0, 0, "invalid number of input parameters specified", NULL); - PrintUsage (); - return STATUS_ERROR; - } - // - // Open the SEC exe file - // - if ((FpIn = fopen (argv[1], "rb")) == NULL) { - Error (NULL, 0, 0, "Unable to open file", argv[1]); - return STATUS_ERROR; - } - // - // Get the entry point of the EXE file - // - Status = GetEntryPoint (FpIn, &AddressOfEntryPoint); - if (Status != STATUS_SUCCESS) { - fclose (FpIn); - return STATUS_ERROR; - } - // - // Get the SEC file size - // - fseek (FpIn, 0, SEEK_END); - SecFileSize = ftell (FpIn); - - // - // Close the SEC file - // - fclose (FpIn); - - // - // Open the reset vector data file - // - if ((FpIn = fopen (argv[2], "rb")) == NULL) { - Error (NULL, 0, 0, "Unable to open file", argv[2]); - return STATUS_ERROR; - } - // - // Open the output file - // - if ((FpOut = fopen (argv[3], "w+b")) == NULL) { - Error (NULL, 0, 0, "Unable to open file", argv[3]); - fclose (FpIn); - return STATUS_ERROR; - } - // - // Copy the input file to the output file - // - if (CopyFile (FpIn, FpOut) != STATUS_SUCCESS) { - fclose (FpIn); - fclose (FpOut); - return STATUS_ERROR; - } - // - // Close the reset vector data file - // - fclose (FpIn); - - // - // Fix the destination relative in the jmp instruction - // in the reset vector data structure - // - fseek (FpOut, -DEST_REL_OFFSET, SEEK_END); - DestRel = AddressOfEntryPoint - (SecFileSize + sizeof (EFI_COMMON_SECTION_HEADER) + (UINT32) (ftell (FpOut)) + 2); - if (DestRel <= -65536) { - Error (NULL, 0, 0, "The SEC EXE file size is too big", NULL); - fclose (FpOut); - return STATUS_ERROR; - } - - if (fwrite (&DestRel, sizeof (UINT16), 1, FpOut) != 1) { - Error (NULL, 0, 0, "Failed to write to the output file", NULL); - fclose (FpOut); - return STATUS_ERROR; - } - // - // Close the output file - // - fclose (FpOut); - - return STATUS_SUCCESS; -} - -STATUS -GetEntryPoint ( - IN FILE *ExeFile, - OUT UINT32 *EntryPoint - ) -/*++ - -Routine Description: - - Get the address of the entry point of a PE/TE file. - -Arguments: - - PeFile - File pointer to the specified PE/TE file. - EntryPoint - Buffer for the address of the entry point to be returned. - -Returns: - STATUS_SUCCESS - Function completed successfully. - STATUS_ERROR - Error occured. - ---*/ -// GC_TODO: ExeFile - add argument and description to function comment -{ - EFI_IMAGE_DOS_HEADER DosHeader; - EFI_IMAGE_NT_HEADERS32 NtHeader; - EFI_TE_IMAGE_HEADER TeHeader; - - // - // Check if it is a TE file - // - fseek (ExeFile, 0, SEEK_SET); - // - // Attempt to read the TE header - // - if (fread (&TeHeader, sizeof (TeHeader), 1, ExeFile) == 1) { - if (TeHeader.Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - if (TeHeader.Machine != EFI_IMAGE_MACHINE_IA32) { - Error (NULL, 0, 0, "The SEC file is PE but is not PE32 for IA32", NULL); - return STATUS_ERROR; - } - - *EntryPoint = TeHeader.AddressOfEntryPoint + sizeof (EFI_TE_IMAGE_HEADER) - TeHeader.StrippedSize; - return STATUS_SUCCESS; - } - } - // - // Check if it is a PE file - // - fseek (ExeFile, 0, SEEK_SET); - // - // Attempt to read the DOS header - // - if (fread (&DosHeader, sizeof (DosHeader), 1, ExeFile) != 1) { - goto InvalidFile; - } - // - // Check the magic number - // - if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) { - goto InvalidFile; - } - // - // Position into the file and read the NT PE header - // - fseek (ExeFile, (long) DosHeader.e_lfanew, SEEK_SET); - if (fread (&NtHeader, sizeof (NtHeader), 1, ExeFile) != 1) { - goto InvalidFile; - } - // - // Check the PE signature in the header - // - if (NtHeader.Signature != EFI_IMAGE_NT_SIGNATURE) { - goto InvalidFile; - } - // - // Make sure the PE file is PE32 for IA32 - // - if (NtHeader.FileHeader.Machine != EFI_IMAGE_MACHINE_IA32 || - NtHeader.OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC - ) { - Error (NULL, 0, 0, "The SEC file is PE but is not PE32 for IA32", NULL); - return STATUS_ERROR; - } - // - // Get the entry point from the optional header - // - *EntryPoint = NtHeader.OptionalHeader.AddressOfEntryPoint; - return STATUS_SUCCESS; - -InvalidFile: - Error (NULL, 0, 0, "The SEC file is neither PE nor TE file", NULL); - return STATUS_ERROR; -} - -STATUS -CopyFile ( - FILE *FpIn, - FILE *FpOut - ) -/*++ - -Routine Description: - - Copy file. - -Arguments: - - FpIn - File pointer to the source file. - FpOut - File pointer to the destination file. - -Returns: - STATUS_SUCCESS - Function completed successfully. - STATUS_ERROR - Error occured. - ---*/ -{ - INTN FileSize; - - INTN Offset; - - INTN Length; - UINT8 Buffer[BUF_SIZE]; - - fseek (FpIn, 0, SEEK_END); - FileSize = ftell (FpIn); - - fseek (FpIn, 0, SEEK_SET); - fseek (FpOut, 0, SEEK_SET); - - Offset = 0; - while (Offset < FileSize) { - Length = sizeof (Buffer); - if (FileSize - Offset < Length) { - Length = FileSize - Offset; - } - - if (fread (Buffer, Length, 1, FpIn) != 1 || fwrite (Buffer, Length, 1, FpOut) != 1) { - Error (NULL, 0, 0, "Copy file error", NULL); - return STATUS_ERROR; - } - - Offset += Length; - } - - return STATUS_SUCCESS; -} diff --git a/Tools/CodeTools/TianoTools/SecFixup/SecFixup.h b/Tools/CodeTools/TianoTools/SecFixup/SecFixup.h deleted file mode 100644 index 3694b1516a..0000000000 --- a/Tools/CodeTools/TianoTools/SecFixup/SecFixup.h +++ /dev/null @@ -1,146 +0,0 @@ -/*++ - -Copyright (c) 1999-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -Module Name: - - SecFixup.h - -Abstract: - - Definitions for the SecFixup utility. - ---*/ - -#ifndef _SEC_FIXUP_H -#define _SEC_FIXUP_H - -// -// Utility Name -// -#define UTILITY_NAME "SecFixup" - -// -// Utility version information -// -#define UTILITY_MAJOR_VERSION 0 -#define UTILITY_MINOR_VERSION 1 -#define UTILITY_DATE __DATE__ - -// -// The maximum number of arguments accepted from the command line. -// -#define MAX_ARGS 4 - -#define DEST_REL_OFFSET 13 -#define BUF_SIZE (8 * 1024) - -// -// The function that displays general utility information -// -VOID -PrintUtilityInfo ( - VOID - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - None - -Returns: - - GC_TODO: add return values - ---*/ -; - -// -// The function that displays the utility usage message. -// -VOID -PrintUsage ( - VOID - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - None - -Returns: - - GC_TODO: add return values - ---*/ -; - -// -// The function that gets the entry point of a PE/TE file. -// -STATUS -GetEntryPoint ( - IN FILE *ExeFile, - OUT UINT32 *EntryPoint - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - ExeFile - GC_TODO: add argument description - EntryPoint - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -; - -// -// The function that copies a file. -// -STATUS -CopyFile ( - FILE *FpIn, - FILE *FpOut - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - FpIn - GC_TODO: add argument description - FpOut - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -; - -#endif diff --git a/Tools/CodeTools/TianoTools/SecFixup/build.xml b/Tools/CodeTools/TianoTools/SecFixup/build.xml deleted file mode 100644 index ebc408ba26..0000000000 --- a/Tools/CodeTools/TianoTools/SecFixup/build.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/SetStamp/SetStamp.c b/Tools/CodeTools/TianoTools/SetStamp/SetStamp.c deleted file mode 100644 index 539aced1d9..0000000000 --- a/Tools/CodeTools/TianoTools/SetStamp/SetStamp.c +++ /dev/null @@ -1,475 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - SetStamp.c - -Abstract: - Set Date/Time Stamp of Portable Executable (PE) format file - ---*/ - -#include -#include -#include - -#define LINE_MAXLEN 80 - -void -PrintUsage ( - void - ) -/*++ -Routine Description: - print usage of setstamp command - -Arguments: - void - -Returns: - None ---*/ -{ - // - // print usage of command - // - printf ("Usage: SetStamp \n"); -} - -int -GetDateTime ( - FILE *fp, - time_t *ltime - ) -/*++ -Routine Description: - Read the date and time from TIME file. If the date/time string is -"NOW NOW", write the current date and time to TIME file and set it to -ltime. Else, set the date and time of TIME file to ltime. - -Arguments: - fp - The pointer of TIME file - ltime - Date and time - -Returns: - = 0 - Success - = -1 - Failed ---*/ -{ - char buffer[LINE_MAXLEN]; - struct tm stime; - struct tm *now; - - if (fgets (buffer, LINE_MAXLEN, fp) == NULL) { - printf ("Error: Cannot read TIME file.\n"); - return -1; - } - // - // compare the value with "NOW NOW", write TIME file if equal - // - if (strncmp (buffer, "NOW NOW", 7) == 0) { - // - // get system current time and date - // - time (ltime); - - now = localtime (ltime); - if (now == NULL) { - printf ("Error: Cannot get local time.\n"); - return -1; - } - - if (strftime (buffer, LINE_MAXLEN, "%Y-%m-%d %H:%M:%S", now) == 0) { - printf ("Error: Cannot format time string.\n"); - return -1; - } - // - // write TIME file - // - if (fseek (fp, 0, SEEK_SET) != 0) { - printf ("Error: Cannot move location of TIME file.\n"); - return -1; - } - - if (fputs (buffer, fp) == EOF) { - printf ("Error: Cannot write time string to TIME file.\n"); - return -1; - } - // - // ltime has been set as current time and date, return - // - return 0; - } - // - // get the date and time from buffer - // - if (6 != sscanf ( - buffer, - "%d-%d-%d %d:%d:%d", - &stime.tm_year, - &stime.tm_mon, - &stime.tm_mday, - &stime.tm_hour, - &stime.tm_min, - &stime.tm_sec - )) { - printf ("Error: Invaild date or time!\n"); - return -1; - } - // - // in struct, Month (0 - 11; Jan = 0). So decrease 1 from it - // - stime.tm_mon -= 1; - - // - // in struct, Year (current year minus 1900) - // and only the dates can be handled from Jan 1, 1970 to Jan 18, 2038 - // - // - // convert 0 -> 100 (2000), 1 -> 101 (2001), ..., 38 -> 138 (2038) - // - if (stime.tm_year <= 38) { - stime.tm_year += 100; - } - // - // convert 1970 -> 70, 2000 -> 100, ... - // - else if (stime.tm_year >= 1970) { - stime.tm_year -= 1900; - } - // - // convert the date and time to time_t format - // - *ltime = mktime (&stime); - if (*ltime == (time_t) - 1) { - printf ("Error: Invalid date or time!\n"); - return -1; - } - - return 0; -} - -int -ReadFromFile ( - FILE *fp, - long offset, - void *buffer, - int size - ) -/*++ -Routine Description: - read data from a specified location of file - -Arguments: - fp - file pointer - offset - number of bytes from beginning of file - buffer - buffer used to store data - size - size of buffer - -Returns: - = 0 - Success - = -1 - Failed ---*/ -{ - // - // set file pointer to the specified location of file - // - if (fseek (fp, offset, SEEK_SET) != 0) { - printf ("Error: Cannot move the current location of the file.\n"); - return -1; - } - // - // read data from the file - // - if (fread (buffer, size, 1, fp) != 1) { - printf ("Error: Cannot read data from the file.\n"); - return -1; - } - - return 0; -} - -int -WriteToFile ( - FILE *fp, - long offset, - void *buffer, - int size - ) -/*++ -Routine Description: - write data to a specified location of file - -Arguments: - fp - file pointer - offset - number of bytes from beginning of file - buffer - buffer used to store data - size - size of buffer - -Returns: - = 0 - Success - = -1 - Failed ---*/ -{ - // - // set file pointer to the specified location of file - // - if (fseek (fp, offset, SEEK_SET) != 0) { - printf ("Error: Cannot move the current location of the file.\n"); - return -1; - } - // - // write data to the file - // - if (fwrite (buffer, size, 1, fp) != 1) { - perror ("Error: Cannot write data to the file.\n"); - return -1; - } - - return 0; -} - -int -SetStamp ( - FILE *fp, - time_t ltime - ) -/*++ -Routine Description: - set Date/Time Stamp of the file - -Arguments: - fp - file pointer - ltime - time and date - -Returns: - = 0 - Success - = -1 - Failed ---*/ -{ - unsigned char header[4]; - unsigned long offset; - unsigned long NumberOfRvaAndSizes; - unsigned int nvalue; - unsigned long lvalue; - - // - // read the header of file - // - if (ReadFromFile (fp, 0, header, 2) != 0) { - return -1; - } - // - // "MZ" -- the header of image file (PE) - // - if (strncmp ((char *) header, "MZ", 2) != 0) { - printf ("Error: Invalid Image file.\n"); - return -1; - } - // - // At location 0x3C, the stub has the file offset to the - // PE signature. - // - if (ReadFromFile (fp, 0x3C, &offset, 4) != 0) { - return -1; - } - // - // read the header of optional - // - if (ReadFromFile (fp, offset, header, 4) != 0) { - return -1; - } - // - // "PE\0\0" -- the signature of optional header - // - if (strncmp ((char *) header, "PE\0\0", 4) != 0) { - printf ("Error: Invalid PE format file.\n"); - return -1; - } - // - // Add 8 to skip PE signature (4-byte), Machine (2-byte) and - // NumberOfSection (2-byte) - // - offset += 8; - - if (WriteToFile (fp, offset, <ime, 4) != 0) { - return -1; - } - // - // Add 16 to skip COFF file header, and get to optional header. - // - offset += 16; - - // - // Check the magic field, 0x10B for PE32 and 0x20B for PE32+ - // - if (ReadFromFile (fp, offset, &nvalue, 2) != 0) { - return -1; - } - // - // If this is PE32 image file, offset of NumberOfRvaAndSizes is 92. - // Else it is 108. - // - switch (nvalue & 0xFFFF) { - case 0x10B: - offset += 92; - break; - - case 0x20B: - offset += 108; - break; - - default: - printf ("Error: Sorry! The Magic value is unknown.\n"); - return -1; - } - // - // get the value of NumberOfRvaAndSizes - // - if (ReadFromFile (fp, offset, &NumberOfRvaAndSizes, 4) != 0) { - return -1; - } - // - // Date/time stamp exists in Export Table, Import Table, Resource Table, - // Debug Table and Delay Import Table. And in Import Table and Delay Import - // Table, it will be set when bound. So here only set the date/time stamp - // of Export Table, Resource Table and Debug Table. - // - // - // change date/time stamp of Export Table, the offset of Export Table - // is 4 + 0 * 8 = 4. And the offset of stamp is 4. - // - if (NumberOfRvaAndSizes >= 1) { - if (ReadFromFile (fp, offset + 4, &lvalue, 4) != 0) { - return -1; - } - - if (lvalue != 0) { - if (WriteToFile (fp, lvalue + 4, <ime, 4) != 0) { - return -1; - } - } - } - // - // change date/time stamp of Resource Table, the offset of Resource Table - // is 4 + 2 * 8 = 20. And the offset of stamp is 4. - // - if (NumberOfRvaAndSizes >= 3) { - if (ReadFromFile (fp, offset + 20, &lvalue, 4) != 0) { - return -1; - } - - if (lvalue != 0) { - if (WriteToFile (fp, lvalue + 4, <ime, 4) != 0) { - return -1; - } - } - } - // - // change date/time stamp of Debug Table, offset of Debug Table - // is 4 + 6 * 8 = 52. And the offset of stamp is 4. - // - if (NumberOfRvaAndSizes >= 7) { - if (ReadFromFile (fp, offset + 52, &lvalue, 4) != 0) { - return -1; - } - - if (lvalue != 0) { - if (WriteToFile (fp, lvalue + 4, <ime, 4) != 0) { - return -1; - } - } - // - // change the date/time stamp of Debug Data - // - if (ReadFromFile (fp, lvalue + 24, &lvalue, 4) != 0) { - return -1; - } - // - // get the signature of debug data - // - if (ReadFromFile (fp, lvalue, header, 2) != 0) { - return -1; - } - // - // "NB" - the signature of Debug Data - // Need Review: (From Spec. is "NB05", From .dll is "NB10") - // - if (strncmp ((char *) header, "NB", 2) == 0) { - if (WriteToFile (fp, lvalue + 8, <ime, 4) != 0) { - return -1; - } - } - } - - return 0; -} - -int -main ( - int argc, - char *argv[] - ) -{ - FILE *fp; - time_t ltime; - - // - // check the number of parameters - // - if (argc != 3) { - PrintUsage (); - return -1; - } - // - // open the TIME file, if not exists, return - // - fp = fopen (argv[2], "r+"); - if (fp == NULL) { - return 0; - } - // - // get time and date from file - // - if (GetDateTime (fp, <ime) != 0) { - fclose (fp); - return -1; - } - // - // close the TIME file - // - fclose (fp); - - // - // open the PE file - // - fp = fopen (argv[1], "r+b"); - if (fp == NULL) { - printf ("Error: Cannot open the PE file!\n"); - return -1; - } - // - // set time and date stamp to the PE file - // - if (SetStamp (fp, ltime) != 0) { - fclose (fp); - return -1; - } - - printf ("Set Date/Time Stamp to %s", ctime (<ime)); - - // - // close the PE file - // - fclose (fp); - - return 0; -} diff --git a/Tools/CodeTools/TianoTools/SetStamp/build.xml b/Tools/CodeTools/TianoTools/SetStamp/build.xml deleted file mode 100644 index 9425797c45..0000000000 --- a/Tools/CodeTools/TianoTools/SetStamp/build.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/SplitFile/SplitFile.c b/Tools/CodeTools/TianoTools/SplitFile/SplitFile.c deleted file mode 100644 index a1bda7dc31..0000000000 --- a/Tools/CodeTools/TianoTools/SplitFile/SplitFile.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - -Copyright (c) 1999-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -*/ - -// GC_TODO: fix comment to start with /*++ -#include "stdio.h" -#include "string.h" -#include "stdlib.h" - -void -helpmsg ( - void - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - -Returns: - - GC_TODO: add return values - ---*/ -{ - printf ( - "SplitFile Filename Offset\n"" Filename = Input file to split\n"" Offset = offset at which to split file\n" - "\n\n""SplitFile will break a file in two pieces at the requested offset\n" - " outputting Filename1 and Filename2\n" - ); -} - -int -main ( - int argc, - char*argv[] - ) -/*++ - -Routine Description: - - GC_TODO: Add function description - -Arguments: - - argc - GC_TODO: add argument description - ] - GC_TODO: add argument description - -Returns: - - GC_TODO: add return values - ---*/ -{ - FILE *In; - - FILE *Out1; - - FILE *Out2; - char OutName1[512]; - char OutName2[512]; - unsigned long Index; - unsigned long splitpoint; - char CharC; - - if (argc != 3) { - helpmsg (); - return -1; - } - - In = fopen (argv[1], "rb"); - if (In == NULL) { - printf ("Unable to open file \"%s\"\n", argv[1]); - return -1; - } - - strncpy (OutName1, argv[1], 510); - strncpy (OutName2, argv[1], 510); - strcat (OutName1, "1"); - strcat (OutName2, "2"); - - Out1 = fopen (OutName1, "wb"); - if (Out1 == NULL) { - printf ("Unable to open file \"%s\"\n", OutName1); - return -1; - } - - Out2 = fopen (OutName2, "wb"); - if (Out2 == NULL) { - printf ("Unable to open file \"%s\"\n", OutName2); - return -1; - } - - splitpoint = atoi (argv[2]); - - for (Index = 0; Index < splitpoint; Index++) { - CharC = (char) fgetc (In); - if (feof (In)) { - break; - } - - fputc (CharC, Out1); - } - - for (;;) { - CharC = (char) fgetc (In); - if (feof (In)) { - break; - } - - fputc (CharC, Out2); - } - - fclose (In); - fclose (Out1); - fclose (Out2); - - return 0; -} diff --git a/Tools/CodeTools/TianoTools/SplitFile/build.xml b/Tools/CodeTools/TianoTools/SplitFile/build.xml deleted file mode 100644 index 6fa9b573c3..0000000000 --- a/Tools/CodeTools/TianoTools/SplitFile/build.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/StrGather/StrGather.c b/Tools/CodeTools/TianoTools/StrGather/StrGather.c deleted file mode 100644 index 9eb5c5a19e..0000000000 --- a/Tools/CodeTools/TianoTools/StrGather/StrGather.c +++ /dev/null @@ -1,2531 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - StrGather.c - -Abstract: - - Parse a strings file and create or add to a string database file. - ---*/ - -#include -#include -#include -#include - -#include - -#include "CommonLib.h" -#include "EfiUtilityMsgs.h" -#include "StrGather.h" -#include "StringDB.h" - -#define TOOL_VERSION "0.31" - -#ifndef MAX_PATH -#define MAX_PATH 255 -#endif -#define MAX_NEST_DEPTH 20 // just in case we get in an endless loop. -#define MAX_STRING_IDENTIFIER_NAME 100 // number of wchars -#define MAX_LINE_LEN 200 -#define STRING_TOKEN "STRING_TOKEN" -#define DEFAULT_BASE_NAME "BaseName" -// -// Operational modes for this utility -// -#define MODE_UNKNOWN 0 -#define MODE_PARSE 1 -#define MODE_SCAN 2 -#define MODE_DUMP 3 - -// -// We keep a linked list of these for the source files we process -// -typedef struct _SOURCE_FILE { - FILE *Fptr; - WCHAR *FileBuffer; - WCHAR *FileBufferPtr; - UINT32 FileSize; - CHAR8 FileName[MAX_PATH]; - UINT32 LineNum; - BOOLEAN EndOfFile; - BOOLEAN SkipToHash; - struct _SOURCE_FILE *Previous; - struct _SOURCE_FILE *Next; - WCHAR ControlCharacter; -} SOURCE_FILE; - -#define DEFAULT_CONTROL_CHARACTER UNICODE_SLASH - -// -// Here's all our globals. We need a linked list of include paths, a linked -// list of source files, a linked list of subdirectories (appended to each -// include path when searching), and a couple other fields. -// -static struct { - SOURCE_FILE SourceFiles; - TEXT_STRING_LIST *IncludePaths; // all include paths to search - TEXT_STRING_LIST *LastIncludePath; - TEXT_STRING_LIST *ScanFileName; - TEXT_STRING_LIST *LastScanFileName; - TEXT_STRING_LIST *SkipExt; // if -skipext .uni - TEXT_STRING_LIST *LastSkipExt; - TEXT_STRING_LIST *IndirectionFileName; - TEXT_STRING_LIST *LastIndirectionFileName; - TEXT_STRING_LIST *DatabaseFileName; - TEXT_STRING_LIST *LastDatabaseFileName; - WCHAR_STRING_LIST *Language; - WCHAR_STRING_LIST *LastLanguage; - WCHAR_MATCHING_STRING_LIST *IndirectionList; // from indirection file(s) - WCHAR_MATCHING_STRING_LIST *LastIndirectionList; - BOOLEAN Verbose; // for more detailed output - BOOLEAN VerboseDatabaseWrite; // for more detailed output when writing database - BOOLEAN VerboseDatabaseRead; // for more detailed output when reading database - BOOLEAN NewDatabase; // to start from scratch - BOOLEAN IgnoreNotFound; // when scanning - BOOLEAN VerboseScan; - BOOLEAN UnquotedStrings; // -uqs option - CHAR8 OutputDatabaseFileName[MAX_PATH]; - CHAR8 StringHFileName[MAX_PATH]; - CHAR8 StringCFileName[MAX_PATH]; // output .C filename - CHAR8 DumpUFileName[MAX_PATH]; // output unicode dump file name - CHAR8 HiiExportPackFileName[MAX_PATH]; // HII export pack file name - CHAR8 BaseName[MAX_PATH]; // base filename of the strings file - UINT32 Mode; -} mGlobals; - -static -BOOLEAN -IsValidIdentifierChar ( - CHAR8 Char, - BOOLEAN FirstChar - ); - -static -void -RewindFile ( - SOURCE_FILE *SourceFile - ); - -static -BOOLEAN -SkipTo ( - SOURCE_FILE *SourceFile, - WCHAR WChar, - BOOLEAN StopAfterNewline - ); - -static -UINT32 -SkipWhiteSpace ( - SOURCE_FILE *SourceFile - ); - -static -BOOLEAN -IsWhiteSpace ( - SOURCE_FILE *SourceFile - ); - -static -BOOLEAN -EndOfFile ( - SOURCE_FILE *SourceFile - ); - -static -void -PreprocessFile ( - SOURCE_FILE *SourceFile - ); - -static -UINT32 -GetStringIdentifierName ( - IN SOURCE_FILE *SourceFile, - IN OUT WCHAR *StringIdentifierName, - IN UINT32 StringIdentifierNameLen - ); - -static -UINT32 -GetLanguageIdentifierName ( - IN SOURCE_FILE *SourceFile, - IN OUT WCHAR *LanguageIdentifierName, - IN UINT32 LanguageIdentifierNameLen, - IN BOOLEAN Optional - ); - -static -WCHAR * -GetPrintableLanguageName ( - IN SOURCE_FILE *SourceFile - ); - -static -STATUS -AddCommandLineLanguage ( - IN CHAR8 *Language - ); - -static -WCHAR * -GetQuotedString ( - SOURCE_FILE *SourceFile, - BOOLEAN Optional - ); - -static -STATUS -ProcessIncludeFile ( - SOURCE_FILE *SourceFile, - SOURCE_FILE *ParentSourceFile - ); - -static -STATUS -ParseFile ( - SOURCE_FILE *SourceFile - ); - -static -FILE * -FindFile ( - IN CHAR8 *FileName, - OUT CHAR8 *FoundFileName, - IN UINT32 FoundFileNameLen - ); - -static -STATUS -ProcessArgs ( - int Argc, - char *Argv[] - ); - -static -STATUS -ProcessFile ( - SOURCE_FILE *SourceFile - ); - -static -UINT32 -wstrcmp ( - WCHAR *Buffer, - WCHAR *Str - ); - -static -void -Usage ( - VOID - ); - -static -void -FreeLists ( - VOID - ); - -static -void -ProcessTokenString ( - SOURCE_FILE *SourceFile - ); - -static -void -ProcessTokenInclude ( - SOURCE_FILE *SourceFile - ); - -static -void -ProcessTokenScope ( - SOURCE_FILE *SourceFile - ); - -static -void -ProcessTokenLanguage ( - SOURCE_FILE *SourceFile - ); - -static -void -ProcessTokenLangDef ( - SOURCE_FILE *SourceFile - ); - -static -STATUS -ScanFiles ( - TEXT_STRING_LIST *ScanFiles - ); - -static -STATUS -ParseIndirectionFiles ( - TEXT_STRING_LIST *Files - ); - -STATUS -StringDBCreateHiiExportPack ( - CHAR8 *OutputFileName - ); - -int -main ( - int Argc, - char *Argv[] - ) -/*++ - -Routine Description: - - Call the routine to parse the command-line options, then process the file. - -Arguments: - - Argc - Standard C main() argc and argv. - Argv - Standard C main() argc and argv. - -Returns: - - 0 if successful - nonzero otherwise - ---*/ -{ - STATUS Status; - - SetUtilityName (PROGRAM_NAME); - // - // Process the command-line arguments - // - Status = ProcessArgs (Argc, Argv); - if (Status != STATUS_SUCCESS) { - return Status; - } - // - // Initialize the database manager - // - StringDBConstructor (); - // - // We always try to read in an existing database file. It may not - // exist, which is ok usually. - // - if (mGlobals.NewDatabase == 0) { - // - // Read all databases specified. - // - for (mGlobals.LastDatabaseFileName = mGlobals.DatabaseFileName; - mGlobals.LastDatabaseFileName != NULL; - mGlobals.LastDatabaseFileName = mGlobals.LastDatabaseFileName->Next - ) { - Status = StringDBReadDatabase (mGlobals.LastDatabaseFileName->Str, TRUE, mGlobals.VerboseDatabaseRead); - if (Status != STATUS_SUCCESS) { - return Status; - } - } - } - // - // Read indirection file(s) if specified - // - if (ParseIndirectionFiles (mGlobals.IndirectionFileName) != STATUS_SUCCESS) { - goto Finish; - } - // - // If scanning source files, do that now - // - if (mGlobals.Mode == MODE_SCAN) { - ScanFiles (mGlobals.ScanFileName); - } else if (mGlobals.Mode == MODE_PARSE) { - // - // Parsing a unicode strings file - // - mGlobals.SourceFiles.ControlCharacter = DEFAULT_CONTROL_CHARACTER; - Status = ProcessIncludeFile (&mGlobals.SourceFiles, NULL); - if (Status != STATUS_SUCCESS) { - goto Finish; - } - } - // - // Create the string defines header file if there have been no errors. - // - ParserSetPosition (NULL, 0); - if ((mGlobals.StringHFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) { - Status = StringDBDumpStringDefines (mGlobals.StringHFileName, mGlobals.BaseName); - if (Status != EFI_SUCCESS) { - goto Finish; - } - } - // - // Dump the strings to a .c file if there have still been no errors. - // - if ((mGlobals.StringCFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) { - Status = StringDBDumpCStrings ( - mGlobals.StringCFileName, - mGlobals.BaseName, - mGlobals.Language, - mGlobals.IndirectionList - ); - if (Status != EFI_SUCCESS) { - goto Finish; - } - } - // - // Dump the database if requested - // - if ((mGlobals.DumpUFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) { - StringDBDumpDatabase (NULL, mGlobals.DumpUFileName, FALSE); - } - // - // Dump the string data as HII binary string pack if requested - // - if ((mGlobals.HiiExportPackFileName[0] != 0) && (GetUtilityStatus () < STATUS_ERROR)) { - StringDBCreateHiiExportPack (mGlobals.HiiExportPackFileName); - } - // - // Always update the database if no errors and not in dump mode. If they specified -od - // for an output database file name, then use that name. Otherwise use the name of - // the first database file specified with -db - // - if ((mGlobals.Mode != MODE_DUMP) && (GetUtilityStatus () < STATUS_ERROR)) { - if (mGlobals.OutputDatabaseFileName[0]) { - Status = StringDBWriteDatabase (mGlobals.OutputDatabaseFileName, mGlobals.VerboseDatabaseWrite); - } else { - Status = StringDBWriteDatabase (mGlobals.DatabaseFileName->Str, mGlobals.VerboseDatabaseWrite); - } - - if (Status != EFI_SUCCESS) { - goto Finish; - } - } - -Finish: - // - // Free up memory - // - FreeLists (); - StringDBDestructor (); - return GetUtilityStatus (); -} - -static -STATUS -ProcessIncludeFile ( - SOURCE_FILE *SourceFile, - SOURCE_FILE *ParentSourceFile - ) -/*++ - -Routine Description: - - Given a source file, open the file and parse it - -Arguments: - - SourceFile - name of file to parse - ParentSourceFile - for error reporting purposes, the file that #included SourceFile. - -Returns: - - Standard status. - ---*/ -{ - static UINT32 NestDepth = 0; - CHAR8 FoundFileName[MAX_PATH]; - STATUS Status; - - Status = STATUS_SUCCESS; - NestDepth++; - // - // Print the file being processed. Indent so you can tell the include nesting - // depth. - // - if (mGlobals.Verbose) { - fprintf (stdout, "%*cProcessing file '%s'\n", NestDepth * 2, ' ', SourceFile->FileName); - } - - // - // Make sure we didn't exceed our maximum nesting depth - // - if (NestDepth > MAX_NEST_DEPTH) { - Error (NULL, 0, 0, SourceFile->FileName, "max nesting depth (%d) exceeded", NestDepth); - Status = STATUS_ERROR; - goto Finish; - } - // - // Try to open the file locally, and if that fails try along our include paths. - // - strcpy (FoundFileName, SourceFile->FileName); - if ((SourceFile->Fptr = fopen (FoundFileName, "rb")) == NULL) { - // - // Try to find it among the paths if it has a parent (that is, it is included - // by someone else). - // - if (ParentSourceFile == NULL) { - Error (NULL, 0, 0, SourceFile->FileName, "file not found"); - return STATUS_ERROR; - } - - SourceFile->Fptr = FindFile (SourceFile->FileName, FoundFileName, sizeof (FoundFileName)); - if (SourceFile->Fptr == NULL) { - Error (ParentSourceFile->FileName, ParentSourceFile->LineNum, 0, SourceFile->FileName, "include file not found"); - return STATUS_ERROR; - } - } - // - // Process the file found - // - ProcessFile (SourceFile); -Finish: - // - // Close open files and return status - // - if (SourceFile->Fptr != NULL) { - fclose (SourceFile->Fptr); - } - - return Status; -} - -static -STATUS -ProcessFile ( - SOURCE_FILE *SourceFile - ) -{ - // - // Get the file size, and then read the entire thing into memory. - // Allocate space for a terminator character. - // - fseek (SourceFile->Fptr, 0, SEEK_END); - SourceFile->FileSize = ftell (SourceFile->Fptr); - fseek (SourceFile->Fptr, 0, SEEK_SET); - SourceFile->FileBuffer = (WCHAR *) malloc (SourceFile->FileSize + sizeof (WCHAR)); - if (SourceFile->FileBuffer == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - fread ((VOID *) SourceFile->FileBuffer, SourceFile->FileSize, 1, SourceFile->Fptr); - SourceFile->FileBuffer[(SourceFile->FileSize / sizeof (WCHAR))] = UNICODE_NULL; - // - // Pre-process the file to replace comments with spaces - // - PreprocessFile (SourceFile); - // - // Parse the file - // - ParseFile (SourceFile); - free (SourceFile->FileBuffer); - return STATUS_SUCCESS; -} - -static -STATUS -ParseFile ( - SOURCE_FILE *SourceFile - ) -{ - BOOLEAN InComment; - UINT32 Len; - - // - // First character of a unicode file is special. Make sure - // - if (SourceFile->FileBufferPtr[0] != UNICODE_FILE_START) { - Error (SourceFile->FileName, 1, 0, SourceFile->FileName, "file does not appear to be a unicode file"); - return STATUS_ERROR; - } - - SourceFile->FileBufferPtr++; - InComment = FALSE; - // - // Print the first line if in verbose mode - // - if (mGlobals.Verbose) { - printf ("%d: %S\n", SourceFile->LineNum, SourceFile->FileBufferPtr); - } - // - // Since the syntax is relatively straightforward, just switch on the next char - // - while (!EndOfFile (SourceFile)) { - // - // Check for whitespace - // - if (SourceFile->FileBufferPtr[0] == UNICODE_SPACE) { - SourceFile->FileBufferPtr++; - } else if (SourceFile->FileBufferPtr[0] == UNICODE_TAB) { - SourceFile->FileBufferPtr++; - } else if (SourceFile->FileBufferPtr[0] == UNICODE_CR) { - SourceFile->FileBufferPtr++; - } else if (SourceFile->FileBufferPtr[0] == UNICODE_LF) { - SourceFile->FileBufferPtr++; - SourceFile->LineNum++; - if (mGlobals.Verbose) { - printf ("%d: %S\n", SourceFile->LineNum, SourceFile->FileBufferPtr); - } - - InComment = FALSE; - } else if (SourceFile->FileBufferPtr[0] == 0) { - SourceFile->FileBufferPtr++; - } else if (InComment) { - SourceFile->FileBufferPtr++; - } else if ((SourceFile->FileBufferPtr[0] == UNICODE_SLASH) && (SourceFile->FileBufferPtr[1] == UNICODE_SLASH)) { - SourceFile->FileBufferPtr += 2; - InComment = TRUE; - } else if (SourceFile->SkipToHash && (SourceFile->FileBufferPtr[0] != SourceFile->ControlCharacter)) { - SourceFile->FileBufferPtr++; - } else { - SourceFile->SkipToHash = FALSE; - if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && - ((Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"include")) > 0) - ) { - SourceFile->FileBufferPtr += Len + 1; - ProcessTokenInclude (SourceFile); - } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && - (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"scope")) > 0 - ) { - SourceFile->FileBufferPtr += Len + 1; - ProcessTokenScope (SourceFile); - } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && - (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"language")) > 0 - ) { - SourceFile->FileBufferPtr += Len + 1; - ProcessTokenLanguage (SourceFile); - } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && - (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"langdef")) > 0 - ) { - SourceFile->FileBufferPtr += Len + 1; - ProcessTokenLangDef (SourceFile); - } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && - (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"string")) > 0 - ) { - SourceFile->FileBufferPtr += Len + 1; - ProcessTokenString (SourceFile); - } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && - (Len = wstrcmp (SourceFile->FileBufferPtr + 1, L"EFI_BREAKPOINT()")) > 0 - ) { - SourceFile->FileBufferPtr += Len; - // - // BUGBUG: Caling EFI_BREAKOINT() is breaking the link. What is the proper action for this tool - // in this condition? - // -// EFI_BREAKPOINT (); - } else if ((SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter) && - (SourceFile->FileBufferPtr[1] == UNICODE_EQUAL_SIGN) - ) { - SourceFile->ControlCharacter = SourceFile->FileBufferPtr[2]; - SourceFile->FileBufferPtr += 3; - } else { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "unrecognized token", "%S", SourceFile->FileBufferPtr); - // - // Treat rest of line as a comment. - // - InComment = TRUE; - } - } - } - - return STATUS_SUCCESS; -} - -static -void -PreprocessFile ( - SOURCE_FILE *SourceFile - ) -/*++ - -Routine Description: - Preprocess a file to replace all carriage returns with NULLs so - we can print lines from the file to the screen. - -Arguments: - SourceFile - structure that we use to keep track of an input file. - -Returns: - Nothing. - ---*/ -{ - BOOLEAN InComment; - - RewindFile (SourceFile); - InComment = FALSE; - while (!EndOfFile (SourceFile)) { - // - // If a line-feed, then no longer in a comment - // - if (SourceFile->FileBufferPtr[0] == UNICODE_LF) { - SourceFile->FileBufferPtr++; - SourceFile->LineNum++; - InComment = 0; - } else if (SourceFile->FileBufferPtr[0] == UNICODE_CR) { - // - // Replace all carriage returns with a NULL so we can print stuff - // - SourceFile->FileBufferPtr[0] = 0; - SourceFile->FileBufferPtr++; - } else if (InComment) { - SourceFile->FileBufferPtr[0] = UNICODE_SPACE; - SourceFile->FileBufferPtr++; - } else if ((SourceFile->FileBufferPtr[0] == UNICODE_SLASH) && (SourceFile->FileBufferPtr[1] == UNICODE_SLASH)) { - SourceFile->FileBufferPtr += 2; - InComment = TRUE; - } else { - SourceFile->FileBufferPtr++; - } - } - // - // Could check for end-of-file and still in a comment, but - // should not be necessary. So just restore the file pointers. - // - RewindFile (SourceFile); -} - -static -WCHAR * -GetPrintableLanguageName ( - IN SOURCE_FILE *SourceFile - ) -{ - WCHAR *String; - WCHAR *Start; - WCHAR *Ptr; - UINT32 Len; - - SkipWhiteSpace (SourceFile); - if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - "expected quoted printable language name", - "%S", - SourceFile->FileBufferPtr - ); - SourceFile->SkipToHash = TRUE; - return NULL; - } - - Len = 0; - SourceFile->FileBufferPtr++; - Start = Ptr = SourceFile->FileBufferPtr; - while (!EndOfFile (SourceFile)) { - if (SourceFile->FileBufferPtr[0] == UNICODE_CR) { - Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start); - break; - } else if (SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) { - break; - } - - SourceFile->FileBufferPtr++; - Len++; - } - - if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) { - Warning ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - "missing closing quote on printable language name string", - "%S", - Start - ); - } else { - SourceFile->FileBufferPtr++; - } - // - // Now allocate memory for the string and save it off - // - String = (WCHAR *) malloc ((Len + 1) * sizeof (WCHAR)); - if (String == NULL) { - Error (NULL, 0, 0, "memory allocation failed", NULL); - return NULL; - } - // - // Copy the string from the file buffer to the local copy. - // We do no reformatting of it whatsoever at this point. - // - Ptr = String; - while (Len > 0) { - *Ptr = *Start; - Start++; - Ptr++; - Len--; - } - - *Ptr = 0; - // - // Now format the string to convert \wide and \narrow controls - // - StringDBFormatString (String); - return String; -} - -static -WCHAR * -GetQuotedString ( - SOURCE_FILE *SourceFile, - BOOLEAN Optional - ) -{ - WCHAR *String; - WCHAR *Start; - WCHAR *Ptr; - UINT32 Len; - BOOLEAN PreviousBackslash; - - if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) { - if (!Optional) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted string", "%S", SourceFile->FileBufferPtr); - } - - return NULL; - } - - Len = 0; - SourceFile->FileBufferPtr++; - Start = Ptr = SourceFile->FileBufferPtr; - PreviousBackslash = FALSE; - while (!EndOfFile (SourceFile)) { - if ((SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) && (!PreviousBackslash)) { - break; - } else if (SourceFile->FileBufferPtr[0] == UNICODE_CR) { - Warning (SourceFile->FileName, SourceFile->LineNum, 0, "carriage return found in quoted string", "%S", Start); - PreviousBackslash = FALSE; - } else if (SourceFile->FileBufferPtr[0] == UNICODE_BACKSLASH) { - PreviousBackslash = TRUE; - } else { - PreviousBackslash = FALSE; - } - - SourceFile->FileBufferPtr++; - Len++; - } - - if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) { - Warning (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing quote on string", "%S", Start); - } else { - SourceFile->FileBufferPtr++; - } - // - // Now allocate memory for the string and save it off - // - String = (WCHAR *) malloc ((Len + 1) * sizeof (WCHAR)); - if (String == NULL) { - Error (NULL, 0, 0, "memory allocation failed", NULL); - return NULL; - } - // - // Copy the string from the file buffer to the local copy. - // We do no reformatting of it whatsoever at this point. - // - Ptr = String; - while (Len > 0) { - *Ptr = *Start; - Start++; - Ptr++; - Len--; - } - - *Ptr = 0; - return String; -} -// -// Parse: -// #string STR_ID_NAME -// -// All we can do is call the string database to add the string identifier. Unfortunately -// he'll have to keep track of the last identifier we added. -// -static -void -ProcessTokenString ( - SOURCE_FILE *SourceFile - ) -{ - WCHAR StringIdentifier[MAX_STRING_IDENTIFIER_NAME]; - UINT16 StringId; - // - // Extract the string identifier name and add it to the database. - // - if (GetStringIdentifierName (SourceFile, StringIdentifier, sizeof (StringIdentifier)) > 0) { - StringId = STRING_ID_INVALID; - StringDBAddStringIdentifier (StringIdentifier, &StringId, 0); - } else { - // - // Error recovery -- skip to the next # - // - SourceFile->SkipToHash = TRUE; - } -} - -static -BOOLEAN -EndOfFile ( - SOURCE_FILE *SourceFile - ) -{ - // - // The file buffer pointer will typically get updated before the End-of-file flag in the - // source file structure, so check it first. - // - if (SourceFile->FileBufferPtr >= SourceFile->FileBuffer + SourceFile->FileSize / sizeof (WCHAR)) { - SourceFile->EndOfFile = TRUE; - return TRUE; - } - - if (SourceFile->EndOfFile) { - return TRUE; - } - - return FALSE; -} - -static -UINT32 -GetStringIdentifierName ( - IN SOURCE_FILE *SourceFile, - IN OUT WCHAR *StringIdentifierName, - IN UINT32 StringIdentifierNameLen - ) -{ - UINT32 Len; - WCHAR *From; - WCHAR *Start; - - // - // Skip whitespace - // - SkipWhiteSpace (SourceFile); - if (SourceFile->EndOfFile) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-file encountered", "expected string identifier"); - return 0; - } - // - // Verify first character of name is [A-Za-z] - // - Len = 0; - StringIdentifierNameLen /= 2; - From = SourceFile->FileBufferPtr; - Start = SourceFile->FileBufferPtr; - if (((SourceFile->FileBufferPtr[0] >= UNICODE_A) && (SourceFile->FileBufferPtr[0] <= UNICODE_Z)) || - ((SourceFile->FileBufferPtr[0] >= UNICODE_z) && (SourceFile->FileBufferPtr[0] <= UNICODE_z)) - ) { - // - // Do nothing - // - } else { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid character in string identifier name", "%S", Start); - return 0; - } - - while (!EndOfFile (SourceFile)) { - if (((SourceFile->FileBufferPtr[0] >= UNICODE_A) && (SourceFile->FileBufferPtr[0] <= UNICODE_Z)) || - ((SourceFile->FileBufferPtr[0] >= UNICODE_z) && (SourceFile->FileBufferPtr[0] <= UNICODE_z)) || - ((SourceFile->FileBufferPtr[0] >= UNICODE_0) && (SourceFile->FileBufferPtr[0] <= UNICODE_9)) || - (SourceFile->FileBufferPtr[0] == UNICODE_UNDERSCORE) - ) { - Len++; - if (Len >= StringIdentifierNameLen) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "string identifier name too long", "%S", Start); - return 0; - } - - *StringIdentifierName = SourceFile->FileBufferPtr[0]; - StringIdentifierName++; - SourceFile->FileBufferPtr++; - } else if (SkipWhiteSpace (SourceFile) == 0) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid string identifier name", "%S", Start); - return 0; - } else { - break; - } - } - // - // Terminate the copy of the string. - // - *StringIdentifierName = 0; - return Len; -} - -static -UINT32 -GetLanguageIdentifierName ( - IN SOURCE_FILE *SourceFile, - IN OUT WCHAR *LanguageIdentifierName, - IN UINT32 LanguageIdentifierNameLen, - IN BOOLEAN Optional - ) -{ - UINT32 Len; - WCHAR *From; - WCHAR *Start; - // - // Skip whitespace - // - SkipWhiteSpace (SourceFile); - if (SourceFile->EndOfFile) { - if (!Optional) { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - "end-of-file encountered", - "expected language identifier" - ); - } - - return 0; - } - // - // This function is called to optionally get a language identifier name in: - // #string STR_ID eng "the string" - // If it's optional, and we find a double-quote, then return now. - // - if (Optional) { - if (*SourceFile->FileBufferPtr == UNICODE_DOUBLE_QUOTE) { - return 0; - } - } - - Len = 0; - LanguageIdentifierNameLen /= 2; - // - // Internal error if we weren't given at least 4 WCHAR's to work with. - // - if (LanguageIdentifierNameLen < LANGUAGE_IDENTIFIER_NAME_LEN + 1) { - Error ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - "app error -- language identifier name length is invalid", - NULL - ); - } - - From = SourceFile->FileBufferPtr; - Start = SourceFile->FileBufferPtr; - while (!EndOfFile (SourceFile)) { - if (((SourceFile->FileBufferPtr[0] >= UNICODE_a) && (SourceFile->FileBufferPtr[0] <= UNICODE_z))) { - Len++; - if (Len > LANGUAGE_IDENTIFIER_NAME_LEN) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "language identifier name too long", "%S", Start); - return 0; - } - - *LanguageIdentifierName = SourceFile->FileBufferPtr[0]; - SourceFile->FileBufferPtr++; - LanguageIdentifierName++; - } else if (!IsWhiteSpace (SourceFile)) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid language identifier name", "%S", Start); - return 0; - } else { - break; - } - } - // - // Terminate the copy of the string. - // - *LanguageIdentifierName = 0; - return Len; -} - -static -void -ProcessTokenInclude ( - SOURCE_FILE *SourceFile - ) -{ - CHAR8 IncludeFileName[MAX_PATH]; - CHAR8 *To; - UINT32 Len; - BOOLEAN ReportedError; - SOURCE_FILE IncludedSourceFile; - - ReportedError = FALSE; - if (SkipWhiteSpace (SourceFile) == 0) { - Warning (SourceFile->FileName, SourceFile->LineNum, 0, "expected whitespace following #include keyword", NULL); - } - // - // Should be quoted file name - // - if (SourceFile->FileBufferPtr[0] != UNICODE_DOUBLE_QUOTE) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "expected quoted include file name", NULL); - goto FailDone; - } - - SourceFile->FileBufferPtr++; - // - // Copy the filename as ascii to our local string - // - To = IncludeFileName; - Len = 0; - while (!EndOfFile (SourceFile)) { - if ((SourceFile->FileBufferPtr[0] == UNICODE_CR) || (SourceFile->FileBufferPtr[0] == UNICODE_LF)) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "end-of-line found in quoted include file name", NULL); - goto FailDone; - } - - if (SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) { - SourceFile->FileBufferPtr++; - break; - } - // - // If too long, then report the error once and process until the closing quote - // - Len++; - if (!ReportedError && (Len >= sizeof (IncludeFileName))) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "length of include file name exceeds limit", NULL); - ReportedError = TRUE; - } - - if (!ReportedError) { - *To = UNICODE_TO_ASCII (SourceFile->FileBufferPtr[0]); - To++; - } - - SourceFile->FileBufferPtr++; - } - - if (!ReportedError) { - *To = 0; - memset ((char *) &IncludedSourceFile, 0, sizeof (SOURCE_FILE)); - strcpy (IncludedSourceFile.FileName, IncludeFileName); - IncludedSourceFile.ControlCharacter = DEFAULT_CONTROL_CHARACTER; - ProcessIncludeFile (&IncludedSourceFile, SourceFile); - // - // printf ("including file '%s'\n", IncludeFileName); - // - } - - return ; -FailDone: - // - // Error recovery -- skip to next # - // - SourceFile->SkipToHash = TRUE; -} - -static -void -ProcessTokenScope ( - SOURCE_FILE *SourceFile - ) -{ - WCHAR StringIdentifier[MAX_STRING_IDENTIFIER_NAME]; - // - // Extract the scope name - // - if (GetStringIdentifierName (SourceFile, StringIdentifier, sizeof (StringIdentifier)) > 0) { - StringDBSetScope (StringIdentifier); - } -} -// -// Parse: #langdef eng "English" -// #langdef chn "\wideChinese" -// -static -void -ProcessTokenLangDef ( - SOURCE_FILE *SourceFile - ) -{ - WCHAR LanguageIdentifier[MAX_STRING_IDENTIFIER_NAME]; - UINT32 Len; - WCHAR *PrintableName; - // - // Extract the 3-character language identifier - // - Len = GetLanguageIdentifierName (SourceFile, LanguageIdentifier, sizeof (LanguageIdentifier), FALSE); - if (Len != LANGUAGE_IDENTIFIER_NAME_LEN) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid or missing language identifier", NULL); - } else { - // - // Extract the printable name - // - PrintableName = GetPrintableLanguageName (SourceFile); - if (PrintableName != NULL) { - ParserSetPosition (SourceFile->FileName, SourceFile->LineNum); - StringDBAddLanguage (LanguageIdentifier, PrintableName); - free (PrintableName); - return ; - } - } - // - // Error recovery -- skip to next # - // - SourceFile->SkipToHash = TRUE; -} - -static -BOOLEAN -ApparentQuotedString ( - SOURCE_FILE *SourceFile - ) -{ - WCHAR *Ptr; - // - // See if the first and last nonblank characters on the line are double quotes - // - for (Ptr = SourceFile->FileBufferPtr; *Ptr && (*Ptr == UNICODE_SPACE); Ptr++) - ; - if (*Ptr != UNICODE_DOUBLE_QUOTE) { - return FALSE; - } - - while (*Ptr) { - Ptr++; - } - - Ptr--; - for (; *Ptr && (*Ptr == UNICODE_SPACE); Ptr--) - ; - if (*Ptr != UNICODE_DOUBLE_QUOTE) { - return FALSE; - } - - return TRUE; -} -// -// Parse: -// #language eng "some string " "more string" -// -static -void -ProcessTokenLanguage ( - SOURCE_FILE *SourceFile - ) -{ - WCHAR *String; - WCHAR *SecondString; - WCHAR *TempString; - WCHAR *From; - WCHAR *To; - WCHAR Language[LANGUAGE_IDENTIFIER_NAME_LEN + 1]; - UINT32 Len; - BOOLEAN PreviousNewline; - // - // Get the language identifier - // - Language[0] = 0; - Len = GetLanguageIdentifierName (SourceFile, Language, sizeof (Language), TRUE); - if (Len != LANGUAGE_IDENTIFIER_NAME_LEN) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid or missing language identifier", "%S", Language); - SourceFile->SkipToHash = TRUE; - return ; - } - // - // Extract the string value. It's either a quoted string that starts on the current line, or - // an unquoted string that starts on the following line and continues until the next control - // character in column 1. - // Look ahead to find a quote or a newline - // - if (SkipTo (SourceFile, UNICODE_DOUBLE_QUOTE, TRUE)) { - String = GetQuotedString (SourceFile, FALSE); - if (String != NULL) { - // - // Set the position in the file of where we are parsing for error - // reporting purposes. Then start looking ahead for additional - // quoted strings, and concatenate them until we get a failure - // back from the string parser. - // - Len = StrLen (String) + 1; - ParserSetPosition (SourceFile->FileName, SourceFile->LineNum); - do { - SkipWhiteSpace (SourceFile); - SecondString = GetQuotedString (SourceFile, TRUE); - if (SecondString != NULL) { - Len += StrLen (SecondString); - TempString = (WCHAR *) malloc (Len * sizeof (WCHAR)); - if (TempString == NULL) { - Error (NULL, 0, 0, "application error", "failed to allocate memory"); - return ; - } - - StrCpy (TempString, String); - StrCat (TempString, SecondString); - free (String); - free (SecondString); - String = TempString; - } - } while (SecondString != NULL); - StringDBAddString (Language, NULL, NULL, String, TRUE, 0); - free (String); - } else { - // - // Error was reported at lower level. Error recovery mode. - // - SourceFile->SkipToHash = TRUE; - } - } else { - if (!mGlobals.UnquotedStrings) { - // - // They're using unquoted strings. If the next non-blank character is a double quote, and the - // last non-blank character on the line is a double quote, then more than likely they're using - // quotes, so they need to put the quoted string on the end of the previous line - // - if (ApparentQuotedString (SourceFile)) { - Warning ( - SourceFile->FileName, - SourceFile->LineNum, - 0, - "unexpected quoted string on line", - "specify -uqs option if necessary" - ); - } - } - // - // Found end-of-line (hopefully). Skip over it and start taking in characters - // until we find a control character at the start of a line. - // - Len = 0; - From = SourceFile->FileBufferPtr; - PreviousNewline = FALSE; - while (!EndOfFile (SourceFile)) { - if (SourceFile->FileBufferPtr[0] == UNICODE_LF) { - PreviousNewline = TRUE; - SourceFile->LineNum++; - } else { - Len++; - if (PreviousNewline && (SourceFile->FileBufferPtr[0] == SourceFile->ControlCharacter)) { - break; - } - - PreviousNewline = FALSE; - } - - SourceFile->FileBufferPtr++; - } - - if ((Len == 0) && EndOfFile (SourceFile)) { - Error (SourceFile->FileName, SourceFile->LineNum, 0, "unexpected end of file", NULL); - SourceFile->SkipToHash = TRUE; - return ; - } - // - // Now allocate a buffer, copy the characters, and add the string. - // - String = (WCHAR *) malloc ((Len + 1) * sizeof (WCHAR)); - if (String == NULL) { - Error (NULL, 0, 0, "application error", "failed to allocate memory"); - return ; - } - - To = String; - while (From < SourceFile->FileBufferPtr) { - switch (*From) { - case UNICODE_LF: - case 0: - break; - - default: - *To = *From; - To++; - break; - } - - From++; - } - - // - // String[Len] = 0; - // - *To = 0; - StringDBAddString (Language, NULL, NULL, String, TRUE, 0); - } -} - -static -BOOLEAN -IsWhiteSpace ( - SOURCE_FILE *SourceFile - ) -{ - switch (SourceFile->FileBufferPtr[0]) { - case UNICODE_NULL: - case UNICODE_CR: - case UNICODE_SPACE: - case UNICODE_TAB: - case UNICODE_LF: - return TRUE; - - default: - return FALSE; - } -} - -static -UINT32 -SkipWhiteSpace ( - SOURCE_FILE *SourceFile - ) -{ - UINT32 Count; - - Count = 0; - while (!EndOfFile (SourceFile)) { - Count++; - switch (*SourceFile->FileBufferPtr) { - case UNICODE_NULL: - case UNICODE_CR: - case UNICODE_SPACE: - case UNICODE_TAB: - SourceFile->FileBufferPtr++; - break; - - case UNICODE_LF: - SourceFile->FileBufferPtr++; - SourceFile->LineNum++; - if (mGlobals.Verbose) { - printf ("%d: %S\n", SourceFile->LineNum, SourceFile->FileBufferPtr); - } - break; - - default: - return Count - 1; - } - } - // - // Some tokens require trailing whitespace. If we're at the end of the - // file, then we count that as well. - // - if ((Count == 0) && (EndOfFile (SourceFile))) { - Count++; - } - - return Count; -} - -static -UINT32 -wstrcmp ( - WCHAR *Buffer, - WCHAR *Str - ) -{ - UINT32 Len; - - Len = 0; - while (*Str == *Buffer) { - Buffer++; - Str++; - Len++; - } - - if (*Str) { - return 0; - } - - return Len; -} -// -// Given a filename, try to find it along the include paths. -// -static -FILE * -FindFile ( - IN CHAR8 *FileName, - OUT CHAR8 *FoundFileName, - IN UINT32 FoundFileNameLen - ) -{ - FILE *Fptr; - TEXT_STRING_LIST *List; - - // - // Traverse the list of paths and try to find the file - // - List = mGlobals.IncludePaths; - while (List != NULL) { - // - // Put the path and filename together - // - if (strlen (List->Str) + strlen (FileName) + 1 > FoundFileNameLen) { - Error (PROGRAM_NAME, 0, 0, NULL, "internal error - cannot concatenate path+filename"); - return NULL; - } - // - // Append the filename to this include path and try to open the file. - // - strcpy (FoundFileName, List->Str); - strcat (FoundFileName, FileName); - if ((Fptr = fopen (FoundFileName, "rb")) != NULL) { - // - // Return the file pointer - // - return Fptr; - } - - List = List->Next; - } - // - // Not found - // - FoundFileName[0] = 0; - return NULL; -} -// -// Process the command-line arguments -// -static -STATUS -ProcessArgs ( - int Argc, - char *Argv[] - ) -{ - TEXT_STRING_LIST *NewList; - // - // Clear our globals - // - memset ((char *) &mGlobals, 0, sizeof (mGlobals)); - strcpy (mGlobals.BaseName, DEFAULT_BASE_NAME); - // - // Skip program name - // - Argc--; - Argv++; - - if (Argc == 0) { - Usage (); - return STATUS_ERROR; - } - - mGlobals.Mode = MODE_UNKNOWN; - // - // Process until no more -args. - // - while ((Argc > 0) && (Argv[0][0] == '-')) { - // - // -parse option - // - if (stricmp (Argv[0], "-parse") == 0) { - if (mGlobals.Mode != MODE_UNKNOWN) { - Error (NULL, 0, 0, "only one of -parse/-scan/-dump allowed", NULL); - return STATUS_ERROR; - } - - mGlobals.Mode = MODE_PARSE; - // - // -scan option - // - } else if (stricmp (Argv[0], "-scan") == 0) { - if (mGlobals.Mode != MODE_UNKNOWN) { - Error (NULL, 0, 0, "only one of -parse/-scan/-dump allowed", NULL); - return STATUS_ERROR; - } - - mGlobals.Mode = MODE_SCAN; - // - // -vscan verbose scanning option - // - } else if (stricmp (Argv[0], "-vscan") == 0) { - mGlobals.VerboseScan = TRUE; - // - // -dump option - // - } else if (stricmp (Argv[0], "-dump") == 0) { - if (mGlobals.Mode != MODE_UNKNOWN) { - Error (NULL, 0, 0, "only one of -parse/-scan/-dump allowed", NULL); - return STATUS_ERROR; - } - - mGlobals.Mode = MODE_DUMP; - } else if (stricmp (Argv[0], "-uqs") == 0) { - mGlobals.UnquotedStrings = TRUE; - // - // -i path add include search path when parsing - // - } else if (stricmp (Argv[0], "-i") == 0) { - // - // check for one more arg - // - if ((Argc <= 1) || (Argv[1][0] == '-')) { - Error (PROGRAM_NAME, 0, 0, Argv[0], "missing include path"); - return STATUS_ERROR; - } - // - // Allocate memory for a new list element, fill it in, and - // add it to our list of include paths. Always make sure it - // has a "\" on the end of it. - // - NewList = malloc (sizeof (TEXT_STRING_LIST)); - if (NewList == NULL) { - Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); - return STATUS_ERROR; - } - - memset ((char *) NewList, 0, sizeof (TEXT_STRING_LIST)); - NewList->Str = malloc (strlen (Argv[1]) + 2); - if (NewList->Str == NULL) { - free (NewList); - Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); - return STATUS_ERROR; - } - - strcpy (NewList->Str, Argv[1]); - if (NewList->Str[strlen (NewList->Str) - 1] != '\\') { - strcat (NewList->Str, "\\"); - } - // - // Add it to our linked list - // - if (mGlobals.IncludePaths == NULL) { - mGlobals.IncludePaths = NewList; - } else { - mGlobals.LastIncludePath->Next = NewList; - } - - mGlobals.LastIncludePath = NewList; - Argc--; - Argv++; - } else if (stricmp (Argv[0], "-if") == 0) { - // - // Indirection file -- check for one more arg - // - if ((Argc <= 1) || (Argv[1][0] == '-')) { - Error (PROGRAM_NAME, 0, 0, Argv[0], "missing indirection file name"); - return STATUS_ERROR; - } - // - // Allocate memory for a new list element, fill it in, and - // add it to our list of include paths. Always make sure it - // has a "\" on the end of it. - // - NewList = malloc (sizeof (TEXT_STRING_LIST)); - if (NewList == NULL) { - Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); - return STATUS_ERROR; - } - - memset ((char *) NewList, 0, sizeof (TEXT_STRING_LIST)); - NewList->Str = malloc (strlen (Argv[1]) + 1); - if (NewList->Str == NULL) { - free (NewList); - Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); - return STATUS_ERROR; - } - - strcpy (NewList->Str, Argv[1]); - // - // Add it to our linked list - // - if (mGlobals.IndirectionFileName == NULL) { - mGlobals.IndirectionFileName = NewList; - } else { - mGlobals.LastIndirectionFileName->Next = NewList; - } - - mGlobals.LastIndirectionFileName = NewList; - Argc--; - Argv++; - } else if (stricmp (Argv[0], "-db") == 0) { - // - // -db option to specify a database file. - // Check for one more arg (the database file name) - // - if ((Argc <= 1) || (Argv[1][0] == '-')) { - Error (PROGRAM_NAME, 0, 0, Argv[0], "missing database file name"); - return STATUS_ERROR; - } - - NewList = malloc (sizeof (TEXT_STRING_LIST)); - if (NewList == NULL) { - Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); - return STATUS_ERROR; - } - - memset ((char *) NewList, 0, sizeof (TEXT_STRING_LIST)); - NewList->Str = malloc (strlen (Argv[1]) + 1); - if (NewList->Str == NULL) { - free (NewList); - Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); - return STATUS_ERROR; - } - - strcpy (NewList->Str, Argv[1]); - // - // Add it to our linked list - // - if (mGlobals.DatabaseFileName == NULL) { - mGlobals.DatabaseFileName = NewList; - } else { - mGlobals.LastDatabaseFileName->Next = NewList; - } - - mGlobals.LastDatabaseFileName = NewList; - Argc--; - Argv++; - } else if (stricmp (Argv[0], "-ou") == 0) { - // - // -ou option to specify an output unicode file to - // which we can dump our database. - // - if ((Argc <= 1) || (Argv[1][0] == '-')) { - Error (PROGRAM_NAME, 0, 0, Argv[0], "missing database dump output file name"); - return STATUS_ERROR; - } - - if (mGlobals.DumpUFileName[0] == 0) { - strcpy (mGlobals.DumpUFileName, Argv[1]); - } else { - Error (PROGRAM_NAME, 0, 0, Argv[1], "-ou option already specified with '%s'", mGlobals.DumpUFileName); - return STATUS_ERROR; - } - - Argc--; - Argv++; - } else if (stricmp (Argv[0], "-hpk") == 0) { - // - // -hpk option to create an HII export pack of the input database file - // - if ((Argc <= 1) || (Argv[1][0] == '-')) { - Error (PROGRAM_NAME, 0, 0, Argv[0], "missing raw string data dump output file name"); - return STATUS_ERROR; - } - - if (mGlobals.HiiExportPackFileName[0] == 0) { - strcpy (mGlobals.HiiExportPackFileName, Argv[1]); - } else { - Error (PROGRAM_NAME, 0, 0, Argv[1], "-or option already specified with '%s'", mGlobals.HiiExportPackFileName); - return STATUS_ERROR; - } - - Argc--; - Argv++; - } else if ((stricmp (Argv[0], "-?") == 0) || (stricmp (Argv[0], "-h") == 0)) { - Usage (); - return STATUS_ERROR; - } else if (stricmp (Argv[0], "-v") == 0) { - mGlobals.Verbose = 1; - } else if (stricmp (Argv[0], "-vdbw") == 0) { - mGlobals.VerboseDatabaseWrite = 1; - } else if (stricmp (Argv[0], "-vdbr") == 0) { - mGlobals.VerboseDatabaseRead = 1; - } else if (stricmp (Argv[0], "-newdb") == 0) { - mGlobals.NewDatabase = 1; - } else if (stricmp (Argv[0], "-ignorenotfound") == 0) { - mGlobals.IgnoreNotFound = 1; - } else if (stricmp (Argv[0], "-oc") == 0) { - // - // check for one more arg - // - if ((Argc <= 1) || (Argv[1][0] == '-')) { - Error (PROGRAM_NAME, 0, 0, Argv[0], "missing output C filename"); - return STATUS_ERROR; - } - - strcpy (mGlobals.StringCFileName, Argv[1]); - Argc--; - Argv++; - } else if (stricmp (Argv[0], "-bn") == 0) { - // - // check for one more arg - // - if ((Argc <= 1) || (Argv[1][0] == '-')) { - Error (PROGRAM_NAME, 0, 0, Argv[0], "missing base name"); - Usage (); - return STATUS_ERROR; - } - - strcpy (mGlobals.BaseName, Argv[1]); - Argc--; - Argv++; - } else if (stricmp (Argv[0], "-oh") == 0) { - // - // -oh to specify output .h defines file name - // - if ((Argc <= 1) || (Argv[1][0] == '-')) { - Error (PROGRAM_NAME, 0, 0, Argv[0], "missing output .h filename"); - return STATUS_ERROR; - } - - strcpy (mGlobals.StringHFileName, Argv[1]); - Argc--; - Argv++; - } else if (stricmp (Argv[0], "-skipext") == 0) { - // - // -skipext to skip scanning of files with certain filename extensions - // - if ((Argc <= 1) || (Argv[1][0] == '-')) { - Error (PROGRAM_NAME, 0, 0, Argv[0], "missing filename extension"); - return STATUS_ERROR; - } - // - // Allocate memory for a new list element, fill it in, and - // add it to our list of excluded extensions. Always make sure it - // has a "." as the first character. - // - NewList = malloc (sizeof (TEXT_STRING_LIST)); - if (NewList == NULL) { - Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); - return STATUS_ERROR; - } - - memset ((char *) NewList, 0, sizeof (TEXT_STRING_LIST)); - NewList->Str = malloc (strlen (Argv[1]) + 2); - if (NewList->Str == NULL) { - free (NewList); - Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); - return STATUS_ERROR; - } - - if (Argv[1][0] == '.') { - strcpy (NewList->Str, Argv[1]); - } else { - NewList->Str[0] = '.'; - strcpy (NewList->Str + 1, Argv[1]); - } - // - // Add it to our linked list - // - if (mGlobals.SkipExt == NULL) { - mGlobals.SkipExt = NewList; - } else { - mGlobals.LastSkipExt->Next = NewList; - } - - mGlobals.LastSkipExt = NewList; - Argc--; - Argv++; - } else if (stricmp (Argv[0], "-lang") == 0) { - // - // "-lang eng" or "-lang spa+cat" to only output certain languages - // - if ((Argc <= 1) || (Argv[1][0] == '-')) { - Error (PROGRAM_NAME, 0, 0, Argv[0], "missing language name"); - Usage (); - return STATUS_ERROR; - } - - if (AddCommandLineLanguage (Argv[1]) != STATUS_SUCCESS) { - return STATUS_ERROR; - } - - Argc--; - Argv++; - } else if (stricmp (Argv[0], "-od") == 0) { - // - // Output database file name -- check for another arg - // - if ((Argc <= 1) || (Argv[1][0] == '-')) { - Error (PROGRAM_NAME, 0, 0, Argv[0], "missing output database file name"); - return STATUS_ERROR; - } - - strcpy (mGlobals.OutputDatabaseFileName, Argv[1]); - Argv++; - Argc--; - } else { - // - // Unrecognized arg - // - Error (PROGRAM_NAME, 0, 0, Argv[0], "unrecognized option"); - Usage (); - return STATUS_ERROR; - } - - Argv++; - Argc--; - } - // - // Make sure they specified the mode parse/scan/dump - // - if (mGlobals.Mode == MODE_UNKNOWN) { - Error (NULL, 0, 0, "must specify one of -parse/-scan/-dump", NULL); - return STATUS_ERROR; - } - // - // All modes require a database filename - // - if (mGlobals.DatabaseFileName == 0) { - Error (NULL, 0, 0, "must specify a database filename using -db DbFileName", NULL); - Usage (); - return STATUS_ERROR; - } - // - // If dumping the database file, then return immediately if all - // parameters check out. - // - if (mGlobals.Mode == MODE_DUMP) { - // - // Not much use if they didn't specify -oh or -oc or -ou or -hpk - // - if ((mGlobals.DumpUFileName[0] == 0) && - (mGlobals.StringHFileName[0] == 0) && - (mGlobals.StringCFileName[0] == 0) && - (mGlobals.HiiExportPackFileName[0] == 0) - ) { - Error (NULL, 0, 0, "-dump without -oc/-oh/-ou/-hpk is a NOP", NULL); - return STATUS_ERROR; - } - - return STATUS_SUCCESS; - } - // - // Had to specify source string file and output string defines header filename. - // - if (mGlobals.Mode == MODE_SCAN) { - if (Argc < 1) { - Error (PROGRAM_NAME, 0, 0, NULL, "must specify at least one source file to scan with -scan"); - Usage (); - return STATUS_ERROR; - } - // - // Get the list of filenames - // - while (Argc > 0) { - NewList = malloc (sizeof (TEXT_STRING_LIST)); - if (NewList == NULL) { - Error (PROGRAM_NAME, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - memset (NewList, 0, sizeof (TEXT_STRING_LIST)); - NewList->Str = (CHAR8 *) malloc (strlen (Argv[0]) + 1); - if (NewList->Str == NULL) { - Error (PROGRAM_NAME, 0, 0, "memory allocation failure", NULL); - return STATUS_ERROR; - } - - strcpy (NewList->Str, Argv[0]); - if (mGlobals.ScanFileName == NULL) { - mGlobals.ScanFileName = NewList; - } else { - mGlobals.LastScanFileName->Next = NewList; - } - - mGlobals.LastScanFileName = NewList; - Argc--; - Argv++; - } - } else { - // - // Parse mode -- must specify an input unicode file name - // - if (Argc < 1) { - Error (PROGRAM_NAME, 0, 0, NULL, "must specify input unicode string file name with -parse"); - Usage (); - return STATUS_ERROR; - } - - strcpy (mGlobals.SourceFiles.FileName, Argv[0]); - } - - return STATUS_SUCCESS; -} -// -// Found "-lang eng,spa+cat" on the command line. Parse the -// language list and save the setting for later processing. -// -static -STATUS -AddCommandLineLanguage ( - IN CHAR8 *Language - ) -{ - WCHAR_STRING_LIST *WNewList; - WCHAR *From; - WCHAR *To; - // - // Keep processing the input string until we find the end. - // - while (*Language) { - // - // Allocate memory for a new list element, fill it in, and - // add it to our list. - // - WNewList = MALLOC (sizeof (WCHAR_STRING_LIST)); - if (WNewList == NULL) { - Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); - return STATUS_ERROR; - } - - memset ((char *) WNewList, 0, sizeof (WCHAR_STRING_LIST)); - WNewList->Str = malloc ((strlen (Language) + 1) * sizeof (WCHAR)); - if (WNewList->Str == NULL) { - free (WNewList); - Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); - return STATUS_ERROR; - } - // - // Copy it as unicode to our new structure. Then remove the - // plus signs in it, and verify each language name is 3 characters - // long. If we find a comma, then we're done with this group, so - // break out. - // - UnicodeSPrint (WNewList->Str, (strlen (Language) + 1) * sizeof (WCHAR), L"%a", Language); - From = To = WNewList->Str; - while (*From) { - if (*From == L',') { - break; - } - - if ((StrLen (From) < LANGUAGE_IDENTIFIER_NAME_LEN) || - ( - (From[LANGUAGE_IDENTIFIER_NAME_LEN] != 0) && - (From[LANGUAGE_IDENTIFIER_NAME_LEN] != UNICODE_PLUS_SIGN) && - (From[LANGUAGE_IDENTIFIER_NAME_LEN] != L',') - ) - ) { - Error (PROGRAM_NAME, 0, 0, Language, "invalid format for language name on command line"); - FREE (WNewList->Str); - FREE (WNewList); - return STATUS_ERROR; - } - - StrnCpy (To, From, LANGUAGE_IDENTIFIER_NAME_LEN); - To += LANGUAGE_IDENTIFIER_NAME_LEN; - From += LANGUAGE_IDENTIFIER_NAME_LEN; - if (*From == L'+') { - From++; - } - } - - *To = 0; - // - // Add it to our linked list - // - if (mGlobals.Language == NULL) { - mGlobals.Language = WNewList; - } else { - mGlobals.LastLanguage->Next = WNewList; - } - - mGlobals.LastLanguage = WNewList; - // - // Skip to next entry (comma-separated list) - // - while (*Language) { - if (*Language == L',') { - Language++; - break; - } - - Language++; - } - } - - return STATUS_SUCCESS; -} -// -// The contents of the text file are expected to be (one per line) -// STRING_IDENTIFIER_NAME ScopeName -// For example: -// STR_ID_MY_FAVORITE_STRING IBM -// -static -STATUS -ParseIndirectionFiles ( - TEXT_STRING_LIST *Files - ) -{ - FILE *Fptr; - CHAR8 Line[200]; - CHAR8 *StringName; - CHAR8 *ScopeName; - CHAR8 *End; - UINT32 LineCount; - WCHAR_MATCHING_STRING_LIST *NewList; - - Line[sizeof (Line) - 1] = 0; - Fptr = NULL; - while (Files != NULL) { - Fptr = fopen (Files->Str, "r"); - LineCount = 0; - if (Fptr == NULL) { - Error (NULL, 0, 0, Files->Str, "failed to open input indirection file for reading"); - return STATUS_ERROR; - } - - while (fgets (Line, sizeof (Line), Fptr) != NULL) { - // - // remove terminating newline for error printing purposes. - // - if (Line[strlen (Line) - 1] == '\n') { - Line[strlen (Line) - 1] = 0; - } - - LineCount++; - if (Line[sizeof (Line) - 1] != 0) { - Error (Files->Str, LineCount, 0, "line length exceeds maximum supported", NULL); - goto Done; - } - - StringName = Line; - while (*StringName && (isspace (*StringName))) { - StringName++; - } - - if (*StringName) { - if ((*StringName == '_') || isalpha (*StringName)) { - End = StringName; - while ((*End) && (*End == '_') || (isalnum (*End))) { - End++; - } - - if (isspace (*End)) { - *End = 0; - End++; - while (isspace (*End)) { - End++; - } - - if (*End) { - ScopeName = End; - while (*End && !isspace (*End)) { - End++; - } - - *End = 0; - // - // Add the string name/scope pair - // - NewList = malloc (sizeof (WCHAR_MATCHING_STRING_LIST)); - if (NewList == NULL) { - Error (NULL, 0, 0, "memory allocation error", NULL); - goto Done; - } - - memset (NewList, 0, sizeof (WCHAR_MATCHING_STRING_LIST)); - NewList->Str1 = (WCHAR *) malloc ((strlen (StringName) + 1) * sizeof (WCHAR)); - NewList->Str2 = (WCHAR *) malloc ((strlen (ScopeName) + 1) * sizeof (WCHAR)); - if ((NewList->Str1 == NULL) || (NewList->Str2 == NULL)) { - Error (NULL, 0, 0, "memory allocation error", NULL); - goto Done; - } - - UnicodeSPrint (NewList->Str1, strlen (StringName) + 1, L"%a", StringName); - UnicodeSPrint (NewList->Str2, strlen (ScopeName) + 1, L"%a", ScopeName); - if (mGlobals.IndirectionList == NULL) { - mGlobals.IndirectionList = NewList; - } else { - mGlobals.LastIndirectionList->Next = NewList; - } - - mGlobals.LastIndirectionList = NewList; - } else { - Error (Files->Str, LineCount, 0, StringName, "invalid line : expected 'StringIdentifier Scope'"); - goto Done; - } - } else { - Error (Files->Str, LineCount, 0, StringName, "invalid line : expected 'StringIdentifier Scope'"); - goto Done; - } - } else { - Error (Files->Str, LineCount, 0, StringName, "invalid string identifier"); - goto Done; - } - } - } - - fclose (Fptr); - Fptr = NULL; - Files = Files->Next; - } - -Done: - if (Fptr != NULL) { - fclose (Fptr); - return STATUS_ERROR; - } - - return STATUS_SUCCESS; -} - -static -STATUS -ScanFiles ( - TEXT_STRING_LIST *ScanFiles - ) -{ - char Line[MAX_LINE_LEN]; - FILE *Fptr; - UINT32 LineNum; - char *Cptr; - char *SavePtr; - char *TermPtr; - char *StringTokenPos; - TEXT_STRING_LIST *SList; - BOOLEAN SkipIt; - - // - // Put a null-terminator at the end of the line. If we read in - // a line longer than we support, then we can catch it. - // - Line[MAX_LINE_LEN - 1] = 0; - // - // Process each file. If they gave us a skip extension list, then - // skip it if the extension matches. - // - while (ScanFiles != NULL) { - SkipIt = FALSE; - for (SList = mGlobals.SkipExt; SList != NULL; SList = SList->Next) { - if ((strlen (ScanFiles->Str) > strlen (SList->Str)) && - (strcmp (ScanFiles->Str + strlen (ScanFiles->Str) - strlen (SList->Str), SList->Str) == 0) - ) { - SkipIt = TRUE; - // - // printf ("Match: %s : %s\n", ScanFiles->Str, SList->Str); - // - break; - } - } - - if (!SkipIt) { - if (mGlobals.VerboseScan) { - printf ("Scanning %s\n", ScanFiles->Str); - } - - Fptr = fopen (ScanFiles->Str, "r"); - if (Fptr == NULL) { - Error (NULL, 0, 0, ScanFiles->Str, "failed to open input file for scanning"); - return STATUS_ERROR; - } - - LineNum = 0; - while (fgets (Line, sizeof (Line), Fptr) != NULL) { - LineNum++; - if (Line[MAX_LINE_LEN - 1] != 0) { - Error (ScanFiles->Str, LineNum, 0, "line length exceeds maximum supported by tool", NULL); - fclose (Fptr); - return STATUS_ERROR; - } - // - // Remove the newline from the input line so we can print a warning message - // - if (Line[strlen (Line) - 1] == '\n') { - Line[strlen (Line) - 1] = 0; - } - // - // Terminate the line at // comments - // - Cptr = strstr (Line, "//"); - if (Cptr != NULL) { - *Cptr = 0; - } - - Cptr = Line; - while ((Cptr = strstr (Cptr, STRING_TOKEN)) != NULL) { - // - // Found "STRING_TOKEN". Make sure we don't have NUM_STRING_TOKENS or - // something like that. Then make sure it's followed by - // an open parenthesis, a string identifier, and then a closing - // parenthesis. - // - if (mGlobals.VerboseScan) { - printf (" %d: %s", LineNum, Cptr); - } - - if (((Cptr == Line) || (!IsValidIdentifierChar (*(Cptr - 1), FALSE))) && - (!IsValidIdentifierChar (*(Cptr + sizeof (STRING_TOKEN) - 1), FALSE)) - ) { - StringTokenPos = Cptr; - SavePtr = Cptr; - Cptr += strlen (STRING_TOKEN); - while (*Cptr && isspace (*Cptr) && (*Cptr != '(')) { - Cptr++; - } - - if (*Cptr != '(') { - Warning (ScanFiles->Str, LineNum, 0, StringTokenPos, "expected "STRING_TOKEN "(identifier)"); - } else { - // - // Skip over the open-parenthesis and find the next non-blank character - // - Cptr++; - while (isspace (*Cptr)) { - Cptr++; - } - - SavePtr = Cptr; - if ((*Cptr == '_') || isalpha (*Cptr)) { - while ((*Cptr == '_') || (isalnum (*Cptr))) { - Cptr++; - } - - TermPtr = Cptr; - while (*Cptr && isspace (*Cptr)) { - Cptr++; - } - - if (*Cptr != ')') { - Warning (ScanFiles->Str, LineNum, 0, StringTokenPos, "expected "STRING_TOKEN "(identifier)"); - } - - if (*TermPtr) { - *TermPtr = 0; - Cptr = TermPtr + 1; - } else { - Cptr = TermPtr; - } - // - // Add the string identifier to the list of used strings - // - ParserSetPosition (ScanFiles->Str, LineNum); - StringDBSetStringReferenced (SavePtr, mGlobals.IgnoreNotFound); - if (mGlobals.VerboseScan) { - printf ("...referenced %s", SavePtr); - } - } else { - Warning (ScanFiles->Str, LineNum, 0, StringTokenPos, "expected valid string identifier name"); - } - } - } else { - // - // Found it, but it's a substring of something else. Advance our pointer. - // - Cptr++; - } - - if (mGlobals.VerboseScan) { - printf ("\n"); - } - } - } - - fclose (Fptr); - } else { - // - // Skipping this file type - // - if (mGlobals.VerboseScan) { - printf ("Skip scanning of %s\n", ScanFiles->Str); - } - } - - ScanFiles = ScanFiles->Next; - } - - return STATUS_SUCCESS; -} -// -// Free the global string lists we allocated memory for -// -static -void -FreeLists ( - VOID - ) -{ - TEXT_STRING_LIST *Temp; - WCHAR_STRING_LIST *WTemp; - - // - // Traverse the include paths, freeing each - // - while (mGlobals.IncludePaths != NULL) { - Temp = mGlobals.IncludePaths->Next; - free (mGlobals.IncludePaths->Str); - free (mGlobals.IncludePaths); - mGlobals.IncludePaths = Temp; - } - // - // If we did a scan, then free up our - // list of files to scan. - // - while (mGlobals.ScanFileName != NULL) { - Temp = mGlobals.ScanFileName->Next; - free (mGlobals.ScanFileName->Str); - free (mGlobals.ScanFileName); - mGlobals.ScanFileName = Temp; - } - // - // If they gave us a list of filename extensions to - // skip on scan, then free them up. - // - while (mGlobals.SkipExt != NULL) { - Temp = mGlobals.SkipExt->Next; - free (mGlobals.SkipExt->Str); - free (mGlobals.SkipExt); - mGlobals.SkipExt = Temp; - } - // - // Free up any languages specified - // - while (mGlobals.Language != NULL) { - WTemp = mGlobals.Language->Next; - free (mGlobals.Language->Str); - free (mGlobals.Language); - mGlobals.Language = WTemp; - } - // - // Free up our indirection list - // - while (mGlobals.IndirectionList != NULL) { - mGlobals.LastIndirectionList = mGlobals.IndirectionList->Next; - free (mGlobals.IndirectionList->Str1); - free (mGlobals.IndirectionList->Str2); - free (mGlobals.IndirectionList); - mGlobals.IndirectionList = mGlobals.LastIndirectionList; - } - - while (mGlobals.IndirectionFileName != NULL) { - mGlobals.LastIndirectionFileName = mGlobals.IndirectionFileName->Next; - free (mGlobals.IndirectionFileName->Str); - free (mGlobals.IndirectionFileName); - mGlobals.IndirectionFileName = mGlobals.LastIndirectionFileName; - } -} - -static -BOOLEAN -IsValidIdentifierChar ( - CHAR8 Char, - BOOLEAN FirstChar - ) -{ - // - // If it's the first character of an identifier, then - // it must be one of [A-Za-z_]. - // - if (FirstChar) { - if (isalpha (Char) || (Char == '_')) { - return TRUE; - } - } else { - // - // If it's not the first character, then it can - // be one of [A-Za-z_0-9] - // - if (isalnum (Char) || (Char == '_')) { - return TRUE; - } - } - - return FALSE; -} - -static -void -RewindFile ( - SOURCE_FILE *SourceFile - ) -{ - SourceFile->LineNum = 1; - SourceFile->FileBufferPtr = SourceFile->FileBuffer; - SourceFile->EndOfFile = 0; -} - -static -BOOLEAN -SkipTo ( - SOURCE_FILE *SourceFile, - WCHAR WChar, - BOOLEAN StopAfterNewline - ) -{ - while (!EndOfFile (SourceFile)) { - // - // Check for the character of interest - // - if (SourceFile->FileBufferPtr[0] == WChar) { - return TRUE; - } else { - if (SourceFile->FileBufferPtr[0] == UNICODE_LF) { - SourceFile->LineNum++; - if (StopAfterNewline) { - SourceFile->FileBufferPtr++; - if (SourceFile->FileBufferPtr[0] == 0) { - SourceFile->FileBufferPtr++; - } - - return FALSE; - } - } - - SourceFile->FileBufferPtr++; - } - } - - return FALSE; -} - -static -void -Usage ( - VOID - ) -/*++ - -Routine Description: - - Print usage information for this utility. - -Arguments: - - None. - -Returns: - - Nothing. - ---*/ -{ - int Index; - static const char *Str[] = { - "", - PROGRAM_NAME " version "TOOL_VERSION " -- process unicode strings file", - " Usage: "PROGRAM_NAME " -parse {parse options} [FileNames]", - " "PROGRAM_NAME " -scan {scan options} [FileName]", - " "PROGRAM_NAME " -dump {dump options}", - " Common options include:", - " -h or -? for this help information", - " -db Database required name of output/input database file", - " -bn BaseName for use in the .h and .c output files", - " Default = "DEFAULT_BASE_NAME, - " -v for verbose output", - " -vdbw for verbose output when writing database", - " -vdbr for verbose output when reading database", - " -od FileName to specify an output database file name", - " Parse options include:", - " -i IncludePath add IncludePath to list of search paths", - " -newdb to not read in existing database file", - " -uqs to indicate that unquoted strings are used", - " FileNames name of one or more unicode files to parse", - " Scan options include:", - " -scan scan text file(s) for STRING_TOKEN() usage", - " -skipext .ext to skip scan of files with .ext filename extension", - " -ignorenotfound ignore if a given STRING_TOKEN(STR) is not ", - " found in the database", - " FileNames one or more files to scan", - " Dump options include:", - " -oc FileName write string data to FileName", - " -oh FileName write string defines to FileName", - " -ou FileName dump database to unicode file FileName", - " -lang Lang only dump for the language 'Lang'", - " -if FileName to specify an indirection file", - " -hpk FileName to create an HII export pack of the strings", - "", - " The expected process is to parse a unicode string file to create an initial", - " database of string identifier names and string definitions. Then text files", - " should be scanned for STRING_TOKEN() usages, and the referenced", - " strings will be tagged as used in the database. After all files have been", - " scanned, then the database should be dumped to create the necessary output", - " files.", - "", - NULL - }; - for (Index = 0; Str[Index] != NULL; Index++) { - fprintf (stdout, "%s\n", Str[Index]); - } -} diff --git a/Tools/CodeTools/TianoTools/StrGather/StrGather.h b/Tools/CodeTools/TianoTools/StrGather/StrGather.h deleted file mode 100644 index 65dc15cbe8..0000000000 --- a/Tools/CodeTools/TianoTools/StrGather/StrGather.h +++ /dev/null @@ -1,84 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - StrGather.h - -Abstract: - - Common defines and prototypes for StrGather. - ---*/ - -#ifndef _STR_GATHER_H_ -#define _STR_GATHER_H_ - -#define MALLOC(size) malloc (size) -#define FREE(ptr) free (ptr) - -#define PROGRAM_NAME "StrGather" - -typedef CHAR16 WCHAR; - -#define UNICODE_TO_ASCII(w) (INT8) ((w) & 0xFF) -#define ASCII_TO_UNICODE(a) (WCHAR) ((UINT8) (a)) - -#define UNICODE_HASH L'#' -#define UNICODE_BACKSLASH L'\\' -#define UNICODE_SLASH L'/' -#define UNICODE_EQUAL_SIGN L'=' -#define UNICODE_PLUS_SIGN L'+' - -#define UNICODE_FILE_START 0xFEFF -#define UNICODE_CR 0x000D -#define UNICODE_LF 0x000A -#define UNICODE_NULL 0x0000 -#define UNICODE_SPACE L' ' -#define UNICODE_SLASH L'/' -#define UNICODE_DOUBLE_QUOTE L'"' -#define UNICODE_Z L'Z' -#define UNICODE_z L'z' -#define UNICODE_A L'A' -#define UNICODE_a L'a' -#define UNICODE_F L'F' -#define UNICODE_f L'f' -#define UNICODE_UNDERSCORE L'_' -#define UNICODE_0 L'0' -#define UNICODE_9 L'9' -#define UNICODE_TAB L'\t' -#define UNICODE_NBR_STRING L"\\nbr" -#define UNICODE_BR_STRING L"\\br" -#define UNICODE_WIDE_STRING L"\\wide" -#define UNICODE_NARROW_STRING L"\\narrow" - -// -// This is the length of a valid string identifier -// -#define LANGUAGE_IDENTIFIER_NAME_LEN 3 - -typedef struct _TEXT_STRING_LIST { - struct _TEXT_STRING_LIST *Next; - CHAR8 *Str; -} TEXT_STRING_LIST; - -typedef struct _WCHAR_STRING_LIST { - struct _WCHAR_STRING_LIST *Next; - WCHAR *Str; -} WCHAR_STRING_LIST; - -typedef struct _WCHAR_MATCHING_STRING_LIST { - struct _WCHAR_MATCHING_STRING_LIST *Next; - WCHAR *Str1; - WCHAR *Str2; -} WCHAR_MATCHING_STRING_LIST; - -#endif // #ifndef _STR_GATHER_H_ diff --git a/Tools/CodeTools/TianoTools/StrGather/StringDB.c b/Tools/CodeTools/TianoTools/StrGather/StringDB.c deleted file mode 100644 index 16ef0526d7..0000000000 --- a/Tools/CodeTools/TianoTools/StrGather/StringDB.c +++ /dev/null @@ -1,2759 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - StringDB.c - -Abstract: - - String database implementation - ---*/ - -#include -#include -#include -#include // for tolower() - -#include -#include -#include -#include // for EFI_UGA_PIXEL definition -#include - -#include "EfiUtilityMsgs.h" -#include "StrGather.h" -#include "StringDB.h" - - -#define STRING_OFFSET RELOFST - -#define STRING_DB_KEY (('S' << 24) | ('D' << 16) | ('B' << 8) | 'K') -// -// Version supported by this tool -// -#define STRING_DB_VERSION 0x00010000 - -#define STRING_DB_MAJOR_VERSION_MASK 0xFFFF0000 -#define STRING_DB_MINOR_VERSION_MASK 0x0000FFFF - -#define DEFINE_STR L"// #define" - -#define LANGUAGE_CODE_WIDTH 4 -// -// This is the header that gets written to the top of the -// output binary database file. -// -typedef struct { - UINT32 Key; - UINT32 HeaderSize; - UINT32 Version; - UINT32 NumStringIdenfiers; - UINT32 StringIdentifiersSize; - UINT32 NumLanguages; -} STRING_DB_HEADER; - -// -// When we write out data to the database, we have a UINT16 identifier, which -// indicates what follows, followed by the data. Here's the structure. -// -typedef struct { - UINT16 DataType; - UINT16 Reserved; -} DB_DATA_ITEM_HEADER; - -#define DB_DATA_TYPE_INVALID 0x0000 -#define DB_DATA_TYPE_STRING_IDENTIFIER 0x0001 -#define DB_DATA_TYPE_LANGUAGE_DEFINITION 0x0002 -#define DB_DATA_TYPE_STRING_DEFINITION 0x0003 -#define DB_DATA_TYPE_LAST DB_DATA_TYPE_STRING_DEFINITION - -// -// We have to keep track of a list of languages, each of which has its own -// list of strings. Define a structure to keep track of all languages and -// their list of strings. -// -typedef struct _STRING_LIST { - struct _STRING_LIST *Next; - UINT32 Size; // number of bytes in string, including null terminator - WCHAR *LanguageName; - WCHAR *StringName; // for example STR_ID_TEXT1 - WCHAR *Scope; // - WCHAR *Str; // the actual string - UINT16 Flags; // properties of this string (used, undefined) -} STRING_LIST; - -typedef struct _LANGUAGE_LIST { - struct _LANGUAGE_LIST *Next; - WCHAR LanguageName[4]; - WCHAR *PrintableLanguageName; - STRING_LIST *String; - STRING_LIST *LastString; -} LANGUAGE_LIST; - -// -// We also keep track of all the string identifier names, which we assign unique -// values to. Create a structure to keep track of them all. -// -typedef struct _STRING_IDENTIFIER { - struct _STRING_IDENTIFIER *Next; - UINT32 Index; // only need 16 bits, but makes it easier with UINT32 - WCHAR *StringName; - UINT16 Flags; // if someone referenced it via STRING_TOKEN() -} STRING_IDENTIFIER; -// -// Keep our globals in this structure to be as modular as possible. -// -typedef struct { - FILE *StringDBFptr; - LANGUAGE_LIST *LanguageList; - LANGUAGE_LIST *LastLanguageList; - LANGUAGE_LIST *CurrentLanguage; // keep track of the last language they used - STRING_IDENTIFIER *StringIdentifier; - STRING_IDENTIFIER *LastStringIdentifier; - UINT8 *StringDBFileName; - UINT32 NumStringIdentifiers; - UINT32 NumStringIdentifiersReferenced; - STRING_IDENTIFIER *CurrentStringIdentifier; // keep track of the last string identifier they added - WCHAR *CurrentScope; -} STRING_DB_DATA; - -static STRING_DB_DATA mDBData; - -static const char *mSourceFileHeader[] = { - "//", - "// DO NOT EDIT -- auto-generated file", - "//", - "// This file is generated by the string gather utility", - "//", - NULL -}; - -static -STRING_LIST * -StringDBFindString ( - WCHAR *LanguageName, - WCHAR *StringName, - WCHAR *Scope, - WCHAR_STRING_LIST *LanguagesOfInterest, - WCHAR_MATCHING_STRING_LIST *IndirectionList - ); - -static -STRING_IDENTIFIER * -StringDBFindStringIdentifierByName ( - WCHAR *Name - ); - -static -STRING_IDENTIFIER * -StringDBFindStringIdentifierByIndex ( - UINT32 Index - ); - -static -LANGUAGE_LIST * -StringDBFindLanguageList ( - WCHAR *LanguageName - ); - -static -void -StringDBWriteStandardFileHeader ( - FILE *OutFptr - ); - -static -WCHAR * -AsciiToWchar ( - CHAR8 *Str - ); - -static -WCHAR * -DuplicateString ( - WCHAR *Str - ); - -static -STATUS -StringDBWriteStringIdentifier ( - FILE *DBFptr, - UINT16 StringId, - UINT16 Flags, - WCHAR *IdentifierName - ); - -static -STATUS -StringDBReadStringIdentifier ( - FILE *DBFptr - ); - -static -STATUS -StringDBWriteLanguageDefinition ( - FILE *DBFptr, - WCHAR *LanguageName, - WCHAR *PrintableLanguageName - ); - -static -STATUS -StringDBReadLanguageDefinition ( - FILE *DBFptr - ); - -static -STATUS -StringDBWriteString ( - FILE *DBFptr, - UINT16 Flags, - WCHAR *Language, - WCHAR *StringName, - WCHAR *Scope, - WCHAR *Str - ); - -static -STATUS -StringDBReadString ( - FILE *DBFptr - ); - -static -STATUS -StringDBReadGenericString ( - FILE *DBFptr, - UINT16 *Size, - WCHAR **Str - ); - -static -STATUS -StringDBWriteGenericString ( - FILE *DBFptr, - WCHAR *Str - ); - -static -void -StringDBAssignStringIndexes ( - VOID - ); - -/*****************************************************************************/ - -/*++ - -Routine Description: - Constructor function for the string database handler. - -Arguments: - None. - -Returns: - None. - ---*/ -void -StringDBConstructor ( - VOID - ) -{ - memset ((char *) &mDBData, 0, sizeof (STRING_DB_DATA)); - mDBData.CurrentScope = DuplicateString (L"NULL"); -} - -/*****************************************************************************/ - -/*++ - -Routine Description: - Destructor function for the string database handler. - -Arguments: - None. - -Returns: - None. - ---*/ -void -StringDBDestructor ( - VOID - ) -{ - LANGUAGE_LIST *NextLang; - STRING_LIST *NextStr; - STRING_IDENTIFIER *NextIdentifier; - // - // Close the database file if it's open - // - if (mDBData.StringDBFptr != NULL) { - fclose (mDBData.StringDBFptr); - mDBData.StringDBFptr = NULL; - } - // - // If we've allocated any strings/languages, free them up - // - while (mDBData.LanguageList != NULL) { - NextLang = mDBData.LanguageList->Next; - // - // Free up all strings for this language - // - while (mDBData.LanguageList->String != NULL) { - NextStr = mDBData.LanguageList->String->Next; - FREE (mDBData.LanguageList->String->Str); - FREE (mDBData.LanguageList->String); - mDBData.LanguageList->String = NextStr; - } - - FREE (mDBData.LanguageList->PrintableLanguageName); - FREE (mDBData.LanguageList); - mDBData.LanguageList = NextLang; - } - // - // Free up string identifiers - // - while (mDBData.StringIdentifier != NULL) { - NextIdentifier = mDBData.StringIdentifier->Next; - FREE (mDBData.StringIdentifier->StringName); - FREE (mDBData.StringIdentifier); - mDBData.StringIdentifier = NextIdentifier; - } - // - // Free the filename - // - if (mDBData.StringDBFileName != NULL) { - FREE (mDBData.StringDBFileName); - mDBData.StringDBFileName = NULL; - } - // - // We save a copy of the scope, so free it up if we - // have one. - // - if (mDBData.CurrentScope != NULL) { - FREE (mDBData.CurrentScope); - mDBData.CurrentScope = NULL; - } -} - -/*****************************************************************************/ - -/*++ - -Routine Description: - - Dump the contents of a database to an output C file. - -Arguments: - - FileName - name of the output file to write - BaseName - used for the name of the C array defined - Languages - list of languages of interest - -Returns: - - STATUS - -Notes: - - Languages is a pointer to a linked list of languages specified on - the command line. Format is "eng" and "spa+cat". For this, print - the strings for eng. Print the strings for spa too, but if one is - missing look for a cat string and print if it it exists. - ---*/ -STATUS -StringDBDumpCStrings ( - CHAR8 *FileName, - CHAR8 *BaseName, - WCHAR_STRING_LIST *LanguagesOfInterest, - WCHAR_MATCHING_STRING_LIST *IndirectionList - ) -{ - FILE *Fptr; - LANGUAGE_LIST *Lang; - STRING_LIST *CurrString; - STRING_LIST EmptyString; - UINT32 Offset; - UINT32 StringIndex; - UINT32 TempIndex; - UINT32 BytesThisLine; - EFI_HII_STRING_PACK StringPack; - UINT8 *Ptr; - UINT32 Len; - WCHAR ZeroString[1]; - WCHAR_STRING_LIST *LOIPtr; - BOOLEAN LanguageOk; - WCHAR *TempStringPtr; - WCHAR *LangName; - STRING_IDENTIFIER *StringIdentifier; - WCHAR Line[200]; - - if ((Fptr = fopen (FileName, "w")) == NULL) { - Error (NULL, 0, 0, FileName, "failed to open output C string file"); - return STATUS_ERROR; - } - // - // Assign index values to the string identifiers - // - StringDBAssignStringIndexes (); - // - // Write the standard header to the output file, then the structure - // definition header. - // - StringDBWriteStandardFileHeader (Fptr); - fprintf (Fptr, "\nunsigned char %s[] = {\n", BaseName); - // - // If a given string is not defined, then we'll use this one. - // - memset (&EmptyString, 0, sizeof (EmptyString)); - EmptyString.Size = sizeof (ZeroString); - EmptyString.Str = ZeroString; - // - // Process each language, then each string for each langage - // - ZeroString[0] = 0; - for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) { - // - // If we have a language list, then make sure this language is in that - // list. - // - LanguageOk = TRUE; - LangName = Lang->LanguageName; - if (LanguagesOfInterest != NULL) { - LanguageOk = FALSE; - for (LOIPtr = LanguagesOfInterest; LOIPtr != NULL; LOIPtr = LOIPtr->Next) { - if (StrnCmp (LOIPtr->Str, Lang->LanguageName, LANGUAGE_IDENTIFIER_NAME_LEN) == 0) { - LangName = LOIPtr->Str; - LanguageOk = TRUE; - break; - } - } - } - - if (!LanguageOk) { - continue; - } - // - // Process each string for this language. We have to make 3 passes on the strings: - // Pass1: computes sizes and fill in the string pack header - // Pass2: write the array of offsets - // Pass3: write the strings - // - // - // PASS 1: Fill in and print the HII string pack header - // - // Compute the size for this language package and write - // the header out. Each string package contains: - // Header - // Offset[] -- an array of offsets to strings, of type RELOFST each - // String[] -- the actual strings themselves - // - AsciiSPrint ( Line, sizeof(Line), - "\n//******************************************************************************" - "\n// Start of string definitions for %s/%s", - Lang->LanguageName, - Lang->PrintableLanguageName - ); - fprintf (Fptr, "%s", Line); - memset ((char *) &StringPack, 0, sizeof (EFI_HII_STRING_PACK)); - StringPack.Header.Type = EFI_HII_STRING; - StringPack.NumStringPointers = (UINT16) mDBData.NumStringIdentifiersReferenced; - // - // First string is the language name. If we're printing all languages, then - // it's just the "spa". If we were given a list of languages to print, then it's - // the "spacat" string. Compute its offset and fill in - // the info in the header. Since we know the language name string's length, - // and the printable language name follows it, use that info to fill in the - // entry for the printable language name as well. - // - StringPack.LanguageNameString = (STRING_OFFSET) (sizeof (EFI_HII_STRING_PACK) + (mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET))); - StringPack.PrintableLanguageName = (STRING_OFFSET) (StringPack.LanguageNameString + (StrLen (LangName) + 1) * sizeof (WCHAR)); - // - // Add up the size of all strings so we can fill in our header. - // - Len = 0; - for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) { - // - // For the first string (language name), we print out the "spacat" if they - // requested it. We set LangName to point to the proper language name string above. - // - if (StringIndex == STRING_ID_LANGUAGE_NAME) { - Len += (StrLen (LangName) + 1) * sizeof (WCHAR); - } else { - // - // Find a string with this language.stringname - // - StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex); - if (StringIdentifier == NULL) { - Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex); - return STATUS_ERROR; - } - // - // Find a matching string if this string identifier was referenced - // - EmptyString.Flags = STRING_FLAGS_UNDEFINED; - CurrString = NULL; - if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) { - CurrString = StringDBFindString ( - Lang->LanguageName, - StringIdentifier->StringName, - NULL, - LanguagesOfInterest, - IndirectionList - ); - if (NULL == CurrString) { - // - // If string for Lang->LanguageName is not found, try to get an English version - // - CurrString = StringDBFindString ( - L"eng", - StringIdentifier->StringName, - NULL, - LanguagesOfInterest, - IndirectionList - ); - } - } - - if (CurrString == NULL) { - CurrString = &EmptyString; - EmptyString.Flags |= StringIdentifier->Flags; - } - - Len += CurrString->Size; - } - } - StringPack.Header.Length = sizeof (EFI_HII_STRING_PACK) - + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET) - + Len; - // - // Write out the header one byte at a time - // - Ptr = (UINT8 *) &StringPack; - for (TempIndex = 0; TempIndex < sizeof (EFI_HII_STRING_PACK); TempIndex++, Ptr++) { - if ((TempIndex & 0x07) == 0) { - fprintf (Fptr, "\n "); - } - - fprintf (Fptr, "0x%02X, ", (UINT32) *Ptr); - } - - fprintf (Fptr, "\n // offset 0x%X\n", sizeof (StringPack)); - // - // PASS2 : write the offsets - // - // Traverse the list of strings again and write the array of offsets. The - // offset to the first string is the size of the string pack header - // plus the size of the offsets array. The other strings follow it. - // - StringIndex = 0; - Offset = sizeof (StringPack) + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET); - for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) { - // - // Write the offset, followed by a useful comment - // - fprintf (Fptr, " "); - Ptr = (UINT8 *) &Offset; - for (TempIndex = 0; TempIndex < sizeof (STRING_OFFSET); TempIndex++) { - fprintf (Fptr, "0x%02X, ", (UINT32) Ptr[TempIndex]); - } - // - // Find the string name - // - StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex); - if (StringIdentifier == NULL) { - Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex); - return STATUS_ERROR; - } - - AsciiSPrint (Line, sizeof(Line) , " // offset to string %s (0x%04X)", StringIdentifier->StringName, StringIndex); - fprintf (Fptr, "%s", Line); - // - // For the first string (language name), we print out the "spacat" if they - // requested it. We set LangName to point to the proper language name string above. - // - if (StringIndex == STRING_ID_LANGUAGE_NAME) { - Offset += (StrLen (LangName) + 1) * sizeof (WCHAR); - CurrString = StringDBFindString ( - Lang->LanguageName, - StringIdentifier->StringName, - NULL, // scope - NULL, - NULL - ); - } else { - // - // Find a matching string - // - CurrString = StringDBFindString ( - Lang->LanguageName, - StringIdentifier->StringName, - NULL, // scope - LanguagesOfInterest, - IndirectionList - ); - - if (NULL == CurrString) { - CurrString = StringDBFindString ( - L"eng", - StringIdentifier->StringName, - NULL, // scope - LanguagesOfInterest, - IndirectionList - ); - } - - EmptyString.LanguageName = Lang->LanguageName; - if (CurrString == NULL) { - CurrString = &EmptyString; - EmptyString.Flags = STRING_FLAGS_UNDEFINED; - } else if ((StringIdentifier->Flags & STRING_FLAGS_REFERENCED) == 0) { - CurrString = &EmptyString; - EmptyString.Flags = 0; - } - - Offset += CurrString->Size; - } - // - // Print useful info about this string - // - if ((StringIdentifier->Flags & STRING_FLAGS_REFERENCED) == 0) { - fprintf (Fptr, " - not referenced"); - } - - if (CurrString->Flags & STRING_FLAGS_UNDEFINED) { - fprintf (Fptr, " - not defined for this language"); - } else if (StrCmp (CurrString->LanguageName, Lang->LanguageName) != 0) { - AsciiSPrint ( - Line, sizeof(Line), - " - not defined for this language -- using secondary language %s definition", - CurrString->LanguageName - ); - fprintf ( Fptr, "%s", Line); - } - - fprintf (Fptr, "\n"); - } - // - // For unreferenced string identifiers, print a message that they are not referenced anywhere - // - while (StringIndex < mDBData.NumStringIdentifiers) { - StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex); - if (StringIdentifier != NULL) { - AsciiSPrint (Line, sizeof(Line), " // %s not referenced\n", StringIdentifier->StringName); - fprintf (Fptr, "%s", Line); - } - - StringIndex++; - } - - // - // PASS 3: write the strings themselves. - // Keep track of how many bytes we write per line because some editors - // (Visual Studio for instance) can't handle too long of lines. - // - Offset = sizeof (StringPack) + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET); - for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) { - StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex); - if (StringIdentifier == NULL) { - Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex); - return STATUS_ERROR; - } - - AsciiSPrint (Line, sizeof(Line), " // string %s offset 0x%08X\n ", StringIdentifier->StringName, Offset); - fprintf (Fptr, "%s", Line); - // - // For the first string (language name), we print out the "spacat" if they - // requested it. We set LangName to point to the proper language name string above. - // - if (StringIndex == STRING_ID_LANGUAGE_NAME) { - TempStringPtr = LangName; - } else { - // - // Find a matching string if this string identifier was referenced - // - CurrString = NULL; - if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) { - CurrString = StringDBFindString ( - Lang->LanguageName, - StringIdentifier->StringName, - NULL, // scope - LanguagesOfInterest, - IndirectionList - ); - if (NULL == CurrString) { - CurrString = StringDBFindString ( - L"eng", - StringIdentifier->StringName, - NULL, // scope - LanguagesOfInterest, - IndirectionList - ); - } - } - - if (CurrString == NULL) { - CurrString = &EmptyString; - } - - TempStringPtr = CurrString->Str; - } - - BytesThisLine = 0; - for (TempIndex = 0; TempStringPtr[TempIndex] != 0; TempIndex++) { - fprintf ( - Fptr, - "0x%02X, 0x%02X, ", - (UINT32) TempStringPtr[TempIndex] & 0xFF, - (UINT32) ((TempStringPtr[TempIndex] >> 8) & 0xFF) - ); - BytesThisLine += 2; - Offset += 2; - // - // Let's say we only allow 14 per line - // - if (BytesThisLine > 14) { - fprintf (Fptr, "\n "); - BytesThisLine = 0; - } - } - // - // Print NULL WCHAR at the end of this string. - // - fprintf (Fptr, "0x00, 0x00,\n"); - Offset += 2; - } - // - // Sanity check the offset. Make sure our running offset is what we put in the - // string pack header. - // - if (StringPack.Header.Length != Offset) { - Error ( - __FILE__, - __LINE__, - 0, - "application error", - "stringpack size 0x%X does not match final size 0x%X", - StringPack.Header.Length, - Offset - ); - } - } - // - // Print terminator string pack, closing brace and close the file. - // The size of 0 triggers to the consumer that this is the end. - // - memset ((char *) &StringPack, 0, sizeof (EFI_HII_STRING_PACK)); - StringPack.Header.Type = EFI_HII_STRING; - Ptr = (UINT8 *) &StringPack; - fprintf (Fptr, "\n // strings terminator pack"); - for (TempIndex = 0; TempIndex < sizeof (StringPack); TempIndex++, Ptr++) { - if ((TempIndex & 0x0F) == 0) { - fprintf (Fptr, "\n "); - } - - fprintf (Fptr, "0x%02X, ", (UINT32) *Ptr); - } - - fprintf (Fptr, "\n};\n"); - fclose (Fptr); - return STATUS_SUCCESS; -} - -/*****************************************************************************/ - -/*++ - -Routine Description: - - Dump the #define string names - -Arguments: - - FileName - name of the output file to write - BaseName - used for the protection #ifndef/#endif - -Returns: - - STATUS - ---*/ -STATUS -StringDBDumpStringDefines ( - CHAR8 *FileName, - CHAR8 *BaseName - ) -{ - FILE *Fptr; - STRING_IDENTIFIER *Identifier; - CHAR8 CopyBaseName[100]; - WCHAR Line[200]; - UINT32 Index; - const CHAR8 *StrDefHeader[] = { - "#ifndef _%s_STRINGS_DEFINE_H_\n", - "#define _%s_STRINGS_DEFINE_H_\n\n", - NULL - }; - - if ((Fptr = fopen (FileName, "w")) == NULL) { - Error (NULL, 0, 0, FileName, "failed to open output string defines file"); - return STATUS_ERROR; - } - // - // Get the base source filename and convert to uppercase. - // - if (sizeof (CopyBaseName) <= strlen (BaseName) + 1) { - Error (NULL, 0, 0, "application error", "StringDBDumpStringDefines() string length insufficient"); - return STATUS_ERROR; - } - - strcpy (CopyBaseName, BaseName); - for (Index = 0; CopyBaseName[Index] != 0; Index++) { - if (islower (CopyBaseName[Index])) { - CopyBaseName[Index] = (INT8) toupper (CopyBaseName[Index]); - } - } - // - // Assign index values to the string identifiers - // - StringDBAssignStringIndexes (); - // - // Write the standard header to the output file, and then the - // protective #ifndef. - // - StringDBWriteStandardFileHeader (Fptr); - for (Index = 0; StrDefHeader[Index] != NULL; Index++) { - fprintf (Fptr, StrDefHeader[Index], CopyBaseName); - } - // - // Print all the #defines for the string identifiers. Print identifiers - // whose names start with '$' as comments. Add comments for string - // identifiers not used as well. - // - Identifier = mDBData.StringIdentifier; - while (Identifier != NULL) { - if (Identifier->StringName[0] == L'$') { - fprintf (Fptr, "// "); - } - - if (Identifier->Flags & STRING_FLAGS_REFERENCED) { - AsciiSPrint (Line, sizeof(Line), "#define %-40s 0x%04X\n", Identifier->StringName, Identifier->Index); - fprintf (Fptr, "%s", Line); - } else { - AsciiSPrint (Line, sizeof(Line), "//#define %-40s 0x%04X // not referenced\n", Identifier->StringName, Identifier->Index); - fprintf (Fptr, "%s", Line); - } - - Identifier = Identifier->Next; - } - - fprintf (Fptr, "\n#endif\n"); - fclose (Fptr); - return STATUS_SUCCESS; -} - -/*****************************************************************************/ - -/*++ - -Routine Description: - - Add a string identifier to the database. - -Arguments: - - StringName - name of the string identifier. For example "STR_MY_STRING" - NewId - if an ID has been assigned - Flags - characteristics for the identifier - -Returns: - - STATUS - ---*/ -STATUS -StringDBAddStringIdentifier ( - WCHAR *StringName, - UINT16 *NewId, - UINT16 Flags - ) -{ - STRING_IDENTIFIER *StringIdentifier; - STATUS Status; - // - // If it was already used for some other language, then we don't - // need to add it. But set it to the current string identifier. - // The referenced bit is sticky. - // - Status = STATUS_SUCCESS; - StringIdentifier = StringDBFindStringIdentifierByName (StringName); - if (StringIdentifier != NULL) { - if (Flags & STRING_FLAGS_REFERENCED) { - StringIdentifier->Flags |= STRING_FLAGS_REFERENCED; - } - - mDBData.CurrentStringIdentifier = StringIdentifier; - *NewId = (UINT16) StringIdentifier->Index; - return Status; - } - - StringIdentifier = (STRING_IDENTIFIER *) MALLOC (sizeof (STRING_IDENTIFIER)); - if (StringIdentifier == NULL) { - Error (NULL, 0, 0, NULL, "memory allocation error"); - return STATUS_ERROR; - } - - memset ((char *) StringIdentifier, 0, sizeof (STRING_IDENTIFIER)); - StringIdentifier->StringName = (WCHAR *) malloc ((StrLen (StringName) + 1) * sizeof (WCHAR)); - if (StringIdentifier->StringName == NULL) { - Error (NULL, 0, 0, NULL, "memory allocation error"); - return STATUS_ERROR; - } - - StrCpy (StringIdentifier->StringName, StringName); - if (*NewId != STRING_ID_INVALID) { - StringIdentifier->Index = *NewId; - StringIdentifier->Flags |= STRING_FLAGS_INDEX_ASSIGNED; - if (mDBData.NumStringIdentifiers <= StringIdentifier->Index) { - mDBData.NumStringIdentifiers = StringIdentifier->Index + 1; - } - } else { - StringIdentifier->Index = mDBData.NumStringIdentifiers++; - } - - StringIdentifier->Flags |= Flags; - // - // Add it to our list of string identifiers - // - if (mDBData.StringIdentifier == NULL) { - mDBData.StringIdentifier = StringIdentifier; - } else { - mDBData.LastStringIdentifier->Next = StringIdentifier; - } - - mDBData.LastStringIdentifier = StringIdentifier; - mDBData.CurrentStringIdentifier = StringIdentifier; - *NewId = (UINT16) StringIdentifier->Index; - return Status; -} - -/*****************************************************************************/ - -/*++ - -Routine Description: - - Add a new string to the database. - -Arguments: - - LanguageName - "eng" or "spa" language name - StringName - "STR_MY_TEXT" string name - Scope - from the #scope statements in the string file - Format - if we should format the string - Flags - characteristic flags for the string - -Returns: - - STATUS - -Notes: - - Several of the fields can be "inherited" from the previous calls to - our database functions. For example, if scope is NULL here, then - we'll use the previous setting. - ---*/ -STATUS -StringDBAddString ( - WCHAR *LanguageName, - WCHAR *StringName, - WCHAR *Scope, - WCHAR *String, - BOOLEAN Format, - UINT16 Flags - ) -{ - LANGUAGE_LIST *Lang; - UINT32 Size; - STRING_LIST *Str; - UINT16 StringIndex; - WCHAR TempLangName[4]; - STRING_IDENTIFIER *StringIdentifier; - - // - // Check that language name is exactly 3 characters, or emit an error. - // Truncate at 3 if it's longer, or make it 3 if it's shorter. - // - if (LanguageName != NULL) { - Size = StrLen (LanguageName); - if (Size != 3) { - ParserError (0, "invalid length for language name", "%S", LanguageName); - if (Size > 3) { - LanguageName[3] = 0; - } else { - // - // Make a local copy of the language name string, and extend to - // 3 characters since we make assumptions elsewhere in this program - // on the length. - // - StrCpy (TempLangName, LanguageName); - for (; Size < 3; Size++) { - TempLangName[Size] = L'?'; - } - - TempLangName[4] = 0; - LanguageName = TempLangName; - } - } - } - // - // If they specified a language, make sure they've defined it already - // via a #langdef statement. Otherwise use the current default language. - // - if (LanguageName != NULL) { - Lang = StringDBFindLanguageList (LanguageName); - if (Lang == NULL) { - ParserError (0, "language not defined", "%S", LanguageName); - return STATUS_ERROR; - } else { - StringDBSetCurrentLanguage (LanguageName); - } - } else { - Lang = mDBData.CurrentLanguage; - if (Lang == NULL) { - // - // Have to call SetLanguage() first - // - ParserError (0, "no language defined", "%S", StringName); - return STATUS_ERROR; - } - } - // - // If they didn't define a string identifier, use the last string identifier - // added. - // - if (StringName == NULL) { - StringName = mDBData.CurrentStringIdentifier->StringName; - if (StringName == NULL) { - ParserError (0, "no string identifier previously specified", NULL); - return STATUS_ERROR; - } - } - // - // If scope was not specified, use the default setting - // - if (Scope != NULL) { - Scope = DuplicateString (Scope); - } else { - Scope = DuplicateString (mDBData.CurrentScope); - } - // - // printf ("Adding string: %S.%S.%S\n", Lang->LanguageName, StringName, Scope); - // - // Check for duplicates for this Language.StringName.Scope. Allow multiple - // definitions of the language name and printable language name, since the - // user does not specifically define them. - // - if (StringDBFindString (Lang->LanguageName, StringName, Scope, NULL, NULL) != NULL) { - if ((StrCmp (StringName, LANGUAGE_NAME_STRING_NAME) == 0) && - (StrCmp (StringName, PRINTABLE_LANGUAGE_NAME_STRING_NAME) == 0) - ) { - ParserError ( - 0, - "string multiply defined", - "Language.Name.Scope = %S.%S.%S", - Lang->LanguageName, - StringName, - Scope - ); - return STATUS_ERROR; - } - } - - StringIndex = STRING_ID_INVALID; - if (StringDBAddStringIdentifier (StringName, &StringIndex, Flags) != STATUS_SUCCESS) { - return STATUS_ERROR; - } - - StringIdentifier = StringDBFindStringIdentifierByName (StringName); - // - // Add this string to the end of the strings for this language. - // - Str = (STRING_LIST *) malloc (sizeof (STRING_LIST)); - if (Str == NULL) { - Error (NULL, 0, 0, NULL, "memory allocation error"); - return STATUS_ERROR; - } - - memset ((char *) Str, 0, sizeof (STRING_LIST)); - Size = (StrLen (String) + 1) * sizeof (WCHAR); - Str->Flags = Flags; - Str->Scope = Scope; - Str->StringName = StringIdentifier->StringName; - Str->LanguageName = DuplicateString (LanguageName); - Str->Str = (WCHAR *) MALLOC (Size); - if (Str->Str == NULL) { - Error (NULL, 0, 0, NULL, "memory allocation error"); - return STATUS_ERROR; - } - // - // If not formatting, just copy the string. - // - StrCpy (Str->Str, String); - if (Format) { - StringDBFormatString (Str->Str); - } - // - // Size may change after formatting. We set the size to - // the actual size of the string, including the null for - // easier processing later. - // - Str->Size = (StrLen (Str->Str) + 1) * sizeof (WCHAR); - if (Lang->String == NULL) { - Lang->String = Str; - } else { - Lang->LastString->Next = Str; - } - - Lang->LastString = Str; - return STATUS_SUCCESS; -} - -/*****************************************************************************/ - -/*++ - -Routine Description: - - Given a language name, see if a language list for it has been defined - -Arguments: - - LanguageName - like "eng" - -Returns: - - A pointer to the language list - ---*/ -static -LANGUAGE_LIST * -StringDBFindLanguageList ( - WCHAR *LanguageName - ) -{ - LANGUAGE_LIST *Lang; - - Lang = mDBData.LanguageList; - while (Lang != NULL) { - if (StrCmp (LanguageName, Lang->LanguageName) == 0) { - break; - } - - Lang = Lang->Next; - } - - return Lang; -} - -/*****************************************************************************/ -STATUS -StringDBSetCurrentLanguage ( - WCHAR *LanguageName - ) -{ - LANGUAGE_LIST *Lang; - - Lang = StringDBFindLanguageList (LanguageName); - if (Lang == NULL) { - ParserError (0, "language not previously defined", "%S", LanguageName); - return STATUS_ERROR; - } - - mDBData.CurrentLanguage = Lang; - return STATUS_SUCCESS; -} - -/*****************************************************************************/ -STATUS -StringDBAddLanguage ( - WCHAR *LanguageName, - WCHAR *PrintableLanguageName - ) -{ - LANGUAGE_LIST *Lang; - // - // Check for redefinitions - // - Lang = StringDBFindLanguageList (LanguageName); - if (Lang != NULL) { - // - // Better be the same printable name - // - if (StrCmp (PrintableLanguageName, Lang->PrintableLanguageName) != 0) { - ParserError ( - 0, - "language redefinition", - "%S:%S != %S:%S", - Lang->LanguageName, - Lang->PrintableLanguageName, - LanguageName, - PrintableLanguageName - ); - return STATUS_ERROR; - // - // } else { - // ParserWarning (0, "benign language redefinition", "%S", PrintableLanguageName); - // return STATUS_WARNING; - // - } - } else { - // - // Allocate memory to keep track of this new language - // - Lang = (LANGUAGE_LIST *) malloc (sizeof (LANGUAGE_LIST)); - if (Lang == NULL) { - Error (NULL, 0, 0, NULL, "memory allocation error"); - return STATUS_ERROR; - } - - memset ((char *) Lang, 0, sizeof (LANGUAGE_LIST)); - // - // Save the language name, then allocate memory to save the - // printable language name - // - StrCpy (Lang->LanguageName, LanguageName); - Lang->PrintableLanguageName = (WCHAR *) malloc ((StrLen (PrintableLanguageName) + 1) * sizeof (WCHAR)); - if (Lang->PrintableLanguageName == NULL) { - Error (NULL, 0, 0, NULL, "memory allocation error"); - return STATUS_ERROR; - } - - StrCpy (Lang->PrintableLanguageName, PrintableLanguageName); - - if (mDBData.LanguageList == NULL) { - mDBData.LanguageList = Lang; - } else { - mDBData.LastLanguageList->Next = Lang; - } - - mDBData.LastLanguageList = Lang; - } - // - // Default is to make our active language this new one - // - StringDBSetCurrentLanguage (LanguageName); - // - // The first two strings for any language are the language name, - // followed by the printable language name. Add them and set them - // to referenced so they never get stripped out. - // - StringDBAddString ( - LanguageName, - LANGUAGE_NAME_STRING_NAME, - NULL, - LanguageName, - FALSE, - STRING_FLAGS_REFERENCED - ); - StringDBAddString ( - LanguageName, - PRINTABLE_LANGUAGE_NAME_STRING_NAME, - NULL, - PrintableLanguageName, - FALSE, - STRING_FLAGS_REFERENCED - ); - return STATUS_SUCCESS; -} - -/*****************************************************************************/ -static -STRING_IDENTIFIER * -StringDBFindStringIdentifierByName ( - WCHAR *StringName - ) -{ - STRING_IDENTIFIER *Identifier; - - Identifier = mDBData.StringIdentifier; - while (Identifier != NULL) { - if (StrCmp (StringName, Identifier->StringName) == 0) { - return Identifier; - } - - Identifier = Identifier->Next; - } - - return NULL; -} - -static -STRING_IDENTIFIER * -StringDBFindStringIdentifierByIndex ( - UINT32 StringIndex - ) -{ - STRING_IDENTIFIER *Identifier; - - Identifier = mDBData.StringIdentifier; - while (Identifier != NULL) { - if (Identifier->Index == StringIndex) { - return Identifier; - } - - Identifier = Identifier->Next; - } - - return NULL; -} - -/*****************************************************************************/ -static -void -StringDBWriteStandardFileHeader ( - FILE *OutFptr - ) -{ - UINT32 TempIndex; - for (TempIndex = 0; mSourceFileHeader[TempIndex] != NULL; TempIndex++) { - fprintf (OutFptr, "%s\n", mSourceFileHeader[TempIndex]); - } -} - -/*****************************************************************************/ - -/*++ - -Routine Description: - - Given a Unicode string from an input file, reformat the string to replace - backslash control sequences with the appropriate encoding. - -Arguments: - - String - pointer to string to reformat - -Returns: - - Nothing - ---*/ -void -StringDBFormatString ( - WCHAR *String - ) -{ - WCHAR *From; - WCHAR *To; - int HexNibbles; - WCHAR HexValue; - // - // Go through the string and process any formatting characters - // - From = String; - To = String; - while (*From) { - if (*From == UNICODE_BACKSLASH) { - // - // First look for \wide and replace with the appropriate control character. Note that - // when you have "define STR L"ABC"", then sizeof(ABC) is 8 because the null char is - // counted. Make adjustments for this. We advance From below, so subtract 2 each time. - // - if (StrnCmp (From, UNICODE_WIDE_STRING, sizeof (UNICODE_WIDE_STRING) / sizeof (WCHAR) - 1) == 0) { - *To = WIDE_CHAR; - From += sizeof (UNICODE_WIDE_STRING) / sizeof (WCHAR) - 2; - } else if (StrnCmp (From, UNICODE_NARROW_STRING, sizeof (UNICODE_NARROW_STRING) / sizeof (WCHAR) - 1) == 0) { - // - // Found: \narrow - // - *To = NARROW_CHAR; - From += sizeof (UNICODE_NARROW_STRING) / sizeof (WCHAR) - 2; - } else if (StrnCmp (From, UNICODE_NBR_STRING, sizeof (UNICODE_NBR_STRING) / sizeof (WCHAR) - 1) == 0) { - // - // Found: \nbr - // - *To = NON_BREAKING_CHAR; - From += sizeof (UNICODE_NBR_STRING) / sizeof (WCHAR) - 2; - } else if (StrnCmp (From, UNICODE_BR_STRING, sizeof (UNICODE_BR_STRING) / sizeof (WCHAR) - 1) == 0) { - // - // Found: \br -- pass through untouched - // - *To = *From; - } else { - // - // Standard one-character control sequences such as \n, \r, \\, or \x - // - From++; - switch (*From) { - case ASCII_TO_UNICODE ('n'): - *To = UNICODE_CR; - To++; - *To = UNICODE_LF; - break; - - // - // carriage return - // - case ASCII_TO_UNICODE ('r'): - *To = UNICODE_CR; - break; - - // - // backslash - // - case UNICODE_BACKSLASH: - *To = UNICODE_BACKSLASH; - break; - - // - // Tab - // - case ASCII_TO_UNICODE ('t'): - *To = UNICODE_TAB; - break; - - // - // embedded double-quote - // - case UNICODE_DOUBLE_QUOTE: - *To = UNICODE_DOUBLE_QUOTE; - break; - - // - // Hex Unicode character \x1234. We'll process up to 4 hex characters - // - case ASCII_TO_UNICODE ('x'): - HexValue = 0; - for (HexNibbles = 0; HexNibbles < 4; HexNibbles++) { - if ((From[1] >= UNICODE_0) && (From[1] <= UNICODE_9)) { - HexValue = (HexValue << 4) | (From[1] - UNICODE_0); - } else if ((From[1] >= UNICODE_a) && (From[1] <= UNICODE_f)) { - HexValue = (HexValue << 4) | (10 + From[1] - UNICODE_a); - } else if ((From[1] >= UNICODE_A) && (From[1] <= UNICODE_F)) { - HexValue = (HexValue << 4) | (10 + From[1] - UNICODE_A); - } else { - break; - } - - From++; - } - - if (HexNibbles == 0) { - ParserWarning ( - 0, - "expected at least one valid hex digit with \\x escaped character in string", - "\\%C", - *From - ); - } else { - *To = HexValue; - } - break; - - default: - *To = UNICODE_SPACE; - ParserWarning (0, "invalid escaped character in string", "\\%C", *From); - break; - } - } - } else { - *To = *From; - } - - From++; - To++; - } - - *To = 0; -} - -/*****************************************************************************/ -STATUS -StringDBReadDatabase ( - CHAR8 *DBFileName, - BOOLEAN IgnoreIfNotExist, - BOOLEAN Verbose - ) -{ - STRING_DB_HEADER DbHeader; - STATUS Status; - FILE *DBFptr; - DB_DATA_ITEM_HEADER DataItemHeader; - - Status = STATUS_SUCCESS; - DBFptr = NULL; - // - // if (Verbose) { - // fprintf (stdout, "Reading database file %s\n", DBFileName); - // } - // - // Try to open the input file - // - if ((DBFptr = fopen (DBFileName, "rb")) == NULL) { - if (IgnoreIfNotExist) { - return STATUS_SUCCESS; - } - - Error (NULL, 0, 0, DBFileName, "failed to open input database file for reading"); - return STATUS_ERROR; - } - // - // Read and verify the database header - // - if (fread ((void *) &DbHeader, sizeof (STRING_DB_HEADER), 1, DBFptr) != 1) { - Error (NULL, 0, 0, DBFileName, "failed to read header from database file"); - Status = STATUS_ERROR; - goto Finish; - } - - if (DbHeader.Key != STRING_DB_KEY) { - Error (NULL, 0, 0, DBFileName, "invalid header in database file"); - Status = STATUS_ERROR; - goto Finish; - } - - if ((DbHeader.Version & STRING_DB_MAJOR_VERSION_MASK) != (STRING_DB_VERSION & STRING_DB_MAJOR_VERSION_MASK)) { - Error (NULL, 0, 0, DBFileName, "incompatible database file version -- rebuild clean"); - Status = STATUS_ERROR; - goto Finish; - } - // - // Read remaining items - // - while (fread (&DataItemHeader, sizeof (DataItemHeader), 1, DBFptr) == 1) { - switch (DataItemHeader.DataType) { - case DB_DATA_TYPE_STRING_IDENTIFIER: - StringDBReadStringIdentifier (DBFptr); - break; - - case DB_DATA_TYPE_LANGUAGE_DEFINITION: - StringDBReadLanguageDefinition (DBFptr); - break; - - case DB_DATA_TYPE_STRING_DEFINITION: - StringDBReadString (DBFptr); - break; - - default: - Error ( - NULL, - 0, - 0, - "database corrupted", - "invalid data item type 0x%X at offset 0x%X", - (UINT32) DataItemHeader.DataType, - ftell (DBFptr) - sizeof (DataItemHeader) - ); - Status = STATUS_ERROR; - goto Finish; - } - } - -Finish: - if (DBFptr != NULL) { - fclose (DBFptr); - } - - return Status; -} - -/*****************************************************************************/ - -/*++ - -Routine Description: - - Write everything we know to the output database file. Write: - - Database header - String identifiers[] - StringPacks[] - -Arguments: - - DBFileName - name of the file to write to - Verbose - for debug purposes, print info messages along the way. - -Returns: - - STATUS - ---*/ -STATUS -StringDBWriteDatabase ( - CHAR8 *DBFileName, - BOOLEAN Verbose - ) -{ - STRING_DB_HEADER DbHeader; - UINT32 Counter; - UINT32 StrLength; - LANGUAGE_LIST *Lang; - STRING_IDENTIFIER *StringIdentifier; - STRING_LIST *StrList; - FILE *DBFptr; - - if (Verbose) { - fprintf (stdout, "Writing database %s\n", DBFileName); - } - - if ((DBFptr = fopen (DBFileName, "wb")) == NULL) { - Error (NULL, 0, 0, DBFileName, "failed to open output database file for writing"); - return STATUS_ERROR; - } - // - // Fill in and write the database header - // - memset (&DbHeader, 0, sizeof (STRING_DB_HEADER)); - DbHeader.HeaderSize = sizeof (STRING_DB_HEADER); - DbHeader.Key = STRING_DB_KEY; - DbHeader.Version = STRING_DB_VERSION; - // - // Count the number of languages we have - // - for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) { - DbHeader.NumLanguages++; - } - // - // Count up how many string identifiers we have, and total up the - // size of the names plus the size of the flags field we will - // write out too. - // - DbHeader.NumStringIdenfiers = mDBData.NumStringIdentifiers; - StringIdentifier = mDBData.StringIdentifier; - for (Counter = 0; Counter < mDBData.NumStringIdentifiers; Counter++) { - StrLength = StrLen (StringIdentifier->StringName) + 1; - DbHeader.StringIdentifiersSize += StrLength * sizeof (WCHAR) + sizeof (StringIdentifier->Flags); - StringIdentifier = StringIdentifier->Next; - } - - // - // Write the header - // - fwrite (&DbHeader, sizeof (STRING_DB_HEADER), 1, DBFptr); - if (Verbose) { - fprintf (stdout, " Number of string identifiers 0x%04X\n", DbHeader.NumStringIdenfiers); - fprintf (stdout, " Number of languages %d\n", DbHeader.NumLanguages); - } - // - // Write the string identifiers - // - for (StringIdentifier = mDBData.StringIdentifier; StringIdentifier != NULL; StringIdentifier = StringIdentifier->Next) { - StringDBWriteStringIdentifier ( - DBFptr, - (UINT16) StringIdentifier->Index, - StringIdentifier->Flags, - StringIdentifier->StringName - ); - } - // - // Now write all the strings for each language - // - for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) { - StringDBWriteLanguageDefinition (DBFptr, Lang->LanguageName, Lang->PrintableLanguageName); - for (StrList = Lang->String; StrList != NULL; StrList = StrList->Next) { - StringDBWriteString ( - DBFptr, - StrList->Flags, - Lang->LanguageName, - StrList->StringName, - StrList->Scope, - StrList->Str - ); - } - } - - fclose (DBFptr); - return STATUS_SUCCESS; -} - -STATUS -StringDBSetStringReferenced ( - CHAR8 *StringIdentifierName, - BOOLEAN IgnoreNotFound - ) -{ - STRING_IDENTIFIER *Id; - WCHAR *WName; - STATUS Status; - // - // See if it's already been defined. - // - Status = STATUS_SUCCESS; - WName = (WCHAR *) malloc ((strlen (StringIdentifierName) + 1) * sizeof (WCHAR)); - UnicodeSPrint (WName, (strlen (StringIdentifierName) + 1) * sizeof (WCHAR), L"%a", StringIdentifierName); - Id = StringDBFindStringIdentifierByName (WName); - if (Id != NULL) { - Id->Flags |= STRING_FLAGS_REFERENCED; - } else { - if (IgnoreNotFound == 0) { - ParserWarning (0, StringIdentifierName, "string identifier not found in database"); - Status = STATUS_WARNING; - } - } - - free (WName); - return Status; -} - -/*****************************************************************************/ - -/*++ - -Routine Description: - - Dump the contents of a database to an output unicode file. - -Arguments: - - DBFileName - name of the pre-existing database file to read - OutputFileName - name of the file to dump the database contents to - Verbose - for printing of additional info useful for debugging - -Returns: - - STATUS - -Notes: - - There's some issue with the unicode printing routines. Therefore to - write to the output file properly, open it as binary and use fwrite. - Ideally we could open it with just L"w" and use fwprintf(). - ---*/ -STATUS -StringDBDumpDatabase ( - CHAR8 *DBFileName, - CHAR8 *OutputFileName, - BOOLEAN Verbose - ) -{ - LANGUAGE_LIST *Lang; - STRING_IDENTIFIER *StringIdentifier; - STRING_LIST *StrList; - FILE *OutFptr; - WCHAR WChar; - WCHAR CrLf[2]; - WCHAR Line[200]; - WCHAR *Scope; - // - // This function assumes the database has already been read, and - // we're just dumping our internal data structures to a unicode file. - // - if (Verbose) { - fprintf (stdout, "Dumping database file %s\n", DBFileName); - } - - OutFptr = fopen (OutputFileName, "wb"); - if (OutFptr == NULL) { - Error (NULL, 0, 0, OutputFileName, "failed to open output file for writing"); - return STATUS_ERROR; - } - - WChar = UNICODE_FILE_START; - fwrite (&WChar, sizeof (WCHAR), 1, OutFptr); - CrLf[1] = UNICODE_LF; - CrLf[0] = UNICODE_CR; - // - // The default control character is '/'. Make it '#' by writing - // "/=#" to the output file. - // - UnicodeSPrint (Line, sizeof(Line), L"/=#"); - fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr); - fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); - fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); - // - // Dump all the string identifiers and their values - // - StringDBAssignStringIndexes (); - for (StringIdentifier = mDBData.StringIdentifier; StringIdentifier != NULL; StringIdentifier = StringIdentifier->Next) { - // - // Write the "#define " string - // - if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) { - UnicodeSPrint ( - Line, - sizeof(Line), L"%s %-60.60s 0x%04X", - DEFINE_STR, - StringIdentifier->StringName, - StringIdentifier->Index - ); - } else { - UnicodeSPrint ( - Line, - sizeof(Line), L"%s %-60.60s 0x%04X // NOT REFERENCED", - DEFINE_STR, - StringIdentifier->StringName, - StringIdentifier->Index - ); - } - - fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr); - fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); - } - - fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); - // - // Now write all the strings for each language. - // - WChar = UNICODE_DOUBLE_QUOTE; - Scope = NULL; - for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) { - fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); - UnicodeSPrint (Line, sizeof(Line), L"#langdef %s \"%s\"", Lang->LanguageName, Lang->PrintableLanguageName); - fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr); - fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); - fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); - // - // Now the strings (in double-quotes) for this language. Write - // #string STR_NAME #language eng "string" - // - for (StrList = Lang->String; StrList != NULL; StrList = StrList->Next) { - // - // Print the internal flags for debug - // - UnicodeSPrint (Line, sizeof(Line), L"// flags=0x%02X", (UINT32) StrList->Flags); - fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr); - fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); - // - // Print the scope if changed - // - if ((Scope == NULL) || (StrCmp (Scope, StrList->Scope) != 0)) { - UnicodeSPrint (Line, sizeof(Line), L"#scope %s", StrList->Scope); - fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr); - fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); - Scope = StrList->Scope; - } - - UnicodeSPrint ( - Line, - sizeof(Line), L"#string %-50.50s #language %s \"", - StrList->StringName, - Lang->LanguageName - ); - fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr); - fwrite (StrList->Str, StrList->Size - sizeof (WCHAR), 1, OutFptr); - UnicodeSPrint (Line, sizeof(Line), L"\""); - fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr); - fwrite (&CrLf, sizeof (CrLf), 1, OutFptr); - } - } - - fclose (OutFptr); - return STATUS_SUCCESS; -} - -/*****************************************************************************/ - -/*++ - -Routine Description: - - Given a primary language, a string identifier number, and a list of - languages, find a secondary string. - -Arguments: - - LanguageName - primary language, like "spa" - StringId - string index value - LanguageList - linked list of "eng", "spa+cat",... - -Returns: - - Pointer to a secondary string if found. NULL otherwise. - -Notes: - - Given: LanguageName "spa" and LanguageList "spa+cat", match the - "spa" and extract the "cat" and see if there is a string defined - for "cat".StringId. - ---*/ -static -STATUS -StringDBWriteStringIdentifier ( - FILE *DBFptr, - UINT16 StringId, - UINT16 Flags, - WCHAR *IdentifierName - ) -{ - DB_DATA_ITEM_HEADER Hdr; - memset (&Hdr, 0, sizeof (DB_DATA_ITEM_HEADER)); - Hdr.DataType = DB_DATA_TYPE_STRING_IDENTIFIER; - if (fwrite (&Hdr, sizeof (DB_DATA_ITEM_HEADER), 1, DBFptr) != 1) { - Error (NULL, 0, 0, "failed to write string to output database file", NULL); - return STATUS_ERROR; - } - - if (fwrite (&StringId, sizeof (StringId), 1, DBFptr) != 1) { - Error (NULL, 0, 0, "failed to write StringId to output database", NULL); - return STATUS_ERROR; - } - - if (fwrite (&Flags, sizeof (Flags), 1, DBFptr) != 1) { - Error (NULL, 0, 0, "failed to write StringId flags to output database", NULL); - return STATUS_ERROR; - } - - if (StringDBWriteGenericString (DBFptr, IdentifierName) != STATUS_SUCCESS) { - return STATUS_ERROR; - } - - return STATUS_SUCCESS; -} - -static -STATUS -StringDBReadStringIdentifier ( - FILE *DBFptr - ) -{ - WCHAR *IdentifierName; - UINT16 Flags; - UINT16 StringId; - UINT16 Size; - - if (fread (&StringId, sizeof (StringId), 1, DBFptr) != 1) { - Error (NULL, 0, 0, "failed to read StringId from database", NULL); - return STATUS_ERROR; - } - - if (fread (&Flags, sizeof (Flags), 1, DBFptr) != 1) { - Error (NULL, 0, 0, "failed to read StringId flags from database", NULL); - return STATUS_ERROR; - } - - if (StringDBReadGenericString (DBFptr, &Size, &IdentifierName) != STATUS_SUCCESS) { - return STATUS_ERROR; - } - - StringDBAddStringIdentifier (IdentifierName, &StringId, Flags); - // - // printf ("STRID: 0x%04X %S\n", (UINT32)StringId, IdentifierName); - // - FREE (IdentifierName); - return STATUS_SUCCESS; -} - -static -STATUS -StringDBWriteString ( - FILE *DBFptr, - UINT16 Flags, - WCHAR *Language, - WCHAR *StringName, - WCHAR *Scope, - WCHAR *Str - ) -{ - DB_DATA_ITEM_HEADER Hdr; - memset (&Hdr, 0, sizeof (DB_DATA_ITEM_HEADER)); - Hdr.DataType = DB_DATA_TYPE_STRING_DEFINITION; - if (fwrite (&Hdr, sizeof (DB_DATA_ITEM_HEADER), 1, DBFptr) != 1) { - Error (NULL, 0, 0, "failed to write string header to output database file", NULL); - return STATUS_ERROR; - } - - if (fwrite (&Flags, sizeof (Flags), 1, DBFptr) != 1) { - Error (NULL, 0, 0, "failed to write string flags to output database", NULL); - return STATUS_ERROR; - } - - if (StringDBWriteGenericString (DBFptr, Language) != STATUS_SUCCESS) { - return STATUS_ERROR; - } - - if (StringDBWriteGenericString (DBFptr, StringName) != STATUS_SUCCESS) { - return STATUS_ERROR; - } - - if (StringDBWriteGenericString (DBFptr, Scope) != STATUS_SUCCESS) { - return STATUS_ERROR; - } - - if (StringDBWriteGenericString (DBFptr, Str) != STATUS_SUCCESS) { - return STATUS_ERROR; - } - // - // printf ("DBWriteString: %S.%S.%S\n", Language, StringName, Scope); - // - return STATUS_SUCCESS; -} - -static -STATUS -StringDBReadString ( - FILE *DBFptr - ) -{ - UINT16 Flags; - UINT16 Size; - WCHAR *Language; - WCHAR *StringName; - WCHAR *Scope; - WCHAR *Str; - - if (fread (&Flags, sizeof (Flags), 1, DBFptr) != 1) { - Error (NULL, 0, 0, "failed to read string flags from database", NULL); - return STATUS_ERROR; - } - - if (StringDBReadGenericString (DBFptr, &Size, &Language) != STATUS_SUCCESS) { - return STATUS_ERROR; - } - - if (StringDBReadGenericString (DBFptr, &Size, &StringName) != STATUS_SUCCESS) { - return STATUS_ERROR; - } - - if (StringDBReadGenericString (DBFptr, &Size, &Scope) != STATUS_SUCCESS) { - return STATUS_ERROR; - } - - if (StringDBReadGenericString (DBFptr, &Size, &Str) != STATUS_SUCCESS) { - return STATUS_ERROR; - } - // - // If the first or second string (language name and printable language name), - // then skip them. They're added via language definitions data items in - // the database. - // - if (StringName[0] != L'$') { - StringDBAddString (Language, StringName, Scope, Str, FALSE, Flags); - } - // - // printf ("DBReadString: %S.%S.%S\n", Language, StringName, Scope); - // - FREE (Language); - FREE (StringName); - if (Str != NULL) { - FREE (Str); - } - - if (Scope != NULL) { - FREE (Scope); - } - - return STATUS_SUCCESS; -} - -static -STATUS -StringDBWriteLanguageDefinition ( - FILE *DBFptr, - WCHAR *LanguageName, - WCHAR *PrintableLanguageName - ) -{ - DB_DATA_ITEM_HEADER Hdr; - memset (&Hdr, 0, sizeof (DB_DATA_ITEM_HEADER)); - Hdr.DataType = DB_DATA_TYPE_LANGUAGE_DEFINITION; - if (fwrite (&Hdr, sizeof (DB_DATA_ITEM_HEADER), 1, DBFptr) != 1) { - Error (NULL, 0, 0, "failed to write string to output database file", NULL); - return STATUS_ERROR; - } - - if (StringDBWriteGenericString (DBFptr, LanguageName) != STATUS_SUCCESS) { - return STATUS_ERROR; - } - - if (StringDBWriteGenericString (DBFptr, PrintableLanguageName) != STATUS_SUCCESS) { - return STATUS_ERROR; - } - - return STATUS_SUCCESS; -} - -static -STATUS -StringDBReadLanguageDefinition ( - FILE *DBFptr - ) -{ - WCHAR *LanguageName; - WCHAR *PrintableLanguageName; - UINT16 Size; - STATUS Status; - - if (StringDBReadGenericString (DBFptr, &Size, &LanguageName) != STATUS_SUCCESS) { - return STATUS_ERROR; - } - - if (StringDBReadGenericString (DBFptr, &Size, &PrintableLanguageName) != STATUS_SUCCESS) { - return STATUS_ERROR; - } - // - // printf("LANG: %S %S\n", LanguageName, PrintableLanguageName); - // - Status = StringDBAddLanguage (LanguageName, PrintableLanguageName); - FREE (LanguageName); - FREE (PrintableLanguageName); - return Status; -} -// -// All unicode strings in the database consist of a UINT16 length -// field, followed by the string itself. This routine reads one -// of those and returns the info. -// -static -STATUS -StringDBReadGenericString ( - FILE *DBFptr, - UINT16 *Size, - WCHAR **Str - ) -{ - UINT16 LSize; - UINT16 Flags; - WCHAR *LStr; - - if (fread (&LSize, sizeof (UINT16), 1, DBFptr) != 1) { - Error (NULL, 0, 0, "failed to read a string length field from the database", NULL); - return STATUS_ERROR; - } - - if (fread (&Flags, sizeof (UINT16), 1, DBFptr) != 1) { - Error (NULL, 0, 0, "failed to read a string flags field from the database", NULL); - return STATUS_ERROR; - } - - LStr = MALLOC (LSize); - if (LStr == NULL) { - Error (__FILE__, __LINE__, 0, "memory allocation failed reading the database", NULL); - return STATUS_ERROR; - } - - if (fread (LStr, sizeof (WCHAR), (UINT32) LSize / sizeof (WCHAR), DBFptr) != (UINT32) LSize / sizeof (WCHAR)) { - Error (NULL, 0, 0, "failed to read string from database", NULL); - Error (NULL, 0, 0, "database read failure", "offset 0x%X", ftell (DBFptr)); - free (LStr); - return STATUS_ERROR; - } - // - // printf ("DBR: %S\n", LStr); - // - // If the flags field indicated we were asked to write a NULL string, then - // return them a NULL pointer. - // - if (Flags & STRING_FLAGS_UNDEFINED) { - *Size = 0; - *Str = NULL; - } else { - *Size = LSize; - *Str = LStr; - } - - return STATUS_SUCCESS; -} - -static -STATUS -StringDBWriteGenericString ( - FILE *DBFptr, - WCHAR *Str - ) -{ - UINT16 Size; - UINT16 Flags; - WCHAR ZeroString[1]; - // - // Strings in the database consist of a size UINT16 followed - // by the string itself. - // - if (Str == NULL) { - ZeroString[0] = 0; - Str = ZeroString; - Size = sizeof (ZeroString); - Flags = STRING_FLAGS_UNDEFINED; - } else { - Flags = 0; - Size = (UINT16) ((StrLen (Str) + 1) * sizeof (WCHAR)); - } - - if (fwrite (&Size, sizeof (UINT16), 1, DBFptr) != 1) { - Error (NULL, 0, 0, "failed to write string size to database", NULL); - return STATUS_ERROR; - } - - if (fwrite (&Flags, sizeof (UINT16), 1, DBFptr) != 1) { - Error (NULL, 0, 0, "failed to write string flags to database", NULL); - return STATUS_ERROR; - } - - if (fwrite (Str, sizeof (WCHAR), Size / sizeof (WCHAR), DBFptr) != Size / sizeof (WCHAR)) { - Error (NULL, 0, 0, "failed to write string to database", NULL); - return STATUS_ERROR; - } - - return STATUS_SUCCESS; -} - -static -STRING_LIST * -StringDBFindString ( - WCHAR *LanguageName, - WCHAR *StringName, - WCHAR *Scope, - WCHAR_STRING_LIST *LanguagesOfInterest, - WCHAR_MATCHING_STRING_LIST *IndirectionList - ) -{ - LANGUAGE_LIST *Lang; - STRING_LIST *CurrString; - WCHAR_MATCHING_STRING_LIST *IndListPtr; - WCHAR TempLangName[LANGUAGE_IDENTIFIER_NAME_LEN + 1]; - WCHAR *WCharPtr; - - // - // If we were given an indirection list, then see if one was specified for this - // string identifier. That is to say, if the indirection says "STR_ID_MY_FAVORITE MyScope", - // then if this string name matches one in the list, then do a lookup with the - // specified scope and return that value. - // - if (IndirectionList != NULL) { - for (IndListPtr = IndirectionList; IndListPtr != NULL; IndListPtr = IndListPtr->Next) { - if (StrCmp (StringName, IndListPtr->Str1) == 0) { - CurrString = StringDBFindString (LanguageName, StringName, IndListPtr->Str2, LanguagesOfInterest, NULL); - if (CurrString != NULL) { - return CurrString; - } - } - } - } - // - // First look for exact match language.stringname - // - for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) { - if (StrCmp (LanguageName, Lang->LanguageName) == 0) { - // - // Found language match. Try to find string name match - // - for (CurrString = Lang->String; CurrString != NULL; CurrString = CurrString->Next) { - if (StrCmp (StringName, CurrString->StringName) == 0) { - // - // Found a string name match. See if we're supposed to find - // a scope match. - // - if (Scope != NULL) { - if (StrCmp (CurrString->Scope, Scope) == 0) { - return CurrString; - } - } else { - return CurrString; - } - } - } - } - } - // - // If we got here, then we didn't find a match. Look for secondary string - // matches. That is to say, if we're processing "spa", and they requested - // "spa+cat", then recursively call with "cat" - // - while (LanguagesOfInterest != NULL) { - // - // If this is the language we're looking for, then process the - // languages of interest list for it. - // - if (StrnCmp (LanguageName, LanguagesOfInterest->Str, LANGUAGE_IDENTIFIER_NAME_LEN) == 0) { - WCharPtr = LanguagesOfInterest->Str + LANGUAGE_IDENTIFIER_NAME_LEN; - while (*WCharPtr) { - // - // Double-check the length, though it should have been checked on the - // command line. - // - if (StrLen (WCharPtr) < LANGUAGE_IDENTIFIER_NAME_LEN) { - Error (NULL, 0, 0, "malformed alternate language list", "%S", LanguagesOfInterest->Str); - return NULL; - } - - StrnCpy (TempLangName, WCharPtr, LANGUAGE_IDENTIFIER_NAME_LEN); - TempLangName[LANGUAGE_IDENTIFIER_NAME_LEN] = 0; - CurrString = StringDBFindString (TempLangName, StringName, NULL, NULL, IndirectionList); - if (CurrString != NULL) { - return CurrString; - } - - WCharPtr += LANGUAGE_IDENTIFIER_NAME_LEN; - } - } - - LanguagesOfInterest = LanguagesOfInterest->Next; - } - - return NULL; -} - -STATUS -StringDBSetScope ( - WCHAR *Scope - ) -{ - // - // Free up existing scope memory. - // - if (mDBData.CurrentScope != NULL) { - FREE (mDBData.CurrentScope); - } - - mDBData.CurrentScope = DuplicateString (Scope); - return STATUS_SUCCESS; -} -// -// We typically don't assign index values to string identifiers -// until we're ready to write out files. To reduce the size of -// the output file, re-order the string identifiers to move any -// unreferenced ones to the end. Then we'll walk the list -// again to assign string indexes, keeping track of the last -// one referenced. -// -static -void -StringDBAssignStringIndexes ( - VOID - ) -{ - STRING_IDENTIFIER *StrId; - STRING_IDENTIFIER *FirstUsed; - STRING_IDENTIFIER *LastUsed; - STRING_IDENTIFIER *FirstUnused; - STRING_IDENTIFIER *LastUnused; - UINT32 Index; - UINT32 MaxReferenced; - - // - // Create two lists -- used and unused. Then put them together with - // the unused ones on the end. - // - FirstUsed = NULL; - LastUsed = NULL; - FirstUnused = NULL; - LastUnused = NULL; - StrId = mDBData.StringIdentifier; - while (StrId != NULL) { - if ((StrId->Flags & STRING_FLAGS_REFERENCED) == 0) { - // - // Put it on the unused list - // - if (FirstUnused == NULL) { - FirstUnused = StrId; - } else { - LastUnused->Next = StrId; - } - - LastUnused = StrId; - StrId = StrId->Next; - LastUnused->Next = NULL; - } else { - // - // Put it on the used list - // - if (FirstUsed == NULL) { - FirstUsed = StrId; - } else { - LastUsed->Next = StrId; - } - - LastUsed = StrId; - StrId = StrId->Next; - LastUsed->Next = NULL; - } - } - // - // Join the lists - // - if (FirstUsed != NULL) { - mDBData.StringIdentifier = FirstUsed; - LastUsed->Next = FirstUnused; - } else { - mDBData.StringIdentifier = FirstUnused; - } - - MaxReferenced = 0; - Index = 0; - for (StrId = mDBData.StringIdentifier; StrId != NULL; StrId = StrId->Next) { - StrId->Index = Index; - Index++; - if (StrId->Flags & STRING_FLAGS_REFERENCED) { - mDBData.NumStringIdentifiersReferenced = Index; - } - } - - mDBData.NumStringIdentifiers = Index; -} - -static -WCHAR * -DuplicateString ( - WCHAR *Str - ) -{ - WCHAR *NewStr; - if (Str == NULL) { - return NULL; - } - - NewStr = MALLOC ((StrLen (Str) + 1) * sizeof (WCHAR)); - if (NewStr == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - return NULL; - } - - StrCpy (NewStr, Str); - return NewStr; -} - -static -WCHAR * -AsciiToWchar ( - CHAR8 *Str - ) -{ - UINT32 Len; - WCHAR *NewStr; - WCHAR *Ptr; - - Len = strlen (Str) + 1; - NewStr = (WCHAR *) malloc (Len * sizeof (WCHAR)); - for (Ptr = NewStr; *Str != 0; Str++, Ptr++) { - *Ptr = (UINT16) (UINT8) *Str; - } - - *Ptr = 0; - return NewStr; -} - -/*****************************************************************************/ - -/*++ - -Routine Description: - - Create an HII export string pack for the strings in our database. - -Arguments: - - FileName - name of the output file to write - -Returns: - - STATUS - - ---*/ -STATUS -StringDBCreateHiiExportPack ( - CHAR8 *FileName - ) -{ - FILE *Fptr; - LANGUAGE_LIST *Lang; - STRING_LIST *CurrString; - STRING_LIST EmptyString; - UINT32 Offset; - UINT32 StringIndex; - UINT32 TempIndex; - EFI_HII_STRING_PACK StringPack; - UINT32 Len; - WCHAR ZeroString[1]; - WCHAR *TempStringPtr; - WCHAR *LangName; - STRING_IDENTIFIER *StringIdentifier; - - if ((Fptr = fopen (FileName, "wb")) == NULL) { - Error (NULL, 0, 0, FileName, "failed to open output HII export file"); - return STATUS_ERROR; - } - // - // Assign index values to the string identifiers - // - StringDBAssignStringIndexes (); - // - // If a given string is not defined, then we'll use this one. - // - memset (&EmptyString, 0, sizeof (EmptyString)); - EmptyString.Size = sizeof (ZeroString); - EmptyString.Str = ZeroString; - // - // Process each language, then each string for each langage - // - ZeroString[0] = 0; - for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) { - // - // Process each string for this language. We have to make 3 passes on the strings: - // Pass1: computes sizes and fill in the string pack header - // Pass2: write the array of offsets - // Pass3: write the strings - // - // - // PASS 1: Fill in and print the HII string pack header - // - // Compute the size for this language package and write - // the header out. Each string package contains: - // Header - // Offset[] -- an array of offsets to strings, of type RELOFST each - // String[] -- the actual strings themselves - // - memset ((char *) &StringPack, 0, sizeof (EFI_HII_STRING_PACK)); - StringPack.Header.Type = EFI_HII_STRING; - StringPack.NumStringPointers = (UINT16) mDBData.NumStringIdentifiersReferenced; - LangName = Lang->LanguageName; - // - // First string is the language name. If we're printing all languages, then - // it's just the "spa". If we were given a list of languages to print, then it's - // the "spacat" string. Compute its offset and fill in - // the info in the header. Since we know the language name string's length, - // and the printable language name follows it, use that info to fill in the - // entry for the printable language name as well. - // - StringPack.LanguageNameString = (STRING_OFFSET) (sizeof (EFI_HII_STRING_PACK) + (mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET))); - StringPack.PrintableLanguageName = (STRING_OFFSET) (StringPack.LanguageNameString + (StrLen (LangName) + 1) * sizeof (WCHAR)); - // - // Add up the size of all strings so we can fill in our header. - // - Len = 0; - for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) { - // - // For the first string (language name), we print out the "spacat" if they - // requested it. We set LangName to point to the proper language name string above. - // - if (StringIndex == STRING_ID_LANGUAGE_NAME) { - Len += (StrLen (LangName) + 1) * sizeof (WCHAR); - } else { - // - // Find a string with this language.stringname - // - StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex); - if (StringIdentifier == NULL) { - Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex); - return STATUS_ERROR; - } - // - // Find a matching string if this string identifier was referenced - // - EmptyString.Flags = STRING_FLAGS_UNDEFINED; - CurrString = NULL; - if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) { - CurrString = StringDBFindString ( - Lang->LanguageName, - StringIdentifier->StringName, - NULL, - NULL, // LanguagesOfInterest, - NULL - ); - // - // IndirectionList); - // - if (NULL == CurrString) { - // - // If string for Lang->LanguageName is not found, try to get an English version - // - CurrString = StringDBFindString ( - L"eng", - StringIdentifier->StringName, - NULL, - NULL, // LanguagesOfInterest, - NULL - ); - // - // IndirectionList); - // - } - } - - if (CurrString == NULL) { - CurrString = &EmptyString; - EmptyString.Flags |= StringIdentifier->Flags; - } - - Len += CurrString->Size; - } - } - StringPack.Header.Length = sizeof (EFI_HII_STRING_PACK) - + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET) - + Len; - // - // Write out the string pack header - // - fwrite ((void *) &StringPack, sizeof (StringPack), 1, Fptr); - // - // PASS2 : write the offsets - // - // Traverse the list of strings again and write the array of offsets. The - // offset to the first string is the size of the string pack header - // plus the size of the offsets array. The other strings follow it. - // - StringIndex = 0; - Offset = sizeof (StringPack) + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET); - for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) { - // - // Write the offset - // - fwrite (&Offset, sizeof (STRING_OFFSET), 1, Fptr); - // - // Find the string name - // - StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex); - if (StringIdentifier == NULL) { - Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex); - return STATUS_ERROR; - } - // - // For the first string (language name), we print out the "spacat" if they - // requested it. We set LangName to point to the proper language name string above. - // - if (StringIndex == STRING_ID_LANGUAGE_NAME) { - Offset += (StrLen (LangName) + 1) * sizeof (WCHAR); - CurrString = StringDBFindString ( - Lang->LanguageName, - StringIdentifier->StringName, - NULL, // scope - NULL, - NULL - ); - } else { - // - // Find a matching string - // - CurrString = StringDBFindString ( - Lang->LanguageName, - StringIdentifier->StringName, - NULL, // scope - NULL, // LanguagesOfInterest, - NULL - ); - // - // IndirectionList); - // - if (NULL == CurrString) { - CurrString = StringDBFindString ( - L"eng", - StringIdentifier->StringName, - NULL, // scope - NULL, // LanguagesOfInterest, - NULL - ); - // - // IndirectionList); - // - } - - EmptyString.LanguageName = Lang->LanguageName; - if (CurrString == NULL) { - CurrString = &EmptyString; - EmptyString.Flags = STRING_FLAGS_UNDEFINED; - } else if ((StringIdentifier->Flags & STRING_FLAGS_REFERENCED) == 0) { - CurrString = &EmptyString; - EmptyString.Flags = 0; - } - - Offset += CurrString->Size; - } - } - - // - // PASS 3: write the strings themselves. - // - Offset = sizeof (StringPack) + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET); - for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) { - StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex); - if (StringIdentifier == NULL) { - Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex); - return STATUS_ERROR; - } - // - // For the first string (language name), we print out the "spacat" if they - // requested it. We set LangName to point to the proper language name string above. - // - if (StringIndex == STRING_ID_LANGUAGE_NAME) { - TempStringPtr = LangName; - } else { - // - // Find a matching string if this string identifier was referenced - // - CurrString = NULL; - if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) { - CurrString = StringDBFindString ( - Lang->LanguageName, - StringIdentifier->StringName, - NULL, // scope - NULL, // LanguagesOfInterest, - NULL - ); - // - // IndirectionList); - // - if (NULL == CurrString) { - CurrString = StringDBFindString ( - L"eng", - StringIdentifier->StringName, - NULL, // scope - NULL, // LanguagesOfInterest, - NULL - ); - // - // IndirectionList); - // - } - } - - if (CurrString == NULL) { - CurrString = &EmptyString; - } - - TempStringPtr = CurrString->Str; - } - - for (TempIndex = 0; TempStringPtr[TempIndex] != 0; TempIndex++) { - fwrite (&TempStringPtr[TempIndex], sizeof (CHAR16), 1, Fptr); - Offset += 2; - } - // - // Print NULL WCHAR at the end of this string. - // - TempIndex = 0; - fwrite (&TempIndex, sizeof (CHAR16), 1, Fptr); - Offset += 2; - } - // - // Sanity check the offset. Make sure our running offset is what we put in the - // string pack header. - // - if (StringPack.Header.Length != Offset) { - Error ( - __FILE__, - __LINE__, - 0, - "application error", - "stringpack size 0x%X does not match final size 0x%X", - StringPack.Header.Length, - Offset - ); - } - } - // - // Print terminator string pack, closing brace and close the file. - // The size of 0 triggers to the consumer that this is the end. - // - memset ((char *) &StringPack, 0, sizeof (EFI_HII_STRING_PACK)); - StringPack.Header.Type = EFI_HII_STRING; - fwrite ((void *) &StringPack, sizeof (StringPack), 1, Fptr); - fclose (Fptr); - return STATUS_SUCCESS; -} diff --git a/Tools/CodeTools/TianoTools/StrGather/StringDB.h b/Tools/CodeTools/TianoTools/StrGather/StringDB.h deleted file mode 100644 index c52573151f..0000000000 --- a/Tools/CodeTools/TianoTools/StrGather/StringDB.h +++ /dev/null @@ -1,136 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - StringDB.h - -Abstract: - - Common defines and prototypes for string database management - ---*/ - -#ifndef _STRING_DB_H_ -#define _STRING_DB_H_ - -#define LANGUAGE_NAME_STRING_NAME L"$LANGUAGE_NAME" -#define PRINTABLE_LANGUAGE_NAME_STRING_NAME L"$PRINTABLE_LANGUAGE_NAME" - -void -StringDBConstructor ( - void - ) -; -void -StringDBDestructor ( - void - ) -; - -STATUS -StringDBAddString ( - WCHAR *LanguageName, - WCHAR *StringIdentifier, - WCHAR *Scope, - WCHAR *String, - BOOLEAN Format, - UINT16 Flags - ) -; - -STATUS -StringDBSetScope ( - WCHAR *Scope - ) -; - -#define STRING_FLAGS_REFERENCED 0x0001 // if referenced somewhere -#define STRING_FLAGS_UNDEFINED 0x0002 // if we added it for padding purposes -#define STRING_FLAGS_INDEX_ASSIGNED 0x0004 // so don't change the index value -#define STRING_ID_INVALID 0xFFFF -#define STRING_ID_LANGUAGE_NAME 0x0000 -#define STRING_ID_PRINTABLE_LANGUAGE_NAME 0x0001 - -STATUS -StringDBAddStringIdentifier ( - WCHAR *StringIdentifier, - UINT16 *NewId, - UINT16 Flags - ) -; - -STATUS -StringDBReadDatabase ( - CHAR8 *DBFileName, - BOOLEAN IgnoreIfNotExist, - BOOLEAN Verbose - ) -; - -STATUS -StringDBWriteDatabase ( - CHAR8 *DBFileName, - BOOLEAN Verbose - ) -; - -STATUS -StringDBDumpDatabase ( - CHAR8 *DBFileName, - CHAR8 *OutputFileName, - BOOLEAN Verbose - ) -; - -STATUS -StringDBAddLanguage ( - WCHAR *LanguageName, - WCHAR *PrintableLanguageName - ) -; - -STATUS -StringDBDumpCStrings ( - CHAR8 *FileName, - CHAR8 *BaseName, - WCHAR_STRING_LIST *LanguagesOfInterest, - WCHAR_MATCHING_STRING_LIST *IndirectionList - ) -; - -STATUS -StringDBDumpStringDefines ( - CHAR8 *FileName, - CHAR8 *BaseName - ) -; - -STATUS -StringDBSetCurrentLanguage ( - WCHAR *LanguageName - ) -; - -STATUS -StringDBSetStringReferenced ( - CHAR8 *StringIdentifierName, - BOOLEAN IgnoreNotFound - ) -; - -void -StringDBFormatString ( - WCHAR *String - ) -; - -#endif // #ifndef _STRING_DB_H_ diff --git a/Tools/CodeTools/TianoTools/StrGather/build.xml b/Tools/CodeTools/TianoTools/StrGather/build.xml deleted file mode 100644 index f01117777a..0000000000 --- a/Tools/CodeTools/TianoTools/StrGather/build.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/String/PrintLib.c b/Tools/CodeTools/TianoTools/String/PrintLib.c deleted file mode 100644 index eef3f4d083..0000000000 --- a/Tools/CodeTools/TianoTools/String/PrintLib.c +++ /dev/null @@ -1,674 +0,0 @@ -/*++ - -Copyright (c) 2004-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -Module Name: - - PrintLib.c - -Abstract: - - Print Library. - ---*/ - -#include -#include - -#include "CommonLib.h" -#include "PrintLibInternal.h" - -typedef struct { - RETURN_STATUS Status; - CHAR8 *String; -} STATUS_LOOKUP_TABLE_ENTRY; - -static CONST STATUS_LOOKUP_TABLE_ENTRY StatusString[] = { - { RETURN_SUCCESS, "Success" }, - { RETURN_LOAD_ERROR, "Load Error" }, - { RETURN_INVALID_PARAMETER, "Invalid Parameter" }, - { RETURN_UNSUPPORTED, "Unsupported" }, - { RETURN_BAD_BUFFER_SIZE, "Bad Buffer Size" }, - { RETURN_BUFFER_TOO_SMALL, "Buffer Too Small" }, - { RETURN_NOT_READY, "Not Ready" }, - { RETURN_DEVICE_ERROR, "Device Error" }, - { RETURN_WRITE_PROTECTED, "Write Protected" }, - { RETURN_OUT_OF_RESOURCES, "Out of Resources" }, - { RETURN_VOLUME_CORRUPTED, "Volume Corrupt" }, - { RETURN_VOLUME_FULL, "Volume Full" }, - { RETURN_NO_MEDIA, "No Media" }, - { RETURN_MEDIA_CHANGED, "Media changed" }, - { RETURN_NOT_FOUND, "Not Found" }, - { RETURN_ACCESS_DENIED, "Access Denied" }, - { RETURN_NO_RESPONSE, "No Response" }, - { RETURN_NO_MAPPING, "No mapping" }, - { RETURN_TIMEOUT, "Time out" }, - { RETURN_NOT_STARTED, "Not started" }, - { RETURN_ALREADY_STARTED, "Already started" }, - { RETURN_ABORTED, "Aborted" }, - { RETURN_ICMP_ERROR, "ICMP Error" }, - { RETURN_TFTP_ERROR, "TFTP Error" }, - { RETURN_PROTOCOL_ERROR, "Protocol Error" }, - { RETURN_WARN_UNKNOWN_GLYPH, "Warning Unknown Glyph" }, - { RETURN_WARN_DELETE_FAILURE, "Warning Delete Failure" }, - { RETURN_WARN_WRITE_FAILURE, "Warning Write Failure" }, - { RETURN_WARN_BUFFER_TOO_SMALL, "Warning Buffer Too Small" }, - { 0, NULL } -}; - - -/** - VSPrint function to process format and place the results in Buffer. Since a - VA_LIST is used this rountine allows the nesting of Vararg routines. Thus - this is the main print working routine - - @param StartOfBuffer Unicode buffer to print the results of the parsing of Format into. - - @param BufferSize Maximum number of characters to put into buffer. Zero means - no limit. - - @param Flags Intial flags value. Can only have FORMAT_UNICODE and OUTPUT_UNICODE set - - @param FormatString Unicode format string see file header for more details. - - @param Marker Vararg list consumed by processing Format. - - @return Number of characters printed. - -**/ -UINTN -BasePrintLibVSPrint ( - OUT CHAR8 *Buffer, - IN UINTN BufferSize, - IN UINTN Flags, - IN CONST CHAR8 *Format, - IN VA_LIST Marker - ) -{ - CHAR8 *OriginalBuffer; - CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS]; - UINTN BytesPerOutputCharacter; - UINTN BytesPerFormatCharacter; - UINTN FormatMask; - UINTN FormatCharacter; - UINTN Width; - UINTN Precision; - INT64 Value; - CHAR8 *ArgumentString; - UINTN Character; - GUID *TmpGuid; - TIME *TmpTime; - UINTN Count; - UINTN ArgumentMask; - INTN BytesPerArgumentCharacter; - UINTN ArgumentCharacter; - BOOLEAN Done; - UINTN Index; - CHAR8 Prefix; - BOOLEAN ZeroPad; - BOOLEAN Comma; - UINTN Digits; - UINTN Radix; - RETURN_STATUS Status; - - OriginalBuffer = Buffer; - - if ((Flags & OUTPUT_UNICODE) != 0) { - BytesPerOutputCharacter = 2; - } else { - BytesPerOutputCharacter = 1; - } - if ((Flags & FORMAT_UNICODE) != 0) { - BytesPerFormatCharacter = 2; - FormatMask = 0xffff; - } else { - BytesPerFormatCharacter = 1; - FormatMask = 0xff; - } - - // - // Reserve space for the Null terminator. - // If BufferSize is 0, this will set BufferSize to the max unsigned value - // - BufferSize--; - - // - // Get the first character from the format string - // - FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask; - - // - // Loop until the end of the format string is reached or the output buffer is full - // - while (FormatCharacter != 0 && BufferSize > 0) { - // - // Clear all the flag bits except those that may have been passed in - // - Flags &= (OUTPUT_UNICODE | FORMAT_UNICODE); - - // - // Set the default width to zero, and the default precision to 1 - // - Width = 0; - Precision = 1; - Prefix = 0; - Comma = FALSE; - ZeroPad = FALSE; - Count = 0; - Digits = 0; - - switch (FormatCharacter) { - case '%': - // - // Parse Flags and Width - // - for (Done = FALSE; !Done; ) { - Format += BytesPerFormatCharacter; - FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask; - switch (FormatCharacter) { - case '.': - Flags |= PRECISION; - break; - case '-': - Flags |= LEFT_JUSTIFY; - break; - case '+': - Flags |= PREFIX_SIGN; - break; - case ' ': - Flags |= PREFIX_BLANK; - break; - case ',': - Flags |= COMMA_TYPE; - break; - case 'L': - case 'l': - Flags |= LONG_TYPE; - break; - case '*': - if ((Flags & PRECISION) == 0) { - Flags |= PAD_TO_WIDTH; - Width = VA_ARG (Marker, UINTN); - } else { - Precision = VA_ARG (Marker, UINTN); - } - break; - case '0': - if ((Flags & PRECISION) == 0) { - Flags |= PREFIX_ZERO; - } - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - for (Count = 0; ((FormatCharacter >= '0') && (FormatCharacter <= '9')); ){ - Count = (Count * 10) + FormatCharacter - '0'; - Format += BytesPerFormatCharacter; - FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask; - } - Format -= BytesPerFormatCharacter; - if ((Flags & PRECISION) == 0) { - Flags |= PAD_TO_WIDTH; - Width = Count; - } else { - Precision = Count; - } - break; - default: - Done = TRUE; - break; - } - } - - // - // Limit the maximum field width to the remaining characters in the output buffer - // - if (Width > BufferSize) { - Width = BufferSize; - } - - // - // Handle each argument type - // - switch (FormatCharacter) { - case 'X': - Flags |= PREFIX_ZERO; - // - // break skiped on purpose - // - case 'x': - Flags |= RADIX_HEX; - // - // break skiped on purpose - // - case 'd': - if ((Flags & LONG_TYPE) == 0) { - Value = (VA_ARG (Marker, INTN)); - } else { - Value = VA_ARG (Marker, INT64); - } - if ((Flags & PREFIX_BLANK) != 0) { - Prefix = ' '; - } - if ((Flags & PREFIX_SIGN) != 0) { - Prefix = '+'; - } - if ((Flags & COMMA_TYPE) != 0) { - Comma = TRUE; - } - if ((Flags & RADIX_HEX) == 0) { - Radix = 10; - if (Comma) { - Flags &= (~PREFIX_ZERO); - Precision = 1; - } - if (Value < 0) { - Flags |= PREFIX_SIGN; - Prefix = '-'; - Value = -Value; - } - } else { - Radix = 16; - Comma = FALSE; - if ((Flags & LONG_TYPE) == 0 && Value < 0) { - Value = (UINTN)Value; - } - } - // - // Convert Value to a reversed string - // - Count = BasePrintLibValueToString (ValueBuffer, Value, Radix); - if (Value == 0 && Precision == 0) { - Count = 0; - } - ArgumentString = (CHAR8 *)ValueBuffer + Count; - Digits = 3 - (Count % 3); - if (Comma && Count != 0) { - Count += ((Count - 1) / 3); - } - if (Prefix != 0) { - Count++; - } - Flags |= ARGUMENT_REVERSED; - ZeroPad = TRUE; - if ((Flags & PREFIX_ZERO) != 0) { - if ((Flags & PAD_TO_WIDTH) != 0) { - if ((Flags & PRECISION) == 0) { - Precision = Width; - } - } - } - break; - - case 's': - case 'S': - Flags |= ARGUMENT_UNICODE; - // - // break skipped on purpose - // - case 'a': - ArgumentString = (CHAR8 *)VA_ARG (Marker, CHAR8 *); - if (ArgumentString == NULL) { - Flags &= (~ARGUMENT_UNICODE); - ArgumentString = ""; - } - break; - - case 'c': - Character = VA_ARG (Marker, UINTN) & 0xffff; - ArgumentString = (CHAR8 *)&Character; - Flags |= ARGUMENT_UNICODE; - break; - - case 'g': - TmpGuid = VA_ARG (Marker, GUID *); - if (TmpGuid == NULL) { - ArgumentString = ""; - } else { - BasePrintLibSPrint ( - ValueBuffer, - 0, - 0, - "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", - TmpGuid->Data1, - TmpGuid->Data2, - TmpGuid->Data3, - TmpGuid->Data4[0], - TmpGuid->Data4[1], - TmpGuid->Data4[2], - TmpGuid->Data4[3], - TmpGuid->Data4[4], - TmpGuid->Data4[5], - TmpGuid->Data4[6], - TmpGuid->Data4[7] - ); - ArgumentString = ValueBuffer; - } - break; - - case 't': - TmpTime = VA_ARG (Marker, TIME *); - if (TmpTime == NULL) { - ArgumentString = ""; - } else { - BasePrintLibSPrint ( - ValueBuffer, - 0, - 0, - "%02d/%02d/%04d %02d:%02d", - TmpTime->Month, - TmpTime->Day, - TmpTime->Year, - TmpTime->Hour, - TmpTime->Minute - ); - ArgumentString = ValueBuffer; - } - break; - - case 'r': - Status = VA_ARG (Marker, RETURN_STATUS); - ArgumentString = ValueBuffer; - for (Index = 0; StatusString[Index].String != NULL; Index++) { - if (Status == StatusString[Index].Status) { - ArgumentString = StatusString[Index].String; - } - } - if (ArgumentString == ValueBuffer) { - BasePrintLibSPrint ((CHAR8 *) ValueBuffer, 0, 0, "%08X", Status); - } - break; - - case '%': - default: - // - // if the type is '%' or unknown, then print it to the screen - // - ArgumentString = (CHAR8 *)&FormatCharacter; - Flags |= ARGUMENT_UNICODE; - break; - } - break; - case '\n': - ArgumentString = "\n"; - - break; - default: - ArgumentString = (CHAR8 *)&FormatCharacter; - Flags |= ARGUMENT_UNICODE; - break; - } - - // - // Retrieve the ArgumentString attriubutes - // - if ((Flags & ARGUMENT_UNICODE) != 0) { - ArgumentMask = 0xffff; - BytesPerArgumentCharacter = 2; - } else { - ArgumentMask = 0xff; - BytesPerArgumentCharacter = 1; - } - if ((Flags & ARGUMENT_REVERSED) != 0) { - BytesPerArgumentCharacter = -BytesPerArgumentCharacter; - } else { - // - // Compute the number of characters in ArgumentString and store it in Count - // ArgumentString is either null-terminated, or it contains Precision characters - // - for (Count = 0; Count < Precision || ((Flags & PRECISION) == 0); Count++) { - ArgumentCharacter = ((ArgumentString[Count * BytesPerArgumentCharacter] & 0xff) | ((ArgumentString[Count * BytesPerArgumentCharacter + 1]) << 8)) & ArgumentMask; - if (ArgumentCharacter == 0) { - break; - } - } - } - - // - // Limit the length of the string to append to the remaining characters in the output buffer - // - if (Count > BufferSize) { - Count = BufferSize; - } - if (Precision < Count) { - Precision = Count; - } - - // - // Pad before the string - // - if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH)) { - Buffer = BasePrintLibFillBuffer (Buffer, Width - Precision, ' ', BytesPerOutputCharacter); - } - - if (ZeroPad) { - if (Prefix != 0) { - Buffer = BasePrintLibFillBuffer (Buffer, 1, Prefix, BytesPerOutputCharacter); - } - Buffer = BasePrintLibFillBuffer (Buffer, Precision - Count, '0', BytesPerOutputCharacter); - } else { - Buffer = BasePrintLibFillBuffer (Buffer, Precision - Count, ' ', BytesPerOutputCharacter); - if (Prefix != 0) { - Buffer = BasePrintLibFillBuffer (Buffer, 1, Prefix, BytesPerOutputCharacter); - } - } - - // - // Output the Prefix character if it is present - // - Index = 0; - if (Prefix) { - Index++; - } - - // - // Copy the string into the output buffer performing the required type conversions - // - while (Index < Count) { - ArgumentCharacter = ((*ArgumentString & 0xff) | (*(ArgumentString + 1) << 8)) & ArgumentMask; - - Buffer = BasePrintLibFillBuffer (Buffer, 1, ArgumentCharacter, BytesPerOutputCharacter); - ArgumentString += BytesPerArgumentCharacter; - Index++; - if (Comma) { - Digits++; - if (Digits == 3) { - Digits = 0; - Index++; - if (Index < Count) { - Buffer = BasePrintLibFillBuffer (Buffer, 1, ',', BytesPerOutputCharacter); - } - } - } - } - - // - // Pad after the string - // - if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH | LEFT_JUSTIFY)) { - Buffer = BasePrintLibFillBuffer (Buffer, Width - Precision, ' ', BytesPerOutputCharacter); - } - - // - // Reduce the number of characters - // - BufferSize -= Count; - - // - // Get the next character from the format string - // - Format += BytesPerFormatCharacter; - - // - // Get the next character from the format string - // - FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask; - } - - // - // Null terminate the Unicode or ASCII string - // - Buffer = BasePrintLibFillBuffer (Buffer, 1, 0, BytesPerOutputCharacter); - - return ((Buffer - OriginalBuffer) / BytesPerOutputCharacter); -} - -UINTN -BasePrintLibSPrint ( - OUT CHAR8 *StartOfBuffer, - IN UINTN BufferSize, - IN UINTN Flags, - IN CONST CHAR8 *FormatString, - ... - ) -{ - VA_LIST Marker; - - VA_START (Marker, FormatString); - return BasePrintLibVSPrint (StartOfBuffer, BufferSize, Flags, FormatString, Marker); -} - -UINTN -EFIAPI -UnicodeVSPrint ( - OUT CHAR16 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR16 *FormatString, - IN VA_LIST Marker - ) -{ - return BasePrintLibVSPrint ((CHAR8 *)StartOfBuffer, BufferSize >> 1, FORMAT_UNICODE | OUTPUT_UNICODE, (CHAR8 *)FormatString, Marker); -} - -UINTN -EFIAPI -UnicodeSPrint ( - OUT CHAR16 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR16 *FormatString, - ... - ) -{ - VA_LIST Marker; - - VA_START (Marker, FormatString); - return UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker); -} - -UINTN -EFIAPI -UnicodeVSPrintAsciiFormat ( - OUT CHAR16 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR8 *FormatString, - IN VA_LIST Marker - ) -{ - return BasePrintLibVSPrint ((CHAR8 *)StartOfBuffer, BufferSize >> 1, OUTPUT_UNICODE,FormatString, Marker); -} - -UINTN -EFIAPI -UnicodeSPrintAsciiFormat ( - OUT CHAR16 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR8 *FormatString, - ... - ) -{ - VA_LIST Marker; - - VA_START (Marker, FormatString); - return UnicodeVSPrintAsciiFormat (StartOfBuffer, BufferSize >> 1, FormatString, Marker); -} - -UINTN -EFIAPI -AsciiVSPrint ( - OUT CHAR8 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR8 *FormatString, - IN VA_LIST Marker - ) -{ - return BasePrintLibVSPrint (StartOfBuffer, BufferSize, 0, FormatString, Marker); -} - -UINTN -EFIAPI -AsciiSPrint ( - OUT CHAR8 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR8 *FormatString, - ... - ) -{ - VA_LIST Marker; - - VA_START (Marker, FormatString); - return AsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker); -} - -UINTN -EFIAPI -AsciiVSPrintUnicodeFormat ( - OUT CHAR8 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR16 *FormatString, - IN VA_LIST Marker - ) -{ - return BasePrintLibVSPrint (StartOfBuffer, BufferSize, FORMAT_UNICODE, (CHAR8 *)FormatString, Marker); -} - -UINTN -EFIAPI -AsciiSPrintUnicodeFormat ( - OUT CHAR8 *StartOfBuffer, - IN UINTN BufferSize, - IN CONST CHAR16 *FormatString, - ... - ) -{ - VA_LIST Marker; - - VA_START (Marker, FormatString); - return AsciiVSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker); -} - -UINTN -EFIAPI -UnicodeValueToString ( - IN OUT CHAR16 *Buffer, - IN UINTN Flags, - IN INT64 Value, - IN UINTN Width - ) -{ - return BasePrintLibConvertValueToString ((CHAR8 *)Buffer, Flags, Value, Width, 2); -} - -UINTN -EFIAPI -AsciiValueToString ( - IN OUT CHAR8 *Buffer, - IN UINTN Flags, - IN INT64 Value, - IN UINTN Width - ) -{ - return BasePrintLibConvertValueToString ((CHAR8 *)Buffer, Flags, Value, Width, 1); -} diff --git a/Tools/CodeTools/TianoTools/String/PrintLibInternal.c b/Tools/CodeTools/TianoTools/String/PrintLibInternal.c deleted file mode 100644 index 63d0c7196f..0000000000 --- a/Tools/CodeTools/TianoTools/String/PrintLibInternal.c +++ /dev/null @@ -1,142 +0,0 @@ -/*++ - -Copyright (c) 2004-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -Module Name: - - PrintLibInternal.c - -Abstract: - - Print Library worker functions. - ---*/ - -#include -#include - -#include "CommonLib.h" -#include "PrintLibInternal.h" - -static CONST CHAR8 mHexStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; - -CHAR8 * -BasePrintLibFillBuffer ( - CHAR8 *Buffer, - INTN Length, - UINTN Character, - INTN Increment - ) -{ - INTN Index; - - for (Index = 0; Index < Length; Index++) { - *Buffer = (CHAR8) Character; - *(Buffer + 1) = (CHAR8) (Character >> 8); - Buffer += Increment; - } - return Buffer; -} - -/** - Print worker function that prints a Value as a decimal number in Buffer. - - @param Buffer Location to place the Unicode or ASCII string of Value. - - @param Value Value to convert to a Decimal or Hexidecimal string in Buffer. - - @param Flags Flags to use in printing string, see file header for details. - - @param Precision Minimum number of digits to return in the ASCII string - - @return Number of characters printed. - -**/ -UINTN -EFIAPI -BasePrintLibValueToString ( - IN OUT CHAR8 *Buffer, - IN INT64 Value, - IN UINTN Radix - ) -{ - UINTN Digits; - UINT32 Remainder; - - // - // Loop to convert one digit at a time in reverse order - // - *(Buffer++) = 0; - Digits = 0; - do { - // Value = (INT64)DivU64x32Remainder ((UINT64)Value, (UINT32)Radix, &Remainder); - Remainder = (UINT64)Value % (UINT32)Radix; - Value = (UINT64)Value / (UINT32)Radix; - *(Buffer++) = mHexStr[Remainder]; - Digits++; - } while (Value != 0); - return Digits; -} - -UINTN -BasePrintLibConvertValueToString ( - IN OUT CHAR8 *Buffer, - IN UINTN Flags, - IN INT64 Value, - IN UINTN Width, - IN UINTN Increment - ) -{ - CHAR8 *OriginalBuffer; - CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS]; - UINTN Count; - UINTN Digits; - UINTN Index; - - OriginalBuffer = Buffer; - - if (Width == 0 || (Flags & COMMA_TYPE) != 0) { - Flags &= (~PREFIX_ZERO); - } - - if (Width == 0 || Width > (MAXIMUM_VALUE_CHARACTERS - 1)) { - Width = MAXIMUM_VALUE_CHARACTERS - 1; - } - - if (Value < 0) { - Value = -Value; - Buffer = BasePrintLibFillBuffer (Buffer, 1, '-', Increment); - } - - Count = BasePrintLibValueToString (ValueBuffer, Value, 10); - - if ((Flags & PREFIX_ZERO) != 0) { - Buffer = BasePrintLibFillBuffer (Buffer, Width - Count, '0', Increment); - } - - Digits = 3 - (Count % 3); - for (Index = 0; Index < Count; Index++) { - Buffer = BasePrintLibFillBuffer (Buffer, 1, ValueBuffer[Count - Index], Increment); - if ((Flags & COMMA_TYPE) != 0) { - Digits++; - if (Digits == 3) { - Digits = 0; - if ((Index + 1) < Count) { - Buffer = BasePrintLibFillBuffer (Buffer, 1, ',', Increment); - } - } - } - } - - Buffer = BasePrintLibFillBuffer (Buffer, 1, 0, Increment); - - return ((Buffer - OriginalBuffer) / Increment); -} diff --git a/Tools/CodeTools/TianoTools/String/PrintLibInternal.h b/Tools/CodeTools/TianoTools/String/PrintLibInternal.h deleted file mode 100644 index 87f0955e05..0000000000 --- a/Tools/CodeTools/TianoTools/String/PrintLibInternal.h +++ /dev/null @@ -1,101 +0,0 @@ -/*++ - -Copyright (c) 2004-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -Module Name: - - PrintLibInternal.h - -Abstract: - - Print Library. - ---*/ - - - -// -// Print primitives -// -//#define LEFT_JUSTIFY 0x01 -#define PREFIX_SIGN 0x02 -#define PREFIX_BLANK 0x04 -//#define COMMA_TYPE 0x08 -#define LONG_TYPE 0x10 -//#define PREFIX_ZERO 0x20 -#define OUTPUT_UNICODE 0x40 -#define RADIX_HEX 0x80 -#define FORMAT_UNICODE 0x100 -#define PAD_TO_WIDTH 0x200 -#define ARGUMENT_UNICODE 0x400 -#define PRECISION 0x800 -#define ARGUMENT_REVERSED 0x1000 - -/// -/// Define the maximum number of characters that are required to encode -/// a decimal, hexidecimal, GUID, or TIME value with a Nll terminator. -/// Maximum Length Decimal String = 28 "-9,223,372,036,854,775,808" -/// Maximum Length Hexidecimal String = 17 "FFFFFFFFFFFFFFFF" -/// Maximum Length GUID = 37 "00000000-0000-0000-0000-000000000000" -/// Maximum Length TIME = 18 "12/12/2006 12:12" -/// -#define MAXIMUM_VALUE_CHARACTERS 38 - -// -// -// -typedef struct { - UINT16 Year; - UINT8 Month; - UINT8 Day; - UINT8 Hour; - UINT8 Minute; - UINT8 Second; - UINT8 Pad1; - UINT32 Nanosecond; - INT16 TimeZone; - UINT8 Daylight; - UINT8 Pad2; -} TIME; - -UINTN -BasePrintLibSPrint ( - OUT CHAR8 *Buffer, - IN UINTN BufferSize, - IN UINTN Flags, - IN CONST CHAR8 *FormatString, - ... - ); - -CHAR8 * -BasePrintLibFillBuffer ( - CHAR8 *Buffer, - INTN Length, - UINTN Character, - INTN Increment - ); - -UINTN -EFIAPI -BasePrintLibValueToString ( - IN OUT CHAR8 *Buffer, - IN INT64 Value, - IN UINTN Radix - ); - -UINTN -BasePrintLibConvertValueToString ( - IN OUT CHAR8 *Buffer, - IN UINTN Flags, - IN INT64 Value, - IN UINTN Width, - IN UINTN Increment - ); diff --git a/Tools/CodeTools/TianoTools/String/String.c b/Tools/CodeTools/TianoTools/String/String.c deleted file mode 100644 index 78d0a59fca..0000000000 --- a/Tools/CodeTools/TianoTools/String/String.c +++ /dev/null @@ -1,732 +0,0 @@ -/*++ - -Copyright (c) 2004-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -Module Name: - - String.c - -Abstract: - - Unicode and ASCII string primatives. - ---*/ - -#include - -#include - -#include - -#include "CommonLib.h" - -/** - Returns the length of a Null-terminated Unicode string. - - This function returns the number of Unicode characters in the Null-terminated - Unicode string specified by String. - - If String is NULL, then ASSERT(). - - @param String Pointer to a Null-terminated Unicode string. - - @return The length of String. - -**/ -UINTN -EFIAPI -StrLen ( - IN CONST CHAR16 *String - ) -{ - UINTN Length; - - ASSERT (String != NULL); - - for (Length = 0; *String != L'\0'; String++, Length++) { - ; - } - return Length; -} - -/** - Returns the length of a Null-terminated ASCII string. - - This function returns the number of ASCII characters in the Null-terminated - ASCII string specified by String. - - If String is NULL, then ASSERT(). - - @param String Pointer to a Null-terminated ASCII string. - - @return The length of String. - -**/ -UINTN -EFIAPI -AsciiStrLen ( - IN CONST CHAR8 *String - ) -{ - UINTN Length; - - ASSERT (String != NULL); - - for (Length = 0; *String != '\0'; String++, Length++) { - ; - } - return Length; -} - -/** - Copies one Null-terminated Unicode string to another Null-terminated Unicode - string and returns the new Unicode string. - - This function copies the contents of the Unicode string Source to the Unicode - string Destination, and returns Destination. If Source and Destination - overlap, then the results are undefined. - - If Destination is NULL, then ASSERT(). - If Source is NULL, then ASSERT(). - If Source and Destination overlap, then ASSERT(). - - @param Destination Pointer to a Null-terminated Unicode string. - @param Source Pointer to a Null-terminated Unicode string. - - @return Destiantion - -**/ -CHAR16 * -EFIAPI -StrCpy ( - OUT CHAR16 *Destination, - IN CONST CHAR16 *Source - ) -{ - CHAR16 *ReturnValue; - - // - // Destination cannot be NULL - // - ASSERT (Destination != NULL); - - // - // Destination and source cannot overlap - // - ASSERT ((UINTN)(Destination - Source) > StrLen (Source)); - ASSERT ((UINTN)(Source - Destination) > StrLen (Source)); - - ReturnValue = Destination; - while (*Source) { - *(Destination++) = *(Source++); - } - *Destination = 0; - return ReturnValue; -} - -/** - Copies one Null-terminated Unicode string with a maximum length to another - Null-terminated Unicode string with a maximum length and returns the new - Unicode string. - - This function copies the contents of the Unicode string Source to the Unicode - string Destination, and returns Destination. At most, Length Unicode - characters are copied from Source to Destination. If Length is 0, then - Destination is returned unmodified. If Length is greater that the number of - Unicode characters in Source, then Destination is padded with Null Unicode - characters. If Source and Destination overlap, then the results are - undefined. - - If Destination is NULL, then ASSERT(). - If Source is NULL, then ASSERT(). - If Source and Destination overlap, then ASSERT(). - - @param Destination Pointer to a Null-terminated Unicode string. - @param Source Pointer to a Null-terminated Unicode string. - @param Length Maximum number of Unicode characters to copy. - - @return Destination - -**/ -CHAR16 * -EFIAPI -StrnCpy ( - OUT CHAR16 *Destination, - IN CONST CHAR16 *Source, - IN UINTN Length - ) -{ - CHAR16 *ReturnValue; - - if (Length == 0) { - return Destination; - } - - // - // Destination cannot be NULL if Length is not zero - // - ASSERT (Destination != NULL); - - // - // Destination and source cannot overlap - // Q: Does Source have to be NULL-terminated? - // - ASSERT ((UINTN)(Destination - Source) > StrLen (Source)); - ASSERT ((UINTN)(Source - Destination) >= Length); - - ReturnValue = Destination; - - while ((*Source != L'\0') && (Length > 0)) { - *(Destination++) = *(Source++); - Length--; - } - - memset (Destination, 0, Length * sizeof (*Destination)); - return ReturnValue; -} - -/** - Returns the size of a Null-terminated Unicode string in bytes, including the - Null terminator. - - This function returns the size, in bytes, of the Null-terminated Unicode - string specified by String. - - If String is NULL, then ASSERT(). - - @param String Pointer to a Null-terminated Unicode string. - - @return The size of String. - -**/ -UINTN -EFIAPI -StrSize ( - IN CONST CHAR16 *String - ) -{ - return (StrLen (String) + 1) * sizeof (*String); -} - -/** - Compares two Null-terminated Unicode strings, and returns the difference - between the first mismatched Unicode characters. - - This function compares the Null-terminated Unicode string FirstString to the - Null-terminated Unicode string SecondString. If FirstString is identical to - SecondString, then 0 is returned. Otherwise, the value returned is the first - mismatched Unicode character in SecondString subtracted from the first - mismatched Unicode character in FirstString. - - If FirstString is NULL, then ASSERT(). - If SecondString is NULL, then ASSERT(). - - @param FirstString Pointer to a Null-terminated Unicode string. - @param SecondString Pointer to a Null-terminated Unicode string. - - @retval 0 FirstString is identical to SecondString. - @retval !=0 FirstString is not identical to SecondString. - -**/ -INTN -EFIAPI -StrCmp ( - IN CONST CHAR16 *FirstString, - IN CONST CHAR16 *SecondString - ) -{ - // - // ASSERT both strings should never be zero - // - ASSERT (StrSize (FirstString) != 0); - ASSERT (StrSize (SecondString) != 0); - - while ((*FirstString != L'\0') && (*FirstString == *SecondString)) { - FirstString++; - SecondString++; - } - return *FirstString - *SecondString; -} - -/** - Compares two Null-terminated Unicode strings with maximum lengths, and - returns the difference between the first mismatched Unicode characters. - - This function compares the Null-terminated Unicode string FirstString to the - Null-terminated Unicode string SecondString. At most, Length Unicode - characters will be compared. If Length is 0, then 0 is returned. If - FirstString is identical to SecondString, then 0 is returned. Otherwise, the - value returned is the first mismatched Unicode character in SecondString - subtracted from the first mismatched Unicode character in FirstString. - - If FirstString is NULL, then ASSERT(). - If SecondString is NULL, then ASSERT(). - - @param FirstString Pointer to a Null-terminated Unicode string. - @param SecondString Pointer to a Null-terminated Unicode string. - @param Length Maximum number of Unicode characters to compare. - - @retval 0 FirstString is identical to SecondString. - @retval !=0 FirstString is not identical to SecondString. - -**/ -INTN -EFIAPI -StrnCmp ( - IN CONST CHAR16 *FirstString, - IN CONST CHAR16 *SecondString, - IN UINTN Length - ) -{ - if (Length == 0) { - return 0; - } - - // - // ASSERT both strings should never be zero - // - ASSERT (StrSize (FirstString) != 0); - ASSERT (StrSize (SecondString) != 0); - - while ((*FirstString != L'\0') && - (*FirstString == *SecondString) && - (Length > 1)) { - FirstString++; - SecondString++; - Length--; - } - - return *FirstString - *SecondString; -} - -/** - Concatenates one Null-terminated Unicode string to another Null-terminated - Unicode string, and returns the concatenated Unicode string. - - This function concatenates two Null-terminated Unicode strings. The contents - of Null-terminated Unicode string Source are concatenated to the end of - Null-terminated Unicode string Destination. The Null-terminated concatenated - Unicode String is returned. If Source and Destination overlap, then the - results are undefined. - - If Destination is NULL, then ASSERT(). - If Source is NULL, then ASSERT(). - If Source and Destination overlap, then ASSERT(). - - @param Destination Pointer to a Null-terminated Unicode string. - @param Source Pointer to a Null-terminated Unicode string. - - @return Destination - -**/ -CHAR16 * -EFIAPI -StrCat ( - IN OUT CHAR16 *Destination, - IN CONST CHAR16 *Source - ) -{ - StrCpy (Destination + StrLen (Destination), Source); - - // - // Size of the resulting string should never be zero. - // - ASSERT (StrSize (Destination) != 0); - return Destination; -} - -/** - Concatenates one Null-terminated Unicode string with a maximum length to the - end of another Null-terminated Unicode string, and returns the concatenated - Unicode string. - - This function concatenates two Null-terminated Unicode strings. The contents - of Null-terminated Unicode string Source are concatenated to the end of - Null-terminated Unicode string Destination, and Destination is returned. At - most, Length Unicode characters are concatenated from Source to the end of - Destination, and Destination is always Null-terminated. If Length is 0, then - Destination is returned unmodified. If Source and Destination overlap, then - the results are undefined. - - If Destination is NULL, then ASSERT(). - If Source is NULL, then ASSERT(). - If Source and Destination overlap, then ASSERT(). - - @param Destination Pointer to a Null-terminated Unicode string. - @param Source Pointer to a Null-terminated Unicode string. - @param Length Maximum number of Unicode characters to concatenate from - Source. - - @return Destination - -**/ -CHAR16 * -EFIAPI -StrnCat ( - IN OUT CHAR16 *Destination, - IN CONST CHAR16 *Source, - IN UINTN Length - ) -{ - StrnCpy (Destination + StrLen (Destination), Source, Length); - - // - // Size of the resulting string should never be zero. - // - ASSERT (StrSize (Destination) != 0); - return Destination; -} - -/** - Copies one Null-terminated ASCII string to another Null-terminated ASCII - string and returns the new ASCII string. - - This function copies the contents of the ASCII string Source to the ASCII - string Destination, and returns Destination. If Source and Destination - overlap, then the results are undefined. - - If Destination is NULL, then ASSERT(). - If Source is NULL, then ASSERT(). - If Source and Destination overlap, then ASSERT(). - - @param Destination Pointer to a Null-terminated ASCII string. - @param Source Pointer to a Null-terminated ASCII string. - - @return Destination - -**/ -CHAR8 * -EFIAPI -AsciiStrCpy ( - OUT CHAR8 *Destination, - IN CONST CHAR8 *Source - ) -{ - CHAR8 *ReturnValue; - - // - // Destination cannot be NULL - // - ASSERT (Destination != NULL); - - // - // Destination and source cannot overlap - // - ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source)); - ASSERT ((UINTN)(Source - Destination) > AsciiStrLen (Source)); - - ReturnValue = Destination; - while (*Source) { - *(Destination++) = *(Source++); - } - *Destination = 0; - return ReturnValue; -} - -/** - Copies one Null-terminated ASCII string with a maximum length to another - Null-terminated ASCII string with a maximum length and returns the new ASCII - string. - - This function copies the contents of the ASCII string Source to the ASCII - string Destination, and returns Destination. At most, Length ASCII characters - are copied from Source to Destination. If Length is 0, then Destination is - returned unmodified. If Length is greater that the number of ASCII characters - in Source, then Destination is padded with Null ASCII characters. If Source - and Destination overlap, then the results are undefined. - - If Destination is NULL, then ASSERT(). - If Source is NULL, then ASSERT(). - If Source and Destination overlap, then ASSERT(). - - @param Destination Pointer to a Null-terminated ASCII string. - @param Source Pointer to a Null-terminated ASCII string. - @param Length Maximum number of ASCII characters to copy. - - @return Destination - -**/ -CHAR8 * -EFIAPI -AsciiStrnCpy ( - OUT CHAR8 *Destination, - IN CONST CHAR8 *Source, - IN UINTN Length - ) -{ - CHAR8 *ReturnValue; - - if (Length == 0) { - return Destination; - } - - // - // Destination cannot be NULL - // - ASSERT (Destination != NULL); - - // - // Destination and source cannot overlap - // - ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source)); - ASSERT ((UINTN)(Source - Destination) >= Length); - - ReturnValue = Destination; - - while (*Source && Length > 0) { - *(Destination++) = *(Source++); - Length--; - } - - // ZeroMem (Destination, Length * sizeof (*Destination)); - memset (Destination, 0, Length * sizeof (*Destination)); - return ReturnValue; -} - -/** - Returns the size of a Null-terminated ASCII string in bytes, including the - Null terminator. - - This function returns the size, in bytes, of the Null-terminated ASCII string - specified by String. - - If String is NULL, then ASSERT(). - - @param String Pointer to a Null-terminated ASCII string. - - @return The size of String. - -**/ -UINTN -EFIAPI -AsciiStrSize ( - IN CONST CHAR8 *String - ) -{ - return (AsciiStrLen (String) + 1) * sizeof (*String); -} - -/** - Compares two Null-terminated ASCII strings, and returns the difference - between the first mismatched ASCII characters. - - This function compares the Null-terminated ASCII string FirstString to the - Null-terminated ASCII string SecondString. If FirstString is identical to - SecondString, then 0 is returned. Otherwise, the value returned is the first - mismatched ASCII character in SecondString subtracted from the first - mismatched ASCII character in FirstString. - - If FirstString is NULL, then ASSERT(). - If SecondString is NULL, then ASSERT(). - - @param FirstString Pointer to a Null-terminated ASCII string. - @param SecondString Pointer to a Null-terminated ASCII string. - - @retval 0 FirstString is identical to SecondString. - @retval !=0 FirstString is not identical to SecondString. - -**/ -INTN -EFIAPI -AsciiStrCmp ( - IN CONST CHAR8 *FirstString, - IN CONST CHAR8 *SecondString - ) -{ - // - // ASSERT both strings should never be zero - // - ASSERT (AsciiStrSize (FirstString)); - ASSERT (AsciiStrSize (SecondString)); - - while ((*FirstString != '\0') && (*FirstString == *SecondString)) { - FirstString++; - SecondString++; - } - - return *FirstString - *SecondString; -} - -STATIC -CHAR8 -EFIAPI -AsciiToUpper ( - IN CHAR8 Chr - ) -{ - return (Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr; -} - -/** - Performs a case insensitive comparison of two Null-terminated ASCII strings, - and returns the difference between the first mismatched ASCII characters. - - This function performs a case insensitive comparison of the Null-terminated - ASCII string FirstString to the Null-terminated ASCII string SecondString. If - FirstString is identical to SecondString, then 0 is returned. Otherwise, the - value returned is the first mismatched lower case ASCII character in - SecondString subtracted from the first mismatched lower case ASCII character - in FirstString. - - If FirstString is NULL, then ASSERT(). - If SecondString is NULL, then ASSERT(). - - @param FirstString Pointer to a Null-terminated ASCII string. - @param SecondString Pointer to a Null-terminated ASCII string. - - @retval 0 FirstString is identical to SecondString using case insensitive - comparisons. - @retval !=0 FirstString is not identical to SecondString using case - insensitive comparisons. - -**/ -INTN -EFIAPI -AsciiStriCmp ( - IN CONST CHAR8 *FirstString, - IN CONST CHAR8 *SecondString - ) -{ - // - // ASSERT both strings should never be zero - // - ASSERT (AsciiStrSize (FirstString)); - ASSERT (AsciiStrSize (SecondString)); - - while ((*FirstString != '\0') && - (AsciiToUpper (*FirstString) == AsciiToUpper (*SecondString))) { - FirstString++; - SecondString++; - } - - return AsciiToUpper (*FirstString) - AsciiToUpper (*SecondString); -} - -/** - Compares two Null-terminated ASCII strings with maximum lengths, and returns - the difference between the first mismatched ASCII characters. - - This function compares the Null-terminated ASCII string FirstString to the - Null-terminated ASCII string SecondString. At most, Length ASCII characters - will be compared. If Length is 0, then 0 is returned. If FirstString is - identical to SecondString, then 0 is returned. Otherwise, the value returned - is the first mismatched ASCII character in SecondString subtracted from the - first mismatched ASCII character in FirstString. - - If FirstString is NULL, then ASSERT(). - If SecondString is NULL, then ASSERT(). - - @param FirstString Pointer to a Null-terminated ASCII string. - @param SecondString Pointer to a Null-terminated ASCII string. - - @retval 0 FirstString is identical to SecondString. - @retval !=0 FirstString is not identical to SecondString. - -**/ -INTN -EFIAPI -AsciiStrnCmp ( - IN CONST CHAR8 *FirstString, - IN CONST CHAR8 *SecondString, - IN UINTN Length - ) -{ - // - // ASSERT both strings should never be zero - // - ASSERT (AsciiStrSize (FirstString)); - ASSERT (AsciiStrSize (SecondString)); - - while ((*FirstString != '\0') && - (*FirstString == *SecondString) && - (Length > 1)) { - FirstString++; - SecondString++; - Length--; - } - return *FirstString - *SecondString; -} - -/** - Concatenates one Null-terminated ASCII string to another Null-terminated - ASCII string, and returns the concatenated ASCII string. - - This function concatenates two Null-terminated ASCII strings. The contents of - Null-terminated ASCII string Source are concatenated to the end of Null- - terminated ASCII string Destination. The Null-terminated concatenated ASCII - String is returned. - - If Destination is NULL, then ASSERT(). - If Source is NULL, then ASSERT(). - - @param Destination Pointer to a Null-terminated ASCII string. - @param Source Pointer to a Null-terminated ASCII string. - - @return Destination - -**/ -CHAR8 * -EFIAPI -AsciiStrCat ( - IN OUT CHAR8 *Destination, - IN CONST CHAR8 *Source - ) -{ - AsciiStrCpy (Destination + AsciiStrLen (Destination), Source); - - // - // Size of the resulting string should never be zero. - // - ASSERT (AsciiStrSize (Destination) != 0); - return Destination; -} - -/** - Concatenates one Null-terminated ASCII string with a maximum length to the - end of another Null-terminated ASCII string, and returns the concatenated - ASCII string. - - This function concatenates two Null-terminated ASCII strings. The contents - of Null-terminated ASCII string Source are concatenated to the end of Null- - terminated ASCII string Destination, and Destination is returned. At most, - Length ASCII characters are concatenated from Source to the end of - Destination, and Destination is always Null-terminated. If Length is 0, then - Destination is returned unmodified. If Source and Destination overlap, then - the results are undefined. - - If Destination is NULL, then ASSERT(). - If Source is NULL, then ASSERT(). - If Source and Destination overlap, then ASSERT(). - - @param Destination Pointer to a Null-terminated ASCII string. - @param Source Pointer to a Null-terminated ASCII string. - @param Length Maximum number of ASCII characters to concatenate from - Source. - - @return Destination - -**/ -CHAR8 * -EFIAPI -AsciiStrnCat ( - IN OUT CHAR8 *Destination, - IN CONST CHAR8 *Source, - IN UINTN Length - ) -{ - AsciiStrnCpy (Destination + AsciiStrLen (Destination), Source, Length); - - // - // Size of the resulting string should never be zero. - // - ASSERT (AsciiStrSize (Destination) != 0); - return Destination; -} diff --git a/Tools/CodeTools/TianoTools/String/build.xml b/Tools/CodeTools/TianoTools/String/build.xml deleted file mode 100644 index 933cb5c1e4..0000000000 --- a/Tools/CodeTools/TianoTools/String/build.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/Strip/Strip.c b/Tools/CodeTools/TianoTools/Strip/Strip.c deleted file mode 100644 index bccdffb55a..0000000000 --- a/Tools/CodeTools/TianoTools/Strip/Strip.c +++ /dev/null @@ -1,105 +0,0 @@ -/*++ - -Copyright (c) 2004-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -Module Name: - - Strip.c - -Abstract: - - Quick Exe2Bin equivalent. - ---*/ - -#include -#include -#include -#include - -int -main ( - int argc, - char *argv[] - ) -/*++ - -Routine Description: - - Converts executable files to binary files. - -Arguments: - - argc - Number of command line arguments - argv[] - Array of pointers to the command line arguments - -Returns: - - Zero - Function completed successfully. - Non-zero - Function exited with errors. - ---*/ -{ - FILE *InFile; - FILE *OutFile; - int Index; - int FileSize; - char *Buffer; - char *Ptrx; - - if (argc < 3) { - printf ("Need more args, such as file name to convert and output name\n"); - return -1; - } - - InFile = fopen (argv[1], "rb"); - OutFile = fopen (argv[2], "wb"); - - if (!InFile) { - printf ("no file, exit\n"); - return -1; - } - - if (OutFile == NULL) { - printf ("Unable to open output file.\n"); - return -1; - } - - fseek (InFile, 0, SEEK_END); - FileSize = ftell (InFile); - - if (FileSize < 0x200) { - printf ("%d is not a legal size, exit\n", FileSize); - return -1; - } - - fseek (InFile, 0, SEEK_SET); - - Buffer = (char *) malloc (FileSize); - if (Buffer == NULL) { - printf ("Error: Out of resources.\n"); - return -1; - } - - fread (Buffer, 1, FileSize, InFile); - - Ptrx = Buffer + 0x200; - - Index = FileSize - 0x200; - - fwrite (Ptrx, Index, 1, OutFile); - - fclose (InFile); - fclose (OutFile); - free (Buffer); - - return 0; -} diff --git a/Tools/CodeTools/TianoTools/Strip/build.xml b/Tools/CodeTools/TianoTools/Strip/build.xml deleted file mode 100644 index 9ead28d16f..0000000000 --- a/Tools/CodeTools/TianoTools/Strip/build.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/TianoTools.msa b/Tools/CodeTools/TianoTools/TianoTools.msa deleted file mode 100644 index 2e4b27c19d..0000000000 --- a/Tools/CodeTools/TianoTools/TianoTools.msa +++ /dev/null @@ -1,316 +0,0 @@ - - - - Tiano C Tools - TOOL - A169C678-3F55-4b6a-80BF-FD8B8DCAB883 - 2.0 - This is the TianoTools Module - This Module provides the EFI/Tiano Tools that are used to create EFI/Tiano - Modules and Platform Binary Files (PBF) - These tools require compilation only once if the Developer Workstation and - the Developer's choice of HOST tool chain are stable. If the developer - updates either the OS or the HOST tool chain, these tools should be rebuilt. - Copyright 2006, Intel Corporation - All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the -BSD License which accompanies this distribution. The full text of the -license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 - - - EBC IA32 X64 IPF - false - NULL - - - build.xml - Common/build.xml - Common/CommonLib.c - Common/CommonLib.h - Common/Crc32.c - Common/Crc32.h - Common/EfiCompress.c - Common/EfiCompress.h - Common/EfiCustomizedCompress.h - Common/EfiDecompress.c - Common/EfiDecompress.h - Common/EfiUtilityMsgs.c - Common/EfiUtilityMsgs.h - Common/FvLib.c - Common/FvLib.h - Common/MyAlloc.c - Common/MyAlloc.h - Common/ParseInf.c - Common/ParseInf.h - Common/SimpleFileParsing.c - Common/SimpleFileParsing.h - Common/WinNtInclude.h - CompressDll/build.xml - CompressDll/CompressDll.c - CompressDll/CompressDll.h - CreateMtFile/build.xml - CreateMtFile/CreateMtFile.c - CustomizedCompress/build.xml - CustomizedCompress/CustomizedCompress.c - EfiCompress/build.xml - EfiCompress/EfiCompressMain.c - EfiCompress/makefile - EfiRom/build.xml - EfiRom/EfiRom.c - FlashMap/build.xml - FlashMap/FlashDefFile.c - FlashMap/FlashDefFile.h - FlashMap/FlashMap.c - FlashMap/Microcode.c - FlashMap/Microcode.h - FlashMap/Symbols.c - FlashMap/Symbols.h - FwImage/build.xml - FwImage/fwimage.c - GenAcpiTable/build.xml - GenAcpiTable/GenAcpiTable.c - GenCapsuleHdr/build.xml - GenCapsuleHdr/CreateGuid.c - GenCapsuleHdr/GenCapsuleHdr.c - GenCRC32Section/build.xml - GenCRC32Section/GenCRC32Section.c - GenCRC32Section/GenCRC32Section.h - GenDepex/build.xml - GenDepex/DepexParser.c - GenDepex/DepexParser.h - GenDepex/GenDepex.c - GenDepex/GenDepex.h - GenFfsFile/build.xml - GenFfsFile/GenFfsFile.c - GenFfsFile/GenFfsFile.h - GenFfsFile/SimpleFileParsing.c - GenFvImage/build.xml - GenFvImage/Ebc/PeCoffLoaderEx.c - GenFvImage/GenFvImageExe.c - GenFvImage/GenFvImageExe.h - GenFvImage/GenFvImageLib.c - GenFvImage/GenFvImageLib.h - GenFvImage/GenFvImageLibInternal.h - GenSection/build.xml - GenSection/GenSection.c - GenSection/GenSection.h - GenTEImage/build.xml - GenTEImage/GenTEImage.c - GuidChk/build.xml - GuidChk/CommonUtils.h - GuidChk/FileSearch.c - GuidChk/FileSearch.h - GuidChk/GuidChk.c - GuidChk/GuidList.c - GuidChk/UtilsMsgs.c - GuidChk/UtilsMsgs.h - Include/Common/BaseTypes.h - Include/Common/Capsule.h - Include/Common/Dependency.h - Include/Common/EfiImage.h - Include/Common/FirmwareFileSystem.h - Include/Common/FirmwareVolumeHeader.h - Include/Common/FirmwareVolumeImageFormat.h - Include/Common/InternalFormRepresentation.h - Include/Common/MultiPhase.h - Include/Common/UefiBaseTypes.h - Include/Common/Variable.h - Include/Common/WorkingBlockHeader.h - Include/Guid/AcpiTableStorage.h - Include/Guid/Apriori.h - Include/Guid/Capsule.h - Include/Guid/FirmwareFileSystem.h - Include/Ia32/ProcessorBind.h - Include/IndustryStandard/pci22.h - Include/Library/PeCoffLib.h - Include/Library/PrintLib.h - Include/Protocol/DevicePath.h - Include/Protocol/GuidedSectionExtraction.h - Include/Protocol/Hii.h - Include/Protocol/UgaDraw.h - MakeDeps/build.xml - MakeDeps/MakeDeps.c - ModifyInf/build.xml - ModifyInf/ModifyInf.c - Pccts/antlr/antlr.1 - Pccts/antlr/antlr.c - Pccts/antlr/antlr.g - Pccts/antlr/antlr.ilk - Pccts/antlr/antlr.pdb - Pccts/antlr/antlr.r - Pccts/antlr/antlr1.txt - Pccts/antlr/AntlrMS.mak - Pccts/antlr/AntlrPPC.mak - Pccts/antlr/bits.c - Pccts/antlr/build.c - Pccts/antlr/build.xml - Pccts/antlr/dumpcycles.c - Pccts/antlr/dumpnode.c - Pccts/antlr/egman.c - Pccts/antlr/err.c - Pccts/antlr/fcache.c - Pccts/antlr/fset.c - Pccts/antlr/fset2.c - Pccts/antlr/gen.c - Pccts/antlr/generic.h - Pccts/antlr/globals.c - Pccts/antlr/hash.c - Pccts/antlr/hash.h - Pccts/antlr/lex.c - Pccts/antlr/main.c - Pccts/antlr/makefile - Pccts/antlr/makefile1 - Pccts/antlr/misc.c - Pccts/antlr/mode.h - Pccts/antlr/mrhoist.c - Pccts/antlr/parser.dlg - Pccts/antlr/pred.c - Pccts/antlr/proto.h - Pccts/antlr/README - Pccts/antlr/scan.c - Pccts/antlr/stdpccts.h - Pccts/antlr/syn.h - Pccts/antlr/tokens.h - Pccts/antlr/vc70.pdb - Pccts/build.xml - Pccts/CHANGES_FROM_131.txt - Pccts/CHANGES_FROM_133.txt - Pccts/CHANGES_FROM_133_BEFORE_MR13.txt - Pccts/CHANGES_SUMMARY.txt - Pccts/dlg/automata.c - Pccts/dlg/build.xml - Pccts/dlg/dlg.1 - Pccts/dlg/dlg.h - Pccts/dlg/dlg.r - Pccts/dlg/dlg1.txt - Pccts/dlg/dlg_a.c - Pccts/dlg/dlg_p.c - Pccts/dlg/dlg_p.g - Pccts/dlg/DlgMS.mak - Pccts/dlg/DlgPPC.mak - Pccts/dlg/err.c - Pccts/dlg/main.c - Pccts/dlg/makefile - Pccts/dlg/makefile1 - Pccts/dlg/mode.h - Pccts/dlg/output.c - Pccts/dlg/parser.dlg - Pccts/dlg/relabel.c - Pccts/dlg/stdpccts.h - Pccts/dlg/support.c - Pccts/dlg/tokens.h - Pccts/h/antlr.h - Pccts/h/AParser.cpp - Pccts/h/AParser.h - Pccts/h/ast.c - Pccts/h/ast.h - Pccts/h/ASTBase.cpp - Pccts/h/ASTBase.h - Pccts/h/AToken.h - Pccts/h/ATokenBuffer.cpp - Pccts/h/ATokenBuffer.h - Pccts/h/ATokenStream.h - Pccts/h/ATokPtr.h - Pccts/h/ATokPtrImpl.h - Pccts/h/BufFileInput.cpp - Pccts/h/BufFileInput.h - Pccts/h/charbuf.h - Pccts/h/charptr.c - Pccts/h/charptr.h - Pccts/h/config.h - Pccts/h/DLexer.h - Pccts/h/DLexerBase.cpp - Pccts/h/DLexerBase.h - Pccts/h/DLG_stream_input.h - Pccts/h/dlgauto.h - Pccts/h/dlgdef.h - Pccts/h/err.h - Pccts/h/int.h - Pccts/h/PBlackBox.h - Pccts/h/pccts_assert.h - Pccts/h/pccts_iostream.h - Pccts/h/pccts_istream.h - Pccts/h/pccts_setjmp.h - Pccts/h/pccts_stdarg.h - Pccts/h/pccts_stdio.h - Pccts/h/pccts_stdlib.h - Pccts/h/pccts_string.h - Pccts/h/PCCTSAST.cpp - Pccts/h/PCCTSAST.h - Pccts/h/pcctscfg.h - Pccts/h/pcnames.bat - Pccts/h/slist.cpp - Pccts/h/SList.h - Pccts/history.ps - Pccts/history.txt - Pccts/KNOWN_PROBLEMS.txt - Pccts/makefile - Pccts/MPW_Read_Me - Pccts/NOTES.bcc - Pccts/NOTES.msvc - Pccts/README - Pccts/RIGHTS - Pccts/support/genmk/genmk.c - Pccts/support/genmk/genmk_old.c - Pccts/support/genmk/makefile - Pccts/support/rexpr/makefile - Pccts/support/rexpr/rexpr.c - Pccts/support/rexpr/rexpr.h - Pccts/support/rexpr/test.c - Pccts/support/set/set.c - Pccts/support/set/set.h - Pccts/support/sym/sym.c - Pccts/support/sym/template.h - PeCoffLoader/BasePeCoff.c - PeCoffLoader/build.xml - PeCoffLoader/Common/EfiImage.h - PeCoffLoader/Ia32/PeCoffLoaderEx.c - PeCoffLoader/Ipf/PeCoffLoaderEx.c - PeCoffLoader/X64/PeCoffLoaderEx.c - PeiRebase/build.xml - PeiRebase/makefile - PeiRebase/PeiRebaseExe.c - PeiRebase/PeiRebaseExe.h - SecApResetVectorFixup/build.xml - SecApResetVectorFixup/SecApResetVectorFixup.c - SecApResetVectorFixup/SecApResetVectorFixup.h - SecFixup/build.xml - SecFixup/SecFixup.c - SecFixup/SecFixup.h - SetStamp/build.xml - SetStamp/SetStamp.c - SplitFile/build.xml - SplitFile/SplitFile.c - StrGather/build.xml - StrGather/StrGather.c - StrGather/StrGather.h - StrGather/StringDB.c - StrGather/StringDB.h - String/build.xml - String/PrintLib.c - String/PrintLibInternal.c - String/PrintLibInternal.h - String/String.c - Strip/build.xml - Strip/Strip.c - VfrCompile/build.xml - VfrCompile/DLGLexer.cpp - VfrCompile/DLGLexer.h - VfrCompile/EfiVfr.h - VfrCompile/EfiVfrParser.cpp - VfrCompile/EfiVfrParser.h - VfrCompile/parser.dlg - VfrCompile/tokens.h - VfrCompile/VfrCompile.cpp - VfrCompile/VfrCompile.g - VfrCompile/VfrServices.cpp - VfrCompile/VfrServices.h - ZeroDebugData/build.xml - ZeroDebugData/ZeroDebugData.c - - \ No newline at end of file diff --git a/Tools/CodeTools/TianoTools/VfrCompile/EfiVfr.h b/Tools/CodeTools/TianoTools/VfrCompile/EfiVfr.h deleted file mode 100644 index 6419ad7e71..0000000000 --- a/Tools/CodeTools/TianoTools/VfrCompile/EfiVfr.h +++ /dev/null @@ -1,181 +0,0 @@ -/*++ - -Copyright (c) 2004 - 2005, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - EfiVfr.h - -Abstract: - - Defines and prototypes for the EFI internal forms representation - setup protocol and drivers - ---*/ - -#ifndef _EFI_VFR_H_ -#define _EFI_VFR_H_ - -#include - -#include -#include - -// -// This number should be incremented with each change to the VFR compiler. -// We write the version to the output list file for debug purposes. -// -#define VFR_COMPILER_VERSION "1.88" - -// -// Maximum file path for filenames -// -#ifndef MAX_PATH -#define MAX_PATH 255 -#endif -#define MAX_QUEUE_COUNT 255 -#define MAX_LINE_LEN 1024 -#define PROGRAM_NAME "VfrCompile" - -// -// We parse C-style structure definitions which can then be referenced -// in VFR statements. -// We need to define an internal structure that can be used to -// track the fields in a structure definition, and another structure -// to keep track of the structure name and subfields. -// -typedef struct _STRUCT_FIELD_DEFINITION { - struct _STRUCT_FIELD_DEFINITION *Next; - int DataSize; - int Offset; // from the start of the structure - int ArrayLength; - char IsArray; - char *Name; -} STRUCT_FIELD_DEFINITION; - -typedef struct _STRUCT_DEFINITION { - struct _STRUCT_DEFINITION *Next; - int Size; - int LineNum; // line number where the structure was defined - int IsNonNV; // if this is the non-NV data structure definition - int Referenced; // if it's referenced anywhere in the VFR - int VarStoreIdValid; // found a 'varstore' statement for it in the VFR - unsigned short VarStoreId; // key from a varstore IFR statement - int VarStoreLineNum; // line number where VARSTORE was defined - char *Name; - STRUCT_FIELD_DEFINITION *Field; - STRUCT_FIELD_DEFINITION *LastField; -} STRUCT_DEFINITION; - -// -// For the IdEqValList variable list of UINT16's, keep track of them using -// a linked list until we know how many there are. -// We also use a linked list of these to keep track of labels used in -// the VFR script so we can catch duplicates. -// We'll also use it to keep track of defined varstore id's so we can -// detect duplicate definitions. -// -typedef struct _UINT16_LIST { - struct _UINT16_LIST *Next; - UINT16 Value; - UINT32 LineNum; -} UINT16_LIST; - -typedef struct _GOTO_REFERENCE { - struct _GOTO_REFERENCE *Next; - UINT32 RefLineNum; // line number of source file where referenced - UINT16 Value; -} GOTO_REFERENCE; - -typedef struct _FORM_ID_VALUE { - struct _FORM_ID_VALUE *Next; - UINT32 LineNum; - UINT16 Value; -} FORM_ID_VALUE; - -// -// We keep track in the parser of all "#line 4 "x.y"" strings so we -// can cross-reference the line numbers in the preprocessor output .i file -// to the original input files. -// -typedef struct _PARSER_LINE_DEFINITION { - struct _PARSER_LINE_DEFINITION *Next; - UINT32 HashLineNum; // from the #line stmt - UINT32 TokenLineNum; // line number in the .i file - CHAR8 *FileName; // from the #line stmt -} PARSER_LINE_DEFINITION; - -extern PARSER_LINE_DEFINITION *gLineDefinition; -extern PARSER_LINE_DEFINITION *gLastLineDefinition; - -extern -char * -ConvertLineNumber ( - UINT32 *LineNum - ) -/*++ - -Routine Description: - Given the line number in the preprocessor-output file, use the line number - information we've saved to determine the source file name and line number - where the code originally came from. This is required for error reporting. - -Arguments: - LineNum - the line number in the preprocessor-output file. - -Returns: - Returns a pointer to the source file name. Also returns the line number - in the provided LineNum argument - ---*/ -; - -typedef struct _IFR_BYTE { - struct _IFR_BYTE *Next; - UINT32 LineNum; - UINT8 OpcodeByte; - UINT8 KeyByte; -} IFR_BYTE; - -typedef struct { - CHAR8 VfrFileName[MAX_PATH]; - CHAR8 VfrListFileName[MAX_PATH]; - INT8 CreateListFile; - INT8 CreateIfrBinFile; - CHAR8 IfrOutputFileName[MAX_PATH]; - CHAR8 OutputDirectory[MAX_PATH]; - CHAR8 PreprocessorOutputFileName[MAX_PATH]; - CHAR8 VfrBaseFileName[MAX_PATH]; // name of input VFR file with no path or extension - CHAR8 *IncludePaths; - CHAR8 *CPreprocessorOptions; -} OPTIONS; - -extern OPTIONS gOptions; - -VOID -WriteStandardFileHeader ( - FILE *OutFptr - ) -/*++ - -Routine Description: - This function is invoked to emit a standard header to an - output text file. - -Arguments: - OutFptr - file to write the header to - -Returns: - None - ---*/ -; - -#endif // #ifndef _EFI_VFR_H_ diff --git a/Tools/CodeTools/TianoTools/VfrCompile/VfrCompile.g b/Tools/CodeTools/TianoTools/VfrCompile/VfrCompile.g deleted file mode 100644 index 44820bc31b..0000000000 --- a/Tools/CodeTools/TianoTools/VfrCompile/VfrCompile.g +++ /dev/null @@ -1,3529 +0,0 @@ -/*++ - -Copyright (c) 2004 - 2005, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - VfrCompile.g - -Abstract: - - PCCTS parser and lexer definitions for the EFI VFR forms compiler - ---*/ - -#header<< - -#include -#include -#include -#include -#include - -#include "CommonLib.h" -#include "EfiUtilityMsgs.h" -#include "EfiVfr.h" -#include "VfrServices.h" - -#include -#ifndef __GNUC__ -#include -#include // for spawn functions -#else -#include -#endif - ->> - -<< - -// -// Base info for DLG-generated scanner -// -#include "DLexerBase.h" - -// -// Include the scanner file generated by DLG -// -#include "DLGLexer.h" - -class DLGLexerVfr : public DLGLexer -{ -public: - DLGLexerVfr (DLGFileInput *F) : DLGLexer (F) {}; - INT32 errstd (char *Text) - { - printf ("unrecognized input '%s'\n", Text); - } - -}; - -// -// Base token definitions for ANTLR -// -#include "AToken.h" - -// -// This is how we invoke the C preprocessor on the VFR source file -// to resolve #defines, #includes, etc. To make C source files -// shareable between VFR and drivers, define VFRCOMPILE so that -// #ifdefs can be used in shared .h files. -// -#ifdef __GNUC__ -#define PREPROCESSOR_COMMAND "gcc " -#define PREPROCESSOR_OPTIONS "-x c -E -P -DVFRCOMPILE " -#define FILE_SEP_CHAR '/' -#define FILE_SEP_STRING "/" -#else -#define PREPROCESSOR_COMMAND "cl.exe " -#define PREPROCESSOR_OPTIONS "/nologo /P /TC /DVFRCOMPILE " -#define FILE_SEP_CHAR '/' -#define FILE_SEP_STRING "/" -#endif - -typedef ANTLRCommonToken ANTLRToken; - -// -// Specify the filename extensions for the files we generate. -// -#define VFR_BINARY_FILENAME_EXTENSION ".c" -#define VFR_LIST_FILENAME_EXTENSION ".lst" - -static -VOID -Usage (); - -static -STATUS -ProcessArgs ( - int Argc, - char *Argv[] - ); - -static -VOID -Cleanup (); - -// -// Globals -// -OPTIONS gOptions; - -int -main ( - int argc, - char **argv - ) -/*++ - -Routine Description: - Application entry point function. Parse command-line arguments, - invoke the parser, clean up, and return. - -Arguments: - argc - standard argc passed to main() per C conventions - argv - standard argv passed to main() per C conventions - -Returns: - STATUS_SUCCESS - program executed with no errors or warnings - STATUS_WARNING - program executed with warnings - STATUS_ERROR - non-recoverable errors encountered while processing - ---*/ -{ - FILE *VfrFptr; - char *Cmd; - char *Cptr; - int Len; - STATUS Status; - - // - // Set our program name for the error printing routines. - // Then set printing limits. - // - SetUtilityName (PROGRAM_NAME); - SetPrintLimits (20, 20, 30); - // - // Process the command-line arguments - // - if (ProcessArgs (argc, argv) != STATUS_SUCCESS) { - Usage (); - Cleanup(); - return STATUS_ERROR; - } - VfrFptr = NULL; - // - // Verify the VFR script file exists - // - if ((VfrFptr = fopen (gOptions.VfrFileName, "r")) == NULL) { - Error (PROGRAM_NAME, 0, 0, gOptions.VfrFileName, "could not open input VFR file"); - Cleanup(); - return STATUS_ERROR; - } - // - // Now close the file and make a system call to run the preprocessor - // on it. - // - fclose (VfrFptr); - Len = strlen (PREPROCESSOR_OPTIONS) + strlen (gOptions.VfrFileName) + 10; - if (gOptions.CPreprocessorOptions != NULL) { - Len += strlen (gOptions.CPreprocessorOptions) + 1; - } - if (gOptions.IncludePaths != NULL) { - Len += strlen (gOptions.IncludePaths) + 1; - } - Cmd = (char *)malloc (Len); - if (Cmd == NULL) { - Error (PROGRAM_NAME, 0, 0, NULL, "could not allocate memory"); - Cleanup(); - return STATUS_ERROR; - } - strcpy (Cmd, PREPROCESSOR_OPTIONS); - if (gOptions.IncludePaths != NULL) { - strcat (Cmd, gOptions.IncludePaths); - strcat (Cmd, " "); - } - if (gOptions.CPreprocessorOptions != NULL) { - strcat (Cmd, gOptions.CPreprocessorOptions); - strcat (Cmd, " "); - } - strcat (Cmd, gOptions.VfrFileName); -#ifndef __GNUC__ - Status = _spawnlp (_P_WAIT, PREPROCESSOR_COMMAND, Cmd, NULL); -#else - { - char CommandLine[1000]; - char *p; - - // - // Lean the slashes forward. - // - for (p = gOptions.PreprocessorOutputFileName; *p; p++) { - if (*p=='\\') { - *p=FILE_SEP_CHAR; - } - } - - // - // Lean the slashes forward. - // - for (p = Cmd; *p; p++) { - if (*p=='\\') { - *p=FILE_SEP_CHAR; - } - } - - sprintf(CommandLine, "%s %s > %s", PREPROCESSOR_COMMAND, Cmd, gOptions.PreprocessorOutputFileName); - Status = system (CommandLine); - } -#endif - if (Status != 0) { - Error (PROGRAM_NAME, 0, 0, gOptions.VfrFileName, "failed to spawn C preprocessor on VFR file"); - printf ("Command: '%s %s'\n", PREPROCESSOR_COMMAND, Cmd); - Cleanup(); - return STATUS_ERROR; - } - free (Cmd); - // - // Open the preprocessor output file - // - if ((VfrFptr = fopen (gOptions.PreprocessorOutputFileName, "r")) == NULL) { - Error (PROGRAM_NAME, 0, 0, "failed to open input VFR preprocessor output file", - gOptions.PreprocessorOutputFileName); - Cleanup(); - return STATUS_ERROR; - } - // - // Define input VFR file - // - DLGFileInput InputFile (VfrFptr); - // - // Define an instance of the scanner - // - DLGLexerVfr Scanner (&InputFile); - // - // Define token buffer between scanner and parser - // - ANTLRTokenBuffer Pipe (&Scanner); - // - // Create a token to use as a model - // - ANTLRToken Tok; - // - // Tell the scanner what type the token is - // - Scanner.setToken (&Tok); - // - // Create an instance of our parser - // - EfiVfrParser Parser (&Pipe); - // - // Initialize the parser - // - Parser.init (); - Status = GetUtilityStatus (); - if (Status != STATUS_SUCCESS) { - Cleanup(); - return Status; - } - // - // Start the first rule - // - Parser.program (); - // - // Close the input script file - // - fclose (VfrFptr); - Parser.WriteIfrBytes (); - // - // Call cleanup, which does some extra checking of the script - // - Parser.Cleanup (); - Cleanup(); - // - // If we had an error somewhere, delete our output files so that - // a subsequent build will rebuild them. - // - Status = GetUtilityStatus (); - if (Status == STATUS_ERROR) { - remove (gOptions.IfrOutputFileName); - } - return Status; -} -static -VOID -Cleanup () -/*++ - -Routine Description: - Free up memory allocated during parsing. - -Arguments: - None - -Returns: - None - ---*/ -{ - // - // Free up our string we allocated to track the include paths - // - if (gOptions.IncludePaths != NULL) { - free (gOptions.IncludePaths); - gOptions.IncludePaths = NULL; - } - // - // Free up our string we allocated to track preprocessor options - // - if (gOptions.CPreprocessorOptions != NULL) { - free (gOptions.CPreprocessorOptions); - gOptions.CPreprocessorOptions = NULL; - } -} - -static -STATUS -ProcessArgs ( - int Argc, - char *Argv[] - ) -/*++ - -Routine Description: - Process the command-line arguments. - -Arguments: - Argc - standard argc passed to main() - Argv - standard argv passed to main() - -Returns: - STATUS_SUCCESS - program should continue (all args ok) - ---*/ -{ - char *IncludePaths; - char *CPreprocessorOptions; - int Len; - char CopyStr[MAX_PATH]; - char *Cptr; - - // - // Put options in known state. - // - memset ((char *)&gOptions, 0, sizeof (OPTIONS)); - // - // Go through all the arguments that start with '-' - // - Argc--; - Argv++; - while ((Argc > 0) && (Argv[0][0] == '-')) { - // - // -? or -h help option -- return an error for printing usage - // - if ((stricmp (Argv[0], "-?") == 0) || (stricmp (Argv[0], "-h") == 0)) { - return STATUS_ERROR; - break; - // - // -l to create a listing output file - // - } else if (stricmp (Argv[0], "-l") == 0) { - gOptions.CreateListFile = 1; - // - // -I include_path option for finding include files. We'll pass this - // to the preprocessor. Turn them all into a single include string. - // - } else if (stricmp (Argv[0], "-i") == 0) { - if ((Argc < 2) || (Argv[1][0] == '-')) { - Error (PROGRAM_NAME, 0, 0, Argv[0], "missing path argument"); - return STATUS_ERROR; - } - Argc--; - Argv++; - Len = strlen (" -I "); - Len += strlen (Argv[0]) + 2; - if (gOptions.IncludePaths != NULL) { - Len += strlen (gOptions.IncludePaths); - } - IncludePaths = (CHAR8 *)malloc (Len); - if (IncludePaths == NULL) { - Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); - return STATUS_ERROR; - } - IncludePaths[0] = 0; - if (gOptions.IncludePaths != NULL) { - strcpy (IncludePaths, gOptions.IncludePaths); - free (gOptions.IncludePaths); - } - strcat (IncludePaths, " -I "); - strcat (IncludePaths, Argv[0]); - gOptions.IncludePaths = IncludePaths; - // - // -od OutputDirectory to define a common directory for output files - // - } else if (stricmp (Argv[0], "-od") == 0) { - if ((Argc < 2) || (Argv[1][0] == '-')) { - Error (PROGRAM_NAME, 0, 0, Argv[0], "missing output directory name"); - return STATUS_ERROR; - } - Argc--; - Argv++; - strcpy (gOptions.OutputDirectory, Argv[0]); - } else if (stricmp (Argv[0], "-ibin") == 0) { - gOptions.CreateIfrBinFile = 1; - } else if (stricmp (Argv[0], "-nostrings") == 0) { - // deprecated option - // - // -ppflag C-preprocessor-flag option for passing options to the C preprocessor. - // Turn them all into a single string. - // - } else if (stricmp (Argv[0], "-ppflag") == 0) { - if (Argc < 2) { - Error (PROGRAM_NAME, 0, 0, Argv[0], "missing C-preprocessor argument"); - return STATUS_ERROR; - } - Argc--; - Argv++; - Len = strlen (Argv[0]) + 2; - if (gOptions.CPreprocessorOptions != NULL) { - Len += strlen (gOptions.CPreprocessorOptions); - } - CPreprocessorOptions = (CHAR8 *)malloc (Len); - if (CPreprocessorOptions == NULL) { - Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); - return STATUS_ERROR; - } - CPreprocessorOptions[0] = 0; - if (gOptions.CPreprocessorOptions != NULL) { - strcpy (CPreprocessorOptions, gOptions.CPreprocessorOptions); - free (gOptions.CPreprocessorOptions); - } - strcat (CPreprocessorOptions, " "); - strcat (CPreprocessorOptions, Argv[0]); - gOptions.CPreprocessorOptions = CPreprocessorOptions; - } else { - Error (PROGRAM_NAME, 0, 0, Argv[0], "unrecognized option"); - return STATUS_ERROR; - } - Argc--; - Argv++; - } - // - // Must specify at least the vfr file name - // - if (Argc > 1) { - Error (PROGRAM_NAME, 0, 0, Argv[1], "unrecognized argument after VFR file name"); - return STATUS_ERROR; - } else if (Argc < 1) { - Error (PROGRAM_NAME, 0, 0, NULL, "must specify VFR file name"); - return STATUS_ERROR; - } - strcpy (gOptions.VfrFileName, Argv[0]); - // - // We run the preprocessor on the VFR file to manage #include statements. - // Unfortunately the preprocessor does not allow you to specify the - // output name or path of the resultant .i file, so we have to do - // some work. Here we'll extract the basename of the VFR file, then - // append .i on the end. - // - strcpy (CopyStr, gOptions.VfrFileName); - Cptr = CopyStr + strlen (CopyStr) - 1; - for (;(Cptr > CopyStr) && (*Cptr != '\\') && (*Cptr != ':') && (*Cptr != '/'); Cptr--); - if (Cptr == CopyStr) { - strcpy (gOptions.PreprocessorOutputFileName, Cptr); - strcpy (gOptions.VfrBaseFileName, Cptr); - } else { - strcpy (gOptions.PreprocessorOutputFileName, Cptr+1); - strcpy (gOptions.VfrBaseFileName, Cptr+1); - } - for (Cptr = gOptions.PreprocessorOutputFileName; *Cptr && (*Cptr != '.'); Cptr++); - strcpy (Cptr, ".i"); - // - // Terminate the vfr file basename at the extension - // - for (Cptr = gOptions.VfrBaseFileName; *Cptr && (*Cptr != '.'); Cptr++) { - } - *Cptr = 0; - // - // If they defined an output directory, prepend all output files - // with the working directory. Output files of interest: - // VfrListFileName -- list file - // IfrOutputFileName -- IFR bytes - // StringOutputFileName -- string bytes - // StringListFileName -- not used - // StringDefineFileName -- #defines of string identifiers - // - // We have two cases: - // 1. Output directory (-od) not specified, in which case output files - // go to the current working directory. - // 2. Output directory specified, in which case the output files - // go directly to the specified directory. - // - if (gOptions.OutputDirectory[0] == 0) { - CopyStr[0] = 0; -#ifndef __GNUC__ - _getcwd (CopyStr, sizeof (CopyStr)); -#else - getcwd (CopyStr, sizeof (CopyStr)); -#endif - strcpy (gOptions.OutputDirectory, CopyStr); - } - // - // Make sure output directory has a trailing backslash - // - if (gOptions.OutputDirectory[strlen (gOptions.OutputDirectory) - 1] != '\\' || - gOptions.OutputDirectory[strlen (gOptions.OutputDirectory) - 1] != '/') { - strcat (gOptions.OutputDirectory, FILE_SEP_STRING); - } - // - // Create the base output file name as: path\base, copy it to all the output - // filenames, and then add the appropriate extension to each. - // - strcpy (gOptions.VfrListFileName, gOptions.OutputDirectory); - strcat (gOptions.VfrListFileName, gOptions.VfrBaseFileName); - strcpy (gOptions.IfrOutputFileName, gOptions.VfrListFileName); - strcat (gOptions.VfrListFileName, VFR_LIST_FILENAME_EXTENSION); - strcat (gOptions.IfrOutputFileName, VFR_BINARY_FILENAME_EXTENSION); - // - // We set a default list file name, so if they do not - // want a list file, null out the name now. - // - if (gOptions.CreateListFile == 0) { - gOptions.VfrListFileName[0] = 0; - } - return STATUS_SUCCESS; -} -static -VOID -Usage () -/*++ - -Routine Description: - Print utility usage instructions - -Arguments: - None - -Returns: - None - ---*/ -{ - int Index; - const char *Help[] = { - " ", - "VfrCompile version " VFR_COMPILER_VERSION, - " ", - " Usage: VfrCompile {options} [VfrFile]", - " ", - " where options include:", - " -? or -h prints this help", - " -l create an output IFR listing file", - " -i IncPath add IncPath to the search path for VFR included files", - " -od OutputDir deposit all output files to directory OutputDir (default=cwd)", - " -ibin create an IFR HII pack file", - " where parameters include:", - " VfrFile name of the input VFR script file", - " ", - NULL - }; - for (Index = 0; Help[Index] != NULL; Index++) { - fprintf (stdout, "%s\n", Help[Index]); - } -} - ->> - - -#lexaction -<< - -#include "EfiVfr.h" - -PARSER_LINE_DEFINITION *gLineDefinition = NULL; -PARSER_LINE_DEFINITION *gLastLineDefinition = NULL; - -VOID -AddFileLine ( - char *TokenString, - UINT32 TokenLine - ) -/*++ - -Routine Description: - During the lexer phase, if we encounter a #line statement output by - the preprocessor, this function gets called. We'll save off the info - for error reporting purposes. The preprocessor line information has the - form: - - #line 3 "FileName.c" - -Arguments: - TokenString - the parsed string as shown above - TokenLine - the line number in the preprocessed output file - -Returns: - NA - ---*/ -{ - PARSER_LINE_DEFINITION *LineDef; - CHAR8 *Cptr; - - // - // Allocate a structure in which we can keep track of this line information. - // - LineDef = (PARSER_LINE_DEFINITION *)malloc (sizeof (PARSER_LINE_DEFINITION)); - memset ((char *)LineDef, 0, sizeof (PARSER_LINE_DEFINITION)); - LineDef->TokenLineNum = TokenLine; - LineDef->HashLineNum = atoi (TokenString + 6); - // - // Find the quotes in the filename, then allocate space in the line - // def structure for a copy of the filename. Finally, copy it without - // quotes to the line def. - // - for (Cptr = TokenString + 7; *Cptr && (*Cptr != '"'); Cptr++); - if (*Cptr == '"') { - LineDef->FileName = (CHAR8 *)malloc (strlen (Cptr)); - Cptr++; - strcpy (LineDef->FileName, Cptr); - for (Cptr = LineDef->FileName; *Cptr && (*Cptr != '"'); Cptr++); - *Cptr = 0; - // - // Now add this new one to the list - // - if (gLineDefinition == NULL) { - gLineDefinition = LineDef; - } else { - gLastLineDefinition->Next = LineDef; - } - gLastLineDefinition = LineDef; - } else { - Error (PROGRAM_NAME, 0, 0, "invalid line definition in preprocessor output file", TokenString); - free (LineDef); - return; - } -} -char * -ConvertLineNumber ( - UINT32 *LineNum - ) -/*++ - -Routine Description: - Given the line number in the preprocessor-output file, use the line number - information we've saved to determine the source file name and line number - where the code originally came from. This is required for error reporting. - -Arguments: - LineNum - the line number in the preprocessor-output file. - -Returns: - Returns a pointer to the source file name. Also returns the line number - in the provided LineNum argument - ---*/ -{ - PARSER_LINE_DEFINITION *LineDef; - // - // Step through our linked list of #line information we saved off. - // For each one, look at its line number, and the line number of the - // next record, and see if the passed-in line number is in the range. - // If it is, then convert the line number to the appropriate line number - // of the original source file. - // - for (LineDef = gLineDefinition; LineDef != NULL; LineDef = LineDef->Next) { - // - // The given LineNum is the line number from the .i file. - // Find a line definition whose range includes this line number, - // convert the line number, and return the filename. - // - if (LineDef->TokenLineNum <= *LineNum) { - if (LineDef->Next != NULL) { - if (LineDef->Next->TokenLineNum > *LineNum) { - *LineNum = *LineNum - LineDef->TokenLineNum + LineDef->HashLineNum; - return LineDef->FileName; - } - } else { - // - // Last one in the list of line definitions, so has to be right - // - *LineNum = *LineNum - LineDef->TokenLineNum + LineDef->HashLineNum; - return LineDef->FileName; - } - } - } - return NULL; -} - ->> - -// -// Define a lexical class for parsing quoted strings. Basically -// starts with a double quote, and ends with a double quote that -// is not preceeded with a backslash. -// -#lexclass QUOTED_STRING -#token TheString "~[\"]*\"" << mode (START); >> - -// -// Define a lexical class for parsing "#pragma pack" statements. -// We do this just for convenience (since we skip them here) so -// that users can include some minimal .h files. -// -#lexclass PRAGMA_PACK -#token "pack" << skip (); >> -#token "[\ \t]" << skip (); >> -#token "\(" << skip (); >> -#token "[0-9]*" << skip (); >> -#token "\)" << skip (); mode (START); >> - -// -// Define a lexclass for skipping over C++ style comments -// -#lexclass CPP_COMMENT -#token "~[\n]*" << skip (); >> -#token "\n" << skip (); mode (START); newline (); >> - -// -// Standard lexclass is START -// -#lexclass START - -// -// Find start of C++ style comments -// -#token "//" << skip (); mode (CPP_COMMENT); >> - -// -// Skip whitespace -// -#token "[\ \t]" << skip (); >> - -// -// Skip over newlines, but count them -// -#token "\n" << skip (); newline (); >> - -// -// Skip pragma pack statements -// -#token "\#pragma" << skip (); mode(PRAGMA_PACK); >> - -// -// Skip over 'extern' in any included .H file -// -#token "extern" << skip (); >> - -// -// Tokens for the different keywords. Syntax is: -// TokenName("ErrorMessageText") "TokenString" -// where: -// TokenName is the token name (must be capitalized) that is used in the rules -// ErrorMessageText is the string the compiler emits when it detects a syntax error -// TokenString is the actual matching string used in the user script -// -#token LineDefinition "#line\ [0-9]+\ \"~[\"]+\"[\ \t]*\n" << AddFileLine (begexpr (), line ()); skip (); >> -#token FormSet("formset") "formset" -#token EndFormSet("endformset") "endformset" -#token Title("title") "title" -#token FormId("formid") "formid" -#token OneOf("oneof") "oneof" -#token Prompt("prompt") "prompt" -#token OrderedList("orderedlist") "orderedlist" -#token EndList("endlist") "endlist" -#token EndForm("endform") "endform" -#token EndOneOf("endoneof") "endoneof" -#token Form("form") "form" -#token Subtitle("subtitle") "subtitle" -#token Help("help") "help" -#token VarId("varid") "varid" -#token Text("text") "text" -#token Option("option") "option" -#token Value("value") "value" -#token Flags("flags") "flags" -#token Date("date") "date" -#token EndDate("enddate") "enddate" -#token Year("year") "year" -#token Month("month") "month" -#token Day("day") "day" -#token Time("time") "time" -#token EndTime("endtime") "endtime" -#token Hour("hour") "hour" -#token Minute("minute") "minute" -#token Second("second") "second" -#token AND("AND") "AND" -#token OR("OR") "OR" -#token GrayOutIf("grayoutif") "grayoutif" -#token NOT("NOT") "NOT" -#token Label("label") "label" -#token Timeout("timeout") "timeout" -#token Inventory("inventory") "inventory" -#token StringToken("STRING_TOKEN") "STRING_TOKEN" -#token NonNvDataMap("_NON_NV_DATA_MAP") "_NON_NV_DATA_MAP" -#token Struct("struct") "struct" -#token Uint64("UINT64") "UINT64" -#token Uint32("UINT32") "UINT32" -#token Uint16("UINT16") "UINT16" -#token Char16("CHAR16") "CHAR16" -#token Uint8("UINT8") "UINT8" -#token Guid("guid") "guid" -#token CheckBox("checkbox") "checkbox" -#token EndCheckBox("endcheckbox") "endcheckbox" -#token Numeric("numeric") "numeric" -#token EndNumeric("endnumeric") "endnumeric" -#token Minimum("minimum") "minimum" -#token Maximum("maximum") "maximum" -#token Step("step") "step" -#token Default("default") "default" -#token Password("password") "password" -#token EndPassword("endpassword") "endpassword" -#token String("string") "string" -#token EndString("endstring") "endstring" -#token MinSize("minsize") "minsize" -#token MaxSize("maxsize") "maxsize" -#token Encoding("encoding") "encoding" -#token SuppressIf("suppressif") "suppressif" -#token Hidden("hidden") "hidden" -#token Goto("goto") "goto" -#token InconsistentIf "inconsistentif" -#token EndIf("endif") "endif" -#token IdEqId("ideqid") "ideqid" -#token IdEqVal("ideqval") "ideqval" -#token VarEqVal("vareqval") "vareqval" -#token Var("var") "var" -#token IdEqValList("ideqvallist") "ideqvallist" -#token Length("length") "length" -#token Values("values") "values" -#token Key("key") "key" -#token DefaultFlag("DEFAULT") "DEFAULT" -#token ManufacturingFlag("MANUFACTURING") "MANUFACTURING" -#token InteractiveFlag("INTERACTIVE") "INTERACTIVE" -#token NVAccessFlag("NV_ACCESS") "NV_ACCESS" -#token ResetRequiredFlag("RESET_REQUIRED") "RESET_REQUIRED" -#token LateCheckFlag("LATE_CHECK") "LATE_CHECK" -#token Class("class") "class" -#token Subclass("subclass") "subclass" -#token TypeDef("typedef") "typedef" -#token Restore("restore") "restore" -#token Save("save") "save" -#token Defaults("defaults") "defaults" -#token Banner("banner") "banner" -#token Align("align") "align" -#token Left("left") "left" -#token Right("right") "right" -#token Center("center") "center" -#token Line("line") "line" -#token VarStore("varstore") "varstore" -#token Name("name") "name" -#token Oem("oem") "oem" -#token True("TRUE") "TRUE" -#token False("FALSE") "FALSE" -#token GreaterThan(">") ">" -#token GreaterEqual(">=") ">=" -#token LessThan("<") "<" -#token LessEqual("<=") "<=" - -// -// Define the class and subclass tokens -// -#token ClassNonDevice("NONDEVICE") "NON_DEVICE" -#token ClassDiskDevice("DISK_DEVICE") "DISK_DEVICE" -#token ClassVideoDevice("VIDEO_DEVICE") "VIDEO_DEVICE" -#token ClassNetworkDevice("NETWORK_DEVICE") "NETWORK_DEVICE" -#token ClassInputDevice("INPUT_DEVICE") "INPUT_DEVICE" -#token ClassOnBoardDevice("ONBOARD_DEVICE") "ONBOARD_DEVICE" -#token ClassOtherDevice("OTHER_DEVICE") "OTHER_DEVICE" - -#token SubclassSetupApplication("SETUP_APPLICATION") "SETUP_APPLICATION" -#token SubclassGeneralApplication("GENERAL_APPLICATION") "GENERAL_APPLICATION" -#token SubclassFrontPage("FRONT_PAGE") "FRONT_PAGE" -#token SubclassSingleUse("SINGLE_USE") "SINGLE_USE" - -#token LanguageIdentifier("language identifier") "[a-z][a-z][a-z]" // 3 lowercase characters -#token StringIdentifier("string identifier") "[A-Za-z_][A-Za-z_0-9]*" -#token Number("numeric value") "(0x[0-9A-Fa-f]+) | [0-9]+" -#token OpenBrace("{") "\{" -#token CloseBrace("}") "\}" -#token OpenParen("(") "\(" -#token CloseParen(")") "\)" -#token OpenBracket("[") "\[" -#token CloseBracket("]") "\]" - -// -// Define all other invalid characters so that they get through the lexical phase -// and we can catch them during the parse phase. We get much better error -// messages then. -// -#token InvalidCharacters("invalid characters") "~[;:=,\.\|]" - -// -// This is the overall definition of a VFR form definition script. -// -program : - ( dataStructDefinition )* - formSetStatement - ( vfrStatementVarStore )* - ( formDefinition )* - EFS:EndFormSet ";" << WriteOpByte (EFS->getLine(), EFI_IFR_END_FORM_SET_OP); >> - "@" // end of file - ; - -formSetStatement : - FS:FormSet << WriteOpByte (FS->getLine(), EFI_IFR_FORM_SET_OP); >> - Guid "=" - OpenBrace - G1:Number "," - G2:Number "," - G3:Number "," - OpenBrace - G4:Number "," - G5:Number "," - G6:Number "," - G7:Number "," - G8:Number "," - G9:Number "," - G10:Number "," - G11:Number - CloseBrace - CloseBrace << WriteGuidValue (G1->getLine (), G1->getText (), G2->getText (), G3->getText (), - G4->getText (), G5->getText (), G6->getText (), G7->getText (), - G8->getText (), G9->getText (), G10->getText (), G11->getText () - ); - >> - "," - Title "=" getStringId "," - Help "=" getStringId "," - // - // insert padding for an EFI_PHYSICAL_ADDRESS (UINT64) - // - << WriteDWord (0, 0); WriteDWord (0, 0); >> - Class "=" CVAL:classDefinition "," << WriteClass (); >> - Subclass "=" SVAL:subclassDefinition "," << WriteSubclass (); >> - << WriteWord (mNvDataStructSize); >> - ; - -// -// A form can be of multiple classes, thus allow CLASS_A | CLASS_B | CLASS_C -// -classDefinition : - validClassNames ( "\|" validClassNames )* - ; - -validClassNames : - CND:ClassNonDevice << SetClass (CND->getLine(), EFI_NON_DEVICE_CLASS); >> - | CDD:ClassDiskDevice << SetClass (CDD->getLine(), EFI_DISK_DEVICE_CLASS); >> - | CVD:ClassVideoDevice << SetClass (CVD->getLine(), EFI_VIDEO_DEVICE_CLASS); >> - | CNW:ClassNetworkDevice << SetClass (CNW->getLine(), EFI_NETWORK_DEVICE_CLASS); >> - | CID:ClassInputDevice << SetClass (CID->getLine(), EFI_INPUT_DEVICE_CLASS); >> - | COB:ClassOnBoardDevice << SetClass (COB->getLine(), EFI_ON_BOARD_DEVICE_CLASS); >> - | COD:ClassOtherDevice << SetClass (COD->getLine(), EFI_OTHER_DEVICE_CLASS); >> - | CNUM:Number << SetClass (CNUM->getLine(), GetNumber (CNUM->getText(), CNUM->getLine(), 4)); >> - ; << PrintErrorMessage (LT(1)->getLine(), LT(1)->getText(), "invalid class"); >> - -// -// A form can only be of one subclass type. -// -subclassDefinition : - SSA:SubclassSetupApplication << SetSubclass (SSA->getLine(), EFI_SETUP_APPLICATION_SUBCLASS); >> - | SGA:SubclassGeneralApplication << SetSubclass (SGA->getLine(), EFI_GENERAL_APPLICATION_SUBCLASS); >> - | SFP:SubclassFrontPage << SetSubclass (SFP->getLine(), EFI_FRONT_PAGE_SUBCLASS); >> - | SSU:SubclassSingleUse << SetSubclass (SSU->getLine(), EFI_SINGLE_USE_SUBCLASS); >> - | SNUM:Number << SetSubclass (SNUM->getLine(), GetNumber (SNUM->getText(), SNUM->getLine(), 4)); >> - ; << PrintErrorMessage (LT(1)->getLine(), LT(1)->getText(), "invalid subclass"); >> - -// -// Parse a C type data structure for storing VFR setup data. Allow: -// typedef struct _XXX_ { -// (fields) -// } MY_NV_DATA; -// -dataStructDefinition : - << int IsNonNV = 0; >> - { TypeDef } - S:Struct - ( - NonNvDataMap << IsNonNV = 1; >> - | - { StringIdentifier } - ) << StartStructDefinition (IsNonNV, S->getLine()); >> - OpenBrace - dataStructFields - CloseBrace NAME:StringIdentifier << EndStructDefinition (NAME->getText(), NAME->getLine()); >> - ";" - ; - -// -// Parse a C type data structure for defining data that is not stored in NV. -// typedef struct _NON_NV_DATA_MAP { -// (fields) -// } NON_NV_DATA_MAP; -// -nonNvDataStructDefinition : - { TypeDef } - Struct NonNvDataMap - { StringIdentifier } - OpenBrace - dataStructFields - CloseBrace NAME:StringIdentifier << AddStructField (NAME->getText(), NAME->getLine(), 0, 0, 0); >> - ";" - ; - -dataStructFields : - ( dataStructField64 | dataStructField32 | dataStructField16 | dataStructField8 ) * - ; - -//***************************************************************************** -// -// PARSE: -// UINT64 Name[4]; -// UINT64 Name; -// -// Used while parsing the NV data map structures. -// -dataStructField64 : - << int ArrayLength = 1; char IsArray = 0; >> - "UINT64" - NAME:StringIdentifier - ( ";" | OpenBracket IVal:Number CloseBracket ";" << ArrayLength = GetNumber (IVal->getText(), IVal->getLine(), 4); IsArray = 1; >> ) - << AddStructField (NAME->getText(), NAME->getLine(), 8, ArrayLength, IsArray); >> - ; - -//***************************************************************************** -// -// PARSE: -// UINT32 Name[4]; -// UINT32 Name; -// -// Used while parsing the NV data map structures. -// -dataStructField32 : - << int ArrayLength = 1; char IsArray = 0; >> - "UINT32" - NAME:StringIdentifier - ( ";" | OpenBracket IVal:Number CloseBracket ";" << ArrayLength = GetNumber (IVal->getText(), IVal->getLine(), 4); IsArray = 1; >> ) - << AddStructField (NAME->getText(), NAME->getLine(), 4, ArrayLength, IsArray); >> - ; - -//***************************************************************************** -// -// PARSE: -// UINT16 Name[4]; -// UINT16 Name; -// -// Used while parsing the NV data map structures. -// -dataStructField16 : - << int ArrayLength = 1; char IsArray = 0; >> - ( "UINT16" | "CHAR16" ) - NAME:StringIdentifier - ( ";" | OpenBracket IVal:Number CloseBracket ";" << ArrayLength = GetNumber (IVal->getText(), IVal->getLine(), 4); IsArray = 1; >> ) - << AddStructField (NAME->getText(), NAME->getLine(), 2, ArrayLength, IsArray); >> - ; - -//***************************************************************************** -// -// PARSE: -// UINT8 Name[4]; -// UINT8 Name; -// -// Used while parsing the NV data map structures. -// -dataStructField8 : - << int ArrayLength = 1; char IsArray = 0; >> - "UINT8" - NAME:StringIdentifier - ( ";" | OpenBracket IVal:Number CloseBracket ";" << ArrayLength = GetNumber (IVal->getText(), IVal->getLine(), 4); IsArray = 1; >> ) - << AddStructField (NAME->getText(), NAME->getLine(), 1, ArrayLength, IsArray); >> - ; - -//***************************************************************************** -// -// PARSE: -// form formid = 1, -// title = STRING_TOKEN(STR_FORM_TITLE); -// -- form statements -- -// endform; -// -// The Form ID cannot be 0 -// -formDefinition : - FRM:Form FormId << WriteOpByte (FRM->getLine(), EFI_IFR_FORM_OP); >> - "=" - VAL:Number << WriteWord (GetNumber (VAL->getText(), VAL->getLine(), 2)); AddFormId (GetNumber (VAL->getText(), VAL->getLine(), 2), VAL->getLine()); >> - "," - Title "=" getStringId ";" // writes string identifier - ( vfrStatements )* - ENDF:EndForm ";" << WriteOpByte (ENDF->getLine(), EFI_IFR_END_FORM_OP); >> - ; - -// -// VFR statements in a formset -// -vfrStatements : - vfrStatementSubTitle | - vfrStatementOneOf | - vfrStatementTextText | - vfrStatementCheckBox | - vfrStatementNumeric | - vfrStatementDate | - vfrStatementTime | - vfrStatementPassword | - vfrStatementString | - vfrStatementSuppressIf | - vfrStatementHidden | - vfrStatementGoto | - vfrStatementGrayOutIf | - vfrStatementInconsistentIf | - vfrStatementLabel | - vfrStatementBanner | - vfrStatementInventory | - vfrStatementOrderedList | - vfrStatementOem | - vfrStatementSaveRestoreDefaults - ; - -//***************************************************************************** -// -// PARSE: -// label 100; -// -vfrStatementLabel : - OPID:Label << WriteOpByte (OPID->getLine(), EFI_IFR_LABEL_OP); >> - VAL:Number << - WriteWord (GetNumber (VAL->getText(), VAL->getLine(), 2)); - AddLabel (GetNumber (VAL->getText(), VAL->getLine(), 2), VAL->getLine()); - >> - ";" - ; - -//***************************************************************************** -// -// PARSE: -// oem 0x12, 0x34, 0x56; -// -vfrStatementOem : - OPID:Oem << WriteOpByte (OPID->getLine(), EFI_IFR_OEM_DEFINED_OP); >> - ( VAL1:Number << WriteByte (GetNumber (VAL1->getText(), VAL1->getLine(), 1), 0); >> ) - ( "," VAL2:Number << WriteByte (GetNumber (VAL2->getText(), VAL2->getLine(), 1), 0); >> )* - ";" - ; - -//***************************************************************************** -// -// PARSE: -// inconsistentif NOT .... AND NOT .... OR ... endif; -// -vfrStatementInconsistentIf : - << ResetFlags (); >> - IIFOP:InconsistentIf << WriteOpByte (IIFOP->getLine(), EFI_IFR_INCONSISTENT_IF_OP); >> - Prompt "=" getStringId "," - { - FF:Flags "=" flagsField ( "\|" flagsField )* "," - } - << WriteFlags (); >> // write the flags field - vfrBooleanExpression - EOP:EndIf ";" << WriteOpByte (EOP->getLine(), EFI_IFR_END_IF_OP); >> - ; - -//***************************************************************************** -// -// PARSE: -// TRUE AND (ideqval SomeStruct.SomeMember >= 0x10 OR -// ideqid SomeStruct.SomeMember < SomeStruct.SomeOtherMember) AND -// (ideqlist SomeStruct.SomeOtherMember == 0x10, 0x20, 0x30 OR -// vareqval var(VAR_EQ_TEST_NAME) == 0x1) -// -// For supporting complex express, divide the vfrBooleanExpression to two parts -// so that pred-LL(k) parser can parse incrementally. -// -vfrBooleanExpression : - leftPartVfrBooleanExp { rightPartVfrBooleanExp } - ; - -leftPartVfrBooleanExp : - OpenParen vfrBooleanExpression CloseParen | - (ideqval | ideqid | ideqvallist | vareqval | truefalse) | - NOPID:NOT leftPartVfrBooleanExp << WriteOpByte (NOPID->getLine(), EFI_IFR_NOT_OP); >> - ; - -rightPartVfrBooleanExp : - AOPID:AND vfrBooleanExpression << WriteOpByte (AOPID->getLine(), EFI_IFR_AND_OP); >> | - OOPID:OR vfrBooleanExpression << WriteOpByte (OOPID->getLine(), EFI_IFR_OR_OP); >> - ; - -//***************************************************************************** -// -// PARSE: -// TRUE -// -truefalse : - TOPID:True << WriteOpByte (TOPID->getLine(), EFI_IFR_TRUE_OP); >> | - FOPID:False << WriteOpByte (FOPID->getLine(), EFI_IFR_FALSE_OP); >> - ; - -//***************************************************************************** -// -// PARSE: -// varstore MY_STRUCT_NAME, key = 0x1234, name = "MyVariableName", guid = {...}; -// -vfrStatementVarStore : - OP:VarStore << WriteOpByte (OP->getLine(), EFI_IFR_VARSTORE_OP); >> - STRUCT_NAME:StringIdentifier "," - Key "=" KNUM:Number "," - Name "=" VAR_NAME:StringIdentifier "," - Guid "=" - OpenBrace - G1:Number "," - G2:Number "," - G3:Number "," - OpenBrace - G4:Number "," - G5:Number "," - G6:Number "," - G7:Number "," - G8:Number "," - G9:Number "," - G10:Number "," - G11:Number - CloseBrace - CloseBrace << WriteGuidValue (G1->getLine (), G1->getText (), G2->getText (), G3->getText (), - G4->getText (), G5->getText (), G6->getText (), G7->getText (), - G8->getText (), G9->getText (), G10->getText (), G11->getText () - ); - WriteWord (GetNumber (KNUM->getText(), KNUM->getLine(), 2)); - AddVarStore (STRUCT_NAME->getText(), VAR_NAME->getText(), GetNumber (KNUM->getText(), KNUM->getLine(), 2), STRUCT_NAME->getLine()); - >> - - ";" - ; - -//***************************************************************************** -// -// PARSE: -// vareqval var(0x100) == 0x20 -// -vareqval : - OPID:VarEqVal << WriteOpByte (OPID->getLine(), EFI_IFR_EQ_VAR_VAL_OP); >> - Var OpenParen - VAR:Number << WriteWord (GetNumber (VAR->getText(), VAR->getLine(), 2)); >> - CloseParen - compareNumber - ; - -ideqval : - OPID:IdEqVal << WriteOpByte (OPID->getLine(), EFI_IFR_EQ_ID_VAL_OP); >> - vfrStructFieldName[0] - compareNumber - ; - -//***************************************************************************** -// -// PARSE: -// ideqid MyNVData3.Field16A == MyNVData3.Field16B -// -// NOTE: Before processing the second variable store in the ideqid statement, set a global flag -// so that when we parse the second variable we set the secondary variable store id. -// -ideqid : - OPID:IdEqId << WriteOpByte (OPID->getLine(), EFI_IFR_EQ_ID_ID_OP); >> - vfrStructFieldName[0] - compareVfrStructFieldNameNL0 - ; - -//***************************************************************************** -// -// compareNumber is the combination of compare operation and Number -// -compareNumber : - ( - "==" - VAL1:Number << WriteWord (GetNumber (VAL1->getText(), VAL1->getLine(), 2)); >> - ) | - ( - GTOPID:GreaterThan - VAL2:Number << WriteWord (GetNumber (VAL2->getText(), VAL2->getLine(), 2)); - WriteOpByte (GTOPID->getLine(), EFI_IFR_GT_OP); >> - ) | - ( - GEOPID:GreaterEqual - VAL3:Number << WriteWord (GetNumber (VAL3->getText(), VAL3->getLine(), 2)); - WriteOpByte (GEOPID->getLine(), EFI_IFR_GE_OP); >> - ) | - ( - LTOPID:LessThan - VAL4:Number << WriteWord (GetNumber (VAL4->getText(), VAL4->getLine(), 2)); - WriteOpByte (LTOPID->getLine(), EFI_IFR_GE_OP); - WriteOpByte (LTOPID->getLine(), EFI_IFR_NOT_OP); >> - ) | - ( - LEOPID:LessEqual - VAL5:Number << WriteWord (GetNumber (VAL5->getText(), VAL5->getLine(), 2)); - WriteOpByte (LEOPID->getLine(), EFI_IFR_GT_OP); - WriteOpByte (LEOPID->getLine(), EFI_IFR_NOT_OP); >> - ) - ; - -//***************************************************************************** -// -// compareVfrStructFieldNameNL0 is the combination of compare operation and vfrStructFieldNameNL[0] -// -compareVfrStructFieldNameNL0 : - ( - "==" << mIdEqIdStmt = 1; >> - vfrStructFieldNameNL[0] << mIdEqIdStmt = 0; >> - ) | - ( - GTOPID:GreaterThan << mIdEqIdStmt = 1; >> - vfrStructFieldNameNL[0] << mIdEqIdStmt = 0; - WriteOpByte (GTOPID->getLine(), EFI_IFR_GT_OP); >> - ) | - ( - GEOPID:GreaterEqual << mIdEqIdStmt = 1; >> - vfrStructFieldNameNL[0] << mIdEqIdStmt = 0; - WriteOpByte (GEOPID->getLine(), EFI_IFR_GE_OP); >> - ) | - ( - LTOPID:LessThan << mIdEqIdStmt = 1; >> - vfrStructFieldNameNL[0] << mIdEqIdStmt = 0; - WriteOpByte (LTOPID->getLine(), EFI_IFR_GE_OP); - WriteOpByte (LTOPID->getLine(), EFI_IFR_NOT_OP); >> - ) | - ( - LEOPID:LessEqual << mIdEqIdStmt = 1; >> - vfrStructFieldNameNL[0] << mIdEqIdStmt = 0; - WriteOpByte (LEOPID->getLine(), EFI_IFR_GT_OP); - WriteOpByte (LEOPID->getLine(), EFI_IFR_NOT_OP); >> - ) - ; - - -ideqvallist : - OPID:IdEqValList << WriteOpByte (OPID->getLine(), EFI_IFR_EQ_ID_LIST_OP); >> - vfrStructFieldName[0] - "==" - ( VAL:Number << QueueIdEqValList (GetNumber (VAL->getText(), VAL->getLine(), 2)); >> ) + - << FlushQueueIdEqValList(); >> - ; - -vfrStatementGoto : - << UINT32 LineNum, KeyValue = 0; ResetFlags (); >> - IDG:Goto << WriteOpByte (IDG->getLine(), EFI_IFR_REF_OP); >> - VAL:Number "," << WriteWord (GetNumber (VAL->getText(), VAL->getLine(), 2)); - AddGotoReference (GetNumber (VAL->getText(), VAL->getLine(), 2), VAL->getLine()); - >> - KP:Prompt "=" getStringId "," << LineNum = KP->getLine(); >> - Help "=" getStringId - { - "," - FF:Flags "=" flagsField ( "\|" flagsField )* << LineNum = FF->getLine(); >> - } - { - "," Key "=" KNUM:Number << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >> - } - << WriteFlagsKey (KeyValue, LineNum); >> - ";" - ; - -vfrStatementHidden : - IDH:Hidden << WriteOpByte (IDH->getLine(), EFI_IFR_HIDDEN_OP); >> - Value "=" - VAL:Number "," << WriteWord (GetNumber (VAL->getText(), VAL->getLine(), 2)); >> - Key "=" - KVAL:Number << WriteWord (GetNumber (KVAL->getText(), KVAL->getLine(), 2)); >> - ";" - ; - -//***************************************************************************** -// -// PARSE: -// suppressif { grayoutif } + endif; -// Note: -// You can have: suppressif:grayoutif:statements:endif -// suppressif:grayoutif:endif -- serves no purpose -// suppressif:statements:endif -// suppressif:endif -- serves no purpose -// -vfrStatementSuppressIf : - << ResetFlags (); >> - OPID:SuppressIf << WriteOpByte (OPID->getLine(), EFI_IFR_SUPPRESS_IF_OP); SetIfStart (OPID->getLine()); >> - { - FF:Flags "=" flagsField ( "\|" flagsField )* "," - } - << WriteFlags (); >> // write the flags field - vfrBooleanExpression - ";" - { suppressIfGrayOutIf } ( suppressIfAndGrayoutIfSubstatements )+ - ENDOP:EndIf ";" << WriteOpByte (ENDOP->getLine(), EFI_IFR_END_IF_OP); SetIfStart (0); >> - ; - -// -// This is the form for a grayoutif nested in a suppressif statement -// -suppressIfGrayOutIf : - << ResetFlags (); >> - OPID:GrayOutIf << WriteOpByte (OPID->getLine(), EFI_IFR_GRAYOUT_IF_OP); >> - { - FF:Flags "=" flagsField ( "\|" flagsField )* "," - } - << WriteFlags (); >> // write the flags field - vfrBooleanExpression - ";" - ; - -//***************************************************************************** -// -// PARSE: -// grayoutif { flags = n, } endif; -// Note: -// You can have: grayoutif:suppressif:statements:endif -// grayoutif:statements:endif -// -// -vfrStatementGrayOutIf : - << ResetFlags (); >> - OPID:GrayOutIf << WriteOpByte (OPID->getLine(), EFI_IFR_GRAYOUT_IF_OP); SetIfStart (OPID->getLine()); >> - { - FF:Flags "=" flagsField ( "\|" flagsField )* "," - } - << WriteFlags (); >> // write the flags field - vfrBooleanExpression - ";" - { grayoutIfSuppressIf } ( suppressIfAndGrayoutIfSubstatements )+ - ENDOP:EndIf ";" << WriteOpByte (ENDOP->getLine(), EFI_IFR_END_IF_OP); SetIfStart (0); >> - ; - -// -// This is the format for a suppressif nested in a grayoutif -// -grayoutIfSuppressIf : - << ResetFlags (); >> - OPID:SuppressIf << WriteOpByte (OPID->getLine(), EFI_IFR_SUPPRESS_IF_OP); >> - { - FF:Flags "=" flagsField ( "\|" flagsField )* "," - } - << WriteFlags (); >> // write the flags field - vfrBooleanExpression - ";" - ; - -// -// These are the VFR statements that are valid inside a suppressif or grayoutif statement. -// -suppressIfAndGrayoutIfSubstatements : - vfrStatementOneOf | - vfrStatementTextText | - vfrStatementCheckBox | - vfrStatementNumeric | - vfrStatementDate | - vfrStatementTime | - vfrStatementPassword | - vfrStatementString | - vfrStatementHidden | - vfrStatementGoto | - vfrStatementLabel | - vfrStatementInventory | - vfrStatementOrderedList | - vfrStatementSaveRestoreDefaults - ; - -//***************************************************************************** -// -// PARSE: -// -// password varid = MyNvData.Password, -// prompt = STRING_TOKEN(STR_PASSWORD_PROMPT), -// help = STRING_TOKEN(STR_PASSWORD_HELP), -// minsize = 6, -// maxsize = 20, -// encoding = 1, -// endpassword; - -vfrStatementPassword : - << UINT32 KeyValue = 0; UINT32 LineNum; ResetFlags (); >> - IDPW:Password << WriteOpByte (IDPW->getLine(), EFI_IFR_PASSWORD_OP); >> - VarId "=" vfrStructFieldNameArray[0] "," - Prompt "=" getStringId "," - KH:Help "=" getStringId "," << LineNum = KH->getLine(); >> - { - FF:Flags "=" flagsField ( "\|" flagsField )* "," << LineNum = FF->getLine(); >> - } - { - Key "=" KNUM:Number "," << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >> - } - << WriteFlagsKey (KeyValue, LineNum); >> - MinSize "=" MIN:Number "," << WriteByte (GetNumber (MIN->getText(), MIN->getLine(), 1), 0); >> - MaxSize "=" MAX:Number "," << WriteByte (GetNumber (MAX->getText(), MAX->getLine(), 1), 0); >> - Encoding "=" ENC:Number "," << WriteWord (GetNumber (ENC->getText(), ENC->getLine(), 2)); >> - EndPassword ";" - ; - -//***************************************************************************** -// -// PARSE: -// -// string varid = MyNv.String, -// prompt = STRING_TOKEN(STR_STRING_PROMPT), -// help = STRING_TOKEN(STR_STRING_HELP), -// flags = INTERACTIVE, -// key = 0x1234, -// minsize = 6, -// maxsize = 0x14, -// endstring; -// -// Since flags and key are optional, we can't use Flags->getLine(). Therefore for error -// reporting we save the line number of the "help" keyword. -// -vfrStatementString : - << unsigned int KeyValue = 0; UINT32 LineNum; ResetFlags (); >> - IDS:String << WriteOpByte (IDS->getLine(), EFI_IFR_STRING_OP); >> - VarId "=" vfrStructFieldNameArray[0] "," - Prompt "=" getStringId "," - KH:Help "=" getStringId "," << LineNum = KH->getLine(); >> - { - FF:Flags "=" - flagsField ( "\|" flagsField )* << LineNum = FF->getLine(); >> - "," - } - { - Key "=" KNUM:Number "," << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >> - } - << WriteFlagsKey (KeyValue, LineNum); >> - MinSize "=" MIN:Number "," << WriteByte (GetNumber (MIN->getText(), MIN->getLine(), 1), 0); >> - MaxSize "=" MAX:Number "," << WriteByte (GetNumber (MAX->getText(), MAX->getLine(), 1), 0); >> - EndString ";" - ; - -//***************************************************************************** -// -// PARSE: -// numeric varid = MyIfrNVData.HowOldAreYouInYears, -// prompt = STRING_TOKEN(STR_NUMERIC_PROMPT), -// help = STRING_TOKEN(STR_NUMERIC_HELP), -// flags = INTERACTIVE, // flags is optional -// key = 0x1234, // key is optional if (flags & INTERACTIVE = 0) -// minimum = 0x0, -// maximum = 0xf0, -// step = 1, // step is option, and step=1 if not specified -// default = 0; // default is optional, and default=minimum if not specified -// endnumeric; -// -// Make flags and key optional. However if flags includes INTERACTIVE, then a key is required. -// That check is done in WriteFlagsKey() function. -// -vfrStatementNumeric : - << UINT32 LineNum, KeyValue = 0; ResetFlags (); >> - IDN:Numeric << WriteOpByte (IDN->getLine(), EFI_IFR_NUMERIC_OP); >> - VarId "=" vfrStructFieldName[2] "," - Prompt "=" getStringId "," - KH:Help "=" getStringId "," << LineNum = KH->getLine(); >> - { - FF:Flags "=" flagsField ( "\|" flagsField )* "," << LineNum = FF->getLine (); >> - } - { - Key "=" KNUM:Number "," << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >> - } - << WriteFlagsKey (KeyValue, LineNum); >> - minMaxStepDefault - EndNumeric ";" << WriteMinMaxStepDefault (); >> - ; - -// -// Parse minimum/maximum/step/default statements. Special cases: -// - if step not specified, then the value is 1 -// - if default not specified, then the value is the min value specified -// - if max < min, print a warning and swap the values (changes default too) -// -minMaxStepDefault : - << InitMinMaxStepDefault (); >> - Minimum "=" MIN:Number "," << SetMinMaxStepDefault (GetNumber (MIN->getText(), MIN->getLine(), 2), 0, MIN->getLine()); >> - Maximum "=" MAX:Number "," << SetMinMaxStepDefault (GetNumber (MAX->getText(), MAX->getLine(), 2), 1, MAX->getLine()); >> - { Step "=" STEP:Number "," << SetMinMaxStepDefault (GetNumber (STEP->getText(), STEP->getLine(), 2), 2, STEP->getLine()); >> } - { Default "=" DEF:Number "," << SetMinMaxStepDefault (GetNumber (DEF->getText(), DEF->getLine(), 2), 3, DEF->getLine()); >> } - ; - - -//***************************************************************************** -// -// PARSE: -// -// date year varid = Date.Year, // "Date.Year" is a special case we recognize -// prompt = STRING_TOKEN(STR_DATE_PROMPT), -// help = STRING_TOKEN(STR_DATE_YEAR_HELP), -// minimum = 1939, -// maximum = 2101, -// step = 1, -// default = 1964, -// -// month varid = Date.Month, -// prompt = STRING_TOKEN(STR_DATE_PROMPT), -// help = STRING_TOKEN(STR_DATE_MONTH_HELP), -// minimum = 1, -// maximum = 12, -// step = 1, -// default = 1, -// -// day varid = Date.Day, -// prompt = STRING_TOKEN(STR_DATE_PROMPT), -// help = STRING_TOKEN(STR_DATE_DAY_HELP), -// minimum = 1, -// maximum = 31, -// step = 0x1, -// default = 1, -// -// enddate; -// -vfrStatementDate : - Date - IDY:Year VarId "=" << WriteOpByte (IDY->getLine(), EFI_IFR_DATE_OP); >> - vfrStructFieldName[2] "," - dateTimeSubStatement - IDM:Month VarId "=" << WriteOpByte (IDM->getLine(), EFI_IFR_DATE_OP); >> - vfrStructFieldName[2] "," - dateTimeSubStatement - IDD:Day VarId "=" << WriteOpByte (IDD->getLine(), EFI_IFR_DATE_OP); >> - vfrStructFieldName[2] "," - dateTimeSubStatement - EndDate ";" - ; - -vfrStatementTime : - Time - IDH:Hour VarId "=" << WriteOpByte (IDH->getLine(), EFI_IFR_TIME_OP); >> - vfrStructFieldName[2] "," - dateTimeSubStatement - IDM:Minute VarId "=" << WriteOpByte (IDM->getLine(), EFI_IFR_TIME_OP); >> - vfrStructFieldName[2] "," - dateTimeSubStatement - IDS:Second VarId "=" << WriteOpByte (IDS->getLine(), EFI_IFR_TIME_OP); >> - vfrStructFieldName[2] "," - dateTimeSubStatement - EndTime ";" - ; - -//***************************************************************************** -// -// PARSE: -// -// text text = STRING_ID; -// text text = STRING_ID, text = STRING_ID; -// text text = STRING_ID, text = STRING_ID, flags = x, key = y; -// -vfrStatementTextText : - << ResetFlags (); >> - IDT:Text << WriteOpByte (IDT->getLine(), EFI_IFR_TEXT_OP); >> - Help "=" getStringId "," - Text "=" - getStringId // writes string identifier - { "," Text "=" getStringId - "," Flags "=" flagsField ( "\|" flagsField )* << WriteFlags (); >> - "," - Key "=" KNUM:Number << WriteWord (GetNumber(KNUM->getText(), KNUM->getLine(), 2)); >> - } - ";" - ; - -//***************************************************************************** -// -// PARSE: -// -// inventory help = ID, text = ID; -// inventory help = ID, text = id, text = ID; -// -vfrStatementInventory : - IDI:Inventory << WriteOpByte (IDI->getLine(), EFI_IFR_INVENTORY_OP); >> - Help "=" getStringId "," - Text "=" getStringId // writes string identifier - { "," Text "=" getStringId - } - ";" - ; - -//***************************************************************************** -// -// PARSE: -// -// restore defaults, -// formid = 4, -// prompt = STRING_TOKEN(STR_RESTORE_DEFAULTS_PROMPT), -// help = STRING_TOKEN(STR_RESTORE_DEFAULTS_HELP), -// flags = 0, -// key = 0; -// -// save defaults, -// formid = 4, -// prompt = STRING_TOKEN(STR_SAVE_DEFAULTS_PROMPT), -// help = STRING_TOKEN(STR_SAVE_DEFAULTS_HELP), -// flags = 0, -// key = 0; -// -vfrStatementSaveRestoreDefaults : - << unsigned int KeyValue = 0; UINT32 LineNum; ResetFlags (); >> - ( IDS:Save << WriteOpByte (IDS->getLine(), EFI_IFR_SAVE_DEFAULTS_OP); >> - | IDR:Restore << WriteOpByte (IDR->getLine(), EFI_IFR_RESTORE_DEFAULTS_OP); >> - ) - Defaults "," - FormId "=" FRMID:Number "," << WriteWord (GetNumber (FRMID->getText(), FRMID->getLine(), 2)); - AddGotoReference (GetNumber (FRMID->getText(), FRMID->getLine(), 2), FRMID->getLine()); - >> - Prompt "=" getStringId "," - KH:Help "=" getStringId << LineNum = KH->getLine(); >> - { - "," FF:Flags "=" flagsField ( "\|" flagsField )* << LineNum = FF->getLine(); >> - } - { - "," Key "=" KNUM:Number << LineNum = KNUM->getLine(); KeyValue = GetNumber(KNUM->getText(), LineNum, 2); >> - } - << WriteFlagsKey (KeyValue, LineNum); >> - ";" - ; - -//***************************************************************************** -// -// PARSE: -// -// flags = 0x10 | DEFAULT | MANUFACTURING | INTERACTIVE | NV_ACCESS | RESET_REQUIRED | LATE_CHECK -// -// -flagsField : - VAL:Number << SetFlags (GetNumber(VAL->getText(), VAL->getLine(), 4), VAL->getLine()); >> - | IF:InteractiveFlag << SetFlags (EFI_IFR_FLAG_INTERACTIVE, IF->getLine()); >> - | MF:ManufacturingFlag << SetFlags (EFI_IFR_FLAG_MANUFACTURING, MF->getLine()); >> - | DF:DefaultFlag << SetFlags (EFI_IFR_FLAG_DEFAULT, DF->getLine()); >> - | NV:NVAccessFlag << SetFlags (EFI_IFR_FLAG_NV_ACCESS, NV->getLine()); >> - | RR:ResetRequiredFlag << SetFlags (EFI_IFR_FLAG_RESET_REQUIRED, RR->getLine()); >> - | LC:LateCheckFlag << SetFlags (EFI_IFR_FLAG_LATE_CHECK, LC->getLine()); >> - ; - -dateTimeSubStatement : - Prompt "=" getStringId "," - Help "=" getStringId "," - << WriteByte (0, 0); WriteWord (0); >> // bogus flags and key - minMaxStepDefault << WriteMinMaxStepDefault (); >> - ; - -vfrStatementCheckBox : - << UINT32 LineNum, KeyValue = 0; ResetFlags (); >> - IDCB:CheckBox << WriteOpByte (IDCB->getLine(), EFI_IFR_CHECKBOX_OP); >> - VarId "=" vfrStructFieldName[1] "," - Prompt "=" getStringId "," - Help "=" getStringId "," - FF:Flags "=" flagsField ( "\|" flagsField )* "," << LineNum = FF->getLine(); >> - { - Key "=" KV:Number "," << LineNum = KV->getLine(); KeyValue = GetNumber(KV->getText(), LineNum, 2); >> - } - << WriteFlagsKey (KeyValue, LineNum); >> - EndCheckBox ";" - ; - -vfrStatementSubTitle : - IDS:Subtitle Text "=" << WriteOpByte (IDS->getLine(), EFI_IFR_SUBTITLE_OP); >> - getStringId // writes string indentifier - ";" - ; - -//***************************************************************************** -// -// PARSE: -// banner -// title = STRING_TOKEN(STR_BANNER_TITLE), -// line 1, -// align center; // or left or right -// -// banner, -// title = STRING_TOKEN(STR_BANNER_TITLE), timeout = 100; -// -vfrStatementBanner : - IDB:Banner { "," } << WriteOpByte (IDB->getLine(), EFI_IFR_BANNER_OP); >> - Title "=" getStringId "," - ( - Line VAL:Number "," << WriteWord (GetNumber(VAL->getText(), VAL->getLine(), 2)); >> - Align - ( Left << WriteByte (EFI_IFR_BANNER_ALIGN_LEFT, 0); >> - | Center << WriteByte (EFI_IFR_BANNER_ALIGN_CENTER, 0); >> - | Right << WriteByte (EFI_IFR_BANNER_ALIGN_RIGHT, 0); >> - ) ";" - | - Timeout "=" TO:Number ";" << WriteWord (GetNumber(TO->getText(), TO->getLine(), 2)); >> - << WriteByte (EFI_IFR_BANNER_TIMEOUT, 0); >> - ) - ; - -//***************************************************************************** -// -// PARSE: -// oneof varid = MyNv.OneOfData, -// prompt = STRING_TOKEN(STR_ONE_OF_PROMPT), -// help = STRING_TOKEN(STR_ONE_OF_HELP), -// option text = STRING_TOKEN(STR_ONE_OF_TEXT), -// value = 0, -// flags = DEFAULT | INTERACTIVE; -// -// supressif/grayoutif are supported inside oneof stmt. -// We do not restrict the number of oneOfOptionText to >=2, but >=1. -// The situation that all oneOfOptionText are suppressed is also possiable. -// -vfrStatementOneOf : - << ResetFlags (); >> - IDOO:OneOf << WriteOpByte (IDOO->getLine(), EFI_IFR_ONE_OF_OP); >> - VarId "=" vfrStructFieldName[2] "," - Prompt "=" getStringId "," // writes string identifier - Help "=" getStringId "," // writes string identifier - ( oneOfOptionText )+ // there must be at least 1 option to be choosed, not 2. - IDEOO:EndOneOf ";" << TestOneOfFlags (IDEOO->getLine()); WriteOpByte (IDEOO->getLine(), EFI_IFR_END_ONE_OF_OP); >> - ; - -//***************************************************************************** -// -// PARSE: -// -// orderedlist varid = MyNv.OrderedListData, -// prompt = STRING_TOKEN(STR_ORDERED_LIST_PROMPT), -// help = STRING_TOKEN(STR_ORDERED_LIST_HELP), -// option text = STRING_TOKEN(STR_ORDERED_LIST_TEXT), value = 0, flags = INTERACTIVE; -// -- additional option text -- -// endlist; -// -vfrStatementOrderedList : - << ResetFlags (); InitOrderedList(); >> - IDOL:OrderedList << WriteOpByte (IDOL->getLine(), EFI_IFR_ORDERED_LIST_OP); >> - VarId "=" vfrStructFieldNameArray[1] "," - Prompt "=" getStringId "," // writes string identifier - Help "=" getStringId "," // writes string identifier - orderedListOptionText ( orderedListOptionText )+ - IDEOL:EndList ";" << WriteOpByte (IDEOL->getLine(), EFI_IFR_END_OP); EndOrderedList(IDEOL->getLine()); >> - ; - -//***************************************************************************** -// -// PARSE: -// -// option text = STRING_TOKEN(STRING_ID), value = 0 flags = 99; -// -// Differs from the oneOfOptionText in that we don't allow the DEFAULT flag to -// be set, and value cannot be 0. -// -orderedListOptionText : - << UINT32 KeyValue = 0; >> - IDO:Option << WriteOpByte (IDO->getLine(), EFI_IFR_ONE_OF_OPTION_OP); >> - Text "=" getStringId "," // writes string identifier - Value "=" WVAL:Number "," << - if (GetNumber(WVAL->getText(), WVAL->getLine(), 2) == 0) { - PrintErrorMessage (WVAL->getLine(), "value=0 is invalid for ordered lists", NULL); - } else { - WriteWord (GetNumber(WVAL->getText(), WVAL->getLine(), 2)); - } - >> - FF:Flags "=" orderedListFlagsField - ("\|" orderedListFlagsField )* - { - "," Key "=" KV:Number << KeyValue = GetNumber (KV->getText(), KV->getLine(), 2); >> - } - << WriteFlagsKey (KeyValue, FF->getLine()); >> - ";" << mOptionCount++; >> - ; - -//***************************************************************************** -// -// PARSE: -// -// flags = 0x10 | DEFAULT | MANUFACTURING | INTERACTIVE | NV_ACCESS | RESET_REQUIRED | LATE_CHECK -// -// The ordered list flags field cannot have a default. -// -orderedListFlagsField : - VAL:Number << SetFlags (GetNumber(VAL->getText(), VAL->getLine(), 4), VAL->getLine()); >> - | IF:InteractiveFlag << SetFlags (EFI_IFR_FLAG_INTERACTIVE, IF->getLine()); >> - | MF:ManufacturingFlag << SetFlags (EFI_IFR_FLAG_MANUFACTURING, MF->getLine()); >> - | NV:NVAccessFlag << SetFlags (EFI_IFR_FLAG_NV_ACCESS, NV->getLine()); >> - | RR:ResetRequiredFlag << SetFlags (EFI_IFR_FLAG_RESET_REQUIRED, RR->getLine()); >> - | LC:LateCheckFlag << SetFlags (EFI_IFR_FLAG_LATE_CHECK, LC->getLine()); >> - | DF:DefaultFlag << PrintWarningMessage (DF->getLine(), "DEFAULT flag not valid for ordered lists", NULL); >> - ; - -// -// Parse references to VFR structure field names of form "MyNvStructure.Field". -// This implementation is specific to strings, passwords, and references in an -// ordered list statement because we want to specify the size of the entire -// field, rather than just one element. Then call a function to write out its -// offset and length. -// -vfrStructFieldNameArray[int FieldWidth] : - << int ArrayIndex = 1; char IsArrayIndex = 0; >> - SName:StringIdentifier - "." - SFieldName:StringIdentifier - { OpenBracket AIndex:Number CloseBracket << ArrayIndex = GetNumber(AIndex->getText(), AIndex->getLine(), 4); IsArrayIndex = 1; >> } - << - WriteFieldOffset (1, - SName->getText(), - SName->getLine(), - SFieldName->getText(), - SFieldName->getLine(), - ArrayIndex, - IsArrayIndex, - FieldWidth, - 1 - ); - >> - ; - -// -// Parse references to VFR structure field names of form "MyNvStructure.Field", -// then call a function to write out its offset and length. -// -vfrStructFieldName[int FieldWidth] : - << int ArrayIndex = 1; char IsArrayIndex = 0; >> - SName:StringIdentifier - "." - SFieldName:StringIdentifier - { OpenBracket AIndex:Number CloseBracket << ArrayIndex = GetNumber(AIndex->getText(), AIndex->getLine(), 4); IsArrayIndex = 1; >> } - << - WriteFieldOffset (1, - SName->getText(), - SName->getLine(), - SFieldName->getText(), - SFieldName->getLine(), - ArrayIndex, - IsArrayIndex, - FieldWidth, - 0 - ); - >> - ; - -//***************************************************************************** -// -// PARSE: -// -// MyNvStructure.FieldName[4] -// -// Parse references to VFR structure field names of form "MyNvStructure.Field", -// then call a function to write out the offset with no length. -// -vfrStructFieldNameNL[int FieldWidth] : - << int ArrayIndex = 1; char IsArrayIndex = 0; >> - SName:StringIdentifier - "." - SFieldName:StringIdentifier - { OpenBracket AIndex:Number CloseBracket << ArrayIndex = GetNumber(AIndex->getText(), AIndex->getLine(), 4); IsArrayIndex = 1; >> } - << - WriteFieldOffset (0, - SName->getText(), - SName->getLine(), - SFieldName->getText(), - SFieldName->getLine(), - ArrayIndex, - IsArrayIndex, - FieldWidth, - 0 - ); - >> - ; - -//***************************************************************************** -// -// PARSE: -// suppressif TRUE OR FALSE; -// grayoutif FALSE OR TRUE; -// option text = STRING_TOKEN(STRING_ID), value = 0 flags = 99; -// option text = STRING_TOKEN(STRING_ID2), value = 1 flags = 98; -// endif; -// -oneOfOptionText : - suppressIfOptionText | - grayOutIfOptionText | - commonOptionText - ; - -suppressIfOptionText : - << ResetFlags (); >> - OPID:SuppressIf << WriteOpByte (OPID->getLine(), EFI_IFR_SUPPRESS_IF_OP); SetIfStart (OPID->getLine()); >> - { - FF:Flags "=" flagsField ( "\|" flagsField )* "," - } - << WriteFlags (); >> // write the flags field - vfrBooleanExpression - ";" - { suppressIfGrayOutIf } ( commonOptionText )+ - ENDOP:EndIf ";" << WriteOpByte (ENDOP->getLine(), EFI_IFR_END_IF_OP); SetIfStart (0); >> - ; - -grayOutIfOptionText : - << ResetFlags (); >> - OPID:GrayOutIf << WriteOpByte (OPID->getLine(), EFI_IFR_GRAYOUT_IF_OP); SetIfStart (OPID->getLine()); >> - { - FF:Flags "=" flagsField ( "\|" flagsField )* "," - } - << WriteFlags (); >> // write the flags field - vfrBooleanExpression - ";" - { grayoutIfSuppressIf } ( commonOptionText )+ - ENDOP:EndIf ";" << WriteOpByte (ENDOP->getLine(), EFI_IFR_END_IF_OP); SetIfStart (0); >> - ; - -commonOptionText : - << UINT32 KeyValue = 0; >> - IDO:Option << WriteOpByte (IDO->getLine(), EFI_IFR_ONE_OF_OPTION_OP); >> - Text "=" getStringId "," // writes string identifier - Value "=" WVal:Number "," << WriteWord (GetNumber(WVal->getText(), WVal->getLine(), 2)); >> - FF:Flags "=" flagsField ("\|" flagsField )* - { - "," Key "=" KV:Number << KeyValue = GetNumber (KV->getText(), KV->getLine(), 2); >> - } - << WriteFlagsKey (KeyValue, FF->getLine()); >> - ";" << mOptionCount++; >> - ; - -// -// Gets a string identifier. It must be a numeric value of form: -// -// STRING_TOKEN(100) -// -getStringId : - << unsigned short StrId; >> - StringToken OpenParen - IdVal:Number << StrId = GetNumber (IdVal->getText(), IdVal->getLine(), 2); WriteStringIdWord (StrId); >> - CloseParen - ; - -//****************************************************************************** -// -// Parser class definition. -// -class EfiVfrParser { -<< -// -// Parser definitions go here -// -private: - STRUCT_DEFINITION *mFirstStructDefinition; - STRUCT_DEFINITION *mLastStructDefinition; - INT32 mNvDataStructSize; - INT32 mNonNvDataStructSize; - // - // Flag to indicate that we're processing a ideqid VFR statement so that - // we can do late checks on the statement. - // - INT32 mIdEqIdStmt; - INT32 mLastNVVariableDataSize; - GOTO_REFERENCE *mGotoReferences; - FORM_ID_VALUE *mFormIdValues; - VfrOpcodeHandler mOpcodeHandler; - UINT16_LIST *mUint16List; - UINT16_LIST *mLastUint16; - UINT16_LIST *mDefinedLabels; - UINT16_LIST *mDefinedVarStoreId; - UINT16_LIST *mLastDefinedVarStoreId; - UINT32 mMinimumValue, mMaximumValue, mStepValue, mDefaultValue; - UINT32 mStmtFlags; - UINT32 mSubStmtFlags; - UINT32 mSubStmtFlagsLineNum; - EFI_GUID mFormSetGuid; - UINT8 mNvDataStructDefined; - UINT16 mClass, mSubclass; - UINT32 mIfStart; - UINT32 mOptionCount; // how many "option" fields in a given statement - UINT32 mLastVarIdSize; - UINT8 mOutput; -public: - -VOID -EfiVfrParser::SetIfStart ( - UINT32 LineNum - ) -/*++ - -Routine Description: - Invoked during VFR parsing when an "if" is encountered. Save the - source line number so we can point to it if we don't find a - corresponding endif later. - -Arguments: - LineNum - source line number where the "if" was parsed. - -Returns: - None - ---*/ -{ - mIfStart = LineNum; -} -VOID -EfiVfrParser::SetClass ( - UINT32 LineNum, - UINT32 Value - ) -/*++ - -Routine Description: - Invoked during VFR parsing when a "class" statement is found. Check the - range on the class value and save it for later. - -Arguments: - LineNum - source line number where the class statement was parsed. - Value - the class value - -Returns: - None - ---*/ -{ - if (Value & 0xFFFF0000) { - PrintWarningMessage (LineNum, NULL, "class value exceeds maximum allowed"); - } - mClass |= (UINT16)Value; -} -VOID -EfiVfrParser::SetSubclass ( - UINT32 LineNum, - UINT32 Value - ) -/*++ - -Routine Description: - Invoked during VFR parsing when a subclass statement is found. Check the - range on the value and save it for later. - -Arguments: - LineNum - source line number where the class statement was parsed. - Value - the subclass value from the VFR statement - -Returns: - None - ---*/ -{ - if (Value & 0xFFFF0000) { - PrintWarningMessage (LineNum, NULL, "subclass value exceeds maximum allowed"); - } - mSubclass |= (UINT16)Value; -} -VOID EfiVfrParser::WriteClass () -{ - WriteWord (mClass); - mClass = 0; -} -VOID EfiVfrParser::WriteSubclass () -{ - WriteWord (mSubclass); - mSubclass = 0; -} -VOID EfiVfrParser::WriteIfrBytes () -{ - mOpcodeHandler.WriteIfrBytes (); -} -VOID -EfiVfrParser::WriteFlagsKey ( - UINT32 KeyValue, - UINT32 LineNum - ) -/*++ - -Routine Description: - Write out the flags and key values from the previous VFR statement. - Many statements take a flags/key pair. If not specified, then 0 - values are written out. However do not allow an interactive flags field - to be specified if no key value is specified. Also, if NV_ACCESS flag - is set but INTERACTIVE is not, then set interactive and issue a warning. - -Arguments: - KeyValue - the key value from the VFR statement - LineNum - source line number where the statement was parsed - -Returns: - None - ---*/ -{ - if ((mSubStmtFlags & EFI_IFR_FLAG_INTERACTIVE) && (KeyValue == 0)) { - PrintErrorMessage (LineNum, NULL, "invalid or missing key value - required with INTERACTIVE"); - } - if ((mSubStmtFlags & EFI_IFR_FLAG_NV_ACCESS) && !(mSubStmtFlags & EFI_IFR_FLAG_INTERACTIVE)) { - PrintWarningMessage (LineNum, NULL, "NV_ACCESS without INTERACTIVE has no effect -- setting INTERACTIVE"); - mSubStmtFlags |= EFI_IFR_FLAG_INTERACTIVE; - } - WriteFlags (); - WriteWord (KeyValue); -} -VOID -EfiVfrParser::InitOrderedList () -{ - mOptionCount = 0; -} -VOID -EfiVfrParser::EndOrderedList ( - UINT32 LineNum - ) -{ - if (mLastVarIdSize < mOptionCount) { - PrintErrorMessage (LineNum, NULL, "number of options exceeds the variable store size"); - } -} -VOID -EfiVfrParser::ResetFlags () -/*++ - -Routine Description: - - Flags are set for each substatement in a given one-of statement. - To make sure there are no conflicts, for example setting DEFAULT on - more than one substatement, we keep track of the flags at a statement - level and a substatement level. This function resets the flags so - we get a fresh start. - -Arguments: - None - -Returns: - None - ---*/ -{ - mStmtFlags = 0; - mSubStmtFlagsLineNum = 0; - mSubStmtFlags = 0; -} -// -// Test validity of flags value for a one-of statement. -// -VOID -EfiVfrParser::TestOneOfFlags ( - UINT32 LineNum - ) -{ - // - // One of the fields must have had the default bit set - // - if ((mStmtFlags & EFI_IFR_FLAG_DEFAULT) == 0) { - PrintWarningMessage (LineNum, "default value must be specified", NULL); - } -} -VOID -EfiVfrParser::SetFlags ( - UINT32 Flags, - UINT32 LineNum - ) -{ - // - // Check for redefinitions and invalid combinations - // - if (mStmtFlags & Flags & EFI_IFR_FLAG_MANUFACTURING) { - PrintErrorMessage (LineNum, "MANUFACTURING", "a field with this flag already defined"); - } - if (mStmtFlags & Flags & EFI_IFR_FLAG_DEFAULT) { - PrintErrorMessage (LineNum, "DEFAULT", "a field with this flag already defined"); - } - mSubStmtFlags |= Flags; - mSubStmtFlagsLineNum = LineNum; -} -VOID -EfiVfrParser::WriteFlags () -{ - // - // Check value for validity - // - if (mSubStmtFlags & ~(EFI_IFR_FLAG_DEFAULT | - EFI_IFR_FLAG_MANUFACTURING | - EFI_IFR_FLAG_INTERACTIVE | - EFI_IFR_FLAG_NV_ACCESS | - EFI_IFR_FLAG_RESET_REQUIRED | - EFI_IFR_FLAG_LATE_CHECK )) { - PrintWarningMessage (mSubStmtFlagsLineNum, "invalid bits defined in flag", NULL); - } - WriteByte ((UINT8)mSubStmtFlags, 'F'); - // - // We can now clear the substatement flags - // - mStmtFlags |= mSubStmtFlags; - mSubStmtFlags = 0; -} -// -// When we parse a min/max/step/default sequence, save off the values for -// later use. Call this first to init the values. -// -VOID -EfiVfrParser::InitMinMaxStepDefault () -{ - mMinimumValue = 0; - mMaximumValue = 0; - mStepValue = 1; - mDefaultValue = 0; -} -VOID -EfiVfrParser::WriteMinMaxStepDefault () -{ - WriteWord (mMinimumValue); - WriteWord (mMaximumValue); - WriteWord (mStepValue); - WriteWord (mDefaultValue); -} -VOID -EfiVfrParser::SetMinMaxStepDefault ( - UINT16 Value, - INT32 MMSD, - INT32 LineNum - ) -{ - UINT16 TempValue; - // - // Min specified - // - if (MMSD == 0) { - mMinimumValue = Value; - mDefaultValue = Value; - // - // Max specified - // - } else if (MMSD == 1) { - mMaximumValue = Value; - // - // If min > max, then swap the values. That includes resetting the default - // value as well. - // - if (mMinimumValue > mMaximumValue) { - PrintWarningMessage (LineNum, NULL, "maximum < minimum"); - TempValue = Value; - mMaximumValue = mMinimumValue; - mMinimumValue = TempValue; - mDefaultValue = mMinimumValue; - } - // - // Step specified - // - } else if (MMSD == 2) { - mStepValue = Value; - // - // Default specified. Make sure min <= default <= max. - // - } else if (MMSD == 3) { - mDefaultValue = Value; - if (mMinimumValue > Value) { - PrintErrorMessage (LineNum, NULL, "default value < minimum value"); - } else if (Value > mMaximumValue) { - PrintErrorMessage (LineNum, NULL, "default value > maximum value"); - } - } else { - PrintErrorMessage (LineNum, "application error", "internal MMSD error"); - } -} -VOID -EfiVfrParser::AddLabel ( - UINT32 LabelNumber, - UINT32 LineNum - ) -{ - UINT16_LIST *Label; - - // - // Added a label from the user VFR script. Make sure they haven't already - // defined the same label elsewhere - // - for (Label = mDefinedLabels; Label != NULL; Label = Label->Next) { - if (Label->Value == LabelNumber) { - PrintErrorMessage (LineNum, NULL, "label already defined"); - PrintErrorMessage (Label->LineNum, NULL, "previous definition of redefined label"); - break; - } - } - Label = (UINT16_LIST *)malloc (sizeof (UINT16_LIST)); - if (Label == NULL) { - PrintErrorMessage (0, NULL, "memory allocation error"); - return; - } - memset ((char *)Label, 0, sizeof (UINT16_LIST)); - Label->Value = LabelNumber; - Label->LineNum = LineNum; - Label->Next = mDefinedLabels; - mDefinedLabels = Label; -} -VOID -EfiVfrParser::QueueIdEqValList ( - UINT16 Value - ) -{ - UINT16_LIST *U16; - - U16 = (UINT16_LIST *)malloc (sizeof (UINT16_LIST)); - if (U16 == NULL) { - Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failed"); - } else { - memset ((char *)U16, 0, sizeof (UINT16_LIST)); - U16->Value = Value; - if (mUint16List == NULL) { - mUint16List = U16; - } else { - mLastUint16->Next = U16; - } - mLastUint16 = U16; - } -} -VOID -EfiVfrParser::FlushQueueIdEqValList () -{ - UINT32 Count; - - // - // We queued up a list of IdEqValList items. The IFR requires a count - // followed by the actual values. Do it. - // - Count = 0; - mLastUint16 = mUint16List; - while (mLastUint16 != NULL) { - Count++; - mLastUint16 = mLastUint16->Next; - } - // BUGBUG -- check for more than 16K items? - WriteWord (Count); - // - // Now write the values. - // - mLastUint16 = mUint16List; - while (mLastUint16 != NULL) { - WriteWord ((UINT32)mLastUint16->Value); - mLastUint16 = mLastUint16->Next; - } - // - // Free up the list - // - mLastUint16 = mUint16List; - while (mUint16List != NULL) { - mLastUint16 = mUint16List->Next; - free (mUint16List); - mUint16List = mLastUint16; - } -} -VOID -EfiVfrParser::PrintErrorMessage ( - UINT32 LineNum, - CHAR8 *Msg1, - CHAR8 *Msg2 - ) -{ - char *FileName; - - if (LineNum != 0) { - FileName = ConvertLineNumber ((UINT32 *)&LineNum); - Error (FileName, LineNum, 0, Msg1, Msg2); - } else { - Error (PROGRAM_NAME, 0, 0, Msg1, Msg2); - } -} -VOID -EfiVfrParser::PrintWarningMessage ( - UINT32 LineNum, - CHAR8 *Msg1, - CHAR8 *Msg2 - ) -{ - char *FileName; - - if (LineNum != 0) { - FileName = ConvertLineNumber ((UINT32 *)&LineNum); - Warning (FileName, LineNum, 0, Msg1, Msg2); - } else { - Warning (PROGRAM_NAME, 0, 0, Msg1, Msg2); - } -} -VOID -EfiVfrParser::syn ( - ANTLRAbstractToken *Tok, - ANTLRChar *Egroup, - SetWordType *Eset, - ANTLRTokenType ETok, - INT32 Huh - ) -/*++ - -Routine Description: - Called by the parser base class as a result of parse syntax errors. - -Arguments: - Tok - token that caused the error - Egroup - not sure - Eset - index in token table of the expected token - Huh - not sure - -Returns: - NA - ---*/ -{ - char *FileName; - UINT32 LineNum; - - LineNum = Tok->getLine (); - FileName = ConvertLineNumber ((UINT32 *)&LineNum); - // - // Sometimes the token number is 0, in which case I don't know what to - // print. - // - if (ETok == 0) { - Error (FileName, LineNum, 0, Tok->getText (), "unexpected token"); - } else { - // - // If we were expecting an endif, then report the line where the corresponding - // IF began. - // - if ((strcmp (_token_tbl[ETok], "endif") == 0) && (mIfStart != 0)) { - LineNum = mIfStart; - FileName = ConvertLineNumber (&LineNum); - Error (FileName, LineNum, 0, "statement missing corresponding endif", NULL); - } else { - Error (FileName, LineNum, 0, Tok->getText (), "expected %s", _token_tbl[ETok]); - } - } -} - -VOID -EfiVfrParser::init() -/*++ - -Routine Description: - Initializations function for our parser. - -Arguments: - None. - -Returns: - None. - ---*/ -{ - ANTLRParser::init(); - - // - // Used for queuing a variable list of UINT16's - // - mUint16List = NULL; - mLastUint16 = NULL; - mFirstStructDefinition = NULL; - mLastStructDefinition = NULL; - mNvDataStructSize = 0; - mNonNvDataStructSize = 0; - mNvDataStructDefined = 0; - mGotoReferences = NULL; - mFormIdValues = NULL; - mDefinedLabels = NULL; - mClass = 0; - mSubclass = 0; - mIfStart = 0; - mDefinedVarStoreId = NULL; - mLastDefinedVarStoreId = NULL; - mIdEqIdStmt = 0; - mLastNVVariableDataSize = 0; - - memset ((char *)&mFormSetGuid, 0, sizeof (EFI_GUID)); -} -// -// Destructor for the parser. -// -EfiVfrParser::~EfiVfrParser(VOID) -{ - Cleanup(); -} -VOID -EfiVfrParser::Cleanup (VOID) -/*++ - -Routine Description: - Free memory allocated during parsing - -Arguments: - None. - -Returns: - None. - ---*/ -{ - STRUCT_DEFINITION *NextStruct; - STRUCT_FIELD_DEFINITION *NextField; - UINT8 Buff[6]; - UINT16_LIST *NextU16List; - - // - // Free up the structure definitions if any - // - while (mFirstStructDefinition != NULL) { - // - // Free up all the fields for this struct - // - while (mFirstStructDefinition->Field != NULL) { - NextField = mFirstStructDefinition->Field->Next; - free (mFirstStructDefinition->Field->Name); - free (mFirstStructDefinition->Field); - mFirstStructDefinition->Field = NextField; - } - NextStruct = mFirstStructDefinition->Next; - free (mFirstStructDefinition->Name); - free (mFirstStructDefinition); - mFirstStructDefinition = NextStruct; - } - // - // Free up the goto references and form id defines - // - FreeGotoReferences (); - // - // Free up label list - // - while (mDefinedLabels != NULL) { - NextU16List = mDefinedLabels->Next; - delete (mDefinedLabels); - mDefinedLabels = NextU16List; - } - // - // Free up the list of defined variable storage IDs - // - while (mDefinedVarStoreId != NULL) { - NextU16List = mDefinedVarStoreId->Next; - delete (mDefinedVarStoreId); - mDefinedVarStoreId = NextU16List; - } -} - -INT32 -EfiVfrParser::AtoX ( - CHAR8 *HexString, - INT32 NumBytes, - UINT32 *HexValue - ) -/*++ - -Routine Description: - Given a pointer to a ascii hex string, convert to a number with the given - number of bytes. - -Arguments: - HexString - pointer to a string of format 30BCA - Size - number of bytes to convert - HexValue - return result - -Returns: - The number of bytes converted. - ---*/ -{ - INT32 Count; - INT32 Value; - - *HexValue = 0; - Count = 0; - while (Count < NumBytes) { - if ((*HexString >= '0') && (*HexString <= '9')) { - Value = *HexString - '0'; - } else if ((*HexString >= 'a') && (*HexString <= 'f')) { - Value = *HexString - 'a' + 10; - } else if ((*HexString >= 'A') && (*HexString <= 'F')) { - Value = *HexString - 'A' + 10; - } else { - return Count; - } - HexString++; - *HexValue = (*HexValue << 4) | Value; - if ((*HexString >= '0') && (*HexString <= '9')) { - Value = *HexString - '0'; - } else if ((*HexString >= 'a') && (*HexString <= 'f')) { - Value = *HexString - 'a' + 10; - } else if ((*HexString >= 'A') && (*HexString <= 'F')) { - Value = *HexString - 'A' + 10; - } else { - return Count; - } - *HexValue = (*HexValue << 4) | Value; - HexString++; - Count++; - } - return Count; -} -VOID -EfiVfrParser::WriteGuidValue ( - UINT32 TokenLineNum, - CHAR8 *G1, - CHAR8 *G2, - CHAR8 *G3, - CHAR8 *G4, - CHAR8 *G5, - CHAR8 *G6, - CHAR8 *G7, - CHAR8 *G8, - CHAR8 *G9, - CHAR8 *G10, - CHAR8 *G11 - ) -/*++ - -Routine Description: - A Guid was parsed, likely of format: - #define MY_GUID { 0x12345678, 0xAABB, 0xCCDD, 0xEE, 0xFF, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 } - - Write out the value. - -Arguments: - TokenLineNum - line number where the guid was used - G1-G11 - the 11 fields of the guid value - -Returns: - None. - ---*/ -{ - UINT32 Value; - INT32 Loop; - - mFormSetGuid.Data1 = GetNumber (G1, TokenLineNum, 4); - mFormSetGuid.Data2 = (UINT16)GetNumber (G2, TokenLineNum, 2); - mFormSetGuid.Data3 = (UINT16)GetNumber (G3, TokenLineNum, 2); - mFormSetGuid.Data4[0] = (UINT8)GetNumber (G4, TokenLineNum, 1); - mFormSetGuid.Data4[1] = (UINT8)GetNumber (G5, TokenLineNum, 1); - mFormSetGuid.Data4[2] = (UINT8)GetNumber (G6, TokenLineNum, 1); - mFormSetGuid.Data4[3] = (UINT8)GetNumber (G7, TokenLineNum, 1); - mFormSetGuid.Data4[4] = (UINT8)GetNumber (G8, TokenLineNum, 1); - mFormSetGuid.Data4[5] = (UINT8)GetNumber (G9, TokenLineNum, 1); - mFormSetGuid.Data4[6] = (UINT8)GetNumber (G10, TokenLineNum, 1); - mFormSetGuid.Data4[7] = (UINT8)GetNumber (G11, TokenLineNum, 1); - - WriteDWord (mFormSetGuid.Data1, 'G'); - WriteWord (mFormSetGuid.Data2); - WriteWord (mFormSetGuid.Data3); - WriteByte (mFormSetGuid.Data4[0], 0); - WriteByte (mFormSetGuid.Data4[1], 0); - WriteByte (mFormSetGuid.Data4[2], 0); - WriteByte (mFormSetGuid.Data4[3], 0); - WriteByte (mFormSetGuid.Data4[4], 0); - WriteByte (mFormSetGuid.Data4[5], 0); - WriteByte (mFormSetGuid.Data4[6], 0); - WriteByte (mFormSetGuid.Data4[7], 0); -} -VOID -EfiVfrParser::WriteFieldOffset ( - INT8 WriteLength, - CHAR8 *StructName, - INT32 LineNum1, - CHAR8 *FieldName, - INT32 LineNum2, - INT32 ArrayIndex, - INT8 IsArrayIndex, - INT32 FieldWidth, - INT8 WriteArraySize - ) -/*++ - -Routine Description: - A VFR script referenced the NV store structure. Given the structure's name - and the field's name, write the offset of the field to the output file. - -Arguments: - WriteLength - write the field length byte out - StructName - name of the NV store structure - LineNum1 - line number in the VFR where we are (for error printing) - FieldName - the name of the field within the NV store structure - LineNum2 - line number in the VFR where FieldName is referenced - ArrayIndex - the index specified, for example NV_DATA.Field[ArrayIndex] - IsArrayIndex - non-zero if an array index was specified - FieldWidth - expected size for the Field (1 byte? 2 bytes?) - WriteArraySize - write the size of the entire field, not the size of a single element - -Returns: - None. - ---*/ -{ - STRUCT_DEFINITION *StructDef; - STRUCT_FIELD_DEFINITION *FieldDef; - UINT32 Offset; - UINT32 VarSize; - CHAR8 Msg[100]; - // - // If we're writing an array size, then they better have referenced the field without an - // index. - // - if (WriteArraySize && IsArrayIndex) { - sprintf (Msg, "array index specified where an array is required"); - PrintErrorMessage (LineNum2, FieldName, Msg); - return; - } - // - // Look through our list of known structures for a match - // - for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) { - // - // Check for matching structure name - // - if (strcmp (StructDef->Name, StructName) == 0) { - // - // Mark it as referenced (for debug purposes only). Check the - // flag that indicates that we have already found a varstore VFR - // statement for it. - // - StructDef->Referenced++; - if (StructDef->VarStoreIdValid == 0) { - // - // Set it valid so we don't flag it multiple times, then emit the error - // - StructDef->VarStoreIdValid = 1; - PrintErrorMessage (LineNum1, StructName, "varstore statement missing for this variable store"); - } - // - // Let the opcode-handler know which variable storage we're now using - // - if (mIdEqIdStmt) { - mOpcodeHandler.SetSecondaryVarStoreId (StructDef->VarStoreId); - } else { - mOpcodeHandler.SetVarStoreId (StructDef->VarStoreId); - } - // - // Found matching structure name. Now find the matching field name - // - for (FieldDef = StructDef->Field; FieldDef != NULL; FieldDef = FieldDef->Next) { - if (strcmp (FieldDef->Name, FieldName) == 0) { - // - // Make sure the variable size is valid - // - if ((FieldWidth != 0) && (FieldDef->DataSize > FieldWidth)) { - sprintf (Msg, "field width exceeds %d byte%c", FieldWidth, FieldWidth == 1 ? ' ' : 's'); - PrintErrorMessage (LineNum2, FieldName, Msg); - } - // - // If they specified an index (MyVfrData.FieldX[10]), then make sure that the - // data structure was declared as an array, and that the index is in bounds. - // If they did not specify an index, then we'll assume 0. This is required for - // strings. - // - if (IsArrayIndex) { - VarSize = FieldDef->DataSize; - if (FieldDef->IsArray == 0) { - PrintErrorMessage (LineNum2, FieldName, "field is not declared as an array"); - return; - } - if (FieldDef->ArrayLength < ArrayIndex) { - PrintErrorMessage (LineNum2, FieldName, "array index exceeds declared size of field"); - return; - } - } else { - if (FieldDef->IsArray) { - VarSize = FieldDef->DataSize * FieldDef->ArrayLength; - } else { - VarSize = FieldDef->DataSize; - } - } - // - // If we're in the middle of a ideqid VFR statement, then this is the second - // variable ID that we're now processing. Make sure that its size is the same - // as the first variable. - // - if (mIdEqIdStmt) { - if (mLastVarIdSize != VarSize) { - PrintErrorMessage (LineNum2, FieldName, "variables must have the same size"); - return; - } - } - mLastVarIdSize = VarSize; - // - // If we're supposed to write an array size, then require it to be an array - // - if (WriteArraySize && !FieldDef->IsArray) { - PrintErrorMessage (LineNum2, FieldName, "array required"); - return; - } - // - // Write the variable offset and size. If we're in the non-NV structure, then - // set the offset beyond the NV data structure size. - // - Offset = FieldDef->Offset + FieldDef->DataSize * (ArrayIndex - 1); - if (StructDef->IsNonNV) Offset += mNvDataStructSize; - WriteWord (Offset); - if (WriteLength) { - if (WriteArraySize) { - if (FieldDef->DataSize * FieldDef->ArrayLength > 255) { - PrintErrorMessage (LineNum2, FieldName, "array size exceeds 255 maximum encoding limit"); - return; - } - WriteByte (FieldDef->DataSize * FieldDef->ArrayLength, 0); - } else { - WriteByte (FieldDef->DataSize, 0); - } - } - return; - } - } - sprintf (Msg, "structure %s does not have a field named '%s'", StructName, FieldName); - PrintErrorMessage (LineNum2, Msg, NULL); - PrintErrorMessage (StructDef->LineNum, "see structure definition", NULL); - return; - } - } - // - // The structure was not found in the defined list. See if it's the "Date" structure - // - if (strcmp (StructName, "Date") == 0) { - // - // BUGBUG -- remove support for Date and Time as valid structure - // names. They should use the NON_NV_DATA_MAP structure for this. - // - // Someone specified Date.Years|Months|Days - // BUGBUG -- define some constants for the IDs used here - // Length == 0 implies that this is not user NV data storage. - // - if (strcmp (FieldName, "Year") == 0) { - // - // Write ID (offset), ID, and size - // - WriteWord (mNvDataStructSize + mNonNvDataStructSize + 0); - if (WriteLength) { - WriteByte (0, 0); - } - } else if (strcmp (FieldName, "Month") == 0) { - // - // Write ID (offset), ID, and size - // - WriteWord (mNvDataStructSize + mNonNvDataStructSize + 2); - if (WriteLength) { - WriteByte (0, 0); - } - } else if (strcmp (FieldName, "Day") == 0) { - // - // Write ID (offset), ID, and size - // - WriteWord (mNvDataStructSize + mNonNvDataStructSize + 4); - if (WriteLength) { - WriteByte (0, 0); - } - } else { - PrintErrorMessage (LineNum1, FieldName, "expected valid field name TheYear/TheMonth/TheDay"); - } - return; - } else if (strcmp (StructName, "Time") == 0) { - // - // Someone specified Time.Hours|Minutes|Seconds - // BUGBUG -- define some constants for the IDs used here - // - if (strcmp (FieldName, "Hours") == 0) { - // - // Write ID (offset), ID, and size - // - WriteWord (mNvDataStructSize + mNonNvDataStructSize + 6); - if (WriteLength) { - WriteByte (0, 0); - } - } else if (strcmp (FieldName, "Minutes") == 0) { - // - // Write ID (offset), ID, and size - // - WriteWord (mNvDataStructSize + mNonNvDataStructSize + 8); - if (WriteLength) { - WriteByte (0, 0); - } - } else if (strcmp (FieldName, "Seconds") == 0) { - // - // Write ID (offset), ID, and size - // - WriteWord (mNvDataStructSize + mNonNvDataStructSize + 10); - if (WriteLength) { - WriteByte (0, 0); - } - } else { - PrintErrorMessage (LineNum1, FieldName, "expected valid field name Hours/Minutes/Seconds"); - } - return; - } else { - PrintErrorMessage (LineNum1, StructName, "undefined structure"); - return; - } -} -VOID -EfiVfrParser::StartStructDefinition ( - INT32 IsNonNV, - INT32 LineNum - ) -/*++ - -Routine Description: - Called when we encounter a new "struct _MY_STRUCT..." statement while parsing. - Initialize internal data and structures for parsing the fields of the structure. - -Arguments: - LineNum - line number in the source file (for error reporting purposes) - IsNonNv - flag indicating (if nonzero) that the variable referred to is not in - the standard NV store. -Returns: - None - ---*/ -{ - STRUCT_DEFINITION *StructDef; - // - // Allocate memory for the structure record - // - StructDef = (STRUCT_DEFINITION *)malloc (sizeof (STRUCT_DEFINITION)); - memset (StructDef, 0, sizeof (STRUCT_DEFINITION)); - StructDef->LineNum = LineNum; - // - // Set flag indicating non-NV data structure or not - // - StructDef->IsNonNV = IsNonNV; - // - // Add it to the end of our linked list. If it's the first one - // defined, then it's the default varstore ID, so set it valid. - // - if (mFirstStructDefinition == NULL) { - mFirstStructDefinition = StructDef; - StructDef->VarStoreIdValid = 1; - } else { - mLastStructDefinition->Next = StructDef; - } - mLastStructDefinition = StructDef; -} -VOID -EfiVfrParser::EndStructDefinition ( - CHAR8 *StructName, - INT32 LineNum - ) -{ - STRUCT_DEFINITION *StructDef; - STRUCT_FIELD_DEFINITION *FieldDef; - UINT32 Offset; - // - // Make sure they have not already defined a structure with this name - // - for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) { - if ((StructDef->Name != NULL) && (strcmp (StructDef->Name, StructName) == 0)) { - PrintErrorMessage (LineNum, StructName, "structure with this name already defined"); - // - // Fall through and fill in the rest of the structure information. We do - // this because the structure has already been added to our global list, - // so will be used elsewhere, so we want it to contain valid fields. - // - } - } - // - // Allocate memory for the structure name - // - mLastStructDefinition->Name = (char *)malloc (strlen (StructName) + 1); - strcpy (mLastStructDefinition->Name, StructName); - // - // Compute the structure size, and the offsets to each field - // - Offset = 0; - for (FieldDef = mLastStructDefinition->Field; FieldDef != NULL; FieldDef = FieldDef->Next) { - FieldDef->Offset = Offset; - Offset += FieldDef->ArrayLength * FieldDef->DataSize; - } - mLastStructDefinition->Size = Offset; - // - // Go through all the structure we have so far and figure out (if we can) - // the size of the non-NV storage. We also assume that the first structure - // definition is the primary/default storage for the VFR form. - // - if (mNonNvDataStructSize == 0) { - for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) { - if (StructDef->IsNonNV) { - mNonNvDataStructSize = StructDef->Size; - break; - } - } - } - if (mNvDataStructSize == 0) { - for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) { - if (StructDef->IsNonNV == 0) { - mNvDataStructSize = StructDef->Size; - break; - } - } - } -} -VOID -EfiVfrParser::AddStructField ( - CHAR8 *FieldName, - INT32 LineNum, - INT32 DataSize, - INT32 ArrayLength, - INT8 IsArray - ) -/*++ - -Routine Description: - We're parsing the VFR structure definition. Add another defined field to - our definition. - -Arguments: - FieldName - name of the field in the structure. - LineNum - the line number from the input (preprocessor output) file - DataSize - the size of the field (1, 2, or 4 bytes) - ArrayLength - the number of elements (for array) - IsArray - non-zero if the field is an array - -Returns: - None. - ---*/ -{ - STRUCT_FIELD_DEFINITION *FieldDef; - STRUCT_FIELD_DEFINITION *Temp; - // - // Make sure we don't already have a field of this name in our structure - // - for (FieldDef = mLastStructDefinition->Field; FieldDef != NULL; FieldDef = FieldDef->Next) { - if (strcmp (FieldDef->Name, FieldName) == 0) { - PrintErrorMessage (LineNum, FieldName, "field with this name already defined"); - return; - } - } - // - // If it's an array, then they better not have a size of 0. For example: - // UINT8 MyBytes[0]; - // - if (IsArray && (ArrayLength <= 0)) { - PrintErrorMessage (LineNum, FieldName, "invalid array size"); - return; - } - // - // Allocate memory for a new structure field definition - // - FieldDef = (STRUCT_FIELD_DEFINITION *)malloc (sizeof (STRUCT_FIELD_DEFINITION)); - memset ((char *)FieldDef, 0, sizeof (STRUCT_FIELD_DEFINITION)); - FieldDef->ArrayLength = ArrayLength; - FieldDef->DataSize = DataSize; - FieldDef->IsArray = IsArray; - FieldDef->Name = (char *)malloc (strlen (FieldName) + 1); - strcpy (FieldDef->Name, FieldName); - // - // Add it to the end of the field list for the currently active structure - // - if (mLastStructDefinition->Field == NULL) { - mLastStructDefinition->Field = FieldDef; - } else { - mLastStructDefinition->LastField->Next = FieldDef; - } - mLastStructDefinition->LastField = FieldDef; -} -VOID -EfiVfrParser::AddVarStore ( - CHAR8 *StructName, // actual name of the structure - CHAR8 *VarName, // actual NV variable name - UINT16 VarStoreId, // key value - INT32 LineNum // parse line number (for error reporting) - ) -/*++ - -Routine Description: - Called while parsing a varstore statement. Add the variable store - to our linked list. - -Arguments: - StructName - the name of the typedef'ed structure to use - VarName - the NV variable name as specified in the varstore statement - VarStoreId - the variable store ID as specified in the varstore statememt - LineNum - the line number from the input (preprocessor output) file - -Returns: - None. - ---*/ -{ - STRUCT_DEFINITION *StructDef; - UINT16_LIST *L16Ptr; - // - // Go through our list of previously-defined variable store IDs and - // make sure this one is not a duplicate in name or key value. - // - for (L16Ptr = mDefinedVarStoreId; L16Ptr != NULL; L16Ptr = L16Ptr->Next) { - if (L16Ptr->Value == VarStoreId) { - PrintErrorMessage (LineNum, "variable storage key already used", NULL); - PrintErrorMessage (L16Ptr->LineNum, "previous usage of storage key", NULL); - } - } - // - // Key value of 0 is invalid since that's assigned by default to the default - // variable store (the first structure parsed). - // - if (VarStoreId == 0) { - PrintErrorMessage (LineNum, "variable storage key of 0 is invalid", NULL); - } - // - // Create a new element to add to the list - // - L16Ptr = (UINT16_LIST *)malloc(sizeof (UINT16_LIST)); - memset (L16Ptr, 0, sizeof (UINT16_LIST)); - L16Ptr->LineNum = LineNum; - L16Ptr->Value = VarStoreId; - if (mDefinedVarStoreId == NULL) { - mDefinedVarStoreId = L16Ptr; - } else { - mLastDefinedVarStoreId->Next = L16Ptr; - } - mLastDefinedVarStoreId = L16Ptr; - // - // Find the structure definition with this name - // - for (StructDef = mFirstStructDefinition; StructDef != NULL; StructDef = StructDef->Next) { - if (strcmp (StructDef->Name, StructName) == 0) { - // - // Make sure they did not already define a variable storage ID - // for this structure. - // - if (StructDef->VarStoreId != 0) { - PrintErrorMessage (LineNum, StructName, "variable storage already defined for this structure"); - PrintErrorMessage (StructDef->VarStoreLineNum, StructName, "previous definition for variable storage"); - } - StructDef->VarStoreId = VarStoreId; - StructDef->VarStoreIdValid = 1; - StructDef->VarStoreLineNum = LineNum; - WriteWord (StructDef->Size); - while (*VarName) { - WriteByte(*VarName, 0); - VarName++; - } - WriteByte(0,0); - return; - } - } - PrintErrorMessage (LineNum, StructName, "structure with this name not defined"); -} -VOID -EfiVfrParser::WriteDWord ( - UINT32 Value, - UINT8 KeyByte - ) -/*++ - -Routine Description: - During parsing, we came upon some code that requires a 32-bit value be - written to the VFR binary file. Queue up the 4 bytes. - -Arguments: - Value - the 32-bit value to write - KeyByte - a single character which gets written out beside the first byte. - This is used to tag the data in the output file so that during - debug you have an idea what the value is. - -Returns: - None. - ---*/ -{ - // - // Write 4 bytes, little endian. Specify a key byte only on the first one - // - mOpcodeHandler.AddByte ((UINT8)Value, KeyByte); - Value \>>= 8; - mOpcodeHandler.AddByte ((UINT8)Value, 0); - Value \>>= 8; - mOpcodeHandler.AddByte ((UINT8)Value, 0); - Value \>>= 8; - mOpcodeHandler.AddByte ((UINT8)Value, 0); -} -VOID -EfiVfrParser::WriteOpByte ( - UINT32 LineNum, - UINT8 ByteValue - ) -/*++ - -Routine Description: - - During parsing, we came upon a new VFR opcode. At this point we flush - the output queue and then queue up this byte (with 'O' for opcode tag). - -Arguments: - - ByteValue - opcode value - -Returns: - - None. - ---*/ -{ - mOpcodeHandler.AddOpcodeByte (ByteValue, LineNum); -} -VOID -EfiVfrParser::WriteByte ( - UINT8 ByteValue, - UINT8 Key - ) -/*++ - -Routine Description: - - During parsing of the VFR we spoonfeed this function with bytes to write to - the output VFR binary file. This function simply queues up the bytes, and - the queue gets flushed each time a new VFR opcode is encountered. - -Arguments: - - ByteValue - raw byte to write - Key - character to tag the byte with when we write ByteValue to the - output file. - -Returns: - - None. - ---*/ -{ - mOpcodeHandler.AddByte (ByteValue, Key); -} -VOID -EfiVfrParser::WriteWord ( - UINT32 Value - ) -/*++ - -Routine Description: - During VFR parsing we came upon a case where we need to write out a - 16-bit value. Queue it up. - -Arguments: - Value - value to write. - -Returns: - None. - ---*/ -{ - mOpcodeHandler.AddByte ((UINT8)Value, 0); - mOpcodeHandler.AddByte ((UINT8)((Value \>> 8) & 0xFF), 0); -} -VOID -EfiVfrParser::WriteStringIdWord ( - UINT16 WordValue - ) -{ - mOpcodeHandler.AddByte ((UINT8)WordValue, 'S'); - mOpcodeHandler.AddByte ((UINT8)((WordValue \>> 8) & 0xFF), 0); -} -VOID -EfiVfrParser::FreeGotoReferences () -/*++ - -Routine Description: - Called during cleanup to free up the memory we allocated when - keeping track of VFR goto statements. - -Arguments: - None - -Returns: - None - ---*/ -{ - GOTO_REFERENCE *CurrRef; - GOTO_REFERENCE *NextRef; - FORM_ID_VALUE *CurrFormId; - FORM_ID_VALUE *NextFormId; - UINT8 Found; - CHAR8 Name[20]; - - // - // Go through all the "goto" references and make sure there was a - // form ID of that value defined. - // - for (CurrRef = mGotoReferences; CurrRef != NULL; CurrRef = CurrRef->Next) { - Found = 0; - for (CurrFormId = mFormIdValues; CurrFormId != NULL; CurrFormId = CurrFormId->Next) { - if (CurrRef->Value == CurrFormId->Value) { - Found = 1; - break; - } - } - if (!Found) { - sprintf (Name, "%d", (UINT32)CurrRef->Value); - PrintErrorMessage (CurrRef->RefLineNum, Name, "undefined form ID"); - } - } - // - // Now free up the form id and goto references - // - CurrFormId = mFormIdValues; - while (CurrFormId != NULL) { - NextFormId = CurrFormId->Next; - free (CurrFormId); - CurrFormId = NextFormId; - } - mFormIdValues = NULL; - CurrRef = mGotoReferences; - while (CurrRef != NULL) { - NextRef = CurrRef->Next; - free (CurrRef); - CurrRef = NextRef; - } - mGotoReferences = NULL; -} -VOID -EfiVfrParser::AddGotoReference ( - UINT32 GotoNumber, - UINT32 LineNum - ) -/*++ - -Routine Description: - During VFR parsing we came upon a goto statement. Since we support - forward references, save the referenced label and at the end of parsing - we'll check that the label was actually defined somewhere. - -Arguments: - GotoNumber - the label number referenced - LineNum - the line number where the reference was made (used for - error reporting) - -Returns: - None - ---*/ -{ - GOTO_REFERENCE *NewRef; - - NewRef = (GOTO_REFERENCE *)malloc (sizeof (GOTO_REFERENCE)); - if (NewRef == NULL) { - Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); - return; - } - memset ((char *)NewRef, 0, sizeof (GOTO_REFERENCE)); - NewRef->Value = (UINT16)GotoNumber; - NewRef->RefLineNum = LineNum; - NewRef->Next = mGotoReferences; - mGotoReferences = NewRef; -} -VOID -EfiVfrParser::AddFormId ( - INT32 FormIdValue, - UINT32 LineNum - ) -/*++ - -Routine Description: - This function is called when we parse "form formid = 3" statements. - We save the form ID valud so we can verify that duplicates are not - defined. Also, these are the targets of goto statements, so when we're - done parsing the script we also go through all the goto statements to - check that there was a target FormId defined as referenced by each - goto statement. - - Note that formid = 0 is invalid. - -Arguments: - FormIdValue - the parsed value for the Form ID - LineNum - line number of the source file we're parsing - -Returns: - NA - ---*/ -{ - FORM_ID_VALUE *NewFormId; - char *FileName; - char *FileName2; - UINT32 LineNum2; - // - // Verify that FormId != 0 - // - if (FormIdValue == 0) { - FileName = ConvertLineNumber (&LineNum); - Error (FileName, LineNum, 0, "form ID cannot be 0", NULL); - return; - } - // - // First go through all previously defined form IDs and make sure they have not defined - // duplicates. - // - for (NewFormId = mFormIdValues; NewFormId != NULL; NewFormId = NewFormId->Next) { - if ((UINT16)FormIdValue == NewFormId->Value) { - FileName = ConvertLineNumber (&LineNum); - LineNum2 = NewFormId->LineNum; - FileName2 = ConvertLineNumber (&LineNum2); - Error (FileName, LineNum, 0, NULL, "form ID %d already defined", FormIdValue); - Error (FileName2, LineNum2, 0, NULL, "form ID %d previous definition", FormIdValue); - return; - } - } - // - // Allocate memory for a new one - // - NewFormId = (FORM_ID_VALUE *)malloc (sizeof (FORM_ID_VALUE)); - if (NewFormId == NULL) { - Error (PROGRAM_NAME, 0, 0, NULL, "memory allocation failure"); - return; - } - memset ((char *)NewFormId, 0, sizeof (FORM_ID_VALUE)); - NewFormId->LineNum = LineNum; - NewFormId->Next = mFormIdValues; - NewFormId->Value = (UINT16)FormIdValue; - mFormIdValues = NewFormId; -} -UINT32 -EfiVfrParser::GetNumber ( - CHAR8 *NumStr, - UINT32 LineNum, - UINT32 NumBytes - ) -{ - UINT32 Value; - - if ((NumStr[0] == '0') && (NumStr[1] == 'x')) { - AtoX (NumStr + 2, 4, &Value); - } else { - Value = (UINT32)atoi (NumStr); - } - // - // Check range - // - if ((NumBytes < 4) && (Value & ((UINT32)0xFFFFFFFF << (NumBytes * 8)))) { - PrintErrorMessage (LineNum, NumStr, "value out of range"); - return 0; - } - return Value; -} - ->> - -} // end grammar class - diff --git a/Tools/CodeTools/TianoTools/VfrCompile/VfrServices.cpp b/Tools/CodeTools/TianoTools/VfrCompile/VfrServices.cpp deleted file mode 100644 index 359256a358..0000000000 --- a/Tools/CodeTools/TianoTools/VfrCompile/VfrServices.cpp +++ /dev/null @@ -1,758 +0,0 @@ -/*++ - -Copyright (c) 2004 - 2005, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - VfrServices.cpp - -Abstract: - - Support routines for the VFR compiler - ---*/ - -#include // for FILE routines -#include // for malloc() and free() - -#include -#include -#include -#include // for EFI_UGA_PIXEL definition -#include - -#include "EfiUtilityMsgs.h" -#include "EfiVfr.h" -#include "VfrServices.h" - - -static const char *mSourceFileHeader[] = { - "//", - "// DO NOT EDIT -- auto-generated file", - "//", - "// This file is generated by the VFR compiler.", - "//", - NULL -}; - -typedef struct { - CHAR8 *Name; - INT32 Size; -} IFR_OPCODE_SIZES; - -// -// Create a table that can be used to do internal checking on the IFR -// bytes we emit. -// -static const IFR_OPCODE_SIZES mOpcodeSizes[] = { - { 0, 0 }, // invalid - { "EFI_IFR_FORM", sizeof (EFI_IFR_FORM) }, - { "EFI_IFR_SUBTITLE", sizeof (EFI_IFR_SUBTITLE) }, - { "EFI_IFR_TEXT", -6 }, //sizeof (EFI_IFR_TEXT) }, - { "unused 0x04 opcode", 0 }, // EFI_IFR_GRAPHIC_OP - { "EFI_IFR_ONE_OF", sizeof (EFI_IFR_ONE_OF) }, - { "EFI_IFR_CHECKBOX", sizeof (EFI_IFR_CHECKBOX) }, - { "EFI_IFR_NUMERIC", sizeof (EFI_IFR_NUMERIC) }, - { "EFI_IFR_PASSWORD", sizeof (EFI_IFR_PASSWORD) }, - { "EFI_IFR_ONE_OF_OPTION", sizeof (EFI_IFR_ONE_OF_OPTION) }, - { "EFI_IFR_SUPPRESS", sizeof (EFI_IFR_SUPPRESS) }, - { "EFI_IFR_END_FORM", sizeof (EFI_IFR_END_FORM) }, - { "EFI_IFR_HIDDEN", sizeof (EFI_IFR_HIDDEN) }, - { "EFI_IFR_END_FORM_SET", sizeof (EFI_IFR_END_FORM_SET) }, - { "EFI_IFR_FORM_SET", sizeof (EFI_IFR_FORM_SET) }, - { "EFI_IFR_REF", sizeof (EFI_IFR_REF) }, - { "EFI_IFR_END_ONE_OF", sizeof (EFI_IFR_END_ONE_OF) }, - { "EFI_IFR_INCONSISTENT", sizeof (EFI_IFR_INCONSISTENT) }, - { "EFI_IFR_EQ_ID_VAL", sizeof (EFI_IFR_EQ_ID_VAL) }, - { "EFI_IFR_EQ_ID_ID", sizeof (EFI_IFR_EQ_ID_ID) }, - { "EFI_IFR_EQ_ID_LIST", -sizeof (EFI_IFR_EQ_ID_LIST) }, - { "EFI_IFR_AND", sizeof (EFI_IFR_AND) }, - { "EFI_IFR_OR", sizeof (EFI_IFR_OR) }, - { "EFI_IFR_NOT", sizeof (EFI_IFR_NOT) }, - { "EFI_IFR_END_EXPR", sizeof (EFI_IFR_END_EXPR) }, - { "EFI_IFR_GRAY_OUT", sizeof (EFI_IFR_GRAY_OUT) }, - { "EFI_IFR_DATE", sizeof (EFI_IFR_DATE) / 3 }, - { "EFI_IFR_TIME", sizeof (EFI_IFR_TIME) / 3 }, - { "EFI_IFR_STRING", sizeof (EFI_IFR_STRING) }, - { "EFI_IFR_LABEL", sizeof (EFI_IFR_LABEL) }, - { "EFI_IFR_SAVE_DEFAULTS", sizeof (EFI_IFR_SAVE_DEFAULTS) }, - { "EFI_IFR_RESTORE_DEFAULTS", sizeof (EFI_IFR_RESTORE_DEFAULTS) }, - { "EFI_IFR_BANNER", sizeof (EFI_IFR_BANNER) }, - { "EFI_IFR_INVENTORY", sizeof (EFI_IFR_INVENTORY) }, - { "EFI_IFR_EQ_VAR_VAL_OP", sizeof (EFI_IFR_EQ_VAR_VAL) }, - { "EFI_IFR_ORDERED_LIST_OP", sizeof (EFI_IFR_ORDERED_LIST) }, - { "EFI_IFR_VARSTORE_OP", -sizeof (EFI_IFR_VARSTORE) }, - { "EFI_IFR_VARSTORE_SELECT_OP", sizeof (EFI_IFR_VARSTORE_SELECT) }, - { "EFI_IFR_VARSTORE_SELECT_PAIR_OP", sizeof (EFI_IFR_VARSTORE_SELECT_PAIR) }, - { "EFI_IFR_TRUE", sizeof (EFI_IFR_TRUE)}, - { "EFI_IFR_FALSE", sizeof (EFI_IFR_FALSE)}, - { "EFI_IFR_GT", sizeof (EFI_IFR_GT)}, - { "EFI_IFR_GE", sizeof (EFI_IFR_GE)}, - { "EFI_IFR_OEM_DEFINED_OP", -2 }, -}; - - -VfrOpcodeHandler::VfrOpcodeHandler ( - ) -/*++ - -Routine Description: - Constructor for the VFR opcode handling class. - -Arguments: - None - -Returns: - None - ---*/ -{ - mIfrBytes = NULL; - mLastIfrByte = NULL; - mBytesWritten = 0; - mQueuedByteCount = 0; - mQueuedOpcodeByteValid = 0; - mPrimaryVarStoreId = 0; - mSecondaryVarStoreId = 0; - mSecondaryVarStoreIdSet = 0; - mPrimaryVarStoreIdSet = 0; - mDefaultVarStoreId = 0; -} - -VOID -VfrOpcodeHandler::SetVarStoreId ( - UINT16 VarStoreId - ) -/*++ - -Routine Description: - This function is invoked by the parser when a variable is referenced in the - VFR. Save the variable store (and set a flag) so that we can later determine - if we need to emit a varstore-select or varstore-select-pair opcode. - -Arguments: - VarStoreId - ID of the variable store referenced in the VFR - -Returns: - None - ---*/ -{ - mPrimaryVarStoreId = VarStoreId; - mPrimaryVarStoreIdSet = 1; -} - -VOID -VfrOpcodeHandler::SetSecondaryVarStoreId ( - UINT16 VarStoreId - ) -/*++ - -Routine Description: - This function is invoked by the parser when a secondary variable is - referenced in the VFR. Save the variable store (and set a flag) so - that we can later determine if we need to emit a varstore-select or - varstore-pair opcode. - -Arguments: - VarStoreId - ID of the variable store referenced in the VFR - -Returns: - None - ---*/ -{ - mSecondaryVarStoreId = VarStoreId; - mSecondaryVarStoreIdSet = 1; -} - -VOID -VfrOpcodeHandler::WriteIfrBytes ( - ) -/*++ - -Routine Description: - This function is invoked at the end of parsing. Its purpose - is to write out all the IFR bytes that were queued up while - parsing. - -Arguments: - None - -Returns: - None - ---*/ -{ - IFR_BYTE *Curr; - IFR_BYTE *Next; - UINT32 Count; - UINT32 LineCount; - UINT32 PoundLines; - UINT32 ByteCount; - CHAR8 Line[MAX_LINE_LEN]; - CHAR8 *Cptr; - FILE *InFptr; - FILE *OutFptr; - UINT32 ListFile; - EFI_HII_IFR_PACK_HEADER IfrHeader; - UINT8 *Ptr; - FILE *IfrBinFptr; - UINT32 BytesLeftThisOpcode; - // - // If someone added a new opcode and didn't update our opcode sizes structure, error out. - // - if (sizeof(mOpcodeSizes) / sizeof (mOpcodeSizes[0]) != EFI_IFR_LAST_OPCODE + 1) { - Error (__FILE__, __LINE__, 0, "application error", "internal IFR binary table size is incorrect"); - return; - } - // - // Flush the queue - // - FlushQueue (); - // - // If there have been any errors to this point, then skip dumping the IFR - // binary data. This way doing an nmake again will try to build it again, and - // the build will fail if they did not fix the problem. - // - if (GetUtilityStatus () != STATUS_ERROR) { - if ((IfrBinFptr = fopen (gOptions.IfrOutputFileName, "w")) == NULL) { - Error (PROGRAM_NAME, 0, 0, gOptions.IfrOutputFileName, "could not open file for writing"); - return; - } - // - // Write the standard file header to the output file - // - WriteStandardFileHeader (IfrBinFptr); - // - // Write the structure header - // - fprintf (IfrBinFptr, "\nunsigned char %sBin[] = {", gOptions.VfrBaseFileName); - // - // Write the header - // - memset ((char *)&IfrHeader, 0, sizeof (IfrHeader)); - IfrHeader.Header.Type = EFI_HII_IFR; - IfrHeader.Header.Length = mBytesWritten + sizeof (IfrHeader); - Ptr = (UINT8 *)&IfrHeader; - for (Count = 0; Count < sizeof (IfrHeader); Count++, Ptr++) { - if ((Count & 0x03) == 0) { - fprintf (IfrBinFptr, "\n "); - } - fprintf (IfrBinFptr, "0x%02X, ", *Ptr); - } - // - // - // Write all the IFR bytes - // - fprintf (IfrBinFptr, "\n // start of IFR data"); - Curr = mIfrBytes; - Count = 0; - while (Curr != NULL) { - if ((Count & 0x0F) == 0) { - fprintf (IfrBinFptr, "\n "); - } - if (Curr->KeyByte != 0) { - fprintf (IfrBinFptr, "/*%c*/ ", Curr->KeyByte); - } - fprintf (IfrBinFptr, "0x%02X, ", Curr->OpcodeByte); - Count++; - Curr = Curr->Next; - } - fprintf (IfrBinFptr, "\n};\n\n"); - // - // - // Close the file - // - fclose (IfrBinFptr); - IfrBinFptr = NULL; - } - // - // Write the bytes as binary data if the user specified to do so - // - if ((GetUtilityStatus () != STATUS_ERROR) && (gOptions.CreateIfrBinFile != 0)) { - // - // Use the Ifr output file name with a ".hpk" extension. - // - for (Cptr = gOptions.IfrOutputFileName + strlen (gOptions.IfrOutputFileName) - 1; - (*Cptr != '.') && (Cptr > gOptions.IfrOutputFileName) && (*Cptr != '\\'); - Cptr--) { - // - // do nothing - // - } - if (*Cptr == '.') { - strcpy (Cptr, ".hpk"); - } else { - strcat (gOptions.IfrOutputFileName, ".hpk"); - } - if ((IfrBinFptr = fopen (gOptions.IfrOutputFileName, "wb")) == NULL) { - Error (PROGRAM_NAME, 0, 0, gOptions.IfrOutputFileName, "could not open file for writing"); - return; - } - // - // Write the structure header - // - memset ((char *)&IfrHeader, 0, sizeof (IfrHeader)); - IfrHeader.Header.Type = EFI_HII_IFR; - IfrHeader.Header.Length = mBytesWritten + sizeof (IfrHeader); - Ptr = (UINT8 *)&IfrHeader; - for (Count = 0; Count < sizeof (IfrHeader); Count++, Ptr++) { - fwrite (Ptr, 1, 1, IfrBinFptr); - } - // - // - // Write all the IFR bytes - // - Curr = mIfrBytes; - Count = 0; - while (Curr != NULL) { - fwrite (&Curr->OpcodeByte, 1, 1, IfrBinFptr); - Curr = Curr->Next; - } - // - // - // Close the file - // - fclose (IfrBinFptr); - IfrBinFptr = NULL; - } - // - // If creating a listing file, then open the input and output files - // - ListFile = 0; - if (gOptions.CreateListFile) { - // - // Open the input VFR file and the output list file - // - if ((InFptr = fopen (gOptions.PreprocessorOutputFileName, "r")) == NULL) { - Warning (PROGRAM_NAME, 0, 0, gOptions.PreprocessorOutputFileName, "could not open file for creating a list file"); - } else { - if ((OutFptr = fopen (gOptions.VfrListFileName, "w")) == NULL) { - Warning (PROGRAM_NAME, 0, 0, gOptions.VfrListFileName, "could not open output list file for writing"); - fclose (InFptr); - InFptr = NULL; - } else { - LineCount = 0; - ListFile = 1; - PoundLines = 0; - ByteCount = 0; - } - } - } - // - // Write the list file - // - if (ListFile) { - // - // Write out the VFR compiler version - // - fprintf (OutFptr, "//\n// VFR compiler version " VFR_COMPILER_VERSION "\n//\n"); - Curr = mIfrBytes; - while (Curr != NULL) { - // - // Print lines until we reach the line of the current opcode - // - while (LineCount < PoundLines + Curr->LineNum) { - if (fgets (Line, sizeof (Line), InFptr) != NULL) { - // - // We should check for line length exceeded on the fgets(). Otherwise it - // throws the listing file output off. Future enhancement perhaps. - // - fprintf (OutFptr, "%s", Line); - if (strncmp (Line, "#line", 5) == 0) { - PoundLines++; - } - } - LineCount++; - } - // - // Print all opcodes with line numbers less than where we are now - // - BytesLeftThisOpcode = 0; - while ((Curr != NULL) && ((Curr->LineNum == 0) || (LineCount >= PoundLines + Curr->LineNum))) { - if (BytesLeftThisOpcode == 0) { - fprintf (OutFptr, ">%08X: ", ByteCount); - if (Curr->Next != NULL) { - BytesLeftThisOpcode = (UINT32)Curr->Next->OpcodeByte; - } - } - fprintf (OutFptr, "%02X ", (UINT32)Curr->OpcodeByte); - ByteCount++; - BytesLeftThisOpcode--; - if (BytesLeftThisOpcode == 0) { - fprintf (OutFptr, "\n"); - } - Curr = Curr->Next; - } - } - // - // Dump any remaining lines from the input file - // - while (fgets (Line, sizeof (Line), InFptr) != NULL) { - fprintf (OutFptr, "%s", Line); - } - fclose (InFptr); - fclose (OutFptr); - } - // - // Debug code to make sure that each opcode we write out has as many - // bytes as the IFR structure requires. If there were errors, then - // don't do this step. - // - if (GetUtilityStatus () != STATUS_ERROR) { - Curr = mIfrBytes; - ByteCount = 0; - while (Curr != NULL) { - // - // First byte is the opcode, second byte is the length - // - if (Curr->Next == NULL) { - Error (__FILE__, __LINE__, 0, "application error", "last opcode written does not contain a length byte"); - break; - } - Count = (UINT32)Curr->Next->OpcodeByte; - if (Count == 0) { - Error ( - __FILE__, - __LINE__, - 0, - "application error", - "opcode with 0 length specified in output at offset 0x%X", - ByteCount - ); - break; - } - // - // Check the length - // - if ((Curr->OpcodeByte > EFI_IFR_LAST_OPCODE) || (Curr->OpcodeByte == 0)) { - Error ( - __FILE__, - __LINE__, - 0, - "application error", - "invalid opcode 0x%X in output at offset 0x%X", - (UINT32) Curr->OpcodeByte, ByteCount - ); - } else if (mOpcodeSizes[Curr->OpcodeByte].Size < 0) { - // - // For those cases where the length is variable, the size is negative, and indicates - // the miniumum size. - // - if ((mOpcodeSizes[Curr->OpcodeByte].Size * -1) > Count) { - Error ( - __FILE__, - __LINE__, - 0, - "application error", - "insufficient number of bytes written for %s at offset 0x%X", - mOpcodeSizes[Curr->OpcodeByte].Name, - ByteCount - ); - } - } else { - // - // Check for gaps - // - if (mOpcodeSizes[Curr->OpcodeByte].Size == 0) { - Error ( - __FILE__, - __LINE__, - 0, - "application error", - "invalid opcode 0x%X in output at offset 0x%X", - (UINT32)Curr->OpcodeByte, - ByteCount - ); - } else { - // - // Check size - // - if (mOpcodeSizes[Curr->OpcodeByte].Size != Count) { - Error ( - __FILE__, - __LINE__, - 0, - "application error", - "invalid number of bytes (%d written s/b %d) written for %s at offset 0x%X", - Count, - mOpcodeSizes[Curr->OpcodeByte].Size, - mOpcodeSizes[Curr->OpcodeByte].Name, - ByteCount - ); - } - } - } - // - // Skip to next opcode - // - while (Count > 0) { - ByteCount++; - if (Curr == NULL) { - Error (__FILE__, __LINE__, 0, "application error", "last opcode written has invalid length"); - break; - } - Curr = Curr->Next; - Count--; - } - } - } -} - -VfrOpcodeHandler::~VfrOpcodeHandler( - ) -/*++ - -Routine Description: - Destructor for the VFR opcode handler. Free up memory allocated - while parsing the VFR script. - -Arguments: - None - -Returns: - None - ---*/ -{ - IFR_BYTE *Curr; - IFR_BYTE *Next; - // - // Free up the IFR bytes - // - Curr = mIfrBytes; - while (Curr != NULL) { - Next = Curr->Next; - free (Curr); - Curr = Next; - } -} - -int -VfrOpcodeHandler::AddOpcodeByte ( - UINT8 OpcodeByte, - UINT32 LineNum - ) -/*++ - -Routine Description: - This function is invoked by the parser when a new IFR - opcode should be emitted. - -Arguments: - OpcodeByte - the IFR opcode - LineNum - the line number from the source file that resulted - in the opcode being emitted. - -Returns: - 0 always - ---*/ -{ - UINT32 Count; - - FlushQueue(); - // - // Now add this new byte - // - mQueuedOpcodeByte = OpcodeByte; - mQueuedLineNum = LineNum; - mQueuedOpcodeByteValid = 1; - return 0; -} - -VOID -VfrOpcodeHandler::AddByte ( - UINT8 ByteVal, - UINT8 KeyByte - ) -/*++ - -Routine Description: - This function is invoked by the parser when it determines - that more raw IFR bytes should be emitted to the output stream. - Here we just queue them up into an output buffer. - -Arguments: - ByteVal - the raw byte to emit to the output IFR stream - KeyByte - a value that can be used for debug. - -Returns: - None - ---*/ -{ - // - // Check for buffer overflow - // - if (mQueuedByteCount > MAX_QUEUE_COUNT) { - Error (PROGRAM_NAME, 0, 0, NULL, "opcode queue overflow"); - } else { - mQueuedBytes[mQueuedByteCount] = ByteVal; - mQueuedKeyBytes[mQueuedByteCount] = KeyByte; - mQueuedByteCount++; - } -} - -int -VfrOpcodeHandler::FlushQueue ( - ) -/*++ - -Routine Description: - This function is invoked to flush the internal IFR buffer. - -Arguments: - None - -Returns: - 0 always - ---*/ -{ - UINT32 Count; - UINT32 EmitNoneOnePair; - - EmitNoneOnePair = 0; - // - // If the secondary varstore was specified, then we have to emit - // a varstore-select-pair opcode, which only applies to the following - // statement. - // - if (mSecondaryVarStoreIdSet) { - mSecondaryVarStoreIdSet = 0; - // - // If primary and secondary are the same as the current default - // varstore, then we don't have to do anything. - // Note that the varstore-select-pair only applies to the following - // opcode. - // - if ((mPrimaryVarStoreId != mSecondaryVarStoreId) || (mPrimaryVarStoreId != mDefaultVarStoreId)) { - IAddByte (EFI_IFR_VARSTORE_SELECT_PAIR_OP, 'O', mQueuedLineNum); - IAddByte ((UINT8)sizeof (EFI_IFR_VARSTORE_SELECT_PAIR), 'L', 0); - IAddByte ((UINT8)mPrimaryVarStoreId, 0, 0); - IAddByte ((UINT8)(mPrimaryVarStoreId >> 8), 0, 0); - IAddByte ((UINT8)mSecondaryVarStoreId, 0, 0); - IAddByte ((UINT8)(mSecondaryVarStoreId >> 8), 0, 0); - } - } else if (mPrimaryVarStoreIdSet != 0) { - mPrimaryVarStoreIdSet = 0; - if (mDefaultVarStoreId != mPrimaryVarStoreId) { - // - // The VFR statement referenced a different variable store - // than the last one we reported. Insert a new varstore select - // statement. - // - IAddByte (EFI_IFR_VARSTORE_SELECT_OP, 'O', mQueuedLineNum); - IAddByte ((UINT8)sizeof (EFI_IFR_VARSTORE_SELECT), 'L', 0); - IAddByte ((UINT8)mPrimaryVarStoreId, 0, 0); - IAddByte ((UINT8)(mPrimaryVarStoreId >> 8), 0, 0); - mDefaultVarStoreId = mPrimaryVarStoreId; - } - } - // - // Likely a new opcode is being added. Since each opcode item in the IFR has - // a header that specifies the size of the opcode item (which we don't - // know until we find the next opcode in the VFR), we queue up bytes - // until we know the size. Then we write them out. So flush the queue - // now. - // - if (mQueuedOpcodeByteValid != 0) { - // - // Add the previous opcode byte, the length byte, and the binary - // data. - // - IAddByte (mQueuedOpcodeByte, 'O', mQueuedLineNum); - IAddByte ((UINT8)(mQueuedByteCount + 2), 'L', 0); - for (Count = 0; Count < mQueuedByteCount; Count++) { - IAddByte (mQueuedBytes[Count], mQueuedKeyBytes[Count], 0); - } - mQueuedByteCount = 0; - mQueuedOpcodeByteValid = 0; - } - return 0; -} - -int -VfrOpcodeHandler::IAddByte ( - UINT8 ByteVal, - UINT8 KeyByte, - UINT32 LineNum - ) -/*++ - -Routine Description: - This internal function is used to add actual IFR bytes to - the output stream. Most other functions queue up the bytes - in an internal buffer. Once they come here, there's no - going back. - - -Arguments: - ByteVal - value to write to output - KeyByte - key value tied to the byte -- useful for debug - LineNum - line number from source file the byte resulted from - -Returns: - 0 - if successful - 1 - failed due to memory allocation failure - ---*/ -{ - IFR_BYTE *NewByte; - NewByte = (IFR_BYTE *)malloc (sizeof (IFR_BYTE)); - if (NewByte == NULL) { - return 1; - } - memset ((char *)NewByte, 0, sizeof (IFR_BYTE)); - NewByte->OpcodeByte = ByteVal; - NewByte->KeyByte = KeyByte; - NewByte->LineNum = LineNum; - // - // Add to the list - // - if (mIfrBytes == NULL) { - mIfrBytes = NewByte; - } else { - mLastIfrByte->Next = NewByte; - } - mLastIfrByte = NewByte; - mBytesWritten++; - return 0; -} - -VOID -WriteStandardFileHeader ( - FILE *OutFptr - ) -/*++ - -Routine Description: - This function is invoked to emit a standard header to an - output text file. - -Arguments: - OutFptr - file to write the header to - -Returns: - None - ---*/ -{ - UINT32 TempIndex; - for (TempIndex = 0; mSourceFileHeader[TempIndex] != NULL; TempIndex++) { - fprintf (OutFptr, "%s\n", mSourceFileHeader[TempIndex]); - } - // - // Write out the VFR compiler version - // - fprintf (OutFptr, "// VFR compiler version " VFR_COMPILER_VERSION "\n//\n"); -} diff --git a/Tools/CodeTools/TianoTools/VfrCompile/VfrServices.h b/Tools/CodeTools/TianoTools/VfrCompile/VfrServices.h deleted file mode 100644 index 6b8c560d63..0000000000 --- a/Tools/CodeTools/TianoTools/VfrCompile/VfrServices.h +++ /dev/null @@ -1,227 +0,0 @@ -/*++ - -Copyright (c) 2004, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - VfrServices.h - -Abstract: - - Prototypes and defines for routines and classes used by the - EFI VFR compiler. - ---*/ - -#ifndef _VFR_SERVICES_H_ -#define _VFR_SERVICES_H_ - -class VfrOpcodeHandler -{ -public: - VfrOpcodeHandler ( - VOID - ) - /*++ - -Routine Description: - Constructor for the VFR opcode handling class. - -Arguments: - None - -Returns: - None - ---*/ - ; - ~VfrOpcodeHandler ( - VOID - ) - /*++ - -Routine Description: - Destructor for the VFR opcode handler. Free up memory allocated - while parsing the VFR script. - -Arguments: - None - -Returns: - None - ---*/ - ; - void - WriteIfrBytes ( - VOID - ) - /*++ - -Routine Description: - This function is invoked at the end of parsing. Its purpose - is to write out all the IFR bytes that were queued up while - parsing. - -Arguments: - None - -Returns: - None - ---*/ - ; - int - AddOpcodeByte ( - UINT8 OpcodeByte, - UINT32 LineNum - ) - /*++ - -Routine Description: - This function is invoked by the parser when a new IFR - opcode should be emitted. - -Arguments: - OpcodeByte - the IFR opcode - LineNum - the line number from the source file that resulted - in the opcode being emitted. - -Returns: - 0 always - ---*/ - ; - void - AddByte ( - UINT8 ByteVal, - UINT8 KeyByte - ) - /*++ - -Routine Description: - This function is invoked by the parser when it determines - that more raw IFR bytes should be emitted to the output stream. - Here we just queue them up into an output buffer. - -Arguments: - ByteVal - the raw byte to emit to the output IFR stream - KeyByte - a value that can be used for debug. - -Returns: - None - ---*/ - ; - void - SetVarStoreId ( - UINT16 VarStoreId - ) - /*++ - -Routine Description: - This function is invoked by the parser when a variable is referenced in the - VFR. Save the variable store (and set a flag) so that we can later determine - if we need to emit a varstore-select or varstore-select-pair opcode. - -Arguments: - VarStoreId - ID of the variable store referenced in the VFR - -Returns: - None - ---*/ - ; - void - SetSecondaryVarStoreId ( - UINT16 VarStoreId - ) - /*++ - -Routine Description: - This function is invoked by the parser when a secondary variable is - referenced in the VFR. Save the variable store (and set a flag) so - that we can later determine if we need to emit a varstore-select or - varstore-pair opcode. - -Arguments: - VarStoreId - ID of the variable store referenced in the VFR - -Returns: - None - ---*/ - ; - -/* */ -private: - int - FlushQueue ( - VOID - ) - /*++ - -Routine Description: - This function is invoked to flush the internal IFR buffer. - -Arguments: - None - -Returns: - 0 always - ---*/ - ; - int - IAddByte ( - UINT8 ByteVal, - UINT8 KeyByte, - UINT32 LineNum - ) - /*++ - -Routine Description: - This internal function is used to add actual IFR bytes to - the output stream. Most other functions queue up the bytes - in an internal buffer. Once they come here, there's no - going back. - - -Arguments: - ByteVal - value to write to output - KeyByte - key value tied to the byte -- useful for debug - LineNum - line number from source file the byte resulted from - -Returns: - 0 - if successful - 1 - failed due to memory allocation failure - ---*/ - ; - -/* */ -private: - IFR_BYTE *mIfrBytes; - IFR_BYTE *mLastIfrByte; - UINT32 mQueuedByteCount; - UINT32 mBytesWritten; - UINT32 mQueuedLineNum; - UINT8 mQueuedBytes[MAX_QUEUE_COUNT]; - UINT8 mQueuedKeyBytes[MAX_QUEUE_COUNT]; - UINT8 mQueuedOpcodeByte; - UINT32 mQueuedOpcodeByteValid; - UINT16 mPrimaryVarStoreId; - UINT8 mPrimaryVarStoreIdSet; - UINT16 mSecondaryVarStoreId; - UINT8 mSecondaryVarStoreIdSet; - UINT16 mDefaultVarStoreId; -}; - -#endif // #ifndef _VFR_SERVICES_H_ diff --git a/Tools/CodeTools/TianoTools/VfrCompile/build.xml b/Tools/CodeTools/TianoTools/VfrCompile/build.xml deleted file mode 100644 index 247f0d2315..0000000000 --- a/Tools/CodeTools/TianoTools/VfrCompile/build.xml +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/ZeroDebugData/ZeroDebugData.c b/Tools/CodeTools/TianoTools/ZeroDebugData/ZeroDebugData.c deleted file mode 100644 index caf129b429..0000000000 --- a/Tools/CodeTools/TianoTools/ZeroDebugData/ZeroDebugData.c +++ /dev/null @@ -1,391 +0,0 @@ -/*++ - -Copyright (c) 2004-2006 Intel Corporation. All rights reserved -This program and the accompanying materials are licensed and made available -under the terms and conditions of the BSD License which accompanies this -distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - - -Module Name: - - ZeroDebugData.c - -Abstract: - - Zero the Debug Data Fields of Portable Executable (PE) format file. - ---*/ - -#include -#include -#include - -void -PrintUsage ( - void - ) -/*++ -Routine Description: - print usage of ZeroDebugData command - -Arguments: - None - -Returns: - None ---*/ -// GC_TODO: void - add argument and description to function comment -{ - // - // print usage of command - // - printf ("\nUsage: ZeroDebugData [DebugData-File]\n"); -} - -int -ReadFromFile ( - FILE *fp, - long offset, - void *buffer, - int size - ) -/*++ -Routine Description: - read data from a specified location of file - -Arguments: - fp - file pointer - offset - number of bytes from beginning of file - buffer - buffer used to store data - size - size of buffer - -Returns: - = 0 - Success - = -1 - Failed ---*/ -{ - // - // set file pointer to the specified location of file - // - if (fseek (fp, offset, SEEK_SET) != 0) { - printf ("Error: Cannot move the current location of the file.\n"); - return -1; - } - // - // read data from the file - // - if (fread (buffer, size, 1, fp) != 1) { - printf ("Error: Cannot read data from the file.\n"); - return -1; - } - - return 0; -} - -int -ZeroDebugData ( - FILE *fp, - FILE *fpData - ) -/*++ - -Routine Description: - - Zero the debug data fields of the file - -Arguments: - - fp - file pointer - fpData - pointer to output file that ZeroDebugData progress is written to - -Returns: - - = 0 - Success - = -1 - Failed - ---*/ -{ - unsigned char header[4]; - unsigned long offset; - unsigned long NumberOfRvaAndSizes; - unsigned int nvalue; - unsigned long lvalue; - unsigned long Size; - unsigned long Pointer; - unsigned char *Buffer; - unsigned long Index; - - // - // read the header of file - // - if (ReadFromFile (fp, 0, header, 2) != 0) { - printf ("Error: open image file\n"); - return -1; - } - // - // "MZ" -- the header of image file (PE) - // - if (strncmp ((char *) header, "MZ", 2) != 0) { - printf ("Error: Invalid Image file.\n"); - return -1; - } - // - // At location 0x3C, the stub has the file offset to the - // PE signature. - // - if (ReadFromFile (fp, 0x3C, &offset, 4) != 0) { - return -1; - } - // - // read the header of optional - // - if (ReadFromFile (fp, offset, header, 4) != 0) { - return -1; - } - // - // "PE\0\0" -- the signature of optional header - // - if (strncmp ((char *) header, "PE\0\0", 4) != 0) { - printf ("Error: Invalid PE format file.\n"); - return -1; - } - // - // Add 16 to skip COFF file header, and get to optional header. - // - offset += 24; - - // - // Check the magic field, 0x10B for PE32 and 0x20B for PE32+ - // - if (ReadFromFile (fp, offset, &nvalue, 2) != 0) { - return -1; - } - // - // If this is PE32 image file, offset of NumberOfRvaAndSizes is 92. - // Else it is 108. - // - switch (nvalue & 0xFFFF) { - case 0x10B: - offset += 92; - printf ("Info: Image is PE32. "); - break; - - case 0x20B: - offset += 108; - printf ("Info: Image is PE32+. "); - break; - - default: - printf ("Error: Magic value is unknown.\n"); - return -1; - } - // - // get the value of NumberOfRvaAndSizes - // - if (ReadFromFile (fp, offset, &NumberOfRvaAndSizes, 4) != 0) { - printf ("Error: read NumberOfRvaAndSizes error.\n"); - return -1; - } - // - // printf ("Info: NumberOfRvaAndSizes = %d\n", NumberOfRvaAndSizes); - // - // - // Finding Debug Table, offset of Debug Table - // is 4 + 6 * 8 = 52. - // - if (NumberOfRvaAndSizes >= 7) { - if (ReadFromFile (fp, offset + 52, &lvalue, 4) != 0) { - return -1; - } - // - // Read the SizeOfData(16) and PointerToRawData(24) - // - if (ReadFromFile (fp, lvalue + 16, &Size, 4) != 0) { - printf ("error: Size = %d\n", Size); - return -1; - } - - printf ("Debug data: size = %xh, ", Size); - fprintf (fpData, "Debug data: size = %xh, ", Size); - - if (ReadFromFile (fp, lvalue + 20, &Pointer, 4) != 0) { - printf ("error: LoadOffset = %xh\n", Pointer); - return -1; - } - // - // printf ("LoadOffset = %xh, ", Pointer); - // - fprintf (fpData, "LoadOffset = %xh, ", Pointer); - - if (ReadFromFile (fp, lvalue + 24, &Pointer, 4) != 0) { - printf ("error: FileOffset = %xh\n", Pointer); - return -1; - } - - printf ("FileOffset = %xh, ", Pointer); - fprintf (fpData, "FileOffset = %xh, \n", Pointer); - - if ((lvalue != 0) && (Pointer != 0)) { - // - // prepare buffer - // - Buffer = malloc (Size + 1); - if (Buffer == NULL) { - printf ("Error: Cannot allocate memory.\n"); - return -1; - } - // - // set file pointer to the specified location of file - // - if (fseek (fp, Pointer, SEEK_SET) != 0) { - printf ("Error: Cannot move the current location of the file.\n"); - free (Buffer); - return -1; - } - // - // read data from PE file - // - if (fread (Buffer, Size, 1, fp) != 1) { - printf ("Error: Cannot read data from the file.\n"); - free (Buffer); - return -1; - } - // - // write to data file - // - for (Index = 0; Index < Size;) { - fprintf (fpData, "%02x ", Buffer[Index]); - - Index++; - if (Index % 8 == 0) { - fprintf (fpData, "\n"); - } - } - - fprintf (fpData, "\n"); - - // - // zero buffer and write back to PE file - // - if (fseek (fp, Pointer, SEEK_SET) != 0) { - printf ("Error: Cannot move the current location of the file.\n"); - free (Buffer); - return -1; - } - - memset (Buffer, 0, Size); - if (fwrite (Buffer, Size, 1, fp) != 1) { - perror ("Error: Cannot write zero to the file.\n"); - free (Buffer); - return -1; - } - // - // set file pointer to the specified location of file - // - if (fseek (fp, lvalue + 4, SEEK_SET) != 0) { - printf ("Error: Cannot move the current location of the file.\n"); - free (Buffer); - return -1; - } - - if (fwrite (Buffer, 4, 1, fp) != 1) { - perror ("Error: Cannot write zero to the file.\n"); - free (Buffer); - return -1; - } - - free (Buffer); - } - } - - return 0; -} - -int -main ( - int argc, - char *argv[] - ) -/*++ - -Routine Description: - - Prints the zero debug data of the PE file to the DebugData file. - Executes the ZeroDebugData function. - -Arguments: - - argc - Standard C argument, number of command line arguments. - argv[] - Standard C argument, array of pointers to the input files, - such as the PE and DebugData files. - -Returns: - - zero - success - nonzero - failure - ---*/ -{ - FILE *fp; - FILE *fpData; - char DataFile[1024] = ""; - - // - // check the number of parameters - // - if (argc < 2) { - printf ("\nUsage: ZeroDebugData [DebugData-File]\n"); - return -1; - } - // - // open the DebugData file, if not exists, return - // - if (argc >= 3) { - strcpy (DataFile, argv[2]); - } else { - strcpy (DataFile, "DebugData.dat"); - } - - fpData = fopen (DataFile, "a+"); - if (fpData == NULL) { - fpData = fopen (DataFile, "w"); - if (fpData == NULL) { - printf ("Error: Cannot open the data file!\n"); - return -1; - } - } - // - // open the PE file - // - fp = fopen (argv[1], "r+b"); - if (fp == NULL) { - printf ("Error: Cannot open the PE file!\n"); - return -1; - } - // - // Zero the Debug Data to the PE file - // - printf ("Zero Debug Data to file %s:\n", argv[1]); - fprintf (fpData, "\nZero Debug Data to file %s:\n", argv[1]); - if ((int *) ZeroDebugData (fp, fpData) != 0) { - printf ("Error: Zero Debug Data PE file\n"); - fclose (fp); - return -1; - } - - printf (" success\n"); - - // - // close the PE file - // - fflush (fpData); - fflush (fp); - fclose (fpData); - fclose (fp); - - return 0; -} diff --git a/Tools/CodeTools/TianoTools/ZeroDebugData/build.xml b/Tools/CodeTools/TianoTools/ZeroDebugData/build.xml deleted file mode 100644 index 2a85fc1af2..0000000000 --- a/Tools/CodeTools/TianoTools/ZeroDebugData/build.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/CodeTools/TianoTools/build.xml b/Tools/CodeTools/TianoTools/build.xml deleted file mode 100644 index 3d59c9c2c2..0000000000 --- a/Tools/CodeTools/TianoTools/build.xml +++ /dev/null @@ -1,269 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/build.xml b/Tools/build.xml index 5b194667e4..59f027a715 100644 --- a/Tools/build.xml +++ b/Tools/build.xml @@ -22,7 +22,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. @@ -124,7 +124,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. Java/Source/PcdTools/build.xml Java/Source/Common/build.xml Java/Source/SurfaceArea/build.xml - Source/TianoTools/build.xml + CCode/Source/build.xml Java/Source/MigrationTools/build.xml Java/Source/ContextTool/build.xml Java/Source/Merge/build.xml @@ -158,7 +158,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. Java/Source/PcdTools/build.xml Java/Source/Common/build.xml Java/Source/SurfaceArea/build.xml - Source/TianoTools/build.xml + CCode/Source/build.xml Java/Source/MigrationTools/build.xml Java/Source/ContextTool/build.xml Java/Source/Merge/build.xml