|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 13952 (0x3680) Types: TextFile Names: »RECREATE.PLI«
└─⟦57f0389e8⟧ Bits:30005761 SW1611 Access Manager v. 1.0 └─ ⟦this⟧ »RECREATE.PLI«
RECREATE: PROC OPTIONS (MAIN); /* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::: RECREATE PROGRAM VERSION 1.02 03/03/83 REQUIRES AM86BUF = 4844 (decimal) BYTES ::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */ %REPLACE MAX_REC_LEN BY 1024, MAX_KEY_LEN BY 48, NAME_LEN BY 14, MAX_NO_KEYS BY 9, MAX_NO_KEY_PARTS BY 5; %REPLACE YES BY 1, NO BY 0, BUFFER_SIZE BY 4844, MAX_SORT BY 1500, MAX_SPACE BY 10000, END_DATA_FILE BY 53, INVALID_RECORD BY 52, CORRUPT_DATA BY 70, END_INDEX_FILE BY 23, CORRUPT_INDEX BY 40; %INCLUDE 'AM86EXTR.PLI'; DCL (DRNL,DRNH,DEL_PTRL,DEL_PTRH,NO_DELL,NO_DELH,UTLL,UTLH) FIXED, (XFILE,NLOCK,FILE_NO,NO_SORT,DUMMY,NO_READ) FIXED, 1 SORT_DRN(MAX_SORT), 2 LSW FIXED, 2 MSW FIXED, LINK(MAX_SORT) FIXED, KEYVAL(MAX_SPACE) CHAR(1), SPACES CHAR(MAX_KEY_LEN) STATIC INIT( ' '), INDEX_NAME(MAX_NO_KEYS) CHAR(NAME_LEN) VAR, (KEY_LEN,KEY_POS) (9,0:MAX_NO_KEY_PARTS) FIXED, (AUTO_SUFFIX,NO_KEY_PARTS,KEY_TYPE) (MAX_NO_KEYS) FIXED, BLANK_KEY_TO_NULL(MAX_NO_KEYS) CHAR(1); DCL REC_PAR CHAR(NAME_LEN) VAR, REC_FILE FILE, (NO_DATA_FILES,NODE_SECTORS) FIXED, (TERMINAL,ERROPT,TIMOUT) FIXED, (NO_BUFFERS,NO_FILES,NO_KEYS,BUFFER_SPACE) FIXED; DCL FILE_NAME CHAR(NAME_LEN) VAR, (REC_LEN,BEG_REC,KEY,PART) FIXED, INPBUF(MAX_REC_LEN) CHAR(1), INPBUF_PTR POINTER, 1 LNKBUF BASED (LNKBUF_PTR), 2 DEL_FLD CHAR(1), 2 LSW FIXED, 2 MSW FIXED, LNKBUF_PTR POINTER, 1 HDRBUF BASED (HDRBUF_PTR), 2 VAL(6) FIXED, 2 FLG CHAR(1), HDRBUF_PTR POINTER, DEL_FLG CHAR(1), DEL_NUM FIXED(7) BASED (DEL_NUM_PTR), DEL_NUM_PTR POINTER, RET_CHR CHAR(1) STATIC INIT('^M'), DFILE FIXED; PUT SKIP LIST ('Enter recreate parameter file name:'); GET LIST (REC_PAR); OPEN FILE (REC_FILE) TITLE(REC_PAR); GET FILE (REC_FILE) LIST (NO_DATA_FILES,NODE_SECTORS); DEL_NUM_PTR = ADDR(DEL_FLG); DEL_NUM = -1; XFILE = 4; NLOCK = 0; TERMINAL = -1; ERROPT = YES; TIMOUT = 2; TERMINAL = INTUSR(TERMINAL,ERROPT,TIMOUT); BUFFER_SPACE = BUFFER_SIZE - 2 * 36; /* assumes only one key file and one data file open at the same time. */ NO_BUFFERS = DIVIDE(BUFFER_SPACE,NODE_SECTORS * 128 + 52,15); IF NO_BUFFERS > 18 THEN NO_BUFFERS = 18; NO_KEYS = 1; NO_FILES = 1; IF SETUP(NO_BUFFERS,NO_KEYS,NODE_SECTORS,NO_FILES) ü= 0 THEN DO; PUT SKIP LIST ('Illegal SETUP parameters.'); CALL ABANDON(); END; DO DFILE = 1 TO NO_DATA_FILES; CALL REBUILD(); PUT SKIP; END; PUT SKIP LIST ('Normal Termination.'); STOP; ABANDON: PROC; PUT SKIP LIST ('Rebuild Aborted!'); CLOSE FILE (REC_FILE); STOP; END ABANDON; INC_4_BYTE: PROC (LSW,MSW); DCL (LSW,MSW) FIXED; LSW = LSW + 1; IF LSW = 0 THEN MSW = MSW + 1; RETURN; END INC_4_BYTE; REBUILD: PROC; DCL REDO_DATA FIXED; GET FILE (REC_FILE) LIST (FILE_NAME,REC_LEN,NO_KEYS,BEG_REC); IF NO_KEYS > MAX_NO_KEYS THEN DO; PUT SKIP EDIT ('Error in ',REC_PAR,' for data file ', FILE_NAME,'More than ',MAX_NO_KEYS, ' key files requested.') (4A,SKIP,A,F(2),A); CALL ABANDON(); END; IF REC_LEN > MAX_REC_LEN THEN DO; PUT SKIP EDIT ('Error in ',REC_PAR,' for data file ', FILE_NAME,'Record length > ',MAX_REC_LEN) (4A,SKIP,A,F(7)); CALL ABANDON(); END; IF NO_KEYS > 0 THEN DO KEY = 1 TO NO_KEYS; GET FILE (REC_FILE) LIST (INDEX_NAME(KEY), KEY_LEN(KEY,0),KEY_TYPE(KEY),AUTO_SUFFIX(KEY), NO_KEY_PARTS(KEY),BLANK_KEY_TO_NULL(KEY)); IF BLANK_KEY_TO_NULL(KEY) = 'y' THEN BLANK_KEY_TO_NULL(KEY) = 'Y'; IF NO_KEY_PARTS(KEY) < 1 ø NO_KEY_PARTS(KEY) > MAX_NO_KEY_PARTS THEN CALL KEY_ERROR; GET FILE (REC_FILE) LIST ((KEY_POS(KEY,PART),KEY_LEN( KEY,PART) DO PART = 1 TO NO_KEY_PARTS(KEY))); END; REDO_DATA = REBUILD_DATA(); IF REDO_DATA = 2 THEN PUT SKIP EDIT ('Data file ',FILE_NAME,' could not be locked.') (3A); IF REDO_DATA = 3 THEN PUT SKIP EDIT ('Data file ',FILE_NAME,' is apparently empty.') (3A); IF REDO_DATA < 0 THEN PUT SKIP EDIT ('Unanticipated AM86 Error #',-REDO_DATA, ' while processing ',FILE_NAME) (A,F(4),2A); IF REDO_DATA < 0 ø REDO_DATA > 1 THEN DO; PUT SKIP LIST ('No rebuild performed.'); RETURN; END; CALL REBUILD_INDICES(REDO_DATA); PUT SKIP EDIT ('Rebuild for ',FILE_NAME,' completed.') (3A); RETURN; KEY_ERROR: PROC; PUT SKIP EDIT ('Error in ',REC_PAR,' for data file ',FILE_NAME, ' with key file ',INDEX_NAME(KEY), 'Number of key parts must satisfy -','1 <= # Parts <= ', MAX_NO_KEY_PARTS) (6A,SKIP,A,SKIP(2),A,F(3)); CALL ABANDON(); END KEY_ERROR; END REBUILD; REBUILD_DATA: PROC RETURNS (FIXED); DCL (TEMP,STATUS) FIXED; STATUS = 0; FILE_NO = -1; FILE_NO = OPNDAT(FILE_NO,XFILE,FILE_NAME,REC_LEN); IF ERRCOD() = END_DATA_FILE THEN DO; DUMMY = CLSDAT(FILE_NO); RETURN(3); END; IF ERRCOD() = CORRUPT_DATA THEN DO; STATUS = 1; FILE_NO = OPRDAT(FILE_NO,XFILE,FILE_NAME,REC_LEN); END; IF STATUS = 0 & ERRCOD() ü= 0 THEN DO; TEMP = ERRCOD(); DUMMY = CLSDAT(FILE_NO); RETURN (-TEMP); END; IF LOKCOD() ü= 0 THEN DO; DUMMY = CLSDAT(FILE_NO); RETURN(2); END; IF BEG_REC = 0 THEN BEG_REC = DIVIDE(128 + REC_LEN -1,REC_LEN,15) + 1; INPBUF_PTR = ADDR(INPBUF(1)); LNKBUF_PTR = INPBUF_PTR; HDRBUF_PTR = INPBUF_PTR; IF STATUS = 0 THEN DO; DUMMY = CLSDAT(FILE_NO); PUT SKIP EDIT ('No need to modify ',FILE_NAME) (2A); RETURN(0); END; /* DATA FILE IS CORRUPTED. MUST BE REBUILT. */ PUT SKIP EDIT ('Rebuilding data file ',FILE_NAME) (2A); DRNL = BEG_REC; DRNH = 0; DEL_PTRL = 0; DEL_PTRH = 0; NO_DELL = BEG_REC - 1; /* allowance for header record(s) */ NO_DELH = 0; READ_LOOP: CALL SETDAT(DRNH); IF READAT(FILE_NO,DRNL,INPBUF_PTR) = END_DATA_FILE THEN GOTO END_OF_FILE; IF ERRCOD() ü= 0 THEN DO; TEMP = ERRCOD(); DUMMY = CLSDAT(FILE_NO); RETURN(-TEMP); END; PUT SKIP EDIT (FILE_NAME,DRNL,DRNH) (A,2F(5)); IF INPBUF(1) = DEL_FLG THEN DO; CALL WRITE_DELETE_LINK(); CALL INC_4_BYTE(NO_DELL,NO_DELH); END; CALL INC_4_BYTE(DRNL,DRNH); GOTO READ_LOOP; END_OF_FILE: PUT SKIP EDIT (FILE_NAME,' is reorganized. Now rebuild index files.') (2A); IF CLSDAT(FILE_NO) ü= 0 THEN DO; PUT SKIP EDIT ( 'Could not close data file (to recreate header)', FILE_NAME) (2A); CALL ABANDON(); END; CALL RECREATE_HEADER(); RETURN(1); TEST: PROC (LSW,MSW) RETURNS (FLOAT); DCL (LSW,MSW) FIXED, (TL,TH) FLOAT; TL = LSW; IF TL < 0 THEN TL = TL + 65536.; RETURN(TL + TH * 65536.); END TEST; WRITE_DELETE_LINK: PROC; LNKBUF.DEL_FLD = DEL_FLG; LNKBUF.LSW = DEL_PTRL; LNKBUF.MSW = DEL_PTRH; CALL SETDAT(DRNH); IF WRTDAT(FILE_NO,DRNL,LNKBUF_PTR) ü= 0 THEN DO; PUT SKIP EDIT ('Could not rewrite deleted record.', 'Data file ',FILE_NAME,' (',DRNL,DRNH,')') (A,SKIP,3A,2F(6),A); CALL ABANDON(); END; DEL_PTRL = DRNL; DEL_PTRH = DRNH; RETURN; END WRITE_DELETE_LINK; RECREATE_HEADER: PROC; DCL TEMP FIXED, HDR_FILE FILE; OPEN FILE (HDR_FILE) TITLE(FILE_NAME) DIRECT UPDATE ENV(F(128)); DRNL = DRNL - 1; IF DRNL = 0 THEN DRNH = DRNH - 1; /* DRN = file size */ HDRBUF.VAL(5) = DRNL; HDRBUF.VAL(6) = DRNH; DRNL = DRNL - NO_DELL; DRNH = DRNH - NO_DELH; /* DRN = file utl */ IF TEST(DRNL,DRNH) > TEST(HDRBUF.VAL(5),HDRBUF.VAL(6)) THEN DRNH = DRNH - 1; HDRBUF.VAL(3) = DRNL; HDRBUF.VAL(4) = DRNH; HDRBUF.VAL(1) = DEL_PTRL; HDRBUF.VAL(2) = DEL_PTRH; HDRBUF.FLG = ASCII(0); DO TEMP = 14 TO 128; INPBUF(TEMP) = ' '; END; WRITE FILE (HDR_FILE) FROM (HDRBUF) KEYFROM(0); CLOSE FILE (HDR_FILE); RETURN; END RECREATE_HEADER; END REBUILD_DATA; REBUILD_INDICES: PROC (REDO_DATA); DCL (KEY_NO,KEY,TEMP,REDO_DATA) FIXED; IF NO_KEYS < 1 THEN RETURN; FILE_NO = -1; FILE_NO = OPNDAT(FILE_NO,XFILE,FILE_NAME,REC_LEN); IF ERRCOD() ü= 0 ø LOKCOD() ü= 0 THEN DO; PUT SKIP EDIT ('Could not attempt index rebuild.', 'Error/Lock Codes...',ERRCOD(),LOKCOD()) (A,SKIP,A,2F(5)); DUMMY = CLSDAT(FILE_NO); RETURN; END; DO KEY = 1 TO NO_KEYS; KEY_NO = -1; KEY_NO = OPNIDX(KEY_NO,INDEX_NAME(KEY),KEY_LEN(KEY,0), KEY_TYPE(KEY),AUTO_SUFFIX(KEY)); IF ERRCOD() = 0 & REDO_DATA = 0 THEN DO; TEMP = NOKEYS(KEY_NO); IF TEMP ü= 0 ø DATVAL() ü= 0 THEN DO; PUT SKIP EDIT (INDEX_NAME(KEY),' is OK as is.', ' No rebuild performed.') (3A); GOTO SKIP_INDEX; END; END; IF ERRCOD() ü= 0 & ERRCOD() ü= CORRUPT_INDEX & ERRCOD() ü= END_INDEX_FILE THEN DO; PUT SKIP LIST ('Unanticipated Error with '); CALL KEY_ERROR(); GOTO SKIP_INDEX; END; IF ERRCOD() = CORRUPT_INDEX THEN KEY_NO = OPRIDX(KEY_NO,INDEX_NAME(KEY),KEY_LEN(KEY,0), KEY_TYPE(KEY),AUTO_SUFFIX(KEY)); IF ERAIDX(KEY_NO) ü= 0 THEN DO; PUT SKIP LIST ('Could not erase old '); CALL KEY_ERROR(); GOTO SKIP_INDEX; END; KEY_NO = -1; KEY_NO = OPNIDX(KEY_NO,INDEX_NAME(KEY),KEY_LEN(KEY,0), KEY_TYPE(KEY),AUTO_SUFFIX(KEY)); IF ERRCOD() ü= 0 THEN DO; PUT SKIP LIST ('Could not re-open '); CALL KEY_ERROR(); GOTO SKIP_INDEX; END; CALL SORT_SETUP(KEY); CALL SORT_READ(KEY,KEY_NO); SKIP_INDEX: DUMMY = CLSIDX(KEY_NO); END; DUMMY = CLSDAT(FILE_NO); RETURN; KEY_ERROR: PROC; PUT SKIP EDIT (INDEX_NAME(KEY),' Error: #',ERRCOD(),'Index not rebuilt.') (2A,F(4),SKIP,A); RETURN; END KEY_ERROR; SPACE: PROC (FLDLEN) RETURNS (CHAR(MAX_KEY_LEN) VAR); DCL FLDLEN FIXED; RETURN(SUBSTR(SPACES,1,FLDLEN)); END SPACE; SORT_SETUP: PROC (KEY); DCL KEY FIXED; NO_SORT = DIVIDE(MAX_SPACE - MAX_KEY_LEN,KEY_LEN(KEY,0) + 1,15); IF NO_SORT > MAX_SORT THEN NO_SORT = MAX_SORT; RETURN; END SORT_SETUP; PUT_KEYVAL: PROC (I,KEY); DCL KEY_VALUE CHAR(MAX_KEY_LEN) VAR, (I,KEY) FIXED; DCL TMP_I FIXED, TMPBUF CHAR(MAX_KEY_LEN) BASED (TMP_VALUE_PTR), TMP_VALUE CHAR(MAX_KEY_LEN) VAR BASED(TMP_VALUE_PTR), TMP_VALUE_PTR POINTER; KEY_VALUE = ''; DO TMP_I = 1 TO NO_KEY_PARTS(KEY); TMP_VALUE_PTR = ADDR(INPBUF(KEY_POS(KEY,TMP_I))); KEY_VALUE = KEY_VALUE øø SUBSTR(TMPBUF,1, KEY_LEN(KEY,TMP_I)); END; IF BLANK_KEY_TO_NULL(KEY) = 'Y' & KEY_VALUE = SPACE(LENGTH( KEY_VALUE)) THEN KEY_VALUE = ''; TMP_I = (I - 1) * (KEY_LEN(KEY,0) + 1) + 1; TMP_VALUE_PTR = ADDR(KEYVAL(TMP_I)); TMP_VALUE = KEY_VALUE; RETURN; END PUT_KEYVAL; GET_KEYVAL: PROC (I,KEY) RETURNS (CHAR(MAX_KEY_LEN) VAR); DCL (I,KEY) FIXED, TMP_I FIXED, TMP_VALUE CHAR(MAX_KEY_LEN) VAR BASED(TMP_VALUE_PTR), TMP_VALUE_PTR POINTER; TMP_I = (I - 1) * (KEY_LEN(KEY,0) + 1) + 1; TMP_VALUE_PTR = ADDR(KEYVAL(TMP_I)); RETURN(TMP_VALUE); END GET_KEYVAL; ENTRY_ERROR: PROC (KEY_NO,LSW,MSW); DCL (KEY_NO,LSW,MSW) FIXED; PUT SKIP EDIT (' Error: #',ERRCOD(),' (rec#',LSW,MSW,')') (A,F(4),A,2F(6),A); PUT SKIP LIST ('during index rebuild.'); DUMMY = CLSDAT(FILE_NO); DUMMY = ERAIDX(KEY_NO); CALL ABANDON(); END ENTRY_ERROR; SORT_READ: PROC (KEY,KEY_NO); DCL (KEY,KEY_NO,END_FILE,TEMP) FIXED; DRNL = BEG_REC; DRNH = 0; END_FILE = NO; PUT LIST (SPACE(20),RET_CHR); SORT_LOOP: IF END_FILE = YES THEN DO; PUT SKIP EDIT (INDEX_NAME(KEY),' is rebuilt.') (2A); RETURN; END; NO_READ = 0; DATA_LOOP: CALL SETDAT(DRNH); TEMP = READAT(FILE_NO,DRNL,INPBUF_PTR); IF TEMP = END_DATA_FILE ø TEMP = INVALID_RECORD THEN DO; END_FILE = YES; GOTO BUILD_INDEX; END; IF TEMP ü= 0 THEN DO; PUT SKIP EDIT ('Could not read ',FILE_NAME) (2A); CALL ENTRY_ERROR(KEY_NO,DRNL,DRNH); END; IF INPBUF(1) = DEL_FLG THEN GOTO SKIP_RECORD; PUT SKIP EDIT (FILE_NAME,DRNL,DRNH) (A,2F(6)); NO_READ = NO_READ + 1; CALL PUT_KEYVAL(NO_READ,KEY); SORT_DRN(NO_READ).LSW = DRNL; SORT_DRN(NO_READ).MSW = DRNH; SKIP_RECORD: CALL INC_4_BYTE(DRNL,DRNH); IF NO_READ < NO_SORT THEN GOTO DATA_LOOP; BUILD_INDEX: PUT LIST (SPACE(20),RET_CHR); CALL SORT_INDEX(KEY,KEY_NO,NO_READ); GOTO SORT_LOOP; SORT_INDEX: PROC (KEY,KEY_NO,NO_READ); DCL KEY_VALUE CHAR(MAX_KEY_LEN) VAR, (KEY,KEY_NO,NO_READ,I,RET_CODE) FIXED; IF NO_READ = 0 THEN RETURN; CALL SORT_KEYVAL(KEY,NO_READ); I = LINK(0); INDEX_LOOP: IF I = 0 THEN RETURN; KEY_VALUE = GET_KEYVAL(I,KEY); CALL SETDAT(SORT_DRN(I).MSW); RET_CODE = ADDKEY(KEY_NO,FILE_NO,NLOCK,KEY_VALUE,SORT_DRN(I).LSW); IF ERRCOD() ü= 0 THEN DO; PUT SKIP EDIT ('Could not enter key value in ', INDEX_NAME(KEY)) (2A); CALL ENTRY_ERROR(KEY_NO,SORT_DRN(I).LSW,SORT_DRN(I).MSW); END; IF RET_CODE ü= 1 THEN DO; PUT SKIP EDIT ('WARNING...ADDKEY Return Code: ',RET_CODE) (A,F(4)); PUT SKIP EDIT ('while processing record #',SORT_DRN(I).LSW, SORT_DRN(I).MSW,' for ',INDEX_NAME(KEY)) (A,2F(6),2A); END; PUT SKIP EDIT (INDEX_NAME(KEY),SORT_DRN(I).LSW,SORT_DRN(I).MSW) (A,2F(6)); I = LINK(I); GOTO INDEX_LOOP; SORT_KEYVAL: PROC (KEY,NO_READ); DCL KEY_VALUE CHAR(MAX_KEY_LEN) VAR, (KEY,NO_READ,J,P,Q) FIXED; LINK(0) = NO_READ; LINK(NO_READ) = 0; IF NO_READ < 2 THEN RETURN; DO J = NO_READ TO 1 BY -1; P = LINK(0); Q = 0; KEY_VALUE = GET_KEYVAL(J,KEY); L3: IF KEY_VALUE < GET_KEYVAL(P,KEY) THEN GOTO L5; L4: Q = P; P = LINK(Q); IF P > 0 THEN GOTO L3; L5: LINK(Q) = J; LINK(J) = P; END; RETURN; END SORT_KEYVAL; END SORT_INDEX; END SORT_READ; END REBUILD_INDICES; END; «eof»