/* 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();
}
}