Esempio n. 1
0
/*
 * stc_msg_vformat
 *
 * The core formatting routine.
 * Do NOT use sprintf-style formatting codes in
 * message strings! Use the formatting directives
 * below:
 * !SL = text with length (char *str, int len)
 * !SZ = null-terminated string (char *azstr)
 * !SD = string descriptor (strdesc_t *sdsc)
 * !U{I,S,L} = unsigned int, short, long
 * !I{I,S,L} = signed int, short, long
 * !X{I,S,L} = hexadecimal int, short, long
 * !P = pointer
 * !! = exclamation point
 */
int
stc_msg_vformat (statcode_t statcode, char *buf, size_t bufsiz, va_list ap)
{
    int len;
    char tmpbuf[32];
    char *outp;
    const char *fmt;
    unsigned int msgno = stc_msgno(statcode);
    unsigned int sev = stc_severity(statcode);

    if (msgno >= MSG_COUNT) {
        return snprintf(buf, bufsiz, "%%BLISS-%c-UNKNOWN: unknown message code %u",
                       sevchars[sev], msgno);
    }

    len = snprintf(buf, bufsiz, "%%BLISS-%c-%s, ", sevchars[sev], mcnames[msgno]);
    if (len >= bufsiz) len = (int) bufsiz - 1;
    outp = buf + len;
    bufsiz -= len;

    fmt = mctext[msgno];

    while (bufsiz > 0 && *fmt != '\0') {
        if (*fmt != '!') {
            *outp++ = *fmt++;
            bufsiz -= 1;
            continue;
        }
        fmt += 1;
        if (*fmt == '\0') break;
        if (*fmt == '!') {
            *outp++ = *fmt++;
            bufsiz -= 1;
            continue;
        }
        if (*fmt == 'U' || *fmt == 'X') {
            unsigned long val;
            if (*(fmt+1) == 'L') {
                val = va_arg(ap, unsigned long);
            } else if (*(fmt+1) == 'S' || *(fmt+1) == 'I') {
Esempio n. 2
0
/*
 * log_vsignal
 *
 * Core logging function.  Formats the diagnostic message and text
 * position (if possible), emits the message on stderr, and handles
 * the next step - incrementing the appropriate diagnostic counter
 * and possibly aborting.
 */
void
log_vsignal (logctx_t ctx, textpos_t pos, statcode_t code, va_list ap)
{
    char logbuf[256];
    int len;
    unsigned int sev = stc_severity(code);

    if (sev == STC_K_FATAL) {
        ctx->logtoterm = 1;
    }

    if (ctx->listprintfn != 0 || ctx->logtoterm) {
        int fileno = textpos_fileno(pos);
        unsigned int lineno = textpos_lineno(pos);
        unsigned int colno  = textpos_colnum(pos);
        if (ctx->linefetchfn != 0) {
            strdesc_t *curline = (*ctx->linefetchfn)(ctx->lfctx, fileno, lineno);
            if (curline != 0) {
                doprintsrc(ctx, curline->ptr, curline->len);
                if (curline->len < sizeof(logbuf) && colno < curline->len) {
                    memset(logbuf, '.', colno);
                    logbuf[colno] = '|';
                    doprint(ctx, logbuf, colno+1, !ctx->logsrctolst);
                }
            }
        }
        len = stc_msg_vformat(code, logbuf, sizeof(logbuf)-1, ap);
        doprint(ctx, logbuf, len, 0);
        if (pos != 0 && ctx->fetchfn != 0) {
            strdesc_t *fname = ctx->fetchfn(ctx->ffctx, fileno);
            if (fname != 0)  {
                len = snprintf(logbuf, sizeof(logbuf)-1, "-  at %-*.*s:%u:%u",
                               fname->len, fname->len, fname->ptr, lineno, colno+1);
                if (len > 0) doprint(ctx, logbuf, len, 0);
            }
        }
    }
    switch (sev) {
        case STC_K_ERROR:
            ctx->errcount += 1;
            if (ctx->errcount < ctx->maxerrs) break;
            // Force this error message to the terminal
            ctx->logtoterm = 1;
            len = snprintf(logbuf, sizeof(logbuf)-1, "%%BLISS-F-TOOMANYERRS, "
                           "maximum number of errors exceeded, aborting");
            if (len > 0) doprint(ctx, logbuf, len, 0);
            // FALLTHROUGH
        case STC_K_FATAL:
            fflush(stderr);
            longjmp(ctx->retenv, 1);
            break;
        case STC_K_WARN:
            ctx->warncount += 1;
            break;
        case STC_K_INFO:
            ctx->infocount += 1;
            break;
        default:
            break;
    }

} /* log_vsignal */