diff options
author | Mattias Andrée <maandree@operamail.com> | 2014-11-09 20:48:31 +0100 |
---|---|---|
committer | Mattias Andrée <maandree@operamail.com> | 2014-11-09 20:48:31 +0100 |
commit | 6afd09f080f3f4501f04d3f9fbfc55768be3b675 (patch) | |
tree | 9c56068b45839cf3a80c05e45251e12876a93735 /src/mds-kbdc/parse-error.c | |
parent | whitespace (diff) | |
download | mds-6afd09f080f3f4501f04d3f9fbfc55768be3b675.tar.gz mds-6afd09f080f3f4501f04d3f9fbfc55768be3b675.tar.bz2 mds-6afd09f080f3f4501f04d3f9fbfc55768be3b675.tar.xz |
working on tree parsing
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to 'src/mds-kbdc/parse-error.c')
-rw-r--r-- | src/mds-kbdc/parse-error.c | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/src/mds-kbdc/parse-error.c b/src/mds-kbdc/parse-error.c new file mode 100644 index 0000000..c16b9f4 --- /dev/null +++ b/src/mds-kbdc/parse-error.c @@ -0,0 +1,160 @@ +/** + * mds — A micro-display server + * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include "parse-error.h" + +#include <stdlib.h> +#include <alloca.h> +#include <string.h> + + + +/** + * Print information about a parsing error + * + * @param this The error structure + * @param output The output file + */ +void mds_kbdc_parse_error_print(const mds_kbdc_parse_error_t* restrict this, FILE* restrict output) +{ + size_t i, n, start = 0, end = 0; + ssize_t m; + const char* restrict code = this->code; + char* desc; + char* dend = this->description + strlen(this->description); + char* dstart; + char* dptr; + char* p; + char* q; + + /* Count the number points in the description we should modify to format it. */ + for (p = this->description, n = 0;;) + { + if (q = strstr(p, "‘"), q == NULL) q = dend; + if (p = strstr(p, "’"), p == NULL) p = dend; + if (q < p) p = q; + if (*p++) n++; + else break; + } + + /* Allocate string for the formatted description. */ + n = 1 + strlen(this->description) + strlen("\033[xxm’") * n; + dptr = desc = alloca(n * sizeof(char)); + + /* Format description. */ + for (p = this->description;;) + { + dstart = p; + if (q = strstr(p, "‘"), q == NULL) q = dend; + if (p = strstr(p, "’"), p == NULL) p = dend; + if (q < p) p = q; + if ((n = (size_t)(p - dstart))) + memcpy(dptr, dstart, n), dptr += n; + if (p == dend) + break; + if (strstr(p, "‘") == p) sprintf(dptr, "\033[01m‘%zn", &m), dptr += (size_t)m, p += strlen("‘"); + else sprintf(dptr, "’\033[21m%zn", &m), dptr += (size_t)m, p += strlen("’"); + } + *dptr = '\0'; + + /* Convert bytes count to character count for the code position */ + for (i = 0, n = this->start; i < n; i++) + start++; + for (n = this->end; i < n; i++) + if ((code[i] & 0xC0) != 0x80) + end++; + end += start; + + /* Print error information. */ + fprintf(output, "\033[01m%s\033[21m:", this->pathname); /* TODO should be relative to the current dir */ + if (this->error_is_in_file) + fprintf(output, "%zu:%zu–%zu:", this->line + 1, start + 1, end + 1); + switch (this->severity) + { + case MDS_KBDC_PARSE_ERROR_NOTE: fprintf(output, " \033[01;36mnote:\033[00m "); break; + case MDS_KBDC_PARSE_ERROR_WARNING: fprintf(output, " \033[01;35mwarning:\033[00m "); break; + case MDS_KBDC_PARSE_ERROR_ERROR: fprintf(output, " \033[01;31merror:\033[00m "); break; + case MDS_KBDC_PARSE_ERROR_INTERNAL_ERROR: fprintf(output, " \033[01;31minternal error:\033[00m "); break; + default: + abort(); + break; + } + fprintf(output, "%s\n %s\n \033[01;32m", desc, code); + i = 0; + for (n = start; i < n; i++) fputc(' ', output); + for (n = end; i < n; i++) fputc('^', output); + fprintf(output, "\033[00m\n"); +} + + + +/** + * Release all resources allocated in a `mds_kbdc_parse_error_t*` + * + * @param this The error structure + */ +void mds_kbdc_parse_error_destroy(mds_kbdc_parse_error_t* restrict this) +{ + if (this == NULL) + return; + free(this->pathname), this->pathname = NULL; + free(this->code), this->code = NULL; + free(this->description), this->description = NULL; +} + + +/** + * Release all resources allocated in a `mds_kbdc_parse_error_t*` + * and release the allocation of the structure itself + * + * @param this The error structure + */ +void mds_kbdc_parse_error_free(mds_kbdc_parse_error_t* restrict this) +{ + mds_kbdc_parse_error_destroy(this); + free(this); +} + + +/** + * Release all resources allocated in a `NULL`-terminated group + * of `mds_kbdc_parse_error_t*`:s + * + * @param this The group of error structures + */ +void mds_kbdc_parse_error_destroy_all(mds_kbdc_parse_error_t** restrict these) +{ + mds_kbdc_parse_error_t* restrict that; + if (these == NULL) + return; + while (that = *these, that != NULL) + mds_kbdc_parse_error_free(that), *these++ = NULL; +} + + +/** + * Release all resources allocated in a `NULL`-terminated group of + * `mds_kbdc_parse_error_t*`:s and release the allocation of the group itself + * + * @param this The group of error structures + */ +void mds_kbdc_parse_error_free_all(mds_kbdc_parse_error_t** restrict these) +{ + mds_kbdc_parse_error_destroy_all(these); + free(these); +} + |