100 ON ERROR GOTO ERR'CODE
120 STRSIZ 100
140 !
160 ! PROGRAM NAME: LETTER.BAS
180 !
200 ! FUNCTION: THIS PROGRAM COPIES A LETTER FILE TO THE PRINTER OR TO A
220 ! SPOOL FILE, WHILE DOING SUBSTITUTIONS FOR VARIABLES EMBEDDED
240 ! IN THE TEXT. THE DATA FOR THESE SUBSTITUTIONS MAY COME EITHER
260 ! FROM THE TERMINAL OR FROM A FILE. A VARIABLE IS DENOTED BY
280 ! LEADING AND TRAILING BACKSLASHES. IN ORDER TO INSERT A
300 ! BACKSLASH AS TEXT, TWO BACKSLASHES MUST BE TYPED. THE
320 ! INPUT FILE MAY CONTAIN PAGE BREAKS, IN WHICH CASE THE FF
340 ! MUST BE THE FIRST CHARACTER IN THE LINE, OR THEY MAY BE
360 ! GENERATED BY THIS PROGRAM.
380 !
400 ! AUTHOR: TOM DAHLQUIST
420 !
440 ! DATE REVISION
460 ! 11/21/79 CHANGED EXIT PROCEDURE TO CHAIN TO "DSK0:LTREXT.CMD[2,2]"
480 ! ADDED ABILITY TO SPECIFY LINES/PAGE FOR NONSTANDARD FORMS
500 ! ADDED DEFAULT AND ABILITY TO SPECIFY OUTPUT TO OTHER PRINTERS
520 !
540 MAP1 COPYRIGHT,S,47,"COPYRIGHT 1979, DATA PROCESSING CONSULTING, INC"
560 ! THIS PROGRAM IS THE SOLE PROPERTY OF DATA PROCESSING CONSULTING, INC.
580 ! EXCEPT FOR THE PURPOSE OF USE AT THE INSTALLATION TO WHICH IT WAS
600 ! SOLD, IT MAY NOT BE REPRODUCED IN ANY WAY WITHOUT THE EXPRESS WRITTEN
620 ! PERMISSION OF DPCI.
640 !
660 ! WORKING STORAGE
680 !
700 MAP1 ISTG,S,132
720 MAP1 OSTG,S,132
740 MAP1 OSTG'S(132),S,1,@OSTG
760 MAP1 LFILE(15),S,24
780 MAP1 VAR'NAME,S,50
800 MAP1 DFLT,S,24,"TRM1:ANDY"
820 MAP1 DLUSE,S,15,"$$##,###,###.##"
840 MAP1 DAT,B,4
860 MAP1 DTE,@DAT
880 MAP2 M,B,1
900 MAP2 D,B,1
920 MAP2 Y,B,1
940 MAP2 DFILL,B,1
960 MAP1 BLKTAB,S,2
980 MAP1 NOSPECS,F,,2
1000 MAP1 SPECS(2),S,12
1020 MAP1 MOTAB(12),S,9
1040 !
1060 BLKTAB=" "+CHR(9)
1080 FOR I=1 TO 12:READ MOTAB(I):NEXT
1100 DATA January,February,March,April,May,June
1120 DATA July,August,September,October,November,December
1140 FOR I=1 TO 2:READ SPECS(I):NEXT
1160 DATA DATEA,DATEB
1180 !
1200 ! INITIALIZATION
1220 !
1240 GET'FILE: INPUT LINE "First Text File Name: ";A$
1260 A$=UCS(A$)
1280 C$=".TXT" : GOSUB DEFAULT : LFILE(1)=A$
1300 FILENUM=1
1320 OPEN #1,LFILE(1),INPUT
1340 CLOSE #1
1360 INFILES=2
1380 FILENUM=2
1400 GET'PARAS: INPUT LINE "Next Text File (Or RETURN): ";A$
1420 A$=UCS(A$)
1440 IF A$="" THEN INFILES=INFILES-1 : GOTO GET'OUT
1460 GOSUB DEFAULT : LFILE(INFILES)=A$
1480 OPEN #1,LFILE(INFILES),INPUT
1500 CLOSE #1
1520 INFILES=INFILES+1
1540 GOTO GET'PARAS
1560 GET'OUT: ?"Enter Output File Name Or Hit RETURN"
1580 ?"For Output To Word Processing Printer: ";
1600 INPUT LINE A$
1620 A$=UCS(A$)
1640 FILENUM=3
1660 IF A$="" THEN A$=DFLT
1680 IF A$[1,3]="TRM" THEN OUTTRM=-1 : GOTO OPEN'OUT
1700 C$=".LST" : GOSUB DEFAULT : FORMS=1 : FFLAG=-1
1720 ! FOR OUTPUT TO A FILE, FORCE CONTINUOUS AND SKIP ALIGNMENT OF FIRST PAGE
1740 OPEN'OUT: OFILE$=A$
1760 OPEN #2,OFILE$,OUTPUT
1780 GET'LINES: INPUT "Lines Per Page (Or RETURN): ";LINES
1800 IF LINES=0 THEN ?"*** No Page Break Generation ***"
1820 GET'PHYS: ?"Hit RETURN For Standard Length Forms Or"
1840 ?"Enter Lines Per Page For Nonstandard Forms: ";
1860 INPUT LINE PHYS'LINES
1880 IF PHYS'LINES=0 OR PHYS'LINES>=LINES GOTO GET'FORMS
1900 ?"Sorry, Forms Length Must Be GREATER Than Lines Per Page"
1920 GOTO GET'LINES
1940 GET'FORMS: IF FORMS#0 GOTO GET'DFILE
1960 INPUT "Continuous Or Single Forms--C/S: ";A$
1980 FORMS=INSTR(1,"CS",UCS(A$)) : IF FORMS=0 GOTO GET'FORMS
2000 GET'DFILE: ?"Enter T For Data Input From Terminal"
2020 ?" F For Data Input From A File"
2040 ?" N For No Data Input (Backslashes Ignored)"
2060 INPUT A$
2080 I=INSTR(1,"TFN",UCS(A$))
2100 ON I GOTO TERMIN,GET'DNAME,NODATA
2120 GOTO GET'DFILE
2140 TERMIN:
2160 DF=1
2180 GOTO BEGIN
2200 GET'DNAME: INPUT LINE "Data File Name: ",A$
2220 A$=UCS(A$)
2240 IF A$="" THEN GOTO GET'DNAME
2260 DF=2
2280 C$=".DAT" : GOSUB DEFAULT : DFILE$=A$
2300 FILENUM=4
2320 OPEN #3,DFILE$,INPUT
2340 INPUT LINE #3,D$
2360 GOTO BEGIN
2380 NODATA:
2400 DF=1
2420 BFLAG=-1
2440 GET'COPIES: A$=""
2460 INPUT "Number Of Copies (Or RETURN): ";A$
2480 IF A$="" THEN ?"*** Hit CONTROL-C To End Execution ***" : GOTO BEGIN
2500 COPIES=A$
2520 IF COPIES=0 GOTO GET'COPIES
2540 !
2560 ! BEGIN LOOP THROUGH ENTIRE LETTER
2580 !
2600 BEGIN: NCOPIES=NCOPIES+1
2620 ON FORMS GOTO TEST'F,BEGIN'S
2640 TEST'F: IF FFLAG GOTO BEGIN'C
2660 BEGIN'S: INPUT "Hit RETURN When First Page Ready: ";A$
2680 FFLAG=-1
2700 BEGIN'C: IF COPIES<>0 THEN ?"*** Printing Copy #";NCOPIES
2720 INFILE=1
2740 OPEN #1,LFILE(1),INPUT
2760 INPUT LINE #1,ISTG ! GET RID OF FIRST FF IF PRESENT
2780 IF EOF(1)=1 GOTO ENDFILE
2800 IF ASC(ISTG[1;1])=12 THEN ISTG=RIGHT(ISTG,LEN(ISTG)-1)
2820 GOTO NO'FF
2840 !
2860 ! LOOP THROUGH INPUT FILE
2880 !
2900 LOOP: INPUT LINE #1,ISTG
2920 IF EOF(1)=1 GOTO ENDFILE
2940 IF LINES <>0 THEN GOTO NO'FF ! SKIP IF NOT CHECKING FOR FF
2960 ON FORMS GOTO NO'FF,CHK'FF ! SKIP IF CONTINUOUS FORMS
2980 CHK'FF: IF ASC(ISTG[1;1])<>12 GOTO NO'FF ! SKIP IF FIRST CHAR NOT FF
3000 ISTG=RIGHT(ISTG,LEN(ISTG)-1)
3020 GOSUB NEXT'S
3040 NO'FF: IF BFLAG THEN ?#2,ISTG : GOTO CHK'LINES
3060 K=LEN(ISTG)
3080 BEG=1
3100 VFLAG=0
3120 !
3140 ! BEGIN LOOP THROUGH SINGLE RECORD
3160 !
3180 IN'LOOP: IF BEG>K GOTO LOOP'END
3200 I=INSTR(BEG,ISTG,"\")
3220 IF I=0 GOTO NO'MORE
3240 J=INSTR(I+1,ISTG,"\")
3260 IF J=0 GOTO BAD'FILE
3280 IF J=I+1 GOTO B'SLASH
3300 IF EOF(3)=1 GOTO D'ENDFILE
3320 VFLAG=-1
3340 VAR'NAME=ISTG[I+1,J-1]
3360 JUMP=INSTR(1,"*$",LEFT(VAR'NAME,1)) ! SEE IF SPECIAL PROCESSING--
3380 IF JUMP=0 GOTO NORMAL
3390 VAR'NAME=VAR'NAME[2,-1]
3400 !
3420 ! SPECIAL CONTROL VARIABLES OR TYPES PROCESSED HERE
3440 !
3460 ON JUMP GOTO SPECIAL,DOLLAR
3480 !
3500 SPECIAL:
3520 VAR'NAME=UCS(VAR'NAME)
3540 FOR TEMP1=1 TO NOSPECS
3560 IF VAR'NAME#SPECS(TEMP1) GOTO SPNEXT
3580 JUMP=TEMP1 : TEMP1=NOSPECS : NEXT TEMP1 : GOTO SPECJUMP
3600 SPNEXT: NEXT TEMP1
3620 ?"*** ERROR: Special Function Name ";VAR'NAME;" Not In Table ***"
3630 INPUT LINE "*** Hit RETURN To Continue: "XXX$
3640 GOTO CHAINOUT
3660 SPECJUMP:
3680 ON JUMP GOTO SPEC1,SPEC2
3700 !
3720 SPEC1: ! DATE AS MONTH DD,19YY
3740 IF DATE=0 GOSUB GET'DATE
3760 DAT=DATE
3780 SP$=MOTAB(M)+" "+D+",19"+Y
3800 GOTO USESPEC
3820 !
3840 SPEC2: ! DATE AS MM/DD/YY
3860 IF DATE=0 GOSUB GET'DATE
3880 DAT=DATE
3900 SP$=(M USING "#Z")+"/"+(D USING "#Z")+"/"+Y
3920 GOTO USESPEC
3940 !
3960 USESPEC:
3980 OSTG=OSTG+ISTG[BEG;I-BEG]+SP$
4000 GOTO IN'LOOP'END
4020 !
4040 DOLLAR:
4060 DFLAG=-1
4080 GOTO NORMAL
4100 !
4120 ! NORMAL VARIABLES PROCESSED HERE
4140 !
4160 NORMAL:
4180 ON DF GOTO FROM'TERM,GOT'DATA
4200 FROM'TERM: IF UCS(VAR'NAME)#"SKIP" THEN ?VAR'NAME+": "; :INPUT LINE D$
4220 GOT'DATA: IF UCS(VAR'NAME)="SKIP" THEN D$=""
4240 IF NOT DFLAG GOTO NOEDIT
4260 D$=D$ USING DLUSE
4280 D$=D$[INSTR(1,D$,"$"),-1]
4300 IF RIGHT(D$,3)=".00" THEN D$=D$[1,-4]
4320 DFLAG=0
4340 NOEDIT:
4360 OSTG=OSTG+ISTG[BEG;I-BEG]+D$
4380 ON DF GOTO IN'LOOP'END,NEXT'D
4400 NEXT'D: INPUT LINE #3,D$
4420 GOTO IN'LOOP'END
4440 B'SLASH: OSTG=OSTG+ISTG[BEG;I-BEG]+"\"
4460 IN'LOOP'END: BEG=J+1
4480 GOTO IN'LOOP
4500 !
4520 ! END OF SINGLE RECORD LOOP
4540 !
4560 NO'MORE: OSTG=OSTG+ISTG[BEG,K]
4580 LOOP'END: IF NOT VFLAG GOTO PRT'IT
4582 TEMP1=LEN(OSTG) ! DETERMINE IF LINE SHOULD BE SKIPPED--
4583 IF TEMP1=0 GOTO LOOP
4584 FOR TEMP2=1 TO TEMP1
4586 IF INSTR(1,BLKTAB,OSTG'S(TEMP2))=0 THEN TEMP2=TEMP1 : NEXT TEMP2 : GOTO PRT'IT
4588 NEXT TEMP2
4590 OSTG="" : GOTO LOOP
4592 PRT'IT:
4600 ?#2,OSTG
4620 OSTG=""
4640 CHK'LINES: IF LINES=0 GOTO LOOP
4660 OLINES=OLINES+1
4680 IF OLINES<LINES GOTO LOOP
4690 ON FORMS GOSUB FORM'FEED,NEXT'S
4700 OLINES=0
4760 GOTO LOOP
4780 PAGE'S: GOSUB NEXT'S
4800 GOTO LOOP
4820 !
4840 ! END OF LOOP THROUGH INPUT FILE
4860 !
4880 !
4900 ! END-OF-FILE CODE
4920 !
4940 ENDFILE: IF INFILE=INFILES GOTO REAL'END
4960 CLOSE #1
4980 INFILE=INFILE+1
5000 OPEN #1,LFILE(INFILE),INPUT
5020 GOTO LOOP
5040 REAL'END: GOSUB FORM'FEED
5060 OLINES=0
5080 ON DF GOTO END'TERM,END'FILE
5100 END'TERM: IF OUTTRM THEN CLOSE #2
5120 IF NOT BFLAG GOTO ASK'RESTART
5140 IF COPIES=0 GOTO REOPEN
5160 IF NCOPIES<COPIES THEN GOTO REOPEN ELSE GOTO CHAINOUT
5180 ASK'RESTART: ?"End Of Letter: Type 'R' To Restart, Hit RETURN To End: ";
5200 INPUT LINE A$
5220 IF A$#"" GOTO REOPEN
5240 IF NOT OUTTRM THEN CLOSE #2
5260 GOTO CHAINOUT
5280 REOPEN: IF OUTTRM THEN OPEN #2,OFILE$,OUTPUT
5300 GOTO RESTART
5320 END'FILE: IF EOF(3)=1 GOTO D'ENDFILE
5340 ON FORMS GOTO RESTART,CLOSOPEN
5360 CLOSOPEN: CLOSE #2
5380 OPEN #2,OFILE$,OUTPUT
5400 RESTART: CLOSE #1
5420 GOTO BEGIN
5440 !
5460 ! END-OF-FILE ON DATA
5480 !
5500 D'ENDFILE: ?"*** End Of Data ***"
5520 CLOSE #2 : GOTO CHAINOUT
5540 !
5560 ! SUBROUTINE TO ASK FOR NEXT PAGE
5580 !
5600 NEXT'S: GOSUB FORM'FEED ! SHOOT THIS PAGE OUT
5620 CLOSE #2
5640 OPEN #2,OFILE$,OUTPUT
5660 INPUT "Insert Next Page; Hit RETURN When Ready: ",A$
5680 RETURN
5700 !
5720 ! EXTENSION DEFAULT ROUTINE--A$ IS INPUT, C$ IS DEFAULT EXTENSION
5740 !
5760 DEFAULT: IF INSTR(1,A$,".")<>0 RETURN
5780 I=INSTR(1,A$,"[")
5800 IF I=0 THEN A$=A$+C$ : RETURN
5820 A$=LEFT(A$,I-1)+C$+RIGHT(A$,LEN(A$)-I+1)
5840 RETURN
5860 !
5880 ! FORMFEED ROUTINE
5900 !
5920 FORM'FEED: IF PHYS'LINES=0 THEN ?#2,CHR(12);SPACE(46);CHR(13); : RETURN
5940 FOR I=1 TO PHYS'LINES-OLINES
5960 ?#2
5980 NEXT I
6000 RETURN
6020 !
6040 ! GET TODAY'S DATE
6060 !
6080 GET'DATE:
6100 ?"System Date Is Not Set--"
6120 ASK'DATE: INPUT LINE "Please Enter As MMDDYY: "DT$
6140 IF LEN(DT$)#6 GOTO ASK'DATE
6160 M=DT$[1,2] : D=DT$[3,4] : Y=DT$[5,6]
6180 DATE=DAT
6200 RETURN
6220 !
6240 ! ON ERROR ROUTINE
6260 !
6280 ERR'CODE: IF ERR(0)=1 THEN RESUME QUIT
6300 IF ERR(0)<>17 GOTO CHK'SPEC
6320 ?"*** FILE NOT FOUND ***"
6340 RESUME RETRY
6360 CHK'SPEC: IF ERR(0)<>16 GOTO CHK'DEVRDY
6380 ?"*** FILE SPECIFICATION ERROR ***"
6400 RESUME RETRY
6420 CHK'DEVRDY: IF ERR(0)<>18 GOTO CHK'DEVFLL
6440 ?"*** DEVICE NOT READY ***"
6460 RESUME RETRY
6480 CHK'DEVFLL: IF ERR(0)<>19 GOTO CHK'DEVERR
6500 ?"*** DEVICE FULL ***"
6520 RESUME RETRY
6540 CHK'DEVERR: IF ERR(0)<>20 GOTO CHK'CODE
6560 ?"*** DEVICE ERROR ***"
6580 RESUME RETRY
6600 CHK'CODE: IF ERR(0)<>22 GOTO CHK'PROT
6620 ?"*** ILLEGAL USER CODE ***"
6640 RESUME RETRY
6660 CHK'PROT: IF ERR(0)<>23 GOTO CHK'WRIT
6680 ?"*** PROTECTION VIOLATION ***"
6700 RESUME RETRY
6720 CHK'WRIT: IF ERR(0)<>24 GOTO CHK'TYPE
6740 ?"*** WRITE PROTECTED ***"
6760 RESUME RETRY
6780 CHK'TYPE: IF ERR(0)<>25 GOTO CHK'DEV
6800 ?"*** NOT A SEQUENTIAL FILE ***"
6820 RESUME RETRY
6840 CHK'DEV: IF ERR(0)<>26 GOTO CHK'BIT
6860 ?"*** DEVICE DOES NOT EXIST ***"
6880 RESUME RETRY
6900 CHK'BIT: IF ERR(0)<>27 GOTO CHK'MNT
6920 ?"*** BITMAP DESTROYED ***"
6940 RESUME QUIT
6960 CHK'MNT: IF ERR(0)<>28 GOTO DIE
6980 ?"*** DISK NOT MOUNTED ***"
7000 RESUME RETRY
7020 DIE: ?"*** ERROR: CODE=";ERR(0);" LINE=";ERR(1);" LASTFILE=";ERR(2)
7040 ?"*** UNABLE TO CONTINUE"
7060 QUIT: ON ERROR GOTO 0
7080 GOTO CHAINOUT
7100 RETRY: ON FILENUM GOTO GET'FILE,GET'PARAS,GET'OUT,GET'DNAME
7120 !
7140 ! UNPAIRED BACKSLASH ERROR
7160 !
7180 BAD'FILE: ?"*** ERROR IN INPUT FILE: UNPAIRED BACKSLASH FOUND"
7200 ?"*** BAD RECORD FOLLOWS:"
7220 ?ISTG
7240 CHAINOUT: CHAIN "DSK0:LTREXT.CMD[2,2]"