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

Converter utility for files with CARRIAGECONTROL = 'FORTRAN'

sabalan
New Contributor I
547 Views
Does anybody now a free utility software for converting whole trees with many files saved with CARRIAGECONTROLL = 'FORTRAN' to CARRIAGECONTROLL = 'LIST'?
I know that I can create a program myself which can read files (one file at a time?) and write them with the new format. But I have thousands of files in directory trees, and maybe I don't need to invent the wheel again?
Sabalan.
0 Kudos
11 Replies
Jugoslav_Dujic
Valued Contributor II
547 Views
Visual Studio .NET (if you have it already) has the "Replace in Files" option. Now, I'm not sure what's the exact difference between CARRIAGECONTROL="Fortran" and "List" -- is it char(13)//char(10)//" " versus char(10) -- canyou elaborate? In any case, you should study "regular expressions" since you cannot specify or in search/replace string.
I usually use attached Fortran source (working with XFTFile.f90 module) for quick'n'dirty "bulk" file operations... I feel better when I have things under control. However, I'm not sure how easy is to convert CARRIAGECONTROL from one form to another.
Jugoslav
0 Kudos
Steven_L_Intel1
Employee
547 Views
Files written to disk with CARRIAGECONTROL='FORTRAN' have the column 1 carriage control converted into the appropriate series of CRs and LFs. It would probably be sufficient to just strip those characters out of your data files.
0 Kudos
sabalan
New Contributor I
547 Views
Thanks Yugoslav for your reply.
I am not sure either what the exact difference between CARRIAGECONTROL='FORTRAN' and 'LIST' is. The first problem is that these files which are copied from VAX/VMS to PC, appear in one long line when opened in text editors. I have solved this problem by writing a little program in Fortran which opens the file without specifying CARRIAGECONTROL, reads it line by line trimming " ":s, and writes lines into a new file with CARRIAGECONTROLL='LIST' specified.
Then I have created a program in VB with file dialog call and cdlOFNAllowMultiselect. This allows the user to select multiple files and send the names to the fortran program which identifies each file name, processes it as I described, and saves it with the new format. And here appears the second problem which I suspect that would not be so easy to solve: The program is not applicable on directory trees automatically and must be run for each directory separately.
Sabalan.
0 Kudos
Jugoslav_Dujic
Valued Contributor II
547 Views
XEnumFiles functionused in the source above can optionally traverse recursively through the list of directories:
{quote}
XEnumFiles enumerates all files in given directory (and its subdirectories) which satisfy given file filter and passes them to user-written callback procedure.
RECURSIVE INTEGER FUNCTION XEnumFiles(sDir, sFilter, fnCallback, bRecursive, lParam)

CHARACTER(*),INTENT(IN):: sDir
CHARACTER(*),INTENT(IN):: sFilter
INTERFACE
LOGICAL FUNCTION fnCallback(sFile, lParam)
CHARACTER(*),INTENT(IN):: sFile
!DEC$ATTRIBUTES NO_ARG_CHECK:: lParam
INTEGER:: lParam
END FUNCTION fnCallback
END INTERFACE
LOGICAL, OPTIONAL, INTENT(IN):: bRecursive
!DEC$ATTRIBUTES NO_ARG_CHECK:: lParam
INTEGER, OPTIONAL, INTENT(IN):: lParam

Arguments

sDir
Path of the directory to be searched, without trailing backslash. If empty, the current directory is searched.

sFilter
String that specifies a valid filename to be searched for, which can contain wildcard characters (* and ?).

fnCallback
Callback function of specified prototype. This function is called whenever XEnumFiles finds a file which satisfies given filter. The callback function should return .FALSE. if it wants the enumeration to be continued, or .TRUE. if it wants to stop the enumeration.

[bRecursive]
If present and .TRUE., subdirectories of sDir are searched as well. Otherwise, only sDir is searched for files satisfying given filter.

[lParam]
An arbitrary value defined by the calling application, which XEnumFiles just passes as second argument to fnCallback. If not present, 0 is passed. This parameter is useful if additional communication is needed between the routine which calls XEnumFiles and fnCallback; if lParam is used, there's no need for global variables.

{/quote}

Implementation is in the attached file (make sure you !DEC$DEFINE XLITE at the top of the file & remove read-only attribute). Basically, it's a wrapper around FindFirstFile/FindNextFile/FindClose APIs.

HTH

Jugoslav

0 Kudos
Jugoslav_Dujic
Valued Contributor II
547 Views
...and, additionally, you can select a folder instead of group of files using ShBrowseForFolder API, or XBrowse in the attached file, and there's probably a VB wrapper which does the same (don't know how it's called though).
Jugoslav

Message Edited by JugoslavDujic on 09-07-2004 05:18 PM

0 Kudos
Jugoslav_Dujic
Valued Contributor II
547 Views
...this file... [sigh]
0 Kudos
sabalan
New Contributor I
547 Views
Thanks Yugoslav for your comments and codes. They put me on right direction and I could find Q185601 "HOWTO: Recursively Search Directories Using FileSystemObject" in VB. This is about 30 lines of code in VB which does the work (replacing list box updates with calls to the file converter routine).
BUT I was wrong in one thing: My file converter routine does not work in PC, because all CRs and LFs are replaced with spaces as soon as a file is moved from Vax/VMS into PC and it is impossible to detect and rebuild the original text flow of the file.
This means that I have to process all files in VAX first and then copy them to PC. Therefore I need a utility to run this converter in a loop through all directories and sub directories in VAX. But I haven't worked with VAX that long time to be expert in system calls.
Steve, don't you have a code snippet from the good Digital time which can browse all directories automatically? Any hint would be appreciated.
Sabalan.
0 Kudos
Jugoslav_Dujic
Valued Contributor II
547 Views
My file converter routine does not work in PC, because all CRs and LFs are replaced with spaces as soon as a file is moved from Vax/VMS into PC
Huh???! Replaced by what tool? I've never seen a Vax in my life and couldn't tell one from a microwave oven, but I doubt that there isn't an option somewhere somehow to perform the file transfer "cleanly".
Jugoslav
0 Kudos
Steven_L_Intel1
Employee
547 Views
The problem here is that VMS does not use CR-LF as record delimiters, but rather has a record-oriented file system. If you simply do a binary FTP of a text file from VMS to another OS, you lose the record information. An ASCII conversion would work. Once you have lost the record info, there is no way of recovering it (unless you know the layout of the records.)
0 Kudos
sabalan
New Contributor I
547 Views
Thanks Steve. I didnt know that about records, but I could guess that it should be something like that.

Unfortunately our software for network communication with VAX through LAN (WRQ Reflection, which does not support LAN after version 8 now v.12) added some garbage to the beginning and the end of files, and sometimes to the end of lines, even when transferring the files as ASCII, and I dont know why (record length difference?). Therefore we decided to convert all files first and then transfer them.
The problem is solved now. Since I have forgotten all system resource commands SYS$... (I am 52 soon!!) and since all manuals are destroyed by people who believed that we are not going to need to use our VAX never ever again, then I did it the following way:
1- Create a file containing file names and paths through the whole directory tree:
$ DIR/nohe/notra [MyOldDir]*.*.* /out=FilesList.txt
2- Take a copy of MyOldDir as MyNewDir to not to need to recreate each subdirectory separately for output files:
$ Copy [MyOldDir]*.*.* [MyNewDir]*.*.*
3- Complete, compile, link, and run the following code;
4- PURGE MyNewDir to replace original files inside it with the new files.
$ PURGE [MyNewDir]*.*
Code:
      Program CarrCON

      IMPLICIT NONE

      Parameter RL = 300     ! Max line length

      CHARACTER*300 aLine, InFile, OutFile
      INTEGER I, J, L

      Open (1, File='FilesList.txt', STATUS='old')

      READ (1,'(A)', IOSTAT=I) InFile

      DO WHILE (I.GE.0)
        ! Skip lines with directory name only, executables,
        J = INDEX (InFile, '.DIR];') ! object files, etc. repeat 
        If (J .LE. 1) Then           ! this for '.EXE];' or '.OBJ];' 
          K = K + 1              ! etc. or delete these lines
          Goto 200               ! from FilesLis.txt before 
        End If                       ! running this code.

        ! Now we have found a file name and path

        J = INDEX (InFile, ';') - 1
        Open (2, File=InFile(:J), STATUS='old', IOSTAT=I)
        IF (I.NE.0) THEN
          Write (*,*) ' *** Open Error in file ', InFile, ' no ', I
          CALL EXIT
        END IF

        OutFile = '[MyNewDir.'// InFile(Index(MyOldDir, whatever):J)

        Open (3, File=OutFile(:J+ path length diff.), STATUS='New', 
     &                                   CarriageControl='LIST', IOSTAT=I)
        IF (I.NE.0) THEN
          Write (*,*) ' *** Open Error in file ', OutFile, ' no ', I
          CALL EXIT
        END IF

        DO WHILE (I.GE.0)
          READ (2,'(A)', IOSTAT=I) aLine
          IF (I.NE.0) THEN
            Write (*,*) ' *** Read Error in File ', InFile, ' no ', I
            Goto 100          ! Take next file
          END IF

          L = RL
          ! Trim the line (There was no 'TRIM' in VAX FORTRAN!)
          DO WHILE (aLine(L:L).LT.' ' .AND. L.GT.0)
            L = L - 1
          END DO

          ! Write to the new file
          WRITE (3, '(A)') aLine(:L)
        END DO

 100    
Close(2)
        Close(3)

        Write(*,*) OutFile(:J + path length diff.), ' done!'

 200    READ (1,'(A)', IOSTAT=I) InFile

      END DO	

      Close(1)

      END
Sabalan.
0 Kudos
Steven_L_Intel1
Employee
547 Views
See here for information on converting these files.
0 Kudos
Reply