MWCC/CompilerTools.c

1245 lines
30 KiB
C

#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;
char r;
p = (unsigned char *) (*list->data + list->size);
list->size++;
r = p[0];
return r;
}
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] & 0xFF;
p = &str[1];
if (str[0] & 0xFF) {
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 :( */
unsigned char len;
short result; // orig r4
unsigned char work; // orig r5
short counter; // orig r3
// counter,result,work -> r3=work, r4=counter, r5=result
// result,counter,work -> r3=work, r4=result, r5=counter
// work,result,counter -> r3=work, r4=result, r5=counter
// work,counter,result -> r3=work, r4=counter, r5=result
// counter,work,result -> r3=work, r4=counter, r5=result
// result,work,counter -> r3=work, r4=result, r5=counter
// i am: r4 = result, r5 = counter, r3 = work
len = strlen(str);
result = len;
if (len) {
counter = len;
work = 0;
while (counter > 0) {
work = (work >> 3) | (work << 5);
work = work + *str;
//work = *(str++) + (unsigned char) ((work >> 3) | (work << 5));
counter--;
str++;
}
result = result << 8;
result = result | 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;
}
}