{$TITLE:'MULTIPLE FILE PRINT SPOOLER     ---       VERSION 1.1 '}
{$LINESIZE:131}
{$PAGESIZE:58}
{$LIST+}
{$WARN-}
{$SYMTAB+}
{$DEBUG+}
{$LINE+}
{-------------------------------------------------------------}
{                                                             }
{      I B M / P C   M U L T I - F I L E     S P O O L E R    }
{                                                             }
{                                                             }
{                                                             }
{   THIS PROGRAM ALLOWS SEVERAL DATASETS TO BE "STACKED"      }
{   FOR PRINTING.                                             }
{                                                             }
{   CONTROLS FOR PAGE LENGTH, COLUMN RASTER, AND PAGE         }
{   NUMBERING ARE PROVIDED.                                   }
{                                                             }
{                                                             }
{-------------------------------------------------------------}
{$PAGE+}

PROGRAM PRINTER ( OPTIONS) ;

CONST 
      MAXPAGESIZE       = 88 ;
      MINPAGESIZE       = 10 ;
      MAXLINESIZE       = 132 ;
      MINLINESIZE       = 40  ;
      DSMAX             = 16 ;
      PGN               = 'Page ' ;
      DSN_EMPTY         = '*             ' ;

  RR1 = '1...5....0....5....0....5....0....5....0....5....0....5....0';
  RR2 = '....5....0....5....0';
  RR3 = '....5....0....5....0....5....0....5....0....5....0..';
  RA1 = '0        1         2         3         4         5         6';
  RA2 = '         7         8';
  RA3 = '         9         0         1         2         3  ';
  RB1 = '                                                            ';
  RB2 = '                    ';
  RB3 = '                   1         1         1         1  ';
      RAST32_oh  = RB1 * RB2* RB3 ;

      RAST80_ONE = RA1 * RA2 ;
      RAST80_TWO = RR1 * RR2 ;
      RAST32_ONE = RA1 * RA2* RA3 ;
      RAST32_TWO = RR1 * RR2* RR3 ;


VAR 
    DSNUM,
    IKF,
    IHC,
    IKJ,
    PAGESIZE,         {actual pagesize}
    LINESIZE,         {actual linesize MUST be 80 or 132}
    PAGECOUNT,
    LINECOUNT         :  INTEGER  ;
    LPI8,
    PAGENUM,
    SEQUENCE,
    PRT_TITLE,
    SHOW_RASTER,
    HEADING           :  BOOLEAN   ;
    P_DATE            :  STRING(8) ;
    P_TIME            :  STRING(8) ;
    P_TITL            :  LSTRING(80) ;
    INPUT_LINE        :  LSTRING(255) ;
    OUTPUT_LINE       :  LSTRING(255) ;
    PRINTER           :  TEXT ;
    INFILES           :  TEXT ;
    OPTIONS           :  LSTRING(66) ;
    DSNAME            :  LSTRING(14) ;
    DATASET           :  ARRAY [1..DSMAX] OF STRING(14) ;
    TITLE             :  ARRAY [1..DSMAX] OF LSTRING(80)  ;
 
{$INCLUDE:'B:INDEX.P'}
{$INCLUDE:'B:PARSE.P'}
{$INCLUDE:'B:DSNAME.P'}
PROCEDURE GETDSN ; FORWARD ;

PROCEDURE FILEDSN;
FORWARD;

 PROCEDURE TIME(VAR S: STRING);
EXTERNAL;

 PROCEDURE DATE(VAR S: STRING);
EXTERNAL;

PROCEDURE INITIALIZE;
BEGIN
  WRITE(PRINTER,CHR(27),'@',CHR(27),'5',CHR(27),'C',CHR(PAGESIZE));
  IF LINESIZE = 132
    THEN
      WRITE(PRINTER,CHR(27),'P');
  IF LINESIZE = 80
    THEN
      WRITE(PRINTER,CHR(27),'Q');
  IF LPI8
    THEN
      WRITE(PRINTER,CHR(27),'0')
     ELSE
       WRITE(PRINTER,CHR(27),'2');
  WRITE(PRINTER,CHR(7)) ;

  IF (OPTIONS  = ' ') OR (OPTIONS = '*') 
    THEN
      BEGIN
      OPTIONS := NULL ;
      DSNAME := NULL ;
      END; {BEGIN-OPTIONS empty}

  IF DSNAME.LEN = 0
    THEN
      GETDSN
    ELSE
      FILEDSN;
  IF (PRT_TITLE) or (PAGENUM) or (SHOW_RASTER) or (SEQUENCE)
     THEN HEADING := TRUE ;
  ELSE HEADING := FALSE ;

  IF HEADING THEN 
     BEGIN
      LINECOUNT := PAGESIZE - 3 ;
     IF PRT_TITLE THEN
      LINECOUNT := LINECOUNT - 1 ;
     IF PAGENUM THEN
      LINECOUNT := LINECOUNT - 2 ;
     IF SHOW_RASTER THEN
      IF LINESIZE = 80 
         THEN LINECOUNT := LINECOUNT - 4 ;
      ELSE LINECOUNT := LINECOUNT - 6 ;
  END; {HEADING-BEGIN}
 
END; {INITIALIZE}


PROCEDURE FILEDSN;

VAR 
    I     :   INTEGER;
    DSNS  :   TEXT ;
    INREC :   LSTRING(255);
    FNAME :    STRING(14) ;
BEGIN
   ASSIGN(DSNS,DSNAME);
   RESET(DSNS);
   I := 1 ;
   REPEAT
     READLN(DSNS,INREC);
     IKJ := INDEX(INREC,'/');
     IF IKJ <> 0
       THEN
         BEGIN
           {TITLE CAPTURE GOES HERE }
         END; {I <> 0 }
     IKJ := INDEX(INREC,' ');
     GET_DSNAME(FNAME,INREC);
     IF IKJ > 14
       THEN
         BEGIN
           WRITELN('Error in Filename Format in',DSNAME);
           ABORT('EXECUTION HALTED',013,018);
         END; {IKJ>14}
     I := I + 1 ;
     DATASET[I] := FNAME;
  UNTIL EOF(DSNS);
END; {FILEDSN}

PROCEDURE DEFAULTS;

VAR 
    I    : INTEGER ;
BEGIN
   PAGESIZE     :=   66 ;
   LINESIZE     :=   MAXLINESIZE ;
   LPI8         :=   FALSE ;
   PAGENUM      :=   TRUE ;
   PRT_TITLE    :=   FALSE ;
   SHOW_RASTER  :=   TRUE  ;
   HEADING      :=   TRUE ;
   PAGECOUNT    :=   1 ;
   LINECOUNT    :=   1 ;
   FOR I := 1 TO DSMAX DO
     DATASET[I] := DSN_EMPTY ;
END; {DEFAULTS}

PROCEDURE GET_TITLE;

 VAR 
     I        :  INTEGER;
     REPLY1    :  CHAR ;
BEGIN
  WRITE('TITLE PROMPT FOR EACH DATASET (Y/N) ?') ;
  READLN(REPLY1);
  IF (REPLY1 = 'Y') OR (REPLY1 = 'y')
    THEN
      BEGIN
        PRT_TITLE := TRUE ;
        FOR I := 1 TO DSNUM DO
          BEGIN
            WRITELN('DSN#':4,I:2,' = [':4,DATASET[I]:14);
            WRITE('TITLE [79] =');
            READLN(TITLE[I]);
          END; {FOR I -DSMAX}
      END; {REPLY=Y}
END; {TITLE}

PROCEDURE TRUNK (VAR INSTR: LSTRING; VAR OUTSTR: LSTRING) ;

  VAR 
      II,X,Y,Z : INTEGER;
      U     : BYTE ;
  BEGIN   {TRUNK}

          U := INSTR.LEN ;
          X := ORD(U) ;
          IF  X > LINESIZE
            THEN
              Y := LINESIZE
            ELSE
              Y := X ;
          Z := 0 ;
          II := Y ;
          REPEAT
            IF INSTR[II] = ' '
              THEN
                Z := 256
              ELSE
                Z := II ;
            II := II - 1 ;
          UNTIL (Z <> 256) ;
          FOR II := 1 TO Z DO
            OUTSTR[II] := INSTR[II] ;
          OUTSTR.LEN := WRD(Z) ;
  END;  {TRUNK}

    PROCEDURE GETDSN;

   VAR 
       I       :  INTEGER ;
   BEGIN
                    FOR I := 1 TO DSMAX DO
                      BEGIN
                        WRITE('Dsname:') ;
                        READLN(DATASET[I]);
                        IF DATASET[I] = DSN_EMPTY
                          THEN
                            BREAK ;
                      END; {GETDSN}
                    DSNUM := I - 1 ;
      END; {GETDSN}

PROCEDURE PRINTDSN (VAR DSN : STRING ) ;

VAR 
    J           : INTEGER  ;
    CONTROL   :   BOOLEAN  ;

PROCEDURE PAGENATE ;

BEGIN
IF J = 255 THEN ;
 ELSE
  BEGIN
 
 if not(SHOW_RASTER) THEN  ;
   
 ELSE
    BEGIN
      WRITELN(PRINTER) ;
      IF LINESIZE = 80 THEN
        BEGIN
           WRITELN(PRINTER,RAST80_TWO);
           WRITELN(PRINTER,RAST80_ONE);
        END;  {RASTER := 80}
      ELSE
        BEGIN
           WRITELN(PRINTER,RAST32_TWO);
           WRITELN(PRINTER,RAST32_ONE);
           WRITELN(PRINTER,RAST32_OH) ;
        END;  {RASTER := 132}
     END; {ELSE-SHWO_RASTER}
  END; {J = 255}
 
   WRITE(PRINTER,CHR(12));
   IF NOT (PRT_TITLE)
     THEN
                      ;
     ELSE
       BEGIN
         IF LINESIZE = 80
           THEN
             WRITELN(PRINTER,P_TITL)
           ELSE
             WRITELN(PRINTER,P_TITL:104);
       END; {ELSE OF NOT PRT_TITLE}
   IF LINESIZE = 132
     THEN
       BEGIN
         WRITE(PRINTER,'SPOOL - V1.1 ':12,'  ':100,P_DATE:8,'  ':4) ;
         WRITELN(PRINTER,PGN:5,PAGECOUNT:3) ;
       END; {BEGIN =132}
  ELSE
     BEGIN
        WRITE(PRINTER,'SPOOL - V1.1 ':12,'  ':48,P_DATE:8,'  ':4) ;
        WRITELN(PRINTER,PGN:5,PAGECOUNT:3) ;
     END; {BEGIN := 80}

  IF NOT (SHOW_RASTER)
    THEN
                      ;
    ELSE
      BEGIN
        WRITELN(PRINTER) ;
        IF LINESIZE = 80
          THEN
            BEGIN
              WRITELN(PRINTER,RAST80_ONE);
              WRITELN(PRINTER,RAST80_TWO);
            END; {RASTER := 80}
      ELSE
        BEGIN
          WRITELN(PRINTER,RAST32_OH) ;
          WRITELN(PRINTER,RAST32_ONE);
          WRITELN(PRINTER,RAST32_TWO);
        END; {RASTER := 132}

     END;  {BEGIN -SHOW_RASTER}

   PAGECOUNT := PAGECOUNT + 1 ;
 END; {PAGENATE}

BEGIN {PRINTDSN}
  ASSIGN(INFILES,DSN);
  RESET(INFILES);
  WRITELN('Printing Dataset [',DSN,'] ') ;
  J := 255;
  REPEAT
  IF (HEADING) THEN
     BEGIN
     IF J >= LINECOUNT
       THEN
         BEGIN
           PAGENATE ;
           j := 0 ;
         END; {J GT PAGESIZE}
   END;  { IF HEADING}

    READLN(INFILES,INPUT_LINE);
    TRUNK(INPUT_LINE,OUTPUT_LINE);
    WRITELN(PRINTER,OUTPUT_LINE);
     J := J + 1 ;
  UNTIL EOF(INFILES);
   IF (HEADING) THEN
      BEGIN 
  IKJ = LINECOUNT  - J ;
  IKJ := IKJ - 1 ;
  FOR IKF := 1 TO IKJ DO 
      WRITELN(PRINTER) ;
  { PRINT LAST BOTTOM RASTER }
  IF NOT (SHOW_RASTER) THEN  ;
   ELSE
     BEGIN
       IF LINESIZE = 80 THEN
          BEGIN
            WRITELN(PRINTER,RAST80_TWO) ;
            WRITELN(PRINTER,RAST80_ONE) ;
          END; {LINE := 80}
       ELSE 
          BEGIN
            WRITELN(PRINTER,RAST32_TWO);
            WRITELN(PRINTER,RAST32_ONE) ;
            WRITELN(PRINTER,RAST32_OH)  ;
          END; {LINE := 132}
     END; {ELSE - SHOW_RASTER}
   end; { IF HEADING}

  CLOSE(INFILES);
END; {PRINTDSN}
{                                                                     }
{  S T A R T    O F    M A I N    L I N E     C O D E                 }
{                                                                     }
BEGIN {PRINTER}
  ASSIGN(PRINTER,'LPT1:') ;
  REWRITE(PRINTER);
  DEFAULTS ;
  INITIALIZE ;
  GET_TITLE ;
  FOR IHC := 1 TO DSNUM DO
    BEGIN
      PAGECOUNT := 1 ;
      TIME(P_TIME);
      DATE(P_DATE) ;
      IF PRT_TITLE
        THEN
          P_TITL := TITLE[IHC] ;
      PRINTDSN(DATASET[IHC]) ;
    END; {IHC FOR}
END. {PRINTER}
