decs.c 17.7 KB
Newer Older
1
#include <stdio.h>
dcw's avatar
dcw committed
2
3
4
5
#include "struct.h"
#include "decs.h"


dcw's avatar
dcw committed
6
7
8
9
10
11
12
/*
/^#ifdef HASPROTOS
!/endif$
stat %
*/


dcw's avatar
dcw committed
13
#ifdef HASPROTOS
dcw's avatar
dcw committed
14
static void line( char * , long , long , long , long );
dcw's avatar
dcw committed
15
16
static void h_declns( char * , char * , BOOL , declnlist );
static void c_declns( char * , char * , char * , declnlist );
17
static void data_decls( declnlist );
18
static void declare_type( decln );
19
static void declfields( paramlist );
dcw's avatar
dcw committed
20
static void protos( BOOL , char * , declnlist , BOOL );
21
static void proto_type( decln , BOOL );
22
static void cons_fns( declnlist );
23
24
25
26
27
28
29
static void cons_fn_proto( decln , shapelist , BOOL );
static void cons_fn( decln , shapelist );
static void decons_fns( declnlist );
static void decons_fns_type( decln );
static void deconskind_proto( decln , BOOL );
static void deconskind_fn( decln );
static void decons_fn_proto( decln , shapelist , BOOL );
dcw's avatar
dcw committed
30
static void decons_fn( decln , shapelist );
31
static void print_fn_proto( char * , BOOL );
dcw's avatar
dcw committed
32
static void print_fns( declnlist );
33
34
static void print_fn_shape( declnlist , shapelist );
static void print_all_params( declnlist , shapelist );
dcw's avatar
dcw committed
35
static void print_param( shapelist , paramlist , BOOL );
dcw's avatar
dcw committed
36
#else
dcw's avatar
dcw committed
37
static void line();
38
39
static void h_declns();
static void c_declns();
dcw's avatar
dcw committed
40
static void data_decls();
41
static void declare_type();
42
static void declfields();
dcw's avatar
dcw committed
43
static void protos();
44
static void proto_type();
45
static void cons_fns();
46
47
48
49
50
51
52
53
54
static void cons_fn_proto();
static void cons_fn();
static void decons_fns();
static void decons_fns_type();
static void deconskind_proto();
static void deconskind_fn();
static void decons_fn_proto();
static void decons_fn();
static void print_fn_proto();
dcw's avatar
dcw committed
55
static void print_fns();
56
57
58
static void print_fn_shape();
static void print_all_params();
static void print_param();
dcw's avatar
dcw committed
59
60
61
#endif


62
63
64
65
66
67
68
static int numtabs = 0;
static FILE *outfile;


#define indent() numtabs++
#define outdent() numtabs--

dcw's avatar
dcw committed
69
70
71
72
#define nl()		fputc( '\n', outfile )
#define outchar(c)	fputc( c, outfile )
#define usefile(f)	outfile = f, numtabs = 0

73
74
75
76
77
78
79
80
81


/*VARARGS*/
static void line( fmt, a, b, c, d ) char *fmt; long a, b, c, d;
{
	int i;

	for( i=numtabs; i; i-- ) fputc( '\t', outfile );
	fprintf( outfile, fmt, a, b, c, d );
dcw's avatar
dcw committed
82
	nl();
83
84
85
}


dcw's avatar
dcw committed
86
void make_declns( exports, globals, begin, d, base ) declnlist d; char *exports, *globals, *begin, *base;
dcw's avatar
dcw committed
87
{
dcw's avatar
dcw committed
88
89
90
	printf( "datadec: Making data declarations in %s.[ch]\n", base );
	h_declns( base, exports, *begin != '\0', d );
	c_declns( base, globals, begin, d );
91
92
93
}


dcw's avatar
dcw committed
94
static void h_declns( base, exports, init, d ) char *base, *exports; BOOL init; declnlist d;
95
96
97
98
99
{
	char		tempname[256];
	char		*exportptr;
	FILE		*hfile;

dcw's avatar
dcw committed
100
	sprintf( tempname, "%s.h", base );
101
	hfile = fopen( tempname, "w" );
102
103
104
105
106
	if( hfile == NULL )
	{
		fprintf( stderr, "datadec: can't create '%s'\n", tempname );
		exit(1);
	}
107
108
109
110
111
112
113
114
115
116
117
118

	usefile( hfile );

	line( "/*" );
	line( " * Automatically Generated by DataDec" );
	line( " */\n" );
	line( "typedef char *string;\n" );
	line( "typedef char BOOL;" );
	line( "#define TRUE 1" );
	line( "#define FALSE 0\n" );
	line( "#define NEW(t) ((t)malloc(sizeof(struct t)))\n\n" );

119
	exportptr = exports;
120
	if( *exports != '\0' )
dcw's avatar
dcw committed
121
	{
122
		line( "/* Contents of EXPORT section */" );
123
		for( ; *exportptr; exportptr++ )
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
		{
			if( *exportptr == '@' && exportptr[1] == '@'
			&&   exportptr[2] == '\n' )
			{
				exportptr += 2;
				break;
			}
			outchar( *exportptr );
		}

		nl();
		nl();
	}

	data_decls( d );

140
	line( "\n/* Prototypes for all types */\n" );
141
#ifdef KANDR
142
	line( "#ifdef HASPROTOS" );
143
#endif
dcw's avatar
dcw committed
144
	protos( init, base, d, TRUE );
145
#ifdef KANDR
146
	line( "#else" );
dcw's avatar
dcw committed
147
	protos( init, base, d, FALSE );
148
	line( "#endif" );
149
#endif
150
151
152
153
154
155
156

	if( *exportptr != '\0' )
	{
		nl();
		line( "/* Remaining contents of EXPORT section */" );
		line( exportptr );
		nl();
dcw's avatar
dcw committed
157
	}
158
159

	fclose( hfile );
dcw's avatar
dcw committed
160
161
162
}


dcw's avatar
dcw committed
163
static void c_declns( base, globals, begin, d ) char *base, *globals, *begin; declnlist d;
164
165
166
167
168
{
	char	tempname[256];
	FILE	*cfile;
	char	*globalptr;

dcw's avatar
dcw committed
169
	sprintf( tempname, "%s.c", base );
170
	cfile = fopen( tempname, "w" );
171
172
173
174
175
	if( cfile == NULL )
	{
		fprintf( stderr, "datadec: can't create '%s'\n", tempname );
		exit(1);
	}
176
177
178
179
180
181
182
183

	usefile( cfile );

	line( "/*" );
	line( " * Automatically Generated by DataDec" );
	line( " */\n" );
	line( "#include <stdio.h>" );
	line( "#include <malloc.h>" );
dcw's avatar
dcw committed
184
	line( "#include \"%s.h\"\n\n", base );
185

186
	globalptr=globals;
187
188
189
	if( *globals != '\0' )
	{
		line( "/* Contents of GLOBAL section */" );
190
		for( ; *globalptr; globalptr++ )
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
		{
			if( *globalptr == '@' && globalptr[1] == '@'
			&&   globalptr[2] == '\n' )
			{
				globalptr += 2;
				break;
			}
			outchar( *globalptr );
		}

		nl();
		nl();
	}

	cons_fns( d );
206
	decons_fns( d );
207
208
209
210
211
212
213
214
215
216
217
	print_fns( d );

	if( *globalptr != '\0' )
	{
		nl();
		nl();
		line( "/* Remaining contents of GLOBAL section */" );
		line( globalptr );
		nl();
	}

dcw's avatar
dcw committed
218
219
220
221
222
223
224
225
	if( *begin != '\0' )
	{
		line( "/* Contents of BEGIN section */" );
		line( "void init_%s()", base );
		line( "{" );
		line( begin );
		line( "}" );
	}
226
227
228
229
	fclose( cfile );
}


230
/* ------------------------ Declare the types ------------------------------ */
231
232


233
static void data_decls( decs ) declnlist decs;
dcw's avatar
dcw committed
234
{
235
	declnlist	d;
dcw's avatar
dcw committed
236

dcw's avatar
dcw committed
237
	for( d=decs; d != NULL; d=d->next )
dcw's avatar
dcw committed
238
	{
dcw's avatar
dcw committed
239
240
		if( d->Struct )
		{
241
242
			line("struct %s;", d->name);
			line("typedef struct %s *%s;", d->name, d->name );
dcw's avatar
dcw committed
243
244
245
246
		} else
		{
			line( "typedef int %s;", d->name );
		}
dcw's avatar
dcw committed
247
	}
248
249
	nl();
	nl();
dcw's avatar
dcw committed
250
	for( d=decs; d != NULL; d=d->next )
dcw's avatar
dcw committed
251
	{
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
		declare_type( d );
	}
}


static void declare_type( d ) decln d;
{
	shapelist	s;

	line( "/* ---- Type %s ---- */\n", d->name );

	if( d->ManyShapes )
	{
		line( "typedef enum {" );
		indent();

		for( s = d->shapes; s != NULL; s=s->next )
dcw's avatar
dcw committed
269
		{
270
			line( "%s_is_%s,", d->name, s->name );
dcw's avatar
dcw committed
271
		}
272
273
274
		outdent();
		line( "} kind_of_%s;\n", d->name );
	}
275

276
277
278
279
280
281
282
283
284
	if( d->Struct )
	{
		line( "struct %s {", d->name );
		indent();
		if( d->TagField )
		{
			line( "kind_of_%s\ttag;", d->name );
		}
		if( d->Union )
dcw's avatar
dcw committed
285
		{
286
			line( "union {" );
dcw's avatar
dcw committed
287
			indent();
288
289
290
291
292
		}
		for( s = d->shapes; s != NULL; s=s->next )
		{
			if( s->params == NULL ) continue;

dcw's avatar
dcw committed
293
294
			if( d->Union )
			{
295
296
297
298
299
300
301
				if( s->params->next == NULL )
				{
					/* don't need internal struct */
					/* but use {shape name}_{field name} */
					line( "%s\t%s_%s;", s->params->type,
						s->name, s->params->name );
				} else
dcw's avatar
dcw committed
302
				{
303
					/* need internal struct */
dcw's avatar
dcw committed
304
305
306
307
308
					line( "struct {" );
					indent();
					declfields( s->params );
					outdent();
					line( "} %s;", s->name );
dcw's avatar
dcw committed
309
				}
310
			} else
dcw's avatar
dcw committed
311
			{
312
313
				/* only one chunk of data: this one */
				declfields( s->params );
dcw's avatar
dcw committed
314
			}
315
316
317
		}
		if( d->Union )
		{
dcw's avatar
dcw committed
318
			outdent();
319
			line( "} u;" );
dcw's avatar
dcw committed
320
		}
321
322
		outdent();
		line( "};\n" );
dcw's avatar
dcw committed
323
324
325
326
	}
}


327
328
329
330
331
332
333
334
335
static void declfields( p ) paramlist p;
{
	for( ; p != NULL; p=p->next )
	{
		line( "%s\t%s;", p->type, p->name );
	}
}


336
/* ---------------------- Declare all prototypes -------------------------- */
337
338


dcw's avatar
dcw committed
339
static void protos( init, base, d, prot ) BOOL init; char *base; declnlist d; BOOL prot;
340
341
342
343
344
{
	for( ; d != NULL; d = d->next )
	{
		proto_type( d, prot );
	}
dcw's avatar
dcw committed
345
346
347
348
349
350
351
352
353
	if( init )
	{
		fprintf( outfile, "extern void init_%s( ", base );
		if( prot )
		{
			fputs( "void ", outfile );
		}
		fputs( ");\n", outfile );
	}
354
355
356
357
}


static void proto_type( d, prot ) decln d; BOOL prot;
358
359
360
{
	shapelist	s;

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
	s = d->shapes;
	if( d->Struct )
	{
		/* genuine constructor functions needed */
		if( d->UseNull )
		{
			/* except for first shape */
			line( "#define %s_%s() ((%s)NULL)",
				d->name, d->shapes->name, d->name );
			s = s->next;
		}
		for( ; s != NULL; s = s->next )
		{
			cons_fn_proto( d, s, prot );
		}
	} else
	{
		/* enumeration: use #define for all constructors */
		for( ; s != NULL; s = s->next )
		{
			line( "#define %s_%s() ((int)%s_is_%s)",
				d->name, s->name,
				d->name, s->name );
		}
	}
	if( d->ManyShapes )
387
	{
388
		/* need a deconstructor kind function/macro */
389
390
		if( d->Struct )
		{
391
392
393
394
395
396
397
398
399
400
401
402
403
404
			/* a true function is required */
			deconskind_proto( d, prot );
		} else
		{
			/* enumeration: a macro will do */
			line( "#define %s_kind(this) ((kind_of_%s) this)",
				d->name, d->name );
		}
	}
	if( d->Struct )
	{
		for( s = d->shapes; s != NULL; s = s->next )
		{
			if( s->params != NULL )
405
			{
406
				decons_fn_proto( d, s, prot );
407
408
			}
		}
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
	}
	print_fn_proto( d->name, prot );
}


/* ------------------------------- Constructors --------------------------- */


static void cons_fns( d ) declnlist d;
{
	shapelist	s;

	for( ; d != NULL; d=d->next )
	{
		/* ignore enumerations: constructors already in .h file */
		if( ! d->Struct ) continue;

		/* We need constructor functions for this type */
		s = d->shapes;
		if( d->UseNull )
429
		{
430
431
432
433
434
435
			/* Null cons func is a #define in .h file: skip it */
			s = s->next;
		}
		for( ; s != NULL; s=s->next )
		{
			cons_fn( d, s );
436
437
438
439
440
		}
	}
}


441
static void cons_fn_proto( d, s, prot ) decln d; shapelist s; BOOL prot;
dcw's avatar
dcw committed
442
443
444
445
{
	paramlist p;
	BOOL first;

446
447
448
449
450
	if( ! d->Struct )
	{
		fprintf( stderr, "cons_fn_proto: d->Struct is false!\n" );
		exit(1);
	}
451
452

	fprintf( outfile, "extern %s %s_%s( ", d->name, d->name, s->name );
453
	if( prot )
dcw's avatar
dcw committed
454
455
456
	{
		if( s->params == NULL )
		{
dcw's avatar
dcw committed
457
			fputs( "void ", outfile );
dcw's avatar
dcw committed
458
459
		} else
		{
dcw's avatar
dcw committed
460
			first = TRUE;
dcw's avatar
dcw committed
461
			for( p = s->params; p != NULL ; p=p->next, first=FALSE )
dcw's avatar
dcw committed
462
			{
dcw's avatar
dcw committed
463
464
465
				if( !first ) fputs( ", ", outfile );
				fputs( p->type, outfile );
				fputc( ' ', outfile );
dcw's avatar
dcw committed
466
467
468
			}
		}
	}
dcw's avatar
dcw committed
469
	fputs( ");\n", outfile );
dcw's avatar
dcw committed
470
471
472
}


473
static void cons_fn( d, s ) decln d; shapelist s;
dcw's avatar
dcw committed
474
{
475
476
	paramlist p;
	BOOL first;
dcw's avatar
dcw committed
477

478
479
480
481
482
	if( ! d->Struct )
	{
		fprintf( stderr, "cons_fn: d->Struct is FALSE!\n" );
		exit(1);
	}
483
484
485

	fprintf( outfile, "%s %s_%s( ", d->name, d->name, s->name );
	first = TRUE;
486
487

#ifdef KANDR
488
	for( p=s->params; p != NULL; p=p->next, first=FALSE )
dcw's avatar
dcw committed
489
	{
490
491
492
493
494
495
496
497
		if( !first ) fputs( ", ", outfile );
		fputs( p->name, outfile );
	}
	fputs( " )", outfile );
	for( p=s->params; p != NULL; p=p->next )
	{
		fprintf( outfile, " %s %s;", p->type, p->name );
	}
498
499
500
501
502
503
504
505
506
507
508
509
#else
	if( s->params == NULL )
	{
		fprintf( outfile, "void" );
	}
	for( p=s->params; p != NULL; p=p->next, first = FALSE )
	{
		if( !first ) fputs( ", ", outfile );
		fprintf( outfile, "%s %s", p->type, p->name );
	}
	fputs( " )", outfile );
#endif
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527

	line( "\n{" );
	indent();
	line( "%s\tnew = NEW(%s);", d->name, d->name );
	if( d->TagField )
	{
		line( "new->tag = %s_is_%s;", d->name, s->name );
	}
	if( d->Union && s->params != NULL && s->params->next == NULL )
	{
		/* no internal struct needed for this shape */
		line( "new->u.%s_%s = %s;", s->name,
			s->params->name, s->params->name );
	} else
	{
		paramlist p;

		for( p=s->params; p != NULL; p=p->next )
dcw's avatar
dcw committed
528
		{
529
			if( d->Union )
dcw's avatar
dcw committed
530
			{
531
532
533
534
				/* an internal struct */
				line( "new->u.%s.%s = %s;", s->name,
					p->name, p->name );
			} else
dcw's avatar
dcw committed
535
			{
536
537
				/* only one chunk of data: this one */
				line( "new->%s = %s;", p->name, p->name );
dcw's avatar
dcw committed
538
			}
539
		}
dcw's avatar
dcw committed
540
	}
541
542
543
	line( "return new;" );
	outdent();
	line( "}\n\n" );
dcw's avatar
dcw committed
544
545
546
}


547
548
549
550
/* ------------------------- Deconstructors ------------------------------- */


static void decons_fns( d ) declnlist d;
dcw's avatar
dcw committed
551
{
552
553
554
555
556
557
558
559
560
	for( ; d != NULL; d=d->next )
	{
		if( d->Struct )
		{
			decons_fns_type( d );
		}
		/* enumerations need none (decon kind macro already in .h) */
	}
}
dcw's avatar
dcw committed
561

562
563
564
565
566

static void decons_fns_type( d ) decln d;
{
	shapelist	s;

567
568
569
570
571
	if( ! d->Struct )
	{
		fprintf( stderr, "decons_fns_type: d->Struct is FALSE!\n" );
		exit(1);
	}
572
573

	if( d->ManyShapes )
dcw's avatar
dcw committed
574
	{
575
576
		/* We need a true deconstructor kind function */
		deconskind_fn( d );
dcw's avatar
dcw committed
577
	}
578
579
	/* We need (some) deconstructor functions */
	for( s = d->shapes; s != NULL; s=s->next )
dcw's avatar
dcw committed
580
	{
581
582
583
584
		if( s->params != NULL )
		{
			decons_fn( d, s );
		}
dcw's avatar
dcw committed
585
586
587
588
	}
}


589
590
591
592
/* ------------------- Deconstructor Kind procedure ----------------------- */


static void deconskind_proto( d, prot ) decln d; BOOL prot;
dcw's avatar
dcw committed
593
{
594
595
596
597
598
599
600
601
602
603
604
	if( ! d->ManyShapes )
	{
		fprintf( stderr,
			"deconskind_proto: d->ManyShapes is FALSE!\n" );
		exit(1);
	}
	if( ! d->Struct )
	{
		fprintf( stderr, "deconskind_proto: d->Struct is FALSE!\n" );
		exit(1);
	}
605
606
607
608
609
610
611
612
613
614
615
616
617
618

	fprintf( outfile, "extern kind_of_%s %s_kind( ", d->name, d->name );
	if( prot )
	{
		fprintf( outfile, "%s ", d->name );
	}
	fputs( ");\n", outfile );
}


static void deconskind_fn( d ) decln d;
{
	shapelist s = d->shapes;

619
620
621
622
623
624
625
626
627
628
	if( ! d->ManyShapes )
	{
		fprintf( stderr, "deconskind_fn: d->ManyShapes is FALSE!\n" );
		exit(1);
	}
	if( ! d->Struct )
	{
		fprintf( stderr, "deconskind_fn: d->Struct is FALSE!\n" );
		exit(1);
	}
629

630
#ifdef KANDR
631
632
	fprintf( outfile, "kind_of_%s %s_kind( this ) %s this;\n",
		 d->name, d->name, d->name );
633
634
635
636
#else
	fprintf( outfile, "kind_of_%s %s_kind( %s this )\n",
		 d->name, d->name, d->name );
#endif
dcw's avatar
dcw committed
637

638
639
	line( "{" );
	indent();
640
641
642
643
644
645
646
647
648
649
650

	if ( d->UseNull )
	{
		line( "if( this == NULL )" );
		line( "{" );
		indent();
		line( "return %s_is_%s;", d->name, s->name );
		outdent();
		line( "}" );
		s = s->next;
	}
dcw's avatar
dcw committed
651
652
	if( d->TagField )
	{
653
		line( "return this->tag;" );
dcw's avatar
dcw committed
654
	}
655
	else
dcw's avatar
dcw committed
656
	{
657
658
659
660
661
662
663
664
665
666
667
668
		line( "return %s_is_%s;", d->name, s->name );
	}
	outdent();
	line( "}\n\n" );
}


/* ----------------------- Deconstructor functions ------------------------ */


static void decons_fn_proto( d, s, prot ) decln d; shapelist s; BOOL prot;
{
669
670
671
672
673
674
675
676
677
678
	if( ! d->Struct )
	{
		fprintf( stderr, "decons_fn_proto: d->Struct is FALSE!\n" );
		exit(1);
	}
	if( s->params == NULL )
	{
		fprintf( stderr, "decons_fn_proto: no fields in shape!!\n" );
		exit(1);
	}
679
680
681
682
683
684
685
686

	fprintf( outfile, "extern void get_%s_%s(", d->name, s->name );
	if( prot )
	{
		paramlist p;

		fprintf( outfile, " %s ", d->name );
		for( p = s->params; p != NULL ; p=p->next )
dcw's avatar
dcw committed
687
		{
688
689
690
691
692
693
694
695
696
697
698
			fprintf( outfile, ", %s * ", p->type );
		}
	}
	fputs( ");\n", outfile );
}


static void decons_fn( d, s ) decln d; shapelist s;
{
	paramlist p;

699
700
701
702
703
704
705
706
707
708
	if( ! d->Struct )
	{
		fprintf( stderr, "decons_fn: d->Struct is FALSE!\n" );
		exit(1);
	}
	if( s->params == NULL )
	{
		fprintf( stderr, "decons_fn: no fields in shape!!\n" );
		exit(1);
	}
709

710
#ifdef KANDR
711
712
713
714
715
716
717
718
719
720
	fprintf( outfile, "void get_%s_%s( this", d->name, s->name );
	for( p=s->params; p != NULL; p=p->next )
	{
		fprintf( outfile, ", %s ", p->name );
	}
	fprintf( outfile, ") %s this;", d->name );
	for( p=s->params; p != NULL; p=p->next )
	{
		fprintf( outfile, " %s *%s;", p->type, p->name );
	}
721
722
723
724
725
726
727
728
#else
	fprintf( outfile, "void get_%s_%s( %s this", d->name, s->name, d->name );
	for( p=s->params; p != NULL; p=p->next )
	{
		fprintf( outfile, ", %s *%s", p->type, p->name );
	}
	fprintf( outfile, " )" );
#endif
729
730
731
732
733
734
735
736
737
738
739
	line( "\n{" );
	indent();

	if( d->Union && s->params != NULL && s->params->next == NULL )
	{
		/* no internal struct: one field only */
		line( "*%s = this->u.%s_%s;",
			s->params->name, s->name, s->params->name );
	} else
	{
		for( p=s->params; p != NULL; p=p->next )
dcw's avatar
dcw committed
740
		{
741
742
743
744
745
746
747
748
749
750
			if( d->Union )
			{
				/* internal struct */
				line( "*%s = this->u.%s.%s;",
					p->name, s->name, p->name );
			} else
			{
				/* only one chunk of data: this one */
				line( "*%s = this->%s;", p->name, p->name );
			}
dcw's avatar
dcw committed
751
		}
dcw's avatar
dcw committed
752
	}
753
	outdent();
754
	line( "}\n\n" );
dcw's avatar
dcw committed
755
756
757
}


758
/* -------------------------- Print functions ----------------------------- */
dcw's avatar
dcw committed
759
760


761
static void print_fn_proto( name, prot ) char *name; BOOL prot;
dcw's avatar
dcw committed
762
{
763
764
765
	fprintf( outfile, "extern void print_%s(", name );
	if( prot )
	{
766
		fprintf( outfile, " FILE *, %s ", name );
767
768
769
	}
	fputs( ");\n", outfile );
}
dcw's avatar
dcw committed
770

771
772
773

static void print_fns( d ) declnlist d;
{
dcw's avatar
dcw committed
774
	for( ; d != NULL; d = d->next )
dcw's avatar
dcw committed
775
	{
776
777
		shapelist s;

778
#ifdef KANDR
779
		line( "void print_%s( f, p ) FILE *f; %s p;",d->name, d->name );
780
781
782
#else
		line( "void print_%s( FILE *f, %s p )",d->name, d->name );
#endif
783
784
		line( "{" );
		indent();
785
		s = d->shapes;
dcw's avatar
dcw committed
786
		if( d->UseNull )
dcw's avatar
dcw committed
787
		{
dcw's avatar
dcw committed
788
789
790
			line( "if( p == NULL )" );
			line( "{" );
			indent();
791
			print_all_params( d, s );
dcw's avatar
dcw committed
792
793
794
			line( "return;" );
			outdent();
			line( "}" );
795
			s = s->next;
dcw's avatar
dcw committed
796
797
798
799
800
		}
		if( d->TagField )
		{
			line( "switch( p->tag )" );
			line( "{" );
801
			for( ; s != NULL; s = s->next )
dcw's avatar
dcw committed
802
803
804
805
806
807
808
809
810
811
812
			{
				print_fn_shape( d, s );
			}
			line( "default:" );
			indent();
			line( "fprintf( stderr," );
			line( " \"print_%s: impossible tag %%d\\n\", p->tag );",
				d->name );
			line( "exit(1);" );
			outdent();
			line( "}" );
813
814
		}
		else if( ! d->TagField && d->Struct )	/* one shape left */
dcw's avatar
dcw committed
815
		{
816
817
818
			print_all_params( d, s );
		}
		else if( ! d->Struct && d->ManyShapes ) /* enumerated type */
dcw's avatar
dcw committed
819
820
821
		{
			line( "switch( p )" );
			line( "{" );
822
			for( ; s != NULL; s = s->next )
dcw's avatar
dcw committed
823
			{
dcw's avatar
dcw committed
824
				line( "case %s_%s():", d->name, s->name );
dcw's avatar
dcw committed
825
826
827
828
829
830
				indent();
				print_all_params( d, s );
				line( "break;" );
				outdent();
			}
			line( "}" );
dcw's avatar
dcw committed
831
832
833
834
835
		} else
		{
			fprintf( stderr,
				 "datadec: internal error in print_fns\n" );
			exit(1);
dcw's avatar
dcw committed
836
		}
837
		outdent();
838
		line( "}\n\n" );
dcw's avatar
dcw committed
839
840
841
	}
}

dcw's avatar
dcw committed
842

843
static void print_fn_shape( d, s ) declnlist d; shapelist s;
dcw's avatar
dcw committed
844
{
845
	line( "case %s_is_%s:", d->name, s->name );
846
847
848
849
	indent();
	print_all_params( d, s );
	line( "break;" );
	outdent();
dcw's avatar
dcw committed
850
851
852
}


853
static void print_all_params( d, s ) declnlist d; shapelist s;
dcw's avatar
dcw committed
854
{
855
856
857
	printlist	pl;
	paramlist	p;
	int		n;
dcw's avatar
dcw committed
858

859
	if( s->pl == NULL )
dcw's avatar
dcw committed
860
	{
861
862
		line( "fputs( \"%s\", f );", s->name );
		if( s->params )
dcw's avatar
dcw committed
863
		{
864
			line( "fputc( '(', f );" );
dcw's avatar
dcw committed
865
		}
866
		for( p = s->params; p != NULL; p = p->next )
dcw's avatar
dcw committed
867
		{
868
			print_param( s, p, d->Union );
dcw's avatar
dcw committed
869
		}
870
871
872
873
874
		if( s->params )
		{
			line( "fputc( ')', f );" );
		}
	} else
dcw's avatar
dcw committed
875
	{
876
		for( pl = s->pl; pl != NULL; pl = pl->next )
dcw's avatar
dcw committed
877
		{
878
			if( pl->item->tag == printitem_is_str )
dcw's avatar
dcw committed
879
			{
880
881
882
883
884
885
886
				line( "fputs( \"%s\", f );",
					pl->item->str );
			} else
			{
				n = pl->item->num;
				for( p = s->params; --n; p = p->next )
				{
887
888
889
890
891
892
893
					if( p == NULL )
					{
						fprintf( stderr,
	"datadec: bad printitem in shape %s of type %s\n",
	s->name, d->name );
						exit(1);
					}
894
				}
895
				print_param( s, p, d->Union );
dcw's avatar
dcw committed
896
897
898
			}
		}
	}
899
}
dcw's avatar
dcw committed
900
901


902
static void print_param( s, p, Union ) shapelist s; paramlist p; BOOL Union;
903
904
{
	char pname[200];
dcw's avatar
dcw committed
905

906
	if( Union )
dcw's avatar
dcw committed
907
	{
908
909
910
911
912
913
914
915
916
		if( s->params->next == NULL )
		{
			/* no internal struct */
			sprintf( pname, "p->u.%s_%s", s->name, p->name );
		} else
		{
			/* internal struct */
			sprintf( pname, "p->u.%s.%s", s->name, p->name );
		}
917
918
919
	} else
	{
		sprintf( pname, "p->%s", p->name );
dcw's avatar
dcw committed
920
921
	}

922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
	if( streq( p->type, "int" ) )
	{
		line( "fprintf( f, \"%%d\", %s );", pname );
	} else if( streq( p->type, "char" ) )
	{
		line( "fputc( %s, f );", pname );
	} else if( streq( p->type, "BOOL" ) )
	{
		line( "fputs( %s?\"true\":\"false\", f );", pname );
	} else if( streq( p->type, "string" ) )
	{
		line( "fputs( %s, f );", pname );
	} else
	{
		line( "print_%s( f, %s );", p->type, pname );
	}
dcw's avatar
dcw committed
938
}