/** \file * Implementation of the ANTLR3 string and string factory classes */ // [The "BSD licence"] // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC // http://www.temporal-wave.com // http://www.linkedin.com/in/jimidle // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // 3. The name of the author may not be used to endorse or promote products // derived from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <antlr3string.h> /* Factory API */ static pANTLR3_STRING newRaw8 (pANTLR3_STRING_FACTORY factory); static pANTLR3_STRING newRawUTF16 (pANTLR3_STRING_FACTORY factory); static pANTLR3_STRING newSize8 (pANTLR3_STRING_FACTORY factory, ANTLR3_UINT32 size); static pANTLR3_STRING newSizeUTF16 (pANTLR3_STRING_FACTORY factory, ANTLR3_UINT32 size); static pANTLR3_STRING newPtr8 (pANTLR3_STRING_FACTORY factory, pANTLR3_UINT8 string, ANTLR3_UINT32 size); static pANTLR3_STRING newPtrUTF16_8 (pANTLR3_STRING_FACTORY factory, pANTLR3_UINT8 string, ANTLR3_UINT32 size); static pANTLR3_STRING newPtrUTF16_UTF16 (pANTLR3_STRING_FACTORY factory, pANTLR3_UINT8 string, ANTLR3_UINT32 size); static pANTLR3_STRING newStr8 (pANTLR3_STRING_FACTORY factory, pANTLR3_UINT8 string); static pANTLR3_STRING newStrUTF16_8 (pANTLR3_STRING_FACTORY factory, pANTLR3_UINT8 string); static pANTLR3_STRING newStrUTF16_UTF16 (pANTLR3_STRING_FACTORY factory, pANTLR3_UINT8 string); static void destroy (pANTLR3_STRING_FACTORY factory, pANTLR3_STRING string); static pANTLR3_STRING printable8 (pANTLR3_STRING_FACTORY factory, pANTLR3_STRING string); static pANTLR3_STRING printableUTF16 (pANTLR3_STRING_FACTORY factory, pANTLR3_STRING string); static void closeFactory(pANTLR3_STRING_FACTORY factory); /* String API */ static pANTLR3_UINT8 set8 (pANTLR3_STRING string, const char * chars); static pANTLR3_UINT8 setUTF16_8 (pANTLR3_STRING string, const char * chars); static pANTLR3_UINT8 setUTF16_UTF16 (pANTLR3_STRING string, const char * chars); static pANTLR3_UINT8 append8 (pANTLR3_STRING string, const char * newbit); static pANTLR3_UINT8 appendUTF16_8 (pANTLR3_STRING string, const char * newbit); static pANTLR3_UINT8 appendUTF16_UTF16 (pANTLR3_STRING string, const char * newbit); static pANTLR3_UINT8 insert8 (pANTLR3_STRING string, ANTLR3_UINT32 point, const char * newbit); static pANTLR3_UINT8 insertUTF16_8 (pANTLR3_STRING string, ANTLR3_UINT32 point, const char * newbit); static pANTLR3_UINT8 insertUTF16_UTF16 (pANTLR3_STRING string, ANTLR3_UINT32 point, const char * newbit); static pANTLR3_UINT8 setS (pANTLR3_STRING string, pANTLR3_STRING chars); static pANTLR3_UINT8 appendS (pANTLR3_STRING string, pANTLR3_STRING newbit); static pANTLR3_UINT8 insertS (pANTLR3_STRING string, ANTLR3_UINT32 point, pANTLR3_STRING newbit); static pANTLR3_UINT8 addc8 (pANTLR3_STRING string, ANTLR3_UINT32 c); static pANTLR3_UINT8 addcUTF16 (pANTLR3_STRING string, ANTLR3_UINT32 c); static pANTLR3_UINT8 addi8 (pANTLR3_STRING string, ANTLR3_INT32 i); static pANTLR3_UINT8 addiUTF16 (pANTLR3_STRING string, ANTLR3_INT32 i); static pANTLR3_UINT8 inserti8 (pANTLR3_STRING string, ANTLR3_UINT32 point, ANTLR3_INT32 i); static pANTLR3_UINT8 insertiUTF16 (pANTLR3_STRING string, ANTLR3_UINT32 point, ANTLR3_INT32 i); static ANTLR3_UINT32 compare8 (pANTLR3_STRING string, const char * compStr); static ANTLR3_UINT32 compareUTF16_8 (pANTLR3_STRING string, const char * compStr); static ANTLR3_UINT32 compareUTF16_UTF16(pANTLR3_STRING string, const char * compStr); static ANTLR3_UINT32 compareS (pANTLR3_STRING string, pANTLR3_STRING compStr); static ANTLR3_UCHAR charAt8 (pANTLR3_STRING string, ANTLR3_UINT32 offset); static ANTLR3_UCHAR charAtUTF16 (pANTLR3_STRING string, ANTLR3_UINT32 offset); static pANTLR3_STRING subString8 (pANTLR3_STRING string, ANTLR3_UINT32 startIndex, ANTLR3_UINT32 endIndex); static pANTLR3_STRING subStringUTF16 (pANTLR3_STRING string, ANTLR3_UINT32 startIndex, ANTLR3_UINT32 endIndex); static ANTLR3_INT32 toInt32_8 (pANTLR3_STRING string); static ANTLR3_INT32 toInt32_UTF16 (pANTLR3_STRING string); static pANTLR3_STRING to8_8 (pANTLR3_STRING string); static pANTLR3_STRING to8_UTF16 (pANTLR3_STRING string); static pANTLR3_STRING toUTF8_8 (pANTLR3_STRING string); static pANTLR3_STRING toUTF8_UTF16 (pANTLR3_STRING string); /* Local helpers */ static void stringInit8 (pANTLR3_STRING string); static void stringInitUTF16 (pANTLR3_STRING string); static void ANTLR3_CDECL stringFree (pANTLR3_STRING string); ANTLR3_API pANTLR3_STRING_FACTORY antlr3StringFactoryNew(ANTLR3_UINT32 encoding) { pANTLR3_STRING_FACTORY factory; /* Allocate memory */ factory = (pANTLR3_STRING_FACTORY) ANTLR3_CALLOC(1, sizeof(ANTLR3_STRING_FACTORY)); if (factory == NULL) { return NULL; } /* Now we make a new list to track the strings. */ factory->strings = antlr3VectorNew(0); factory->index = 0; if (factory->strings == NULL) { ANTLR3_FREE(factory); return NULL; } // Install the API // // TODO: These encodings need equivalent functions to // UTF16 and 8Bit if I am going to support those encodings in the STRING stuff. // The STRING stuff was intended as a quick and dirty hack for people that did not // want to worry about memory and performance very much, but nobody ever reads the // notes or comments or uses the email list search. I want to discourage using these // interfaces as it is much more efficient to use the pointers within the tokens // directly, so I am not implementing the string stuff for the newer encodings. // We install the standard 8 and 16 bit functions for the UTF 8 and 16 but they // will not be useful beyond returning the text. // switch(encoding) { case ANTLR3_ENC_UTF32: break; case ANTLR3_ENC_UTF32BE: break; case ANTLR3_ENC_UTF32LE: break; case ANTLR3_ENC_UTF16BE: case ANTLR3_ENC_UTF16LE: case ANTLR3_ENC_UTF16: factory->newRaw = newRawUTF16; factory->newSize = newSizeUTF16; factory->newPtr = newPtrUTF16_UTF16; factory->newPtr8 = newPtrUTF16_8; factory->newStr = newStrUTF16_UTF16; factory->newStr8 = newStrUTF16_8; factory->printable = printableUTF16; factory->destroy = destroy; factory->close = closeFactory; break; case ANTLR3_ENC_UTF8: case ANTLR3_ENC_EBCDIC: case ANTLR3_ENC_8BIT: default: factory->newRaw = newRaw8; factory->newSize = newSize8; factory->newPtr = newPtr8; factory->newPtr8 = newPtr8; factory->newStr = newStr8; factory->newStr8 = newStr8; factory->printable = printable8; factory->destroy = destroy; factory->close = closeFactory; break; } return factory; } /** * * \param factory * \return */ static pANTLR3_STRING newRaw8 (pANTLR3_STRING_FACTORY factory) { pANTLR3_STRING string; string = (pANTLR3_STRING) ANTLR3_MALLOC(sizeof(ANTLR3_STRING)); if (string == NULL) { return NULL; } /* Structure is allocated, now fill in the API etc. */ stringInit8(string); string->factory = factory; /* Add the string into the allocated list */ factory->strings->set(factory->strings, factory->index, (void *) string, (void (ANTLR3_CDECL *)(void *))(stringFree), ANTLR3_TRUE); string->index = factory->index++; return string; } /** * * \param factory * \return */ static pANTLR3_STRING newRawUTF16 (pANTLR3_STRING_FACTORY factory) { pANTLR3_STRING string; string = (pANTLR3_STRING) ANTLR3_MALLOC(sizeof(ANTLR3_STRING)); if (string == NULL) { return NULL; } /* Structure is allocated, now fill in the API etc. */ stringInitUTF16(string); string->factory = factory; /* Add the string into the allocated list */ factory->strings->set(factory->strings, factory->index, (void *) string, (void (ANTLR3_CDECL *)(void *))(stringFree), ANTLR3_TRUE); string->index = factory->index++; return string; } static void ANTLR3_CDECL stringFree (pANTLR3_STRING string) { /* First free the string itself if there was anything in it */ if (string->chars) { ANTLR3_FREE(string->chars); } /* Now free the space for this string */ ANTLR3_FREE(string); return; } /** * * \param string * \return */ static void stringInit8 (pANTLR3_STRING string) { string->len = 0; string->size = 0; string->chars = NULL; string->encoding = ANTLR3_ENC_8BIT ; /* API for 8 bit strings*/ string->set = set8; string->set8 = set8; string->append = append8; string->append8 = append8; string->insert = insert8; string->insert8 = insert8; string->addi = addi8; string->inserti = inserti8; string->addc = addc8; string->charAt = charAt8; string->compare = compare8; string->compare8 = compare8; string->subString = subString8; string->toInt32 = toInt32_8; string->to8 = to8_8; string->toUTF8 = toUTF8_8; string->compareS = compareS; string->setS = setS; string->appendS = appendS; string->insertS = insertS; } /** * * \param string * \return */ static void stringInitUTF16 (pANTLR3_STRING string) { string->len = 0; string->size = 0; string->chars = NULL; string->encoding = ANTLR3_ENC_8BIT; /* API for UTF16 strings */ string->set = setUTF16_UTF16; string->set8 = setUTF16_8; string->append = appendUTF16_UTF16; string->append8 = appendUTF16_8; string->insert = insertUTF16_UTF16; string->insert8 = insertUTF16_8; string->addi = addiUTF16; string->inserti = insertiUTF16; string->addc = addcUTF16; string->charAt = charAtUTF16; string->compare = compareUTF16_UTF16; string->compare8 = compareUTF16_8; string->subString = subStringUTF16; string->toInt32 = toInt32_UTF16; string->to8 = to8_UTF16; string->toUTF8 = toUTF8_UTF16; string->compareS = compareS; string->setS = setS; string->appendS = appendS; string->insertS = insertS; } /** * * \param string * \return * TODO: Implement UTF-8 */ static void stringInitUTF8 (pANTLR3_STRING string) { string->len = 0; string->size = 0; string->chars = NULL; /* API */ } // Convert an 8 bit string into a UTF8 representation, which is in fact just the string itself // a memcpy as we make no assumptions about the 8 bit encoding. // static pANTLR3_STRING toUTF8_8 (pANTLR3_STRING string) { return string->factory->newPtr(string->factory, (pANTLR3_UINT8)(string->chars), string->len); } // Convert a UTF16 string into a UTF8 representation using the Unicode.org // supplied C algorithms, which are now contained within the ANTLR3 C runtime // as permitted by the Unicode license (within the source code antlr3convertutf.c/.h // UCS2 has the same encoding as UTF16 so we can use UTF16 converter. // static pANTLR3_STRING toUTF8_UTF16 (pANTLR3_STRING string) { UTF8 * outputEnd; UTF16 * inputEnd; pANTLR3_STRING utf8String; ConversionResult cResult; // Allocate the output buffer, which needs to accommodate potentially // 3X (in bytes) the input size (in chars). // utf8String = string->factory->newStr8(string->factory, (pANTLR3_UINT8)""); if (utf8String != NULL) { // Free existing allocation // ANTLR3_FREE(utf8String->chars); // Reallocate according to maximum expected size // utf8String->size = string->len *3; utf8String->chars = (pANTLR3_UINT8)ANTLR3_MALLOC(utf8String->size +1); if (utf8String->chars != NULL) { inputEnd = (UTF16 *) (string->chars); outputEnd = (UTF8 *) (utf8String->chars); // Call the Unicode converter // cResult = ConvertUTF16toUTF8 ( (const UTF16**)&inputEnd, ((const UTF16 *)(string->chars)) + string->len, &outputEnd, outputEnd + utf8String->size - 1, lenientConversion ); // We don't really care if things failed or not here, we just converted // everything that was vaguely possible and stopped when it wasn't. It is // up to the grammar programmer to verify that the input is sensible. // utf8String->len = ANTLR3_UINT32_CAST(((pANTLR3_UINT8)outputEnd) - utf8String->chars); *(outputEnd+1) = '\0'; // Always null terminate } } return utf8String; } /** * Creates a new string with enough capacity for size 8 bit characters plus a terminator. * * \param[in] factory - Pointer to the string factory that owns strings * \param[in] size - In characters * \return pointer to the new string. */ static pANTLR3_STRING newSize8 (pANTLR3_STRING_FACTORY factory, ANTLR3_UINT32 size) { pANTLR3_STRING string; string = factory->newRaw(factory); if (string == NULL) { return string; } /* Always add one more byte for a terminator ;-) */ string->chars = (pANTLR3_UINT8) ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_UINT8) * (size+1))); *(string->chars) = '\0'; string->size = size + 1; return string; } /** * Creates a new string with enough capacity for size UTF16 characters plus a terminator. * * \param[in] factory - Pointer to the string factory that owns strings * \param[in] size - In characters (count double for surrogate pairs!!!) * \return pointer to the new string. */ static pANTLR3_STRING newSizeUTF16 (pANTLR3_STRING_FACTORY factory, ANTLR3_UINT32 size) { pANTLR3_STRING string; string = factory->newRaw(factory); if (string == NULL) { return string; } /* Always add one more byte for a terminator ;-) */ string->chars = (pANTLR3_UINT8) ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_UINT16) * (size+1))); *(string->chars) = '\0'; string->size = size+1; /* Size is always in characters, as is len */ return string; } /** Creates a new 8 bit string initialized with the 8 bit characters at the * supplied ptr, of pre-determined size. * \param[in] factory - Pointer to the string factory that owns the strings * \param[in] ptr - Pointer to 8 bit encoded characters * \return pointer to the new string */ static pANTLR3_STRING newPtr8 (pANTLR3_STRING_FACTORY factory, pANTLR3_UINT8 ptr, ANTLR3_UINT32 size) { pANTLR3_STRING string; string = factory->newSize(factory, size); if (string == NULL) { return NULL; } if (size <= 0) { return string; } if (ptr != NULL) { ANTLR3_MEMMOVE(string->chars, (const void *)ptr, size); *(string->chars + size) = '\0'; /* Terminate, these strings are usually used for Token streams and printing etc. */ string->len = size; } return string; } /** Creates a new UTF16 string initialized with the 8 bit characters at the * supplied 8 bit character ptr, of pre-determined size. * \param[in] factory - Pointer to the string factory that owns the strings * \param[in] ptr - Pointer to 8 bit encoded characters * \return pointer to the new string */ static pANTLR3_STRING newPtrUTF16_8 (pANTLR3_STRING_FACTORY factory, pANTLR3_UINT8 ptr, ANTLR3_UINT32 size) { pANTLR3_STRING string; /* newSize accepts size in characters, not bytes */ string = factory->newSize(factory, size); if (string == NULL) { return NULL; } if (size <= 0) { return string; } if (ptr != NULL) { pANTLR3_UINT16 out; ANTLR3_INT32 inSize; out = (pANTLR3_UINT16)(string->chars); inSize = size; while (inSize-- > 0) { *out++ = (ANTLR3_UINT16)(*ptr++); } /* Terminate, these strings are usually used for Token streams and printing etc. */ *(((pANTLR3_UINT16)(string->chars)) + size) = '\0'; string->len = size; } return string; } /** Creates a new UTF16 string initialized with the UTF16 characters at the * supplied ptr, of pre-determined size. * \param[in] factory - Pointer to the string factory that owns the strings * \param[in] ptr - Pointer to UTF16 encoded characters * \return pointer to the new string */ static pANTLR3_STRING newPtrUTF16_UTF16 (pANTLR3_STRING_FACTORY factory, pANTLR3_UINT8 ptr, ANTLR3_UINT32 size) { pANTLR3_STRING string; string = factory->newSize(factory, size); if (string == NULL) { return NULL; } if (size <= 0) { return string; } if (ptr != NULL) { ANTLR3_MEMMOVE(string->chars, (const void *)ptr, (size * sizeof(ANTLR3_UINT16))); /* Terminate, these strings are usually used for Token streams and printing etc. */ *(((pANTLR3_UINT16)(string->chars)) + size) = '\0'; string->len = size; } return string; } /** Create a new 8 bit string from the supplied, null terminated, 8 bit string pointer. * \param[in] factory - Pointer to the string factory that owns strings. * \param[in] ptr - Pointer to the 8 bit encoded string * \return Pointer to the newly initialized string */ static pANTLR3_STRING newStr8 (pANTLR3_STRING_FACTORY factory, pANTLR3_UINT8 ptr) { return factory->newPtr8(factory, ptr, (ANTLR3_UINT32)strlen((const char *)ptr)); } /** Create a new UTF16 string from the supplied, null terminated, 8 bit string pointer. * \param[in] factory - Pointer to the string factory that owns strings. * \param[in] ptr - Pointer to the 8 bit encoded string * \return POinter to the newly initialized string */ static pANTLR3_STRING newStrUTF16_8 (pANTLR3_STRING_FACTORY factory, pANTLR3_UINT8 ptr) { return factory->newPtr8(factory, ptr, (ANTLR3_UINT32)strlen((const char *)ptr)); } /** Create a new UTF16 string from the supplied, null terminated, UTF16 string pointer. * \param[in] factory - Pointer to the string factory that owns strings. * \param[in] ptr - Pointer to the UTF16 encoded string * \return Pointer to the newly initialized string */ static pANTLR3_STRING newStrUTF16_UTF16 (pANTLR3_STRING_FACTORY factory, pANTLR3_UINT8 ptr) { pANTLR3_UINT16 in; ANTLR3_UINT32 count; /** First, determine the length of the input string */ in = (pANTLR3_UINT16)ptr; count = 0; while (*in++ != '\0') { count++; } return factory->newPtr(factory, ptr, count); } static void destroy (pANTLR3_STRING_FACTORY factory, pANTLR3_STRING string) { // Record which string we are deleting // ANTLR3_UINT32 strIndex = string->index; // Ensure that the string was not factory made, or we would try // to delete memory that wasn't allocated outside the factory // block. // Remove the specific indexed string from the vector // factory->strings->del(factory->strings, strIndex); // One less string in the vector, so decrement the factory index // so that the next string allocated is indexed correctly with // respect to the vector. // factory->index--; // Now we have to reindex the strings in the vector that followed // the one we just deleted. We only do this if the one we just deleted // was not the last one. // if (strIndex< factory->index) { // We must reindex the strings after the one we just deleted. // The one that follows the one we just deleted is also out // of whack, so we start there. // ANTLR3_UINT32 i; for (i = strIndex; i < factory->index; i++) { // Renumber the entry // ((pANTLR3_STRING)(factory->strings->elements[i].element))->index = i; } } // The string has been destroyed and the elements of the factory are reindexed. // } static pANTLR3_STRING printable8(pANTLR3_STRING_FACTORY factory, pANTLR3_STRING instr) { pANTLR3_STRING string; /* We don't need to be too efficient here, this is mostly for error messages and so on. */ pANTLR3_UINT8 scannedText; ANTLR3_UINT32 i; /* Assume we need as much as twice as much space to parse out the control characters */ string = factory->newSize(factory, instr->len *2 + 1); /* Scan through and replace unprintable (in terms of this routine) * characters */ scannedText = string->chars; for (i = 0; i < instr->len; i++) { if (*(instr->chars + i) == '\n') { *scannedText++ = '\\'; *scannedText++ = 'n'; } else if (*(instr->chars + i) == '\r') { *scannedText++ = '\\'; *scannedText++ = 'r'; } else if (!isprint(*(instr->chars +i))) { *scannedText++ = '?'; } else { *scannedText++ = *(instr->chars + i); } } *scannedText = '\0'; string->len = (ANTLR3_UINT32)(scannedText - string->chars); return string; } static pANTLR3_STRING printableUTF16(pANTLR3_STRING_FACTORY factory, pANTLR3_STRING instr) { pANTLR3_STRING string; /* We don't need to be too efficient here, this is mostly for error messages and so on. */ pANTLR3_UINT16 scannedText; pANTLR3_UINT16 inText; ANTLR3_UINT32 i; ANTLR3_UINT32 outLen; /* Assume we need as much as twice as much space to parse out the control characters */ string = factory->newSize(factory, instr->len *2 + 1); /* Scan through and replace unprintable (in terms of this routine) * characters */ scannedText = (pANTLR3_UINT16)(string->chars); inText = (pANTLR3_UINT16)(instr->chars); outLen = 0; for (i = 0; i < instr->len; i++) { if (*(inText + i) == '\n') { *scannedText++ = '\\'; *scannedText++ = 'n'; outLen += 2; } else if (*(inText + i) == '\r') { *scannedText++ = '\\'; *scannedText++ = 'r'; outLen += 2; } else if (!isprint(*(inText +i))) { *scannedText++ = '?'; outLen++; } else { *scannedText++ = *(inText + i); outLen++; } } *scannedText = '\0'; string->len = outLen; return string; } /** Fascist Capitalist Pig function created * to oppress the workers comrade. */ static void closeFactory (pANTLR3_STRING_FACTORY factory) { /* Delete the vector we were tracking the strings with, this will * causes all the allocated strings to be deallocated too */ factory->strings->free(factory->strings); /* Delete the space for the factory itself */ ANTLR3_FREE((void *)factory); } static pANTLR3_UINT8 append8 (pANTLR3_STRING string, const char * newbit) { ANTLR3_UINT32 len; len = (ANTLR3_UINT32)strlen(newbit); if (string->size < (string->len + len + 1)) { string->chars = (pANTLR3_UINT8) ANTLR3_REALLOC((void *)string->chars, (ANTLR3_UINT32)(string->len + len + 1)); string->size = string->len + len + 1; } /* Note we copy one more byte than the strlen in order to get the trailing */ ANTLR3_MEMMOVE((void *)(string->chars + string->len), newbit, (ANTLR3_UINT32)(len+1)); string->len += len; return string->chars; } static pANTLR3_UINT8 appendUTF16_8 (pANTLR3_STRING string, const char * newbit) { ANTLR3_UINT32 len; pANTLR3_UINT16 apPoint; ANTLR3_UINT32 count; len = (ANTLR3_UINT32)strlen(newbit); if (string->size < (string->len + len + 1)) { string->chars = (pANTLR3_UINT8) ANTLR3_REALLOC((void *)string->chars, (ANTLR3_UINT32)((sizeof(ANTLR3_UINT16)*(string->len + len + 1)))); string->size = string->len + len + 1; } apPoint = ((pANTLR3_UINT16)string->chars) + string->len; string->len += len; for (count = 0; count < len; count++) { *apPoint++ = *(newbit + count); } *apPoint = '\0'; return string->chars; } static pANTLR3_UINT8 appendUTF16_UTF16 (pANTLR3_STRING string, const char * newbit) { ANTLR3_UINT32 len; pANTLR3_UINT16 in; /** First, determine the length of the input string */ in = (pANTLR3_UINT16)newbit; len = 0; while (*in++ != '\0') { len++; } if (string->size < (string->len + len + 1)) { string->chars = (pANTLR3_UINT8) ANTLR3_REALLOC((void *)string->chars, (ANTLR3_UINT32)( sizeof(ANTLR3_UINT16) *(string->len + len + 1) )); string->size = string->len + len + 1; } /* Note we copy one more byte than the strlen in order to get the trailing delimiter */ ANTLR3_MEMMOVE((void *)(((pANTLR3_UINT16)string->chars) + string->len), newbit, (ANTLR3_UINT32)(sizeof(ANTLR3_UINT16)*(len+1))); string->len += len; return string->chars; } static pANTLR3_UINT8 set8 (pANTLR3_STRING string, const char * chars) { ANTLR3_UINT32 len; len = (ANTLR3_UINT32)strlen(chars); if (string->size < len + 1) { string->chars = (pANTLR3_UINT8) ANTLR3_REALLOC((void *)string->chars, (ANTLR3_UINT32)(len + 1)); string->size = len + 1; } /* Note we copy one more byte than the strlen in order to get the trailing '\0' */ ANTLR3_MEMMOVE((void *)(string->chars), chars, (ANTLR3_UINT32)(len+1)); string->len = len; return string->chars; } static pANTLR3_UINT8 setUTF16_8 (pANTLR3_STRING string, const char * chars) { ANTLR3_UINT32 len; ANTLR3_UINT32 count; pANTLR3_UINT16 apPoint; len = (ANTLR3_UINT32)strlen(chars); if (string->size < len + 1) { string->chars = (pANTLR3_UINT8) ANTLR3_REALLOC((void *)string->chars, (ANTLR3_UINT32)(sizeof(ANTLR3_UINT16)*(len + 1))); string->size = len + 1; } apPoint = ((pANTLR3_UINT16)string->chars); string->len = len; for (count = 0; count < string->len; count++) { *apPoint++ = *(chars + count); } *apPoint = '\0'; return string->chars; } static pANTLR3_UINT8 setUTF16_UTF16 (pANTLR3_STRING string, const char * chars) { ANTLR3_UINT32 len; pANTLR3_UINT16 in; /** First, determine the length of the input string */ in = (pANTLR3_UINT16)chars; len = 0; while (*in++ != '\0') { len++; } if (string->size < len + 1) { string->chars = (pANTLR3_UINT8) ANTLR3_REALLOC((void *)string->chars, (ANTLR3_UINT32)(sizeof(ANTLR3_UINT16)*(len + 1))); string->size = len + 1; } /* Note we copy one more byte than the strlen in order to get the trailing '\0' */ ANTLR3_MEMMOVE((void *)(string->chars), chars, (ANTLR3_UINT32)((len+1) * sizeof(ANTLR3_UINT16))); string->len = len; return string->chars; } static pANTLR3_UINT8 addc8 (pANTLR3_STRING string, ANTLR3_UINT32 c) { if (string->size < string->len + 2) { string->chars = (pANTLR3_UINT8) ANTLR3_REALLOC((void *)string->chars, (ANTLR3_UINT32)(string->len + 2)); string->size = string->len + 2; } *(string->chars + string->len) = (ANTLR3_UINT8)c; *(string->chars + string->len + 1) = '\0'; string->len++; return string->chars; } static pANTLR3_UINT8 addcUTF16 (pANTLR3_STRING string, ANTLR3_UINT32 c) { pANTLR3_UINT16 ptr; if (string->size < string->len + 2) { string->chars = (pANTLR3_UINT8) ANTLR3_REALLOC((void *)string->chars, (ANTLR3_UINT32)(sizeof(ANTLR3_UINT16) * (string->len + 2))); string->size = string->len + 2; } ptr = (pANTLR3_UINT16)(string->chars); *(ptr + string->len) = (ANTLR3_UINT16)c; *(ptr + string->len + 1) = '\0'; string->len++; return string->chars; } static pANTLR3_UINT8 addi8 (pANTLR3_STRING string, ANTLR3_INT32 i) { ANTLR3_UINT8 newbit[32]; sprintf((char *)newbit, "%d", i); return string->append8(string, (const char *)newbit); } static pANTLR3_UINT8 addiUTF16 (pANTLR3_STRING string, ANTLR3_INT32 i) { ANTLR3_UINT8 newbit[32]; sprintf((char *)newbit, "%d", i); return string->append8(string, (const char *)newbit); } static pANTLR3_UINT8 inserti8 (pANTLR3_STRING string, ANTLR3_UINT32 point, ANTLR3_INT32 i) { ANTLR3_UINT8 newbit[32]; sprintf((char *)newbit, "%d", i); return string->insert8(string, point, (const char *)newbit); } static pANTLR3_UINT8 insertiUTF16 (pANTLR3_STRING string, ANTLR3_UINT32 point, ANTLR3_INT32 i) { ANTLR3_UINT8 newbit[32]; sprintf((char *)newbit, "%d", i); return string->insert8(string, point, (const char *)newbit); } static pANTLR3_UINT8 insert8 (pANTLR3_STRING string, ANTLR3_UINT32 point, const char * newbit) { ANTLR3_UINT32 len; if (point >= string->len) { return string->append(string, newbit); } len = (ANTLR3_UINT32)strlen(newbit); if (len == 0) { return string->chars; } if (string->size < (string->len + len + 1)) { string->chars = (pANTLR3_UINT8) ANTLR3_REALLOC((void *)string->chars, (ANTLR3_UINT32)(string->len + len + 1)); string->size = string->len + len + 1; } /* Move the characters we are inserting before, including the delimiter */ ANTLR3_MEMMOVE((void *)(string->chars + point + len), (void *)(string->chars + point), (ANTLR3_UINT32)(string->len - point + 1)); /* Note we copy the exact number of bytes */ ANTLR3_MEMMOVE((void *)(string->chars + point), newbit, (ANTLR3_UINT32)(len)); string->len += len; return string->chars; } static pANTLR3_UINT8 insertUTF16_8 (pANTLR3_STRING string, ANTLR3_UINT32 point, const char * newbit) { ANTLR3_UINT32 len; ANTLR3_UINT32 count; pANTLR3_UINT16 inPoint; if (point >= string->len) { return string->append8(string, newbit); } len = (ANTLR3_UINT32)strlen(newbit); if (len == 0) { return string->chars; } if (string->size < (string->len + len + 1)) { string->chars = (pANTLR3_UINT8) ANTLR3_REALLOC((void *)string->chars, (ANTLR3_UINT32)(sizeof(ANTLR3_UINT16)*(string->len + len + 1))); string->size = string->len + len + 1; } /* Move the characters we are inserting before, including the delimiter */ ANTLR3_MEMMOVE((void *)(((pANTLR3_UINT16)string->chars) + point + len), (void *)(((pANTLR3_UINT16)string->chars) + point), (ANTLR3_UINT32)(sizeof(ANTLR3_UINT16)*(string->len - point + 1))); string->len += len; inPoint = ((pANTLR3_UINT16)(string->chars))+point; for (count = 0; count<len; count++) { *(inPoint + count) = (ANTLR3_UINT16)(*(newbit+count)); } return string->chars; } static pANTLR3_UINT8 insertUTF16_UTF16 (pANTLR3_STRING string, ANTLR3_UINT32 point, const char * newbit) { ANTLR3_UINT32 len; pANTLR3_UINT16 in; if (point >= string->len) { return string->append(string, newbit); } /** First, determine the length of the input string */ in = (pANTLR3_UINT16)newbit; len = 0; while (*in++ != '\0') { len++; } if (len == 0) { return string->chars; } if (string->size < (string->len + len + 1)) { string->chars = (pANTLR3_UINT8) ANTLR3_REALLOC((void *)string->chars, (ANTLR3_UINT32)(sizeof(ANTLR3_UINT16)*(string->len + len + 1))); string->size = string->len + len + 1; } /* Move the characters we are inserting before, including the delimiter */ ANTLR3_MEMMOVE((void *)(((pANTLR3_UINT16)string->chars) + point + len), (void *)(((pANTLR3_UINT16)string->chars) + point), (ANTLR3_UINT32)(sizeof(ANTLR3_UINT16)*(string->len - point + 1))); /* Note we copy the exact number of characters */ ANTLR3_MEMMOVE((void *)(((pANTLR3_UINT16)string->chars) + point), newbit, (ANTLR3_UINT32)(sizeof(ANTLR3_UINT16)*(len))); string->len += len; return string->chars; } static pANTLR3_UINT8 setS (pANTLR3_STRING string, pANTLR3_STRING chars) { return string->set(string, (const char *)(chars->chars)); } static pANTLR3_UINT8 appendS (pANTLR3_STRING string, pANTLR3_STRING newbit) { /* We may be passed an empty string, in which case we just return the current pointer */ if (newbit == NULL || newbit->len == 0 || newbit->size == 0 || newbit->chars == NULL) { return string->chars; } else { return string->append(string, (const char *)(newbit->chars)); } } static pANTLR3_UINT8 insertS (pANTLR3_STRING string, ANTLR3_UINT32 point, pANTLR3_STRING newbit) { return string->insert(string, point, (const char *)(newbit->chars)); } /* Function that compares the text of a string to the supplied * 8 bit character string and returns a result a la strcmp() */ static ANTLR3_UINT32 compare8 (pANTLR3_STRING string, const char * compStr) { return strcmp((const char *)(string->chars), compStr); } /* Function that compares the text of a string with the supplied character string * (which is assumed to be in the same encoding as the string itself) and returns a result * a la strcmp() */ static ANTLR3_UINT32 compareUTF16_8 (pANTLR3_STRING string, const char * compStr) { pANTLR3_UINT16 ourString; ANTLR3_UINT32 charDiff; ourString = (pANTLR3_UINT16)(string->chars); while (((ANTLR3_UCHAR)(*ourString) != '\0') && ((ANTLR3_UCHAR)(*compStr) != '\0')) { charDiff = *ourString - *compStr; if (charDiff != 0) { return charDiff; } ourString++; compStr++; } /* At this point, one of the strings was terminated */ return (ANTLR3_UINT32)((ANTLR3_UCHAR)(*ourString) - (ANTLR3_UCHAR)(*compStr)); } /* Function that compares the text of a string with the supplied character string * (which is assumed to be in the same encoding as the string itself) and returns a result * a la strcmp() */ static ANTLR3_UINT32 compareUTF16_UTF16 (pANTLR3_STRING string, const char * compStr8) { pANTLR3_UINT16 ourString; pANTLR3_UINT16 compStr; ANTLR3_UINT32 charDiff; ourString = (pANTLR3_UINT16)(string->chars); compStr = (pANTLR3_UINT16)(compStr8); while (((ANTLR3_UCHAR)(*ourString) != '\0') && ((ANTLR3_UCHAR)(*((pANTLR3_UINT16)compStr)) != '\0')) { charDiff = *ourString - *compStr; if (charDiff != 0) { return charDiff; } ourString++; compStr++; } /* At this point, one of the strings was terminated */ return (ANTLR3_UINT32)((ANTLR3_UCHAR)(*ourString) - (ANTLR3_UCHAR)(*compStr)); } /* Function that compares the text of a string with the supplied string * (which is assumed to be in the same encoding as the string itself) and returns a result * a la strcmp() */ static ANTLR3_UINT32 compareS (pANTLR3_STRING string, pANTLR3_STRING compStr) { return string->compare(string, (const char *)compStr->chars); } /* Function that returns the character indexed at the supplied * offset as a 32 bit character. */ static ANTLR3_UCHAR charAt8 (pANTLR3_STRING string, ANTLR3_UINT32 offset) { if (offset > string->len) { return (ANTLR3_UCHAR)'\0'; } else { return (ANTLR3_UCHAR)(*(string->chars + offset)); } } /* Function that returns the character indexed at the supplied * offset as a 32 bit character. */ static ANTLR3_UCHAR charAtUTF16 (pANTLR3_STRING string, ANTLR3_UINT32 offset) { if (offset > string->len) { return (ANTLR3_UCHAR)'\0'; } else { return (ANTLR3_UCHAR)(*((pANTLR3_UINT16)(string->chars) + offset)); } } /* Function that returns a substring of the supplied string a la .subString(s,e) * in java runtimes. */ static pANTLR3_STRING subString8 (pANTLR3_STRING string, ANTLR3_UINT32 startIndex, ANTLR3_UINT32 endIndex) { pANTLR3_STRING newStr; if (endIndex > string->len) { endIndex = string->len + 1; } newStr = string->factory->newPtr(string->factory, string->chars + startIndex, endIndex - startIndex); return newStr; } /* Returns a substring of the supplied string a la .subString(s,e) * in java runtimes. */ static pANTLR3_STRING subStringUTF16 (pANTLR3_STRING string, ANTLR3_UINT32 startIndex, ANTLR3_UINT32 endIndex) { pANTLR3_STRING newStr; if (endIndex > string->len) { endIndex = string->len + 1; } newStr = string->factory->newPtr(string->factory, (pANTLR3_UINT8)((pANTLR3_UINT16)(string->chars) + startIndex), endIndex - startIndex); return newStr; } /* Function that can convert the characters in the string to an integer */ static ANTLR3_INT32 toInt32_8 (struct ANTLR3_STRING_struct * string) { return atoi((const char *)(string->chars)); } /* Function that can convert the characters in the string to an integer */ static ANTLR3_INT32 toInt32_UTF16 (struct ANTLR3_STRING_struct * string) { pANTLR3_UINT16 input; ANTLR3_INT32 value; ANTLR3_BOOLEAN negate; value = 0; input = (pANTLR3_UINT16)(string->chars); negate = ANTLR3_FALSE; if (*input == (ANTLR3_UCHAR)'-') { negate = ANTLR3_TRUE; input++; } else if (*input == (ANTLR3_UCHAR)'+') { input++; } while (*input != '\0' && isdigit(*input)) { value = value * 10; value += ((ANTLR3_UINT32)(*input) - (ANTLR3_UINT32)'0'); input++; } return negate ? -value : value; } /* Function that returns a pointer to an 8 bit version of the string, * which in this case is just the string as this is * 8 bit encodiing anyway. */ static pANTLR3_STRING to8_8 (pANTLR3_STRING string) { return string; } /* Function that returns an 8 bit version of the string, * which in this case is returning all the UTF16 characters * narrowed back into 8 bits, with characters that are too large * replaced with '_' */ static pANTLR3_STRING to8_UTF16 (pANTLR3_STRING string) { pANTLR3_STRING newStr; ANTLR3_UINT32 i; /* Create a new 8 bit string */ newStr = newRaw8(string->factory); if (newStr == NULL) { return NULL; } /* Always add one more byte for a terminator */ newStr->chars = (pANTLR3_UINT8) ANTLR3_MALLOC((size_t)(string->len + 1)); newStr->size = string->len + 1; newStr->len = string->len; /* Now copy each UTF16 charActer , making it an 8 bit character of * some sort. */ for (i=0; i<string->len; i++) { ANTLR3_UCHAR c; c = *(((pANTLR3_UINT16)(string->chars)) + i); *(newStr->chars + i) = (ANTLR3_UINT8)(c > 255 ? '_' : c); } /* Terminate */ *(newStr->chars + newStr->len) = '\0'; return newStr; }