123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- /* This file is part of nit.
- *
- * Nit is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Nit 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with nit. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <errno.h>
- #include <stdio.h>
- #include <string.h>
- #include "err.h"
- static void
- reset(Err *err)
- {
- err->print_under = err->print_where = err->print_what =
- err->print_line = err->print_pos = err->occured = 0;
- }
- static void
- err_print(Err *err)
- {
- char buf[256];
- int space = err->print_where || err->print_line || err->print_pos;
- if (!err->occured) {
- fprintf(stderr, "No error has occured\n");
- return;
- }
- if (err->print_under) {
- /* It is useless to print this to stderr */
- for (unsigned i = 0; i < err->under; ++i)
- printf(" ");
- printf("^\n");
- }
- if (err->print_where) {
- if (err->where)
- fprintf(stderr, "%s:", err->where);
- else
- fprintf(stderr, "(Failed to allocate "
- "failure location string):");
- }
- if (err->print_line)
- fprintf(stderr, "%zu:", err->line);
- if (err->print_pos)
- fprintf(stderr, "%zu:", err->pos);
- if (space)
- fprintf(stderr, " ");
- if (err->custom) {
- fprintf(stderr, "%s", err->custom);
- } else {
- strerror_r(err->errnum, buf, sizeof(buf));
- fprintf(stderr, "%s", buf);
- }
- if (err->print_what) {
- if (err->what)
- fprintf(stderr, ": %s", err->what);
- else
- fprintf(stderr, ": (Failed to allocate "
- "failure content string)");
- }
- fprintf(stderr, "\n");
- }
- void
- err_init(Err *err, Err_log log)
- {
- err->where = err->what = NULL;
- err->where_len = err->what_len = 0;
- err->occured = 0;
- err->log = log ? log : err_print;
- }
- void
- err_dispose(Err *err)
- {
- free(err->where);
- free(err->what);
- }
- void
- err_std(Err *err)
- {
- reset(err);
- err->custom = NULL;
- err->errnum = errno;
- err->occured = 1;
- }
- void
- err_nit(Err *err, Nit_error error)
- {
- static const char *str_tbl[] = {
- [NIT_ERROR_FINE] = "No error",
- [NIT_ERROR_MEMORY] = "Ran out of memory",
- [NIT_ERROR_EMPTY] = "Data structure empty",
- [NIT_ERROR_NO_NEXT] = "Missing next value",
- [NIT_ERROR_ALREADY] = "Value already exists",
- [NIT_ERROR_NOT_FOUND] = "Value not found",
- [NIT_ERROR_NOT_DOABLE] = "Action is not doable",
- [NIT_ERROR_NOT_UNDOABLE] = "Action is not undoable",
- [NIT_ERROR_NOT_DIFF] = "Action cannot be done differently",
- [NIT_ERROR_FAILED] = "Failed to do action",
- [NIT_ERROR_ROI] = "Real action cannot be done on imaginary "
- "branch",
- [NIT_ERROR_REDO_PAST] = "Past cannot be redone for real"
- };
- err_cust(err, str_tbl[error]);
- }
- void
- err_cust(Err *err, const char *msg)
- {
- reset(err);
- err->custom = msg;
- err->occured = 1;
- }
- void
- err_under(Err *err, size_t under)
- {
- err->print_under = 1;
- err->under = under;
- }
- int
- err_where(Err *err, const char *where)
- {
- size_t new_len = strlen(where) + 1;
- size_t total_len = new_len;
- size_t old_len = 0;
- char *tmp;
- if (err->print_where)
- total_len += (old_len = strlen(err->where) + 1);
- if (total_len > err->where_len) {
- if (!(tmp = realloc(err->where, total_len))) {
- err->where_len = 0;
- free(err->where);
- err->where = NULL;
- return -1;
- }
- err->where = tmp;
- err->where_len = total_len;
- }
- memmove(err->where + new_len, err->where, old_len);
- strcpy(err->where, where);
- if (err->print_where)
- err->where[new_len - 1] = ':';
- err->print_where = 1;
- return 0;
- }
- int
- err_what(Err *err, const char *what)
- {
- size_t what_len = strlen(what) + 1;
- char *tmp;
- err->print_what = 1;
- if (what_len > err->what_len) {
- if (!(tmp = realloc(err->what, what_len))) {
- err->what_len = 0;
- free(err->what);
- err->what = NULL;
- return -1;
- }
- err->what = tmp;
- err->what_len = what_len;
- }
- strcpy(err->what, what);
- return 0;
- }
- void
- err_line(Err *err, size_t line)
- {
- err->print_line = 1;
- err->line = line;
- }
- void
- err_pos(Err *err, size_t pos)
- {
- err->print_pos = 1;
- err->pos = pos;
- }
- void
- err_log(Err *err)
- {
- err->log(err);
- }
|