1 : /* ***** BEGIN LICENSE BLOCK *****
2 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 : *
4 : * The contents of this file are subject to the Mozilla Public License Version
5 : * 1.1 (the "License"); you may not use this file except in compliance with
6 : * the License. You may obtain a copy of the License at
7 : * http://www.mozilla.org/MPL/
8 : *
9 : * Software distributed under the License is distributed on an "AS IS" basis,
10 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 : * for the specific language governing rights and limitations under the
12 : * License.
13 : *
14 : * The Original Code is the Netscape Portable Runtime (NSPR).
15 : *
16 : * The Initial Developer of the Original Code is
17 : * Netscape Communications Corporation.
18 : * Portions created by the Initial Developer are Copyright (C) 1998-2000
19 : * the Initial Developer. All Rights Reserved.
20 : *
21 : * Contributor(s):
22 : *
23 : * Alternatively, the contents of this file may be used under the terms of
24 : * either the GNU General Public License Version 2 or later (the "GPL"), or
25 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 : * in which case the provisions of the GPL or the LGPL are applicable instead
27 : * of those above. If you wish to allow use of your version of this file only
28 : * under the terms of either the GPL or the LGPL, and not to allow others to
29 : * use your version of this file under the terms of the MPL, indicate your
30 : * decision by deleting the provisions above and replace them with the notice
31 : * and other provisions required by the GPL or the LGPL. If you do not delete
32 : * the provisions above, a recipient may use your version of this file under
33 : * the terms of any one of the MPL, the GPL or the LGPL.
34 : *
35 : * ***** END LICENSE BLOCK ***** */
36 :
37 :
38 :
39 :
40 : /*
41 :
42 : Copyright 1987, 1988 by the Student Information Processing Board
43 : of the Massachusetts Institute of Technology
44 :
45 : Permission to use, copy, modify, and distribute this software
46 : and its documentation for any purpose and without fee is
47 : hereby granted, provided that the above copyright notice
48 : appear in all copies and that both that copyright notice and
49 : this permission notice appear in supporting documentation,
50 : and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
51 : used in advertising or publicity pertaining to distribution
52 : of the software without specific, written prior permission.
53 : M.I.T. and the M.I.T. S.I.P.B. make no representations about
54 : the suitability of this software for any purpose. It is
55 : provided "as is" without express or implied warranty.
56 :
57 : */
58 :
59 : #include <string.h>
60 : #ifdef SUNOS4
61 : #include "md/sunos4.h" /* for strerror */
62 : #endif
63 : #include <assert.h>
64 : #include <errno.h>
65 : #include "prmem.h"
66 : #include "prerror.h"
67 :
68 : #define ERRCODE_RANGE 8 /* # of bits to shift table number */
69 : #define BITS_PER_CHAR 6 /* # bits to shift per character in name */
70 :
71 : #ifdef NEED_SYS_ERRLIST
72 : extern char const * const sys_errlist[];
73 : extern const int sys_nerr;
74 : #endif
75 :
76 : /* List of error tables */
77 : struct PRErrorTableList {
78 : struct PRErrorTableList *next;
79 : const struct PRErrorTable *table;
80 : struct PRErrorCallbackTablePrivate *table_private;
81 : };
82 : static struct PRErrorTableList * Table_List = (struct PRErrorTableList *) NULL;
83 :
84 : /* Supported languages */
85 : static const char * default_languages[] = { "i-default", "en", 0 };
86 : static const char * const * callback_languages = default_languages;
87 :
88 : /* Callback info */
89 : static struct PRErrorCallbackPrivate *callback_private = 0;
90 : static PRErrorCallbackLookupFn *callback_lookup = 0;
91 : static PRErrorCallbackNewTableFn *callback_newtable = 0;
92 :
93 :
94 : static const char char_set[] =
95 : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
96 :
97 : static const char *
98 0 : error_table_name (PRErrorCode num)
99 : {
100 : static char buf[6]; /* only used if internal code problems exist */
101 :
102 : long ch;
103 : int i;
104 : char *p;
105 :
106 : /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
107 0 : p = buf;
108 0 : num >>= ERRCODE_RANGE;
109 : /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
110 0 : num &= 077777777;
111 : /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
112 0 : for (i = 4; i >= 0; i--) {
113 0 : ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1);
114 0 : if (ch != 0)
115 0 : *p++ = char_set[ch-1];
116 : }
117 0 : *p = '\0';
118 0 : return(buf);
119 : }
120 :
121 : PR_IMPLEMENT(const char *)
122 0 : PR_ErrorToString(PRErrorCode code, PRLanguageCode language)
123 : {
124 : /* static buffer only used if code is using inconsistent error message
125 : * numbers, so just ignore the possible thread contention
126 : */
127 : static char buffer[25];
128 :
129 : const char *msg;
130 : int offset;
131 : PRErrorCode table_num;
132 : struct PRErrorTableList *et;
133 0 : int started = 0;
134 : char *cp;
135 :
136 0 : for (et = Table_List; et; et = et->next) {
137 0 : if (et->table->base <= code &&
138 0 : et->table->base + et->table->n_msgs > code) {
139 : /* This is the right table */
140 0 : if (callback_lookup) {
141 0 : msg = callback_lookup(code, language, et->table,
142 : callback_private, et->table_private);
143 0 : if (msg) return msg;
144 : }
145 :
146 0 : return(et->table->msgs[code - et->table->base].en_text);
147 : }
148 : }
149 :
150 0 : if (code >= 0 && code < 256) {
151 0 : return strerror(code);
152 : }
153 :
154 0 : offset = (int) (code & ((1<<ERRCODE_RANGE)-1));
155 0 : table_num = code - offset;
156 0 : strcpy (buffer, "Unknown code ");
157 0 : if (table_num) {
158 0 : strcat(buffer, error_table_name (table_num));
159 0 : strcat(buffer, " ");
160 : }
161 0 : for (cp = buffer; *cp; cp++)
162 : ;
163 0 : if (offset >= 100) {
164 0 : *cp++ = (char)('0' + offset / 100);
165 0 : offset %= 100;
166 0 : started++;
167 : }
168 0 : if (started || offset >= 10) {
169 0 : *cp++ = (char)('0' + offset / 10);
170 0 : offset %= 10;
171 : }
172 0 : *cp++ = (char)('0' + offset);
173 0 : *cp = '\0';
174 0 : return(buffer);
175 : }
176 :
177 : PR_IMPLEMENT(const char *)
178 0 : PR_ErrorToName(PRErrorCode code)
179 : {
180 : struct PRErrorTableList *et;
181 :
182 0 : for (et = Table_List; et; et = et->next) {
183 0 : if (et->table->base <= code &&
184 0 : et->table->base + et->table->n_msgs > code) {
185 : /* This is the right table */
186 0 : return(et->table->msgs[code - et->table->base].name);
187 : }
188 : }
189 :
190 0 : return 0;
191 : }
192 :
193 : PR_IMPLEMENT(const char * const *)
194 0 : PR_ErrorLanguages(void)
195 : {
196 0 : return callback_languages;
197 : }
198 :
199 : PR_IMPLEMENT(PRErrorCode)
200 20830 : PR_ErrorInstallTable(const struct PRErrorTable *table)
201 : {
202 : struct PRErrorTableList * new_et;
203 :
204 20830 : new_et = (struct PRErrorTableList *)
205 20830 : PR_Malloc(sizeof(struct PRErrorTableList));
206 20830 : if (!new_et)
207 0 : return errno; /* oops */
208 20830 : new_et->table = table;
209 20830 : if (callback_newtable) {
210 0 : new_et->table_private = callback_newtable(table, callback_private);
211 : } else {
212 20830 : new_et->table_private = 0;
213 : }
214 20830 : new_et->next = Table_List;
215 20830 : Table_List = new_et;
216 20830 : return 0;
217 : }
218 :
219 : PR_IMPLEMENT(void)
220 0 : PR_ErrorInstallCallback(const char * const * languages,
221 : PRErrorCallbackLookupFn *lookup,
222 : PRErrorCallbackNewTableFn *newtable,
223 : struct PRErrorCallbackPrivate *cb_private)
224 : {
225 : struct PRErrorTableList *et;
226 :
227 0 : assert(strcmp(languages[0], "i-default") == 0);
228 0 : assert(strcmp(languages[1], "en") == 0);
229 :
230 0 : callback_languages = languages;
231 0 : callback_lookup = lookup;
232 0 : callback_newtable = newtable;
233 0 : callback_private = cb_private;
234 :
235 0 : if (callback_newtable) {
236 0 : for (et = Table_List; et; et = et->next) {
237 0 : et->table_private = callback_newtable(et->table, callback_private);
238 : }
239 : }
240 0 : }
|