move string utility to util.cc + small script identifier fix
This commit is contained in:
parent
3f557369c7
commit
5f883a8017
@ -61,7 +61,7 @@ STATIC_ASSERT(sizeof(int) == 4);
|
||||
#endif
|
||||
|
||||
#if COMPILER_MSVC
|
||||
# define TRAP() __debugbreak();
|
||||
# define TRAP() __debugbreak()
|
||||
#elif COMPILER_GCC || COMPILER_CLANG
|
||||
# define TRAP() __builtin_trap()
|
||||
#else
|
||||
@ -137,6 +137,18 @@ void SetPrintFunction(TPrintFunction *Function);
|
||||
void error(char *Text, ...) ATTR_PRINTF(1, 2);
|
||||
void print(int Level, char *Text, ...) ATTR_PRINTF(1, 2);
|
||||
|
||||
bool isSpace(int c);
|
||||
bool isAlpha(int c);
|
||||
bool isEngAlpha(int c);
|
||||
bool isDigit(int c);
|
||||
int toLower(int c);
|
||||
int toUpper(int c);
|
||||
char *strLower(char *s);
|
||||
char *strUpper(char *s);
|
||||
int stricmp(const char *s1, const char *s2, int Pos);
|
||||
char *findFirst(char *s, char c);
|
||||
char *findLast(char *s, char c);
|
||||
|
||||
struct TReadStream {
|
||||
// VIRTUAL FUNCTIONS
|
||||
// =========================================================================
|
||||
|
||||
@ -128,10 +128,8 @@ void ReadConfig(void){
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(fusion): If the following `readSymbol` calls `nextToken`, then the
|
||||
// buffer the identifier is in will get wiped. (UPDATE: Yes, the original
|
||||
// version copies it into a local stack buffer, lol.)
|
||||
const char *Identifier = Script.readIdentifier();
|
||||
char Identifier[MAX_IDENT_LENGTH];
|
||||
strcpy(Identifier, Script.readIdentifier());
|
||||
Script.readSymbol('=');
|
||||
|
||||
// TODO(fusion): Ughh... Get rid of all `strcpy`s. A malicious configuration
|
||||
|
||||
@ -735,7 +735,8 @@ static void ReadMapConfig(void){
|
||||
break;
|
||||
}
|
||||
|
||||
const char *Identifier = Script.readIdentifier();
|
||||
char Identifier[MAX_IDENT_LENGTH];
|
||||
strcpy(Identifier, Script.readIdentifier());
|
||||
Script.readSymbol('=');
|
||||
|
||||
if(strcmp(Identifier, "sectorxmin") == 0){
|
||||
|
||||
106
src/script.cc
106
src/script.cc
@ -15,108 +15,6 @@ static char ErrorString[100];
|
||||
|
||||
// Helper Functions
|
||||
// =============================================================================
|
||||
// TODO(fusion): Move to `util.cc`?
|
||||
|
||||
static bool isSpace(int c){
|
||||
return c == ' '
|
||||
|| c == '\t'
|
||||
|| c == '\n'
|
||||
|| c == '\r'
|
||||
|| c == '\v'
|
||||
|| c == '\f';
|
||||
}
|
||||
|
||||
static bool isAlpha(int c){
|
||||
// TODO(fusion): This is most likely wrong! We're assuming a direct conversion
|
||||
// from `char` to `int` which will cause sign extension for negative values. This
|
||||
// wouldn't be a problem if we expected to parse only streams of `char[]` but can
|
||||
// be problematic for the output of `getc` which returns bytes as `unsigned char`
|
||||
// converted to `int`.
|
||||
// TLDR: The parameter `c` should be `uint8`.
|
||||
return ('A' <= c && c <= 'Z')
|
||||
|| ('a' <= c && c <= 'z')
|
||||
|| c == -0x1C // E4 => ä
|
||||
|| c == -0x0A // F6 => ö
|
||||
|| c == -0x04 // FC => ü
|
||||
|| c == -0x3C // C4 => Ä
|
||||
|| c == -0x2A // D6 => Ö
|
||||
|| c == -0x24 // DC => Ü
|
||||
|| c == -0x21; // DF => ß
|
||||
}
|
||||
|
||||
static bool isEngAlpha(int c){
|
||||
return ('A' <= c && c <= 'Z')
|
||||
|| ('a' <= c && c <= 'z');
|
||||
}
|
||||
|
||||
static bool isDigit(int c){
|
||||
return ('0' <= c && c <= '9');
|
||||
}
|
||||
|
||||
static int toLower(int c){
|
||||
// TODO(fusion): Same problem as `isAlpha`.
|
||||
if(('A' <= c && c <= 'Z') || (0xC0 <= c && c <= 0xDE && c != 0xD7)){
|
||||
c += 32;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
static int toUpper(int c){
|
||||
// TODO(fusion): Same problem as `isAlpha`.
|
||||
if(('A' <= c && c <= 'Z') || (0xE0 <= c && c <= 0xFE && c != 0xF7)){
|
||||
c -= 32;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
static char *strLower(char *s){
|
||||
for(int i = 0; s[i] != 0; i += 1){
|
||||
s[i] = (char)toLower(s[i]);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static char *strUpper(char *s){
|
||||
for(int i = 0; s[i] != 0; i += 1){
|
||||
s[i] = (char)toUpper(s[i]);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static int stricmp(const char *s1, const char *s2, int Pos){
|
||||
for(int i = 0; i < Pos; i += 1){
|
||||
int c1 = toLower(s1[i]);
|
||||
int c2 = toLower(s2[i]);
|
||||
if(c1 > c2){
|
||||
return 1;
|
||||
}else if(c1 < c2){
|
||||
return -1;
|
||||
}else{
|
||||
ASSERT(c1 == c2);
|
||||
if(c1 == 0){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *findFirst(char *s, char c){
|
||||
return strchr(s, (int)c);
|
||||
}
|
||||
|
||||
static char *findLast(char *s, char c){
|
||||
char *Current = s;
|
||||
char *Last = NULL;
|
||||
while(true){
|
||||
Current = strchr(Current, (int)c);
|
||||
if(Current == NULL)
|
||||
break;
|
||||
Last = Current;
|
||||
Current += 1; // skip character
|
||||
}
|
||||
return Last;
|
||||
}
|
||||
|
||||
static void SaveFile(const char *Filename){
|
||||
if(Filename == NULL){
|
||||
error("SaveFile: Filename ist NULL.\n");
|
||||
@ -143,7 +41,7 @@ static void SaveFile(const char *Filename){
|
||||
|
||||
// NOTE(fusion): This function was in pretty bad shape after this point. The
|
||||
// reason is probably because GHIDRA didn't make sense of it using `alloca`
|
||||
// or some other mechanism to allocate a buffer on the stack to copy the whole
|
||||
// or some other mechanism to allocate a buffer on the stack and copy the whole
|
||||
// file in one go. It's probably not a good idea to mimic that here so we'll
|
||||
// do it gradually.
|
||||
|
||||
@ -535,7 +433,7 @@ void TReadScriptFile::nextToken(void){
|
||||
while(true){
|
||||
int next = getc(File);
|
||||
if(isAlpha(next) || isDigit(next) || next == '_'){
|
||||
if(IdentLength >= 30){
|
||||
if(IdentLength >= (MAX_IDENT_LENGTH - 1)){
|
||||
this->error("identifier too long");
|
||||
}
|
||||
this->String[IdentLength] = (char)next;
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
#include "common.hh"
|
||||
#include "enums.hh"
|
||||
|
||||
#define MAX_IDENT_LENGTH 30
|
||||
|
||||
struct TReadScriptFile {
|
||||
// REGULAR FUNCTIONS
|
||||
// =========================================================================
|
||||
|
||||
102
src/util.cc
102
src/util.cc
@ -41,6 +41,108 @@ void print(int Level, char *Text, ...){
|
||||
}
|
||||
}
|
||||
|
||||
// String Utility
|
||||
// =============================================================================
|
||||
bool isSpace(int c){
|
||||
return c == ' '
|
||||
|| c == '\t'
|
||||
|| c == '\n'
|
||||
|| c == '\r'
|
||||
|| c == '\v'
|
||||
|| c == '\f';
|
||||
}
|
||||
|
||||
bool isAlpha(int c){
|
||||
// TODO(fusion): This is most likely wrong! We're assuming a direct conversion
|
||||
// from `char` to `int` which will cause sign extension for negative values. This
|
||||
// wouldn't be a problem if we expected to parse only streams of `char[]` but can
|
||||
// be problematic for the output of `getc` which returns bytes as `unsigned char`
|
||||
// converted to `int`.
|
||||
// TLDR: The parameter `c` should be `uint8`.
|
||||
return ('A' <= c && c <= 'Z')
|
||||
|| ('a' <= c && c <= 'z')
|
||||
|| c == -0x1C // E4 => ä
|
||||
|| c == -0x0A // F6 => ö
|
||||
|| c == -0x04 // FC => ü
|
||||
|| c == -0x3C // C4 => Ä
|
||||
|| c == -0x2A // D6 => Ö
|
||||
|| c == -0x24 // DC => Ü
|
||||
|| c == -0x21; // DF => ß
|
||||
}
|
||||
|
||||
bool isEngAlpha(int c){
|
||||
return ('A' <= c && c <= 'Z')
|
||||
|| ('a' <= c && c <= 'z');
|
||||
}
|
||||
|
||||
bool isDigit(int c){
|
||||
return ('0' <= c && c <= '9');
|
||||
}
|
||||
|
||||
int toLower(int c){
|
||||
// TODO(fusion): Same problem as `isAlpha`.
|
||||
if(('A' <= c && c <= 'Z') || (0xC0 <= c && c <= 0xDE && c != 0xD7)){
|
||||
c += 32;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
int toUpper(int c){
|
||||
// TODO(fusion): Same problem as `isAlpha`.
|
||||
if(('A' <= c && c <= 'Z') || (0xE0 <= c && c <= 0xFE && c != 0xF7)){
|
||||
c -= 32;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
char *strLower(char *s){
|
||||
for(int i = 0; s[i] != 0; i += 1){
|
||||
s[i] = (char)toLower(s[i]);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
char *strUpper(char *s){
|
||||
for(int i = 0; s[i] != 0; i += 1){
|
||||
s[i] = (char)toUpper(s[i]);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int stricmp(const char *s1, const char *s2, int Pos){
|
||||
for(int i = 0; i < Pos; i += 1){
|
||||
int c1 = toLower(s1[i]);
|
||||
int c2 = toLower(s2[i]);
|
||||
if(c1 > c2){
|
||||
return 1;
|
||||
}else if(c1 < c2){
|
||||
return -1;
|
||||
}else{
|
||||
ASSERT(c1 == c2);
|
||||
if(c1 == 0){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *findFirst(char *s, char c){
|
||||
return strchr(s, (int)c);
|
||||
}
|
||||
|
||||
char *findLast(char *s, char c){
|
||||
char *Current = s;
|
||||
char *Last = NULL;
|
||||
while(true){
|
||||
Current = strchr(Current, (int)c);
|
||||
if(Current == NULL)
|
||||
break;
|
||||
Last = Current;
|
||||
Current += 1; // skip character
|
||||
}
|
||||
return Last;
|
||||
}
|
||||
|
||||
// TReadStream
|
||||
// =============================================================================
|
||||
bool TReadStream::readFlag(void){
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user