|
|
d36645 |
/*******************************************************************/
|
|
|
d36645 |
/* slibtool: a skinny libtool implementation, written in C */
|
|
|
49181b |
/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */
|
|
|
d36645 |
/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */
|
|
|
d36645 |
/*******************************************************************/
|
|
|
d36645 |
|
|
|
d36645 |
#include <stdio.h>
|
|
|
d36645 |
#include <string.h>
|
|
|
d36645 |
#include <errno.h>
|
|
|
5fd707 |
#include <unistd.h>
|
|
|
d36645 |
#include <slibtool/slibtool.h>
|
|
|
d36645 |
|
|
|
a82cc2 |
#include "slibtool_driver_impl.h"
|
|
|
a82cc2 |
#include "slibtool_dprintf_impl.h"
|
|
|
a82cc2 |
|
|
|
d36645 |
static const char aclr_reset[] = "\x1b[0m";
|
|
|
d36645 |
static const char aclr_bold[] = "\x1b[1m";
|
|
|
d36645 |
|
|
|
d36645 |
static const char aclr_green[] = "\x1b[32m";
|
|
|
d36645 |
static const char aclr_blue[] = "\x1b[34m";
|
|
|
d36645 |
static const char aclr_magenta[] = "\x1b[35m";
|
|
|
d36645 |
|
|
|
d36645 |
static const char * slbt_output_error_header(const struct slbt_error_info * erri)
|
|
|
d36645 |
{
|
|
|
cacd3e |
if (erri->eflags & SLBT_ERROR_CHILD)
|
|
|
d36645 |
return "exec error upon";
|
|
|
d36645 |
|
|
|
cacd3e |
else if (erri->eflags & SLBT_ERROR_TOP_LEVEL)
|
|
|
d36645 |
return "error logged in";
|
|
|
d36645 |
|
|
|
cacd3e |
else if (erri->eflags & SLBT_ERROR_NESTED)
|
|
|
d36645 |
return "< returned to >";
|
|
|
d36645 |
|
|
|
d36645 |
else
|
|
|
d36645 |
return "distorted state";
|
|
|
d36645 |
}
|
|
|
d36645 |
|
|
|
009664 |
static const char * slbt_output_strerror(
|
|
|
009664 |
const struct slbt_error_info * erri,
|
|
|
009664 |
char (*errbuf)[256])
|
|
|
d36645 |
{
|
|
|
cacd3e |
if (erri->eflags & SLBT_ERROR_CUSTOM)
|
|
|
53b79c |
return "flow error: unexpected condition or other";
|
|
|
d36645 |
|
|
|
cacd3e |
else if (erri->eflags & SLBT_ERROR_NESTED)
|
|
|
d36645 |
return "";
|
|
|
d36645 |
|
|
|
cacd3e |
else if (erri->eflags & SLBT_ERROR_CHILD)
|
|
|
d36645 |
return "(see child process error messages)";
|
|
|
d36645 |
|
|
|
cacd3e |
else if (erri->esyscode == ENOBUFS)
|
|
|
2191ff |
return "input error: string length exceeds buffer size";
|
|
|
d36645 |
|
|
|
5c84b6 |
else if ((erri->esyscode == ENOENT) && erri->eany)
|
|
|
5c84b6 |
return "path not found: ";
|
|
|
5c84b6 |
|
|
|
d36645 |
else
|
|
|
009664 |
return strerror_r(erri->esyscode,*errbuf,sizeof(*errbuf))
|
|
|
009664 |
? "internal error: strerror_r(3) call failed"
|
|
|
009664 |
: *errbuf;
|
|
|
d36645 |
}
|
|
|
d36645 |
|
|
|
d36645 |
static int slbt_output_error_record_plain(
|
|
|
d36645 |
const struct slbt_driver_ctx * dctx,
|
|
|
d36645 |
const struct slbt_error_info * erri)
|
|
|
d36645 |
{
|
|
|
009664 |
char errbuf[256];
|
|
|
633308 |
|
|
|
633308 |
int fderr = slbt_driver_fderr(dctx);
|
|
|
009664 |
const char * errdesc = slbt_output_strerror(erri,&errbuf);
|
|
|
5c84b6 |
const char * path;
|
|
|
5c84b6 |
|
|
|
5c84b6 |
path = ((erri->esyscode == ENOENT) && erri->eany)
|
|
|
5c84b6 |
? erri->eany : "";
|
|
|
d36645 |
|
|
|
633308 |
if (slbt_dprintf(
|
|
|
633308 |
fderr,
|
|
|
5c84b6 |
"%s: %s %s(), line %d%s%s%s.\n",
|
|
|
d36645 |
dctx->program,
|
|
|
d36645 |
slbt_output_error_header(erri),
|
|
|
cacd3e |
erri->efunction,
|
|
|
cacd3e |
erri->eline,
|
|
|
d36645 |
strlen(errdesc) ? ": " : "",
|
|
|
5c84b6 |
errdesc,path) < 0)
|
|
|
d36645 |
return -1;
|
|
|
d36645 |
|
|
|
a82cc2 |
return 0;
|
|
|
d36645 |
}
|
|
|
d36645 |
|
|
|
d36645 |
static int slbt_output_error_record_annotated(
|
|
|
d36645 |
const struct slbt_driver_ctx * dctx,
|
|
|
d36645 |
const struct slbt_error_info * erri)
|
|
|
d36645 |
{
|
|
|
009664 |
char errbuf[256];
|
|
|
633308 |
|
|
|
633308 |
int fderr = slbt_driver_fderr(dctx);
|
|
|
009664 |
const char * errdesc = slbt_output_strerror(erri,&errbuf);
|
|
|
5c84b6 |
const char * path;
|
|
|
5c84b6 |
|
|
|
5c84b6 |
path = ((erri->esyscode == ENOENT) && erri->eany)
|
|
|
5c84b6 |
? erri->eany : "";
|
|
|
d36645 |
|
|
|
a82cc2 |
if (slbt_dprintf(
|
|
|
633308 |
fderr,
|
|
|
5c84b6 |
"%s%s%s:%s %s%s%s %s%s%s()%s, %s%sline %d%s%s%s%s%s%s%s%s%s.\n",
|
|
|
d36645 |
|
|
|
d36645 |
aclr_bold,aclr_magenta,
|
|
|
d36645 |
dctx->program,
|
|
|
d36645 |
aclr_reset,
|
|
|
d36645 |
|
|
|
d36645 |
aclr_bold,
|
|
|
d36645 |
slbt_output_error_header(erri),
|
|
|
d36645 |
aclr_reset,
|
|
|
d36645 |
|
|
|
d36645 |
aclr_bold,aclr_blue,
|
|
|
cacd3e |
erri->efunction,
|
|
|
d36645 |
aclr_reset,
|
|
|
d36645 |
|
|
|
d36645 |
aclr_bold,aclr_green,
|
|
|
cacd3e |
erri->eline,
|
|
|
d36645 |
aclr_reset,
|
|
|
d36645 |
strlen(errdesc) ? ": " : "",
|
|
|
d36645 |
|
|
|
d36645 |
aclr_bold,
|
|
|
009664 |
errdesc,
|
|
|
5c84b6 |
aclr_reset,
|
|
|
5c84b6 |
|
|
|
5c84b6 |
aclr_bold,aclr_blue,
|
|
|
5c84b6 |
path,
|
|
|
d36645 |
aclr_reset) < 0)
|
|
|
d36645 |
return -1;
|
|
|
d36645 |
|
|
|
a82cc2 |
return 0;
|
|
|
d36645 |
}
|
|
|
d36645 |
|
|
|
d36645 |
int slbt_output_error_record(
|
|
|
d36645 |
const struct slbt_driver_ctx * dctx,
|
|
|
d36645 |
const struct slbt_error_info * erri)
|
|
|
d36645 |
{
|
|
|
a82cc2 |
int fderr = slbt_driver_fderr(dctx);
|
|
|
a82cc2 |
|
|
|
d36645 |
if (dctx->cctx->drvflags & SLBT_DRIVER_ANNOTATE_NEVER)
|
|
|
d36645 |
return slbt_output_error_record_plain(dctx,erri);
|
|
|
d36645 |
|
|
|
d36645 |
else if (dctx->cctx->drvflags & SLBT_DRIVER_ANNOTATE_ALWAYS)
|
|
|
d36645 |
return slbt_output_error_record_annotated(dctx,erri);
|
|
|
d36645 |
|
|
|
a82cc2 |
else if (isatty(fderr))
|
|
|
d36645 |
return slbt_output_error_record_annotated(dctx,erri);
|
|
|
d36645 |
|
|
|
d36645 |
else
|
|
|
d36645 |
return slbt_output_error_record_plain(dctx,erri);
|
|
|
d36645 |
}
|
|
|
d36645 |
|
|
|
d36645 |
static int slbt_output_error_vector_plain(const struct slbt_driver_ctx * dctx)
|
|
|
d36645 |
{
|
|
|
d36645 |
struct slbt_error_info ** perr;
|
|
|
d36645 |
|
|
|
d36645 |
for (perr=dctx->errv; *perr; perr++)
|
|
|
d36645 |
if (slbt_output_error_record_plain(dctx,*perr))
|
|
|
d36645 |
return -1;
|
|
|
d36645 |
|
|
|
d36645 |
return 0;
|
|
|
d36645 |
}
|
|
|
d36645 |
|
|
|
d36645 |
static int slbt_output_error_vector_annotated(const struct slbt_driver_ctx * dctx)
|
|
|
d36645 |
{
|
|
|
d36645 |
struct slbt_error_info ** perr;
|
|
|
d36645 |
|
|
|
d36645 |
for (perr=dctx->errv; *perr; perr++)
|
|
|
d36645 |
if (slbt_output_error_record_annotated(dctx,*perr))
|
|
|
d36645 |
return -1;
|
|
|
d36645 |
|
|
|
d36645 |
return 0;
|
|
|
d36645 |
}
|
|
|
d36645 |
|
|
|
d36645 |
int slbt_output_error_vector(const struct slbt_driver_ctx * dctx)
|
|
|
d36645 |
{
|
|
|
a82cc2 |
int fderr = slbt_driver_fderr(dctx);
|
|
|
a82cc2 |
|
|
|
d36645 |
if (dctx->cctx->drvflags & SLBT_DRIVER_ANNOTATE_NEVER)
|
|
|
d36645 |
return slbt_output_error_vector_plain(dctx);
|
|
|
d36645 |
|
|
|
d36645 |
else if (dctx->cctx->drvflags & SLBT_DRIVER_ANNOTATE_ALWAYS)
|
|
|
d36645 |
return slbt_output_error_vector_annotated(dctx);
|
|
|
d36645 |
|
|
|
a82cc2 |
else if (isatty(fderr))
|
|
|
d36645 |
return slbt_output_error_vector_annotated(dctx);
|
|
|
d36645 |
|
|
|
d36645 |
else
|
|
|
d36645 |
return slbt_output_error_vector_plain(dctx);
|
|
|
d36645 |
}
|