346 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			OpenEdge ABL
		
	
	
	
	
	
			
		
		
	
	
			346 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			OpenEdge ABL
		
	
	
	
	
	
15000 #include "rundecs.h"
 | 
						|
15010     (*  COPYRIGHT 1983 C.H.LINDSEY, UNIVERSITY OF MANCHESTER  *)
 | 
						|
15020 (**)
 | 
						|
15030 (**)
 | 
						|
15040 PROCEDURE GARBAGE(ANOBJECT:OBJECTP); EXTERN;
 | 
						|
15050 PROCEDURE ERRORR(N: INTEGER); EXTERN;
 | 
						|
15060 (**)
 | 
						|
15070 (**)
 | 
						|
15080 PROCEDURE FORMPDESC(OLDESC: OBJECTP; VAR PDESC1: PDESC);
 | 
						|
15090   VAR N: OFFSETRANGE; I, J, K: INTEGER;
 | 
						|
15100     BEGIN WITH OLDESC^, PDESC1 DO
 | 
						|
15110       BEGIN
 | 
						|
15120       PSIZE := SIZE;
 | 
						|
15130       ACCOFFS := -ELSCONST;
 | 
						|
15140       J := 0;
 | 
						|
15150       FOR I := 0 TO ROWS DO WITH DESCVEC[I], PDESCVEC[J] DO
 | 
						|
15160         BEGIN
 | 
						|
15170         N := UI-LI+1; IF N<0 THEN N := 0;
 | 
						|
15180         ACCOFFS := ACCOFFS+LI*DI;
 | 
						|
15190         PND := DI*N;
 | 
						|
15200         PROWS := J;
 | 
						|
15210         IF PSIZE=DI THEN
 | 
						|
15220           BEGIN PSIZE := PND; PD := PSIZE END
 | 
						|
15230         ELSE
 | 
						|
15240           BEGIN J := J+1; PD := DI END;
 | 
						|
15250         PL := ELSCONST-LBADJ+ACCOFFS+PND;
 | 
						|
15260         PP := PL;
 | 
						|
15270         FOR K := PROWS-1 DOWNTO 0 DO WITH PDESCVEC[K] DO
 | 
						|
15280           BEGIN PL := PL+LI*DI; PP := PL END;
 | 
						|
15290         END;
 | 
						|
15300       WITH PDESCVEC[PROWS] DO PP := PL-PND-PD
 | 
						|
15310       END
 | 
						|
15320     END;
 | 
						|
15330 (**)
 | 
						|
15340 (**)
 | 
						|
15350 FUNCTION NEXTEL(I: INTEGER; VAR PDESC1: PDESC): BOOLEAN;
 | 
						|
15360     BEGIN WITH PDESC1 DO WITH PDESCVEC[I] DO
 | 
						|
15370       BEGIN
 | 
						|
15380       PP := PP+PD;
 | 
						|
15390       IF PP<PL THEN
 | 
						|
15400         BEGIN
 | 
						|
15410         NEXTEL := TRUE
 | 
						|
15420         END
 | 
						|
15430       ELSE IF I<PROWS THEN
 | 
						|
15440         IF NEXTEL(I+1, PDESC1) THEN
 | 
						|
15450           BEGIN
 | 
						|
15460           PP := PDESCVEC[I+1].PP;
 | 
						|
15470           PL := PP+PND;
 | 
						|
15480           NEXTEL := TRUE
 | 
						|
15490           END
 | 
						|
15500         ELSE NEXTEL := FALSE
 | 
						|
15510       ELSE
 | 
						|
15520         BEGIN
 | 
						|
15530         NEXTEL := FALSE;
 | 
						|
15540         PP := PL-PND-PD
 | 
						|
15550         END
 | 
						|
15560       END
 | 
						|
15570     END;
 | 
						|
15580 (**)
 | 
						|
15590 (**)
 | 
						|
15600 PROCEDURE PCINCR(STRUCTPTR: UNDRESSP; TEMPLATE: DPOINT; INCREMENT: INTEGER);
 | 
						|
15610  VAR  TEMPOS, STRUCTPOS: INTEGER;
 | 
						|
15620       PTR: UNDRESSP;
 | 
						|
15630  BEGIN
 | 
						|
15640       TEMPOS:= 1;
 | 
						|
15650       STRUCTPOS:= TEMPLATE^[1];
 | 
						|
15660       WHILE STRUCTPOS >= 0
 | 
						|
15670       DO BEGIN
 | 
						|
15680            PTR := INCPTR(STRUCTPTR, STRUCTPOS);
 | 
						|
15690            WITH PTR^ DO
 | 
						|
15700              BEGIN
 | 
						|
15710              FINCD(FIRSTPTR^,INCREMENT);
 | 
						|
15720              IF FPTST(FIRSTPTR^) THEN GARBAGE(FIRSTPTR);
 | 
						|
15730              END;
 | 
						|
15740            TEMPOS:= TEMPOS+1;
 | 
						|
15750            STRUCTPOS:= TEMPLATE^[TEMPOS];
 | 
						|
15760       END;
 | 
						|
15770  END;
 | 
						|
15780 (**)
 | 
						|
15790 (**)
 | 
						|
15800 PROCEDURE PCINCRMULT(ELSPTR:OBJECTP; INCREMENT: INTEGER);
 | 
						|
15810 VAR   TEMPLATE: DPOINT;
 | 
						|
15820       COUNT, ELSIZE: INTEGER;
 | 
						|
15830       PTR: UNDRESSP;
 | 
						|
15840  BEGIN
 | 
						|
15850       TEMPLATE:= ELSPTR^.DBLOCK;
 | 
						|
15860       IF ORD(TEMPLATE)<=MAXSIZE  (*NOT STRUCT*)
 | 
						|
15870      THEN
 | 
						|
15880            IF ORD(TEMPLATE)=0 (*DRESSED*)
 | 
						|
15890            THEN
 | 
						|
15900                 BEGIN
 | 
						|
15910                 PTR := INCPTR(ELSPTR, ELSCONST);
 | 
						|
15920                 WHILE ORD(PTR)<ORD(ELSPTR)+ELSCONST+ELSPTR^.D0 DO WITH PTR^ DO
 | 
						|
15930                      BEGIN
 | 
						|
15940                      FINCD(FIRSTPTR^,INCREMENT);
 | 
						|
15950                      IF FPTST(FIRSTPTR^) THEN GARBAGE(FIRSTPTR);
 | 
						|
15960                      PTR := INCPTR(PTR, SZADDR);
 | 
						|
15970                      END
 | 
						|
15980                 END
 | 
						|
15990           ELSE (*NO ACTION*)
 | 
						|
16000      ELSE BEGIN (*STRUCT*)
 | 
						|
16010                 ELSIZE:= TEMPLATE^[0];
 | 
						|
16020                IF TEMPLATE^[1]>0
 | 
						|
16030                 THEN BEGIN
 | 
						|
16040                      COUNT := ELSPTR^.D0-ELSIZE;
 | 
						|
16050                      PTR := INCPTR(ELSPTR, ELSCONST);
 | 
						|
16060                      WHILE COUNT >= 0
 | 
						|
16070                      DO BEGIN
 | 
						|
16080                           PCINCR(PTR, TEMPLATE, INCREMENT);
 | 
						|
16090                           PTR := INCPTR(PTR, ELSIZE);
 | 
						|
16100                           COUNT:= COUNT-ELSIZE
 | 
						|
16110                      END;
 | 
						|
16120                 END;
 | 
						|
16130       END;
 | 
						|
16140  END;
 | 
						|
16150 (**)
 | 
						|
16160 (**)
 | 
						|
16170 PROCEDURE COPYSLICE(ASLICE: OBJECTP);
 | 
						|
16180   VAR NEWSLICE, OLDELS, NEWELS: OBJECTP;
 | 
						|
16190       COUNT, SIZEACC, OFFACC: INTEGER;
 | 
						|
16200       PDESC1: PDESC;
 | 
						|
16210       OLDESCVEC: ARRAY [0..7] OF PDS;
 | 
						|
16220       OLDLBADJ: BOUNDSRANGE;
 | 
						|
16230       OLDROWS: 0..7;
 | 
						|
16240   PROCEDURE CSSUPP(ASLICE: OBJECTP);
 | 
						|
16250     VAR LSLICEADJ, COUNT, NCOUNT, NEWDI, ACCOFFS, ACCADJ: INTEGER;
 | 
						|
16260       BEGIN
 | 
						|
16270       WITH ASLICE^ DO
 | 
						|
16280         BEGIN
 | 
						|
16290         FPDEC(PVALUE^);
 | 
						|
16300         IF FPTST(PVALUE^) THEN GARBAGE(PVALUE);
 | 
						|
16310         PVALUE := NEWELS;
 | 
						|
16320         FPINC(NEWELS^);
 | 
						|
16330         ASLICE := IHEAD;
 | 
						|
16340         END;
 | 
						|
16350       WHILE ASLICE<>NIL DO WITH ASLICE^ DO
 | 
						|
16360         BEGIN
 | 
						|
16370         ACCOFFS := -ELSCONST;
 | 
						|
16380         FOR COUNT := 0 TO ROWS DO WITH DESCVEC[COUNT] DO
 | 
						|
16390           ACCOFFS := ACCOFFS+LI*DI;
 | 
						|
16400         LSLICEADJ := ACCOFFS-LBADJ-PDESC1.ACCOFFS+OLDLBADJ;
 | 
						|
16410         ACCADJ := 0;
 | 
						|
16420         NCOUNT := ROWS;
 | 
						|
16430         FOR COUNT := OLDROWS DOWNTO 0 DO WITH OLDESCVEC[COUNT] DO
 | 
						|
16440           BEGIN
 | 
						|
16450           NEWDI := NEWSLICE^.DESCVEC[COUNT].DI;
 | 
						|
16460           ACCADJ := ACCADJ+(LSLICEADJ DIV DI)*NEWDI;
 | 
						|
16470           LSLICEADJ := LSLICEADJ MOD DI;
 | 
						|
16480           IF NCOUNT>=0 THEN
 | 
						|
16490             IF DESCVEC[NCOUNT].DI=DI THEN WITH DESCVEC[NCOUNT] DO
 | 
						|
16500               BEGIN
 | 
						|
16510               ACCOFFS := ACCOFFS+LI*(NEWDI-DI);
 | 
						|
16520               DI := NEWDI;
 | 
						|
16530               NCOUNT := NCOUNT-1
 | 
						|
16540               END;
 | 
						|
16550           END;
 | 
						|
16560         LBADJ := ACCOFFS-ACCADJ;
 | 
						|
16570         CSSUPP(ASLICE);
 | 
						|
16580         ASLICE := FPTR;
 | 
						|
16590         END
 | 
						|
16600       END;
 | 
						|
16610 (**)
 | 
						|
16620     BEGIN (*COPYSLICE*)
 | 
						|
16630     FORMPDESC(ASLICE, PDESC1);
 | 
						|
16640     WITH ASLICE^  DO
 | 
						|
16650       BEGIN
 | 
						|
16660       OLDELS := PVALUE;
 | 
						|
16670       OLDLBADJ := LBADJ;
 | 
						|
16680       OLDROWS := ROWS;
 | 
						|
16690       SIZEACC:= SIZE;
 | 
						|
16700       OFFACC:= -ELSCONST;
 | 
						|
16710       FOR COUNT := 0 TO ROWS DO
 | 
						|
16720         BEGIN
 | 
						|
16730         OLDESCVEC[COUNT] := DESCVEC[COUNT];
 | 
						|
16740         WITH DESCVEC[COUNT] DO
 | 
						|
16750           BEGIN
 | 
						|
16760                DI:= SIZEACC;
 | 
						|
16770                SIZEACC := OFFACC+SIZEACC*LI;
 | 
						|
16780                OFFACC:= SIZEACC;
 | 
						|
16790                SIZEACC:= UI-LI;
 | 
						|
16800                IF SIZEACC < 0
 | 
						|
16810                THEN SIZEACC:= 0
 | 
						|
16820                ELSE SIZEACC:= SIZEACC+1;
 | 
						|
16830                SIZEACC:= SIZEACC*DI;
 | 
						|
16840           END;
 | 
						|
16850         END;
 | 
						|
16860       LBADJ := OFFACC;
 | 
						|
16870       ENEW(NEWELS, SIZEACC+ELSCONST);
 | 
						|
16880       WITH NEWELS^ DO
 | 
						|
16890         BEGIN
 | 
						|
16900 (*-02() FIRSTWORD := SORTSHIFT*ORD(IELS); ()-02*)
 | 
						|
16910 (*+02() PCOUNT:=0; SORT:=IELS; ()+02*)
 | 
						|
16920         OSCOPE := 0;
 | 
						|
16930         D0 := SIZEACC;
 | 
						|
16940         CCOUNT:= 1;
 | 
						|
16950         DBLOCK:= OLDELS^.DBLOCK;
 | 
						|
16960         IHEAD := NIL;
 | 
						|
16970         END;
 | 
						|
16980       IF ASLICE=BPTR^.IHEAD THEN
 | 
						|
16990         BEGIN
 | 
						|
17000         BPTR^.IHEAD:= FPTR;
 | 
						|
17010         IF FPTR=NIL THEN
 | 
						|
17020           BEGIN FPDEC(BPTR^); IF FPTST(BPTR^) THEN GARBAGE(BPTR) END
 | 
						|
17030         END
 | 
						|
17040       ELSE BPTR^.FPTR := FPTR;
 | 
						|
17050       IF FPTR<>NIL THEN
 | 
						|
17060         BEGIN FPTR^.BPTR := BPTR; FPTR := NIL END;
 | 
						|
17070       BPTR:= NIL;
 | 
						|
17080       END;
 | 
						|
17090     COUNT := ELSCONST;
 | 
						|
17100     WHILE NEXTEL(0, PDESC1) DO WITH PDESC1 DO WITH PDESCVEC[0] DO
 | 
						|
17110           BEGIN
 | 
						|
17120           MOVELEFT(INCPTR(OLDELS, PP), INCPTR(NEWELS, COUNT), PSIZE);
 | 
						|
17130           COUNT := COUNT+PSIZE;
 | 
						|
17140           END;
 | 
						|
17150     PCINCRMULT(NEWELS, +INCRF);
 | 
						|
17160     NEWSLICE := ASLICE;
 | 
						|
17170     CSSUPP(ASLICE);
 | 
						|
17180     END;
 | 
						|
17190 (**)
 | 
						|
17200 (**)
 | 
						|
17210 PROCEDURE TESTCC(TARGET: OBJECTP);
 | 
						|
17220   LABEL 0000;
 | 
						|
17230   VAR DESTREF, LDESC, HEAD, NEWMULT, NEWELS: OBJECTP;
 | 
						|
17240       I, CREATIONC, ELSIZE, ACCOFF, LACOFFSET, LACOFF2: INTEGER;
 | 
						|
17250     BEGIN
 | 
						|
17260     WITH TARGET^.ANCESTOR^ DO
 | 
						|
17270       IF PVALUE^.PCOUNT-ORD(PVALUE^.IHEAD<>NIL)>1 THEN
 | 
						|
17280         BEGIN
 | 
						|
17290         (*  PCOUNT > 1 FOR OTHERS BESIDES IHEAD *)
 | 
						|
17300         WITH PVALUE^ DO BEGIN
 | 
						|
17310           FDEC;
 | 
						|
17320           ENEW(NEWELS, D0+ELSCONST)
 | 
						|
17330           END;
 | 
						|
17340         MOVELEFT(PVALUE, NEWELS, PVALUE^.D0+ELSCONST);
 | 
						|
17350         PCINCRMULT(PVALUE, +INCRF);
 | 
						|
17360         PVALUE:= NEWELS;
 | 
						|
17370         NEWELS^.PCOUNT := 1; (* SORT ALREADY SET*)
 | 
						|
17380         NEWELS^.IHEAD := NIL;
 | 
						|
17390         CCOUNT := NEWELS^.CCOUNT
 | 
						|
17400         END
 | 
						|
17410       ELSE
 | 
						|
17420         BEGIN
 | 
						|
17430         NEWELS := PVALUE;
 | 
						|
17440         CREATIONC := NEWELS^.CCOUNT;
 | 
						|
17450         DESTREF := TARGET;
 | 
						|
17460         IF CREATIONC=TARGET^.CCOUNT THEN GOTO 0000; (*EXIT*)
 | 
						|
17470         WITH DESTREF^ DO
 | 
						|
17480           IF SORT=REFSL1 THEN
 | 
						|
17490             BEGIN
 | 
						|
17500             ELSIZE := TARGET^.ANCESTOR^.SIZE; ACCOFF := ELSIZE+OFFSET;
 | 
						|
17510             END
 | 
						|
17520           ELSE
 | 
						|
17530             BEGIN
 | 
						|
17540             ELSIZE := PVALUE^.D0;
 | 
						|
17550             ACCOFF := ELSIZE-LBADJ;
 | 
						|
17560             FOR I := 0 TO ROWS DO WITH DESCVEC[I] DO
 | 
						|
17570               ACCOFF := ACCOFF+LI*DI;
 | 
						|
17580               (*ACCOFF = DIST FROM START OF ELEMENTS TO 1ST EL BEYOND THIS SLICE*)
 | 
						|
17590             END;
 | 
						|
17600         (*SLCOPY*)
 | 
						|
17610         HEAD := NEWELS^.IHEAD;
 | 
						|
17620         WHILE HEAD <> NIL DO WITH HEAD^ DO
 | 
						|
17630           BEGIN
 | 
						|
17640           LACOFFSET := -LBADJ-ACCOFF;
 | 
						|
17650           FOR I := 0 TO ROWS DO WITH DESCVEC[I] DO
 | 
						|
17660             LACOFFSET := LACOFFSET+LI*DI;
 | 
						|
17670           (*DIST FROM BEYOND LAST EL OF DESTREF TO 1ST EL OF HEAD*)
 | 
						|
17680           WITH DESCVEC[ROWS] DO
 | 
						|
17690             IF UI < LI THEN
 | 
						|
17700               I:= 0
 | 
						|
17710             ELSE I := (UI-LI+1)*DI;
 | 
						|
17720           LACOFF2 := I+LACOFFSET+ELSIZE;
 | 
						|
17730           (*DIST FROM 1ST EL OF DESTREF TO BEYOND LAST EL OF HEAD*)
 | 
						|
17740           IF (LACOFFSET>=0) OR (LACOFF2<=0) THEN
 | 
						|
17750             HEAD := FPTR
 | 
						|
17760           ELSE BEGIN
 | 
						|
17770             COPYSLICE(HEAD);
 | 
						|
17780             HEAD := NEWELS^.IHEAD;
 | 
						|
17790             END;
 | 
						|
17800           END;
 | 
						|
17810         0000:IF CREATIONC<>0 THEN DESTREF^.CCOUNT := CREATIONC
 | 
						|
17820         END
 | 
						|
17830     END;
 | 
						|
17840 (**)
 | 
						|
17850 (**)
 | 
						|
17860 PROCEDURE TESTSS (REFSTRUCT: OBJECTP);
 | 
						|
17870 (*ASSERT ITS PCOUNT > 1*)
 | 
						|
17880   VAR OBJSIZE: INTEGER;
 | 
						|
17890       TEMPLATE: DPOINT;
 | 
						|
17900       NEWSTRUCT: OBJECTP;
 | 
						|
17910     BEGIN
 | 
						|
17920     WITH REFSTRUCT^ DO
 | 
						|
17930       BEGIN
 | 
						|
17940       FPDEC(PVALUE^);
 | 
						|
17950       TEMPLATE := PVALUE^.DBLOCK;
 | 
						|
17960       OBJSIZE := TEMPLATE^[0];
 | 
						|
17970       ENEW(NEWSTRUCT, OBJSIZE+STRUCTCONST);
 | 
						|
17980       MOVELEFT(INCPTR(PVALUE, STRUCTCONST), INCPTR(NEWSTRUCT, STRUCTCONST), OBJSIZE);
 | 
						|
17990       PCINCR(INCPTR(PVALUE, STRUCTCONST), TEMPLATE, +INCRF);
 | 
						|
18000       WITH NEWSTRUCT^ DO
 | 
						|
18010       BEGIN
 | 
						|
18020 (*-02() FIRSTWORD := SORTSHIFT*ORD(STRUCT); ()-02*)
 | 
						|
18030 (*+02() SORT:=STRUCT; ()+02*)
 | 
						|
18040         PCOUNT := 1;
 | 
						|
18050         LENGTH := REFSTRUCT^.PVALUE^.LENGTH;
 | 
						|
18060         DBLOCK:= TEMPLATE
 | 
						|
18070         END;
 | 
						|
18080       PVALUE:= NEWSTRUCT
 | 
						|
18090       END
 | 
						|
18100     END;
 | 
						|
18110 (**)
 | 
						|
18120 (**)
 | 
						|
18130 FUNCTION SAFEACCESS(LOCATION: OBJECTP): UNDRESSP;
 | 
						|
18140 (* RETURNS A POINTER TO THE REAL PART OF THE STRUCTURE *)
 | 
						|
18150     BEGIN
 | 
						|
18160     WITH LOCATION^.ANCESTOR^ DO
 | 
						|
18170         IF FPTWO(PVALUE^) THEN 
 | 
						|
18180         CASE SORT OF
 | 
						|
18190           REF1: SAFEACCESS := INCPTR(LOCATION,REF1SIZE-SZINT);
 | 
						|
18200 (*-01()   REF2: SAFEACCESS := INCPTR(LOCATION,REF2SIZE-SZLONG); ()-01*)
 | 
						|
18210           CREF: SAFEACCESS := IPTR;
 | 
						|
18220           REFR, RECR, RECN, REFN:
 | 
						|
18230             BEGIN
 | 
						|
18240             IF SORT IN [REFR, RECR] THEN
 | 
						|
18250               TESTCC(LOCATION)
 | 
						|
18260             ELSE
 | 
						|
18270               TESTSS(ANCESTOR);
 | 
						|
18280             PVALUE^.OSCOPE := 0;
 | 
						|
18290             SAFEACCESS := INCPTR(PVALUE, LOCATION^.OFFSET)
 | 
						|
18300             END;
 | 
						|
18310           UNDEF: ERRORR(RASSIG);
 | 
						|
18320           NILL: ERRORR(RASSIGNIL)
 | 
						|
18330           END
 | 
						|
18340       ELSE BEGIN
 | 
						|
18350         PVALUE^.OSCOPE := 0;
 | 
						|
18360         SAFEACCESS := INCPTR(PVALUE,LOCATION^.OFFSET)
 | 
						|
18370         END
 | 
						|
18380     END;
 | 
						|
18390 (**)
 | 
						|
18400 (**)
 | 
						|
18410 (*-02() BEGIN END ; ()-02*)
 | 
						|
18420 (*+01()
 | 
						|
18430 BEGIN (*OF MAIN PROGRAM*)
 | 
						|
18440 END (*OF EVERYTHING*).
 | 
						|
18450 ()+01*)
 |