diff options
author | Ash Wolf <ninji@wuffs.org> | 2022-10-07 20:02:27 +0100 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2022-10-07 20:02:27 +0100 |
commit | 97f6a2438df1eaeb4128ce36f29346ea38a3db4a (patch) | |
tree | 78260f8f0f2b84fc70fadb1e50e7fc104390eee4 /CompilerTools.c | |
download | MWCC-97f6a2438df1eaeb4128ce36f29346ea38a3db4a.tar.gz MWCC-97f6a2438df1eaeb4128ce36f29346ea38a3db4a.zip |
first very unfinished commit lol
Diffstat (limited to '')
-rw-r--r-- | CompilerTools.c | 1230 |
1 files changed, 1230 insertions, 0 deletions
diff --git a/CompilerTools.c b/CompilerTools.c new file mode 100644 index 0000000..daba8df --- /dev/null +++ b/CompilerTools.c @@ -0,0 +1,1230 @@ +#include "CompilerTools.h" + +static short lheaplockcount; +static void (*heaperror)(); +static Allocator bheap; +static Allocator oheap; +static Allocator aheap; +static Allocator lheap; +static Allocator gheap; +long hash_name_id; +StringNode **name_hash_nodes; +void (*GListErrorProc)(); + +void CompilerGetPString(short index, unsigned char *str) { + COS_GetPString(str, 10100, index); +} + +void CompilerGetCString(short index, char *str) { + COS_GetString(str, 10100, index); +} + +unsigned char *CTool_CtoPstr(char *input) { + char *work = input; + int length = 0; + int i; + + while (*work) { + ++length; + ++work; + } + + for (i = length; i > 0; i--) { + work[0] = work[-1]; + --work; + } + + input[0] = length; + return (unsigned char *) input; +} + +static void GListError() { + if (GListErrorProc) + GListErrorProc(); +} + +int InitGList(GList *list, long capacity) { + if ((list->data = COS_NewOSHandle(capacity)) == 0) + if ((list->data = COS_NewHandle(capacity)) == 0) + return -1; + list->size = 0; + list->expansion = capacity >> 1; + list->capacity = capacity; + return 0; +} + +void FreeGList(GList *list) { + if (list->data != 0) { + COS_FreeHandle(list->data); + list->data = 0; + } + list->capacity = 0; + list->size = 0; +} + +void LockGList(GList *list) { + COS_LockHandleHi(list->data); +} + +void UnlockGList(GList *list) { + COS_UnlockHandle(list->data); +} + +void ShrinkGList(GList *list) { + COS_ResizeHandle(list->data, list->capacity = list->size); +} + +void AppendGListData(GList *list, const void *data, long size) { + if ((list->size + size) > list->capacity) { + if (!COS_ResizeHandle(list->data, list->capacity += size + list->expansion)) + GListError(); + } + + memcpy(*list->data + list->size, data, size); + list->size += size; +} + +void AppendGListNoData(GList *list, long size) { + if ((list->size + size) > list->capacity) { + if (!COS_ResizeHandle(list->data, list->capacity += size + list->expansion)) + GListError(); + } + + list->size += size; +} + +void AppendGListByte(GList *list, char v) { + if ((list->size + 1) > list->capacity) { + if (!COS_ResizeHandle(list->data, list->capacity += 1 + list->expansion)) + GListError(); + } + + (*list->data)[list->size++] = v; +} + +void AppendGListWord(GList *list, short v) { + char *p; + + if ((list->size + 2) > list->capacity) { + if (!COS_ResizeHandle(list->data, list->capacity += 2 + list->expansion)) + GListError(); + } + + p = *list->data + list->size; + list->size += 2; + *(p++) = ((unsigned char *) &v)[0]; + *(p++) = ((unsigned char *) &v)[1]; +} + +void AppendGListTargetEndianWord(GList *list, short v) { + char *p; + + if ((list->size + 2) > list->capacity) { + if (!COS_ResizeHandle(list->data, list->capacity += 2 + list->expansion)) + GListError(); + } + + p = *list->data + list->size; + list->size += 2; + *(p++) = ((unsigned char *) &v)[0]; + *(p++) = ((unsigned char *) &v)[1]; +} + +void AppendGListLong(GList *list, long v) { + char *p; + + if ((list->size + 4) > list->capacity) { + if (!COS_ResizeHandle(list->data, list->capacity += 4 + list->expansion)) + GListError(); + } + + p = *list->data + list->size; + list->size += 4; + *(p++) = ((unsigned char *) &v)[0]; + *(p++) = ((unsigned char *) &v)[1]; + *(p++) = ((unsigned char *) &v)[2]; + *(p++) = ((unsigned char *) &v)[3]; +} + +void AppendGListTargetEndianLong(GList *list, long v) { + char *p; + + if ((list->size + 4) > list->capacity) { + if (!COS_ResizeHandle(list->data, list->capacity += 4 + list->expansion)) + GListError(); + } + + p = *list->data + list->size; + list->size += 4; + *(p++) = ((unsigned char *) &v)[0]; + *(p++) = ((unsigned char *) &v)[1]; + *(p++) = ((unsigned char *) &v)[2]; + *(p++) = ((unsigned char *) &v)[3]; +} + +void AppendGListID(GList *list, const char *str) { + unsigned long size = strlen(str) + 1; + if ((list->size + size) > list->capacity) { + if (!COS_ResizeHandle(list->data, list->capacity += size + list->expansion)) + GListError(); + } + + memcpy(*list->data + list->size, str, size); + list->size += size; +} + +void AppendGListName(GList *list, const char *str) { + unsigned long size = strlen(str); + if ((list->size + size) > list->capacity) { + if (!COS_ResizeHandle(list->data, list->capacity += size + list->expansion)) + GListError(); + } + + memcpy(*list->data + list->size, str, size); + list->size += size; +} + +void RemoveGListData(GList *list, long size) { + list->size -= size; + if (list->capacity > (list->size + list->expansion * 2)) + COS_ResizeHandle(list->data, list->capacity = list->size + list->expansion); +} + +char GetGListByte(GList *list) { + unsigned char *p; + + p = (unsigned char *) (*list->data + list->size); + list->size++; + return p[0]; +} + +short GetGListWord(GList *list) { + unsigned char *p; + union { unsigned char bytes[2]; short s; } data; + + p = (unsigned char *) (*list->data + list->size); + list->size += 2; + data.bytes[0] = p[0]; + data.bytes[1] = p[1]; + return data.s; +} + +long GetGListLong(GList *list) { + unsigned char *p; + union { unsigned char bytes[4]; long l; } data; + + p = (unsigned char *) (*list->data + list->size); + list->size += 4; + data.bytes[0] = p[0]; + data.bytes[1] = p[1]; + data.bytes[2] = p[2]; + data.bytes[3] = p[3]; + return data.l; +} + +short GetGListID(GList *list, char *buf) { + short len; + char *p; + + len = 1; + p = *list->data + list->size; + while (*p) { + *(buf++) = *(p++); + len++; + } + + *buf = *p; + list->size += len; + return len; +} + +void GetGListData(GList *list, char *buf, long size) { + memcpy(buf, *list->data + list->size, size); + list->size += size; +} + +static long hashpjw(const char *str) { + unsigned long work = 0; + unsigned long tmp; + + while (*str) { + work = (work << 4) + *str; + tmp = work & 0xF0000000; + if (tmp) { + work ^= (tmp >> 24); + work ^= tmp; + } + str++; + } + + return work % 0xFFFFFD; +} + +static short PHash(const unsigned char *str) { + short result; + short counter; + unsigned char work; + const unsigned char *p; + + result = str[0]; + result &= 0xFF; + p = &str[1]; + if (str[0]) { + counter = result; + work = 0; + while (counter > 0) { + work = (work >> 3) | (work << 5); + work += *p; + --counter; + ++p; + } + + result = (result << 8) | work; + } + + return result & 0x7FF; +} + +short CHash(const char *str) { + /* not matching :( */ + short result; // orig r4 + unsigned char work; // orig r5 + short counter; // orig r3 + + // i am: r4 = result, r5 = counter, r3 = work + + if (result = strlen(str) & 0xFF) { + counter = result; + work = 0; + while (counter > 0) { + work = (work >> 3) | (work << 5); + work = work + *(str++); + counter--; + } + result = (result << 8) | work; + } + + return result & 0x7FF; +} + +StringNode *GetHashNameNode(const char *str) { + StringNode *node; + short hash; + + hash = CHash(str); + node = name_hash_nodes[hash]; + if (node == 0) { + node = (StringNode *) galloc(strlen(str) + sizeof(StringNode)); + name_hash_nodes[hash] = node; + node->next = 0; + node->index = hash_name_id++; + node->hash = hash; + strcpy(node->data, str); + return node; + } else { + for (;;) { + if (strcmp(str, node->data) == 0) { + if (node->index < 0) + node->index = hash_name_id++; + return node; + } + + if (node->next == 0) { + node->next = (StringNode *) galloc(strlen(str) + sizeof(StringNode)); + node = node->next; + node->next = 0; + node->index = hash_name_id++; + node->hash = hash; + strcpy(node->data, str); + return node; + } else { + node = node->next; + } + } + } +} + +StringNode *GetHashNameNodeHash(const char *str, short hash) { + StringNode *node; + + node = name_hash_nodes[hash]; + if (node == 0) { + node = (StringNode *) galloc(strlen(str) + sizeof(StringNode)); + name_hash_nodes[hash] = node; + node->next = 0; + node->index = hash_name_id++; + node->hash = hash; + strcpy(node->data, str); + return node; + } else { + for (;;) { + if (strcmp(str, node->data) == 0) + return node; + + if (node->next == 0) { + node->next = (StringNode *) galloc(strlen(str) + sizeof(StringNode)); + node = node->next; + node->next = 0; + node->index = hash_name_id++; + node->hash = hash; + strcpy(node->data, str); + return node; + } else { + node = node->next; + } + } + } +} + +StringNode *GetHashNameNodeHash2(const char *str, short hash) { + StringNode *node; + + node = name_hash_nodes[hash]; + if (node == 0) { + node = (StringNode *) galloc(strlen(str) + sizeof(StringNode)); + name_hash_nodes[hash] = node; + node->next = 0; + node->index = -1; + node->hash = hash; + strcpy(node->data, str); + return node; + } else { + for (;;) { + if (strcmp(str, node->data) == 0) + return node; + + if (node->next == 0) { + node->next = (StringNode *) galloc(strlen(str) + sizeof(StringNode)); + node = node->next; + node->next = 0; + node->index = -1; + node->hash = hash; + strcpy(node->data, str); + return node; + } else { + node = node->next; + } + } + } +} + +StringNode *GetHashNameNodeExport(const char *str) { + // not matching + StringNode *node; + short hash; + + hash = CHash(str); + if ((node = name_hash_nodes[hash]) == 0) { + node = (StringNode *) galloc(strlen(str) + sizeof(StringNode)); + name_hash_nodes[hash] = node; + node->next = 0; + node->index = -1; + node->hash = hash; + strcpy(node->data, str); + return node; + } else { + for (;;) { + if (strcmp(str, node->data) == 0) + return node; + + if (node->next == 0) { + node->next = (StringNode *) galloc(strlen(str) + sizeof(StringNode)); + node = node->next; + node->next = 0; + node->index = -1; + node->hash = hash; + strcpy(node->data, str); + return node; + } else { + node = node->next; + } + } + } +} + +long GetHashNameNodeExportID(StringNode *node) { + if (node->index < 0) + node->index = hash_name_id++; + return node->index; +} + +StringNode *GetHashNameNodeByID(long id) { + StringNode *node; + short i; + + for (i = 0; i < 2048; i++) { + for (node = name_hash_nodes[i]; node; node = node->next) { + if (id == node->index) + return node; + } + } + + return 0; +} + +void NameHashExportReset() { + short i; + StringNode *node; + + for (i = 0; i < 0x800; i++) { + node = name_hash_nodes[i]; + while (node) { + node->index = -1; + node = node->next; + } + } + + hash_name_id = 1; +} + +void NameHashWriteNameTable(GList *list) { + StringNode *node; + StringNode **nodes; + short grp; + int i; + + nodes = (StringNode **) galloc(sizeof(StringNode *) * hash_name_id); + + for (grp = 0; grp < 0x800; grp++) { + node = name_hash_nodes[grp]; + while (node) { + if (node->index > 0) + nodes[node->index] = node; + node = node->next; + } + } + + for (i = 1; i < hash_name_id; i++) { + node = nodes[i]; + AppendGListWord(list, node->hash); + AppendGListID(list, node->data); + } + + if (list->size & 1) + AppendGListByte(list, 0); +} + +void NameHashWriteTargetEndianNameTable(GList *list) { + StringNode *node; + StringNode **nodes; + short grp; + int i; + + nodes = (StringNode **) galloc(sizeof(StringNode *) * hash_name_id); + memclrw(nodes, sizeof(StringNode *) * hash_name_id); + + for (grp = 0; grp < 0x800; grp++) { + node = name_hash_nodes[grp]; + while (node) { + if (node->index > 0) + nodes[node->index] = node; + node = node->next; + } + } + + for (i = 1; i < hash_name_id; i++) { + node = nodes[i]; + if (node == 0) { + AppendGListTargetEndianWord(list, 0); + AppendGListID(list, ""); + } else { + AppendGListTargetEndianWord(list, node->hash); + AppendGListID(list, node->data); + } + } + + if (list->size & 1) + AppendGListByte(list, 0); +} + +void InitNameHash() { + name_hash_nodes = (StringNode **) galloc(0x800 * sizeof(StringNode *)); + memclrw(name_hash_nodes, 0x800 * sizeof(StringNode *)); + hash_name_id = 1; +} + +long CTool_TotalHeapSize() { + long total = 0; + AllocatorBlock *block; + + for (block = gheap.blockList; block; block = block->nextBlock) { + total += block->size; + } + for (block = lheap.blockList; block; block = block->nextBlock) { + total += block->size; + } + for (block = aheap.blockList; block; block = block->nextBlock) { + total += block->size; + } + for (block = oheap.blockList; block; block = block->nextBlock) { + total += block->size; + } + for (block = bheap.blockList; block; block = block->nextBlock) { + total += block->size; + } + + return total; +} + +static void getheapinfo(HeapInfo *result, Allocator *heap) { + AllocatorBlock *block; + + result->_4 = heap->paddingSize; + for (block = heap->blockList; block; block = block->nextBlock) { + result->_8 += block->size - sizeof(AllocatorBlock); + result->xx_C += block->remaining; + result->_0++; + if (block->remaining > result->_18) + result->_18 = block->remaining; + } + + result->_10 = result->_8 / result->_0; + result->_14 = result->xx_C / result->_0; +} + +void CTool_GetHeapInfo(HeapInfo *result, unsigned char heapID) { + memclrw(result, sizeof(HeapInfo)); + + switch (heapID) { + case 0: + getheapinfo(result, &gheap); + break; + case 1: + getheapinfo(result, &lheap); + break; + case 2: + getheapinfo(result, &aheap); + break; + case 3: + getheapinfo(result, &oheap); + break; + case 4: + getheapinfo(result, &bheap); + break; + case 5: + getheapinfo(result, &gheap); + getheapinfo(result, &lheap); + getheapinfo(result, &aheap); + getheapinfo(result, &oheap); + getheapinfo(result, &bheap); + break; + } +} + +static void MoreHeapSpace(Allocator *alloc, long size) { + Handle blockHandle; + long blockSize; + AllocatorBlock *block; + + block = alloc->blockList; + if (block) { + alloc->lastBlockUsed->remaining = alloc->remaining; + while (block) { + if (block->remaining >= size) + goto gotBlock; + block = block->nextBlock; + } + } + + /* create new block */ + blockSize = size + alloc->paddingSize; + if (systemHandles) { + blockHandle = COS_NewOSHandle(blockSize << 1); + if (blockHandle != 0) + goto createdTempDoubleBlock; + blockHandle = COS_NewOSHandle(blockSize); + if (blockHandle != 0) + goto createdBlock; + } + blockHandle = COS_NewHandle(blockSize); + if (blockHandle != 0) + goto createdBlock; + + if (heaperror) + heaperror(); + return; + + createdTempDoubleBlock: + blockSize <<= 1; + goto createdBlock; + createdBlock: + COS_LockHandleHi(blockHandle); + block = (AllocatorBlock *) *blockHandle; + block->nextBlock = alloc->blockList; + alloc->blockList = block; + block->handle = blockHandle; + block->size = blockSize; + block->remaining = blockSize - sizeof(AllocatorBlock); + gotBlock: + alloc->lastBlockUsed = block; + alloc->remaining = block->remaining; + alloc->ptrToFreeArea = ((char *) block) + block->size - block->remaining; +} + +int initheaps(heaperror_t failureCallback) { + heaperror = 0; + lheaplockcount = 0; + + memclrw(&gheap, sizeof(Allocator)); + memclrw(&lheap, sizeof(Allocator)); + memclrw(&aheap, sizeof(Allocator)); + memclrw(&oheap, sizeof(Allocator)); + memclrw(&bheap, sizeof(Allocator)); + + gheap.paddingSize = 0x38000; + lheap.paddingSize = 0x10000; + aheap.paddingSize = 0x4000; + oheap.paddingSize = 0x40000; + bheap.paddingSize = 0x4000; + + MoreHeapSpace(&gheap, 0); + MoreHeapSpace(&lheap, 0); + MoreHeapSpace(&aheap, 0); + MoreHeapSpace(&oheap, 0); + MoreHeapSpace(&bheap, 0); + + gheap.paddingSize = 0x8000; + lheap.paddingSize = 0x8000; + + heaperror = failureCallback; + + if (!gheap.lastBlockUsed || !lheap.lastBlockUsed || !aheap.lastBlockUsed || !oheap.lastBlockUsed || !bheap.lastBlockUsed) + return -1; + else + return 0; +} + +int initgheap(heaperror_t failureCallback) { + heaperror = 0; + lheaplockcount = 0; + + memclrw(&gheap, sizeof(Allocator)); + memclrw(&lheap, sizeof(Allocator)); + memclrw(&aheap, sizeof(Allocator)); + memclrw(&oheap, sizeof(Allocator)); + memclrw(&bheap, sizeof(Allocator)); + + gheap.paddingSize = 0x38000; + MoreHeapSpace(&gheap, 0); + gheap.paddingSize = 0x8000; + + heaperror = failureCallback; + + if (!gheap.lastBlockUsed) + return -1; + else + return 0; +} + +heaperror_t getheaperror() { + return heaperror; +} + +void setheaperror(heaperror_t failureCallback) { + heaperror = failureCallback; +} + +static void relheap(Allocator *alloc) { + AllocatorBlock *block; + Handle handle; + + block = alloc->blockList; + while (block) { + handle = block->handle; + block = block->nextBlock; + COS_FreeHandle(handle); + } + + memclrw(alloc, sizeof(Allocator)); +} + +void releaseheaps() { + relheap(&gheap); + relheap(&lheap); + relheap(&aheap); + relheap(&oheap); + relheap(&bheap); +} + +void releasegheap() { + relheap(&gheap); +} + +void releaseoheap() { + relheap(&gheap); + oheap.paddingSize = 0x40000; + MoreHeapSpace(&oheap, 0); +} + +char *galloc(long size) { + long alignedSize; + char *ptr; + + alignedSize = (size & ~7) + 8; + if (gheap.remaining < alignedSize) + MoreHeapSpace(&gheap, alignedSize); + + gheap.remaining -= alignedSize; + ptr = (char *) gheap.ptrToFreeArea; + gheap.ptrToFreeArea = ptr + alignedSize; + return ptr; +} + +char *lalloc(long size) { + long alignedSize; + char *ptr; + + alignedSize = (size & ~7) + 8; + if (lheap.remaining < alignedSize) + MoreHeapSpace(&lheap, alignedSize); + + lheap.remaining -= alignedSize; + ptr = (char *) lheap.ptrToFreeArea; + lheap.ptrToFreeArea = ptr + alignedSize; + return ptr; +} + +char *aalloc(long size) { + long alignedSize; + char *ptr; + + alignedSize = (size & ~7) + 8; + if (aheap.remaining < alignedSize) + MoreHeapSpace(&aheap, alignedSize); + + aheap.remaining -= alignedSize; + ptr = (char *) aheap.ptrToFreeArea; + aheap.ptrToFreeArea = ptr + alignedSize; + return ptr; +} + +char *oalloc(long size) { + long alignedSize; + char *ptr; + + alignedSize = (size & ~7) + 8; + if (oheap.remaining < alignedSize) + MoreHeapSpace(&oheap, alignedSize); + + oheap.remaining -= alignedSize; + ptr = (char *) oheap.ptrToFreeArea; + oheap.ptrToFreeArea = ptr + alignedSize; + return ptr; +} + +char *balloc(long size) { + long alignedSize; + char *ptr; + + alignedSize = (size & ~7) + 8; + if (bheap.remaining < alignedSize) + MoreHeapSpace(&bheap, alignedSize); + + bheap.remaining -= alignedSize; + ptr = (char *) bheap.ptrToFreeArea; + bheap.ptrToFreeArea = ptr + alignedSize; + return ptr; +} + +void locklheap() { + lheaplockcount++; +} + +void unlocklheap() { + if (lheaplockcount > 0) + --lheaplockcount; +} + +void freelheap() { + AllocatorBlock *block; + + if (lheaplockcount == 0) { + block = lheap.blockList; + lheap.lastBlockUsed = block; + lheap.ptrToFreeArea = ((char *) block) + sizeof(AllocatorBlock); + lheap.remaining = block->size - sizeof(AllocatorBlock); + + while (block) { + block->remaining = block->size - sizeof(AllocatorBlock); + block = block->nextBlock; + } + } +} + +void freeaheap() { + AllocatorBlock *block; + + block = aheap.blockList; + aheap.lastBlockUsed = block; + aheap.ptrToFreeArea = ((char *) block) + sizeof(AllocatorBlock); + aheap.remaining = block->size - sizeof(AllocatorBlock); + + while (block) { + block->remaining = block->size - sizeof(AllocatorBlock); + block = block->nextBlock; + } +} + +void freeoheap() { + AllocatorBlock *block; + + block = oheap.blockList; + oheap.lastBlockUsed = block; + oheap.ptrToFreeArea = ((char *) block) + sizeof(AllocatorBlock); + oheap.remaining = block->size - sizeof(AllocatorBlock); + + while (block) { + block->remaining = block->size - sizeof(AllocatorBlock); + block = block->nextBlock; + } +} + +void freebheap() { + AllocatorBlock *block; + + block = bheap.blockList; + bheap.lastBlockUsed = block; + bheap.ptrToFreeArea = ((char *) block) + sizeof(AllocatorBlock); + bheap.remaining = block->size - sizeof(AllocatorBlock); + + while (block) { + block->remaining = block->size - sizeof(AllocatorBlock); + block = block->nextBlock; + } +} + +char *ScanHex(char *str, long *output, Boolean *overflow) { + long work; + int ch; + + work = 0; + *overflow = 0; + + for (;;) { + ch = *str; + if (ch >= '0' && ch <= '9') { + ch = ch - '0'; + } else if (ch >= 'A' && ch <= 'F') { + ch = ch - 'A' + 10; + } else if (ch >= 'a' && ch <= 'f') { + ch = ch - 'a' + 10; + } else { + break; + } + + if (work & 0xF0000000) + *overflow = 1; + work = (work << 4) | (short) ch; + ++str; + } + + *output = work; + return str; +} + +char *ScanOct(char *str, long *output, Boolean *overflow) { + short digit; + long work; + + work = 0; + *overflow = 0; + + for (;;) { + digit = *str - '0'; + if (digit >= 0 && digit <= 9) { + if (digit >= 8) { + *overflow = 1; + ++str; + break; + } + } else { + break; + } + + if (work & 0xE0000000) + *overflow = 1; + work = (work << 3) | digit; + ++str; + } + + *output = work; + return str; +} + +char *ScanDec(char *str, long *output, Boolean *overflow) { + short digit; + unsigned long work; + + work = 0; + *overflow = 0; + + for (;;) { + digit = *str - '0'; + if (digit >= 0 && digit <= 9) { + if (work >= 0x19999999 && (work > 0x19999999 || digit > 5)) + *overflow = 1; + } else { + break; + } + + work = (work << 3) + (work << 1) + digit; + ++str; + } + + *output = work; + return str; +} + +static char *UnmangleClassname(char *work, char **pNameStart, short *pNameLength, char **a4, short *a5, Boolean a6) { + char ch; + short len; + char *p2; + short len2; + short i; + short wtf; + + *pNameLength = 0; + if (*(work++) != '_') + return work; + if (*(work++) != '_') { + return work; + } else { + len = 0; + while (work[0] >= '0' && work[0] <= '9') { + len = (len * 10) + work[0] - '0'; + ++work; + } + + if (len > 0) { + *pNameStart = work; + *pNameLength = len; + + if (a6) { + p2 = *a4; + len2 = *a5; + i = 0; + wtf = len; + while (i < wtf && len2 < 255) { + *(p2++) = work[i]; + ++i; + ++len2; + } + if (len2 < 255) { + *(p2++) = ':'; + len2++; + } + if (len2 < 255) { + *(p2++) = ':'; + len2++; + } + *a4 = p2; + *a5 = len2; + } + } + + return work + len; + } +} + +static char *UnmangleAppend(char *src, char srcLen, char **pOutput, short *pOutputLen) { + char *output; + short i; + short outputLen; + + output = *pOutput; + outputLen = *pOutputLen; + + for (i = 0; i < srcLen && outputLen < 255; i++, outputLen++) { + *(output++) = src[i]; + } + + *pOutput = output; + *pOutputLen = outputLen; +} + +void OldUnmangle(char *input, char *output, Boolean flag) { + short var26; + char *nameStart; + short nameLength; + char *saved; + int i; + + if (*input == '.') + ++input; + + var26 = 0; + saved = input; + if (input[0] == '_' && input[1] == '_') { + if (input[2] == 'c' && input[3] == 't') { + saved = UnmangleClassname(&input[4], &nameStart, &nameLength, &output, &var26, flag); + if (nameLength == 0) + goto invalid; + UnmangleAppend(nameStart, nameLength, &output, &var26); + } else if (input[2] == 'd' && input[3] == 't') { + saved = UnmangleClassname(&input[4], &nameStart, &nameLength, &output, &var26, flag); + if (nameLength == 0) + goto invalid; + if (var26 <= 255) { + *(output++) = '~'; + var26++; + } + UnmangleAppend(nameStart, nameLength, &output, &var26); + } else if (input[2] == 'n' && input[3] == 'w') { + saved = UnmangleClassname(&input[4], &nameStart, &nameLength, &output, &var26, flag); + UnmangleAppend("operator new", 15, &output, &var26); + } else if (input[2] == 'd' && input[3] == 'l') { + saved = UnmangleClassname(&input[4], &nameStart, &nameLength, &output, &var26, flag); + UnmangleAppend("operator delete", 15, &output, &var26); + } else { + invalid: + strncpy(output, input, 256); + return; + } + } else { + i = 0; + while (*saved) { + ++saved; + ++i; + if (saved[0] == '_' && saved[1] == '_') { + saved = UnmangleClassname(saved, &nameStart, &nameLength, &output, &var26, flag); + break; + } + } + UnmangleAppend(input, i, &output, &var26); + } + + if (flag && saved[0] == 'F') { + if (saved[1] == 'v') { + UnmangleAppend("(void)", 6, &output, &var26); + } else { + UnmangleAppend("(...)", 5, &output, &var26); + } + } + + *output = 0; +} + +short hash(char *str) { + char hash = 0; + + while (*str) { + hash = hash << 1; + hash ^= *(str++); + } + + return hash & 0x7F; +} + +void memclr(void *buffer, long size) { + memset(buffer, 0, size); +} + +void memclrw(void *buffer, long size) { + memset(buffer, 0, size); +} + +void CToLowercase(char *src, char *dst) { + char ch; + + do { + ch = tolower(*(src++)); + *(dst++) = ch; + } while (ch); +} + +int getbit(long v) { + switch (v) { + case 0: return -1; + case 1: return 0; + case 2: return 1; + case 4: return 2; + case 8: return 3; + case 0x10: return 4; + case 0x20: return 5; + case 0x40: return 6; + case 0x80: return 7; + case 0x100: return 8; + case 0x200: return 9; + case 0x400: return 10; + case 0x800: return 11; + case 0x1000: return 12; + case 0x2000: return 13; + case 0x4000: return 14; + case 0x8000: return 15; + case 0x10000: return 16; + case 0x20000: return 17; + case 0x40000: return 18; + case 0x80000: return 19; + case 0x100000: return 20; + case 0x200000: return 21; + case 0x400000: return 22; + case 0x800000: return 23; + case 0x1000000: return 24; + case 0x2000000: return 25; + case 0x4000000: return 26; + case 0x8000000: return 27; + case 0x10000000: return 28; + case 0x20000000: return 29; + case 0x40000000: return 30; + case 0x80000000: return 31; + default: return -2; + } +} + +void CTool_EndianConvertWord64(WtfWord64 value, unsigned long long *p) { + union { unsigned char bytes[8]; WtfWord64 w; } data; + data.w.a = value.a; + data.w.b = value.b; + memcpy(p, data.bytes, 8); +} + +unsigned short CTool_EndianConvertInPlaceWord16Ptr(unsigned short *p) { + unsigned short v; + v = *p; + // this probably has a conversion on non-ppc + *p = v; + return v; +} + +unsigned long CTool_EndianConvertInPlaceWord32Ptr(unsigned long *p) { + unsigned long v; + v = *p; + // this probably has a conversion on non-ppc + *p = v; + return v; +} + +void CTool_EndianConvertVector128() { + // not correct but idc +} + +StringNode *CTool_GetPathName(const FSSpec *spec, long *mdDat) { + char buffer[256]; + COS_FileGetPathName(buffer, spec, mdDat); + return GetHashNameNodeExport(buffer); +} + +Boolean strcat_safe(char *dst, const char *src, int maxLen) { + int len; + char ch; + + len = strlen(dst); + dst += len; + maxLen -= len; + if (maxLen < 0) + return 1; + + while (maxLen != 0) { + ch = *(dst++) = *(src++); + if (ch == 0) + break; + --maxLen; + } + + if (maxLen == 0 && dst[-1]) { + dst[-1] = 0; + return 1; + } else { + return 0; + } +} |