{$I plistt1.pas }

FUNCTION sonderzeile (VAR x : line) : boolean;

{ In Sonderzeilen duerfen keine einfachen Anfuehrungszeichen sein. }

VAR h               : boolean;
    w               : STRING [2];
    z               : STRING [3];
    fehler, i, j, m : integer;

BEGIN { sonderzeile }
  h := sonder (x);
  IF h
    THEN
      BEGIN
        i := pos ('{.', x) OR pos ('(*.', x);
        IF i > 0
          THEN
            IF pos ('(*.', x) = i
              THEN
                m := 1
              ELSE
                m := 0;
        IF i > 0
          THEN
            REPEAT
              w := '';
              fehler := 0;
              IF x [i] IN ['A'..'Z', 'a'..'z']
                THEN
                  BEGIN
                    w := x [i]+x [i+1];
                    i := i+2;
                    IF (w = 'pl') OR (w = 'mt') OR (w = 'mb')
                                  OR (w = 'po') OR (w = 'cp')
                      THEN
                        BEGIN
                          z := '';
                          WHILE NOT (x [i] IN ['0'..'9']) DO
                            i := i+1;
                          WHILE x [i] IN ['0'..'9'] DO
                            BEGIN
                              z := z+x [i];
                              i := i+1
                            END;
                          IF w = 'pl'
                            THEN
                              val (z, pl, fehler);
                          IF w = 'mt'
                            THEN
                              val (z, mt, fehler);
                          IF w = 'mb'
                            THEN
                              val (z, mb, fehler);
                          IF w = 'po'
                            THEN
                              val (z, po, fehler);
                          IF w = 'cp'
                            THEN
                              val (z, cp, fehler)
                        END;
                        h := fehler = 0;
                        IF w = 'he'
                          THEN
                            BEGIN
                              he := copy (x, i, length (x)-i-m);
                              i := 127
                            END;
                        IF w = 'fo'
                          THEN
                            BEGIN
                              fo := copy (x, i, length (x)-i-m);
                              i := 127
                            END;
                        IF w = 'pa'
                          THEN
                            neueseite;
                        IF w = 'cp'
                          THEN
                            IF pl-mt-mb-zeilenzahl < cp
                              THEN
                                neueseite;
                        IF w = 'L+'
                          THEN
                            listflag := true;
                        IF w = 'L-'
                          THEN
                            listflag := false;
                        IF w = 'A+'
                          THEN
                            autoblockflag := true;
                        IF w = 'A-'
                          THEN
                            autoblockflag := false
                  END;
                  i := i+1
            UNTIL i > length (x)
          ELSE
            BEGIN
              i := pos ('{$I', x)+2;
              IF i = 2
                THEN
                  i := pos ('(*$I', x)+3;
              inclfilename := '';
              WHILE (i < length(x)) AND (length (inclfilename) < 12) DO
                BEGIN
                  i := i+1;
                  IF x [i] IN ['-', '.', '0'..'9', 'A'..'Z', 'a'..'z']
                    THEN
                      inclfilename := inclfilename+gross (x [i])
                END;
              IF mainfilename [2] = ':'
                THEN
                  IF inclfilename [2] = ':'
                    THEN
                      inclfilename [1] := mainfilename [1]
                    ELSE
                      inclfilename := mainfilename [1]+':'+inclfilename;
              includeflag := fileexists (include);
              h := includeflag;
              IF includeflag
                THEN
                  writeln ('Including ', inclfilename)
                ELSE
                  writeln ('File ', inclfilename, ' not found,');
      END
    END;
  sonderzeile := h
END;  { sonderzeile }

{======================================================================}

{                   Puffer-Operationen mit FIFO                        }

FUNCTION leer (VAR x : line) : boolean;

VAR h : boolean;
    i : integer;

BEGIN { leer }
  h := true;
  i := 1;
  WHILE h AND (i <= length (x)) DO
    BEGIN
      h := ord (x [i]) = 32;
      i := i+1
    END;
  leer := h
END;  { leer }

{----------------------------------------------------------------------}

FUNCTION endofblock : boolean;

VAR h : boolean;

BEGIN { endofblock }
  h := eof (mainfile);
  IF includeflag
    THEN
      IF eof (inclfile)
        THEN
          BEGIN
            h := true;
            includeflag := false;
            schliessincludefile
          END;
  IF NOT (h)
    THEN
      h := leer (zeile);
  IF NOT (h)
    THEN
      h := sonder (zeile);
  IF puffergroesse > pl-mt-mb-3
    THEN
      h := true;
  endofblock := h
END;  { endofblock }

{----------------------------------------------------------------------}

PROCEDURE clearpuffer;

BEGIN { clearpuffer }
  p := anfang;
  WHILE p^.naechster <> NIL DO
    BEGIN
      q := p;
      dispose (p);
      p := q^.naechster
    END;
  dispose (p);
  puffervoll := false
END;  { clearpuffer }

{----------------------------------------------------------------------}

PROCEDURE liespuffer;

BEGIN { liespuffer }
  puffergroesse := 0;
  new (q);
  anfang := q;
  q^.naechster := NIL;
  REPEAT
    IF includeflag
      THEN
        readln (inclfile, zeile)
      ELSE
        readln (mainfile, zeile);
    q^.eintrag := zeile;
    puffergroesse := puffergroesse+1;
    new (p);
    q^.naechster := p;
    p^.naechster := NIL;
    q := p;
  UNTIL endofblock;
  puffervoll := true
END;  { liespuffer }

{======================================================================}

{                           Hauptprogramm                              }

BEGIN { plist }
  includeflag   := false;
  listflag      := true;
  seitenzahl    := 1;
  stringflag    := false;
  kommentarflag := false;
  puffervoll    := false;
  caseflag      := true;
  iter          := 0;
  clrscr;
  writeln ('PLIST vers. 3.6');
  writeln;
  REPEAT
    writeln ('Geben Sie den Namen des zu druckenden Programms ein.');
    write ('("RETURN" fuer Ende, oder "?" fuer Help.)  Eingabe: ');
    liesfilename;
    IF mainfilename = '?'
      THEN
        BEGIN
clrscr;
writeln ('Um den Ausdruck des Programms zu formatieren, koennen Sie');
writeln ('folgende Punktkommandos benuetzen:  (Syntax: {.Kommando})');
writeln;
writeln ('Kommando  Wirkung                        Voreinstellung');
writeln;
writeln ('PL nn     Seitenlaenge                         ',pl);
writeln ('MT nn     Rand oben                             ',mt);
writeln ('MB nn     Rand unten                            ',mb);
writeln ('PO nn     Rand links                            ',po);
writeln ('CP nn     Neue Seite bei weniger als n Zeilen   ',cp);
writeln ('PA        Neue Seite');
writeln ('HE        Kopfzeile               Listing of ... PAGE #');
writeln ('FO        Fusszeile                            (keine)');
writeln ('L+/L-     Listing   ein/aus');
writeln ('A+/A-     Autoblock ein/aus');
writeln;
writeln ('Alle Kommandos ausser HE und FO koennen auch in eine Zeile');
writeln ('geschrieben werden. Beispiel {.PL 64, MT 8, PO 5}');
writeln ('In HE und FO kann # fuer die Seitennummer angegeben werden.');
writeln
        END
      ELSE
        IF (mainfilename <> '') AND fileexists (main)
          THEN
            BEGIN
              liesoptions;
              crosslist := NIL;
              seitenzahl := 1;
              writeln ('Listing of ', mainfilename, '.');
              he := 'Listing of '+mainfilename
                    +'                                          PAGE #';
              zeilenzahl := 0;
              zeilennummer := 1;
              WHILE NOT (eof (mainfile)) OR puffervoll DO
                BEGIN
                  IF NOT puffervoll
                    THEN
                      BEGIN
                        liespuffer;
                        p := anfang
                      END;
                  zeile := p^.eintrag;
                  p := p^.naechster;
                  IF p^.naechster = NIL
                    THEN
                      clearpuffer;
                  IF autoblockflag AND (puffergroesse >
                                        pl-zeilenzahl-mb-3)
                                   AND (puffergroesse <=
                                        pl-mt-mb-3)
                    THEN
                      neueseite;
                  puffergroesse := 0;
                  IF NOT sonderzeile (zeile)
                    THEN
                      BEGIN
                        IF zeilenzahl MOD pl = 0
                          THEN
                            seitenkopf;
                        IF pl-zeilenzahl = mb+3
                          THEN
                            neueseite;
                        IF listflag
                          THEN
                            BEGIN
                              drucke (zeile);
                              zeilenzahl := zeilenzahl+1
                            END;
                        zeilennummer := zeilennummer+1
                      END
                END;
                IF cross IN options
                  THEN
                    schreibcrossliste;
                close (mainfile)
            END
          ELSE
            IF mainfilename <> ''
              THEN
                writeln ('File existiert nicht.')
  UNTIL mainfilename = ''
END.  { plist }