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