decs.c 16.3 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"


Duncan White's avatar
Duncan White committed
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
static void literalline( char * mesg );
static void h_declns( char * base, char * exports, BOOL init, declnlist d );
static void c_declns( char * base, char * globals, char * begin, declnlist d );
static void data_decls( declnlist decs );
static void declare_type( decln d );
static void declfields( paramlist p );
static void protos( BOOL init, char * base, declnlist d, BOOL prot );
static void proto_type( decln d, BOOL prot );
static void cons_fns( declnlist d );
static void cons_fn_proto( decln d, shapelist s, BOOL prot );
static void cons_fn( decln d, shapelist s );
static void decons_fns( declnlist d );
static void decons_fns_type( decln d );
static void deconskind_proto( decln d, BOOL prot );
static void deconskind_fn( decln d );
static void decons_fn_proto( decln d, shapelist s, BOOL prot );
static void decons_fn( decln d, shapelist s );
static void print_fn_proto( char * name, BOOL prot );
static void print_fns( declnlist d );
static void print_fn_shape( declnlist d, shapelist s );
static void print_all_params( declnlist d, shapelist s );
static void print_param( shapelist s, paramlist p, BOOL Union );
dcw's avatar
dcw committed
31
32


33
34
35
36
37
38
39
static int numtabs = 0;
static FILE *outfile;


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

dcw's avatar
dcw committed
40
41
42
43
#define nl()		fputc( '\n', outfile )
#define outchar(c)	fputc( c, outfile )
#define usefile(f)	outfile = f, numtabs = 0

44
45
46
47


/*VARARGS*/
static void line( fmt, a, b, c, d ) char *fmt; long a, b, c, d;
Duncan White's avatar
Duncan White committed
48
//static void line( char *fmt, long a, long b, long c, long d )
49
50
51
52
53
{
	int i;

	for( i=numtabs; i; i-- ) fputc( '\t', outfile );
	fprintf( outfile, fmt, a, b, c, d );
dcw's avatar
dcw committed
54
	nl();
55
56
57
}


Duncan White's avatar
Duncan White committed
58
static void literalline( char *mesg )
59
60
61
62
63
64
65
66
67
{
	int i;

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


Duncan White's avatar
Duncan White committed
68
void make_declns( char *exports, char *globals, char *begin, declnlist d, char *base )
dcw's avatar
dcw committed
69
{
dcw's avatar
dcw committed
70
71
72
	printf( "datadec: Making data declarations in %s.[ch]\n", base );
	h_declns( base, exports, *begin != '\0', d );
	c_declns( base, globals, begin, d );
73
74
75
}


Duncan White's avatar
Duncan White committed
76
static void h_declns( char *base, char *exports, BOOL init, declnlist d )
77
78
79
80
81
{
	char		tempname[256];
	char		*exportptr;
	FILE		*hfile;

dcw's avatar
dcw committed
82
	sprintf( tempname, "%s.h", base );
83
	hfile = fopen( tempname, "w" );
84
85
86
87
88
	if( hfile == NULL )
	{
		fprintf( stderr, "datadec: can't create '%s'\n", tempname );
		exit(1);
	}
89
90
91
92
93
94
95
96
97
98
99
100

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

101
	exportptr = exports;
102
	if( *exports != '\0' )
dcw's avatar
dcw committed
103
	{
104
		line( "/* Contents of EXPORT section */" );
105
		for( ; *exportptr; exportptr++ )
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
		{
			if( *exportptr == '@' && exportptr[1] == '@'
			&&   exportptr[2] == '\n' )
			{
				exportptr += 2;
				break;
			}
			outchar( *exportptr );
		}

		nl();
		nl();
	}

	data_decls( d );

122
	line( "\n/* Prototypes for all types */\n" );
dcw's avatar
dcw committed
123
	protos( init, base, d, TRUE );
124
125
126
127
128

	if( *exportptr != '\0' )
	{
		nl();
		line( "/* Remaining contents of EXPORT section */" );
129
		literalline( exportptr );
130
		nl();
dcw's avatar
dcw committed
131
	}
132
133

	fclose( hfile );
dcw's avatar
dcw committed
134
135
136
}


Duncan White's avatar
Duncan White committed
137
static void c_declns( char *base, char *globals, char *begin, declnlist d )
138
139
140
141
142
{
	char	tempname[256];
	FILE	*cfile;
	char	*globalptr;

dcw's avatar
dcw committed
143
	sprintf( tempname, "%s.c", base );
144
	cfile = fopen( tempname, "w" );
145
146
147
148
149
	if( cfile == NULL )
	{
		fprintf( stderr, "datadec: can't create '%s'\n", tempname );
		exit(1);
	}
150
151
152
153
154
155
156

	usefile( cfile );

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

160
	globalptr=globals;
161
162
163
	if( *globals != '\0' )
	{
		line( "/* Contents of GLOBAL section */" );
164
		for( ; *globalptr; globalptr++ )
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
		{
			if( *globalptr == '@' && globalptr[1] == '@'
			&&   globalptr[2] == '\n' )
			{
				globalptr += 2;
				break;
			}
			outchar( *globalptr );
		}

		nl();
		nl();
	}

	cons_fns( d );
180
	decons_fns( d );
181
182
183
184
185
186
187
	print_fns( d );

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

dcw's avatar
dcw committed
192
193
194
195
196
197
198
199
	if( *begin != '\0' )
	{
		line( "/* Contents of BEGIN section */" );
		line( "void init_%s()", base );
		line( "{" );
		line( begin );
		line( "}" );
	}
200
201
202
203
	fclose( cfile );
}


204
/* ------------------------ Declare the types ------------------------------ */
205
206


Duncan White's avatar
Duncan White committed
207
static void data_decls( declnlist decs )
dcw's avatar
dcw committed
208
{
209
	declnlist	d;
dcw's avatar
dcw committed
210

dcw's avatar
dcw committed
211
	for( d=decs; d != NULL; d=d->next )
dcw's avatar
dcw committed
212
	{
dcw's avatar
dcw committed
213
214
		if( d->Struct )
		{
215
216
			line("struct %s;", d->name);
			line("typedef struct %s *%s;", d->name, d->name );
dcw's avatar
dcw committed
217
218
219
220
		} else
		{
			line( "typedef int %s;", d->name );
		}
dcw's avatar
dcw committed
221
	}
222
223
	nl();
	nl();
dcw's avatar
dcw committed
224
	for( d=decs; d != NULL; d=d->next )
dcw's avatar
dcw committed
225
	{
226
227
228
229
230
		declare_type( d );
	}
}


Duncan White's avatar
Duncan White committed
231
static void declare_type( decln d )
232
233
234
235
236
237
238
239
240
241
242
{
	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
243
		{
244
			line( "%s_is_%s,", d->name, s->name );
dcw's avatar
dcw committed
245
		}
246
247
248
		outdent();
		line( "} kind_of_%s;\n", d->name );
	}
249

250
251
252
253
254
255
256
257
258
	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
259
		{
260
			line( "union {" );
dcw's avatar
dcw committed
261
			indent();
262
263
264
265
266
		}
		for( s = d->shapes; s != NULL; s=s->next )
		{
			if( s->params == NULL ) continue;

dcw's avatar
dcw committed
267
268
			if( d->Union )
			{
269
270
271
272
273
274
275
				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
276
				{
277
					/* need internal struct */
dcw's avatar
dcw committed
278
279
280
281
282
					line( "struct {" );
					indent();
					declfields( s->params );
					outdent();
					line( "} %s;", s->name );
dcw's avatar
dcw committed
283
				}
284
			} else
dcw's avatar
dcw committed
285
			{
286
287
				/* only one chunk of data: this one */
				declfields( s->params );
dcw's avatar
dcw committed
288
			}
289
290
291
		}
		if( d->Union )
		{
dcw's avatar
dcw committed
292
			outdent();
293
			line( "} u;" );
dcw's avatar
dcw committed
294
		}
295
296
		outdent();
		line( "};\n" );
dcw's avatar
dcw committed
297
298
299
300
	}
}


Duncan White's avatar
Duncan White committed
301
static void declfields( paramlist p )
302
303
304
305
306
307
308
309
{
	for( ; p != NULL; p=p->next )
	{
		line( "%s\t%s;", p->type, p->name );
	}
}


310
/* ---------------------- Declare all prototypes -------------------------- */
311
312


Duncan White's avatar
Duncan White committed
313
static void protos( BOOL init, char *base, declnlist d, BOOL prot )
314
315
316
317
318
{
	for( ; d != NULL; d = d->next )
	{
		proto_type( d, prot );
	}
dcw's avatar
dcw committed
319
320
321
322
323
324
325
326
327
	if( init )
	{
		fprintf( outfile, "extern void init_%s( ", base );
		if( prot )
		{
			fputs( "void ", outfile );
		}
		fputs( ");\n", outfile );
	}
328
329
330
}


Duncan White's avatar
Duncan White committed
331
static void proto_type( decln d, BOOL prot )
332
333
334
{
	shapelist	s;

335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
	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 )
361
	{
362
		/* need a deconstructor kind function/macro */
363
364
		if( d->Struct )
		{
365
366
367
368
369
370
371
372
373
374
375
376
377
378
			/* 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 )
379
			{
380
				decons_fn_proto( d, s, prot );
381
382
			}
		}
383
384
385
386
387
388
389
390
	}
	print_fn_proto( d->name, prot );
}


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


Duncan White's avatar
Duncan White committed
391
static void cons_fns( declnlist d )
392
393
394
395
396
397
398
399
400
401
402
{
	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 )
403
		{
404
405
406
407
408
409
			/* Null cons func is a #define in .h file: skip it */
			s = s->next;
		}
		for( ; s != NULL; s=s->next )
		{
			cons_fn( d, s );
410
411
412
413
414
		}
	}
}


Duncan White's avatar
Duncan White committed
415
static void cons_fn_proto( decln d, shapelist s, BOOL prot )
dcw's avatar
dcw committed
416
417
418
419
{
	paramlist p;
	BOOL first;

420
421
422
423
424
	if( ! d->Struct )
	{
		fprintf( stderr, "cons_fn_proto: d->Struct is false!\n" );
		exit(1);
	}
425
426

	fprintf( outfile, "extern %s %s_%s( ", d->name, d->name, s->name );
427
	if( prot )
dcw's avatar
dcw committed
428
429
430
	{
		if( s->params == NULL )
		{
dcw's avatar
dcw committed
431
			fputs( "void ", outfile );
dcw's avatar
dcw committed
432
433
		} else
		{
dcw's avatar
dcw committed
434
			first = TRUE;
dcw's avatar
dcw committed
435
			for( p = s->params; p != NULL ; p=p->next, first=FALSE )
dcw's avatar
dcw committed
436
			{
dcw's avatar
dcw committed
437
438
439
				if( !first ) fputs( ", ", outfile );
				fputs( p->type, outfile );
				fputc( ' ', outfile );
dcw's avatar
dcw committed
440
441
442
			}
		}
	}
dcw's avatar
dcw committed
443
	fputs( ");\n", outfile );
dcw's avatar
dcw committed
444
445
446
}


Duncan White's avatar
Duncan White committed
447
static void cons_fn( decln d, shapelist s )
dcw's avatar
dcw committed
448
{
449
450
	paramlist p;
	BOOL first;
dcw's avatar
dcw committed
451

452
453
454
455
456
	if( ! d->Struct )
	{
		fprintf( stderr, "cons_fn: d->Struct is FALSE!\n" );
		exit(1);
	}
457
458
459

	fprintf( outfile, "%s %s_%s( ", d->name, d->name, s->name );
	first = TRUE;
460
461
462
463
464
465
466
467
468
469
470

	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 );
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488

	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
489
		{
490
			if( d->Union )
dcw's avatar
dcw committed
491
			{
492
493
494
495
				/* an internal struct */
				line( "new->u.%s.%s = %s;", s->name,
					p->name, p->name );
			} else
dcw's avatar
dcw committed
496
			{
497
498
				/* only one chunk of data: this one */
				line( "new->%s = %s;", p->name, p->name );
dcw's avatar
dcw committed
499
			}
500
		}
dcw's avatar
dcw committed
501
	}
502
503
504
	line( "return new;" );
	outdent();
	line( "}\n\n" );
dcw's avatar
dcw committed
505
506
507
}


508
509
510
/* ------------------------- Deconstructors ------------------------------- */


Duncan White's avatar
Duncan White committed
511
static void decons_fns( declnlist d )
dcw's avatar
dcw committed
512
{
513
514
515
516
517
518
519
520
521
	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
522

523

Duncan White's avatar
Duncan White committed
524
static void decons_fns_type( decln d )
525
526
527
{
	shapelist	s;

528
529
530
531
532
	if( ! d->Struct )
	{
		fprintf( stderr, "decons_fns_type: d->Struct is FALSE!\n" );
		exit(1);
	}
533
534

	if( d->ManyShapes )
dcw's avatar
dcw committed
535
	{
536
537
		/* We need a true deconstructor kind function */
		deconskind_fn( d );
dcw's avatar
dcw committed
538
	}
539
540
	/* We need (some) deconstructor functions */
	for( s = d->shapes; s != NULL; s=s->next )
dcw's avatar
dcw committed
541
	{
542
543
544
545
		if( s->params != NULL )
		{
			decons_fn( d, s );
		}
dcw's avatar
dcw committed
546
547
548
549
	}
}


550
551
552
/* ------------------- Deconstructor Kind procedure ----------------------- */


Duncan White's avatar
Duncan White committed
553
static void deconskind_proto( decln d, BOOL prot )
dcw's avatar
dcw committed
554
{
555
556
557
558
559
560
561
562
563
564
565
	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);
	}
566
567
568
569
570
571
572
573
574
575

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


Duncan White's avatar
Duncan White committed
576
static void deconskind_fn( decln d )
577
578
579
{
	shapelist s = d->shapes;

580
581
582
583
584
585
586
587
588
589
	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);
	}
590

591
592
	fprintf( outfile, "kind_of_%s %s_kind( %s this )\n",
		 d->name, d->name, d->name );
dcw's avatar
dcw committed
593

594
595
	line( "{" );
	indent();
596
597
598
599
600
601
602
603
604
605
606

	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
607
608
	if( d->TagField )
	{
609
		line( "return this->tag;" );
dcw's avatar
dcw committed
610
	}
611
	else
dcw's avatar
dcw committed
612
	{
613
614
615
616
617
618
619
620
621
622
		line( "return %s_is_%s;", d->name, s->name );
	}
	outdent();
	line( "}\n\n" );
}


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


Duncan White's avatar
Duncan White committed
623
static void decons_fn_proto( decln d, shapelist s, BOOL prot )
624
{
625
626
627
628
629
630
631
632
633
634
	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);
	}
635
636
637
638
639
640
641
642

	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
643
		{
644
645
646
647
648
649
650
			fprintf( outfile, ", %s * ", p->type );
		}
	}
	fputs( ");\n", outfile );
}


Duncan White's avatar
Duncan White committed
651
static void decons_fn( decln d, shapelist s )
652
653
654
{
	paramlist p;

655
656
657
658
659
660
661
662
663
664
	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);
	}
665

666
667
668
669
670
671
	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, " )" );
672
673
674
675
676
677
678
679
680
681
682
	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
683
		{
684
685
686
687
688
689
690
691
692
693
			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
694
		}
dcw's avatar
dcw committed
695
	}
696
	outdent();
697
	line( "}\n\n" );
dcw's avatar
dcw committed
698
699
700
}


701
/* -------------------------- Print functions ----------------------------- */
dcw's avatar
dcw committed
702
703


Duncan White's avatar
Duncan White committed
704
static void print_fn_proto( char *name, BOOL prot )
dcw's avatar
dcw committed
705
{
706
707
708
	fprintf( outfile, "extern void print_%s(", name );
	if( prot )
	{
709
		fprintf( outfile, " FILE *, %s ", name );
710
711
712
	}
	fputs( ");\n", outfile );
}
dcw's avatar
dcw committed
713

714

Duncan White's avatar
Duncan White committed
715
static void print_fns( declnlist d )
716
{
dcw's avatar
dcw committed
717
	for( ; d != NULL; d = d->next )
dcw's avatar
dcw committed
718
	{
719
720
		shapelist s;

721
		line( "void print_%s( FILE *f, %s p )",d->name, d->name );
722
723
		line( "{" );
		indent();
724
		s = d->shapes;
dcw's avatar
dcw committed
725
		if( d->UseNull )
dcw's avatar
dcw committed
726
		{
dcw's avatar
dcw committed
727
728
729
			line( "if( p == NULL )" );
			line( "{" );
			indent();
730
			print_all_params( d, s );
dcw's avatar
dcw committed
731
732
733
			line( "return;" );
			outdent();
			line( "}" );
734
			s = s->next;
dcw's avatar
dcw committed
735
736
737
738
739
		}
		if( d->TagField )
		{
			line( "switch( p->tag )" );
			line( "{" );
740
			for( ; s != NULL; s = s->next )
dcw's avatar
dcw committed
741
742
743
744
745
746
747
748
749
750
751
			{
				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( "}" );
752
753
		}
		else if( ! d->TagField && d->Struct )	/* one shape left */
dcw's avatar
dcw committed
754
		{
755
756
757
			print_all_params( d, s );
		}
		else if( ! d->Struct && d->ManyShapes ) /* enumerated type */
dcw's avatar
dcw committed
758
759
760
		{
			line( "switch( p )" );
			line( "{" );
761
			for( ; s != NULL; s = s->next )
dcw's avatar
dcw committed
762
			{
dcw's avatar
dcw committed
763
				line( "case %s_%s():", d->name, s->name );
dcw's avatar
dcw committed
764
765
766
767
768
769
				indent();
				print_all_params( d, s );
				line( "break;" );
				outdent();
			}
			line( "}" );
dcw's avatar
dcw committed
770
771
772
773
774
		} else
		{
			fprintf( stderr,
				 "datadec: internal error in print_fns\n" );
			exit(1);
dcw's avatar
dcw committed
775
		}
776
		outdent();
777
		line( "}\n\n" );
dcw's avatar
dcw committed
778
779
780
	}
}

dcw's avatar
dcw committed
781

Duncan White's avatar
Duncan White committed
782
static void print_fn_shape( declnlist d, shapelist s )
dcw's avatar
dcw committed
783
{
784
	line( "case %s_is_%s:", d->name, s->name );
785
786
787
788
	indent();
	print_all_params( d, s );
	line( "break;" );
	outdent();
dcw's avatar
dcw committed
789
790
791
}


Duncan White's avatar
Duncan White committed
792
static void print_all_params( declnlist d, shapelist s )
dcw's avatar
dcw committed
793
{
794
795
796
	printlist	pl;
	paramlist	p;
	int		n;
dcw's avatar
dcw committed
797

798
	if( s->pl == NULL )
dcw's avatar
dcw committed
799
	{
800
801
		line( "fputs( \"%s\", f );", s->name );
		if( s->params )
dcw's avatar
dcw committed
802
		{
803
			line( "fputc( '(', f );" );
dcw's avatar
dcw committed
804
		}
805
		for( p = s->params; p != NULL; p = p->next )
dcw's avatar
dcw committed
806
		{
807
			print_param( s, p, d->Union );
808
809
810
811
			if( p->next != NULL )
			{
				line( "fputc( ',', f );" );
			}
dcw's avatar
dcw committed
812
		}
813
814
815
816
817
		if( s->params )
		{
			line( "fputc( ')', f );" );
		}
	} else
dcw's avatar
dcw committed
818
	{
819
		for( pl = s->pl; pl != NULL; pl = pl->next )
dcw's avatar
dcw committed
820
		{
821
			if( pl->item->tag == printitem_is_str )
dcw's avatar
dcw committed
822
			{
823
824
825
826
827
				line( "fputs( \"%s\", f );",
					pl->item->str );
			} else
			{
				n = pl->item->num;
828
829
830
831
832
				for( p = s->params; p != NULL && --n;
					p = p->next )
					;

				if( p == NULL )
833
				{
834
					fprintf( stderr,
835
836
	"datadec: bad printitem in shape %s of type %s\n",
	s->name, d->name );
837
					exit(1);
838
				}
839
				print_param( s, p, d->Union );
dcw's avatar
dcw committed
840
841
842
			}
		}
	}
843
}
dcw's avatar
dcw committed
844
845


Duncan White's avatar
Duncan White committed
846
static void print_param( shapelist s, paramlist p, BOOL Union )
847
848
{
	char pname[200];
dcw's avatar
dcw committed
849

850
	if( Union )
dcw's avatar
dcw committed
851
	{
852
853
854
855
856
857
858
859
860
		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 );
		}
861
862
863
	} else
	{
		sprintf( pname, "p->%s", p->name );
dcw's avatar
dcw committed
864
865
	}

866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
	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
882
}