Subversion Repositories tendra.SVN

Rev

Rev 2 | Go to most recent revision | Details | Compare with Previous | 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
/**** c-code.c --- SID C code ADT routines.
32
 *
33
 ** Author: Steve Folkes <smf@hermes.mod.uk>
34
 *
35
 **** Commentary:
36
 *
37
 * This file implements the C code ADT used to represent action definitions
38
 * for the C output language.
39
 *
40
 **** Change Log:
41
 * $Log: c-code.c,v $
42
 * Revision 1.1.1.1  1998/01/17  15:57:42  release
43
 * First version to be checked into rolling release.
44
 *
45
 * Revision 1.3  1996/03/01  09:53:12  smf
46
 * c-code.c, c-out-info.c, c-out-info.h, c-output.c:
47
 * 	- improved unreachable code analysis;
48
 * 	- improved some output formatting;
49
 * 	- added support for comment or macro to mark unreachable code.
50
 *
51
 * Revision 1.2  1994/12/15  09:56:23  smf
52
 * Brought into line with OSSG C Coding Standards Document, as per
53
 * "CR94_178.sid+tld-update".
54
 *
55
 * Revision 1.1.1.1  1994/07/25  16:04:17  smf
56
 * Initial import of SID 1.8 non shared files.
57
 *
58
**/
59
 
60
/****************************************************************************/
61
 
62
#include "c-code.h"
63
#include "c-out-key.h"
64
#include "c-output.h"
65
#include "gen-errors.h"
66
#include "name.h"
67
 
68
/*--------------------------------------------------------------------------*/
69
 
70
static void
71
c_code_set_labels PROTO_N ((code))
72
		  PROTO_T (CCodeP code)
73
{
74
    CCodeItemP item;
75
 
76
    for (item = code->head; item; item = item->next) {
77
	if (item->type == CCT_LABEL) {
78
	    NameP name = entry_get_name (item->u.ident);
79
 
80
	    if (!name_has_label (name)) {
81
		name_set_label (name, c_out_next_label ());
82
	    }
83
	}
84
    }
85
}
86
 
87
static void
88
c_code_reset_labels PROTO_N ((code))
89
		    PROTO_T (CCodeP code)
90
{
91
    CCodeItemP item;
92
 
93
    for (item = code->head; item; item = item->next) {
94
	if (item->type == CCT_LABEL) {
95
	    NameP name = entry_get_name (item->u.ident);
96
 
97
	    name_reset_label (name);
98
	}
99
    }
100
}
101
 
102
static EntryP
103
c_code_get_translation PROTO_N ((state, translator, ident, type_ref,
104
			      reference_ref, entry_ref))
105
		       PROTO_T (SaveRStackP state X
106
				TypeBTransP translator X
107
				EntryP      ident X
108
				EntryP     *type_ref X
109
				BoolT      *reference_ref X
110
				EntryP     *entry_ref)
111
{
112
    EntryP entry = btrans_get_translation (translator, ident);
113
    EntryP stack_entry;
114
 
115
    ASSERT (entry);
116
    stack_entry = rstack_get_translation (state, entry, type_ref,
117
					  reference_ref);
118
    if ((stack_entry == NIL (EntryP)) && (entry_is_non_local (entry))) {
119
	stack_entry    = entry;
120
	*type_ref      = entry_get_non_local (entry);
121
	*reference_ref = FALSE;
122
    }
123
    ASSERT (stack_entry);
124
    if (entry_ref) {
125
	*entry_ref = entry;
126
    }
127
    return (stack_entry);
128
}
129
 
130
/*--------------------------------------------------------------------------*/
131
 
132
CCodeP
133
c_code_create PROTO_N ((file, line))
134
	      PROTO_T (CStringP file X
135
		       unsigned line)
136
{
137
    CCodeP code = ALLOCATE (CCodeT);
138
 
139
    code->head = NIL (CCodeItemP);
140
    code->tail = &(code->head);
141
    code->file = file;
142
    code->line = line;
143
    types_init (&(code->param));
144
    types_init (&(code->result));
145
    return (code);
146
}
147
 
148
void
149
c_code_append_string PROTO_N ((code, string))
150
		     PROTO_T (CCodeP   code X
151
			      NStringP string)
152
{
153
    CCodeItemP item = ALLOCATE (CCodeItemT);
154
 
155
    item->next    = NIL (CCodeItemP);
156
    item->type    = CCT_STRING;
157
    nstring_assign (&(item->u.string), string);
158
    *(code->tail) = item;
159
    code->tail    = &(item->next);
160
}
161
 
162
void
163
c_code_append_label PROTO_N ((code, string))
164
		    PROTO_T (CCodeP   code X
165
			     NStringP string)
166
{
167
    CCodeItemP item = ALLOCATE (CCodeItemT);
168
 
169
    item->next    = NIL (CCodeItemP);
170
    item->type    = CCT_LABEL;
171
    nstring_assign (&(item->u.string), string);
172
    *(code->tail) = item;
173
    code->tail    = &(item->next);
174
}
175
 
176
void
177
c_code_append_identifier PROTO_N ((code, string))
178
			 PROTO_T (CCodeP   code X
179
				  NStringP string)
180
{
181
    CCodeItemP item = ALLOCATE (CCodeItemT);
182
 
183
    item->next    = NIL (CCodeItemP);
184
    item->type    = CCT_IDENT;
185
    nstring_assign (&(item->u.string), string);
186
    *(code->tail) = item;
187
    code->tail    = &(item->next);
188
}
189
 
190
void
191
c_code_append_modifiable PROTO_N ((code, string))
192
			 PROTO_T (CCodeP   code X
193
				  NStringP string)
194
{
195
    CCodeItemP item = ALLOCATE (CCodeItemT);
196
 
197
    item->next    = NIL (CCodeItemP);
198
    item->type    = CCT_MOD_IDENT;
199
    nstring_assign (&(item->u.string), string);
200
    *(code->tail) = item;
201
    code->tail    = &(item->next);
202
}
203
 
204
void
205
c_code_append_reference PROTO_N ((code, string))
206
			PROTO_T (CCodeP   code X
207
				 NStringP string)
208
{
209
    CCodeItemP item = ALLOCATE (CCodeItemT);
210
 
211
    item->next    = NIL (CCodeItemP);
212
    item->type    = CCT_REF_IDENT;
213
    nstring_assign (&(item->u.string), string);
214
    *(code->tail) = item;
215
    code->tail    = &(item->next);
216
}
217
 
218
void
219
c_code_append_exception PROTO_N ((code))
220
			PROTO_T (CCodeP code)
221
{
222
    CCodeItemP item = ALLOCATE (CCodeItemT);
223
 
224
    item->next    = NIL (CCodeItemP);
225
    item->type    = CCT_EXCEPTION;
226
    *(code->tail) = item;
227
    code->tail    = &(item->next);
228
}
229
 
230
void
231
c_code_append_advance PROTO_N ((code))
232
		      PROTO_T (CCodeP code)
233
{
234
    CCodeItemP item = ALLOCATE (CCodeItemT);
235
 
236
    item->next    = NIL (CCodeItemP);
237
    item->type    = CCT_ADVANCE;
238
    *(code->tail) = item;
239
    code->tail    = &(item->next);
240
}
241
 
242
void
243
c_code_append_terminal PROTO_N ((code))
244
		       PROTO_T (CCodeP code)
245
{
246
    CCodeItemP item = ALLOCATE (CCodeItemT);
247
 
248
    item->next    = NIL (CCodeItemP);
249
    item->type    = CCT_TERMINAL;
250
    *(code->tail) = item;
251
    code->tail    = &(item->next);
252
}
253
 
254
void
255
c_code_check PROTO_N ((code, exceptions, param_op, param, result, table))
256
	     PROTO_T (CCodeP     code X
257
		      BoolT      exceptions X
258
		      BoolT      param_op X
259
		      TypeTupleP param X
260
		      TypeTupleP result X
261
		      TableP     table)
262
{
263
    CCodeItemP item;
264
    EntryP     entry;
265
 
266
    for (item = code->head; item; item = item->next) {
267
	switch (item->type) EXHAUSTIVE {
268
	  case CCT_IDENT:
269
	    entry         = table_add_name (table, &(item->u.string));
270
	    item->u.ident = entry;
271
	    if (((param == NIL (TypeTupleP)) ||
272
		 (!types_contains (param, entry))) &&
273
		((result == NIL (TypeTupleP)) ||
274
		 (!types_contains (result, entry)))) {
275
		E_bad_id_substitution (c_code_file (code), c_code_line (code),
276
				       entry);
277
	    } else if (result) {
278
		name_used (entry_get_name (entry));
279
	    }
280
	    break;
281
	  case CCT_MOD_IDENT:
282
	    entry         = table_add_name (table, &(item->u.string));
283
	    item->u.ident = entry;
284
	    if (exceptions) {
285
		if ((param == NIL (TypeTupleP)) ||
286
		    (!types_mutated (param, entry))) {
287
		    E_bad_mod_id_substitution (c_code_file (code),
288
					       c_code_line (code), entry);
289
		}
290
	    } else {
291
		E_mod_id_in_assign (c_code_file (code), c_code_line (code),
292
				    entry);
293
	    }
294
	    break;
295
	  case CCT_REF_IDENT:
296
	    entry         = table_add_name (table, &(item->u.string));
297
	    item->u.ident = entry;
298
	    if (!param_op) {
299
		if ((param == NIL (TypeTupleP)) ||
300
		    (!types_contains (param, entry))) {
301
		    E_bad_ref_id_substitution (c_code_file (code),
302
					       c_code_line (code), entry);
303
		}
304
	    } else {
305
		E_ref_id_in_param_op (c_code_file (code), c_code_line (code),
306
				      entry);
307
	    }
308
	    break;
309
	  case CCT_LABEL:
310
	    entry         = table_add_name (table, &(item->u.string));
311
	    item->u.ident = entry;
312
	    if ((param == NIL (TypeTupleP)) && (result == NIL (TypeTupleP))) {
313
		E_bad_label_substitution (c_code_file (code),
314
					  c_code_line (code), entry);
315
	    }
316
	    break;
317
	  case CCT_EXCEPTION:
318
	    if (!exceptions) {
319
		E_bad_exception_substitution (c_code_file (code),
320
					      c_code_line (code));
321
	    }
322
	    break;
323
	  case CCT_ADVANCE:
324
	    if (!exceptions) {
325
		E_bad_advance_substitution (c_code_file (code),
326
					    c_code_line (code));
327
	    }
328
	    break;
329
	  case CCT_TERMINAL:
330
	    if (!exceptions) {
331
		E_bad_terminal_substitution (c_code_file (code),
332
					     c_code_line (code));
333
	    }
334
	    break;
335
	  case CCT_STRING:
336
	    break;
337
	}
338
    }
339
    if (result) {
340
	types_check_used (result, E_code_undefined_result, (GenericP) code);
341
	for (item = code->head; item; item = item->next) {
342
	    if (item->type == CCT_IDENT) {
343
		name_not_used (entry_get_name (item->u.ident));
344
	    }
345
	}
346
    }
347
    if (param) {
348
	types_assign (&(code->param), param);
349
    }
350
    if (result) {
351
	types_assign (&(code->result), result);
352
    }
353
}
354
 
355
#ifdef FS_FAST
356
#undef c_code_file
357
#endif /* defined (FS_FAST) */
358
CStringP
359
c_code_file PROTO_N ((code))
360
	    PROTO_T (CCodeP code)
361
{
362
    return (code->file);
363
}
364
#ifdef FS_FAST
365
#define c_code_file(c) ((c)->file)
366
#endif /* defined(FS_FAST) */
367
 
368
#ifdef FS_FAST
369
#undef c_code_line
370
#endif /* defined (FS_FAST) */
371
unsigned
372
c_code_line PROTO_N ((code))
373
	    PROTO_T (CCodeP code)
374
{
375
    return (code->line);
376
}
377
#ifdef FS_FAST
378
#define c_code_line(c) ((c)->line)
379
#endif /* defined(FS_FAST) */
380
 
381
TypeTupleP
382
c_code_param PROTO_N ((code))
383
	     PROTO_T (CCodeP code)
384
{
385
    return (&(code->param));
386
}
387
 
388
TypeTupleP
389
c_code_result PROTO_N ((code))
390
	      PROTO_T (CCodeP code)
391
{
392
    return (&(code->result));
393
}
394
 
395
void
396
c_code_deallocate PROTO_N ((code))
397
		  PROTO_T (CCodeP code)
398
{
399
    CCodeItemP item = code->head;
400
 
401
    while (item) {
402
	CCodeItemP next = item->next;
403
 
404
	switch (item->type) EXHAUSTIVE {
405
	  case CCT_STRING:
406
	    nstring_destroy (&(item->u.string));
407
	    break;
408
	  case CCT_IDENT:
409
	  case CCT_MOD_IDENT:
410
	  case CCT_REF_IDENT:
411
	  case CCT_LABEL:
412
	  case CCT_EXCEPTION:
413
	  case CCT_TERMINAL:
414
	  case CCT_ADVANCE:
415
	    break;
416
	}
417
	DEALLOCATE (item);
418
	item = next;
419
    }
420
    types_destroy (&(code->param));
421
    types_destroy (&(code->result));
422
    DEALLOCATE (code);
423
}
424
 
425
void
426
c_output_c_code_action PROTO_N ((info, code, param, result, state,
427
				 handler_rule))
428
		       PROTO_T (COutputInfoP info X
429
				CCodeP       code X
430
				TypeTupleP   param X
431
				TypeTupleP   result X
432
				SaveRStackP  state X
433
				RuleP        handler_rule)
434
{
435
    OStreamP    ostream      = c_out_info_ostream (info);
436
    NStringP    label_prefix = c_out_info_label_prefix (info);
437
    NStringP    in_prefix    = c_out_info_in_prefix (info);
438
    CCodeItemP  item;
439
    EntryP      stack_entry;
440
    EntryP      entry;
441
    EntryP      stack_type;
442
    BoolT       stack_reference;
443
    BoolT       use_cast;
444
    TypeBTransT translator;
445
 
446
    c_code_set_labels (code);
447
    btrans_init (&translator);
448
    btrans_add_translations (&translator, &(code->param), param);
449
    btrans_add_translations (&translator, &(code->result), result);
450
    for (item = code->head; item; item = item->next) {
451
	switch (item->type) EXHAUSTIVE {
452
	  case CCT_STRING:
453
	    write_nstring (ostream, &(item->u.string));
454
	    break;
455
	  case CCT_LABEL:
456
	    write_nstring (ostream, label_prefix);
457
	    write_unsigned (ostream,
458
			    name_get_label (entry_get_name (item->u.ident)));
459
	    break;
460
	  case CCT_IDENT:
461
	    stack_entry = c_code_get_translation (state, &translator,
462
						  item->u.ident, &stack_type,
463
						  &stack_reference, &entry);
464
	    use_cast = (types_contains (param, entry) &&
465
			c_out_info_get_casts (info));
466
	    if (use_cast) {
467
		write_cstring (ostream, "((");
468
		c_output_mapped_key (info, stack_type);
469
		write_cstring (ostream, ") (");
470
	    } else {
471
		write_char (ostream, '(');
472
	    }
473
	    if (stack_reference) {
474
		write_char (ostream, '*');
475
	    }
476
	    c_output_key (info, entry_key (stack_entry), in_prefix);
477
	    if (use_cast) {
478
		write_cstring (ostream, "))");
479
	    } else {
480
		write_char (ostream, ')');
481
	    }
482
	    break;
483
	  case CCT_MOD_IDENT:
484
	    stack_entry = c_code_get_translation (state, &translator,
485
						  item->u.ident, &stack_type,
486
						  &stack_reference,
487
						  NIL (EntryP *));
488
	    write_char (ostream, '(');
489
	    if (stack_reference) {
490
		write_char (ostream, '*');
491
	    }
492
	    c_output_key (info, entry_key (stack_entry), in_prefix);
493
	    write_char (ostream, ')');
494
	    break;
495
	  case CCT_REF_IDENT:
496
	    stack_entry = c_code_get_translation (state, &translator,
497
						  item->u.ident, &stack_type,
498
						  &stack_reference,
499
						  NIL (EntryP *));
500
	    write_char (ostream, '(');
501
	    if (!stack_reference) {
502
		write_char (ostream, '&');
503
	    }
504
	    c_output_key (info, entry_key (stack_entry), in_prefix);
505
	    write_char (ostream, ')');
506
	    break;
507
	  case CCT_EXCEPTION:
508
	    write_cstring (ostream, "goto ");
509
	    write_nstring (ostream, label_prefix);
510
	    write_unsigned (ostream, rule_get_handler_label (handler_rule));
511
	    break;
512
	  case CCT_ADVANCE:
513
	    write_cstring (ostream, "ADVANCE_LEXER");
514
	    break;
515
	  case CCT_TERMINAL:
516
	    write_cstring (ostream, "CURRENT_TERMINAL");
517
	    break;
518
	}
519
    }
520
    btrans_destroy (&translator);
521
    c_code_reset_labels (code);
522
}
523
 
524
void
525
c_output_c_code_basic PROTO_N ((info, code, result, state))
526
		      PROTO_T (COutputInfoP info X
527
			       CCodeP       code X
528
			       TypeTupleP   result X
529
			       SaveRStackP  state)
530
{
531
    OStreamP    ostream      = c_out_info_ostream (info);
532
    NStringP    label_prefix = c_out_info_label_prefix (info);
533
    NStringP    in_prefix    = c_out_info_in_prefix (info);
534
    CCodeItemP  item;
535
    EntryP      stack_entry;
536
    EntryP      stack_type;
537
    BoolT       stack_reference;
538
    TypeBTransT translator;
539
 
540
    c_code_set_labels (code);
541
    btrans_init (&translator);
542
    btrans_add_translations (&translator, &(code->result), result);
543
    for (item = code->head; item; item = item->next) {
544
	switch (item->type) EXHAUSTIVE {
545
	  case CCT_STRING:
546
	    write_nstring (ostream, &(item->u.string));
547
	    break;
548
	  case CCT_LABEL:
549
	    write_nstring (ostream, label_prefix);
550
	    write_unsigned (ostream,
551
			    name_get_label (entry_get_name (item->u.ident)));
552
	    break;
553
	  case CCT_IDENT:
554
	    stack_entry = c_code_get_translation (state, &translator,
555
						  item->u.ident, &stack_type,
556
						  &stack_reference,
557
						  NIL (EntryP *));
558
	    c_output_key (info, entry_key (stack_entry), in_prefix);
559
	    break;
560
	  case CCT_MOD_IDENT:
561
	  case CCT_REF_IDENT:
562
	  case CCT_EXCEPTION:
563
	  case CCT_ADVANCE:
564
	  case CCT_TERMINAL:
565
	    UNREACHED;
566
	}
567
    }
568
    btrans_destroy (&translator);
569
    c_code_reset_labels (code);
570
}
571
 
572
void
573
c_output_c_code_assign PROTO_N ((info, code, type, from, to, from_reference,
574
			      to_reference))
575
		       PROTO_T (COutputInfoP info X
576
				CCodeP       code X
577
				EntryP       type X
578
				EntryP       from X
579
				EntryP       to X
580
				BoolT        from_reference X
581
				BoolT        to_reference)
582
{
583
    OStreamP   ostream      = c_out_info_ostream (info);
584
    NStringP   label_prefix = c_out_info_label_prefix (info);
585
    NStringP   in_prefix    = c_out_info_in_prefix (info);
586
    BoolT      is_param;
587
    BoolT      use_cast;
588
    CCodeItemP item;
589
 
590
    c_code_set_labels (code);
591
    for (item = code->head; item; item = item->next) {
592
	switch (item->type) EXHAUSTIVE {
593
	  case CCT_STRING:
594
	    write_nstring (ostream, &(item->u.string));
595
	    break;
596
	  case CCT_LABEL:
597
	    write_nstring (ostream, label_prefix);
598
	    write_unsigned (ostream,
599
			    name_get_label (entry_get_name (item->u.ident)));
600
	    break;
601
	  case CCT_IDENT:
602
	    is_param = types_contains (&(code->param), item->u.ident);
603
	    use_cast = (is_param && c_out_info_get_casts (info));
604
	    if (use_cast) {
605
		write_cstring (ostream, "((");
606
		c_output_mapped_key (info, type);
607
		write_cstring (ostream, ") (");
608
	    } else {
609
		write_char (ostream, '(');
610
	    }
611
	    if (is_param) {
612
		if (from_reference) {
613
		    write_char (ostream, '*');
614
		}
615
		c_output_key (info, entry_key (from), in_prefix);
616
	    } else {
617
		if (to_reference) {
618
		    write_char (ostream, '*');
619
		}
620
		c_output_key (info, entry_key (to), in_prefix);
621
	    }
622
	    if (use_cast) {
623
		write_cstring (ostream, "))");
624
	    } else {
625
		write_char (ostream, ')');
626
	    }
627
	    break;
628
	  case CCT_REF_IDENT:
629
	    write_char (ostream, '(');
630
	    if (!from_reference) {
631
		write_char (ostream, '&');
632
	    }
633
	    c_output_key (info, entry_key (from), in_prefix);
634
	    write_char (ostream, ')');
635
	    break;
636
	  case CCT_MOD_IDENT:
637
	  case CCT_EXCEPTION:
638
	  case CCT_ADVANCE:
639
	  case CCT_TERMINAL:
640
	    UNREACHED;
641
	}
642
    }
643
    c_code_reset_labels (code);
644
}
645
 
646
void
647
c_output_c_code_param_assign PROTO_N ((info, code, type, entry))
648
			     PROTO_T (COutputInfoP info X
649
				      CCodeP       code X
650
				      EntryP       type X
651
				      EntryP       entry)
652
{
653
    OStreamP   ostream      = c_out_info_ostream (info);
654
    NStringP   label_prefix = c_out_info_label_prefix (info);
655
    NStringP   in_prefix    = c_out_info_in_prefix (info);
656
    NStringP   out_prefix   = c_out_info_out_prefix (info);
657
    CCodeItemP item;
658
 
659
    c_code_set_labels (code);
660
    for (item = code->head; item; item = item->next) {
661
	switch (item->type) EXHAUSTIVE {
662
	  case CCT_STRING:
663
	    write_nstring (ostream, &(item->u.string));
664
	    break;
665
	  case CCT_LABEL:
666
	    write_nstring (ostream, label_prefix);
667
	    write_unsigned (ostream,
668
			    name_get_label (entry_get_name (item->u.ident)));
669
	    break;
670
	  case CCT_IDENT:
671
	    if (types_contains (&(code->param), item->u.ident)) {
672
		BoolT use_cast = c_out_info_get_casts (info);
673
 
674
		if (use_cast) {
675
		    write_cstring (ostream, "((");
676
		    c_output_mapped_key (info, type);
677
		    write_cstring (ostream, " *) (");
678
		}
679
		c_output_key (info, entry_key (entry), out_prefix);
680
		if (use_cast) {
681
		    write_cstring (ostream, "))");
682
		}
683
	    } else {
684
		c_output_key (info, entry_key (entry), in_prefix);
685
	    }
686
	    break;
687
	  case CCT_MOD_IDENT:
688
	  case CCT_REF_IDENT:
689
	  case CCT_EXCEPTION:
690
	  case CCT_ADVANCE:
691
	  case CCT_TERMINAL:
692
	    UNREACHED;
693
	}
694
    }
695
    c_code_reset_labels (code);
696
}
697
 
698
void
699
c_output_c_code_result_assign PROTO_N ((info, code, type, entry))
700
			      PROTO_T (COutputInfoP info X
701
				       CCodeP       code X
702
				       EntryP       type X
703
				       EntryP       entry)
704
{
705
    OStreamP   ostream      = c_out_info_ostream (info);
706
    NStringP   label_prefix = c_out_info_label_prefix (info);
707
    NStringP   in_prefix    = c_out_info_in_prefix (info);
708
    NStringP   out_prefix   = c_out_info_out_prefix (info);
709
    CCodeItemP item;
710
 
711
    c_code_set_labels (code);
712
    for (item = code->head; item; item = item->next) {
713
	switch (item->type) EXHAUSTIVE {
714
	  case CCT_STRING:
715
	    write_nstring (ostream, &(item->u.string));
716
	    break;
717
	  case CCT_LABEL:
718
	    write_nstring (ostream, label_prefix);
719
	    write_unsigned (ostream,
720
			    name_get_label (entry_get_name (item->u.ident)));
721
	    break;
722
	  case CCT_IDENT:
723
	    if (types_contains (&(code->param), item->u.ident)) {
724
		BoolT use_cast = c_out_info_get_casts (info);
725
 
726
		if (use_cast) {
727
		    write_cstring (ostream, "((");
728
		    c_output_mapped_key (info, type);
729
		    write_cstring (ostream, ") (");
730
		}
731
		c_output_key (info, entry_key (entry), in_prefix);
732
		if (use_cast) {
733
		    write_cstring (ostream, "))");
734
		}
735
	    } else {
736
		c_output_key (info, entry_key (entry), out_prefix);
737
	    }
738
	    break;
739
	  case CCT_REF_IDENT:
740
	    write_cstring (ostream, "(&");
741
	    c_output_key (info, entry_key (entry), in_prefix);
742
	    write_char (ostream, ')');
743
	    break;
744
	  case CCT_MOD_IDENT:
745
	  case CCT_EXCEPTION:
746
	  case CCT_ADVANCE:
747
	  case CCT_TERMINAL:
748
	    UNREACHED;
749
	}
750
    }
751
    c_code_reset_labels (code);
752
}
753
 
754
void
755
c_output_c_code PROTO_N ((info, code))
756
		PROTO_T (COutputInfoP info X
757
			 CCodeP       code)
758
{
759
    OStreamP   ostream = c_out_info_ostream (info);
760
    CCodeItemP item;
761
 
762
    for (item = code->head; item; item = item->next) {
763
	switch (item->type) EXHAUSTIVE {
764
	  case CCT_STRING:
765
	    write_nstring (ostream, &(item->u.string));
766
	    break;
767
	  case CCT_LABEL:
768
	  case CCT_IDENT:
769
	  case CCT_MOD_IDENT:
770
	  case CCT_REF_IDENT:
771
	  case CCT_EXCEPTION:
772
	  case CCT_ADVANCE:
773
	  case CCT_TERMINAL:
774
	    UNREACHED;
775
	}
776
    }
777
}
778
 
779
/*
780
 * Local variables(smf):
781
 * eval: (include::add-path-entry "../os-interface" "../library")
782
 * eval: (include::add-path-entry "../transforms" "../output" "../generated")
783
 * end:
784
**/