Google
 

Trailing-Edge - PDP-10 Archives - 704rmsf2 - 10,7/rms10/rmssrc/rmsmsc.b36
There are 6 other files named rmsmsc.b36 in the archive. Click here to see a list.
MODULE MISCEL =


BEGIN

GLOBAL BIND	MISCV = 1^24 + 0^18 + 9;	!EDIT DATE: 05-APR-78

%([

THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.

!COPYRIGHT (C) 1977, 1979 BY DIGITAL EQUIPMENT CORPORATION


AUTHOR:	S. BLOUNT /EGM
FUNCTION:	THIS MODULE CONTAINS SEVERAL MISCELLANEOUS
		ROUTINES, EACH OF WHICH IS SMALL AND VERY
		SPECIAL-PURPOSE.


**********	TABLE OF CONTENTS	**************




	ROUTINE			FUNCTION
	=======			========

	GETKDB			FIND THE KEY DESCRIPTOR FOR A KEY OF REFERENCE

	MOVEKEY			MOVE A USER KEY STRING TO A BUFFER

	CKEYKK			COMPARE TWO NON-SEGMENTED KEY STRINGS

	CKEYKU			COMPARE KEY STRING TO SEGMENTED DATA RECORD

	CKEYUU			COMPARE TWO SEGMENTED KEY STRINGS (DATA RECORDS)

	SETNRP			SET UP THE NRP FOR INDEXED FILES





REVISION HISTORY:

EDIT	DATE		WHO	PURPOSE
====	====		===	=======

1	20-AUG-76	JK	ADD 'FBYRFA' ROUTINE.
2	3-SEP-76	JK	'FBYRFA' SHOULD TELL 'GETBKT' TO LOCK BKT.
3	3-SEP-76	JK	'FBYRFA' MOVED TO RMSUD2.
4	31-JAN-77	SB	GETKDB DOESNT CHECK FOR BAD KRF (FOR DISPLAY)
5	3-MAY-77	SB	MOVE SIDRELEMENT FROM RD TO RST
6	21-JUN-77	SB	SPEED UP SETNRP BY USING REGISTER RST PTR
7	21-JUN-77	SB	SET SIDR-ELEMENT IN RST ON EACH CALL TO SETNRP


*************************************************
*						*
*		NEW REVISION HISTORY		*
*						*
*************************************************

PRODUCT	MODULE	 SPR
 EDIT	 EDIT	 QAR		DESCRIPTION
======	======	=====		===========

13	8		NO SYMPTOMS OBSERVED, BUT THE KEY VALUES IN THE
			VARIOUS INDEX ARRAYS HAVE EXTRA BITS IN THEM. THIS
			IS STACK CONTENTS DEPENDENT, WHICH MEANS THAT SLIGHT
			ALTERATIONS TO USER PROGRAMS COULD PRODUCE FILES
			WHICH ARE FUNCTIONALLY EQUIVALENT BUT 'BIT-WISE'
			DIFFERENT. AVOID THIS BY CLEARING OUT THE DESTINATION
			KEY BUFFER BEFORE COPYING THE KEY.

****************** Start RMS-10 V1.1 *********************
********************* TOPS-10 ONLY ***********************

PRODUCT	MODULE	 SPR
 EDIT	 EDIT	 QAR		DESCRIPTION
======	======	=====		===========

 100	  9	Dev		Make declarations for routine names
				be EXTERNAL ROUTINE so RMS will compile 
				under BLISS V4 (RMT, 10/22/85).

	***** END OF REVISION HISTORY *****




])%



	%([ FORWARD DECLARATIONS ])%


	%([ EXTERNAL DECLARATIONS ])%

	EXTERNAL ROUTINE
	    CRASH,		! FOR DEBUGGING
	    DUMP,		! SAME
	    GETBKT,		! GET A BUFFER AND MAP A BUCKET
	    SDATABKT;	! SEARCH A DATA BUCKET


	%([ ERROR MESSAGES REFERENCED IN THIS MODULE ])%

	EXTERNAL
	    MSGINPUT,	! BAD INPUT VALUES
	    MSGKSZ,		! BAD KEY SIZE VALUE
	    MSGMOVESTRING,	! MOVE STRING FAILED
	    MSGKDB;		! NOT A KDB




REQUIRE 'RMSREQ';
EXTDECLARATIONS;



! GETKDB
! ======

! ROUTINE TO LOCATE A SPECIFIC KEY DESCRIPTOR BLOCK IN THE KDB CHAIN.
!	THIS ROUTINE IS CALLED WITH A KEY-OF-REFERENCE VALUEAND IT
!	RETURNS THE LOCATION OF THAT KDB.

! INPUT:
!	KEY-OF-REFERENCE VALUE

! OUTPUT:
!	FALSE:		KDB NOT FOUND
!	NOT FALSE:	KDB ADDRESS (NOT PUT INTO GLOBAL "KDB")

! ROUTINES CALLED:
!	CRASH

GLOBAL ROUTINE GETKDB ( KEYOFREFERENCE ) =
BEGIN
	ARGUMENT	(KEYOFREFERENCE,VALUE);	! REF VALUE

REGISTER
    KDBADDRESS:	POINTER,
    COUNTER;				! TEMP COUNTER OF KDB'S

	TRACE ( 'GETKDB' );


	%([ GET KDB ADDRESS ])%

	KDBADDRESS = .FST [ FSTKDB ];		! GET KDB FOR PRIMARY KEY
	COUNTER = ZERO;				! CLEAR COUNTER VALUE
	UNTIL .COUNTER IS .KEYOFREFERENCE
	DO %(THIS LOOP)%

		BEGIN
		IF ( KDBADDRESS = .KDBADDRESS [ KDBNXT ] )
			IS ZERO THEN BADRETURN;		! CHECK FOR END OF CHAIN
		INC ( COUNTER, 1 )			! BUMP THE COUNT
		END; %(OF LOOP)%

	%([ WE HAVE FOUND THE CORRECT KDB HERE ])%
	IF .KEYOFREFERENCE ISNT .KDBADDRESS [ KDBREF ]
		THEN RMSBUG (MSGKDB);

	LOOKAT ('	KDB FOUND AT: ',KDBADDRESS );
	RETURN .KDBADDRESS
END; %(OF GETKDB)%


! MOVEKEY
! =======

! ROUTINE TO MOVE A NON-CONTIGUOUS USER KEY STRING TO
!	A CONTIGUOUS  KEY BUFFER

! INPUT:
!	RECPTR		ADDRESS OF USER DATA RECORD
!
!	BUFFPTR		ADDRESS OF THE KEY BUFFER

! OUTPUT:
!	<NO STATUS RETURNED>

! ROUTINES CALLED:
!	<NONE>

GLOBAL ROUTINE MOVEKEY ( RECPTR, BUFFPTR ):NOVALUE =
BEGIN

	ARGUMENT	(RECPTR,BASEADD);		! RECORD ADDRESS
	ARGUMENT	(BUFFPTR,BASEADD);		! KEY BUFFER

REGISTER
	TEMPAC;
MAP
	RECPTR:	POINTER;

LOCAL
    TEMP1,			! TEMPORARIES FOR MOVING KEY 
    TEMP2,
    TEMP5,
    BYTEPTRLEFTHALF,				! USED TO FORM A BYTE PTR
    STARTOFRECRDPTR,
    FULLKEYSIZE,					! SIZE OF ENTIRE KEY
    KEYDESCPTR:	POINTER;				! KEY DESCRIPTOR PTR

	TRACE ( 'MOVEKEY' );

	%([ GET A BYTE POINTER TO THE START OF THE USER RECORD ])%

	STARTOFRECRDPTR = .RECPTR;

	%([ COMPUTE A LEFT HALF USING THE KEY BYTE SIZE ])%

	BYTEPTRLEFTHALF =  ( .KDB [ KDBKBSZ ] ^ 6 ) + NULLBP;	! FORM LEFT HALF OF BYTE PTR

	STARTOFRECRDPTR<LH> = .BYTEPTRLEFTHALF;

!** [13] ROUTINE:MOVEKEY AT LINE 6891, EGM, 3-AP-78
%([13])%	%([ CLEAR THE DESTINATION KEY AREA BEFORE THE COPY ])%
%([13])%
!**%([22])% ROUTINE:MOVEKEY , AU, 31-JULY-79
%([22])%	%([ If the key is just one word long, don't use BLT])%
%([22])%	IF .KDB [ KDBKSZW ]  EQL  1
%([22])%	THEN
%([22])%		(.BUFFPTR)<WRD> = 0
%([22])%	ELSE
%([13])%		CLEAR ( .BUFFPTR, .KDB [KDBKSZW ] );

	%([ SET UP THE BYTE POINTERS IN THE EXTEND AC BLOCK ])%

	TEMP5  = .BUFFPTR;
	TEMP5 <LH> = .BYTEPTRLEFTHALF;
	KEYDESCPTR = .KDB + KDBKSDOFFSET;		! FORM PTR TO KEY SEG DESC

	%([ GET THE SIZE OF THIS KEY STRING ])%

	FULLKEYSIZE = .KDB [ KDBKSZ ];
	%([ DO THIS LOOP ONCE FOR EACH KEY SEGMENT ])%

	INCR J FROM 0 TO MAXKEYSEGS-1
	DO
		BEGIN

		%([ IF WE HAVE MOVED ENTIRE KEY...EXIT ])%

		IF .FULLKEYSIZE IS ZERO THEN GOODRETURN;


		%([ GET THE STARTING POSITION OF THIS KEY ])%

		TEMPAC = .KEYDESCPTR [ .J, KEYPOS ];	! GET KEY POSITION

		%([ FORM A BYTE POINTER TO THIS KEY SEGMENT ])%


		ADJBP ( TEMPAC, STARTOFRECRDPTR );
		TEMP2 = .TEMPAC;


		%([ get the size of this segment ])%

		TEMP1 = .KEYDESCPTR [ .J, KEYSIZ ];
		DEC ( FULLKEYSIZE, .TEMP1 );

		%([ DO THE EXTEND INSTRUCTION ])%

		IF MOVELEFT (	%(FROM)%	TEMP2,
				%(TO)%		TEMP5,
				%(FROMSIZE)%	TEMP1,
				%(TOSIZE)%	TEMP1 ) IS FALSE
		THEN
			RMSBUG ( MSGMOVESTRING )
		END; %(OF INCR LOOP)%

	RETURN

END; %(OF MOVEKEY)%



! CKEYKK
! ======

! ROUTINE TO COMPARE TWO NON-SEGMENTED KEY STRINGS.
!	THIS ROUTINE IS USED TO COMPARE TWO CONTIGUOUS KEY STRINGS.
!	FOR EXAMPLE, A USER SEARCH KEY STRING AND AN INDEX RECORD
!	KEY STRING CAN BE COMPARED. HOWEVER, USER DATA RECORDS
!	CANNOT BE COMPARED WITH THIS ROUTINE BECAUSE THE KEYS
!	ARE (OR MAY BE) SEGMENTED.

! INPUT:
!	RECDESC		RECORD DESCRIPTOR
!		USERPTR		ADDRESS OF SEARCH KEY STRING
!		USERSIZE	SIZE OF SEARCH KEY STRING
!	TARGETKEYPTR	ADDRESS OF TARGET KEY STRING
!
! OUTPUT STATUS:
!	TRUE:	SEARCH TERMINATED NORMALLY (SEARCH KEY LEQ TARGET KEY)
!		RDFLGLSS MAY BE SET IN THE RECORD DESCRIPTOR
!	FALSE:	SEARCH KEY GTR TARGET KEY

! ROUTINES CALLED:
!	<NONE>

GLOBAL ROUTINE CKEYKK ( RECDESC, TARGETKEYPTR ) =
BEGIN
	ARGUMENT	(RECDESC,BASEADD);		! RECORD DESCRIPTOR
	ARGUMENT	(TARGETKEYPTR,BASEADD);		! ADDR OF DEST KEY

MAP
    RECDESC:	POINTER,
    TARGETKEYPTR:	POINTER;
REGISTER
	TEMPAC1,
	TEMPAC2,
	TEMPAC3,
	TEMPAC4;

	TRACE ('CKEYKK');
	CHECKEXACTCOUNT;

	%([ CHECK INPUT VALUES ])%

	CHECKINPUT (TARGETKEYPTR,GTR,ZERO);

	%([ CLEAR THE LSS FLAG BIT ])%

	CLRFLAG ( RECDESC [ RDSTATUS ], RDFLGLSS );


	%([ SET UP SOME BYTE POINTERS TO THE KEY STRINGS ])%

	TARGETKEYPTR = POINT ( .TARGETKEYPTR, 36, .KDB [ KDBKBSZ ]);
	TEMPAC1 = .TARGETKEYPTR;
	TEMPAC2 = .RECDESC [ RDUSERPTR ];
	TEMPAC2<LH> = .TARGETKEYPTR<LH>;			! USE SAME BYTE PTR FORMAT
	TEMPAC3 = .RECDESC [ RDUSERSIZE ];			! SIZE FOR COMPARE

	%([ COMPARE THE TWO KEY STRINGS ])%

	IF CSTRINGLE (  %(SEARCH PTR)%	TEMPAC2,
			%(TARGET)%	TEMPAC1,
			%(SIZES)%	TEMPAC3,
			%(SAME)%	TEMPAC3 ) IS FALSE

	%([ IF FALSE, THE SEARCH KEY WAS GTR THAN THE TARGET KEY ])%
	THEN
		BADRETURN;				! GIVE ERROR RETURN


	%([ KEY IS EITHER LSS OR EQUAL TO TARGET KEY ])%


	LDB ( TEMPAC3, TEMPAC2 );		! GET THE BYTES
	LDB ( TEMPAC4, TEMPAC1 );

	IF  . TEMPAC3  %(LAST CHAR OF SEARCH KEY)%
		LSS
	    . TEMPAC4  %(LAST CHAR OF TARGET KEY)%
	THEN
		SETLSSFLAG ( RECDESC );			! SET THE FLAG
	GOODRETURN
END; %(OF CKEYKK)%


! CKEYKU
! ======

! ROUTINE TO COMPARE KEY STRING TO A USER DATA RECORD (SEGMENTED)

! INPUT:
!	RECDESC		RECORD DESCRIPTOR PACKET
!		USERPTR		ADDRESS OF SEARCH KEY STRING
!		USERSIZE	SIZE OF SEARCH KEY STRING
!
!	DATAPTR		ADDRESS OF USER DATA RECORD

! OUTPUT:
!	TRUE:	SEARCH KEY .LEQ. TARGET KEY
!		FLGLSS MAY BE SET IN THE STATUS WORD
!	FALSE:	SEARCH KEY .GTR. TARGET KEY

! ROUTINES CALLED:
!	<NONE>

GLOBAL ROUTINE CKEYKU ( RECDESC, DATAPTR ) =
BEGIN
	ARGUMENT	(RECDESC,BASEADD);		! RECORD DESCRIPTOR
	ARGUMENT	(DATAPTR,BASEADD);		! DATA RECORD ADDRESS

MAP
    RECDESC:	POINTER,
    DATAPTR:	POINTER;

LOCAL
    SEARCHKEYPTR:	POINTER,				! BYTE PTR TO SEARCH KEY
    STARTOFRECPTR:	POINTER,				! BYTE PTR TO START OF DATA RECORD
    KSDPTR:	POINTER,					! PTR TO KEY SEGMENT DESC
    KEYSIZETOUSE,
    SEARCHKEYSIZE;					! SIZE OF K(S)

REGISTER
	TEMPAC1,
	TEMPAC2,
	TEMPAC3,
	TEMPAC4;


	TRACE ('CKEYKU');

	%([ SET UP SOME BYTE POINTERS ])%

	CLRFLAG ( RECDESC [ RDSTATUS ], RDFLGLSS );	! CLEAR STATUS
	SEARCHKEYSIZE = .RECDESC [ RDUSERSIZE ];	! GET KEY SIZE
	DATAPTR = POINT (.DATAPTR, 36, .KDB [ KDBKBSZ ]);	!FORM PTR

	STARTOFRECPTR = .DATAPTR;

	KSDPTR = .KDB + KDBKSDOFFSET;			! PTR TO KEY SEG DESC

	%([ SET UP PTRS TO SEARCH KEY ])%

	TEMPAC2 = .RECDESC [ RDUSERPTR ];
	TEMPAC2 <LH> = .DATAPTR<LH>;		! USE SAME LEFT HALF

	%([ DO THIS LOOP ONCE FOR EACH KEY SEGMENT ])%

	INCR J FROM 0 TO MAXKEYSEGS-1
	DO
		BEGIN


		TEMPAC4 = .KSDPTR [ .J, KEYPOS ];	! GET KEY POS

		%([ FORM A BYTE POINTER TO THIS KEY BYTE ])%

		ADJBP ( TEMPAC4, STARTOFRECPTR );

		%([ USE SMALLER OF THE SIZE OF THIS KEYSEGMENT
		   AND THE REST OF THE SEARCH KEY ])%

		KEYSIZETOUSE = .KSDPTR [ .J, KEYSIZ ];
		IF .SEARCHKEYSIZE LSS .KEYSIZETOUSE
		THEN
			KEYSIZETOUSE = .SEARCHKEYSIZE;
		TEMPAC1 = .KEYSIZETOUSE;	! LENGTH OF COMPARE

		%([ COMPARE THE STRINGS ])%

		IF CSTRINGLE (	%(K(S))%	TEMPAC2,
				%(TARGET)%	TEMPAC4,
				%(SIZE)%	TEMPAC1,
				%(SAME)%	TEMPAC1) IS FALSE

		%([ IF THIS FAILS, K(S) WAS GTR THAN THE TARGET KEY ])%

		THEN
			BADRETURN;

		%([ CHECK IF K(S) WAS LSS USER DATA RECORD KEY ])%


		LDB ( TEMPAC1, TEMPAC2 );
		LDB ( TEMPAC3, TEMPAC4 );

		IF  . TEMPAC1	%(LAST CHAR OF SEARCH KEY)%
			LSS
		    . TEMPAC3 	%(LAST CHAR OF USER KEY)%
		THEN
			BEGIN
			SETLSSFLAG ( RECDESC );
			GOODRETURN
			END;

		%([ DECREMENT SIZE OF SEARCH KEY ])%

		DEC ( SEARCHKEYSIZE, .KEYSIZETOUSE );

		IF .SEARCHKEYSIZE IS ZERO 
		THEN %(WE HAVE COMPARED THE ENTIRE KEY)%
			GOODRETURN;


		%IF DBUG %THEN
		IF .SEARCHKEYSIZE LSS ZERO THEN RMSBUG ( MSGKSZ )
		%FI

		END; %(OF INCR LOOP)%

	%([ KEY WAS AN EXACT MATCH ])%

	GOODRETURN
END; %(OF CKEYKU)%



! CKEYUU
! ======

! ROUTINE TO COMPARE TWO SEGMENTED KEY STRINGS.
!	THIS ROUTINE ACCEPTS THE ADDRESSES OF TWO KEY STRINGS
!	WHICH ARE SEGMENTED ( I.E., EXIST WITHIN A DATA RECORD ).
!	IT WILL COMPARE THESE TWO STRINGS TO DETERMINE WHICH ONE
!	IS "GREATER" THAN THE OTHER. CURRENTLY, THIS ROUTINE IS
!	USED ONLY WHEN AN $UPDATE IS DONE TO AN INDEXED FILE
!	AND THE NEW KEY STRINGS MUST BE COMPARED WITH THE OLD
!	VALUES OF EACH KEY.

! INPUT:
!	RECDESC		RECORD DESCRIPTOR PACKET
!		USERPTR		ADDRESS OF SOURCE DATA RECORD
!		USERSIZE	<IGNORED>
!
!	TARGETPTR	ADDRESS OF TARGET DATA RECORD

! OUTPUT:
!	TRUE:	SOURCE KEY STRING WAS .LEQ. TARGET KEY STRING
!		FLGLSS WILL BE SET IF SOURCE .LSS. TARGET
!
!	FALSE:	SOURCE KEY STRING WAS .GTR. TARGET KEY STRING

! ROUTINES CALLED:
!	<NONE>

! NOTES:
!
!	1.	THE SIZE OF THE KEY STRINGS CONTAINED IN THE
!		DATA RECORD IS NOT USED BY THIS ROUTINE. THIS
!		MEANS THAT IF THE DATA RECORD IS NOT LONG ENOUGH
!		TO COMPLETELY CONTAIN A PARTICULAR KEY STRING,
!		THIS ROUTINE SHOULD NOT BE CALLED.

GLOBAL ROUTINE CKEYUU ( RECDESC, TARGETPTR ) =
BEGIN

	ARGUMENT	(RECDESC,BASEADD);	! RECORD DESC PACKET
	ARGUMENT	(TARGETPTR,BASEADD);	! TARGET RECORD PTR
MAP
    RECDESC:	POINTER,
    TARGETPTR:	POINTER;

LOCAL
    SOURCEPTR:	POINTER,			! PTR TO SOURCE RECORD
    KSDPTR:	POINTER,				! PTR TO KEY SEGMENT DESCRIPTORS
    FULLKEYSIZE;				! SIZE OF ENTIRE KEY STRING

REGISTER
	TEMPAC1,
	TEMPAC2,
	TEMPAC3,
	TEMPAC4;



	TRACE ('CKEYUU');

	%([ CLEAR THE LSS FLAG BEFORE WE DO THE COMPARISON ])%

	CLRFLAG ( RECDESC [ RDSTATUS ], RDFLGLSS );

	%([ SET UP A BYTE POINTER TO THE SOURCE DATA RECORD ])%

	SOURCEPTR = POINT ( .RECDESC [ RDUSERPTR ], 36, .KDB [ KDBKBSZ ] );
	TARGETPTR<LH> = .SOURCEPTR<LH>;			! FORM PTR FOR TARGET

	%([ SET UP A POINTER TO THE KEY SEGMENT DESCRIPTORS IN THE KDB ])%

	KSDPTR = .KDB + KDBKSDOFFSET;

	%([ FETCH THE FULL SIZE OF THE ENTIRE KEY STRING ])%

	FULLKEYSIZE = .KDB [ KDBKSZ ];

	%([ DO THIS LOOP ONCE FOR EACH KEY SEGMENT ])%

	INCR J FROM 0 TO MAXKEYSEGS -1
	DO

		BEGIN

		%([ IF WE HAVE SCANNED ENTIRE KEY, WE CAN EXIT ])%

		IF .FULLKEYSIZE IS ZERO THEN GOODRETURN;


		%([ IF THIS SEGMENT IS NULL, DON'T BOTHER WITH IT ])%

		IF ( TEMPAC1 = .KSDPTR [ .J, KEYSIZ ] ) ISNT ZERO
		THEN	%(WE CAN COMPARE IT)%

			BEGIN

			%([ DECREMENT THE AMOUNT LEFT TO PROCESS ])%

			DEC ( FULLKEYSIZE, .TEMPAC1 );

			%IF DBUG %THEN
			IF .FULLKEYSIZE LSS ZERO THEN RMSBUG ( MSGKSZ );
			%FI

			%([ GET THE POSITION OF THIS SEGMENT ])%

			TEMPAC2 = .KSDPTR [ .J, KEYPOS ];
			TEMPAC4 = .TEMPAC2;

			%([ FORM A BYTE PTR TO THIS SEGMENT ])%

			ADJBP ( TEMPAC2, SOURCEPTR );
			ADJBP ( TEMPAC4, TARGETPTR );


			%([ WE NOW HAVE TWO BYTE PTRS TO THE TWO RECORDS.
			   WE CAN COMPARE THIS KEY SEGMENT. ])%

			IF CSTRINGLE ( %(SOURCE)%	TEMPAC2,
					%(TARGET)%	TEMPAC4,
					%(SIZE)%	TEMPAC1,
					%(SIZE)%	TEMPAC1) IS FALSE

			%([ IF THIS INSTRUCTION FAILS, THEN THE SOURCE
			   KEY SEGMENT WAS .GTR. THAN THE TARGET KEY
			   SEGMENT. IN SUCH A CASE, WE CAN EXIT. ])%

			THEN
				RETURN FALSE;

			%([ HOWEVER, THE SOURCE KEY SEGMENT MAY HAVE BEEN
			   .LSS. THEN TARGET KEY SEGMENT. SO, WE MUST
			   COMPARE THE LAST TWO CHARACTERS PROCESSED BY
			   THIS INSTRUCTION TO SEE IF THEY ARE EQUAL. ])%

			LDB ( TEMPAC1, TEMPAC2 );		! GET THE BYTES
			LDB ( TEMPAC3, TEMPAC4 );
			IF  . TEMPAC1 	%(LAST CHAR OF SOURCE)%
				LSS
			    . TEMPAC3 	%(LAST CHAR OF TARGET)%
			THEN	%(SOURCE WAS LSS THEN TARGET)%

				BEGIN
				SETLSSFLAG ( RECDESC );
				GOODRETURN
				END

			%([ AT THIS POINT, THE KEY SEGMENTS WERE EQUAL,	
			   OR THE SIZE WAS ZERO. IN EITHER CASE, WE CAN
			   GO BACK FOR THE NEXT KEY SEGMENT. ])%

			END	%(OF IF KEYSIZ ISNT ZERO)%

		END;	%(OF INCR J LOOP)%

	%([ THE SOURCE KEY WAS IDENTICAL TO THE TARGET KEY ])%

	GOODRETURN

END;	%(OF CKEYUU)%



! SETNRP
! ======

! ROUTINE TO SET UP THE NEXT-RECORD-POINTER CONTEXT FOR 
!	INDEXED FILES IN THE RST. THIS ROUTINE IS CALLED
!	WHENEVER THE NRP MIGHT HAVE TO BE CHANGED (E.G., $GET,
!	$FIND, $PUT SEQ, ETC. ).

! INPUT:
!	RECDESC		RECORD DESCRIPTOR PACKET
!		RFA		RFA OF DATA RECORD
!				(EITHER UDR OR SIDR)
!		RRV		RFA OF RRV RECORD
!		RECPTR		ADDRESS OF DATA RECORD IN BUFFER
!		SIDRELEMENT	OFFSET INTO CURRENT POINTER ARRAY
!
!	DATABD		BUCKET DESCRIPTOR OF DATA BUCKET

! OUTPUT:
!	<NO STATUS RETURNED>

GLOBAL ROUTINE SETNRP ( RECDESC, DATABD ): NOVALUE =
BEGIN
	ARGUMENT	(RECDESC,BASEADD);
	ARGUMENT	(DATABD,BASEADD);	! BKT DESC FOR DATA BKT
MAP
    RECDESC:	POINTER,
    DATABD:	POINTER;

REGISTER
    KEYSIZEINWORDS,
    RSTPTR:	POINTER,			! FOR SPEED
    ACPTR:	POINTER;			! TEMP PTR

LOCAL
    RECORDPTR:	POINTER,		! PTR TO CURRENT RECORD
    KEYBUFFPTR:	POINTER;		! PTR TO KEY BUFFER

	TRACE ('SETNRP');

	%([ GET A POINTER TO THE ACTUAL PRIMARY DATA RECORD ])%

	RECORDPTR = .RECDESC [ RDRECPTR ];		! GET PTR TO RECORD

	RSTPTR = .RST;					! GET RST ADDRESS
	RSTPTR [ RSTRPREF ] = .KDB [ KDBREF ];		! SET UP KRF OF RP

	%([ SET UP THE INTERNAL REPRESENTATION OF THE CURRENT RECORD.
	   NOTE THAT THIS REPRESENTATIN IS DIFFERENT FROM THE
	   EXTERNAL (USER'S RFA) FORMAT. THIS IS BECAUSE THE USER
	   MUST HAVE A PERMANENT HANDLE ON THE RECORD...THUS THE
	   RRV FORMAT. HOWEVER, SINCE THE RECORD CANT MOVE WHILE
	   IT IS OUR CURRENT RECORD, WE CAN REPRESENT IT INTERNALLY
	   BY ITS RFA FORMAT. ])%

	RSTPTR [ RSTDATARFA ] = MAKERFA ( .DATABD [ BKDBKTNO ], .RECORDPTR [ DRRECORDID ] );

	%([ SET UP THE OFFSET INTO THE CURRENT POINTER ARRAY OF
	   THE CURRENT RECORD (FOR PRIMARY KEYS, THIS OPERATION
	   IS UNIMPORTANT) ])%

	RSTPTR [ RSTRPSIDR ] = .RECDESC [ RDSIDRELEMENT ];	![%44]SET TENTATIVE SIDR ELEM

	%([ IF THIS IS A $FIND RANDOM, THEN WE DONT NEED TO SET
	   UP THE NRP DATA -- UNLESS ROPNRP SET. ])%

	IF	( CURRENTJSYS IS C$FIND )
			AND
		( NOT SEQADR )
			AND
		(CHKFLAG( RAB [RABROP], ROPNRP) EQL 0)
	THEN
		RETURN;

	%([ WE CAN NOW SET UP THE NEXT RECORD POINTER DATA ])%

	%([ SET UP THESE VALUES ])%

	RSTPTR [ RSTNRP ] = .RECDESC [ RDRFA ];
	RSTPTR [ RSTNRPRRV ] = .RECDESC [ RDRRV ];

	%([ MOVE THE KEY STRING INTO THE RST KEY BUFFER.
	   NOTE THAT THE KEY OF THE CURRENT DATA RECORD IS
	   MOVED INTO THE BUFFER WITH THE FULL KEY-STRING SIZE,
	   NOT THE SIZE GIVEN BY THE USER (MAY HAVE BEEN A
	   GENERIC SELECTION ) ])%


	%([ WE MUST BUMP THE POINTER TO THE DATA (ALWAYS A PRIMARY DATA RECOR)
	   BUT THEN MOVE THE KEY (COULD BE SECONDARY)
	   INTO THE KEY BUFFER. SO, WE WILL NEED A TEMP
	   POINTER TO THE PRIMARY KDB ])%

	ACPTR = .FST [ FSTKDB ];			! PRIMARY KDB
	INC ( RECORDPTR, .ACPTR [ KDBHSZ ] );		! BUMP OVER PRIMARY HEADER
	KEYBUFFPTR = .RSTPTR [ RSTKEYBUFF ];		! ADDRESS TO MOVE IT
	CALLMOVEKEY (	%(FROM RECORD)%	LPT ( RECORDPTR ),
			%(TO BUFFER)%	LPT ( KEYBUFFPTR ) );

	%([ SAVE THE KEY OF REFERENCE OF THE NRP ])%

	RSTPTR [ RSTNRPREF ] = .KDB [ KDBREF ];
	RSTPTR [ RSTSIDRELEMENT ] = .RECDESC [ RDSIDRELEMENT ];
							![%44]NOT $FIND RANDOM, SO SET ACTU SIDR ELEM

	RETURN
END; %(OF SETNRP)%
END
ELUDOM