summaryrefslogtreecommitdiff
path: root/CompilerTools.c
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2022-10-07 20:02:27 +0100
committerAsh Wolf <ninji@wuffs.org>2022-10-07 20:02:27 +0100
commit97f6a2438df1eaeb4128ce36f29346ea38a3db4a (patch)
tree78260f8f0f2b84fc70fadb1e50e7fc104390eee4 /CompilerTools.c
downloadMWCC-97f6a2438df1eaeb4128ce36f29346ea38a3db4a.tar.gz
MWCC-97f6a2438df1eaeb4128ce36f29346ea38a3db4a.zip
first very unfinished commit lol
Diffstat (limited to '')
-rw-r--r--CompilerTools.c1230
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;
+ }
+}