diff options
Diffstat (limited to 'src')
| -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);  | 
