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

SPLITPATHQQ on v15 of the compiler

Jacob_Williams
New Contributor III
801 Views

I'm seeing some odd behavior of SPLITPATHQQ on v15 of the compiler (compared to v14 update 2).  Consider this code:

program main
	
	use ifport 
	
	implicit none
		
	character(len=256)	:: filepath
	integer(4)		:: filelen
	character(len=256)	:: drive,dir,name,ext
	
	filepath = '\\blah\blah\blah\'
	filelen	= SPLITPATHQQ (filepath, drive, dir, name, ext)
	
	write(*,*) '---------'
	write(*,*) 'filepath:'//trim(filepath)
	write(*,*) 'drive:'//trim(drive)
	write(*,*) 'dir  :'//trim(dir)
	write(*,*) 'name :'//trim(name)
	write(*,*) 'ext  :'//trim(ext)
	write(*,*) '---------'
	
	filepath = 'C:\blah\blah\blah.dat'
	filelen	= SPLITPATHQQ (filepath, drive, dir, name, ext)
	
	write(*,*) '---------'
	write(*,*) 'filepath:'//trim(filepath)
	write(*,*) 'drive:'//trim(drive)
	write(*,*) 'dir  :'//trim(dir)
	write(*,*) 'name :'//trim(name)
	write(*,*) 'ext  :'//trim(ext)
	write(*,*) '---------'
	
	filepath = '\\blah\blah\blah\'
	filelen	= SPLITPATHQQ (filepath, drive, dir, name, ext)
	
	write(*,*) '---------'
	write(*,*) 'filepath:'//trim(filepath)
	write(*,*) 'drive:'//trim(drive)
	write(*,*) 'dir  :'//trim(dir)
	write(*,*) 'name :'//trim(name)
	write(*,*) 'ext  :'//trim(ext)
	write(*,*) '---------'

end program main
	

The result on my PC is this:

 ---------
 filepath:\\blah\blah\blah\
 drive:



 dir  :\\blah\blah\blah\
 name :



 ext  :



 ---------
 ---------
 filepath:C:\blah\blah\blah.dat
 drive:C:
 dir  :\blah\blah\
 name :blah
 ext  :.dat
 ---------
 ---------
 filepath:\\blah\blah\blah\
 drive:C:
 dir  :\\blah\blah\blah\
 name :blah
 ext  :.dat
 ---------

The first time it is called, drive, name, and ext are blank as expected.  (But note that the strings are not being trimmed properly, which is weird).  The second time it is called, everything is fine and non-blank as expected.  The third time it is called, drive, name, and ext should be blank, but they are retaining the values from the previous call.  I don't believe the previous version of the compiler behaved this way.

0 Kudos
6 Replies
mecej4
Honored Contributor III
801 Views

You may find more clues about what the library routine is doing by changing 'blah' to 'blbh' in the second pathname, and to 'blch' in the third pathname. Doing so will prove conclusively that, as you stated, after the third call, instead of being blanked, the name and extension retain their values from the second call. Probably, components missing in the input path string result in corresponding output variables being left unmodified instead of being blanked out.

Again, as you wrote, there are no such errors when this program is compiled with the 14.0 compiler (or with CVF6.6C).

An inconvenient workaround is to write a wrapper around SPLITPATHQQ in which you blank out all the output variables before calling SPLITPATHQQ. In your caller code, call the wrapper routine name instead of SPLITPATHQQ.

0 Kudos
andrew_4619
Honored Contributor III
801 Views

I would imaging SPLITPATHQQ is a wrapper for the c stdlib  _splitpath.  

void _splitpath(
   const char *path,
   char *drive,
   char *dir,
   char *fname,
   char *ext 
);

 

0 Kudos
mecej4
Honored Contributor III
801 Views

Based on what app4619 wrote, here is a wrapper function (note: because the strings passed to _splitpath are put into memory by the Fortran processor, there is no need to double up backslash characters as is done in the text representation of strings in C source files). It is assumed that the character variable arguments are of adequate lengths to hold the strings that are expected to be returned.

integer function splitpathqq(path,drive,dir,name,ext)
integer p
character(len=*) :: path,drive,dir,name,ext
  interface
    subroutine splitpath ( path, drive, dir, name,ext ) bind ( C, name = "_splitpath" )
      use iso_c_binding, only : C_CHAR
      character ( kind = C_CHAR ) :: path(*),drive(*),dir(*),name(*),ext(*)
    end subroutine splitpath
  end interface

  call splitpath(trim(path)//char(0),drive,dir,name,ext)
  p=index(drive,char(0)); drive=drive(1:p-1)
  p=index(name,char(0));  name =name(1:p-1)
  p=index(ext,char(0));   ext  =ext(1:p-1)
  p=index(dir,char(0));   dir  =dir(1:p-1)
  splitpathqq=p-1
  return
end function splitpathqq

 

0 Kudos
Steven_L_Intel1
Employee
801 Views

I can reproduce this and have escalated it as issue DPD200360620. It looks to me as if it's not blank-filling the output variables properly. Strange, as I don't see any issues reported with this routine since 2006 that would have triggered a code change. Thanks for the nice example.

0 Kudos
Jacob_Williams
New Contributor III
801 Views

mecej4, my workaround was to just wrap the SPLITPATHQQ routine.  This seems to work OK:

function split_path(path,drive,dir,name,ext) result(filelen)

	use ifport, only: SPLITPATHQQ
	
	implicit none 
	
	integer(4) :: filelen
	character(len=*),intent(in) :: path
	character(len=*),intent(out) :: drive,dir,name,ext
	
	drive = ''
	dir   = ''
	name  = ''
	ext   = ''
	
	filelen = SPLITPATHQQ(path,drive,dir,name,ext)
	
end function split_path
0 Kudos
Steven_L_Intel1
Employee
801 Views

Thanks for letting us know about this problem - it affected more than just SPLITPATHQQ. I expect it to be fixed in Update 1.

0 Kudos
Reply