Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

FORTRAN IO mixing with C IO

Christopher_Watford
581 Views
I'm working on a Lexer and Grammar, which will end up in a shared library. I've used flex/bison, which produces C code, which in turn uses FILE* (by default) to retrieve the stream of data.

Previously, users specified their input unit and output unit to the library (in F77). Because of this fact, they were able to build input on the fly, rewind the unit, and then use the library. Other uses included storing multiple inputs in the same file, but having the top level handle seeking in the file to the right point.

My question is, how can I get at the underlying stream for a given logical unit number? A few other FORTRAN implementations expose FSTREAM/FNUM to get the FILE* or file descriptor used by the library, however, I cannot seem to find any suitable match in IVF.

I would prefer to not write stubs in FORTRAN to replace the YY_INPUT routine, yet this is also an option if I cannot use pure C to enable the old functionality.
0 Kudos
1 Solution
Steven_L_Intel1
Employee
581 Views
You might end up having to read one character at a time and process it.

View solution in original post

0 Kudos
5 Replies
Steven_L_Intel1
Employee
581 Views
IVF does not use C I/O, it calls directly to Win32. You can get the file handle by opening the file with a USEROPEN procedure, but that doesn't help you mix with C.

I strongly advise against trying to mix languages for I/O - this is an invitation to headaches as each language has its own rules and implementation quirks for buffering and context.
0 Kudos
Christopher_Watford
581 Views
I had figured as much. I guess at this point I have to roll my own YY_INPUT routine.

A pseudo-YY_INPUT would look like:

function YY_INPUT( ctx, buffer, max_size ) result ( chars_read )
type(my_context) :: ctx
character(max_size) :: buffer
integer :: max_size ! this is unsigned, ensure we never go negative
integer :: chars_read ! this is unsigned, ensure we never go negative

! read into buffer from ctx%input_unit up to max_size characters
! including ' ' and ' ', then return the actual number of characters read

return
end function YY_INPUT

What would be the best way to pull (up to) max_size characters into buffer from a unit? Roll my own format string?

0 Kudos
Steven_L_Intel1
Employee
581 Views
If you use formatted I/O, you'll be needing to deal with a record structure. You can open the file FORM='BINARY' and do unformatted I/O to basically do C-type bytestream I/O. The number of bytes read will be the size of the variable.

Later this year we'll be supporting Fortran 2003 Stream I/O, which you may find handy.
0 Kudos
Christopher_Watford
581 Views
I believe I'll be at the mercy of my users, who will be doing something along the lines of:

open ( unit=30, file='input.dat', action='read', iostat=ios )

...

readloop: do
read (30, '(a)', end=8500) line
first = nonwhite(line) ! first non-whitespace
if ( line(first:first) .eq. ')' ) then
! do something with the rest of 'line'
! let input_processor handle the rest of the input
call input_processor( ctx, 30, output_unit )
! when this returns, it will have either read until EOF, or until its own
! internal EOR, at which case control is passed back to here
! and we can loop
else
! error handler
end if

! use the information input_processor has recieved

enddo readloop
8500 continue

...

close ( unit=30 )

Could I still use a YY_INPUT that does:
if ( excess_len > 0 ) then
! copy the excess from the last call into buffer
endif
yyinput: do
read ( lun, '(a)', size=line_len, end=8500 ) line
! copy_len is the min of what is left and the line length
! copy into the buffer
! append CHAR(10)
! update the length
! save the excess buffer for the next go
if ( copy_len < line_len ) then
excess = line(copy_len+1:)
excess_len = line_len - copy_len
exit yyinput
endif
enddo yyinput
chars_read = buffer_len
return
8500 continue
chars_read = 0
return


0 Kudos
Steven_L_Intel1
Employee
582 Views
You might end up having to read one character at a time and process it.
0 Kudos
Reply