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


#ifdef HASPROTOS
dcw's avatar
dcw committed
7
static void init( FILE * , FILE * , char * );
8
static void data_decls( declnlist );
dcw's avatar
dcw committed
9
10
11
static void one_proto( FILE * , char * , shapelist , BOOL );
static void protos( FILE * , declnlist , BOOL );
static void cons_fn_hdr( FILE * , char * , shapelist );
12
static void cons_fn_body( char * , shapelist );
dcw's avatar
dcw committed
13
14
static void cons_fns( FILE * , declnlist );
static void print_fns( FILE * , declnlist );
15
16
static void print_fn_shape( char * , shapelist );
static void print_param( char * , char * , char * );
17
18
19
static void count_empty_non( shapelist , int *, int * );
static void optimize( declnlist );
static void line( char *, long, long, long, long );
dcw's avatar
dcw committed
20
#else
dcw's avatar
dcw committed
21
22
23
24
25
26
27
28
29
30
static void init();
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_fns();
static void print_fn_shape();
static void print_param();
31
32
33
static void count_empty_non();
static void optimize();
static void line();
dcw's avatar
dcw committed
34
35
36
#endif


37
38
39
BOOL print, verbose;		/* print == generate print functions */
				/* verbose == be verbose - diagnostics */

40
41
42
43
44
45
46
static int numtabs = 0;
static FILE *outfile;


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

47
#define usefile(f) outfile = f, numtabs = 0
48
49
50
51
52
53
54
55
56
57
58
59
60


/*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 );
	fputc( '\n', outfile );
}


dcw's avatar
dcw committed
61
static void init( h, c, basename ) FILE *c, *h; char *basename;
dcw's avatar
dcw committed
62
{
63
64
65
66
67
68
69
70
71
72
73
74
75
	fputs( "/*\n", h );
	fputs( " * Automatically Generated by DataDec\n", h );
	fputs( " */\n\n", h );
	fputs( "typedef char *string;\n\n", h );
	fputs( "typedef char BOOL;\n", h );
	fputs( "#define TRUE 1\n", h );
	fputs( "#define FALSE 0\n\n", h );
	fputs( "#define NEW(t) ((t *)malloc(sizeof(t)))\n\n\n", h );

	fputs( "/*\n", c );
	fputs( " * Automatically Generated by DataDec\n", c );
	fputs( " */\n\n", c);
	fputs( "#include <stdio.h>\n", c );
dcw's avatar
dcw committed
76
	fprintf( c, "#include \"%s.h\"\n\n\n", basename );
dcw's avatar
dcw committed
77
78
79
}


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

87
	for( d=decs; d; d=d->next )
dcw's avatar
dcw committed
88
	{
89
		line( "typedef struct %s_str *%s;", d->name, d->name );
dcw's avatar
dcw committed
90
	}
91
92
	line( "\n" );
	for( d=decs; d; d=d->next )
dcw's avatar
dcw committed
93
	{
94
		line( "/* ---- Type %s ---- */\n", d->name );
dcw's avatar
dcw committed
95
		n = 0;
dcw's avatar
dcw committed
96
97
		for( s = d->shapes; s; s=s->next )
		{
98
99
			line( "#define %s_%s_tag %d",
				d->name, s->name, n++ );
dcw's avatar
dcw committed
100
		}
101
		line( "" );
102

103
		line( "struct %s_str {", d->name );
104
105
106
107
		indent();
		line( "int\ttag;" );
		line( "union {" );
		indent();
dcw's avatar
dcw committed
108
109
		for( s = d->shapes; s; s=s->next )
		{
dcw's avatar
dcw committed
110
			if( s->params )
dcw's avatar
dcw committed
111
			{
112
113
				line( "struct {" );
				indent();
dcw's avatar
dcw committed
114
115
				for( p = s->params; p; p=p->next )
				{
116
					line( "%s\t%s;",
dcw's avatar
dcw committed
117
118
						p->type, p->name );
				}
119
				outdent();
120
				line( "} %s;", s->name );
dcw's avatar
dcw committed
121
122
			}
		}
123
124
125
126
		outdent();
		line( "} u;" );
		outdent();
		line( "};\n" );
dcw's avatar
dcw committed
127
128
129
130
	}
}


131
static void one_proto( f, name, s, prot ) FILE *f; char *name; shapelist s; BOOL prot;
dcw's avatar
dcw committed
132
133
134
135
{
	paramlist p;
	BOOL first;

136
137
	fprintf( f, "extern %s %s_%s( ", name, name, s->name );
	if( prot )
dcw's avatar
dcw committed
138
139
140
	{
		if( s->params == NULL )
		{
141
			fputs( "void ", f );
dcw's avatar
dcw committed
142
143
		} else
		{
dcw's avatar
dcw committed
144
			first = TRUE;
dcw's avatar
dcw committed
145
146
			for( p = s->params; p ; p=p->next, first=FALSE )
			{
147
148
149
				if( !first ) fputs( ", ", f );
				fputs( p->type, f );
				fputc( ' ', f );
dcw's avatar
dcw committed
150
151
152
			}
		}
	}
153
	fputs( ");\n", f );
dcw's avatar
dcw committed
154
155
156
}


157
static void protos( f, d, prot ) FILE *f; declnlist d; BOOL prot;
dcw's avatar
dcw committed
158
{
159
	shapelist	s;
dcw's avatar
dcw committed
160

161
	for( ; d; d = d->next )
dcw's avatar
dcw committed
162
	{
163
		for( s = d->shapes; s; s = s->next )
dcw's avatar
dcw committed
164
		{
165
166
167
168
169
170
171
172
173
174
175
176
177
			one_proto( f, d->name, s, prot );
		}
		if( print )
		{
			if( prot )
			{
				fprintf( f, "extern void print_%s( %s );\n",
					d->name, d->name );
			} else
			{
				fprintf( f, "extern void print_%s( );\n",
					d->name );
			}
dcw's avatar
dcw committed
178
		}
dcw's avatar
dcw committed
179
	}
dcw's avatar
dcw committed
180
181
182
}


dcw's avatar
dcw committed
183
static void cons_fn_hdr( f, name, s ) FILE *f; char *name; shapelist s;
dcw's avatar
dcw committed
184
185
186
187
{
	paramlist p;
	BOOL first;

188
	fprintf( f, "%s %s_%s( ", name, name, s->name );
dcw's avatar
dcw committed
189
	first = TRUE;
dcw's avatar
dcw committed
190
191
	for( p=s->params; p; p=p->next, first=FALSE )
	{
192
193
		if( !first ) fputs( ", ", f );
		fputs( p->name, f );
dcw's avatar
dcw committed
194
	}
195
	fputs( " ) ", f );
dcw's avatar
dcw committed
196
197
198
	for( p=s->params; p; p=p->next )
	{
		fprintf( f, "%s %s; ", p->type, p->name );
dcw's avatar
dcw committed
199
200
201
202
203
	}
	fputc( '\n', f );
}


204
static void cons_fn_body( name, s ) char *name; shapelist s;
dcw's avatar
dcw committed
205
206
207
{
	paramlist p;

208
209
210
211
	line( "{" );
	indent();
	line( "%s new;\n", name );
	line( "new = NEW( struct %s_str );", name );
212
	line( "new->tag = %s_%s_tag;", name, s->name );
dcw's avatar
dcw committed
213
214
	for( p=s->params; p; p=p->next )
	{
215
		line( "new->u.%s.%s = %s;", s->name, p->name, p->name );
dcw's avatar
dcw committed
216
	}
217
218
219
	line( "return new;" );
	outdent();
	line( "}" );
dcw's avatar
dcw committed
220
221
222
}


dcw's avatar
dcw committed
223
static void cons_fns( f, d ) FILE *f; declnlist d;
dcw's avatar
dcw committed
224
225
226
{
	shapelist s;

227
228
	usefile( f );

dcw's avatar
dcw committed
229
230
231
232
	for( ; d; d=d->next )
	{
		for( s = d->shapes; s; s=s->next )
		{
233
234
			cons_fn_hdr( f, d->name, s );
			cons_fn_body( d->name, s );
dcw's avatar
dcw committed
235
236
237
238
239
240
			fprintf( f, "\n\n" );
		}
	}
}


241
static void print_param( shape, ftype, fname ) char *shape, *ftype, *fname;
dcw's avatar
dcw committed
242
243
244
{
	char pname[200];

dcw's avatar
dcw committed
245
	sprintf( pname, "p->u.%s.%s", shape, fname );
dcw's avatar
dcw committed
246
247
	if( streq( ftype, "int" ) )
	{
248
		line( "fprintf( f, \"%%d\", %s );", pname );
dcw's avatar
dcw committed
249
250
	} else if( streq( ftype, "char" ) )
	{
251
		line( "fputc( %s, f );", pname );
dcw's avatar
dcw committed
252
253
	} else if( streq( ftype, "BOOL" ) )
	{
254
		line( "fputs( %s?\"true\":\"false\", f );", pname );
dcw's avatar
dcw committed
255
256
	} else if( streq( ftype, "string" ) )
	{
257
		line( "fputs( %s, f );", pname );
dcw's avatar
dcw committed
258
259
	} else
	{
260
		line( "print_%s( f, %s );", ftype, pname );
dcw's avatar
dcw committed
261
262
263
264
	}
}


265
static void print_fn_shape( typename, s ) char *typename; shapelist s;
dcw's avatar
dcw committed
266
{
267
268
269
	printlist	pl;
	paramlist	p;
	int		n;
dcw's avatar
dcw committed
270

271
	line( "case %s_%s_tag:", typename, s->name );
dcw's avatar
dcw committed
272

273
	indent();
dcw's avatar
dcw committed
274
275
	if( s->pl == NULL )
	{
276
277
278
279
280
		line( "fputs( \"%s\", f );", s->name );
		if( s->params )
		{
			line( "fputc( '(', f );" );
		}
dcw's avatar
dcw committed
281
282
		for( p = s->params; p; p = p->next )
		{
283
284
285
286
287
			print_param( s->name, p->type, p->name );
		}
		if( s->params )
		{
			line( "fputc( ')', f );" );
dcw's avatar
dcw committed
288
289
290
291
292
293
294
		}
	} else
	{
		for( pl = s->pl; pl; pl = pl->next )
		{
			if( pl->item->tag == printitem_is_str )
			{
295
				line( "fputs( \"%s\", f );",
dcw's avatar
dcw committed
296
297
298
299
300
301
302
					pl->item->str );
			} else
			{
				n = pl->item->num;
				for( p = s->params; --n; p = p->next )
				{
					ASSERT( p != NULL,
303
("datadec: bad printitem in shape %s of type %s\n",s->name,typename));
dcw's avatar
dcw committed
304
				}
305
				print_param( s->name, p->type, p->name );
dcw's avatar
dcw committed
306
307
308
			}
		}
	}
309
310
	line( "break;" );
	outdent();
dcw's avatar
dcw committed
311
312
313
314
315
316
317
}


static void print_fns( f, d ) FILE *f ; declnlist d;
{
	shapelist s;

318
319
	usefile( f );

dcw's avatar
dcw committed
320
321
	for( ; d; d = d->next )
	{
322
323
324
325
326
		line( "void print_%s( f, p ) FILE *f; %s p;",d->name, d->name );
		line( "{" );
		indent();
		line( "switch( p->tag )" );
		line( "{" );
dcw's avatar
dcw committed
327
328
		for( s = d->shapes; s; s = s->next )
		{
329
			print_fn_shape( d->name, s );
dcw's avatar
dcw committed
330
		}
331
332
333
334
335
336
337
338
339
340
		line( "default:" );
		indent();
		line( "fprintf( stderr," );
		line( " \"print_%s: impossible tag %%d\\n\", p->tag );",
			d->name );
		line( "exit(1);" );
		outdent();
		line( "}" );
		outdent();
		line( "}\n" );
dcw's avatar
dcw committed
341
342
343
	}
}

dcw's avatar
dcw committed
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363

static void count_empty_non( s, e, ne ) shapelist s; int *e, *ne;
{
	*e = *ne = 0;
	for( ; s!=NULL; s = s->next )
	{
		if( s->params == NULL ) (*e)++; else (*ne)++;
	}
}


#define implies( a, b ) (!(a) || (b))


static void optimize( d ) declnlist d;
{
	int t, e, ne;

	for( ; d != NULL; d = d->next )
	{
364
365
366
367
368
369
370
371
		if( ! opt )
		{
			d->Defines = d->TagField = d->Struct = d->Union = TRUE;
			d->UseNull = FALSE;
		} else
		{
			count_empty_non( d->shapes, &e, &ne );
			t = e+ne;
dcw's avatar
dcw committed
372

373
374
			d->Defines = d->TagField = d->Struct =
			d->Union = d->UseNull = FALSE;
dcw's avatar
dcw committed
375
376

/* ONE, EMPTY, eg. 'data x = y' => ERROR */
377
378
			ASSERT( t!=1 || e!=1,
				( "datadec: type %s is empty!\n",d->name) );
dcw's avatar
dcw committed
379

380
			if( t==1 && ne==1 )
dcw's avatar
dcw committed
381
/* ONE, NON EMPTY, eg. 'data x = fred(string z)' */
382
383
384
385
			{
				d->Struct = TRUE;
				/* !Defines, !TagField, !Union, !UseNull */
			} else if( t>1 && ne==0 )
dcw's avatar
dcw committed
386
387
/* >1, ALL EMPTY, eg. 'data x = a | b | c | d | e' */
			{
388
389
390
				d->Defines = TRUE;
				/* !TagField, !Struct, !Union, !UseNull */
			} else if( d->shapes->params == NULL ) /* 1st empty */
dcw's avatar
dcw committed
391
			{
392
393
394
395
396
397
398
399
				d->UseNull = d->Struct = TRUE;
				if( t==2 && ne==1 )
				{
/* TWO, 1ST EMPTY, 2ND NE, eg. 'data x = a | b(char z)' */
					d->UseNull = d->Struct = TRUE;
					/* !Union, !TagField, !Defines */
				} else if( t>2 && ne==1 )
				{
dcw's avatar
dcw committed
400
/* >TWO, 1ST EMPTY, ONLY ONE NE, eg. 'data x = a | b | c(char z) | d | e' */
401
402
403
404
405
406
407
408
409
410
					d->UseNull = d->Struct =
					d->Defines = d->TagField = TRUE;
					/* !Union */
				} else
				{
/* >TWO, 1ST EMPTY, >ONE NE, eg. 'data x = a | b(int y) | c(char z) | d | e' */
					d->UseNull = d->Struct =
					d->Defines = d->TagField =
					d->Union = TRUE;
				}
dcw's avatar
dcw committed
411
			} else
412
/* ELSE */
dcw's avatar
dcw committed
413
			{
414
				d->Defines = d->TagField = d->Struct =
dcw's avatar
dcw committed
415
416
				d->Union = TRUE;
			}
417

418
419
			if( verbose )
			{
420
#define XXX(x)	( (x)?' ':'!')
421
422
423
424
425
426
				printf( "type %s: %cDefines, %cTagField, ",
					d->name, XXX(d->Defines),
					XXX(d->TagField) );
				printf( "%cStruct, %cUnion, %cUseNull\n",
					XXX(d->Struct), XXX(d->Union),
					XXX(d->UseNull) );
427
#undef XXX
428
			}
429

430
431
432
433
434
435
436
437
438
439
440
			ASSERT( implies(d->Union,d->TagField),
			("optimizer error: type %s has Union&!TagField\n",d->name) );
			ASSERT( implies(d->Union,d->Struct),
			("optimizer error: type %s has Union&!Struct\n",d->name) );
			ASSERT( implies(d->TagField,d->Struct),
			("optimizer error: type %s has TagField&!Struct\n",d->name) );
			ASSERT( implies(d->UseNull,d->Struct),
			("optimizer error: type %s has UseNull&!Struct\n",d->name) );
			ASSERT( implies(d->TagField,d->Defines),
			("optimizer error: type %s has TagField&!Defines\n",d->name) );
		}
dcw's avatar
dcw committed
441
442
443
444
	}
}


dcw's avatar
dcw committed
445
446
void make_declns( d, c, h, basename ) declnlist d; FILE *c, *h; char *basename;
{
447
	printf( "datadec: Making data declarations\n" );
dcw's avatar
dcw committed
448

dcw's avatar
dcw committed
449
	init( h, c, basename );
dcw's avatar
dcw committed
450

dcw's avatar
dcw committed
451
452
	optimize( d );

453
454
455
	usefile( h );

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

457
	line( "#ifdef HASPROTOS" );
dcw's avatar
dcw committed
458
	protos( h, d, TRUE );
459
	line( "#else" );
dcw's avatar
dcw committed
460
	protos( h, d, FALSE );
461
	line( "#endif" );
dcw's avatar
dcw committed
462

dcw's avatar
dcw committed
463
	cons_fns( c, d );
464
	if( print ) print_fns( c, d );
dcw's avatar
dcw committed
465
}