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

  1.  
  2.  
  3. --::::::::::
  4. --fget.pro
  5. --::::::::::
  6.  
  7. -------- SIMTEL20 Ada Software Repository Prologue ------------
  8. --                                                           -*
  9. -- Unit name    : FGET
  10. -- Version      : 1.0
  11. -- Author       : Richard Conn
  12. --              : TI Ada Technology Branch
  13. --              : PO Box 801, MS 8007
  14. --              : McKinney, TX  75069
  15. -- DDN Address  : RCONN at SIMTEL20
  16. -- Copyright    : N/A
  17. -- Date created : 15 Apr 85
  18. -- Release date : 15 Apr 85
  19. -- Last update  : 15 Apr 85
  20. -- Machine/System Compiled/Run on : DG MV 10000, ROLM ADE
  21. --                                  DEC VAX 11/785, DEC Ada
  22. --                                                           -*
  23. ---------------------------------------------------------------
  24. --                                                           -*
  25. -- Keywords     : character I/O, GETC, UNGETC, GETCH, GET_CHAR
  26. ----------------:
  27. --
  28. -- Abstract     :
  29. --       Package FGET manipulates an object which is a text file. Its
  30. -- main purpose is to return characters from this file, allowing one-character
  31. -- look-ahead.  A character which has been obtained from the file via GETC can
  32. -- be returned to the file by an UNGETC, in which case the next GETC will return
  33. -- the same character again.  Additionally, GETC returns ASCII.CR if the end of
  34. -- a text line is reached and ASCII.ETX if the end of the file is reached.
  35. --                                                           -*
  36. ------------------ Revision history ---------------------------
  37. --                                                           -*
  38. -- DATE         VERSION AUTHOR                  HISTORY
  39. -- 4/15/85      1.0     Richard Conn            Initial Release
  40. --                                                           -*
  41. ------------------ Distribution and Copyright -----------------
  42. --                                                           -*
  43. -- This prologue must be included in all copies of this software.
  44. --
  45. -- This software is released to the Public Domain (note:
  46. --   software released to the Public Domain is not subject
  47. --   to copyright protection).
  48. -- Restrictions on use or distribution:  NONE
  49. --                                                           -*
  50. ------------------ Disclaimer ---------------------------------
  51. --                                                           -*
  52. -- This software and its documentation are provided "AS IS" and
  53. -- without any expressed or implied warranties whatsoever.
  54. -- No warranties as to performance, merchantability, or fitness
  55. -- for a particular purpose exist.
  56. --
  57. -- Because of the diversity of conditions and hardware under
  58. -- which this software may be used, no warranty of fitness for
  59. -- a particular purpose is offered.  The user is advised to
  60. -- test the software thoroughly before relying on it.  The user
  61. -- must assume the entire risk and liability of using this
  62. -- software.
  63. --
  64. -- In no event shall any person or organization of people be
  65. -- held responsible for any direct, indirect, consequential
  66. -- or inconsequential damages or lost profits.
  67. --                                                           -*
  68. -------------------END-PROLOGUE--------------------------------
  69. --::::::::::
  70. --fget.ada
  71. --::::::::::
  72. with TEXT_IO;
  73. package FGET is
  74. --------------------------------------------------------------------------
  75. -- Abstract: Package FGET manipulates an object which is a text file. Its
  76. -- main purpose is to return characters from this file, allowing one-character
  77. -- look-ahead.  A character which has been obtained from the file via GETC can
  78. -- be returned to the file by an UNGETC, in which case the next GETC will return
  79. -- the same character again.  Additionally, GETC returns ASCII.CR if the end of
  80. -- a text line is reached and ASCII.ETX if the end of the file is reached.
  81. --------------------------------------------------------------------------
  82.  
  83.     type FILE_ID is limited private;
  84.  
  85.     OPEN_ERROR : exception;
  86. --------------------------------------------------------------------------
  87. -- OPEN_ERROR is raised if a file cannot be opened by the OPEN procedure or
  88. -- if GETC or UNGETC are invoked on an unopened file.
  89. --------------------------------------------------------------------------
  90.  
  91.     procedure OPEN (ID : in out FILE_ID; FILE_NAME : STRING);
  92. --------------------------------------------------------------------------
  93. -- Open the file for input via GETC.
  94. --------------------------------------------------------------------------
  95.  
  96.     procedure GETC   (ID : in out FILE_ID; CH : out CHARACTER);
  97.     procedure UNGETC (ID : in out FILE_ID; CH : CHARACTER);
  98. --------------------------------------------------------------------------
  99. -- GETC returns the next character from the file.  ASCII.CR is returned if
  100. -- the last character returned was the last character of a line, and ASCII.ETX
  101. -- is returned if the end of file is encountered.
  102.  
  103. -- UNGETC sets the indicated character as the next character to be returned
  104. -- by GETC.
  105. --------------------------------------------------------------------------
  106.  
  107.     procedure CLOSE (ID : in out FILE_ID);
  108. --------------------------------------------------------------------------
  109. -- Close the file previously opened by the OPEN procedure.
  110. --------------------------------------------------------------------------
  111.  
  112.     function LINE_COUNT (ID : FILE_ID) return NATURAL;
  113. --------------------------------------------------------------------------
  114. -- Return the number of the current line in the file.  This is a number from
  115. -- 1 to N, where N is the number of lines in the file.
  116. --------------------------------------------------------------------------
  117.  
  118. private
  119.     INPUT_LINE_LENGTH : constant NATURAL := 256; -- max length of line
  120.     type FILE_ID is
  121.         record
  122.             FID             : TEXT_IO.FILE_TYPE;
  123.             IS_CHAR_PENDING : BOOLEAN := FALSE;
  124.             PENDING_CHAR    : CHARACTER;
  125.             INPUT_LINE      : STRING (1 .. INPUT_LINE_LENGTH);
  126.             NEXT_CHAR_INDEX : NATURAL := 1;
  127.             LAST_CHAR_INDEX : NATURAL := 0;
  128.             LINE_NUMBER     : NATURAL := 0;
  129.         end record;
  130.  
  131. end FGET;
  132.  
  133. package body FGET is
  134.  
  135. --
  136. -- Initialize for future GETC/UNGETC
  137. --
  138.     procedure OPEN (ID : in out FILE_ID; FILE_NAME : STRING) is
  139.     begin
  140.         TEXT_IO.OPEN (ID.FID, TEXT_IO.IN_FILE, FILE_NAME);
  141.         ID.IS_CHAR_PENDING := FALSE;
  142.         ID.NEXT_CHAR_INDEX := 1;
  143.         ID.LAST_CHAR_INDEX := 0;
  144.         ID.LINE_NUMBER := 0;
  145.     exception
  146.         when others =>
  147.             raise OPEN_ERROR;
  148.     end OPEN;
  149.  
  150. --
  151. -- Close a file
  152. --
  153.     procedure CLOSE (ID : in out FILE_ID) is
  154.     begin
  155.         TEXT_IO.CLOSE (ID.FID);
  156.     end CLOSE;
  157.  
  158. --
  159. -- Return next character from file
  160. --
  161.     procedure GETC (ID : in out FILE_ID; CH : out CHARACTER) is
  162.     begin
  163. --
  164. -- If a character is pending, then return it
  165. --
  166.         if ID.IS_CHAR_PENDING then
  167.             CH := ID.PENDING_CHAR;
  168.             ID.IS_CHAR_PENDING := FALSE;
  169.             --
  170.             -- Else return next character from file if not at end of file
  171.             --
  172.         else
  173.             if ID.NEXT_CHAR_INDEX > ID.LAST_CHAR_INDEX then
  174.                 TEXT_IO.GET_LINE (ID.FID, ID.INPUT_LINE, ID.LAST_CHAR_INDEX);
  175.                 ID.LINE_NUMBER := ID.LINE_NUMBER + 1;
  176.                 if ID.LAST_CHAR_INDEX /= ID.INPUT_LINE'LAST then
  177.                     ID.LAST_CHAR_INDEX := ID.LAST_CHAR_INDEX + 1;
  178.                 end if;
  179.                 ID.INPUT_LINE (ID.LAST_CHAR_INDEX) := ASCII.CR;
  180.                 ID.NEXT_CHAR_INDEX := 1;
  181.             end if;
  182.             CH := ID.INPUT_LINE (ID.NEXT_CHAR_INDEX);
  183.             ID.NEXT_CHAR_INDEX := ID.NEXT_CHAR_INDEX + 1;
  184.         end if;
  185.     exception
  186. --
  187. -- Indicate end of file with ETX
  188. --
  189.         when TEXT_IO.END_ERROR =>
  190.             CH := ASCII.ETX;
  191.         when others =>
  192.             raise OPEN_ERROR;
  193.     end GETC;
  194.  
  195. --
  196. -- Set next character to be returned by GETC
  197. --
  198.     procedure UNGETC (ID : in out FILE_ID; CH : CHARACTER) is
  199.     begin
  200.         if not TEXT_IO.IS_OPEN (ID.FID) then
  201.             raise OPEN_ERROR;
  202.         end if;
  203.         ID.IS_CHAR_PENDING := TRUE;
  204.         ID.PENDING_CHAR := CH;
  205.     end UNGETC;
  206.  
  207. --
  208. -- Return count of lines
  209. --
  210.     function LINE_COUNT (ID : FILE_ID) return NATURAL is
  211.     begin
  212.         if not TEXT_IO.IS_OPEN (ID.FID) then
  213.             raise OPEN_ERROR;
  214.         end if;
  215.         return ID.LINE_NUMBER;
  216.     end LINE_COUNT;
  217.  
  218. end FGET;
  219. --::::::::::
  220. --test_fget.ada
  221. --::::::::::
  222. with TEXT_IO,
  223.      FGET;
  224. procedure TEST_FGET is
  225.  
  226. ---------------------------------------------------------------------------
  227. -- Background: This test is a simple, yet dramatic, demonstration of the
  228. -- capabilities afforded by the routines in FGET.  This program passes through
  229. -- an input file and extracts (and prints) the words in this file.  A word
  230. -- is defined as being a sequence of one or more alphanumeric characters.
  231. -- The program does this by extracting characters until an alphanumeric is
  232. -- found, building a word until a non-alphanumeric is found, and then
  233. -- printing the word and putting the last (invalid) character back in case
  234. -- it was a new line (ASCII.CR) or end of file (ASCII.ETX) indicator.
  235. -- The tests for new line and end of file are done at the beginning of the
  236. -- loop, so this "put-back" procedure prepares the last character of the word
  237. -- for the tests at the beginning of the loop.
  238. ---------------------------------------------------------------------------
  239.  
  240.     INPUT_FILE             : FGET.FILE_ID;
  241.     INPUT_FILE_NAME        : STRING (1 .. 60);
  242.     INPUT_FILE_NAME_LENGTH : NATURAL;
  243.     IN_CHAR                : CHARACTER;
  244.  
  245.     function IS_ALPHA_NUMERIC (CH : CHARACTER) return BOOLEAN is
  246.     begin
  247.         return (CH in 'A' .. 'Z') or (CH in 'a' .. 'z') or (CH in '0' .. '9');
  248.     end IS_ALPHA_NUMERIC;
  249.  
  250. begin
  251.     TEXT_IO.PUT ("Input File Name > ");
  252.     TEXT_IO.GET_LINE (INPUT_FILE_NAME, INPUT_FILE_NAME_LENGTH);
  253.     FGET.OPEN (INPUT_FILE, INPUT_FILE_NAME (1 .. INPUT_FILE_NAME_LENGTH));
  254.     loop
  255.         FGET.GETC (INPUT_FILE, IN_CHAR);
  256.         if IS_ALPHA_NUMERIC (IN_CHAR) then
  257.             -- Alpha-numeric character found - print word
  258.             TEXT_IO.PUT (IN_CHAR);
  259.             loop
  260.                 FGET.GETC (INPUT_FILE, IN_CHAR);
  261.                 exit when not IS_ALPHA_NUMERIC (IN_CHAR);
  262.                 TEXT_IO.PUT (IN_CHAR);
  263.             end loop;
  264.             FGET.UNGETC (INPUT_FILE, IN_CHAR);
  265.             TEXT_IO.PUT ("  ");
  266.         else
  267. -- Non-alpha-numeric character found - test of ETX or CR
  268.             case IN_CHAR is
  269.                 when ASCII.ETX =>  exit;
  270.                 when ASCII.CR  =>  TEXT_IO.NEW_LINE;
  271.                 when others    =>  null;
  272.             end case;
  273.         end if;
  274.     end loop;
  275.     TEXT_IO.NEW_LINE;
  276.     FGET.CLOSE (INPUT_FILE);
  277. exception
  278.     when FGET.OPEN_ERROR =>  TEXT_IO.PUT_LINE ("Open File Error");
  279.     when TEXT_IO.END_ERROR =>  TEXT_IO.PUT_LINE ("Bad EOF");
  280. end TEST_FGET;