Build with debug symbols enabled.
[oweals/cde.git] / cde / lib / DtSvc / DtUtil2 / MsgCat.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* 
24  * (c) Copyright 1995 Digital Equipment Corporation.
25  * (c) Copyright 1995 Hewlett-Packard Company.
26  * (c) Copyright 1995 International Business Machines Corp.
27  * (c) Copyright 1995 Sun Microsystems, Inc.
28  * (c) Copyright 1995 Novell, Inc. 
29  * (c) Copyright 1995 FUJITSU LIMITED.
30  * (c) Copyright 1995 Hitachi.
31  *
32  * MsgCat.c - public interfaces for the Cached Message Catalog Service
33  *
34  * $TOG: MsgCat.c /main/4 1999/07/02 14:02:03 mgreess $
35  *
36  */
37
38 #include <stdio.h>
39 #include <string.h>
40 #include <nl_types.h>
41 #include <Dt/MsgCatP.h>
42 #include <DtSvcLock.h>
43
44 typedef struct _dt_msg_cache
45 {
46     char ***cached_msgs;
47     int     nmsgs_per_set;
48     int     nsets;
49
50     nl_catd catd;
51     struct _dt_msg_cache *next;
52 } _DtMsgCache;
53
54 static _DtMsgCache      *catalog_message_caches = NULL;
55
56 static _DtMsgCache *get_msg_cache(nl_catd catd)
57 {
58     #define INITIAL_NMSGS_PER_SET       300
59     #define INITIAL_NSETS               50
60
61     _DtMsgCache *c;
62
63     for (c=catalog_message_caches; NULL!=c; c=c->next)
64       if (catd == c->catd) return c;
65
66     c = (_DtMsgCache*) XtMalloc(sizeof(_DtMsgCache));
67     c->cached_msgs = NULL;
68     c->nmsgs_per_set = INITIAL_NMSGS_PER_SET;
69     c->nsets = INITIAL_NSETS;
70     c->catd = catd;
71     c->next = catalog_message_caches;
72     catalog_message_caches = c;
73     return c;
74 }
75
76
77 /*
78  * Wrapper around catgets -- this makes sure the message string is saved
79  * in a safe location; so repeated calls to catgets() do not overwrite
80  * the catgets() internal buffer.  This has been a problem on HP systems.
81  */
82 char *_DtCatgetsCached(nl_catd catd, int set, int num, char *dflt)
83 {
84     char        *message;
85
86 #if !defined(hpV4)
87     message = catgets(catd, set, num, dflt);
88 #else
89     _DtMsgCache *c;
90     char        **setptr;
91     int         i, multiplier;
92     int         size;
93
94     /* convert to a zero based index */
95     int         setIdx = set - 1;
96     int         numIdx = num - 1;
97
98     _DtSvcProcessLock();
99
100     c = get_msg_cache(catd);
101     if (NULL == c) 
102     {
103         message = catgets(catd, set, num, dflt);
104         return message;
105     }
106
107     if (NULL == c->cached_msgs)
108     {
109         size = sizeof(char**) * c->nsets;
110         c->cached_msgs = (char***) XtMalloc(size);
111         memset((char*) c->cached_msgs, 0, size);
112     }
113     else if (setIdx >= c->nsets)
114     {
115         for (multiplier=2; setIdx > multiplier*c->nsets; multiplier++) {}
116         size = sizeof(char**) * c->nsets;
117         c->cached_msgs =
118           (char***) XtRealloc((char*) c->cached_msgs, multiplier*size);
119         memset((char*) (c->cached_msgs + size), 0, multiplier*size);
120         c->nsets *= multiplier;
121     }
122
123     if (NULL == c->cached_msgs[setIdx])
124     {
125         size = sizeof(char*) * c->nmsgs_per_set;
126         c->cached_msgs[setIdx] = (char**) XtMalloc(size);
127         memset((char*) c->cached_msgs[setIdx], 0, size);
128     }
129     else if (numIdx >= c->nmsgs_per_set)
130     {
131         for (multiplier=2; numIdx > multiplier*c->nsets; multiplier++) {}
132         size = sizeof(char*) * c->nmsgs_per_set;
133   
134         for (i=0; i<c->nmsgs_per_set; i++)
135         {
136             if (NULL != c->cached_msgs[i])
137             {
138                 c->cached_msgs[i] =
139                   (char**) XtRealloc((char*)c->cached_msgs[i], multiplier*size);
140                 memset((char*) (c->cached_msgs[i] + size), 0, multiplier*size);
141             }
142         }
143         c->nmsgs_per_set *= multiplier;
144     }
145
146     setptr = c->cached_msgs[setIdx];
147     if (NULL == setptr[numIdx])
148       setptr[numIdx] = strdup(catgets(catd, set, num, dflt));
149   
150     message = setptr[numIdx];
151
152     _DtSvcProcessUnlock();
153 #endif /* hpV4 */
154
155     return message;
156 }