#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
// Ref struct
/*
typedef struct
{
uint32_t VersionID;
uint8_t KeyID[16];
uint8_t CertifyingKeyID[16];
uint32_t KeyUsageFlag;
uint8_t PlatformBindingInfo;
uint8_t Reserved[15];
uint32_t PublicExponentSize;
uint32_t ModulusSize;
PSPRSAKey RSAKeyData;
} PSPRSAKeyHdr;
* */
const char Structure[] =
"typedef struct\n"
"{\n"
" uint32_t VersionID;\n"
" uint8_t KeyID[16];\n"
" uint8_t CertifyingKeyID[16];\n"
" uint32_t KeyUsageFlag;\n"
" uint8_t PlatformBindingInfo;\n"
" uint8_t Reserved[15];\n"
" uint32_t PublicExponentSize;\n"
" uint32_t ModulusSize;\n"
" PSPRSAKey RSAKeyData;\n"
"} PSPRSAKeyHdr;\n";
typedef struct StructMember_s
{
char *TypeStr;
char *NameStr;
uint32_t TypeSize;
uint32_t ArraySize;
struct StructMember_s *next;
} StructMember;
char *CarveStr(const char *Src, size_t StartOffset, size_t Len)
{
//char *TmpBuf = (char *)malloc(sizeof(char) * (Len + 1));
char TmpBuf[256];
char *Output;
memcpy(TmpBuf, Src + StartOffset, Len);
TmpBuf[Len] = 0x00;
Output = strdup(TmpBuf);
//free(TmpBuf);
return(Output);
}
int main(int argc, char **argv)
{
//char *inputstruct = Structure;
StructMember *MemberList = NULL;
if(argc != 2)
{
printf("Usage: %s <structure definition>\n", argv[0]);
return(-1);
}
char *inputstruct = (char *)malloc(strlen(argv[1]) + 1);
strcpy(inputstruct, argv[1]);
for(char *line = strtok(inputstruct, "\n"); line; line = strtok(NULL, "\n"))
{
StructMember *memb = MemberList;
// If the line does not have a semicolon, it can be
// safely ignored.
if(!strchr(line, ';'))
continue;
// First, is this really a type?
uint32_t SizeOfType;
char *NamePos, *NameEnd, *TypePos, *TypeEnd, *ArrStart, *ArrEnd;
TypePos = strstr(line, "uint");
if(TypePos)
{
// Is it uint8_t? If so, stash the info in variables
if(TypePos[4] == '8' && TypePos[5] == '_' && TypePos[6] == 't')
{
NamePos = TypePos + strlen("uint8_t");
SizeOfType = 1;
}
// Is it uint16_t? Same deal.
else if(TypePos[4] == '1' && TypePos[5] == '6' && TypePos[6] == '_' && TypePos[7] == 't')
{
NamePos = TypePos + strlen("uint16_t");
SizeOfType = 2;
}
// Same for uint32_t...
else if(TypePos[4] == '3' && TypePos[5] == '2' && TypePos[6] == '_' && TypePos[7] == 't')
{
NamePos = TypePos + strlen("uint32_t");
SizeOfType = 4;
}
// Ditto for uint64_t.
else if(TypePos[4] == '6' && TypePos[5] == '4' && TypePos[6] == '_' && TypePos[7] == 't')
{
NamePos = TypePos + strlen("uint64_t");
SizeOfType = 8;
}
if(!memb) MemberList = memb = (StructMember *)malloc(sizeof(StructMember));
else
{
// Skip all previous members
for(memb = MemberList; memb->next; memb = memb->next);
memb = memb->next = (StructMember *)malloc(sizeof(StructMember));
}
memset(memb, 0x00, sizeof(StructMember));
TypeEnd = TypePos;
while(!isspace(*TypeEnd)) TypeEnd++;
//printf("TypeEnd = %s\nTypePos = %s\n", TypeEnd, TypePos);
NamePos = TypeEnd + 1;
NameEnd = strchr(NamePos, ';') - 1;
if(!NameEnd)
{
printf("Error: Malformed line %s\n", line);
exit(1);
}
memb->TypeStr = CarveStr(TypePos, 0x00, (SizeOfType == 1) ? 7 : 8);
memb->NameStr = CarveStr(NamePos, 0x00, NameEnd - NamePos + 1);
memb->TypeSize = SizeOfType;
// Is it an array?
ArrStart = strchr(memb->NameStr, '[');
// If so, get the size.
if(ArrStart)
{
ArrEnd = strchr(memb->NameStr, ']');
memb->ArraySize = strtoul(ArrStart + 1, NULL, 0);
// Cut the array notation off the name.
ArrStart[0] = 0x00;
}
memb->next = NULL;
}
else
{
printf("Warning: Line not recognized: '%s'\n", line);
}
}
// Info harvested; time to generate code.
for(StructMember *CurMemb = MemberList; CurMemb; CurMemb = CurMemb->next)
{
char *TypeSpecifier = NULL;
//printf("TypeStr = %s\nNameStr = %s\nArraySize = %d\n", CurMemb->TypeStr, CurMemb->NameStr, CurMemb->ArraySize);
if(CurMemb->TypeSize == 1) TypeSpecifier = "0x%02X";
else if(CurMemb->TypeSize == 2) TypeSpecifier = "0x%04X";
else if(CurMemb->TypeSize == 4) TypeSpecifier = "0x%08X";
else if(CurMemb->TypeSize == 8) TypeSpecifier = "0x%016llX";
else printf("How did you even get here?");
printf("printf(\"%s: ", CurMemb->NameStr);
if(CurMemb->ArraySize)
{
printf("\");\n");
printf("\nfor(int i = 0; i < %d; ++i)\n", CurMemb->ArraySize);
printf("\tprintf(\"%s, \", dmp->%s[i]);\n\n", TypeSpecifier, CurMemb->NameStr);
printf("putchar('\\n');\n");
}
else
{
printf("%s\\n\", dmp->%s);\n", TypeSpecifier, CurMemb->NameStr);
}
}
return(0);
}
Comments