decs.c 9.57 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--

53
#define usefile(f) outfile = f, numtabs = 0
54
55
56
57
58
59
60
61
62
63
64
65
66


/*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
67
68
static void declfields( p ) paramlist p;
{
dcw's avatar
dcw committed
69
	for( ; p != NULL; p=p->next )
dcw's avatar
dcw committed
70
71
72
73
74
75
	{
		line( "%s\t%s;", p->type, p->name );
	}
}


76
static void data_decls( decs ) declnlist decs;
dcw's avatar
dcw committed
77
{
78
79
80
	declnlist	d;
	shapelist	s;
	int		n;
dcw's avatar
dcw committed
81

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

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


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

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


dcw's avatar
dcw committed
181
static void protos( d, prot ) declnlist d; BOOL prot;
dcw's avatar
dcw committed
182
{
183
	shapelist	s;
dcw's avatar
dcw committed
184
	shapelist	shapes;
dcw's avatar
dcw committed
185

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


dcw's avatar
dcw committed
207
static void cons_fn_hdr( name, s ) char *name; shapelist s;
dcw's avatar
dcw committed
208
209
210
211
{
	paramlist p;
	BOOL first;

dcw's avatar
dcw committed
212
	fprintf( outfile, "%s %s_%s( ", name, name, s->name );
dcw's avatar
dcw committed
213
	first = TRUE;
dcw's avatar
dcw committed
214
	for( p=s->params; p != NULL; p=p->next, first=FALSE )
dcw's avatar
dcw committed
215
	{
dcw's avatar
dcw committed
216
217
		if( !first ) fputs( ", ", outfile );
		fputs( p->name, outfile );
dcw's avatar
dcw committed
218
	}
dcw's avatar
dcw committed
219
220
	fputs( " ) ", outfile );
	for( p=s->params; p != NULL; p=p->next )
dcw's avatar
dcw committed
221
	{
dcw's avatar
dcw committed
222
		fprintf( outfile, "%s %s; ", p->type, p->name );
dcw's avatar
dcw committed
223
	}
dcw's avatar
dcw committed
224
	fputc( '\n', outfile );
dcw's avatar
dcw committed
225
226
227
}


dcw's avatar
dcw committed
228
static void cons_fn_body( d, name, s ) declnlist d; char *name; shapelist s;
dcw's avatar
dcw committed
229
230
231
{
	paramlist p;

dcw's avatar
dcw committed
232
	ASSERT( d->Struct,
233
		("error: cons_fn_body called but d->Struct is FALSE!\n") );
234
235
	line( "{" );
	indent();
dcw's avatar
dcw committed
236
	line( "%s\tnew;\n", name );
dcw's avatar
dcw committed
237
	line( "new = NEW(%s);", name );
dcw's avatar
dcw committed
238
239
240
241
	if( d->TagField )
	{
		line( "new->tag = %s_%s_tag;", name, s->name );
	}
dcw's avatar
dcw committed
242
	for( p=s->params; p != NULL; p=p->next )
dcw's avatar
dcw committed
243
	{
dcw's avatar
dcw committed
244
245
246
247
248
249
250
251
		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
252
	}
253
254
255
	line( "return new;" );
	outdent();
	line( "}" );
dcw's avatar
dcw committed
256
257
258
}


dcw's avatar
dcw committed
259
static void cons_fns( d ) declnlist d;
dcw's avatar
dcw committed
260
{
dcw's avatar
dcw committed
261
262
	shapelist	s;
	shapelist	shapes;
dcw's avatar
dcw committed
263

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


dcw's avatar
dcw committed
286
static void print_param( shape, p, Union ) char *shape; paramlist p; BOOL Union;
dcw's avatar
dcw committed
287
288
289
{
	char pname[200];

dcw's avatar
dcw committed
290
291
292
293
294
295
296
297
298
	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
299
	{
300
		line( "fprintf( f, \"%%d\", %s );", pname );
dcw's avatar
dcw committed
301
	} else if( streq( p->type, "char" ) )
dcw's avatar
dcw committed
302
	{
303
		line( "fputc( %s, f );", pname );
dcw's avatar
dcw committed
304
	} else if( streq( p->type, "BOOL" ) )
dcw's avatar
dcw committed
305
	{
306
		line( "fputs( %s?\"true\":\"false\", f );", pname );
dcw's avatar
dcw committed
307
	} else if( streq( p->type, "string" ) )
dcw's avatar
dcw committed
308
	{
309
		line( "fputs( %s, f );", pname );
dcw's avatar
dcw committed
310
311
	} else
	{
dcw's avatar
dcw committed
312
		line( "print_%s( f, %s );", p->type, pname );
dcw's avatar
dcw committed
313
314
315
316
	}
}


dcw's avatar
dcw committed
317
static void print_all_params( d, s ) declnlist d; shapelist s;
dcw's avatar
dcw committed
318
{
319
320
321
	printlist	pl;
	paramlist	p;
	int		n;
dcw's avatar
dcw committed
322
323
324

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


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 );
366
367
	line( "break;" );
	outdent();
dcw's avatar
dcw committed
368
369
370
}


dcw's avatar
dcw committed
371
static void print_fns( d ) declnlist d;
dcw's avatar
dcw committed
372
373
{
	shapelist s;
dcw's avatar
dcw committed
374
	shapelist shapes;
dcw's avatar
dcw committed
375

dcw's avatar
dcw committed
376
	for( ; d != NULL; d = d->next )
dcw's avatar
dcw committed
377
	{
dcw's avatar
dcw committed
378
		shapes = d->shapes;
379
380
381
		line( "void print_%s( f, p ) FILE *f; %s p;",d->name, d->name );
		line( "{" );
		indent();
dcw's avatar
dcw committed
382
		if( d->UseNull )
dcw's avatar
dcw committed
383
		{
dcw's avatar
dcw committed
384
385
386
387
388
389
390
391
392
393
394
395
396
			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
397
			for( s = shapes; s != NULL; s = s->next )
dcw's avatar
dcw committed
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
			{
				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( "}" );
		} else if( d->Struct )	/* only one shape left */
		{
			print_all_params( d, shapes );
		} else			/* enumerated type */
		{
			line( "switch( p )" );
			line( "{" );
dcw's avatar
dcw committed
416
			for( s = shapes; s != NULL; s = s->next )
dcw's avatar
dcw committed
417
418
419
420
421
422
423
424
			{
				line( "case %s_%s:", d->name, s->name );
				indent();
				print_all_params( d, s );
				line( "break;" );
				outdent();
			}
			line( "}" );
dcw's avatar
dcw committed
425
		}
426
427
		outdent();
		line( "}\n" );
dcw's avatar
dcw committed
428
429
430
	}
}

dcw's avatar
dcw committed
431

dcw's avatar
dcw committed
432
void make_declns( exports, globals, d, basename ) declnlist d; char *exports, *globals, *basename;
dcw's avatar
dcw committed
433
{
dcw's avatar
dcw committed
434
435
436
	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
437
438
439
440

}


dcw's avatar
dcw committed
441
static void h_declns( basename, exports, d ) char *basename, *exports; declnlist d;
dcw's avatar
dcw committed
442
{
dcw's avatar
dcw committed
443
444
445
        char		tempname[256];
	FILE		*hfile;
	declnlist	dl;
dcw's avatar
dcw committed
446

dcw's avatar
dcw committed
447
448
449
        sprintf( tempname, "%s.h", basename );
        hfile = fopen( tempname, "w" );
        ASSERT( hfile != NULL, ("datadec: can't create '%s'\n",tempname) );
dcw's avatar
dcw committed
450

dcw's avatar
dcw committed
451
	usefile( hfile );
dcw's avatar
dcw committed
452

dcw's avatar
dcw committed
453
454
455
456
457
458
459
460
	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(t)))\n\n" );
dcw's avatar
dcw committed
461

dcw's avatar
dcw committed
462
	line( exports );
463
464

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

dcw's avatar
dcw committed
466
	for( dl = d; dl != NULL; dl=dl->next )
dcw's avatar
dcw committed
467
468
469
470
471
472
473
	{
		if( dl->UseNull )
		{
			line( "#define %s_%s() ((%s)NULL)",
				dl->name, dl->shapes->name, dl->name );
		}
	}
474
	line( "#ifdef HASPROTOS" );
dcw's avatar
dcw committed
475
	protos( d, TRUE );
476
	line( "#else" );
dcw's avatar
dcw committed
477
	protos( d, FALSE );
478
	line( "#endif" );
dcw's avatar
dcw committed
479

dcw's avatar
dcw committed
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
	fclose( hfile );
}


static void c_declns( basename, globals, d ) char *basename, *globals; declnlist d;
{
        char	tempname[256];
	FILE	*cfile;

        sprintf( tempname, "%s.c", basename );
        cfile = fopen( tempname, "w" );
        ASSERT( cfile != NULL, ("datadec: can't create '%s'\n",tempname) );

	usefile( cfile );

	line( "/*" );
	line( " * Automatically Generated by DataDec" );
	line( " */\n" );
	line( "#include <stdio.h>" );
	line( "#include \"%s.h\"\n\n", basename );

	line( globals );

	cons_fns( d );

	print_fns( d );

	fclose( cfile );
dcw's avatar
dcw committed
508
}