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
}