diff options
author | dfranke <dfranke@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-05-04 18:02:18 +0000 |
---|---|---|
committer | dfranke <dfranke@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-05-04 18:02:18 +0000 |
commit | 7d86687017fb9bfa58571cfc46f786f539ba2601 (patch) | |
tree | f5fbb8c905ad4fe8db79b23d98f6fdde28648680 /gcc/fortran | |
parent | 71ac9b47b872934e8d78ff35882d69f845545fbd (diff) | |
download | gcc-7d86687017fb9bfa58571cfc46f786f539ba2601.tar.gz |
gcc/fortran:
2007-05-04 Daniel Franke <franke.daniel@gmail.com>
PR fortran/22539
* intrinsic.c (add_subroutines): Added FSEEK.
* intrinsic.h (gfc_resolve_fseek_sub, gfc_check_fseek_sub): New.
* iresolve.c (gfc_resolve_fseek_sub): New.
* check.c (gfc_check_fseek_sub): New.
* intrinsic.texi (FSEEK): Updated.
gcc/testsuite:
2007-05-01 Daniel Franke <franke.daniel@gmail.com>
PR fortran/22539
* gfortran.dg/fseek.f90: New test.
libgfortran:
2007-05-04 Daniel Franke <franke.daniel@gmail.com>
PR fortran/22539
* io/intrinsics.c (fseek_sub): New.
* io/unix.c (fd_fseek): Change logical and physical offsets only
if seek succeeds.
* gfortran.map (fseek_sub): New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@124437 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/fortran/check.c | 38 | ||||
-rw-r--r-- | gcc/fortran/intrinsic.c | 8 | ||||
-rw-r--r-- | gcc/fortran/intrinsic.h | 2 | ||||
-rw-r--r-- | gcc/fortran/intrinsic.texi | 64 | ||||
-rw-r--r-- | gcc/fortran/iresolve.c | 44 |
6 files changed, 158 insertions, 7 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index b3b17fd8630..84b90231bfd 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,12 @@ +2007-05-04 Daniel Franke <franke.daniel@gmail.com> + + PR fortran/22539 + * intrinsic.c (add_subroutines): Added FSEEK. + * intrinsic.h (gfc_resolve_fseek_sub, gfc_check_fseek_sub): New. + * iresolve.c (gfc_resolve_fseek_sub): New. + * check.c (gfc_check_fseek_sub): New. + * intrinsic.texi (FSEEK): Updated. + 2007-05-04 Tobias Burnus <burnus@net-b.de> PR fortran/31803 diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c index 9806ebdf79a..73192e9fa67 100644 --- a/gcc/fortran/check.c +++ b/gcc/fortran/check.c @@ -2461,6 +2461,44 @@ gfc_check_fgetput (gfc_expr *c) try +gfc_check_fseek_sub (gfc_expr *unit, gfc_expr *offset, gfc_expr *whence, gfc_expr *status) +{ + if (type_check (unit, 0, BT_INTEGER) == FAILURE) + return FAILURE; + + if (scalar_check (unit, 0) == FAILURE) + return FAILURE; + + if (type_check (offset, 1, BT_INTEGER) == FAILURE) + return FAILURE; + + if (scalar_check (offset, 1) == FAILURE) + return FAILURE; + + if (type_check (whence, 2, BT_INTEGER) == FAILURE) + return FAILURE; + + if (scalar_check (whence, 2) == FAILURE) + return FAILURE; + + if (status == NULL) + return SUCCESS; + + if (type_check (status, 3, BT_INTEGER) == FAILURE) + return FAILURE; + + if (kind_value_check (status, 3, 4) == FAILURE) + return FAILURE + + if (scalar_check (status, 3) == FAILURE) + return FAILURE; + + return SUCCESS; +} + + + +try gfc_check_fstat (gfc_expr *unit, gfc_expr *array) { if (type_check (unit, 0, BT_INTEGER) == FAILURE) diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c index de74678d268..927fcc13dcd 100644 --- a/gcc/fortran/intrinsic.c +++ b/gcc/fortran/intrinsic.c @@ -2313,7 +2313,8 @@ add_subroutines (void) *com = "command", *length = "length", *st = "status", *val = "value", *num = "number", *name = "name", *trim_name = "trim_name", *ut = "unit", *han = "handler", - *sec = "seconds", *res = "result", *of = "offset", *md = "mode"; + *sec = "seconds", *res = "result", *of = "offset", *md = "mode", + *whence = "whence"; int di, dr, dc, dl, ii; @@ -2489,6 +2490,11 @@ add_subroutines (void) add_sym_1s ("free", NOT_ELEMENTAL, BT_UNKNOWN, 0, GFC_STD_GNU, gfc_check_free, NULL, gfc_resolve_free, c, BT_INTEGER, ii, REQUIRED); + add_sym_4s ("fseek", NOT_ELEMENTAL, BT_UNKNOWN, 0, GFC_STD_GNU, + gfc_check_fseek_sub, NULL, gfc_resolve_fseek_sub, + ut, BT_INTEGER, di, REQUIRED, of, BT_INTEGER, di, REQUIRED, + whence, BT_INTEGER, di, REQUIRED, st, BT_INTEGER, di, OPTIONAL); + add_sym_2s ("ftell", NOT_ELEMENTAL, BT_UNKNOWN, 0, GFC_STD_GNU, gfc_check_ftell_sub, NULL, gfc_resolve_ftell_sub, ut, BT_INTEGER, di, REQUIRED, of, BT_INTEGER, ii, REQUIRED); diff --git a/gcc/fortran/intrinsic.h b/gcc/fortran/intrinsic.h index 46d49f7e744..8f07c05ca5c 100644 --- a/gcc/fortran/intrinsic.h +++ b/gcc/fortran/intrinsic.h @@ -162,6 +162,7 @@ try gfc_check_random_seed (gfc_expr *, gfc_expr *, gfc_expr *); try gfc_check_etime_sub (gfc_expr *, gfc_expr *); try gfc_check_fgetputc_sub (gfc_expr *, gfc_expr *, gfc_expr *); try gfc_check_fgetput_sub (gfc_expr *, gfc_expr *); +try gfc_check_fseek_sub (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *); try gfc_check_ftell_sub (gfc_expr *, gfc_expr *); try gfc_check_getcwd_sub (gfc_expr *, gfc_expr *); try gfc_check_hostnm_sub (gfc_expr *, gfc_expr *); @@ -456,6 +457,7 @@ void gfc_resolve_exit (gfc_code *); void gfc_resolve_fdate_sub (gfc_code *); void gfc_resolve_flush (gfc_code *); void gfc_resolve_free (gfc_code *); +void gfc_resolve_fseek_sub (gfc_code *); void gfc_resolve_fstat_sub (gfc_code *); void gfc_resolve_ftell_sub (gfc_code *); void gfc_resolve_fgetc_sub (gfc_code *); diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi index b71609b4dd4..4e6b26a21d9 100644 --- a/gcc/fortran/intrinsic.texi +++ b/gcc/fortran/intrinsic.texi @@ -3966,10 +3966,31 @@ See @code{MALLOC} for an example. @cindex file operation, seek @cindex file operation, position -Not yet implemented in GNU Fortran. - @table @asis @item @emph{Description}: +Moves @var{UNIT} to the specified @var{OFFSET}. If @var{WHENCE} +is set to 0, the @var{OFFSET} is taken as an absolute value @code{SEEK_SET}, +if set to 1, @var{OFFSET} is taken to be relative to the current position +@code{SEEK_CUR}, and if set to 2 relative to the end of the file @code{SEEK_END}. +On error, @var{STATUS} is set to a non-zero value. If @var{STATUS} the seek +fails silently. + +This intrinsic routine is not fully backwards compatible with @command{g77}. +In @command{g77}, the @code{FSEEK} takes a statement label instead of a +@var{STATUS} variable. If FSEEK is used in old code, change +@smallexample + CALL FSEEK(UNIT, OFFSET, WHENCE, *label) +@end smallexample +to +@smallexample + INTEGER :: status + CALL FSEEK(UNIT, OFFSET, WHENCE, status) + IF (status /= 0) GOTO label +@end smallexample + +Please note that GNU Fortran provides the Fortran 2003 Stream facility. +Programmers should consider the use of new stream IO feature in new code +for future portability. See also @ref{Fortran 2003 status}. @item @emph{Standard}: GNU extension @@ -3978,13 +3999,44 @@ GNU extension Subroutine @item @emph{Syntax}: +@code{CALL FSEEK(UNIT, OFFSET, WHENCE[, STATUS])} + @item @emph{Arguments}: -@item @emph{Return value}: +@multitable @columnfractions .15 .70 +@item @var{UNIT} @tab Shall be a scalar of type @code{INTEGER}. +@item @var{OFFSET} @tab Shall be a scalar of type @code{INTEGER}. +@item @var{WHENCE} @tab Shall be a scalar of type @code{INTEGER}. +Its value shall be either 0, 1 or 2. +@item @var{STATUS} @tab (Optional) shall be a scalar of type +@code{INTEGER(4)}. +@end multitable + @item @emph{Example}: -@item @emph{Specific names}: -@item @emph{See also}: -@uref{http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19292, g77 features lacking in gfortran} +@smallexample +PROGRAM test_fseek + INTEGER, PARAMETER :: SEEK_SET = 0, SEEK_CUR = 1, SEEK_END = 2 + INTEGER :: fd, offset, ierr + + ierr = 0 + offset = 5 + fd = 10 + + OPEN(UNIT=fd, FILE="fseek.test") + CALL FSEEK(fd, offset, SEEK_SET, ierr) ! move to OFFSET + print *, FTELL(fd), ierr + + CALL FSEEK(fd, 0, SEEK_END, ierr) ! move to end + print *, FTELL(fd), ierr + CALL FSEEK(fd, 0, SEEK_SET, ierr) ! move to beginning + print *, FTELL(fd), ierr + + CLOSE(UNIT=fd) +END PROGRAM +@end smallexample + +@item @emph{See also}: +@ref{FTELL} @end table diff --git a/gcc/fortran/iresolve.c b/gcc/fortran/iresolve.c index 14ed3e32e8d..b0a1c37dda6 100644 --- a/gcc/fortran/iresolve.c +++ b/gcc/fortran/iresolve.c @@ -2965,6 +2965,50 @@ gfc_resolve_fput_sub (gfc_code *c) } +void +gfc_resolve_fseek_sub (gfc_code *c) +{ + gfc_expr *unit; + gfc_expr *offset; + gfc_expr *whence; + gfc_expr *status; + gfc_typespec ts; + + unit = c->ext.actual->expr; + offset = c->ext.actual->next->expr; + whence = c->ext.actual->next->next->expr; + status = c->ext.actual->next->next->next->expr; + + if (unit->ts.kind != gfc_c_int_kind) + { + ts.type = BT_INTEGER; + ts.kind = gfc_c_int_kind; + ts.derived = NULL; + ts.cl = NULL; + gfc_convert_type (unit, &ts, 2); + } + + if (offset->ts.kind != gfc_intio_kind) + { + ts.type = BT_INTEGER; + ts.kind = gfc_intio_kind; + ts.derived = NULL; + ts.cl = NULL; + gfc_convert_type (offset, &ts, 2); + } + + if (whence->ts.kind != gfc_c_int_kind) + { + ts.type = BT_INTEGER; + ts.kind = gfc_c_int_kind; + ts.derived = NULL; + ts.cl = NULL; + gfc_convert_type (whence, &ts, 2); + } + + c->resolved_sym = gfc_get_intrinsic_sub_symbol (PREFIX ("fseek_sub")); +} + void gfc_resolve_ftell_sub (gfc_code *c) { |