#include "compiler/CompilerTools.h" #include "compiler/CInt64.h" #include "cos.h" extern Boolean systemHandles; UInt32 bit_masks[32] = { 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF }; static short lheaplockcount; static void (*heaperror)(); static HeapMem bheap; static HeapMem oheap; static HeapMem aheap; static HeapMem lheap; static HeapMem gheap; long hash_name_id; HashNameNode **name_hash_nodes; void (*GListErrorProc)(); void CompilerGetPString(short index, unsigned char *string) { COS_GetPString(string, 10100, index); } void CompilerGetCString(short index, char *string) { COS_GetString(string, 10100, index); } unsigned char *CTool_CtoPstr(char *cstr) { char *cp = cstr; int length = 0; int i; while (*cp) { ++length; ++cp; } for (i = length; i > 0; i--) { cp[0] = cp[-1]; --cp; } cstr[0] = length; return (unsigned char *) cstr; } #ifdef CW_64_BIT_SUPPORT enum { PoolCapacity = 64 }; typedef struct ITPPool { void *pointers[PoolCapacity]; UInt32 baseIndex; UInt32 size; struct ITPPool *next; } ITPPool; static ITPPool *poolHead; static ITPPool *poolTail; void *CTool_ResolveIndexToPointer(UInt32 index) { ITPPool *pool = poolHead; if (index == 0) return NULL; while (pool && index >= PoolCapacity) { pool = pool->next; index -= PoolCapacity; } if (pool && index < pool->size) return pool->pointers[index]; else return NULL; } UInt32 CTool_CreateIndexFromPointer(void *ptr) { ITPPool *pool = poolTail; UInt32 index; if (ptr == NULL) return 0; if (!pool || pool->size >= PoolCapacity) { pool = lalloc(sizeof(ITPPool)); pool->size = 0; if (poolTail) { pool->baseIndex = poolTail->baseIndex + PoolCapacity; poolTail->next = pool; } else { pool->baseIndex = 0; // always reserve index 0 for NULL pool->pointers[0] = NULL; pool->size = 1; poolHead = pool; } poolTail = pool; } index = pool->baseIndex + pool->size; pool->pointers[pool->size] = ptr; pool->size++; return index; } static void CTool_ResetPointerPool(void) { poolHead = NULL; poolTail = NULL; } #endif static void GListError(void) { if (GListErrorProc) GListErrorProc(); } short InitGList(GList *gl, SInt32 size) { if ((gl->data = COS_NewOSHandle(size)) == 0) if ((gl->data = COS_NewHandle(size)) == 0) return -1; gl->size = 0; gl->growsize = size >> 1; gl->hndlsize = size; return 0; } void FreeGList(GList *gl) { if (gl->data != 0) { COS_FreeHandle(gl->data); gl->data = 0; } gl->hndlsize = 0; gl->size = 0; } void LockGList(GList *gl) { COS_LockHandleHi(gl->data); } void UnlockGList(GList *gl) { COS_UnlockHandle(gl->data); } void ShrinkGList(GList *gl) { COS_ResizeHandle(gl->data, gl->hndlsize = gl->size); } void AppendGListData(GList *gl, const void *data, SInt32 size) { if ((gl->size + size) > gl->hndlsize) { if (!COS_ResizeHandle(gl->data, gl->hndlsize += size + gl->growsize)) GListError(); } memcpy(*gl->data + gl->size, data, size); gl->size += size; } void AppendGListNoData(GList *gl, SInt32 size) { if ((gl->size + size) > gl->hndlsize) { if (!COS_ResizeHandle(gl->data, gl->hndlsize += size + gl->growsize)) GListError(); } gl->size += size; } void AppendGListByte(GList *gl, SInt8 thebyte) { if ((gl->size + 1) > gl->hndlsize) { if (!COS_ResizeHandle(gl->data, gl->hndlsize += 1 + gl->growsize)) GListError(); } (*gl->data)[gl->size++] = thebyte; } void AppendGListWord(GList *gl, SInt16 theword) { char *ptr; if ((gl->size + 2) > gl->hndlsize) { if (!COS_ResizeHandle(gl->data, gl->hndlsize += 2 + gl->growsize)) GListError(); } ptr = *gl->data + gl->size; gl->size += 2; *(ptr++) = ((unsigned char *) &theword)[0]; *(ptr++) = ((unsigned char *) &theword)[1]; } void AppendGListTargetEndianWord(GList *gl, SInt16 theword) { char *ptr; if ((gl->size + 2) > gl->hndlsize) { if (!COS_ResizeHandle(gl->data, gl->hndlsize += 2 + gl->growsize)) GListError(); } ptr = *gl->data + gl->size; gl->size += 2; theword = CTool_EndianConvertWord16(theword); *(ptr++) = ((unsigned char *) &theword)[0]; *(ptr++) = ((unsigned char *) &theword)[1]; } void AppendGListLong(GList *gl, SInt32 theword) { char *ptr; if ((gl->size + 4) > gl->hndlsize) { if (!COS_ResizeHandle(gl->data, gl->hndlsize += 4 + gl->growsize)) GListError(); } ptr = *gl->data + gl->size; gl->size += 4; *(ptr++) = ((unsigned char *) &theword)[0]; *(ptr++) = ((unsigned char *) &theword)[1]; *(ptr++) = ((unsigned char *) &theword)[2]; *(ptr++) = ((unsigned char *) &theword)[3]; } void AppendGListTargetEndianLong(GList *gl, SInt32 theword) { char *ptr; if ((gl->size + 4) > gl->hndlsize) { if (!COS_ResizeHandle(gl->data, gl->hndlsize += 4 + gl->growsize)) GListError(); } ptr = *gl->data + gl->size; gl->size += 4; theword = CTool_EndianConvertWord32(theword); *(ptr++) = ((unsigned char *) &theword)[0]; *(ptr++) = ((unsigned char *) &theword)[1]; *(ptr++) = ((unsigned char *) &theword)[2]; *(ptr++) = ((unsigned char *) &theword)[3]; } void AppendGListID(GList *gl, const char *name) { UInt32 n = strlen(name) + 1; if ((gl->size + n) > gl->hndlsize) { if (!COS_ResizeHandle(gl->data, gl->hndlsize += n + gl->growsize)) GListError(); } memcpy(*gl->data + gl->size, name, n); gl->size += n; } void AppendGListName(GList *gl, const char *name) { UInt32 n = strlen(name); if ((gl->size + n) > gl->hndlsize) { if (!COS_ResizeHandle(gl->data, gl->hndlsize += n + gl->growsize)) GListError(); } memcpy(*gl->data + gl->size, name, n); gl->size += n; } void RemoveGListData(GList *gl, SInt32 size) { gl->size -= size; if (gl->hndlsize > (gl->size + gl->growsize * 2)) COS_ResizeHandle(gl->data, gl->hndlsize = gl->size + gl->growsize); } SInt16 GetGListByte(GList *gl) { return (*gl->data)[gl->size++]; } SInt16 GetGListWord(GList *gl) { char *ptr; union { unsigned char bytes[2]; short s; } data; // according to stabs, this one just uses a local short called 'n', not a union ptr = *gl->data + gl->size; gl->size += 2; data.bytes[0] = ptr[0]; data.bytes[1] = ptr[1]; return data.s; } SInt32 GetGListLong(GList *gl) { char *ptr; union { unsigned char bytes[4]; long l; } data; // according to stabs, this one just uses a local long called 'n', not a union ptr = *gl->data + gl->size; gl->size += 4; data.bytes[0] = ptr[0]; data.bytes[1] = ptr[1]; data.bytes[2] = ptr[2]; data.bytes[3] = ptr[3]; return data.l; } short GetGListID(GList *gl, char *name) { short n; char *a; char *b; n = 1; a = *gl->data + gl->size; b = name; while (*a) { *(b++) = *(a++); n++; } *b = *a; gl->size += n; return n; } void GetGListData(GList *gl, char *where, SInt32 size) { memcpy(where, *gl->data + gl->size, size); gl->size += size; } static UInt32 hashpjw(const char *p) { UInt32 h = 0; UInt32 g; while (*p) { h = (h << 4) + *p; g = h & 0xF0000000; if (g) { h ^= (g >> 24); h ^= g; } p++; } return h % 0xFFFFFD; } static SInt16 PHash(const unsigned char *string) { SInt16 i; SInt16 hashval; UInt8 u; if ((hashval = *(string++))) { i = hashval; u = 0; while (i > 0) { u = (u >> 3) | (u << 5); u += *(string++); --i; } hashval = (hashval << 8) | u; } return hashval & 0x7FF; } SInt16 CHash(const char *string) { SInt16 i; SInt16 hashval; UInt8 u; if ((hashval = (UInt8) strlen(string))) { i = hashval; u = 0; while (i > 0) { u = (u >> 3) | (u << 5); u += *(string++); --i; } hashval = (hashval << 8) | u; } return hashval & 0x7FF; } HashNameNode *GetHashNameNode(const char *name) { HashNameNode *node; SInt16 n; if ((node = name_hash_nodes[n = CHash(name)]) == NULL) { node = galloc(strlen(name) + sizeof(HashNameNode)); name_hash_nodes[n] = node; node->next = NULL; node->id = hash_name_id++; node->hashval = n; strcpy(node->name, name); return node; } else { for (;;) { if (strcmp(name, node->name) == 0) { if (node->id < 0) node->id = hash_name_id++; return node; } if (node->next == NULL) { node->next = galloc(strlen(name) + sizeof(HashNameNode)); node = node->next; node->next = NULL; node->id = hash_name_id++; node->hashval = n; strcpy(node->name, name); return node; } else { node = node->next; } } } } HashNameNode *GetHashNameNodeHash(const char *name, SInt16 hashval) { HashNameNode *node; if ((node = name_hash_nodes[hashval]) == NULL) { node = galloc(strlen(name) + sizeof(HashNameNode)); name_hash_nodes[hashval] = node; node->next = NULL; node->id = hash_name_id++; node->hashval = hashval; strcpy(node->name, name); return node; } else { for (;;) { if (strcmp(name, node->name) == 0) return node; if (node->next == NULL) { node->next = galloc(strlen(name) + sizeof(HashNameNode)); node = node->next; node->next = NULL; node->id = hash_name_id++; node->hashval = hashval; strcpy(node->name, name); return node; } else { node = node->next; } } } } HashNameNode *GetHashNameNodeHash2(const char *name, SInt16 hashval) { HashNameNode *node; if ((node = name_hash_nodes[hashval]) == NULL) { node = galloc(strlen(name) + sizeof(HashNameNode)); name_hash_nodes[hashval] = node; node->next = NULL; node->id = -1; node->hashval = hashval; strcpy(node->name, name); return node; } else { for (;;) { if (strcmp(name, node->name) == 0) return node; if (node->next == NULL) { node->next = galloc(strlen(name) + sizeof(HashNameNode)); node = node->next; node->next = NULL; node->id = -1; node->hashval = hashval; strcpy(node->name, name); return node; } else { node = node->next; } } } } HashNameNode *GetHashNameNodeExport(const char *name) { HashNameNode *node; SInt16 n; if ((node = name_hash_nodes[n = CHash(name)]) == NULL) { node = galloc(strlen(name) + sizeof(HashNameNode)); name_hash_nodes[n] = node; node->next = NULL; node->id = -1; node->hashval = n; strcpy(node->name, name); return node; } else { for (;;) { if (strcmp(name, node->name) == 0) return node; if (node->next == NULL) { node->next = galloc(strlen(name) + sizeof(HashNameNode)); node = node->next; node->next = NULL; node->id = -1; node->hashval = n; strcpy(node->name, name); return node; } else { node = node->next; } } } } SInt32 GetHashNameNodeExportID(HashNameNode *node) { if (node->id < 0) node->id = hash_name_id++; return node->id; } HashNameNode *GetHashNameNodeByID(SInt32 id) { HashNameNode *node; short i; for (i = 0; i < 2048; i++) { for (node = name_hash_nodes[i]; node; node = node->next) { if (id == node->id) return node; } } return NULL; } void NameHashExportReset(void) { HashNameNode *node; short i; for (i = 0; i < 2048; i++) { node = name_hash_nodes[i]; while (node) { node->id = -1; node = node->next; } } hash_name_id = 1; } void NameHashWriteNameTable(GList *glist) { HashNameNode *node; HashNameNode **nodes; short i; SInt32 n; nodes = galloc(sizeof(HashNameNode *) * hash_name_id); for (i = 0; i < 2048; i++) { node = name_hash_nodes[i]; while (node) { if (node->id > 0) nodes[node->id] = node; node = node->next; } } for (n = 1; n < hash_name_id; n++) { node = nodes[n]; AppendGListWord(glist, node->hashval); AppendGListID(glist, node->name); } if (glist->size & 1) AppendGListByte(glist, 0); } void NameHashWriteTargetEndianNameTable(GList *glist) { HashNameNode *node; HashNameNode **nodes; short i; SInt32 n; nodes = galloc(sizeof(HashNameNode *) * hash_name_id); memclrw(nodes, sizeof(HashNameNode *) * hash_name_id); for (i = 0; i < 2048; i++) { node = name_hash_nodes[i]; while (node) { if (node->id > 0) nodes[node->id] = node; node = node->next; } } for (n = 1; n < hash_name_id; n++) { node = nodes[n]; if (node == NULL) { AppendGListTargetEndianWord(glist, 0); AppendGListID(glist, ""); } else { AppendGListTargetEndianWord(glist, node->hashval); AppendGListID(glist, node->name); } } if (glist->size & 1) AppendGListByte(glist, 0); } void InitNameHash(void) { name_hash_nodes = galloc(2048 * sizeof(HashNameNode *)); memclrw(name_hash_nodes, 2048 * sizeof(HashNameNode *)); hash_name_id = 1; } SInt32 CTool_TotalHeapSize(void) { HeapBlock *blockp; SInt32 size = 0; for (blockp = gheap.blocks; blockp; blockp = blockp->next) { size += blockp->blocksize; } for (blockp = lheap.blocks; blockp; blockp = blockp->next) { size += blockp->blocksize; } for (blockp = aheap.blocks; blockp; blockp = blockp->next) { size += blockp->blocksize; } for (blockp = oheap.blocks; blockp; blockp = blockp->next) { size += blockp->blocksize; } for (blockp = bheap.blocks; blockp; blockp = blockp->next) { size += blockp->blocksize; } return size; } static void getheapinfo(HeapInfo *result, HeapMem *heap) { HeapBlock *block; result->allocsize = heap->allocsize; for (block = heap->blocks; block; block = block->next) { result->total_size += block->blocksize - sizeof(HeapBlock); result->total_free += block->blockfree; result->blocks++; if (block->blockfree > result->largest_free_block) result->largest_free_block = block->blockfree; } result->average_block_size = result->total_size / result->blocks; result->average_block_free = result->total_free / result->blocks; } 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(HeapMem *heapp, SInt32 size) { HeapBlock *blockp; Handle hndl; blockp = heapp->blocks; if (blockp) { heapp->curblock->blockfree = heapp->curfree; while (blockp) { if (blockp->blockfree >= size) goto gotBlock; blockp = blockp->next; } } /* create new block */ size += heapp->allocsize; if (systemHandles) { hndl = COS_NewOSHandle(size << 1); if (hndl != 0) goto createdTempDoubleBlock; hndl = COS_NewOSHandle(size); if (hndl != 0) goto createdBlock; } hndl = COS_NewHandle(size); if (hndl != 0) goto createdBlock; if (heaperror) heaperror(); return; createdTempDoubleBlock: size <<= 1; goto createdBlock; createdBlock: COS_LockHandleHi(hndl); blockp = (HeapBlock *) *hndl; blockp->next = heapp->blocks; heapp->blocks = blockp; blockp->blockhandle = hndl; blockp->blocksize = size; blockp->blockfree = size - sizeof(HeapBlock); gotBlock: heapp->curblock = blockp; heapp->curfree = blockp->blockfree; heapp->curfreep = ((char *) blockp) + blockp->blocksize - blockp->blockfree; } short initheaps(heaperror_t heaperrorproc) { heaperror = NULL; lheaplockcount = 0; memclrw(&gheap, sizeof(HeapMem)); memclrw(&lheap, sizeof(HeapMem)); memclrw(&aheap, sizeof(HeapMem)); memclrw(&oheap, sizeof(HeapMem)); memclrw(&bheap, sizeof(HeapMem)); gheap.allocsize = 0x38000; lheap.allocsize = 0x10000; aheap.allocsize = 0x4000; oheap.allocsize = 0x40000; bheap.allocsize = 0x4000; MoreHeapSpace(&gheap, 0); MoreHeapSpace(&lheap, 0); MoreHeapSpace(&aheap, 0); MoreHeapSpace(&oheap, 0); MoreHeapSpace(&bheap, 0); gheap.allocsize = 0x8000; lheap.allocsize = 0x8000; heaperror = heaperrorproc; if (!gheap.curblock || !lheap.curblock || !aheap.curblock || !oheap.curblock || !bheap.curblock) return -1; else return 0; } short initgheap(heaperror_t heaperrorproc) { heaperror = NULL; lheaplockcount = 0; memclrw(&gheap, sizeof(HeapMem)); memclrw(&lheap, sizeof(HeapMem)); memclrw(&aheap, sizeof(HeapMem)); memclrw(&oheap, sizeof(HeapMem)); memclrw(&bheap, sizeof(HeapMem)); gheap.allocsize = 0x38000; MoreHeapSpace(&gheap, 0); gheap.allocsize = 0x8000; heaperror = heaperrorproc; if (!gheap.curblock) return -1; else return 0; } heaperror_t getheaperror(void) { return heaperror; } void setheaperror(heaperror_t heaperrorproc) { heaperror = heaperrorproc; } static void relheap(HeapMem *heapp) { HeapBlock *blockp; Handle hndl; blockp = heapp->blocks; while (blockp) { hndl = blockp->blockhandle; blockp = blockp->next; COS_FreeHandle(hndl); } memclrw(heapp, sizeof(HeapMem)); } void releaseheaps(void) { relheap(&gheap); relheap(&lheap); relheap(&aheap); relheap(&oheap); relheap(&bheap); } void releasegheap(void) { relheap(&gheap); } void releaseoheap(void) { relheap(&gheap); oheap.allocsize = 0x40000; MoreHeapSpace(&oheap, 0); } void *galloc(SInt32 s) { char *cp; s = (s & ~7) + 8; if (gheap.curfree < s) MoreHeapSpace(&gheap, s); gheap.curfree -= s; cp = gheap.curfreep; gheap.curfreep = cp + s; return cp; } void *lalloc(SInt32 s) { char *cp; s = (s & ~7) + 8; if (lheap.curfree < s) MoreHeapSpace(&lheap, s); lheap.curfree -= s; cp = lheap.curfreep; lheap.curfreep = cp + s; return cp; } void *aalloc(SInt32 s) { char *cp; s = (s & ~7) + 8; if (aheap.curfree < s) MoreHeapSpace(&aheap, s); aheap.curfree -= s; cp = aheap.curfreep; aheap.curfreep = cp + s; return cp; } void *oalloc(SInt32 s) { char *cp; s = (s & ~7) + 8; if (oheap.curfree < s) MoreHeapSpace(&oheap, s); oheap.curfree -= s; cp = oheap.curfreep; oheap.curfreep = cp + s; return cp; } void *balloc(SInt32 s) { char *cp; s = (s & ~7) + 8; if (bheap.curfree < s) MoreHeapSpace(&bheap, s); bheap.curfree -= s; cp = bheap.curfreep; bheap.curfreep = cp + s; return cp; } void locklheap(void) { lheaplockcount++; } void unlocklheap(void) { if (lheaplockcount > 0) --lheaplockcount; } void freelheap(void) { HeapBlock *blockp; if (lheaplockcount == 0) { blockp = lheap.blocks; lheap.curblock = blockp; lheap.curfreep = ((char *) blockp) + sizeof(HeapBlock); lheap.curfree = blockp->blocksize - sizeof(HeapBlock); while (blockp) { blockp->blockfree = blockp->blocksize - sizeof(HeapBlock); blockp = blockp->next; } #ifdef CW_64_BIT_SUPPORT CTool_ResetPointerPool(); #endif } } void freeaheap(void) { HeapBlock *blockp; blockp = aheap.blocks; aheap.curblock = blockp; aheap.curfreep = ((char *) blockp) + sizeof(HeapBlock); aheap.curfree = blockp->blocksize - sizeof(HeapBlock); while (blockp) { blockp->blockfree = blockp->blocksize - sizeof(HeapBlock); blockp = blockp->next; } } void freeoheap(void) { HeapBlock *blockp; blockp = oheap.blocks; oheap.curblock = blockp; oheap.curfreep = ((char *) blockp) + sizeof(HeapBlock); oheap.curfree = blockp->blocksize - sizeof(HeapBlock); while (blockp) { blockp->blockfree = blockp->blocksize - sizeof(HeapBlock); blockp = blockp->next; } } void freebheap(void) { HeapBlock *blockp; blockp = bheap.blocks; bheap.curblock = blockp; bheap.curfreep = ((char *) blockp) + sizeof(HeapBlock); bheap.curfree = blockp->blocksize - sizeof(HeapBlock); while (blockp) { blockp->blockfree = blockp->blocksize - sizeof(HeapBlock); blockp = blockp->next; } } char *ScanHex(char *string, UInt32 *result, Boolean *overflow) { short c; UInt32 x; x = 0; *overflow = 0; for (;;) { c = *string; if (c >= '0' && c <= '9') { c -= '0'; } else if (c >= 'A' && c <= 'F') { c -= ('A' - 10); } else if (c >= 'a' && c <= 'f') { c -= ('a' - 10); } else { break; } if (x & 0xF0000000) *overflow = 1; x = (x << 4) | c; ++string; } *result = x; return string; } char *ScanOct(char *string, UInt32 *result, Boolean *overflow) { short c; UInt32 x; x = 0; *overflow = 0; for (;;) { c = *string - '0'; if (c >= 0 && c <= 9) { if (c >= 8) { *overflow = 1; ++string; break; } } else { break; } if (x & 0xE0000000) *overflow = 1; x = (x << 3) | c; ++string; } *result = x; return string; } char *ScanDec(char *string, UInt32 *result, Boolean *overflow) { short c; UInt32 x; x = 0; *overflow = 0; for (;;) { c = *string - '0'; if (c >= 0 && c <= 9) { if (x >= 0x19999999 && (x > 0x19999999 || c > 5)) *overflow = 1; } else { break; } x = (x << 3) + (x << 1) + c; ++string; } *result = x; return string; } static char *UnmangleClassname(char *name, char **classname, short *classnamesize, char **out, short *outsize, Boolean addclassname) { char *cp; short i; short n; short os; *classnamesize = 0; if (*(name++) != '_' || *(name++) != '_') return name; n = 0; while (name[0] >= '0' && name[0] <= '9') { n = (n * 10) + name[0] - '0'; ++name; } if (n > 0) { *classname = name; *classnamesize = n; if (addclassname) { cp = *out; os = *outsize; for (i = 0; i < n && os < 255; i++, os++) { *(cp++) = name[i]; } if (os < 255) { *(cp++) = ':'; os++; } if (os < 255) { *(cp++) = ':'; os++; } *out = cp; *outsize = os; } } return name + n; } static char *UnmangleAppend(char *name, char namesize, char **out, short *outsize) { char *cp; short i; short os; cp = *out; os = *outsize; for (i = 0; i < namesize && os < 255; i++, os++) { *(cp++) = name[i]; } *out = cp; *outsize = os; } void OldUnmangle(char *name, char *out, Boolean full) { short n; short namesize; short classnamesize; char *classname; char *cptr; if (*name == '.') ++name; namesize = 0; cptr = name; if (name[0] == '_' && name[1] == '_') { if (name[2] == 'c' && name[3] == 't') { cptr = UnmangleClassname(&name[4], &classname, &classnamesize, &out, &namesize, full); if (classnamesize == 0) goto invalid; UnmangleAppend(classname, classnamesize, &out, &namesize); } else if (name[2] == 'd' && name[3] == 't') { cptr = UnmangleClassname(&name[4], &classname, &classnamesize, &out, &namesize, full); if (classnamesize == 0) goto invalid; if (namesize <= 255) { *(out++) = '~'; namesize++; } UnmangleAppend(classname, classnamesize, &out, &namesize); } else if (name[2] == 'n' && name[3] == 'w') { cptr = UnmangleClassname(&name[4], &classname, &classnamesize, &out, &namesize, full); UnmangleAppend("operator new", 15, &out, &namesize); } else if (name[2] == 'd' && name[3] == 'l') { cptr = UnmangleClassname(&name[4], &classname, &classnamesize, &out, &namesize, full); UnmangleAppend("operator delete", 15, &out, &namesize); } else { invalid: strncpy(out, name, 256); return; } } else { n = 0; while (*cptr) { ++cptr; ++n; if (cptr[0] == '_' && cptr[1] == '_') { cptr = UnmangleClassname(cptr, &classname, &classnamesize, &out, &namesize, full); break; } } UnmangleAppend(name, n, &out, &namesize); } if (full && cptr[0] == 'F') { if (cptr[1] == 'v') { UnmangleAppend("(void)", 6, &out, &namesize); } else { UnmangleAppend("(...)", 5, &out, &namesize); } } *out = 0; } short hash(char *a) { char hash = 0; while (*a) { hash = hash << 1; hash ^= *(a++); } return hash & 0x7F; } void memclr(void *ptr, SInt32 size) { memset(ptr, 0, size); } void memclrw(void *ptr, SInt32 size) { memset(ptr, 0, size); } void CToLowercase(char *a, char *b) { char ch; do { ch = tolower(*(a++)); *(b++) = ch; } while (ch); } short getbit(SInt32 l) { switch (l) { 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; } } #ifdef ENDIAN_CONVERSION UInt16 CTool_EndianConvertWord16(UInt16 theword) { UInt16 conv; ((UInt8 *) &conv)[0] = ((UInt8 *) &theword)[1]; ((UInt8 *) &conv)[1] = ((UInt8 *) &theword)[0]; return conv; } UInt32 CTool_EndianConvertWord32(UInt32 theword) { UInt32 conv; ((UInt8 *) &conv)[0] = ((UInt8 *) &theword)[3]; ((UInt8 *) &conv)[1] = ((UInt8 *) &theword)[2]; ((UInt8 *) &conv)[2] = ((UInt8 *) &theword)[1]; ((UInt8 *) &conv)[3] = ((UInt8 *) &theword)[0]; return conv; } void CTool_EndianConvertMem(UInt8 *data, short len) { UInt8 *a = data; UInt8 *b = data + len; while (--b > a) { UInt8 val = *b; *b = *a; *a++ = val; } } #endif void CTool_EndianConvertWord64(CInt64 ci, char *result) { UInt32 buf[2]; buf[0] = CTool_EndianConvertWord32(CTool_EndianReadWord32(&ci.hi)); buf[1] = CTool_EndianConvertWord32(CInt64_GetULong(&ci)); memcpy(result, buf, 8); } #ifdef ENDIAN_CONVERSION UInt32 CTool_EndianReadWord32(void *ptr) { return *((UInt32 *) ptr); } #endif UInt16 CTool_EndianConvertInPlaceWord16Ptr(UInt16 *x) { UInt16 v; *x = v = CTool_EndianConvertWord16(*x); return v; } UInt32 CTool_EndianConvertInPlaceWord32Ptr(UInt32 *x) { UInt32 v; *x = v = CTool_EndianConvertWord32(*x); return v; } void CTool_EndianConvertVector128() { // not correct but idc } HashNameNode *CTool_GetPathName(const FSSpec *fss, SInt32 *moddateptr) { char name[256]; COS_FileGetPathName(name, fss, moddateptr); return GetHashNameNodeExport(name); } int strcat_safe(char *dest, const char *src, SInt32 len) { SInt32 dest_len; char ch; dest_len = strlen(dest); dest += dest_len; len -= dest_len; if (len < 0) return 1; while (len != 0) { ch = *(dest++) = *(src++); if (ch == 0) break; --len; } if (len == 0 && dest[-1]) { dest[-1] = 0; return 1; } else { return 0; } }