/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */




/*

Copyright 1987, 1988 by the Student Information Processing Board
	of the Massachusetts Institute of Technology

Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is
hereby granted, provided that the above copyright notice
appear in all copies and that both that copyright notice and
this permission notice appear in supporting documentation,
and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
M.I.T. and the M.I.T. S.I.P.B. make no representations about
the suitability of this software for any purpose.  It is
provided "as is" without express or implied warranty.

*/

#include <string.h>
#include <assert.h>
#include <errno.h>
#include "prmem.h"
#include "prerror.h"

#define	ERRCODE_RANGE	8	/* # of bits to shift table number */
#define	BITS_PER_CHAR	6	/* # bits to shift per character in name */

#ifdef NEED_SYS_ERRLIST
extern char const * const sys_errlist[];
extern const int sys_nerr;
#endif

/* List of error tables */
struct PRErrorTableList {
    struct PRErrorTableList *next;
    const struct PRErrorTable *table;
    struct PRErrorCallbackTablePrivate *table_private;
};
static struct PRErrorTableList * Table_List = (struct PRErrorTableList *) NULL;

/* Supported languages */
static const char * default_languages[] = { "i-default", "en", 0 };
static const char * const * callback_languages = default_languages;

/* Callback info */
static struct PRErrorCallbackPrivate *callback_private = 0;
static PRErrorCallbackLookupFn *callback_lookup = 0;
static PRErrorCallbackNewTableFn *callback_newtable = 0;


static const char char_set[] =
	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";

static const char *
error_table_name (PRErrorCode num)
{
    static char buf[6];	/* only used if internal code problems exist */

    long ch;
    int i;
    char *p;

    /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
    p = buf;
    num >>= ERRCODE_RANGE;
    /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
    num &= 077777777;
    /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
    for (i = 4; i >= 0; i--) {
	ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1);
	if (ch != 0)
	    *p++ = char_set[ch-1];
    }
    *p = '\0';
    return(buf);
}

PR_IMPLEMENT(const char *)
PR_ErrorToString(PRErrorCode code, PRLanguageCode language)
{
    /* static buffer only used if code is using inconsistent error message
     * numbers, so just ignore the possible thread contention
     */
    static char buffer[25];

    const char *msg;
    int offset;
    PRErrorCode table_num;
    struct PRErrorTableList *et;
    int started = 0;
    char *cp;

    for (et = Table_List; et; et = et->next) {
	if (et->table->base <= code &&
	    et->table->base + et->table->n_msgs > code) {
	    /* This is the right table */
	    if (callback_lookup) {
		msg = callback_lookup(code, language, et->table,
		    callback_private, et->table_private);
		if (msg) return msg;
	    }
    
	    return(et->table->msgs[code - et->table->base].en_text);
	}
    }

    if (code >= 0 && code < 256) {
	return strerror(code);
    }

    offset = (int) (code & ((1<<ERRCODE_RANGE)-1));
    table_num = code - offset;
    strcpy (buffer, "Unknown code ");
    if (table_num) {
	strcat(buffer, error_table_name (table_num));
	strcat(buffer, " ");
    }
    for (cp = buffer; *cp; cp++)
	;
    if (offset >= 100) {
	*cp++ = (char)('0' + offset / 100);
	offset %= 100;
	started++;
    }
    if (started || offset >= 10) {
	*cp++ = (char)('0' + offset / 10);
	offset %= 10;
    }
    *cp++ = (char)('0' + offset);
    *cp = '\0';
    return(buffer);
}

PR_IMPLEMENT(const char *)
PR_ErrorToName(PRErrorCode code)
{
    struct PRErrorTableList *et;

    for (et = Table_List; et; et = et->next) {
	if (et->table->base <= code &&
	    et->table->base + et->table->n_msgs > code) {
	    /* This is the right table */
	    return(et->table->msgs[code - et->table->base].name);
	}
    }

    return 0;
}

PR_IMPLEMENT(const char * const *)
PR_ErrorLanguages(void)
{
    return callback_languages;
}

PR_IMPLEMENT(PRErrorCode)
PR_ErrorInstallTable(const struct PRErrorTable *table)
{
    struct PRErrorTableList * new_et;

    new_et = (struct PRErrorTableList *)
					PR_Malloc(sizeof(struct PRErrorTableList));
    if (!new_et)
	return errno;	/* oops */
    new_et->table = table;
    if (callback_newtable) {
	new_et->table_private = callback_newtable(table, callback_private);
    } else {
	new_et->table_private = 0;
    }
    new_et->next = Table_List;
    Table_List = new_et;
    return 0;
}

PR_IMPLEMENT(void)
PR_ErrorInstallCallback(const char * const * languages,
		       PRErrorCallbackLookupFn *lookup, 
		       PRErrorCallbackNewTableFn *newtable,
		       struct PRErrorCallbackPrivate *cb_private)
{
    struct PRErrorTableList *et;

    assert(strcmp(languages[0], "i-default") == 0);
    assert(strcmp(languages[1], "en") == 0);
    
    callback_languages = languages;
    callback_lookup = lookup;
    callback_newtable = newtable;
    callback_private = cb_private;

    if (callback_newtable) {
	for (et = Table_List; et; et = et->next) {
	    et->table_private = callback_newtable(et->table, callback_private);
	}
    }
}
