diff options
-rw-r--r-- | gcc/fortran/ChangeLog | 24 | ||||
-rw-r--r-- | gcc/fortran/check.c | 10 | ||||
-rw-r--r-- | gcc/fortran/gfortran.h | 8 | ||||
-rw-r--r-- | gcc/fortran/intrinsic.c | 41 | ||||
-rw-r--r-- | gcc/fortran/intrinsic.h | 11 | ||||
-rw-r--r-- | gcc/fortran/iresolve.c | 74 | ||||
-rw-r--r-- | gcc/fortran/simplify.c | 60 | ||||
-rw-r--r-- | gcc/fortran/trans-intrinsic.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/int_conv_1.f90 | 36 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/mclock.f90 | 13 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/stat_1.f90 | 22 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/stat_2.f90 | 22 | ||||
-rw-r--r-- | libgfortran/ChangeLog | 12 | ||||
-rw-r--r-- | libgfortran/Makefile.am | 1 | ||||
-rw-r--r-- | libgfortran/Makefile.in | 14 | ||||
-rw-r--r-- | libgfortran/config.h.in | 3 | ||||
-rwxr-xr-x | libgfortran/configure | 3 | ||||
-rw-r--r-- | libgfortran/configure.ac | 2 | ||||
-rw-r--r-- | libgfortran/intrinsics/clock.c | 78 | ||||
-rw-r--r-- | libgfortran/intrinsics/stat.c | 113 |
21 files changed, 540 insertions, 20 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 7940ea5dbca..e863f2d654b 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,25 @@ +2006-07-26 Francois-Xavier Coudert <coudert@clipper.ens.fr> + + * intrinsic.c (add_functions): Add INT2, SHORT, INT8, LONG, + LSTAT, MCLOCK and MCLOCK8 intrinsic functions. + (add_subroutines): Add LSTAT intrinsic subroutine. + * gfortran.h (gfc_generic_isym_id): Add GFC_ISYM_INT2, + GFC_ISYM_INT8, GFC_ISYM_LONG, GFC_ISYM_LSTAT, GFC_ISYM_MCLOCK + and GFC_ISYM_MCLOCK8. + * iresolve.c (gfc_resolve_int2, gfc_resolve_int8, + gfc_resolve_long, gfc_resolve_lstat, gfc_resolve_mclock, + gfc_resolve_mclock8, gfc_resolve_lstat_sub): New functions. + * check.c (gfc_check_intconv): New function. + * trans-intrinsic.c (gfc_conv_intrinsic_function): Add cases for + the added GFC_ISYM_*. + * simplify.c (gfc_simplify_intconv, gfc_simplify_int2, + gfc_simplify_int8, gfc_simplify_long): New functions. + * intrinsic.h (gfc_check_intconv, gfc_simplify_int2, + gfc_simplify_int8, gfc_simplify_long, gfc_resolve_int2, + gfc_resolve_int8, gfc_resolve_long, gfc_resolve_lstat, + gfc_resolve_mclock, gfc_resolve_mclock8, gfc_resolve_lstat_sub): + Add prototypes. + 2006-07-24 Erik Edelmann <eedelman@gcc.gnu.org> PR fortran/28416 @@ -17,7 +39,7 @@ 2006-07-22 Steven Bosscher <steven@gcc.gnu.org> - PR fortran/28439 + PR fortran/28439 * trans-stmt.c (gfc_trans_arithmetic_if): Evaluate the condition once. 2006-07-16 Jakub Jelinek <jakub@redhat.com> diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c index 1332c2bd6aa..4384fdb01cd 100644 --- a/gcc/fortran/check.c +++ b/gcc/fortran/check.c @@ -1200,6 +1200,16 @@ gfc_check_int (gfc_expr * x, gfc_expr * kind) try +gfc_check_intconv (gfc_expr * x) +{ + if (numeric_check (x, 0) == FAILURE) + return FAILURE; + + return SUCCESS; +} + + +try gfc_check_ior (gfc_expr * i, gfc_expr * j) { if (type_check (i, 0, BT_INTEGER) == FAILURE) diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 37d70f393ae..ba73d1d05d0 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -377,6 +377,8 @@ enum gfc_generic_isym_id GFC_ISYM_IERRNO, GFC_ISYM_INDEX, GFC_ISYM_INT, + GFC_ISYM_INT2, + GFC_ISYM_INT8, GFC_ISYM_IOR, GFC_ISYM_IRAND, GFC_ISYM_ISATTY, @@ -391,15 +393,19 @@ enum gfc_generic_isym_id GFC_ISYM_LGT, GFC_ISYM_LLE, GFC_ISYM_LLT, - GFC_ISYM_LOG, GFC_ISYM_LOC, + GFC_ISYM_LOG, GFC_ISYM_LOG10, GFC_ISYM_LOGICAL, + GFC_ISYM_LONG, + GFC_ISYM_LSTAT, GFC_ISYM_MALLOC, GFC_ISYM_MATMUL, GFC_ISYM_MAX, GFC_ISYM_MAXLOC, GFC_ISYM_MAXVAL, + GFC_ISYM_MCLOCK, + GFC_ISYM_MCLOCK8, GFC_ISYM_MERGE, GFC_ISYM_MIN, GFC_ISYM_MINLOC, diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c index 3ee0829f259..1b8e7cdcd28 100644 --- a/gcc/fortran/intrinsic.c +++ b/gcc/fortran/intrinsic.c @@ -1535,6 +1535,26 @@ add_functions (void) make_generic ("int", GFC_ISYM_INT, GFC_STD_F77); + add_sym_1 ("int2", 1, 0, BT_INTEGER, di, GFC_STD_GNU, + gfc_check_intconv, gfc_simplify_int2, gfc_resolve_int2, + a, BT_REAL, dr, REQUIRED); + + make_alias ("short", GFC_STD_GNU); + + make_generic ("int2", GFC_ISYM_INT2, GFC_STD_GNU); + + add_sym_1 ("int8", 1, 0, BT_INTEGER, di, GFC_STD_GNU, + gfc_check_intconv, gfc_simplify_int8, gfc_resolve_int8, + a, BT_REAL, dr, REQUIRED); + + make_generic ("int8", GFC_ISYM_INT8, GFC_STD_GNU); + + add_sym_1 ("long", 1, 0, BT_INTEGER, di, GFC_STD_GNU, + gfc_check_intconv, gfc_simplify_long, gfc_resolve_long, + a, BT_REAL, dr, REQUIRED); + + make_generic ("long", GFC_ISYM_LONG, GFC_STD_GNU); + add_sym_2 ("ior", 1, 1, BT_INTEGER, di, GFC_STD_F95, gfc_check_ior, gfc_simplify_ior, gfc_resolve_ior, i, BT_INTEGER, di, REQUIRED, j, BT_INTEGER, di, REQUIRED); @@ -1679,6 +1699,12 @@ add_functions (void) make_generic ("logical", GFC_ISYM_LOGICAL, GFC_STD_F95); + add_sym_2 ("lstat", 0, 1, BT_INTEGER, di, GFC_STD_GNU, + gfc_check_stat, NULL, gfc_resolve_lstat, + a, BT_CHARACTER, dc, REQUIRED, b, BT_INTEGER, di, REQUIRED); + + make_generic ("lstat", GFC_ISYM_LSTAT, GFC_STD_GNU); + add_sym_1 ("malloc", 0, 1, BT_INTEGER, ii, GFC_STD_GNU, gfc_check_malloc, NULL, gfc_resolve_malloc, a, BT_INTEGER, di, REQUIRED); @@ -1739,6 +1765,16 @@ add_functions (void) make_generic ("maxval", GFC_ISYM_MAXVAL, GFC_STD_F95); + add_sym_0 ("mclock", 1, 0, BT_INTEGER, di, GFC_STD_GNU, + NULL, NULL, gfc_resolve_mclock); + + make_generic ("mclock", GFC_ISYM_MCLOCK, GFC_STD_GNU); + + add_sym_0 ("mclock8", 1, 0, BT_INTEGER, di, GFC_STD_GNU, + NULL, NULL, gfc_resolve_mclock8); + + make_generic ("mclock8", GFC_ISYM_MCLOCK8, GFC_STD_GNU); + add_sym_3 ("merge", 1, 1, BT_REAL, dr, GFC_STD_F95, gfc_check_merge, NULL, gfc_resolve_merge, ts, BT_REAL, dr, REQUIRED, fs, BT_REAL, dr, REQUIRED, @@ -2410,6 +2446,11 @@ add_subroutines (void) ut, BT_INTEGER, di, REQUIRED, vl, BT_INTEGER, di, REQUIRED, st, BT_INTEGER, di, OPTIONAL); + add_sym_3s ("lstat", 0, 1, BT_UNKNOWN, 0, GFC_STD_GNU, + gfc_check_stat_sub, NULL, gfc_resolve_lstat_sub, + name, BT_CHARACTER, dc, REQUIRED, vl, BT_INTEGER, di, REQUIRED, + st, BT_INTEGER, di, OPTIONAL); + add_sym_3s ("stat", 0, 1, BT_UNKNOWN, 0, GFC_STD_GNU, gfc_check_stat_sub, NULL, gfc_resolve_stat_sub, name, BT_CHARACTER, dc, REQUIRED, vl, BT_INTEGER, di, REQUIRED, diff --git a/gcc/fortran/intrinsic.h b/gcc/fortran/intrinsic.h index 63e0ff0fad6..e2a81c82a9a 100644 --- a/gcc/fortran/intrinsic.h +++ b/gcc/fortran/intrinsic.h @@ -74,6 +74,7 @@ try gfc_check_idnint (gfc_expr *); try gfc_check_ieor (gfc_expr *, gfc_expr *); try gfc_check_index (gfc_expr *, gfc_expr *, gfc_expr *); try gfc_check_int (gfc_expr *, gfc_expr *); +try gfc_check_intconv (gfc_expr *); try gfc_check_ior (gfc_expr *, gfc_expr *); try gfc_check_irand (gfc_expr *); try gfc_check_isatty (gfc_expr *); @@ -222,6 +223,9 @@ gfc_expr *gfc_simplify_ichar (gfc_expr *); gfc_expr *gfc_simplify_ieor (gfc_expr *, gfc_expr *); gfc_expr *gfc_simplify_index (gfc_expr *, gfc_expr *, gfc_expr *); gfc_expr *gfc_simplify_int (gfc_expr *, gfc_expr *); +gfc_expr *gfc_simplify_int2 (gfc_expr *); +gfc_expr *gfc_simplify_int8 (gfc_expr *); +gfc_expr *gfc_simplify_long (gfc_expr *); gfc_expr *gfc_simplify_ifix (gfc_expr *); gfc_expr *gfc_simplify_idint (gfc_expr *); gfc_expr *gfc_simplify_ior (gfc_expr *, gfc_expr *); @@ -352,6 +356,9 @@ void gfc_resolve_ieor (gfc_expr *, gfc_expr *, gfc_expr *); void gfc_resolve_ichar (gfc_expr *, gfc_expr *); void gfc_resolve_idnint (gfc_expr *, gfc_expr *); void gfc_resolve_int (gfc_expr *, gfc_expr *, gfc_expr *); +void gfc_resolve_int2 (gfc_expr *, gfc_expr *); +void gfc_resolve_int8 (gfc_expr *, gfc_expr *); +void gfc_resolve_long (gfc_expr *, gfc_expr *); void gfc_resolve_ior (gfc_expr *, gfc_expr *, gfc_expr *); void gfc_resolve_isatty (gfc_expr *, gfc_expr *); void gfc_resolve_ishft (gfc_expr *, gfc_expr *, gfc_expr *); @@ -365,11 +372,14 @@ void gfc_resolve_loc (gfc_expr *, gfc_expr *); void gfc_resolve_log (gfc_expr *, gfc_expr *); void gfc_resolve_log10 (gfc_expr *, gfc_expr *); void gfc_resolve_logical (gfc_expr *, gfc_expr *, gfc_expr *); +void gfc_resolve_lstat (gfc_expr *, gfc_expr *, gfc_expr *); void gfc_resolve_malloc (gfc_expr *, gfc_expr *); void gfc_resolve_matmul (gfc_expr *, gfc_expr *, gfc_expr *); void gfc_resolve_max (gfc_expr *, gfc_actual_arglist *); void gfc_resolve_maxloc (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *); void gfc_resolve_maxval (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *); +void gfc_resolve_mclock (gfc_expr *); +void gfc_resolve_mclock8 (gfc_expr *); void gfc_resolve_merge (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *); void gfc_resolve_min (gfc_expr *, gfc_actual_arglist *); void gfc_resolve_minloc (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *); @@ -448,6 +458,7 @@ void gfc_resolve_get_environment_variable (gfc_code *); void gfc_resolve_hostnm_sub (gfc_code *); void gfc_resolve_idate (gfc_code *); void gfc_resolve_itime (gfc_code *); +void gfc_resolve_lstat_sub (gfc_code *); void gfc_resolve_kill_sub (gfc_code *); void gfc_resolve_mvbits (gfc_code *); void gfc_resolve_perror (gfc_code *); diff --git a/gcc/fortran/iresolve.c b/gcc/fortran/iresolve.c index 3eeebc71c7a..a65992eca2e 100644 --- a/gcc/fortran/iresolve.c +++ b/gcc/fortran/iresolve.c @@ -854,6 +854,42 @@ gfc_resolve_int (gfc_expr * f, gfc_expr * a, gfc_expr * kind) void +gfc_resolve_int2 (gfc_expr * f, gfc_expr * a) +{ + f->ts.type = BT_INTEGER; + f->ts.kind = 2; + + f->value.function.name = + gfc_get_string ("__int_%d_%c%d", f->ts.kind, gfc_type_letter (a->ts.type), + a->ts.kind); +} + + +void +gfc_resolve_int8 (gfc_expr * f, gfc_expr * a) +{ + f->ts.type = BT_INTEGER; + f->ts.kind = 8; + + f->value.function.name = + gfc_get_string ("__int_%d_%c%d", f->ts.kind, gfc_type_letter (a->ts.type), + a->ts.kind); +} + + +void +gfc_resolve_long (gfc_expr * f, gfc_expr * a) +{ + f->ts.type = BT_INTEGER; + f->ts.kind = 4; + + f->value.function.name = + gfc_get_string ("__int_%d_%c%d", f->ts.kind, gfc_type_letter (a->ts.type), + a->ts.kind); +} + + +void gfc_resolve_isatty (gfc_expr * f, gfc_expr * u) { gfc_typespec ts; @@ -1191,6 +1227,24 @@ gfc_resolve_maxval (gfc_expr * f, gfc_expr * array, gfc_expr * dim, void +gfc_resolve_mclock (gfc_expr * f) +{ + f->ts.type = BT_INTEGER; + f->ts.kind = 4; + f->value.function.name = PREFIX("mclock"); +} + + +void +gfc_resolve_mclock8 (gfc_expr * f) +{ + f->ts.type = BT_INTEGER; + f->ts.kind = 8; + f->value.function.name = PREFIX("mclock8"); +} + + +void gfc_resolve_merge (gfc_expr * f, gfc_expr * tsource, gfc_expr * fsource ATTRIBUTE_UNUSED, gfc_expr * mask ATTRIBUTE_UNUSED) @@ -1804,6 +1858,16 @@ gfc_resolve_stat (gfc_expr * f, gfc_expr * n ATTRIBUTE_UNUSED, void +gfc_resolve_lstat (gfc_expr * f, gfc_expr * n ATTRIBUTE_UNUSED, + gfc_expr * a ATTRIBUTE_UNUSED) +{ + f->ts.type = BT_INTEGER; + f->ts.kind = gfc_default_integer_kind; + f->value.function.name = gfc_get_string (PREFIX("lstat_i%d"), f->ts.kind); +} + + +void gfc_resolve_fstat (gfc_expr * f, gfc_expr * n, gfc_expr * a ATTRIBUTE_UNUSED) { f->ts.type = BT_INTEGER; @@ -2656,6 +2720,16 @@ gfc_resolve_stat_sub (gfc_code * c) void +gfc_resolve_lstat_sub (gfc_code * c) +{ + const char *name; + + name = gfc_get_string (PREFIX("lstat_i%d_sub"), gfc_default_integer_kind); + c->resolved_sym = gfc_get_intrinsic_sub_symbol (name); +} + + +void gfc_resolve_fstat_sub (gfc_code * c) { const char *name; diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index b77537cc0a5..8a7d79b4df6 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -1610,6 +1610,66 @@ gfc_simplify_int (gfc_expr * e, gfc_expr * k) } +static gfc_expr * +gfc_simplify_intconv (gfc_expr * e, int kind, const char *name) +{ + gfc_expr *rpart, *rtrunc, *result; + + if (e->expr_type != EXPR_CONSTANT) + return NULL; + + result = gfc_constant_result (BT_INTEGER, kind, &e->where); + + switch (e->ts.type) + { + case BT_INTEGER: + mpz_set (result->value.integer, e->value.integer); + break; + + case BT_REAL: + rtrunc = gfc_copy_expr (e); + mpfr_trunc (rtrunc->value.real, e->value.real); + gfc_mpfr_to_mpz (result->value.integer, rtrunc->value.real); + gfc_free_expr (rtrunc); + break; + + case BT_COMPLEX: + rpart = gfc_complex2real (e, kind); + rtrunc = gfc_copy_expr (rpart); + mpfr_trunc (rtrunc->value.real, rpart->value.real); + gfc_mpfr_to_mpz (result->value.integer, rtrunc->value.real); + gfc_free_expr (rpart); + gfc_free_expr (rtrunc); + break; + + default: + gfc_error ("Argument of %s at %L is not a valid type", name, &e->where); + gfc_free_expr (result); + return &gfc_bad_expr; + } + + return range_check (result, name); +} + +gfc_expr * +gfc_simplify_int2 (gfc_expr * e) +{ + return gfc_simplify_intconv (e, 2, "INT2"); +} + +gfc_expr * +gfc_simplify_int8 (gfc_expr * e) +{ + return gfc_simplify_intconv (e, 8, "INT8"); +} + +gfc_expr * +gfc_simplify_long (gfc_expr * e) +{ + return gfc_simplify_intconv (e, 4, "LONG"); +} + + gfc_expr * gfc_simplify_ifix (gfc_expr * e) { diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index b23fc5f79e7..472d982d902 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -3477,6 +3477,9 @@ gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr) /* Integer conversions are handled separately to make sure we get the correct rounding mode. */ case GFC_ISYM_INT: + case GFC_ISYM_INT2: + case GFC_ISYM_INT8: + case GFC_ISYM_LONG: gfc_conv_intrinsic_int (se, expr, FIX_TRUNC_EXPR); break; @@ -3732,8 +3735,11 @@ gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr) case GFC_ISYM_IRAND: case GFC_ISYM_ISATTY: case GFC_ISYM_LINK: + case GFC_ISYM_LSTAT: case GFC_ISYM_MALLOC: case GFC_ISYM_MATMUL: + case GFC_ISYM_MCLOCK: + case GFC_ISYM_MCLOCK8: case GFC_ISYM_RAND: case GFC_ISYM_RENAME: case GFC_ISYM_SECOND: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 26a25b9680b..5f5bdccda79 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2006-07-26 Francois-Xavier Coudert <coudert@clipper.ens.fr> + + * gfortran.dg/mclock.f90: New test. + * gfortran.dg/int_conv_1.f90: New test. + * gfortran.dg/stat_1.f90: New test. + * gfortran.dg/stat_2.f90: New test. + 2006-07-25 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libgfortran/28335 diff --git a/gcc/testsuite/gfortran.dg/int_conv_1.f90 b/gcc/testsuite/gfortran.dg/int_conv_1.f90 new file mode 100644 index 00000000000..15f71f9336c --- /dev/null +++ b/gcc/testsuite/gfortran.dg/int_conv_1.f90 @@ -0,0 +1,36 @@ +! { dg-do run } +! { dg-options "-std=gnu" } + integer(kind=2) :: i2, j2, k2, l2, m2, n2, o2 + integer(kind=4) :: i4, j4 + integer(kind=8) :: i8, j8 + real :: x + complex :: z + + i2 = huge(i2) / 3 + i8 = int8(i2) + i4 = long(i2) + j2 = short(i2) + k2 = int2(i2) + l2 = int2(i8) + m2 = short(i8) + n2 = int2(i4) + o2 = short(i4) + + if (i8 /= i2 .or. i4 /= i2 .or. j2 /= i2 .or. k2 /= i2 & + .or. l2 /= i2 .or. m2 /= i2 .or. n2 /= i2 .or. o2 /= i2) call abort + + x = i2 + i8 = int8(x) + i4 = long(x) + j2 = short(x) + k2 = int2(x) + if (i8 /= i2 .or. i4 /= i2 .or. j2 /= i2 .or. k2 /= i2) call abort + + z = i2 + (0.,-42.) + i8 = int8(z) + i4 = long(z) + j2 = short(z) + k2 = int2(z) + if (i8 /= i2 .or. i4 /= i2 .or. j2 /= i2 .or. k2 /= i2) call abort + + end diff --git a/gcc/testsuite/gfortran.dg/mclock.f90 b/gcc/testsuite/gfortran.dg/mclock.f90 new file mode 100644 index 00000000000..5af96d0fc9f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/mclock.f90 @@ -0,0 +1,13 @@ +! { dg-do run } +! { dg-options "-std=gnu" } + integer(kind=4) :: i4, j4 + integer(kind=8) :: i8, j8 + + i4 = mclock() + i8 = mclock8() + j4 = mclock() + j8 = mclock8() + + if (i4 > j4 .or. i8 > j8 .or. i4 > i8 .or. j4 > j8) call abort + + end diff --git a/gcc/testsuite/gfortran.dg/stat_1.f90 b/gcc/testsuite/gfortran.dg/stat_1.f90 new file mode 100644 index 00000000000..c8e38815400 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/stat_1.f90 @@ -0,0 +1,22 @@ +! { dg-do run } +! { dg-options "-std=gnu" } + character(len=*), parameter :: f = "testfile" + integer :: s1(13), r1, s2(13), r2, s3(13), r3 + + open (10,file=f) + write (10,"(A)") "foo" + close (10,status="keep") + + open (10,file=f) + call lstat (f, s1, r1) + call stat (f, s2, r2) + call fstat (10, s3, r3) + + if (r1 /= 0 .or. r2 /= 0 .or. r3 /= 0) call abort + if (any (s1 /= s2) .or. any (s1 /= s3)) call abort + if (s1(5) /= getuid()) call abort + if (s1(6) /= getgid()) call abort + if (s1(8) < 3 .or. s1(8) > 5) call abort + + close (10,status="delete") + end diff --git a/gcc/testsuite/gfortran.dg/stat_2.f90 b/gcc/testsuite/gfortran.dg/stat_2.f90 new file mode 100644 index 00000000000..7ebd057239f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/stat_2.f90 @@ -0,0 +1,22 @@ +! { dg-do run } +! { dg-options "-std=gnu" } + character(len=*), parameter :: f = "testfile" + integer :: s1(13), r1, s2(13), r2, s3(13), r3 + + open (10,file=f) + write (10,"(A)") "foo" + close (10,status="keep") + + open (10,file=f) + r1 = lstat (f, s1) + r2 = stat (f, s2) + r3 = fstat (10, s3) + + if (r1 /= 0 .or. r2 /= 0 .or. r3 /= 0) call abort + if (any (s1 /= s2) .or. any (s1 /= s3)) call abort + if (s1(5) /= getuid()) call abort + if (s1(6) /= getgid()) call abort + if (s1(8) < 3 .or. s1(8) > 5) call abort + + close (10,status="delete") + end diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 28923a20113..bc86448feb1 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,15 @@ +2006-07-26 Francois-Xavier Coudert <coudert@clipper.ens.fr> + + * configure.ac: Check for function clock. + * Makefile.am: Compile new file intrinsics/clock.c. + * intrinsics/clock.c: New file. + * Makefile.in: Regenerate. + * configure: Regenerate. + * config.h.in: Regenerate. + * intrinsics/stat.c: Rename the old stat_i?_sub functions to + helper functions stat_i?_sub_0, and use them for both STAT and + LSTAT. + 2006-07-25 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libgfortran/28335 diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am index f7482b74fad..ff1211a7d85 100644 --- a/libgfortran/Makefile.am +++ b/libgfortran/Makefile.am @@ -45,6 +45,7 @@ intrinsics/args.c \ intrinsics/bessel.c \ intrinsics/c99_functions.c \ intrinsics/chdir.c \ +intrinsics/clock.c \ intrinsics/cpu_time.c \ intrinsics/cshift0.c \ intrinsics/ctime.c \ diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in index 761e048e3f8..ba3c3b0e2a6 100644 --- a/libgfortran/Makefile.in +++ b/libgfortran/Makefile.in @@ -162,11 +162,11 @@ am__objects_29 = close.lo file_pos.lo format.lo inquire.lo \ list_read.lo lock.lo open.lo read.lo size_from_kind.lo \ transfer.lo unit.lo unix.lo write.lo am__objects_30 = associated.lo abort.lo args.lo bessel.lo \ - c99_functions.lo chdir.lo cpu_time.lo cshift0.lo ctime.lo \ - date_and_time.lo env.lo erf.lo eoshift0.lo eoshift2.lo \ - etime.lo exit.lo fget.lo flush.lo fnum.lo ftell.lo gerror.lo \ - getcwd.lo getlog.lo getXid.lo hyper.lo hostnm.lo kill.lo \ - ierrno.lo ishftc.lo link.lo malloc.lo mvbits.lo \ + c99_functions.lo chdir.lo clock.lo cpu_time.lo cshift0.lo \ + ctime.lo date_and_time.lo env.lo erf.lo eoshift0.lo \ + eoshift2.lo etime.lo exit.lo fget.lo flush.lo fnum.lo ftell.lo \ + gerror.lo getcwd.lo getlog.lo getXid.lo hyper.lo hostnm.lo \ + kill.lo ierrno.lo ishftc.lo link.lo malloc.lo mvbits.lo \ pack_generic.lo perror.lo signal.lo size.lo sleep.lo \ spread_generic.lo string_intrinsics.lo system.lo rand.lo \ random.lo rename.lo reshape_generic.lo reshape_packed.lo \ @@ -389,6 +389,7 @@ intrinsics/args.c \ intrinsics/bessel.c \ intrinsics/c99_functions.c \ intrinsics/chdir.c \ +intrinsics/clock.c \ intrinsics/cpu_time.c \ intrinsics/cshift0.c \ intrinsics/ctime.c \ @@ -2215,6 +2216,9 @@ c99_functions.lo: intrinsics/c99_functions.c chdir.lo: intrinsics/chdir.c $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o chdir.lo `test -f 'intrinsics/chdir.c' || echo '$(srcdir)/'`intrinsics/chdir.c +clock.lo: intrinsics/clock.c + $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clock.lo `test -f 'intrinsics/clock.c' || echo '$(srcdir)/'`intrinsics/clock.c + cpu_time.lo: intrinsics/cpu_time.c $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpu_time.lo `test -f 'intrinsics/cpu_time.c' || echo '$(srcdir)/'`intrinsics/cpu_time.c diff --git a/libgfortran/config.h.in b/libgfortran/config.h.in index 29faefdd1ac..573c0938f07 100644 --- a/libgfortran/config.h.in +++ b/libgfortran/config.h.in @@ -150,6 +150,9 @@ /* Define to 1 if you have the `chsize' function. */ #undef HAVE_CHSIZE +/* Define to 1 if you have the `clock' function. */ +#undef HAVE_CLOCK + /* libm includes clog */ #undef HAVE_CLOG diff --git a/libgfortran/configure b/libgfortran/configure index ee018ad732a..6cb118b88e2 100755 --- a/libgfortran/configure +++ b/libgfortran/configure @@ -9975,7 +9975,8 @@ done -for ac_func in sleep time ttyname signal alarm ctime + +for ac_func in sleep time ttyname signal alarm ctime clock do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac index 4742882815f..51756597d03 100644 --- a/libgfortran/configure.ac +++ b/libgfortran/configure.ac @@ -171,7 +171,7 @@ AC_CHECK_MEMBERS([struct stat.st_rdev]) # Check for library functions. AC_CHECK_FUNCS(getrusage times mkstemp strtof strtold snprintf ftruncate chsize) AC_CHECK_FUNCS(chdir strerror getlogin gethostname kill link symlink perror) -AC_CHECK_FUNCS(sleep time ttyname signal alarm ctime) +AC_CHECK_FUNCS(sleep time ttyname signal alarm ctime clock) # Check libc for getgid, getpid, getuid AC_CHECK_LIB([c],[getgid],[AC_DEFINE([HAVE_GETGID],[1],[libc includes getgid])]) diff --git a/libgfortran/intrinsics/clock.c b/libgfortran/intrinsics/clock.c new file mode 100644 index 00000000000..73e50634e36 --- /dev/null +++ b/libgfortran/intrinsics/clock.c @@ -0,0 +1,78 @@ +/* Implementation of the MCLOCK and MCLOCK8 g77 intrinsics. + Copyright (C) 2006 Free Software Foundation, Inc. + Contributed by François-Xavier Coudert <coudert@clipper.ens.fr> + +This file is part of the GNU Fortran 95 runtime library (libgfortran). + +Libgfortran is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +In addition to the permissions in the GNU General Public License, the +Free Software Foundation gives you unlimited permission to link the +compiled version of this file into combinations with other programs, +and to distribute those combinations without any restriction coming +from the use of this file. (The General Public License restrictions +do apply in other respects; for example, they cover modification of +the file, and distribution when not linked into a combine +executable.) + +Libgfortran is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public +License along with libgfortran; see the file COPYING. If not, +write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ + +#include "config.h" +#include "libgfortran.h" + +#ifdef TIME_WITH_SYS_TIME +# include <sys/time.h> +# include <time.h> +#else +# if HAVE_SYS_TIME_H +# include <sys/time.h> +# else +# ifdef HAVE_TIME_H +# include <time.h> +# endif +# endif +#endif + + +/* INTEGER(KIND=4) FUNCTION MCLOCK() */ + +extern GFC_INTEGER_4 mclock (void); +export_proto(mclock); + +GFC_INTEGER_4 +mclock (void) +{ +#ifdef HAVE_CLOCK + return (GFC_INTEGER_4) clock (); +#else + return (GFC_INTEGER_4) -1; +#endif +} + + +/* INTEGER(KIND=8) FUNCTION MCLOCK8() */ + +extern GFC_INTEGER_8 mclock8 (void); +export_proto(mclock8); + +GFC_INTEGER_8 +mclock8 (void) +{ +#ifdef HAVE_CLOCK + return (GFC_INTEGER_8) clock (); +#else + return (GFC_INTEGER_8) -1; +#endif +} + diff --git a/libgfortran/intrinsics/stat.c b/libgfortran/intrinsics/stat.c index 98511640f56..150387dad5b 100644 --- a/libgfortran/intrinsics/stat.c +++ b/libgfortran/intrinsics/stat.c @@ -59,13 +59,13 @@ Boston, MA 02110-1301, USA. */ CHARACTER(len=*), INTENT(IN) :: FILE INTEGER, INTENT(OUT), :: SARRAY(13) */ -extern void stat_i4_sub (char *, gfc_array_i4 *, GFC_INTEGER_4 *, - gfc_charlen_type); -iexport_proto(stat_i4_sub); +/*extern void stat_i4_sub_0 (char *, gfc_array_i4 *, GFC_INTEGER_4 *, + gfc_charlen_type, int); +internal_proto(stat_i4_sub_0);*/ -void -stat_i4_sub (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status, - gfc_charlen_type name_len) +static void +stat_i4_sub_0 (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status, + gfc_charlen_type name_len, int is_lstat) { int val; char *str; @@ -88,7 +88,10 @@ stat_i4_sub (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status, memcpy (str, name, name_len); str[name_len] = '\0'; - val = stat(str, &sb); + if (is_lstat) + val = lstat(str, &sb); + else + val = stat(str, &sb); if (val == 0) { @@ -147,16 +150,39 @@ stat_i4_sub (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status, if (status != NULL) *status = (val == 0) ? 0 : errno; } + + +extern void stat_i4_sub (char *, gfc_array_i4 *, GFC_INTEGER_4 *, + gfc_charlen_type); +iexport_proto(stat_i4_sub); + +void +stat_i4_sub (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status, + gfc_charlen_type name_len) +{ + stat_i4_sub_0 (name, sarray, status, name_len, 0); +} iexport(stat_i4_sub); -extern void stat_i8_sub (char *, gfc_array_i8 *, GFC_INTEGER_8 *, + +extern void lstat_i4_sub (char *, gfc_array_i4 *, GFC_INTEGER_4 *, gfc_charlen_type); -iexport_proto(stat_i8_sub); +iexport_proto(lstat_i4_sub); void -stat_i8_sub (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status, +lstat_i4_sub (char *name, gfc_array_i4 *sarray, GFC_INTEGER_4 *status, gfc_charlen_type name_len) { + stat_i4_sub_0 (name, sarray, status, name_len, 1); +} +iexport(lstat_i4_sub); + + + +static void +stat_i8_sub_0 (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status, + gfc_charlen_type name_len, int is_lstat) +{ int val; char *str; struct stat sb; @@ -178,7 +204,10 @@ stat_i8_sub (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status, memcpy (str, name, name_len); str[name_len] = '\0'; - val = stat(str, &sb); + if (is_lstat) + val = lstat(str, &sb); + else + val = stat(str, &sb); if (val == 0) { @@ -237,8 +266,36 @@ stat_i8_sub (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status, if (status != NULL) *status = (val == 0) ? 0 : errno; } + + +extern void stat_i8_sub (char *, gfc_array_i8 *, GFC_INTEGER_8 *, + gfc_charlen_type); +iexport_proto(stat_i8_sub); + +void +stat_i8_sub (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status, + gfc_charlen_type name_len) +{ + stat_i8_sub_0 (name, sarray, status, name_len, 0); +} + iexport(stat_i8_sub); + +extern void lstat_i8_sub (char *, gfc_array_i8 *, GFC_INTEGER_8 *, + gfc_charlen_type); +iexport_proto(lstat_i8_sub); + +void +lstat_i8_sub (char *name, gfc_array_i8 *sarray, GFC_INTEGER_8 *status, + gfc_charlen_type name_len) +{ + stat_i8_sub_0 (name, sarray, status, name_len, 1); +} + +iexport(lstat_i8_sub); + + extern GFC_INTEGER_4 stat_i4 (char *, gfc_array_i4 *, gfc_charlen_type); export_proto(stat_i4); @@ -262,6 +319,40 @@ stat_i8 (char *name, gfc_array_i8 *sarray, gfc_charlen_type name_len) } +/* SUBROUTINE STAT(FILE, SARRAY, STATUS) + CHARACTER(len=*), INTENT(IN) :: FILE + INTEGER, INTENT(OUT), :: SARRAY(13) + INTEGER, INTENT(OUT), OPTIONAL :: STATUS + + FUNCTION STAT(FILE, SARRAY) + INTEGER STAT + CHARACTER(len=*), INTENT(IN) :: FILE + INTEGER, INTENT(OUT), :: SARRAY(13) */ + +extern GFC_INTEGER_4 lstat_i4 (char *, gfc_array_i4 *, gfc_charlen_type); +export_proto(lstat_i4); + +GFC_INTEGER_4 +lstat_i4 (char *name, gfc_array_i4 *sarray, gfc_charlen_type name_len) +{ + GFC_INTEGER_4 val; + lstat_i4_sub (name, sarray, &val, name_len); + return val; +} + +extern GFC_INTEGER_8 lstat_i8 (char *, gfc_array_i8 *, gfc_charlen_type); +export_proto(lstat_i8); + +GFC_INTEGER_8 +lstat_i8 (char *name, gfc_array_i8 *sarray, gfc_charlen_type name_len) +{ + GFC_INTEGER_8 val; + lstat_i8_sub (name, sarray, &val, name_len); + return val; +} + + + /* SUBROUTINE FSTAT(UNIT, SARRAY, STATUS) INTEGER, INTENT(IN) :: UNIT INTEGER, INTENT(OUT) :: SARRAY(13) |