100 DIM A%(500%,2%),L$(20%),A$(20%),U$(14%): PRINT "EDIT VER. 4.4" !WRITTEN BY W.H. BLAKE - PROJECT MIRACLE - PURDUE UNIVERSITY COLUMN 1 OF A% CONTAINS THE NUMBER OF LINES IN THAT DISK RECORD COLUMN 2 OF A% POINTS TO THE NEXT DISK RECORD 110 READ U$(U%) FOR U%=1% TO 14% : ON ERROR GOTO 480 !READ IN COMMAND NAMES 120 PRINT"INPUT FILE";:INPUT LINE I$:OPEN LEFT(I$,LEN(I$)-2%)FOR INPUT AS FILE1% !L$ USED TO STORE LENGTH OF EACH LINE A$ USED TO STORE LINES OF A RECORD IN CORE OPEN HIS SOURCE FILE 130 Z%=0% : B%,M%=1% : L2%=0% : ON ERROR GOTO 170 !B% IS FIRST ACTIVE RECORD OF EDIT.TMP 140 OPEN "EDIT.TMP" AS FILE 2% , CLUSTERSIZE 16% : PUT #2 RECORD 16% 150 FIELD #2 , J% AS X$ , 1% AS L$(J%+1%) FOR J%=0% TO 19% !SET UP FIELD FOR LENGTH OF LINES 160 INPUT LINE #1 T$ : GOSUB 740 : GOTO 160 !GENERATE EDIT.TMP 170 IF ERR<>11% THEN ON ERROR GOTO 0 ELSE GOSUB 780 : A%(I%,2%)=0% : P%=I% : RESUME 190 !STORE PARTIAL RECORD WHEN END OF FILE IS DETECTED 180 H1%=0% : FOR K%=1% TO P% : H1%=H1%+A%(K%,1%) : NEXT K% : IF H1% THEN RETURN ELSE B%=1% : RETURN !SUBROUTINE TO FIND NUMBER OF LINES IN EDIT.TMP 190 L2%=0% : H%=0% : CLOSE 1 : OPEN "KB:" AS FILE 4 : GOSUB 180 !NOW WE CAN START EDITING WE GET COMMANDS FROM THE USER HERE 200 OPEN "KB:" AS FILE 4% : PRINT #4%"*";:INPUT LINE #4 C$:ON ERROR GOTO 480 !GET A COMMAND FROM THE USER 210 IF INSTR(1%,C$,"/L"+CHR$(13%)) THEN PRINT "LAST LINE = ";H1% : GOTO 200 !GIVE HIM THE LAST LINE IN THE FILE 220 F$="KB:":E%=INSTR(1%,C$,"/") : IF E% THEN 230 ELSE 240 !NO ALTERNATE INPUT OR OUTPUT FILE GIVEN 230 F$=MID(C$,E%+1%,LEN(C$)-E%-2%):C$=LEFT(C$,E%-1%)+" ":CLOSE 4% !GET THE ALTERNATE FILE INTO F$ 240 W%=0% : IF F$="KB:" OR F$="LP:" THEN W%=1% !PRINT LINE NUMBERS ON KB: OR LP: ONLY 250 FOR U%=1% TO 14% : E%=INSTR(1%,C$,U$(U%)) : IF E% THEN 270 !LOOK FOR A VALID COMMAND 260 NEXT U% : GOTO 340 !GO PRINT MESSAGE 270 IF E%>1% THEN 340 ELSE E%=E%+LEN(U$(U%)): GOSUB 350: IF U%>7% THEN U%=U%-7% !GET THE LINE LIMITS FOR THE COMMAND 280 IF U%=1% OR U%=5% OR U%=7% THEN OPEN F$ FOR OUTPUT AS FILE 4% !FOR LIST , SEARCH , AND REPLACE 290 IF U%=2% OR U%=3% THEN OPEN F$ FOR INPUT AS FILE 4% !FOR INSERTIONS AND CHANGE 300 IF F$="LP:" THEN PRINT #4% , I$ ,TIME$(0%),DATE$(0%) !PRINT FILE NAME , TIME AND DATE ON LISTING 310 ON U% GOTO 490,510,320,330,590,620,650 !JUMP TO THE APPROPRIATE ROUTINE 320 GOSUB 580 : IF H1%>F1% THEN 510 ELSE F%=F1%-1% : GOSUB 880:H%=H%+1% :GOTO 510 330 GOSUB 580 : GOTO 500 !DO THE DELETE 340 PRINT "INVALID COMMAND" : GOTO 200 350 F1%=1% : L1%=H1% : E$=MID(C$,E%,LEN(C$)-E%-1%) : D%=INSTR(1%,E$,",") !SET DEFAULT LIMITS , GET ARGS, AND LOOK FOR COMMA 360 IF E$=SPACE$(LEN(E$)) THEN 400 !IF NO ARGS USE DEFAULT 370 ON ERROR GOTO 440 : IF D%=0% THEN F1%,L1%=VAL(E$): GOTO 390 !IF NO COMMA, SET BOTH LIMITS EQUAL TO ARG 380 F1%=VAL(LEFT(E$,D%-1%)) : L1%=VAL(RIGHT(E$,D%+1%)) !FIRST LINE=LEFT, LAST LINE=RIGHT 390 ON ERROR GOTO 480 : IF L1%>=F1% AND F1%>=1% AND L1%<=H1% THEN 400 ELSE GOTO 340 !CHECK LIMITS TO KEEP HIM HONEST 400 IF F1%=1% AND L1%=H1% THEN 410 ELSE RETURN !ASK HIM IF HE WANTS HIS ENTIRE FILE DELETED 410 IF U%=3% OR U%=4% OR U%=10% OR U%=11% THEN PRINT"TYPE 'YES' TO DELETE THE ENTIRE FILE" ELSE RETURN !IF HE TYPES CHANGE , DELETE,D, OR C 420 PRINT"ANYTHING ELSE WILL ABORT THIS COMMAND";: INPUT C$ !GET HIS RESPONSE 430 IF INSTR(1%,C$,"YES") THEN 120ELSE PRINT"WHEW !! THAT WAS CLOSE!":GOTO 200 !START A NEW FILE IF HE WANTS 440 IF ERR<>52% THEN GOTO 480 ELSE RESUME 340 !COME HERE IF ARGS WERE GARBAGE 450 DEF FNL$(F%)= MID(" "+NUM$(F%),LEN(NUM$(F%)),4%)+")" !FUNCTION TO GENERATE LINE NUMBERS 460 IF W% THEN PRINT #4% , FNL$(F%); !SUBROUTINE TO PRINT A LINE OF TEXT WITH OR WITHOUT LINE NUMBERS 470 PRINT #4% , A$(C%); : RETURN !DEPENDING ON W% 480 PRINT "ERROR";ERR;"ON OPERATION" : IF H1% THEN RESUME 200 ELSE RESUME 120 !ERROR COME HERE *LIST* 490 FOR F%=F1% TO L1% : GOSUB 880 : GOSUB 460 : NEXT F% !GET THE LINES AND PRINT THEM 500 PRINT #4%,CHR$(26%); :CLOSE 4 : IF T% THEN RETURN ELSE 200 !CLOSE THE OUTPUT FILE : GO GET ANOTHER COMMAND *INSERT* 510 F%=F1% : GOSUB 880 : L2%=0% : M%=2% : ON ERROR GO TO 560 !GET LINE NUMBER FOR INSERTION 520 FOR K%=1% TO C%-1% : T$=A$(K%) : GOSUB 740 : NEXT K% !STORE WHAT IS IN CORE UP TO THE LINE TO BE INSERTED 530 IF INSTR(1%,F$,"KB:")=0% THEN 550 ELSE PRINT"TYPE CTRL-Z TO STOP INSERTIONS" 540 PRINT #4% , FNL$(F%);:INPUT LINE #4% T$:GOSUB 740:F%=F%+1%:GOTO 540 !PROMPT THE USER FOR INSERTIONS FROM KB: 550 INPUT LINE #4% T$ : GOSUB 740 : F%=F%+1% : GOTO 550 !GET THE INSERTIONS FROM FILE C$ 560 IF ERR= 11% THEN 570 ELSE ON ERROR GOTO 0 !HANDLE THE END OF FILE ERROR ONLY 570 FOR K%=C% TO N% : T$=A$(K%) : GOSUB 740 : NEXT K% : GOSUB 830 : GOSUB 180 : CLOSE 4 : RESUME 200 !CLEAN UP THE FILE *DELETE *(SUBROUTINE) 580 FOR F%=L1% TO F1% STEP -1% : GOSUB 880 : M%=3% : A$(C%)="" : NEXT F% : M%=4% : GOSUB 960 : GOSUB 180 : RETURN !DELETE A BLOCK OF LINES *SEARCH* 590 PRINT "STRING";:INPUT LINE Z$ : Z$=LEFT(Z$,LEN(Z$)-2%) !GET THE SEARCH STRING 600 FOR F%=F1% TO L1% : GOSUB 880 : IF INSTR(1%,A$(C%),Z$) THEN GOSUB 460 !PRINT THE LINE IF THE STRING IS THERE 610 NEXT F% : GOTO 500 !RETURN WHEN DONE *END* 620 PRINT "OUTPUT FILE" ; :INPUT LINE O$ : IF LEN(O$)=2%THEN O$=I$ !GET THE OUTPUT FILE 630 CLOSE 4% : OPEN LEFT(O$,LEN(O$)-2%) FOR OUTPUT AS FILE 4% !OPEN THE OUTPUT FILE 640 W%=0% : T%=1% : GOSUB490 : T%,H1%=0% : CLOSE 2:KILL"EDIT.TMP" : GOTO120 !GO SEE IF THERE IS MORE TO DO *REPLACE* 650 F%=F1% : GOSUB 880 : PRINT "OLD$";: INPUT LINE O$ : IF LEN(O$)<=2% THEN 340 !GET THE STRING TO BE REPLACED 660 PRINT "NEW$";: INPUT LINE N$ : IF O$=N$ OR LEN(N$)=1% THEN 340 !AVOID ENDLESS LOOP 670 O%=LEN(O$)-2% :N1%=LEN(N$)-2% : O$=LEFT(O$,O%) :N$=LEFT(N$,N1%) !CHOP CRLF 680 IF INSTR(1%,N$+O$,CHR$(10%)) THEN 340 !DID HE ACCIDENTLY TYPE LF ? 690 FOR F%=F1% TO L1% : GOSUB 880 : O1%=0% : GOSUB 710 : IF O1% THEN GOSUB 460 !MAKE THE REPLACEMENTS 700 NEXT F% : GOTO 500 !AND RETURN 710 R%=INSTR(O1%,A$(C%),O$) : IF R%=0% THEN RETURN ELSE M%=3% !OLD$ NOT FOUND 720 IF LEN(A$(C%))+N1%-O% > 256% THEN PRINT "STRING TOO LONG AT TEXT LINE";F%: RETURN !DO NOT MAKE THE LINES TOO LONG 730 A$(C%)=LEFT(A$(C%),R%-1%)+N$+RIGHT(A$(C%),R%+O%):O1%=R%+N1%:GOTO 710 !REPLACE OLD$ WITH NEW$ UNTIL OLD$ IS NOT FOUND THE ROUTINE STARTING AT LINE 740 CREATES EDIT.TMP AND HANDLES INSERTIONS AND DELETIONS 740 I%=Z% : IF L2%=0% THEN X%=20% !SUBROUTINE FOR GENERATING AND UPDATING EDIT.TMP 750 S%=LEN(T$) : IF S%+X% > 512% OR L2% = 20% THEN 780 !PUT MAXIMUM OF 20 LINES INTO EACH RECORD OR 492 CHARACTERS INTO EACH RECORD 760 IF S% THEN L2%=L2%+1% : LSET L$(L2%)=CHR$(S%) !STORE LENGTH OF CURRENT LINE 770 FIELD #2 , X% AS X$ , S% AS S$ : LSET S$=T$ : X%=X%+S% : RETURN !PUT THE LINE INTO THE RECORD : INCREMENT SKIP COUNT 780 GOSUB 790 : GOSUB 830 : L2%=0% : GOTO 740 !PUT THIS RECORD ON DISK 790 Z%=0% : IF M%=1% THEN I%=I%+1% : Z%=I% : A%(I%,2%)=I%+1% :RETURN !M%=1% WHEN EDIT.TMP IS CREATED 800 FOR Z%=1% TO P% : IF A%(Z%,1%)=0% THEN 820 !LOOK FOR AN EMPTY RECORD 810 NEXT Z%: P%=P%+1% : Z%=P% !P% IS MAXIMUM RECORD USED 820 A%(Z%,2%)=A%(I%,2%): A%(I%,2%)=Z% : A%(Z%,1%)=-1% : RETURN !LINK THE RECORD 830 A%(I%,1%)=L2% : PUT #2%,RECORD I% : H%=0% !STORE A RECORD 840 IF L2% THEN RETURN ELSE Y%=0% !ARE THERE NO LINES TO STORE . EG. ALL WERE DELETED 850 IF I%=B% THEN B%=A%(I%,2%) : GOTO 870 !RESET STARTING BLOCK IF IT IS DELETED 860 Y%=Y%+1% : IF A%(Y%,2%)<> I% THEN 860 ELSE A%(Y%,2%)=A%(I%,2%) !DELINK THE RECORD 870 A%(I%,2%)=0% : RETURN !AND RETURN THE ROUTINE STARTING AT LINE 880 DETERMINES IF THE LINE DESIRED IS IN CORE . IF IT IS NOT , THE ROUTINE LOOKS IN ARRAY A% TO FIND THE DISK RECORD . 880 IF H1% THEN 890 ELSE CLOSE 2%,4% :PRINT"THERE IS NO TEXT":GOTO 120 !MAKE CERTAIN WE HAVE SOME TEXT 890 IF F%>=L% AND F%<=H% THEN C%=F%-L%+1% : RETURN !CONVERT TEXT LINE NUMBER TO A CORE LOCATION]% 900 IF M%=3% THEN 960 ELSE I%=B% : L%=1% : H%=A%(I%,1%) !IF THE LINE IS NOT IN CORE THEN START LOOKING AT THE FIRST ACTIVE RECORD 910 IF F%>= L% AND F% <= H% THEN 930 !FOUND THE RECORD 920 L%=H%+1% : I%=A%(I%,2%) : H%=H%+A%(I%,1%) : GOTO 910 !L%= LOW LINE IN THE RECORD , H% = HIGH LINE IN THE RECORD 930 N%=A%(I%,1%) : X%=20% : GET #2 , RECORD I% : Z%=I% !N%=NUMBER OF LINES IN THE BLOCK : GET THE RECORD 940 FOR J%=1% TO N% : S%=ASCII(L$(J%)) :FIELD #2% , X% AS X$ , S% AS S$ !BREAK THE RECORD APART 950 A$(J%)=S$+"" : X%=X%+S% : NEXT J% : GOTO 880 !AND STORE THE LINES IN CORE 960 Z%=I% : L2%=0% : FOR K%=1% TO N% : T$=A$(K%) : GOSUB 740 !PUT THE CURRENT RECORD BACK ON DISK IF ANYTHING HAS BEEN CHANGED 970 NEXT K% : GO