decs.c 10.6 KB
Newer Older
dcw's avatar
dcw committed
1
2
3
4
5
#include <dcw.h>
#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
15
static void line( char * , long , long , long , long );
static void declfields( paramlist );
16
static void data_decls( declnlist );
dcw's avatar
dcw committed
17
18
19
20
21
static void one_proto( char * , shapelist , BOOL );
static void protos( declnlist , BOOL );
static void cons_fn_hdr( char * , shapelist );
static void cons_fn_body( declnlist , char * , shapelist );
static void cons_fns( declnlist );
dcw's avatar
dcw committed
22
23
static void print_param( char * , paramlist , BOOL );
static void print_all_params( declnlist , shapelist );
dcw's avatar
dcw committed
24
25
26
27
static void print_fn_shape( declnlist , shapelist );
static void print_fns( declnlist );
static void h_declns( char * , char * , declnlist );
static void c_declns( char * , char * , declnlist );
dcw's avatar
dcw committed
28
#else
dcw's avatar
dcw committed
29
30
static void line();
static void declfields();
dcw's avatar
dcw committed
31
32
33
34
35
36
37
static void data_decls();
static void one_proto();
static void protos();
static void cons_fn_hdr();
static void cons_fn_body();
static void cons_fns();
static void print_param();
dcw's avatar
dcw committed
38
static void print_all_params();
dcw's avatar
dcw committed
39
40
41
42
static void print_fn_shape();
static void print_fns();
static void h_declns();
static void c_declns();
dcw's avatar
dcw committed
43
44
45
#endif


46
47
48
49
50
51
52
static int numtabs = 0;
static FILE *outfile;


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

dcw's avatar
dcw committed
53
54
55
56
#define nl()		fputc( '\n', outfile )
#define outchar(c)	fputc( c, outfile )
#define usefile(f)	outfile = f, numtabs = 0

57
58
59
60
61
62
63
64
65


/*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
66
	nl();
67
68
69
}


dcw's avatar
dcw committed
70
71
static void declfields( p ) paramlist p;
{
dcw's avatar
dcw committed
72
	for( ; p != NULL; p=p->next )
dcw's avatar
dcw committed
73
74
75
76
77
78
	{
		line( "%s\t%s;", p->type, p->name );
	}
}


79
static void data_decls( decs ) declnlist decs;
dcw's avatar
dcw committed
80
{
81
82
83
	declnlist	d;
	shapelist	s;
	int		n;
dcw's avatar
dcw committed
84

dcw's avatar
dcw committed
85
	for( d=decs; d != NULL; d=d->next )
dcw's avatar
dcw committed
86
	{
dcw's avatar
dcw committed
87
88
		if( d->Struct )
		{
89
90
			line("struct %s;", d->name);
			line("typedef struct %s *%s;", d->name, d->name );
dcw's avatar
dcw committed
91
92
93
94
		} else
		{
			line( "typedef int %s;", d->name );
		}
dcw's avatar
dcw committed
95
	}
96
	line( "\n" );
dcw's avatar
dcw committed
97
	for( d=decs; d != NULL; d=d->next )
dcw's avatar
dcw committed
98
	{
99
		line( "/* ---- Type %s ---- */\n", d->name );
dcw's avatar
dcw committed
100
		n = 0;
dcw's avatar
dcw committed
101
		if( d->Defines )
dcw's avatar
dcw committed
102
		{
dcw's avatar
dcw committed
103
			for( s = d->shapes; s != NULL; s=s->next )
dcw's avatar
dcw committed
104
105
106
107
108
109
110
111
112
113
114
115
			{
				if( d->Struct )
				{
					line( "#define %s_%s_tag %d",
						d->name, s->name, n++ );
				} else
				{
					line( "#define %s_%s() %d",
						d->name, s->name, n++ );
				}
			}
			line( "" );
dcw's avatar
dcw committed
116
		}
117

dcw's avatar
dcw committed
118
		if( d->Struct )
dcw's avatar
dcw committed
119
		{
dcw's avatar
dcw committed
120
			line( "struct %s {", d->name );
dcw's avatar
dcw committed
121
122
			indent();
			if( d->TagField )
dcw's avatar
dcw committed
123
			{
dcw's avatar
dcw committed
124
125
126
127
128
				line( "int\ttag;" );
			}
			if( d->Union )
			{
				line( "union {" );
129
				indent();
dcw's avatar
dcw committed
130
			}
dcw's avatar
dcw committed
131
			for( s = d->shapes; s != NULL; s=s->next )
dcw's avatar
dcw committed
132
133
134
135
136
137
138
139
140
141
			{
				if( d->Union && s->params )
				/* need internal structures */
				{
					line( "struct {" );
					indent();
					declfields( s->params );
					outdent();
					line( "} %s;", s->name );
				} else
dcw's avatar
dcw committed
142
				{
dcw's avatar
dcw committed
143
					declfields( s->params );
dcw's avatar
dcw committed
144
				}
dcw's avatar
dcw committed
145
146
147
			}
			if( d->Union )
			{
148
				outdent();
dcw's avatar
dcw committed
149
				line( "} u;" );
dcw's avatar
dcw committed
150
			}
dcw's avatar
dcw committed
151
152
			outdent();
			line( "};\n" );
dcw's avatar
dcw committed
153
154
155
156
157
		}
	}
}


dcw's avatar
dcw committed
158
static void one_proto( name, s, prot ) char *name; shapelist s; BOOL prot;
dcw's avatar
dcw committed
159
160
161
162
{
	paramlist p;
	BOOL first;

dcw's avatar
dcw committed
163
	fprintf( outfile, "extern %s %s_%s( ", name, name, s->name );
164
	if( prot )
dcw's avatar
dcw committed
165
166
167
	{
		if( s->params == NULL )
		{
dcw's avatar
dcw committed
168
			fputs( "void ", outfile );
dcw's avatar
dcw committed
169
170
		} else
		{
dcw's avatar
dcw committed
171
			first = TRUE;
dcw's avatar
dcw committed
172
			for( p = s->params; p != NULL ; p=p->next, first=FALSE )
dcw's avatar
dcw committed
173
			{
dcw's avatar
dcw committed
174
175
176
				if( !first ) fputs( ", ", outfile );
				fputs( p->type, outfile );
				fputc( ' ', outfile );
dcw's avatar
dcw committed
177
178
179
			}
		}
	}
dcw's avatar
dcw committed
180
	fputs( ");\n", outfile );
dcw's avatar
dcw committed
181
182
183
}


dcw's avatar
dcw committed
184
static void protos( d, prot ) declnlist d; BOOL prot;
dcw's avatar
dcw committed
185
{
186
	shapelist	s;
dcw's avatar
dcw committed
187
	shapelist	shapes;
dcw's avatar
dcw committed
188

dcw's avatar
dcw committed
189
	for( ; d != NULL; d = d->next )
dcw's avatar
dcw committed
190
	{
dcw's avatar
dcw committed
191
		if( d->Struct )
dcw's avatar
dcw committed
192
		{
dcw's avatar
dcw committed
193
194
195
196
197
198
199
200
201
			shapes = d->shapes;
			if( d->UseNull )
			{
				shapes = shapes->next;
			}
			for( s = shapes; s != NULL; s = s->next )
			{
				one_proto( d->name, s, prot );
			}
202
		}
dcw's avatar
dcw committed
203
204
		fprintf( outfile, "extern void print_%s(", d->name );
		if( prot )
205
		{
dcw's avatar
dcw committed
206
			fprintf( outfile, " %s ", d->name );
dcw's avatar
dcw committed
207
		}
dcw's avatar
dcw committed
208
		fputs( ");\n", outfile );
dcw's avatar
dcw committed
209
	}
dcw's avatar
dcw committed
210
211
212
}


dcw's avatar
dcw committed
213
static void cons_fn_hdr( name, s ) char *name; shapelist s;
dcw's avatar
dcw committed
214
215
216
217
{
	paramlist p;
	BOOL first;

dcw's avatar
dcw committed
218
	fprintf( outfile, "%s %s_%s( ", name, name, s->name );
dcw's avatar
dcw committed
219
	first = TRUE;
dcw's avatar
dcw committed
220
	for( p=s->params; p != NULL; p=p->next, first=FALSE )
dcw's avatar
dcw committed
221
	{
dcw's avatar
dcw committed
222
223
		if( !first ) fputs( ", ", outfile );
		fputs( p->name, outfile );
dcw's avatar
dcw committed
224
	}
dcw's avatar
dcw committed
225
226
	fputs( " ) ", outfile );
	for( p=s->params; p != NULL; p=p->next )
dcw's avatar
dcw committed
227
	{
dcw's avatar
dcw committed
228
		fprintf( outfile, "%s %s; ", p->type, p->name );
dcw's avatar
dcw committed
229
	}
dcw's avatar
dcw committed
230
	nl();
dcw's avatar
dcw committed
231
232
233
}


dcw's avatar
dcw committed
234
static void cons_fn_body( d, name, s ) declnlist d; char *name; shapelist s;
dcw's avatar
dcw committed
235
236
237
{
	paramlist p;

dcw's avatar
dcw committed
238
	ASSERT( d->Struct,
239
		("error: cons_fn_body called but d->Struct is FALSE!\n") );
240
241
	line( "{" );
	indent();
dcw's avatar
dcw committed
242
	line( "%s\tnew;\n", name );
dcw's avatar
dcw committed
243
	line( "new = NEW(%s);", name );
dcw's avatar
dcw committed
244
245
246
247
	if( d->TagField )
	{
		line( "new->tag = %s_%s_tag;", name, s->name );
	}
dcw's avatar
dcw committed
248
	for( p=s->params; p != NULL; p=p->next )
dcw's avatar
dcw committed
249
	{
dcw's avatar
dcw committed
250
251
252
253
254
255
256
257
		if( d->Union )
		{
			line( "new->u.%s.%s = %s;",
				s->name, p->name, p->name );
		} else
		{
			line( "new->%s = %s;", p->name, p->name );
		}
dcw's avatar
dcw committed
258
	}
259
260
261
	line( "return new;" );
	outdent();
	line( "}" );
dcw's avatar
dcw committed
262
263
264
}


dcw's avatar
dcw committed
265
static void cons_fns( d ) declnlist d;
dcw's avatar
dcw committed
266
{
dcw's avatar
dcw committed
267
268
	shapelist	s;
	shapelist	shapes;
dcw's avatar
dcw committed
269

dcw's avatar
dcw committed
270
	for( ; d != NULL; d=d->next )
dcw's avatar
dcw committed
271
	{
dcw's avatar
dcw committed
272
		if( d->Struct )
dcw's avatar
dcw committed
273
		{
dcw's avatar
dcw committed
274
275
276
277
278
279
280
			/* We need constructor functions */
			shapes = d->shapes;
			if( d->UseNull )
			{
				/* Null cons func already made */
				shapes = shapes->next;
			}
dcw's avatar
dcw committed
281
			for( s = shapes; s != NULL; s=s->next )
dcw's avatar
dcw committed
282
			{
dcw's avatar
dcw committed
283
				cons_fn_hdr( d->name, s );
dcw's avatar
dcw committed
284
				cons_fn_body( d, d->name, s );
dcw's avatar
dcw committed
285
				fprintf( outfile, "\n\n" );
dcw's avatar
dcw committed
286
			}
dcw's avatar
dcw committed
287
288
289
290
291
		}
	}
}


dcw's avatar
dcw committed
292
static void print_param( shape, p, Union ) char *shape; paramlist p; BOOL Union;
dcw's avatar
dcw committed
293
294
295
{
	char pname[200];

dcw's avatar
dcw committed
296
297
298
299
300
301
302
303
304
	if( Union )
	{
		sprintf( pname, "p->u.%s.%s", shape, p->name );
	} else
	{
		sprintf( pname, "p->%s", p->name );
	}

	if( streq( p->type, "int" ) )
dcw's avatar
dcw committed
305
	{
306
		line( "fprintf( f, \"%%d\", %s );", pname );
dcw's avatar
dcw committed
307
	} else if( streq( p->type, "char" ) )
dcw's avatar
dcw committed
308
	{
309
		line( "fputc( %s, f );", pname );
dcw's avatar
dcw committed
310
	} else if( streq( p->type, "BOOL" ) )
dcw's avatar
dcw committed
311
	{
312
		line( "fputs( %s?\"true\":\"false\", f );", pname );
dcw's avatar
dcw committed
313
	} else if( streq( p->type, "string" ) )
dcw's avatar
dcw committed
314
	{
315
		line( "fputs( %s, f );", pname );
dcw's avatar
dcw committed
316
317
	} else
	{
dcw's avatar
dcw committed
318
		line( "print_%s( f, %s );", p->type, pname );
dcw's avatar
dcw committed
319
320
321
322
	}
}


dcw's avatar
dcw committed
323
static void print_all_params( d, s ) declnlist d; shapelist s;
dcw's avatar
dcw committed
324
{
325
326
327
	printlist	pl;
	paramlist	p;
	int		n;
dcw's avatar
dcw committed
328
329
330

	if( s->pl == NULL )
	{
331
332
333
334
335
		line( "fputs( \"%s\", f );", s->name );
		if( s->params )
		{
			line( "fputc( '(', f );" );
		}
dcw's avatar
dcw committed
336
		for( p = s->params; p != NULL; p = p->next )
dcw's avatar
dcw committed
337
		{
dcw's avatar
dcw committed
338
			print_param( s->name, p, d->Union );
339
340
341
342
		}
		if( s->params )
		{
			line( "fputc( ')', f );" );
dcw's avatar
dcw committed
343
344
345
		}
	} else
	{
dcw's avatar
dcw committed
346
		for( pl = s->pl; pl != NULL; pl = pl->next )
dcw's avatar
dcw committed
347
348
349
		{
			if( pl->item->tag == printitem_is_str )
			{
350
				line( "fputs( \"%s\", f );",
dcw's avatar
dcw committed
351
352
353
354
355
356
357
					pl->item->str );
			} else
			{
				n = pl->item->num;
				for( p = s->params; --n; p = p->next )
				{
					ASSERT( p != NULL,
dcw's avatar
dcw committed
358
("datadec: bad printitem in shape %s of type %s\n",s->name,d->name));
dcw's avatar
dcw committed
359
				}
dcw's avatar
dcw committed
360
				print_param( s->name, p, d->Union );
dcw's avatar
dcw committed
361
362
363
			}
		}
	}
dcw's avatar
dcw committed
364
365
366
367
368
369
370
371
}


static void print_fn_shape( d, s ) declnlist d; shapelist s;
{
	line( "case %s_%s_tag:", d->name, s->name );
	indent();
	print_all_params( d, s );
372
373
	line( "break;" );
	outdent();
dcw's avatar
dcw committed
374
375
376
}


dcw's avatar
dcw committed
377
static void print_fns( d ) declnlist d;
dcw's avatar
dcw committed
378
379
{
	shapelist s;
dcw's avatar
dcw committed
380
	shapelist shapes;
dcw's avatar
dcw committed
381

dcw's avatar
dcw committed
382
	for( ; d != NULL; d = d->next )
dcw's avatar
dcw committed
383
	{
dcw's avatar
dcw committed
384
		shapes = d->shapes;
385
386
387
		line( "void print_%s( f, p ) FILE *f; %s p;",d->name, d->name );
		line( "{" );
		indent();
dcw's avatar
dcw committed
388
		if( d->UseNull )
dcw's avatar
dcw committed
389
		{
dcw's avatar
dcw committed
390
391
392
393
394
395
396
397
398
399
400
401
402
			line( "if( p == NULL )" );
			line( "{" );
			indent();
			print_all_params( d, shapes );
			line( "return;" );
			outdent();
			line( "}" );
			shapes = shapes->next;
		}
		if( d->TagField )
		{
			line( "switch( p->tag )" );
			line( "{" );
dcw's avatar
dcw committed
403
			for( s = shapes; s != NULL; s = s->next )
dcw's avatar
dcw committed
404
405
406
407
408
409
410
411
412
413
414
			{
				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( "}" );
dcw's avatar
dcw committed
415
		} else if( ! d->TagField && d->Struct )	/* one shape left */
dcw's avatar
dcw committed
416
417
		{
			print_all_params( d, shapes );
dcw's avatar
dcw committed
418
		} else if( ! d->Struct && d->Defines )	/* enumerated type */
dcw's avatar
dcw committed
419
420
421
		{
			line( "switch( p )" );
			line( "{" );
dcw's avatar
dcw committed
422
			for( s = shapes; s != NULL; s = s->next )
dcw's avatar
dcw committed
423
			{
dcw's avatar
dcw committed
424
				line( "case %s_%s():", d->name, s->name );
dcw's avatar
dcw committed
425
426
427
428
429
430
				indent();
				print_all_params( d, s );
				line( "break;" );
				outdent();
			}
			line( "}" );
dcw's avatar
dcw committed
431
432
433
434
435
		} else
		{
			fprintf( stderr,
				 "datadec: internal error in print_fns\n" );
			exit(1);
dcw's avatar
dcw committed
436
		}
437
438
		outdent();
		line( "}\n" );
dcw's avatar
dcw committed
439
440
441
	}
}

dcw's avatar
dcw committed
442

dcw's avatar
dcw committed
443
void make_declns( exports, globals, d, basename ) declnlist d; char *exports, *globals, *basename;
dcw's avatar
dcw committed
444
{
dcw's avatar
dcw committed
445
446
447
	printf( "datadec: Making data declarations in %s.[ch]\n", basename );
	h_declns( basename, exports, d );
	c_declns( basename, globals, d );
dcw's avatar
dcw committed
448
449
450
451

}


dcw's avatar
dcw committed
452
static void h_declns( basename, exports, d ) char *basename, *exports; declnlist d;
dcw's avatar
dcw committed
453
{
dcw's avatar
dcw committed
454
	char		tempname[256];
dcw's avatar
dcw committed
455
	char		*exportptr;
dcw's avatar
dcw committed
456
457
	FILE		*hfile;
	declnlist	dl;
dcw's avatar
dcw committed
458

dcw's avatar
dcw committed
459
460
461
	sprintf( tempname, "%s.h", basename );
	hfile = fopen( tempname, "w" );
	ASSERT( hfile != NULL, ("datadec: can't create '%s'\n",tempname) );
dcw's avatar
dcw committed
462

dcw's avatar
dcw committed
463
	usefile( hfile );
dcw's avatar
dcw committed
464

dcw's avatar
dcw committed
465
466
467
468
469
470
471
	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" );
dcw's avatar
dcw committed
472
	line( "#define NEW(t) ((t)malloc(sizeof(struct t)))\n\n" );
dcw's avatar
dcw committed
473

dcw's avatar
dcw committed
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
	if( *exports != '\0' )
	{
		int i;

		line( "/* Contents of EXPORT section */" );
		for( exportptr=exports; *exportptr; exportptr++ )
		{
			if( *exportptr == '@' && exportptr[1] == '@'
			&&   exportptr[2] == '\n' )
			{
				exportptr += 2;
				break;
			}
			outchar( *exportptr );
		}

		nl();
		nl();
	}
493
494

	data_decls( d );
dcw's avatar
dcw committed
495

dcw's avatar
dcw committed
496
	for( dl = d; dl != NULL; dl=dl->next )
dcw's avatar
dcw committed
497
498
499
500
501
502
503
	{
		if( dl->UseNull )
		{
			line( "#define %s_%s() ((%s)NULL)",
				dl->name, dl->shapes->name, dl->name );
		}
	}
504
	line( "#ifdef HASPROTOS" );
dcw's avatar
dcw committed
505
	protos( d, TRUE );
506
	line( "#else" );
dcw's avatar
dcw committed
507
	protos( d, FALSE );
508
	line( "#endif" );
dcw's avatar
dcw committed
509

dcw's avatar
dcw committed
510
511
512
513
514
515
516
517
	if( *exportptr != '\0' )
	{
		nl();
		line( "/* Remaining contents of EXPORT section */" );
		line( exportptr );
		nl();
	}

dcw's avatar
dcw committed
518
519
520
521
522
523
	fclose( hfile );
}


static void c_declns( basename, globals, d ) char *basename, *globals; declnlist d;
{
dcw's avatar
dcw committed
524
	char	tempname[256];
dcw's avatar
dcw committed
525
	FILE	*cfile;
dcw's avatar
dcw committed
526
	char	*globalptr;
dcw's avatar
dcw committed
527

dcw's avatar
dcw committed
528
529
530
	sprintf( tempname, "%s.c", basename );
	cfile = fopen( tempname, "w" );
	ASSERT( cfile != NULL, ("datadec: can't create '%s'\n",tempname) );
dcw's avatar
dcw committed
531
532
533
534
535
536
537

	usefile( cfile );

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

dcw's avatar
dcw committed
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
	if( *globals != '\0' )
	{
		line( "/* Contents of GLOBAL section */" );
		for( globalptr=globals; *globalptr; globalptr++ )
		{
			if( *globalptr == '@' && globalptr[1] == '@'
			&&   globalptr[2] == '\n' )
			{
				globalptr += 2;
				break;
			}
			outchar( *globalptr );
		}

		nl();
		nl();
	}
dcw's avatar
dcw committed
558
559
560
561
562

	cons_fns( d );

	print_fns( d );

dcw's avatar
dcw committed
563
564
565
566
567
568
569
570
571
	if( *globalptr != '\0' )
	{
		nl();
		nl();
		line( "/* Remaining contents of GLOBAL section */" );
		line( globalptr );
		nl();
	}

dcw's avatar
dcw committed
572
	fclose( cfile );
dcw's avatar
dcw committed
573
}