ErrDes.c revision b4ee4795
1/*
2 */
3
4/***********************************************************
5
6Copyright 1987, 1988, 1998  The Open Group
7
8Permission to use, copy, modify, distribute, and sell this software and its
9documentation for any purpose is hereby granted without fee, provided that
10the above copyright notice appear in all copies and that both that
11copyright notice and this permission notice appear in supporting
12documentation.
13
14The above copyright notice and this permission notice shall be included in
15all copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
20OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24Except as contained in this notice, the name of The Open Group shall not be
25used in advertising or otherwise to promote the sale, use or other dealings
26in this Software without prior written authorization from The Open Group.
27
28
29Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
30
31                        All Rights Reserved
32
33Permission to use, copy, modify, and distribute this software and its
34documentation for any purpose and without fee is hereby granted,
35provided that the above copyright notice appear in all copies and that
36both that copyright notice and this permission notice appear in
37supporting documentation, and that the name of Digital not be
38used in advertising or publicity pertaining to distribution of the
39software without specific, written prior permission.
40
41DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
42ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
43DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
44ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
45WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
46ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
47SOFTWARE.
48
49******************************************************************/
50
51#ifdef HAVE_CONFIG_H
52#include <config.h>
53#endif
54#include "Xlibint.h"
55#include <X11/Xos.h>
56#include "Xresource.h"
57#include <stdio.h>
58
59#ifndef ERRORDB
60#ifndef XERRORDB
61#define ERRORDB "/usr/lib/X11/XErrorDB"
62#else
63#define ERRORDB XERRORDB
64#endif
65#endif
66
67/*
68 * descriptions of errors in Section 4 of Protocol doc (pp. 350-351); more
69 * verbose descriptions are given in the error database
70 */
71static const char _XErrorList[] =
72    /* No error */          "no error\0"
73    /* BadRequest */        "BadRequest\0"
74    /* BadValue */          "BadValue\0"
75    /* BadWindow */         "BadWindow\0"
76    /* BadPixmap */         "BadPixmap\0"
77    /* BadAtom */           "BadAtom\0"
78    /* BadCursor */         "BadCursor\0"
79    /* BadFont */           "BadFont\0"
80    /* BadMatch */          "BadMatch\0"
81    /* BadDrawable */       "BadDrawable\0"
82    /* BadAccess */         "BadAccess\0"
83    /* BadAlloc */          "BadAlloc\0"
84    /* BadColor */          "BadColor\0"
85    /* BadGC */             "BadGC\0"
86    /* BadIDChoice */       "BadIDChoice\0"
87    /* BadName */           "BadName\0"
88    /* BadLength */         "BadLength\0"
89    /* BadImplementation */ "BadImplementation"
90;
91
92/* offsets into _XErrorList */
93static const unsigned char _XErrorOffsets[] = {
94    0, 9, 20, 29, 39, 49, 57, 67, 75, 84, 96,
95    106, 115, 124, 130, 142, 150, 160
96};
97
98
99int
100XGetErrorText(
101    register Display *dpy,
102    register int code,
103    char *buffer,
104    int nbytes)
105{
106    char buf[150];
107    register _XExtension *ext;
108    _XExtension *bext = (_XExtension *)NULL;
109
110    if (nbytes == 0) return 0;
111    if (code <= BadImplementation && code > 0) {
112	sprintf(buf, "%d", code);
113        (void) XGetErrorDatabaseText(dpy, "XProtoError", buf,
114                                     _XErrorList + _XErrorOffsets[code],
115				     buffer, nbytes);
116    } else
117	buffer[0] = '\0';
118    /* call out to any extensions interested */
119    for (ext = dpy->ext_procs; ext; ext = ext->next) {
120 	if (ext->error_string)
121 	    (*ext->error_string)(dpy, code, &ext->codes, buffer, nbytes);
122	if (ext->codes.first_error &&
123	    ext->codes.first_error <= code &&
124	    (!bext || ext->codes.first_error > bext->codes.first_error))
125	    bext = ext;
126    }
127    if (!buffer[0] && bext) {
128	sprintf(buf, "%s.%d", bext->name, code - bext->codes.first_error);
129	(void) XGetErrorDatabaseText(dpy, "XProtoError", buf, "", buffer, nbytes);
130    }
131    if (!buffer[0])
132	sprintf(buffer, "%d", code);
133    return 0;
134}
135
136int
137/*ARGSUSED*/
138XGetErrorDatabaseText(
139    Display *dpy,
140    register _Xconst char *name,
141    register _Xconst char *type,
142    _Xconst char *defaultp,
143    char *buffer,
144    int nbytes)
145{
146
147    static XrmDatabase db = NULL;
148    XrmString type_str;
149    XrmValue result;
150    char temp[BUFSIZ];
151    char* tptr;
152    unsigned long tlen;
153
154    if (nbytes == 0) return 0;
155
156    if (!db) {
157	/* the Xrm routines expect to be called with the global
158	   mutex unlocked. */
159	XrmDatabase temp_db;
160	int do_destroy;
161	const char *dbname;
162
163	XrmInitialize();
164#ifdef WIN32
165	dbname = getenv("XERRORDB");
166	if (!dbname)
167	    dbname = ERRORDB;
168#else
169    dbname = ERRORDB;
170#endif
171	temp_db = XrmGetFileDatabase(dbname);
172
173	_XLockMutex(_Xglobal_lock);
174	if (!db) {
175	    db = temp_db;
176	    do_destroy = 0;
177	} else
178	    do_destroy = 1;	/* we didn't need to get it after all */
179	_XUnlockMutex(_Xglobal_lock);
180
181	if (do_destroy)
182	    XrmDestroyDatabase(temp_db);
183    }
184
185    if (db)
186    {
187	tlen = strlen (name) + strlen (type) + 2;
188	if (tlen <= sizeof(temp))
189	    tptr = temp;
190	else
191	    tptr = Xmalloc (tlen);
192	if (tptr) {
193	    sprintf(tptr, "%s.%s", name, type);
194	    XrmGetResource(db, tptr, "ErrorType.ErrorNumber",
195	      &type_str, &result);
196	    if (tptr != temp)
197		Xfree (tptr);
198	} else {
199	    result.addr = (XPointer) NULL;
200	}
201    }
202    else
203	result.addr = (XPointer)NULL;
204    if (!result.addr) {
205	result.addr = (XPointer) defaultp;
206	result.size = strlen(defaultp) + 1;
207    }
208    (void) strncpy (buffer, (char *) result.addr, nbytes);
209    if (result.size > nbytes) buffer[nbytes-1] = '\0';
210    return 0;
211}
212