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

  1. ::::::::::
  2. IOSPT.ADA
  3. ::::::::::
  4.  
  5.  
  6.  
  7.  
  8. -------- SIMTEL20 Ada Software Repository Prologue ------------
  9. --                                                           -*
  10. -- Unit name    : IO_SUPPORT
  11. -- Version      : 1.0
  12. -- Author       : Richard Conn
  13. --              : Texas Instruments, Ada Technology Branch
  14. --              : PO Box 801, MS 8007
  15. --              : McKinney, TX  75069
  16. -- DDN Address  : RCONN at SIMTEL20
  17. -- Copyright    : (c) 1985 Richard Conn
  18. -- Date created : 15 Feb 85
  19. -- Release date : 15 Feb 85
  20. -- Last update  : 15 Feb 85
  21. -- Machine/System Compiled/Run on : DG MV 10000, ROLM ADE
  22. --                                                           -*
  23. ---------------------------------------------------------------
  24. --                                                           -*
  25. -- Keywords     :
  26. ----------------: Input Line Editor, I/O Support
  27. --
  28. -- Abstract     :
  29. ----------------: IO_SUPPORT is a companion package for SYSDEP,
  30. -- a system dependencies package that provides console input and
  31. -- console output without echo on the input and without control
  32. -- character interpretation.  IO_SUPPORT, which employs SYSDEP,
  33. -- provides an input line editor and interfaces to the routines
  34. -- in SYSDEP which provide a greater degree of functionality than
  35. -- SYSDEP itself provides.
  36. --
  37. --      For applications which are embedded and do not require
  38. -- features of TEXT_IO other than simple character or string I/O,
  39. -- IO_SUPPORT with SYSDEP offer an alternative to withing in the
  40. -- entire TEXT_IO package.
  41. --
  42. --      The philosophy behind creating SYSDEP is to provide low-level
  43. -- I/O routines which can be built upon to implement applications which
  44. -- require raw I/O, such as communications servers and character-oriented
  45. -- tools.  IO_SUPPORT goes one step further by providing a set of
  46. -- commonly-used routines around SYSDEP, preventing the need for
  47. -- constantly reinventing the basic wheel.
  48. --                                                           -*
  49. ------------------ Revision history ---------------------------
  50. --                                                           -*
  51. -- DATE         VERSION AUTHOR                  HISTORY
  52. -- 2/15/85      1.0     Richard Conn            Initial Release
  53. --                                                           -*
  54. ------------------ Distribution and Copyright -----------------
  55. --                                                           -*
  56. -- This prologue must be included in all copies of this software.
  57. --
  58. -- This software is copyright by the author.
  59. --
  60. -- This software is released to the Ada community.
  61. -- This software is released to the Public Domain (note:
  62. --   software released to the Public Domain is not subject
  63. --   to copyright protection).
  64. -- Restrictions on use or distribution:  NONE
  65. --                                                           -*
  66. ------------------ Disclaimer ---------------------------------
  67. --                                                           -*
  68. -- This software and its documentation are provided "AS IS" and
  69. -- without any expressed or implied warranties whatsoever.
  70. -- No warranties as to performance, merchantability, or fitness
  71. -- for a particular purpose exist.
  72. --
  73. -- Because of the diversity of conditions and hardware under
  74. -- which this software may be used, no warranty of fitness for
  75. -- a particular purpose is offered.  The user is advised to
  76. -- test the software thoroughly before relying on it.  The user
  77. -- must assume the entire risk and liability of using this
  78. -- software.
  79. --
  80. -- In no event shall any person or organization of people be
  81. -- held responsible for any direct, indirect, consequential
  82. -- or inconsequential damages or lost profits.
  83. --                                                           -*
  84. -------------------END-PROLOGUE--------------------------------
  85. --
  86. -- Components Package IO_SUPPORT
  87. --  Written by Richard Conn, TI Ada Technology Branch
  88. --
  89.  
  90. package IO_SUPPORT is
  91.  
  92. --
  93. -- Editor constants
  94. --
  95.     EDIT_DEL_CHAR    : constant CHARACTER := ASCII.DEL;
  96.     EDIT_DEL_LINE    : constant CHARACTER := ASCII.NAK;
  97.     EDIT_RETYPE_LINE : constant CHARACTER := ASCII.DC2;
  98.     EDIT_QUOTE       : constant CHARACTER := '\';
  99.     EDIT_TAB         : constant CHARACTER := ASCII.HT;
  100.     TAB_SIZE         : constant NATURAL := 8; -- for indenting
  101.  
  102. --
  103. -- The following initialization/deinitialization routines are provided:
  104. --
  105.     procedure CONSOLE_INIT; -- initialize console
  106.     procedure CONSOLE_DEINIT; -- deinitialize console
  107.  
  108. --
  109. -- GET_LINE inputs a line from the user as a string; padded with ASCII.NUL
  110. --
  111.     procedure GET_LINE    (INPUT_LINE : in out STRING);
  112.     procedure GET_LINE    (INPUT_LINE : in out STRING; LAST : out NATURAL);
  113.     function  LINE_LENGTH (INPUT_LINE : STRING) return NATURAL;
  114.  
  115. --
  116. -- PUT and PUT_LINE output a string (padded with ASCII.NUL)
  117. -- NEW_LINE outputs CRLF
  118. -- PUT outputs a character without processing
  119. --
  120.     procedure PUT      (STR : STRING);
  121.     procedure NEW_LINE;
  122.     procedure PUT_LINE (STR : STRING);
  123.     procedure PUT      (INCHAR : CHARACTER);
  124.  
  125.  
  126. --
  127. -- GETC inputs a character without echo; any character in the 128-char
  128. --      ASCII character set may be input
  129. -- GETC_WITH_ECHO is the same as GETC but echoes
  130. -- UNGETC sets the next character to be returned by GETC or GETC_WITH_ECHO
  131. --
  132.     function  GETC           return CHARACTER;
  133.     procedure GETC           (CH : out CHARACTER);
  134.     function  GETC_WITH_ECHO return CHARACTER;
  135.     procedure GETC_WITH_ECHO (CH : out CHARACTER);
  136.     procedure UNGETC         (INCHAR : CHARACTER);
  137.  
  138.  
  139. end IO_SUPPORT;
  140.  
  141.  
  142. with SYSDEP;
  143. package body IO_SUPPORT is
  144.  
  145. --
  146. -- Local Globals
  147. --
  148.     GET_LINE_LENGTH      : NATURAL;
  149.     CHARACTER_IS_PENDING : BOOLEAN := FALSE;
  150.     PENDING_CHARACTER    : CHARACTER;
  151.  
  152.  
  153. --
  154. -- Initialize console
  155. --
  156.     procedure CONSOLE_INIT is
  157.     begin
  158.         SYSDEP.OPEN_CONSOLE;
  159.     end CONSOLE_INIT;
  160.  
  161. --
  162. -- Deinitialize console
  163. --
  164.     procedure CONSOLE_DEINIT is
  165.     begin
  166.         SYSDEP.CLOSE_CONSOLE;
  167.     end CONSOLE_DEINIT;
  168.  
  169. --
  170. -- PRINTING_CHARACTER indicates if the character presented to it is printable
  171. -- (ie, occupies a position on the screen)
  172. --
  173.     function PRINTING_CHARACTER (INCHAR : CHARACTER) return BOOLEAN is
  174.     begin
  175.         if INCHAR >= ' ' and INCHAR < ASCII.DEL then
  176.             return TRUE;
  177.         else
  178.             return FALSE;
  179.         end if;
  180.     end PRINTING_CHARACTER;
  181.  
  182. --
  183. -- The input line editor
  184. --  Customization can be done via the constant declarations
  185. --
  186.     procedure GET_LINE (INPUT_LINE : in out STRING) is
  187.  
  188.         WORK_LINE : STRING (1 .. INPUT_LINE'LAST);
  189.         INCHAR    : CHARACTER;
  190.         INDEX     : NATURAL;
  191.         POSITION  : NATURAL;
  192.  
  193.         procedure BACKUP is -- erase previous character from display
  194.         begin
  195.             SYSDEP.PUT (ASCII.BS);
  196.             SYSDEP.PUT (' ');
  197.             SYSDEP.PUT (ASCII.BS);
  198.         end BACKUP;
  199.  
  200.         procedure BACKUP_CHARACTER is -- backup over last char w/tab processing
  201.             INCHAR          : CHARACTER;
  202.             BACKUP_POSITION : NATURAL;
  203.         begin
  204.             INCHAR := WORK_LINE (INDEX); -- extract target character
  205.             if INCHAR = ASCII.HT then    -- back up over tab
  206.                 -- compute position prior to this tab
  207.                 POSITION := 1;
  208.                 for I in 1 .. INDEX - 1 loop
  209.                     if WORK_LINE (I) /= ASCII.HT then
  210.                         POSITION := POSITION + 1;
  211.                     else
  212.                         POSITION := POSITION + 1;
  213.                         while POSITION mod TAB_SIZE /= 1 loop
  214.                             POSITION := POSITION + 1;
  215.                         end loop;
  216.                     end if;
  217.                 end loop;
  218.                 -- BACKUP required number of character positions
  219.                 BACKUP_POSITION := POSITION;
  220.                 BACKUP;
  221.                 BACKUP_POSITION := BACKUP_POSITION + 1;
  222.                 while BACKUP_POSITION mod TAB_SIZE /= 1 loop
  223.                     BACKUP;
  224.                     BACKUP_POSITION := BACKUP_POSITION + 1;
  225.                 end loop;
  226.             else -- back up over normal char
  227.                 if PRINTING_CHARACTER (INCHAR) then
  228.                     BACKUP;
  229.                     POSITION := POSITION - 1;
  230.                 end if;
  231.             end if;
  232.         end BACKUP_CHARACTER;
  233.  
  234.         procedure STORE_CHARACTER (INCHAR : CHARACTER) is
  235.         begin
  236.             if INDEX < WORK_LINE'LAST then
  237.                 -- room for char
  238.                 WORK_LINE (INDEX) := INCHAR;
  239.                 INDEX := INDEX + 1;
  240.             else
  241.                 -- no room
  242.                 SYSDEP.PUT (ASCII.BEL); -- alarm
  243.             end if;
  244.         end STORE_CHARACTER;
  245.  
  246.     begin
  247.         INDEX := 1;
  248.         POSITION := 1;
  249.         loop
  250.             SYSDEP.GET (INCHAR);
  251.             exit when INCHAR = ASCII.CR;
  252.             case INCHAR is
  253.                 when EDIT_DEL_CHAR =>  -- delete previous character
  254.                     if INDEX /= 1 then
  255.                         INDEX := INDEX - 1;
  256.                         BACKUP_CHARACTER;
  257.                     else
  258.                         SYSDEP.PUT (ASCII.BEL);
  259.                     end if;
  260.                 when EDIT_DEL_LINE =>  -- delete line typed so far
  261.                     for I in 1 .. INDEX - 1 loop
  262.                         INDEX := INDEX - 1;
  263.                         BACKUP_CHARACTER;
  264.                     end loop;
  265.                     INDEX := 1;
  266.                     POSITION := 1;
  267.                 when EDIT_RETYPE_LINE =>  -- retype line input so far
  268.                     NEW_LINE; -- next line
  269.                     WORK_LINE (INDEX) := ASCII.NUL; -- mark end of line
  270.                     PUT (WORK_LINE);
  271.                 when EDIT_QUOTE =>  -- quote next char
  272.                     SYSDEP.PUT (EDIT_QUOTE); -- echo EDIT_QUOTE char
  273.                     POSITION := POSITION + 1; -- EDIT_QUOTE is printing char
  274.                     SYSDEP.GET (INCHAR); -- get quoted char
  275.                     STORE_CHARACTER (INCHAR);
  276.                     if PRINTING_CHARACTER (INCHAR) then
  277.                         SYSDEP.PUT (INCHAR); -- echo it
  278.                         POSITION := POSITION + 1;
  279.                     end if;
  280.                 when EDIT_TAB =>  -- tabulate
  281.                     STORE_CHARACTER (INCHAR);
  282.                     SYSDEP.PUT (' ');
  283.                     POSITION := POSITION + 1;
  284.                     while POSITION mod TAB_SIZE /= 1 loop
  285.                         SYSDEP.PUT (' ');
  286.                         POSITION := POSITION + 1;
  287.                     end loop;
  288.                 when others =>  -- process next char
  289.                     STORE_CHARACTER (INCHAR); -- store char
  290.                     if PRINTING_CHARACTER (INCHAR) then
  291.                         SYSDEP.PUT (INCHAR);
  292.                         POSITION := POSITION + 1;
  293.                     end if;
  294.             end case;
  295.         end loop;
  296.         NEW_LINE;
  297. --
  298. -- NUL-fill line
  299. --
  300.         for I in INDEX .. WORK_LINE'LAST loop
  301.             WORK_LINE (I) := ASCII.NUL;
  302.         end loop;
  303. --
  304. -- return line and line length
  305. --
  306.         INPUT_LINE := WORK_LINE;
  307.         GET_LINE_LENGTH := INDEX - 1;
  308. --
  309.     end GET_LINE;
  310.  
  311.  
  312. --
  313. -- GET_LINE like above but returns a character count also
  314. --
  315.     procedure GET_LINE (INPUT_LINE : in out STRING; LAST : out NATURAL) is
  316.     begin
  317.         GET_LINE (INPUT_LINE);
  318.         LAST := GET_LINE_LENGTH;
  319.     end GET_LINE;
  320.  
  321.  
  322. --
  323. -- LINE_LENGTH computes the length of the string (padded with ASCII.NULs)
  324. --
  325.     function LINE_LENGTH (INPUT_LINE : STRING) return NATURAL is
  326.     begin
  327.         for I in 1 .. INPUT_LINE'LAST loop
  328.             if INPUT_LINE (I) = ASCII.NUL then
  329.                 return I - 1;
  330.             end if;
  331.         end loop;
  332.         return INPUT_LINE'LAST;
  333.     end LINE_LENGTH;
  334.  
  335.  
  336. --
  337. -- PUT outputs the string to the user's terminal.
  338. --
  339.     procedure PUT (STR : STRING) is
  340.  
  341.         INDEX    : NATURAL := 1;
  342.         POSITION : NATURAL := 1;
  343.  
  344.     begin
  345.         loop
  346.             exit when INDEX > STR'LAST;
  347.             exit when STR (INDEX) = ASCII.NUL;
  348.             if STR (INDEX) = ASCII.HT then
  349.                 -- tabulate
  350.                 SYSDEP.PUT (' ');
  351.                 POSITION := POSITION + 1;
  352.                 while (POSITION mod TAB_SIZE) /= 1 loop
  353.                     SYSDEP.PUT (' ');
  354.                     POSITION := POSITION + 1;
  355.                 end loop;
  356.             else
  357.                 -- output character
  358.                 SYSDEP.PUT (STR (INDEX));
  359.                 if PRINTING_CHARACTER (STR (INDEX)) then
  360.                     POSITION := POSITION + 1;
  361.                 end if;
  362.             end if;
  363.             INDEX := INDEX + 1;
  364.         end loop;
  365.     end PUT;
  366.  
  367. --
  368. -- NEW_LINE outputs CRLF to the user's terminal.
  369. --
  370.     procedure NEW_LINE is
  371.     begin
  372.         SYSDEP.PUT (ASCII.CR);
  373.         SYSDEP.PUT (ASCII.LF);
  374.     end NEW_LINE;
  375.  
  376.  
  377. --
  378. -- PUT_LINE outputs the string followed by a CRLF to the user's terminal.
  379. --
  380.     procedure PUT_LINE (STR : STRING) is
  381.     begin
  382.         PUT (STR);
  383.         NEW_LINE;
  384.     end PUT_LINE;
  385.  
  386.  
  387. --
  388. -- PUT outputs a character without processing
  389. --
  390.     procedure PUT (INCHAR : CHARACTER) is
  391.     begin
  392.         SYSDEP.PUT (INCHAR);
  393.     end PUT;
  394.  
  395.  
  396. --
  397. -- GETC returns the next character without echo
  398. --
  399.     function GETC return CHARACTER is
  400.         INCHAR : CHARACTER;
  401.     begin
  402.         if CHARACTER_IS_PENDING then
  403.             INCHAR := PENDING_CHARACTER;
  404.             CHARACTER_IS_PENDING := FALSE;
  405.         else
  406.             SYSDEP.GET (INCHAR);
  407.         end if;
  408.         return INCHAR;
  409.     end GETC;
  410.  
  411.  
  412. --
  413. -- GETC as a procedure
  414. --
  415.     procedure GETC (CH : out CHARACTER) is
  416.     begin
  417.         CH := GETC;
  418.     end GETC;
  419.  
  420.  
  421. --
  422. -- GETC_WITH_ECHO returns the next character and echoes it if > ' ' and < DEL
  423. --
  424.     function GETC_WITH_ECHO return CHARACTER is
  425.         INCHAR : CHARACTER;
  426.     begin
  427.         INCHAR := GETC;
  428.         if INCHAR >= ' ' and INCHAR < ASCII.DEL then
  429.             SYSDEP.PUT (INCHAR);
  430.         end if;
  431.         return INCHAR;
  432.     end GETC_WITH_ECHO;
  433.  
  434.  
  435. --
  436. -- GETC_WITH_ECHO as a procedure
  437. --
  438.     procedure GETC_WITH_ECHO (CH : out CHARACTER) is
  439.     begin
  440.         CH := GETC_WITH_ECHO;
  441.     end GETC_WITH_ECHO;
  442.  
  443.  
  444. --
  445. -- UNGETC sets the next character to be returned by GETC or GETC_WITH_ECHO
  446. --
  447.     procedure UNGETC (INCHAR : CHARACTER) is
  448.     begin
  449.         CHARACTER_IS_PENDING := TRUE;
  450.         PENDING_CHARACTER := INCHAR;
  451.     end UNGETC;
  452.  
  453.  
  454. end IO_SUPPORT;
  455.  
  456.  
  457. ::::::::::
  458. TCHAR.ADA
  459. ::::::::::
  460.  
  461.  
  462. -- 
  463. -- Test for IO_SUPPORT Character-Oriented Routines
  464. -- by Richard Conn, TI Ada Technology Branch
  465. -- 
  466. with IO_SUPPORT;
  467. use IO_SUPPORT;
  468. procedure TCHAR is
  469.  
  470.     INCHAR : CHARACTER;
  471.     MYCHAR : CHARACTER;
  472.  
  473. begin
  474.     CONSOLE_INIT;
  475.     PUT_LINE ("Input characters -- RETURN to exit, . to test UNGETC");
  476.     loop
  477.         INCHAR := GETC;
  478.         case INCHAR is
  479.             when 'a' .. 'z' | 'A' .. 'Z' => 
  480.                 PUT ("Letter: ");
  481.                 PUT (INCHAR);
  482.             when '0' .. '9' => 
  483.                 PUT ("Digit:  ");
  484.                 PUT (INCHAR);
  485.             when '.' => 
  486.                 PUT ("Char to UNGETC? ");
  487.                 GETC_WITH_ECHO (MYCHAR);
  488.                 UNGETC (MYCHAR);
  489.             when others => 
  490.                 if INCHAR >= ' ' and INCHAR < ASCII.DEL then
  491.                     PUT ("        ");
  492.                     PUT (INCHAR);
  493.                 else
  494.                     PUT (ASCII.BEL);
  495.                 end if;
  496.         end case;
  497.         NEW_LINE;
  498.         exit when INCHAR = ASCII.CR;
  499.     end loop;
  500.     PUT_LINE ("Done");
  501.     CONSOLE_DEINIT;
  502. end TCHAR;
  503.  
  504.  
  505.  
  506. ::::::::::
  507. TLINE.ADA
  508. ::::::::::
  509.  
  510.  
  511. -- 
  512. -- Test program for routines in IO_SUPPORT
  513. -- by Richard Conn
  514. -- 
  515.  
  516. with IO_SUPPORT;
  517. use IO_SUPPORT;
  518. procedure TLINE is
  519.  
  520. -- 
  521. -- Variables
  522. -- 
  523.     MYLINE : STRING (1 .. 80);
  524.  
  525. -- 
  526. -- Mainline
  527. -- 
  528. begin
  529.     CONSOLE_INIT;
  530.     PUT_LINE ("Input Lines and end test with a <RETURN>");
  531.     loop
  532.         PUT ("INPUT     > ");
  533.         GET_LINE (MYLINE);
  534.         exit when MYLINE (1) = ASCII.NUL;
  535.         PUT (" OUT_LINE > ");
  536.         PUT_LINE (MYLINE);
  537.     end loop;
  538.     PUT_LINE ("Done with Test");
  539.     CONSOLE_DEINIT;
  540. end TLINE;
  541.  
  542.