Back to index

lightning-sunbird  0.9+nobinonly
prerrortable.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape Portable Runtime (NSPR).
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1998-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 
00038 
00039 
00040 /*
00041 
00042 Copyright 1987, 1988 by the Student Information Processing Board
00043        of the Massachusetts Institute of Technology
00044 
00045 Permission to use, copy, modify, and distribute this software
00046 and its documentation for any purpose and without fee is
00047 hereby granted, provided that the above copyright notice
00048 appear in all copies and that both that copyright notice and
00049 this permission notice appear in supporting documentation,
00050 and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
00051 used in advertising or publicity pertaining to distribution
00052 of the software without specific, written prior permission.
00053 M.I.T. and the M.I.T. S.I.P.B. make no representations about
00054 the suitability of this software for any purpose.  It is
00055 provided "as is" without express or implied warranty.
00056 
00057 */
00058 
00059 #include <string.h>
00060 #ifdef SUNOS4
00061 #include "md/sunos4.h"  /* for strerror */
00062 #endif
00063 #include <assert.h>
00064 #include <errno.h>
00065 #include "prmem.h"
00066 #include "prerror.h"
00067 
00068 #define       ERRCODE_RANGE 8      /* # of bits to shift table number */
00069 #define       BITS_PER_CHAR 6      /* # bits to shift per character in name */
00070 
00071 #ifdef NEED_SYS_ERRLIST
00072 extern char const * const sys_errlist[];
00073 extern const int sys_nerr;
00074 #endif
00075 
00076 /* List of error tables */
00077 struct PRErrorTableList {
00078     struct PRErrorTableList *next;
00079     const struct PRErrorTable *table;
00080     struct PRErrorCallbackTablePrivate *table_private;
00081 };
00082 static struct PRErrorTableList * Table_List = (struct PRErrorTableList *) NULL;
00083 
00084 /* Supported languages */
00085 static const char * default_languages[] = { "i-default", "en", 0 };
00086 static const char * const * callback_languages = default_languages;
00087 
00088 /* Callback info */
00089 static struct PRErrorCallbackPrivate *callback_private = 0;
00090 static PRErrorCallbackLookupFn *callback_lookup = 0;
00091 static PRErrorCallbackNewTableFn *callback_newtable = 0;
00092 
00093 
00094 static const char char_set[] =
00095        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
00096 
00097 static const char *
00098 error_table_name (PRErrorCode num)
00099 {
00100     static char buf[6];     /* only used if internal code problems exist */
00101 
00102     long ch;
00103     int i;
00104     char *p;
00105 
00106     /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
00107     p = buf;
00108     num >>= ERRCODE_RANGE;
00109     /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
00110     num &= 077777777;
00111     /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
00112     for (i = 4; i >= 0; i--) {
00113        ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1);
00114        if (ch != 0)
00115            *p++ = char_set[ch-1];
00116     }
00117     *p = '\0';
00118     return(buf);
00119 }
00120 
00121 PR_IMPLEMENT(const char *)
00122 PR_ErrorToString(PRErrorCode code, PRLanguageCode language)
00123 {
00124     /* static buffer only used if code is using inconsistent error message
00125      * numbers, so just ignore the possible thread contention
00126      */
00127     static char buffer[25];
00128 
00129     const char *msg;
00130     int offset;
00131     PRErrorCode table_num;
00132     struct PRErrorTableList *et;
00133     int started = 0;
00134     char *cp;
00135 
00136     for (et = Table_List; et; et = et->next) {
00137        if (et->table->base <= code &&
00138            et->table->base + et->table->n_msgs > code) {
00139            /* This is the right table */
00140            if (callback_lookup) {
00141               msg = callback_lookup(code, language, et->table,
00142                   callback_private, et->table_private);
00143               if (msg) return msg;
00144            }
00145     
00146            return(et->table->msgs[code - et->table->base].en_text);
00147        }
00148     }
00149 
00150     if (code >= 0 && code < 256) {
00151        return strerror(code);
00152     }
00153 
00154     offset = (int) (code & ((1<<ERRCODE_RANGE)-1));
00155     table_num = code - offset;
00156     strcpy (buffer, "Unknown code ");
00157     if (table_num) {
00158        strcat(buffer, error_table_name (table_num));
00159        strcat(buffer, " ");
00160     }
00161     for (cp = buffer; *cp; cp++)
00162        ;
00163     if (offset >= 100) {
00164        *cp++ = (char)('0' + offset / 100);
00165        offset %= 100;
00166        started++;
00167     }
00168     if (started || offset >= 10) {
00169        *cp++ = (char)('0' + offset / 10);
00170        offset %= 10;
00171     }
00172     *cp++ = (char)('0' + offset);
00173     *cp = '\0';
00174     return(buffer);
00175 }
00176 
00177 PR_IMPLEMENT(const char *)
00178 PR_ErrorToName(PRErrorCode code)
00179 {
00180     struct PRErrorTableList *et;
00181 
00182     for (et = Table_List; et; et = et->next) {
00183        if (et->table->base <= code &&
00184            et->table->base + et->table->n_msgs > code) {
00185            /* This is the right table */
00186            return(et->table->msgs[code - et->table->base].name);
00187        }
00188     }
00189 
00190     return 0;
00191 }
00192 
00193 PR_IMPLEMENT(const char * const *)
00194 PR_ErrorLanguages(void)
00195 {
00196     return callback_languages;
00197 }
00198 
00199 PR_IMPLEMENT(PRErrorCode)
00200 PR_ErrorInstallTable(const struct PRErrorTable *table)
00201 {
00202     struct PRErrorTableList * new_et;
00203 
00204     new_et = (struct PRErrorTableList *)
00205                                    PR_Malloc(sizeof(struct PRErrorTableList));
00206     if (!new_et)
00207        return errno; /* oops */
00208     new_et->table = table;
00209     if (callback_newtable) {
00210        new_et->table_private = callback_newtable(table, callback_private);
00211     } else {
00212        new_et->table_private = 0;
00213     }
00214     new_et->next = Table_List;
00215     Table_List = new_et;
00216     return 0;
00217 }
00218 
00219 PR_IMPLEMENT(void)
00220 PR_ErrorInstallCallback(const char * const * languages,
00221                      PRErrorCallbackLookupFn *lookup, 
00222                      PRErrorCallbackNewTableFn *newtable,
00223                      struct PRErrorCallbackPrivate *cb_private)
00224 {
00225     struct PRErrorTableList *et;
00226 
00227     assert(strcmp(languages[0], "i-default") == 0);
00228     assert(strcmp(languages[1], "en") == 0);
00229     
00230     callback_languages = languages;
00231     callback_lookup = lookup;
00232     callback_newtable = newtable;
00233     callback_private = cb_private;
00234 
00235     if (callback_newtable) {
00236        for (et = Table_List; et; et = et->next) {
00237            et->table_private = callback_newtable(et->table, callback_private);
00238        }
00239     }
00240 }