mirror of
https://github.com/ksherlock/mpw.git
synced 2024-11-22 15:31:50 +00:00
225 lines
3.9 KiB
C++
225 lines
3.9 KiB
C++
|
#include "template.h"
|
||
|
#include "debugger.h"
|
||
|
|
||
|
namespace Debug {
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
|
||
|
unsigned CalcOneSize(FieldEntry *e)
|
||
|
{
|
||
|
unsigned s = (e->type & 0x0f00) >> 8;
|
||
|
|
||
|
if (!s) {
|
||
|
// struct or pointer...
|
||
|
if (e->type & 0x8000) s = 4;
|
||
|
else if (e->tmpl) s = e->tmpl->struct_size;
|
||
|
}
|
||
|
|
||
|
if (e->count) s *= e->count;
|
||
|
|
||
|
return s;
|
||
|
}
|
||
|
|
||
|
unsigned CalcSize(FieldEntry *e)
|
||
|
{
|
||
|
unsigned size = 0;
|
||
|
|
||
|
while (e)
|
||
|
{
|
||
|
size += CalcOneSize(e);
|
||
|
e = e->next;
|
||
|
}
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
FieldEntry *Reverse(FieldEntry *e)
|
||
|
{
|
||
|
if (!e) return e;
|
||
|
|
||
|
// reverse the order...
|
||
|
FieldEntry *prev;
|
||
|
FieldEntry *next;
|
||
|
|
||
|
prev = nullptr;
|
||
|
for(;;)
|
||
|
{
|
||
|
next = e->next;
|
||
|
e->next = prev;
|
||
|
|
||
|
prev = e;
|
||
|
e = next;
|
||
|
if (!e) return prev;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
void CreateTypedef(const std::string *name, int type, TemplateParseInfo *info)
|
||
|
{
|
||
|
// check if it's an existing typedef...
|
||
|
|
||
|
auto &Templates = *info->templates;
|
||
|
auto &Types = *info->types;
|
||
|
|
||
|
|
||
|
auto iter = Types.find(*name);
|
||
|
if (iter != Types.end())
|
||
|
{
|
||
|
if (iter->second == type) return; // ok, just a duplicate.
|
||
|
fprintf(stderr, "Template Error: line %d - redefining %s\n",
|
||
|
info->LineNumber, name->c_str());
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (Templates.find(*name) != Templates.end())
|
||
|
{
|
||
|
fprintf(stderr, "Template Error: line %d - redefining %s\n",
|
||
|
info->LineNumber, name->c_str());
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
Types.emplace(std::make_pair(*name, type));
|
||
|
}
|
||
|
|
||
|
|
||
|
void CreateTemplate(const std::string *name, FieldEntry *firstField, TemplateParseInfo *info)
|
||
|
{
|
||
|
auto &Templates = *info->templates;
|
||
|
auto &Types = *info->types;
|
||
|
|
||
|
// check if it exists...
|
||
|
|
||
|
if (Templates.find(*name) != Templates.end())
|
||
|
{
|
||
|
fprintf(stderr, "Template Error: line %d - redefining %s\n",
|
||
|
info->LineNumber, name->c_str());
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (Types.find(*name) != Types.end())
|
||
|
{
|
||
|
fprintf(stderr, "Template Error: line %d - redefining %s\n",
|
||
|
info->LineNumber, name->c_str());
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
firstField = Reverse(firstField);
|
||
|
firstField->struct_size = CalcSize(firstField);
|
||
|
|
||
|
Templates.emplace(std::make_pair(*name, firstField));
|
||
|
}
|
||
|
|
||
|
|
||
|
void PrettyPrint(uint32_t value, unsigned type)
|
||
|
{
|
||
|
|
||
|
switch (type)
|
||
|
{
|
||
|
case kOSType:
|
||
|
// print 4-cc code
|
||
|
return;
|
||
|
case kOSErr:
|
||
|
// print value + short name
|
||
|
return;
|
||
|
|
||
|
case kPStringPtr:
|
||
|
// read the string...
|
||
|
return;
|
||
|
|
||
|
case kCStringPtr:
|
||
|
// read the string...
|
||
|
return;
|
||
|
|
||
|
case kBoolean:
|
||
|
fputs(value ? "true" : "false", stdout);
|
||
|
return;
|
||
|
|
||
|
case kHandle:
|
||
|
// print address, size, locked stats.
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
// int/signed int - print base 10.
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
void ApplyTemplate(uint32_t address, FieldEntry *e, unsigned indent)
|
||
|
{
|
||
|
unsigned offset = 0;
|
||
|
|
||
|
for( ; e ; e = e->next)
|
||
|
{
|
||
|
|
||
|
unsigned count = e->count;
|
||
|
unsigned type = e->type;
|
||
|
unsigned s = (type & 0x0f00) >> 8;
|
||
|
|
||
|
if (!s) {
|
||
|
// struct or pointer...
|
||
|
if (e->type & 0x8000) s = 4;
|
||
|
else if (e->tmpl) s = e->tmpl->struct_size;
|
||
|
}
|
||
|
|
||
|
|
||
|
printf("%-20s", e->name->c_str());
|
||
|
|
||
|
// todo -- support arrays
|
||
|
// todo -- pretty print values (boolean, oserr, ostype, etc.)
|
||
|
switch(s)
|
||
|
{
|
||
|
case 1:
|
||
|
{
|
||
|
uint8_t value = ReadByte(address + offset);
|
||
|
printf(" %02x", value);
|
||
|
PrettyPrint(value, type);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 2:
|
||
|
{
|
||
|
uint16_t value = ReadWord(address + offset);
|
||
|
printf(" %04x", value);
|
||
|
PrettyPrint(value, type);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 4:
|
||
|
{
|
||
|
uint32_t value = ReadLong(address + offset);
|
||
|
printf("%08x", value);
|
||
|
PrettyPrint(value, type);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 0:
|
||
|
// either a pointer or a struct
|
||
|
if (type & 0x8000) {
|
||
|
// pointer.
|
||
|
uint32_t value = ReadLong(address + offset);
|
||
|
printf("%08x", value);
|
||
|
PrettyPrint(value, type);
|
||
|
break;
|
||
|
}
|
||
|
if (type == 0) {
|
||
|
// struct ... recurse.
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
printf("\n");
|
||
|
offset += CalcOneSize(e);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|