This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
Re: ASM allowed in Fortran? and OpenDir?
- From: "Christopher D. Rickett" <crickett at lanl dot gov>
- To: Tobias Burnus <burnus at net-b dot de>
- Cc: RadSurfer <RadSurfer at yahoo dot com>, fortran at gcc dot gnu dot org
- Date: Tue, 7 Aug 2007 11:12:03 -0600 (MDT)
- Subject: Re: ASM allowed in Fortran? and OpenDir?
- References: <loom.20070807T045837-299@post.gmane.org> <46B81DC4.8090502@net-b.de>
hi Tobias, all,
i looked over the code below and found a couple bugs. first, the
parameter to readdir needs to be a c_ptr passed by value. also, the
parameter to opendir is not null terminated! and, the same problem exists
in the print *, Result line where the d%d_name may be null terminated, but
i doubt the fortran print routine cares; the printf routine of C is
probably the safest thing to call here.
the following code should fix the bugs i found:
module mod
use iso_c_binding
implicit none
end module mod
program test
use iso_c_binding
use mod
implicit none
type, bind(C) :: dirent
integer(c_long) :: d_ino
integer(c_long) :: d_off; ! __off_t, check size
integer(c_short) :: d_reclen
character(len=1,kind=c_char) :: d_name(256)
end type
interface
function opendir(a) bind(C,name='opendir')
import
type(c_ptr) :: opendir
character(len=1,kind=c_char), intent(in) :: a(*)
end function opendir
function readdir(dir) bind(C,name='readdir')
import
type(c_ptr), value :: dir
type(c_ptr) :: readdir
end function readdir
subroutine print_string(format_string, string) bind(c, name='printf')
import :: c_ptr, c_char
type(c_ptr), value :: format_string
character(c_char) :: string(*)
end subroutine print_string
end interface
type(c_ptr) :: dir, dc
type(dirent), pointer :: d
type(c_ptr) :: f_ptr
character(len=20), target :: format_string
format_string = 'Result: %s\n' // C_NULL_CHAR
f_ptr = c_loc(format_string(1:1))
dir = opendir("."//C_NULL_CHAR)
if(.not.c_associated(dir)) then
print *, 'Error opening "."'
else
do
dc = readdir (dir)
if(.not. c_associated(dc)) exit
call c_f_pointer(dc,d)
call print_string(f_ptr, d%d_name)
end do
end if
end program
this code compiled and executed on my linux box with no problems, even
giving me the expected output. hope this helps.
Chris
On Tue, 7 Aug 2007, Tobias Burnus wrote:
RadSurfer wrote:
I was just curious if there was such a thing as discreet assembly code ever
being allowed inside a Fortran program...
Perhpas that seems like a ludicrous question -- but I'll have to wait to see
what the replies are.
This slowly becomes a frequently ask question:
http://gcc.gnu.org/ml/fortran/2007-07/msg00470.html
One other question, seriously:
I did not notice any functions/extensions/etc. which permit the getting of
directory information which allows to "walk through" files...
I refer to "opendir" or "findfirst" type of directory-walking functions.
I realize there are extensions which allow information about _known_ files
to be returned... but not retreiving files from a directory to be placed
into a list for processing and that sort of functionality.
In principle the following program should do this; however, I only get
NULL returned by opendir (with gfortran), a compiler error (g95) or an
endless loop (NAG f95). Besides compiler errors, I think I made a
mistake somewhere too.
Tobias
module mod
use iso_c_binding
implicit none
integer(c_int), bind(c,name="errno") :: errno
end module mod
program test
use iso_c_binding
use mod
implicit none
type, bind(C) :: dirent
integer(c_long) :: d_ino
integer(c_long) :: d_off; ! __off_t, check size
integer(c_short) :: d_reclen
character(len=1,kind=c_char) :: d_name(256)
end type
interface
function opendir(a) bind(C,name='opendir')
import
type(c_ptr) :: opendir
character(len=1,kind=c_char), intent(in) :: a(*)
end function opendir
function readdir(dir) bind(C,name='readdir')
import
type(c_ptr), intent(in) :: dir
type(c_ptr) :: readdir
end function readdir
end interface
type(c_ptr) :: dir, dc
type(dirent), pointer :: d
errno = 0
dir = opendir(".")
if(.not.c_associated(dir)) then
print *, 'Error opening "."', errno
else
do
dc = readdir (dir)
if(.not. c_associated(dc)) exit
call c_f_pointer(dc,d)
print *, "Result: ", d%d_name
end do
end if
end program