MWCC/compiler_and_linker/FrontEnd/Common/CompilerTools.c

1316 lines
30 KiB
C

#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;
}
}