1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/nsprpub/pr/src/misc/prerrortable.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,205 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 + 1.9 + 1.10 + 1.11 +/* 1.12 + 1.13 +Copyright 1987, 1988 by the Student Information Processing Board 1.14 + of the Massachusetts Institute of Technology 1.15 + 1.16 +Permission to use, copy, modify, and distribute this software 1.17 +and its documentation for any purpose and without fee is 1.18 +hereby granted, provided that the above copyright notice 1.19 +appear in all copies and that both that copyright notice and 1.20 +this permission notice appear in supporting documentation, 1.21 +and that the names of M.I.T. and the M.I.T. S.I.P.B. not be 1.22 +used in advertising or publicity pertaining to distribution 1.23 +of the software without specific, written prior permission. 1.24 +M.I.T. and the M.I.T. S.I.P.B. make no representations about 1.25 +the suitability of this software for any purpose. It is 1.26 +provided "as is" without express or implied warranty. 1.27 + 1.28 +*/ 1.29 + 1.30 +#include <string.h> 1.31 +#include <assert.h> 1.32 +#include <errno.h> 1.33 +#include "prmem.h" 1.34 +#include "prerror.h" 1.35 + 1.36 +#define ERRCODE_RANGE 8 /* # of bits to shift table number */ 1.37 +#define BITS_PER_CHAR 6 /* # bits to shift per character in name */ 1.38 + 1.39 +#ifdef NEED_SYS_ERRLIST 1.40 +extern char const * const sys_errlist[]; 1.41 +extern const int sys_nerr; 1.42 +#endif 1.43 + 1.44 +/* List of error tables */ 1.45 +struct PRErrorTableList { 1.46 + struct PRErrorTableList *next; 1.47 + const struct PRErrorTable *table; 1.48 + struct PRErrorCallbackTablePrivate *table_private; 1.49 +}; 1.50 +static struct PRErrorTableList * Table_List = (struct PRErrorTableList *) NULL; 1.51 + 1.52 +/* Supported languages */ 1.53 +static const char * default_languages[] = { "i-default", "en", 0 }; 1.54 +static const char * const * callback_languages = default_languages; 1.55 + 1.56 +/* Callback info */ 1.57 +static struct PRErrorCallbackPrivate *callback_private = 0; 1.58 +static PRErrorCallbackLookupFn *callback_lookup = 0; 1.59 +static PRErrorCallbackNewTableFn *callback_newtable = 0; 1.60 + 1.61 + 1.62 +static const char char_set[] = 1.63 + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; 1.64 + 1.65 +static const char * 1.66 +error_table_name (PRErrorCode num) 1.67 +{ 1.68 + static char buf[6]; /* only used if internal code problems exist */ 1.69 + 1.70 + long ch; 1.71 + int i; 1.72 + char *p; 1.73 + 1.74 + /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */ 1.75 + p = buf; 1.76 + num >>= ERRCODE_RANGE; 1.77 + /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */ 1.78 + num &= 077777777; 1.79 + /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */ 1.80 + for (i = 4; i >= 0; i--) { 1.81 + ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1); 1.82 + if (ch != 0) 1.83 + *p++ = char_set[ch-1]; 1.84 + } 1.85 + *p = '\0'; 1.86 + return(buf); 1.87 +} 1.88 + 1.89 +PR_IMPLEMENT(const char *) 1.90 +PR_ErrorToString(PRErrorCode code, PRLanguageCode language) 1.91 +{ 1.92 + /* static buffer only used if code is using inconsistent error message 1.93 + * numbers, so just ignore the possible thread contention 1.94 + */ 1.95 + static char buffer[25]; 1.96 + 1.97 + const char *msg; 1.98 + int offset; 1.99 + PRErrorCode table_num; 1.100 + struct PRErrorTableList *et; 1.101 + int started = 0; 1.102 + char *cp; 1.103 + 1.104 + for (et = Table_List; et; et = et->next) { 1.105 + if (et->table->base <= code && 1.106 + et->table->base + et->table->n_msgs > code) { 1.107 + /* This is the right table */ 1.108 + if (callback_lookup) { 1.109 + msg = callback_lookup(code, language, et->table, 1.110 + callback_private, et->table_private); 1.111 + if (msg) return msg; 1.112 + } 1.113 + 1.114 + return(et->table->msgs[code - et->table->base].en_text); 1.115 + } 1.116 + } 1.117 + 1.118 + if (code >= 0 && code < 256) { 1.119 + return strerror(code); 1.120 + } 1.121 + 1.122 + offset = (int) (code & ((1<<ERRCODE_RANGE)-1)); 1.123 + table_num = code - offset; 1.124 + strcpy (buffer, "Unknown code "); 1.125 + if (table_num) { 1.126 + strcat(buffer, error_table_name (table_num)); 1.127 + strcat(buffer, " "); 1.128 + } 1.129 + for (cp = buffer; *cp; cp++) 1.130 + ; 1.131 + if (offset >= 100) { 1.132 + *cp++ = (char)('0' + offset / 100); 1.133 + offset %= 100; 1.134 + started++; 1.135 + } 1.136 + if (started || offset >= 10) { 1.137 + *cp++ = (char)('0' + offset / 10); 1.138 + offset %= 10; 1.139 + } 1.140 + *cp++ = (char)('0' + offset); 1.141 + *cp = '\0'; 1.142 + return(buffer); 1.143 +} 1.144 + 1.145 +PR_IMPLEMENT(const char *) 1.146 +PR_ErrorToName(PRErrorCode code) 1.147 +{ 1.148 + struct PRErrorTableList *et; 1.149 + 1.150 + for (et = Table_List; et; et = et->next) { 1.151 + if (et->table->base <= code && 1.152 + et->table->base + et->table->n_msgs > code) { 1.153 + /* This is the right table */ 1.154 + return(et->table->msgs[code - et->table->base].name); 1.155 + } 1.156 + } 1.157 + 1.158 + return 0; 1.159 +} 1.160 + 1.161 +PR_IMPLEMENT(const char * const *) 1.162 +PR_ErrorLanguages(void) 1.163 +{ 1.164 + return callback_languages; 1.165 +} 1.166 + 1.167 +PR_IMPLEMENT(PRErrorCode) 1.168 +PR_ErrorInstallTable(const struct PRErrorTable *table) 1.169 +{ 1.170 + struct PRErrorTableList * new_et; 1.171 + 1.172 + new_et = (struct PRErrorTableList *) 1.173 + PR_Malloc(sizeof(struct PRErrorTableList)); 1.174 + if (!new_et) 1.175 + return errno; /* oops */ 1.176 + new_et->table = table; 1.177 + if (callback_newtable) { 1.178 + new_et->table_private = callback_newtable(table, callback_private); 1.179 + } else { 1.180 + new_et->table_private = 0; 1.181 + } 1.182 + new_et->next = Table_List; 1.183 + Table_List = new_et; 1.184 + return 0; 1.185 +} 1.186 + 1.187 +PR_IMPLEMENT(void) 1.188 +PR_ErrorInstallCallback(const char * const * languages, 1.189 + PRErrorCallbackLookupFn *lookup, 1.190 + PRErrorCallbackNewTableFn *newtable, 1.191 + struct PRErrorCallbackPrivate *cb_private) 1.192 +{ 1.193 + struct PRErrorTableList *et; 1.194 + 1.195 + assert(strcmp(languages[0], "i-default") == 0); 1.196 + assert(strcmp(languages[1], "en") == 0); 1.197 + 1.198 + callback_languages = languages; 1.199 + callback_lookup = lookup; 1.200 + callback_newtable = newtable; 1.201 + callback_private = cb_private; 1.202 + 1.203 + if (callback_newtable) { 1.204 + for (et = Table_List; et; et = et->next) { 1.205 + et->table_private = callback_newtable(et->table, callback_private); 1.206 + } 1.207 + } 1.208 +}