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

  1.  
  2. -------- SIMTEL20 Ada Software Repository Prologue ------------
  3. --
  4. -- Unit name    :
  5. -- function COUNT_OF_ADA_STATEMENTS (FILE_NAME  : STRING) return INTEGER;
  6. -- Version      : 1.0
  7. -- Author       : W. A. Whitaker, WIS JPMO
  8. -- DDN Address  : WWHITAKER@ECLB
  9. -- Date created :  3 MAR 84
  10. -- Release date : 15 JAN 85
  11. -- Last update  :  3 MAR 84
  12. --
  13. ---------------------------------------------------------------
  14. --
  15. -- Keywords     :  Source analysis, Quantity, Statements
  16. --
  17. ----------------:
  18. --
  19. -- Abstract     :
  20. --  This function calculates the "STATEMENTS" of a valid Ada fragment
  21. --  specified by a FILE_NAME string parameter.
  22. --  It need not be a complete compilation unit
  23. --  but it should have closed all open parentheses and string brackets.
  24. --  The number of STATEMENTS of code is returned as an INTEGER.
  25.  
  26. --  The Ada statement is defined by a semicolon terminator
  27. --  outside of comments, parentheses, or string or character literals.
  28. --  This definition is insensitive to formatting or layout of the source.
  29.  
  30. --  There are exotic cases for which this will misestimate the count
  31. --  but we have never encountered one in real code.
  32.  
  33. --  This copy of the function is embedded in a test and driver program.
  34. --  Running the program on its own source file should give
  35. --  The driver has an additional feature of correcting for the common
  36. --  error of leaving out the extension on a file name.
  37. --  The nature of this extension is system dependent and a ".TXT" is used.
  38.  
  39. --
  40. ------------------ Revision history ---------------------------
  41. --
  42. -- DATE         VERSION         AUTHOR          HISTORY
  43. -- 19850115     1.0             W Whitaker      Initial Release
  44. --
  45. ------------------ Distribution and Copyright -----------------
  46. --
  47. -- This software is released to the Public Domain (note:
  48. --   software released to the Public Domain is not subject
  49. --   to copyright protection).
  50. --
  51. ------------------ Disclaimer ---------------------------------
  52. --
  53. -- This software and its documentation are provided "AS IS" and
  54. -- without any expressed or implied warranties whatsoever.
  55. -- No warranties as to performance, merchantability, or fitness
  56. -- for a particular purpose exist.
  57. --
  58. -- In no event shall any person or organization of people be
  59. -- held responsible for any direct, indirect, consequential
  60. -- or inconsequential damages or lost profits.
  61. --
  62. -------------------END-PROLOGUE--------------------------------
  63.  
  64. with TEXT_IO;  use TEXT_IO;
  65. procedure CAS is
  66. --  function COUNT_OF_ADA_STATEMENTS (FILE_NAME  : STRING) return INTEGER
  67. --  calculates the "STATEMENTS" in an Ada fragment specified by FILE_NAME.
  68.  
  69. --  This copy of the function is embedded in a test and driver program.
  70. --  Running the CAS program on its own source file should give
  71. --
  72. --COUNT_OF_ADA_STATEMENTS:
  73. --Input file name terminated by <RETURN>  => CAS.TXT
  74. --        59 ADA STATEMENTS IN FILE CAS.TXT
  75. --
  76. --  The driver has an additional feature of correcting for the common
  77. --  error of leaving out the extension on a file name.
  78. --  The nature of this extension is system dependent and a ".TXT" is used.
  79.  
  80. ------------------ Revision history ---------------------------
  81. --
  82. -- DATE         VERSION         AUTHOR          HISTORY
  83. -- 19850115     1.0             W Whitaker      Initial Release
  84. --
  85.   package INT_IO is new INTEGER_IO(INTEGER);
  86.   use INT_IO;
  87.  
  88.   FILE_NAME  : STRING (1..80);
  89.   FILE_NAME_LENGTH : NATURAL;
  90.   FIRST_TIME : BOOLEAN := TRUE;
  91.  
  92.   function COUNT_OF_ADA_STATEMENTS (FILE_NAME  : STRING) return INTEGER is
  93.   --  This function calculates the "STATEMENTS" of a valid Ada fragment
  94.   --  specified by a FILE_NAME string parameter
  95.   --  It need not be a complete compilation unit
  96.   --  but it should have closed all open parentheses and string brackets
  97.   --  The number of STATEMENTS of code is returned as an INTEGER
  98.  
  99.   --  The Ada statement is defined by a semicolon terminator
  100.   --  outside of comments, parentheses, or string or character literals
  101.   --  This definition is insensitive to formatting or layout of the source
  102.  
  103.   --  There are exotic cases for which this will misestimate the count
  104.   --  but we have never encountered one in real code
  105.  
  106.     INPUT        : FILE_TYPE;
  107.     C            : CHARACTER := ' ';
  108.     STATEMENTS   : INTEGER := 0;
  109.     LEVEL        : INTEGER := 0;
  110.  
  111.   begin
  112.  
  113.     OPEN (INPUT, IN_FILE, FILE_NAME);
  114.  
  115.     loop
  116.       GET (INPUT, C);
  117.  
  118.       --  Check for comment on the line
  119.       if C = '-' then
  120.         GET (INPUT, C);
  121.         --  Which is signaled by the '-' following a '-'
  122.         if C = '-' then
  123.           --  Then just skip the rest of the line and go to the next
  124.           SKIP_LINE (INPUT);
  125.         end if;
  126.       end if;
  127.  
  128.       --  Check for one of the characters which introduce code constructs
  129.       --  like string or character literal or formal parameter list
  130.       --  within which a ';' does not terminate a "line of code"
  131.       if C = '(' or C = '"' or C = '%' or C = ''' then
  132.  
  133.         --  Check for opening parentheses
  134.         --  Every ';' within is in a formal parameter list
  135.         if C = '(' then
  136.           --  Count the number of levels of parentheses
  137.           LEVEL := LEVEL + 1;
  138.           --  Read ahead until the whole construct is closed, LEVEL = 0
  139.           while LEVEL > 0 loop
  140.             GET (INPUT, C);
  141.             if C = '(' then
  142.               --  Increase the level if another '(' is found
  143.               LEVEL := LEVEL + 1;
  144.             elsif C = ')' then
  145.               --  Decrease the level if a ')' is found
  146.               LEVEL := LEVEL - 1;
  147.             end if;
  148.           end loop;
  149.  
  150.         --  Now check for string brackets of either kind, " or %
  151.         elsif C = '"' or C = '%' then
  152.           --  Treat them in parallel, one must lead off
  153.           if C = '"' then
  154.             loop
  155.               GET (INPUT, C);
  156.               --  Loop until the close comes
  157.               --  If there is a doubled character it just starts again
  158.               exit when C = '"';
  159.             end loop;
  160.           --  The '%' is handled exactly the same way as '"'
  161.           elsif C = '%' then
  162.             loop
  163.               GET (INPUT, C);
  164.               exit when C = '%';
  165.             end loop;
  166.           end if;
  167.  
  168.         --  Character literals are just three characters long including '
  169.         elsif C = ''' then
  170.           GET (INPUT, C);
  171.           GET (INPUT, C);
  172.         end if;
  173.  
  174.       --  Any ';' that can be found at this point after all exclusions
  175.       --  must be a valid "line of code" terminator
  176.       elsif C = ';' then
  177.         STATEMENTS := STATEMENTS + 1;
  178.  
  179.       end if;
  180.  
  181.     end loop;
  182.  
  183.   exception
  184.     --  Return through exception since the end of file may be encountered
  185.     --  at several levels in the function and in any case it stops and returns
  186.     --  Otherwise one would use END_OF_FILE but here it would have to appear
  187.     --  in a number of places to no advantage
  188.     --  and would cause multiple exits or returns
  189.     --  This is much cleaner
  190.     when END_ERROR =>
  191.       return STATEMENTS;
  192.     when NAME_ERROR =>
  193.       NEW_LINE;
  194.       PUT("NAME_ERROR in COUNT_OF_ADA_STATEMENTS "); NEW_LINE;
  195.       raise NAME_ERROR;
  196.   end COUNT_OF_ADA_STATEMENTS;
  197.  
  198.  
  199. begin
  200.   NEW_LINE;
  201.   PUT_LINE("COUNT_OF_ADA_STATEMENTS:");
  202.   PUT("Input file name terminated by <RETURN>  => ");
  203.   GET_LINE(FILE_NAME, FILE_NAME_LENGTH);
  204.   PUT (COUNT_OF_ADA_STATEMENTS (FILE_NAME(1..FILE_NAME_LENGTH)));
  205.   PUT (" ADA STATEMENTS IN FILE ");
  206.   PUT (FILE_NAME(1..FILE_NAME_LENGTH));
  207.   NEW_LINE;
  208.  
  209. exception
  210.   when NAME_ERROR =>
  211.     --  *********************************************  SYSTEM NAME DEPENDENT
  212.     --  This handles the case when you have left off the file name extension
  213.     --  (if that is appropriate for you file system)
  214.     --  It is dependent on the naming convention and is set up for ".TXT"
  215.     if FIRST_TIME
  216.       and (FILE_NAME'LAST <= 4
  217.            or else FILE_NAME(FILE_NAME'LAST-3..FILE_NAME'LAST) /= ".TXT")  then
  218.       FIRST_TIME := FALSE;
  219.       PUT("Maybe you forgot the .TXT?"); NEW_LINE;  --  System dependent
  220.       PUT (COUNT_OF_ADA_STATEMENTS (FILE_NAME(1..FILE_NAME_LENGTH) & ".TXT"));
  221.       PUT (" ADA STATEMENTS IN FILE ");
  222.       PUT (FILE_NAME(1..FILE_NAME_LENGTH) & ".TXT");
  223.       NEW_LINE;
  224.     end if;
  225.   --  **********************************************************************
  226. end CAS;
  227.