SUBROUTINE CALLNO(STR,LN) #THIS SUBROUTINE CONVERTS A LIBRARY OF CONGRESS BOOK #CATALOG NUMBER INTO A FORM THAT CAN BE SORTED BY #A NORMAL ALPHABETIC SORT. #THIS ROUTINE MODIFIES THE CALL NUMBER IN PLACE, SO IT #ONLY HAS TWO PARAMETERS: THE CALL NUMBER STRING, AND #THE MAXIMUM LENGTH OF A CALL NUMBER. DEFINE PNTR 1 DEFINE COUNT 2 DEFINE EXP 3 DEFINE ALPH 0 DEFINE NUMS 1 INTEGER LEGAL(3),MODE,P,ALPHA(2,4),NUMER(3,4),EXT BYTE STR(132),TEM(132),C,SPACE,POINT,ZERO,NINE,A,Z,NUL DATA SPACE,POINT,ZERO,NINE,A,Z,NUL/' ','.','0','9','A','Z',0/ DATA LEGAL/2,1,1/ #FIRST THE PROGRAM INITALIZES POINTERS #COUNTERS AND TABLES MODE=ALPH #FIRST CHAR EXPECTED SHOULD BE ALPHA N=1 #INTALIZE INDEX TO FIRST TABLE ENTRY DO I=1,3 { #ZERO ALL POINTERS AND COUNTERS DO J=1,2 { #IN THE TABLES ALPHA(J,I)=0 NUMER(J,I)=0 } NUMER(EXP,I)=-1 #-1 MEANS NO DECIMAL POINT HAS BEEN FOUND } P=1 #P POINTS TO THE CURRENT "INPUT" CHARACTER C=STR(P) #GET THE FIRST CHARACTER ALPHA(PNTR,N)=P #POINT FIRST TABLE ENTRY AT FIRST CHAR REPEAT { IF (MODE == ALPH) { #AM I EXPECTING AN ALPHA? IF (C>=A & C<=Z) { #YES, MAKE SURE IT IS ONE ALPHA(COUNT,N)=ALPHA(COUNT,N)+1 #COUNT ALL ALPHAS FOUND P=P+1 #INCRIMENT TO NEXT INPOUT CHAR C=STR(P) } ELSE { #IF IT IS NOT AN ALPHA, NUMER(PNTR,N)=P #CHANGE TO NUMERIC MODE MODE=NUMS } } ELSE { #I AM IN NUMERIC MODE IF ((C>=ZERO & C<=NINE) | C==POINT) { #MAKE SURE THIS CHAR IS NUMERIC IF (C==POINT & NUMER(EXP,N)==-1) #IF THIS IS THE FIRST DECIMAL POINT NUMER(EXP,N)=NUMER(COUNT,N) #REMEMMBER HOW MANY CHARS CAME BEFORE. NUMER(COUNT,N)=NUMER(COUNT,N)+1 #COUNT ALL NUMERIC CHARACTERS P=P+1 #INCRIMENT TO NEXT CHARACTER C=STR(P) } ELSE { #IF NOT NUMERIC, THEN N=N+1 #INCRIMENT TO NEXT TABLE PAIR ALPHA(PNTR,N)=P #AND SWITCH TO ALPHA MODE MODE=ALPH } } IF (C==NUL | P>LN | N>3 | C==SPACE) #REPEAT UNTIL ANY OF THESE CONDITIONS ARE MET BREAK } EXT=P #THE "EXTENTION" IS PROBABLY WHATEVER IS LEFT DO I=1,3 { #CHECK THE ALPHA AND NUMERIC WIDTHS FOR LEGALITY IF (ALPHA(COUNT,I) > LEGAL(I) | NUMER(COUNT,I)==0 | NUMER(EXP,I)==0) { IF (ALPHA(PNTR,I)~=0) #IF THERE IS SOMETHING ILLEGAL HERE, EXT=ALPHA(PNTR,I) #IT MUST BE PART OF THE EXTENTION DO J=I,3 #ALL REMAINING TEXT ALSO BELONGS ALPHA(COUNT,J)=0 #IN THE EXTENTION, SO BREAK #ZERO THE POINTERS AND EXIT } } DO I=1,LN #SPACE FILL THE SCRATCH BUFFER TEM(I)=SPACE IF (ALPHA(COUNT,1) > 0) { #IF THERE IS A CLASIFICATION NUMBER, P=1 #CONVERT IT TO NORMALIZED FORM K=ALPHA(PNTR,1) DO J=1,ALPHA(COUNT,1) { #FIRST TRANSFER THE ALPHA SECTION TEM(P)=STR(K) #LEFT JUSTIFIED K=K+1 P=P+1 } TEM(3)=NUMER(COUNT,1)+ZERO #THE "EXPONENT" OF THE CLASS NUMBER IF (NUMER(EXP,1) >= 0) #IS EQUAL TO THE NUMBER OF DIGITS, TEM(3)=NUMER(EXP,1)+Z #UNLESS THERE WAS A DECIMAL POINT K=NUMER(PNTR,1) P=4 #THEN TRANSFER THE NUMERIC SECTION WHILE (STR(K)>=ZERO & STR(K)<=NINE | STR(K)==POINT) { IF (STR(K) ~= POINT) #SKIP DECIMAL POINTS TEM(P)=STR(K) P=P+1 K=K+1 } } DO M=2,3 { #LOOP FOR THE SUB-CLASS AND CUTTER NUMBERS IF (ALPHA(COUNT,M) > 0) { #IS THERE SOMTHING HERE? P=M*8-5 #CALCULATE WHERE IT GOES IN OUTPUT TEM(P)=STR(ALPHA(PNTR,M)) #TRANSFER THE ALPHA SECTION P=P+1 K=NUMER(PNTR,M) #THEN TRANSFER THE NUMERIC DO I=1,NUMER(COUNT,M) { IF (STR(K) == POINT) { #IGNORE DECIMALS IN K=K+1 #SUB-CLASS AND CUTTER NUMBERS } ELSE { TEM(P)=STR(K) K=K+1 P=P+1 } } } } P=27 #27 IS THE CHARACTER OUTPUT K=EXT #POSITION OF THE EXTENTION SECTION WHILE (P<=LN & K<=LN & STR(K)~=NUL) { #LOOP FOR ALL REMAINING CHARACTERS IF (STR(K)>=ZERO & STR(K)<=NINE){ #NUMERIC CHARS ARE N=0 #TREATED DIFERENTLY J=K WHILE (STR(K)>=ZERO & STR(K)<=NINE) { #MOVE FORWARD PAST N=N+1 #THE LAST NUMERIC K=K+1 #COUNT ALL THE NUMERICS FOUND } IF (N>3) { #IF THERE ARE MORE THAN 3 DIGITS, DO I=1,N { #THEN JUST TRANSFER THE WHOLE TEM(P)=STR(J) #THING WITH NO CHANGES. P=P+1 J=J+1 } } ELSE { #IF THERE ARE 3 OR FEWER DIGITS, REPEAT { #FIRST BACK UP OVER ANY LEADING P=P-1 #SPACES IF (P<26 || TEM(P)~=SPACE) BREAK } P=P+1 DO I=1,4 { #THEN ZERO FILL THE OUTPUT, TEM(P)=ZERO P=P+1 } M=P-1 J=K-1 DO I=1,N { #FINALLY, STORE THE NUMBER RIGHT JUSTIFIED TEM(M)=STR(J) #AND ZERO FILLED M=M-1 J=J-1 } } } ELSE { #IF THE CHARACTER WAS NOT NUMERIC TO START WITH, TEM(P)=STR(K) #THEN JUST TRANSFER IT TO THE OUTPUT STRING P=P+1 K=K+1 } } DO I=1,LN #AFTER THE OUTPUT STRING IS ALL DONE, STR(I)=TEM(I) #THEN TRANSFER IT BACK TO THE FORTRAN PARAMETER RETURN END