home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / extra18 / optipas / pretty.inc < prev    next >
Encoding:
Text File  |  1991-12-04  |  11.4 KB  |  382 lines

  1. (* ------------------------------------------------- *)
  2. (*                  PRETTY.INC                       *)
  3. (*    Include-File - wird in PRETTY.PAS geladen      *)
  4. (*    Sprache  : Turbo Pascal Version 6.0            *)
  5. (*   (c) 1991 Wilfried Lottermoser & DMV-Verlag      *)
  6. (* ------------------------------------------------- *)
  7. CONST
  8.   tempfilename  = 'temp.$$$';
  9.  
  10. VAR
  11.   quelldatei,
  12.   zieldatei,
  13.   bakdatei      : TEXT;
  14.  
  15.  
  16.   FUNCTION Optimize(quellname       : STRING;
  17.                     stand, struktur,
  18.                     platzspar       : BOOLEAN;
  19.                     einruecktiefe,
  20.                     maxzeilenlaenge : BYTE) : WORD;
  21.  
  22. CONST
  23.   Buchstaben   : SET OF CHAR =
  24.     ['A'..'Z', 'a'..'z', '_'];
  25.   trennzeichen : SET OF CHAR =
  26.     [' ', ';', ',', '+', '-', '=', '*', '/', '.'];
  27.  
  28.   tab = 8;
  29.  
  30.   anfangworte  : ARRAY[1..11] OF STRING[6] =
  31.     ('BEGIN', 'REPEAT', 'CASE', 'RECORD', 'IF', 'THEN',
  32.      'WHILE', 'UNTIL',  'ELSE', 'DO', 'OBJECT');
  33.  
  34. VAR
  35.   bakname,
  36.   wort, puffer   : STRING;
  37.   zeichen        : CHAR;
  38.   laenge,          { aktuelle Zeilenlaenge            }
  39.   einr,            { aktuelle Einrücktiefe            }
  40.   n, durchlaeufe : BYTE;
  41.   neuzeile       : BOOLEAN;
  42.                    { ist Puffer am  Zeilenanfang      }
  43.   ebene          : ARRAY [0..255] OF RECORD
  44.                      EndWort     : STRING[6];
  45.                      Tiefe       : BYTE;
  46.                      AnfZeileAlt : BOOLEAN;
  47.                      TiefWort    : BYTE;
  48.                    END;
  49.   aktebene,        { aktuelle  Ebene                  }
  50.   kommentar,       { 1=Strings   2={   3=(*           }
  51.   caseebene      : BYTE;
  52.   errornr        : WORD;
  53.  
  54.  
  55.   FUNCTION IoError : BOOLEAN;      { IO-Fehlerabfrage }
  56.   BEGIN
  57.     ErrorNr := IOResult;
  58.     IF ErrorNr > 0 THEN BEGIN
  59.       IoError  := TRUE;
  60.       Optimize := ErrorNr;
  61.     END ELSE
  62.       IoError := FALSE;
  63.   END;
  64.  
  65.   PROCEDURE GetZeichen;
  66.                        { liest Zeichen aus Quelldatei }
  67.   BEGIN
  68.     Read(QuellDatei, Zeichen);
  69.     Inc(Laenge);
  70.   END;
  71.  
  72.   PROCEDURE WritePuffer;
  73.     { schreibt Puffer in Datei ggf.
  74.       mit #13#10 & Einrücken }
  75.   VAR
  76.     i : BYTE;
  77.   BEGIN
  78.     IF Eof(QuellDatei) THEN Puffer := Puffer + Zeichen;
  79.     IF NeuZeile THEN
  80.       FOR i := 1 TO Einr DO Puffer := #32 + Puffer;
  81.     IF NeuZeile THEN Puffer := #13#10 + Puffer;
  82.     Write(Zieldatei, Puffer);
  83.   END;
  84.  
  85.   PROCEDURE Return;
  86.     { liest #13#10 und Einrückleerzeichen + Tabs }
  87.   VAR
  88.     i : BYTE;
  89.   BEGIN
  90.     Einr := 0;  NeuZeile := TRUE;
  91.     IF Zeichen = #13 THEN GetZeichen;
  92.     IF Zeichen = #10 THEN GetZeichen;
  93.     WHILE Zeichen IN [#32, #9] DO BEGIN
  94.       IF Zeichen = #32 THEN
  95.         Inc(Einr)
  96.       ELSE
  97.         Einr := Einr + Tab;
  98.       GetZeichen;
  99.     END;
  100.     FOR i := 1 TO AktEbene DO
  101.       Ebene[i].AnfZeileAlt := TRUE;
  102.     IF (AktEbene > 0) THEN
  103.       WITH Ebene[AktEbene] DO BEGIN
  104.         IF (Endwort = 'THEN') OR
  105.            { Einrücktiefe & Länge für Ebene bestimmen }
  106.            (Endwort = 'DO') OR
  107.            (Endwort = 'until;') THEN
  108.           Einr := Tiefwort
  109.            { Alles unter Bedingung einrücken }
  110.         ELSE Einr := Tiefe + Einruecktiefe;
  111.     END;
  112.     IF Einr > MaxZeilenLaenge DIV 2 THEN
  113.       einr := MaxZeilenlaenge DIV 2;
  114.     Laenge := Einr;
  115.   END;
  116.  
  117.   PROCEDURE Semikolon;
  118.     { beendet THEN-,ELSE-,DO-,
  119.       UNTIL-schleifen bei Semikolon }
  120.   BEGIN
  121.     WHILE ((Ebene[Aktebene].Endwort = 'ELSE')   OR
  122.            (Ebene[Aktebene].Endwort = 'until;') OR
  123.            (Ebene[Aktebene].Endwort = 'case:;') OR
  124.            (Ebene[Aktebene].Endwort = 'else;')  OR
  125.            (Ebene[Aktebene].endwort = 'do;'))   AND
  126.            (Aktebene > 0) DO Dec(Aktebene);
  127.   END;
  128.  
  129.   PROCEDURE WortAnalyse;
  130.     { Erstellen und Löschen von Strukturierungsebenen }
  131.   VAR
  132.     i      : BYTE;
  133.     UpWort : STRING;
  134.   BEGIN
  135.     UpWort := Up(Wort);
  136.     IF Stand THEN StandSchrW(UpWort, Wort);
  137.       { Standardschreibweise s. Unit }
  138.     IF Struktur THEN BEGIN
  139.       IF Aktebene > 0 THEN BEGIN
  140.         WHILE ((UpWort = 'ELSE') OR (UpWort = 'END') OR
  141.                (Upwort = 'UNTIL')) AND
  142.               ((Ebene[AktEbene].Endwort = 'ELSE')    OR
  143.                (Ebene[AktEbene].Endwort = 'until;')  OR
  144.                (Ebene[AktEbene].Endwort = 'case:;')  OR
  145.                (Ebene[AktEbene].Endwort = 'else;')   OR
  146.                (Ebene[AktEbene].Endwort = 'do;'))   AND
  147.                (Ebene[AktEbene].Endwort <> UpWort)   DO
  148.         Dec(AktEbene);
  149.         IF UpWort = Ebene[AktEbene].Endwort THEN BEGIN
  150.           IF Ebene[AktEbene].AnfZeileAlt THEN BEGIN
  151.             IF NOT(NeuZeile) THEN NeuZeile := TRUE;
  152.             Laenge := Laenge - Einr;
  153.               { Länge & Einr neu bestimmen }
  154.             Einr := Ebene[AktEbene].Tiefe;
  155.             Laenge := Laenge + Einr;
  156.           END;
  157.           Dec(AktEbene);
  158.         END;
  159.       END;
  160.       IF (Upwort = 'CASE') AND (CaseEbene = 0) THEN
  161.         CaseEbene := AktEbene;
  162.       IF (Upwort = 'END') AND
  163.          (CaseEbene = AktEbene) THEN CaseEbene := 0;
  164.       IF (Upwort = 'ELSE') AND
  165.          (CaseEbene = Aktebene-1) THEN
  166.            { case-else einrücken }
  167.         Einr := Ebene[AktEbene].Tiefe + EinrueckTiefe;
  168.       FOR i := 1 TO 11 DO
  169.         IF Upwort = AnfangWorte[i] THEN
  170.           WITH Ebene[AktEbene+1] DO BEGIN
  171.             Inc(AktEbene);
  172.             CASE i OF
  173.               1,3,4,11 : Endwort := 'END';
  174.               2        : Endwort := 'UNTIL';
  175.               5        : Endwort := 'THEN';
  176.               6        : Endwort := 'ELSE';
  177.               7        : Endwort := 'DO';
  178.               8        : Endwort := 'until;';
  179.               9        : Endwort := 'else;';
  180.               10       : Endwort := 'do;'
  181.             END;
  182.             IF NOT (PlatzSpar) AND (i IN [4,11]) THEN
  183.               Tiefe := laenge-6
  184.               { Record-, object-end bündig }
  185.             ELSE
  186.               Tiefe := Einr;
  187.             IF i IN [5,7,8] THEN BEGIN
  188.               WHILE zeichen = #32 DO BEGIN
  189.                 GetZeichen;
  190.                 Wort := Wort + #32;
  191.               END;
  192.               Tiefwort := Laenge;
  193.                 { if-,while,-until,-
  194.                   Bedingung untereinander }
  195.             END;
  196.             Anfzeilealt := FALSE;
  197.           END;
  198.     END;
  199.   END;
  200.  
  201.   PROCEDURE Ueberlaenge;
  202.     { Zeilenlängenformatierung der Quelldatei }
  203.   VAR
  204.     hPuffer        : STRING;
  205.     Merk39,          { Anführungszeichen              }
  206.     Anfuerzeichen  : BOOLEAN;
  207.                      { Anführungszeichen gepuffert    }
  208.     i              : BYTE;
  209.   BEGIN
  210.     Laenge        := 0;
  211.     Einr          := 0;
  212.     Anfuerzeichen := FALSE;
  213.     Merk39        := FALSE;
  214.     GetZeichen;
  215.     WHILE NOT (Eof(QuellDatei) OR (ErrorNr>0)) DO BEGIN
  216.       Puffer   := '';
  217.       NeuZeile := FALSE;
  218.       IF Zeichen IN [#10, #13] THEN Return;
  219.       WHILE NOT ((Zeichen IN Trennzeichen+[#10,#13]) OR
  220.                   Eof(Quelldatei)) DO BEGIN
  221.         IF (Zeichen = #39) THEN Merk39 := NOT(Merk39);
  222.         Puffer := Puffer + Zeichen;
  223.         GetZeichen;
  224.       END;
  225.       WHILE Zeichen IN Trennzeichen DO BEGIN
  226.         Puffer := Puffer + Zeichen;
  227.         GetZeichen;
  228.       END;
  229.       IF Laenge > MaxZeilenlaenge-1 THEN BEGIN;
  230.         { neue Zeile und Stringtrennung }
  231.       hPuffer := #13#10;
  232.       IF Anfuerzeichen THEN hPuffer := #39 + hPuffer;
  233.       FOR i := 1 TO Einr DO hPuffer := hPuffer + #32;
  234.       IF Anfuerzeichen AND (Puffer[1] <> #39) THEN
  235.         Puffer := '+' + #39 + Puffer;
  236.       IF Anfuerzeichen AND (Puffer[1] = #39) THEN
  237.         { kein +'' }
  238.         Puffer := Copy(Puffer, 2, Length(Puffer));
  239.         Laenge := Einr + Length(Puffer);
  240.         Puffer := hPuffer + Puffer;
  241.       END;
  242.       Anfuerzeichen := Merk39;
  243.       WritePuffer;
  244.     END;
  245.   END;
  246.  
  247.   PROCEDURE UeberLesen(ch : CHAR);
  248.     { Überlesen aller Strings und Kommentare }
  249.   BEGIN
  250.     Puffer := Puffer + ch;
  251.     GetZeichen;
  252.     CASE ch OF
  253.       #39 : IF Kommentar = 1 THEN Kommentar := 0;
  254.       '}' : IF Kommentar = 2 THEN Kommentar := 0;
  255.       '*' : IF Zeichen = ')' THEN
  256.               IF Kommentar = 3 THEN Kommentar := 0;
  257.     END;
  258.   END;
  259.  
  260.   PROCEDURE ZeichenAnalyse(ch : CHAR);
  261.   BEGIN
  262.     Puffer := Puffer + ch;
  263.     GetZeichen;
  264.     CASE ch OF
  265.       #39 : IF Kommentar = 0 THEN Kommentar := 1;
  266.       '{' : IF Kommentar = 0 THEN Kommentar := 2;
  267.       '(' : IF Zeichen   = '*' THEN
  268.               IF Kommentar = 0 THEN Kommentar := 3;
  269.       ';' : BEGIN
  270.               Semikolon;
  271.               IF NOT(Platzspar) THEN
  272.                 IF Zeichen <> #32 THEN
  273.                   Puffer := Puffer + #32
  274.             END;
  275.       ':' : IF NOT(Platzspar) THEN BEGIN
  276.               WHILE zeichen=#32 DO BEGIN
  277.                 Puffer := Puffer + Zeichen;
  278.                 GetZeichen;
  279.               END;
  280.               IF (CaseEbene > 0) AND
  281.                   NOT (Zeichen IN ['0'..'9', '=']) THEN
  282.                    { caselabel? }
  283.                 WITH Ebene[AktEbene+1] DO BEGIN
  284.                   Inc(AktEbene);
  285.                   Tiefe   := Laenge;
  286.                   Einr    := Tiefe;
  287.                   EndWort := 'case:;';
  288.                 END;
  289.             END;
  290.     END;
  291.   END;
  292.  
  293.   PROCEDURE Strukturierung;
  294.   VAR
  295.     i : BYTE;
  296.   BEGIN
  297.     Laenge    := 0;
  298.     Einr      := 0;
  299.     AktEbene  := 0;
  300.     CaseEbene := 0;
  301.     Kommentar := 0;
  302.     GetZeichen;
  303.     WHILE NOT (Eof(QuellDatei) OR
  304.               (ErrorNr > 0)) DO BEGIN
  305.       Puffer   := '';
  306.       Wort     := '';
  307.       NeuZeile := FALSE;
  308.       IF Zeichen IN [#10,#13] THEN Return;
  309.       IF NOT (Zeichen IN [#10,#13]) THEN
  310.         IF Kommentar = 0 THEN BEGIN
  311.           WHILE Zeichen IN Buchstaben DO BEGIN
  312.             Wort := Wort + Zeichen;
  313.             GetZeichen;
  314.           END;
  315.           IF Wort = '' THEN
  316.             ZeichenAnalyse(Zeichen)
  317.           ELSE BEGIN
  318.             WortAnalyse;
  319.             Puffer := Wort;
  320.           END;
  321.         END ELSE
  322.           Ueberlesen(Zeichen);
  323.       IF Kommentar = 0 THEN
  324.         WHILE NOT ((zeichen IN
  325.            [#39,'{','(',';',':',#10,#13]+Buchstaben) OR
  326.              Eof(QuellDatei)) DO BEGIN
  327.           Puffer := Puffer + Zeichen;
  328.           GetZeichen;
  329.         END
  330.       ELSE
  331.         WHILE NOT ((Zeichen IN
  332.            [#39,'}','*',#10,#13]) OR
  333.              Eof(QuellDatei) ) DO BEGIN
  334.           Puffer := Puffer + Zeichen;
  335.           GetZeichen;
  336.         END;
  337.       WritePuffer;
  338.     END;
  339.   END;
  340.  
  341. BEGIN
  342.   BakName := Copy(QuellName, 1,
  343.              Length(QuellName)-4) + '.' + 'BAK';
  344.   IF MaxZeilenlaenge < 255 THEN
  345.     Durchlaeufe := 3
  346.   ELSE
  347.     Durchlaeufe := 1;
  348.   FOR n := 1 TO Durchlaeufe DO BEGIN
  349.     Assign(QuellDatei, QuellName);
  350.     Reset(QuellDatei);
  351.     IF IoError THEN Exit;
  352.     Assign(ZielDatei, TempFileName);
  353.     Rewrite(ZielDatei);
  354.     IF IoError THEN Exit;
  355.     Assign(BakDatei, BakName);
  356.     CASE n OF
  357.       1 : Strukturierung;
  358.       2 : Ueberlaenge;
  359.       3 : Strukturierung;
  360.     END;
  361.     IF (ErrorNr > 0) THEN Exit;
  362.     Close(ZielDatei);
  363.     IF IoError THEN Exit;
  364.     Close(QuellDatei);
  365.     IF IoError THEN Exit;
  366.     IF n = 1 THEN BEGIN
  367.       Erase(BakDatei);
  368.       IF IOResult = 0 THEN ;
  369.       Rename(QuellDatei, BakName);
  370.       IF IoError THEN Exit;
  371.     END ELSE
  372.       Erase(QuellDatei);
  373.     IF IoError THEN Exit;
  374.     Rename(Zieldatei, QuellName);
  375.     IF IoError THEN Exit;
  376.   END;
  377.   Optimize := ErrorNr;
  378. END;
  379. (* ------------------------------------------------- *)
  380. (*                Ende von PRETTY.INC                *)
  381.  
  382.