summaryrefslogtreecommitdiff
path: root/mozilla/nsprpub/pr/src/misc/prerrortable.c
diff options
context:
space:
mode:
Diffstat (limited to 'mozilla/nsprpub/pr/src/misc/prerrortable.c')
-rw-r--r--mozilla/nsprpub/pr/src/misc/prerrortable.c240
1 files changed, 240 insertions, 0 deletions
diff --git a/mozilla/nsprpub/pr/src/misc/prerrortable.c b/mozilla/nsprpub/pr/src/misc/prerrortable.c
new file mode 100644
index 0000000..a51b4e8
--- /dev/null
+++ b/mozilla/nsprpub/pr/src/misc/prerrortable.c
@@ -0,0 +1,240 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+
+
+/*
+
+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>
+#ifdef SUNOS4
+#include "md/sunos4.h" /* for strerror */
+#endif
+#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);
+ }
+ }
+}