From 65521437b7bde22500eb63de2adf6a4beb4f545f Mon Sep 17 00:00:00 2001 From: "James K. Lowden" <jklowden@symas.com> Date: Tue, 2 Jan 2024 15:44:58 -0500 Subject: [PATCH] introduce -preprocess option --- gcc/cobol/cdf_text.h | 75 +++++++++++++++++++++++++++++++++++++++++++- gcc/cobol/cobol1.cc | 4 ++- gcc/cobol/lexio.h | 7 ----- 3 files changed, 77 insertions(+), 9 deletions(-) diff --git a/gcc/cobol/cdf_text.h b/gcc/cobol/cdf_text.h index 4f2c281f23c5..8c86bc770db7 100644 --- a/gcc/cobol/cdf_text.h +++ b/gcc/cobol/cdf_text.h @@ -28,7 +28,51 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +static const char * +find_filter( const char filter[] ) { + + if( 0 == access(filter, X_OK) ) { + return filter; + } + + const char *path = getenv("PATH"); + if( ! path ) return NULL; + char *p = strdup(path), *eopath = p + strlen(p); + + while( *p != '\0' ) { + auto pend = std::find( p, eopath, ':' ); + if( *pend == ':' ) *pend++ = '\0'; + + static char name[PATH_MAX]; + + snprintf( name, sizeof(name), "%s/%s", p, filter ); + + if( 0 == access(name, X_OK) ) { + return name; + } + p = pend; + } + return NULL; +} + +bool verbose_file_reader = false; +static std::list<char *> preprocessor_filters; + #include "lexio.h" + +#include <sys/types.h> +#include <sys/wait.h> + +bool preprocess_filter_add( const char filter[] ) { + auto filename = find_filter(filter); + if( !filename ) { + warnx("error: preprocessor '%s/%s' not found", getcwd(NULL, 0), filter); + return false; + } + preprocessor_filters.push_back( strdup(filename) ); + return true; +} + FILE * cdftext::lex_open( const char filename[] ) { int input = open_input( filename ); @@ -39,6 +83,29 @@ cdftext::lex_open( const char filename[] ) { cobol_filename(filename); process_file( mfile, output ); + for( auto filter : preprocessor_filters ) { + input = output; + output = open_output(); + + pid_t pid = fork(); + + switch(pid){ + case -1: err(EXIT_FAILURE, "%s", __func__); + case 0: // child + if( -1 == dup2(input, STDIN_FILENO) ) { + errx(EXIT_FAILURE, "%s: could not dup input", __func__); + } + if( -1 == dup2(output, STDOUT_FILENO) ) { + errx(EXIT_FAILURE, "%s: could not dup output", __func__); + } + _exit( execl( filter, filter, "/dev/stdin", NULL ) ); + } + int status; + if( pid != wait(&status) ) { + err(EXIT_FAILURE, "error: %s failed with exit status %d", filter, status); + } + } + return fdopen( output, "r"); } @@ -49,6 +116,12 @@ cdftext::open_input( const char filename[] ) { if( fd == -1 ) { if( yydebug ) warn( "error: could not open '%s'", filename ); } + + verbose_file_reader = NULL != getenv("GCOBOL_TEMPDIR"); + + if( verbose_file_reader ) { + warnx("verbose: opening %s for input", filename); + } return fd; } @@ -58,7 +131,7 @@ cdftext::open_output() { char *name = getenv("GCOBOL_TEMPDIR"); int fd; - if( name ) { + if( name && 0 != strcmp(name, "/") ) { sprintf(stem, "%sXXXXXX", name); if( -1 == (fd = mkstemp(stem)) ) { err(EXIT_FAILURE, diff --git a/gcc/cobol/cobol1.cc b/gcc/cobol/cobol1.cc index 3eaa25a32e48..4cc4f3c9e7e4 100644 --- a/gcc/cobol/cobol1.cc +++ b/gcc/cobol/cobol1.cc @@ -155,6 +155,8 @@ void parser_internal_is_ebcdic(bool is_ebcdic); bool use_static_call( bool yn ); void add_cobol_exception( int ); +bool preprocess_filter_add( const char filter[] ); + bool max_errors_exceeded( int nerr ) { return flag_max_errors != 0 && flag_max_errors <= nerr; } @@ -252,7 +254,7 @@ cobol_langhook_handle_option (size_t scode, return true; case OPT_preprocess: - ////preprocess_filter_add(arg); + preprocess_filter_add(arg); return true; case OPT_main: diff --git a/gcc/cobol/lexio.h b/gcc/cobol/lexio.h index e619d853abfd..2deca53c15c9 100644 --- a/gcc/cobol/lexio.h +++ b/gcc/cobol/lexio.h @@ -230,13 +230,6 @@ struct replace_t { #include <list> class cdftext { - ////std::stack< std::list<replace_t> > replace_directives; - - //// bool parse_copy_directive( filespan_t& mfile ); - //// bool parse_replace_last_off( filespan_t& mfile ); - //// bool parse_replace_text( filespan_t& mfile, size_t current_lineno ); - //// parse_replace_directive( filespan_t& mfile, size_t current_lineno ); - static filespan_t free_form_reference_format( int fd ); static void process_file( filespan_t, int output, bool second_pass = false ); -- GitLab