From 35e0b04072cdbf906b4f91e337a410d88a5b46c4 Mon Sep 17 00:00:00 2001
From: Bob Dubner <rdubner@symas.com>
Date: Thu, 23 Jan 2025 14:17:16 -0500
Subject: [PATCH] Tweaked ROUNDING into compliance with the standard

---
 .../UAT/testsuite.src/intrinsic_annuity.cob   |   4 +-
 gcc/cobol/UAT/testsuite.src/run_float.at      |  98 ++---
 gcc/cobol/UAT/testsuite.src/run_functions.at  |   2 +-
 gcc/cobol/UAT/testsuite.src/run_misc.at       |  10 +-
 libgcobol/libgcobol.cc                        | 403 ++++++++----------
 5 files changed, 234 insertions(+), 283 deletions(-)

diff --git a/gcc/cobol/UAT/testsuite.src/intrinsic_annuity.cob b/gcc/cobol/UAT/testsuite.src/intrinsic_annuity.cob
index fb66f5acf34e..ae07a22a2773 100644
--- a/gcc/cobol/UAT/testsuite.src/intrinsic_annuity.cob
+++ b/gcc/cobol/UAT/testsuite.src/intrinsic_annuity.cob
@@ -7,8 +7,8 @@
        77 trig-val-1 PIC S9v999999.
        PROCEDURE DIVISION.
            MOVE FUNCTION ANNUITY(0.07, 12) TO trig-val-1.
-           IF trig-val-1 NOT EQUAL +0.125902
+           IF trig-val-1 NOT EQUAL +0.125901
                    MOVE 1 TO RETURN-CODE
                    DISPLAY 'FUNCTION ANNUITY(0.07, 12) FAILS.'
-                   DISPLAY 'RETURNED ' trig-val-1 ', not 0.125902'
+                   DISPLAY 'RETURNED ' trig-val-1 ', not 0.125901'
                    END-IF.
diff --git a/gcc/cobol/UAT/testsuite.src/run_float.at b/gcc/cobol/UAT/testsuite.src/run_float.at
index e8d9bd971a50..a79a1a6d9d18 100644
--- a/gcc/cobol/UAT/testsuite.src/run_float.at
+++ b/gcc/cobol/UAT/testsuite.src/run_float.at
@@ -430,59 +430,59 @@ AT_DATA([prog.cob], [
         01 D7            FLOAT-EXTENDED VALUE 666.66.
         PROCEDURE DIVISION.
             SUBTRACT S1 FROM D1
-            SUBTRACT S2 FROM D2
-            SUBTRACT S3 FROM D3
-            SUBTRACT S4 FROM D4
-            SUBTRACT S5 FROM D5
-            SUBTRACT S6 FROM D6
-            SUBTRACT S7 FROM D7
-            PERFORM DISPLAY-D.
             SUBTRACT S1 FROM D2
-            SUBTRACT S2 FROM D3
-            SUBTRACT S3 FROM D4
-            SUBTRACT S4 FROM D5
-            SUBTRACT S5 FROM D6
-            SUBTRACT S6 FROM D7
-            SUBTRACT S7 FROM D1
-            PERFORM DISPLAY-D.
             SUBTRACT S1 FROM D3
-            SUBTRACT S2 FROM D4
-            SUBTRACT S3 FROM D5
-            SUBTRACT S4 FROM D6
-            SUBTRACT S5 FROM D7
-            SUBTRACT S6 FROM D1
-            SUBTRACT S7 FROM D2
-            PERFORM DISPLAY-D.
             SUBTRACT S1 FROM D4
-            SUBTRACT S2 FROM D5
-            SUBTRACT S3 FROM D6
-            SUBTRACT S4 FROM D7
-            SUBTRACT S5 FROM D1
-            SUBTRACT S6 FROM D2
-            SUBTRACT S7 FROM D3
-            PERFORM DISPLAY-D.
             SUBTRACT S1 FROM D5
-            SUBTRACT S2 FROM D6
-            SUBTRACT S3 FROM D7
-            SUBTRACT S4 FROM D1
-            SUBTRACT S5 FROM D2
-            SUBTRACT S6 FROM D3
-            SUBTRACT S7 FROM D4
-            PERFORM DISPLAY-D.
             SUBTRACT S1 FROM D6
-            SUBTRACT S2 FROM D7
-            SUBTRACT S3 FROM D1
-            SUBTRACT S4 FROM D2
-            SUBTRACT S5 FROM D3
-            SUBTRACT S6 FROM D4
-            SUBTRACT S7 FROM D5
-            PERFORM DISPLAY-D.
             SUBTRACT S1 FROM D7
+            PERFORM DISPLAY-D.
+            SUBTRACT S2 FROM D2
+            SUBTRACT S2 FROM D3
+            SUBTRACT S2 FROM D4
+            SUBTRACT S2 FROM D5
+            SUBTRACT S2 FROM D6
+            SUBTRACT S2 FROM D7
             SUBTRACT S2 FROM D1
+            PERFORM DISPLAY-D.
+            SUBTRACT S3 FROM D3
+            SUBTRACT S3 FROM D4
+            SUBTRACT S3 FROM D5
+            SUBTRACT S3 FROM D6
+            SUBTRACT S3 FROM D7
+            SUBTRACT S3 FROM D1
             SUBTRACT S3 FROM D2
+            PERFORM DISPLAY-D.
+            SUBTRACT S4 FROM D4
+            SUBTRACT S4 FROM D5
+            SUBTRACT S4 FROM D6
+            SUBTRACT S4 FROM D7
+            SUBTRACT S4 FROM D1
+            SUBTRACT S4 FROM D2
             SUBTRACT S4 FROM D3
+            PERFORM DISPLAY-D.
+            SUBTRACT S5 FROM D5
+            SUBTRACT S5 FROM D6
+            SUBTRACT S5 FROM D7
+            SUBTRACT S5 FROM D1
+            SUBTRACT S5 FROM D2
+            SUBTRACT S5 FROM D3
             SUBTRACT S5 FROM D4
+            PERFORM DISPLAY-D.
+            SUBTRACT S6 FROM D6
+            SUBTRACT S6 FROM D7
+            SUBTRACT S6 FROM D1
+            SUBTRACT S6 FROM D2
+            SUBTRACT S6 FROM D3
+            SUBTRACT S6 FROM D4
             SUBTRACT S6 FROM D5
+            PERFORM DISPLAY-D.
+            SUBTRACT S7 FROM D7
+            SUBTRACT S7 FROM D1
+            SUBTRACT S7 FROM D2
+            SUBTRACT S7 FROM D3
+            SUBTRACT S7 FROM D4
+            SUBTRACT S7 FROM D5
             SUBTRACT S7 FROM D6
             PERFORM DISPLAY-D.
             GOBACK.
@@ -498,14 +498,14 @@ AT_DATA([prog.cob], [
         END PROGRAM float-sub1.
 ])
 AT_CHECK([$COMPILE prog.cob], [0], [], [])
-AT_CHECK([$COBCRUN_DIRECT ./a.out], [0],
+AT_CHECK([$COBCRUN_DIRECT ./a.out], [0], 
 [555.55 555.55 555.55 555.55 555.5499878 555.549999999999955 555.5499999999999999999999999999999606
-555.55 555.55 555.55 555.55 555.5499878 555.549999389648406 555.5500000000000005684341886080801211
-555.55 555.55 555.55 555.55 555.5499878 555.549999999999955 555.5499993896484374999999999999999724
-555.54 555.55 555.55 555.55 555.5499878 555.549999999999955 555.5499999999999999999999999999999606
-555.55 555.54 555.55 555.55 555.5499878 555.549999999999955 555.5499999999999999999999999999999606
-555.55 555.55 555.54 555.55 555.5499878 555.549999999999955 555.5499999999999999999999999999999606
-555.55 555.55 555.55 555.54 555.5499878 555.549999999999955 555.5499999999999999999999999999999606
+555.55 555.55 555.55 555.55 555.5499878 555.549999999999955 555.5499999999999999999999999999999606
+555.55 555.55 555.55 555.55 555.5499878 555.549999999999955 555.5499999999999999999999999999999606
+555.55 555.55 555.55 555.55 555.5499878 555.549999999999955 555.5499999999999999999999999999999606
+555.54 555.54 555.54 555.54 555.5499878 555.549999389648406 555.5499993896484374999999999999999724
+555.55 555.55 555.55 555.55 555.5499878 555.549999999999955 555.5500000000000005684341886080801211
+555.54 555.54 555.54 555.54 555.5499878 555.549999999999955 555.5499999999999999999999999999999606
 ])
 AT_CLEANUP
 
diff --git a/gcc/cobol/UAT/testsuite.src/run_functions.at b/gcc/cobol/UAT/testsuite.src/run_functions.at
index 95ec5ceb6bce..bc04f0e2d0a2 100644
--- a/gcc/cobol/UAT/testsuite.src/run_functions.at
+++ b/gcc/cobol/UAT/testsuite.src/run_functions.at
@@ -73,7 +73,7 @@ AT_DATA([prog.cob], [
        01  Z   PIC   S9V9(33).
        PROCEDURE        DIVISION.
            MOVE FUNCTION ANNUITY ( 3, 5 ) TO Z.
-           IF Z NOT = 3.002932551319648093841642228739002
+           IF Z NOT = 3.002932551319648093841642228739003
               DISPLAY Z
               END-DISPLAY
            END-IF.
diff --git a/gcc/cobol/UAT/testsuite.src/run_misc.at b/gcc/cobol/UAT/testsuite.src/run_misc.at
index 20b47ff0bdea..5831caaccea2 100644
--- a/gcc/cobol/UAT/testsuite.src/run_misc.at
+++ b/gcc/cobol/UAT/testsuite.src/run_misc.at
@@ -3099,6 +3099,12 @@ AT_DATA([prog.cob], [
            DISPLAY 'RES 1 = ' RES.
            COMPUTE RES = RES / DIV2.
            DISPLAY 'RES F = ' RES.
+           COMPUTE RES  =
+                VAL / DIV1 / DIV2.
+           DISPLAY 'RES NOT ROUNDED = ' RES.
+           COMPUTE RES ROUNDED MODE NEAREST-AWAY-FROM-ZERO =
+                VAL / DIV1 / DIV2.
+           DISPLAY 'RES ROUNDED NEAREST-AWAY = ' RES.
            COMPUTE RES ROUNDED MODE AWAY-FROM-ZERO =
                 VAL / DIV1 / DIV2.
            DISPLAY 'RES ROUNDED AWAY = ' RES.
@@ -3112,7 +3118,9 @@ RES MULT1 = +0000680.95
 RES MULT2 = +0000680.95
 RES 1 = +0022777.77
 RES F = +0000680.94
-RES ROUNDED AWAY = +0000680.95
+RES NOT ROUNDED = +0000680.95
+RES ROUNDED NEAREST-AWAY = +0000680.95
+RES ROUNDED AWAY = +0000680.96
 ], [])
 AT_CLEANUP
 
diff --git a/libgcobol/libgcobol.cc b/libgcobol/libgcobol.cc
index 42dccaf51d76..ef6cf5fc7dd1 100644
--- a/libgcobol/libgcobol.cc
+++ b/libgcobol/libgcobol.cc
@@ -96,7 +96,7 @@ int         __gg__odo_violation               = 0    ;
 int         __gg__nop                         = 0    ;
 int         __gg__main_called                 = 0    ;
 
-// What follows are arrays that are used by features like INSPECT, STRING, 
+// What follows are arrays that are used by features like INSPECT, STRING,
 // UNSTRING, and, particularly, arithmetic_operation.  These features are
 // characterized by having unknown, and essentially unlimited, numbers of
 // variables. Consider, for example, ADD A B C D ... TO L M N O ...
@@ -109,10 +109,10 @@ int         __gg__main_called                 = 0    ;
 //
 // The current solution is to make the pointers to the arrays of values global,
 // and initialize them with space for MIN_FIELD_BLOCK_SIZE values.  Thus, at
-// compile time, we can ignore all tests for fewer than MIN_FIELD_BLOCK_SIZE 
+// compile time, we can ignore all tests for fewer than MIN_FIELD_BLOCK_SIZE
 // (which is generally the case).  Only when N is greater than the MIN do we
 // have to check the current run-time size and, if necessary, expand the buffer
-// with realloc. 
+// with realloc.
 size_t       __gg__arithmetic_rounds_size      = 0     ;
 int *        __gg__arithmetic_rounds           = NULL  ;
 
@@ -123,17 +123,17 @@ static size_t         treeplet_1_size          = 0     ;
 cblc_field_t ** __gg__treeplet_1f              = NULL  ;
 size_t       *  __gg__treeplet_1o              = NULL  ;
 size_t       *  __gg__treeplet_1s              = NULL  ;
-                                           
+
 static size_t         treeplet_2_size          = 0     ;
 cblc_field_t ** __gg__treeplet_2f              = NULL  ;
 size_t       *  __gg__treeplet_2o              = NULL  ;
 size_t       *  __gg__treeplet_2s              = NULL  ;
-                                           
+
 static size_t         treeplet_3_size          = 0     ;
 cblc_field_t ** __gg__treeplet_3f              = NULL  ;
 size_t       *  __gg__treeplet_3o              = NULL  ;
 size_t       *  __gg__treeplet_3s              = NULL  ;
-                                           
+
 static size_t         treeplet_4_size          = 0     ;
 cblc_field_t ** __gg__treeplet_4f              = NULL  ;
 size_t       *  __gg__treeplet_4o              = NULL  ;
@@ -475,7 +475,7 @@ cstrncmp(   char const * const left_,
   const char *left  = left_;
   const char *right = right_;
   // This is the version of strncmp() that uses the current collation
-  
+
   // It also is designed to handle strings with embedded NUL characters, so
   // it treats NULs like any other characters.
   int retval = 0;
@@ -588,7 +588,7 @@ __gg__scale_by_power_of_ten_1(__int128 value, int N)
   // have non-zero rdigits.  __gg__rdigits is set to 1 when the result is
   // in the bad zone.  The ultimate caller needs to examine __gg__rdigits to
   // decide what to do about it.
-  
+
   // This is a separate routine because of the performance hit caused by the
   // value % pot operation, which is needed only when certain EC checking is
   // turned on.
@@ -718,7 +718,7 @@ value_is_too_big(   cblc_field_t *var,
       // var->digits is zero.  We are dealing with a binary-style number that
       // fills the whole of the value
       assert(    var->type == FldNumericBin5
-              || var->type == FldPointer 
+              || var->type == FldPointer
               || var->type == FldIndex);
       if( var->capacity < 16 )
         {
@@ -835,59 +835,26 @@ __gg__string_to_alpha_edited_ascii( char *dest,
   free(dupe);
   }
 
-static bool
-is_exactly_500( __int128  value,
-                int       rdigits,
-                cbl_round_t rounded )
+static __int128
+int128_to_int128_rounded( cbl_round_t rounded,
+                          __int128    value,
+                          __int128    factor,
+                          __int128    remainder,
+                          int        *compute_error)
   {
-  // We need to know if the value's fractional part is exactly 0.50000
-  bool retval = false;
+  // value is signed, and is scaled to the target
+  _Float128 fpart = _Float128(remainder) / _Float128(factor);
+  __int128 retval = value;
 
-  switch( rounded )
+  if(rounded == nearest_even_e && fpart != -0.5Q && fpart != 0.5Q )
     {
-    case nearest_toward_zero_e:
-    case nearest_even_e:
-      if(value < 0)
-        {
-        value = -value;
-        }
-      retval  = true;
-      // The rightmost rdigits-1 have to be zero:
-      for(int i=0; i<rdigits-1; i++)
-        {
-        if( value % 10 )
-          {
-          retval = false;
-          break;
-          }
-        value /= 10;
-        }
-
-      // The first digit to the right of the decimal point has to be five:
-      if( retval && (value % 10) != 5 )
-        {
-        retval = false;
-        }
-
-    default:
-      break;
+    // "bankers rounding" has been requested.
+    //
+    // Since the fraction is not 0.5, this is an ordinary rounding
+    // problem
+    rounded =  nearest_away_from_zero_e;
     }
 
-
-  return retval;
-  }
-
-
-extern "C"
-__int128
-__XX__round_int128( cbl_round_t rounded,
-                    __int128  value,
-                    bool      exactly_500,
-                    int      *compute_error)
-  {
-  // value is signed, and is scaled to the target but with an additional factor
-  // of ten.
-  // We assume our caller does the final /= 10;
   switch(rounded)
     {
     case truncation_e:
@@ -896,94 +863,86 @@ __XX__round_int128( cbl_round_t rounded,
     case nearest_away_from_zero_e:
       {
       // This is ordinary rounding, like you learned in grade school
-      // 0 through 4 becomes 00
-      // 5 through 9 becomes 10
+      // 0.0 through 0.4 becomes 0
+      // 0.5 through 0.9 becomes 1
       if( value < 0 )
         {
-        value -= 5;
+        if( fpart <= -0.5Q )
+          {
+          retval -= 1;
+          }
         }
       else
         {
-        value += 5;
+        if( fpart >= 0.5Q )
+          {
+          retval += 1;
+          }
         }
       break;
       }
 
-    case nearest_toward_zero_e:
+    case away_from_zero_e:
       {
-      // 0 through 5 becomes 00
-      // 6 through 9 becomes 10
+      // zero stays zero, otherwise head for the next number away from zero
       if( value < 0 )
         {
-        if( exactly_500 )
-          {
-          value += 5;
-          }
-        else
+        if( fpart != 0 )
           {
-          value -= 5;
+          retval -= 1;
           }
         }
       else
         {
-        if( exactly_500 )
-          {
-          value -= 5;
-          }
-        else
+        if( fpart != 0 )
           {
-          value += 5;
+          retval += 1;
           }
         }
       break;
       }
 
-    case toward_greater_e:
+    case nearest_toward_zero_e:
       {
-      // 0 stays 00
-      // 1 through 9 becomes 10
-      // -1 through -9 becomes 10
+      // 0.0 through 0.5 becomes 0
+      // 0.6 through 0.9 becomes 1
       if( value < 0 )
         {
-        value /= 10;
-        value *= 10;
+        if( fpart < -0.5Q )
+          {
+          retval -= 1;
+          }
         }
       else
         {
-        value += 9;
+        if( fpart > 0.5Q )
+          {
+          retval += 1;
+          }
         }
       break;
       }
 
-    case toward_lesser_e:
+    case toward_greater_e:
       {
-      // 0 stays 00
-      // 1 through 9 becomes 10
-      // -1 through -9 becomes 10
-      if( value < 0 )
-        {
-        value -= 9;
-        }
-      else
+      if( value > 0 )
         {
-        value /= 10;
-        value *= 10;
+        if( fpart != 0 )
+          {
+          retval += 1;
+          }
         }
       break;
       }
 
-    case away_from_zero_e:
+    case toward_lesser_e:
       {
-      // This is ordinary rounding:
-      // 0 stays zero
-      // 1 through 9 becomes 1
       if( value < 0 )
         {
-        value -= 9;
-        }
-      else
-        {
-        value += 9;
+        if(fpart != 0)
+          {
+          retval -= 1;
+          }
         }
       break;
       }
@@ -991,57 +950,37 @@ __XX__round_int128( cbl_round_t rounded,
     case nearest_even_e:
       {
       // This is "banker's rounding"
-      // 34 -> 30
-      // 35 -> 40
-      // 36 -> 40
+      // 3.4 -> 3.0
+      // 3.5 -> 4.0
+      // 3.6 -> 4.0
 
-      // 44 -> 40
-      // 45 -> 40
-      // 46 -> 50
+      // 4.4 -> 4.0
+      // 4.5 -> 4.0
+      // 4.6 -> 5.0
 
-      bool is_negative = false;
-      if(value < 0)
-        {
-        value = -value;
-        is_negative = true;
-        }
-      int d0 = value % 10;
-      if( d0 != 5 || !exactly_500 )
-        {
-        // We aren't at 0.5, so we do ordinary rounding
-        value += 5;
-        }
-      else
+     // We know that the fractional part is 0.5 or -0.5, and we know that
+     // we want 3 to become 4 and for 4 to stay 4.
+
+    if( value < 0 )
+      {
+      if( retval & 1 )
         {
-        // We know we are at the exact 0.5000 midpoint:
-        // 05 becomes  05 add 00
-        // 15 becomes  25 add 10
-        // 25 becomes  25 add 00
-        // 35 becomes  45 add 10
-        // 45 becomes  45 add 00
-        // 55 becomes  65 add 10
-        // 65 becomes  65 add 00
-        // 75 becomes  85 add 10
-        // 85 becomes  85 add 00
-        // 95 becomes 105 add 10
-        d0  = value %100;
-        d0 /= 10; // d0 is now zero through 9
-        if( d0 & 0x01 )
-          {
-          value += 10;
-          }
+        retval -= 1;
         }
-      if( is_negative )
+      }
+    else
+      {
+      if( retval & 1 )
         {
-        value = -value;
+        retval += 1;
         }
+      }
       break;
       }
 
     case prohibited_e:
       {
-      int d0 = value % 10;
-      if( d0 != 0 )
+      if( fpart != 0 )
         {
         *compute_error |= compute_error_truncate;
         }
@@ -1053,7 +992,7 @@ __XX__round_int128( cbl_round_t rounded,
       abort();
       break;
     }
-  return value;
+  return retval;
   }
 
 static __int128
@@ -1070,7 +1009,7 @@ f128_to_i128_rounded( cbl_round_t rounded,
     {
     // "bankers rounding" has been requested.
     //
-    // Since the fraction is not 0.5, this is an ordinary rounding 
+    // Since the fraction is not 0.5, this is an ordinary rounding
     // problem
     rounded =  nearest_away_from_zero_e;
     }
@@ -1180,7 +1119,7 @@ f128_to_i128_rounded( cbl_round_t rounded,
 
      // We know that the fractional part is 0.5 or -0.5, and we know that
      // we want 3 to become 4 and for 4 to stay 4.
-     
+
     if( value < 0 )
       {
       if( retval & 1 )
@@ -1259,23 +1198,23 @@ int128_to_field(cblc_field_t   *var,
           // handle at most 36 digits.  I decided to implement fixed-point
           // values to 38 places (which is what an __int128 can hold), and as a
           // result, at this point in the code we can be asking the compiler to
-          // turn a 38-digit __int128 into a _Float128.  
-          
+          // turn a 38-digit __int128 into a _Float128.
+
           // This caused a problem that I noticed in COMPUTE var = (2/3)*3.
-          
+
           // The default is truncation, and so the PIC 9V9999 result should be
-          // 1.9999.  
-          
+          // 1.9999.
+
           // At this point in the code, the 128-bit value was the
           // 38-digit 19999999999999999999999999999999999998
 
           // So, I then converted that to a _Float128, and the conversion
           // routine properly did the best it could and returned exactly
           // 2E37
-          
-          // The problem: This rounded the number up from 1.9999...., and so 
+
+          // The problem: This rounded the number up from 1.9999...., and so
           // the truncation resulted in 2.0000 when we wanted 1.9999
-          
+
           // The solution:  Throw away digits on the right to make sure there
           // are no more than 33 significant digits.
 
@@ -1312,10 +1251,6 @@ int128_to_field(cblc_field_t   *var,
 
     default:
       {
-      // For some rounding modes, we need to know if the value to the right
-      // of the decimal point is exactly .500000
-      bool exactly_500 = is_exactly_500(value, source_rdigits, rounded);
-
       bool size_error = false;
 
       int target_rdigits = var->rdigits;
@@ -1370,22 +1305,30 @@ int128_to_field(cblc_field_t   *var,
       // Convert the scale of value to match the scale of var
       if( source_rdigits < target_rdigits )
         {
-        // Multiply value by ten until the source_rdigits match
+        // The source (value), has fewer rdigits than the target (var)
+
+        // Multiply value by ten until the source_rdigits matches the
+        // target_rdigits.  No rounding will be necessary
         value *= __gg__power_of_ten(target_rdigits - source_rdigits);
         source_rdigits = target_rdigits;
         }
 
       if( source_rdigits > target_rdigits )
         {
-        // We're going to divide value by 10 until we are within
-        // one rdigit:
-        value /= __gg__power_of_ten(source_rdigits - (target_rdigits+1));
-        source_rdigits = (target_rdigits+1);
-        // value now has one extra digit to the right:
+        // The source(value) has more rdigits than the target (var)
 
-        value = __XX__round_int128(rounded, value, exactly_500, compute_error);
+        // Extract those extra digits; we'll need them for rounding:
+        __int128 factor = __gg__power_of_ten(source_rdigits - target_rdigits);
+
+        __int128 remainder = value % factor;
+        value /= factor;
+        source_rdigits = target_rdigits;
 
-        value /= 10;
+        value = int128_to_int128_rounded( rounded,
+                                          value,
+                                          factor,
+                                          remainder,
+                                          compute_error);
         }
 
       // The documentation for ROUNDED MODE PHOHIBITED says that if the value
@@ -1575,7 +1518,7 @@ int128_to_field(cblc_field_t   *var,
             if( var->attr & separate_e )
               {
               // This is a comp-6 / packed-decimal NO SIGN variable
-              
+
               // Because comp-76 can only be positive, make negative numbers
               // positive:
               if( value<0 )
@@ -1669,7 +1612,7 @@ int128_to_field(cblc_field_t   *var,
                 }
 
               // We are going to lay our nybbles into the destination starting
-              // at sign nybble, and then working our way up through the nach 
+              // at sign nybble, and then working our way up through the nach
               // digits:
 
               // Place the sign nybble:
@@ -2878,7 +2821,7 @@ format_for_display_internal(char **dest,
 
     case FldNumericDisplay:
       {
-      // We are going to make use of fact that a NumericDisplay's data is 
+      // We are going to make use of fact that a NumericDisplay's data is
       // almost already in the format we need.  We have to add a decimal point,
       // if necessary, in the right place, and we need to tack on leading or
       // trailing zeroes for PPP999 and 999PPP scaled-e variables.
@@ -2896,8 +2839,8 @@ format_for_display_internal(char **dest,
       // We need the counts of digits to the left and right of the decimal point
       int rdigits = get_scaled_rdigits(var);
       int ldigits = var->digits - rdigits;
-      
-      // Calculate the minimum allocated size we need, keeping in mind that 
+
+      // Calculate the minimum allocated size we need, keeping in mind that
       // ldigits can be negative when working with a PPP999 number
       int nsize   = std::max(ldigits,0) + rdigits+1;
       if( ldigits < 0 )
@@ -3128,7 +3071,7 @@ format_for_display_internal(char **dest,
 
     case FldIndex:
       {
-      // The display of a FldIndex doesn't need to provide clues about its 
+      // The display of a FldIndex doesn't need to provide clues about its
       // length, so don't bother with leading zeroes.
       int dummy;
       __int128 value = get_binary_value_local(&dummy,
@@ -3611,7 +3554,7 @@ compare_field_class(cblc_field_t  *conditional,
         left_len = strtoull(walker, &pend, 10);
         left_flag = *pend;
         left = pend+1;
-        
+
         right = left + left_len;
         right_len = strtoull(right, &pend, 10);
         right_flag = *pend;
@@ -3698,7 +3641,7 @@ compare_field_class(cblc_field_t  *conditional,
         fig1 = *pend == 'F';
         first = pend+1;
         first_e = first + first_len;
-        
+
         last = first_e;
 
         last_len = strtoull(last, &pend, 10);
@@ -3758,7 +3701,7 @@ compare_field_class(cblc_field_t  *conditional,
         left_len = strtoull(walker, &pend, 10);
         left_flag = *pend;
         left = pend+1;
-        
+
         right = left + left_len;
         right_len = strtoull(right, &pend, 10);
         right_flag = *pend;
@@ -6693,12 +6636,12 @@ the_alpha_and_omega(const normalized_operand &id_before,
   {
   /*  The 2023 ISO description of the AFTER and BEFORE phrases of the INSPECT
       statement is, in a word, garbled.
-      
+
       IBM's COBOL for Linux 1.2 is a little better, but still a bit confusing
       because the description for AFTER neglects to specifically state that
       the scan starts one character to the right of the *first* occurrence of
       the AFTER value.
-      
+
       Micro Focus 9.2.5 has the advantage of being ungarbled, succinct, and
       unambiguous.
 
@@ -6744,7 +6687,7 @@ the_alpha_and_omega(const normalized_operand &id_before,
     {
     // This is the AFTER delimiter.  We look for the first occurrence of that
     // delimiter in id_1
-      
+
     const char *start = id_after.the_characters.c_str();
     const char *end   = start + id_after.length;
     const char *found = funky_find(start, end, alpha, omega);
@@ -6771,7 +6714,7 @@ the_alpha_and_omega_backward( const normalized_operand &id_before,
                               const char *          &omega)
   {
   /*  Not unlike the_alpha_and_omega(), but for handling BACKWARD.
-  
+
       "xyzxyzBEFORExyzxyzAFTERxyzxyzxyzxyzBEFORExyzxyzAFTERxyzxyz"
                                                 ^     ^
                                                 |     |
@@ -6802,14 +6745,14 @@ the_alpha_and_omega_backward( const normalized_operand &id_before,
   if( id_after.length )
     {
     // This is the AFTER delimiter.  We look for the first occurrence in id_1
-      
+
     const char *start = id_after.the_characters.c_str();
     const char *end   = start + id_after.length;
     const char *found = funky_find_backward(start, end, alpha, omega);
     if( found )
       {
       // We found id_after in id_1.  We update omega to be
-      // at that location.  
+      // at that location.
       omega = found;
       }
     else
@@ -7049,10 +6992,10 @@ inspect_backward_format_1(size_t integers[])
 
             if( comparands[k].leading )
               {
-              if( rightmost + comparands[k].identifier_3.length 
+              if( rightmost + comparands[k].identifier_3.length
                                                         == comparands[k].omega)
                 {
-                // This means that the match here is just the latest of a 
+                // This means that the match here is just the latest of a
                 // string of LEADING matches that started at .omega
                 comparands[k].leading_count += 1;
                 match = true;
@@ -7068,13 +7011,13 @@ inspect_backward_format_1(size_t integers[])
             // We want to know if this is a trailing match.  For that to be,
             // all of the possible matches from here leftward to the alpha have
             // to be true as well:
-            
+
             if( (rightmost - comparands[k].alpha )
                     % comparands[k].identifier_3.length == 0 )
               {
               // The remaining number of characters is correct for a match.
               // Keep checking.
-              
+
               // Assume a match until we learn otherwise:
               match = true;
               const char *local_left = rightmost;
@@ -7376,7 +7319,7 @@ __gg__inspect_format_1(int backward, size_t integers[])
             {
             // We have a match at leftmost.  But we need to figure out if this
             // particular match is valid for LEADING.
-            
+
             // Hang onto your hat.  This is delightfully clever.
             //
             // This position is LEADING if:
@@ -7387,11 +7330,11 @@ __gg__inspect_format_1(int backward, size_t integers[])
             if( comparands[k].leading )
               {
               // So far, so good.
-              size_t count = (leftmost - comparands[k].alpha) 
+              size_t count = (leftmost - comparands[k].alpha)
                               / comparands[k].identifier_3.length;
               if( count == comparands[k].leading_count )
                 {
-                // This means that the match here is just the latest of a 
+                // This means that the match here is just the latest of a
                 // string of LEADING matches that started at .alpha
                 comparands[k].leading_count += 1;
                 match = true;
@@ -7407,13 +7350,13 @@ __gg__inspect_format_1(int backward, size_t integers[])
             // We want to know if this is a trailing match.  For that to be,
             // all of the possible matches from here to the omega have to be
             // true as well:
-            
+
             if( (comparands[k].omega-leftmost)
                     % comparands[k].identifier_3.length == 0 )
               {
               // The remaining number of characters is correct for a match.
               // Keep checking.
-              
+
               // Assume a match until we learn otherwise:
               match = true;
               const char *local_left = leftmost;
@@ -7726,12 +7669,12 @@ inspect_backward_format_2(size_t integers[])
 
             if( comparands[k].leading )
               {
-              if(   rightmost 
-                  + comparands[k].identifier_3.length 
+              if(   rightmost
+                  + comparands[k].identifier_3.length
                   + comparands[k].leading_count
                     == comparands[k].omega)
                 {
-                // This means that the match here is just the latest of a 
+                // This means that the match here is just the latest of a
                 // string of LEADING matches that started at .omega
                 comparands[k].leading_count += 1;
                 match = true;
@@ -7747,13 +7690,13 @@ inspect_backward_format_2(size_t integers[])
             // We want to know if this is a trailing match.  For that to be,
             // all of the possible matches from here leftward to the alpha have
             // to be true as well:
-            
+
             if( (rightmost - comparands[k].alpha )
                     % comparands[k].identifier_3.length == 0 )
               {
               // The remaining number of characters is correct for a match.
               // Keep checking.
-              
+
               // Assume a match until we learn otherwise:
               match = true;
               const char *local_left = rightmost;
@@ -8069,7 +8012,7 @@ __gg__inspect_format_2(int backward, size_t integers[])
             {
             // We have a match at leftmost.  But we need to figure out if this
             // particular match is valid for LEADING.
-            
+
             // Hang onto your hat.  This is delightfully clever.
             //
             // This position is LEADING if:
@@ -8080,11 +8023,11 @@ __gg__inspect_format_2(int backward, size_t integers[])
             if( comparands[k].leading )
               {
               // So far, so good.
-              size_t count = (leftmost - comparands[k].alpha) 
+              size_t count = (leftmost - comparands[k].alpha)
                               / comparands[k].identifier_3.length;
               if( count == comparands[k].leading_count )
                 {
-                // This means that the match here is just the latest of a 
+                // This means that the match here is just the latest of a
                 // string of LEADING matches that started at .alpha
                 comparands[k].leading_count += 1;
                 match = true;
@@ -8100,13 +8043,13 @@ __gg__inspect_format_2(int backward, size_t integers[])
             // We want to know if this is a trailing match.  For that to be,
             // all of the possible matches from here to the omega have to be
             // true as well:
-            
+
             if( (comparands[k].omega-leftmost)
                     % comparands[k].identifier_3.length == 0 )
               {
               // The remaining number of characters is correct for a match.
               // Keep checking.
-              
+
               // Assume a match until we learn otherwise:
               match = true;
               const char *local_left = leftmost;
@@ -8328,7 +8271,7 @@ __gg__inspect_format_4( int backward,
       size_t nfound = std::string(psz_input).rfind(psz_before);
       if( nfound == std::string::npos )
         {
-        // The BEFORE string isn't in the input, so we will scan from 
+        // The BEFORE string isn't in the input, so we will scan from
         // the leftmost character
         pstart = psz_input;
         }
@@ -8346,7 +8289,7 @@ __gg__inspect_format_4( int backward,
       {
       pstart = psz_input;
       }
- 
+
     if( strlen(psz_after) )
       {
       size_t nfound = std::string(psz_input).rfind(psz_after);
@@ -8372,7 +8315,7 @@ __gg__inspect_format_4( int backward,
       pstart = psz_input;
       }
     pstart += strlen(psz_after);
-    
+
     if( strlen(psz_before) )
       {
       pend = strstr(psz_input, psz_before);
@@ -8538,7 +8481,7 @@ __gg__string(size_t integers[])
   cblc_field_t **ref   = __gg__treeplet_1f;
   size_t        *ref_o = __gg__treeplet_1o;
   size_t        *ref_s = __gg__treeplet_1s;
-  
+
   static const int INDEX_OF_POINTER = 1;
 
   size_t index_int  = 0;
@@ -11056,7 +10999,7 @@ default_exception_handler( ec_type_t ec)
       err(EXIT_FAILURE,
           "logic error: %s:%zu: %s unknown exception %x",
            ec_status.source_file,
-           ec_status.lineno, 
+           ec_status.lineno,
            ec_status.statement,
            ec );
     }
@@ -11192,7 +11135,7 @@ __gg__match_exception( cblc_field_t *index,
   // been set to a non-zero value.  Having picked up that value it is our job
   // to immediately set it back to zero:
   __gg__exception_file_number = 0;
-  
+
   int  handled = __gg__exception_handled;
   cblc_file_t *stashed = __gg__file_stashed();
 
@@ -11201,7 +11144,7 @@ __gg__match_exception( cblc_field_t *index,
   auto eodcls  = dcls + 1 + ndcl, p = eodcls;
 
   auto ec = ec_status.update().unhandled();
-  
+
   // We need to set exception handled back to 0.  We do it here because
   // ec_status.update() looks at it
   __gg__exception_handled = 0;
@@ -11587,7 +11530,7 @@ __gg__float32_from_int128(cblc_field_t *destination,
 
   if( fabsf128(value) > 3.4028235E38Q )
     {
-    if(size_error) 
+    if(size_error)
       {
       *size_error = 1;
       }
@@ -12147,7 +12090,7 @@ __gg__variables_to_init(cblc_field_t *array[], const char *clear)
   }
 
 extern "C"
-void 
+void
 __gg__mirror_range( size_t         nrows,
                     cblc_field_t  *src,     // The row
                     size_t         src_o,
@@ -12175,7 +12118,7 @@ __gg__mirror_range( size_t         nrows,
 
   // We need to know the width of one row of this table, which is different
   // depending on type of src:
-  
+
   cblc_field_t *parent = src;
   while( parent )
     {
@@ -12247,7 +12190,7 @@ __gg__mirror_range( size_t         nrows,
           {
           size_t subtable_offset = tbls[2*subtable  ];
           size_t subtable_index  = tbls[2*subtable+1];
-          
+
           assert( widths_of_table.find(subtable_index) != widths_of_table.end());
           size_t subtable_width = widths_of_table[subtable_index];
           size_t subtable_rows   = rows_in_table  [subtable_index];
@@ -12281,9 +12224,9 @@ __gg__mirror_range( size_t         nrows,
         {
         size_t subtable_offset = tbls[2*subtable  ];
         size_t subtable_index  = tbls[2*subtable+1];
-        
+
         assert( widths_of_table.find(subtable_index) != widths_of_table.end());
-        
+
         size_t subtable_stride = widths_of_table[subtable_index];
         size_t subtable_rows   = rows_in_table  [subtable_index];
         std::vector<size_t> subtable_spans
@@ -12344,14 +12287,14 @@ __gg__sleep(cblc_field_t *field, size_t offset, size_t size)
 
   // Convert the time to nanoseconds.
   delay = delay * 1000000000;
-  
+
   // Convert the result to seconds/nanoseconds for nanosleep()
   size_t tdelay = (size_t)delay;
   timespec duration;
 
   duration.tv_sec  = tdelay / 1000000000;
   duration.tv_nsec = tdelay % 1000000000;
-  
+
   nanosleep(&duration, NULL);
   }
 
@@ -12423,7 +12366,7 @@ get_the_byte(cblc_field_t *field)
   }
 
 extern "C"
-void 
+void
 __gg__allocate( cblc_field_t *first,
                 size_t        first_offset,
                 int           initialized,
@@ -12437,7 +12380,7 @@ __gg__allocate( cblc_field_t *first,
   int local_byte   = get_the_byte(f_local_byte);
 
   unsigned char *retval = NULL;
-  if( first->attr & based_e ) 
+  if( first->attr & based_e )
     {
     // first is the BASED variable we are allocating memory for
     if( first->capacity )
@@ -12469,7 +12412,7 @@ __gg__allocate( cblc_field_t *first,
             fill_char = local_byte;
             }
           }
-        else 
+        else
           {
           if( working_byte >= 0 )
             {
@@ -12496,7 +12439,7 @@ __gg__allocate( cblc_field_t *first,
     // If there are any non-zero digits to the right of the decimal point,
     // increment the units place:
     tsize += (pof10-1);
-    
+
     // Adjust the result to be an integer.
     tsize /= pof10;
     if( tsize )
@@ -12526,7 +12469,7 @@ __gg__allocate( cblc_field_t *first,
             fill_char = local_byte;
             }
           }
-        else 
+        else
           {
           if( working_byte >= 0 )
             {
@@ -12542,7 +12485,7 @@ __gg__allocate( cblc_field_t *first,
   if( returning )
     {
     // 'returning' has to be a FldPointer variable; assign the retval to it.
-    *(unsigned char **)(returning->data + returning_offset) = retval; 
+    *(unsigned char **)(returning->data + returning_offset) = retval;
     }
   }
 
@@ -12562,7 +12505,7 @@ __gg__module_name_pop()
   assert( module_name_stack.size() );
   module_name_stack.pop_back();
   }
-  
+
 extern "C"
 void
 __gg__module_name(cblc_field_t *dest, module_type_t type)
@@ -12594,13 +12537,13 @@ __gg__module_name(cblc_field_t *dest, module_type_t type)
       {
       case 'T':
         // We are in a top-level program, not nested:
-        if(    module_name_stack.size() == 1 
-            || (module_name_stack.size() == 2 
+        if(    module_name_stack.size() == 1
+            || (module_name_stack.size() == 2
                && module_name_stack.front()[0] == 'M' ) )
           {
           // This is a "main program", so we return a single space.
           strcpy(result, " ");
-          } 
+          }
         else
           {
           // This is a called program, so we return the name of the "runtime
@@ -12623,7 +12566,7 @@ __gg__module_name(cblc_field_t *dest, module_type_t type)
       // 7) If the CURRENT keyword is specified then the returned value is the
       // name of the runtime element of the outermost program of the compilation
       // unit’s code that is currently running.
-      
+
       // Look upward for our parent T.
       // Termination is weird because size_t is unsigned
       for(size_t i=ssize-1; i<ssize; i--)
@@ -12640,10 +12583,10 @@ __gg__module_name(cblc_field_t *dest, module_type_t type)
       // 8) If the NESTED keyword is specified, then the returned value is the
       // name, as specified in the PROGRAM-ID, of the currently running, most
       // recently nested program.
-      
+
       // This specification seems weird to me.  What if the currently running
       // program isn't nested?
-      
+
       // So, we'll just return us
       strcpy(result, module_name_stack[ssize-1].substr(1).c_str());
       break;
@@ -12651,7 +12594,7 @@ __gg__module_name(cblc_field_t *dest, module_type_t type)
     case module_stack_e:
       for(size_t i=ssize-1; i<ssize; i--)
         {
-        if(    module_name_stack[i][0] == 'T' 
+        if(    module_name_stack[i][0] == 'T'
             || module_name_stack[i][0] == 'N' )
           {
           if( strlen(result) + module_name_stack[i].substr(1).length() + 4 > result_size)
@@ -12682,4 +12625,4 @@ __gg__module_name(cblc_field_t *dest, module_type_t type)
 __gg__adjust_dest_size(dest, strlen(result));
   memcpy(dest->data, result, strlen(result)+1);
   }
-  
+
-- 
GitLab