LCOV - code coverage report
Current view: top level - nsprpub/pr/src/misc - prerrortable.c (source / functions) Hit Total Coverage
Test: output.info Lines: 8 63 12.7 %
Date: 2017-07-14 16:53:18 Functions: 0 1 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13