===================================================================
@@ -677,7 +677,13 @@ read_decimal (st_parameter_dt *dtp, const fnode *f
if (c == ' ')
{
- if (dtp->u.p.blank_status == BLANK_NULL) continue;
+ if (dtp->u.p.blank_status == BLANK_NULL)
+ {
+ /* Skip spaces. */
+ for ( ; w > 0; p++, w--)
+ if (*p != ' ') break;
+ continue;
+ }
if (dtp->u.p.blank_status == BLANK_ZERO) c = '0';
}
===================================================================
@@ -375,6 +375,25 @@ find_or_create_unit (int n)
}
+/* Helper function to test for BZ (Blank Zero) in format string. This
+ is used for optimization. You can't trim out blanks if they have
+ significance. */
+static bool
+is_BZ (st_parameter_dt *dtp)
+{
+ if (dtp->common.flags & IOPARM_DT_HAS_FORMAT)
+ {
+ char *p = dtp->format;
+ off_t i;
+ for (i = 0; i < dtp->format_len; i++)
+ if (p[i] == 'b' || p[i] == 'B')
+ if (p[i+1] == 'z' || p[i+1] == 'Z')
+ return true;
+ }
+ return false;
+}
+
+
gfc_unit *
get_internal_unit (st_parameter_dt *dtp)
{
@@ -402,6 +421,33 @@ get_internal_unit (st_parameter_dt *dtp)
some other file I/O unit. */
iunit->unit_number = -1;
+ /* As an optimization, adjust the unit record length to not
+ include trailing blanks. This will not work under certain conditions
+ where trailing blanks have significance. */
+ if (dtp->u.p.mode == READING && !dtp->u.p.ionml
+ && !(dtp->internal_unit_desc
+ && (GFC_DESCRIPTOR_RANK (dtp->internal_unit_desc) > 1
+ || GFC_DESCRIPTOR_STRIDE(dtp->internal_unit_desc, 0) != 1))
+ && !is_BZ (dtp) && dtp->blank_len == 0)
+ {
+ if (dtp->common.unit == 0)
+ {
+ int tmp = string_len_trim (dtp->internal_unit_len,
+ dtp->internal_unit);
+ if (tmp > 0)
+ dtp->internal_unit_len = tmp;
+ iunit->recl = dtp->internal_unit_len;
+ }
+ else
+ {
+ int tmp = string_len_trim_char4 (dtp->internal_unit_len,
+ (const gfc_char4_t*) dtp->internal_unit);
+ if (tmp > 0)
+ dtp->internal_unit_len = tmp;
+ iunit->recl = dtp->internal_unit_len;
+ }
+ }
+
/* Set up the looping specification from the array descriptor, if any. */
if (is_array_io (dtp))
@@ -414,27 +460,6 @@ get_internal_unit (st_parameter_dt *dtp)
start_record *= iunit->recl;
}
- else
- {
- /* If we are not processing an array, adjust the unit record length not
- to include trailing blanks for list-formatted reads. */
- if (dtp->u.p.mode == READING && !(dtp->common.flags & IOPARM_DT_HAS_FORMAT))
- {
- if (dtp->common.unit == 0)
- {
- dtp->internal_unit_len =
- string_len_trim (dtp->internal_unit_len, dtp->internal_unit);
- iunit->recl = dtp->internal_unit_len;
- }
- else
- {
- dtp->internal_unit_len =
- string_len_trim_char4 (dtp->internal_unit_len,
- (const gfc_char4_t*) dtp->internal_unit);
- iunit->recl = dtp->internal_unit_len;
- }
- }
- }
/* Set initial values for unit parameters. */
if (dtp->common.unit)