1     ! LSLOW V7	C. HORNIG/RSL	1977.09.14
      ! V7: 1977.09.14/RSL: PUT NUMBER OF ASSOCIATIONS INTO HEADER
2     ! V6: 1977.08.10/RSL: FIX REVERSE SORT FOR QUERY USE.
3     !
      !   LSLOW IS THE INTERFACE BETWEEN THE LEADS DBMS AND THE
      ! LEADS SORT.  IT EXTRACTS KEYS.
      !
5     ! USES THE LEADS FUNCTION PACKAGES: 'FNA', 'FNB', 'FNC', 'FND'
6     !
      ! DOES NOT USE: FNA1%, FNI1$, FNP2$, FNS%, FNC%, FNA%
      !
7     !
      ! A SOFTWARE PRODUCT OF:
      !   PROJECT LEADS AND THE LEXINGTON PUBLIC SCHOOLS
      !
10    !		***** CORE COMMON FORMAT *****
      !
20    ! # BYTES		WHAT
      ! -------		-------------------------------------------
30    !  1 - 26		FILE NAME FOR KEY FILE
32    !    1		CHR$(13%)
34    !    1		CHR$(EXT. FILE NUMBER) TO SORT ALL RECORDS
      !			CVT%$(0%)+FILENAME TO USE A POINTER FILE
36    ! 2*(A+1)		ASSOCIATOR TYPES TO USE IN GETTIING RECORDS
      !			CVT%$(EXT. TYPE NUMBER)
38    ! 2*(A+1)		CVT%$(EXT. FILE #)
      !				FILES FOR WHICH TO MAKE POINTERS
40    !			CVT%$(EXT. FIELD #)
      !			CVT%$(0%)+CVT%$(PTR. FIELD)
      !				KEY FIELD LIST ENDED WITH:
      !					CVT%$(0%)+CVT%$(0%)
10000	DIM F2%(8%), F%(50%)
	: PRINT '	LSLOW V7';
	: T0=TIME(0%) : T1=TIME(1%)
10015 !
      ! READ THE CORE COMMON STRING AND EXTRACT THE KEY FILE NAME
      !
10020	V$=SYS(CHR$(7%))
	: P0%=INSTR(1%,V$,CHR$(13%))
	: O$=LEFT(V$,P0%)
	: P%=P0%+1%
10025 !
      ! AND THE SOURCE OF RECORDS.
      !
10030	READ F2%(I%) FOR I%=0% TO 8%
	: S%=CVT$%(MID(V$,P%,2%))
	: IF S% THEN S%=16%+FNO1%(0%,S%,'',-8%)
	ELSE P0%=INSTR(P%,V$,CHR$(13%))
	: S%=FNP%(MID(V$,P%+2%,P0%-P%-2%))
	: P%=P0%-1%
10035 !
      ! WHAT THE DIFFERENT FORMATS MEAN:
      !   1=STRING  2=INTEGER  3=FLOAT  4=CVT$$(156)
      !
10040	DATA 1,4,1,2,3,1,1,1,1
10041 !
      ! GET UP ASSOCIATOR LIST
      !
10042	S0%=S% AND 15%
10043	A1%=FNK%
	: IF A1% THEN A0%=A0%+1%
		: A0%(A0%),A1%=FNO3%(S0%,A1%,'')
		: S0%=A8%(A1%)
		: GOTO 10043
10044 !
      ! READ IN THE POINTER OUTPUT LIST
      !
10045	K%(I%)=FNO1%(0%,FNK%,'',-8%) FOR I%=0% TO A0%
	: L%=0%
10048 !
      ! START READING THE COMMAND LIST AND PROCESS FIELDS
      !
10050	F%=FNK%
	: IF F%=0% THEN 10070
	ELSE F0%=ABS(F%)
	: F%,F%(L%)=SGN(F%)*FNO2%(F0%,'',4%)
		: IF F%>0% THEN B8%(6%,F%)=F2%(B8%(6%,F%))
			ELSE B8%(6%,-F%)=-F2%(B8%(6%,-F%)) :
				F%(L%) = -F%
10055 !
      ! TOTAL UP THE LENGTHS
      !
10060	F%=ABS(F%)
	: R%=R%+B8%(2%,F%) : GOTO 10050
10065 !
      ! IT'S SOMETHING SPECIAL:
      !   F%<0% POINTER FIELD, F%=0% END OF LIST, F%>0% ASSOCIATOR
      !
10070	F%(L%)=0% : F%=FNK%
	: IF F% THEN F%(L%)=FNO2%(F%,'',4%) : GOTO 10050
10085 !
      ! WE'RE DONE HERE: OPEN THE OUTPUT AND SAVE CORE COMMON
      !
10090	L%=L%-2%
	: R%=3% UNLESS R%>=3% OR A0%
	: O%=FNO1%(0%,-R%-5%*(A0%+1%),O$,0%)
	: FIELD #O%, FNB%(O%)+8% AS I8$, 2% AS I8$
	: LSET I8$ = CVT%$(A0%)
	: C0$=RIGHT(V$,P%+2%)
10112 !
      ! GO TO THE FAST EXTRACTION IF THIS IS AN ISAM TYPE EXTRACTION
      !
10115	GOTO 11000 IF (S% AND 48%)=16% AND L%=1% AND A0%=0%
10117 !
      ! START THE ACTUAL PROCESSING
      !
10120	I8%=FNI%(S%)
10122	UNTIL FNX%(S%)
	: A1%=0%
10124	A1%=A1%+1%
	: IF A1%>A0% THEN GOSUB 15000
		: A1%=A1%-1%
10126	IF A1%=0% THEN 10134
	ELSE IF FNA2%(S0%,A0%(A1%))<>-1% THEN 10124
	ELSE A1%=A1%-1% : GOTO 10126
10134	NEXT
10135 !
      ! PUT THE RIGHT STUFF IN CORE COMMON
      !
10140	I8$=SYS(CHR$(8%)+O$+C0$)
	: PRINT USING '	XTRAC TIME: WALL=#####  CPU=#####.#',
		TIME(0%)-T0, .1*(TIME(1%)-T1)
10155 !
      ! AND GO AWAY TO THE SORTING PROGRAM
      !
10160	I8%=FNC2%(0%) : CHAIN 'SSLOW.BAC$' 20000
10995 !
      ! FAST AND QUICK EXTRACTION
      !
11000	S%=S% AND 15% : I8%=FNB%(S%) : F%=F%(1%)
11005 !
      ! S%=FILE, F%=FIELD
      !
11010	UNTIL FNY%(S%)
	: I8%=FNZ%(S%)
	: IF ASCII (D8$) = 0% THEN GOSUB 16000
	: FIELD #O%, FNE1%(O%) AS I8$, R% AS R$, 5% AS P$
	: LSET R$=S$
	: LSET P$=CVT%$(B9%(9%,S%))+FNP$(S%)
11020	NEXT
	: GOTO 10140
14995 !
      !				F N K $
      !
      !			EXTRACT THE KEY STRING
      !
15000	K$=''
15002	FOR P%=1% UNTIL P%>L%
15005 !
      ! HANDLE NORMAL FIELDS HERE
      !
15010	F%=F%(P%)
	: IF F% THEN GOSUB 16000
		: K$=K$+S$
		: GOTO 15150
15115 !
      ! 0 IS A POINTER FIELD - GET THE RECORD TO WHICH IT POINTS
      !
15120	P%=P%+1% : F%=F%(P%)
	: I8$=FNK1$(FNG2$(F%),F%)
		: I8%=FNG1%(B8%(7%,F%),CVT$%(I8$),ASCII(RIGHT(I8$,3%)))
15145 !
      ! KEY CREATED - WRITE IT OUT
      !
15150	NEXT P%
	: O0%=FNE1%(O%)+R%
	: FIELD #O%, O0%-R% AS I8$, R% AS R$
		: LSET R$=K$
15152 !
      ! PUT IN ALL THE NECESSARY POINTERS
      !
15155	FOR I%=0% TO A0%
	: FIELD #O%, O0%+5%*I% AS I8$, 5% AS P$
	: LSET P$=CVT%$(B9%(9%,K%(I%)))+FNP$(K%(I%))
15160	NEXT I%
	: RETURN
15995 !
      !			CONVERT A FIELD TO SORTABLE FORM
      !
16000	S$=FNK1$(FNG2$(F%),F%)
	: ON ABS(B8%(6%,F%)) GOTO 16100, 16030, 16050, 16010
16005 !
      ! $SP TYPE FORMAT - SQUISH THE FIELD
      !
16010	LSET S$=CVT$$(S$,156%) : GOTO 16100
16020 !
      ! NUMBER! - SET S$ TO NULL (OUTPUT KEY STRING) - SKIP
      ! SECTION IF FLOATING POINT NUMBER ELSE SET INTO INTEGER
      ! SORTABLE FORMAT AS DEFINED IN DOCUMENTATION
      !
16030	S$=CVT%$(32767%+1% XOR CVT$%(S$)) : GOTO 16100
16040 !
      ! NUMBER IS FLOATING POINT - SET INTO SORTABLE FORMAT AS
      ! DEFINED IN DOCUMENTATION
      !
16050	CHANGE S$ TO D9%
16060	FOR I9%=1% TO D9%(0%) STEP 4%
	: D9%=D9%(0%)-I9%
	: I8%=D9%(I9%) : D9%(I9%)=D9%(D9%) : D9%(D9%)=I8%
	: I8%=D9%(I9%+1%) : D9%(I9%+1%)=D9%(D9%+1%) : D9%(D9%+1%)=I8%
16070	NEXT I9%
	: IF D9%(1%) AND 128%
		THEN D9%(I8%)=NOT D9%(I8%) FOR I8%=1% TO D9%(0%)
		ELSE D9%(1%)=D9%(1%) OR 128%
16080	CHANGE D9% TO S$
16090 !
      ! ASCENDING OR DESCENDING?
      !
16100	IF B8%(6%,F%)<0% THEN CHANGE S$ TO D9%
	: D9%(Z%)=NOT D9%(Z%) FOR Z%=1% TO D9%(0%)
	: CHANGE D9% TO S$
16110	RETURN
19995 !
      ! CHAIN ENTRY TO 'LSLOW'
      !  CORE COMMON=OUT FILE/SOURCE/KEY/CHAIN
      !
20000	I%=-1% : GOTO 1000
25995 !
      ! GET AN INTEGER
      !
26000	DEF FNK%
	: L%=L%+1% : P%=P%+2% : FNK%=CVT$%(MID(V$,P%,2%))
26005	FNEND
32767	END
