Index: list_read.c =================================================================== --- list_read.c (revision 208303) +++ list_read.c (working copy) @@ -160,7 +160,7 @@ next_char (st_parameter_dt *dtp) dtp->u.p.line_buffer_pos = 0; dtp->u.p.line_buffer_enabled = 0; - } + } /* Handle the end-of-record and end-of-file conditions for internal array unit. */ @@ -208,20 +208,8 @@ next_char (st_parameter_dt *dtp) c = cc; } - if (length < 0) - { - generate_error (&dtp->common, LIBERROR_OS, NULL); - return '\0'; - } - if (is_array_io (dtp)) { - /* Check whether we hit EOF. */ - if (length == 0) - { - generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL); - return '\0'; - } dtp->u.p.current_unit->bytes_left--; } else @@ -264,6 +252,28 @@ eat_spaces (st_parameter_dt *dtp) { int c; + /* If internal character array IO, peak ahead and seek past spaces. + This is an optimazation to eliminate numerous calls to + next character unique to character arrays with large character + lengths (PR38199). */ + if (is_array_io (dtp)) + { + gfc_offset offset = stell (dtp->u.p.current_unit->s); + gfc_offset limit = dtp->u.p.current_unit->bytes_left; + + do + { + c = dtp->internal_unit[offset++]; + dtp->u.p.current_unit->bytes_left--; + } + while (offset < limit && (c == ' ' || c == '\t')); + /* Back up, seek ahead, and fall through to complete the process + so that END conditions are handled correctly. */ + dtp->u.p.current_unit->bytes_left++; + sseek (dtp->u.p.current_unit->s, offset-1, SEEK_SET); + } + + /* Now skip spaces, EOF and EOL are handled in next_char. */ do c = next_char (dtp); while (c != EOF && (c == ' ' || c == '\t'));