1 /*
2 * Motif
3 *
4 * Copyright (c) 1987-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 #ifdef REV_INFO
24 #ifndef lint
25 static char rcsid[] = "$XConsortium: wmlutils.c /main/8 1995/08/29 11:11:24 drk $"
26 #endif
27 #endif
28
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32
33 /*
34 * This file contains utilities used by WML.
35 */
36
37
38 #include "wml.h"
39
40 #if defined(__STDC__)
41 #include <stdlib.h>
42 #include <string.h>
43 #endif
44 #include <stdio.h>
45
46
47 /*
48 * Utility to allocate dynamic space for a string, and return the
49 * dynamic copy. Produces a NULL on null input.
50 */
51
wmlAllocateString(stg)52 char *wmlAllocateString (stg)
53 char *stg;
54
55 {
56
57 char *dynstg; /* the dynamic copy */
58
59
60 if ( stg == NULL ) return NULL;
61
62 dynstg = (char *) malloc (strlen(stg)+1);
63 strcpy (dynstg, stg);
64 return dynstg;
65
66 }
67
68
69
70 /*
71 * Utility to convert a string to upper case. The conversion happens in
72 * place, destroying the original string.
73 */
74
wmlUpperCaseString(stg)75 void wmlUpperCaseString (stg)
76 char *stg;
77
78 {
79
80 int ndx; /* loop index */
81
82
83 if ( stg == NULL ) return;
84 for ( ndx=0 ; ndx<strlen(stg) ; ndx++ )
85 stg[ndx] = _upper (stg[ndx]);
86
87 }
88
89
90
91 /*
92 * Routines for accessing and manipulating dynamic handle lists.
93 */
94
95
96 /*
97 * Initialize a dynamic handle list. Allocate a vector of the given
98 * size, and set the count and number used (0).
99 *
100 * listptr the list to be inited
101 * size # entries in handle vector
102 * is_ordered TRUE is list is to be ordered
103 */
104
wmlInitHList(listptr,size,is_ordered)105 void wmlInitHList (listptr, size, is_ordered)
106 DynamicHandleListDefPtr listptr;
107 int size;
108 int is_ordered;
109
110 {
111
112 listptr->cnt = 0;
113 listptr->max = size;
114 listptr->ordered = is_ordered;
115 listptr->hvec = (ObjectHandleDefPtr) malloc(size*sizeof(ObjectHandleDef));
116
117 return;
118
119 }
120
121
122
123 /*
124 * Routine to resize a dynamic handle list. Increases the size if required,
125 * but does nothing if the list is already big enough.
126 *
127 * listptr the dynamic list
128 * new_size new list size
129 */
130
wmlResizeHList(listptr,new_size)131 void wmlResizeHList (listptr, new_size)
132 DynamicHandleListDefPtr listptr;
133 int new_size;
134
135 {
136
137 ObjectHandleDefPtr new_vec; /* reallocated vector */
138
139
140 if ( listptr->max >= new_size ) return;
141 listptr->max = new_size;
142 new_vec = (ObjectHandleDefPtr) realloc
143 (listptr->hvec, new_size*sizeof(ObjectHandleDef));
144 listptr->hvec = new_vec;
145
146 return;
147
148 }
149
150
151
152 /*
153 * Routine to clear a dynamic handle list. It leaves the handle vector intact,
154 * but frees all the allocated names. The count is reset to 0.
155 * but does nothing if the list is already big enough.
156 *
157 * listptr the dynamic list
158 */
159
wmlClearHList(listptr)160 void wmlClearHList (listptr)
161 DynamicHandleListDefPtr listptr;
162
163 {
164
165 int ndx; /* current index in list */
166
167
168 for ( ndx=0 ; ndx<listptr->cnt ; ndx++ )
169 {
170 free (listptr->hvec[ndx].objname);
171 listptr->hvec[ndx].objname = NULL;
172 }
173 listptr->cnt = 0;
174
175 return;
176
177 }
178
179
180
181 /*
182 * Function to find a name in a dynamic list. This will function on both
183 * ordered and unordered lists.
184 *
185 * listptr the dynamic list
186 * name the name to look up in the list
187 *
188 * returns:
189 * >= 0 name found, index in list
190 * < 0 name not found
191 */
192
wmlFindInHList(listptr,name)193 int wmlFindInHList (listptr, name)
194 DynamicHandleListDefPtr listptr;
195 char *name;
196
197 {
198
199 int ndx; /* current index in list */
200 int londx; /* low index */
201 int hindx; /* high index */
202 int midndx; /* midpoint index */
203 int cmpres; /* strcmp result */
204
205
206 /*
207 * Binary search if ordered, brute force otherwise
208 */
209 if ( listptr->ordered )
210 {
211 for ( londx=0,hindx=listptr->cnt-1 ; hindx>=londx ; )
212 {
213 midndx = (londx+hindx) / 2;
214 cmpres = strcmp (name, listptr->hvec[midndx].objname);
215 if ( cmpres < 0 )
216 hindx = midndx - 1;
217 if ( cmpres > 0 )
218 londx = midndx + 1;
219 if ( cmpres == 0 )
220 return midndx;
221 }
222 return -1;
223 }
224 else
225 {
226 for ( ndx=0 ; ndx<listptr->cnt ; ndx++ )
227 if ( strcmp(name,listptr->hvec[ndx].objname) == 0 )
228 return ndx;
229 return -1;
230 }
231
232 }
233
234
235
236 /*
237 * Routine to insert an entry into a list. The insertion is ordered or
238 * unordered depending on the way the list is marked. Unordered lists
239 * insert at the end. This routine assumes no duplicates will be entered
240 * in the list.
241 *
242 * listptr the list
243 * name the name under which to insert
244 * obj the object to insert
245 */
246
wmlInsertInHList(listptr,name,obj)247 void wmlInsertInHList (listptr, name, obj)
248 DynamicHandleListDefPtr listptr;
249 char *name;
250 ObjectPtr obj;
251
252 {
253
254 int ndx; /* current index in list */
255 int londx; /* low index */
256 int hindx; /* high index */
257 int midndx = 0; /* midpoint index */
258 int newndx; /* new entry index */
259 int cmpres = 0; /* strcmp result */
260
261
262 /*
263 * Guarantee enough space in the list
264 */
265 wmlResizeHList (listptr, listptr->cnt+1);
266
267 /*
268 * Binary search and insert if ordered, brute force otherwise
269 */
270 if ( listptr->ordered )
271 {
272 if ( listptr->cnt == 0 )
273 {
274 listptr->hvec[0].objname = wmlAllocateString (name);
275 listptr->hvec[0].objptr = obj;
276 listptr->cnt += 1;
277 return;
278 }
279 for ( londx=0,hindx=listptr->cnt-1 ; hindx>=londx ; )
280 {
281 midndx = (londx+hindx) / 2;
282 cmpres = strcmp (name, listptr->hvec[midndx].objname);
283 if ( cmpres == 0 )
284 {
285 printf ("\nwmlInsertInHList: duplicate name '%s'found\n", name);
286 return;
287 }
288 if ( londx == hindx ) break;
289 if ( cmpres < 0 )
290 hindx = midndx - 1;
291 if ( cmpres > 0 )
292 londx = midndx + 1;
293 }
294 /*
295 * The new entry will go either at midndx or after midndx. Move down
296 * the vector appropriately.
297 */
298 if ( cmpres < 0 )
299 newndx = midndx;
300 else
301 newndx = midndx + 1;
302 for ( ndx=listptr->cnt-1 ; ndx>=newndx ; ndx-- )
303 {
304 listptr->hvec[ndx+1].objname = listptr->hvec[ndx].objname;
305 listptr->hvec[ndx+1].objptr = listptr->hvec[ndx].objptr;
306 }
307 listptr->hvec[newndx].objname = wmlAllocateString (name);
308 listptr->hvec[newndx].objptr = obj;
309 listptr->cnt += 1;
310 return;
311 }
312 else
313 {
314 listptr->hvec[listptr->cnt].objname = wmlAllocateString (name);
315 listptr->hvec[listptr->cnt].objptr = obj;
316 listptr->cnt += 1;
317 return;
318 }
319
320 }
321
322
323 /*
324 * Routine to insert an entry into a token list. The insertion is ordered.
325 * This routine allows duplicates
326 *
327 * listptr the list
328 * name the name under which to insert
329 * obj the object to insert
330 */
wmlInsertInKeyList(listptr,name,obj)331 void wmlInsertInKeyList (listptr, name, obj)
332 DynamicHandleListDefPtr listptr;
333 char *name;
334 ObjectPtr obj;
335
336 {
337 int ndx; /* current index in list */
338 int londx; /* low index */
339 int hindx; /* high index */
340 int midndx = 0; /* midpoint index */
341 int newndx; /* new entry index */
342 int cmpres = 0; /* strcmp result */
343
344 /*
345 * Guarantee enough space in the list
346 */
347 wmlResizeHList (listptr, listptr->cnt+1);
348
349 /*
350 * Binary search and insert
351 */
352 if ( listptr->cnt == 0 )
353 {
354 listptr->hvec[0].objname = wmlAllocateString (name);
355 listptr->hvec[0].objptr = obj;
356 listptr->cnt += 1;
357 return;
358 }
359 for ( londx=0,hindx=listptr->cnt-1 ; hindx>=londx ; )
360 {
361 midndx = (londx+hindx) / 2;
362 cmpres = strcmp (name, listptr->hvec[midndx].objname);
363 if ( londx == hindx ) break;
364 if ( cmpres < 0 )
365 hindx = midndx - 1;
366 if ( cmpres >= 0 )
367 londx = midndx + 1;
368 }
369 /*
370 * The new entry will go either at midndx or after midndx. Move down
371 * the vector appropriately.
372 */
373 if ( cmpres < 0 )
374 newndx = midndx;
375 else
376 newndx = midndx + 1;
377 for ( ndx=listptr->cnt-1 ; ndx>=newndx ; ndx-- )
378 {
379 listptr->hvec[ndx+1].objname = listptr->hvec[ndx].objname;
380 listptr->hvec[ndx+1].objptr = listptr->hvec[ndx].objptr;
381 }
382 listptr->hvec[newndx].objname = wmlAllocateString (name);
383 listptr->hvec[newndx].objptr = obj;
384 listptr->cnt += 1;
385 return;
386 }
387
388
389 /*
390 * Indicate if a resource is in a resource reference list by returning its
391 * reference pointer.
392 */
393
wmlResolveResIsMember(resobj,resref)394 WmlClassResDefPtr wmlResolveResIsMember (resobj, resref)
395 WmlResourceDefPtr resobj;
396 WmlClassResDefPtr resref;
397
398 {
399
400 while ( resref != NULL )
401 {
402 if ( resref->act_resource == resobj ) return resref;
403 resref = resref->next;
404 }
405 return NULL;
406
407 }
408
409
410 /*
411 * Indicate if a child is in a child reference list by returning its
412 * reference pointer.
413 */
414
wmlResolveChildIsMember(childobj,childref)415 WmlClassChildDefPtr wmlResolveChildIsMember (childobj, childref)
416 WmlChildDefPtr childobj;
417 WmlClassChildDefPtr childref;
418
419 {
420
421 while ( childref != NULL )
422 {
423 if ( childref->act_child == childobj ) return childref;
424 childref = childref->next;
425 }
426 return NULL;
427
428 }
429
430
431