home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / edit / wpcommon.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  147.0 KB  |  3,667 lines

  1. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2. --stringli
  3. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4.  
  5.   --$$$+ stringli
  6.    
  7.   --
  8.   -- File 001
  9.   --
  10.   -- Editor Written By Robert S. Cymbalski
  11.   --                   Science Applications International Corporation
  12.   --                   Energy Systems Group
  13.   --                   Ada Software Development Project Team
  14.   --                   2280 U.S. Highway 19 North, Suite 120
  15.   --                   Clearwater, Florida  33575
  16.   --
  17.   -- Program Revised from text Copyright (c) 1984 , R.S.Cymbalski
  18.    
  19.   package String_Library is
  20.    
  21.     user_abort : exception ;
  22.    
  23.     MaxStrIndex : constant Integer := 255 ;
  24.     Subtype StrIndex Is Integer Range 0..MaxStrIndex; -- Maximum string index
  25.     type Pstring is 
  26.            record
  27.              actual_length  : strindex := 0           ;
  28.              maximum_length : strindex := maxstrindex ;
  29.              data           : string ( 1 .. maxstrindex ) ;
  30.            end record ;
  31.        
  32.     Subtype Number_Base is integer range 2 .. 16 ;
  33.        
  34.     blank_line : pstring ;
  35.      
  36.     Function Length (str : In Pstring) Return Integer;
  37.       -- Returns the length of the given pstring
  38.       
  39.     Procedure Set_Length( Str : In Out Pstring ; Len : in Integer ) ;
  40.       -- Sets the  length of the given Pstring
  41.       
  42.     Function Position (pattern,str : Pstring) Return Integer;
  43.       -- Returns the position of the first occurance of pattern in str,
  44.       -- or 0 if there is none
  45.       
  46.     Function Position ( Pattern : character ;
  47.                         Str     : pstring   ) return Integer ;
  48.                          
  49.     Function Position ( Pattern : string    ;
  50.                         Str     : pstring   ) return Integer ;
  51.                          
  52.     Function Position ( Pattern : character ;
  53.                         Str     : string    ) return Integer ;
  54.                          
  55.     Function Position ( Pattern : string    ;
  56.                         Str     : string    ) return Integer ;
  57.                          
  58.     Function char_to_str (char : character) Return String;
  59.       -- Converts the given character into a string of length 1
  60.       
  61.     Function str_to_int (str : Pstring) Return Integer;
  62.       -- Converts the given pstring into an integer
  63.       
  64.     Function int_to_str (int : Integer ; base : number_base := 10 ) 
  65.                        return pstring ;
  66.       -- Converts the given integer in base 10 to an equivalent number in the
  67.       -- given base and Returns the result in a pstring
  68.       
  69.     Function string_to_pstring ( s : string ) Return Pstring ;
  70.       -- Converts the string into a pstring
  71.       
  72.     Function "&" ( Left_String  : Pstring ;
  73.                    Right_String : Pstring ) return Pstring ;
  74.        
  75.     Function "&" ( Left_String  :  string ;
  76.                    Right_String : Pstring ) return Pstring ;
  77.        
  78.     Function "&" ( Left_String  : Pstring ;
  79.                    Right_String :  string ) return Pstring ;
  80.        
  81.     function "&" ( c : character ; s : string ) return string ;
  82.      
  83.     function "&" ( s : string ; c : character ) return string ;
  84.      
  85.     function "&" ( c , d : character          ) return string ;
  86.      
  87.     Function equal( Left_String  : Pstring ;
  88.                     Right_String : Pstring ) return Boolean ;
  89.                     
  90.     Function compress( comp_string : in string  ) return Pstring ;
  91.      
  92.     Function compress( comp_string : in Pstring ) return Pstring ;
  93.      
  94.     Function MIN ( FIRST , SECOND : in INTEGER ) return INTEGER ;
  95.        -- return minimum of first and second
  96.        
  97.     Function MAX ( FIRST , SECOND : in INTEGER ) return INTEGER ;
  98.        -- return maximum of first and second
  99.       
  100.   end String_Library ;
  101.    
  102.   package body String_Library is
  103.    
  104.     Function Length (str : In Pstring) Return Integer Is
  105.       -- Returns the length of the string
  106.     Begin
  107.       Return Str.Actual_Length ;
  108.     End Length;
  109.        
  110.     Procedure Set_Length( Str : In Out Pstring ; Len : in Integer ) is
  111.       -- Set Length Of String
  112.     begin
  113.       if len <= Str.Maximum_Length then
  114.         Str.Actual_Length := Len ;
  115.       end if ;
  116.     end set_length ;
  117.         
  118.     Function Position (pattern,str : Pstring) Return Integer Is
  119.       -- Returns the position of the first occurance of pattern in str,
  120.       -- or 0 if there is none
  121.       len : Integer := Length(str);
  122.       len2 : Integer := Length(pattern);
  123.       j : Integer;
  124.     Begin
  125.       For i In 0..len-len2 Loop
  126.         j := 1;
  127.         While j <= len2 And Then pattern.data(j) = str.data(i + j) Loop
  128.           j := j + 1;
  129.         End Loop;
  130.         If j > len2 Then -- Pattern found
  131.           Return i+1; -- Return the position
  132.         End If;
  133.           -- Otherwise, go around again
  134.       End Loop;
  135.       Return 0; -- Pattern is not found
  136.     End Position;
  137.        
  138.     Function Position ( Pattern : character ;
  139.                         Str     : pstring   ) return integer is
  140.       s : string ( 1 .. 1 ) ;
  141.     begin -- position
  142.       s(1) := Pattern ;
  143.       return position(s,str);
  144.     end position ;
  145.  
  146.     Function Position ( Pattern : string    ;
  147.                         Str     : pstring   ) return integer is
  148.       s : pstring ;
  149.     begin -- position
  150.       s := string_to_pstring(pattern);
  151.       return position(s,str);
  152.     end position ;
  153.     
  154.     Function Position ( Pattern : character ;
  155.                         Str     : string    ) return integer is
  156.       s : pstring ;
  157.     begin -- position
  158.       s := string_to_pstring(str);
  159.       return position(pattern,s);
  160.     end position ;
  161.     
  162.     Function Position ( Pattern : string    ;
  163.                         Str     : string    ) return integer is
  164.       s1 , s2 : pstring ;
  165.     begin -- position
  166.       s1 := string_to_pstring(pattern);
  167.       s2 := string_to_pstring(str);
  168.       return position(s1,s2);
  169.     end position ;
  170.     
  171.     Function char_to_str (char : character) Return String Is
  172.       -- Converts a character into a string of length 1
  173.       ch : string(1 .. 1);
  174.     Begin
  175.       ch := " ";
  176.       ch(1) := char;
  177.       Return ch;
  178.     End char_to_str;
  179.        
  180.     Function str_to_int (str : Pstring) Return Integer Is
  181.       -- Converts a string into an integer
  182.       pos,temp : Integer;
  183.       len : Integer := Length(str);
  184.       sign : Boolean := False; -- Positive until otherwise determined
  185.     Begin
  186.       temp := 0; -- Value is zero so far
  187.       pos := 1; -- Start at the beginning of the string
  188.       If len = 0 Then
  189.         Return 0;
  190.       End If;
  191.       While (str.data(pos) = ' ')  -- Strip Blanks 
  192.           or (str.data(pos) = '-')  -- Strip Signs 
  193.           or (str.data(pos) = '+')  --             both types 
  194.           or (str.data(pos) = ascii.ht  ) Loop -- Strip Tabs
  195.         If str.data(pos) = '-' Then -- Flip the sign
  196.           sign := Not sign;
  197.         End If;
  198.         If pos = len Then
  199.           Return 0;
  200.         End If;
  201.         pos := pos + 1;
  202.       End Loop;
  203.       While (str.data(pos) In '0'..'9') Loop
  204.         If temp > 3276 Then
  205.           null ;
  206.         End If;
  207.         temp := temp * 10 + (Character'Pos(str.data(pos)) 
  208.                           -  Character'Pos('0'));
  209.         If pos = len Then
  210.           If sign Then Return - temp;
  211.           Else Return temp;
  212.           End If;
  213.         End If;
  214.         pos := pos + 1;
  215.       End Loop;
  216.       If sign Then
  217.         Return - temp;
  218.       Else
  219.         Return temp;
  220.       End If;
  221.     End str_to_int;
  222.        
  223.     Function string_to_pstring ( s : string ) Return Pstring is
  224.       -- Converts the string into a pstring
  225.       real_string : string ( 1 .. s'length ) ;
  226.       pstr : Pstring ;
  227.       len : integer := s'length ;
  228.     Begin
  229.       -- put(s);
  230.       real_string := s ;
  231.       set_length(pstr,len);
  232.       for ind in 1 .. len loop
  233.         pstr.data(ind) := real_string(ind) ;
  234.       end loop ;
  235.       return pstr ;
  236.     End string_to_pstring ;
  237.       
  238.     Function int_to_str (int : Integer ; base : number_base := 10 ) 
  239.                        return pstring is
  240.       longest_string : constant integer := 40 ;
  241.         -- In fact, we will only get good numbers when the length 
  242.         -- (not including the base) is less than 40
  243.       place : integer ;
  244.       do_negative : boolean;
  245.       ada_string  : string ( 1 .. longest_string ) ;
  246.       new_string  : pstring ;
  247.       base_string : pstring ;
  248.       number      : integer;
  249.       a_number    : integer;
  250.       new_place   : integer;
  251.     begin
  252.       if Int < 0 then
  253.         do_negative := true;
  254.         number := - Int ;
  255.       else
  256.         do_negative := false;
  257.         number := Int ;
  258.       end if;
  259.       for lopr in 1 .. longest_string loop
  260.         ada_string(lopr) := ' ';
  261.       end loop;
  262.       place := longest_string ;
  263.       loop
  264.         a_number := number mod base ;
  265.         if a_number < 10 then
  266.           a_number := 48 + a_number;
  267.         else
  268.           a_number := 65 + a_number - 10 ;
  269.         end if;
  270.         ada_string(place) := character'val(a_number) ;
  271.         place := place - 1 ;
  272.         number := number / base ;
  273.         exit when ( place = 0 ) or ( number = 0 ) ;
  274.       end loop;
  275.       -- put_line("  Current Ada String Is """ & ada_string & """");
  276.       -- Now, we have the number in the right part of the string
  277.       if do_negative then
  278.         ada_string(1) := '-' ;
  279.         -- Note that we had better not have put a number into (1)
  280.       end if;
  281.       new_place := 0 ;
  282.       for looper in 1 .. ada_string'length loop
  283.         if ada_string(looper) /= ' ' then
  284.           new_place := new_place + 1 ;
  285.           new_string.data(new_place) := ada_string(looper);
  286.         end if;
  287.       end loop ;
  288.       set_length(new_string,new_place);
  289.         -- Now, to work on the base string
  290.       if base /= 10 then
  291.         -- We need to put all the info into the string
  292.         base_string:= int_to_str(base,10) ;
  293.         new_string := new_string & "#" & base_string & "#" ;
  294.       end if;
  295.       return new_string;
  296.     End int_to_str;
  297.        
  298.     Function "&" ( Left_String  : Pstring ;
  299.                    Right_String : Pstring ) return Pstring is
  300.       len_left : integer ;
  301.       len_right : integer ;
  302.       new_string : pstring ;
  303.     begin
  304.       new_string := Left_String ;
  305.       len_left := length(left_string);
  306.       len_right := length(right_string);
  307.       if len_left + len_right <= maxstrindex then
  308.         if len_right > 0 then
  309.           new_string.data(len_left+1..len_left+len_right) := 
  310.                                   Right_String.data(1..len_right);
  311.           set_length(new_string,len_left + len_right);
  312.         end if;
  313.       end if;
  314.       return new_string ;
  315.     end;
  316.       
  317.     Function "&" ( Left_String  :  string ;
  318.                    Right_String : Pstring ) return Pstring is
  319.       len_left : integer ;
  320.       len_right : integer ;
  321.       new_string : pstring ;
  322.     begin
  323.       new_string := string_to_pstring(Left_String) ;
  324.       len_left := length(new_string);
  325.       len_right := length(right_string);
  326.       if len_left + len_right <= maxstrindex then
  327.         if len_right > 0 then
  328.           new_string.data(len_left+1..len_left+len_right) := 
  329.                                   Right_String.data(1..len_right);
  330.           set_length(new_string,len_left + len_right);
  331.         end if;
  332.       end if;
  333.       return new_string ;
  334.     end;
  335.       
  336.     Function "&" ( Left_String  : Pstring ;
  337.                    Right_String :  string ) return Pstring is
  338.       len_left : integer ;
  339.       len_right : integer ;
  340.       new_string : pstring ;
  341.       real_right : string ( 1 .. right_string'length ) ;
  342.     begin
  343.       new_string := Left_String ;
  344.       real_right := right_string ;
  345.       len_left := length(left_string);
  346.       len_right := real_right'length ;
  347.       if len_left + len_right <= maxstrindex then
  348.         if len_right > 0 then
  349.           new_string.data(len_left+1..len_left+len_right) := 
  350.                                   real_right(1..len_right);
  351.           set_length(new_string,len_left + len_right);
  352.         end if;
  353.       end if;
  354.       return new_string ;
  355.     end;
  356.       
  357.     function "&" ( c : character ; s : string ) return string is
  358.       new_string : string ( 1 .. s'length + 1 ) ;
  359.     begin
  360.       new_string := " " & s ;
  361.       new_string(1) := c ;
  362.       return new_string ;
  363.     end;
  364.      
  365.     function "&" ( s : string ; c : character ) return string is
  366.       new_string : string ( 1 .. s'length + 1 ) ;
  367.     begin
  368.       new_string := s & " " ;
  369.       new_string( new_string'length ) := c ;
  370.       return new_string ;
  371.     end;
  372.      
  373.     function "&" ( c , d : character          ) return string is
  374.       new_string : string ( 1 .. 2 ) := "  " ;
  375.     begin
  376.       new_string(1) := c ;
  377.       new_string(2) := d ;
  378.       return new_string ;
  379.     end;
  380.     
  381.     Function equal( Left_String  : Pstring ;
  382.                     Right_String : Pstring ) return Boolean is
  383.       len : integer ;
  384.     begin
  385.       if left_string.actual_length /= right_string.actual_length then
  386.         return false ;
  387.       else
  388.         len := left_string.actual_length ;
  389.         return left_string.data( 1 .. len ) = right_string.data( 1 .. len ) ;
  390.       end if ;
  391.     end;
  392.      
  393.     Function compress( comp_string : in string ) return Pstring is
  394.       start_ind : integer := 1 ;
  395.       ending_ind : integer := comp_string'length ;
  396.       real_string : string ( 1 .. comp_string'length ) ;
  397.     begin
  398.       real_string := comp_string ;
  399.       While start_ind <= ending_ind
  400.       and then real_string(start_ind) = ' ' loop
  401.         start_ind := start_ind + 1 ;
  402.       end loop ;
  403.       while ending_ind >= start_ind 
  404.       and then real_string(ending_ind) = ' ' loop
  405.         ending_ind := ending_ind - 1 ;
  406.       end loop ;
  407.       if start_ind > ending_ind then
  408.         return blank_line ;
  409.       else
  410.         return string_to_pstring(real_string(start_ind .. ending_ind)) ;
  411.       end if ;
  412.     end compress ;
  413.  
  414.     Function compress( comp_string : in Pstring ) return Pstring is
  415.     begin
  416.       return compress(comp_string.data( 1 .. comp_string.actual_length ) ) ;
  417.     end compress ;
  418.      
  419.     Function MIN ( FIRST , SECOND : in INTEGER ) return INTEGER is
  420.       -- return minimum of first and second
  421.     begin
  422.       if FIRST < SECOND then
  423.         return ( FIRST ) ;
  424.       else
  425.         return ( SECOND ) ;
  426.       end if ;
  427.     end MIN ;
  428.         
  429.     Function MAX ( FIRST , SECOND : in INTEGER ) return INTEGER is
  430.       -- return maximum of first and second
  431.     begin
  432.       if FIRST < SECOND then
  433.         return ( SECOND ) ;
  434.       else
  435.         return ( FIRST ) ;
  436.       end if ;
  437.     end  MAX ;
  438.    
  439.   begin -- String_Library 
  440.     -- stringli by SAIC/Clearwater General Primatives          31 Dec 84
  441.     -- STRLIB   by SAIC/Clearwater UCSD String Library         21 Dec 84
  442.     blank_line := string_to_pstring("");
  443.   end String_Library ;
  444.    
  445.   --$$$- stringli
  446.  
  447. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  448. --basicios
  449. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  450.  
  451.   --$$$+ BasicIOS
  452.    
  453.   --
  454.   -- File 002
  455.   --
  456.   -- Editor Written By Robert S. Cymbalski
  457.   --                   Science Applications International Corporation
  458.   --                   Energy Systems Group
  459.   --                   Ada Software Development Project Team
  460.   --                   2280 U.S. Highway 19 North, Suite 120
  461.   --                   Clearwater, Florida  33575
  462.   --
  463.   -- Program Revised from text Copyright (c) 1984 , R.S.Cymbalski
  464.   -- Basic I/O Routines revised 18 Dec 84 - RSC
  465.   --
  466.       
  467.   with calendar           ;
  468.   
  469.   with direct_io          ;                                            --###--
  470.   
  471.   with text_io            ;                                            --###--
  472.   
  473.   with string_library     ;
  474.   use  string_library     ;
  475.    
  476.   package Basic_IO_System is
  477.       
  478.     subtype extended_character is integer range 0 .. 255 ;
  479.         
  480.     procedure put_transparent( a_character : in character ) ;
  481.       -- Outputs a character to the CRT device without any interpretation
  482.           
  483.     procedure put_transparent( a_string : in string ) ; 
  484.       -- Outputs a string to the CRT device without any interpretation
  485.       -- Only for constants...
  486.         
  487.     procedure put_transparent( a_string : in pstring ) ;
  488.       -- Outputs a pstring to the CRT device without any interpretaion
  489.       -- This is just a short-cut for the character routine
  490.           
  491.     procedure put_transparent( an_integer : in integer ) ;
  492.       -- Outputs a number to the CRT device without any interpretation
  493.         
  494.     function get_transparent return extended_character ;
  495.       -- Get extended_character from the CRT device without any interpretation
  496.           
  497.     function key_is_pressed return boolean ;
  498.       -- Return true if a key has been pressed but the value has not been
  499.       -- read in; false otherwise.
  500.         
  501.     procedure replace_transparent_input( an_extended_character 
  502.                                                         : extended_character ) ;
  503.       -- Saves the given extended_character back in the input buffer in the 
  504.       -- correct place so it may be gotten on the next get_transparent
  505.         
  506.     -- The IO portions will use the following
  507.         
  508.     max_screen_columns : constant integer := 132 ; -- maximum screen columns
  509.     max_screen_lines   : constant integer :=  66 ; -- maximum screen lines
  510.       
  511.     subtype a_screen_column_number is integer range 0 .. max_screen_columns ;
  512.     subtype a_screen_line_number   is integer range 0 .. max_screen_lines   ;
  513.       
  514.     CRT_LINE       : a_screen_line_number   := 1 ; -- current crt line
  515.     CRT_COL        : a_screen_column_number := 1 ; -- current crt column
  516.     TOTAL_CRT_LINE : a_screen_line_number   := max_screen_lines ;
  517.                         -- total number of crt lines allowed....
  518.                         -- can be changed by the caller....
  519.     TOTAL_CRT_COL  : a_screen_column_number := max_screen_columns ;
  520.                         -- same for columns ... 
  521.         
  522.     -- Now, we have the non-transparent I/O routines
  523.         
  524.     subtype NUMBER_BASE is INTEGER range 2 .. 16 ;
  525.     DEFAULT_WIDTH  : constant INTEGER     :=  0 ;
  526.     DEFAULT_BASE   : constant NUMBER_BASE := 10 ;
  527.       -- Is there supposed to be a way that the above two can be
  528.       -- variables?  For some reason, the compiler will not accept
  529.       -- the values assigned as default values for input to procedures
  530.       -- unless constant.
  531.         
  532.     procedure put( item : in character ) ;
  533.       -- Outputs the given character to the CRT screen
  534.         
  535.     procedure put( item : in string    ) ;
  536.       -- Outputs the given string to the CRT screen
  537.        
  538.     procedure put( item : in pstring    ) ;
  539.       -- Outputs the given pstring to the CRT screen
  540.       
  541.     procedure put( item : in INTEGER     ;
  542.                    width: in INTEGER     := default_width  ;
  543.                    base : in number_base := default_base ) ;
  544.       -- Converts the base 10 number to its equivalent value with the 
  545.       -- given base, and then outputs that value using the given width
  546.       -- to the CRT screen.
  547.       
  548.     procedure put_line ;
  549.       -- Outputs a <return> to the CRT screen;  cursor moves to
  550.       -- column 1 of the next line
  551.         
  552.     function num_to_pstring( i : integer ; 
  553.                              base : number_base := default_base ) 
  554.                              return pstring ;
  555.       -- Converts the given base 10 integer to its equivalent value
  556.       -- in the given base and returns this value in a pstring
  557.         
  558.     -- Now, We have the special information for reading the clock
  559.         
  560.     procedure terminate_Basic_IO_System ;
  561.      
  562.     subtype year_number         is integer range 1901 .. 2099 ;
  563.     subtype month_number        is integer range 1    .. 12   ;
  564.     subtype day_number          is integer range 1    .. 31   ;
  565.     subtype day_duration        is calendar.day_duration      ;        --###--
  566.                                  
  567.     type day_of_week_name       is ( sunday , monday , tuesday , wednesday ,
  568.                                      thursday , friday , saturday ) ;
  569.     subtype hour_number         is integer range 0    .. 23   ;
  570.     subtype minute_number       is integer range 0    .. 59   ;
  571.     subtype second_number       is integer range 0    .. 59   ;
  572.      
  573.     type timer is 
  574.            record
  575.              year         : year_number    ;
  576.              month        : month_number   ;
  577.              day          : day_number     ;
  578.              d_duration   : day_duration   ;
  579.              day_of_week  : day_of_week_name ;
  580.              hour         : hour_number    ;
  581.              minute       : minute_number  ;
  582.              second       : second_number  ;
  583.            end record ;
  584.    
  585.     function clock return timer ;
  586.      
  587.     function year    ( date : timer ) return year_number  ;
  588.     function month   ( date : timer ) return month_number ;
  589.     function day     ( date : timer ) return day_number   ;
  590.     function seconds ( date : timer ) return day_duration ;
  591.      
  592.     function day_of_week ( date : timer ) return day_of_week_name ;
  593.     function hour    ( date : timer ) return hour_number  ;
  594.     function minute  ( date : timer ) return minute_number;
  595.     function second  ( date : timer ) return second_number;
  596.      
  597.     procedure split  ( date     : in timer           ;
  598.                        year     : out year_number    ;
  599.                        month    : out month_number   ;
  600.                        day      : out day_number     ;
  601.                        seconds  : out day_duration ) ;
  602.                         
  603.     procedure split  ( date     : in timer           ;
  604.                        year     : out year_number    ;
  605.                        month    : out month_number   ;
  606.                        day      : out day_number     ;
  607.                        seconds  : out day_duration   ;
  608.                        weekday  : out day_of_week_name ;
  609.                        hour     : out hour_number    ;
  610.                        minute   : out minute_number  ;
  611.                        second   : out second_number) ;
  612.                         
  613.     function time_of ( year     : in year_number     ;
  614.                        month    : in month_number    ;
  615.                        day      : in day_number      ;
  616.                        seconds  : in day_duration := 0.0 ) 
  617.                                                         return timer ; --###--
  618.      
  619.     function time_of ( year     : in year_number     ;
  620.                        month    : in month_number    ;
  621.                        day      : in day_number      ;
  622.                        weekday  : in day_of_week_name;
  623.                        hour     : in hour_number     ;
  624.                        minute   : in minute_number   ;
  625.                        second   : in second_number   ) return timer ;
  626.      
  627.     function figure_week_day ( date : timer ) return day_of_week_name ;
  628.      
  629.     timer_error : exception ;
  630.                         
  631.     -- These last routines are special because they need to be changed
  632.     -- when you move computers
  633.      
  634.     function word_processor_directory return pstring ;
  635.       -- Return the string defining where the word processor program
  636.       -- files reside (such as the help files and default environment)
  637.       -- If unknown, return blank_line
  638.      
  639.     function user_directory  return pstring ;
  640.       -- Return the string defining where the user files reside.  
  641.       -- If unknown, return blank_line
  642.        
  643.     function directory_separator return character ;
  644.       -- Return the character which is used to separate the directory name
  645.       -- from the file name.  If unknown or unimplemented, return space
  646.          
  647.     procedure wait ;
  648.       
  649.     input_name  : constant string := "SYS$INPUT:"    ;                 --###--
  650.     output_name : constant string := "SYS$OUTPUT:"   ;                 --###--
  651.     print_name  : constant string := "SYS$PRINT:"    ;                 --###--
  652.     
  653.   private
  654.      
  655.     max_input_buffer : constant INTEGER := 200 ;
  656.          
  657.     input_buffer : array ( 1 .. max_input_buffer ) of character ;
  658.     place_put_into_input_buffer : integer := 1 ;
  659.     place_get_from_input_buffer : integer := 1 ;
  660.       -- When into = from no data is waiting
  661.     
  662.     procedure real_put_transparent( a_character : in character ) ; 
  663.       
  664.     procedure terminate_physical_io ;
  665.       
  666.   end Basic_IO_System ;
  667.         
  668.   package body Basic_IO_System is
  669.       
  670.   --
  671.   -- VAX/VMS I/O Code        Revised 07 Jan 85 - Bob Cymbalski
  672.   --
  673.   -- Portions of this package taken from WIS/JPMO code.
  674.   -- All implementations must implement the routine to fill the input buffer
  675.     
  676.     package c_io is new direct_io(character) ;                         --###--
  677.     
  678.     ot_file : c_io.file_type ;
  679.     
  680.     Task null_task is       -- does nothing except kill time and stimulate 
  681.             Entry wait;     -- other tasks to run.  ROS characteristic.
  682.             Entry kill;
  683.     End;
  684.     
  685.     Task RKB is             -- reads the keyboard.
  686.             Entry kill;
  687.     End;
  688.     
  689.     Task Body null_task is
  690.     begin
  691.       nt:loop
  692.            select
  693.              accept wait;
  694.            or
  695.              accept kill;
  696.              exit nt;
  697.            end select;
  698.          end loop nt;
  699.     end null_task;
  700.   
  701.     Task body RKB is        -- Reads the KeyBoard.
  702.       kb_file            : c_io.file_type ;                            --###--
  703.       kb_name            : constant string       := input_name ;       --###--
  704.       D               : character;
  705.       new_place       : integer ;
  706.      
  707.       function get_a_new_transparent return character is
  708.         d : character ;                                                --###--
  709.       begin
  710.         c_io.read(KB_file,D);   -- task hangs waiting for byte         --###--
  711.         return d ;
  712.       end;
  713.        
  714.       function difference ( a , b , len : integer ) return integer is
  715.        -- in a circular buffer, return the number which must be
  716.        -- added to a to get b , when len is the length of the
  717.        -- buffer .
  718.       begin -- difference
  719.         if a < b then
  720.           -- nothing special here, because both are in normal order
  721.           return b - a ;
  722.         else
  723.           -- here, b has moved to the start, but a has not
  724.           return ( b + len ) - a ;
  725.         end if ;
  726.       end difference ;
  727.        
  728.     Begin
  729.       c_io.Open(KB_File,c_io.IN_file,KB_Name);                         --###--
  730.       r:loop
  731.           
  732.         -- Here we really need to only read if a char is waiding!
  733.         d := get_a_new_transparent ;
  734.         input_buffer(place_put_into_input_buffer) := d ;
  735.         new_place := place_put_into_input_buffer + 1 ;
  736.         if new_place > max_input_buffer then
  737.           new_place := 1 ;
  738.         end if ;
  739.         -- while new_place = place_get_from_input_buffer loop
  740.         --   null_task.wait ; -- other tasks take care of this.
  741.         -- end loop ;
  742.         -- The above code replaced 7 Jan 85 to take into account for
  743.         -- the replacement of up to 9 characters in the input buffer
  744.         -- (which can happen when trying to match up a function key
  745.         while difference( new_place , place_get_from_input_buffer ,
  746.                           max_input_buffer ) < 10 loop
  747.           null_task.wait ; -- only necessary for wicat?
  748.         end loop ;
  749.         place_put_into_input_buffer := new_place ;
  750.       
  751.         -- Now, just check to see if we should abort
  752.         select 
  753.           accept kill ;
  754.           exit r ;
  755.         else 
  756.           null_task.wait ;
  757.         end select ;
  758.       end loop r;
  759.     End RKB;
  760.       
  761.     procedure real_put_transparent( a_character : in character ) is
  762.       -- Outputs a character to the CRT device without any interpretation
  763.     begin
  764.       c_io.write( ot_file , a_character ) ;                            --###--
  765.     end ;
  766.     
  767.     procedure wait is
  768.     begin
  769.       null_task.wait ;
  770.     end;
  771.       
  772.     procedure terminate_physical_io is
  773.     begin -- terminate_physical_io
  774.       null_task.kill ;
  775.       rkb.kill       ;
  776.     end terminate_physical_io ;
  777.       
  778.     function word_processor_directory return pstring is
  779.       -- Return the string defining where the word processor program
  780.       -- files reside (such as the help files and default environment)
  781.       -- If unknown, return blank_line
  782.       -- If known, then the directory name, with directory_separator
  783.       -- must be returned
  784.     begin -- word_processor_directory 
  785.       return blank_line ;
  786.     end word_processor_directory ;
  787.      
  788.     function user_directory  return pstring is
  789.       -- Return the string defining where the user files reside.  
  790.       -- If unknown, return blank_line
  791.       -- If known, then the directory name, with directory_separator
  792.       -- must be returned
  793.     begin -- user_directory
  794.       return blank_line ;
  795.     end user_directory ;
  796.        
  797.     function directory_separator return character is
  798.       -- Return the character which is used to separate the directory name
  799.       -- from the file name.  If unknown or unimplemented, return space
  800.     begin -- directory_separator
  801.       return ' ' ;
  802.     end directory_separator ;
  803.        
  804.     procedure put_transparent( a_character : in character ) is
  805.     begin
  806.       real_put_transparent( a_character ) ;
  807.     end ;
  808.         
  809.     procedure put_transparent( a_string : in string ) is
  810.       -- This is just a short-cut for the character routine
  811.     begin
  812.       for loop_param in 1 .. a_string'length loop
  813.         real_put_transparent( a_string(loop_param) ) ;
  814.       end loop;
  815.     end;
  816.           
  817.     procedure put_transparent( a_string : in pstring ) is
  818.       -- This is just a short-cut for the character routine
  819.       -- The in/out is just so the string will not be copied over
  820.     begin
  821.       for loop_param in 1 .. length(a_string) loop
  822.         real_put_transparent( a_string.data(loop_param) ) ;
  823.       end loop;
  824.     end;
  825.           
  826.     procedure put_transparent( an_integer : in integer ) is
  827.       ps : pstring ;
  828.     begin
  829.       put_transparent( int_to_str(an_integer) ) ;
  830.     end;
  831.         
  832.     function get_transparent return extended_character is
  833.       -- Get an extended_character from CRT device without any interpretation
  834.       c : character ;
  835.     begin
  836.       if place_put_into_input_buffer = place_get_from_input_buffer then
  837.         -- No characters waiting for input from CRT
  838.         loop
  839.           wait ;
  840.           exit when place_put_into_input_buffer /= place_get_from_input_buffer ;
  841.         end loop ;
  842.       end if ;
  843.       -- We know that we have a character here...
  844.       c := input_buffer(place_get_from_input_buffer);
  845.       if place_get_from_input_buffer = max_input_buffer then
  846.         place_get_from_input_buffer := 1 ;
  847.       else 
  848.         place_get_from_input_buffer := place_get_from_input_buffer + 1 ;
  849.       end if ;
  850.       return extended_character( character'pos(c) ) ;
  851.     end;
  852.           
  853.     function key_is_pressed return boolean is 
  854.       -- Return true if a key has been pressed but the value has not been
  855.       -- read in.  This routine copied from Janus/Ada IO Utility Package
  856.     begin
  857.       return place_put_into_input_buffer /= place_get_from_input_buffer ;
  858.     end;
  859.         
  860.     procedure replace_transparent_input( an_extended_character 
  861.                                                        : extended_character ) is
  862.       -- saves the given extended_character back in the input buffer in the 
  863.       -- correct place so it may be gotten next
  864.       new_place : integer ;
  865.     begin
  866.       if place_get_from_input_buffer = 1 then
  867.         new_place := max_input_buffer ;
  868.       else
  869.         new_place := place_get_from_input_buffer - 1 ;
  870.       end if;
  871.       -- now, did we move back past the put into buffer loc?
  872.       -- we will always allow at least one character between the two pointers
  873.       -- ( so on putting in in the forward direction, we never inc to make
  874.       -- both pointers equal)
  875.       if new_place = place_put_into_input_buffer then
  876.         -- decrement it too.
  877.         if place_put_into_input_buffer = 1 then
  878.           place_put_into_input_buffer := max_input_buffer;
  879.         else
  880.           place_put_into_input_buffer := place_put_into_input_buffer - 1 ;
  881.         end if;
  882.       end if;
  883.       place_get_from_input_buffer := new_place ;
  884.       --now, save extended_character into the correct place to be gotten next...
  885.       input_buffer(place_get_from_input_buffer) 
  886.                   := character'val(integer(an_extended_character));
  887.     end;
  888.         
  889.     -- Now, we have the non-transparent I/O routines
  890.         
  891.     procedure move_crt( c : character ) is
  892.     begin
  893.       if c = ASCII.CR then
  894.         CRT_COL := 1 ;
  895.       elsif c = ASCII.LF then
  896.         if CRT_LINE < TOTAL_CRT_LINE then
  897.           CRT_LINE := CRT_LINE + 1 ;
  898.         end if;
  899.       elsif c = ASCII.BS then
  900.         if crt_col = 1 then
  901.           -- we are at the first character on the line
  902.           CRT_COL := TOTAL_CRT_COL;
  903.           if crt_line = 1 then
  904.             -- we are at the first line on the screen
  905.             CRT_LINE := TOTAL_CRT_LINE;
  906.           else
  907.             CRT_LINE := CRT_LINE - 1 ;
  908.           end if;
  909.         else
  910.           CRT_COL := CRT_COL - 1 ;
  911.         end if;
  912.       elsif c = ASCII.BEL then
  913.         null;  -- No printable character
  914.       else
  915.         if crt_col = total_crt_col then
  916.           -- at the last column on the screen
  917.           CRT_COL := 1 ;
  918.           if CRT_LINE < TOTAL_CRT_LINE then
  919.             CRT_LINE := CRT_LINE + 1 ;
  920.           end if;
  921.         else
  922.           CRT_COL := CRT_COL + 1 ;
  923.         end if;
  924.       end if;
  925.     end;
  926.         
  927.     procedure put( item : in character ) is
  928.     begin
  929.       put_transparent(item);
  930.       move_crt(item);
  931.     end;
  932.      
  933.     procedure put( item : in pstring    ) is
  934.       c : CHARACTER;
  935.     begin
  936.       put_transparent(item);
  937.       for place in 1 .. length(item) loop
  938.         c := item.data(place);
  939.         move_crt(c);
  940.       end loop;
  941.     end;
  942.      
  943.     procedure put( item : in string    ) is
  944.       c : CHARACTER;
  945.     begin
  946.       put_transparent(item);
  947.       for place in 1 .. item'length loop
  948.         c := item(place);
  949.         move_crt(c);
  950.       end loop;
  951.     end;
  952.      
  953.     procedure put_spaces( number : integer ) is
  954.     begin
  955.       for i in 1 .. number loop
  956.         put(' ');
  957.       end loop;
  958.     end;
  959.      
  960.     procedure put( item : in INTEGER     ;
  961.                    width: in INTEGER     := default_width  ;
  962.                    base : in number_base := default_base ) is
  963.       new_string : pstring ;
  964.     begin
  965.       new_string := int_to_str(item,base);
  966.       if width > 0 then
  967.         --  We need to check for leading spaces
  968.         put_spaces( width - length(new_string) );
  969.       end if;
  970.       put(new_string);
  971.     end;
  972.      
  973.     procedure put_line is
  974.     begin
  975.       put_transparent(ASCII.CR);
  976.       -- put_transparent(ASCII.LF);
  977.       CRT_COL := 1 ;
  978.       if CRT_LINE < TOTAL_CRT_LINE then
  979.         CRT_LINE := CRT_LINE + 1 ;
  980.       end if;
  981.     end;
  982.      
  983.     function num_to_pstring( i : integer ; 
  984.                              base : number_base := default_base ) 
  985.                              return pstring is
  986.     begin
  987.       return int_to_str(i,base);
  988.     end;
  989.      
  990.     procedure terminate_Basic_IO_System is
  991.     begin
  992.       terminate_physical_io ;
  993.     end terminate_Basic_IO_System ;
  994.      
  995.     function clock return timer is                                     --###--
  996.       new_timer     : timer ;                                          --###--
  997.     begin -- clock                                                     --###--
  998.       calendar.split(calendar.clock,new_timer.year, new_timer.month ,  --###--
  999.                       new_timer.day  , new_timer.d_duration       ) ;  --###--
  1000.       return time_of( new_timer.year , new_timer.month              ,  --###--
  1001.                       new_timer.day  , new_timer.d_duration       ) ;  --###--
  1002.     end clock ;
  1003.      
  1004.     function year    ( date : timer ) return year_number   is
  1005.     begin -- year
  1006.       return date.year ;
  1007.     end year ;
  1008.      
  1009.     function month   ( date : timer ) return month_number  is
  1010.     begin -- month
  1011.       return date.month ;
  1012.     end month ;
  1013.      
  1014.     function day     ( date : timer ) return day_number    is
  1015.     begin -- day
  1016.       return date.day ;
  1017.     end day ;
  1018.      
  1019.     function seconds ( date : timer ) return day_duration  is
  1020.     begin -- seconds 
  1021.       return date.d_duration ;
  1022.     end seconds ;
  1023.      
  1024.     function day_of_week ( date : timer ) return day_of_week_name is
  1025.     begin -- day_of_week 
  1026.       return date.day_of_week ;
  1027.     end day_of_week ;
  1028.      
  1029.     function hour    ( date : timer ) return hour_number   is
  1030.     begin -- hour 
  1031.       return date.hour ;
  1032.     end hour ;
  1033.      
  1034.     function minute  ( date : timer ) return minute_number is
  1035.     begin -- minute 
  1036.       return date.minute ;
  1037.     end minute ;
  1038.      
  1039.     function second  ( date : timer ) return second_number is
  1040.     begin -- second
  1041.       return date.second ;
  1042.     end second ;
  1043.      
  1044.     procedure split  ( date     : in timer           ;
  1045.                        year     : out year_number    ;
  1046.                        month    : out month_number   ;
  1047.                        day      : out day_number     ;
  1048.                        seconds  : out day_duration ) is
  1049.     begin -- split
  1050.       year    := date.year ;
  1051.       month   := date.month ;
  1052.       day     := date.day ;
  1053.       seconds := date.d_duration ;
  1054.     end split ;
  1055.                         
  1056.     procedure split  ( date     : in timer           ;
  1057.                        year     : out year_number    ;
  1058.                        month    : out month_number   ;
  1059.                        day      : out day_number     ;
  1060.                        seconds  : out day_duration   ;
  1061.                        weekday  : out day_of_week_name ;
  1062.                        hour     : out hour_number    ;
  1063.                        minute   : out minute_number  ;
  1064.                        second   : out second_number) is
  1065.     begin -- split 
  1066.       year      := date.year ;
  1067.       month     := date.month ;
  1068.       day       := date.day ;
  1069.       seconds   := date.d_duration ;
  1070.       weekday   := date.day_of_week ;
  1071.       hour      := date.hour ;
  1072.       minute    := date.minute ;
  1073.       second    := date.second ;
  1074.     end split ;
  1075.                         
  1076.     function time_of ( year     : in year_number     ;
  1077.                        month    : in month_number    ;
  1078.                        day      : in day_number      ;
  1079.                        seconds  : in day_duration := 0.0 ) 
  1080.                                    return timer is                     --###--
  1081.       h : hour_number   ;
  1082.       m : minute_number ;
  1083.       s : second_number ;
  1084.       remaining : day_duration ;
  1085.       new_timer : timer ;
  1086.       temp_float    : float   ;                                        --###--
  1087.       temp_duration : integer ;                                        --###--
  1088.     begin -- time_of 
  1089.       new_timer.year := year ;
  1090.       new_timer.month := month ;
  1091.       new_timer.day   := day   ;
  1092.       new_timer.d_duration := seconds ;
  1093.       temp_float := float( new_timer.d_duration ) ;                    --###--
  1094.       new_timer.hour := integer ( temp_float / 60.0 / 60.0 ) ;         --###--
  1095.       temp_float := temp_float - float( new_timer.hour ) * 60.0 * 60.0;--###--
  1096.       if temp_float < 0.0 then                                         --###--
  1097.         temp_float := 0.0 ; -- in cases of rounding could be negative..--###--
  1098.       end if ;                                                         --###--
  1099.       temp_duration := integer( temp_float ) ; -- 0 .. 3600            --###--
  1100.       new_timer.minute := temp_duration / 60 ;                         --###--
  1101.       new_timer.second := temp_duration - (new_timer.minute * 60) ;    --###--
  1102.       new_timer.day_of_week := figure_week_day( new_timer ) ;          --###--
  1103.       return new_timer ;                                               --###--
  1104.     end time_of ;
  1105.     
  1106.     function time_of ( year     : in year_number     ;
  1107.                        month    : in month_number    ;
  1108.                        day      : in day_number      ;
  1109.                        weekday  : in day_of_week_name;
  1110.                        hour     : in hour_number     ;
  1111.                        minute   : in minute_number   ;
  1112.                        second   : in second_number   ) return timer is
  1113.       new_week_day : day_of_week_name ;
  1114.       temp_float   : float ;                                           --###--
  1115.     begin -- time_of
  1116.       new_week_day := figure_week_day ( timer'( year , month , day , 0.0 ,
  1117.                                                 sunday , 0, 0, 0 ) ) ; --###--
  1118.       temp_float := float( second ) +                                  --###--
  1119.               60.0 * ( float( minute ) + 60.0 * float( hour ) ) ;      --###--
  1120.       return ( year , month , day , day_duration( temp_float ) ,       --###--
  1121.                       new_week_day , hour , minute , second) ;         --###--
  1122.     end time_of ;                                                      --###--
  1123.          
  1124.    
  1125.     function figure_week_day ( date : timer ) return day_of_week_name is
  1126.       -- assume unknown week day and return correct one
  1127.       val : integer ;
  1128.       years  : integer ;
  1129.       pre_days : integer ;
  1130.     begin -- figure_week_day
  1131.       val := 0 ;
  1132.       years :=  date.year - 1 - 1900 ;
  1133.         -- figure the number of days since December 31, 1900
  1134.       val   :=  ( years mod 7 ) * 365 ;  -- tells number of days within year grp
  1135.       val   :=  val + ( date.year - 1 - 1900 ) / 4 ;
  1136.         -- add a day for each leap year
  1137.       val   :=  val - ( date.year - 1 - 1900 ) / 100 ;
  1138.         -- subtract a day for each century
  1139.       case date.month is
  1140.         when 01     => pre_days := 000 ;
  1141.         when 02     => pre_days := 031 ;
  1142.         when 03     => pre_days := 059 ;
  1143.         when 04     => pre_days := 090 ;
  1144.         when 05     => pre_days := 120 ;
  1145.         when 06     => pre_days := 151 ;
  1146.         when 07     => pre_days := 181 ;
  1147.         when 08     => pre_days := 212 ;
  1148.         when 09     => pre_days := 243 ;
  1149.         when 10     => pre_days := 273 ;
  1150.         when 11     => pre_days := 304 ;
  1151.         when 12     => pre_days := 334 ;
  1152.       end case ;
  1153.       if date.month > 2 
  1154.       and then ( ( date.year mod   4 )  = 0 )
  1155.       and then ((( date.year mod 100 ) /= 0 ) or ( ( date.year mod 400 ) = 0 ) )
  1156.                 then
  1157.         pre_days := pre_days + 1 ;
  1158.       end if ;
  1159.       val := val + pre_days + date.day + 1 ;
  1160.       val := val mod 7 ; -- seven days per week
  1161.       case val is
  1162.         when 00     => return sunday    ;
  1163.         when 01     => return monday    ;
  1164.         when 02     => return tuesday   ;
  1165.         when 03     => return wednesday ;
  1166.         when 04     => return thursday  ;
  1167.         when 05     => return friday    ;
  1168.         when 06     => return saturday  ;
  1169.         when others => return sunday    ;
  1170.       end case ;
  1171.     end figure_week_day ;
  1172.      
  1173.   begin -- Basic_IO_System 
  1174.     -- PHYSICAL_IO   by SAIC/Clearwater Wicat I/O Routines     07 Jan 85
  1175.     -- Basic_IO_System by SAIC/Clearwater Primary I/O Routines        11 Jan 85
  1176.     c_io.Open(ot_file,c_io.out_file,output_name);                       --###--
  1177.   end Basic_IO_System ;
  1178.  
  1179.   --$$$- BasicIOS
  1180.  
  1181. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1182. --crt
  1183. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1184.  
  1185. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1186. --dwindows
  1187. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1188.  
  1189.   --$$$+ CWINDOWS
  1190.    
  1191.   --
  1192.   -- File 004 (part 1)
  1193.   --
  1194.   -- Editor Written By Robert S. Cymbalski
  1195.   --                   Science Applications International Corporation
  1196.   --                   Energy Systems Group
  1197.   --                   Ada Software Development Project Team
  1198.   --                   2280 U.S. Highway 19 North, Suite 120
  1199.   --                   Clearwater, Florida  33575
  1200.   --
  1201.   -- Window Manager Revised from text Copyright (c) 1984 , R.S.Cymbalski
  1202.  
  1203.   with text_io ;
  1204.    
  1205.   with string_library     ;
  1206.   use  string_library     ;
  1207.    
  1208.   with basic_io_system    ;
  1209.        
  1210.   with crt_customization  ;
  1211.   use  crt_customization  ;
  1212.   use  crt ;
  1213.   use  editor_customization ;
  1214.    
  1215.   package crt_windows is
  1216.             
  1217.     maximum_prompt_lines : constant integer := 1 ;
  1218.        
  1219.     subtype prompt_line_index is integer range 1 .. maximum_prompt_lines ;
  1220.        
  1221.     subtype window_line_number         is basic_io_system.a_screen_line_number ;
  1222.     subtype window_column_number       is integer ;
  1223.       -- integer because we don't know the limits on columns over
  1224.        
  1225.     type WINDOW_POINTER is private ;
  1226.         
  1227.     Function current_window return window_pointer ;
  1228.         
  1229.     Function no_window return window_pointer ;
  1230.      
  1231.     Procedure set_current_window ( to : in window_pointer ) ;
  1232.       -- *** set the current window as requested
  1233.        
  1234.     procedure clear_window ( which_window : in window_pointer ) ;
  1235.       -- Clear the entire window of all text 
  1236.           
  1237.     procedure clear_prompt ( which_window : in window_pointer ) ;
  1238.       -- Clear the prompt line(s) of a window
  1239.         
  1240.     procedure Clear_Line       ( which_window : in window_pointer       ;
  1241.                                  line         : in window_line_number   ) ;
  1242.       -- Clear the Line Specified
  1243.           
  1244.     procedure Clear_End_Of_Line( which_window : in window_pointer       ;
  1245.                                  line         : in window_line_number   ;
  1246.                                  column       : in window_column_number ) ;
  1247.       -- Clear the Line Specified, from line,column to end of line
  1248.           
  1249.     procedure Clear_Prompt_End_Of_Line( which_window : in window_pointer ;
  1250.                                         line         : in window_line_number   ;
  1251.                                         column       : in window_column_number);
  1252.       -- Clear the Prompt Line Specified, from line,column to end of line
  1253.           
  1254.     procedure Clear_End_Of_Screen( which_window : in window_pointer     ;
  1255.                                  line         : in window_line_number   ;
  1256.                                  column       : in window_column_number ) ;
  1257.       -- Clear from Line, Column to the end of the window
  1258.           
  1259.     procedure goto_line_column ( which_window : in window_pointer ;
  1260.                                  line         : in window_line_number ;
  1261.                                  column       : in window_column_number ) ;
  1262.       -- Move to the specified line and column within a window.  Note that
  1263.       -- the first column and line are numbered #1.  A Window area is 
  1264.       -- exclusive of any prompt area
  1265.           
  1266.     procedure goto_Prompt_line_column ( which_window : in window_pointer ;
  1267.                                  line         : in window_line_number ;
  1268.                                  column       : in window_column_number ) ;
  1269.       -- Move to the specified line and column within a window's Prompt
  1270.       -- Area.  Note that the first column and line are numbered #1.  
  1271.           
  1272.     procedure set_prompt ( which_window : in window_pointer ;
  1273.                            which_prompt_line : in integer     ;
  1274.                            prompt_line  : in string           ) ;
  1275.       -- Set the prompt line as specified 
  1276.         
  1277.     procedure set_prompt ( which_window : in window_pointer ;
  1278.                            which_prompt_line : in integer     ;
  1279.                            prompt_line  : in pstring          ) ;
  1280.       -- Set the prompt line as specified 
  1281.           
  1282.     procedure save_prompt_temporarily ;
  1283.       -- save the prompt area because an error message will be written
  1284.      
  1285.     procedure restore_prompt_after_temporary_save ;
  1286.       -- and restore the prompt area after that error message 
  1287.        
  1288.     Function Lowest_Column_Number  ( which_window : in window_pointer )
  1289.                                    return window_column_number ;
  1290.        -- Return the lowest column number available on the window
  1291.       
  1292.     Function Highest_Column_Number ( which_window : in window_pointer )
  1293.                                    return window_column_number ;
  1294.        -- Return the highest column number available on the window
  1295.       
  1296.     Function Window_Height         ( which_window : in window_pointer )
  1297.                                    return window_line_number ;
  1298.        -- return the number of text lines available in window
  1299.         
  1300.     Function current_line   return window_line_number ;
  1301.      
  1302.     Function current_col    return window_column_number ;
  1303.      
  1304.     function current_shift  return integer ;
  1305.      
  1306.     procedure set_reverse ( do_reverse : boolean ) ;
  1307.        -- set current_window.next_will_be_reverse and do the
  1308.        -- appropriate crt command
  1309.         
  1310.     procedure set_reverse_if_necessary ( do_reverse : boolean ) ;
  1311.        -- set current_window.next_will_be_reverse and do the
  1312.        -- appropriate crt command only if we are not set correctly
  1313.         
  1314.     function current_reverse return boolean ;
  1315.        -- return the current setting of the reverse flag 
  1316.      
  1317.     procedure put( c : character ) ;
  1318.       -- puts a character into the current window.  We only recognize
  1319.       -- ' ' .. tilde and ascii.cr.  Ascii.cr moves to the first column
  1320.       -- of the next line
  1321.        
  1322.     procedure put( s : string ) ;
  1323.       -- puts out a string of all printable characters
  1324.        
  1325.     procedure put( s : pstring ) ;
  1326.       -- puts out a pstring of all printable characters
  1327.        
  1328.     procedure put( num : integer ; 
  1329.                    width: in INTEGER     := basic_io_system.default_width  ;
  1330.                    base : in number_base := basic_io_system.default_base ) ;
  1331.        
  1332.     Procedure ADJUST_WINDOW ( which_window : in out WINDOW_POINTER ;
  1333.                              ADD_TO_TOP, ADD_TO_BOTTOM : in INTEGER ) ;
  1334.       -- *** modifies the number of screen lines the window occupies
  1335.        
  1336.     Function CREATE_WINDOW ( left_screen_column ,
  1337.                  right_screen_column : basic_io_system.a_screen_column_number ;
  1338.                  top_screen_line,        
  1339.                  bottom_screen_line  : in window_line_number   ;
  1340.                  status_line_on_top  : in boolean := false    ; 
  1341.                  prompt_height       : in window_line_number := 0 )
  1342.                                              return WINDOW_POINTER  ;
  1343.       -- *** defines a new screen area 
  1344.        
  1345.     procedure redisplay ( which_window : window_pointer ) ;
  1346.       -- redisplay the entire window
  1347.        
  1348.     Procedure SHIFT ( SHIFT_WINDOW : in out WINDOW_POINTER ;
  1349.                       SHIFT_AMOUNT : in INTEGER ) ;
  1350.       -- *** change which relative character position on the line will be
  1351.       --     displayed in column 1 on the screen.  Applies to any buffer 
  1352.       --     mapped to the window.
  1353.          
  1354.     procedure dispose_window ( old_window : in out window_pointer ) ;
  1355.       -- get rid of an old window 
  1356.      
  1357.     procedure bell ;
  1358.      
  1359.     procedure scroll_up_entire_window (
  1360.                         number_of_lines_to_scroll : window_line_number ) ;
  1361.      
  1362.     procedure scroll_down_entire_window (
  1363.                         number_of_lines_to_scroll : window_line_number ) ;
  1364.     
  1365.     -- special functions
  1366.      
  1367.     procedure KEY_INPUT( CH : out CHARACTER; OR_SPECIAL : out SPECIAL_KEYS);
  1368.       -- Reads in a character from the keyboard and returns the character
  1369.       -- and its special meaning.  If a function key or an escape sequence
  1370.       -- is entered then CH contains the function number.  
  1371.       
  1372.     procedure flush_input ;
  1373.       -- Clears the input buffer of any characters entered from the
  1374.       -- keyboard, but not yet read
  1375.    
  1376.     function read_character return character ;
  1377.       -- read in a character and return.  This routine cannot read in 
  1378.       -- special characters......only ' ' .. '~'
  1379.        
  1380.     procedure wait_for_character ( character_to_wait_for : character ) ;
  1381.       -- wait until the specified character is typed.  Beep in case
  1382.       -- of mistakes
  1383.        
  1384.     type CHARACTER_SET is array (CHARACTER) of BOOLEAN;
  1385.            
  1386.     procedure CLEAR_SET( A_SET : in out character_set ) ;
  1387.          
  1388.     function IN_SET( ELEMENT : in CHARACTER ;
  1389.                      A_SET   : in character_set ) return BOOLEAN ;
  1390.        
  1391.     function map_up ( c : character ) return character ;
  1392.      
  1393.     function map_down ( c : character ) return character ;
  1394.      
  1395.     function goodchar( allowed : character_set ; default : character ;
  1396.                        map_to_upper_case : boolean := true )
  1397.                        return character ;
  1398.       -- get in a single character.  Map to upper case.  Keep
  1399.       -- reading until a <return> (in which case default is returned) or
  1400.       -- else a character is read which is in the allowed set.  Then, 
  1401.       -- echo the character to the screen and return
  1402.        
  1403.     function char_within_range_or_abort ( default , lowest_item , 
  1404.                                                     highest_item : character ) 
  1405.                                           return character ;
  1406.       -- get a character which is within the range specified 
  1407.        
  1408.     function char_or_abort ( default , c_1 , c_2 , c_3 , c_4 ,
  1409.                                        c_5 , c_6 , c_7 , c_8 ,
  1410.                                        c_9 : in character := ascii.nul )
  1411.                              return character ;
  1412.       -- get in a character which is an ascii.cr or else one of the nine
  1413.       -- allowed characters or else a <reject>.  In case of the <reject>,
  1414.       -- return ascii.nul , otherwise, if a ascii.cr, return default 
  1415.       -- (as long as it is allowed in 1..9) 
  1416.        
  1417.     function STRING_READ( FORMAT : in PSTRING         ;
  1418.                           DEFAULT: in PSTRING         ; -- := "";
  1419.                           LENGTH : in window_column_number := 0 ;
  1420.                           COL    : in window_column_number := 0 ;
  1421.                           LINE   : in window_line_number   := 0 ;
  1422.                           ALLOW_LOWER_CASE : in BOOLEAN  := TRUE
  1423.                         ) return PSTRING;
  1424.       -- Reads in characters from the keyboard depending on what format
  1425.       -- characters are in the format string, and returns this input string.
  1426.       -- The default string is returned if a <return> is typed at the
  1427.       -- request for an input string.
  1428.       -- The cursor is repositioned on the screen to COL,LINE in preparation
  1429.       -- for this input request.  If either is 0, then the cursor is not
  1430.       -- re-positioned. If ALLOW_LOWER_CASE tells if you want characters
  1431.       -- typed in lower case to remain in lower case (true), or if they should
  1432.       -- be transposed into their upper case equivalents (false).
  1433.       -- The input string length is determined by LENGTH.  If LENGTH is 0,
  1434.       -- then the length is controlled by the length of FORMAT.  If LENGTH
  1435.       -- is greater than the length of FORMAT, then FORMAT is assumed to be
  1436.       -- lengthened to the right with blanks.
  1437.       --      The following Format Characters Are Recognized:
  1438.       --         'A' - Read in an alphabetic character
  1439.       --         '9' - Read in a numeric character
  1440.       --         'Z' - Read in an alpha-numeric character
  1441.       --         '~' - Read in a numeric character or '+' or '-'
  1442.       --         '.' - Read in a real number
  1443.       --         '^' - Read in a money amount such as +/- 1,234,567.89
  1444.       --         ' ' - Read in anything
  1445.       --         All other characters are inserted into the input string as
  1446.       --             though typed by the user.
  1447.    
  1448.     procedure get_character ( new_c       : out character ;
  1449.                               new_command : out crt_editor_command ) ;
  1450.       -- get a character or a command from the keyboard 
  1451.        
  1452.     function get_number ( line : in window_line_number   ;
  1453.                           col  : in window_column_number ;
  1454.                           smallest : in integer          ;
  1455.                           largest  : in integer          ;
  1456.                           len      : in integer          ;
  1457.                           default  : in integer          )
  1458.                           return integer ;
  1459.       -- get a number within the range if possible.  On reject/return
  1460.       -- simply return default
  1461.    
  1462.   private
  1463.      
  1464.     type window_character_position is
  1465.            record
  1466.              c         : character             := ' ' ;
  1467.              show_reverse : boolean            := false ;
  1468.            end record ;
  1469.             
  1470.     type window_actual_text is array 
  1471.       ( 1 .. basic_io_system.max_screen_columns ) of window_character_position ;
  1472.                 
  1473.     type window_line_of_text is
  1474.            record
  1475.              line_length : integer := 0 ;
  1476.              text        : window_actual_text ;
  1477.            end record ;
  1478.             
  1479.     type window_of_text is array ( 1 .. basic_io_system.max_screen_lines ) 
  1480.                of window_line_of_text ;
  1481.                 
  1482.     blank_window_line : constant window_line_of_text :=
  1483.         ( 0 , ( 1 .. basic_io_system.max_screen_columns => ( ' ' , false ) ) ) ;
  1484.      
  1485.     type prompt_area is array ( prompt_line_index 
  1486.                 range 1 .. maximum_prompt_lines ) of window_line_of_text ;
  1487.      
  1488.     type screen_window is 
  1489.       record
  1490.         -- The following are valid for both the Prompt and Text Areas
  1491.         left_screen_column ,
  1492.         right_screen_column : basic_io_system.a_screen_column_number ;
  1493.         screenwidth    : basic_io_system.a_screen_column_number ;
  1494.            
  1495.         -- The following are the actual physical boundries of the 
  1496.         -- Window itself
  1497.         top_screen_line,        
  1498.         bottom_screen_line  : window_line_number ;
  1499.            
  1500.         -- The following describe the Text Area
  1501.         text_window_height : window_line_number   ;
  1502.         top_text_line      : window_line_number   ; -- where text goes
  1503.         bottom_text_line   : window_line_number   ;
  1504.            
  1505.         -- The following describes the Prompt Area
  1506.         status_line_on_top : boolean ;
  1507.         prompt_height  : window_line_number   ;
  1508.         top_prompt_line: window_line_number   ; -- where prompts go
  1509.         bottom_prompt_line : window_line_number ;
  1510.                 
  1511.         columns_over   : integer         ; -- because it is physical ;
  1512.        
  1513.         -- now, the text within the window
  1514.         text : window_of_text ;
  1515.         cursor_line : window_line_number ;
  1516.         cursor_col  : window_column_number ;
  1517.         next_will_be_reversed : boolean ;
  1518.          
  1519.         prompt_save_area : prompt_area ;
  1520.        
  1521.       end record ;
  1522.        
  1523.     type WINDOW_POINTER is access screen_window ;
  1524.         
  1525.     Real_Current_Window : window_Pointer ;
  1526.      
  1527.     char_in       : character ; -- what is the input character?
  1528.          
  1529.     compare_place : integer ;
  1530.            
  1531.     subtype extended_character is basic_io_system.extended_character ;
  1532.        
  1533.   end crt_windows ;
  1534.       
  1535.   package body crt_windows is
  1536.    
  1537.   --
  1538.   -- File 004 (part 2)
  1539.   --
  1540.   -- Editor Written By Robert S. Cymbalski
  1541.   --                   Science Applications International Corporation
  1542.   --                   Energy Systems Group
  1543.   --                   Ada Software Development Project Team
  1544.   --                   2280 U.S. Highway 19 North, Suite 120
  1545.   --                   Clearwater, Florida  33575
  1546.   --
  1547.   -- Window Manager Revised from text Copyright (c) 1984 , R.S.Cymbalski
  1548.  
  1549.     -- Current Assumption is that the prompt area is 1 line, and that 
  1550.     -- it is at the top line on the screen.  The rest of the screen consists
  1551.     -- of a single window.
  1552.         
  1553.     procedure set_line_column ( which_window : in     window_pointer ;
  1554.                     line : in window_line_number ;
  1555.                     col  : in basic_io_system.a_screen_column_number ) is
  1556.                --  Position the cursor on the line and column specified
  1557.                --  we know that which_window is an access variable so that
  1558.                --  we can have it as an in item and still change the
  1559.                --  contents of what it points to... because the caller 
  1560.                --  doesn't know that a simple cursor movement changes items
  1561.                --  contained in a window_pointer
  1562.     begin -- set_line_column
  1563.       crt.gotoxy( col , line ) ;
  1564.       which_window.cursor_line := line ;
  1565.       which_window.cursor_col  := col  ;
  1566.       if which_window.text(line).line_length < col - 1 then
  1567.         -- need to put in some spaces
  1568.         for posn in which_window.text(line).line_length + 1 .. col - 1 loop
  1569.           which_window.text(line).text(posn).c := ' ' ;
  1570.           which_window.text(line).text(posn).show_reverse := false ;
  1571.         end loop ;
  1572.         which_window.text(line).line_length := col - 1 ;
  1573.       end if ;
  1574.     end set_line_column ;
  1575.      
  1576.     -- Window Text Array
  1577.     -- Window.Text( Line_Number 1 .. basic_io_system.max_screen_lines)
  1578.     --            .line_length
  1579.     --            .text ( 1 .. basic_io_system.max_screen_columns ) 
  1580.     --                 .c
  1581.     --                 .show_reverse
  1582.     -- However, lines are really defined only for 
  1583.     --  top_prompt_line .. top_prompt_line + prompt_height - 1 
  1584.     --  top_text_line   .. top_text_line + text_window_height - 1 
  1585.     -- and columns for
  1586.     --  left_screen_column .. right_screen_column 
  1587.                         
  1588.     function current_window return window_pointer is
  1589.     begin
  1590.       return real_current_window ;
  1591.     end current_window ;
  1592.      
  1593.     function no_window return window_pointer is
  1594.     begin -- no_window
  1595.       return null ;
  1596.     end no_window ;
  1597.      
  1598.     procedure set_current_window ( to : in window_pointer ) is
  1599.       -- *** set the current window as requested
  1600.     begin -- set_current_window
  1601.       real_current_window := to ;
  1602.     end set_current_window ;
  1603.        
  1604.     procedure clear_window ( which_window : in window_pointer ) is
  1605.       -- Clear the entire window of all text 
  1606.     begin -- clear_window
  1607.       set_line_column( which_window , which_window.top_text_line ,
  1608.                        which_window.left_screen_column ) ;
  1609.       crt.do_crt(crt.erase_eos) ;  -- but really should stay in window 
  1610.       for linen in which_window.top_text_line .. which_window.bottom_text_line
  1611.                                     loop
  1612.         which_window.text(linen) := blank_window_line ;
  1613.       end loop ;
  1614.     end clear_window ;
  1615.           
  1616.     procedure clear_prompt ( which_window : in window_pointer ) is
  1617.       -- Clear the prompt line(s) of a window
  1618.     begin -- clear_prompt
  1619.       for indx in which_window.top_prompt_line .. 
  1620.                                           which_window.bottom_prompt_line loop
  1621.         set_line_column( which_window,Indx , which_window.left_screen_column ) ;
  1622.         crt.do_crt(crt.erase_eol); -- really should be only to end of window
  1623.         which_window.text(Indx) := blank_window_line ;
  1624.       end loop ;
  1625.     end clear_prompt ;
  1626.         
  1627.     procedure Clear_Line       ( which_window : in window_pointer       ;
  1628.                                  line         : in window_line_number   ) is
  1629.       -- Clear the Line Specified
  1630.     begin -- Clear_Line
  1631.       if ( line > 0 ) and ( line <= which_window.text_window_height ) then
  1632.         set_line_column( which_window ,
  1633.                          which_window.top_text_line + line - 1 ,
  1634.                          which_window.left_screen_column ) ;
  1635.         crt.do_crt(crt.erase_eol) ; -- really should be end of window
  1636.         which_window.text( which_window.top_text_line + line - 1 )
  1637.                        := blank_window_line ;
  1638.       end if ;  
  1639.     end Clear_Line ;
  1640.           
  1641.     procedure Clear_End_Of_Line( which_window : in window_pointer       ;
  1642.                                  line         : in window_line_number   ;
  1643.                                  column       : in window_column_number ) is
  1644.       -- Clear the Line Specified, from line,column to end of line
  1645.       actual_window_column : window_column_number ;
  1646.       w_line               : window_line_number   ;
  1647.     begin -- Clear_End_Of_Line
  1648.       if ( line > 0 ) and ( line <= which_window.text_window_height ) then
  1649.         -- we can get onto the right line
  1650.         actual_window_column := which_window.columns_over + column ;
  1651.         w_line := which_window.top_text_line + line - 1 ;
  1652.         if  ( actual_window_column > 0 ) 
  1653.         and ( actual_window_column <= which_window.right_screen_column ) then
  1654.           set_line_column( which_window , w_line  , actual_window_column ) ;
  1655.           crt.do_crt(crt.erase_eol) ; -- really should be end of window
  1656.           if which_window.text(w_line).line_length >= actual_window_column then
  1657.             which_window.text(w_line).line_length := actual_window_column - 1 ;
  1658.           end if;
  1659.         end if ;
  1660.       end if ;  
  1661.     end Clear_End_Of_Line ;
  1662.           
  1663.     procedure Clear_Prompt_End_Of_Line( which_window : in window_pointer ;
  1664.                                         line         : in window_line_number   ;
  1665.                                       column       : in window_column_number) is
  1666.       -- Clear the Prompt Line Specified, from line,column to end of line
  1667.       w_line               : window_line_number   ;
  1668.     begin -- clear_prompt_end_of_line
  1669.       if ( line > 0 ) and ( line <= which_window.prompt_height ) then
  1670.         if  ( column > 0 ) 
  1671.         and ( column <= which_window.right_screen_column ) then
  1672.           w_line := which_window.top_prompt_line + line - 1 ;
  1673.           set_line_column( which_window , w_line , column ) ;
  1674.           crt.do_crt(crt.erase_eol) ; -- really should be end of window
  1675.           if which_window.text(w_line).line_length >= column then
  1676.             which_window.text(w_line).line_length := column - 1 ;
  1677.           end if;
  1678.         end if ;
  1679.       end if ;  
  1680.     end clear_prompt_end_of_line ;
  1681.      
  1682.     procedure Clear_End_Of_Screen( which_window : in window_pointer     ;
  1683.                                  line         : in window_line_number   ;
  1684.                                  column       : in window_column_number ) is
  1685.       -- Clear from Line, Column to the end of the window
  1686.       actual_window_column : window_column_number ;
  1687.       w_line               : window_line_number   ;
  1688.     begin -- Clear_End_Of_Screen
  1689.       if ( line > 0 ) and ( line <= which_window.text_window_height ) then
  1690.         actual_window_column := which_window.columns_over + column ;
  1691.         w_line := which_window.top_text_line + line - 1 ;
  1692.         if  ( actual_window_column > 0 ) 
  1693.         and ( actual_window_column <= which_window.right_screen_column ) then
  1694.           set_line_column( which_window , w_line , actual_window_column ) ;
  1695.           crt.do_crt(crt.erase_eos) ; -- really should be end of window
  1696.           if which_window.text(w_line).line_length >= actual_window_column then
  1697.             which_window.text(w_line).line_length := actual_window_column - 1 ;
  1698.           end if;
  1699.           if w_line < which_window.bottom_text_line then
  1700.             for ln in w_line + 1 .. which_window.bottom_text_line loop
  1701.               which_window.text(ln) := blank_window_line ;
  1702.             end loop ;
  1703.           end if ;
  1704.         end if ;
  1705.       end if ;  
  1706.     end Clear_End_Of_Screen ;
  1707.      
  1708.     procedure goto_line_column ( which_window : in window_pointer ;
  1709.                                  line         : in window_line_number ;
  1710.                                  column       : in window_column_number ) is
  1711.       -- Move to the specified line and column within a window.  Note that
  1712.       -- the first column and line are numbered #1.  A Window area is 
  1713.       -- exclusive of any prompt area
  1714.       actual_window_column : window_column_number ;
  1715.       w_line               : window_line_number   ;
  1716.     begin -- GoTo_Line_Column
  1717.       if ( line > 0 ) and ( line <= which_window.text_window_height ) then
  1718.         actual_window_column := which_window.columns_over + column ;
  1719.         if  ( actual_window_column > 0 ) 
  1720.         and ( actual_window_column <= which_window.right_screen_column ) then
  1721.           w_line := which_window.top_text_line + line - 1 ;
  1722.           set_line_column( which_window , w_line , actual_window_column ) ;
  1723.         end if ;
  1724.       end if ;  
  1725.     end GoTo_Line_Column ;
  1726.           
  1727.     procedure goto_Prompt_line_column ( which_window : in window_pointer ;
  1728.                                  line         : in window_line_number ;
  1729.                                  column       : in window_column_number ) is
  1730.       -- Move to the specified line and column within a window's Prompt
  1731.       -- Area.  Note that the first column and line are numbered #1.  
  1732.       w_line : window_line_number ;
  1733.     begin -- goto_prompt_line_column
  1734.       if ( line > 0 ) and ( line <= which_window.prompt_height ) then
  1735.         if  ( column > 0 ) 
  1736.         and ( column <= which_window.right_screen_column ) then
  1737.           w_line := which_window.top_prompt_line + line - 1 ;
  1738.           set_line_column( which_window , w_line , column ) ;
  1739.         end if ;
  1740.       end if ;  
  1741.     end goto_prompt_line_column ;
  1742.           
  1743.     procedure set_prompt ( which_window : in window_pointer ;
  1744.                            which_prompt_line : in integer     ;
  1745.                            prompt_line  : in string           ) is
  1746.       -- Set the prompt line as specified 
  1747.     begin -- Set_Prompt
  1748.       set_line_column( which_window , 
  1749.                        which_window.top_prompt_line + which_prompt_line - 1 ,
  1750.                        which_window.left_screen_column ) ;
  1751.       which_window.text( which_window.top_prompt_line 
  1752.                        + which_prompt_line - 1 ) := blank_window_line ;
  1753.       crt.do_crt(crt.erase_eol); -- really should be only to end of window
  1754.       -- We don't do any error checking on the length!
  1755.       crt_windows.put(prompt_line) ;
  1756.     end Set_Prompt ;
  1757.         
  1758.     procedure set_prompt ( which_window : in window_pointer ;
  1759.                            which_prompt_line : in integer     ;
  1760.                            prompt_line  : in pstring          ) is
  1761.       -- Set the prompt line as specified 
  1762.     begin -- Set_Prompt
  1763.       set_line_column( which_window , 
  1764.                        which_window.top_prompt_line + which_prompt_line - 1 ,
  1765.                        which_window.left_screen_column ) ;
  1766.       which_window.text( which_window.top_prompt_line 
  1767.                        + which_prompt_line - 1 ) := blank_window_line ;
  1768.       crt.do_crt(crt.erase_eol); -- really should be only to end of window
  1769.       -- We don't do any error checking on the length!
  1770.       crt_windows.put(prompt_line) ;
  1771.     end Set_Prompt ;
  1772.           
  1773.     procedure save_prompt_temporarily is
  1774.       -- save the prompt area because an error message will be written
  1775.     begin -- save_prompt_temporarily
  1776.       if real_current_window.prompt_height > 0 then
  1777.         for which_prompt_line in real_current_window.top_prompt_line 
  1778.                .. real_current_window.top_prompt_line 
  1779.                 + real_current_window.prompt_height - 1 loop
  1780.           real_current_window.prompt_save_area(which_prompt_line)
  1781.                           := real_current_window.text( 
  1782.                                   real_current_window.top_prompt_line
  1783.                                    + which_prompt_line - 1 ) ;
  1784.         end loop ;
  1785.       end if ;
  1786.     end save_prompt_temporarily ;
  1787.      
  1788.     procedure restore_prompt_after_temporary_save is
  1789.       -- and restore the prompt area after that error message 
  1790.       remember_reverse : boolean ;
  1791.     begin -- restore_prompt_after_temporary_save 
  1792.       if real_current_window.prompt_height > 0 then
  1793.         clear_prompt( real_current_window ) ;
  1794.         remember_reverse := real_current_window.next_will_be_reversed ;
  1795.         for which_prompt_line in real_current_window.top_prompt_line 
  1796.                .. real_current_window.top_prompt_line 
  1797.                 + real_current_window.prompt_height - 1 loop
  1798.           -- through each of the various prompt lines
  1799.           real_current_window.text(real_current_window.top_prompt_line
  1800.                                    + which_prompt_line - 1 ).line_length := 0 ;
  1801.           set_line_column( real_current_window ,
  1802.                            real_current_window.top_prompt_line
  1803.                                 + which_prompt_line - 1, 
  1804.                            real_current_window.left_screen_column ) ;
  1805.           -- We don't do any error checking on the length!
  1806.           -- now, we need to output each of the locations
  1807.           for posn in real_current_window.left_screen_column ..
  1808.                          real_current_window.right_screen_column loop
  1809.             if posn <= real_current_window.prompt_save_area(which_prompt_line)
  1810.                                   .line_length then
  1811.               set_reverse_if_necessary( real_current_window.prompt_save_area
  1812.                                       ( which_prompt_line ).text ( posn ).
  1813.                                         show_reverse ) ;
  1814.               put(real_current_window.prompt_save_area(which_prompt_line)
  1815.                   .text(posn).c ) ;
  1816.             end if ;
  1817.           end loop ;
  1818.         end loop ;
  1819.         set_reverse_if_necessary(remember_reverse);
  1820.       end if ;
  1821.     end restore_prompt_after_temporary_save ;
  1822.      
  1823.     Function Lowest_Column_Number ( which_window : in window_pointer )
  1824.                                    return window_column_number is
  1825.        -- Return the Lowest column number available on the window
  1826.     begin -- Lowest_column_number
  1827.       if which_window.columns_over >= 0 then
  1828.         return 1 ; -- because we don't allow writing in "magic" columns
  1829.       else
  1830.         return - ( which_window.columns_over ) + 1 ;
  1831.       end if ;
  1832.     end Lowest_column_number ;
  1833.        
  1834.     Function Highest_Column_Number ( which_window : in window_pointer )
  1835.                                    return window_column_number is
  1836.        -- Return the highest column number available on the window
  1837.     begin -- highest_column_number
  1838.       return which_window.right_screen_column - which_window.columns_over ;
  1839.     end highest_column_number ;
  1840.        
  1841.     Function Window_Height         ( which_window : in window_pointer )
  1842.                                    return window_line_number is
  1843.        -- return the number of text lines available in window
  1844.     begin -- window_height
  1845.       return which_window.text_window_height ;
  1846.     end window_height ;
  1847.      
  1848.     Function current_line       return window_line_number is
  1849.     begin -- current_line
  1850.       if real_current_window.status_line_on_top then
  1851.         return real_current_window.cursor_line 
  1852.                     - real_current_window.prompt_height ;
  1853.       else 
  1854.         return real_current_window.cursor_line ;
  1855.       end if ;
  1856.     end current_line ;
  1857.      
  1858.     Function current_col        return window_column_number is
  1859.     begin -- current_col
  1860.       return real_current_window.cursor_col 
  1861.                   - real_current_window.left_screen_column + 1 ;
  1862.     end current_col ;
  1863.      
  1864.     function current_shift      return integer              is
  1865.     begin -- current_shift 
  1866.       return real_current_window.columns_over ;
  1867.     end current_shift ;
  1868.      
  1869.     procedure set_reverse ( do_reverse : boolean ) is
  1870.        -- set current_window.next_will_be_reverse and do the
  1871.        -- appropriate crt command
  1872.     begin -- set_reverse
  1873.       real_current_window.next_will_be_reversed := do_reverse ;
  1874.       if do_reverse then
  1875.         crt.change_crt( other_intensity ) ;
  1876.       else
  1877.         crt.change_crt( normal ) ;
  1878.       end if ;
  1879.     end set_reverse ;
  1880.         
  1881.     procedure set_reverse_if_necessary ( do_reverse : boolean ) is
  1882.        -- set current_window.next_will_be_reverse and do the
  1883.        -- appropriate crt command only if we are not set correctly
  1884.     begin -- set_reverse_if_necessary 
  1885.       if real_current_window.next_will_be_reversed /= do_reverse then
  1886.         set_reverse( do_reverse ) ;
  1887.       end if ;
  1888.     end set_reverse_if_necessary ;
  1889.         
  1890.     function current_reverse return boolean is
  1891.        -- return the current setting of the reverse flag 
  1892.     begin -- current_reverse
  1893.       return real_current_window.next_will_be_reversed ;
  1894.     end current_reverse ;
  1895.      
  1896.     procedure put( c : character ) is
  1897.       -- puts c into current window.  only recognise ' ' .. tilde and ascii.cr
  1898.       -- Ascii.cr moves to the first column of the next line
  1899.       col : window_column_number ;
  1900.     begin -- put
  1901.       if c = ascii.cr then
  1902.         if real_current_window.cursor_line 
  1903.                                    = real_current_window.bottom_screen_line then
  1904.           -- we need to scroll......
  1905.           scroll_up_entire_window(1);
  1906.           real_current_window.cursor_line 
  1907.                                   := real_current_window.bottom_screen_line ;
  1908.         else
  1909.           real_current_window.cursor_line 
  1910.                                         := real_current_window.cursor_line + 1 ;
  1911.         end if ;
  1912.         set_line_column( real_current_window ,
  1913.                          real_current_window.cursor_line ,
  1914.                          real_current_window.left_screen_column ) ;
  1915.       elsif c = ascii.bs then
  1916.         if real_current_window.cursor_col 
  1917.                                   > real_current_window.left_screen_column then 
  1918.           basic_io_system.put(ascii.bs);
  1919.           real_current_window.cursor_col  := real_current_window.cursor_col- 1 ;
  1920.         end if ;
  1921.       else
  1922.         col := real_current_window.cursor_col ;
  1923.         if col <= real_current_window.right_screen_column then
  1924.           basic_io_system.put(c);
  1925.           real_current_window.text(real_current_window.cursor_line).text(col)
  1926.                  := ( c , real_current_window.next_will_be_reversed ) ;
  1927.           if real_current_window.text(
  1928.                          real_current_window.cursor_line).line_length < col then
  1929.             real_current_window.text(
  1930.                               real_current_window.cursor_line).line_length:=col;
  1931.           end if ;
  1932.           if col = real_current_window.right_screen_column then
  1933.             crt_windows.put(ascii.cr);
  1934.           else
  1935.             real_current_window.cursor_col := col + 1 ;
  1936.           end if ;
  1937.         end if ;
  1938.       end if ;
  1939.     end put ;
  1940.        
  1941.     procedure put( s : string ) is
  1942.       -- all printable characters
  1943.     begin -- put
  1944.       crt_windows.put( string_to_pstring(s) ) ;
  1945.     end put ;
  1946.        
  1947.     procedure put( s : pstring ) is
  1948.       -- all printable characters
  1949.       col : window_column_number ;
  1950.       ps  : pstring ;
  1951.       w_line : window_line_number ;
  1952.       new_position : integer ; -- integer -- to skip the error checking...
  1953.       highest_position : window_column_number := real_current_window.
  1954.                                                     right_screen_column ;
  1955.     begin -- put
  1956.       col := real_current_window.cursor_col ;
  1957.       w_line := real_current_window.cursor_line ;
  1958.       ps := s ;
  1959.       new_position := col + length(ps ) ;
  1960.       if new_position <= highest_position + 1 then
  1961.         basic_io_system.put(ps);
  1962.       elsif col <= highest_position then
  1963.         -- truncate
  1964.         set_length(ps,highest_position - col + 1);
  1965.         basic_io_system.put(ps);
  1966.         new_position := highest_position + 1 ;
  1967.       else
  1968.         -- else at right edge of window
  1969.         ps := string_library.blank_line ;
  1970.       end if ;
  1971.       for clm in 1 .. length(ps) loop
  1972.         real_current_window.text(w_line).text(col + clm - 1 ) :=
  1973.             ( ps.data(clm) , real_current_window.next_will_be_reversed ) ;
  1974.       end loop ;
  1975.       if real_current_window.text(w_line).line_length < new_position - 1 then
  1976.         real_current_window.text(w_line).line_length := new_position - 1 ;
  1977.       end if ;
  1978.       if new_position > highest_position then
  1979.         crt_windows.put(ascii.cr);
  1980.       else
  1981.         real_current_window.cursor_col := new_position ;
  1982.       end if ;
  1983.     end put ;
  1984.        
  1985.     procedure put( num : integer ; 
  1986.                    width: in INTEGER     := basic_io_system.default_width  ;
  1987.                    base : in number_base := basic_io_system.default_base ) is
  1988.       -- number within the width indicated
  1989.       temp_string : string_library.pstring ;
  1990.     begin -- put 
  1991.       temp_string := int_to_str( num , base ) ;
  1992.       while length(temp_string) < width loop
  1993.         temp_string := " " & temp_string ;
  1994.       end loop ;
  1995.       put(temp_string);
  1996.     end put ;
  1997.        
  1998.     Procedure ADJUST_WINDOW ( which_window : in out WINDOW_POINTER ;
  1999.                               ADD_TO_TOP, ADD_TO_BOTTOM : in INTEGER ) is
  2000.       new_top , new_bottom : integer ;
  2001.     begin -- adjust_window 
  2002.       new_top := which_window.top_screen_line - add_to_top ;
  2003.       new_bottom := which_window.bottom_screen_line + add_to_bottom ;
  2004.       if new_top < 1 then
  2005.         new_top := 1;
  2006.       end if ;
  2007.       if new_bottom > basic_io_system.total_crt_line then
  2008.         new_bottom := basic_io_system.total_crt_line ;
  2009.       end if ;
  2010.       which_window.top_screen_line     := new_top ;
  2011.       which_window.bottom_screen_line  := new_bottom ;
  2012.       -- status and text areas 
  2013.       if which_window.status_line_on_top then
  2014.         -- do it
  2015.         which_window.top_prompt_line   := new_top ;
  2016.         which_window.top_text_line     := new_top 
  2017.                                                 + which_window.prompt_height ;
  2018.         which_window.text_window_height:= new_bottom 
  2019.                                                 - which_window.prompt_height ;
  2020.       else
  2021.         -- status line on bottom 
  2022.         which_window.top_prompt_line   := new_bottom + 1 
  2023.                                                 - which_window.prompt_height ;
  2024.         which_window.top_text_line     := new_top ;
  2025.         which_window.text_window_height:= new_bottom 
  2026.                                                 - which_window.prompt_height ;
  2027.       end if ;
  2028.       which_window.bottom_text_line := which_window.top_text_line 
  2029.                                        + which_window.text_window_height - 1 ;
  2030.       which_window.bottom_prompt_line:=which_window.top_prompt_line
  2031.                                        + which_window.prompt_height - 1 ;
  2032.     end adjust_window ;
  2033.      
  2034.     Function CREATE_WINDOW ( left_screen_column ,
  2035.                  right_screen_column : basic_io_system.a_screen_column_number ;
  2036.                  top_screen_line,        
  2037.                  bottom_screen_line  : in window_line_number   ;
  2038.                  status_line_on_top  : in boolean := false    ; 
  2039.                  prompt_height       : in window_line_number := 0 )
  2040.                                              return WINDOW_POINTER  is
  2041.       new_window : window_pointer ;
  2042.     begin -- create_window 
  2043.       -- we do not do error checking here
  2044.       new_window := new screen_window  ;
  2045.       new_window.left_screen_column  := left_screen_column ;
  2046.       new_window.right_screen_column := right_screen_column ;
  2047.       new_window.screenwidth         := right_screen_column 
  2048.                                                - left_screen_column + 1 ;
  2049.       new_window.top_screen_line     := top_screen_line ;
  2050.       new_window.bottom_screen_line  := bottom_screen_line ;
  2051.       new_window.text_window_height  := bottom_screen_line
  2052.                                                - top_screen_line + 1 
  2053.                                                - prompt_height ;
  2054.       if status_line_on_top then
  2055.         new_window.top_text_line     := top_screen_line              
  2056.                                                + prompt_height ;
  2057.         new_window.top_prompt_line   := top_screen_line ;
  2058.       else
  2059.         new_window.top_text_line     := top_screen_line ;
  2060.         new_window.top_prompt_line   := bottom_screen_line
  2061.                                                - prompt_height + 1 ;
  2062.       end if ;
  2063.       new_window.status_line_on_top  := status_line_on_top ;
  2064.       new_window.prompt_height       := prompt_height ;
  2065.       new_window.bottom_text_line := new_window.top_text_line 
  2066.                                        + new_window.text_window_height - 1 ;
  2067.       new_window.bottom_prompt_line:=new_window.top_prompt_line
  2068.                                        + new_window.prompt_height - 1 ;
  2069.       new_window.cursor_line := 0 ;
  2070.       new_window.cursor_col  := 0 ;
  2071.       new_window.next_will_be_reversed := false ;
  2072.       new_window.columns_over := 0 ;
  2073.       return new_window ;
  2074.     end create_window ;
  2075.         
  2076.     procedure redisplay ( which_window : window_pointer ) is
  2077.       -- redisplay the entire window 
  2078.       last_was_reverse : boolean ;
  2079.       old_reverse      : boolean ;
  2080.       next_pos         : window_character_position ;
  2081.     begin -- redisplay
  2082.       last_was_reverse := real_current_window.next_will_be_reversed ;
  2083.       old_reverse      := last_was_reverse ;
  2084.       for ln in which_window.top_screen_line .. 
  2085.                 which_window.bottom_screen_line loop
  2086.         if which_window.text(ln).line_length > 0 then
  2087.           set_line_column( which_window,ln,which_window.left_screen_column ) ;
  2088.           for posn in 1 .. which_window.text(ln).line_length loop
  2089.             next_pos := which_window.text(ln).text(posn) ;
  2090.             if next_pos.show_reverse /= last_was_reverse then
  2091.               last_was_reverse := not last_was_reverse ;
  2092.               set_reverse(last_was_reverse) ;
  2093.             end if ;
  2094.             basic_io_system.put(next_pos.c);
  2095.           end loop ;
  2096.         end if ;
  2097.       end loop ;
  2098.       if last_was_reverse /= old_reverse then
  2099.         -- must set reversed as appropriate
  2100.         set_reverse(old_reverse);
  2101.         -- sets it in current_window 
  2102.       end if ;
  2103.     end redisplay ;
  2104.      
  2105.     Procedure SHIFT ( SHIFT_WINDOW : in out WINDOW_POINTER ;
  2106.                       SHIFT_AMOUNT : in INTEGER ) is
  2107.       -- *** change which relative character position on the line  *** --
  2108.       -- *** will be displayed in column 1 on the screen.  Applies *** --
  2109.       -- *** to any buffer mapped to the window.                   *** --
  2110.       -- *** + moves column 1 right on the screen      *** --
  2111.       -- *** A Minus moves it left.  If shift is set to 5 you      *** --
  2112.       -- ***   could put a line number in the first five columns   *** --
  2113.     begin -- shift
  2114.       shift_window.columns_over := shift_window.columns_over + shift_amount ;
  2115.     end shift ;
  2116.          
  2117.     procedure dispose_window ( old_window : in out window_pointer ) is
  2118.       -- get rid of an old window 
  2119.     begin -- dispose_window
  2120.       null;
  2121.     end dispose_window ;
  2122.          
  2123.     procedure bell is
  2124.     begin
  2125.       basic_io_system.put(ascii.bel);
  2126.     end bell ;
  2127.      
  2128.     procedure scroll_up_entire_window (
  2129.                         number_of_lines_to_scroll : window_line_number ) is
  2130.     begin -- scroll_up_entire_window
  2131.       -- we want to scroll the text area up
  2132.       if crt_has( scroll_middle_screen_up ) then
  2133.         scroll_up_middle_screen ( real_current_window.top_text_line ,
  2134.                                   number_of_lines_to_scroll ) ;
  2135.       else
  2136.         save_prompt_temporarily ;
  2137.         scroll_up_entire_screen ( number_of_lines_to_scroll ) ;
  2138.         restore_prompt_after_temporary_save ;
  2139.       end if ;
  2140.       for ln in real_current_window.top_text_line .. 
  2141.                 real_current_window.bottom_text_line 
  2142.                 - number_of_lines_to_scroll loop
  2143.         real_current_window.text(ln) 
  2144.           := real_current_window.text(ln + number_of_lines_to_scroll );
  2145.       end loop ;
  2146.       for posn in real_current_window.bottom_text_line 
  2147.                               - number_of_lines_to_scroll + 1 
  2148.                                  .. real_current_window.bottom_text_line loop
  2149.         real_current_window.text(posn) := blank_window_line ;
  2150.       end loop ;
  2151.     end scroll_up_entire_window ;
  2152.      
  2153.     procedure scroll_down_entire_window (
  2154.                         number_of_lines_to_scroll : window_line_number ) is
  2155.     begin -- scroll_down_entire_window
  2156.       null ;
  2157.     end scroll_down_entire_window ;
  2158.  
  2159.   --
  2160.   -- File 004 (part 3)
  2161.   --
  2162.   -- Editor Written By Robert S. Cymbalski
  2163.   --                   Science Applications International Corporation
  2164.   --                   Energy Systems Group
  2165.   --                   Ada Software Development Project Team
  2166.   --                   2280 U.S. Highway 19 North, Suite 120
  2167.   --                   Clearwater, Florida  33575
  2168.   --
  2169.   -- Window Manager Revised from text Copyright (c) 1984 , R.S.Cymbalski
  2170.  
  2171.     procedure KEY_INPUT( CH : out CHARACTER; OR_SPECIAL : out SPECIAL_KEYS) is
  2172.       -- Reads in a character from the keyboard and returns the character
  2173.       -- and its special meaning.  If a function key or an escape sequence
  2174.       -- is entered then CH contains the function number.  
  2175.          
  2176.       extended_character_in : extended_character;
  2177.       temp_ch : character ;
  2178.       temp_or_special : special_keys ;
  2179.              
  2180.       procedure get_next_in is
  2181.         -- get the next character in;
  2182.       begin -- get_next_in
  2183.         extended_character_in := basic_io_system.get_transparent ;
  2184.         if extended_character_in < extended_character(128) then 
  2185.           char_in := CHARACTER'VAL( INTEGER(extended_character_in) );
  2186.         else
  2187.           char_in := ASCII.NUL;
  2188.         end if;
  2189.       end get_next_in;
  2190.            
  2191.       procedure process_non_printing_character is
  2192.         complete : boolean;
  2193.         function_bank : integer ; -- What bank of the function keys have we
  2194.                                   -- examined last?
  2195.            
  2196.         function is_it_this_bank return boolean is
  2197.           -- use function_bank to determine if this key starts this bank
  2198.              
  2199.           procedure do_ansi is
  2200.             -- we get here after geting the lead in characters <esc> "["
  2201.             -- and now must read in umbers until we hit chr(cbefore) or
  2202.             -- until we have an alphabetic character
  2203.             new_i:integer;
  2204.           begin -- do_ansi
  2205.             new_i := 0 ;
  2206.             loop
  2207.               get_next_in ;
  2208.               if extended_character_in = extended_character(0) then 
  2209.               -- this used to be chr(cbefore)
  2210.                 exit ; -- loop
  2211.               else
  2212.                 if char_in in '0' .. '9' then
  2213.                   new_i := new_i * 10 + extended_character_in 
  2214.                                                           - character'pos('0') ;
  2215.                 else
  2216.                   exit ; -- loop
  2217.                 end if;
  2218.               end if;
  2219.             end loop;
  2220.             extended_character_in := extended_character(new_i);
  2221.           end do_ansi;
  2222.                
  2223.         begin -- is_it_this_bank 
  2224.           -- is extended_character_IN = key_map(function_bank).lead_in(1) ?
  2225.           -- if we return TRUE, then we must have set CH and OR_SPECIAL
  2226.           compare_place := 1; -- where to compare first 
  2227.           loop
  2228.             exit when compare_place > key_map(function_bank).lead_in_length ;
  2229.             -- we have to compare a character
  2230.             if key_map(function_bank).lead_in(compare_place) = char_in then
  2231.               -- we match this character...great...
  2232.               compare_place := compare_place + 1;
  2233.               get_next_in;
  2234.             else
  2235.               -- put back current character and all leading ones....
  2236.               -- make first of string the current extended_character_in/char_in
  2237.               if compare_place = 1 then
  2238.                 return false ; -- nothing special on just plain old miss
  2239.               end if ;
  2240.               basic_io_system.replace_transparent_input(extended_character_in);
  2241.               for loop_pos in reverse 1 .. compare_place - 1 loop
  2242.                 basic_io_system.replace_transparent_input(extended_character(character'pos(
  2243.                               key_map(function_bank).lead_in(loop_pos) ) ) ) ;
  2244.               end loop;
  2245.               get_next_in ;
  2246.               return false ;
  2247.             end if;  -- we are comparing the charcter to the string
  2248.           end loop; -- looking for a match on the lead in string
  2249.           -- have lead_in matched now determine which key
  2250.           for i in 1 .. num_keys_within_type loop
  2251.             if key_map(function_bank).each_key(i).key 
  2252.                                                    /= extended_character(0) then
  2253.               if extended_character_in 
  2254.                                    = key_map(function_bank).each_key(i).key then
  2255.                 temp_ch:= character'val(
  2256.                    key_map(function_bank).each_key(i).final_key) ;
  2257.                 temp_or_special := 
  2258.                   key_map(function_bank).each_key(i).special_meaning ;
  2259.                 return true ;
  2260.               end if ;
  2261.             end if ;
  2262.           end loop ;
  2263.           -- never matched 
  2264.           -- put back current char and leading ones....
  2265.           -- make first of string the current extended_character_in/char_in
  2266.           basic_io_system.replace_transparent_input(extended_character_in);
  2267.           for loop_pos in reverse 1 .. 
  2268.                           key_map(function_bank).lead_in_length loop
  2269.             basic_io_system.replace_transparent_input(extended_character(character'pos(
  2270.                           key_map(function_bank).lead_in(loop_pos) ) ) ) ;
  2271.           end loop;
  2272.           get_next_in ;
  2273.           return false ;
  2274.         end is_it_this_bank ;
  2275.              
  2276.       begin -- process_non_printing_character 
  2277.         -- extended_character_IN is < ' ' or >= '~'
  2278.         -- Note: the reason ~ is included here is because some OLD terminals
  2279.         -- use it as a lead in character
  2280.         --
  2281.         if extended_character_in > extended_character(127) then
  2282.           -- this is an alternate character and only needs to be mapped...
  2283.           temp_ch:= CHARACTER'VAL(INTEGER(real_key_on_input( 
  2284.                                             integer( extended_character_in ))));
  2285.           temp_or_special := special_meaning_on_input ( 
  2286.                                             integer( extended_character_in ) ) ;
  2287.           return;
  2288.         end if;
  2289.         --
  2290.         -- we only get here if the above if statement is false...
  2291.         --
  2292.         function_bank := 1 ;
  2293.         loop
  2294.           complete := is_it_this_bank ;
  2295.           exit when complete;
  2296.           exit when ( function_bank = num_key_types ) ;
  2297.           function_bank := function_bank + 1 ; -- next bank to check
  2298.         end loop;
  2299.         if not complete then
  2300.           -- we did not find this extended_character to be a starter of the 
  2301.           -- sequence.   Simply map this character into a new one and return...
  2302.           temp_ch:= CHARACTER'VAL(INTEGER(real_key_on_input( 
  2303.                                             integer( extended_character_in ))));
  2304.           temp_or_special := special_meaning_on_input ( 
  2305.                                             integer( extended_character_in ) ) ;
  2306.         -- else do nothing, CH, and OR_SPECIAL are already set
  2307.         end if;
  2308.         --
  2309.         -- End up with CH and OR_SPECIAL set
  2310.       end process_non_printing_character ;
  2311.            
  2312.     begin -- key_input
  2313.       -- We are getting input text from the keyboard ...
  2314.       get_next_in; -- gets extended_character_in and char_in
  2315.       if  ( extended_character_in >= extended_character(32))       
  2316.         --  extended_character( CHARACTER'POS(' ') ) )
  2317.       and ( extended_character_in <  extended_character(127)) then 
  2318.         --  extended_character( CHARACTER'POS('~') ) ) then
  2319.         -- We have a printable character....
  2320.         -- Simply map this character into a new one and return...
  2321.         temp_ch:= CHARACTER'VAL(INTEGER(real_key_on_input( 
  2322.                                           integer( extended_character_in ))));
  2323.         temp_or_special := special_meaning_on_input ( 
  2324.                                           integer( extended_character_in ) ) ;
  2325.         -- And, we are done!!
  2326.       else
  2327.         -- We have a non_printable character which must be looked at
  2328.         process_non_printing_character;
  2329.         -- Done, getting a character (string) which was (started with)
  2330.         -- a non-printable character
  2331.       end if ;
  2332.       -- Here after we have read in a character (string) from the keyboard
  2333.       ch := temp_ch ;
  2334.       or_special := temp_or_special ;
  2335.     end key_input;
  2336.          
  2337.     procedure flush_input is
  2338.       -- Clears the input buffer of any characters entered from the
  2339.       -- keyboard, but not yet read
  2340.       t_extended_character : extended_character ;
  2341.     begin
  2342.       while basic_io_system.key_is_pressed loop
  2343.         t_extended_character := basic_io_system.get_transparent ;
  2344.       end loop ;
  2345.     end;
  2346.          
  2347.     function read_character return character is
  2348.       -- read in a character and return.  This routine cannot read in 
  2349.       -- special characters......only ' ' .. '~'
  2350.       chr : character ;
  2351.       spc : special_keys ;
  2352.     begin -- read_character 
  2353.       loop
  2354.         key_input( chr , spc ) ;
  2355.       exit when ( spc = key_character ) ; 
  2356.         bell;
  2357.       end loop ;
  2358.       return chr ;
  2359.     end read_character ;
  2360.      
  2361.     procedure wait_for_character ( character_to_wait_for : character ) is
  2362.       -- wait until the specified character is typed.  Beep in case
  2363.       -- of mistakes
  2364.     begin -- wait_for_character
  2365.       loop 
  2366.       exit when read_character = character_to_wait_for ;
  2367.       end loop ;
  2368.     end wait_for_character ;
  2369.      
  2370.     procedure CLEAR_SET( A_SET : in out CHARACTER_SET ) is
  2371.     begin
  2372.       for A_CHARACTER in CHARACTER'FIRST .. CHARACTER'LAST
  2373.       loop
  2374.         A_SET(A_CHARACTER) := FALSE ;
  2375.       end loop;
  2376.     end CLEAR_SET;
  2377.          
  2378.     function IN_SET( ELEMENT : in CHARACTER ;
  2379.                      A_SET   : in CHARACTER_SET ) return BOOLEAN is
  2380.     begin
  2381.       return A_SET(ELEMENT);
  2382.     end;
  2383.          
  2384.     function goodchar( allowed : character_set ; default : character ;
  2385.                        map_to_upper_case : boolean := true )
  2386.                        return character is
  2387.       -- get in a single character.  Map to upper case.  Keep
  2388.       -- reading until a <return> (in which case default is returned) or
  2389.       -- else a character is read which is in the allowed set.  Then, 
  2390.       -- echo the character to the screen and return
  2391.       chr : character ;
  2392.       spc : special_keys ;
  2393.       ValidSet : character_set ;
  2394.     begin -- goodchar 
  2395.       ValidSet := allowed ;
  2396.       if map_to_upper_case then
  2397.         for c in 'a' .. 'z' loop
  2398.           if allowed(c) then
  2399.             ValidSet( map_up(c) ) := true ;
  2400.           end if ;
  2401.         end loop ;
  2402.       end if ;
  2403.       loop
  2404.         key_input( chr , spc ) ;
  2405.         if ( spc = key_carriage_return ) or ( spc = key_line_feed ) then
  2406.           spc := key_character ;
  2407.           chr := default ;
  2408.         elsif map_to_upper_case then
  2409.           chr := map_up(chr);
  2410.         end if ;
  2411.       exit when ( spc = key_character ) and then in_set( chr , ValidSet ) ;
  2412.         bell;
  2413.       end loop ;
  2414.       put(chr);
  2415.       return chr ;
  2416.     end goodchar ;
  2417.        
  2418.     procedure get_character ( new_c       : out character ;
  2419.                               new_command : out crt_editor_command ) is
  2420.       -- get a character or a command from the keyboard 
  2421.       physical_c : character ;
  2422.       physical_command : crt.special_keys ;
  2423.     begin -- get_character
  2424.       key_input( physical_c , physical_command ) ;
  2425.       translate( physical_c , physical_command , new_c , new_command ) ;
  2426.     end get_character ;
  2427.        
  2428.     function map_up ( c : character ) return character is
  2429.     begin -- map_up
  2430.       if c in 'a' .. 'z' then
  2431.         return character'val( character'pos(c) 
  2432.                               - character'pos('a')
  2433.                               + character'pos('A') );
  2434.       else
  2435.         return c ;
  2436.       end if ;
  2437.     end map_up ;
  2438.      
  2439.     function map_down ( c : character ) return character is
  2440.     begin
  2441.       if c in 'A' .. 'Z' then
  2442.         return character'val( character'pos(c) 
  2443.                               - character'pos('A')
  2444.                               + character'pos('a') );
  2445.       else
  2446.         return c ;
  2447.       end if ;
  2448.     end map_down ;
  2449.      
  2450.     function char_within_range_or_abort ( default , lowest_item , 
  2451.                                                     highest_item : character ) 
  2452.                                           return character is
  2453.       -- get a character which is within the range specified 
  2454.       ValidSet : character_set ;
  2455.       chr : character ;
  2456.       spc : special_keys ;
  2457.     begin --char_within_range_or_abort
  2458.       clear_set(ValidSet);
  2459.       for cc in lowest_item .. highest_item loop
  2460.         ValidSet ( cc ) := true ;
  2461.         if cc in 'a' .. 'z' then
  2462.           ValidSet ( map_up(cc )  ) := true ;
  2463.         end if ;
  2464.       end loop ;loop
  2465.         key_input( chr , spc ) ;
  2466.         if ( spc = key_carriage_return ) or ( spc = key_line_feed ) then
  2467.           spc := key_character ;
  2468.           chr := default ;
  2469.         else
  2470.           chr := map_up(chr) ;
  2471.         end if ;
  2472.       exit when ( ( spc = key_character ) and then in_set( chr, ValidSet ) )
  2473.       or   else ( spc = key_escape ) ;
  2474.         bell;
  2475.       end loop ;
  2476.       if spc = key_escape then
  2477.         return ascii.nul ;
  2478.       else
  2479.         put(chr);
  2480.         return chr ;
  2481.       end if ;
  2482.     end char_within_range_or_abort ;
  2483.      
  2484.     function char_or_abort ( default , c_1 , c_2 , c_3 , c_4 ,
  2485.                                        c_5 , c_6 , c_7 , c_8 ,
  2486.                                        c_9 : in character := ascii.nul )
  2487.                              return character is
  2488.       ValidSet : character_set ;
  2489.       chr : character ;
  2490.       spc : special_keys ;
  2491.     begin -- char_or_abort 
  2492.       clear_set(ValidSet);
  2493.       ValidSet(c_1) := true ;
  2494.       ValidSet(c_2) := true ;
  2495.       ValidSet(c_3) := true ;
  2496.       ValidSet(c_4) := true ;
  2497.       ValidSet(c_5) := true ;
  2498.       ValidSet(c_6) := true ;
  2499.       ValidSet(c_7) := true ;
  2500.       ValidSet(c_8) := true ;
  2501.       ValidSet(c_9) := true ;
  2502.       ValidSet(ascii.nul ) := false ;
  2503.       -- Now, make sure that we get all upper/lower combinations
  2504.       for c in 'a' .. 'z' loop
  2505.         if ValidSet(c) then
  2506.           ValidSet( map_up(c) ) := true ;
  2507.         end if ;
  2508.       end loop ;
  2509.       loop
  2510.         key_input( chr , spc ) ;
  2511.         if ( spc = key_carriage_return ) or ( spc = key_line_feed ) then
  2512.           spc := key_character ;
  2513.           chr := default ;
  2514.         else
  2515.           chr := map_up(chr);
  2516.         end if ;
  2517.       exit when ( ( spc = key_character ) and then in_set( chr, ValidSet ) )
  2518.       or   else ( spc = key_escape ) ;
  2519.         bell;
  2520.       end loop ;
  2521.       if spc = key_escape then
  2522.         return ascii.nul ;
  2523.       else
  2524.         put(chr);
  2525.         return chr ;
  2526.       end if ;
  2527.     end char_or_abort ;
  2528.        
  2529.     function STRING_READ( FORMAT : in PSTRING ;
  2530.                           DEFAULT: in PSTRING ; -- := "" ;
  2531.                           LENGTH : in window_column_number := 0 ;
  2532.                           COL    : in window_column_number := 0 ;
  2533.                           LINE   : in window_line_number := 0 ;
  2534.                           ALLOW_LOWER_CASE : in BOOLEAN  := TRUE 
  2535.                         ) return PSTRING is
  2536.          
  2537.       --  INPUTS
  2538.       --
  2539.       --  The FORMAT string must contain format characters telling the
  2540.       --    string read routine what type of characters to accept as 
  2541.       --    input.  The length of the allowed input string is controlled
  2542.       --    by either the length variable or the length of the format
  2543.       --    string.  If LENGTH is 0, then the length is controlled by
  2544.       --    the length of FORMAT.  In all other cases, the input string
  2545.       --    length is determined by LENGTH.  If LENGTH is greater than
  2546.       --    the length of FORMAT, then FORMAT is assumed to be lengthened
  2547.       --    to the right with blanks.
  2548.       --  The DEFAULT string contains the default value of the field
  2549.       --    should the user type <return> in response to this input request.
  2550.       --  The LENGTH is the maximum input length allowed.
  2551.       --  The COL,LINE pair control where on the screen the cursor is 
  2552.       --    positioned in preparation for this input request.  If either
  2553.       --    is 0, then the cursor is not re-positioned.
  2554.       --  If ALLOW_LOWER_CASE is true, then lower case characters are accepted
  2555.       --    from the keyboard and left as is.  Otherwise, lower case character
  2556.       --    are transposed into their upper case equivalents.
  2557.       --
  2558.       --  OPERATION
  2559.       --
  2560.       --  OUTPUTS
  2561.       --
  2562.       --  STRING_READ returns a string as a result of the reading of character
  2563.       --    from the terminal device.
  2564.       --
  2565.       FORMAT_CHARACTERS : CHARACTER_SET;  
  2566.                               -- Valid Format Characters In Fmat Str
  2567.       ORIG_CRT_COLOR    : CRT_COLOR;      
  2568.                               -- Origional CRT Color before call
  2569.       IN_STRING         : PSTRING;  
  2570.                               -- The input string typed at CRT
  2571.       PLACE             : INTEGER;
  2572.       ALLOWED_LENGTH    : INTEGER;
  2573.          
  2574.       FINISHED          : BOOLEAN ;
  2575.       DONE              : BOOLEAN ;
  2576.       CHR               : CHARACTER ; -- character read in from CRT
  2577.       CHR_SPECIAL       : SPECIAL_KEYS ;
  2578.          
  2579.       GOOD_SET          : CHARACTER_SET;
  2580.       VALID_INPT_RESULT : BOOLEAN ;  -- returned from valid_input
  2581.       current_format    : character    ;
  2582.           
  2583.       procedure BACKSPACE is
  2584.       begin
  2585.         put(ASCII.BS);
  2586.       end;
  2587.            
  2588.       procedure INITIALIZE is
  2589.       begin -- initialize
  2590.         -- Set Format Initialization.  These are the valid format characters
  2591.         CLEAR_SET(FORMAT_CHARACTERS);
  2592.         FORMAT_CHARACTERS('A') := TRUE ;
  2593.         FORMAT_CHARACTERS('9') := TRUE ;
  2594.         FORMAT_CHARACTERS('Z') := TRUE ;
  2595.         FORMAT_CHARACTERS('~') := TRUE ;
  2596.         FORMAT_CHARACTERS('.') := TRUE ;
  2597.         FORMAT_CHARACTERS(' ') := TRUE ;
  2598.         -- Now, remember the color of characters on the screen for later
  2599.         ORIG_CRT_COLOR := CURRENT_CRT_COLOR;
  2600.         -- Now, determine the length of the input string
  2601.         if length > 0 then
  2602.           allowed_length := length;
  2603.         else
  2604.           allowed_length := string_library.length(format) ;
  2605.         end if;
  2606.         if (col > 0) and (line > 0) then
  2607.           goto_line_column ( current_window , line , col ) ;
  2608.         end if;
  2609.         -- Now, show the colored bar on the screen
  2610.         change_color(black,white);
  2611.         for index in 1..allowed_length
  2612.         loop
  2613.           if IN_SET(FORMAT.data(index),FORMAT_CHARACTERS) then
  2614.             put(' ');
  2615.           else
  2616.             put(FORMAT.data(index));
  2617.           end if;
  2618.         end loop;
  2619.         for index in 1..allowed_length
  2620.         loop
  2621.           backspace;
  2622.         end loop;
  2623.         -- Now, we are back to where we started...
  2624.         change_color(red);
  2625.         -- with red characters ready to appear 
  2626.       end initialize;
  2627.    
  2628.       procedure CLEAR_BELL is
  2629.         -- This routine will:
  2630.         --   1) ring the bell
  2631.         --   2) wait 1 second
  2632.         --   3) clear the input buffer (if possible)
  2633.         --   4) and ring the bell again
  2634.       begin
  2635.         bell;
  2636.         delay 1.0 ;
  2637.         flush_input ; -- Clear the input buffer
  2638.         bell;
  2639.       end clear_bell;
  2640.            
  2641.       procedure BACKOUT is
  2642.       begin
  2643.         change_color(black,white);
  2644.         if IN_SET( format.data(place) , FORMAT_CHARACTERS ) then
  2645.           put(' ');
  2646.         else 
  2647.           put(format.data(place));
  2648.         end if;
  2649.         backspace;
  2650.         change_color(red,black);
  2651.       end backout;
  2652.            
  2653.       procedure MY_BACKSPACE( ERROR : in BOOLEAN ) is
  2654.         DONE : BOOLEAN := false ;
  2655.       begin
  2656.         if error then
  2657.           clear_bell;
  2658.         else
  2659.           loop
  2660.             backspace;
  2661.             backout;
  2662.             IN_STRING.data(place) := ' ' ; -- Clear the old input characters
  2663.             place := place - 1 ;
  2664.           exit when ( place = 0 ) or else IN_SET(format.data(place+1),
  2665.                                                  FORMAT_CHARACTERS) ;
  2666.           end loop;
  2667.         end if;
  2668.       end my_backspace;
  2669.            
  2670.       function VALID_INPUT( A_CHARACTER : in CHARACTER;
  2671.                             ALLOWED_SET : in CHARACTER_SET ) return BOOLEAN is
  2672.         -- returns true if a_character is a valid input for the given
  2673.         -- character set
  2674.       begin
  2675.         if IN_SET(A_CHARACTER,ALLOWED_SET) then
  2676.           place := place + 1;
  2677.           IN_STRING.data(place) := A_CHARACTER;
  2678.           PUT(A_CHARACTER);
  2679.           return TRUE ;
  2680.         else
  2681.           MY_BACKSPACE(TRUE);
  2682.           return FALSE ;
  2683.         end if;
  2684.       end valid_input;
  2685.          
  2686.       Procedure SET_GOOD_SET ( start_rng , stop_rng : in character ) is
  2687.       begin
  2688.         for i in character'pos(start_rng) .. character'pos(stop_rng) loop
  2689.           good_set(character'val(i)) := true ;
  2690.         end loop ;
  2691.       end set_good_set;
  2692.            
  2693.     begin  -- string_read 
  2694.       initialize;
  2695.       for place in 1 .. allowed_length loop
  2696.         in_string.data(place) := ' ' ;
  2697.       end loop ;
  2698.       place := 0 ;
  2699.       change_color(black , white) ;
  2700.       change_crt(crt.underline) ;
  2701.       for place in 1 .. allowed_length loop
  2702.         if place <= string_library.length(format) then
  2703.           if in_set(format.data(place) , format_characters) then
  2704.             put(' ');
  2705.           else
  2706.             put(format.data(place)) ;
  2707.           end if;
  2708.         else
  2709.           put(' ') ;
  2710.         end if ;
  2711.       end loop ;
  2712.       for place in 1 .. allowed_length loop
  2713.         backspace ;
  2714.       end loop ;
  2715.       change_color(red) ;
  2716.       -- now get the string in
  2717.       place := 0 ;  -- how many filled
  2718.       finished := false ;
  2719.       while (not finished) and (place < allowed_length) loop
  2720.         if string_library.length(format) <= place then 
  2721.           -- assume format lengthed w/blanks
  2722.           current_format := ' ' ;
  2723.         else
  2724.           current_format := format.data(place+1);
  2725.         end if ;
  2726.         if not in_set(current_format,format_characters) then
  2727.           place := place + 1 ;
  2728.           in_string.data(place) := format.data(place) ;
  2729.           put(format.data(place)) ;
  2730.         else
  2731.           -- we need to get in a character
  2732.           key_input( chr , chr_special ) ;
  2733.           if not allow_lower_case then
  2734.             chr := map_up(chr) ;
  2735.           end if ;
  2736.           if (chr_special = key_carriage_return )
  2737.           or (chr_special = key_line_feed       ) then
  2738.             finished := TRUE ;
  2739.           elsif (chr_special = key_backspace ) 
  2740.              or (chr_special = key_delete    ) then 
  2741.             my_backspace(place=0) ;
  2742.           elsif chr = ascii.etb then
  2743.             -- ^W 
  2744.             done := false ;
  2745.             while not done loop
  2746.               if place = 0 then
  2747.                 done := true ;
  2748.               elsif (in_string.data(place) >= '0' 
  2749.                                             and in_string.data(place) <= '9') 
  2750.                  or (in_string.data(place) >= 'A' 
  2751.                                             and in_string.data(place) <= 'Z') 
  2752.                  or (in_string.data(place) >= 'a' 
  2753.                                             and in_string.data(place) <= 'z') 
  2754.                             then
  2755.                 my_backspace(false) ;
  2756.               else 
  2757.                 done := true ;
  2758.               end if ;
  2759.             end loop ;
  2760.           elsif chr < ' ' then
  2761.             clear_bell ; -- illegal response
  2762.           else
  2763.             clear_set( good_set ) ;
  2764.             case format.data(place+1) is
  2765.               when ' ' =>set_good_set(' ' ,  '~') ;
  2766.                          valid_inpt_result := valid_input( chr , good_set ) ;
  2767.               when '9' =>set_good_set('0' , '9') ;
  2768.                          good_set(',') := true ;
  2769.                          valid_inpt_result := valid_input( chr , good_set ) ;
  2770.               when 'A' =>set_good_set('A' , 'Z') ;
  2771.                          set_good_set('a' , 'z') ;
  2772.                          valid_inpt_result := valid_input( chr , good_set ) ;
  2773.               when 'Z' =>set_good_set('0' , '9') ;
  2774.                          set_good_set('A' , 'Z') ;
  2775.                          set_good_set('a' , 'z') ;
  2776.                          valid_inpt_result := valid_input( chr , good_set ) ;
  2777.               when '~' =>set_good_set('0' , '9') ;
  2778.                          good_set(',') := true ;
  2779.                          good_set('+') := true ;
  2780.                          good_set('-') := true ;
  2781.                          valid_inpt_result := valid_input( chr , good_set ) ;
  2782.               when '.' =>set_good_set('0' , '9') ;
  2783.                          good_set('E') := true ;
  2784.                          good_set('e') := true ;
  2785.                          good_set('+') := true ;
  2786.                          good_set('-') := true ;
  2787.                          good_set('.') := true ;
  2788.                          good_set(',') := true ;
  2789.                          valid_inpt_result := valid_input( chr , good_set ) ;
  2790.               when '^' =>set_good_set('0' , '9') ;
  2791.                          good_set('+') := true ;
  2792.                          good_set('-') := true ;
  2793.                          good_set(',') := true ;
  2794.                          good_set('.') := true ;
  2795.                          valid_inpt_result := valid_input( chr , good_set ) ;
  2796.               when others => null ; -- we can't get here
  2797.             end case ;
  2798.           end if ;
  2799.         end if ;
  2800.       end loop ;
  2801.       -- Set the crt color back to the original setting
  2802.       if place = 0 then
  2803.         for i in 1 .. allowed_length loop
  2804.           in_string.data(i) := default.data(i) ;
  2805.         end loop ;
  2806.         set_length(in_string,allowed_length) ;
  2807.       else
  2808.         set_length(in_string,place) ;
  2809.       end if ;
  2810.       for tmp in place+1 .. allowed_length loop
  2811.         put(' ');
  2812.       end loop ;
  2813.       CHANGE_COLOR(ORIG_CRT_COLOR);
  2814.       CHANGE_CRT(NORMAL);
  2815.       RETURN IN_STRING ;
  2816.          
  2817.     end STRING_READ;
  2818.          
  2819.     function get_number ( line : in window_line_number   ;
  2820.                           col  : in window_column_number ;
  2821.                           smallest : in integer          ;
  2822.                           largest  : in integer          ;
  2823.                           len      : in integer          ;
  2824.                           default  : in integer          )
  2825.                           return integer is
  2826.       -- get a number within the range if possible.  On reject/return
  2827.       -- simply return default
  2828.       new_string : pstring ;
  2829.       err_message: pstring ;
  2830.       num        : integer ;
  2831.      
  2832.       function n ( c : character ) return integer is
  2833.       begin -- n
  2834.         return character'pos(c) - character'pos('0') ;
  2835.       end n ;
  2836.        
  2837.     begin -- get_number 
  2838.       loop
  2839.         new_string := string_read( string_to_pstring( "9999999999" ) , 
  2840.                                    string_to_pstring( "          " ) ,
  2841.                                    len , col , line ) ;
  2842.         if ( line > 0 ) and then ( col > 0 ) then
  2843.           goto_line_column ( current_window , line , col ) ;
  2844.         else
  2845.           for posn in 1 .. len loop
  2846.             put(ascii.bs);
  2847.           end loop ;
  2848.         end if ;
  2849.         if new_string.data(1) = ' ' then
  2850.           put( default , len ) ;
  2851.           return default ;
  2852.         else
  2853.           num := 0 ;
  2854.           for place in 1 .. string_library.length(new_string) loop
  2855.             num := num * 10 + n(new_string.data(place)) ;
  2856.           end loop ;
  2857.           if ( num < smallest ) or ( num > largest ) then
  2858.             -- we need to send out an error message 
  2859.             -- err_message := " Error: Number must be in the range " 
  2860.                               -- & int_to_str(smallest)
  2861.                               -- & " .. "
  2862.                               -- & int_to_str(largest)
  2863.                               -- & ".  " ;
  2864.             -- error(err_message, not_fatal_error, operator_wait, short_beep ) ;
  2865.             bell ;
  2866.           else
  2867.             put( num , len ) ;
  2868.             return num ;
  2869.           end if ;
  2870.         end if ;
  2871.       end loop ;
  2872.     end get_number ;
  2873.    
  2874.   begin -- crt_Windows
  2875.     -- WINDOWS  by SAIC/Clearwater Window Management Routines  07 Jan 85
  2876.     -- WINDOWIN by SAIC/Clearwater Extended I/O Routines       30 Jan 85
  2877.     --
  2878.       null ;
  2879.     --
  2880.   end crt_Windows ;
  2881.     
  2882.   --$$$- CWINDOWS
  2883.  
  2884. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2885. --wpglobal
  2886. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2887.  
  2888.   --$$$+ WPGLOBAL
  2889.    
  2890.   --
  2891.   -- File 005
  2892.   --
  2893.   -- Editor Written By Robert S. Cymbalski
  2894.   --                   Science Applications International Corporation
  2895.   --                   Energy Systems Group
  2896.   --                   Ada Software Development Project Team
  2897.   --                   2280 U.S. Highway 19 North, Suite 120
  2898.   --                   Clearwater, Florida  33575
  2899.   --
  2900.   -- Program Revised from text Copyright (c) 1984 , R.S.Cymbalski
  2901.        
  2902.   with text_io , io_exceptions ;
  2903.     
  2904.   with string_library  ;
  2905.   use  string_library  ;
  2906.    
  2907.   with basic_io_system ;
  2908.    
  2909.   with crt_customization  ;
  2910.   use  crt_customization  ;
  2911.   use  crt             ;
  2912.    
  2913.   with crt_windows     ;
  2914.   use  crt_windows     ;
  2915.    
  2916.   package Wordp_Globals is
  2917.     
  2918.     maximum_file_name_length : constant integer := 20 ;
  2919.       
  2920.     default_text_file_suffix : constant string ( 1 .. 5 ) := ".text" ;
  2921.     default_backup_ending    : constant string ( 1 .. 4 ) := ".bak"  ;
  2922.       
  2923.     subtype ascii_text_file_name is string ( 1 .. maximum_file_name_length ) ;
  2924.       
  2925.     no_file : constant ascii_text_file_name := "                    " ;
  2926.       
  2927.     editor_entry_input_file_name         : ascii_text_file_name := no_file ;
  2928.     editor_entry_output_file_name        : ascii_text_file_name := no_file ;
  2929.     editor_requested_input_file_name     : ascii_text_file_name := no_file ;
  2930.     editor_requested_output_file_name    : ascii_text_file_name := no_file ;
  2931.       
  2932.     formatter_entry_input_file_name      : ascii_text_file_name := no_file ;
  2933.     formatter_entry_output_file_name     : ascii_text_file_name := no_file ;
  2934.     formatter_requested_input_file_name  : ascii_text_file_name := no_file ;
  2935.     formatter_requested_output_file_name : ascii_text_file_name := no_file ;
  2936.       
  2937.     only_editor : constant boolean := true  ;
  2938.       -- tells editor if it should allow the "P" option on exit
  2939.        
  2940.     type type_what_to_run_next is ( master_menu , text_editor , text_formatter ,
  2941.                                     operating_system , format_editor_file ,
  2942.                                     edit_formatter_file ) ;
  2943.                            
  2944.     what_to_run_next : type_what_to_run_next ;
  2945.      
  2946.     -- Each of the two main packages can have an entry input and output
  2947.     -- file name.  If so, those file names are used ( if possible ) .  
  2948.     -- If the input file does not exist, then we ask for the file they
  2949.     -- really want.  If we do ask, we set the requested file name as 
  2950.     -- appropriate.  
  2951.     
  2952.     -- Now , we list the Predefined File Names --
  2953.     -- First , The SYSTEM Files
  2954.       
  2955.     -- Now , The USER Files
  2956.       
  2957.     Help_On_Editor_Commands_File_Name        : constant ascii_text_file_name 
  2958.                                              := "EDITCMD.HLP         " ;
  2959.     Help_On_Set_Commands_File_Name           : constant ascii_text_file_name
  2960.                                              := "EDITSET.HLP         " ;
  2961.     Help_On_Environment_Commands_File_Name   : constant ascii_text_file_name
  2962.                                              := "EDITENV.HLP         " ;
  2963.     Default_Environment_File_Name            : constant ascii_text_file_name
  2964.                                              := "EDITENV.DEF         " ;
  2965.                                         
  2966.     -- a..z , 0 ..9 only chars allowed
  2967.     -- only  3 chars allowed after .
  2968.     
  2969.     function file_exists ( file_name : in  string ) return boolean ; 
  2970.       -- look for this file name with no changes
  2971.      
  2972.     function file_exists ( file_name : in pstring ) return boolean ; 
  2973.       -- look for this file name with no changes
  2974.      
  2975.     procedure ok_to_read    ( orig_file_name : in string      ;
  2976.                               final_file_name : out pstring   ;
  2977.                               successfull     : out boolean ) ;
  2978.       -- look for the orig_file_name on the appropriate disks.  Return
  2979.       -- successfull if found, and also set the final_file_name as 
  2980.       -- the fully elaborated file path/name
  2981.        
  2982.     procedure ok_to_read    ( orig_file_name : in pstring     ;
  2983.                               final_file_name : out pstring   ;
  2984.                               successfull     : out boolean ) ;
  2985.       -- look for the orig_file_name on the appropriate disks.  Return
  2986.       -- successfull if found, and also set the final_file_name as 
  2987.       -- the fully elaborated file path/name
  2988.        
  2989.     procedure ok_to_read    ( orig_file_name  : in  ascii_text_file_name ;
  2990.                               final_file_name : out ascii_text_file_name ;
  2991.                               successfull     : out boolean ) ;
  2992.       -- look for the orig_file_name on the appropriate disks.  Return
  2993.       -- successfull if found, and also set the final_file_name as 
  2994.       -- the fully elaborated file path/name
  2995.        
  2996.     procedure open_for_read ( file_handle     : in out text_io.file_type ;
  2997.                               file_name       : in out ascii_text_file_name ;
  2998.                               successfull     : out boolean            ) ;
  2999.       -- Open the file setting the handle 
  3000.        
  3001.     procedure open_for_write( file_handle     : in out text_io.file_type ;
  3002.                               file_name       : in out ascii_text_file_name ;
  3003.                               successfull     : out boolean            ) ;
  3004.       -- Open the file setting the handle 
  3005.        
  3006.     procedure sok_to_read   ( orig_file_name : in string      ;
  3007.                               final_file_name : out pstring   ;
  3008.                               successfull     : out boolean ) ;
  3009.       -- For Editor Program Files (such as help)
  3010.       -- look for the orig_file_name on the appropriate disks.  Return
  3011.       -- successfull if found, and also set the final_file_name as 
  3012.       -- the fully elaborated file path/name
  3013.        
  3014.     procedure sok_to_read   ( orig_file_name : in pstring     ;
  3015.                               final_file_name : out pstring   ;
  3016.                               successfull     : out boolean ) ;
  3017.       -- For Editor Program Files (such as help)
  3018.       -- look for the orig_file_name on the appropriate disks.  Return
  3019.       -- successfull if found, and also set the final_file_name as 
  3020.       -- the fully elaborated file path/name
  3021.        
  3022.     procedure sok_to_read   ( orig_file_name  : in  ascii_text_file_name ;
  3023.                               final_file_name : out ascii_text_file_name ;
  3024.                               successfull     : out boolean ) ;
  3025.       -- For Editor Program Files (such as help)
  3026.       -- look for the orig_file_name on the appropriate disks.  Return
  3027.       -- successfull if found, and also set the final_file_name as 
  3028.       -- the fully elaborated file path/name
  3029.        
  3030.     function ok_to_write    ( orig_file_name : in string    ) return boolean ;
  3031.       -- check that the file does not exist
  3032.      
  3033.     function ok_to_write    ( orig_file_name : in pstring   ) return boolean ;
  3034.       -- check that the file does not exist
  3035.        
  3036.     Procedure do_purge( s : in string ) ; 
  3037.       -- purge that file from the system (if it exists)
  3038.        
  3039.     Procedure do_purge( s : in pstring ) ; 
  3040.       -- purge that file from the system (if it exists)
  3041.        
  3042.     Procedure Rename_File ( Old_File_Name : in ascii_text_file_name ;
  3043.                             New_File_Name : in ascii_text_file_name ) ;
  3044.                              
  3045.     Procedure no_file_found( s : in  string ; fatal : in  boolean) ;
  3046.     
  3047.     Procedure no_file_found( s : in pstring ; fatal : in  boolean) ;
  3048.     
  3049.     Function get_input_filename_or_return  return ascii_text_file_name ;
  3050.       -- Reads in file name discarding illegal characters , where
  3051.       -- A..Z , a..z , 0 ..9  are only characters allowed in a file name 
  3052.       -- and only  3 characters are allowed after a period(.) 
  3053.       -- If the file does not exist then esc & file-name(1 .. length-1) 
  3054.       -- is returned. 
  3055.    
  3056.     Function get_output_filename_or_return return ascii_text_file_name ;
  3057.      
  3058.     Function get_output_filename_or_return( default_suffix : in string )
  3059.                                             return ascii_text_file_name ;
  3060.      
  3061.     Function No_Blanks ( s : in string ) return string ;
  3062.       
  3063.     type a_beep_length is ( extra_short_beep , short_beep , medium_beep , 
  3064.                             long_beep , extra_long_beep );
  3065.        
  3066.     type a_wait_length is ( extra_short_wait , short_wait , medium_wait , 
  3067.                             long_wait , extra_long_wait , operator_wait );
  3068.        
  3069.     type type_of_error is ( fatal_error , not_fatal_error ) ;
  3070.       
  3071.     procedure error_beep( beep_length : in a_beep_length ) ;
  3072.        
  3073.     procedure error( error_message : in string     ; 
  3074.                      is_it_fatal   : type_of_error ;
  3075.                      wait_length   : a_wait_length ;
  3076.                      beep_length   : a_beep_length ) ;
  3077.       -- We have an error.  Show the message, and then work as appropriate 
  3078.         
  3079.     procedure error( error_message : in string_library.pstring ;
  3080.                      is_it_fatal   : type_of_error ;
  3081.                      wait_length   : a_wait_length ;
  3082.                      beep_length   : a_beep_length ) ;
  3083.       -- We have an error.  Show the message, and then work as appropriate 
  3084.         
  3085.   end Wordp_Globals ;
  3086.     
  3087.   package body Wordp_Globals is
  3088.       
  3089.     function user_name ( s : in pstring ) return pstring is
  3090.       -- turn this file name into a user name 
  3091.     begin -- user_name 
  3092.       if basic_io_system.directory_separator = ' ' then
  3093.         -- nothing defined
  3094.         return s;
  3095.       else
  3096.         -- ok. we have a basic_io_system.directory separator to look for
  3097.         if position( basic_io_system.directory_separator , s ) /= 0 then
  3098.           -- they defined the basic_io_system.directory, so don't do anything
  3099.           return s;
  3100.         else
  3101.           -- ok, turn it into the appropriate one
  3102.           return basic_io_system.user_directory & s ;
  3103.         end if ;
  3104.       end if ;
  3105.     end user_name ;
  3106.      
  3107.     function user_name ( s : in string ) return pstring is
  3108.       -- turn this file name into a user name 
  3109.     begin -- user_name 
  3110.       return user_name( string_to_pstring(s) ) ;
  3111.     end user_name ;
  3112.      
  3113.     function wp_name ( s : in pstring ) return pstring is
  3114.       -- turn this file name into a wp name 
  3115.     begin -- wp_name 
  3116.       if basic_io_system.directory_separator = ' ' then
  3117.         -- nothing defined
  3118.         return s;
  3119.       else
  3120.         -- ok. we have a directory separator to look for
  3121.         if position( basic_io_system.directory_separator , s ) /= 0 then
  3122.           -- they defined the directory, so don't do anything
  3123.           return s;
  3124.         else
  3125.           -- ok, turn it into the appropriate one
  3126.           return basic_io_system.word_processor_directory & s ;
  3127.         end if ;
  3128.       end if ;
  3129.     end wp_name ;
  3130.      
  3131.     function wp_name ( s : in string ) return pstring is
  3132.       -- turn this file name into a wp name 
  3133.     begin -- wp_name 
  3134.       return wp_name( string_to_pstring(s) ) ;
  3135.     end wp_name ;
  3136.      
  3137.     function no_blanks ( s : in string ) return string is
  3138.       ot_string : string ( 1 .. s'length ) ;
  3139.       ot_length : integer ;
  3140.     begin -- no_blanks
  3141.       ot_length := 0 ;
  3142.       for place in 1 .. s'length loop
  3143.         if s(place) /= ' ' then
  3144.           ot_length := ot_length + 1 ;
  3145.           ot_string(ot_length) := s(place);
  3146.         end if ;
  3147.       end loop ;
  3148.       return ot_string( 1 .. ot_length ) ;
  3149.     end no_blanks ;
  3150.      
  3151.     function no_blanks ( s : in pstring ) return string is
  3152.       ot_string : string ( 1 .. length(s) ) ;
  3153.       ot_length : integer ;
  3154.     begin -- no_blanks 
  3155.       ot_length := 0 ;
  3156.       for place in 1 .. length(s) loop
  3157.         if s.data(place) /= ' ' then
  3158.           ot_length := ot_length + 1 ;
  3159.           ot_string(ot_length) := s.data(place);
  3160.         end if ;
  3161.       end loop ;
  3162.       return ot_string( 1 .. ot_length ) ;
  3163.     end no_blanks ;
  3164.      
  3165.     function file_exists ( file_name : in string ) return boolean is
  3166.       -- look for this file name with no changes
  3167.       temp_file : text_io.file_type ;
  3168.     begin -- file_exists
  3169.       text_io.open(temp_file , text_io.in_file , no_blanks(file_name) ) ;
  3170.       text_io.close(temp_file) ;
  3171.       return true ;
  3172.     exception 
  3173.       when io_exceptions.name_error 
  3174.          | io_exceptions.use_error   => return false ;
  3175.       when others                    => return false ;
  3176.     end file_exists ;
  3177.       
  3178.     function file_exists ( file_name : in pstring ) return boolean is
  3179.       -- look for this file name with no changes
  3180.       temp_file : text_io.file_type ;
  3181.     begin -- file_exists
  3182.       text_io.open(temp_file , text_io.in_file , no_blanks(file_name) );
  3183.       text_io.close(temp_file) ;
  3184.       return true ;
  3185.     exception 
  3186.       when io_exceptions.name_error 
  3187.          | io_exceptions.use_error   => return false ;
  3188.       when others                    => return false ;
  3189.     end file_exists ;
  3190.       
  3191.     procedure ok_to_read    ( orig_file_name : in string      ;
  3192.                               final_file_name : out pstring   ;
  3193.                               successfull     : out boolean ) is
  3194.       -- look for the orig_file_name on the appropriate disks.  Return
  3195.       -- successfull if found, and also set the final_file_name as 
  3196.       -- the fully elaborated file path/name
  3197.     begin -- ok_to_read
  3198.       ok_to_read( string_to_pstring( orig_file_name ) , final_file_name ,
  3199.                   successfull ) ;
  3200.     end ok_to_read ;
  3201.        
  3202.     procedure ok_to_read    ( orig_file_name : in pstring     ;
  3203.                               final_file_name : out pstring   ;
  3204.                               successfull     : out boolean ) is
  3205.       -- look for the orig_file_name on the appropriate disks.  Return
  3206.       -- successfull if found, and also set the final_file_name as 
  3207.       -- the fully elaborated file path/name
  3208.       new_name : pstring ;
  3209.     begin -- ok_to_read
  3210.       if file_exists ( orig_file_name ) then
  3211.         final_file_name := orig_file_name ;
  3212.         successfull     := true ;
  3213.       else
  3214.         -- check for a user directory 
  3215.         new_name := user_name( orig_file_name ) ;
  3216.         if new_name = orig_file_name then
  3217.           -- nothing we can do about it
  3218.           final_file_name := blank_line ;
  3219.           successfull     := false      ;
  3220.         else
  3221.           if file_exists( new_name ) then
  3222.             final_file_name := new_name ;
  3223.             successfull     := true     ;
  3224.           else
  3225.             final_file_name := blank_line ;
  3226.             successfull     := false      ;
  3227.           end if ;
  3228.         end if ;
  3229.       end if ;
  3230.     end ok_to_read ;
  3231.        
  3232.     procedure ok_to_read    ( orig_file_name  : in  ascii_text_file_name ;
  3233.                               final_file_name : out ascii_text_file_name ;
  3234.                               successfull     : out boolean ) is
  3235.       -- look for the orig_file_name on the appropriate disks.  Return
  3236.       -- successfull if found, and also set the final_file_name as 
  3237.       -- the fully elaborated file path/name
  3238.       ps : string_library.pstring ;
  3239.     begin -- ok_to_read
  3240.       ok_to_read( string_to_pstring( orig_file_name ) , ps ,
  3241.                   successfull ) ;
  3242.       final_file_name := no_file ;
  3243.       for posn in 1 .. length(ps) loop
  3244.         final_file_name(posn) := ps.data(posn);
  3245.       end loop;
  3246.     end ok_to_read ;
  3247.        
  3248.     function return_name ( file_handle : in text_io.file_type ) 
  3249.                            return ascii_text_file_name is
  3250.       new_name : ascii_text_file_name := no_file ;
  3251.       current_name : constant string := text_io.name(file_handle) ;
  3252.     begin -- return_name 
  3253.       if current_name'length <= new_name'length then
  3254.         new_name( 1 .. current_name'length ) := current_name ;
  3255.       end if ;
  3256.       return new_name ;
  3257.     exception
  3258.       when others => return new_name ;
  3259.     end return_name ;
  3260.  
  3261.     procedure open_for_read ( file_handle     : in out text_io.file_type ;
  3262.                               file_name       : in out ascii_text_file_name ;
  3263.                               successfull     : out boolean            ) is
  3264.       -- look for the orig_file_name on the appropriate disks.  Return
  3265.       -- successfull if found, and also set the final_file_name as 
  3266.       -- the fully elaborated file path/name.  Open the file setting
  3267.       -- the handle 
  3268.       new_name : ascii_text_file_name ;
  3269.     begin -- open_for_read 
  3270.       if text_io.is_open(file_handle) then
  3271.         text_io.close(file_handle);
  3272.       end if ;
  3273.       text_io.open(file_handle,text_io.in_file,no_blanks(file_name));
  3274.       new_name := return_name( file_handle ) ;
  3275.       if new_name /= no_file then
  3276.         file_name := new_name ;
  3277.       end if ;
  3278.       successfull := true ;
  3279.     exception 
  3280.       when others                    => successfull := false ;
  3281.     end open_for_read ;
  3282.      
  3283.     procedure open_for_write( file_handle     : in out text_io.file_type ;
  3284.                               file_name       : in out ascii_text_file_name ;
  3285.                               successfull     : out boolean            ) is
  3286.       -- Open the file setting the handle 
  3287.       new_name : ascii_text_file_name ;
  3288.     begin -- open_for_write
  3289.       if text_io.is_open(file_handle) then
  3290.         text_io.close(file_handle);
  3291.       end if ;
  3292.       text_io.create(file_handle,text_io.out_file,no_blanks(file_name));
  3293.       new_name := return_name( file_handle ) ;
  3294.       if new_name /= no_file then
  3295.         file_name := new_name ;
  3296.       end if ;
  3297.       successfull := true ;
  3298.     exception 
  3299.       when others                    => successfull := false ;
  3300.     end open_for_write ;
  3301.        
  3302.     procedure sok_to_read   ( orig_file_name : in string      ;
  3303.                               final_file_name : out pstring   ;
  3304.                               successfull     : out boolean ) is
  3305.       -- For Editor Program Files (such as help)
  3306.       -- look for the orig_file_name on the appropriate disks.  Return
  3307.       -- successfull if found, and also set the final_file_name as 
  3308.       -- the fully elaborated file path/name
  3309.     begin -- sok_to_read
  3310.       sok_to_read( string_to_pstring( orig_file_name ) , final_file_name ,
  3311.                    successfull ) ;
  3312.     end sok_to_read ;
  3313.        
  3314.     procedure sok_to_read   ( orig_file_name : in pstring     ;
  3315.                               final_file_name : out pstring   ;
  3316.                               successfull     : out boolean ) is
  3317.       -- For Editor Program Files (such as help)
  3318.       -- look for the orig_file_name on the appropriate disks.  Return
  3319.       -- successfull if found, and also set the final_file_name as 
  3320.       -- the fully elaborated file path/name
  3321.       new_name : pstring ;
  3322.       status   : boolean ;
  3323.     begin -- sok_to_read
  3324.       if file_exists ( orig_file_name ) then
  3325.         final_file_name := orig_file_name ;
  3326.         successfull     := true ;
  3327.       else
  3328.         -- check for a user directory 
  3329.         new_name := user_name( orig_file_name ) ;
  3330.         if new_name = orig_file_name then
  3331.           -- nothing we can do about it
  3332.           final_file_name := blank_line ;
  3333.           status          := false      ;
  3334.         else
  3335.           if file_exists( new_name ) then
  3336.             final_file_name := new_name ;
  3337.             status          := true     ;
  3338.           else
  3339.             final_file_name := blank_line ;
  3340.             status          := false      ;
  3341.           end if ;
  3342.         end if ;
  3343.         -- just finished looking in the user directory
  3344.         if status then
  3345.           successfull := true ;
  3346.         else
  3347.           -- look in the system directory 
  3348.           new_name := wp_name( orig_file_name ) ;
  3349.           if new_name = orig_file_name then
  3350.             -- nothing we can do about it
  3351.             final_file_name := blank_line ;
  3352.             successfull     := false      ;
  3353.           elsif file_exists( new_name ) then
  3354.             final_file_name := new_name ;
  3355.             successfull     := true     ;
  3356.           else
  3357.             final_file_name := blank_line ;
  3358.             successfull     := false      ;
  3359.           end if ;
  3360.         end if ;
  3361.       end if ;
  3362.     end sok_to_read ;
  3363.        
  3364.     procedure sok_to_read   ( orig_file_name  : in  ascii_text_file_name ;
  3365.                               final_file_name : out ascii_text_file_name ;
  3366.                               successfull     : out boolean ) is
  3367.       -- For Editor Program Files (such as help)
  3368.       -- look for the orig_file_name on the appropriate disks.  Return
  3369.       -- successfull if found, and also set the final_file_name as 
  3370.       -- the fully elaborated file path/name
  3371.       ps : string_library.pstring ;
  3372.     begin -- sok_to_read
  3373.       sok_to_read( string_to_pstring( orig_file_name ) , ps ,
  3374.                   successfull ) ;
  3375.       final_file_name := no_file ;
  3376.       for posn in 1 .. length(ps) loop
  3377.         final_file_name(posn) := ps.data(posn);
  3378.       end loop;
  3379.     end sok_to_read ;
  3380.        
  3381.     function ok_to_write    ( orig_file_name : in string    ) return boolean is
  3382.       -- check that the file does not exist
  3383.     begin -- ok_to_write
  3384.       return not file_exists( orig_file_name ) ;
  3385.     end ok_to_write ;
  3386.      
  3387.     function ok_to_write    ( orig_file_name : in pstring   ) return boolean is
  3388.       -- check that the file does not exist
  3389.     begin -- ok_to_write
  3390.       return not file_exists( orig_file_name ) ;
  3391.     end ok_to_write ;
  3392.      
  3393.     Procedure do_purge( s : in string ) is
  3394.       -- purge that file from the system (if it exists)
  3395.       temp_file : text_io.file_type ;
  3396.     begin -- do_purge
  3397.       if file_exists(s) then
  3398.         -- purge it
  3399.         text_io.open(temp_file,text_io.out_file,no_blanks(s));
  3400.         text_io.delete(temp_file);
  3401.       end if ;
  3402.     exception
  3403.       when others => null ;
  3404.     end do_purge ;
  3405.        
  3406.     Procedure do_purge( s : in pstring ) is
  3407.       -- purge that file from the system (if it exists)
  3408.       temp_file : text_io.file_type ;
  3409.     begin -- do_purge
  3410.       if file_exists(s) then
  3411.         -- purge it
  3412.         text_io.open(temp_file,text_io.out_file,no_blanks(s));
  3413.         text_io.delete(temp_file);
  3414.       end if ;
  3415.     exception
  3416.       when others => null ;
  3417.     end do_purge ;
  3418.        
  3419.     Procedure Rename_File ( Old_File_Name : in ascii_text_file_name ;
  3420.                             New_File_Name : in ascii_text_file_name ) is
  3421.       -- rename the file with the old file name to have the new file
  3422.       -- name.
  3423.     begin -- rename_file
  3424.       raise user_abort ;
  3425.     end rename_file ;
  3426.  
  3427.     Procedure no_file_found( s : in  string ; fatal : in  boolean) is
  3428.     begin -- no_file_found
  3429.       no_file_found( string_to_pstring(s),fatal);
  3430.     end no_file_found ; 
  3431.      
  3432.     Procedure no_file_found( s : in pstring ; fatal : in  boolean) is
  3433.       c : character ;
  3434.     begin -- no_file_found
  3435.       if fatal then
  3436.         crt.do_crt(crt.erase_all) ;
  3437.       end if ;
  3438.       crt.gotoxy(0,0) ;
  3439.       put("File """);
  3440.       put(s) ;
  3441.       put(""" Does Not Exist.   ");
  3442.       if fatal then
  3443.         crt.gotoxy(5,5) ;
  3444.         put("Please place the file on tha appropriate disk and retry");
  3445.       end if ;
  3446.       put("  Type <space> to continue.. ");
  3447.       crt_windows.wait_for_character(' ');
  3448.       if fatal then
  3449.         raise user_abort ;
  3450.       end if ;
  3451.     end no_file_found ;
  3452.       
  3453.     Function get_input_filename_or_return  return ascii_text_file_name is
  3454.       -- Reads in a file name discarding all illegal characters, where
  3455.       -- a..z , 0 ..9  are only characters allowed in a file name and
  3456.       -- only  3 characters are allowed after a period(.) 
  3457.       -- If the file does not exist then esc & file-name(1 .. length-1) 
  3458.       -- is returned. 
  3459.     
  3460.       ret_file_name : ascii_text_file_name := no_file ;
  3461.       pfile_name    : pstring ;
  3462.       format , 
  3463.       default ,
  3464.       new_name      : pstring ;
  3465.       ok            : boolean ;
  3466.       
  3467.     begin
  3468.       -- First, read in the file name 
  3469.       format   := string_to_pstring(no_file);
  3470.       default  := string_to_pstring(no_file);
  3471.       new_name := crt_windows.string_read( format , default ) ;
  3472.       if new_name = default then
  3473.         return no_file ;
  3474.       else
  3475.         -- Now, we will first allow the addition of .text 
  3476.         if length(new_name) <= maximum_file_name_length - 
  3477.                                default_text_file_suffix'length then
  3478.           if position('.',new_name) = 0 then
  3479.             new_name := compress(new_name) & default_text_file_suffix ;
  3480.           end if;
  3481.         end if ;
  3482.         if new_name.data( length(new_name) ) = '.' then
  3483.           set_length( new_name , length(new_name) - 1 ) ;
  3484.           -- eat last '.' 
  3485.         end if ;
  3486.         ret_file_name( 1 .. length(new_name) ) :=
  3487.                         new_name.data( 1 .. length(new_name) ) ;
  3488.         -- Now, check for all valid characters 
  3489.         ok       := true ;
  3490.         for posn in 1 .. maximum_file_name_length loop
  3491.           ok := ok and 
  3492.             (  ( ( ret_file_name( posn ) = basic_io_system.directory_separator )
  3493.              and ( ret_file_name( posn ) /= ' ' ) )
  3494.             or ( ret_file_name( posn ) = '.' ) 
  3495.             or ( ( ret_file_name(posn)>='A' ) and ( ret_file_name(posn)<='Z' ) )
  3496.             or ( ( ret_file_name(posn)>='a' ) and ( ret_file_name(posn)<='z' ) )
  3497.             or ( ( ret_file_name(posn)>='0' ) and ( ret_file_name(posn)<='9' ) )
  3498.             or ( ret_file_name(posn) = ':' ) 
  3499.             or ( ret_file_name(posn) = ' ' ) -- eaten by no_blanks
  3500.             ) ;
  3501.         end loop ;
  3502.         if ok then
  3503.           -- Now, check for number of characters past '.'
  3504.             
  3505.           -- And finally, check for existance of file itself
  3506.           ok_to_read( ret_file_name , pfile_name , ok ) ;
  3507.         end if ;
  3508.         if ok then
  3509.           -- must turn pfile_name into correct format
  3510.           ret_file_name := no_file ; -- put blanks into file name
  3511.           for posn in 1 .. length(pfile_name) loop
  3512.             -- note that we are not checking here for string too long ...
  3513.             ret_file_name(posn) := pfile_name.data(posn);
  3514.           end loop ;
  3515.         else
  3516.           -- not ok
  3517. for looper in reverse 2 .. maximum_file_name_length - 1 loop
  3518.             ret_file_name(looper) := ret_file_name(looper-1) ;
  3519.           end loop ;
  3520.           ret_file_name(1) := ascii.esc ;
  3521.         end if;
  3522.         return ret_file_name ;
  3523.       end if ;
  3524.     end get_input_filename_or_return ;
  3525.       
  3526.     Function get_output_filename_or_return( default_suffix : in string )
  3527.                                             return ascii_text_file_name is
  3528.      
  3529.       ret_file_name : ascii_text_file_name := no_file ;
  3530.       pfile_name    : pstring ;
  3531.       format , 
  3532.       default ,
  3533.       new_name      : pstring ;
  3534.       ok            : boolean ;
  3535.     begin
  3536.       -- First, read in the file name 
  3537.       format   := string_to_pstring(no_file);
  3538.       default  := string_to_pstring(no_file);
  3539.       new_name := crt_windows.string_read( format , default ) ;
  3540.       if new_name = default then
  3541.         return no_file ;
  3542.       else
  3543.         -- Now, we will first allow the addition of .text 
  3544.         if length(new_name) <= maximum_file_name_length - 
  3545.                                default_suffix'length then
  3546.           if position('.',new_name) = 0 then
  3547.             new_name := compress(new_name) & default_suffix ;
  3548.           end if;
  3549.         end if ;
  3550.         if new_name.data( length(new_name) ) = '.' then
  3551.           set_length( new_name , length(new_name) - 1 ) ;
  3552.           -- eat last '.' 
  3553.         end if ;
  3554.         ret_file_name( 1 .. length(new_name) ) :=
  3555.                         new_name.data( 1 .. length(new_name) ) ;
  3556.         -- Now, check for all valid characters 
  3557.         ok       := true ;
  3558.         for posn in 1 .. maximum_file_name_length loop
  3559.           ok := ok and 
  3560.             (  ( ( ret_file_name( posn ) 
  3561.                                      = basic_io_system.directory_separator )
  3562.              and ( ret_file_name( posn ) /= ' ' ) )
  3563.             or ( ret_file_name( posn ) = '.' ) 
  3564.             or ((ret_file_name(posn)>='A' ) 
  3565.                                         and ( ret_file_name(posn)<='Z'))
  3566.             or ((ret_file_name(posn)>='a' ) 
  3567.                                         and ( ret_file_name(posn)<='z'))
  3568.             or ((ret_file_name(posn)>='0' ) 
  3569.                                         and ( ret_file_name(posn)<='9'))
  3570.             or ( ret_file_name(posn) = ':' ) 
  3571.             or ( ret_file_name(posn) = ' ' ) -- eaten by no_blanks
  3572.             ) ;
  3573.         end loop ;
  3574.         if not ok then
  3575.           -- not ok
  3576. for looper in reverse 2 .. maximum_file_name_length - 1 loop
  3577.             ret_file_name(looper) := ret_file_name(looper-1) ;
  3578.           end loop ;
  3579.           ret_file_name(1) := ascii.esc ;
  3580.         end if;
  3581.         return ret_file_name ;
  3582.       end if ;
  3583.     end get_output_filename_or_return ;
  3584.      
  3585.     Function get_output_filename_or_return return ascii_text_file_name is
  3586.     begin
  3587.       return get_output_filename_or_return( default_text_file_suffix ) ;
  3588.     end ;
  3589.  
  3590.     procedure error_beep( beep_length : in a_beep_length ) is
  3591.     -- type a_beep_length is ( extra_short_beep , short_beep , medium_beep , 
  3592.     --                         long_beep , extra_long_beep );
  3593.     begin -- error_beep 
  3594.       basic_io_system.put(ascii.bel);
  3595.     end error_beep ;
  3596.        
  3597.     procedure error_wait( wait_length : a_wait_length ) is
  3598.     -- type a_wait_length is ( extra_short_wait , short_wait , medium_wait , 
  3599.     --                         long_wait , extra_long_wait , operator_wait );
  3600.      
  3601.     begin -- error_wait
  3602.       case wait_length is
  3603.         when extra_short_wait => delay 1.0 ;
  3604.         when short_wait       => delay 2.0 ;
  3605.         when medium_wait      => delay 4.0 ;
  3606.         when long_wait        => delay 8.0 ;
  3607.         when extra_long_wait  => delay 16.0 ;
  3608.         when operator_wait    => crt_windows.wait_for_character(' ') ;
  3609.       end case ;
  3610.     end error_wait ;
  3611.        
  3612.     procedure error( error_message : in string     ;
  3613.                      is_it_fatal   : type_of_error ;
  3614.                      wait_length   : a_wait_length ;
  3615.                      beep_length   : a_beep_length ) is
  3616.       -- We have an error.  Show the message, and then work as appropriate 
  3617.     begin -- error
  3618.       error( string_to_pstring ( error_message ) , is_it_fatal ,
  3619.              wait_length , beep_length );
  3620.     end error ;
  3621.      
  3622.     procedure error( error_message : in string_library.pstring ;
  3623.                      is_it_fatal   : type_of_error ;
  3624.                      wait_length   : a_wait_length ;
  3625.                      beep_length   : a_beep_length ) is
  3626.       -- We have an error.  Show the message, and then work as appropriate 
  3627.       temp_window : window_pointer ;
  3628.     begin -- error
  3629.       -- first, erase the prompt area to make room for error message
  3630.       if current_window = no_window then
  3631.         -- we need to do something, just to make a window available
  3632.         temp_window := create_window( 1 , 80 , 1 , 24 , true , 1 ) ;
  3633.         set_current_window(temp_window);
  3634.       end if ;
  3635.       save_prompt_temporarily ;
  3636.       clear_prompt(current_window);  
  3637.       -- Now, put out the error message
  3638.       set_reverse(true);
  3639.       if wait_length = operator_wait then
  3640.         set_prompt ( current_window , 1 , 
  3641.                      error_message.data( 1 .. length(error_message) )
  3642.                      & "  Type <space> to continue " );
  3643.       else
  3644.         set_prompt ( current_window , 1 , 
  3645.                      error_message.data( 1 .. length(error_message) ) );
  3646.       end if ;
  3647.       set_reverse(false);
  3648.       error_beep(beep_length);
  3649.       error_wait(wait_length);
  3650.       if is_it_fatal = fatal_error then
  3651.         raise user_abort ;
  3652.       else
  3653.         restore_prompt_after_temporary_save ;
  3654.       end if;
  3655.     end error ;
  3656.       
  3657.   begin -- Wordp_Globals
  3658.     -- WPGLOBAL by SAIC/Clearwater Word Processor Globals      10 Jan 85
  3659.     -- FILENAME by SAIC/Clearwater File Name Package           10 Jan 85
  3660.     -- ERRORS   by SAIC/Clearwater Error Package               10 Jan 85
  3661.     null ;
  3662.   end Wordp_Globals ;
  3663.  
  3664.   --$$$- WPGLOBAL
  3665.  
  3666.  
  3667.