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


dcw's avatar
dcw committed
210
static void cons_fn_hdr( name, s ) char *name; shapelist s;
dcw's avatar
dcw committed
211 212 213 214
{
	paramlist p;
	BOOL first;

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


dcw's avatar
dcw committed
231
static void cons_fn_body( d, name, s ) declnlist d; char *name; shapelist s;
dcw's avatar
dcw committed
232 233 234
{
	paramlist p;

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


dcw's avatar
dcw committed
262
static void cons_fns( d ) declnlist d;
dcw's avatar
dcw committed
263
{
dcw's avatar
dcw committed
264 265
	shapelist	s;
	shapelist	shapes;
dcw's avatar
dcw committed
266

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


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

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


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

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


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 );
369 370
	line( "break;" );
	outdent();
dcw's avatar
dcw committed
371 372 373
}


dcw's avatar
dcw committed
374
static void print_fns( d ) declnlist d;
dcw's avatar
dcw committed
375 376
{
	shapelist s;
dcw's avatar
dcw committed
377
	shapelist shapes;
dcw's avatar
dcw committed
378

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

dcw's avatar
dcw committed
439

dcw's avatar
dcw committed
440
void make_declns( exports, globals, d, basename ) declnlist d; char *exports, *globals, *basename;
dcw's avatar
dcw committed
441
{
dcw's avatar
dcw committed
442 443 444
	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
445 446 447 448

}


dcw's avatar
dcw committed
449
static void h_declns( basename, exports, d ) char *basename, *exports; declnlist d;
dcw's avatar
dcw committed
450
{
dcw's avatar
dcw committed
451 452 453
        char		tempname[256];
	FILE		*hfile;
	declnlist	dl;
dcw's avatar
dcw committed
454

dcw's avatar
dcw committed
455 456 457
        sprintf( tempname, "%s.h", basename );
        hfile = fopen( tempname, "w" );
        ASSERT( hfile != NULL, ("datadec: can't create '%s'\n",tempname) );
dcw's avatar
dcw committed
458

dcw's avatar
dcw committed
459
	usefile( hfile );
dcw's avatar
dcw committed
460

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

dcw's avatar
dcw committed
470
	line( exports );
471 472

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

dcw's avatar
dcw committed
474
	for( dl = d; dl != NULL; dl=dl->next )
dcw's avatar
dcw committed
475 476 477 478 479 480 481
	{
		if( dl->UseNull )
		{
			line( "#define %s_%s() ((%s)NULL)",
				dl->name, dl->shapes->name, dl->name );
		}
	}
482
	line( "#ifdef HASPROTOS" );
dcw's avatar
dcw committed
483
	protos( d, TRUE );
484
	line( "#else" );
dcw's avatar
dcw committed
485
	protos( d, FALSE );
486
	line( "#endif" );
dcw's avatar
dcw committed
487

dcw's avatar
dcw committed
488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506
	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>" );
dcw's avatar
dcw committed
507
	line( "#include <malloc.h>" );
dcw's avatar
dcw committed
508 509 510 511 512 513 514 515 516
	line( "#include \"%s.h\"\n\n", basename );

	line( globals );

	cons_fns( d );

	print_fns( d );

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