/* See LICENSE file for copyright and license details. */ #include "internal.h" static void print_error(struct liberror_error *error, FILE *fp, char *prefix) { if (*error->description) { if (*error->source) fprintf(fp, "%sError in function %s: %s\n", prefix, error->source, error->description); else fprintf(fp, "%sError: %s\n", prefix, error->description); } else if (*error->source) { fprintf(fp, "%sError in function %s: %s error %lli\n", prefix, error->source, error->code_group, error->code); } else { fprintf(fp, "%sError: %s error %lli\n", prefix, error->code_group, error->code); } *strchr(prefix, '\0') = ' '; switch (error->details_type) { case LIBERROR_DETAILS_USER: if (error->details.user.print_data) error->details.user.print_data(error->details.user.data, fp, prefix); break; case LIBERROR_DETAILS_ONE_FILE: if (error->details.one_file.fd >= 0 || error->details.one_file.name) { fprintf(fp, "%sDetails:\n", prefix); if (error->details.one_file.name) { fprintf(fp, "%s %s name: %s\n", prefix, error->details.one_file.role, error->details.one_file.name); } if (error->details.one_file.fd >= 0) { fprintf(fp, "%s %s descriptor: %i\n", prefix, error->details.one_file.role, error->details.one_file.fd); } } break; case LIBERROR_DETAILS_TWO_FILES: if (error->details.two_files.fd1 >= 0 || error->details.two_files.name1 || error->details.two_files.fd2 >= 0 || error->details.two_files.name2) { fprintf(fp, "%sDetails:\n", prefix); if (error->details.two_files.fd1 >= 0) { fprintf(fp, "%s %s descriptor: %i\n", prefix, error->details.two_files.role1, error->details.two_files.fd1); } if (error->details.two_files.name1) { fprintf(fp, "%s %s name: %s\n", prefix, error->details.two_files.role1, error->details.two_files.name1); } if (error->details.two_files.fd2 >= 0) { fprintf(fp, "%s %s descriptor: %i\n", prefix, error->details.two_files.role2, error->details.two_files.fd2); } if (error->details.two_files.name2) { fprintf(fp, "%s %s name: %s\n", prefix, error->details.two_files.role2, error->details.two_files.name2); } } break; case LIBERROR_DETAILS_NONE: default: break; } liberror_print_backtrace(error, fp, prefix); } void liberror_print_error(struct liberror_error *error, FILE *fp, int reset, const char *prefix_) { struct liberror_error *err = error; char *prefix = (char []){" "}; char *p, *q; if (!err) { err = liberror_get_error(); if (!err) return; } if (prefix_ && *prefix_) { prefix = alloca(strlen(prefix) + sizeof(": ")); stpcpy(q = stpcpy(p = stpcpy(stpcpy(prefix, prefix_), ": "), " "), " "); } else { p = &prefix[0]; q = &prefix[2]; } if (!fp) fp = stderr; *p = *q = '\0'; print_error(err, fp, prefix); while ((err = err->cause)) { *p = *q = '\0'; fprintf(fp, "%sCaused by:\n", prefix); *p = ' '; print_error(err, fp, prefix); } if (reset) { if (error) liberror_free_error(error); else liberror_reset_error(); } }