home *** CD-ROM | disk | FTP | other *** search
- {-----------------------------------------------------------------------------}
- { Program PasBlk 1.5 900428 }
- { Show nested block structures in different colors }
- { Written By: John W. Fowler, Pres., Global Solutions }
- { Monochrome-display enhancements provided by Ron Schuster }
- {-----------------------------------------------------------------------------}
- Uses DOS, CRT;
-
- Type
- LineRecType = Record { used to store display line }
- Chars: String[80]; { and its color attributes }
- LineNum: Word; { on the heap }
- ChangeCol: Array[1..20] of Byte;
- Colors: Array[0..20] of Byte;
- End;
- LineRecTypePtr = ^LineRecType;
-
- Var
- PasPgm: Text;
- PgmLine,FilNam,TmpLine: String;
- CurrntLen,I,L,C,NLines,Color0,BG0,NColors,NRecs,
- State,L1End,L2Home,L1,L2,NestDepth,BlkDelimType: Integer;
- Dummy,UserChar: Char;
- LineRec: Array[1..2500] of LineRecTypePtr;
- TmpColors: Array[0..20] of Byte;
- TmpChangeCol: Array[1..20] of Byte;
- SeekUntil,NeedPaint: Boolean;
- VideoMode,ScreenWidth,DisplayPage,MaxColors: Byte;
-
- Const
- ColorStack: Array[1..7] of Integer = (15,10,12,9,13,11,14);
- IsNotUnit: Boolean = True;
- InRecord: Boolean = False;
- TruncErr: Boolean = False;
-
- Label SetUpLine,ShowIt,Clear,Quit;
-
- {---------------------------------------------------------------------------}
- Procedure GetTextAttr(Var C: Char; Var Attr: Integer);
- { This procedure calls Interrupt $10, Function 8: Get Character/Attribute }
- Var
- Regis: Registers;
- Begin
- With Regis Do Begin
- AH := 8; BH := 0; {page 0}
- Intr($10,Regis);
- C := Chr(AL); Attr := AH;
- End;
- End; {GetTextAttr}
-
- {---------------------------------------------------------------------------}
- Procedure GetVideoMode(Var VideoMode,ScreenWidth,DisplayPage: Byte);
- { This procedure calls Interrupt $10, Function $0F: get video mode }
- Var
- Regs: Registers;
- Begin
- With Regs Do Begin
- AH := 15; {Get current video mode}
- Intr($10,Regs);
- VideoMode := AL;
- ScreenWidth := AH;
- DisplayPage := BH;
- End; {with Regs}
- End; {GetVideoMode}
-
- {---------------------------------------------------------------------------}
- Procedure PressRETURN;
- Begin
- Write('Press ENTER to continue... '); ReadLn;
- End; {PressRETURN}
-
- {---------------------------------------------------------------------------}
- Procedure TooMuch;
- Begin
- TextColor(12);
- WriteLn('Too many color changes on the same line ',
- '( > 20); line no. = ',NLines);
- WriteLn('Unable to process this file.'); PressRETURN;
- End; {TooMuch}
-
- {---------------------------------------------------------------------------}
- Procedure SetLabelAttrs(OnOff: Integer);
- Begin
- If OnOff = 1 Then Begin
- TextBackground(1); TextColor(15); End
- Else TextBackground(0);
- End; {SetLabelAttrs}
-
- {---------------------------------------------------------------------------}
- Procedure ExpandTabs;
- Var N,L,Col: Integer;
- Begin
- While Pos(#9,PgmLine) > 0 Do Begin
- N := Pos(#9,PgmLine);
- Col := 8*Succ(N div 8);
- PgmLine[N] := ' ';
- For L := 1 to (Col-N) Do Insert(' ',PgmLine,N);
- End; {While}
- End; {ExpandTabs}
-
- {---------------------------------------------------------------------------}
- Function NextRecOK: Boolean;
- Begin
- If NRecs = 2500 Then Begin
- TextColor(12); WriteLn(#7); WriteLn('More than 2500 lines found;');
- WriteLn('only the first 2500 can be displayed by this version.');
- PressRETURN; NextRecOK := False; Exit;
- End;
- If MaxAvail > SizeOf(LineRecType) Then Begin
- Inc(NRecs); New(LineRec[NRecs]);
- NextRecOK := True; End
- Else Begin
- TextColor(12); WriteLn(#7,'Insufficient RAM to display entire file;');
- WriteLn('only the first ',Pred(NLines),' lines can be displayed.');
- PressRETURN; NextRecOK := False;
- End;
- End; {NextRecOK}
-
- {---------------------------------------------------------------------------}
- Function NewColor(DC: Integer): Integer;
- Begin { push (DC > 0) or pop (DC < 0) color stack }
- C := C + DC;
- If C > MaxColors Then C := 1;
- If C < 1 Then C := MaxColors;
- NewColor := ColorStack[C];
- End; {NewColor}
-
- {---------------------------------------------------------------------------}
- Procedure DoScroll(N: Integer);
- { This procedure uses Interupt $10, Function 6 to scroll part of the screen }
- Var
- Regs: Registers;
- Begin
- With Regs Do Begin
- AH := 6; If N < 0 Then AH := 7;
- AL := 0; If N <> 0 Then AL := 1;
- BH := 0;
- CH := 2; CL := 0;
- DH := 23; DL := 79;
- Intr($10,Regs);
- End; {With Regs}
- End; {DoScroll}
-
- {---------------------------------------------------------------------------}
- Procedure ShowL1L2; { show the range of the displayed lines in }
- Var LL1,LL2: Integer; { terms of their original line numbers }
- Begin
- LL1 := LineRec[L1]^.LineNum;
- LL2 := LineRec[L2]^.LineNum;
- SetLabelAttrs(1); GotoXY(41,1);Write(' '); GotoXY(38,1);
- Write(LL1,'-',LL2,' '); SetLabelAttrs(0); GotoXY(1,25);
- TextColor(0); Write(' ',#8); { hide cursor }
- End; {ShowL1L2}
-
- {---------------------------------------------------------------------------}
- Procedure ShowLine(L: Integer); { display a line with its attributes }
- Var
- I,N,C: Integer;
- Begin
- With LineRec[L]^ Do Begin
- N := 1; C := Colors[0] and 15; { get initial line color }
- TextColor(C);
- If Colors[0] > 15
- Then Begin TextBackground(C); TextColor(0); End
- Else TextBackground(0);
- For I := 1 to Length(Chars) Do Begin { run through the line, }
- While I = ChangeCol[N] Do Begin { changing attributes where }
- C := Colors[N] and 15; { the ChangeCol array says to }
- TextColor(C); { and displaying each character }
- If Colors[N] > 15
- Then Begin TextBackground(C); TextColor(0); End
- Else TextBackground(0);
- If N < 20 Then Inc(N);
- End; {I = ChangeCol[N]}
- Write(Chars[I]);
- End; {For I}
- End; {With LineRec}
- End; {ShowLine}
-
- {---------------------------------------------------------------------------}
- Procedure ShowHome; { display the top of the file }
- Var L: Integer;
- Begin
- If L1 = 1 Then Exit; { if already at top, exit }
- DoScroll(0); { clear file-display part of screen }
- For L := 1 to L2Home Do Begin { loop over lines at top of file }
- GotoXY(1,L+2); ShowLine(L); { and display them }
- End; {For L}
- L1 := 1; L2 := L2Home; { record current top & bottom line numbers }
- End; {ShowHome}
-
- {---------------------------------------------------------------------------}
- Procedure ShowCurrent; { display a page of the file }
- Var LL: Integer;
- Begin
- DoScroll(0); { clear file-display part of screen }
- If KeyPressed Then Exit; { don't keep user waiting }
- LL := 3; { start display at line 3 }
- NeedPaint := False; { clear flag; screen will soon be fresh }
- For L := L1 to L2 Do Begin { loop through requested lines }
- GotoXY(1,Ll); ShowLine(L); Inc(LL); { and display them }
- End; {For L}
- End; {ShowCurrent}
-
- {---------------------------------------------------------------------------}
- Function SetReverse(OnOff: Integer): Integer; { set attributes for }
- Var L: Integer; { reverse video on/off }
- Begin
- If NColors = 20 Then Begin
- TooMuch; SetReverse := -1; PressRETURN; Exit;
- End;
- Inc(NColors);
- TmpColors[NColors] := ColorStack[C];
- If OnOff < 1 Then
- If VideoMode = 7 Then
- TmpColors[NColors] := $1F
- Else
- TmpColors[NColors] := ColorStack[C] + 32;
- If I + OnOff < 2 Then Begin
- TmpColors[0] := TmpColors[NColors];
- For L := 1 to NColors Do TmpChangeCol[L] := 0;
- NColors := 0;
- End {If I ...}
- Else TmpChangeCol[NColors] := I + OnOff;
- SetReverse := 1;
- End; {SetReverse}
-
- {---------------------------------------------------------------------------}
- Procedure ChkBeginEnd;
- Var L: Integer;
- Label ChkRecord;
- Begin
- BlkDelimType := 0;
- If TmpLine[I] = 'N' Then Begin { check for BEGIN }
- If I < 5 Then Exit;
- If TmpLine[Pred(I)] <> 'I' Then Exit;
- If TmpLine[I-2] <> 'G' Then Exit;
- If TmpLine[I-3] <> 'E' Then Exit;
- If TmpLine[I-4] <> 'B' Then Exit;
- If I > 5 Then Begin
- L := I - 5;
- If not (TmpLine[L] in [' ',';',':','}'])
- Then If not ((I > 6) and (TmpLine[Pred(L)] = '*')
- and (TmpLine[L] = ')'))
- Then Exit; {not BEGIN}
- End; {If I > 5}
- If CurrntLen > I Then Begin
- L := Succ(I);
- If not (TmpLine[L] in [' ','{'])
- Then If not ((CurrntLen > L) and (TmpLine[L] = '(')
- and (TmpLine[Succ(L)] = '*'))
- Then Exit; {not BEGIN}
- End; {If CurrntLen > I}
- BlkDelimType := 1; {it is a BEGIN}
- End {BEGIN}
- Else Begin { check for END }
- If I < 3 Then Exit;
- If TmpLine[Pred(I)] <> 'N' Then Goto ChkRecord;
- If TmpLine[I-2] <> 'E' Then Exit;
- If I > 3 Then Begin
- L := I - 3;
- If not (TmpLine[L] in [' ',';',':','}'])
- Then If not ((I > 4) and (TmpLine[Pred(L)] = '*')
- and (TmpLine[L] = ')'))
- Then Exit; {not END}
- End; {If I > 3}
- If CurrntLen > I Then Begin
- L := Succ(I);
- If not (TmpLine[L] in [' ',';','{','.'])
- Then If not ((CurrntLen > L) and (TmpLine[L] = '(')
- and (TmpLine[Succ(L)] = '*'))
- Then Exit; {not END}
- End; {If CurrntLen > I}
- BlkDelimType := 2; {it is an END}
- InRecord := False;
- End; {END}
- Exit;
- ChkRecord:
- If I < 6 Then Exit;
- If TmpLine[Pred(I)] <> 'R' Then Exit;
- If TmpLine[I-2] <> 'O' Then Exit;
- If TmpLine[I-3] <> 'C' Then Exit;
- If TmpLine[I-4] <> 'E' Then Exit;
- If TmpLine[I-5] <> 'R' Then Exit;
- If I > 6 Then Begin
- L := I - 6;
- If not (TmpLine[L] in [' ',';',':','}'])
- Then If not ((I > 7) and (TmpLine[Pred(L)] = '*')
- and (TmpLine[L] = ')'))
- Then Exit; {not RECORD}
- End; {If I > 6}
- If CurrntLen > I Then Begin
- L := Succ(I);
- If not (TmpLine[L] in [' ','{'])
- Then If not ((CurrntLen > L) and (TmpLine[L] = '(')
- and (TmpLine[Succ(L)] = '*'))
- Then Exit; {not RECORD}
- End; {If CurrntLen > I}
- BlkDelimType := 3; {it is a RECORD}
- InRecord := True;
- End; {ChkBeginEnd}
-
- {---------------------------------------------------------------------------}
- Procedure ChkRepUntil;
- Var L: Integer;
- Label TryUnit,ChkObject;
- Begin
- BlkDelimType := 0;
- If TmpLine[I] = 'T' Then Begin { check for REPEAT }
- If I < 6 Then Goto TryUnit;
- If TmpLine[Pred(I)] <> 'A' Then Goto TryUnit;
- If TmpLine[I-2] <> 'E' Then Exit;
- If TmpLine[I-3] <> 'P' Then Exit;
- If TmpLine[I-4] <> 'E' Then Exit;
- If TmpLine[I-5] <> 'R' Then Exit;
- If I > 6 Then Begin
- L := I - 6;
- If not (TmpLine[L] in [' ',';',':','}'])
- Then If not ((I > 7) and (TmpLine[Pred(L)] = '*')
- and (TmpLine[L] = ')'))
- Then Exit; {Not REPEAT}
- End; {If I > 6}
- If CurrntLen > I Then Begin
- L := Succ(I);
- If not (TmpLine[L] in [' ','{'])
- Then If not ((CurrntLen > L) and (TmpLine[L] = '(')
- and (TmpLine[Succ(L)] = '*'))
- Then Exit; {not REPEAT}
- End; {If CurrntLen > I}
- BlkDelimType := 1; {it is a REPEAT}
- End {REPEAT}
- Else Begin { check for UNTIL }
- If I < 5 Then Exit;
- If TmpLine[Pred(I)] <> 'I' Then Exit;
- If TmpLine[I-2] <> 'T' Then Exit;
- If TmpLine[I-3] <> 'N' Then Exit;
- If TmpLine[I-4] <> 'U' Then Exit;
- If I > 5 Then Begin
- L := I - 5;
- If not (TmpLine[L] in [' ',';',':','}'])
- Then If not ((I > 6) and (TmpLine[Pred(L)] = '*')
- and (TmpLine[L] = ')'))
- Then Exit; {not UNTIL}
- End; {If I > 5}
- If CurrntLen > I Then Begin
- L := Succ(I);
- If not (TmpLine[L] in [' ',';','{'])
- Then If not ((CurrntLen > L) and (TmpLine[L] = '(')
- and (TmpLine[Succ(L)] = '*'))
- Then Exit; {not UNTIL}
- End; {If CurrntLen > I}
- BlkDelimType := 2; {it is an UNTIL}
- End; {UNTIL}
- Exit;
-
- TryUnit: { check for UNIT }
- If I < 4 Then Goto ChkObject;
- If TmpLine[Pred(I)] <> 'I' Then Goto ChkObject;
- If TmpLine[I-2] <> 'N' Then Exit;
- If TmpLine[I-3] <> 'U' Then Exit;
- If I > 4 Then Begin
- L := I - 4;
- If not (TmpLine[L] in [' ',';',':','}'])
- Then If not ((I > 5) and (TmpLine[Pred(L)] = '*')
- and (TmpLine[L] = ')'))
- Then Exit; {Not UNIT}
- End; {If I > 4}
- If CurrntLen > I Then Begin
- L := Succ(I);
- If not (TmpLine[L] in [' ','{'])
- Then If not ((CurrntLen > L) and (TmpLine[L] = '(')
- and (TmpLine[Succ(L)] = '*'))
- Then Exit; {not UNIT}
- End; {If CurrntLen > I}
- BlkDelimType := 3; {it is a UNIT}
- IsNotUnit := False;
- Exit;
- ChkObject:
- If I < 6 Then Exit;
- If TmpLine[Pred(I)] <> 'C' Then Exit;
- If TmpLine[I-2] <> 'E' Then Exit;
- If TmpLine[I-3] <> 'J' Then Exit;
- If TmpLine[I-4] <> 'B' Then Exit;
- If TmpLine[I-5] <> 'O' Then Exit;
- If I > 6 Then Begin
- L := I - 6;
- If not (TmpLine[L] in [' ',';',':','}'])
- Then If not ((I > 7) and (TmpLine[Pred(L)] = '*')
- and (TmpLine[L] = ')'))
- Then Exit; {not OBJECT}
- End; {If I > 6}
- If CurrntLen > I Then Begin
- L := Succ(I);
- If not (TmpLine[L] in [' ','(','{'])
- Then Exit; {not OBJECT}
- End; {If CurrntLen > I}
- BlkDelimType := 4; {it is an OBJECT}
- End; {ChkRepUntil}
-
- {---------------------------------------------------------------------------}
- Function NoSplit(C: Char): Boolean; { return True if C is a letter }
- Begin
- NoSplit := (C in ['A'..'Z']) or (C in ['a'..'z']);
- End; {NoSplit}
-
- {---------------------------------------------------------------------------}
- Procedure ChkCase;
- Var L: Integer;
- Begin
- BlkDelimType := 0; { check for CASE }
- If InRecord Then Exit;
- If I < 4 Then Exit;
- If TmpLine[Pred(I)] <> 'S' Then Exit;
- If TmpLine[I-2] <> 'A' Then Exit;
- If TmpLine[I-3] <> 'C' Then Exit;
- If I > 4 Then Begin
- L := I - 4;
- If not (TmpLine[L] in [' ',';',':','}'])
- Then If not ((I > 5) and (TmpLine[Pred(L)] = '*')
- and (TmpLine[L] = ')'))
- Then Exit; {not CASE}
- End; {If I > 4}
- If CurrntLen > I Then Begin
- L := Succ(I);
- If not (TmpLine[L] in [' ','{'])
- Then If not ((CurrntLen > L) and (TmpLine[L] = '(')
- and (TmpLine[Succ(L)] = '*'))
- Then Exit; {not CASE}
- End; {If CurrntLen > I}
- BlkDelimType := 1; {it is a CASE}
- End; {ChkCase}
-
- {---------------------------------------------------------------------------}
-
- Begin
- GetVideoMode(VideoMode,ScreenWidth,DisplayPage); { check for color display }
- GetTextAttr(Dummy,Color0);
- BG0 := Color0 ShR 4; Color0 := Color0 and $F;
- TextBackground(0);
- If VideoMode = 7 Then Begin
- MaxColors := 4;
- TextColor(15);
- End
- Else Begin
- MaxColors := 7;
- TextColor(9);
- End;
- ClrScr; WriteLn;
- WriteLn('--------------------------------------------------',
- '---------------------------');
- WriteLn(' PasBlk 1.5 Pascal ',
- 'Block Nesting Display');
- WriteLn(' Copyright (C) 1990 Global Solutions ',
- 'All Rights Reserved');
- WriteLn(' This Utility May Be Distributed Free of Charge ',
- 'Not to be Sold');
- WriteLn('-----------------------------------------------------------',
- '------------------');
- WriteLn;
- { if no command-line input, give tutorial }
- If (ParamCount = 0) Then Begin
- WriteLn('Usage: PASBLK file'); WriteLn;
- WriteLn('where: file = name of the Pascal program file to be displayed');
- WriteLn(' (if no extension, ".PAS" will be assumed;',
- ' to indicate that');
- WriteLn(' there is no extension, place a period at the end)');
- WriteLn;
- WriteLn(' The file will be displayed with each block structure shown');
- Write ('in a different ');
- If VideoMode = 7 Then
- Write('attribute (the attribute')
- Else
- Write('color (the color');
- WriteLn(' sequence wraps around if block ');
- WriteLn('nesting goes deeper than ',MaxColors,
- '); comments are in reverse video.');
- WriteLn;
- WriteLn(' The cursor control keys may be used to control scrolling');
- WriteLn('while the file is being displayed on the monitor. The Esc key');
- WriteLn('may be used to halt execution.');
- WriteLn;
- WriteLn('Limitations: 2500 displayed lines (wrapped lines count as ',
- 'multiple lines);');
- WriteLn(' Displayed lines must fit in RAM;');
- Write (' 20 or fewer ');
- If VideoMode = 7 Then
- Write('attribute')
- Else
- Write('color');
- WriteLn(' changes per displayed line.');
- WriteLn; PressRETURN; Goto Quit;
- End;
-
- If VideoMode = 7 Then Begin
- ColorStack[1] := 7;
- ColorStack[2] := 1;
- ColorStack[3] := 15;
- ColorStack[4] := 9;
- End; {If VideoMode = 7}
- { get file name for Pascal program }
- FilNam := ParamStr(1); { first parameter should be file name }
- If Pos('.',FilNam) = 0 Then FilNam := FilNam + '.Pas';
- Assign (PasPgm, FilNam);
- {$I-} Reset(PasPgm) {$I+};
- { if error on open, give diagnostic }
- If (IOResult > 0) Then Begin
- WriteLn(#7,'Unable to open file: ',FilNam); PressRETURN;
- Goto Quit;
- End;
- { initialize; clip file name if necessary }
- C := 1; NLines := 0; NRecs := 0;
- State := 0; NestDepth := 0; SeekUntil := False;
- While Pos('\',FilNam) > 0 Do Delete(FilNam,1,Pos('\',FilNam));
- WriteLn('File: ',FilNam);
- Write('Reading line ');
- { read file and prepare heap records }
- While Not EOF(PasPgm) Do Begin
- ReadLn(PasPgm, PgmLine); Inc(NLines);
- GotoXY(14,9); Write(NLines);
- ExpandTabs;
- SetUpLine:
- If Length(PgmLine) > 80
- Then If (PgmLine[80] <> ' ') and (PgmLine[81] <> ' ')
- Then If NoSplit(PgmLine[80])
- Then Begin
- I := 80;
- While NoSplit(PgmLine[I]) and (I > 40) Do Dec(I);
- If (I > 40) Then Begin
- Inc(I);
- For L := I to 80 Do Insert(' ',PgmLine,I);
- If (Length(PgmLine) + 80 - I) > 255 Then TruncErr := True;
- End
- Else TruncErr := True;
- End;
- If Length(PgmLine) > 160
- Then If (PgmLine[160] <> ' ') and (PgmLine[161] <> ' ')
- Then If NoSplit(PgmLine[160])
- Then Begin
- I := 160;
- While NoSplit(PgmLine[I]) and (I > 120) Do Dec(I);
- If (I > 120) Then Begin
- Inc(I);
- For L := I to 160 Do Insert(' ',PgmLine,I);
- If (Length(PgmLine) + 160 - I) > 255 Then TruncErr := True;
- End
- Else TruncErr := True;
- End;
- CurrntLen := Length(PgmLine); NColors := 0; TmpLine := PgmLine;
- For I := 1 to CurrntLen Do TmpLine[I] := UpCase(TmpLine[I]);
- For I := 1 to 20 Do TmpChangeCol[I] := 0;
- For I := 1 to CurrntLen Do Begin
- If I = 1 Then Begin
- TmpColors[0] := ColorStack[C];
- If State > 2 Then TmpColors[0] := ColorStack[C] + 32;
- End; {If I = 1}
- Case State of
- 0: Begin { not currently in quotes or comment }
- Case TmpLine[I] of
- 'N','D': Begin
- ChkBeginEnd; {sets BlkDelimType}
- If BlkDelimType > 0 Then Begin
- If NColors = 20 Then Begin TooMuch; Goto Quit; End;
- Inc(NColors);
- If BlkDelimType = 1 Then Begin
- TmpColors[NColors] := NewColor(1);
- Inc(NestDepth);
- If I = 5 Then Begin
- TmpColors[0] := TmpColors[NColors];
- For L := 1 to NColors Do TmpChangeCol[L] := 0;
- NColors := 0;
- End {If I = 5}
- Else TmpChangeCol[NColors] := I - 4;
- End {If BlkDelimType = 1}
- Else If BlkDelimType = 2 Then Begin
- TmpColors[NColors] := NewColor(-1);
- Dec(NestDepth);
- If CurrntLen > Succ(I)
- Then TmpChangeCol[NColors] := I + 2
- Else Begin
- TmpChangeCol[NColors] := 0; Dec(NColors);
- End; {Else}
- End; {Else [BlkDelimType = 2]}
- If BlkDelimType = 3 Then Begin
- TmpColors[NColors] := NewColor(1);
- Inc(NestDepth);
- If I = 6 Then Begin
- TmpColors[0] := TmpColors[NColors];
- For L := 1 to NColors Do TmpChangeCol[L] := 0;
- NColors := 0;
- End {If I = 6}
- Else TmpChangeCol[NColors] := I - 5;
- End {If BlkDelimType = 3}
- End; {If BlkDelimType > 0}
- End; { Begin..End block }
- 'T','L': Begin
- ChkRepUntil; {sets BlkDelimType}
- If BlkDelimType > 0 Then Begin
- If NColors = 20 Then Begin TooMuch; Goto Quit; End;
- Inc(NColors);
- If BlkDelimType = 1 Then Begin
- TmpColors[NColors] := NewColor(1);
- Inc(NestDepth);
- If I = 6 Then Begin
- TmpColors[0] := TmpColors[NColors];
- For L := 1 to NColors Do TmpChangeCol[L] := 0;
- NColors := 0;
- End {If I = 6}
- Else TmpChangeCol[NColors] := I - 5;
- End {If BlkDelimType = 1}
- Else If BlkDelimType = 2 Then SeekUntil := True;
- If BlkDelimType = 3 Then Begin { UNIT }
- TmpColors[NColors] := NewColor(1);
- Inc(NestDepth);
- If I = 4 Then Begin
- TmpColors[0] := TmpColors[NColors];
- For L := 1 to NColors Do TmpChangeCol[L] := 0;
- NColors := 0;
- End {If I = 4}
- Else TmpChangeCol[NColors] := I - 3;
- End; {If BlkDelimType = 3}
- If BlkDelimType = 4 Then Begin { OBJECT }
- TmpColors[NColors] := NewColor(1);
- Inc(NestDepth);
- If I = 6 Then Begin
- TmpColors[0] := TmpColors[NColors];
- For L := 1 to NColors Do TmpChangeCol[L] := 0;
- NColors := 0;
- End {If I = 6}
- Else TmpChangeCol[NColors] := I - 5;
- End {If BlkDelimType = 4}
- End; {If BlkDelimType > 0}
- End; { Repeat..Until block }
- 'E': Begin
- ChkCase; {sets BlkDelimType}
- If BlkDelimType > 0 Then Begin
- If NColors = 20 Then Begin TooMuch; Goto Quit; End;
- Inc(NColors);
- If BlkDelimType = 1 Then Begin
- TmpColors[NColors] := NewColor(1);
- Inc(NestDepth);
- If I = 4 Then Begin
- TmpColors[0] := TmpColors[NColors];
- For L := 1 to NColors Do TmpChangeCol[L] := 0;
- NColors := 0;
- End {If I = 6}
- Else TmpChangeCol[NColors] := I - 3;
- End {If BlkDelimType = 1}
- End; {If BlkDelimType > 0}
- End; { Case.. block beginning }
- ';': If SeekUntil Then Begin
- SeekUntil := False;
- TmpColors[NColors] := NewColor(-1);
- Dec(NestDepth);
- If CurrntLen > I Then TmpChangeCol[NColors] := Succ(I);
- End;
- #39: State := 1; { state 1 is in '....' }
- (* '"': State := 2; *) { state 2 is in "...." }
- '*': If I > 1 { state 3 is in (*....*) }
- Then If PgmLine[Pred(I)] = '('
- Then Begin
- State := 3; If SetReverse(-1) < 0 Then Goto Quit;
- End; {entered state 3}
- '{': Begin (* state 4 is in {....} *)
- State := 4; If SetReverse(0) < 0 Then Goto Quit;
- End; {entered state 4}
- End; {Case PgmLine[I]}
- End; {0}
- 1: If PgmLine[I] = #39 Then State := 0; { currently in '....' }
- (* 2: If PgmLine[I] = '"' Then State := 0; *) { currently in "...." }
- 3: If PgmLine[I] = ')' { currently in (*....*) }
- Then If I > 1
- Then If PgmLine[Pred(I)] = '*'
- Then Begin
- State := 0; If SetReverse(1) < 0 Then Goto Quit;
- End; {3}
- 4: If PgmLine[I] = '}' Then Begin (* currently in {....} *)
- State := 0; If SetReverse(1) < 0 Then Goto Quit;
- End; {4}
- End; {Case State}
- { process wraparound }
- If I = 80 Then Begin
- If not NextRecOK Then Goto ShowIt; { increments NRecs & allocates }
- With LineRec[NRecs]^ Do Begin { next heap record }
- For L := 0 to NColors Do Colors[L] := TmpColors[L];
- For L := 1 to 20 Do ChangeCol[L] := TmpChangeCol[L];
- LineNum := NLines;
- Chars := Copy(PgmLine,1,80); Delete(PgmLine,1,80);
- End; {With LineRec}
- If Length(PgmLine) > 0 Then Goto SetUpLine;
- End; {If I = 80}
- End; {For I}
- { put line on heap if not just done as part of wraparound }
- If CurrntLen <> 80 Then Begin
- If not NextRecOK Then Goto ShowIt; { increments NRecs & allocates }
- With LineRec[NRecs]^ Do Begin { next heap record }
- For L := 0 to NColors Do Colors[L] := TmpColors[L];
- For L := 1 to 20 Do ChangeCol[L] := TmpChangeCol[L];
- LineNum := NLines;
- Chars := Copy(PgmLine,1,80); Delete(PgmLine,1,80);
- End; {With LineRec}
- End; {If CurrntLen}
- If KeyPressed Then Begin
- While KeyPressed Do Dummy := ReadKey;
- GotoXY(1,10); Write('Abort (y/n) ? ');
- Repeat Dummy := UpCase(ReadKey) Until Dummy in ['N','Y'];
- If Dummy = 'Y' Then Goto Quit;
- GotoXY(1,10); ClrEoL;
- End; {If KeyPressed}
- End; {While Not EOF(PasPgm)}
- Close(PasPgm); If SeekUntil Then If NestDepth >= 0 Then Inc(NestDepth)
- Else Dec(NestDepth);
- If NestDepth <> 0 Then If (IsNotUnit or (NestDepth <> 1)) Then Begin
- WriteLn; I := NestDepth;
- If not IsNotUnit Then Dec(I);
- If Abs(I) = 1 Then Write('A') Else Write(Abs(I));
- Write(' block nesting error');
- If Abs(I) = 1 Then Write(' was') Else Write('s were');
- WriteLn(' found.',#7); PressRETURN;
- End; {If NestDepth}
-
- If TruncErr Then Begin
- WriteLn(#7);
- WriteLn('Line truncation occurred; block nesting errors may result.');
- If (not IsNotUnit and (NestDepth = 1)) or (IsNotUnit and (NestDepth = 0))
- Then WriteLn('Nesting levels completed normally, however.');
- WriteLn(
- 'Check lines that were broken in the middle of a word for display wraparound');
- WriteLn(
- 'and lines that may have been extended beyond 255 columns in order to insert');
- WriteLn(
- 'blanks (to avoid wrapping in the middle of a word); block-delimiting keywords');
- WriteLn(
- 'can be missed by the program in such cases.');
- PressRETURN;
- End; {If TruncErr}
-
- ShowIt:
- GotoXY(1,1); ClrScr; SetLabelAttrs(1);
- Write(' File: Lines ',
- ' Total Lines: ');
- GotoXY(8,1); Write(FilNam); GotoXY(74,1); Write(NLines);
- GotoXY(1,2); Write(' Active Keys: '#24,' ',#25,
- ' PgUp PgDn Home End Esc to Exit ');
- SetLabelAttrs(0);
- L1End := NRecs - 21; If L1End < 1 Then L1End := 1;
- L2Home := 22; If NRecs < 22 Then L2Home := NRecs;
- L1 := -9; ShowHome; NeedPaint := False;
-
- Repeat
- If NeedPaint Then ShowCurrent;
- ShowL1L2;
- UserChar := ReadKey; If UserChar = #27 Then Goto Clear;
- If (UserChar = #0) and KeyPressed Then Begin
- UserChar := ReadKey;
- Case UserChar of
- #71: ShowHome; { Home }
- #72: If L1 > 1 Then Begin { Up }
- DoScroll(-1); Dec(L1); Dec(L2);
- GotoXY(1,3); ShowLine(L1);
- End; {72}
- #73: If L1 > 1 Then Begin { PgUp }
- I := L1 - 18; If I < 1 Then I := 1;
- For L := 1 to L1-I Do Begin
- Dec(L1);
- If not KeyPressed Then Begin
- DoScroll(-1); GotoXY(1,3); ShowLine(L1);
- End
- Else NeedPaint := True;
- End; {For L}
- L2 := L1 + 21;
- If L2 > NRecs Then L2 := NRecs;
- End; {73}
- #79: If L1 < L1End Then Begin { End }
- DoScroll(0); I := 2;
- For L := L1End to NRecs Do Begin
- Inc(I); GotoXY(1,I); ShowLine(L);
- End; {For L}
- L1 := L1End; L2 := NRecs;
- End; {79}
- #80: If L1 < L1End Then Begin { Down }
- DoScroll(1); Inc(L1); Inc(L2);
- GotoXY(1,24); ShowLine(L2);
- End; {80}
- #81: If L1 < L1End Then Begin { PgDn }
- I := L1 + 18; If I > L1End Then I := L1End;
- For L := 1 to I-L1 Do Begin
- Inc(L2);
- If not KeyPressed Then Begin
- DoScroll(1); GotoXY(1,24); ShowLine(L2);
- End
- Else NeedPaint := True;
- End; {For L}
- L1 := I;
- End; {81}
- End; {Case UserChar}
- End; {If UserChar = 0...}
- Until UserChar = #27;
-
- Clear:
- ClrScr; For I := 1 to 25 Do WriteLn;
-
- Quit:
- TextColor(Color0); TextBackground(BG0); ClrScr;
- End.