home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / TURBO5.ZIP / PASLIST.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1986-12-26  |  15.9 KB  |  533 lines

  1. PROGRAM PASLIST (INPUT,OUTPUT,LISTFILE,INCFILE);
  2. {  ***************************************************************************
  3.    Read Turbo PASCAL source and list with date and time, 
  4.    index by page no. at end.
  5.    Includes, Procedures, and Functions may be indented but must be the
  6.    first non-blank on the line they occupy.  Includes are automatic but may
  7.    not be nested.     Overlay procedures and functions are also identified.
  8.    Written by Todd Merriman - Future Communications, Atlanta, GA - 1984.
  9.    (c) 1984 - Future Communications, published in the Public Domain for
  10.    non-commercial use.  This source is probably too large to compile without
  11.    breaking down into includes;  all the modules have been assembled into
  12.    one file for distribution.
  13.    ***************************************************************************
  14. }
  15. {--!--!--!--!--!--!--!--!--!--!--!--!--!--!--!--!--!--!--!--!--!--!--!--!--!---
  16. }
  17. CONST
  18.    VER                      = '1.4';
  19.    PAGELEN                  = 66;
  20.    TOPMARG                  = 2;
  21.    BOTMARG                  = 2;
  22.    HEADMARG                 = 2;
  23.    LEFTMARG                 = 0;
  24.    RIGHTMARG                = 0;
  25.    PAPERWIDTH               = 80;
  26.    MAX                      = 255;
  27.    MATCH0                   = 'PROCEDURE';
  28.    MATCH1                   = 'FUNCTION';
  29.    MATCH2                   = 'OVERLAY';
  30.    LINELEN                  = 255;
  31.    OFF                      = 45;
  32.    HEADING                  = 'PASLIST by Future Communications';
  33.  
  34. LABEL
  35.    EXIT;
  36.  
  37. TYPE
  38.    STRING255                = STRING [LINELEN];
  39.    STRING14                 = STRING [14];
  40.    STRING8                  = STRING [8];
  41.  
  42. VAR
  43.    I,J                      : INTEGER;
  44.    LISTFILE,INCFILE         : TEXT;
  45.    LISTNAME,INCNAME,HEADNAME: STRING14;
  46.    PAGENO,POINT             : INTEGER;
  47.    PROCPAGE                 : ARRAY [0..MAX] OF INTEGER;
  48.    PROCNAME                 : ARRAY [0..MAX] OF STRING [35];
  49.    LINENO                   : INTEGER;
  50.    TESTLINE                 : STRING [LINELEN];
  51.    TOP,INCLUDE              : BOOLEAN;
  52.    DRIVE                    : STRING [2];
  53.    FILL                     : STRING [40];
  54.    ABORT                    : BOOLEAN;
  55.    OK                       : BOOLEAN;
  56.  
  57.  
  58. FUNCTION DATE : STRING8;
  59. {  **************************************************************************
  60.    Read date from reserved memory location (CP/M-80)
  61.    **************************************************************************
  62. }
  63. VAR
  64.    TEMP     : ARRAY [0..2] OF BYTE ABSOLUTE $0010;
  65.    I        : BYTE;
  66.    STR      : STRING8;
  67.  
  68. BEGIN { DATE }
  69.  
  70.    STR      := '';
  71.    FOR I := 0 TO 2 DO
  72.    BEGIN
  73.       STR := STR + CHR (((TEMP [I] AND $F0) SHR 4) + $30);
  74.       STR := STR + CHR ((TEMP [I] AND $0F)+ $30);
  75.       IF I < 2 THEN STR := STR + '/';
  76.    END; { FOR }
  77.    DATE := STR;
  78.  
  79. END; { DATE }
  80.  
  81.  
  82. FUNCTION TIME : STRING8;
  83. {  **************************************************************************
  84.    Read time from reserved memory location (CP/M-80)
  85.    **************************************************************************
  86. }
  87. VAR
  88.    TEMP     : ARRAY [0..2] OF BYTE ABSOLUTE $0013;
  89.    I        : BYTE;
  90.    STR      : STRING8;
  91.  
  92. BEGIN { TIME }
  93.  
  94.    STR      := '';
  95.    FOR I := 0 TO 2 DO
  96.    BEGIN
  97.       STR := STR + CHR (((TEMP [I] AND $F0) SHR 4) + $30);
  98.       STR := STR + CHR ((TEMP [I] AND $0F) + $30);
  99.       IF I < 2 THEN STR := STR + ':';
  100.    END; { FOR }
  101.    TIME := STR;
  102.  
  103. END; { TIME }
  104.  
  105.  
  106. PROCEDURE CHECKDATIME (VAR GOOD : BOOLEAN);
  107. {  ***************************************************************************
  108.    See if valid date and time in memory
  109.    ***************************************************************************
  110. }
  111. VAR
  112.    CHECK,CODE    : INTEGER;
  113.  
  114. BEGIN { CHECKDATIME }
  115.    GOOD := TRUE;
  116.    VAL (COPY (DATE, 1, 2), CHECK, CODE);
  117.    IF (CHECK > 12) OR
  118.       (CHECK < 1) OR
  119.       (CODE > 0) THEN
  120.          GOOD := FALSE;
  121.    VAL (COPY (TIME, 1, 2), CHECK, CODE);
  122.    IF (CHECK > 23) OR
  123.       (CODE > 0) THEN
  124.          GOOD := FALSE;
  125. END; { CHECKDATIME }
  126.  
  127.  
  128. PROCEDURE CONVERT (VAR BIG : STRING8; VAR LITTLE : BYTE);
  129. {  ***************************************************************************
  130.    Convert a character string to BCD numbers
  131.    ***************************************************************************
  132. }
  133. BEGIN { CONVERT }
  134.    LITTLE := ((ORD (BIG [1]) - $30) SHL 4) OR (ORD (BIG [2]) - $30);
  135.    DELETE (BIG,1,2);
  136.    IF LENGTH (BIG) > 0 THEN DELETE (BIG,1,1);      { get the separator }
  137. END; { CONVERT }
  138.  
  139.  
  140. PROCEDURE SETDATE;
  141. {  ***************************************************************************
  142.    Prompt for date and set in memory
  143.    ***************************************************************************
  144. }
  145. CONST
  146.    DIGITS   : SET OF CHAR = ['0'..'9'];
  147.  
  148. VAR
  149.    TEMP     : ARRAY [0..2] OF BYTE ABSOLUTE $0010;
  150.    I        : BYTE;
  151.    STR      : STRING8;
  152.  
  153. BEGIN { SETDATE }
  154.    WRITE ('Enter date [MM/DD/YY] ');
  155.    READLN (STR);
  156.    IF LENGTH (STR) > 0 THEN
  157.    BEGIN
  158.       FOR I := 0 TO 2 DO
  159.       BEGIN
  160.          IF (STR [1] IN DIGITS) AND (NOT (STR [2] IN DIGITS)) THEN
  161.             STR := '0' + STR;          { insure leading zeros }
  162.          CONVERT (STR,TEMP [I]);
  163.       END; { FOR }
  164.    END; { IF }
  165. END; { SETDATE }
  166.  
  167.  
  168. PROCEDURE SETIME;
  169. {  ***************************************************************************
  170.    Prompt for time and set in memory
  171.    ***************************************************************************
  172. }
  173. CONST
  174.    DIGITS   : SET OF CHAR = ['0'..'9'];
  175.  
  176. VAR
  177.    TEMP     : ARRAY [0..2] OF BYTE ABSOLUTE $0013;
  178.    I        : BYTE;
  179.    STR      : STRING8;
  180.  
  181. BEGIN { SETIME }
  182.    WRITE ('Enter time [HH:MM] ');
  183.    READLN (STR);
  184.    IF LENGTH (STR) > 0 THEN
  185.    BEGIN
  186.       INSERT (':00',STR,LENGTH (STR)+1);             { add seconds }
  187.       FOR I := 0 TO 2 DO
  188.       BEGIN
  189.          IF (STR [1] IN DIGITS) AND (NOT (STR [2] IN DIGITS)) THEN
  190.             STR := '0' + STR;          { insure leading zeros }
  191.          CONVERT (STR,TEMP [I]);
  192.       END; { FOR }
  193.    END; { IF }
  194. END; { SETIME }
  195.  
  196.  
  197. FUNCTION CMDLINE: STRING14;
  198. {  ***************************************************************************
  199.    Get command from command line
  200.    ***************************************************************************
  201. }
  202. CONST
  203.    BUF     = $80;
  204.  
  205. VAR
  206.    I       : INTEGER;
  207.    ST      : STRING14;
  208.  
  209. BEGIN { CMDLINE }
  210.  
  211.    ST      := '';
  212.    FOR I:= BUF+2 TO BUF + ORD (MEM [BUF]) DO
  213.    BEGIN
  214.       ST [0] := SUCC (ST [0]);
  215.       ST [ORD (ST [0])] := CHR (MEM [I]);
  216.    END;
  217.  
  218.    CMDLINE:=ST;
  219.  
  220. END; { CMDLINE }
  221.  
  222.  
  223. FUNCTION UPSTRING (ST : STRING255) : STRING255;
  224. {  ***************************************************************************
  225.    Convert a line to upper case
  226.    ***************************************************************************
  227. }
  228. VAR
  229.    I    : INTEGER;
  230.    TEMP : STRING255;
  231.  
  232. BEGIN
  233.    TEMP := '';
  234.    IF LENGTH(ST) <> 0
  235.       THEN FOR I:=1 TO LENGTH (ST) DO
  236.          TEMP := TEMP + UPCASE (ST [I]);
  237.    UPSTRING := TEMP;
  238. END; { UPSTRING }
  239.  
  240.  
  241. PROCEDURE FIXNAME (VAR FNAME : STRING14);
  242. {  ***************************************************************************
  243.    Insert extension if none supplied
  244.    ***************************************************************************
  245. }
  246. BEGIN
  247.    FNAME := UPSTRING (FNAME);
  248.    IF POS ('.',FNAME) = 0 THEN
  249.    BEGIN
  250.       INSERT ('.PAS',FNAME,LENGTH(FNAME)+1);
  251.    END; { IF }
  252. END; { FIXNAME }
  253.  
  254.  
  255. PROCEDURE EMPTYLINE;
  256. {  ***************************************************************************
  257.    Print a line with something in it to show margins
  258.    ***************************************************************************
  259. }
  260. VAR
  261.    I                        : INTEGER;
  262.  
  263. BEGIN { EMPTYLINE }
  264.    WRITE (LST,'.');
  265.    FOR I := 1 TO 78 - RIGHTMARG - LEFTMARG DO WRITE (LST,' ');
  266.    WRITELN (LST,'.');
  267. END; { EMPTYLINE }
  268.  
  269.  
  270. PROCEDURE PAGEHEAD;
  271. {  ***************************************************************************
  272.    Print heading for each page of listing
  273.    ***************************************************************************
  274. }
  275. VAR
  276.    I,J                      : BYTE;
  277.  
  278. BEGIN { PAGEHEAD }
  279.  
  280.    WHILE (LINENO >= PAGELEN - BOTMARG) OR (TOP) DO
  281.    BEGIN
  282.       IF NOT TOP THEN WRITE(LST,^L);
  283.       TOP                      := FALSE;
  284.       LINENO                   := 1;
  285.       FOR I := 1 TO TOPMARG DO
  286.       BEGIN
  287.          EMPTYLINE;
  288.          LINENO              := SUCC (LINENO);
  289.       END; { FOR }
  290.       WRITELN (LST,HEADNAME,FILL,TIME,'  ',DATE,FILL,'Page ',PAGENO);
  291.       LINENO                 := SUCC (LINENO);
  292.       FOR I := 1 TO HEADMARG DO
  293.       BEGIN
  294.          IF (INCLUDE) AND (I=1) THEN
  295.          BEGIN
  296.             FOR J := 1 TO 30 DO WRITE (LST,' ');
  297.             WRITELN (LST,'[INCLUDED: ',INCNAME,']');
  298.          END { IF }
  299.          ELSE EMPTYLINE;
  300.          LINENO              := SUCC (LINENO);
  301.       END; { FOR }
  302.  
  303.       IF EOF (LISTFILE) THEN
  304.       BEGIN
  305.          FOR I := 1 TO 35 DO WRITE (LST,' ');
  306.          WRITELN (LST,'I N D E X');
  307.          WRITELN (LST);
  308.          WRITELN (LST);
  309.          LINENO              := LINENO + 3;
  310.       END; { IF EOF }
  311.  
  312.       PAGENO                 := SUCC (PAGENO);
  313.  
  314.    END; { WHILE }
  315.  
  316. END; { PAGEHEAD }
  317.  
  318.  
  319. PROCEDURE TESTREF;
  320. {  ***************************************************************************
  321.    Test for key words at beginning of line
  322.    ***************************************************************************
  323. }
  324. VAR
  325.    K                        : BYTE;            { points to position in line }
  326.    L                        : BYTE;            { points to first non-blank }
  327.    TESTCHAR                 : SET OF CHAR;
  328.  
  329. BEGIN { TESTREF }
  330.  
  331.    IF LENGTH (TESTLINE) > 0 THEN
  332.    BEGIN
  333.       TESTLINE := UPSTRING (TESTLINE);
  334.       L := 0;
  335.       REPEAT
  336.          L := L+1;
  337.       UNTIL TESTLINE [L] > ' ';                { may be indented }
  338.                                                { test for keywords }
  339.       TESTCHAR                 := [' ','0'..'9','A'..'Z'];
  340.  
  341.       IF  (COPY (TESTLINE,L,4) = '{$I ') THEN INCLUDE := TRUE
  342.       ELSE
  343.       IF COPY (TESTLINE,L,LENGTH(MATCH0)) = MATCH0 THEN
  344.       BEGIN
  345.          K                   := LENGTH (MATCH0) + 1;
  346.          PROCNAME [POINT]    := COPY (TESTLINE,L,K);
  347.          REPEAT
  348.             PROCNAME [POINT] := CONCAT (PROCNAME [POINT],
  349.                                 COPY (TESTLINE,K+L,1));
  350.             K                := SUCC (K);
  351.          UNTIL NOT (COPY (TESTLINE,K+L,1) IN TESTCHAR);
  352.          PROCPAGE [POINT]    := PAGENO - 1;
  353.          POINT               := SUCC (POINT);
  354.       END { IF }
  355.       ELSE IF COPY (TESTLINE,L,LENGTH(MATCH1)) = MATCH1 THEN
  356.       BEGIN
  357.          K                   := LENGTH (MATCH1) + 1;
  358.          PROCNAME [POINT]    := COPY (TESTLINE,L,K);
  359.          REPEAT
  360.             PROCNAME [POINT] := CONCAT (PROCNAME [POINT],
  361.                                 COPY (TESTLINE,K+L,1));
  362.             K                := SUCC (K);
  363.          UNTIL NOT (COPY (TESTLINE,K+L,1) IN TESTCHAR);
  364.          PROCPAGE [POINT]    := PAGENO - 1;
  365.          POINT               := SUCC (POINT);
  366.       END { IF }
  367.       ELSE IF COPY (TESTLINE,L,LENGTH(MATCH2)) = MATCH2 THEN
  368.       BEGIN
  369.          K                   := LENGTH (MATCH2) + 1;
  370.          PROCNAME [POINT]    := COPY (TESTLINE,L,K);
  371.          REPEAT
  372.             PROCNAME [POINT] := CONCAT (PROCNAME [POINT],
  373.                                 COPY (TESTLINE,K+L,1));
  374.             K                := SUCC (K);
  375.          UNTIL NOT (COPY (TESTLINE,K+L,1) IN TESTCHAR);
  376.          PROCPAGE [POINT]    := PAGENO - 1;
  377.          POINT               := SUCC (POINT);
  378.      END; { IF }
  379.   END; { IF LENGTH }
  380.  
  381. END; { TESTREF }
  382.  
  383.  
  384. PROCEDURE LISTINC;
  385. {  ***************************************************************************
  386.    List routine for included files
  387.    ***************************************************************************
  388. }
  389. VAR
  390.    K                        : INTEGER;
  391.  
  392. BEGIN { LISTINC }
  393.  
  394.    K                        := 5;
  395.    INCNAME                  := '';
  396.    REPEAT
  397.       INCNAME               := CONCAT (INCNAME,COPY (TESTLINE,K,1));
  398.       K                     := SUCC (K);
  399.    UNTIL (COPY (TESTLINE,K,1) < '.') OR (COPY (TESTLINE,K,1) > 'Z');
  400.    PROCNAME [POINT]         := INCNAME;
  401.    PROCPAGE [POINT]         := 0;
  402.    POINT                    := SUCC (POINT);
  403.    INCNAME                  := CONCAT (DRIVE, INCNAME);
  404.    FIXNAME (INCNAME);
  405.    ASSIGN (INCFILE,INCNAME);
  406.    {$I-}
  407.    RESET (INCFILE);
  408.    {$I+}
  409.    IF IORESULT = 0 THEN
  410.    BEGIN
  411.       WRITELN ('> Reading Include File: ',INCNAME);
  412.       WHILE (NOT (EOF (INCFILE) OR ABORT)) DO      { include file }
  413.       BEGIN
  414.          PAGEHEAD;
  415.          READLN (INCFILE,TESTLINE);
  416.          WRITELN (LST,TESTLINE);
  417.          IF KEYPRESSED THEN ABORT := TRUE;
  418.          LINENO              := SUCC (LINENO);
  419.          TESTREF;
  420.       END; { WHILE }
  421.       CLOSE (INCFILE);
  422.       INCLUDE := FALSE;
  423.       WRITELN ('> Reading Main File:    ',LISTNAME);
  424.       PROCNAME [POINT]         := LISTNAME;
  425.       PROCPAGE [POINT]         := 0;
  426.       POINT                    := SUCC (POINT);
  427.    END { IF IORESULT }
  428.    ELSE
  429.    BEGIN
  430.       ABORT := TRUE;
  431.       WRITELN (#7,'? ',INCNAME,' not found');
  432.    END; { ELSE }
  433.  
  434. END; { LISTINC }
  435.  
  436. {  ***************************************************************************
  437. }
  438.  
  439. BEGIN { PASLIST }
  440.    PAGENO   := 1;
  441.    LINENO   := 1;
  442.    POINT    := 0;
  443.    TOP      := TRUE;
  444.    INCLUDE  := FALSE;
  445.    ABORT    := FALSE;
  446.    LISTNAME := '';
  447.    INCNAME  := '';
  448.    HEADNAME := '';
  449.    WRITELN ('---------- ',HEADING,' -----------');
  450.    WRITELN ('             Ver. ',VER);
  451.    WRITELN ('Turbo PASCAL source listing with index');
  452.  
  453.    LISTNAME := CMDLINE;
  454.    IF LENGTH (LISTNAME) = 0 THEN
  455.    BEGIN
  456.       WRITELN (#7,'Error: No filename specified on command line');
  457.       ABORT := TRUE;
  458.       GOTO EXIT;
  459.    END; { IF }
  460.    FIXNAME (LISTNAME);
  461.    CHECKDATIME (OK);
  462.    IF NOT OK THEN
  463.    BEGIN
  464.      SETDATE;
  465.      SETIME;
  466.    END; { IF }
  467.    ASSIGN (LISTFILE,LISTNAME);
  468.    {$I-}
  469.    RESET (LISTFILE);
  470.    {$I+}
  471.    IF IORESULT <> 0 THEN
  472.    BEGIN
  473.       WRITELN (#7,'Error: ',LISTNAME,' does not exist');
  474.       ABORT := TRUE;
  475.       GOTO EXIT;
  476.    END;
  477.    WRITELN (CON,'Source File:            ',LISTNAME);
  478.  
  479.    IF POS (':',LISTNAME) = 0 THEN
  480.    BEGIN
  481.       HEADNAME       := LISTNAME;
  482.       DRIVE          := '';
  483.    END { IF }
  484.    ELSE
  485.    BEGIN
  486.       HEADNAME       := COPY (LISTNAME,3,LENGTH (LISTNAME)-2);
  487.       DRIVE          := COPY(LISTNAME,1,2);
  488.    END; { ELSE }
  489.    FILL := ' ';
  490.    FOR I := 1 TO (PAPERWIDTH - LEFTMARG - RIGHTMARG - 42 +
  491.       12 - LENGTH (HEADNAME)) DIV 2 DO
  492.       FILL := FILL + '-';              { 42 spaces and chars in heading }
  493.    FILL := FILL + ' ';
  494.    WRITELN ('> Reading Main File:    ',LISTNAME);
  495.  
  496.    WHILE (NOT (EOF (LISTFILE) OR ABORT)) DO     { main file }
  497.    BEGIN
  498.       PAGEHEAD;
  499.       READLN (LISTFILE,TESTLINE);
  500.       WRITELN (LST,TESTLINE);
  501.       IF KEYPRESSED THEN ABORT := TRUE;
  502.       LINENO              := SUCC (LINENO);
  503.       TESTREF;
  504.       IF INCLUDE THEN LISTINC;   END; { WHILE }
  505.  
  506.    IF ABORT THEN WRITELN (LST,'>> List aborted');
  507.    WRITE (LST,#12);
  508.    IF ABORT THEN GOTO EXIT;
  509.  
  510.    WRITELN ('> ',POINT,' Index references found');
  511.    TOP                      := TRUE;
  512.    FOR I := 0 TO POINT - 1 DO                   { index }
  513.    BEGIN
  514.       PAGEHEAD;
  515.       WRITE (LST,'               ');
  516.       IF PROCPAGE [I] > 0 THEN
  517.       BEGIN
  518.          WRITE (LST,PROCNAME [I],' ');
  519.          FOR J := 1 TO OFF - LENGTH (PROCNAME [I]) DO WRITE (LST,'.');
  520.          WRITELN (LST,' page ',PROCPAGE [I]);
  521.       END { IF }
  522.       ELSE WRITELN (LST,'               ',PROCNAME [I]);
  523.       LINENO              := LINENO + 1;
  524.    END; { FOR }
  525.  
  526.    WRITE (LST,#12);
  527.    EXIT:;
  528.    IF ABORT THEN WRITELN (#7,'> List Aborted');
  529.    WRITELN ('> End <');
  530.    CLOSE (LISTFILE);
  531.  
  532. END. { PASLIST }
  533.