PARSE_OPT_BKSLASH | PARSE_OPT_SHARP, &errptr);
if (err & PARSE_ERR_QUOTE) {
- ha_alert("parsing [%s:%d]: unmatched quote below:\n"
- " %s\n %*s\n", file, linenum, line, (int)(errptr-line+1), "^");
+ size_t newpos = sanitize_for_printing(line, errptr - line, 80);
+
+ ha_alert("parsing [%s:%d]: unmatched quote at position %d:\n"
+ " %s\n %*s\n", file, linenum, (int)(errptr-thisline+1), line, (int)(newpos+1), "^");
err_code |= ERR_ALERT | ERR_FATAL;
fatal++;
goto next_line;
}
if (err & PARSE_ERR_BRACE) {
- ha_alert("parsing [%s:%d]: unmatched brace in environment variable name below:\n"
- " %s\n %*s\n", file, linenum, line, (int)(errptr-line+1), "^");
+ size_t newpos = sanitize_for_printing(line, errptr - line, 80);
+
+ ha_alert("parsing [%s:%d]: unmatched brace in environment variable name at position %d:\n"
+ " %s\n %*s\n", file, linenum, (int)(errptr-thisline+1), line, (int)(newpos+1), "^");
err_code |= ERR_ALERT | ERR_FATAL;
fatal++;
goto next_line;
}
if (err & PARSE_ERR_VARNAME) {
- ha_alert("parsing [%s:%d]: forbidden first char in environment variable name below:\n"
- " %s\n %*s\n", file, linenum, line, (int)(errptr-line+1), "^");
+ size_t newpos = sanitize_for_printing(line, errptr - line, 80);
+
+ ha_alert("parsing [%s:%d]: forbidden first char in environment variable name at position %d:\n"
+ " %s\n %*s\n", file, linenum, (int)(errptr-thisline+1), line, (int)(newpos+1), "^");
err_code |= ERR_ALERT | ERR_FATAL;
fatal++;
goto next_line;
}
if (err & PARSE_ERR_HEX) {
- ha_alert("parsing [%s:%d]: truncated or invalid hexadecimal sequence below:\n"
- " %s\n %*s\n", file, linenum, line, (int)(errptr-line+1), "^");
+ size_t newpos = sanitize_for_printing(line, errptr - line, 80);
+
+ ha_alert("parsing [%s:%d]: truncated or invalid hexadecimal sequence at position %d:\n"
+ " %s\n %*s\n", file, linenum, (int)(errptr-thisline+1), line, (int)(newpos+1), "^");
err_code |= ERR_ALERT | ERR_FATAL;
fatal++;
goto next_line;
}
#undef EMIT_CHAR
+/* This is used to sanitize an input line that's about to be used for error reporting.
+ * It will adjust <line> to print approximately <width> chars around <pos>, trying to
+ * preserve the beginning, with leading or trailing "..." when the line is truncated.
+ * If non-printable chars are present in the output. It returns the new offset <pos>
+ * in the modified line. Non-printable characters are replaced with '?'. <width> must
+ * be at least 6 to support two "..." otherwise the result is undefined. The line
+ * itself must have at least 7 chars allocated for the same reason.
+ */
+size_t sanitize_for_printing(char *line, size_t pos, size_t width)
+{
+ size_t shift = 0;
+ char *out = line;
+ char *in = line;
+ char *end = line + width;
+
+ if (pos >= width) {
+ /* if we have to shift, we'll be out of context, so let's
+ * try to put <pos> at the center of width.
+ */
+ shift = pos - width / 2;
+ in += shift + 3;
+ end = out + width - 3;
+ out[0] = out[1] = out[2] = '.';
+ out += 3;
+ }
+
+ while (out < end && *in) {
+ if (isspace((unsigned char)*in))
+ *out++ = ' ';
+ else if (isprint((unsigned char)*in))
+ *out++ = *in;
+ else
+ *out++ = '?';
+ in++;
+ }
+
+ if (end < line + width) {
+ out[0] = out[1] = out[2] = '.';
+ out += 3;
+ }
+
+ *out++ = 0;
+ return pos - shift;
+}
+
/*
* Local variables:
* c-indent-level: 8