decs.c 17.7 KB
Newer Older
1
#include <stdio.h>
2
3
#include <stdlib.h>

dcw's avatar
dcw committed
4
5
6
7
#include "struct.h"
#include "decs.h"


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


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


64
65
66
67
68
69
70
static int numtabs = 0;
static FILE *outfile;


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

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

75
76
77
78
79
80
81
82
83


/*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
84
	nl();
85
86
87
}


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


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

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

	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" );

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

		nl();
		nl();
	}

	data_decls( d );

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

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

	fclose( hfile );
dcw's avatar
dcw committed
162
163
164
}


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

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

	usefile( cfile );

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

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

		nl();
		nl();
	}

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

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

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


232
/* ------------------------ Declare the types ------------------------------ */
233
234


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

dcw's avatar
dcw committed
239
	for( d=decs; d != NULL; d=d->next )
dcw's avatar
dcw committed
240
	{
dcw's avatar
dcw committed
241
242
		if( d->Struct )
		{
243
244
			line("struct %s;", d->name);
			line("typedef struct %s *%s;", d->name, d->name );
dcw's avatar
dcw committed
245
246
247
248
		} else
		{
			line( "typedef int %s;", d->name );
		}
dcw's avatar
dcw committed
249
	}
250
251
	nl();
	nl();
dcw's avatar
dcw committed
252
	for( d=decs; d != NULL; d=d->next )
dcw's avatar
dcw committed
253
	{
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
		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
271
		{
272
			line( "%s_is_%s,", d->name, s->name );
dcw's avatar
dcw committed
273
		}
274
275
276
		outdent();
		line( "} kind_of_%s;\n", d->name );
	}
277

278
279
280
281
282
283
284
285
286
	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
287
		{
288
			line( "union {" );
dcw's avatar
dcw committed
289
			indent();
290
291
292
293
294
		}
		for( s = d->shapes; s != NULL; s=s->next )
		{
			if( s->params == NULL ) continue;

dcw's avatar
dcw committed
295
296
			if( d->Union )
			{
297
298
299
300
301
302
303
				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
304
				{
305
					/* need internal struct */
dcw's avatar
dcw committed
306
307
308
309
310
					line( "struct {" );
					indent();
					declfields( s->params );
					outdent();
					line( "} %s;", s->name );
dcw's avatar
dcw committed
311
				}
312
			} else
dcw's avatar
dcw committed
313
			{
314
315
				/* only one chunk of data: this one */
				declfields( s->params );
dcw's avatar
dcw committed
316
			}
317
318
319
		}
		if( d->Union )
		{
dcw's avatar
dcw committed
320
			outdent();
321
			line( "} u;" );
dcw's avatar
dcw committed
322
		}
323
324
		outdent();
		line( "};\n" );
dcw's avatar
dcw committed
325
326
327
328
	}
}


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


338
/* ---------------------- Declare all prototypes -------------------------- */
339
340


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


static void proto_type( d, prot ) decln d; BOOL prot;
360
361
362
{
	shapelist	s;

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
	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 )
389
	{
390
		/* need a deconstructor kind function/macro */
391
392
		if( d->Struct )
		{
393
394
395
396
397
398
399
400
401
402
403
404
405
406
			/* 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 )
407
			{
408
				decons_fn_proto( d, s, prot );
409
410
			}
		}
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
	}
	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 )
431
		{
432
433
434
435
436
437
			/* Null cons func is a #define in .h file: skip it */
			s = s->next;
		}
		for( ; s != NULL; s=s->next )
		{
			cons_fn( d, s );
438
439
440
441
442
		}
	}
}


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

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

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


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

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

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

#ifdef KANDR
490
	for( p=s->params; p != NULL; p=p->next, first=FALSE )
dcw's avatar
dcw committed
491
	{
492
493
494
495
496
497
498
499
		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 );
	}
500
501
502
503
504
505
506
507
508
509
510
511
#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
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529

	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
530
		{
531
			if( d->Union )
dcw's avatar
dcw committed
532
			{
533
534
535
536
				/* an internal struct */
				line( "new->u.%s.%s = %s;", s->name,
					p->name, p->name );
			} else
dcw's avatar
dcw committed
537
			{
538
539
				/* only one chunk of data: this one */
				line( "new->%s = %s;", p->name, p->name );
dcw's avatar
dcw committed
540
			}
541
		}
dcw's avatar
dcw committed
542
	}
543
544
545
	line( "return new;" );
	outdent();
	line( "}\n\n" );
dcw's avatar
dcw committed
546
547
548
}


549
550
551
552
/* ------------------------- Deconstructors ------------------------------- */


static void decons_fns( d ) declnlist d;
dcw's avatar
dcw committed
553
{
554
555
556
557
558
559
560
561
562
	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
563

564
565
566
567
568

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

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

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


591
592
593
594
/* ------------------- Deconstructor Kind procedure ----------------------- */


static void deconskind_proto( d, prot ) decln d; BOOL prot;
dcw's avatar
dcw committed
595
{
596
597
598
599
600
601
602
603
604
605
606
	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);
	}
607
608
609
610
611
612
613
614
615
616
617
618
619
620

	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;

621
622
623
624
625
626
627
628
629
630
	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);
	}
631

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

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

	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
653
654
	if( d->TagField )
	{
655
		line( "return this->tag;" );
dcw's avatar
dcw committed
656
	}
657
	else
dcw's avatar
dcw committed
658
	{
659
660
661
662
663
664
665
666
667
668
669
670
		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;
{
671
672
673
674
675
676
677
678
679
680
	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);
	}
681
682
683
684
685
686
687
688

	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
689
		{
690
691
692
693
694
695
696
697
698
699
700
			fprintf( outfile, ", %s * ", p->type );
		}
	}
	fputs( ");\n", outfile );
}


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

701
702
703
704
705
706
707
708
709
710
	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);
	}
711

712
#ifdef KANDR
713
714
715
716
717
718
719
720
721
722
	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 );
	}
723
724
725
726
727
728
729
730
#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
731
732
733
734
735
736
737
738
739
740
741
	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
742
		{
743
744
745
746
747
748
749
750
751
752
			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
753
		}
dcw's avatar
dcw committed
754
	}
755
	outdent();
756
	line( "}\n\n" );
dcw's avatar
dcw committed
757
758
759
}


760
/* -------------------------- Print functions ----------------------------- */
dcw's avatar
dcw committed
761
762


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

773
774
775

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

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

dcw's avatar
dcw committed
844

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


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

861
	if( s->pl == NULL )
dcw's avatar
dcw committed
862
	{
863
864
		line( "fputs( \"%s\", f );", s->name );
		if( s->params )
dcw's avatar
dcw committed
865
		{
866
			line( "fputc( '(', f );" );
dcw's avatar
dcw committed
867
		}
868
		for( p = s->params; p != NULL; p = p->next )
dcw's avatar
dcw committed
869
		{
870
			print_param( s, p, d->Union );
dcw's avatar
dcw committed
871
		}
872
873
874
875
876
		if( s->params )
		{
			line( "fputc( ')', f );" );
		}
	} else
dcw's avatar
dcw committed
877
	{
878
		for( pl = s->pl; pl != NULL; pl = pl->next )
dcw's avatar
dcw committed
879
		{
880
			if( pl->item->tag == printitem_is_str )
dcw's avatar
dcw committed
881
			{
882
883
884
885
886
				line( "fputs( \"%s\", f );",
					pl->item->str );
			} else
			{
				n = pl->item->num;
887
888
889
890
891
				for( p = s->params; p != NULL && --n;
					p = p->next )
					;

				if( p == NULL )
892
				{
893
					fprintf( stderr,
894
895
	"datadec: bad printitem in shape %s of type %s\n",
	s->name, d->name );
896
					exit(1);
897
				}
898
				print_param( s, p, d->Union );
dcw's avatar
dcw committed
899
900
901
			}
		}
	}
902
}
dcw's avatar
dcw committed
903
904


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

909
	if( Union )
dcw's avatar
dcw committed
910
	{
911
912
913
914
915
916
917
918
919
		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 );
		}
920
921
922
	} else
	{
		sprintf( pname, "p->%s", p->name );
dcw's avatar
dcw committed
923
924
	}

925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
	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
941
}