File: attr.c

package info (click to toggle)
xview 3.2p1.4-28.1
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd, wheezy
  • size: 26,680 kB
  • ctags: 34,403
  • sloc: ansic: 241,397; yacc: 1,435; sh: 1,086; makefile: 148; lex: 76; perl: 54; asm: 50; cpp: 15
file content (517 lines) | stat: -rw-r--r-- 14,638 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
#ifndef lint
#ifdef sccs
static char     sccsid[] = "@(#)attr.c 20.24 90/12/04";
#endif
#endif

/*
 *	(c) Copyright 1989 Sun Microsystems, Inc. Sun design patents 
 *	pending in the U.S. and foreign countries. See LEGAL NOTICE 
 *	file for terms of the license.
 */

#include <stdio.h>
#include <xview_private/i18n_impl.h>
#include <xview/pkg_public.h>
#include <xview/xv_error.h>
#include <xview_private/attr_impl.h>
#ifdef SVR4 
#include <stdlib.h> 
#endif /* SVR4 */


Xv_private FILE *xv_help_find_file();

#define ANBUFSIZE 64
static char     attr_name_buf[ANBUFSIZE];	/* to hold name of attribute */

Attr_avlist attr_make_count( listhead, listlen, valist, countptr )
    Attr_avlist     listhead;
    int             listlen;
    va_list         valist;
    int            *countptr;
{
    return( copy_va_to_av( valist, listhead, NULL ));
}

/*
 * attr_name - return a pointer to a string containing the name of
 * the specified attribute, or its hex value if not found.
 */
Xv_private char *
attr_name(attr)
    Attr_attribute attr;
{
    int		    attr_value;
    FILE	   *file_ptr;
    int		    found = FALSE;

    attr_name_buf[0] = 0;
    file_ptr = xv_help_find_file("attr_names");
    if (file_ptr) {
	while (fscanf(file_ptr, "%x %s\n", &attr_value, attr_name_buf) != EOF) {
	    if (found = (attr_value == attr))
		break;
	}
	fclose(file_ptr);
    }
    if (!found)
	sprintf(attr_name_buf, "attr # 0x%08x", attr);
    return attr_name_buf;
}


/* copy_va_to_av copies a varargs parameter list into an avlist. If the
   avlist parameter is NULL a new avlist is malloced and returned after
   the varargs list is copied into it. Attr1 exists because ANSI C requires
   that all varargs be preceded by a normal parameter, but some xview
   functions have only a varargs list as their parameters. So those 
   functions declare the first vararg parameter as a normal parameter, and
   pass it in to copy_va_to_av as attr1.
*/

Attr_attribute avlist_tmp[ATTR_STANDARD_SIZE];

Xv_private Attr_avlist copy_va_to_av( valist1, avlist1, attr1 )
   va_list valist1;
   Attr_avlist avlist1;
   Attr_attribute attr1;
{
   register Attr_attribute attr;
   register unsigned cardinality;
   register int i;
   int avlist_size;
   static va_list valist;
   static Attr_avlist avlist;
   static int arg_count = 0, arg_count_max = ATTR_STANDARD_SIZE,
              recursion_count = 0;

   recursion_count++;

   /* These two variables are used instead of the paramters so that the
      position in the lists is maintained after a recursive call. 
   */
#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
   __va_copy(valist, valist1);
#else
   valist = valist1;
#endif   
   avlist = avlist1;

   if( !avlist )
      avlist = avlist_tmp;

   if( attr1 )
      attr = attr1;
   else
      attr = va_arg( valist, Attr_attribute );

   while( attr )
   {
      if( ++arg_count > arg_count_max )
      {
         xv_error( NULL,
                   ERROR_STRING, XV_MSG(
              "A/V list more than 250 elements long, extra elements ignored"),
                   0);
         return( avlist1 );
      }
      cardinality = ATTR_CARDINALITY(attr);

      switch (ATTR_LIST_TYPE(attr))
      {
         case ATTR_NONE:       /* not a list */
            *avlist++ = attr;

            if(( arg_count += cardinality ) > arg_count_max )
            {
               xv_error( NULL,
                         ERROR_STRING, XV_MSG(
               "A/V list more than 250 elements long, extra elements ignored"),
                         0);
               return( avlist1 );
            }
            for( i=0; i < cardinality; i++ )
               *avlist++ = va_arg( valist, Attr_attribute );
            break;

         case ATTR_NULL:       /* null terminated list */
            *avlist++ = attr; 
            switch (ATTR_LIST_PTR_TYPE(attr))
            {
               case ATTR_LIST_IS_INLINE:
                  /*
                   * Note that this only checks the first four bytes for the
                   * null termination. Copy each value element until we have
                   * copied the null termination.
                   */
                  do {
                      if(( arg_count += cardinality ) > arg_count_max )
                      {
                         xv_error( NULL,
                                   ERROR_STRING, XV_MSG(
              "A/V list more than 250 elements long, extra elements ignored"),
                                   0);
                         return( avlist1 );
                      }
                      for( i=0; i < cardinality; i++ )
                         *avlist++ = va_arg( valist, Attr_attribute );
                  } while (*(avlist - 1));
                  break;

               case ATTR_LIST_IS_PTR:
                  if( ++arg_count  > arg_count_max )
                  {
                     xv_error( NULL,
                               ERROR_STRING, XV_MSG(
              "A/V list more than 250 elements long, extra elements ignored"),
                               0);
                     return( avlist1 );
                  }
                  *avlist++ = va_arg( valist, Attr_attribute );
                  break;
            }
            break;

         case ATTR_COUNTED:    /* counted list */
            *avlist++ = attr;
            switch (ATTR_LIST_PTR_TYPE(attr)) {
               case ATTR_LIST_IS_INLINE:
               {
                  register unsigned count;

                  if( ++arg_count  > arg_count_max )
                  {
                     xv_error( NULL,
                               ERROR_STRING, XV_MSG(
              "A/V list more than 250 elements long, extra elements ignored"),
                               0);
                     return( avlist1 );
                  }
                  *avlist = va_arg( valist, Attr_attribute ); /*copy the count*/
                  count = ((unsigned) *avlist++) * cardinality;

                  if(( arg_count += count ) > arg_count_max )
                  {
                     xv_error( NULL,
                               ERROR_STRING, XV_MSG(
              "A/V list more than 250 elements long, extra elements ignored"),
                               0);
                     return( avlist1 );
                  }
                  for( i=0; i < count; i++ )
                     *avlist++ = va_arg( valist, Attr_attribute );
                }
                break;

                case ATTR_LIST_IS_PTR:
                   if( ++arg_count  > arg_count_max )
                   {
                      xv_error( NULL,
                                ERROR_STRING, XV_MSG(
              "A/V list more than 250 elements long, extra elements ignored"),
                                0);
                      return( avlist1 );
                   }
                   *avlist++ = va_arg( valist, Attr_attribute );
                   break;
             }
             break;

          case ATTR_RECURSIVE:  /* recursive attribute-value list */
             if (cardinality != 0)       /* don't strip it */
                *avlist++ = attr;

             switch (ATTR_LIST_PTR_TYPE(attr))
             {
                case ATTR_LIST_IS_INLINE:
                   (void) copy_va_to_av(valist, avlist, 0);
                   if (cardinality != 0)   /* don't strip it */
                      avlist++;     /* move past the null terminator */
                   break;

                case ATTR_LIST_IS_PTR:
                   if (cardinality != 0)   /* don't collapse inline */
                   {
                      if( ++arg_count  > arg_count_max )
                      {
                         xv_error( NULL,
                                   ERROR_STRING, XV_MSG(
              "A/V list more than 250 elements long, extra elements ignored"),
                                   0);
                         return( avlist1 );
                      }
                      *avlist++ = va_arg( valist, Attr_attribute );
                   }
                   else
                   {
                      attr = va_arg( valist, Attr_attribute );
                      if (attr)
                         /*
                          * Copy the list inline -- don't move past the null
                          * termintor. Here both the attribute and null
                          * terminator will be stripped away.
                          */
                         avlist = attr_copy_avlist(avlist, (Attr_avlist) attr);
                  }
                  break;
            }
            break;
      }

      attr = va_arg( valist, Attr_attribute );
   }    

   *avlist = NULL;
   if( !avlist1 )
   {
      avlist_size = (( avlist - avlist_tmp ) + 1 ) * sizeof( Attr_attribute );
      avlist1 = xv_malloc( avlist_size );
      XV_BCOPY( avlist_tmp, avlist1, avlist_size );
   }

   if( --recursion_count == 0 )
   {
      arg_count = 0;
      arg_count_max = ATTR_STANDARD_SIZE;
   }

   return( avlist1 );
}



/*
 * attr_copy_avlist copies the attribute-value list from avlist to dest.
 * Recursive lists are collapsed into dest.
 */

Attr_avlist
attr_copy_avlist(dest, avlist)
    register Attr_avlist dest;
    register Attr_avlist avlist;
{
    register Attr_attribute attr;
    register unsigned cardinality;

    while (attr = (Attr_attribute) avlist_get(avlist)) {
	cardinality = ATTR_CARDINALITY(attr);
	switch (ATTR_LIST_TYPE(attr)) {
	  case ATTR_NONE:	/* not a list */
	    *dest++ = attr;
	    avlist_copy_values(avlist, dest, cardinality);
	    break;

	  case ATTR_NULL:	/* null terminated list */
	    *dest++ = attr;
	    switch (ATTR_LIST_PTR_TYPE(attr)) {
	      case ATTR_LIST_IS_INLINE:
		/*
		 * Note that this only checks the first four bytes for the
		 * null termination. Copy each value element until we have
		 * copied the null termination.
		 */
		do {
		    avlist_copy_values(avlist, dest, cardinality);
		} while (*(dest - 1));
		break;

	      case ATTR_LIST_IS_PTR:
		*dest++ = avlist_get(avlist);
		break;
	    }
	    break;

	  case ATTR_COUNTED:	/* counted list */
	    *dest++ = attr;
	    switch (ATTR_LIST_PTR_TYPE(attr)) {
	      case ATTR_LIST_IS_INLINE:{
		    register unsigned count;

		    *dest = avlist_get(avlist);	/* copy the count */
		    count = ((unsigned) *dest++) * cardinality;
		    avlist_copy_values(avlist, dest, count);
		}
		break;

	      case ATTR_LIST_IS_PTR:
		*dest++ = avlist_get(avlist);
		break;
	    }
	    break;

	  case ATTR_RECURSIVE:	/* recursive attribute-value list */
	    if (cardinality != 0)	/* don't strip it */
		*dest++ = attr;

	    switch (ATTR_LIST_PTR_TYPE(attr)) {
	      case ATTR_LIST_IS_INLINE:
		dest = attr_copy_avlist(dest, avlist);
		if (cardinality != 0)	/* don't strip it */
		    dest++;	/* move past the null terminator */
		avlist = attr_skip(attr, avlist);
		break;

	      case ATTR_LIST_IS_PTR:
		if (cardinality != 0)	/* don't collapse inline */
		    *dest++ = avlist_get(avlist);
		else {
		    Attr_avlist     new_avlist = (Attr_avlist)
		    avlist_get(avlist);
		    if (new_avlist)
			/*
			 * Copy the list inline -- don't move past the null
			 * termintor. Here both the attribute and null
			 * terminator will be stripped away.
			 */
			dest = attr_copy_avlist(dest, new_avlist);
		}
		break;
	    }
	    break;
	}
    }
    *dest = 0;
    return (dest);
}


/*
 * attr_count counts the number of slots in the av-list avlist. Recursive
 * lists are counted as being collapsed inline.
 */
int
attr_count(avlist)
    Attr_avlist     avlist;
{
    /* count the null termination */
    return (attr_count_avlist(avlist, (Attr_attribute) NULL) + 1);
}


int
attr_count_avlist(avlist, last_attr)
    register Attr_avlist avlist;
    register Attr_attribute last_attr;  /* BUG ALERT: Not used any more */
{
    register Attr_attribute attr;
    register unsigned count = 0;
    register unsigned num;
    register unsigned cardinality;

    while (attr = (Attr_attribute) * avlist++) {
	count++;		/* count the attribute */
	cardinality = ATTR_CARDINALITY(attr);
	last_attr = attr;
	switch (ATTR_LIST_TYPE(attr)) {
	  case ATTR_NONE:	/* not a list */
	    count += cardinality;
	    avlist += cardinality;
	    break;

	  case ATTR_NULL:	/* null terminated list */
	    switch (ATTR_LIST_PTR_TYPE(attr)) {
	      case ATTR_LIST_IS_INLINE:
		/*
		 * Note that this only checks the first four bytes for the
		 * null termination.
		 */
		while (*avlist++)
		    count++;
		count++;	/* count the null terminator */
		break;

	      case ATTR_LIST_IS_PTR:
		count++;
		avlist++;
		break;
	    }
	    break;

	  case ATTR_COUNTED:	/* counted list */
	    switch (ATTR_LIST_PTR_TYPE(attr)) {
	      case ATTR_LIST_IS_INLINE:
		num = ((unsigned) (*avlist)) * cardinality + 1;
		count += num;
		avlist += num;
		break;
	      case ATTR_LIST_IS_PTR:
		count++;
		avlist++;
		break;
	    }
	    break;

	  case ATTR_RECURSIVE:	/* recursive attribute-value list */
	    if (cardinality == 0)	/* don't include the attribute */
		count--;

	    switch (ATTR_LIST_PTR_TYPE(attr)) {
	      case ATTR_LIST_IS_INLINE:
		count += attr_count_avlist(avlist, attr);
		if (cardinality != 0)	/* count the null terminator */
		    count++;
		avlist = attr_skip(attr, avlist);
		break;

	      case ATTR_LIST_IS_PTR:
		if (cardinality != 0) {	/* don't collapse inline */
		    count++;
		    avlist++;
		} else if (*avlist)
		    /*
		     * Here we count the elements of the recursive list as
		     * being inline. Don't count the null terminator.
		     */
		    count += attr_count_avlist((Attr_avlist) * avlist++,
					       attr);
		else
		    avlist++;
		break;
	    }
	    break;
	}
    }
    return count;
}


/*
 * attr_skip_value returns a pointer to the attribute after the value pointed
 * to by avlist.  attr should be the attribute which describes the value at
 * avlist.
 */
Attr_avlist
attr_skip_value(attr, avlist)
    register Attr_attribute attr;
    register Attr_avlist avlist;
{
    switch (ATTR_LIST_TYPE(attr)) {
      case ATTR_NULL:
	if (ATTR_LIST_PTR_TYPE(attr) == ATTR_LIST_IS_PTR)
	    avlist++;
	else
	    while (*avlist++);
	break;

      case ATTR_RECURSIVE:
	if (ATTR_LIST_PTR_TYPE(attr) == ATTR_LIST_IS_PTR)
	    avlist++;
	else
	    while (attr = (Attr_attribute) * avlist++)
		avlist = attr_skip_value(attr, avlist);
	break;

      case ATTR_COUNTED:
	if (ATTR_LIST_PTR_TYPE(attr) == ATTR_LIST_IS_PTR)
	    avlist++;
	else
	    avlist += ((int) *avlist) * ATTR_CARDINALITY(attr) + 1;
	break;

      case ATTR_NONE:
	avlist += ATTR_CARDINALITY(attr);
	break;
    }
    return avlist;
}