/* * DATA DECLARATION BUILDER * ==== =========== ======= * ******* Author: * * Duncan White, Imperial College, London, England. * ******* Description: * * This program builds C data declarations, * constructor and deconstructor functions and write functions * from a series of Haskell/Miranda/Hope style recursive data declarations. * (with optional hints on printing, and optionally, free_* functions) * * The output produced is placed in pair of files (eg. x.c and x.h ) * which together form a module provided the relevant data types. * NEW in 2018: in addition, we write a useful summary of types, * shapes and the types of the shape parameters into a .x.dd file, * this can be used by experimental client-side tools such as "CPM.perl". */ #include #include #include #include #include "struct.h" #include "lexer.h" #include "parser.h" #include "decs.h" #include "optimize.h" #define MUSTBE(b) {if(!(b)){fprintf(stderr,"Usage: datadec [-vnof] 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 ) ) { fprintf( stderr, "datadec: can't parse input properly\n" ); exit(1); } 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 ); exit(0); /*NOTREACHED*/ }