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

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


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


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


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


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

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

76
77
78
79
80
81
82
83
84


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


89
90
91
92
93
94
95
96
97
98
static void literalline( mesg ) char *mesg;
{
	int i;

	for( i=numtabs; i; i-- ) fputc( '\t', outfile );
	fputs( mesg, outfile );
	nl();
}


dcw's avatar
dcw committed
99
void make_declns( exports, globals, begin, d, base ) declnlist d; char *exports, *globals, *begin, *base;
dcw's avatar
dcw committed
100
{
dcw's avatar
dcw committed
101
102
103
	printf( "datadec: Making data declarations in %s.[ch]\n", base );
	h_declns( base, exports, *begin != '\0', d );
	c_declns( base, globals, begin, d );
104
105
106
}


dcw's avatar
dcw committed
107
static void h_declns( base, exports, init, d ) char *base, *exports; BOOL init; declnlist d;
108
109
110
111
112
{
	char		tempname[256];
	char		*exportptr;
	FILE		*hfile;

dcw's avatar
dcw committed
113
	sprintf( tempname, "%s.h", base );
114
	hfile = fopen( tempname, "w" );
115
116
117
118
119
	if( hfile == NULL )
	{
		fprintf( stderr, "datadec: can't create '%s'\n", tempname );
		exit(1);
	}
120
121
122
123
124
125
126
127
128
129
130
131

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

132
	exportptr = exports;
133
	if( *exports != '\0' )
dcw's avatar
dcw committed
134
	{
135
		line( "/* Contents of EXPORT section */" );
136
		for( ; *exportptr; exportptr++ )
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
		{
			if( *exportptr == '@' && exportptr[1] == '@'
			&&   exportptr[2] == '\n' )
			{
				exportptr += 2;
				break;
			}
			outchar( *exportptr );
		}

		nl();
		nl();
	}

	data_decls( d );

153
	line( "\n/* Prototypes for all types */\n" );
154
#ifdef KANDR
155
	line( "#ifdef HASPROTOS" );
156
#endif
dcw's avatar
dcw committed
157
	protos( init, base, d, TRUE );
158
#ifdef KANDR
159
	line( "#else" );
dcw's avatar
dcw committed
160
	protos( init, base, d, FALSE );
161
	line( "#endif" );
162
#endif
163
164
165
166
167

	if( *exportptr != '\0' )
	{
		nl();
		line( "/* Remaining contents of EXPORT section */" );
168
		literalline( exportptr );
169
		nl();
dcw's avatar
dcw committed
170
	}
171
172

	fclose( hfile );
dcw's avatar
dcw committed
173
174
175
}


dcw's avatar
dcw committed
176
static void c_declns( base, globals, begin, d ) char *base, *globals, *begin; declnlist d;
177
178
179
180
181
{
	char	tempname[256];
	FILE	*cfile;
	char	*globalptr;

dcw's avatar
dcw committed
182
	sprintf( tempname, "%s.c", base );
183
	cfile = fopen( tempname, "w" );
184
185
186
187
188
	if( cfile == NULL )
	{
		fprintf( stderr, "datadec: can't create '%s'\n", tempname );
		exit(1);
	}
189
190
191
192
193
194
195

	usefile( cfile );

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

199
	globalptr=globals;
200
201
202
	if( *globals != '\0' )
	{
		line( "/* Contents of GLOBAL section */" );
203
		for( ; *globalptr; globalptr++ )
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
		{
			if( *globalptr == '@' && globalptr[1] == '@'
			&&   globalptr[2] == '\n' )
			{
				globalptr += 2;
				break;
			}
			outchar( *globalptr );
		}

		nl();
		nl();
	}

	cons_fns( d );
219
	decons_fns( d );
220
221
222
223
224
225
226
	print_fns( d );

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

dcw's avatar
dcw committed
231
232
233
234
235
236
237
238
	if( *begin != '\0' )
	{
		line( "/* Contents of BEGIN section */" );
		line( "void init_%s()", base );
		line( "{" );
		line( begin );
		line( "}" );
	}
239
240
241
242
	fclose( cfile );
}


243
/* ------------------------ Declare the types ------------------------------ */
244
245


246
static void data_decls( decs ) declnlist decs;
dcw's avatar
dcw committed
247
{
248
	declnlist	d;
dcw's avatar
dcw committed
249

dcw's avatar
dcw committed
250
	for( d=decs; d != NULL; d=d->next )
dcw's avatar
dcw committed
251
	{
dcw's avatar
dcw committed
252
253
		if( d->Struct )
		{
254
255
			line("struct %s;", d->name);
			line("typedef struct %s *%s;", d->name, d->name );
dcw's avatar
dcw committed
256
257
258
259
		} else
		{
			line( "typedef int %s;", d->name );
		}
dcw's avatar
dcw committed
260
	}
261
262
	nl();
	nl();
dcw's avatar
dcw committed
263
	for( d=decs; d != NULL; d=d->next )
dcw's avatar
dcw committed
264
	{
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
		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
282
		{
283
			line( "%s_is_%s,", d->name, s->name );
dcw's avatar
dcw committed
284
		}
285
286
287
		outdent();
		line( "} kind_of_%s;\n", d->name );
	}
288

289
290
291
292
293
294
295
296
297
	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
298
		{
299
			line( "union {" );
dcw's avatar
dcw committed
300
			indent();
301
302
303
304
305
		}
		for( s = d->shapes; s != NULL; s=s->next )
		{
			if( s->params == NULL ) continue;

dcw's avatar
dcw committed
306
307
			if( d->Union )
			{
308
309
310
311
312
313
314
				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
315
				{
316
					/* need internal struct */
dcw's avatar
dcw committed
317
318
319
320
321
					line( "struct {" );
					indent();
					declfields( s->params );
					outdent();
					line( "} %s;", s->name );
dcw's avatar
dcw committed
322
				}
323
			} else
dcw's avatar
dcw committed
324
			{
325
326
				/* only one chunk of data: this one */
				declfields( s->params );
dcw's avatar
dcw committed
327
			}
328
329
330
		}
		if( d->Union )
		{
dcw's avatar
dcw committed
331
			outdent();
332
			line( "} u;" );
dcw's avatar
dcw committed
333
		}
334
335
		outdent();
		line( "};\n" );
dcw's avatar
dcw committed
336
337
338
339
	}
}


340
341
342
343
344
345
346
347
348
static void declfields( p ) paramlist p;
{
	for( ; p != NULL; p=p->next )
	{
		line( "%s\t%s;", p->type, p->name );
	}
}


349
/* ---------------------- Declare all prototypes -------------------------- */
350
351


dcw's avatar
dcw committed
352
static void protos( init, base, d, prot ) BOOL init; char *base; declnlist d; BOOL prot;
353
354
355
356
357
{
	for( ; d != NULL; d = d->next )
	{
		proto_type( d, prot );
	}
dcw's avatar
dcw committed
358
359
360
361
362
363
364
365
366
	if( init )
	{
		fprintf( outfile, "extern void init_%s( ", base );
		if( prot )
		{
			fputs( "void ", outfile );
		}
		fputs( ");\n", outfile );
	}
367
368
369
370
}


static void proto_type( d, prot ) decln d; BOOL prot;
371
372
373
{
	shapelist	s;

374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
	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 )
400
	{
401
		/* need a deconstructor kind function/macro */
402
403
		if( d->Struct )
		{
404
405
406
407
408
409
410
411
412
413
414
415
416
417
			/* 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 )
418
			{
419
				decons_fn_proto( d, s, prot );
420
421
			}
		}
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
	}
	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 )
442
		{
443
444
445
446
447
448
			/* Null cons func is a #define in .h file: skip it */
			s = s->next;
		}
		for( ; s != NULL; s=s->next )
		{
			cons_fn( d, s );
449
450
451
452
453
		}
	}
}


454
static void cons_fn_proto( d, s, prot ) decln d; shapelist s; BOOL prot;
dcw's avatar
dcw committed
455
456
457
458
{
	paramlist p;
	BOOL first;

459
460
461
462
463
	if( ! d->Struct )
	{
		fprintf( stderr, "cons_fn_proto: d->Struct is false!\n" );
		exit(1);
	}
464
465

	fprintf( outfile, "extern %s %s_%s( ", d->name, d->name, s->name );
466
	if( prot )
dcw's avatar
dcw committed
467
468
469
	{
		if( s->params == NULL )
		{
dcw's avatar
dcw committed
470
			fputs( "void ", outfile );
dcw's avatar
dcw committed
471
472
		} else
		{
dcw's avatar
dcw committed
473
			first = TRUE;
dcw's avatar
dcw committed
474
			for( p = s->params; p != NULL ; p=p->next, first=FALSE )
dcw's avatar
dcw committed
475
			{
dcw's avatar
dcw committed
476
477
478
				if( !first ) fputs( ", ", outfile );
				fputs( p->type, outfile );
				fputc( ' ', outfile );
dcw's avatar
dcw committed
479
480
481
			}
		}
	}
dcw's avatar
dcw committed
482
	fputs( ");\n", outfile );
dcw's avatar
dcw committed
483
484
485
}


486
static void cons_fn( d, s ) decln d; shapelist s;
dcw's avatar
dcw committed
487
{
488
489
	paramlist p;
	BOOL first;
dcw's avatar
dcw committed
490

491
492
493
494
495
	if( ! d->Struct )
	{
		fprintf( stderr, "cons_fn: d->Struct is FALSE!\n" );
		exit(1);
	}
496
497
498

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

#ifdef KANDR
501
	for( p=s->params; p != NULL; p=p->next, first=FALSE )
dcw's avatar
dcw committed
502
	{
503
504
505
506
507
508
509
510
		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 );
	}
511
512
513
514
515
516
517
518
519
520
521
522
#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
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540

	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
541
		{
542
			if( d->Union )
dcw's avatar
dcw committed
543
			{
544
545
546
547
				/* an internal struct */
				line( "new->u.%s.%s = %s;", s->name,
					p->name, p->name );
			} else
dcw's avatar
dcw committed
548
			{
549
550
				/* only one chunk of data: this one */
				line( "new->%s = %s;", p->name, p->name );
dcw's avatar
dcw committed
551
			}
552
		}
dcw's avatar
dcw committed
553
	}
554
555
556
	line( "return new;" );
	outdent();
	line( "}\n\n" );
dcw's avatar
dcw committed
557
558
559
}


560
561
562
563
/* ------------------------- Deconstructors ------------------------------- */


static void decons_fns( d ) declnlist d;
dcw's avatar
dcw committed
564
{
565
566
567
568
569
570
571
572
573
	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
574

575
576
577
578
579

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

580
581
582
583
584
	if( ! d->Struct )
	{
		fprintf( stderr, "decons_fns_type: d->Struct is FALSE!\n" );
		exit(1);
	}
585
586

	if( d->ManyShapes )
dcw's avatar
dcw committed
587
	{
588
589
		/* We need a true deconstructor kind function */
		deconskind_fn( d );
dcw's avatar
dcw committed
590
	}
591
592
	/* We need (some) deconstructor functions */
	for( s = d->shapes; s != NULL; s=s->next )
dcw's avatar
dcw committed
593
	{
594
595
596
597
		if( s->params != NULL )
		{
			decons_fn( d, s );
		}
dcw's avatar
dcw committed
598
599
600
601
	}
}


602
603
604
605
/* ------------------- Deconstructor Kind procedure ----------------------- */


static void deconskind_proto( d, prot ) decln d; BOOL prot;
dcw's avatar
dcw committed
606
{
607
608
609
610
611
612
613
614
615
616
617
	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);
	}
618
619
620
621
622
623
624
625
626
627
628
629
630
631

	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;

632
633
634
635
636
637
638
639
640
641
	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);
	}
642

643
#ifdef KANDR
644
645
	fprintf( outfile, "kind_of_%s %s_kind( this ) %s this;\n",
		 d->name, d->name, d->name );
646
647
648
649
#else
	fprintf( outfile, "kind_of_%s %s_kind( %s this )\n",
		 d->name, d->name, d->name );
#endif
dcw's avatar
dcw committed
650

651
652
	line( "{" );
	indent();
653
654
655
656
657
658
659
660
661
662
663

	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
664
665
	if( d->TagField )
	{
666
		line( "return this->tag;" );
dcw's avatar
dcw committed
667
	}
668
	else
dcw's avatar
dcw committed
669
	{
670
671
672
673
674
675
676
677
678
679
680
681
		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;
{
682
683
684
685
686
687
688
689
690
691
	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);
	}
692
693
694
695
696
697
698
699

	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
700
		{
701
702
703
704
705
706
707
708
709
710
711
			fprintf( outfile, ", %s * ", p->type );
		}
	}
	fputs( ");\n", outfile );
}


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

712
713
714
715
716
717
718
719
720
721
	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);
	}
722

723
#ifdef KANDR
724
725
726
727
728
729
730
731
732
733
	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 );
	}
734
735
736
737
738
739
740
741
#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
742
743
744
745
746
747
748
749
750
751
752
	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
753
		{
754
755
756
757
758
759
760
761
762
763
			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
764
		}
dcw's avatar
dcw committed
765
	}
766
	outdent();
767
	line( "}\n\n" );
dcw's avatar
dcw committed
768
769
770
}


771
/* -------------------------- Print functions ----------------------------- */
dcw's avatar
dcw committed
772
773


774
static void print_fn_proto( name, prot ) char *name; BOOL prot;
dcw's avatar
dcw committed
775
{
776
777
778
	fprintf( outfile, "extern void print_%s(", name );
	if( prot )
	{
779
		fprintf( outfile, " FILE *, %s ", name );
780
781
782
	}
	fputs( ");\n", outfile );
}
dcw's avatar
dcw committed
783

784
785
786

static void print_fns( d ) declnlist d;
{
dcw's avatar
dcw committed
787
	for( ; d != NULL; d = d->next )
dcw's avatar
dcw committed
788
	{
789
790
		shapelist s;

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

dcw's avatar
dcw committed
855

856
static void print_fn_shape( d, s ) declnlist d; shapelist s;
dcw's avatar
dcw committed
857
{
858
	line( "case %s_is_%s:", d->name, s->name );
859
860
861
862
	indent();
	print_all_params( d, s );
	line( "break;" );
	outdent();
dcw's avatar
dcw committed
863
864
865
}


866
static void print_all_params( d, s ) declnlist d; shapelist s;
dcw's avatar
dcw committed
867
{
868
869
870
	printlist	pl;
	paramlist	p;
	int		n;
dcw's avatar
dcw committed
871

872
	if( s->pl == NULL )
dcw's avatar
dcw committed
873
	{
874
875
		line( "fputs( \"%s\", f );", s->name );
		if( s->params )
dcw's avatar
dcw committed
876
		{
877
			line( "fputc( '(', f );" );
dcw's avatar
dcw committed
878
		}
879
		for( p = s->params; p != NULL; p = p->next )
dcw's avatar
dcw committed
880
		{
881
			print_param( s, p, d->Union );
882
883
884
885
			if( p->next != NULL )
			{
				line( "fputc( ',', f );" );
			}
dcw's avatar
dcw committed
886
		}
887
888
889
890
891
		if( s->params )
		{
			line( "fputc( ')', f );" );
		}
	} else
dcw's avatar
dcw committed
892
	{
893
		for( pl = s->pl; pl != NULL; pl = pl->next )
dcw's avatar
dcw committed
894
		{
895
			if( pl->item->tag == printitem_is_str )
dcw's avatar
dcw committed
896
			{
897
898
899
900
901
				line( "fputs( \"%s\", f );",
					pl->item->str );
			} else
			{
				n = pl->item->num;
902
903
904
905
906
				for( p = s->params; p != NULL && --n;
					p = p->next )
					;

				if( p == NULL )
907
				{
908
					fprintf( stderr,
909
910
	"datadec: bad printitem in shape %s of type %s\n",
	s->name, d->name );
911
					exit(1);
912
				}
913
				print_param( s, p, d->Union );
dcw's avatar
dcw committed
914
915
916
			}
		}
	}
917
}
dcw's avatar
dcw committed
918
919


920
static void print_param( s, p, Union ) shapelist s; paramlist p; BOOL Union;
921
922
{
	char pname[200];
dcw's avatar
dcw committed
923

924
	if( Union )
dcw's avatar
dcw committed
925
	{
926
927
928
929
930
931
932
933
934
		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 );
		}
935
936
937
	} else
	{
		sprintf( pname, "p->%s", p->name );
dcw's avatar
dcw committed
938
939
	}

940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
	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
956
}