diff options
author | Rafael G. Martins <rafael@rafaelmartins.eng.br> | 2015-10-24 04:12:43 -0200 |
---|---|---|
committer | Rafael G. Martins <rafael@rafaelmartins.eng.br> | 2015-10-24 04:12:43 -0200 |
commit | 3a5ea19f35e4228cd782d69f21f52656c1e9a1b8 (patch) | |
tree | d587ea7522d51d0d15c63c891a2b4f58e88060a0 /src/error.c | |
parent | b3eb6d3f1cae3449c8f988fe0985c58d1e22a7f8 (diff) | |
download | blogc-3a5ea19f35e4228cd782d69f21f52656c1e9a1b8.tar.gz blogc-3a5ea19f35e4228cd782d69f21f52656c1e9a1b8.tar.bz2 blogc-3a5ea19f35e4228cd782d69f21f52656c1e9a1b8.zip |
error: improved error reporting for parsers
it will now report the line and the approximate position of the error.
Diffstat (limited to 'src/error.c')
-rw-r--r-- | src/error.c | 50 |
1 files changed, 39 insertions, 11 deletions
diff --git a/src/error.c b/src/error.c index ad4e3f4..d3d045d 100644 --- a/src/error.c +++ b/src/error.c @@ -50,26 +50,54 @@ blogc_error_parser(blogc_error_type_t type, const char *src, size_t src_len, char *msg = b_strdup_vprintf(format, ap); va_end(ap); - b_string_t *str = b_string_new(); - while (current < src_len) { - char c = src[current]; - - if (c == '\r' || c == '\n') + size_t lineno = 1; + size_t linestart = 0; + size_t lineend = 0; + size_t pos = 1; + + for (size_t i = 0; i < src_len; i++) { + char c = src[i]; + if (i < current) { + if ((i + 1) < src_len) { + if ((c == '\n' && src[i + 1] == '\r') || + (c == '\r' && src[i + 1] == '\n')) + { + lineno++; + pos = 1; + c = src[++i]; + if ((i + 1) < src_len) + linestart = i + 1; + continue; + } + } + if (c == '\n' || c == '\r') { + lineno++; + pos = 1; + if ((i + 1) < src_len) + linestart = i + 1; + continue; + } + pos++; + } + else if (c == '\n' || c == '\r') { + lineend = i; break; + } + } - b_string_append_c(str, c); + if (lineend <= linestart && src_len >= linestart) + lineend = src_len; - current++; - } - char *line = b_string_free(str, false); + char *line = b_strndup(src + linestart, lineend - linestart); blogc_error_t *rv = NULL; - if (strlen(line) == 0) // "near to" message isn't useful if line is empty + if (line[0] == '\0') // "near" message isn't useful if line is empty rv = blogc_error_new(type, msg); else rv = blogc_error_new_printf(type, - "%s\nError occurred near to '%s'", msg, line); + "%s\nError occurred near line %d, position %d: %s", msg, lineno, + pos, line); free(msg); free(line); |