https://gcc.gnu.org/g:daf8d7612dc022f2f124173be31226fc8791ea48

commit r17-4716-gdaf8d7612dc022f2f124173be31226fc8791ea48
Author: Xavier Del Campo Romero <[email protected]>
Date:   Thu Sep 24 17:21:16 2026 +0200

    cobol: Apply fixed/free format heuristics also for FUNCTION-ID
    
    Previously, the heuristics were limited to PROGRAM-ID, to the point that
    copybooks that only defined function prototypes, such as
    stored-char-length.cpy, could silently make the lexer switch to free
    format mode when copied via -include, thus potentially breaking
    fixed-form programs.
    
    gcc/cobol/ChangeLog:
    
            * lexio.cc (is_p): Rename function, support 'F'.
            (is_pf): Likewise.
            (is_program_id): Support FUNCTION-ID.
            (valid_sequence_area): Likewise.

Diff:
---
 gcc/cobol/lexio.cc | 30 +++++++++++++++++++-----------
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/gcc/cobol/lexio.cc b/gcc/cobol/lexio.cc
index e6e8ffcf6531..71bc21edefa3 100644
--- a/gcc/cobol/lexio.cc
+++ b/gcc/cobol/lexio.cc
@@ -445,20 +445,28 @@ struct buffer_t : public bytespan_t {
   }
 };
 
-static inline bool is_p( char ch ) { return TOUPPER(ch) == 'P'; }
+static inline bool is_pf( char ch ) { return TOUPPER(ch) == 'P' || TOUPPER(ch) 
== 'F'; }
 
 static bool
 is_program_id( const char *p, const char *eol ) {
-  static const std::string program_id("PROGRAM-ID");
-  auto eop = p + program_id.size();
-  if( eop < eol ) {
-    // PROGRAM-ID must be followed by a dot, perhaps with intervening 
whitespace.
-    for( const char *dot=eop; dot < eol && *dot != '.'; dot++ ) {
-      if( !ISSPACE(*dot) ) return false;
+  static const std::vector<std::string> ids { "PROGRAM-ID", "FUNCTION-ID" };
+  for( const auto& id : ids ) {
+    auto eop = p + id.size();
+    if( eop < eol ) {
+      bool valid = true;
+      // PROGRAM-ID must be followed by a dot, perhaps with intervening 
whitespace.
+      for( const char *dot=eop; dot < eol && *dot != '.'; dot++ ) {
+        if( !ISSPACE(*dot) ) {
+          valid = false;
+          break;
+        }
+      }
+      if (!valid)
+        continue;
+      std::string line (p, eop);
+      std::transform(line.begin(), line.end(), line.begin(), ::toupper);
+      return line == id;
     }
-    std::string line (p, eop);
-    std::transform(line.begin(), line.end(), line.begin(), ::toupper);
-    return line == program_id;
   }
   return false;
 }
@@ -1689,7 +1697,7 @@ static const char *
 valid_sequence_area( const char *data, const char *eodata ) {
 
   for( const char *p = data; // find every 'P' to try Program-ID
-       (p = std::find_if(p, eodata, is_p)) != eodata;
+       (p = std::find_if(p, eodata, is_pf)) != eodata;
        p++ )
   {
     auto eol = std::find(p, eodata, '\n');

Reply via email to