Skip to content

Commit

Permalink
Finish matching xIni (#283)
Browse files Browse the repository at this point in the history
* Some work on matching xIni

* Finish matching xIni, use some variable names from seilweiss/rat

Co-authored-by: Seil Weiss <[email protected]>

* xIni: Add missing function prototypes

---------

Co-authored-by: Seil Weiss <[email protected]>
  • Loading branch information
tgsm and seilweiss authored Jun 30, 2024
1 parent 51036b4 commit b20a50b
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 5 deletions.
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

0 comments on commit b20a50b

Please sign in to comment.