/*
 *                      DATA DECLARATION BUILDER
 *                      ==== =========== =======
 *
 ******* Author:
 *
 *      Duncan White, Imperial College, London, England.
 *
 ******* Description:
 *
 *      This program builds C or Modula-2 data declarations,
 *	constructor and deconstructor functions and write functions
 *	from a series of HOPE/Miranda style recursive data declarations.
 *	(with optional hints on printing)
 *
 *      The output produced is placed in pair of files (eg. x.c and x.h )
 *	which together form a module provided the relevent data types.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "struct.h"
#include "lexer.h"
#include "parser.h"
#include "decs.h"
#include "optimize.h"


#define MUSTBE(b)	{if(!(b)){fprintf(stderr,"Usage: datadec [-vno] outfile [infile]\n");exit(1);}}

#define NEED_ANOTHER_ARG	MUSTBE( IS_ANOTHER_ARG )
#define REQUIRE_NO_MORE_ARGS	MUSTBE( argc == arg )
#define IS_ANOTHER_ARG		(argc > arg)


#define CHUNKSIZE 10000

typedef char bigstr[ CHUNKSIZE ];


int main( int argc, char **argv )
{
	char		*basename;
	char		*s;
        declnlist	declns;
	int		len;
	int		arg;
	bigstr		exports, globals, begin;

	arg = 1;
	NEED_ANOTHER_ARG;

	verbose = FALSE; opt = TRUE;
	while( *(s=argv[arg]) == '-' )
	{
		for( s++; *s; s++ )
		{
			switch( *s )
			{
			case 'v':
				verbose = TRUE;
				break;
			case 'f':
				makefree = TRUE;
				break;
			case 'n':
				opt = FALSE;
				break;
			case 'o':
				opt = TRUE;
				break;
			default:
				fprintf( stderr,
					"datadec: illegal option -%c\n", *s );
				exit(1);
			}
		}
		arg++;
		NEED_ANOTHER_ARG;
	}

	basename = argv[arg++];
	len = strlen( basename );
	if( !strcmp( basename+len-2, ".c" ) )
	{
		basename[len-2] = '\0';
	}

        if( IS_ANOTHER_ARG ) {
                lexfile = fopen( argv[arg], "r" );
                if( lexfile == NULL )
		{
			fprintf( stderr, "datadec: can't open '%s'\n",
				argv[arg] );
			exit(1);
		}
		arg++;
        } else {
                lexfile = stdin;
        }

	REQUIRE_NO_MORE_ARGS;

        if( parse_data( exports, globals, begin, &declns ) )
	{
		if( verbose )
		{
			printf( "datadec: declns are:\n\n" );
			print_declnlist( declns );
			printf( "exports = {%s}\n", exports );
			printf( "globals = {%s}\n", globals );
			printf( "begin = {%s}\n", begin );
		}
		optimize( declns );
		make_declns( exports, globals, begin, declns, basename );
	} else
	{
		fprintf( stderr, "datadec: can't parse input properly\n" );
	}
	exit(0);
	/*NOTREACHED*/
}
