/*
 * Error and warning reporting and related functions.
 *
 *  Copyright (C) 2001-2007  Peter Johnson
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#include "util.h"
/*@unused@*/ RCSID("$Id$");

#include <ctype.h>
#include <stdarg.h>

#include "coretype.h"

#include "linemap.h"
#include "errwarn.h"


#define MSG_MAXSIZE     1024

/* Default handlers for replacable functions */
static /*@exits@*/ void def_internal_error_
    (const char *file, unsigned int line, const char *message);
static /*@exits@*/ void def_fatal(const char *message, va_list va);
static const char *def_gettext_hook(const char *msgid);

/* Storage for errwarn's "extern" functions */
/*@exits@*/ void (*yasm_internal_error_)
    (const char *file, unsigned int line, const char *message)
    = def_internal_error_;
/*@exits@*/ void (*yasm_fatal) (const char *message, va_list va) = def_fatal;
const char * (*yasm_gettext_hook) (const char *msgid) = def_gettext_hook;

/* Error indicator */
/* yasm_eclass is not static so that yasm_error_occurred macro can access it */
yasm_error_class yasm_eclass;
static /*@only@*/ /*@null@*/ char *yasm_estr;
static unsigned long yasm_exrefline;
static /*@only@*/ /*@null@*/ char *yasm_exrefstr;

/* Warning indicator */
typedef struct warn {
    /*@reldef@*/ STAILQ_ENTRY(warn) link;

    yasm_warn_class wclass;
    /*@owned@*/ /*@null@*/ char *wstr;
} warn;
static STAILQ_HEAD(, warn) yasm_warns;

/* Enabled warnings.  See errwarn.h for a list. */
static unsigned long warn_class_enabled;

typedef struct errwarn_data {
    /*@reldef@*/ SLIST_ENTRY(errwarn_data) link;

    enum { WE_UNKNOWN, WE_ERROR, WE_WARNING, WE_PARSERERROR } type;

    unsigned long line;
    unsigned long xrefline;
    /*@owned@*/ char *msg;
    /*@owned@*/ char *xrefmsg;
} errwarn_data;

struct yasm_errwarns {
    /*@reldef@*/ SLIST_HEAD(, errwarn_data) errwarns;

    /* Total error count */
    unsigned int ecount;

    /* Total warning count */
    unsigned int wcount;

    /* Last inserted error/warning.  Used to speed up insertions. */
    /*@null@*/ errwarn_data *previous_we;
};

/* Static buffer for use by conv_unprint(). */
static char unprint[5];


static const char *
def_gettext_hook(const char *msgid)
{
    return msgid;
}

void
yasm_errwarn_initialize(void)
{
    /* Default enabled warnings.  See errwarn.h for a list. */
    warn_class_enabled = 
        (1UL<<YASM_WARN_GENERAL) | (1UL<<YASM_WARN_UNREC_CHAR) |
        (1UL<<YASM_WARN_PREPROC) | (0UL<<YASM_WARN_ORPHAN_LABEL) |
        (1UL<<YASM_WARN_UNINIT_CONTENTS);

    yasm_eclass = YASM_ERROR_NONE;
    yasm_estr = NULL;
    yasm_exrefline = 0;
    yasm_exrefstr = NULL;

    STAILQ_INIT(&yasm_warns);
}

void
yasm_errwarn_cleanup(void)
{
    yasm_error_clear();
    yasm_warn_clear();
}

/* Convert a possibly unprintable character into a printable string, using
 * standard cat(1) convention for unprintable characters.
 */
char *
yasm__conv_unprint(int ch)
{
    int pos = 0;

    if (((ch & ~0x7F) != 0) /*!isascii(ch)*/ && !isprint(ch)) {
        unprint[pos++] = 'M';
        unprint[pos++] = '-';
        ch &= toascii(ch);
    }
    if (iscntrl(ch)) {
        unprint[pos++] = '^';
        unprint[pos++] = (ch == '\177') ? '?' : ch | 0100;
    } else
        unprint[pos++] = ch;
    unprint[pos] = '\0';

    return unprint;
}

/* Report an internal error.  Essentially a fatal error with trace info.
 * Exit immediately because it's essentially an assert() trap.
 */
static void
def_internal_error_(const char *file, unsigned int line, const char *message)
{
    fprintf(stderr,
            yasm_gettext_hook(N_("INTERNAL ERROR at %s, line %u: %s\n")),
            file, line, yasm_gettext_hook(message));
#ifdef HAVE_ABORT
    abort();
#else
    exit(EXIT_FAILURE);
#endif
}

/* Report a fatal error.  These are unrecoverable (such as running out of
 * memory), so just exit immediately.
 */
static void
def_fatal(const char *fmt, va_list va)
{
    fprintf(stderr, "%s: ", yasm_gettext_hook(N_("FATAL")));
    vfprintf(stderr, yasm_gettext_hook(fmt), va);
    fputc('\n', stderr);
    exit(EXIT_FAILURE);
}

/* Create an errwarn structure in the correct linked list location.
 * If replace_parser_error is nonzero, overwrites the last error if its
 * type is WE_PARSERERROR.
 */
static errwarn_data *
errwarn_data_new(yasm_errwarns *errwarns, unsigned long line,
                 int replace_parser_error)
{
    errwarn_data *first, *next, *ins_we, *we;
    enum { INS_NONE, INS_HEAD, INS_AFTER } action = INS_NONE;

    /* Find the entry with either line=line or the last one with line<line.
     * Start with the last entry added to speed the search.
     */
    ins_we = errwarns->previous_we;
    first = SLIST_FIRST(&errwarns->errwarns);
    if (!ins_we || !first)
        action = INS_HEAD;
    while (action == INS_NONE) {
        next = SLIST_NEXT(ins_we, link);
        if (line < ins_we->line) {
            if (ins_we == first)
                action = INS_HEAD;
            else
                ins_we = first;
        } else if (!next)
            action = INS_AFTER;
        else if (line >= ins_we->line && line < next->line)
            action = INS_AFTER;
        else
            ins_we = next;
    }

    if (replace_parser_error && ins_we && ins_we->type == WE_PARSERERROR) {
        /* overwrite last error */      
        we = ins_we;
    } else {
        /* add a new error */
        we = yasm_xmalloc(sizeof(errwarn_data));

        we->type = WE_UNKNOWN;
        we->line = line;
        we->xrefline = 0;
        we->msg = NULL;
        we->xrefmsg = NULL;

        if (action == INS_HEAD)
            SLIST_INSERT_HEAD(&errwarns->errwarns, we, link);
        else if (action == INS_AFTER) {
            assert(ins_we != NULL);
            SLIST_INSERT_AFTER(ins_we, we, link);
        } else
            yasm_internal_error(N_("Unexpected errwarn insert action"));
    }

    /* Remember previous err/warn */
    errwarns->previous_we = we;

    return we;
}

void
yasm_error_clear(void)
{
    if (yasm_estr)
        yasm_xfree(yasm_estr);
    if (yasm_exrefstr)
        yasm_xfree(yasm_exrefstr);
    yasm_eclass = YASM_ERROR_NONE;
    yasm_estr = NULL;
    yasm_exrefline = 0;
    yasm_exrefstr = NULL;
}

int
yasm_error_matches(yasm_error_class eclass)
{
    if (yasm_eclass == YASM_ERROR_NONE)
        return eclass == YASM_ERROR_NONE;
    if (yasm_eclass == YASM_ERROR_GENERAL)
        return eclass == YASM_ERROR_GENERAL;
    return (yasm_eclass & eclass) == eclass;
}

void
yasm_error_set_va(yasm_error_class eclass, const char *format, va_list va)
{
    if (yasm_eclass != YASM_ERROR_NONE)
        return;

    yasm_eclass = eclass;
    yasm_estr = yasm_xmalloc(MSG_MAXSIZE+1);
#ifdef HAVE_VSNPRINTF
    vsnprintf(yasm_estr, MSG_MAXSIZE, yasm_gettext_hook(format), va);
#else
    vsprintf(yasm_estr, yasm_gettext_hook(format), va);
#endif
}

void
yasm_error_set(yasm_error_class eclass, const char *format, ...)
{
    va_list va;
    va_start(va, format);
    yasm_error_set_va(eclass, format, va);
    va_end(va);
}

void
yasm_error_set_xref_va(unsigned long xrefline, const char *format, va_list va)
{
    if (yasm_eclass != YASM_ERROR_NONE)
        return;

    yasm_exrefline = xrefline;

    yasm_exrefstr = yasm_xmalloc(MSG_MAXSIZE+1);
#ifdef HAVE_VSNPRINTF
    vsnprintf(yasm_exrefstr, MSG_MAXSIZE, yasm_gettext_hook(format), va);
#else
    vsprintf(yasm_exrefstr, yasm_gettext_hook(format), va);
#endif
}

void
yasm_error_set_xref(unsigned long xrefline, const char *format, ...)
{
    va_list va;
    va_start(va, format);
    yasm_error_set_xref_va(xrefline, format, va);
    va_end(va);
}

void
yasm_error_fetch(yasm_error_class *eclass, char **str, unsigned long *xrefline,
                 char **xrefstr)
{
    *eclass = yasm_eclass;
    *str = yasm_estr;
    *xrefline = yasm_exrefline;
    *xrefstr = yasm_exrefstr;
    yasm_eclass = YASM_ERROR_NONE;
    yasm_estr = NULL;
    yasm_exrefline = 0;
    yasm_exrefstr = NULL;
}

void yasm_warn_clear(void)
{
    /* Delete all error/warnings */
    while (!STAILQ_EMPTY(&yasm_warns)) {
        warn *w = STAILQ_FIRST(&yasm_warns);

        if (w->wstr)
            yasm_xfree(w->wstr);

        STAILQ_REMOVE_HEAD(&yasm_warns, link);
        yasm_xfree(w);
    }
}

yasm_warn_class
yasm_warn_occurred(void)
{
    if (STAILQ_EMPTY(&yasm_warns))
        return YASM_WARN_NONE;
    return STAILQ_FIRST(&yasm_warns)->wclass;
}

void
yasm_warn_set_va(yasm_warn_class wclass, const char *format, va_list va)
{
    warn *w;

    if (!(warn_class_enabled & (1UL<<wclass)))
        return;     /* warning is part of disabled class */

    w = yasm_xmalloc(sizeof(warn));
    w->wclass = wclass;
    w->wstr = yasm_xmalloc(MSG_MAXSIZE+1);
#ifdef HAVE_VSNPRINTF
    vsnprintf(w->wstr, MSG_MAXSIZE, yasm_gettext_hook(format), va);
#else
    vsprintf(w->wstr, yasm_gettext_hook(format), va);
#endif
    STAILQ_INSERT_TAIL(&yasm_warns, w, link);
}

void
yasm_warn_set(yasm_warn_class wclass, const char *format, ...)
{
    va_list va;
    va_start(va, format);
    yasm_warn_set_va(wclass, format, va);
    va_end(va);
}

void
yasm_warn_fetch(yasm_warn_class *wclass, char **str)
{
    warn *w = STAILQ_FIRST(&yasm_warns);

    if (!w) {
        *wclass = YASM_WARN_NONE;
        *str = NULL;
        return;
    }

    *wclass = w->wclass;
    *str = w->wstr;

    STAILQ_REMOVE_HEAD(&yasm_warns, link);
    yasm_xfree(w);
}

void
yasm_warn_enable(yasm_warn_class num)
{
    warn_class_enabled |= (1UL<<num);
}

void
yasm_warn_disable(yasm_warn_class num)
{
    warn_class_enabled &= ~(1UL<<num);
}

void
yasm_warn_disable_all(void)
{
    warn_class_enabled = 0;
}

yasm_errwarns *
yasm_errwarns_create(void)
{
    yasm_errwarns *errwarns = yasm_xmalloc(sizeof(yasm_errwarns));
    SLIST_INIT(&errwarns->errwarns);
    errwarns->ecount = 0;
    errwarns->wcount = 0;
    errwarns->previous_we = NULL;
    return errwarns;
}

void
yasm_errwarns_destroy(yasm_errwarns *errwarns)
{
    errwarn_data *we;

    /* Delete all error/warnings */
    while (!SLIST_EMPTY(&errwarns->errwarns)) {
        we = SLIST_FIRST(&errwarns->errwarns);
        if (we->msg)
            yasm_xfree(we->msg);
        if (we->xrefmsg)
            yasm_xfree(we->xrefmsg);

        SLIST_REMOVE_HEAD(&errwarns->errwarns, link);
        yasm_xfree(we);
    }

    yasm_xfree(errwarns);
}

void
yasm_errwarn_propagate(yasm_errwarns *errwarns, unsigned long line)
{
    if (yasm_eclass != YASM_ERROR_NONE) {
        errwarn_data *we = errwarn_data_new(errwarns, line, 1);
        yasm_error_class eclass;

        yasm_error_fetch(&eclass, &we->msg, &we->xrefline, &we->xrefmsg);
        if (eclass != YASM_ERROR_GENERAL
            && (eclass & YASM_ERROR_PARSE) == YASM_ERROR_PARSE)
            we->type = WE_PARSERERROR;
        else
            we->type = WE_ERROR;
        errwarns->ecount++;
    }

    while (!STAILQ_EMPTY(&yasm_warns)) {
        errwarn_data *we = errwarn_data_new(errwarns, line, 0);
        yasm_warn_class wclass;

        yasm_warn_fetch(&wclass, &we->msg);
        we->type = WE_WARNING;
        errwarns->wcount++;
    }
}

unsigned int
yasm_errwarns_num_errors(yasm_errwarns *errwarns, int warning_as_error)
{
    if (warning_as_error)
        return errwarns->ecount+errwarns->wcount;
    else
        return errwarns->ecount;
}

void
yasm_errwarns_output_all(yasm_errwarns *errwarns, yasm_linemap *lm,
                         int warning_as_error,
                         yasm_print_error_func print_error,
                         yasm_print_warning_func print_warning)
{
    errwarn_data *we;
    const char *filename, *xref_filename;
    unsigned long line, xref_line;

    /* If we're treating warnings as errors, tell the user about it. */
    if (warning_as_error && warning_as_error != 2) {
        print_error("", 0,
                    yasm_gettext_hook(N_("warnings being treated as errors")),
                    NULL, 0, NULL);
        warning_as_error = 2;
    }

    /* Output error/warnings. */
    SLIST_FOREACH(we, &errwarns->errwarns, link) {
        /* Output error/warning */
        yasm_linemap_lookup(lm, we->line, &filename, &line);
        if (we->xrefline)
            yasm_linemap_lookup(lm, we->xrefline, &xref_filename, &xref_line);
        else {
            xref_filename = NULL;
            xref_line = 0;
        }
        if (we->type == WE_ERROR || we->type == WE_PARSERERROR)
            print_error(filename, line, we->msg, xref_filename, xref_line,
                        we->xrefmsg);
        else
            print_warning(filename, line, we->msg);
    }
}

void
yasm__fatal(const char *message, ...)
{
    va_list va;
    va_start(va, message);
    yasm_fatal(message, va);
    /*@notreached@*/
    va_end(va);
}
