Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – tendra.SVN – Blame – //branches/tendra4/src/utilities/calculus/common.c – Rev 2

Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
#include "config.h"
32
#include "calculus.h"
33
#include "error.h"
34
#include "common.h"
35
#include "type_ops.h"
36
#include "xalloc.h"
37
 
38
 
39
/*
40
    TYPE REPRESENTING A LIST OF ALGEBRAS
41
 
42
    This type is used to represent the list of all algebras.
43
*/
44
 
45
typedef struct ALGEBRA_LIST_tag {
46
    ALGEBRA_DEFN alg ;
47
    struct ALGEBRA_LIST_tag *next ;
48
} ALGEBRA_LIST ;
49
 
50
 
51
/*
52
    CURRENT ALGEBRA
53
 
54
    The variable algebra holds all the information on the algebra read
55
    from the input file.  The list all_algebras contains a list of all
56
    the algebras defined.
57
*/
58
 
59
ALGEBRA_DEFN *algebra = NULL ;
60
static ALGEBRA_LIST *all_algebras = NULL ;
61
 
62
 
63
/*
64
    CREATE A NEW ALGEBRA
65
 
66
    This routine allocates and initialises a new algebra structure.
67
*/
68
 
69
void new_algebra
70
    PROTO_Z ()
71
{
72
    ALGEBRA_LIST *p = xmalloc_nof ( ALGEBRA_LIST, 1 ) ;
73
    p->alg.name = "ALGEBRA" ;
74
    p->alg.major_no = 1 ;
75
    p->alg.minor_no = 0 ;
76
    p->alg.primitives = NULL_list ( PRIMITIVE_P ) ;
77
    p->alg.identities = NULL_list ( IDENTITY_P ) ;
78
    p->alg.enumerations = NULL_list ( ENUM_P ) ;
79
    p->alg.structures = NULL_list ( STRUCTURE_P ) ;
80
    p->alg.unions = NULL_list ( UNION_P ) ;
81
    p->alg.types = NULL_list ( TYPE_P ) ;
82
    p->next = all_algebras ;
83
    all_algebras = p ;
84
    algebra = &( p->alg ) ;
85
    return ;
86
}
87
 
88
 
89
/*
90
    LOOK UP AN ALGEBRA
91
 
92
    This routine looks up the algebra named nm.  It returns null if the
93
    algebra has not been defined.
94
*/
95
 
96
ALGEBRA_DEFN *find_algebra
97
    PROTO_N ( ( nm ) )
98
    PROTO_T ( char *nm )
99
{
100
    ALGEBRA_LIST *p ;
101
    for ( p = all_algebras ; p != NULL ; p = p->next ) {
102
	if ( streq ( p->alg.name, nm ) ) return ( &( p->alg ) ) ;
103
    }
104
    return ( NULL ) ;
105
}
106
 
107
 
108
/*
109
    LAST IDENTIFIER
110
 
111
    This variable is set by name_type and name_aux_type to the identifier
112
    of the last non-composite type looked up.
113
*/
114
 
115
static CLASS_ID_P last_id = NULL_ptr ( CLASS_ID ) ;
116
 
117
 
118
/*
119
    REGISTER A TYPE
120
 
121
    This routine adds the type t to the list of all types.
122
*/
123
 
124
TYPE_P register_type
125
    PROTO_N ( ( t ) )
126
    PROTO_T ( TYPE_P t )
127
{
128
    char *nm = name_type ( t ) ;
129
    CLASS_ID_P id = last_id ;
130
    LIST ( TYPE_P ) r = algebra->types ;
131
    while ( !IS_NULL_list ( r ) ) {
132
	TYPE_P s = DEREF_ptr ( HEAD_list ( r ) ) ;
133
	if ( streq ( name_type ( s ), nm ) ) {
134
 
135
	    /* Check for multiple definition */
136
	    if ( !IS_type_undef ( DEREF_type ( s ) ) ) {
137
		char *fn1 = DEREF_string ( cid_file ( id ) ) ;
138
		int ln1 = DEREF_int ( cid_line ( id ) ) ;
139
		char *fn2 = DEREF_string ( cid_file ( last_id ) ) ;
140
		int ln2 = DEREF_int ( cid_line ( last_id ) ) ;
141
		if ( fn2 == crt_file_name ) {
142
		    char *fn = fn1 ;
143
		    int ln = ln1 ;
144
		    fn1 = fn2 ;
145
		    ln1 = ln2 ;
146
		    fn2 = fn ;
147
		    ln2 = ln ;
148
		}
149
		error_posn ( ERROR_SERIOUS, fn1, ln1,
150
			     "Type %s already defined (at %s, line %d)",
151
			     nm, fn2, ln2 ) ;
152
	    }
153
 
154
	    COPY_type ( s, DEREF_type ( t ) ) ;
155
	    return ( s ) ;
156
	}
157
	r = TAIL_list ( r ) ;
158
    }
159
    CONS_ptr ( t, algebra->types, algebra->types ) ;
160
    return ( t ) ;
161
}
162
 
163
 
164
/*
165
    LOOK UP A NAMED TYPE
166
 
167
    This routine looks up the type named nm in the list of all types
168
    associated with the algebra alg.  The type is created if necessary,
169
    and the result is returned.
170
*/
171
 
172
TYPE_P find_type
173
    PROTO_N ( ( alg, nm ) )
174
    PROTO_T ( ALGEBRA_DEFN *alg X char *nm )
175
{
176
    TYPE s0 ;
177
    TYPE_P s ;
178
    LIST ( TYPE_P ) t = alg->types ;
179
    while ( !IS_NULL_list ( t ) ) {
180
	s = DEREF_ptr ( HEAD_list ( t ) ) ;
181
	if ( streq ( name_type ( s ), nm ) ) return ( s ) ;
182
	t = TAIL_list ( t ) ;
183
    }
184
    s = MAKE_ptr ( SIZE_type ) ;
185
    MAKE_type_undef ( 0, nm, s0 ) ;
186
    COPY_type ( s, s0 ) ;
187
    s = register_type ( s ) ;
188
    return ( s ) ;
189
}
190
 
191
 
192
/*
193
    DOES A TYPE INVOLVE AN IDENTITY
194
 
195
    This routine checks whether the type t is an identity or a compound
196
    type derived from an identity.
197
*/
198
 
199
int is_identity_type
200
    PROTO_N ( ( t ) )
201
    PROTO_T ( TYPE_P t )
202
{
203
    TYPE t0 = DEREF_type ( t ) ;
204
    while ( IS_type_ptr_etc ( t0 ) ) {
205
	t0 = DEREF_type ( DEREF_ptr ( type_ptr_etc_sub ( t0 ) ) ) ;
206
    }
207
    return ( IS_type_ident ( t0 ) ) ;
208
}
209
 
210
 
211
/*
212
    DEAL WITH COMPOUND TYPES INVOLVING IDENTITIES
213
 
214
    From the point of view of the list of all types, identity types are
215
    distinct from their definitions.  This routine is called after creating
216
    a compound type, r, to ensure that the corresponding type with any
217
    identities replaced by their definition is also created.
218
*/
219
 
220
static TYPE_P compound_identity
221
    PROTO_N ( ( r, depth ) )
222
    PROTO_T ( TYPE_P r X int depth )
223
{
224
    TYPE r0 = DEREF_type ( r ) ;
225
    if ( depth > MAX_TYPE_DEPTH ) {
226
	error ( ERROR_SERIOUS, "Cyclic type definition involving %s",
227
		name_type ( r ) ) ;
228
	return ( NULL_ptr ( TYPE ) ) ;
229
    }
230
    if ( IS_type_ident ( r0 ) ) {
231
	IDENTITY_P a = DEREF_ptr ( type_ident_id ( DEREF_type ( r ) ) ) ;
232
	TYPE_P s = DEREF_ptr ( ident_defn ( a ) ) ;
233
	return ( s ) ;
234
    }
235
    if ( IS_type_ptr_etc ( r0 ) ) {
236
	unsigned tag = TAG_type ( r0 ) ;
237
	TYPE_P s = DEREF_ptr ( type_ptr_etc_sub ( r0 ) ) ;
238
	s = compound_identity ( s, depth ) ;
239
	if ( !IS_NULL_ptr ( s ) ) {
240
	    return ( compound_type ( tag, s, depth + 1 ) ) ;
241
	}
242
    }
243
    return ( NULL_ptr ( TYPE ) ) ;
244
}
245
 
246
 
247
/*
248
    CREATE A COMPOUND TYPE
249
 
250
    This routine creates a compound type from the type operation indicated
251
    by tag and the sub-type r.  The routine is designed to ensure that
252
    only one copy of each type is created.
253
*/
254
 
255
TYPE_P compound_type
256
    PROTO_N ( ( tag, r, depth ) )
257
    PROTO_T ( unsigned tag X TYPE_P r X int depth )
258
{
259
    TYPE s0 ;
260
    TYPE_P s ;
261
    LIST ( TYPE_P ) t = algebra->types ;
262
 
263
    /* Search for uses */
264
    while ( !IS_NULL_list ( t ) ) {
265
	s = DEREF_ptr ( HEAD_list ( t ) ) ;
266
	s0 = DEREF_type ( s ) ;
267
	if ( TAG_type ( s0 ) == tag ) {
268
	    TYPE_P rr = DEREF_ptr ( type_ptr_etc_sub ( s0 ) ) ;
269
	    if ( EQ_ptr ( r, rr ) ) return ( s ) ;
270
	}
271
	t = TAIL_list ( t ) ;
272
    }
273
    s = MAKE_ptr ( SIZE_type ) ;
274
    MAKE_type_ptr_etc ( tag, 0, r, s0 ) ;
275
    COPY_type ( s, s0 ) ;
276
    CONS_ptr ( s, algebra->types, algebra->types ) ;
277
    ( void ) compound_identity ( s, depth ) ;
278
    return ( s ) ;
279
}
280
 
281
 
282
/*
283
    CHECK FOR UNDEFINED TYPES
284
 
285
    This routine scans the list of all types for any which remain undefined
286
    at the end of the compilation.  It also calculates the sizes of all
287
    the defined types.
288
*/
289
 
290
void check_types
291
    PROTO_Z ()
292
{
293
    LIST ( TYPE_P ) t = algebra->types ;
294
    while ( !IS_NULL_list ( t ) ) {
295
	TYPE_P s = DEREF_ptr ( HEAD_list ( t ) ) ;
296
	TYPE s0 = DEREF_type ( s ) ;
297
	if ( IS_type_undef ( s0 ) ) {
298
	    char *nm = name_type ( s ) ;
299
	    error ( ERROR_SERIOUS, "Type %s used but not defined", nm ) ;
300
	} else {
301
	    int sz = size_type ( s, 0 ) ;
302
	    COPY_int ( type_size ( s0 ), sz ) ;
303
	}
304
	t = TAIL_list ( t ) ;
305
    }
306
    return ;
307
}
308
 
309
 
310
/*
311
    FIND LIST OF DERIVED TYPES
312
 
313
    This routine builds up a list of all the types used in the derivation
314
    of t.
315
*/
316
 
317
static LIST ( TYPE_P ) derived_types
318
    PROTO_N ( ( t, p ) )
319
    PROTO_T ( TYPE_P t X LIST ( TYPE_P ) p )
320
{
321
    TYPE t0 ;
322
    unsigned tag ;
323
    LIST ( TYPE_P ) q = p ;
324
    while ( !IS_NULL_list ( q ) ) {
325
	TYPE_P s = DEREF_ptr ( HEAD_list ( q ) ) ;
326
	if ( EQ_ptr ( s, t ) ) return ( p ) ;
327
	q = TAIL_list ( q ) ;
328
    }
329
    CONS_ptr ( t, p, p ) ;
330
    t0 = DEREF_type ( t ) ;
331
    tag = TAG_type ( t0 ) ;
332
    switch ( tag ) {
333
 
334
	case type_ident_tag : {
335
	    /* Identity definition */
336
	    IDENTITY_P r = DEREF_ptr ( type_ident_id ( t0 ) ) ;
337
	    TYPE_P s = DEREF_ptr ( ident_defn ( r ) ) ;
338
	    p = derived_types ( s, p ) ;
339
	    break ;
340
	}
341
 
342
	case type_structure_tag : {
343
	    /* Structure components */
344
	    STRUCTURE_P r = DEREF_ptr ( type_structure_struc ( t0 ) ) ;
345
	    LIST ( COMPONENT_P ) c = DEREF_list ( str_defn ( r ) ) ;
346
	    while ( !IS_NULL_list ( c ) ) {
347
		COMPONENT_P cmp = DEREF_ptr ( HEAD_list ( c ) ) ;
348
		TYPE_P s = DEREF_ptr ( cmp_type ( cmp ) ) ;
349
		p = derived_types ( s, p ) ;
350
		c = TAIL_list ( c ) ;
351
	    }
352
	    break ;
353
	}
354
 
355
	case type_onion_tag : {
356
	    /* Union components, fields and maps */
357
	    UNION_P r = DEREF_ptr ( type_onion_un ( t0 ) ) ;
358
	    LIST ( COMPONENT_P ) c = DEREF_list ( un_s_defn ( r ) ) ;
359
	    LIST ( FIELD_P ) f = DEREF_list ( un_u_defn ( r ) ) ;
360
	    LIST ( MAP_P ) m = DEREF_list ( un_map ( r ) ) ;
361
	    while ( !IS_NULL_list ( c ) ) {
362
		COMPONENT_P cmp = DEREF_ptr ( HEAD_list ( c ) ) ;
363
		TYPE_P s = DEREF_ptr ( cmp_type ( cmp ) ) ;
364
		p = derived_types ( s, p ) ;
365
		c = TAIL_list ( c ) ;
366
	    }
367
	    while ( !IS_NULL_list ( f ) ) {
368
		FIELD_P fld = DEREF_ptr ( HEAD_list ( f ) ) ;
369
		c = DEREF_list ( fld_defn ( fld ) ) ;
370
		while ( !IS_NULL_list ( c ) ) {
371
		    COMPONENT_P cmp = DEREF_ptr ( HEAD_list ( c ) ) ;
372
		    TYPE_P s = DEREF_ptr ( cmp_type ( cmp ) ) ;
373
		    p = derived_types ( s, p ) ;
374
		    c = TAIL_list ( c ) ;
375
		}
376
		f = TAIL_list ( f ) ;
377
	    }
378
	    while ( !IS_NULL_list ( m ) ) {
379
		MAP_P map = DEREF_ptr ( HEAD_list ( m ) ) ;
380
		LIST ( ARGUMENT_P ) a = DEREF_list ( map_args ( map ) ) ;
381
		TYPE_P s = DEREF_ptr ( map_ret_type ( map ) ) ;
382
		p = derived_types ( s, p ) ;
383
		while ( !IS_NULL_list ( a ) ) {
384
		    ARGUMENT_P arg = DEREF_ptr ( HEAD_list ( a ) ) ;
385
		    s = DEREF_ptr ( arg_type ( arg ) ) ;
386
		    p = derived_types ( s, p ) ;
387
		    a = TAIL_list ( a ) ;
388
		}
389
		m = TAIL_list ( m ) ;
390
	    }
391
	    break ;
392
	}
393
 
394
	case type_list_tag :
395
	case type_ptr_tag :
396
	case type_stack_tag :
397
	case type_vec_tag :
398
	case type_vec_ptr_tag : {
399
	    /* Pointer subtypes */
400
	    TYPE_P s = DEREF_ptr ( type_ptr_etc_sub ( t0 ) ) ;
401
	    p = derived_types ( s, p ) ;
402
	    break ;
403
	}
404
    }
405
    return ( p ) ;
406
}
407
 
408
 
409
/*
410
    IMPORT A LIST OF TYPES
411
 
412
    This routine imports all the types in the list t.
413
*/
414
 
415
static void import_type_list
416
    PROTO_N ( ( t ) )
417
    PROTO_T ( LIST ( TYPE_P ) t )
418
{
419
    while ( !IS_NULL_list ( t ) ) {
420
	TYPE_P s = DEREF_ptr ( HEAD_list ( t ) ) ;
421
	TYPE s0 = DEREF_type ( s ) ;
422
	unsigned tag = TAG_type ( s0 ) ;
423
	switch ( tag ) {
424
	    case type_primitive_tag : {
425
		PRIMITIVE_P p = DEREF_ptr ( type_primitive_prim ( s0 ) ) ;
426
		CONS_ptr ( p, algebra->primitives, algebra->primitives ) ;
427
		goto register_lab ;
428
	    }
429
	    case type_ident_tag : {
430
		IDENTITY_P p = DEREF_ptr ( type_ident_id ( s0 ) ) ;
431
		CONS_ptr ( p, algebra->identities, algebra->identities ) ;
432
		goto register_lab ;
433
	    }
434
	    case type_enumeration_tag : {
435
		ENUM_P p = DEREF_ptr ( type_enumeration_en ( s0 ) ) ;
436
		CONS_ptr ( p, algebra->enumerations, algebra->enumerations ) ;
437
		goto register_lab ;
438
	    }
439
	    case type_structure_tag : {
440
		STRUCTURE_P p = DEREF_ptr ( type_structure_struc ( s0 ) ) ;
441
		CONS_ptr ( p, algebra->structures, algebra->structures ) ;
442
		goto register_lab ;
443
	    }
444
	    case type_onion_tag : {
445
		UNION_P p = DEREF_ptr ( type_onion_un ( s0 ) ) ;
446
		CONS_ptr ( p, algebra->unions, algebra->unions ) ;
447
		goto register_lab ;
448
	    }
449
	    register_lab : {
450
		TYPE_P r = register_type ( s ) ;
451
		if ( !EQ_ptr ( r, s ) ) {
452
		    error ( ERROR_SERIOUS,
453
			    "Can't import previously used type %s",
454
			    name_type ( s ) ) ;
455
		}
456
		break ;
457
	    }
458
	    default : {
459
		TYPE_P p = DEREF_ptr ( type_ptr_etc_sub ( s0 ) ) ;
460
		( void ) compound_type ( tag, p, 0 ) ;
461
		break ;
462
	    }
463
	}
464
	t = TAIL_list ( t ) ;
465
    }
466
    return ;
467
}
468
 
469
 
470
/*
471
    IMPORT A SINGLE ITEM FROM AN ALGEBRA
472
 
473
    This routine imports the type named nm from the algebra alg into the
474
    current algebra.
475
*/
476
 
477
void import_type
478
    PROTO_N ( ( alg, nm ) )
479
    PROTO_T ( char *alg X char *nm )
480
{
481
    TYPE_P t ;
482
    LIST ( TYPE_P ) p ;
483
    ALGEBRA_DEFN *a = find_algebra ( alg ) ;
484
    if ( a == NULL ) {
485
	error ( ERROR_SERIOUS, "Algebra %s not defined", alg ) ;
486
	return ;
487
    } else if ( a == algebra ) {
488
	error ( ERROR_SERIOUS, "Can't import from current algebra" ) ;
489
	return ;
490
    }
491
    t = find_type ( a, nm ) ;
492
    if ( IS_type_undef ( DEREF_type ( t ) ) ) {
493
	error ( ERROR_SERIOUS, "Type %s::%s not defined", alg, nm ) ;
494
	return ;
495
    }
496
    p = derived_types ( t, NULL_list ( TYPE_P ) ) ;
497
    import_type_list ( p ) ;
498
    while ( !IS_NULL_list ( p ) ) {
499
	DESTROY_CONS_ptr ( destroy_calculus, t, p, p ) ;
500
	UNUSED ( t ) ;
501
    }
502
    return ;
503
}
504
 
505
 
506
/*
507
    IMPORT AN ENTIRE ALGEBRA
508
 
509
    This routine imports all the types in the algebra alg into the current
510
    algebra.
511
*/
512
 
513
void import_algebra
514
    PROTO_N ( ( alg ) )
515
    PROTO_T ( char *alg )
516
{
517
    ALGEBRA_DEFN *a = find_algebra ( alg ) ;
518
    if ( a == NULL ) {
519
	error ( ERROR_SERIOUS, "Algebra %s not defined", alg ) ;
520
	return ;
521
    } else if ( a == algebra ) {
522
	error ( ERROR_SERIOUS, "Can't import from current algebra" ) ;
523
	return ;
524
    }
525
    import_type_list ( a->types ) ;
526
    return ;
527
}
528
 
529
 
530
/*
531
    FIND THE SIZE OF A TYPE
532
 
533
    This routine calculates the size of the type t.
534
*/
535
 
536
int size_type
537
    PROTO_N ( ( t, depth ) )
538
    PROTO_T ( TYPE_P t X int depth )
539
{
540
    TYPE t0 = DEREF_type ( t ) ;
541
    int sz = DEREF_int ( type_size ( t0 ) ) ;
542
    if ( sz ) return ( sz ) ;
543
 
544
    if ( depth > MAX_TYPE_DEPTH ) {
545
	error ( ERROR_SERIOUS, "Cyclic type definition involving %s",
546
		name_type ( t ) ) ;
547
	return ( 1 ) ;
548
    }
549
 
550
    switch ( TAG_type ( t0 ) ) {
551
	case type_ident_tag : {
552
	    IDENTITY_P i = DEREF_ptr ( type_ident_id ( t0 ) ) ;
553
	    TYPE_P_P s = ident_defn ( i ) ;
554
	    sz = size_type ( DEREF_ptr ( s ), depth + 1 ) ;
555
	    break ;
556
	}
557
 
558
	case type_structure_tag : {
559
	    STRUCTURE_P str = DEREF_ptr ( type_structure_struc ( t0 ) ) ;
560
	    LIST ( COMPONENT_P ) c = DEREF_list ( str_defn ( str ) ) ;
561
	    sz = 0 ;
562
	    while ( !IS_NULL_list ( c ) ) {
563
		TYPE_P_P s ;
564
		s = cmp_type ( DEREF_ptr ( HEAD_list ( c ) ) ) ;
565
		sz += size_type ( DEREF_ptr ( s ), depth + 1 ) ;
566
		c = TAIL_list ( c ) ;
567
	    }
568
	    break ;
569
	}
570
 
571
	case type_primitive_tag : sz = SIZE_PRIM ; break ;
572
	case type_enumeration_tag : sz = SIZE_ENUM ; break ;
573
	case type_onion_tag : sz = SIZE_UNION ; break ;
574
	case type_ptr_tag : sz = SIZE_PTR ; break ;
575
	case type_list_tag : sz = SIZE_LIST ; break ;
576
	case type_stack_tag : sz = SIZE_STACK ; break ;
577
	case type_vec_tag : sz = SIZE_VEC ; break ;
578
	case type_vec_ptr_tag : sz = SIZE_VEC_PTR ; break ;
579
 
580
	default : {
581
	    error ( ERROR_SERIOUS, "Can't take size of type %s",
582
		    name_type ( t ) ) ;
583
	    sz = 1 ;
584
	    break ;
585
	}
586
    }
587
    return ( sz ) ;
588
}
589
 
590
 
591
/*
592
    FIND THE NAME OF A TYPE
593
 
594
    This routine finds the long name of the type t.
595
*/
596
 
597
char *name_type
598
    PROTO_N ( ( t ) )
599
    PROTO_T ( TYPE_P t )
600
{
601
    CLASS_ID_P id ;
602
    TYPE t0 = DEREF_type ( t ) ;
603
    switch ( TAG_type ( t0 ) ) EXHAUSTIVE {
604
	case type_primitive_tag : {
605
	    PRIMITIVE_P a = DEREF_ptr ( type_primitive_prim ( t0 ) ) ;
606
	    id = DEREF_ptr ( prim_id ( a ) ) ;
607
	    break ;
608
	}
609
	case type_ident_tag : {
610
	    IDENTITY_P a = DEREF_ptr ( type_ident_id ( t0 ) ) ;
611
	    id = DEREF_ptr ( ident_id ( a ) ) ;
612
	    break ;
613
	}
614
	case type_enumeration_tag : {
615
	    ENUM_P a = DEREF_ptr ( type_enumeration_en ( t0 ) ) ;
616
	    id = DEREF_ptr ( en_id ( a ) ) ;
617
	    break ;
618
	}
619
	case type_structure_tag : {
620
	    STRUCTURE_P a = DEREF_ptr ( type_structure_struc ( t0 ) ) ;
621
	    id = DEREF_ptr ( str_id ( a ) ) ;
622
	    break ;
623
	}
624
	case type_onion_tag : {
625
	    UNION_P a = DEREF_ptr ( type_onion_un ( t0 ) ) ;
626
	    id = DEREF_ptr ( un_id ( a ) ) ;
627
	    break ;
628
	}
629
	case type_quote_tag : {
630
	    char *a = DEREF_string ( type_quote_defn ( t0 ) ) ;
631
	    return ( a ) ;
632
	}
633
	case type_ptr_tag : {
634
	    return ( "PTR" ) ;
635
	}
636
	case type_list_tag : {
637
	    return ( "LIST" ) ;
638
	}
639
	case type_stack_tag : {
640
	    return ( "STACK" ) ;
641
	}
642
	case type_vec_tag : {
643
	    return ( "VEC" ) ;
644
	}
645
	case type_vec_ptr_tag : {
646
	    return ( "VEC_PTR" ) ;
647
	}
648
	case type_undef_tag : {
649
	    char *a = DEREF_string ( type_undef_name ( t0 ) ) ;
650
	    return ( a ) ;
651
	}
652
    }
653
    last_id = id ;
654
    return ( DEREF_string ( cid_name ( id ) ) ) ;
655
}
656
 
657
 
658
/*
659
    FIND THE AUXILIARY NAME OF A TYPE
660
 
661
    This routine finds the short name of the type t.
662
*/
663
 
664
char *name_aux_type
665
    PROTO_N ( ( t ) )
666
    PROTO_T ( TYPE_P t )
667
{
668
    CLASS_ID_P id ;
669
    TYPE t0 = DEREF_type ( t ) ;
670
    switch ( TAG_type ( t0 ) ) EXHAUSTIVE {
671
	case type_primitive_tag : {
672
	    PRIMITIVE_P a = DEREF_ptr ( type_primitive_prim ( t0 ) ) ;
673
	    id = DEREF_ptr ( prim_id ( a ) ) ;
674
	    break ;
675
	}
676
	case type_ident_tag : {
677
	    IDENTITY_P a = DEREF_ptr ( type_ident_id ( t0 ) ) ;
678
	    return ( name_aux_type ( DEREF_ptr ( ident_defn ( a ) ) ) ) ;
679
	}
680
	case type_enumeration_tag : {
681
	    ENUM_P a = DEREF_ptr ( type_enumeration_en ( t0 ) ) ;
682
	    id = DEREF_ptr ( en_id ( a ) ) ;
683
	    break ;
684
	}
685
	case type_structure_tag : {
686
	    STRUCTURE_P a = DEREF_ptr ( type_structure_struc ( t0 ) ) ;
687
	    id = DEREF_ptr ( str_id ( a ) ) ;
688
	    break ;
689
	}
690
	case type_onion_tag : {
691
	    UNION_P a = DEREF_ptr ( type_onion_un ( t0 ) ) ;
692
	    id = DEREF_ptr ( un_id ( a ) ) ;
693
	    break ;
694
	}
695
	case type_quote_tag : {
696
	    char *a = DEREF_string ( type_quote_defn ( t0 ) ) ;
697
	    return ( a ) ;
698
	}
699
	case type_ptr_tag : {
700
	    return ( "ptr" ) ;
701
	}
702
	case type_list_tag : {
703
	    return ( "list" ) ;
704
	}
705
	case type_stack_tag : {
706
	    return ( "stack" ) ;
707
	}
708
	case type_vec_tag : {
709
	    return ( "vec" ) ;
710
	}
711
	case type_vec_ptr_tag : {
712
	    return ( "vec_ptr" ) ;
713
	}
714
	case type_undef_tag : {
715
	    char *a = DEREF_string ( type_undef_name ( t0 ) ) ;
716
	    return ( a ) ;
717
	}
718
    }
719
    last_id = id ;
720
    return ( DEREF_string ( cid_name_aux ( id ) ) ) ;
721
}
722
 
723
 
724
/*
725
    CHECK FOR COMPLEX TYPES
726
 
727
    This routine checks whether a type is complex in the sense that it
728
    requires the statement versions of COPY and DEREF rather than the
729
    expression versions.
730
*/
731
 
732
int is_complex_type
733
    PROTO_N ( ( t ) )
734
    PROTO_T ( TYPE_P t )
735
{
736
    TYPE t0 = DEREF_type ( t ) ;
737
    switch ( TAG_type ( t0 ) ) {
738
	case type_structure_tag :
739
	case type_vec_tag :
740
	case type_vec_ptr_tag : {
741
	    return ( 1 ) ;
742
	}
743
	case type_ident_tag : {
744
	    IDENTITY_P r = DEREF_ptr ( type_ident_id ( t0 ) ) ;
745
	    TYPE_P s = DEREF_ptr ( ident_defn ( r ) ) ;
746
	    return ( is_complex_type ( s ) ) ;
747
	}
748
    }
749
    return ( 0 ) ;
750
}