XlationSvc: remove a "'" added in previous spelling commit that causes warnings
[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 libraries 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 <X11/Intrinsic.h>
42 #include <Dt/MsgCatP.h>
43 #include <DtSvcLock.h>
44
45 typedef struct _dt_msg_cache
46 {
47     char ***cached_msgs;
48     int     nmsgs_per_set;
49     int     nsets;
50
51     nl_catd catd;
52     struct _dt_msg_cache *next;
53 } _DtMsgCache;
54
55 static _DtMsgCache      *catalog_message_caches = NULL;
56
57 static _DtMsgCache *get_msg_cache(nl_catd catd)
58 {
59     #define INITIAL_NMSGS_PER_SET       300
60     #define INITIAL_NSETS               50
61
62     _DtMsgCache *c;
63
64     for (c=catalog_message_caches; NULL!=c; c=c->next)
65       if (catd == c->catd) return c;
66
67     c = (_DtMsgCache*) XtMalloc(sizeof(_DtMsgCache));
68     c->cached_msgs = NULL;
69     c->nmsgs_per_set = INITIAL_NMSGS_PER_SET;
70     c->nsets = INITIAL_NSETS;
71     c->catd = catd;
72     c->next = catalog_message_caches;
73     catalog_message_caches = c;
74     return c;
75 }
76
77
78 /*
79  * Wrapper around catgets -- this makes sure the message string is saved
80  * in a safe location; so repeated calls to catgets() do not overwrite
81  * the catgets() internal buffer.  This has been a problem on HP systems.
82  */
83 char *_DtCatgetsCached(nl_catd catd, int set, int num, char *dflt)
84 {
85     char        *message;
86
87 #if !defined(hpV4)
88     message = catgets(catd, set, num, dflt);
89 #else
90     _DtMsgCache *c;
91     char        **setptr;
92     int         i, multiplier;
93     int         size;
94
95     /* convert to a zero based index */
96     int         setIdx = set - 1;
97     int         numIdx = num - 1;
98
99     _DtSvcProcessLock();
100
101     c = get_msg_cache(catd);
102     if (NULL == c) 
103     {
104         message = catgets(catd, set, num, dflt);
105         return message;
106     }
107
108     if (NULL == c->cached_msgs)
109     {
110         size = sizeof(char**) * c->nsets;
111         c->cached_msgs = (char***) XtMalloc(size);
112         memset((char*) c->cached_msgs, 0, size);
113     }
114     else if (setIdx >= c->nsets)
115     {
116         for (multiplier=2; setIdx > multiplier*c->nsets; multiplier++) {}
117         size = sizeof(char**) * c->nsets;
118         c->cached_msgs =
119           (char***) XtRealloc((char*) c->cached_msgs, multiplier*size);
120         memset((char*) (c->cached_msgs + size), 0, multiplier*size);
121         c->nsets *= multiplier;
122     }
123
124     if (NULL == c->cached_msgs[setIdx])
125     {
126         size = sizeof(char*) * c->nmsgs_per_set;
127         c->cached_msgs[setIdx] = (char**) XtMalloc(size);
128         memset((char*) c->cached_msgs[setIdx], 0, size);
129     }
130     else if (numIdx >= c->nmsgs_per_set)
131     {
132         for (multiplier=2; numIdx > multiplier*c->nsets; multiplier++) {}
133         size = sizeof(char*) * c->nmsgs_per_set;
134   
135         for (i=0; i<c->nmsgs_per_set; i++)
136         {
137             if (NULL != c->cached_msgs[i])
138             {
139                 c->cached_msgs[i] =
140                   (char**) XtRealloc((char*)c->cached_msgs[i], multiplier*size);
141                 memset((char*) (c->cached_msgs[i] + size), 0, multiplier*size);
142             }
143         }
144         c->nmsgs_per_set *= multiplier;
145     }
146
147     setptr = c->cached_msgs[setIdx];
148     if (NULL == setptr[numIdx])
149       setptr[numIdx] = strdup(catgets(catd, set, num, dflt));
150   
151     message = setptr[numIdx];
152
153     _DtSvcProcessUnlock();
154 #endif /* hpV4 */
155
156     return message;
157 }