[PATCH] Fortran: Remove double spaces in open() warning [PR99884]
From: Bernhard Reutner-Fischer gcc/fortran/ChangeLog: PR fortran/99884 * io.c (check_open_constraints): Remove double spaces. --- gcc/fortran/io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c index fc97df79eca..9506f35008e 100644 --- a/gcc/fortran/io.c +++ b/gcc/fortran/io.c @@ -2513,7 +2513,7 @@ check_open_constraints (gfc_open *open, locus *where) spec = ""; } - warn_or_error (G_("%s specifier at %L not allowed in OPEN statement for " + warn_or_error (G_("%sspecifier at %L not allowed in OPEN statement for " "unformatted I/O"), spec, loc); } -- 2.33.0
[RFC] User-visible changes for powerpc64-le-linux ABI changes
Hi, I have put together a summary of what users should see as a change. I've made this a diff against the current documentation. This is an RFC, please feel free to suggest any changes. I have put in a few remarks among the diff. If there is general agreement that this is the best way forward, then we can proceed along those lines. Best regards Thomas iff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi index a54153b0951..89319a7836f 100644 --- a/gcc/fortran/gfortran.texi +++ b/gcc/fortran/gfortran.texi @@ -604,7 +604,7 @@ Malformed environment variables are silently ignored. * GFORTRAN_SHOW_LOCUS:: Show location for runtime errors * GFORTRAN_OPTIONAL_PLUS:: Print leading + where permitted * GFORTRAN_LIST_SEPARATOR:: Separator for list output -* GFORTRAN_CONVERT_UNIT:: Set endianness for unformatted I/O +* GFORTRAN_CONVERT_UNIT:: Set conversion for unformatted I/O * GFORTRAN_ERROR_BACKTRACE:: Show backtrace on run-time errors * GFORTRAN_FORMATTED_BUFFER_SIZE:: Buffer size for formatted files * GFORTRAN_UNFORMATTED_BUFFER_SIZE:: Buffer size for unformatted files @@ -701,18 +701,25 @@ when @command{a.out} is the compiled Fortran program that you want to run. Default is a single space. @node GFORTRAN_CONVERT_UNIT -@section @env{GFORTRAN_CONVERT_UNIT}---Set endianness for unformatted I/O +@section @env{GFORTRAN_CONVERT_UNIT}---Set conversion for unformatted I/O By setting the @env{GFORTRAN_CONVERT_UNIT} variable, it is possible to change the representation of data for unformatted files. -The syntax for the @env{GFORTRAN_CONVERT_UNIT} variable is: +The syntax for the @env{GFORTRAN_CONVERT_UNIT} variable for +systems is: @smallexample GFORTRAN_CONVERT_UNIT: mode | mode ';' exception | exception ; -mode: 'native' | 'swap' | 'big_endian' | 'little_endian' ; +mode: 'native' | 'swap' | 'big_endian' | 'little_endian' | power_mode; +power_mode: 'r16_ieee' | 'native+r16_ieee' | 'swap+r16_ieee' +| 'big_endian+r16_ieee' | 'little_endian+r16_ieee' +| 'r16_ibm' | 'native+r16_ibm' | 'swap+r16_ibm' +| 'big_endian+r16_ibm' | 'little_endian+r16_ibm' exception: mode ':' unit_list | unit_list ; -unit_list: unit_spec | unit_list unit_spec ; +unit_list: unit_spec | unit_list ',' unit_spec ; unit_spec: INTEGER | INTEGER '-' INTEGER ; @end smallexample +where @code{power_mode} is valid on POWER systems only. + The variable consists of an optional default mode, followed by a list of optional exceptions, which are separated by semicolons from the preceding default and each other. Each exception consists @@ -726,6 +733,44 @@ the modes are the same as for the @code{CONVERT} specifier: for unformatted files. @item @code{BIG_ENDIAN} Use the big-endian format for unformatted files. @end itemize + +For POWER systems, additionally the options +@itemize @w{} +@item @code{R16_IEEE} Use IEEE 128-bit format for @code{REAL(KIND=16)}. +@item @code{NATIVE+R16_IEEE} Use IEEE 128-bit format for @code{REAL(KIND=16)}. +@item @code{SWAP+R16_IEEE} Swap between little- and big-endian, +use IEEE 128-bit format for @code{REAL(KIND=16)}. +@item @code{LITTLE_ENDIAN+R16_IEEE} Use the little-endian format for +unformatted files, use IEEE 128-bit format for @code{REAL(KIND=16)}. +@item @code{BIG_ENDIAN+R16_IEEE} Use the big-endian format for +unformatted files, use IEEE 128-bit format for @code{REAL(KIND=16)}. +@item @code{R16_IEEE} Use IEEE 128-bit format for @code{REAL(KIND=16)}. +@item @code{NATIVE+R16_IEEE} Use IEEE 128-bit format for @code{REAL(KIND=16)}. +@item @code{SWAP+R16_IEEE} Swap between little- and big-endian, +use IEEE 128-bit format for @code{REAL(KIND=16)}. +@item @code{LITTLE_ENDIAN+R16_IEEE} Use the little-endian format for +unformatted files, use IEEE 128-bit format for @code{REAL(KIND=16)}. +@item @code{BIG_ENDIAN+R16_IEEE} Use the big-endian format for +unformatted files, use IEEE 128-bit format for @code{REAL(KIND=16)}. +@item @code{R16_IBM} Use IBM 128-bit format for @code{REAL(KIND=16)}. +@item @code{NATIVE+R16_IBM} Use IBM 128-bit format for @code{REAL(KIND=16)}. +@item @code{SWAP+R16_IBM} Swap between little- and big-endian, +use IBM 128-bit format for @code{REAL(KIND=16)}. +@item @code{LITTLE_ENDIAN+R16_IBM} Use the little-endian format for +unformatted files, use IBM 128-bit format for @code{REAL(KIND=16)}. +@item @code{BIG_ENDIAN+R16_IBM} Use the big-endian format for +unformatted files, use IBM 128-bit format for @code{REAL(KIND=16)}. +@item @code{R16_IBM} Use IBM 128-bit format for @code{REAL(KIND=16)}. +@item @code{NATIVE+R16_IBM} Use IBM 128-bit format for @code{REAL(KIND=16)}. +@item @code{SWAP+R16_IBM} Swap between little- and big-endian, +use IBM 128-bit format for @code{REAL(KIND=16)}. +@item @code{LITTLE_ENDIAN+R16_IBM} Use the little-endian format for +unformatted files, use IBM 128-bit format for @code{REAL(KIND=16)}. +@item @code{BIG_ENDIAN+R16_IBM} Use the big-endian format for +unformatted files, use IBM 128-bit fo
[PATCH] Fortran: Silence -Wmaybe-uninitialized warning
From: Bernhard Reutner-Fischer gcc/fortran/ChangeLog: * resolve.c (resolve_fl_procedure): Initialize allocatable_or_pointer. --- fortran/resolve.c: In function 'bool resolve_fl_procedure(gfc_symbol*, int)': fortran/resolve.c:13391:7: warning: 'allocatable_or_pointer' may be used uninitialized in this function [-Wmaybe-uninitialized] 13390 | if (sym->attr.elemental && sym->result | ~~ 13391 | && allocatable_or_pointer) | ^ .../fortran/resolve.c:13197:8: note: 'allocatable_or_pointer' was declared here 13197 | bool allocatable_or_pointer; |^~ Bootstrapped and regtested without regressions. Ok for trunk? --- gcc/fortran/resolve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 8da396b32ec..21126cba262 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -13179,7 +13179,7 @@ static bool resolve_fl_procedure (gfc_symbol *sym, int mp_flag) { gfc_formal_arglist *arg; - bool allocatable_or_pointer; + bool allocatable_or_pointer = false; if (sym->attr.function && !resolve_fl_var_and_proc (sym, mp_flag)) -- 2.33.0
Re: [PATCH] Fortran: Silence -Wmaybe-uninitialized warning
Hi Bernhard, gcc/fortran/ChangeLog: * resolve.c (resolve_fl_procedure): Initialize allocatable_or_pointer. Looking at the code, it is clear that this is a false positive, or a false maybe, but the semantics of C/C++ may well indicate that sym->result could change, although it clearly does not. So, OK. Thanks for the patch! Best regards Thomas
[PATCH] Fortran: Missing error with IMPLICIT none (external) [PR100972]
From: Bernhard Reutner-Fischer gcc/fortran/ChangeLog: PR fortran/100972 * decl.c (gfc_match_implicit_none): Fix typo in warning. * resolve.c (resolve_unknown_f): Reject external procedures without explicit EXTERNAL attribute whe IMPLICIT none (external) is in effect. gcc/testsuite/ChangeLog: PR fortran/100972 * gfortran.dg/implicit_14.f90: Adjust error. * gfortran.dg/external_implicit_none_3.f08: New test. --- As Gerhard Steinmetz noticed, gfc_match_implicit_none() had a notify_std that mentioned IMPORT instead of IMPLICIT. Fix that typo. IMPLICIT NONE (external) is supposed to require external procedures to be explicitly declared with EXTERNAL. We cannot do this when parsing in e.g. gfc_match_rvalue->gfc_match_varspec because the procedure might live way down in a CONTAINS like in bind-c-contiguous-3.f90. Hence diagnose missing EXTERNAL declaraions when resolving. Bootstrapped and regtested on x86_64-unknown-linux without regressions. Ok for trunk? --- gcc/fortran/decl.c | 2 +- gcc/fortran/resolve.c | 13 + .../gfortran.dg/external_implicit_none_3.f08| 17 + gcc/testsuite/gfortran.dg/implicit_14.f90 | 2 +- 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/external_implicit_none_3.f08 diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index e9e23fe1acb..ab88ab5e9c1 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -4715,7 +4715,7 @@ gfc_match_implicit_none (void) if (c == '(') { (void) gfc_next_ascii_char (); - if (!gfc_notify_std (GFC_STD_F2018, "IMPORT NONE with spec list at %C")) + if (!gfc_notify_std (GFC_STD_F2018, "IMPLICIT NONE with spec list at %C")) return MATCH_ERROR; gfc_gobble_whitespace (); diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 21126cba262..1f4abd08720 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -2974,6 +2974,19 @@ resolve_unknown_f (gfc_expr *expr) return false; } + /* IMPLICIT NONE (external) procedures require an explicit EXTERNAL attr. */ + /* Intrinsics were handled above, only non-intrinsics left here. */ + if (sym->attr.flavor == FL_PROCEDURE + && sym->attr.implicit_type + && sym->ns + && sym->ns->has_implicit_none_export) +{ + gfc_error ("Missing explicit declaration with EXTERNAL attribute " + "for symbol %qs at %L", sym->name, &sym->declared_at); + sym->error = 1; + return false; +} + /* The reference is to an external name. */ sym->attr.proc = PROC_EXTERNAL; diff --git a/gcc/testsuite/gfortran.dg/external_implicit_none_3.f08 b/gcc/testsuite/gfortran.dg/external_implicit_none_3.f08 new file mode 100644 index 000..329deedc413 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/external_implicit_none_3.f08 @@ -0,0 +1,17 @@ +! { dg-do compile } +! { dg-options "-std=f2018" } +! Tests fix for PR100972 - Fails to warn about missing EXTERNAL attribute +! Contributed by Gerhard Steinmetz + +program p + implicit none (external) + real, external :: f + real :: a + real :: b + integer :: i + character :: c + a = f() ! OK + b = g() ! { dg-error "Missing explicit declaration with EXTERNAL attribute" } + i = h() ! { dg-error "Missing explicit declaration with EXTERNAL attribute" } + c = j() ! { dg-error "Missing explicit declaration with EXTERNAL attribute" } +end diff --git a/gcc/testsuite/gfortran.dg/implicit_14.f90 b/gcc/testsuite/gfortran.dg/implicit_14.f90 index 8282c1f1f86..422d913fd4f 100644 --- a/gcc/testsuite/gfortran.dg/implicit_14.f90 +++ b/gcc/testsuite/gfortran.dg/implicit_14.f90 @@ -4,5 +4,5 @@ ! Support Fortran 2018's IMPLICIT NONE with spec list ! (currently implemented as vendor extension) -implicit none (type) ! { dg-error "Fortran 2018: IMPORT NONE with spec list at \\(1\\)" } +implicit none (type) ! { dg-error "Fortran 2018: IMPLICIT NONE with spec list at \\(1\\)" } end -- 2.33.0
Re: [PATCH] Fortran: Silence -Wmaybe-uninitialized warning
On Sun, 31 Oct 2021 18:05:36 +0100 Thomas Koenig wrote: > Hi Bernhard, > > > gcc/fortran/ChangeLog: > > > > * resolve.c (resolve_fl_procedure): Initialize > > allocatable_or_pointer. > > Looking at the code, it is clear that this is a false > positive, or a false maybe, but the semantics of C/C++ > may well indicate that sym->result could change, although > it clearly does not. Agree wholeheartedly > > So, OK. pushed as r12-4811 > > Thanks for the patch! I have to thank you for the quick review! cheers,
Re: [PATCH,FORTRAN] Fix memory leak of gsymbol
Am 30.10.21 um 23:51 schrieb Bernhard Reutner-Fischer via Fortran: The only caller is translate_all_program_units. Since we free only module gsyms, even -fdump-fortran-global is unaffected by this, fwiw. AFAICS we do not have a test for -fdump-fortran-global Do we want to add one, would the attached be OK? This doesn't seem to test anything new or changed, or a bug fixed. I get the same result for all version from 9 to 12-mainline. So as is it seems pointless. thanks,
[PATCH] Fortran: Diagnose all operands with constraint violations [PR101337]
From: Bernhard Reutner-Fischer PR fortran/101337 gcc/fortran/ChangeLog: * resolve.c (resolve_operator): Continue resolving on op2 error. --- The PR rightfully notes that we only diagnose the right operator and do not check the left operator if the right one was faulty. c407b-2 is one of the testcases with respective XFAILs. Since that testcase is rather big (and full of errors) i'm listing an abbreviated version here, including the output we'd generate with the attached patch. Note: I did not address the XFAILs! Sandra, please take over if you like the patch! Bootstrapped and regtested without new regressions (XFAILs are apparently ignored and not flagged if they are auto-fixed). As said, Sandra please take over, i'm deleting this locally. $ cat c407b-2-b.f90;echo EOF; gfortran -c c407b-2-b.f90 subroutine s2 (x, y) implicit none type(*) :: x, y integer :: i ! relational operations if (x & ! { dg-error "Assumed.type" "pr101337, failure to diagnose both operands" { xfail *-*-*} } .eq. y) then ! { dg-error "Assumed.type" } return end if if (.not. (x & ! { dg-error "Assumed.type" "pr101337, failure to diagnose both operands" { xfail *-*-*} } .ne. y)) then ! { dg-error "Assumed.type" } return end if i = (x & ! { dg-error "Assumed.type" "pr101337, failure to diagnose both operands" { xfail *-*-*} } + y) ! { dg-error "Assumed.type" } end subroutine EOF c407b-2-b.f90:8:10: 8 | .eq. y) then ! { dg-error "Assumed.type" } | 1 Error: Assumed-type variable y at (1) may only be used as actual argument c407b-2-b.f90:7:6: 7 | if (x & ! { dg-error "Assumed.type" "pr101337, failure to diagnose both operands" { xfail *-*-*} } | 1 Error: Assumed-type variable x at (1) may only be used as actual argument c407b-2-b.f90:12:17: 12 | .ne. y)) then ! { dg-error "Assumed.type" } | 1 Error: Assumed-type variable y at (1) may only be used as actual argument c407b-2-b.f90:11:13: 11 | if (.not. (x & ! { dg-error "Assumed.type" "pr101337, failure to diagnose both operands" { xfail *-*-*} } | 1 Error: Assumed-type variable x at (1) may only be used as actual argument c407b-2-b.f90:16:10: 16 |+ y) ! { dg-error "Assumed.type" } | 1 Error: Assumed-type variable y at (1) may only be used as actual argument c407b-2-b.f90:15:7: 15 | i = (x & ! { dg-error "Assumed.type" "pr101337, failure to diagnose both operands" { xfail *-*-*} } | 1 Error: Assumed-type variable x at (1) may only be used as actual argument --- gcc/fortran/resolve.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 1f4abd08720..705d2326a29 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -4064,7 +4064,7 @@ resolve_operator (gfc_expr *e) { default: if (!gfc_resolve_expr (e->value.op.op2)) - return false; + t = false; /* Fall through. */ @@ -4091,6 +4091,9 @@ resolve_operator (gfc_expr *e) op2 = e->value.op.op2; if (op1 == NULL && op2 == NULL) return false; + /* Error out if op2 did not resolve. We already diagnosed op1. */ + if (t == false) +return false; dual_locus_error = false; -- 2.33.0
Re: [PATCH,FORTRAN] Fix memory leak of gsymbol
On Sun, 31 Oct 2021 20:46:07 +0100 Harald Anlauf wrote: > Am 30.10.21 um 23:51 schrieb Bernhard Reutner-Fischer via Fortran: > >>> The only caller is translate_all_program_units. > >>> Since we free only module gsyms, even -fdump-fortran-global is > >>> unaffected by this, fwiw. > > > > AFAICS we do not have a test for -fdump-fortran-global > > Do we want to add one, would the attached be OK? > > This doesn't seem to test anything new or changed, or a bug fixed. > I get the same result for all version from 9 to 12-mainline. > So as is it seems pointless. Yes indeed, it just adds coverage to that functionality which we did not exercise before. TBH i only found that option when looking around translate_all_program_units. I've never actually used that option myself and cannot imagine how it is useful at all :) Dropped the testcase. Thanks for your comment! cheers,
[PATCH] PR fortran/102715 - [12 Regression] ICE in gfc_simplify_transpose, at fortran/simplify.c:8184
Dear Fortranners, the fix for initialization of DT arrays caused an apparent regression for cases where inconsistent ranks were used in such an initialization. This caused either an ICE in subsequent uses of these arrays, or showed up in valgrind as invalid reads, all of which seemed to be related to this rank mismatch. The cleanest solution seems to be to strictly reject rank mismatch earlier than we used to, which helps error recovery. I had to adjust one testcase accordingly. The place I inserted the check does not distinguish between explicit shape and implied shape. The Intel compiler does give a slightly different error message for the implied shape case. If anyone feels strongly about this, I'm open to suggestions for better choices of handling this. Regtested on x86_64-pc-linux-gnu. OK for mainline / affected branches? Thanks, Harald commit b1b5e5da928accfe02a7289a331cbea815255a16 Author: Harald Anlauf Date: Sun Oct 31 22:20:01 2021 +0100 Fortran: error recovery on rank mismatch of array and its initializer gcc/fortran/ChangeLog: PR fortran/102715 * decl.c (add_init_expr_to_sym): Reject rank mismatch between array and its initializer. gcc/testsuite/ChangeLog: PR fortran/102715 * gfortran.dg/pr68019.f90: Adjust error message. * gfortran.dg/pr102715.f90: New test. diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index 2788348d1be..141fdef8c61 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -2105,6 +2105,14 @@ add_init_expr_to_sym (const char *name, gfc_expr **initp, locus *var_locus) } } + if (sym->attr.flavor == FL_PARAMETER && sym->attr.dimension && sym->as + && sym->as->rank && init->rank && init->rank != sym->as->rank) + { + gfc_error ("Rank mismatch of array at %L and its initializer " + "(%d/%d)", &sym->declared_at, sym->as->rank, init->rank); + return false; + } + /* If sym is implied-shape, set its upper bounds from init. */ if (sym->attr.flavor == FL_PARAMETER && sym->attr.dimension && sym->as->type == AS_IMPLIED_SHAPE) diff --git a/gcc/testsuite/gfortran.dg/pr102715.f90 b/gcc/testsuite/gfortran.dg/pr102715.f90 new file mode 100644 index 000..7b29a1c05a6 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr102715.f90 @@ -0,0 +1,13 @@ +! { dg-do compile } +! PR fortran/102715 - ICE in gfc_simplify_transpose + +program p + type t + end type + type(t), parameter :: a(4) = t() + type(t), parameter :: b(2,2) = reshape(a, [2]) ! { dg-error "Rank mismatch" } + type(t), parameter :: c(2,2) = transpose(b)! { dg-error "must be of rank 2" } + type(t), parameter :: s2(*) = b(2,:) ! { dg-error "Syntax error" } + type(t), parameter :: x(*,*) = reshape(a, [2]) ! { dg-error "Rank mismatch" } + type(t), parameter :: s3(*) = x(2,:) ! { dg-error "Syntax error" } +end diff --git a/gcc/testsuite/gfortran.dg/pr68019.f90 b/gcc/testsuite/gfortran.dg/pr68019.f90 index 2e304c3a260..77fd55bd331 100644 --- a/gcc/testsuite/gfortran.dg/pr68019.f90 +++ b/gcc/testsuite/gfortran.dg/pr68019.f90 @@ -9,5 +9,5 @@ program p integer :: n end type type(t), parameter :: vec(*) = [(t(i), i = 1, 4)] - type(t), parameter :: arr(*) = reshape(vec, [2, 2]) ! { dg-error "ranks 1 and 2 in assignment" } + type(t), parameter :: arr(*) = reshape(vec, [2, 2]) ! { dg-error "Rank mismatch" } end
Re: [PATCH,FORTRAN 28/29] Free type-bound procedure structs
On Fri, 29 Oct 2021 22:09:07 +0200 Bernhard Reutner-Fischer wrote: > On Fri, 29 Oct 2021 21:36:26 +0200 > Harald Anlauf via Gcc-patches wrote: > > > Dear Bernhard, all, > > > > Am 29.10.21 um 02:05 schrieb Bernhard Reutner-Fischer via Gcc-patches: > > > > >> diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c > > >> index 53c760a6c38..cde34c67482 100644 > > >> --- a/gcc/fortran/symbol.c > > >> +++ b/gcc/fortran/symbol.c > > > > >> @@ -5052,7 +5052,7 @@ gfc_get_typebound_proc (gfc_typebound_proc *tb0) > > >> > > >> result = XCNEW (gfc_typebound_proc); > > >> if (tb0) > > >> -*result = *tb0; > > >> +memcpy (result, tb0, sizeof (gfc_typebound_proc));; > > >> result->error = 1; > > >> > > >> latest_undo_chgset->tbps.safe_push (result); > > > > > > > > > > please forgive me, but frankly speaking, I don't like this change. > > > > It seems to serve no obvious purpose other than obfuscating the code > > and defeating the compiler's ability to detect type mismatches. > > mhm okay. > > > > I would not have OKed that part of the patch. I reverted this hunk. thanks,
Re: [PATCH] Fortran: Diagnose all operands with constraint violations [PR101337]
On 10/31/21 1:50 PM, Bernhard Reutner-Fischer wrote: From: Bernhard Reutner-Fischer PR fortran/101337 gcc/fortran/ChangeLog: * resolve.c (resolve_operator): Continue resolving on op2 error. --- The PR rightfully notes that we only diagnose the right operator and do not check the left operator if the right one was faulty. c407b-2 is one of the testcases with respective XFAILs. Since that testcase is rather big (and full of errors) i'm listing an abbreviated version here, including the output we'd generate with the attached patch. Note: I did not address the XFAILs! Sandra, please take over if you like the patch! Bootstrapped and regtested without new regressions (XFAILs are apparently ignored and not flagged if they are auto-fixed). As said, Sandra please take over, i'm deleting this locally. OK, I will take a look at the test results once I reach a good stopping point with the other thing I am hacking at present. -Sandra