home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / misc / cas3.ada < prev    next >
Encoding:
Text File  |  1988-05-03  |  8.1 KB  |  226 lines

  1.  
  2. -------- SIMTEL20 Ada Software Repository Prologue ------------
  3. -- 
  4. -- Unit name    : COUNT_OF_ADA_STATEMENTS_3
  5. -- Version      : 1.2
  6. -- Author       : Richard Conn
  7. --              : TI Ada Technology Branch
  8. --              : Box 801, MS 8007
  9. --              : McKinney, TX  75069
  10. -- DDN Address  : RCONN at SIMTEL20
  11. -- Derivation   : COUNT_OF_ADA_STATEMENTS_2 by Richard Conn
  12. -- Derivation   : COUNT_OF_ADA_STATEMENTS by Bill Whitaker
  13. -- Date created : 4 Apr 85
  14. -- Release date : 4 Apr 85
  15. -- Last update  : 24 June 85
  16. -- 
  17. ---------------------------------------------------------------
  18. -- 
  19. -- Keywords     :  Source analysis, Quantity, Statements
  20. -- 
  21. ----------------:
  22. -- 
  23. -- Abstract     :
  24. --  This procedure calculates the "STATEMENTS" of a valid Ada fragment
  25. --  specified by a FILE_NAME string parameter.  It need not be a complete
  26. --  compilation unit, but it should have closed all open parens and
  27. --  strings.
  28. -- 
  29. --  The Ada statement is defined by a semicolon terminator
  30. --  outside of comments, parentheses, or string or character literals.
  31. --  This definition is insensitive to formatting or layout of the source.
  32. -- 
  33. --  There are exotic cases for which this will misestimate the count
  34. --  but we have never encountered one in real code.
  35. -- 
  36. --  This procedure is derived from Bill Whitaker's original
  37. --  COUNT_OF_ADA_STATEMENTS, and it does not change his original algorithm.
  38. --  It adds a line count and a character-checksum hash (sum of POS values of
  39. --  all non-space characters in the file mod 256).  It also adds a count
  40. --  of the comment lines (over CAS2, which does not).
  41. -- 
  42. ------------------ Revision history ---------------------------
  43. -- 
  44. -- DATE         VERSION         AUTHOR          HISTORY
  45. -- 19850215     1.0             R Conn          Initial Release
  46. -- 19850506     1.1             R Conn          Overflow Traps Added
  47. -- 19850624     1.2             R Conn          Bug in Single-Quote Proc Fixed
  48. -- 
  49. ------------------ Distribution and Copyright -----------------
  50. -- 
  51. -- This software is released to the Public Domain (note:
  52. --   software released to the Public Domain is not subject
  53. --   to copyright protection).
  54. -- 
  55. ------------------ Disclaimer ---------------------------------
  56. -- 
  57. -- This software and its documentation are provided "AS IS" and
  58. -- without any expressed or implied warranties whatsoever.
  59. -- No warranties as to performance, merchantability, or fitness
  60. -- for a particular purpose exist.
  61. -- 
  62. -- In no event shall any person or organization of people be
  63. -- held responsible for any direct, indirect, consequential
  64. -- or inconsequential damages or lost profits.
  65. -- 
  66. -------------------END-PROLOGUE--------------------------------
  67.  
  68. with TEXT_IO,
  69.      CHARACTER_SET;
  70. procedure COUNT_OF_ADA_STATEMENTS (FILE_NAME  : STRING;
  71.                                    STATEMENTS : in out NATURAL;
  72.                                    LINE_COUNT : in out NATURAL;
  73.                                    COMMENTS   : in out NATURAL;
  74.                                    HASH       : in out NATURAL) is
  75. -- 
  76. --  Returned values:
  77. --     STATEMENTS    Number of Ada code statements
  78. --     LINE_COUNT    Number of lines of text
  79. --     COMMENTS      Number of comments in the file
  80. --     HASH          Checksum (Mod 256 sum) of all non-space
  81. --                    (a space character as defined by character_set)
  82. --                    characters
  83. -- 
  84.     INPUT        : TEXT_IO.FILE_TYPE;
  85.     CURRENT_LINE : STRING (1 .. 256); --  arbitrarily large
  86.     NEXT_CHAR    : NATURAL := 1;
  87.     LAST_CHAR    : NATURAL := 0;
  88.     C            : CHARACTER;
  89.     LEVEL        : INTEGER := 0;
  90.     CH_PENDING   : BOOLEAN := FALSE;
  91.     PENDING_CH   : CHARACTER;
  92.  
  93.     procedure UNGET (CH : CHARACTER) is
  94.     begin
  95.         CH_PENDING := TRUE;
  96.         PENDING_CH := CH;
  97.     end UNGET;
  98.  
  99.     procedure GET (CH : in out CHARACTER) is
  100.     begin
  101.         if CH_PENDING then
  102.             CH_PENDING := FALSE;
  103.             CH := PENDING_CH;
  104.         else
  105.             if NEXT_CHAR > LAST_CHAR then
  106.                 loop
  107.                     TEXT_IO.GET_LINE (INPUT, CURRENT_LINE, LAST_CHAR);
  108.                     begin
  109.                         LINE_COUNT := LINE_COUNT + 1;
  110.                     exception
  111.                         when others =>  null; -- trap overflow
  112.                     end;
  113.                     NEXT_CHAR := 1;
  114.                     exit when NEXT_CHAR <= LAST_CHAR;
  115.                 end loop;
  116.             end if;
  117.             CH := CURRENT_LINE (NEXT_CHAR);
  118.             if not CHARACTER_SET.IS_SPACE (CH) then
  119.                 HASH := (HASH + CHARACTER'POS (CH)) mod 256;
  120.             end if;
  121.             NEXT_CHAR := NEXT_CHAR + 1;
  122.         end if;
  123.     end GET;
  124.  
  125. begin
  126.  
  127.     TEXT_IO.OPEN (INPUT, TEXT_IO.IN_FILE, FILE_NAME);
  128.     STATEMENTS := 0;
  129.     LINE_COUNT := 0;
  130.     COMMENTS := 0;
  131.     HASH := 0;
  132.  
  133.     loop
  134.         GET (C);
  135.  
  136.         --  Check for comment on the line
  137.         if C = '-' then
  138.             GET (C);
  139.             --  Which is signaled by the '-' following a '-'
  140.             if C = '-' then
  141.                 --  Then just skip the rest of the line and go to the next
  142.                 NEXT_CHAR := LAST_CHAR + 1;
  143.                 begin
  144.                     COMMENTS := COMMENTS + 1;
  145.                 exception
  146.                     when others =>  null; -- trap overflow
  147.                 end;
  148.             end if;
  149.         end if;
  150.  
  151.         --  Check for one of the characters which introduce code constructs
  152.         --  like string or character literal or formal parameter list
  153.         --  within which a ';' does not terminate a "line of code"
  154.         if C = '(' or C = '"' or C = '%' or C = ''' then
  155.  
  156. --  Check for opening parentheses
  157. --  Every ';' within is in a formal parameter list
  158.             if C = '(' then
  159.                 --  Count the number of levels of parentheses
  160.                 LEVEL := LEVEL + 1;
  161.                 --  Read ahead until the whole construct is closed, LEVEL = 0
  162.                 while LEVEL > 0 loop
  163.                     GET (C);
  164.                     if C = '(' then
  165.                         --  Increase the level if another '(' is found
  166.                         LEVEL := LEVEL + 1;
  167.                     elsif C = ')' then
  168.                         --  Decrease the level if a ')' is found
  169.                         LEVEL := LEVEL - 1;
  170.                     end if;
  171.                 end loop;
  172.  
  173.                 --  Now check for string brackets of either kind, " or %
  174.             elsif C = '"' or C = '%' then
  175. --  Treat them in parallel, one must lead off
  176.                 if C = '"' then
  177.                     loop
  178.                         GET (C);
  179.                         --  Loop until the close comes
  180.                         --  If there is a doubled character it starts again
  181.                         exit when C = '"';
  182.                     end loop;
  183.                     --  The '%' is handled exactly the same way as '"'
  184.                 elsif C = '%' then
  185.                     loop
  186.                         GET (C);
  187.                         exit when C = '%';
  188.                     end loop;
  189.                 end if;
  190.  
  191.                 --  Character literals are just three characters long
  192.                 --  including '
  193.             elsif C = ''' then
  194.                 GET (C);
  195.                 GET (C);
  196.                 if C /= ''' then
  197.                     UNGET (C);
  198.                 end if;
  199.             end if;
  200.  
  201.             --  Any ';' that can be found at this point after all
  202.             --  exclusions must be a valid "line of code" terminator
  203.         elsif C = ';' then
  204.             begin
  205.                 STATEMENTS := STATEMENTS + 1;
  206.             exception
  207.                 when others =>  null; -- trap overflow
  208.             end;
  209.  
  210.         end if;
  211.  
  212.     end loop;
  213.  
  214. exception
  215.     when TEXT_IO.END_ERROR => 
  216.         TEXT_IO.CLOSE (INPUT); --  close input file
  217.     when TEXT_IO.NAME_ERROR => 
  218.         TEXT_IO.NEW_LINE;
  219.         TEXT_IO.PUT ("Error in File Name ");
  220.         TEXT_IO.PUT (FILE_NAME);
  221.         TEXT_IO.NEW_LINE;
  222.         raise TEXT_IO.NAME_ERROR;
  223.     when others => 
  224.         raise;
  225. end COUNT_OF_ADA_STATEMENTS;
  226.