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

  1.  
  2.  
  3. -------- SIMTEL20 Ada Software Repository Prologue ------------
  4. --
  5. -- Unit name    : COUNT_OF_ADA_STATEMENTS_2
  6. -- Version      : 1.0
  7. -- Author       : Richard Conn
  8. --              : TI Ada Technology Branch
  9. --              : Box 801, MS 8007
  10. --              : McKinney, TX  75069
  11. -- DDN Address  : RCONN at SIMTEL20
  12. -- Derivation   : COUNT_OF_ADA_STATEMENTS by Bill Whitaker
  13. -- Date created : 14 Feb 85
  14. -- Release date : 15 Feb 85
  15. -- Last update  : 15 Feb 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).
  40. --
  41. ------------------ Revision history ---------------------------
  42. --
  43. -- DATE         VERSION         AUTHOR          HISTORY
  44. -- 19850215     1.0             R Conn          Initial Release
  45. --
  46. ------------------ Distribution and Copyright -----------------
  47. --
  48. -- This software is released to the Public Domain (note:
  49. --   software released to the Public Domain is not subject
  50. --   to copyright protection).
  51. --
  52. ------------------ Disclaimer ---------------------------------
  53. --
  54. -- This software and its documentation are provided "AS IS" and
  55. -- without any expressed or implied warranties whatsoever.
  56. -- No warranties as to performance, merchantability, or fitness
  57. -- for a particular purpose exist.
  58. --
  59. -- In no event shall any person or organization of people be
  60. -- held responsible for any direct, indirect, consequential
  61. -- or inconsequential damages or lost profits.
  62. --
  63. -------------------END-PROLOGUE--------------------------------
  64.  
  65. with TEXT_IO,
  66.      CHARACTER_SET;
  67. procedure COUNT_OF_ADA_STATEMENTS (FILE_NAME  : STRING;
  68.                                    STATEMENTS : in out NATURAL;
  69.                                    LINE_COUNT : in out NATURAL;
  70.                                    HASH       : in out NATURAL) is
  71. --
  72. --  Returned values:
  73. --     STATEMENTS    Number of Ada code statements
  74. --     LINE_COUNT    Number of lines of text
  75. --     HASH          Checksum (Mod 256 sum) of all non-space
  76. --                    (a space character as defined by character_set)
  77. --                    characters
  78. --
  79.     INPUT        : TEXT_IO.FILE_TYPE;
  80.     CURRENT_LINE : STRING (1 .. 256); --  arbitrarily large
  81.     NEXT_CHAR    : NATURAL := 1;
  82.     LAST_CHAR    : NATURAL := 0;
  83.     C            : CHARACTER;
  84.     LEVEL        : INTEGER := 0;
  85.  
  86.     procedure GET (CH : in out CHARACTER) is
  87.     begin
  88.         if NEXT_CHAR > LAST_CHAR then
  89.             loop
  90.                 TEXT_IO.GET_LINE (INPUT, CURRENT_LINE, LAST_CHAR);
  91.                 LINE_COUNT := LINE_COUNT + 1;
  92.                 NEXT_CHAR := 1;
  93.                 exit when NEXT_CHAR <= LAST_CHAR;
  94.             end loop;
  95.         end if;
  96.         CH := CURRENT_LINE (NEXT_CHAR);
  97.         if not CHARACTER_SET.IS_SPACE (CH) then
  98.             HASH := (HASH + CHARACTER'POS (CH)) mod 256;
  99.         end if;
  100.         NEXT_CHAR := NEXT_CHAR + 1;
  101.     end GET;
  102.  
  103. begin
  104.  
  105.     TEXT_IO.OPEN (INPUT, TEXT_IO.IN_FILE, FILE_NAME);
  106.     STATEMENTS := 0;
  107.     LINE_COUNT := 0;
  108.     HASH := 0;
  109.  
  110.     loop
  111.         GET (C);
  112.  
  113.         --  Check for comment on the line
  114.         if C = '-' then
  115.             GET (C);
  116.             --  Which is signaled by the '-' following a '-'
  117.             if C = '-' then
  118.                 --  Then just skip the rest of the line and go to the next
  119.                 NEXT_CHAR := LAST_CHAR + 1;
  120.             end if;
  121.         end if;
  122.  
  123.         --  Check for one of the characters which introduce code constructs
  124.         --  like string or character literal or formal parameter list
  125.         --  within which a ';' does not terminate a "line of code"
  126.         if C = '(' or C = '"' or C = '%' or C = ''' then
  127.  
  128.             --  Check for opening parentheses
  129.             --  Every ';' within is in a formal parameter list
  130.             if C = '(' then
  131.                 --  Count the number of levels of parentheses
  132.                 LEVEL := LEVEL + 1;
  133.                 --  Read ahead until the whole construct is closed, LEVEL = 0
  134.               while LEVEL > 0 loop
  135.                     GET (C);
  136.                     if C = '(' then
  137.                         --  Increase the level if another '(' is found
  138.                         LEVEL := LEVEL + 1;
  139.                     elsif C = ')' then
  140.                         --  Decrease the level if a ')' is found
  141.                         LEVEL := LEVEL - 1;
  142.                     end if;
  143.                 end loop;
  144.  
  145.                 --  Now check for string brackets of either kind, " or %
  146.             elsif C = '"' or C = '%' then
  147.                 --  Treat them in parallel, one must lead off
  148.                 if C = '"' then
  149.                     loop
  150.                         GET (C);
  151.                         --  Loop until the close comes
  152.                         --  If there is a doubled character it just starts again
  153.                         exit when C = '"';
  154.                     end loop;
  155.                     --  The '%' is handled exactly the same way as '"'
  156.                 elsif C = '%' then
  157.                     loop
  158.                         GET (C);
  159.                         exit when C = '%';
  160.                     end loop;
  161.                 end if;
  162.  
  163.                 --  Character literals are just three characters long including
  164.                 -- '
  165.             elsif C = ''' then
  166.                 GET (C);
  167.                 GET (C);
  168.             end if;
  169.  
  170.             --  Any ';' that can be found at this point after all exclusions
  171.             --  must be a valid "line of code" terminator
  172.         elsif C = ';' then
  173.             STATEMENTS := STATEMENTS + 1;
  174.  
  175.         end if;
  176.  
  177.     end loop;
  178.  
  179. exception
  180.     when TEXT_IO.END_ERROR =>
  181.         TEXT_IO.CLOSE (INPUT); --  close input file
  182.     when TEXT_IO.NAME_ERROR =>
  183.         TEXT_IO.NEW_LINE;
  184.         TEXT_IO.PUT ("Error in File Name ");
  185.         TEXT_IO.PUT (FILE_NAME);
  186.         TEXT_IO.NEW_LINE;
  187.         raise TEXT_IO.NAME_ERROR;
  188.     when others =>
  189.         raise;
  190. end COUNT_OF_ADA_STATEMENTS;