* [PATCH] PR 53796 Improve INQUIRE(RECL=...) handling
@ 2017-11-20 20:17 Janne Blomqvist
2017-11-27 15:20 ` Janne Blomqvist
0 siblings, 1 reply; 5+ messages in thread
From: Janne Blomqvist @ 2017-11-20 20:17 UTC (permalink / raw)
To: fortran, gcc-patches; +Cc: Janne Blomqvist
The current F2018 draft (N2137) specifies behavior of the RECL=
specifier in the INQUIRE statement, where it previously was left as
undefined. Namely:
- If the unit is not connected, RECL= should be given the value -1.
- If the unit is connected with stream access, RECL= should be given
the value -2.
Further, as PR 53796 describes, the handling of RECL= is poor in other
ways as well. When the recl is set to the maximum possible
(GFC_INTEGER_8_HUGE / LLONG_MAX), which it does by default except for
preconnected units, and when INQUIRE(RECL=) is used with a 4 byte
integer, the value is truncated and the 4 byte value is thus
-1. Fixing this to generate an error is a lot of work, as currently
the truncation is done by the frontend, the library sees only an 8
byte value with no indication that the frontend is going to copy it to
a 4 byte one. Instead, this patch does a bit twiddling trick such that
the truncated 4 byte value is GFC_INTEGER_4_HUGE while still being
0.99999999 * GFC_INTEGER_8_HUGE which is large enough for all
practical purposes.
Finally, the patch removes GFORTRAN_DEFAULT_RECL which was used only
for preconnected units, and instead uses the same approach as describe
above.
Regtested on x86_64-pc-linux-gnu, Ok for trunk?
gcc/fortran/ChangeLog:
2017-11-20 Janne Blomqvist <jb@gcc.gnu.org>
PR fortran/53796
* gfortran.texi: Remove mentions of GFORTRAN_DEFAULT_RECL.
libgfortran/ChangeLog:
2017-11-20 Janne Blomqvist <jb@gcc.gnu.org>
PR fortran/53796
* io/inquire.c (inquire_via_unit): Set recl to -1 for unconnected
units.
* io/io.h (default_recl): New variable.
* io/open.c (new_unit): Set recl to default_recl for sequential,
-2 for stream access.
* io/transfer.c (read_block_form): Test against default_recl
instead of DEFAULT_RECL.
(write_block): Likewise.
* io/unit.c (init_units): Calculate max_offset, default_recl.
* libgfortran.h (DEFAULT_RECL): Remove.
* runtime/environ.c: Remove GFORTRAN_DEFAULT_RECL.
gcc/testsuite/ChangeLog:
2017-11-20 Janne Blomqvist <jb@gcc.gnu.org>
PR fortran/53796
* gfortran.dg/inquire_recl_f2018.f90: New test.
---
gcc/fortran/gfortran.texi | 9 -----
gcc/testsuite/gfortran.dg/inquire_recl_f2018.f90 | 42 ++++++++++++++++++++++++
libgfortran/io/inquire.c | 4 ++-
libgfortran/io/io.h | 5 +++
libgfortran/io/open.c | 6 ++--
libgfortran/io/transfer.c | 4 +--
libgfortran/io/unit.c | 33 ++++++++++++-------
libgfortran/libgfortran.h | 8 +----
libgfortran/runtime/environ.c | 4 ---
9 files changed, 79 insertions(+), 36 deletions(-)
create mode 100644 gcc/testsuite/gfortran.dg/inquire_recl_f2018.f90
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index 4b4688c..36c7b94 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -600,7 +600,6 @@ Malformed environment variables are silently ignored.
* GFORTRAN_UNBUFFERED_PRECONNECTED:: Do not buffer I/O for preconnected units.
* GFORTRAN_SHOW_LOCUS:: Show location for runtime errors
* GFORTRAN_OPTIONAL_PLUS:: Print leading + where permitted
-* GFORTRAN_DEFAULT_RECL:: Default record length for new files
* GFORTRAN_LIST_SEPARATOR:: Separator for list output
* GFORTRAN_CONVERT_UNIT:: Set endianness for unformatted I/O
* GFORTRAN_ERROR_BACKTRACE:: Show backtrace on run-time errors
@@ -683,14 +682,6 @@ where permitted by the Fortran standard. If the first letter
is @samp{n}, @samp{N} or @samp{0}, a plus sign is not printed
in most cases. Default is not to print plus signs.
-@node GFORTRAN_DEFAULT_RECL
-@section @env{GFORTRAN_DEFAULT_RECL}---Default record length for new files
-
-This environment variable specifies the default record length, in
-bytes, for files which are opened without a @code{RECL} tag in the
-@code{OPEN} statement. This must be a positive integer. The
-default value is 1073741824 bytes (1 GB).
-
@node GFORTRAN_LIST_SEPARATOR
@section @env{GFORTRAN_LIST_SEPARATOR}---Separator for list output
diff --git a/gcc/testsuite/gfortran.dg/inquire_recl_f2018.f90 b/gcc/testsuite/gfortran.dg/inquire_recl_f2018.f90
new file mode 100644
index 0000000..8a13340
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/inquire_recl_f2018.f90
@@ -0,0 +1,42 @@
+! { dg-do run }
+! PR 53796 INQUIRE(RECL=...)
+program inqrecl
+ implicit none
+ integer(8) :: r
+ integer :: r4
+ ! F2018 (N2137) 12.10.2.26: recl for unconnected should be -1
+ inquire(10, recl=r)
+ if (r /= -1) then
+ call abort()
+ end if
+
+ ! Formatted sequential
+ open(10, status="scratch")
+ inquire(10, recl=r)
+ inquire(10, recl=r4)
+ close(10)
+ if (r /= huge(0_8) - huge(0_4) - 1) then
+ call abort()
+ end if
+ if (r4 /= huge(0)) then
+ call abort()
+ end if
+
+ ! Formatted sequential with recl= specifier
+ open(10, status="scratch", recl=100)
+ inquire(10, recl=r)
+ close(10)
+ if (r /= 100) then
+ call abort()
+ end if
+
+ ! Formatted stream
+ ! F2018 (N2137) 12.10.2.26: If unit is connected
+ ! for stream access, recl should be assigned the value -2.
+ open(10, status="scratch", access="stream")
+ inquire(10, recl=r)
+ close(10)
+ if (r /= -2) then
+ call abort()
+ end if
+end program inqrecl
diff --git a/libgfortran/io/inquire.c b/libgfortran/io/inquire.c
index 4cf87d3..f6c6078 100644
--- a/libgfortran/io/inquire.c
+++ b/libgfortran/io/inquire.c
@@ -218,7 +218,9 @@ inquire_via_unit (st_parameter_inquire *iqp, gfc_unit *u)
}
if ((cf & IOPARM_INQUIRE_HAS_RECL_OUT) != 0)
- *iqp->recl_out = (u != NULL) ? u->recl : 0;
+ /* F2018 (N2137) 12.10.2.26: If there is no connection, recl is
+ assigned the value -1. */
+ *iqp->recl_out = (u != NULL) ? u->recl : -1;
if ((cf & IOPARM_INQUIRE_HAS_STRM_POS_OUT) != 0)
*iqp->strm_pos_out = (u != NULL) ? u->strm_pos : 0;
diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h
index d29b112..41611c4 100644
--- a/libgfortran/io/io.h
+++ b/libgfortran/io/io.h
@@ -735,6 +735,11 @@ gfc_saved_unit;
extern gfc_offset max_offset;
internal_proto(max_offset);
+/* Default RECL for sequential access if not given in OPEN statement,
+ computed at library initialization time. */
+extern gfc_offset default_recl;
+internal_proto(default_recl);
+
/* Unit tree root. */
extern gfc_unit *unit_root;
internal_proto(unit_root);
diff --git a/libgfortran/io/open.c b/libgfortran/io/open.c
index 9d3988a..4d292ef 100644
--- a/libgfortran/io/open.c
+++ b/libgfortran/io/open.c
@@ -586,7 +586,7 @@ new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags *flags)
else
{
u->flags.has_recl = 0;
- u->recl = max_offset;
+ u->recl = default_recl;
if (compile_options.max_subrecord_length)
{
u->recl_subrecord = compile_options.max_subrecord_length;
@@ -622,7 +622,9 @@ new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags *flags)
if (flags->access == ACCESS_STREAM)
{
u->maxrec = max_offset;
- u->recl = 1;
+ /* F2018 (N2137) 12.10.2.26: If the connection is for stream
+ access recl is assigned the value -2. */
+ u->recl = -2;
u->bytes_left = 1;
u->strm_pos = stell (u->s) + 1;
}
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index c173447..7f881c7 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -451,7 +451,7 @@ read_block_form (st_parameter_dt *dtp, int *nbytes)
/* For preconnected units with default record length, set bytes left
to unit record length and proceed, otherwise error. */
if (dtp->u.p.current_unit->unit_number == options.stdin_unit
- && dtp->u.p.current_unit->recl == DEFAULT_RECL)
+ && dtp->u.p.current_unit->recl == default_recl)
dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
else
{
@@ -757,7 +757,7 @@ write_block (st_parameter_dt *dtp, int length)
== options.stdout_unit
|| dtp->u.p.current_unit->unit_number
== options.stderr_unit)
- && dtp->u.p.current_unit->recl == DEFAULT_RECL))
+ && dtp->u.p.current_unit->recl == default_recl))
dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
else
{
diff --git a/libgfortran/io/unit.c b/libgfortran/io/unit.c
index e06867a..0f8bbbb 100644
--- a/libgfortran/io/unit.c
+++ b/libgfortran/io/unit.c
@@ -96,7 +96,10 @@ static void newunit_free (int);
#define CACHE_SIZE 3
static gfc_unit *unit_cache[CACHE_SIZE];
+
gfc_offset max_offset;
+gfc_offset default_recl;
+
gfc_unit *unit_root;
#ifdef __GTHREAD_MUTEX_INIT
__gthread_mutex_t unit_lock = __GTHREAD_MUTEX_INIT;
@@ -576,7 +579,6 @@ void
init_units (void)
{
gfc_unit *u;
- unsigned int i;
#ifdef HAVE_NEWLOCALE
c_locale = newlocale (0, "C", 0);
@@ -590,6 +592,22 @@ init_units (void)
__GTHREAD_MUTEX_INIT_FUNCTION (&unit_lock);
#endif
+ if (sizeof (max_offset) == 8)
+ {
+ max_offset = GFC_INTEGER_8_HUGE;
+ /* Why this weird value? Because if the recl specifier in the
+ inquire statement is a 4 byte value, u->recl is truncated,
+ and this trick ensures it becomes HUGE(0) rather than -1.
+ The full 8 byte value of default_recl is still 0.99999999 *
+ max_offset which is large enough for all practical
+ purposes. */
+ default_recl = max_offset & ~(1LL<<31);
+ }
+ else if (sizeof (max_offset) == 4)
+ max_offset = default_recl = GFC_INTEGER_4_HUGE;
+ else
+ internal_error (NULL, "sizeof (max_offset) must be 4 or 8");
+
if (options.stdin_unit >= 0)
{ /* STDIN */
u = insert_unit (options.stdin_unit);
@@ -612,7 +630,7 @@ init_units (void)
u->flags.share = SHARE_UNSPECIFIED;
u->flags.cc = CC_LIST;
- u->recl = options.default_recl;
+ u->recl = default_recl;
u->endfile = NO_ENDFILE;
u->filename = strdup (stdin_name);
@@ -643,7 +661,7 @@ init_units (void)
u->flags.share = SHARE_UNSPECIFIED;
u->flags.cc = CC_LIST;
- u->recl = options.default_recl;
+ u->recl = default_recl;
u->endfile = AT_ENDFILE;
u->filename = strdup (stdout_name);
@@ -673,7 +691,7 @@ init_units (void)
u->flags.share = SHARE_UNSPECIFIED;
u->flags.cc = CC_LIST;
- u->recl = options.default_recl;
+ u->recl = default_recl;
u->endfile = AT_ENDFILE;
u->filename = strdup (stderr_name);
@@ -683,13 +701,6 @@ init_units (void)
__gthread_mutex_unlock (&u->lock);
}
-
- /* Calculate the maximum file offset in a portable manner.
- max will be the largest signed number for the type gfc_offset.
- set a 1 in the LSB and keep a running sum, stopping at MSB-1 bit. */
- max_offset = 0;
- for (i = 0; i < sizeof (max_offset) * 8 - 1; i++)
- max_offset = max_offset + ((gfc_offset) 1 << i);
}
diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h
index cdbdd951..e9648b5 100644
--- a/libgfortran/libgfortran.h
+++ b/libgfortran/libgfortran.h
@@ -514,7 +514,7 @@ typedef struct
int separator_len;
const char *separator;
- int all_unbuffered, unbuffered_preconnected, default_recl;
+ int all_unbuffered, unbuffered_preconnected;
int fpe, backtrace;
}
options_t;
@@ -580,12 +580,6 @@ extern char *filename;
iexport_data_proto(filename);
-/* The default value of record length for preconnected units is defined
- here. This value can be overriden by an environment variable.
- Default value is 1 Gb. */
-#define DEFAULT_RECL 1073741824
-
-
#define CHARACTER2(name) \
gfc_charlen_type name ## _len; \
char * name
diff --git a/libgfortran/runtime/environ.c b/libgfortran/runtime/environ.c
index f0a593e..fb9a3c1 100644
--- a/libgfortran/runtime/environ.c
+++ b/libgfortran/runtime/environ.c
@@ -208,10 +208,6 @@ static variable variable_table[] = {
/* Print optional plus signs in numbers where permitted */
{ "GFORTRAN_OPTIONAL_PLUS", 0, &options.optional_plus, init_boolean },
- /* Default maximum record length for sequential files */
- { "GFORTRAN_DEFAULT_RECL", DEFAULT_RECL, &options.default_recl,
- init_unsigned_integer },
-
/* Separator to use when writing list output */
{ "GFORTRAN_LIST_SEPARATOR", 0, NULL, init_sep },
--
2.7.4
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] PR 53796 Improve INQUIRE(RECL=...) handling
2017-11-20 20:17 [PATCH] PR 53796 Improve INQUIRE(RECL=...) handling Janne Blomqvist
@ 2017-11-27 15:20 ` Janne Blomqvist
2017-11-27 21:36 ` Thomas Koenig
0 siblings, 1 reply; 5+ messages in thread
From: Janne Blomqvist @ 2017-11-27 15:20 UTC (permalink / raw)
To: Fortran List, GCC Patches
PING
On Mon, Nov 20, 2017 at 10:06 PM, Janne Blomqvist
<blomqvist.janne@gmail.com> wrote:
> The current F2018 draft (N2137) specifies behavior of the RECL=
> specifier in the INQUIRE statement, where it previously was left as
> undefined. Namely:
>
> - If the unit is not connected, RECL= should be given the value -1.
> - If the unit is connected with stream access, RECL= should be given
> the value -2.
>
> Further, as PR 53796 describes, the handling of RECL= is poor in other
> ways as well. When the recl is set to the maximum possible
> (GFC_INTEGER_8_HUGE / LLONG_MAX), which it does by default except for
> preconnected units, and when INQUIRE(RECL=) is used with a 4 byte
> integer, the value is truncated and the 4 byte value is thus
> -1. Fixing this to generate an error is a lot of work, as currently
> the truncation is done by the frontend, the library sees only an 8
> byte value with no indication that the frontend is going to copy it to
> a 4 byte one. Instead, this patch does a bit twiddling trick such that
> the truncated 4 byte value is GFC_INTEGER_4_HUGE while still being
> 0.99999999 * GFC_INTEGER_8_HUGE which is large enough for all
> practical purposes.
>
> Finally, the patch removes GFORTRAN_DEFAULT_RECL which was used only
> for preconnected units, and instead uses the same approach as describe
> above.
>
> Regtested on x86_64-pc-linux-gnu, Ok for trunk?
>
> gcc/fortran/ChangeLog:
>
> 2017-11-20 Janne Blomqvist <jb@gcc.gnu.org>
>
> PR fortran/53796
> * gfortran.texi: Remove mentions of GFORTRAN_DEFAULT_RECL.
>
> libgfortran/ChangeLog:
>
> 2017-11-20 Janne Blomqvist <jb@gcc.gnu.org>
>
> PR fortran/53796
> * io/inquire.c (inquire_via_unit): Set recl to -1 for unconnected
> units.
> * io/io.h (default_recl): New variable.
> * io/open.c (new_unit): Set recl to default_recl for sequential,
> -2 for stream access.
> * io/transfer.c (read_block_form): Test against default_recl
> instead of DEFAULT_RECL.
> (write_block): Likewise.
> * io/unit.c (init_units): Calculate max_offset, default_recl.
> * libgfortran.h (DEFAULT_RECL): Remove.
> * runtime/environ.c: Remove GFORTRAN_DEFAULT_RECL.
>
> gcc/testsuite/ChangeLog:
>
> 2017-11-20 Janne Blomqvist <jb@gcc.gnu.org>
>
> PR fortran/53796
> * gfortran.dg/inquire_recl_f2018.f90: New test.
> ---
> gcc/fortran/gfortran.texi | 9 -----
> gcc/testsuite/gfortran.dg/inquire_recl_f2018.f90 | 42 ++++++++++++++++++++++++
> libgfortran/io/inquire.c | 4 ++-
> libgfortran/io/io.h | 5 +++
> libgfortran/io/open.c | 6 ++--
> libgfortran/io/transfer.c | 4 +--
> libgfortran/io/unit.c | 33 ++++++++++++-------
> libgfortran/libgfortran.h | 8 +----
> libgfortran/runtime/environ.c | 4 ---
> 9 files changed, 79 insertions(+), 36 deletions(-)
> create mode 100644 gcc/testsuite/gfortran.dg/inquire_recl_f2018.f90
>
> diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
> index 4b4688c..36c7b94 100644
> --- a/gcc/fortran/gfortran.texi
> +++ b/gcc/fortran/gfortran.texi
> @@ -600,7 +600,6 @@ Malformed environment variables are silently ignored.
> * GFORTRAN_UNBUFFERED_PRECONNECTED:: Do not buffer I/O for preconnected units.
> * GFORTRAN_SHOW_LOCUS:: Show location for runtime errors
> * GFORTRAN_OPTIONAL_PLUS:: Print leading + where permitted
> -* GFORTRAN_DEFAULT_RECL:: Default record length for new files
> * GFORTRAN_LIST_SEPARATOR:: Separator for list output
> * GFORTRAN_CONVERT_UNIT:: Set endianness for unformatted I/O
> * GFORTRAN_ERROR_BACKTRACE:: Show backtrace on run-time errors
> @@ -683,14 +682,6 @@ where permitted by the Fortran standard. If the first letter
> is @samp{n}, @samp{N} or @samp{0}, a plus sign is not printed
> in most cases. Default is not to print plus signs.
>
> -@node GFORTRAN_DEFAULT_RECL
> -@section @env{GFORTRAN_DEFAULT_RECL}---Default record length for new files
> -
> -This environment variable specifies the default record length, in
> -bytes, for files which are opened without a @code{RECL} tag in the
> -@code{OPEN} statement. This must be a positive integer. The
> -default value is 1073741824 bytes (1 GB).
> -
> @node GFORTRAN_LIST_SEPARATOR
> @section @env{GFORTRAN_LIST_SEPARATOR}---Separator for list output
>
> diff --git a/gcc/testsuite/gfortran.dg/inquire_recl_f2018.f90 b/gcc/testsuite/gfortran.dg/inquire_recl_f2018.f90
> new file mode 100644
> index 0000000..8a13340
> --- /dev/null
> +++ b/gcc/testsuite/gfortran.dg/inquire_recl_f2018.f90
> @@ -0,0 +1,42 @@
> +! { dg-do run }
> +! PR 53796 INQUIRE(RECL=...)
> +program inqrecl
> + implicit none
> + integer(8) :: r
> + integer :: r4
> + ! F2018 (N2137) 12.10.2.26: recl for unconnected should be -1
> + inquire(10, recl=r)
> + if (r /= -1) then
> + call abort()
> + end if
> +
> + ! Formatted sequential
> + open(10, status="scratch")
> + inquire(10, recl=r)
> + inquire(10, recl=r4)
> + close(10)
> + if (r /= huge(0_8) - huge(0_4) - 1) then
> + call abort()
> + end if
> + if (r4 /= huge(0)) then
> + call abort()
> + end if
> +
> + ! Formatted sequential with recl= specifier
> + open(10, status="scratch", recl=100)
> + inquire(10, recl=r)
> + close(10)
> + if (r /= 100) then
> + call abort()
> + end if
> +
> + ! Formatted stream
> + ! F2018 (N2137) 12.10.2.26: If unit is connected
> + ! for stream access, recl should be assigned the value -2.
> + open(10, status="scratch", access="stream")
> + inquire(10, recl=r)
> + close(10)
> + if (r /= -2) then
> + call abort()
> + end if
> +end program inqrecl
> diff --git a/libgfortran/io/inquire.c b/libgfortran/io/inquire.c
> index 4cf87d3..f6c6078 100644
> --- a/libgfortran/io/inquire.c
> +++ b/libgfortran/io/inquire.c
> @@ -218,7 +218,9 @@ inquire_via_unit (st_parameter_inquire *iqp, gfc_unit *u)
> }
>
> if ((cf & IOPARM_INQUIRE_HAS_RECL_OUT) != 0)
> - *iqp->recl_out = (u != NULL) ? u->recl : 0;
> + /* F2018 (N2137) 12.10.2.26: If there is no connection, recl is
> + assigned the value -1. */
> + *iqp->recl_out = (u != NULL) ? u->recl : -1;
>
> if ((cf & IOPARM_INQUIRE_HAS_STRM_POS_OUT) != 0)
> *iqp->strm_pos_out = (u != NULL) ? u->strm_pos : 0;
> diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h
> index d29b112..41611c4 100644
> --- a/libgfortran/io/io.h
> +++ b/libgfortran/io/io.h
> @@ -735,6 +735,11 @@ gfc_saved_unit;
> extern gfc_offset max_offset;
> internal_proto(max_offset);
>
> +/* Default RECL for sequential access if not given in OPEN statement,
> + computed at library initialization time. */
> +extern gfc_offset default_recl;
> +internal_proto(default_recl);
> +
> /* Unit tree root. */
> extern gfc_unit *unit_root;
> internal_proto(unit_root);
> diff --git a/libgfortran/io/open.c b/libgfortran/io/open.c
> index 9d3988a..4d292ef 100644
> --- a/libgfortran/io/open.c
> +++ b/libgfortran/io/open.c
> @@ -586,7 +586,7 @@ new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags *flags)
> else
> {
> u->flags.has_recl = 0;
> - u->recl = max_offset;
> + u->recl = default_recl;
> if (compile_options.max_subrecord_length)
> {
> u->recl_subrecord = compile_options.max_subrecord_length;
> @@ -622,7 +622,9 @@ new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags *flags)
> if (flags->access == ACCESS_STREAM)
> {
> u->maxrec = max_offset;
> - u->recl = 1;
> + /* F2018 (N2137) 12.10.2.26: If the connection is for stream
> + access recl is assigned the value -2. */
> + u->recl = -2;
> u->bytes_left = 1;
> u->strm_pos = stell (u->s) + 1;
> }
> diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
> index c173447..7f881c7 100644
> --- a/libgfortran/io/transfer.c
> +++ b/libgfortran/io/transfer.c
> @@ -451,7 +451,7 @@ read_block_form (st_parameter_dt *dtp, int *nbytes)
> /* For preconnected units with default record length, set bytes left
> to unit record length and proceed, otherwise error. */
> if (dtp->u.p.current_unit->unit_number == options.stdin_unit
> - && dtp->u.p.current_unit->recl == DEFAULT_RECL)
> + && dtp->u.p.current_unit->recl == default_recl)
> dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
> else
> {
> @@ -757,7 +757,7 @@ write_block (st_parameter_dt *dtp, int length)
> == options.stdout_unit
> || dtp->u.p.current_unit->unit_number
> == options.stderr_unit)
> - && dtp->u.p.current_unit->recl == DEFAULT_RECL))
> + && dtp->u.p.current_unit->recl == default_recl))
> dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
> else
> {
> diff --git a/libgfortran/io/unit.c b/libgfortran/io/unit.c
> index e06867a..0f8bbbb 100644
> --- a/libgfortran/io/unit.c
> +++ b/libgfortran/io/unit.c
> @@ -96,7 +96,10 @@ static void newunit_free (int);
>
> #define CACHE_SIZE 3
> static gfc_unit *unit_cache[CACHE_SIZE];
> +
> gfc_offset max_offset;
> +gfc_offset default_recl;
> +
> gfc_unit *unit_root;
> #ifdef __GTHREAD_MUTEX_INIT
> __gthread_mutex_t unit_lock = __GTHREAD_MUTEX_INIT;
> @@ -576,7 +579,6 @@ void
> init_units (void)
> {
> gfc_unit *u;
> - unsigned int i;
>
> #ifdef HAVE_NEWLOCALE
> c_locale = newlocale (0, "C", 0);
> @@ -590,6 +592,22 @@ init_units (void)
> __GTHREAD_MUTEX_INIT_FUNCTION (&unit_lock);
> #endif
>
> + if (sizeof (max_offset) == 8)
> + {
> + max_offset = GFC_INTEGER_8_HUGE;
> + /* Why this weird value? Because if the recl specifier in the
> + inquire statement is a 4 byte value, u->recl is truncated,
> + and this trick ensures it becomes HUGE(0) rather than -1.
> + The full 8 byte value of default_recl is still 0.99999999 *
> + max_offset which is large enough for all practical
> + purposes. */
> + default_recl = max_offset & ~(1LL<<31);
> + }
> + else if (sizeof (max_offset) == 4)
> + max_offset = default_recl = GFC_INTEGER_4_HUGE;
> + else
> + internal_error (NULL, "sizeof (max_offset) must be 4 or 8");
> +
> if (options.stdin_unit >= 0)
> { /* STDIN */
> u = insert_unit (options.stdin_unit);
> @@ -612,7 +630,7 @@ init_units (void)
> u->flags.share = SHARE_UNSPECIFIED;
> u->flags.cc = CC_LIST;
>
> - u->recl = options.default_recl;
> + u->recl = default_recl;
> u->endfile = NO_ENDFILE;
>
> u->filename = strdup (stdin_name);
> @@ -643,7 +661,7 @@ init_units (void)
> u->flags.share = SHARE_UNSPECIFIED;
> u->flags.cc = CC_LIST;
>
> - u->recl = options.default_recl;
> + u->recl = default_recl;
> u->endfile = AT_ENDFILE;
>
> u->filename = strdup (stdout_name);
> @@ -673,7 +691,7 @@ init_units (void)
> u->flags.share = SHARE_UNSPECIFIED;
> u->flags.cc = CC_LIST;
>
> - u->recl = options.default_recl;
> + u->recl = default_recl;
> u->endfile = AT_ENDFILE;
>
> u->filename = strdup (stderr_name);
> @@ -683,13 +701,6 @@ init_units (void)
>
> __gthread_mutex_unlock (&u->lock);
> }
> -
> - /* Calculate the maximum file offset in a portable manner.
> - max will be the largest signed number for the type gfc_offset.
> - set a 1 in the LSB and keep a running sum, stopping at MSB-1 bit. */
> - max_offset = 0;
> - for (i = 0; i < sizeof (max_offset) * 8 - 1; i++)
> - max_offset = max_offset + ((gfc_offset) 1 << i);
> }
>
>
> diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h
> index cdbdd951..e9648b5 100644
> --- a/libgfortran/libgfortran.h
> +++ b/libgfortran/libgfortran.h
> @@ -514,7 +514,7 @@ typedef struct
> int separator_len;
> const char *separator;
>
> - int all_unbuffered, unbuffered_preconnected, default_recl;
> + int all_unbuffered, unbuffered_preconnected;
> int fpe, backtrace;
> }
> options_t;
> @@ -580,12 +580,6 @@ extern char *filename;
> iexport_data_proto(filename);
>
>
> -/* The default value of record length for preconnected units is defined
> - here. This value can be overriden by an environment variable.
> - Default value is 1 Gb. */
> -#define DEFAULT_RECL 1073741824
> -
> -
> #define CHARACTER2(name) \
> gfc_charlen_type name ## _len; \
> char * name
> diff --git a/libgfortran/runtime/environ.c b/libgfortran/runtime/environ.c
> index f0a593e..fb9a3c1 100644
> --- a/libgfortran/runtime/environ.c
> +++ b/libgfortran/runtime/environ.c
> @@ -208,10 +208,6 @@ static variable variable_table[] = {
> /* Print optional plus signs in numbers where permitted */
> { "GFORTRAN_OPTIONAL_PLUS", 0, &options.optional_plus, init_boolean },
>
> - /* Default maximum record length for sequential files */
> - { "GFORTRAN_DEFAULT_RECL", DEFAULT_RECL, &options.default_recl,
> - init_unsigned_integer },
> -
> /* Separator to use when writing list output */
> { "GFORTRAN_LIST_SEPARATOR", 0, NULL, init_sep },
>
> --
> 2.7.4
>
--
Janne Blomqvist
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] PR 53796 Improve INQUIRE(RECL=...) handling
2017-11-27 15:20 ` Janne Blomqvist
@ 2017-11-27 21:36 ` Thomas Koenig
2018-09-07 13:37 ` Bernhard Reutner-Fischer
0 siblings, 1 reply; 5+ messages in thread
From: Thomas Koenig @ 2017-11-27 21:36 UTC (permalink / raw)
To: Janne Blomqvist, Fortran List, GCC Patches
Hi Janne,
> PING
Looks good for trunk. Thanks!
Since this is a change in user-visible behavior,
will you also document this in gcc-8/changes.html ?
If you prefer me to do this (haven't installed CVS
or something :-) just drop me a line.
Regards
Thomas
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] PR 53796 Improve INQUIRE(RECL=...) handling
2017-11-27 21:36 ` Thomas Koenig
@ 2018-09-07 13:37 ` Bernhard Reutner-Fischer
2018-09-07 19:01 ` Janne Blomqvist
0 siblings, 1 reply; 5+ messages in thread
From: Bernhard Reutner-Fischer @ 2018-09-07 13:37 UTC (permalink / raw)
To: Thomas Koenig; +Cc: Janne Blomqvist, gfortran, GCC Patches
Janne,
On Mon, 27 Nov 2017 at 20:57, Thomas Koenig <tkoenig@netcologne.de> wrote:
>
> Hi Janne,
>
> > PING
>
> Looks good for trunk. Thanks!
AFAICS this removed the last user of
static void
init_unsigned_integer
which manifests itself as
../../../../../src/gcc-9.0.mine/libgfortran/runtime/environ.c:104:1:
warning: ‘init_unsigned_integer’ defined but not used
[-Wunused-function]
104 | init_unsigned_integer (variable * v)
| ^~~~~~~~~~~~~~~~~~~~~
and hence should be removed.
thanks,
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] PR 53796 Improve INQUIRE(RECL=...) handling
2018-09-07 13:37 ` Bernhard Reutner-Fischer
@ 2018-09-07 19:01 ` Janne Blomqvist
0 siblings, 0 replies; 5+ messages in thread
From: Janne Blomqvist @ 2018-09-07 19:01 UTC (permalink / raw)
To: Bernhard Reutner-Fischer; +Cc: Thomas Koenig, Fortran List, GCC Patches
On Fri, Sep 7, 2018 at 4:37 PM Bernhard Reutner-Fischer <
rep.dot.nop@gmail.com> wrote:
> Janne,
>
> On Mon, 27 Nov 2017 at 20:57, Thomas Koenig <tkoenig@netcologne.de> wrote:
> >
> > Hi Janne,
> >
> > > PING
> >
> > Looks good for trunk. Thanks!
>
> AFAICS this removed the last user of
>
> static void
> init_unsigned_integer
>
> which manifests itself as
> ../../../../../src/gcc-9.0.mine/libgfortran/runtime/environ.c:104:1:
> warning: ‘init_unsigned_integer’ defined but not used
> [-Wunused-function]
> 104 | init_unsigned_integer (variable * v)
> | ^~~~~~~~~~~~~~~~~~~~~
>
> and hence should be removed.
>
> thanks,
>
Thanks for noticing! Committed r264163 as obvious. Commit msg below:
Remove unused init_unsigned_integer function.
As pointed out by Bernhard Reutner-Fischer, this function is unused
since the fix for PR 53796 in November 2017.
2018-09-07 Janne Blomqvist <jb@gcc.gnu.org>
* runtime/environ.c (init_unsigned_integer): Remove.
--
Janne Blomqvist
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2018-09-07 19:01 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-20 20:17 [PATCH] PR 53796 Improve INQUIRE(RECL=...) handling Janne Blomqvist
2017-11-27 15:20 ` Janne Blomqvist
2017-11-27 21:36 ` Thomas Koenig
2018-09-07 13:37 ` Bernhard Reutner-Fischer
2018-09-07 19:01 ` Janne Blomqvist
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).