urba...@comcast.net
unread,Sep 17, 2019, 10:32:18 PM9/17/19You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to
module M_process
use, intrinsic :: iso_c_binding
implicit none
private
public :: process_open_write ! (cmd,fp,ierr) ! open process to write to
public :: process_close ! (fp,ierr) ! close process
public :: process_writeline ! (string,fp,ierr) ! write line to process
private :: process_open ! (fp,ierr) ! open process
type, public :: streampointer
type (c_ptr) :: handle = c_null_ptr
end type streampointer
interface process_writeline
module procedure process_writeline_scalar, process_writeline_array
end interface
!-----------------------------------------------------------------------------------------------------------------------------------
interface
function system_popen(path, mode) bind(C, name='popen')
use, intrinsic :: iso_c_binding
character(kind=c_char), dimension(*) :: path, mode
type (c_ptr) :: system_popen
end function
function system_pclose(handle) bind(C, name='pclose')
use, intrinsic :: iso_c_binding
integer(c_int) :: system_pclose
type (c_ptr), value :: handle
end function
function system_fputs(buf, handle) bind(C, name='fputs')
use, intrinsic :: iso_c_binding
integer(c_int) :: system_fputs
character(kind=c_char), dimension(*) :: buf
type (c_ptr), value :: handle
end function
function fflush(handle) bind(C, name='fflush')
use, intrinsic :: ISO_C_BINDING
integer(c_int) :: fflush
type (c_ptr), value :: handle
end function
end interface
!-----------------------------------------------------------------------------------------------------------------------------------
contains
!-----------------------------------------------------------------------------------------------------------------------------------
subroutine process_open_write(cmd,fp,ierr)
character(len=*),intent(in) :: cmd ! shell command to start process with
type(streampointer),intent(out) :: fp ! file pointer returned for process
integer,intent(out) :: ierr ! status for attempt to open process (0= no error)
ierr=0
call process_open(cmd,fp,ierr)
end subroutine process_open_write
!-----------------------------------------------------------------------------------------------------------------------------------
subroutine process_open(cmd,fp,ierr)
character(len=*),intent(in) :: cmd ! shell command to start process with
type(streampointer),intent(out) :: fp ! file pointer returned for process
integer,intent(out) :: ierr ! status for attempt to open process (0= no error)
ierr=0
fp%handle = system_popen(trim(cmd) // C_NULL_CHAR, 'w'// C_NULL_CHAR)
if (.not.c_associated(fp%handle)) then
write(*,*) '*process_open_write* ERROR: Could not open pipe!'
ierr=-1
endif
end subroutine process_open
!-----------------------------------------------------------------------------------------------------------------------------------
subroutine process_close(fp,ierr)
type(streampointer) :: fp ! file pointer returned for process
integer(c_int) :: ios
integer :: ierr
ierr=fflush(fp%handle)
ios=0
if (.not.c_associated(fp%handle)) then
write(*,*)'*process_close* process not found'
else
ios=system_pclose(fp%handle)
endif
ierr=min(-1_c_int,ios)
end subroutine process_close
!-----------------------------------------------------------------------------------------------------------------------------------
subroutine process_writeline_scalar(writefrom,fp,ierr)
character(len=*),intent(in) :: writefrom
type(streampointer),intent(in) :: fp
integer,intent(out) :: ierr
integer :: ios
ierr=system_fputs(trim(writefrom)//C_NEW_LINE//C_NULL_CHAR,fp%handle)
if(ierr.ne.0)then
ios = system_pclose(fp%handle)
ierr=min(-1,ios)
endif
if(ierr.eq.0)then
ierr=fflush(fp%handle)
endif
end subroutine process_writeline_scalar
!-----------------------------------------------------------------------------------------------------------------------------------
subroutine process_writeline_array(writefrom,fp,ierr)
character(len=*),intent(in) :: writefrom(:)
type(streampointer),intent(in) :: fp
integer,intent(out) :: ierr
integer :: i
ierr=0
do i=1,size(writefrom,dim=1)
call process_writeline_scalar(writefrom(i),fp,ierr)
if(ierr.ne.0)exit
enddo
end subroutine process_writeline_array
!-----------------------------------------------------------------------------------------------------------------------------------
end module M_process
!-==================================================================================================================================
program gnuplotExample
use M_process ,only: process_open_write, process_writeline
use M_process ,only: streampointer, process_close
implicit none
character(len=4096) :: line !*! line of data to write (assumed long enough to hold any command line)
type(streampointer) :: fp !*! C file pointer returned by process_open()
integer :: ierr !*! check status of calls to process module routines
integer :: i !*! DO loop counter
integer,parameter :: n=300 !*! number of points to put into curve to be plotted
real :: x(n),y(n) !*! arrays to fill with curve data to be plotted
integer :: ios
integer :: j
call process_open_write('gnuplot',fp,ierr) !*! open process to write to (ie. start gnuplot(1) program)
!*! Define sample X,Y array.
do j=1,300,3
do i=1,n !*! set X() values as whole numbers 1 to N
x(i)=i
y(i)=sin(x(i)/25.0+j/40.0)
enddo
call plotit() !*! plot the data
write(*,*)' RETURNED TO MAIN PROGRAM',j
enddo
write(*,'(a)')'enter gnuplot commands or "." to exit' !*! Additional gnuplot commands; in this case interactively entered
do
write(*,'(a)',advance='no')'gnu>>'
read(*,'(a)',iostat=ios)line
if(line.eq.'.')exit
call process_writeline(trim(line),fp,ierr)
enddo
call process_close(fp,ierr)
write(*,*)'CLOSED THE PROCESS. RETURNING TO PROGRAM'
contains
subroutine plotit()
!===================================================================================================================================
call process_writeline('$SET1 <<EOD',fp,ierr) !*! create in-line dataset $SET1
do i=1,n
write(line,'(2(f10.3,1x))')x(i),y(i) !*! Write the X,Y array as coordinates to be plotted.
call process_writeline(line,fp,ierr)
enddo
call process_writeline([character(len=128) :: & !*! plot the data using gnuplot(1)
&'EOD ', &
&'set title " Example of GNUPlot data and command file generation"', &
&'set nokey' , &
&'plot $SET1 with lines' , &
&''],fp,ierr)
end subroutine plotit
!===================================================================================================================================
end program gnuplotExample
!-==================================================================================================================================