nsprpub/pr/src/misc/prerrortable.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5
michael@0 6
michael@0 7
michael@0 8 /*
michael@0 9
michael@0 10 Copyright 1987, 1988 by the Student Information Processing Board
michael@0 11 of the Massachusetts Institute of Technology
michael@0 12
michael@0 13 Permission to use, copy, modify, and distribute this software
michael@0 14 and its documentation for any purpose and without fee is
michael@0 15 hereby granted, provided that the above copyright notice
michael@0 16 appear in all copies and that both that copyright notice and
michael@0 17 this permission notice appear in supporting documentation,
michael@0 18 and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
michael@0 19 used in advertising or publicity pertaining to distribution
michael@0 20 of the software without specific, written prior permission.
michael@0 21 M.I.T. and the M.I.T. S.I.P.B. make no representations about
michael@0 22 the suitability of this software for any purpose. It is
michael@0 23 provided "as is" without express or implied warranty.
michael@0 24
michael@0 25 */
michael@0 26
michael@0 27 #include <string.h>
michael@0 28 #include <assert.h>
michael@0 29 #include <errno.h>
michael@0 30 #include "prmem.h"
michael@0 31 #include "prerror.h"
michael@0 32
michael@0 33 #define ERRCODE_RANGE 8 /* # of bits to shift table number */
michael@0 34 #define BITS_PER_CHAR 6 /* # bits to shift per character in name */
michael@0 35
michael@0 36 #ifdef NEED_SYS_ERRLIST
michael@0 37 extern char const * const sys_errlist[];
michael@0 38 extern const int sys_nerr;
michael@0 39 #endif
michael@0 40
michael@0 41 /* List of error tables */
michael@0 42 struct PRErrorTableList {
michael@0 43 struct PRErrorTableList *next;
michael@0 44 const struct PRErrorTable *table;
michael@0 45 struct PRErrorCallbackTablePrivate *table_private;
michael@0 46 };
michael@0 47 static struct PRErrorTableList * Table_List = (struct PRErrorTableList *) NULL;
michael@0 48
michael@0 49 /* Supported languages */
michael@0 50 static const char * default_languages[] = { "i-default", "en", 0 };
michael@0 51 static const char * const * callback_languages = default_languages;
michael@0 52
michael@0 53 /* Callback info */
michael@0 54 static struct PRErrorCallbackPrivate *callback_private = 0;
michael@0 55 static PRErrorCallbackLookupFn *callback_lookup = 0;
michael@0 56 static PRErrorCallbackNewTableFn *callback_newtable = 0;
michael@0 57
michael@0 58
michael@0 59 static const char char_set[] =
michael@0 60 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
michael@0 61
michael@0 62 static const char *
michael@0 63 error_table_name (PRErrorCode num)
michael@0 64 {
michael@0 65 static char buf[6]; /* only used if internal code problems exist */
michael@0 66
michael@0 67 long ch;
michael@0 68 int i;
michael@0 69 char *p;
michael@0 70
michael@0 71 /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
michael@0 72 p = buf;
michael@0 73 num >>= ERRCODE_RANGE;
michael@0 74 /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
michael@0 75 num &= 077777777;
michael@0 76 /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
michael@0 77 for (i = 4; i >= 0; i--) {
michael@0 78 ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1);
michael@0 79 if (ch != 0)
michael@0 80 *p++ = char_set[ch-1];
michael@0 81 }
michael@0 82 *p = '\0';
michael@0 83 return(buf);
michael@0 84 }
michael@0 85
michael@0 86 PR_IMPLEMENT(const char *)
michael@0 87 PR_ErrorToString(PRErrorCode code, PRLanguageCode language)
michael@0 88 {
michael@0 89 /* static buffer only used if code is using inconsistent error message
michael@0 90 * numbers, so just ignore the possible thread contention
michael@0 91 */
michael@0 92 static char buffer[25];
michael@0 93
michael@0 94 const char *msg;
michael@0 95 int offset;
michael@0 96 PRErrorCode table_num;
michael@0 97 struct PRErrorTableList *et;
michael@0 98 int started = 0;
michael@0 99 char *cp;
michael@0 100
michael@0 101 for (et = Table_List; et; et = et->next) {
michael@0 102 if (et->table->base <= code &&
michael@0 103 et->table->base + et->table->n_msgs > code) {
michael@0 104 /* This is the right table */
michael@0 105 if (callback_lookup) {
michael@0 106 msg = callback_lookup(code, language, et->table,
michael@0 107 callback_private, et->table_private);
michael@0 108 if (msg) return msg;
michael@0 109 }
michael@0 110
michael@0 111 return(et->table->msgs[code - et->table->base].en_text);
michael@0 112 }
michael@0 113 }
michael@0 114
michael@0 115 if (code >= 0 && code < 256) {
michael@0 116 return strerror(code);
michael@0 117 }
michael@0 118
michael@0 119 offset = (int) (code & ((1<<ERRCODE_RANGE)-1));
michael@0 120 table_num = code - offset;
michael@0 121 strcpy (buffer, "Unknown code ");
michael@0 122 if (table_num) {
michael@0 123 strcat(buffer, error_table_name (table_num));
michael@0 124 strcat(buffer, " ");
michael@0 125 }
michael@0 126 for (cp = buffer; *cp; cp++)
michael@0 127 ;
michael@0 128 if (offset >= 100) {
michael@0 129 *cp++ = (char)('0' + offset / 100);
michael@0 130 offset %= 100;
michael@0 131 started++;
michael@0 132 }
michael@0 133 if (started || offset >= 10) {
michael@0 134 *cp++ = (char)('0' + offset / 10);
michael@0 135 offset %= 10;
michael@0 136 }
michael@0 137 *cp++ = (char)('0' + offset);
michael@0 138 *cp = '\0';
michael@0 139 return(buffer);
michael@0 140 }
michael@0 141
michael@0 142 PR_IMPLEMENT(const char *)
michael@0 143 PR_ErrorToName(PRErrorCode code)
michael@0 144 {
michael@0 145 struct PRErrorTableList *et;
michael@0 146
michael@0 147 for (et = Table_List; et; et = et->next) {
michael@0 148 if (et->table->base <= code &&
michael@0 149 et->table->base + et->table->n_msgs > code) {
michael@0 150 /* This is the right table */
michael@0 151 return(et->table->msgs[code - et->table->base].name);
michael@0 152 }
michael@0 153 }
michael@0 154
michael@0 155 return 0;
michael@0 156 }
michael@0 157
michael@0 158 PR_IMPLEMENT(const char * const *)
michael@0 159 PR_ErrorLanguages(void)
michael@0 160 {
michael@0 161 return callback_languages;
michael@0 162 }
michael@0 163
michael@0 164 PR_IMPLEMENT(PRErrorCode)
michael@0 165 PR_ErrorInstallTable(const struct PRErrorTable *table)
michael@0 166 {
michael@0 167 struct PRErrorTableList * new_et;
michael@0 168
michael@0 169 new_et = (struct PRErrorTableList *)
michael@0 170 PR_Malloc(sizeof(struct PRErrorTableList));
michael@0 171 if (!new_et)
michael@0 172 return errno; /* oops */
michael@0 173 new_et->table = table;
michael@0 174 if (callback_newtable) {
michael@0 175 new_et->table_private = callback_newtable(table, callback_private);
michael@0 176 } else {
michael@0 177 new_et->table_private = 0;
michael@0 178 }
michael@0 179 new_et->next = Table_List;
michael@0 180 Table_List = new_et;
michael@0 181 return 0;
michael@0 182 }
michael@0 183
michael@0 184 PR_IMPLEMENT(void)
michael@0 185 PR_ErrorInstallCallback(const char * const * languages,
michael@0 186 PRErrorCallbackLookupFn *lookup,
michael@0 187 PRErrorCallbackNewTableFn *newtable,
michael@0 188 struct PRErrorCallbackPrivate *cb_private)
michael@0 189 {
michael@0 190 struct PRErrorTableList *et;
michael@0 191
michael@0 192 assert(strcmp(languages[0], "i-default") == 0);
michael@0 193 assert(strcmp(languages[1], "en") == 0);
michael@0 194
michael@0 195 callback_languages = languages;
michael@0 196 callback_lookup = lookup;
michael@0 197 callback_newtable = newtable;
michael@0 198 callback_private = cb_private;
michael@0 199
michael@0 200 if (callback_newtable) {
michael@0 201 for (et = Table_List; et; et = et->next) {
michael@0 202 et->table_private = callback_newtable(et->table, callback_private);
michael@0 203 }
michael@0 204 }
michael@0 205 }

mercurial