rickjr/bin/overlayhelper/source/cfile.cpp

208 lines
4.8 KiB
C++

//
// cfile.cpp
//
#include "cfile.h"
#include <stdio.h>
//------------------------------------------------------------------------------
// Static Helpers
static bool contains(char x, const char* pSeparators)
{
while (*pSeparators)
{
if (x == *pSeparators)
{
return true;
}
pSeparators++;
}
return false;
}
static std::vector<std::string> split(const std::string& s, const char* separators)
{
std::vector<std::string> output;
std::string::size_type prev_pos = 0, pos = 0;
for (int index = 0; index < s.length(); ++index)
{
pos = index;
// if the index is a separator
if (contains(s[index], separators))
{
// if we've skipped a token, collect it
if (prev_pos != index)
{
output.push_back(s.substr(prev_pos, index-prev_pos));
// skip white space here
while (index < s.length())
{
if (contains(s[index], separators))
{
++index;
}
else
{
prev_pos = index;
pos = index;
break;
}
}
}
else
{
prev_pos++;
}
}
}
output.push_back(s.substr(prev_pos, pos-prev_pos+1)); // Last word
return output;
}
// make this string lowercase
static void tolower(std::string& s)
{
for (int index = 0; index < s.length(); ++index)
{
s[index] = tolower( s[index] );
}
}
static std::string next_token(std::vector<std::string>& tokens, MemoryStream& memStream)
{
std::string result = "";
if (tokens.size() >= 1)
{
result = tokens[0];
tokens.erase(tokens.cbegin());
}
else
{
while (memStream.NumBytesAvailable())
{
std::string lineData = memStream.ReadLine();
tokens = split(lineData, "[](), \t");
if (tokens.size() >= 1)
{
return next_token(tokens, memStream);
}
}
}
return result;
}
//------------------------------------------------------------------------------
CFile::CFile( std::string filepath )
: m_filepath( filepath )
{
FILE* pFile = nullptr;
errno_t err = fopen_s(&pFile, filepath.c_str(), "rb");
if (0==err)
{
fseek(pFile, 0, SEEK_END);
size_t length = ftell(pFile);
fseek(pFile, 0, SEEK_SET);
//printf("\n// CFile %s - %lld bytes\n", filepath.c_str(), length);
//printf("// Reading %s\n", filepath.c_str());
//printf("//\n");
//printf("// This file generated by overlayhelper.exe\n");
//printf("//\n");
//printf("//\n");
u8* pData = new u8[ length ];
fread(pData, sizeof(u8), length / sizeof(u8), pFile);
// Now we have a buffer, with the whole C File
// Looking to parse 2 types of things
// CODE_BLOCK macros
// DATA_BLOCK macros
// INCBIN macros
{
MemoryStream memStream(pData, length);
while (memStream.NumBytesAvailable())
{
std::string lineData = memStream.ReadLine();
// symbols are case sensitive
// we care about the first 32 bit value in hex, and the last value on the line, the symbol
std::vector<std::string> tokens = split(lineData, "[](), \t");
if (tokens.size() >= 2)
{
std::string token = next_token(tokens, memStream);
if (token == "INCBIN")
{
// section
token = next_token(tokens, memStream);
token = next_token(tokens, memStream);
printf("incbin_%s_start_high = incbin_%s_start>>16;\n", token.c_str(),token.c_str());
printf("incbin_%s_start_BLOCK = incbin_%s_start/0x2000;\n", token.c_str(),token.c_str());
printf("incbin_%s_length = incbin_%s_end-incbin_%s_start;\n", token.c_str(),token.c_str(),token.c_str());
printf("incbin_%s_length_high = incbin_%s_length>>16;\n", token.c_str(),token.c_str());
}
else if ( (token == "CODE_BLOCK") ||
(token == "DATA_BLOCK") )
{
// We aren't as good as the C Preprocessor, but we will allow this
// to span 1 line, because RickJr has weird syntax
// First get the block number
token = next_token(tokens, memStream);
u32 block_num = strtoul(token.c_str(), nullptr, 0);
// Next we need the function name
do
{
token = next_token(tokens, memStream);
} while (token=="static" || token =="volatile");
// now token has return type
token = next_token(tokens, memStream);
// now token finally has our function or data name
printf("%s_BLOCK = %d;\n", token.c_str(), block_num); // just need the block number for mapper
}
}
}
}
delete[] pData;
fclose(pFile);
//printf("\n// Read Completed\n");
}
else
{
printf("// CFile could not open %s\n", filepath.c_str());
printf("//\n");
}
}
//------------------------------------------------------------------------------
CFile::~CFile()
{
}
//------------------------------------------------------------------------------