diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2008-02-12 21:28:57 -0800 |
---|---|---|
committer | Aaron Plattner <aplattner@nvidia.com> | 2008-02-12 21:28:57 -0800 |
commit | a6ae005377764b14959ad09725e90dacb5ddc4e3 (patch) | |
tree | 058931d284a13a11449b668ffc4dc4a93624d518 /src/XF86Config-parser/Scan.c | |
parent | fb518983907cf33ab8ee7e71ef79fe920b6b5a17 (diff) |
1.0-96291.0-9629
Diffstat (limited to 'src/XF86Config-parser/Scan.c')
-rw-r--r-- | src/XF86Config-parser/Scan.c | 123 |
1 files changed, 121 insertions, 2 deletions
diff --git a/src/XF86Config-parser/Scan.c b/src/XF86Config-parser/Scan.c index 4e694ba..ab48af8 100644 --- a/src/XF86Config-parser/Scan.c +++ b/src/XF86Config-parser/Scan.c @@ -177,10 +177,129 @@ static unsigned int xconfigStrToUL (char *str) } +/* + * xconfigGetNextLine -- + * + * read from the configFile FILE stream until we encounter a new + * line; this is effectively just a big wrapper for fgets(3). + * + * xconfigGetToken() assumes that we will read up to the next + * newline; we need to grow configBuf and configRBuf as needed to + * support that. + */ + +static char *xconfigGetNextLine() +{ + static int configBufLen = CONFIG_BUF_LEN; + char *tmpConfigBuf, *tmpConfigRBuf; + int c, i, pos = 0, eolFound = 0; + char *ret = NULL; + + /* + * reallocate the string if it was grown last time (i.e., is no + * longer CONFIG_BUF_LEN); we malloc the new strings first, so + * that if either of the mallocs fail, we can fall back on the + * existing buffer allocations + */ + + if (configBufLen != CONFIG_BUF_LEN) { + + tmpConfigBuf = malloc(CONFIG_BUF_LEN); + tmpConfigRBuf = malloc(CONFIG_BUF_LEN); + + if (!tmpConfigBuf || !tmpConfigRBuf) { + + /* + * at least one of the mallocs failed; keep the old buffers + * and free any partial allocations + */ + + free(tmpConfigBuf); + free(tmpConfigRBuf); + + } else { + + /* + * malloc succeeded; free the old buffers and use the new + * buffers + */ + + configBufLen = CONFIG_BUF_LEN; + + free(configBuf); + free(configRBuf); + + configBuf = tmpConfigBuf; + configRBuf = tmpConfigRBuf; + } + } + + /* read in another block of chars */ + + do { + ret = fgets(configBuf + pos, configBufLen - pos - 1, configFile); + + if (!ret) break; + + /* search for EOL in the new block of chars */ + + for (i = pos; i < (configBufLen - 1); i++) { + c = configBuf[i]; + + if (c == '\0') break; + + if ((c == '\n') || (c == '\r')) { + eolFound = 1; + break; + } + } + + /* + * if we didn't find EOL, then grow the string and + * read in more + */ + + if (!eolFound) { + + tmpConfigBuf = realloc(configBuf, configBufLen + CONFIG_BUF_LEN); + tmpConfigRBuf = realloc(configRBuf, configBufLen + CONFIG_BUF_LEN); + + if (!tmpConfigBuf || !tmpConfigRBuf) { + + /* + * at least one of the reallocations failed; use the + * new allocation that succeeded, but we have to + * fallback to the previous configBufLen size and use + * the string we have, even though we don't have an + * EOL + */ + + if (tmpConfigBuf) configBuf = tmpConfigBuf; + if (tmpConfigRBuf) configRBuf = tmpConfigRBuf; + + break; + + } else { + + /* reallocation succeeded */ + + configBuf = tmpConfigBuf; + configRBuf = tmpConfigRBuf; + pos = i; + configBufLen += CONFIG_BUF_LEN; + } + } + + } while (!eolFound); + + return ret; +} + + /* * xconfigGetToken -- - * Read next Token form the config file. Handle the global variable + * Read next Token from the config file. Handle the global variable * pushToken. */ @@ -214,7 +333,7 @@ again: { char *ret; if (configFile) - ret = fgets (configBuf, CONFIG_BUF_LEN - 1, configFile); + ret = xconfigGetNextLine(); else { if (builtinConfig[builtinIndex] == NULL) ret = NULL; |