home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / murutil / look.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1988-09-26  |  14.4 KB  |  587 lines

  1. PROGRAM LOOK;
  2.  
  3. {$N- Don't use the numeric coprocessor.}
  4.  
  5. {  "LOOK at a file."    Version:  26 September 1988.
  6.  
  7.    Syntax:  LOOK filename.ext [/NX]
  8.  
  9.    This program displays a file,  20 lines at a time.   The  "/NX"  flag
  10.    suppresses tab expansion.  The user may move through the file,  print
  11.    the currently displayed page or quit by  using  the  following  keys:
  12.  
  13.          Up Arrow -- Go up (towards the beginning) one line.
  14.          Dn Arrow -- Go down (towards the end) one line.
  15.          PgUp     -- Go up one page of 20 lines.
  16.          ^PgUp    -- Go up ten pages (200 lines).
  17.          PgDn     -- Go down one page of 20 lines.
  18.          ^PgDn    -- Go down ten pages (200) lines.
  19.          Home     -- Go to the beginning of the file.
  20.          End      -- Go to the end of the file.
  21.          ESC      -- Quit.
  22.          ^C       -- Quit.
  23.  
  24.    Note:  The maximum number of lines that can be stored for display  is
  25.    set by MAXLINE.
  26.  
  27.    Updated for Turbo Pascal Version 4.0 by H.M.M. on 24 November 1987.
  28.  
  29.                                 NOTICE
  30.  
  31.        Copyright 1987, Harry M. Murphy.
  32.  
  33.        A general license is hereby  granted  for  non-commercial
  34.        use,  copying and free exchange of this  program  without
  35.        payment of any royalties,  provided that  this  copyright
  36.        notice is not altered nor deleted.   All other rights are
  37.        reserved.   This program is supplied as-is and the author
  38.        hereby disclaims all warranties,  expressed  or  implied,
  39.        including any and all warranties of  merchantability  and
  40.        any and all warranties of suitability  for  any  purpose.
  41.        Use of this program in  any  way  whatsoever  constitutes
  42.        acceptance of the terms of this license.
  43.  
  44.        Harry M. Murphy, Consultant
  45.        3912 Hilton Avenue, NE
  46.        Albuquerque, NM  87110  }
  47.  
  48. USES
  49.   CRT,
  50.   DOS;
  51.  
  52. CONST
  53.   BUFSIZE = 2048;       { Input buffer size, in bytes.     }
  54.   LENSPEC = 65;         { Maximum input file spec length.  }
  55.   LINELEN = 74;         { Line length.                     }
  56.   MAXLINE = 5000;       { Maximum number of lines to read. }
  57.   SP      = ' ';        { Space code.                      }
  58.  
  59. TYPE
  60.   FILESPEC = STRING[LENSPEC];
  61.   TEXTLINE = STRING[LINELEN];
  62.   LINEP    = ^TEXTLINE;
  63.  
  64. VAR
  65.   DONE       : BOOLEAN;      { Done flag.                    }
  66.   INP        : TEXT;         { Input file.                   }
  67.   INPBUFF    : ARRAY[1..BUFSIZE] OF CHAR; {Input file buffer.}
  68.   INPNAME    : FILESPEC;     { Input file name.              }
  69.   L0         : -1..MAXLINE;  { Previous value of L1.         }
  70.   L1         : 1..MAXLINE;   { Starting line to display.     }
  71.   LPA        : ARRAY [1..MAXLINE] OF LINEP; { Pointer array. }
  72.   NLINE      : 0..MAXLINE;   { Number of lines in file.      }
  73.   NTAB       : INTEGER;      { Tab expansion count.          }
  74.   PRINT      : BOOLEAN;      { Print display page flag.      }
  75.   PRN        : TEXT;         { Printer device file.          }
  76.   PRNOUT     : BOOLEAN;      { Printer has been used flag.   }
  77.   TABX       : BOOLEAN;      { Tab expansion flag.           }
  78.  
  79. { -------------------------------- }
  80.  
  81. PROCEDURE BEEP(FREQ,DUR: INTEGER);
  82.  
  83. {  This procedure outputs a "beep" signal of FREQ Hz and DUR milli-
  84.    seconds. }
  85.  
  86. BEGIN
  87.   SOUND(FREQ);
  88.   DELAY(DUR);
  89.   NOSOUND
  90. END { Procedure BEEP };
  91.  
  92. { -------------------------------- }
  93.  
  94. PROCEDURE CURSOROFF;
  95.  
  96. {  This Turbo Pascal V4.0 procedure turns the cursor display off.
  97.  
  98.    Note:  USES DOS;
  99.  
  100.    Procedure by Harry M. Murphy  --  January 1988.  }
  101.  
  102. VAR
  103.   REGS : REGISTERS;
  104.  
  105. BEGIN
  106.   REGS.AX := $0100;
  107.   REGS.CX := $2000;
  108.   INTR($10,REGS)
  109. END  { Procedure CURSOROFF };
  110.  
  111. { -------------------------------- }
  112.  
  113. PROCEDURE CURSORON;
  114.  
  115. {  This Turbo Pascal v4.0 procedure turns the cursor display on.
  116.  
  117.    Note:  USES DOS;
  118.  
  119.    Procedure by Harry M. Murphy  --  January 1988.  }
  120.  
  121. VAR
  122.   REGS : REGISTERS;
  123.  
  124. BEGIN
  125.   REGS.AX := $0100;
  126.   IF MEM[0:$0449] = 7
  127.     THEN
  128.       REGS.CX := $0C0D
  129.     ELSE
  130.       REGS.CX := $0607;
  131.   INTR($10,REGS)
  132. END  { Procedure CURSORON };
  133.  
  134. { -------------------------------- }
  135.  
  136. FUNCTION MIN0(I,J: INTEGER): INTEGER;
  137.  
  138. { This function returns the minimum of (I,J). }
  139.  
  140. BEGIN
  141.   IF I <= J
  142.     THEN
  143.       MIN0 := I
  144.     ELSE
  145.       MIN0 := J
  146. END { Function MIN0 };
  147.  
  148. { -------------------------------- }
  149.  
  150. PROCEDURE CLOSEWINDOW;
  151.  
  152. {  This procedure restores the normal window and cursor, clears the
  153.    screen and leaves the cursor at line 24.  }
  154.  
  155. BEGIN
  156.   WINDOW(1,1,80,25);
  157.   CURSORON;
  158.   GOTOXY(1,24);
  159.   CLREOL
  160. END  { Procedure CLOSEWINDOW };
  161.  
  162. { -------------------------------- }
  163.  
  164. PROCEDURE GETCOMMAND;
  165.  
  166. {  This procedure accepts and processes keyboard commands.
  167.  
  168.    For a list of valid commands, see the comments at the beginning of
  169.    this program.  }
  170.  
  171. VAR
  172.   CHORD    : 0..255;
  173.   KEYPAD   : BOOLEAN;
  174.   SCANCODE : SET OF BYTE;
  175.   SINGLE   : BOOLEAN;
  176.  
  177. BEGIN
  178.   SCANCODE := [71,72,73,79,80,81,118,132];
  179.   REPEAT
  180.     WHILE NOT KEYPRESSED DO;  { Wait for a key to be pressed. }
  181.     CHORD := ORD(READKEY);
  182.     KEYPAD := KEYPRESSED;
  183.     IF KEYPAD                 { Check for a keypad command.   }
  184.       THEN
  185.         CHORD := ORD(READKEY);
  186.     IF CHORD IN SCANCODE
  187.       THEN
  188.         CASE CHORD OF
  189.           { Home}
  190.           71: L1 := 1;
  191.           { UArr}
  192.           72: IF L1 > 1
  193.                          THEN
  194.                            L1 := PRED(L1)
  195.                          ELSE
  196.                            BEEP(512,50);
  197.           { PgUp}
  198.           73: IF L1 > 20
  199.                          THEN
  200.                            L1 := L1-20
  201.                           ELSE
  202.                             BEGIN
  203.                               BEEP(512,50);
  204.                               L1 := 1
  205.                             END;
  206.           { End }
  207.           79: IF NLINE > 19
  208.                          THEN
  209.                            L1 := NLINE-19
  210.                          ELSE
  211.                            L1 := 1;
  212.           { DArr}
  213.           80: IF L1 < (NLINE-19)
  214.                          THEN
  215.                            L1 := SUCC(L1)
  216.                          ELSE
  217.                            BEEP(512,50);
  218.           { PgDn}
  219.           81: IF L1 < (NLINE-19)
  220.                          THEN
  221.                            L1 := L1+20
  222.                          ELSE
  223.                            BEEP(512,50);
  224.           {^PgDn}
  225.           118: IF L1 < (NLINE-199)
  226.                          THEN
  227.                            L1 := L1+200
  228.                          ELSE
  229.                            IF NLINE > 19
  230.                              THEN
  231.                                L1 := NLINE-19
  232.                              ELSE
  233.                                L1 := 1;
  234.           {^PgUp}
  235.           132: IF L1 > 200
  236.                          THEN
  237.                            L1 := L1-200
  238.                          ELSE
  239.                            L1 := 1
  240.         END { CASE };
  241.     SINGLE := (CHORD IN [3,27,42]) AND (NOT KEYPAD);
  242.     KEYPAD := KEYPAD AND (CHORD IN SCANCODE)
  243.   UNTIL SINGLE OR KEYPAD;
  244.   DONE := CHORD IN [3,27];
  245.   PRINT := (CHORD = 42)
  246. END { Procedure GETCOMMAND };
  247.  
  248. { -------------------------------- }
  249.  
  250. PROCEDURE GETLINE(VAR LINE: TEXTLINE);
  251.  
  252. {  This procedure reads the next line from the input file.  Tab codes
  253.    are expanded to the equivalent number of blanks.
  254.  
  255.    Routine by Harry M. Murphy,  11 October 1987.  }
  256.  
  257. CONST
  258.   TAB = #9;
  259.  
  260. VAR
  261.   CH    : CHAR;
  262.   LL,LN : 0..LINELEN;
  263.  
  264. BEGIN
  265.   IF TABX
  266.     THEN
  267.       BEGIN
  268.         LL := 0;
  269.         WHILE NOT EOLN(INP) AND (LL < LINELEN) DO
  270.           BEGIN
  271.             READ(INP,CH);
  272.             IF CH = TAB
  273.               THEN
  274.                 BEGIN
  275.                   NTAB := SUCC(NTAB);
  276.                   LN := MIN0((LL DIV 8)*8+8,LINELEN);
  277.                   REPEAT
  278.                     LL := SUCC(LL);
  279.                     LINE[LL] := SP
  280.                   UNTIL LL = LN
  281.                 END
  282.               ELSE
  283.                 BEGIN
  284.                   LL := SUCC(LL);
  285.                   LINE[LL] := CH
  286.                 END
  287.           END;
  288.         READLN(INP)
  289.       END
  290.     ELSE
  291.       BEGIN
  292.         READLN(INP,LINE);
  293.         LL := LENGTH(LINE)
  294.       END;
  295.   LINE[0] := CHR(0);
  296.   WHILE LINE[LL] = SP DO LL := PRED(LL);
  297.   LINE[0] := CHR(LL)
  298. END { Procedure GETLINE };
  299.  
  300. { -------------------------------- }
  301.  
  302. PROCEDURE GETPARAMS;
  303.  
  304. {  This Turbo Pascal procedure gets the input file name and [optionally]
  305.    the /NX "suppress tab expansion" option from the command line.
  306.  
  307.    Procedure by Harry M. Murphy,  11 October 1987.  }
  308.  
  309. CONST
  310.   SYNTAX = 'Syntax for LOOK is:  LOOK filename.ext [/NX]';
  311.  
  312. VAR
  313.   OPT : STRING[3];
  314.  
  315. BEGIN { Procedure GETPARAMS }
  316.   IF (PARAMCOUNT = 0)
  317.     THEN
  318.       BEGIN
  319.         WRITELN(SYNTAX);
  320.         HALT
  321.       END;
  322.   INPNAME := PARAMSTR(1);
  323.   ASSIGN(INP,INPNAME);
  324.   SETTEXTBUF(INP,INPBUFF,BUFSIZE);
  325.   {$I-} RESET(INP) {$I+};
  326.   IF IORESULT <> 0
  327.     THEN
  328.       BEGIN
  329.         WRITELN('ERROR!  Can''t open file ',INPNAME,'!');
  330.         HALT
  331.       END;
  332.   IF PARAMCOUNT >= 2
  333.     THEN
  334.       BEGIN
  335.         OPT := PARAMSTR(2);
  336.         TABX := NOT (OPT = '/NX')
  337.       END
  338.     ELSE
  339.       TABX := TRUE
  340. END { Procedure GETPARAMS };
  341.  
  342. { -------------------------------- }
  343.  
  344. PROCEDURE GETTEXT;
  345.  
  346. {  This procedure reads up to MAXLINE lines of text from the input
  347.    file.  }
  348.  
  349. VAR
  350.   LINE : TEXTLINE;
  351.  
  352. BEGIN
  353.   WRITELN('LOOK reading ',INPNAME,' now . . .');
  354.   NLINE := 0;
  355.   NTAB := 0;
  356.   WHILE (NOT EOF(INP)) AND (NLINE < MAXLINE) DO
  357.     BEGIN
  358.       GETLINE(LINE);
  359.       NLINE := SUCC(NLINE);
  360.       NEW(LPA[NLINE]);
  361.       LPA[NLINE]^ := LINE
  362.     END;
  363.   IF NTAB > 0
  364.     THEN
  365.       BEGIN
  366.         WRITELN(NTAB:6,' tab codes expanded.');
  367.         BEEP(512,50);
  368.         DELAY(1000)
  369.       END;
  370.   IF NLINE < MAXLINE
  371.     THEN
  372.       BEGIN
  373.         NLINE := SUCC(NLINE);
  374.         NEW(LPA[NLINE]);
  375.         LPA[NLINE]^ := '<<<<<   E N D   O F   F I L E   >>>>>'
  376.       END
  377.     ELSE
  378.       IF NOT EOF(INP)
  379.         THEN
  380.           BEGIN
  381.             HIGHVIDEO;
  382.             WRITELN('BUFFER FULL!');
  383.             WRITELN('More than ',MAXLINE,' lines in the file.');
  384.             WRITELN('Some text will not be displayed.');
  385.             NORMVIDEO;
  386.             BEEP(440,250);
  387.             DELAY(5000)
  388.           END;
  389.   CLOSE(INP)
  390. END { Procedure GETTEXT };
  391.  
  392. { -------------------------------- }
  393.  
  394. PROCEDURE OPENWINDOW;
  395.  
  396. {  This procedure turns the cursor off and opens the display window.  }
  397.  
  398. CONST
  399.   ASTR = '^C or Esc quits.   ';
  400.   BSTR = ', PgUp, ^PgUp, PgDn, ^PgDn, Home or End scans.  * prints.';
  401.  
  402. VAR
  403.   BAR : STRING[80];
  404.   I   : 0..80;
  405.  
  406. BEGIN
  407.   CLRSCR;
  408.   CURSOROFF;
  409.   GOTOXY((80-LENGTH(INPNAME)) DIV 2,1);
  410.   WRITE(INPNAME);
  411.   GOTOXY(70,1);
  412.   WRITELN(NLINE-1:4,' lines');
  413.   BAR[0] := CHR(80);
  414.   BAR[1] := CHR(218);
  415.   BAR[80] := CHR(191);
  416.   FOR I := 2 TO 79 DO BAR[I] := CHR(196);
  417.   WRITE(BAR);
  418.   FOR I:=3 TO 23 DO
  419.     BEGIN
  420.       GOTOXY(1,I);
  421.       WRITE(CHR(179));
  422.       GOTOXY(80,I);
  423.       WRITE(CHR(179))
  424.     END;
  425.   BAR[1] := CHR(192);
  426.   BAR[80] := CHR(217);
  427.   GOTOXY(1,23);
  428.   WRITE(BAR);
  429.   GOTOXY(1,24);
  430.   BAR := ASTR+CHR(24)+', '+CHR(25)+BSTR;
  431.   TEXTCOLOR(0);
  432.   TEXTBACKGROUND(6);
  433.   WRITE(BAR);
  434.   WINDOW(3,3,79,22);
  435.   TEXTCOLOR(7);
  436.   TEXTBACKGROUND(0)
  437. END { Procedure OPENWINDOW };
  438.  
  439. { -------------------------------- }
  440.  
  441. PROCEDURE PRINTPAGE;
  442.  
  443. {  This procedure prints the currently displayed page. }
  444.  
  445. VAR
  446.   L    : 1..MAXLINE;
  447.   LMAX : INTEGER;
  448.  
  449. BEGIN
  450.   IF PRINT
  451.     THEN
  452.       BEGIN
  453.         IF NOT PRNOUT
  454.           THEN
  455.             BEGIN
  456.               ASSIGN(PRN,'PRN');
  457.               REWRITE(PRN);
  458.               WRITELN(PRN,'File: ',INPNAME);
  459.               PRNOUT := TRUE
  460.             END;
  461.         L := L1;
  462.         LMAX := MIN0(L+20,NLINE);
  463.         WRITELN(PRN,'Lines ',L1,' to ',LMAX,':');
  464.         WRITELN(PRN);
  465.         WHILE L <= LMAX DO
  466.           BEGIN
  467.             WRITELN(PRN,LPA[L]^);
  468.             L := SUCC(L)
  469.           END;
  470.         WRITELN(PRN);
  471.         PRINT := FALSE
  472.       END
  473. END { Procedure PRINTPAGE };
  474.  
  475. { -------------------------------- }
  476.  
  477. PROCEDURE SHOWPAGE;
  478.  
  479. {  This procedure displays the current page. }
  480.  
  481. VAR
  482.   I : 1..20;
  483.   L : INTEGER;
  484.  
  485. BEGIN
  486.   IF L1 < 1 THEN L1 := 1;
  487.   IF L0 <> L1
  488.     THEN
  489.       BEGIN
  490.         IF L0 = PRED(L1)
  491.           THEN
  492.             BEGIN             {Down Arrow}
  493.               GOTOXY(77,20);
  494.               WRITELN;
  495.               GOTOXY(1,20);
  496.               CLREOL;
  497.               L := L1+19;
  498.               IF L <= NLINE THEN WRITE(LPA[L]^)
  499.             END
  500.           ELSE
  501.             IF L0 = SUCC(L1)
  502.               THEN
  503.                 BEGIN         {Up Arrow}
  504.                   GOTOXY(1,1);
  505.                   INSLINE;
  506.                   WRITE(LPA[L1]^)
  507.                 END
  508.               ELSE
  509.                 BEGIN
  510.                   L := L1;
  511.                   FOR I := 1 TO 20 DO
  512.                     BEGIN     {Page Up, Page Down, Home & End}
  513.                       GOTOXY(1,I);
  514.                       CLREOL;
  515.                       IF L <= NLINE THEN WRITE(LPA[L]^);
  516.                       L := SUCC(L)
  517.                     END
  518.                 END;
  519.         WINDOW(1,1,80,25);
  520.         GOTOXY(1,1);
  521.         WRITE('            ');
  522.         GOTOXY(1,1);
  523.         WRITE(SP,L1,SP,CHR(26),SP,MIN0(L1+19,NLINE-1));
  524.         WINDOW(3,3,79,22);
  525.         GOTOXY(77,20);
  526.         L0 := L1
  527.       END
  528. END { Procedure SHOWPAGE };
  529.  
  530. { -------------------------------- }
  531.  
  532. PROCEDURE UPPARMS;
  533.  
  534. {  This procedure scans the parameter string in the program's command
  535.    tail at offset 0080H and converts all characters to upper case.
  536.  
  537.    Procedure by Harry M. Murphy,  22 November 1987.
  538.    Updated to Turbo Pascal V4.0 by H.M.M. on 28 November 1987. }
  539.  
  540. CONST
  541.     CT   = $0080;
  542.  
  543. VAR
  544.     L,LP : 0..127;
  545.     PSPS : WORD;
  546.  
  547. BEGIN
  548.   PSPS := PREFIXSEG;
  549.   LP := MEM[PSPS:CT];
  550.   IF LP > 0
  551.     THEN
  552.       FOR L := 1 TO LP DO
  553.         IF MEM[PSPS:L+CT] IN [97..122]
  554.           THEN
  555.             MEM[PSPS:L+CT] := MEM[PSPS:L+CT] XOR $20
  556. END { Procedure UPPARMS };
  557.  
  558. { -------------------------------- }
  559.  
  560. BEGIN { Program LOOK }
  561.   UPPARMS;
  562.   GETPARAMS;
  563.   GETTEXT;
  564.   CHECKBREAK := FALSE;
  565.   OPENWINDOW;
  566.   L0 := -1;
  567.   L1 := 1;
  568.   PRNOUT := FALSE;
  569.   PRINT := FALSE;
  570.   DONE := FALSE;
  571.   REPEAT
  572.     IF PRINT
  573.       THEN
  574.         PRINTPAGE
  575.       ELSE
  576.         SHOWPAGE;
  577.     GETCOMMAND
  578.   UNTIL DONE;
  579.   IF PRNOUT
  580.     THEN
  581.       BEGIN
  582.         WRITELN(PRN,#12);
  583.         CLOSE(PRN)
  584.       END;
  585.   CLOSEWINDOW
  586. END.
  587.