- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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.
1 Solution
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You might end up having to read one character at a time and process it.
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Later this year we'll be supporting Fortran 2003 Stream I/O, which you may find handy.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I believe I'll be at the mercy of my users, who will be doing something along the lines of:
Could I still use a YY_INPUT that does:
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You might end up having to read one character at a time and process it.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page