Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finish matching xIni #283

Merged
merged 3 commits into from
Jun 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ def Rel(lib_name: str, objects: List[Object]) -> Dict[str, Any]:
Object(NonMatching, "SB/Core/x/xHudMeter.cpp"),
Object(NonMatching, "SB/Core/x/xHudModel.cpp"),
Object(NonMatching, "SB/Core/x/xHudUnitMeter.cpp"),
Object(NonMatching, "SB/Core/x/xIni.cpp"),
Object(Matching, "SB/Core/x/xIni.cpp"),
Object(NonMatching, "SB/Core/x/xMath.cpp"),
Object(NonMatching, "SB/Core/x/xMath2.cpp"),
Object(NonMatching, "SB/Core/x/xMath3.cpp"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,12 @@

#include <string.h>

#endif
namespace std
{
inline static char* strstr(char* haystack, const char* needle)
{
return ::strstr(haystack, needle);
}
} // namespace std

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ char* strcat(char* dest, const char* source);
int strcmp(const char* a, const char* b);
int stricmp(const char* a, const char* b);
int strcmpi(const char* a, const char* b);
char* strstr(const char* haystack, const char* needle);
int atoi(const char* s);

#ifdef __cplusplus
}
#endif

#endif
#endif
170 changes: 169 additions & 1 deletion src/SB/Core/x/xIni.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,175 @@
#include "xIni.h"
#include "xString.h"
#include <rwplcore.h>

#include <types.h>
#include <stdlib.h>
#include <cstdlib>
#include <cstring>

char* TrimWhitespace(char* string)
{
// Skip through any leading whitespace
for (; *string == ' ' || *string == '\t'; string++)
{
}
// Return early if there's no other characters to go through
if (*string == '\0')
{
return string;
}

// Find first non-whitespace character at the end of the string
char* substring = &string[strlen(string) - 1];
for (; *substring == ' ' || *substring == '\t'; substring--)
{
}

// Set the null-terminator accordingly
substring[1] = '\0';

return string;
}

xIniFile* xIniParse(char* buf, int32 len)
{
int32 i;
int32 ccr = 1;
int32 clf = 1;
int32 copen = 0;
int32 lastCRLF = -1;
for (i = 0; i < len; i++)
{
switch (buf[i])
{
case '\n':
lastCRLF = i;
clf++;
break;
case '\r':
lastCRLF = i;
ccr++;
break;
case '[':
copen++;
break;
}
}

if (clf > ccr)
{
ccr = clf;
}

int32 sectionAlloc = copen;
int32 valueAlloc = ccr;

xIniFile* ini = (xIniFile*)RwMalloc(sizeof(xIniFile) + (valueAlloc * sizeof(xIniValue)) +
(sectionAlloc * sizeof(xIniSection)) + (len - lastCRLF));
ini->mem = NULL;
ini->NumValues = 0;
ini->NumSections = 0;
ini->Values = (xIniValue*)(ini + 1);
ini->Sections = (xIniSection*)(ini->Values + valueAlloc);

char* lastLine = (char*)(ini->Sections + sectionAlloc);
strncpy(lastLine, buf + (lastCRLF + 1), len - (lastCRLF + 1));
lastLine[len - (lastCRLF + 1)] = '\0';

if (lastCRLF >= 0)
{
buf[lastCRLF] = '\0';
}
else
{
buf[0] = '\0';
}

char* ltoken;
char* line = xStrTok(buf, "\n\r", &ltoken);
if (line == NULL)
{
line = xStrTok(lastLine, "\n\r", &ltoken);
lastLine = NULL;
}

while (line != NULL)
{
line = TrimWhitespace(line);
if (*line != '#' && *line != '\0')
{
if (*line == '[')
{
char* c = std::strstr(line, "]");
if (c != NULL)
{
*c = '\0';
c = TrimWhitespace(line + 1);
if (*c != '\0')
{
ini->Sections[ini->NumSections].sec = c;
ini->Sections[ini->NumSections].first = ini->NumValues;
ini->Sections[ini->NumSections].count = 0;
ini->NumSections++;
}
}
}
else
{
char* c = std::strstr(line, "=");
if (c != NULL)
{
*c = '\0';
char* tok = TrimWhitespace(line);
if (*tok != '\0')
{
line = c + 1;
c = std::strstr(line, "#");
if (c != NULL)
{
*c = '\0';
}
char* val = TrimWhitespace(line);
ini->Values[ini->NumValues].tok = tok;
ini->Values[ini->NumValues].val = val;
ini->NumValues++;
if (ini->NumSections != 0)
{
ini->Sections[ini->NumSections - 1].count++;
}
}
}
}
}

line = xStrTok(NULL, "\n\r", &ltoken);
if (line == NULL && lastLine != NULL)
{
line = xStrTok(lastLine, "\n\r", &ltoken);
lastLine = NULL;
}
}

return ini;
}

void xIniDestroy(xIniFile* ini)
{
RwFree(ini->mem);
RwFree(ini);
}

int32 xIniGetIndex(xIniFile* ini, int8* tok)
{
for (int32 i = 0; i < ini->NumValues; i++)
{
if (xStricmp(ini->Values[i].tok, tok) == 0)
{
return i;
}
}

return -1;
}

int32 xIniGetInt(xIniFile* ini, int8* tok, int32 def)
{
Expand Down
6 changes: 5 additions & 1 deletion src/SB/Core/x/xIni.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ struct xIniFile
int8 pathname[256];
};

xIniFile* xIniParse(char* buf, int32 len);
void xIniDestroy(xIniFile* ini);
int32 xIniGetIndex(xIniFile* ini, int8* tok);
int32 xIniGetInt(xIniFile* ini, int8* tok, int32 def);
float32 xIniGetFloat(xIniFile* ini, int8* tok, float32 def);
int8* xIniGetString(xIniFile* ini, int8* tok, int8* def);

#endif
#endif