C****************************************************************************** C C Neither First Chicago Corporation, the First National Bank of Chicago, C nor any of its employees makes any warranty, either expressed or implied, C assumes any legal liability, nor any responsibility for the accuracy, C completeness or usefulness of any information, product or process disclosed. C Neither does First Chicago Corportion, the First National Bank of Chicago,nor C any of its employees represent that use of this material would not infringe C privately owned rights. C C****************************************************************************** C C C C MATCH.FOR MAIN PROGRAM FOR FILE COMPARISON C C ***************************************************************************** C ***************************************************************************** C C WRITTEN BY: SHERMAN TODD, DOUGLAS BOHRER C PERSONNEL DEPARTMENT, THE FIRST NATIONAL BANK OF CHICAGO C 1 FIRST NATIONAL PLAZA, 22ND FLOOR C CHICAGO, ILLINOIS 60670 C C DATE: 26-FEB-81 C C purpose: this program compares the records of one presorted fortran C sequential ascii file to the records of another presorted C fortran sequential ascii file by checking their keys a C character at a time. if both keys "match" (i.e., are the same) C then both records are combined together and written to the C output file for matched records. if the keys do not match then C the record with the lower key value is written to the error output C file along with an error message generated by the user at beginning C of the program execution. C Output file includes only matched records. C C C **************************************************************************** C C VARIABLES: C C ERR1 - A LOGICAL VARIABLE USED TO DETERMINE WHICH ONE OF THE TWO C RECORDS IS IN ERROR C FILE1 - THE NAME OF THE FIRST INPUT FILE C FILE2 - THE NAME OF THE SECOND INPUT FILE C FILE3 - THE NAME OF THE OUTPUT FILE FOR MATCHED RECORDS C FILE4 - THE NAME OF THE ERROR OUTPUT FILE C I - A CONTROL VARIABLE USED IN SEVERAL OF THE DO LOOPS C IGT - A VARIABLE USED IN DETERMINING THE VALUE OF ERR1 C II - A CONTROL VARIABLE USED IN SEVERAL OF THE DO LOOPS C ILT - ANOTHER VARIABLE USED IN DETERMINING THE VALUE OF ERR1 C JJ - A CONTROL VARIABLE USED IN SEVERAL OF THE DO LOOPS C JLEN1 - IF LEN1 IS GREATER THAN 132 THEN JLEN1 IS EQUAL TO 132; C OTHERWISE IT IS EQUAL TO THE VALUE OF LEN1 C JLEN2 - IF LEN2 IS GREATER THAN 132 THEN JLEN2 IS EQUAL TO 132; C OTHERWISE IT IS EQUAL TO THE VALUE OF LEN2 C KEY1S - THE STARTING POSITION OF THE KEY FOR RECORDS IN FILE1 C KEY2S - THE STARTING POSITION OF THE KEY FOR RECORDS IN FILE2 C LENKEY - THE LENGTH OF THE KEY FOR EACH RECORD C LEN1 - THE MAXIMUM LENGTH A RECORD IN FILE1 IS EXPECTED TO HAVE C LEN2 - THE MAXIMUM LENGTH A RECORD IN FILE2 IS EXPECTED TO HAVE C LOC - SERVES AS AN INDEX INTO BOTH KEYS C MATCH - A LOGICAL VARIABLE USED TO DETERMINE WHTHER TWO RECORDS MATCH C MSG1 - ERROR MESSAGE ENTERED BY THE USER FOR THE TIMES WHEN C A RECORD IN FILE1 HAS NO MATCH C MSG2 - ERROR MESSAGE ENTERED BY THE USER FOR THE TIMES WHEN C A RECORD IN FILE2 HAS NO MATCH C NERR1 - A COUNTER FOR THE NUMBER OF RECORDS IN FILE1 THAT DO NOT C HAVE A MATCH C NERR2 - A COUNTER FOR THE NUMBER OF RECORDS IN FILE2 THAT DO NOT C HAVE A MATCH C NMATCH - A COUNTER FOR THE NUMBER OF MATCHED RECORDS C REC1 - REPRESENTS THE CURRENT RECORD FROM FILE1 C REC2 - REPRESENTS THE CURRENT RECORD FROM FILE2 C C ***************************************************************************** C C C DIMENSION THE VARIABLES C LOGICAL*1 MSG1(132),MSG2(132) LOGICAL*1 FILE1(14),FILE2(14),FILE3(14),FILE4(14) LOGICAL*1 REC1(512),REC2(512),MATCH,ERR1 C C FORMATS USED IN THE PROGRAM C 510 FORMAT(14A1) 520 FORMAT(I3) 530 FORMAT(132A1) 540 FORMAT(255A1,200A1,57A1) C C SYSTEM PROMPTS (FOR A MORE DETAILED DESCRIPTION SEE MATCH.HLP) C TYPE *, ' ENTER NAME OF FIRST INPUT FILE' READ(5,510) (FILE1(I),I=1,14) OPEN(UNIT=1, NAME=FILE1, ACCESS='SEQUENTIAL', FORM='FORMATTED', 1TYPE='OLD') TYPE *, ' RECORD SIZE?' READ(5,520) (LEN1) JLEN1=MIN0(LEN1,132) TYPE *, ' STARTING POSITION OF KEY?' READ(5,520) (KEY1S) KEY1S=KEY1S-1 TYPE *,' ERROR MESSAGE FOR NO MATCH FOR 1ST FILE RECORDS ON OTHER 1 FILE?' READ(5,530) (MSG1(I),I=1,132) TYPE *, ' ENTER NAME OF THE SECOND INPUT FILE' READ(5,510) (FILE2(I),I=1,14) OPEN(UNIT=2, NAME=FILE2, ACCESS='SEQUENTIAL', FORM='FORMATTED', 1TYPE='OLD') TYPE *, ' RECORD SIZE?' READ(5,520) (LEN2) JLEN2=MIN0(LEN2,132) TYPE *, ' STARTING POSITION OF KEY?' READ(5,520) (KEY2S) KEY2S=KEY2S-1 TYPE *,' ERROR MESSAGE FOR NO MATCH FOR 2ND FILE RECORDS ON OTHER 1 FILE?' READ(5,530) (MSG2(I),I=1,132) TYPE *, ' LENGTH OF KEY?' READ(5,520) (LENKEY) TYPE *, ' ENTER NAME OF OUTPUT FILE FOR MATCHED RECORDS' READ(5,510) (FILE3(I),I=1,14) OPEN(UNIT=3, NAME=FILE3, ACCESS='SEQUENTIAL', FORM='FORMATTED', 1INITIALSIZE=3000, TYPE='NEW',CARRIAGECONTROL='LIST') TYPE *, ' ENTER NAME OF THE ERROR OUTPUT FILE' READ(5,510) (FILE4(I),I=1,14) OPEN(UNIT=4, NAME=FILE4, ACCESS='SEQUENTIAL', FORM='FORMATTED', 1INITIALSIZE=3000, TYPE='NEW',CARRIAGECONTROL='LIST') C C INITIALIZE THE COUNTERS C NMATCH=0 NERR1=0 NERR2=0 C C READ THE NEXT TWO RECORDS TO BE COMPARED C 550 READ(1,540,END=900) (REC1(II),II=1,LEN1) READ(2,540,END=910) (REC2(JJ),JJ=1,LEN2) C C INITIALIZE THE VARIABLES C MATCH=.TRUE. ILT=LENKEY+1 IGT=ILT C C COMPARE THE KEYS OF BOTH RECORDS TO DETERMINE A MATCH C C IN THIS LOOP, THE Ith CHARACTER OF THE KEY FOR REC1 IS COMPARED TO C THE Ith CHARACTER OF THE KEY FOR REC2 TO DETERMINE A MATCH. IF THE C TWO CHARACTERS ARE EQUAL THEN MATCH REMAINS THE SAME VALUE IT WAS C BEFORE. IF THE TWO KEYS DO NOT MATCH, WE HAVE TO DETERMINE WHICH KEY C IS GREATER. THIS IS DONE BY TESTING BOTH KEYS A CHARACTER AT A TIME, C STARTING AT THE END OF BOTH KEYS AND WORKING TO THEIR BEGINNING. C IF THE LOCth CHARACTER OF THE KEY FOR REC1 IS LESS THAN THE LOCth C CHARACTER OF THE KEY FOR REC2 THEN ILT IS SET TO LOC. IF THE C LOCth CHARACTER OF THE KEY FOR REC1 IS GREATER THAN THE LOCth C CHARACTER OF THE KEY FOR REC2, HOWEVER, THEN IGT IS SET TO LOC. C ELSE ILT AND IGT RETAIN THEIR CURRENT VALUES. THE LOOP DOES NOT C TERMINATE UNTIL BOTH KEYS HAVE BEEN COMPLETELY TESTED. C 650 DO 750 I=1,LENKEY MATCH=MATCH.AND.(REC1(KEY1S+I).EQ.REC2(KEY2S+I)) LOC=LENKEY+1-I IF (REC1(KEY1S+LOC).LT.REC2(KEY2S+LOC)) ILT=LOC IF (REC1(KEY1S+LOC).GT.REC2(KEY2S+LOC)) IGT=LOC 750 CONTINUE C C IF BOTH KEYS MATCHED THEN CONCATENATE REC2 TO REC1 AND WRITE THIS NEW C RECORD ON THE NORMAL OUTPUT FILE. AFTER THIS IS DONE YOU CAN GO TO C STATEMENT 800. C IF (.NOT.MATCH) GO TO 755 WRITE(3,540) (REC1(II),II=1,LEN1),(REC2(JJ),JJ=1,LEN2) NMATCH=NMATCH+1 IF (MATCH) GO TO 800 C C ELSE IF THE KEYS DO NOT MATCH THEN DETERMINE WHICH KEY IS LARGER BY C COMPARING ILT WITH IGT. THE RESULT IS PLACED IN ERR1. C 755 ERR1=ILT.LT.IGT C C IF ILT IS GREATER THEN IGT THEN THE KEY OF REC1 IS GREATER THAN THE KEY C OF REC2 SO GO TO STATEMENT 760 FOR ERROR PROCRESSING. C IF (.NOT.ERR1) GO TO 760 C C ELSE THE KEY OF REC1 IS LESS THAN THE KEY OF REC2 C C WRITE REC1 AND THE PROPER ERROR MESSAGE OUT TO THE ERROR OUTPUT C FILE. NOW REPOSITION FILE2 BACKWARD ONE RECORD. THIS IS DONE TO C ENABLE US TO LATER DETERMINE WHETHER THERE IS A MATCH FOR REC2. C WRITE(4,530) (MSG1(I),I=1,132) WRITE(4,540) (REC1(II),II=1,JLEN1) NERR1=NERR1+1 BACKSPACE 2 760 IF (ERR1) GO TO 800 C C COME HERE IF KEY OF REC1 IS GREATER THAN KEY OF REC2 C C WRITE REC2 AND THE PROPER ERROR MASSAGE OUT TO THE ERROR OUTPUT C FILE. NOW REPOSITION FILE1 BACKWARD ONE RECORD. THIS IS DONE TO C ENABLE US TO LATER DETERMINE WHETHER THERE IS A MATCH FOR REC1. C WRITE(4,530) (MSG2(I),I=1,132) WRITE(4,540) (REC2(JJ),JJ=1,JLEN2) NERR2=NERR2+1 BACKSPACE 1 800 CONTINUE C C BRANCH TO COMPARE THE KEYS OF THE NEXT TWO RECORDS. C GO TO 550 C C COME HERE IF YOU HAVE REACHED THE END OF FILE1 AND THERE ARE STILL RECORDS C IN FILE2. WRITE THE REMAINING RECORDS OF FILE2 AND THE PROPER ERROR MESSAGE C OUT TO THE ERROR OUTPUT FILE. C 900 READ(2,540,END=1000) (REC2(JJ),JJ=1,JLEN2) WRITE(4,530) (MSG2(I),I=1,132) WRITE(4,540) (REC2(JJ),JJ=1,JLEN2) NERR2=NERR2+1 GO TO 900 C C COME HERE IF YOU HAVE REACHED THE END OF FILE2 AND THERE ARE STILL RECORDS C IN FILE1. WRITE THE REMAINING RECORDS OF FILE1 AND THE PROPER ERROR MESSAGE C OUT TO THE ERROR OUTPUT FILE. C 910 WRITE(4,530) (MSG1(I),I=1,132) WRITE(4,540) (REC1(II),II=1,JLEN1) NERR1=NERR1+1 READ(1,540,END=1000) (REC1(II),II=1,JLEN1) GO TO 910 C C WRITE THE COUNTER VALUES OUT TO THE ERROR OUTPUT FILE C 1000 WRITE(4,940) WRITE(4,930) NMATCH WRITE(4,940) WRITE(4,920) NERR1 WRITE(4,940) WRITE(4,530) (MSG1(I),I=1,132) WRITE(4,940) WRITE(4,920) NERR2 WRITE(4,940) WRITE(4,530) (MSG2(I),I=1,132) TYPE 930, NMATCH TYPE 940 TYPE 920, NERR1 TYPE 940 TYPE 530, (MSG1(I),I=0,132) TYPE 920, NERR2 TYPE 940 TYPE 530, (MSG2(I),I=0,132) 920 FORMAT(' ',I7,' NOT MATCHED WITH MESSAGE:') 930 FORMAT(' ',I7,' RECORDS MATCHED') 940 FORMAT(' ') C C CLOSE ALL IF THE FILES AND RETAIN THE INFORMATION STORED IN THEM. C CLOSE(UNIT=1,DISP='SAVE') CLOSE(UNIT=2,DISP='SAVE') CLOSE(UNIT=3,DISP='SAVE') CLOSE(UNIT=4,DISP='SAVE') STOP END