%{ CODE HEADER KC_TYPES KC_TYPES_HEADER KC_REWRITE KC_REWRITE_HEADER KC_UNPARSE KC_UNPARSE_HEADER KC_CSGIO KC_CSGIO_HEADER /* * The Termprocessor Kimwitu * * Copyright (c) 1991 University of Twente, Dept TIOS. * All rights reserved. * */ %} /* * main.c */ %{ #include "defs.h" #if ! (defined(lint) || defined(SABER) || defined(CODECENTER)) #ifndef KIMWITUCOPYRIGHT # define KIMWITUCOPYRIGHT "@(#) Kimwitu version: (unknown) (c) 1990 University of Twente"; #endif #ifndef RCSMAKEID # define RCSMAKEID "@(#) Makefile version unknown" #endif static char kimwc_cAccesSid[] = "@(#)$Id: main.k,v 1.40 1998/03/18 17:52:27 belinfan Rel $"; static char kimwitu_release[] = KIMWITURELEASE; /* defined in Makefile */ static char kimwitu_version[] = KIMWITUVERSIONSTRING; /* defined in Makefile */ static char Makefile_AccesSid[] = RCSMAKEID; /* defined in Makefile */ char kimwitu_copyright[] = KIMWITUCOPYRIGHT; /* defined in Makefile */ /* used in gen.k */ #else char kimwitu_copyright[] = "KIMWITUCOPYRIGHT"; /* defined in Makefile */ /* used in gen.k */ #endif #ifdef __cplusplus # define KC__CLINKAGE "C" #else # define KC__CLINKAGE #endif #if defined(_WIN32) && ! defined (__GNUC__) # include # define mktemp _mktemp # define open _open # define O_RDONLY _O_RDONLY # define read _read # define close _close #endif /* next include files needed for hpux open (says the man-page) */ /* next include files needed for fstat */ #if defined(hpux) || defined(KC_USE_STAT) # include # include # if defined(_WIN32) && ! defined (__GNUC__) # define fstat _fstat # define stat _stat # endif #endif #include /* for signal/sigvec */ #include #ifdef SIGHOLD /* must be SVR4 */ # define signal sigset /* use reliable signals on SVR4 */ #endif /* string(s) stuff */ #include #if ((! defined(KC_STDC) ) && defined(sun)) extern char *sprintf(); #endif extern int yyparse KC__P((void)); extern void yyrestart KC__P(( FILE* )); extern void do_NORMAL KC__P(( void )); #if ! (defined(_WIN32) && ! defined (__GNUC__)) extern KC__CLINKAGE int read KC__P(( int fildes, char *buf, unsigned int nbyte )); #endif extern KC__CLINKAGE int close KC__P(( int fildes )); #ifndef KC_STDC extern int link KC__P(( char *path1, char *path2 )); extern int unlink KC__P(( char *path )); extern int memcmp KC__P(( void*, void*, size_t )); extern void exit KC__P(( int )); #endif #include "unpk.h" #include "gutil.h" #define MALLOC emalloc #define FREE efree #ifndef efree # ifdef lint # define efree(kc_p) # else # define efree(kc_p) free((kc_malloc_t)(kc_p)) # endif #endif #define STDINPUTNAME "stdin" extern FILE *yyin; static char Thetempcfile[15]; static char Thetemphfile[15]; /* * the following (3) variables are used by processargs and prepare_for_next_file */ static char **inputfilenames = 0; static int no_inputfiles = 0; static int current_inputfile; static boolean g_overwriteAlways = False; %} %{ KC_TYPES_HEADER extern char kimwitu_copyright[]; /* defined above */ extern casestring g_progname; #include extern FILE *g_hfile; extern FILE *g_cfile; extern char *g_hfilename; extern char *g_cfilename; %} %{ casestring g_progname; static char *progname_initvalue = "kc"; FILE *g_hfile, *g_cfile; char *g_hfilename; char *g_cfilename; static boolean verbose = False; %} static char *get_basename(s) char *s; { char *basename = strrchr( s, '/'); if (basename == NULL) { basename = s; } else { basename++; } return basename; } static void processargs(argc, argv) int argc; char* argv[]; { int i; int len; char *basename; g_progname = mkcasestring(get_basename(argv[0])); for( i=1; i < argc; i++ ) { if (strcmp(argv[i], "--version") == 0) { (void)fflush( stdout ); (void)fprintf( stderr, "%s: version %s\n", get_basename(argv[0]), kimwitu_version ); (void)fflush( stderr ); leave(0); } } inputfilenames = ecalloc(argc - 1, sizeof(char*)); no_inputfiles = 0; for( i=1; i < argc; i++ ) { if (strcmp(argv[i], "--overwrite") == 0) { g_overwriteAlways = True; } else { len = strlen(argv[i]); basename = get_basename( argv[i] ); if ( ! (argv[i][len-1] == 'k') && (argv[i][len-2] == '.') ) { v_report( NonFatal( NoFileLine(), Problem2S( "input file must have '.k' suffix:", argv[i] ))); } else if ( (strcmp(basename, "k.k") == 0) || (strcmp(basename, "rk.k") == 0) || (strcmp(basename, "csgiok.k") == 0) || (strcmp(basename, "stdin.k") == 0) ) { v_report( NonFatal( NoFileLine(), Problem2S( "reserved file basename 'k.k', 'rk.k', 'csgiok.k', 'stdin.k' not allowed:", argv[i] ))); } else if ((yyin = fopen(argv[i], "r"))== NULL){ v_report( NonFatal( NoFileLine(), Problem2S( "cannot open ", argv[i] ))); } else { (void)fclose(yyin); /* add the filename to a list of filenames */ inputfilenames[no_inputfiles] = argv[i]; no_inputfiles++; } } } if ( gp_no_fatal_problems ) { if ( no_inputfiles > 0 ) { current_inputfile = 0; pg_filename = make_pg_filename( inputfilenames[current_inputfile] ); if ((yyin = fopen(inputfilenames[current_inputfile], "r"))== NULL){ v_report( Fatal( NoFileLine(), Problem2S( "cannot open ", inputfilenames[current_inputfile] ))); } pg_lineno = 1; /* not sure if this is really necessary */ pg_column = 0; /* not sure if this is really necessary */ pg_charpos = 0; /* not sure if this is really necessary */ } else if (argc == 1 ) { /* read from stdin */ /*EMPTY*/ } } else { leave(1); } } static int prepare_for_next_file() { if ( current_inputfile < no_inputfiles-1 ) { current_inputfile++; pg_filename = make_pg_filename( inputfilenames[current_inputfile] ); pg_lineno = 1; /* really necessary */ pg_column = 0; /* really necessary */ pg_charpos = 0; /* really necessary */ (void)fclose(yyin); if ((yyin = fopen(inputfilenames[current_inputfile], "r"))== NULL){ v_report( Fatal( NoFileLine(), Problem2S( "cannot open ", inputfilenames[current_inputfile] ))); } yyrestart(yyin); /* needed for flex */ return 1; } do_NORMAL(); /* reset scannner if error occurred */ if ( no_inputfiles > 0 ) /* test that we don't close the stdin */ (void)fclose( yyin ); return 0; } %{ KC_TYPES_HEADER #define INC_HEADER "HEADER" #define INC_CODE "CODE" #define INC_KC_TYPES_HEADER "KC_TYPES_HEADER" #define INC_KC_TYPES "KC_TYPES" #define INC_KC_REWRITE_HEADER "KC_REWRITE_HEADER" #define INC_KC_REWRITE "KC_REWRITE" #define INC_KC_CSGIO_HEADER "KC_CSGIO_HEADER" #define INC_KC_CSGIO "KC_CSGIO" #define INC_KC_UNPARSE_HEADER "KC_UNPARSE_HEADER" #define INC_KC_UNPARSE "KC_UNPARSE" /* old keyword for baclwords compatibility */ #define INC_KIMW_TYPES_HEADER "KIMW_TYPES_HEADER" #define INC_KIMW_TYPES "KIMW_TYPES" #define INC_KIMW_REWRITE_HEADER "KIMW_REWRITE_HEADER" #define INC_KIMW_REWRITE "KIMW_REWRITE" #define INC_KIMW_CSGIO_HEADER "KIMW_CSGIO_HEADER" #define INC_KIMW_CSGIO "KIMW_CSGIO" #define INC_KIMW_UNPARSE_HEADER "KIMW_UNPARSE_HEADER" #define INC_KIMW_UNPARSE "KIMW_UNPARSE" %} static void do_parse() { /* initialize the variables that hold the declarations */ includefile Theincheader = IncludeFile( mkcasestring(INC_HEADER)); includefile Theincfile = IncludeFile( mkcasestring(INC_CODE)); ID Thebase_uview = Id( Str( mkcasestring( "base_uview" ))); ID Thebase_view = Id( Str( mkcasestring( "base_view" ))); /* backward compatibility */ ID Thebase_rview = Id( Str( mkcasestring( "base_rview" ))); ID Thekc_not_uniq = Id( Str( mkcasestring( "kc_not_uniq" ))); ID Thekc_uniq_nullary_operator = Id( Str( mkcasestring( "kc_uniq_nullary_operator" ))); ID Theuniq = Id( Str( mkcasestring( "uniq" ))); Thephylumdeclarations = f_add_predefined_phyla( Nilphylumdeclarations() ); Therwdeclarations = Nilrwdeclarations(); Theunparsedeclarations = Nilunparsedeclarations(); Theargsnumbers = Nilargsnumbers(); Thefndeclarations = Nilfndeclarations(); Theincheader->inc_type = include_header; Theincfile->inc_type = include_file; IncludeFile( mkcasestring(INC_KC_TYPES_HEADER))->inc_type = include_header; IncludeFile( mkcasestring(INC_KIMW_TYPES_HEADER))->newinclude = IncludeFile( mkcasestring(INC_KC_TYPES_HEADER)); IncludeFile( mkcasestring(INC_KC_TYPES))->inc_type = include_file; IncludeFile( mkcasestring(INC_KIMW_TYPES))->newinclude = IncludeFile( mkcasestring(INC_KC_TYPES)); IncludeFile( mkcasestring(INC_KC_REWRITE_HEADER))->inc_type = include_header; IncludeFile( mkcasestring(INC_KIMW_REWRITE_HEADER))->newinclude = IncludeFile( mkcasestring(INC_KC_REWRITE_HEADER)); IncludeFile( mkcasestring(INC_KC_REWRITE))->inc_type = include_file; IncludeFile( mkcasestring(INC_KIMW_REWRITE))->newinclude = IncludeFile( mkcasestring(INC_KC_REWRITE)); IncludeFile( mkcasestring(INC_KC_CSGIO_HEADER))->inc_type = include_header; IncludeFile( mkcasestring(INC_KIMW_CSGIO_HEADER))->newinclude = IncludeFile( mkcasestring(INC_KC_CSGIO_HEADER)); IncludeFile( mkcasestring(INC_KC_CSGIO))->inc_type = include_file; IncludeFile( mkcasestring(INC_KIMW_CSGIO))->newinclude = IncludeFile( mkcasestring(INC_KC_CSGIO)); IncludeFile( mkcasestring(INC_KC_UNPARSE_HEADER))->inc_type = include_header; IncludeFile( mkcasestring(INC_KIMW_UNPARSE_HEADER))->newinclude = IncludeFile( mkcasestring(INC_KC_UNPARSE_HEADER)); IncludeFile( mkcasestring(INC_KC_UNPARSE))->inc_type = include_file; IncludeFile( mkcasestring(INC_KIMW_UNPARSE))->newinclude = IncludeFile( mkcasestring(INC_KC_UNPARSE)); v_defoccur( Thebase_uview, ITPredefinedUView() ); v_defoccur( Thebase_view, ITPredefinedUView() ); v_defoccur( Thebase_rview, ITPredefinedRView() ); v_defoccur( Theuniq, ITPredefinedStorageClass() ); Theuviewnames = Consviewnames( Thebase_uview, Nilviewnames() ); Theuviewnames = Consviewnames( Thebase_view, Theuviewnames ); Therviewnames = Consviewnames( Thebase_rview, Nilviewnames() ); Thestorageclasses = Consstorageclasses( Theuniq, Consstorageclasses( Thekc_uniq_nullary_operator, Consstorageclasses( Thekc_not_uniq, Nilstorageclasses() ))); do { (void)yyparse(); /* exits if error */ FnFile( pg_filename )->fns = Thefndeclarations; Thefndeclarations = Nilfndeclarations(); IncludeFile( pg_filename )->inc[(int)include_header] = Theincheader->inc[(int)Theincheader->inc_type]; IncludeFile( pg_filename )->inc[(int)include_file] = Theincfile->inc[(int)Theincfile->inc_type]; IncludeFile( pg_filename )->inc_type = include_both; Theincheader->inc[(int)Theincheader->inc_type] = Nilincludedeclarations(); Theincfile->inc[(int)Theincfile->inc_type] = Nilincludedeclarations(); } while( prepare_for_next_file() ); if (! gp_no_fatal_problems) { leave(1); } } int main (argc, argv) int argc; char* argv[]; { phylumdeclarationsroot proot; char *tmp_cfilename, *tmp_hfilename; #ifdef YYDEBUG extern int yydebug; yydebug = 1; #endif g_hfile = 0; g_cfile = 0; g_progname = mkcasestring( progname_initvalue ); reset_tempfiles(Thetempcfile, Thetemphfile); pg_filename = make_pg_filename( STDINPUTNAME ); gp_no_fatal_problems = True; pg_uviewshavebeendefined = False; pg_rviewshavebeendefined = False; pg_storageclasseshavebeendefined = False; pg_lineno = 0; /* to show that we are not parsing */ pg_column = 0; /* not really necessary */ pg_charpos = 0; /* not really necessary */ processargs(argc, argv); set_signals(); /* don't do this _before_ processargs, because we depend on initialized g_progname */ pg_lineno = 1; /* we start parsing */ pg_column = 0; /* really necessary */ pg_charpos = 0; /* really necessary */ do_parse(); /* calls yyparse on each input file; if wrong exit */ pg_lineno = 0; /* to show that we are no longer parsing */ pg_column = 0; /* not really necessary */ pg_charpos = 0; /* not really necessary */ Thebindingidmarks = 0; /* one of the things to initialize unparsing stuff */ /* * debugging output */ /* print_phylumdeclarations( Thephylumdeclarations ); print_rwdeclarations( Therwdeclarations ); foreach ( a_fnfile; fnfiles Thefnfiles ) { print_fndeclarations( a_fnfile->fns ); } print_unparsedeclarations( Theunparsedeclarations ); */ /* * begin the real work */ /* * start real work by checking the input */ /* * IMPORTANT: view_init_stacks should be 'unparsed' for phylumdeclarations * before any checking can may place, because it initializes some (static) variables */ unparse_phylumdeclarations( Thephylumdeclarations, v_null_printer, view_init_stacks ); unparse_phylumdeclarations( Thephylumdeclarations, v_null_printer, view_check_count ); unparse_phylumdeclarations( Thephylumdeclarations, v_null_printer, view_check ); unparse_rwdeclarations( Therwdeclarations, v_null_printer, view_check ); foreach ( a_fnfile; fnfiles Thefnfiles ) { unparse_fndeclarations( a_fnfile->fns, v_null_printer, view_check ); } unparse_unparsedeclarations( Theunparsedeclarations, v_null_printer, view_check ); unparse_unparsedeclarations( Theunparsedeclarations, v_null_printer, view_check_viewnames ); /* ADD a list of views that should be defined if no views are defined */ unparse_phylumdeclarations( Thephylumdeclarations, v_null_printer, view_check_uniq ); /* * compute the attributes that we need for pattern match code */ unparse_phylumdeclarations( Thephylumdeclarations, v_null_printer, view_make_patternreps ); unparse_rwdeclarations( Therwdeclarations, v_null_printer, view_make_patternreps ); foreach ( a_fnfile; fnfiles Thefnfiles ) { unparse_fndeclarations( a_fnfile->fns, v_null_printer, view_make_patternreps ); } unparse_unparsedeclarations( Theunparsedeclarations, v_null_printer, view_make_patternreps ); /* * TO DO: * add tabbing etc to the printer function * check viewnames and build a list of them */ /* * test if anything fatal happened */ if ( ! gp_no_fatal_problems ) { leave( 1 ); } /* else go on */ proot = PhylumDeclarations( Thephylumdeclarations ); /* to avoid problems in rare situations (eg. if no phyla defined at all */ if (length_argsnumbers(Theargsnumbers) == 0) { Theargsnumbers = Consargsnumbers( 0, Theargsnumbers ); } /* create temporary file names, and open these files and reset the printer functions */ make_tempfile_names(Thetempcfile, Thetemphfile, &tmp_cfilename, &tmp_hfilename); if ((g_hfile = fopen(tmp_hfilename, "w")) == NULL) v_report( Fatal( NoFileLine(), Problem2S( "cannot create temporary k.h file:", tmp_hfilename ))); if ((g_cfile = fopen(tmp_cfilename, "w")) == NULL) v_report( Fatal( NoFileLine(), Problem2S( "cannot create temporary k.c file:", tmp_cfilename ))); v_hfile_printer( "k.h", view_printer_reset ); v_cfile_printer( "k.c", view_printer_reset ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_k_h ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_k_c ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_alloc_h ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_alloc_c ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_enumphyla_h ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_enumoperators_h ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_nodetypedefs_h ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_operatormap_type_h ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_copy_attributes_c ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_phylummap_c ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_operatormap_c ); unparse_storageclasses( Thestorageclasses, v_cfile_printer, view_gen_uniqmap_c ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_yaccstacktype_h ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_noofoperators_h ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_booleans_h ); unparse_includedeclarations( IncludeFile(mkcasestring(INC_KC_TYPES_HEADER))->inc[(int)IncludeFile(mkcasestring(INC_KC_TYPES_HEADER))->inc_type], v_hfile_printer, view_gen_includes ); unparse_includedeclarations( IncludeFile(mkcasestring(INC_KC_TYPES))->inc[(int)IncludeFile(mkcasestring(INC_KC_TYPES))->inc_type], v_cfile_printer, view_gen_includes ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_initialization_h ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_initialization_c ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_assertmacros_h ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_operatordecls_h ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_operatordefs_c ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_error_decls_h ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_error_defs_c ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_nodetypes_h ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_freedecls_h ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_freedefs_c ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_eqdecls_h ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_eqdefs_c ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_printdecls_h ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_printdefs_c ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_printdotdecls_h ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_printdotdefs_c ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_listdecls_h ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_listdefs_c ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_copydecls_h ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_copydefs_c ); /* next line should be last for k.h unparsing */ unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_end_k_h ); /* try to find out if anything went wrong while writing the files */ if (fclose( g_cfile ) == EOF) { v_report( Fatal( NoFileLine(), Problem2S( "writing temporary k.c file failed:", tmp_cfilename ))); } g_cfile = 0; if (fclose( g_hfile ) == EOF) { v_report( Fatal( NoFileLine(), Problem2S( "writing temporary k.h file failed:", tmp_hfilename ))); } g_hfile = 0; compare_and_delete_or_move(tmp_cfilename, "k.c", g_overwriteAlways); compare_and_delete_or_move(tmp_hfilename, "k.h", g_overwriteAlways); reset_tempfiles(Thetempcfile, Thetemphfile); /* create temporary file names, and open these files and reset the printer functions */ make_tempfile_names(Thetempcfile, Thetemphfile, &tmp_cfilename, &tmp_hfilename); if ((g_hfile = fopen(tmp_hfilename, "w")) == NULL) v_report( Fatal( NoFileLine(), Problem2S( "cannot create temporary csgiok.h file:", tmp_hfilename ))); if ((g_cfile = fopen(tmp_cfilename, "w")) == NULL) v_report( Fatal( NoFileLine(), Problem2S( "cannot create temporary csgiok.c file:", tmp_cfilename ))); v_hfile_printer( "csgiok.h", view_printer_reset ); v_cfile_printer( "csgiok.c", view_printer_reset ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_csgio_start_h ); unparse_includedeclarations( IncludeFile(mkcasestring(INC_KC_CSGIO_HEADER))->inc[(int)IncludeFile(mkcasestring(INC_KC_CSGIO_HEADER))->inc_type], v_hfile_printer, view_gen_includes ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_csgio_h ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_csgio_end_h ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_csgio_start_c ); unparse_includedeclarations( IncludeFile(mkcasestring(INC_KC_CSGIO))->inc[(int)IncludeFile(mkcasestring(INC_KC_CSGIO))->inc_type], v_cfile_printer, view_gen_includes ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_csgio_c ); /* try to find out if anything went wrong while writing the files */ if (fclose( g_cfile ) == EOF) { v_report( Fatal( NoFileLine(), Problem2S( "writing temporary csgiok.c file failed:", tmp_cfilename ))); } g_cfile = 0; if (fclose( g_hfile ) == EOF) { v_report( Fatal( NoFileLine(), Problem2S( "writing temporary csgiok.h file failed:", tmp_hfilename ))); } g_hfile = 0; compare_and_delete_or_move(tmp_cfilename, "csgiok.c", g_overwriteAlways); compare_and_delete_or_move(tmp_hfilename, "csgiok.h", g_overwriteAlways); reset_tempfiles(Thetempcfile, Thetemphfile); /* create temporary file names, and open these files and reset the printer functions */ make_tempfile_names(Thetempcfile, Thetemphfile, &tmp_cfilename, &tmp_hfilename); if ((g_hfile = fopen(tmp_hfilename, "w")) == NULL) v_report( Fatal( NoFileLine(), Problem2S( "cannot create temporary unpk.h file:", tmp_hfilename ))); if ((g_cfile = fopen(tmp_cfilename, "w")) == NULL) v_report( Fatal( NoFileLine(), Problem2S( "cannot create temporary unpk.c file:", tmp_cfilename ))); v_hfile_printer( "unpk.h", view_printer_reset ); v_cfile_printer( "unpk.c", view_printer_reset ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_unpk_h ); unparse_includedeclarations( IncludeFile(mkcasestring(INC_KC_UNPARSE_HEADER))->inc[(int)IncludeFile(mkcasestring(INC_KC_UNPARSE_HEADER))->inc_type], v_hfile_printer, view_gen_includes ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_unparsedecls_h ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_end_unpk_h ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_unpk_c ); unparse_includedeclarations( IncludeFile(mkcasestring(INC_KC_UNPARSE))->inc[(int)IncludeFile(mkcasestring(INC_KC_UNPARSE))->inc_type], v_cfile_printer, view_gen_includes ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_default_types_unpk_c ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_unparsedefs_c ); /* try to find out if anything went wrong while writing the files */ if (fclose( g_cfile ) == EOF) { v_report( Fatal( NoFileLine(), Problem2S( "writing temporary unpk.c file failed:", tmp_cfilename ))); } g_cfile = 0; if (fclose( g_hfile ) == EOF) { v_report( Fatal( NoFileLine(), Problem2S( "writing temporary unpk.h file failed:", tmp_hfilename ))); } g_hfile = 0; compare_and_delete_or_move(tmp_cfilename, "unpk.c", g_overwriteAlways); compare_and_delete_or_move(tmp_hfilename, "unpk.h", g_overwriteAlways); reset_tempfiles(Thetempcfile, Thetemphfile); /* create temporary file names, and open these files and reset the printer functions */ make_tempfile_names(Thetempcfile, Thetemphfile, &tmp_cfilename, &tmp_hfilename); if ((g_hfile = fopen(tmp_hfilename, "w")) == NULL) v_report( Fatal( NoFileLine(), Problem2S( "cannot create temporary rk.h file:", tmp_hfilename ))); if ((g_cfile = fopen(tmp_cfilename, "w")) == NULL) v_report( Fatal( NoFileLine(), Problem2S( "cannot create temporary rk.c file:", tmp_cfilename ))); v_hfile_printer( "rk.h", view_printer_reset ); v_cfile_printer( "rk.c", view_printer_reset ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_rewritek_h ); unparse_includedeclarations( IncludeFile(mkcasestring(INC_KC_REWRITE_HEADER))->inc[(int)IncludeFile(mkcasestring(INC_KC_REWRITE_HEADER))->inc_type], v_hfile_printer, view_gen_includes ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_rewritedecls_h ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_end_rewritek_h ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_rewritek_c ); unparse_includedeclarations( IncludeFile(mkcasestring(INC_KC_REWRITE))->inc[(int)IncludeFile(mkcasestring(INC_KC_REWRITE))->inc_type], v_cfile_printer, view_gen_includes ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_rewritedefs_c ); /* try to find out if anything went wrong while writing the files */ if (fclose( g_cfile ) == EOF) { v_report( Fatal( NoFileLine(), Problem2S( "writing temporary rk.c file failed:", tmp_cfilename ))); } g_cfile = 0; if (fclose( g_hfile ) == EOF) { v_report( Fatal( NoFileLine(), Problem2S( "writing temporary rk.h file failed:", tmp_hfilename ))); } g_hfile = 0; compare_and_delete_or_move(tmp_cfilename, "rk.c", g_overwriteAlways); compare_and_delete_or_move(tmp_hfilename, "rk.h", g_overwriteAlways); reset_tempfiles(Thetempcfile, Thetemphfile); foreach ( a_fnfile; fnfiles Thefnfiles ) { /* this should be a foreach file; and a FnFile() in the unparse_fndeclarations calls */ with( a_fnfile ) { FnFile( a_filename ): { g_hfilename = f_mk_filename( a_filename, 'h' ); g_cfilename = f_mk_filename( a_filename, 'c' ); pg_filename = a_filename; /* create temporary file names, and open these files and reset the printer functions */ make_tempfile_names(Thetempcfile, Thetemphfile, &tmp_cfilename, &tmp_hfilename); if ((g_hfile = fopen(tmp_hfilename, "w")) == NULL) v_report( Fatal( NoFileLine(), Problem4S( "cannot create temporary ", g_hfilename," file:", tmp_hfilename ))); if ((g_cfile = fopen(tmp_cfilename, "w")) == NULL) v_report( Fatal( NoFileLine(), Problem4S( "cannot create temporary ", g_cfilename," file:", tmp_cfilename ))); v_hfile_printer( g_hfilename, view_printer_reset ); v_cfile_printer( g_cfilename, view_printer_reset ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_fns_start_h ); unparse_includedeclarations( IncludeFile( a_filename )->inc[(int)include_header], v_hfile_printer, view_gen_includes ); unparse_fndeclarations( a_fnfile->fns, v_hfile_printer, view_gen_fnk_h ); unparse_phylumdeclarationsroot( proot, v_hfile_printer, view_gen_fns_end_h ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_fns_start_c ); unparse_includedeclarations( IncludeFile( a_filename )->inc[(int)include_file], v_cfile_printer, view_gen_includes ); unparse_phylumdeclarationsroot( proot, v_cfile_printer, view_gen_fns_owninclude_c ); unparse_fndeclarations( a_fnfile->fns, v_cfile_printer, view_gen_fnkdecls_c ); unparse_fndeclarations( a_fnfile->fns, v_cfile_printer, view_gen_fnk_c ); /* close .c and .h file based on a_filename */ /* try to find out if anything went wrong while writing the files */ if (fclose( g_cfile ) == EOF) { v_report( Fatal( NoFileLine(), Problem4S( "writing temporary ", g_cfilename, " file failed:", tmp_cfilename ))); } g_cfile = 0; if (fclose( g_hfile ) == EOF) { v_report( Fatal( NoFileLine(), Problem4S( "writing temporary ", g_hfilename, " file failed:", tmp_hfilename ))); } g_hfile = 0; compare_and_delete_or_move(tmp_cfilename, g_cfilename, g_overwriteAlways); compare_and_delete_or_move(tmp_hfilename, g_hfilename, g_overwriteAlways); reset_tempfiles(Thetempcfile, Thetemphfile); FREE((kc_voidptr_t) g_hfilename ); FREE((kc_voidptr_t) g_cfilename ); } } } leave( 0 ); exit( 0 ); return( 0 ); } %{ extern KC__CLINKAGE char *mktemp KC__P(( char* )); %} static void make_tempfile_names(Thetempcfile, Thetemphfile, tmp_cfilename, tmp_hfilename) char *Thetempcfile; char *Thetemphfile; char **tmp_cfilename; char **tmp_hfilename; { (void) strcpy(Thetempcfile, ".kc.c.XXXXXX"); (void) strcpy(Thetemphfile, ".kc.h.XXXXXX"); (void) mktemp(Thetempcfile); (void) mktemp(Thetemphfile); *tmp_cfilename = Thetempcfile; *tmp_hfilename = Thetemphfile; } static void reset_tempfiles(Thetempcfile, Thetemphfile) char *Thetempcfile; char *Thetemphfile; { (void) strcpy(Thetempcfile, ""); (void) strcpy(Thetemphfile, ""); } /* * f1 = file descriptor of first file * f2 = file descriptor of second file * these files should be opened at start of file: read starts at first byte in file * fn1 = name of first file * fn2 = name of second file * these file names are used in error messages */ /* * we could extend this by first comparing the file sizes * if we have a portable way of doing that */ %{ # define MYBUFSIZ 8*BUFSIZ %} static int different(f1, f2, fn1, fn2) int f1; int f2; char *fn1; char *fn2; { char buf1[MYBUFSIZ], buf2[MYBUFSIZ]; int characters_read1, characters_read2; #ifdef KC_USE_STAT struct stat stbuf1, stbuf2; if (fstat(f1, &stbuf1) != 0) { perror("kc: error"); v_report( NonFatal( NoFileLine(), Problem2S( "error stat'ing", fn1 ))); } if (fstat(f2, &stbuf2) != 0) { perror("kc: error"); v_report( NonFatal( NoFileLine(), Problem2S( "error stat'ing", fn2 ))); } if (stbuf1.st_size != stbuf2.st_size) { return 1; } #endif /* KC_USE_STAT */ while( ! kc_zero_constant ) { if ((characters_read1 = read(f1, buf1, MYBUFSIZ)) == -1) { perror("kc: error"); v_report( Fatal( NoFileLine(), Problem2S( "error while reading from", fn1 ))); } if ((characters_read2 = read(f2, buf2, MYBUFSIZ)) == -1) { perror("kc: error"); v_report( Fatal( NoFileLine(), Problem2S( "error while reading from", fn2 ))); } if (characters_read1 == 0) { if (characters_read2 == 0) return 0; else return 1; } else { if (characters_read2 == 0) return 1; else if ( (characters_read1 != characters_read2) || (memcmp(buf1, buf2, characters_read1) != 0) ) return 1; } } /*NOTREACHED*/ # undef MYBUFSIZ } /* * WARNING: the erename routine does _not_ check whether `newfilename' * already exists. * the _caller_ should make sure of this */ %{ #ifdef KC_STDC extern KC__CLINKAGE int rename KC__P((const char*, const char*)); #endif %} static void erename(oldfilename, newfilename) char *oldfilename; char *newfilename; { #ifndef KC_STDC if (link(oldfilename, newfilename) != 0) { perror("kc: error"); v_report( NonFatal( NoFileLine(), Problem4S( "could not create", newfilename, "by linking", oldfilename ))); } if (unlink(oldfilename) != 0) { perror("kc: error"); v_report( NonFatal( NoFileLine(), Problem2S( "error while unlinking", oldfilename ))); } #else if (rename(oldfilename, newfilename) != 0) { perror("kc: error"); v_report( NonFatal( NoFileLine(), Problem4S( "error while renaming", oldfilename, "to", newfilename ))); } #endif } %{ #ifdef KC_STDC extern KC__CLINKAGE int remove KC__P((const char*)); #endif %} static void eremove(filename) char *filename; { #ifndef KC_STDC if (unlink(filename) != 0) { perror("kc: error"); v_report( NonFatal( NoFileLine(), Problem2S( "error while unlinking", filename ))); } #else if (remove(filename) != 0) { perror("kc: error"); v_report( NonFatal( NoFileLine(), Problem2S( "error while removing", filename ))); } #endif } static void compare_and_delete_or_move(tmp_filename, filename, overwriteAlways) char *tmp_filename; char *filename; boolean overwriteAlways; { int tmp_file, file; int they_are_different; if ((file = open(filename, O_RDONLY)) == -1) { erename(tmp_filename, filename); } else if ((tmp_file = open(tmp_filename, O_RDONLY)) == -1) { perror("kc: error"); v_report( Fatal( NoFileLine(), Problem2S( "could not open temporary file", tmp_filename ))); } else { they_are_different = overwriteAlways || different(tmp_file, file, tmp_filename, filename); if (close(tmp_file) == -1) { perror("kc: error"); v_report( NonFatal( NoFileLine(), Problem2S( "error while closing", tmp_filename ))); } if (close(file) == -1) { perror("kc: error"); v_report( NonFatal( NoFileLine(), Problem2S( "error while closing", filename ))); } if (they_are_different) { eremove(filename); erename(tmp_filename, filename); } else { eremove(tmp_filename); } } } static phylumdeclarations f_add_predefined_phyla( p ) phylumdeclarations p; { return Consphylumdeclarations( v_predefined_voidptr(), Consphylumdeclarations( v_predefined_int(), Consphylumdeclarations( v_predefined_float(), Consphylumdeclarations( v_predefined_casestring(), Consphylumdeclarations( v_predefined_nocasestring(), p ) ) ) ) ); } static phylumdeclaration v_predefined_int() { ID int_pid, int_oid, int_sto; alternative int_alternative; phylumdeclaration int_phylumdeclaration; int_pid = Id( Str( mkcasestring( "int" ) )); int_sto = Id( Str( mkcasestring( "uniq" ) )); int_oid = Id( Str( mkcasestring( "_Int" ) )); int_alternative = Alternative( int_oid, Nilarguments() ); int_phylumdeclaration = PhylumDeclaration( int_pid, PositiveStorageOption( /*f_emptyId()*/ int_sto ), PredefinedAlternatives( Consalternatives( int_alternative, Nilalternatives() )), CcodeOption( Nilattributes(), NilCtexts() ) ); v_defoccur( int_oid, ITPredefinedOperator( int_alternative, int_pid ) ); v_defoccur( int_pid, ITPredefinedBigatomPhylum( int_phylumdeclaration ) ); return int_phylumdeclaration; } static phylumdeclaration v_predefined_float() { ID float_pid, float_oid, float_sto; alternative float_alternative; phylumdeclaration float_phylumdeclaration; float_pid = Id( Str( mkcasestring( "float" ) )); float_sto = Id( Str( mkcasestring( "uniq" ) )); float_oid = Id( Str( mkcasestring( "_Real" ) )); float_alternative = Alternative( float_oid, Nilarguments() ); float_phylumdeclaration = PhylumDeclaration( float_pid, PositiveStorageOption( /*f_emptyId()*/ float_sto ), PredefinedAlternatives( Consalternatives( float_alternative, Nilalternatives() )), CcodeOption( Nilattributes(), NilCtexts() ) ); v_defoccur( float_oid, ITPredefinedOperator( float_alternative, float_pid ) ); v_defoccur( float_pid, ITPredefinedBigatomPhylum( float_phylumdeclaration ) ); return float_phylumdeclaration; } static phylumdeclaration v_predefined_casestring() { ID casestring_pid, casestring_oid, casestring_sto; alternative casestring_alternative; phylumdeclaration casestring_phylumdeclaration; casestring_pid = Id( Str( mkcasestring( "casestring" ) )); casestring_sto = Id( Str( mkcasestring( "uniq" ) )); casestring_oid = Id( Str( mkcasestring( "_Str" ) )); casestring_alternative = Alternative( casestring_oid, Nilarguments() ); casestring_phylumdeclaration = PhylumDeclaration( casestring_pid, PositiveStorageOption( /*f_emptyId()*/ casestring_sto ), PredefinedAlternatives( Consalternatives( casestring_alternative, Nilalternatives() )), CcodeOption( Nilattributes(), NilCtexts() ) ); v_defoccur( casestring_oid, ITPredefinedOperator( casestring_alternative, casestring_pid ) ); v_defoccur( casestring_pid, ITPredefinedPhylum( casestring_phylumdeclaration ) ); return casestring_phylumdeclaration; } static phylumdeclaration v_predefined_nocasestring() { ID nocasestring_pid, nocasestring_oid, nocasestring_sto; alternative nocasestring_alternative; phylumdeclaration nocasestring_phylumdeclaration; nocasestring_pid = Id( Str( mkcasestring( "nocasestring" ) )); nocasestring_sto = Id( Str( mkcasestring( "uniq" ) )); nocasestring_oid = Id( Str( mkcasestring( "NoCaseStr" ) )); nocasestring_alternative = Alternative( nocasestring_oid, Nilarguments() ); nocasestring_phylumdeclaration = PhylumDeclaration( nocasestring_pid, PositiveStorageOption( /*f_emptyId()*/ nocasestring_sto ), PredefinedAlternatives( Consalternatives( nocasestring_alternative, Nilalternatives() )), CcodeOption( Nilattributes(), NilCtexts() ) ); v_defoccur( nocasestring_oid, ITPredefinedOperator( nocasestring_alternative, nocasestring_pid ) ); v_defoccur( nocasestring_pid, ITPredefinedPhylum( nocasestring_phylumdeclaration ) ); return nocasestring_phylumdeclaration; } static phylumdeclaration v_predefined_voidptr() { ID voidptr_pid, voidptr_oid, voidptr_sto; alternative voidptr_alternative; phylumdeclaration voidptr_phylumdeclaration; voidptr_pid = Id( Str( mkcasestring( "voidptr" ) )); voidptr_sto = Id( Str( mkcasestring( "uniq" ) )); voidptr_oid = Id( Str( mkcasestring( "_VoidPtr" ) )); voidptr_alternative = Alternative( voidptr_oid, Nilarguments() ); voidptr_phylumdeclaration = PhylumDeclaration( voidptr_pid, PositiveStorageOption( /*f_emptyId()*/ voidptr_sto ), PredefinedAlternatives( Consalternatives( voidptr_alternative, Nilalternatives() )), CcodeOption( Nilattributes(), NilCtexts() ) ); v_defoccur( voidptr_oid, ITPredefinedOperator( voidptr_alternative, voidptr_pid ) ); v_defoccur( voidptr_pid, ITPredefinedPhylum( voidptr_phylumdeclaration ) ); return voidptr_phylumdeclaration; } static casestring make_pg_filename( s ) char *s; { /*********** char *tmpinpfilename; casestring tmp; tmpinpfilename=(char *)MALLOC((kc_size_t)(strlen(s)+3)); (void)sprintf(tmpinpfilename, "\"%s\"", s); tmp = mkcasestring( tmpinpfilename ); FREE((kc_voidptr_t) tmpinpfilename ); return tmp; ***********/ return mkcasestring(s); } /* signal handling, to be able to clean up if we are interupted */ static void set_signals() { #ifdef SIGHUP signal(SIGHUP, cleanup_and_die); #endif #ifdef SIGINT signal(SIGINT, cleanup_and_die); #endif #ifdef SIGTERM signal(SIGTERM, cleanup_and_die); #endif #ifdef SIGQUIT signal(SIGQUIT, cleanup_and_die); #endif #ifdef SIGBUS signal(SIGBUS, cleanup_and_abort); #endif #ifdef SIGSEGV signal(SIGSEGV, cleanup_and_abort); #endif /* signal(SIGSYS, cleanup_and_abort); */ #ifdef SIGILL signal(SIGILL, cleanup_and_abort); #endif #ifdef SIGIOT signal(SIGIOT, cleanup_and_abort); #endif #ifdef SIGABRT signal(SIGABRT, cleanup_and_abort); #endif } /* unused, because we now set a signal handler only once when we start, * instead of just before opening an output file */ static void reset_signals() { #ifdef SIGHUP signal(SIGHUP, SIG_DFL); #endif #ifdef SIGINT signal(SIGINT, SIG_DFL); #endif #ifdef SIGTERM signal(SIGTERM, SIG_DFL); #endif #ifdef SIGQUIT signal(SIGQUIT, SIG_DFL); #endif #ifdef SIGBUS signal(SIGBUS, SIG_DFL); #endif #ifdef SIGSEGV signal(SIGSEGV, SIG_DFL); #endif /* signal(SIGSYS, SIG_DFL); */ #ifdef SIGILL signal(SIGILL, SIG_DFL); #endif #ifdef SIGIOT signal(SIGIOT, SIG_DFL); #endif #ifdef SIGABRT signal(SIGABRT, SIG_DFL); #endif } /* empty. Should we do here somthing to make sure we don't get interupted? */ static void block_signals() { } /* cleanup the generated intermediate files if we are interupted */ static void cleanup_and_die( i ) int i; { fprintf(stderr, "%s: received signal, cleaning up\n", g_progname->name); /* even though we don't die a violent death, we still do inform * our envrionrment that we didn't finish as planned, by exiting * with non-zero exit status */ leave(1); } /* cleanup the generated intermediate files if we are interupted */ static void cleanup_and_abort( i ) int i; { perror("kc: something horrible happened:"); fprintf(stderr, "%s: received signal, cleaning up\n", g_progname->name); leave(1); } /* cleanup the generated intermediate files if we are interupted */ static void cleanup() { /* first, we try to make sure that we will not be interupted */ block_signals(); /* then, we close the open files */ if (g_cfile) { if (fclose( g_cfile ) == EOF) { v_report( Fatal( NoFileLine(), Problem2S( "writing temporary file failed:", Thetempcfile ))); } g_cfile = 0; } if (g_hfile) { if (fclose( g_hfile ) == EOF) { v_report( Fatal( NoFileLine(), Problem2S( "writing temporary file failed:", Thetemphfile ))); } g_hfile = 0; } /* next, we unlink the tempfiles, if they exist */ if (Thetempcfile && (strcmp(Thetempcfile, "") != 0) && ((g_cfile = fopen(Thetempcfile, "r")) != NULL)) { (void)fclose( g_cfile ); if (verbose) printf("removing %s\n", Thetempcfile); eremove(Thetempcfile); } if (Thetemphfile && (strcmp(Thetemphfile, "") != 0) && ((g_hfile = fopen(Thetemphfile, "r")) != NULL)) { (void)fclose( g_hfile ); if (verbose) printf("removing %s\n", Thetemphfile); eremove(Thetemphfile); } } void leave(status) int status; { cleanup(); if (gp_no_fatal_problems) { exit( (status==0) ? 0 : status ); } else { exit( (status==0) ? 1 : status ); } }