1 (edited by JohnWasilewski 2014-01-21 15:55:50)

Topic: Strange GFortran problem suppressing CR

I'm having great trouble with a short bit of Fortran code.

I have a library subroutine coded as follows.
Its purpose is to indent a line in readiness for further output.
The variable, LU, is the file unit of an open write file.


      SUBROUTINE INDENT(LU,nTAB)
C     --------------------------------------
C     Indent LU
C     jw / 13.08.04
C     jw / 21.01.14  last rev.

      INTEGER   nTAB

      DO iTAB=1,nTAB
C        WRITE (LU,'('' '',$)')
C        WRITE (LU,'('' '',$)')
C        WRITE (LU,'(A)', ADVANCE = 'NO') ' '
          WRITE (LU,'(A,$)') ' '
      END DO

      RETURN
      END

As will be apparent from the above, I've made four attempts at achieving the same thing (three are commented out).

What happens is that it compiles OK but fails at runtime.
When I run the program, it does SOMETIMES work.
But then, on re-running immediately, it immediately fails.

From the debugger, I see that it always fails, by freezing, on the WRITE statements.
It tends to work (50% of the time) immediately after re-compiling/rebuilding.
It never works twice in a row.  Mostly, it fails.

As far as I can see, my code is all correct.

I've tried altering the environment variable
GFORTRAN_UNBUFFERED_ALL
between Y and N, and then back to Y.
This makes no difference.

Has anyone any ideas that would help me with this?
---
John

Re: Strange GFortran problem suppressing CR

Hi John. Try this.

      SUBROUTINE INDENT(LU,nTAB)
C     --------------------------------------
C     Indent LU
C     jw / 13.08.04
C     jw / 21.01.14  last rev.

      INTEGER   LU, nTAB

      WRITE (LU,'(A)', ADVANCE = 'NO') REPEAT(' ', nTab)

      RETURN
      END 

There is a single space in the first argument of REPEAT.

--
David

Re: Strange GFortran problem suppressing CR

I'd also tried that. 
Nothing worked.

I've altered the code to avoid the problem but it's a strange one.
I wondered if anyone else had experienced anything similar.
---
J.

Re: Strange GFortran problem suppressing CR

John,

Non-advancing IO in Fortran using the traditional output techniques has always been hit-or-miss in my experience.  There isn't a really "official" way to do so using Fortran 90/95.

You can, however, use Fortran 2003's stream access techniques.  It requires a bit more programming, but that's no surprise.  Here's an example program that does exactly what you want:

program streamio
implicit none

    Print *, "Running"

    open(unit=115, file="test.txt", access="stream", status="replace", &
         form="unformatted")

    write(115) "Testing indents"//NEW_LINE('0')
    
    call indent(115, 3)
    
    write(115) "I'm three spaces in..."//NEW_LINE('0')
    
    call indent(115, 5)
    
    write(115) "I'm five spaces in..."//NEW_LINE('0')
    
    call indent(115, 7)
    
    write(115) "I'm seven spaces in..."//NEW_LINE('0')
    
    close(115)
    
    Print *, "Done"

contains

    subroutine indent(lu, spaces)
    implicit none
    
    integer::lu, spaces
    
        write(lu) repeat(' ', spaces)
    
    end subroutine indent

end program streamio

There are a few things to note.  First, I've opened the file with access="stream", which is new.   Second, all my write calls have only a unit number, no format information.  It will fail if you even include a * format specifier.  Third, I have to explicitly append new line characters to all my strings to advance one line.

Let me know what you think of the above.  It might be workable in your case.

Jeff Armstrong
Approximatrix, LLC

Re: Strange GFortran problem suppressing CR

Thanks Jeff - that's a very interesting solution.  I haven't come across  'access="stream" ' before. 
Very useful tip.
---
John

Re: Strange GFortran problem suppressing CR

Honestly, John, I haven't used it too much myself.  It does allow a more direct way to access files, but you lose the ability to specify formatting directly.  I don't think anyone would argue that text output and manipulation is not one of Fortran's strong points.

Jeff Armstrong
Approximatrix, LLC

7 (edited by ecanot 2014-01-24 08:22:05)

Re: Strange GFortran problem suppressing CR

In my case, non-advancing IO works very well using GNU-gfortran (and also 5 or 6 other different compilers). The only important thing is to flush the unit to be sure that data is written.

     call flush(LU)

is a standard call in gfortran and should remedy your problem. Put it immediately after a non-advancing write.

BTW, I never tried  the environment variable GFORTRAN_UNBUFFERED_ALL, it should effectively have the same effect but it has the drawback to be global.