diff --git a/src/game/opts.c b/src/game/opts.c index e1977f2..486f6d0 100644 --- a/src/game/opts.c +++ b/src/game/opts.c @@ -8,6 +8,54 @@ #define BUF_SIZE 32 +struct proc_buf_dat { + char const* restrict key; // length of the key data + char const* restrict val; // length of the value data + unsigned key_len; // the pointer for the start of the key + unsigned val_len; // the pointer for the start of the value + bool feq; // whether we've found the equal sign and are looking for the value + bool eol; // whether we've reached the end of the line/string, so we don't read what should be comments as data, etc. + bool nodat; // whether we are done and can just look for an EOL indicator +}; + +/* processes the data within the buffer. + NOTE: when the function returns, eol might not be set, this is to ensure that we know for certain that an EOL indicator has been reached. */ +static void proc_buf(char const* restrict buf, struct proc_buf_dat* restrict dat) { + // reset if EOL has been reached + if (dat->eol) *dat = (struct proc_buf_dat){0}; + + // loop through each character + for (unsigned i = 0; i < BUF_SIZE; i++) { + // check EOL / EOF indicators (or just end of string) (CRLF vs LF doesn't matter that much here, since both end with \n) + if (buf[i] == '\n' || buf[i] == '\0') { + dat->eol = true; + break; + } + if (dat->nodat) continue; // just continue until we've found an EOL/EOF indicator + + // ignore whitespace, to acquire a correct starting point + if (buf[i] == ' ' || buf[i] == '\t') { + if (dat->val) dat->nodat = true; // don't continue processing if we encounter a space after starting val + continue; + } + + // ignore comments + if (buf[i] == '#') { + dat->nodat = true; + continue; + } + + // increment the key/value length if set + if (dat->val) dat->val_len++; // first check if value is set, as it is set last + else if (dat->key) dat->key_len++; + + // get the values + if (!dat->key) dat->key = &buf[i]; // store the key's pointer at this point + else if (!dat->feq) dat->feq = (buf[i] == '='); // otherwise store whether we've found the equal sign + else if (!dat->val) dat->val = &buf[i]; // otherwise store the start of the value pointer + } +} + /* attempts to load the options, returns 1 upon failure */ int load_opts(void) { @@ -21,63 +69,16 @@ int load_opts(void) { FILE* fptr = fopen(path_opts, "r"); 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 + struct proc_buf_dat dat = {0}; // 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 while (fgets(buf, BUF_SIZE, fptr)) { - // reset if EOL has been reached - if (eol) { - key_len = 0; - val_len = 0; - key = NULL; - val = NULL; - feq = false; - eol = false; - nodat = false; - } - - // loop through each character - for (unsigned i = 0; i < BUF_SIZE; i++) { - // check EOL / EOF indicators (or just end of string) (CRLF vs LF doesn't matter here, since both end with \n) - if (buf[i] == '\n' || buf[i] == '\0') { - eol = true; - 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; - } - - // increment the key/value length if set - if (val) val_len++; // first check if value is set, as it is set last - else if (key) key_len++; - - // get the values - if (!key) key = &buf[i]; // store the key's pointer at this point - else if (!feq) feq = (buf[i] == '='); // otherwise store whether we've found the equal sign - else if (!val) val = &buf[i]; // otherwise store the start of the value pointer - else { } - } + // process the data in the current buffer + proc_buf(buf, &dat); // 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 (!dat.key || !dat.val) continue; // TODO: load opts from the file // the options shall be loaded as key-value-pairs // lines starting with # are seen as comments