Handle escaped back slashes and missing new lines at end of line by using

fparseln instead of reimplementing it on our own.

with input by and ok nicm@
This commit is contained in:
tobias 2014-06-25 19:17:27 +00:00
parent 54782af616
commit 1aae53596d

64
cfg.c
View File

@ -23,6 +23,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <util.h>
#include "tmux.h" #include "tmux.h"
@ -36,9 +37,10 @@ int
load_cfg(const char *path, struct cmd_q *cmdq, char **cause) load_cfg(const char *path, struct cmd_q *cmdq, char **cause)
{ {
FILE *f; FILE *f;
u_int n, found; char delim[3] = { '\\', '\\', '\0' };
char *buf, *copy, *line, *cause1, *msg; u_int found;
size_t len, oldlen; size_t line = 0;
char *buf, *cause1, *msg, *p;
struct cmd_list *cmdlist; struct cmd_list *cmdlist;
log_debug("loading %s", path); log_debug("loading %s", path);
@ -47,60 +49,30 @@ load_cfg(const char *path, struct cmd_q *cmdq, char **cause)
return (-1); return (-1);
} }
n = found = 0; found = 0;
line = NULL; while ((buf = fparseln(f, NULL, &line, delim, 0))) {
while ((buf = fgetln(f, &len))) { log_debug("%s: %s", path, buf);
/* Trim \n. */
if (buf[len - 1] == '\n')
len--;
log_debug("%s: %.*s", path, (int)len, buf);
/* Current line is the continuation of the previous one. */
if (line != NULL) {
oldlen = strlen(line);
line = xrealloc(line, 1, oldlen + len + 1);
} else {
oldlen = 0;
line = xmalloc(len + 1);
}
/* Append current line to the previous. */
memcpy(line + oldlen, buf, len);
line[oldlen + len] = '\0';
n++;
/* Continuation: get next line? */
len = strlen(line);
if (len > 0 && line[len - 1] == '\\') {
line[len - 1] = '\0';
/* Ignore escaped backslash at EOL. */
if (len > 1 && line[len - 2] != '\\')
continue;
}
copy = line;
line = NULL;
/* Skip empty lines. */ /* Skip empty lines. */
buf = copy; p = buf;
while (isspace((u_char)*buf)) while (isspace((u_char) *p))
buf++; p++;
if (*buf == '\0') { if (*p == '\0') {
free(copy); free(buf);
continue; continue;
} }
/* Parse and run the command. */ /* Parse and run the command. */
if (cmd_string_parse(buf, &cmdlist, path, n, &cause1) != 0) { if (cmd_string_parse(p, &cmdlist, path, line, &cause1) != 0) {
free(copy); free(buf);
if (cause1 == NULL) if (cause1 == NULL)
continue; continue;
xasprintf(&msg, "%s:%u: %s", path, n, cause1); xasprintf(&msg, "%s:%zu: %s", path, line, cause1);
ARRAY_ADD(&cfg_causes, msg); ARRAY_ADD(&cfg_causes, msg);
free(cause1); free(cause1);
continue; continue;
} }
free(copy); free(buf);
if (cmdlist == NULL) if (cmdlist == NULL)
continue; continue;
@ -108,8 +80,6 @@ load_cfg(const char *path, struct cmd_q *cmdq, char **cause)
cmd_list_free(cmdlist); cmd_list_free(cmdlist);
found++; found++;
} }
if (line != NULL)
free(line);
fclose(f); fclose(f);
return (found); return (found);