From d780100c63ffd3b96c4be218edc60627dba1fcc1 Mon Sep 17 00:00:00 2001 From: "James K. Lowden" Date: Wed, 9 Jul 2025 18:14:40 -0400 Subject: [PATCH] cobol: Add PUSH and POP to CDF. Introduce cdf_directives_t class to centralize management of CDF state. Move existing CDF state variables and functions into the new class. gcc/cobol/ChangeLog: PR cobol/120765 * cdf.y: Extend grammar for new CDF syntax, relocate dictionary. * cdfval.h (cdf_dictionary): Use new CDF dictionary. * dts.h: Remove useless assignment, note incorrect behavior. * except.cc: Remove obsolete EC state. * gcobol.1: Document CDF in its own section. * genapi.cc (parser_statement_begin): Use new EC state function. (parser_file_merge): Same. (parser_check_fatal_exception): Same. * genutil.cc (get_and_check_refstart_and_reflen): Same. (get_depending_on_value_from_odo): Same. (get_data_offset): Same. (process_this_exception): Same. * lexio.cc (check_push_pop_directive): New function. (check_source_format_directive): Restrict regex search to 1 line. (cdftext::free_form_reference_format): Use new function. * parse.y: Define new CDF tokens, use new CDF state. * parse_ante.h (cdf_tokens): Use new CDF state. (redefined_token): Same. (class prog_descr_t): Remove obsolete CDF state. (class program_stack_t): Same. (current_call_convention): Same. * scan.l: Recognize new CDF tokens. * scan_post.h (is_cdf_token): Same. * symbols.h (cdf_current_tokens): Change current_call_convention to return void. * token_names.h: Regenerate. * udf/stored-char-length.cbl: Use new PUSH/POP CDF functionality. * util.cc (class cdf_directives_t): Define cdf_directives_t. (current_call_convention): Same. (cdf_current_tokens): Same. (cdf_dictionary): Same. (cdf_enabled_exceptions): Same. (cdf_push): Same. (cdf_push_call_convention): Same. (cdf_push_current_tokens): Same. (cdf_push_dictionary): Same. (cdf_push_enabled_exceptions): Same. (cdf_push_source_format): Same. (cdf_pop): Same. (cdf_pop_call_convention): Same. (cdf_pop_current_tokens): Same. (cdf_pop_dictionary): Same. (cdf_pop_enabled_exceptions): Same. (cdf_pop_source_format): Same. * util.h (cdf_push): Declare cdf_directives_t. (cdf_push_call_convention): Same. (cdf_push_current_tokens): Same. (cdf_push_dictionary): Same. (cdf_push_enabled_exceptions): Same. (cdf_push_source_format): Same. (cdf_pop): Same. (cdf_pop_call_convention): Same. (cdf_pop_current_tokens): Same. (cdf_pop_dictionary): Same. (cdf_pop_source_format): Same. (cdf_pop_enabled_exceptions): Same. libgcobol/ChangeLog: * common-defs.h (cdf_enabled_exceptions): Use new CDF state. (cherry picked from commit 3f59a1cac717f8af84e884e9ec0f6ef14e102e6e) --- gcc/cobol/cdf.y | 94 +- gcc/cobol/cdfval.h | 4 + gcc/cobol/dts.h | 14 +- gcc/cobol/except.cc | 2 - gcc/cobol/gcobol.1 | 192 ++- gcc/cobol/genapi.cc | 6 +- gcc/cobol/genutil.cc | 7 + gcc/cobol/lexio.cc | 72 +- gcc/cobol/parse.y | 21 +- gcc/cobol/parse_ante.h | 48 +- gcc/cobol/scan.l | 13 + gcc/cobol/scan_post.h | 2 + gcc/cobol/symbols.h | 3 +- gcc/cobol/token_names.h | 2228 +++++++++++++------------- gcc/cobol/udf/stored-char-length.cbl | 4 + gcc/cobol/util.cc | 90 +- gcc/cobol/util.h | 15 + libgcobol/common-defs.h | 2 +- 18 files changed, 1541 insertions(+), 1276 deletions(-) diff --git a/gcc/cobol/cdf.y b/gcc/cobol/cdf.y index f1a79124585..840eb503315 100644 --- a/gcc/cobol/cdf.y +++ b/gcc/cobol/cdf.y @@ -105,14 +105,14 @@ void input_file_status_notify(); using std::map; - static map dictionary; - #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" static bool cdfval_add( const char name[], const cdfval_t& value, bool override = false ) { + cdf_values_t& dictionary( cdf_dictionary() ); + if( scanner_parsing() ) { if( ! override ) { if( dictionary.find(name) != dictionary.end() ) return false; @@ -123,6 +123,8 @@ void input_file_status_notify(); } static void cdfval_off( const char name[] ) { + cdf_values_t& dictionary( cdf_dictionary() ); + if( scanner_parsing() ) { auto p = dictionary.find(name); if( p == dictionary.end() ) { @@ -159,6 +161,8 @@ exception_turn_t exception_turn; bool apply_cdf_turn( const exception_turn_t& turn ) { + cbl_enabled_exceptions_t& enabled_exceptions( cdf_enabled_exceptions() ); + for( auto elem : turn.exception_files() ) { std::set files(elem.second.begin(), elem.second.end()); enabled_exceptions.turn_on_off(turn.enabled, @@ -204,15 +208,17 @@ apply_cdf_turn( const exception_turn_t& turn ) { %type filename %type filenames -%token BY 482 +%type cdf_stackable + +%token BY 486 %token COPY 362 %token CDF_DISPLAY 384 ">>DISPLAY" -%token IN 601 +%token IN 605 %token NAME 286 %token NUMSTR 305 "numeric literal" -%token OF 682 -%token PSEUDOTEXT 717 -%token REPLACING 739 +%token OF 686 +%token PSEUDOTEXT 721 +%token REPLACING 743 %token LITERAL 298 %token SUPPRESS 376 @@ -227,25 +233,32 @@ apply_cdf_turn( const exception_turn_t& turn ) { %token CDF_WHEN 389 ">>WHEN" %token CDF_END_EVALUATE 390 ">>END-EVALUATE" -%token AS 464 CONSTANT 361 DEFINED 363 +%token ALL 450 +%token CALL_CONVENTION 391 ">>CALL-CONVENTION" +%token COBOL_WORDS 380 ">>COBOL-WORDS" +%token CDF_PUSH 394 ">>PUSH" +%token CDF_POP 395 ">>POP" +%token SOURCE_FORMAT 396 ">>SOURCE FORMAT" + +%token AS 468 CONSTANT 361 DEFINED 363 %type DEFINED -%token OTHER 694 PARAMETER_kw 368 "PARAMETER" -%token OFF 683 OVERRIDE 369 -%token THRU 935 -%token TRUE_kw 809 "True" +%token OTHER 698 PARAMETER_kw 368 "PARAMETER" +%token OFF 687 OVERRIDE 369 +%token THRU 939 +%token TRUE_kw 813 "True" -%token CALL_COBOL 391 "CALL" -%token CALL_VERBATIM 392 "CALL (as C)" +%token CALL_COBOL 392 "CALL" +%token CALL_VERBATIM 393 "CALL (as C)" -%token TURN 811 CHECKING 492 LOCATION 645 ON 685 WITH 837 +%token TURN 815 CHECKING 496 LOCATION 649 ON 689 WITH 841 -%left OR 936 -%left AND 937 -%right NOT 938 -%left '<' '>' '=' NE 939 LE 940 GE 941 +%left OR 940 +%left AND 941 +%right NOT 942 +%left '<' '>' '=' NE 943 LE 944 GE 945 %left '-' '+' %left '*' '/' -%right NEG 943 +%right NEG 947 %define api.prefix {ydf} %define api.token.prefix{YDF_} @@ -277,6 +290,8 @@ complete: cdf_define | cdf_display | cdf_turn | cdf_call_convention + | cdf_push + | cdf_pop ; /* @@ -328,6 +343,7 @@ cdf_define: CDF_DEFINE cdf_constant NAME as cdf_expr[value] override } if( !cdfval_add( $NAME, cdfval_t($value), $override) ) { error_msg(@NAME, "name already in dictionary: %s", $NAME); + cdf_values_t& dictionary( cdf_dictionary() ); const cdfval_t& entry = dictionary[$NAME]; if( entry.filename ) { error_msg(@NAME, "%s previously defined in %s:%d", @@ -357,7 +373,7 @@ cdf_define: CDF_DEFINE cdf_constant NAME as cdf_expr[value] override * available regardless. */ { - if( 0 == dictionary.count($NAME) ) { + if( 0 == cdf_dictionary().count($NAME) ) { yywarn("CDF: '%s' is defined AS PARAMETER " "but was not defined", $NAME); } @@ -400,6 +416,35 @@ cdf_call_convention: } ; +cdf_push: CDF_PUSH cdf_stackable { + switch( $cdf_stackable ) { + case YDF_ALL: cdf_push(); break; + case YDF_CALL_CONVENTION: cdf_push_call_convention(); break; + case YDF_CDF_DEFINE: cdf_push_dictionary(); break; + case YDF_COBOL_WORDS: cdf_push_current_tokens(); break; + case YDF_SOURCE_FORMAT: cdf_push_source_format(); break; + default: gcc_unreachable(); + } + } + ; +cdf_pop: CDF_POP cdf_stackable { + switch( $cdf_stackable ) { + case YDF_ALL: cdf_pop(); break; + case YDF_CALL_CONVENTION: cdf_pop_call_convention(); break; + case YDF_CDF_DEFINE: cdf_pop_dictionary(); break; + case YDF_COBOL_WORDS: cdf_pop_current_tokens(); break; + case YDF_SOURCE_FORMAT: cdf_pop_source_format(); break; + default: gcc_unreachable(); + } + } + ; + +cdf_stackable: ALL { $$ = YDF_ALL; } + | CALL_CONVENTION { $$ = YDF_CALL_CONVENTION; } + | COBOL_WORDS { $$ = YDF_COBOL_WORDS; } + | CDF_DEFINE { $$ = YDF_CDF_DEFINE; } + | SOURCE_FORMAT { $$ = YDF_SOURCE_FORMAT; } + ; except_names: except_name | except_names except_name @@ -471,6 +516,7 @@ cdf_eval_obj: cdf_cond_expr cdf_cond_expr: BOOL | NAME DEFINED { + cdf_values_t& dictionary( cdf_dictionary() ); auto p = dictionary.find($1); bool found = p != dictionary.end(); if( !$DEFINED ) found = ! found; @@ -552,6 +598,7 @@ cdf_expr: cdf_expr '+' cdf_expr { $$ = $1(@1) + $3(@3); } ; cdf_factor: NAME { + cdf_values_t& dictionary( cdf_dictionary() ); auto that = dictionary.find($1); if( that != dictionary.end() ) { $$ = that->second; @@ -651,6 +698,7 @@ name_any: namelit name_one: NAME { + cdf_values_t& dictionary( cdf_dictionary() ); cdf_arg_t arg = { YDF_NAME, $1 }; auto p = dictionary.find($1); @@ -665,6 +713,7 @@ name_one: NAME namelit: name { + cdf_values_t& dictionary( cdf_dictionary() ); cdf_arg_t arg = { YDF_NAME, $1 }; auto p = dictionary.find($1); @@ -745,6 +794,7 @@ location_set( const YYLTYPE& loc ) { bool // used by cobol1.cc defined_cmd( const char arg[] ) { + cdf_values_t& dictionary( cdf_dictionary() ); cdfval_t value(1); char *name = xstrdup(arg); @@ -868,6 +918,7 @@ static int ydflex(void) { bool cdf_value( const char name[], const cdfval_t& value ) { + cdf_values_t& dictionary( cdf_dictionary() ); auto p = dictionary.find(name); if( p != dictionary.end() ) return false; @@ -878,6 +929,7 @@ cdf_value( const char name[], const cdfval_t& value ) { const cdfval_t * cdf_value( const char name[] ) { + cdf_values_t& dictionary( cdf_dictionary() ); auto p = dictionary.find(name); if( p == dictionary.end() ) return NULL; diff --git a/gcc/cobol/cdfval.h b/gcc/cobol/cdfval.h index 465bdbb4d1a..cc474a22a48 100644 --- a/gcc/cobol/cdfval.h +++ b/gcc/cobol/cdfval.h @@ -126,4 +126,8 @@ cdf_value( const char name[] ); bool cdf_value( const char name[], const cdfval_t& value ); +typedef std::map cdf_values_t; + +cdf_values_t& cdf_dictionary(); + #endif diff --git a/gcc/cobol/dts.h b/gcc/cobol/dts.h index aa3fa585096..e12b979e6a1 100644 --- a/gcc/cobol/dts.h +++ b/gcc/cobol/dts.h @@ -86,18 +86,24 @@ namespace dts { #if __cpp_exceptions static const char msg[] = "input not NUL-terminated"; throw std::domain_error( msg ); -#else - // eoinput terminates input - eoinput = strchr(input, '\0'); // cppcheck-suppress uselessAssignmentPtrArg #endif } auto ncm = re.size(); cm.resize(ncm); std::vector cms(ncm); - int erc = regexec( &re, input, ncm, cms.data(), 0 ); if( erc != 0 ) return false; +#if __cpp_exceptions + // This is not correct at all, but current use depends on current behavior. + // The following line is excluded from the GCC build, which is compiled + // without __cpp_exceptions. parse_copy_directive (for one) depends on + // regex_search returning true even if the match is beyond eoinput. + if( eoinput < cm[0].second ) return false; + // Correct behavior would return match only between input and eoinput. + // Because regex(3) uses a NUL terminator, it may match text between + // eoinput and the NUL. +#endif std::transform( cms.begin(), cms.end(), cm.begin(), [input]( const regmatch_t& m ) { return csub_match( input, m ); diff --git a/gcc/cobol/except.cc b/gcc/cobol/except.cc index 60b841664f5..e42aea2924b 100644 --- a/gcc/cobol/except.cc +++ b/gcc/cobol/except.cc @@ -84,8 +84,6 @@ cbl_enabled_exception_t::dump( int i ) const { file ); } -cbl_enabled_exceptions_t enabled_exceptions; - void cbl_enabled_exceptions_t::dump() const { extern int yydebug; diff --git a/gcc/cobol/gcobol.1 b/gcc/cobol/gcobol.1 index 6db54009fcf..ebb833c793b 100644 --- a/gcc/cobol/gcobol.1 +++ b/gcc/cobol/gcobol.1 @@ -587,6 +587,21 @@ statement, regardless of compile-time constants. .. . .Ss Implemented Exception Conditions +By default, per ISO, no EC is enabled. Implemented ECs may be enabled +on the command line or via the +.Sy TURN +directive. Any attempt to enable an EC that is not implemented is +treated as an error. +.Pp +An enabled EC not handled by a +.Sy DECLARATIVE +is written to the system log and to standard error. (The authors +intend to make that an option.) A fatal EC not handled with +.Sy RESUME +ends with a call to +.Xr abort 3 +and process termination. +.Pp Not all Exception Conditions are implemented. Any attempt to enable an EC that that is not implemented produces a warning message. The following are implemented: @@ -913,11 +928,90 @@ or has no effect; the two are interchangeable. .. . -.Ss Compiler-Directing Facility (CDF) +.Sh COMPILER-DIRECTING FACILITY The CDF should be used with caution because no comprehensive test -suite has been identified. +suite has been identified. . -.Ss Conditional Compilation +.Ss CDF Text Manipulation +.Bl -tag -width >>DEFINE +.It Sy COPY Ar copybook Li Oo OF|BY Ar library Oc Oo Sy REPLACING ... Oc +If +.Ar copybook +is a literal, it treated a literal filename, which either does or does not exist. If +.Ar copybook +is a \*[lang] word, +.Nm +looks first for an environment variable named +.Va copybook +and, if found, uses the contents of that variable as the name of the +copybook file. If that file does not exist, it continues looking for +a file named one of: +.sp +.Bl -bullet -compact -offset 5n +.It +.Pa copybook +(literally) +.It +.Pa copybook.cpy +.It +.Pa copybook.CPY +.It +.Pa copybook.cbl +.It +.Pa copybook.CBL +.It +.Pa copybook.cob +.It +.Pa copybook.COB +.El +.sp +in that order. It looks first in the same directory as the source +code file, and then in any +.Ar copybook-path +named with the +.Fl I +option. +. +.\" FIXME: need escape mechanism for directories with ':' in the name. +.Ar copybook-path +may (like the shell's +.Ev PATH +variable) be a colon-separated list. +The +.Fl I +option may occur multiple times on the command line. Each successive +.Ar copybook-path +is concatenated to previous ones. +Relative paths (having no leading +.Ql / Ns +\&) +are searched relative to the compiler's current working directory. +.Pp +For example, +.D1 \& +.D1 Fl I Li /usr/local/include:include +.D1 \& +searches first the directory where the \*[lang] program is found, next in +.Pa /usr/local/include , +and finally in an +.Pa include +subdirectory of the directory from which +.Nm +was invoked. +.Pp +For the +.Sy REPLACING +phrase, both the modern pseudo-text and the \*[lang]/85 forms are +recognized. (The older forms are used in the NIST CCVS/85 test suite.) +.It Sy REPLACE ... +.Nm +supports the full ISO +.Sy REPLACE +syntax. +.El +. +.Ss CDF Directives +.\"Bl -tag -width >>PROPAGATE .Bl -tag -width >>DEFINE .It >> Ns Sy DEFINE Ar name Sy AS Bro Ar expression Li | Sy PARAMETER Brc Op Sy OVERRIDE Define @@ -959,10 +1053,6 @@ is supported. Boolean literals are not supported. . .It >> Ns Sy EVALUATE Not implemented. -.El -. -.Ss Other CDF Directives -.Bl -tag -width >>PROPAGATE .It >> Ns Sy CALL-CONVENTION Ar convention .Ar convention may be one of: @@ -1036,6 +1126,24 @@ Not implemented. Not implemented. .It >> Ns Sy PROPAGATE Not implemented. +.It >> Ns Sy PUSH Ar directive +.It >> Ns Sy POP Ar directive +With +.Sy PUSH , +push CDF state onto a stack. +With +.Sy POP , +return to the prior pushed state. +.Ar directive +may be one of +.Bl -tag -compact +.It Sy CALL-CONVENTION +.It Sy COBOL-WORDS +.It Sy DEFINE +.It Sy SOURCE FORMAT +.It Sy TURN +.El +. .It >> Ns Sy TURN Oo .Ar ec Oo Ar file Li ... Oc ... .Oc Sy CHECKING Bro Oo Sy ON Oc Oo Oo Sy WITH Oc Sy LOCATION Oc | Sy OFF Brc @@ -1087,76 +1195,6 @@ the directive must appear before To test a feature-set variable, use .Dl >>IF Ar feature Li DEFINED . -.Ss Copybooks -.Nm -supports the CDF -.Sy COPY -statement, with or without its -.Sy REPLACING -component. For any statement -.sp -.D1 COPY Ar copybook -.sp -.Nm -looks first for an environment variable named -.Va copybook -and, if found, uses the contents of that variable as the name of the -copybook file. If that file does not exist, it continues looking for -a file named one of: -.sp -.Bl -bullet -compact -offset 5n -.It -.Pa copybook -(literally) -.It -.Pa copybook.cpy -.It -.Pa copybook.CPY -.It -.Pa copybook.cbl -.It -.Pa copybook.CBL -.It -.Pa copybook.cob -.It -.Pa copybook.COB -.El -.sp -in that order. It looks first in the same directory as the source -code file, and then in any -.Ar copybook-path -named with the -.Fl I -option. -. -.\" FIXME: need escape mechanism for directories with ':' in the name. -.Ar copybook-path -may (like the shell's -.Ev PATH -variable) be a colon-separated list. -. -The -.Fl I -option may occur multiple times on the command line. Each successive -.Ar copybook-path -is concatenated to previous ones. -Relative paths (having no leading -.Ql / Ns -\&) -are searched relative to the compiler's current working directory. -.Pp -For example, -.D1 \& -.D1 Fl I Li /usr/local/include:include -.D1 \& -searches first the directory where the \*[lang] program is found, next in -.Pa /usr/local/include , -and finally in an -.Pa include -subdirectory of the directory from which -.Nm -was invoked. -. .Ss Intrinsic functions .Nm implements all intrinsic functions defined by \*[isostd], plus a few diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc index 55db870c7de..3c4e9a9ebbb 100644 --- a/gcc/cobol/genapi.cc +++ b/gcc/cobol/genapi.cc @@ -1166,7 +1166,7 @@ parser_statement_begin( const cbl_name_t statement_name, // the execution time of a program doing two-billion simple adds in an inner // loop dropped from 3.8 seconds to 0.175 seconds. - bool exception_processing = enabled_exceptions.size() ; + bool exception_processing = cdf_enabled_exceptions().size() ; if( !exception_processing ) { @@ -12236,6 +12236,8 @@ parser_file_merge( cbl_file_t *workfile, ELSE ENDIF + cbl_enabled_exceptions_t& enabled_exceptions( cdf_enabled_exceptions() ); + for(size_t i=0; ioccurs.depending_on)); @@ -601,6 +604,7 @@ get_data_offset(cbl_refer_t &refer, } else { + cbl_enabled_exceptions_t& enabled_exceptions( cdf_enabled_exceptions() ); if( !enabled_exceptions.match(ec_bound_subscript_e) ) { // With no exception testing, just pick up the value @@ -657,6 +661,8 @@ get_data_offset(cbl_refer_t &refer, // Although we strictly don't need to look at the ODO value at this point, // we do want it checked for the purposes of ec-bound-odo + cbl_enabled_exceptions_t& enabled_exceptions( cdf_enabled_exceptions() ); + if( enabled_exceptions.match(ec_bound_odo_e) ) { if( parent->occurs.depending_on ) @@ -1669,6 +1675,7 @@ set_exception_code_func(ec_type_t ec, int /*line*/, int from_raise_statement) bool process_this_exception(ec_type_t ec) { + cbl_enabled_exceptions_t& enabled_exceptions( cdf_enabled_exceptions() ); bool retval; if( enabled_exceptions.match(ec) || !skip_exception_processing ) { diff --git a/gcc/cobol/lexio.cc b/gcc/cobol/lexio.cc index 4a50441f24a..0aebe52ada6 100644 --- a/gcc/cobol/lexio.cc +++ b/gcc/cobol/lexio.cc @@ -320,8 +320,70 @@ recognize_replacements( filespan_t mfile, std::list& pending_replacem } } +static void +check_push_pop_directive( filespan_t& mfile ) { + char eol = '\0'; + const char *p = std::find(mfile.cur, mfile.eol, '>'); + if( ! (p < mfile.eol && p[1] == *p ) ) return; + + const char pattern[] = + ">>[[:blank:]]*(push|pop)[[:blank:]]+" + "(" + "all|" + "call-convention|" + "cobol-words|" + "define|" + "source[[:blank:]]+format|" + "turn" + ")"; + static regex re(pattern, extended_icase); + + // show contents of marked subexpressions within each match + cmatch cm; + + std::swap(*mfile.eol, eol); // see implementation for excuses + bool ok = regex_search(p, const_cast(mfile.eol), cm, re); + std::swap(*mfile.eol, eol); + + if( ok ) { + gcc_assert(cm.size() > 1); + bool push = TOUPPER(cm[1].first[1]) == 'U'; + switch( TOUPPER(cm[2].first[0]) ) { + case 'A': // ALL + push? cdf_push() : cdf_pop(); + break; + case 'C': + switch( TOUPPER(cm[2].first[1]) ) { + case 'A': // CALL-CONVENTION + push? cdf_push_call_convention() : cdf_pop_call_convention(); + break; + case 'O': // COBOL-WORDS + push? cdf_push_current_tokens() : cdf_pop_current_tokens(); + break; + default: + gcc_unreachable(); + } + break; + case 'D': // DEFINE + push? cdf_push_dictionary() : cdf_pop_dictionary(); + break; + case 'S': // SOURCE FORMAT + push? cdf_push_source_format() : cdf_pop_source_format(); + break; + case 'T': // TURN + push? cdf_push_enabled_exceptions() : cdf_pop_enabled_exceptions(); + break; + default: + gcc_unreachable(); + } + erase_line(const_cast(cm[0].first), + const_cast(cm[0].second)); + } +} + static void check_source_format_directive( filespan_t& mfile ) { + char eol = '\0'; const char *p = std::find(mfile.cur, mfile.eol, '>'); if( ! (p < mfile.eol && p[1] == *p ) ) return; @@ -334,7 +396,12 @@ check_source_format_directive( filespan_t& mfile ) { // show contents of marked subexpressions within each match cmatch cm; - if( regex_search(p, const_cast(mfile.eol), cm, re) ) { + + std::swap(*mfile.eol, eol); // see implementation for excuses + bool ok = regex_search(p, const_cast(mfile.eol), cm, re); + std::swap(*mfile.eol, eol); + + if( ok ) { gcc_assert(cm.size() > 1); switch( cm[3].length() ) { case 4: @@ -353,8 +420,8 @@ check_source_format_directive( filespan_t& mfile ) { cdf_source_format().description(), (fmt_size_t)mfile.lineno() ); char *bol = cdf_source_format().is_fixed()? mfile.cur : const_cast(cm[0].first); + gcc_assert(cm[0].second <= mfile.eol); erase_line(bol, const_cast(cm[0].second)); - mfile.cur = const_cast(cm[0].second); } } @@ -1688,6 +1755,7 @@ cdftext::free_form_reference_format( int input ) { } while( mfile.next_line() ) { + check_push_pop_directive(mfile); check_source_format_directive(mfile); remove_inline_comment(mfile.cur, mfile.eol); diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y index 2212acc8e2b..83bffdfccc5 100644 --- a/gcc/cobol/parse.y +++ b/gcc/cobol/parse.y @@ -386,7 +386,10 @@ CDF_EVALUATE ">>EVALUATE" CDF_WHEN ">>WHEN" CDF_END_EVALUATE ">>END-EVALUATE" + CALL_CONVENTION ">>CALL-CONVENTION" CALL_COBOL "CALL" CALL_VERBATIM "CALL (as C)" + CDF_PUSH ">>PUSH" CDF_POP ">>POP" + SOURCE_FORMAT ">>SOURCE FORMAT" IF THEN ELSE SENTENCE @@ -1469,16 +1472,16 @@ cobol_words: cobol_words1 | cobol_words cobol_words1 ; cobol_words1: COBOL_WORDS EQUATE NAME[keyword] WITH NAME[name] { - if( ! tokens.equate(@keyword, $keyword, $name) ) { YYERROR; } + if( ! cdf_tokens.equate(@keyword, $keyword, $name) ) { YYERROR; } } | COBOL_WORDS UNDEFINE NAME[keyword] { - if( ! tokens.undefine(@keyword, $keyword) ) { YYERROR; } + if( ! cdf_tokens.undefine(@keyword, $keyword) ) { YYERROR; } } | COBOL_WORDS SUBSTITUTE NAME[keyword] BY NAME[name] { - if( ! tokens.substitute(@keyword, $keyword, $name) ) { YYERROR; } + if( ! cdf_tokens.substitute(@keyword, $keyword, $name) ) { YYERROR; } } | COBOL_WORDS RESERVE NAME[name] { - if( ! tokens.reserve(@name, $name) ) { YYERROR; } + if( ! cdf_tokens.reserve(@name, $name) ) { YYERROR; } } ; @@ -4915,6 +4918,7 @@ by_value_arg: scalar declaratives: %empty | DECLARATIVES '.'