diff options
Diffstat (limited to '')
-rw-r--r-- | src/mds-kbdc/parsed.c | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/src/mds-kbdc/parsed.c b/src/mds-kbdc/parsed.c new file mode 100644 index 0000000..e7d821b --- /dev/null +++ b/src/mds-kbdc/parsed.c @@ -0,0 +1,121 @@ +/** + * 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 "parsed.h" + +#include <stdlib.h> +#include <string.h> + + + +/** + * Initialise a `mds_kbdc_parsed_t*` + * + * @param this The `mds_kbdc_parsed_t*` + */ +void mds_kbdc_parsed_initialise(mds_kbdc_parsed_t* restrict this) +{ + memset(this, 0, sizeof(mds_kbdc_parsed_t)); +} + + +/** + * Release all resources allocated in a `mds_kbdc_parsed_t*` + * + * @param this The `mds_kbdc_parsed_t*` + */ +void mds_kbdc_parsed_destroy(mds_kbdc_parsed_t* restrict this) +{ + mds_kbdc_tree_free(this->tree); + mds_kbdc_source_code_destroy(this->source_code); + free(this->pathname); + mds_kbdc_parse_error_free_all(this->errors); + memset(this, 0, sizeof(mds_kbdc_parsed_t)); +} + + +/** + * Print all encountered errors + * + * @param this The parsing result + * @param output The output file + */ +void mds_kbdc_parsed_print_errors(mds_kbdc_parsed_t* restrict this, FILE* output) +{ + mds_kbdc_parse_error_t** errors = this->errors; + while (*errors) + mds_kbdc_parse_error_print(*errors++, output); +} + + +/** + * Add a new error to the list + * + * @param this The parsing result + * @param severity A `MDS_KBDC_PARSE_ERROR_*` to indicate severity + * @param error_is_in_file Whether the error is in the layout code + * @param line The line where the error occurred, zero-based + * @param start The byte where the error started, on the line, inclusive, zero-based + * @param end The byte where the error ended, on the line, exclusive, zero-based + * @return The new error on success, `NULL` on error + */ +mds_kbdc_parse_error_t* mds_kbdc_parsed_new_error(mds_kbdc_parsed_t* restrict this, int severity, + int error_is_in_file, size_t line, size_t start, size_t end) +{ + mds_kbdc_parse_error_t* error = NULL; + int saved_errno, old_errors_ptr = this->errors_ptr; + + if (this->errors_ptr + 1 >= this->errors_size) + { + size_t new_errors_size = this->errors_size ? (this->errors_size << 1) : 2; + mds_kbdc_parse_error_t** new_errors = this->errors; + + fail_if (xrealloc(new_errors, new_errors_size, mds_kbdc_parse_error_t*)); + this->errors = new_errors; + this->errors_size = new_errors_size; + } + + fail_if (xcalloc(error, 1, mds_kbdc_parse_error_t)); + this->errors[this->errors_ptr + 0] = error; + this->errors[this->errors_ptr + 1] = NULL; + this->errors_ptr++; + + error->severity = severity; + if (this->severest_error_level < severity) + this->severest_error_level = severity; + + fail_if ((error->pathname = strdup(this->pathname)) == NULL); + + if ((error->error_is_in_file = error_is_in_file)) + { + error->line = line; + error->start = start; + error->end = end; + error->code = strdup(this->source_code.real_lines[line]); + fail_if (error->code == NULL); + } + + return error; + pfail: + saved_errno = errno; + free(error); + this->errors_ptr = old_errors_ptr; + this->errors[this->errors_ptr] = NULL; + errno = saved_errno; + return NULL; +} + |