mirror of
https://github.com/thepigeongenerator/tetris_clone.git
synced 2025-12-17 05:55:46 +01:00
fix: parsing fails for long comment lines
if the data was completed before the line did, and the line is longer than the buffer. The rest of the line would be interperted as additional data.
This commit is contained in:
@@ -21,23 +21,48 @@ int load_opts(void) {
|
|||||||
FILE* fptr = fopen(path_opts, "r");
|
FILE* fptr = fopen(path_opts, "r");
|
||||||
if (!fptr) return 1;
|
if (!fptr) return 1;
|
||||||
|
|
||||||
|
unsigned key_len = 0; // length of the key data
|
||||||
|
unsigned val_len = 0; // length of the value data
|
||||||
|
char const* key = NULL; // the pointer for the start of the key
|
||||||
|
char const* val = NULL; // the pointer for the start of the value
|
||||||
|
bool feq = false; // whether we've found the equal sign
|
||||||
|
bool eol = false; // whether we've reached the end of the line/string, so we don't read what should be comments as data, etc.
|
||||||
|
bool nodat = false; // whether we are done and can just look for an EOL indicator
|
||||||
|
|
||||||
// read the file line by line
|
// read the file line by line
|
||||||
char buf[BUF_SIZE]; // buffer will contain \0 terminated string. fgets stores into the buffer until \n or EOF
|
char buf[BUF_SIZE]; // buffer will contain \0 terminated string. fgets stores into the buffer until \n or EOF
|
||||||
while (fgets(buf, BUF_SIZE, fptr)) {
|
while (fgets(buf, BUF_SIZE, fptr)) {
|
||||||
unsigned key_len = 0;
|
// reset if EOL has been reached
|
||||||
unsigned val_len = 0;
|
if (eol) {
|
||||||
char* key = NULL;
|
key_len = 0;
|
||||||
char* val = NULL;
|
val_len = 0;
|
||||||
bool feq = false; // whether we found the equal sign
|
key = NULL;
|
||||||
|
val = NULL;
|
||||||
|
feq = false;
|
||||||
|
eol = false;
|
||||||
|
nodat = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop through each character
|
||||||
for (unsigned i = 0; i < BUF_SIZE; i++) {
|
for (unsigned i = 0; i < BUF_SIZE; i++) {
|
||||||
// handling of special characters (in the order of most common to least)
|
// check EOL / EOF indicators (or just end of string) (CRLF vs LF doesn't matter here, since both end with \n)
|
||||||
if (buf[i] == ' ' || buf[i] == '\t') { // whitespace is ignored; neither keys or values can contain spaces
|
if (buf[i] == '\n' || buf[i] == '\0') {
|
||||||
if (!val) continue;
|
eol = true;
|
||||||
else break; // if val was found; break out of the loop
|
break;
|
||||||
|
}
|
||||||
|
if (nodat) continue;
|
||||||
|
|
||||||
|
// ignore whitespace, to acquire a correct starting point
|
||||||
|
if (buf[i] == ' ' || buf[i] == '\t') {
|
||||||
|
if (val) nodat = true; // don't continue processing if we encounter a space after starting val
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore comments
|
||||||
|
if (buf[i] == '#') {
|
||||||
|
nodat = true;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
if (buf[i] == '\n') break; // don't check \0, since if \n isn't present, the string will be BUF_SIZE length
|
|
||||||
if (buf[i] == '#') break; // stop the rest of the data is a comment
|
|
||||||
|
|
||||||
// increment the key/value length if set
|
// increment the key/value length if set
|
||||||
if (val) val_len++; // first check if value is set, as it is set last
|
if (val) val_len++; // first check if value is set, as it is set last
|
||||||
@@ -51,6 +76,7 @@ int load_opts(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ignore if either the key or value haven't been set
|
// ignore if either the key or value haven't been set
|
||||||
|
// NOTE: eol might not be set at this point, this is intentional so we don't accidentally read a comment outside the buffer size as a key-value pair
|
||||||
if (!key || !val) continue;
|
if (!key || !val) continue;
|
||||||
// TODO: load opts from the file
|
// TODO: load opts from the file
|
||||||
// the options shall be loaded as key-value-pairs
|
// the options shall be loaded as key-value-pairs
|
||||||
|
|||||||
Reference in New Issue
Block a user