! EVE$ADVANCED.TPU 31-DEC-1992 10:08 Page 1 module eve$advanced ident "V03-011" ! ! COPYRIGHT © 1987, 1992 BY ! DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS ! ALL RIGHTS RESERVED ! ! THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED ! ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE ! INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER ! COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY ! OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY ! TRANSFERRED. ! ! THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE ! AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT ! CORPORATION. ! ! DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS ! SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. ! !++ ! FACILITY: ! DECTPU - Text Processing Utility ! EVE - Extensible Versatile Editor ! ! ABSTRACT: ! This is the source program for the EVE interface advanced features. ! This file was obtained from the old evesecini.tpu file. ! ! ENVIRONMENT: ! OpenVMS VAX, OpenVMS AXP, RISC/ULTRIX ! !Author: Bill Robinson ! ! CREATION DATE: 10-Oct-1986 ! ! MODIFIED BY: ! !-- !++ ! Table of Contents ! ! EVE$ADVANCED.TPU ! 31-DEC-1992 10:08 ! ! Procedure name Page Description ! -------------- ---- ------------ ! ! eve_attach 2 Attach to another process ! eve_dcl 3 Run DCL command and display results ! eve_repeat 4 Repeat next command ! eve$repeat 5 Repeat subprocedure ! eve_spawn 6 Spawn a subprocess ! eve_shell 7 Run shell command and display results !-- ! EVE$ADVANCED.TPU Page 2 procedure eve_attach (; the_process) ! Attach to another process ! Attach back to the parent process. Used when Eve is spawned from DCL ! and run in a subprocess ("kept Eve"). The DECTPU attach command can ! be used for more flexible process control. on_error [TPU$_NOPARENT]: eve$message (EVE$_NOSUBPROC); eve$learn_abort; return (FALSE); [OTHERWISE]: endon_error; %if eve$x_option_decwindows %then if eve$x_decwindows_active then eve$message (EVE$_NODECWCMD, 0, message_text (EVE$_ATTACH)); return (FALSE); endif; %endif if eve$x_ultrix_active then if the_process <> "" then eve$message (EVE$_TAKESNOARGS, 0, "ATTACH"); return (FALSE); endif; endif; eve$clear_message; ! Clear out old message if the_process = "" then attach; else attach (the_process); endif; return (TRUE); endprocedure; ! eve_attach ! EVE$ADVANCED.TPU Page 3 procedure eve_dcl (dcl_parameter) ! Run DCL command and display results ! Run a DCL command and put the output in a second window on the screen. ! This is the only command to automatically create a second window if ! needed, but the user is left in the current buffer at the end of the ! command (reduce trap-door risk). Returns true if successful, false ! if no dcl command was issued. ! ! This command also implements the SHELL command on ULTRIX. ! ! Parameters: ! ! dcl_parameter String containing DCL command - input local prompt_string, ! Prompt for a command no_reply, ! No reply message error_code, ! Message code for errors dcl_string, ! Local copy of dcl_parameter dcl_window, ! Window to map dcl_buffer this_window, ! Current window this_buffer; ! Current buffer on_error [TPU$_CREATEFAIL]: if eve$x_ultrix_active then error_code := message_text (EVE$_CANTCREASHELL, 1); else error_code := message_text (EVE$_CANTCREADCL, 1); endif; %if eve$x_option_decwindows %then if eve$x_decwindows_active then eve$popup_message (error_code); else eve$message (error_code); endif; %else eve$message (error_code); %endif eve$learn_abort; return (FALSE); [TPU$_CONTROLC]: if this_buffer <> eve$dcl_buffer then position (this_window); endif; eve$learn_abort; abort; [OTHERWISE]: endon_error; if eve$x_ultrix_active then prompt_string := message_text (EVE$_SHELLPROMPT, 1); no_reply := message_text (EVE$_NOSHELLCMD, 0); else prompt_string := message_text (EVE$_DCLPROMT, 1); no_reply := message_text (EVE$_NODCLCMD, 0); endif; if not (eve$prompt_string (dcl_parameter, dcl_string, prompt_string, no_reply)) then eve$learn_abort; return (FALSE); endif; if (get_info (eve$dcl_buffer, "type") <> BUFFER) then if eve$x_buf_str_dcl = tpu$k_unspecified then if eve$x_ultrix_active then eve$x_buf_str_dcl := "SHELL"; else eve$x_buf_str_dcl := "DCL"; endif; endif; ! do not make it a permanent buffer eve$dcl_buffer := eve$init_buffer (eve$x_buf_str_dcl, "", FALSE); endif; if (get_info (eve$x_dcl_process, "type") = UNSPECIFIED) or (eve$x_dcl_process = 0) then if eve$x_ultrix_active then eve$message (EVE$_CREATECHILD); eve$x_dcl_process := create_process (eve$dcl_buffer); else eve$message (EVE$_CREATEDCL); eve$x_dcl_process := create_process (eve$dcl_buffer, "$ set noon"); endif; endif; this_buffer := current_buffer; if this_buffer = eve$dcl_buffer then dcl_window := current_window; else if eve$x_number_of_windows = 1 then eve_split_window (2); this_window := eve$top_window; update (eve$top_window); dcl_window := current_window; map (dcl_window, eve$dcl_buffer); else this_window := current_window; dcl_window := eve$get_mapped_window (eve$dcl_buffer); if dcl_window = 0 then ! insure the dcl_window is opposite the current_window dcl_window := eve$bottom_window; if dcl_window = this_window then dcl_window := eve$top_window; endif; endif; map (dcl_window, eve$dcl_buffer); endif; endif; eve$set_status_line (dcl_window); position (end_of (eve$dcl_buffer)); ! Process the command string split_line; copy_text (dcl_string); update (current_window); send (dcl_string, eve$x_dcl_process); position (end_of (eve$dcl_buffer)); update (current_window); if this_buffer <> eve$dcl_buffer then position (this_window); endif; return (TRUE); endprocedure; ! eve_dcl ! EVE$ADVANCED.TPU Page 4 procedure eve_repeat ! Repeat next command (repeat_parameter, ! Number of times to repeat next command - input repeat_command) ! Command to repeat - optional input local count, ! Local copy of repeat_parameter next_key, ! Keyword of next key following repeat command ix, temp; on_error [TPU$_READABORTED]: eve$message (EVE$_READABORTED); return; [OTHERWISE]: endon_error; if not eve$declare_intention (eve$k_action_repeat) then return (FALSE); endif; if not (eve$prompt_number (repeat_parameter, count, message_text (EVE$_RPTPROMPT, 1), message_text (EVE$_NOTRPT, 0))) then eve$learn_abort; return (FALSE); endif; if count <= 1 then eve$message (EVE$_NOTRPT); eve$learn_abort; return (FALSE); else ! Init the repeat variables if needed if eve$x_repeat_count = 0 then eve$init_repeat; temp := count; else ! See if we will be multiplying this count with a previous repeat count. ix := get_info (eve$x_repeat_count, "last"); if ix = tpu$k_unspecified then ix := 1; else ix := ix + 1; endif; if (eve$x_repeat_types {ix - 1} <> LEARN) and (eve$x_repeat_types {ix - 1} <> 0) then temp := eve$x_repeat_count {ix - 1} * count; else temp := count; endif; endif; if repeat_command = "" then eve$message (EVE$_WILLRPT, 1, temp); update (message_window); next_key := read_key; ! Get key to repeat if eve$is_mouse (next_key) then eve$message (EVE$_CANTREPT); eve$learn_abort; return (FALSE); endif; eve$clear_message; else eve$message (EVE$_WILLRPTCMD, 1, temp, repeat_command); endif; if not eve$repeat (count, next_key, repeat_command) then eve$learn_abort; return (FALSE); else eve$clear_message; return (TRUE); endif; endif; endprocedure; ! eve_repeat ! EVE$ADVANCED.TPU Page 5 procedure eve$repeat ! Repeat subprocedure (repeat_count, the_key; repeat_command) ! optional command, ignore the_key if specified local ascii_the_key, ! String of the_key ix, ! Index into repeat array status, temp, saved_do_line, ! Current command saved_parsed_line, ! Current parsed command key_program, ! Program associated with the_key repeat_comment; ! String associated with the_key on_error [TPU$_CONTROLC]: eve$learn_abort; abort; [OTHERWISE]: eve$message (EVE$_REPEATSTOP); eve$learn_abort; return (FALSE); endon_error; if repeat_count = 0 then eve$message (EVE$_NOREPEATZERO); eve$learn_abort; return (FALSE); endif; ! If eve$x_repeat_count = 0, then an error occurred that did not call ! eve$learn_abort (which calls eve$init_repeat to init the repeat variables), ! and TPU cleared our special_error_symbol variable. ! Init the repeat variables if 0. if eve$x_repeat_count = 0 then eve$init_repeat; endif; ! Correct use of eve$x_repeat_count and eve$x_repeat_do arrays requires ! NOT keeping indexes in global variables, but getting the last index into ! a local variable. If user does another REPEAT, it will consume this current ! count by multiplying it with the new count, and then set this count to ! 1 so this repeat stops. ix := get_info (eve$x_repeat_count, "last"); if ix = tpu$k_unspecified then ix := 1; else ix := ix + 1; endif; ! Do not touch learn sequence repeat counts if (eve$x_repeat_types {ix - 1} <> LEARN) and (eve$x_repeat_types {ix - 1} <> 0) then ! A repeat followed by this key: multiply last repeat count with this key's ! repeat count, and stop the first repeat by making its count = 1. eve$x_repeat_count {ix} := eve$x_repeat_count {ix - 1} * repeat_count; eve$x_repeat_count {ix - 1} := 1; else eve$x_repeat_count {ix} := repeat_count; endif; ! If optional command supplied, treat as if a DO key, and execute the command. if (repeat_command <> "") and ! Parser passed "" (repeat_command <> tpu$k_unspecified) ! Called from eve$edt_repeat then ! Save repeat counts by saving the index into eve$x_repeat_count. eve$x_repeat_types {ix} := DO; temp := get_info (eve$x_repeat_do, "last"); if temp = tpu$k_unspecified then temp := 1; else temp := temp + 1; endif; eve$x_repeat_do {temp} := ix; ! Save+restore composite command so can execute it ! For example, composite command= repeat 4 move down ! repeat_command= move down saved_do_line := eve$x_do_line; saved_parsed_line := eve$x_parsed_do_line; status := eve$process_command (repeat_command); ! Do the command eve$x_do_line := saved_do_line; eve$x_parsed_do_line := saved_parsed_line; return (status); endif; ascii_the_key := eve$alphabetic (the_key); key_program := lookup_key (the_key, PROGRAM, eve$current_key_map_list); if (ascii_the_key <> "") and (key_program = 0) then ! insert printing key eve$x_repeat_types {ix} := KEYWORD; loop exitif eve$x_repeat_count {ix} = 0; copy_text (ascii_the_key); eve$x_repeat_count {ix} := eve$x_repeat_count {ix} - 1; endloop; else ! Check for DO key repeat_comment := eve$$lookup_comment (the_key, ""); if eve$test_synonym ("do", repeat_comment) then ! A real DO key. ! Save repeat counts by saving its index into eve$x_repeat_count eve$x_repeat_types {ix} := DO; temp := get_info (eve$x_repeat_do, "last"); if temp = tpu$k_unspecified then temp := 1; else temp := temp + 1; endif; eve$x_repeat_do {temp} := ix; eve$$enter_command_window; ! This return unwinds all repeat counts multiplied into this ! key's repeat count. return (TRUE); else if key_program = 0 then eve$message (EVE$_CANTREPT); eve$learn_abort; return (FALSE); else if get_info (lookup_key (the_key, PROGRAM), "type") = LEARN then eve$x_repeat_types {ix} := LEARN; else eve$x_repeat_types {ix} := KEYWORD; endif; loop exitif eve$x_repeat_count {ix} = 0; if execute (key_program) = 0 then eve$message (EVE$_REPEATSTOP); if eve$x_repeat_count = 0 then ! Error did not call eve$learn_abort, and TPU ! zeroed our special_error_symbol variable; init ! the repeat variables. eve$init_repeat; return (FALSE); endif; if eve$x_repeat_count {ix} = tpu$k_unspecified then ! We are unwinding after an error in a later repeat ! repeat key, just return return (FALSE); endif; exitif; endif; ! Just in case the program did not return 0 if eve$x_repeat_count = 0 then ! Error did not call eve$learn_abort, and TPU ! zeroed our special_error_symbol variable, init ! the repeat variables. eve$init_repeat; return (FALSE); endif; if eve$x_repeat_count {ix} = tpu$k_unspecified then ! We are unwinding after an error, just return return (FALSE); endif; eve$x_repeat_count {ix} := eve$x_repeat_count {ix} - 1; endloop; endif; endif; endif; eve$x_repeat_count {ix} := tpu$k_unspecified; eve$x_repeat_types {ix} := 0; return (TRUE); endprocedure; ! eve$repeat ! EVE$ADVANCED.TPU Page 6 procedure eve_spawn (; the_command) ! Spawn a subprocess ! Spawn a new DCL subprocess and go to that subprocess. Logging out of ! the subprocess will resume the Eve session. Useful for running ! screen-oriented programs that can't go through VMS mailboxes. on_error [TPU$_CREATEFAIL]: eve$message (EVE$_CANTCREADCL); eve$learn_abort; return (FALSE); [OTHERWISE]: endon_error; %if eve$x_option_decwindows %then if eve$x_decwindows_active then eve$message (EVE$_NODECWCMD, 0, message_text (EVE$_SPAWN)); return (FALSE); endif; %endif eve$clear_message; ! Clear out old message if the_command = "" then spawn; else spawn (the_command); endif; return (TRUE); endprocedure; ! eve_spawn ! EVE$ADVANCED.TPU Page 7 procedure eve_shell ! Run shell command and display results (shell_parameter) ! Execute a shell command and put the output in a second window on the screen. ! ! Parameters: ! ! shell_parameter String containing shell command - input return (eve_dcl (shell_parameter)); endprocedure; ! eve_shell ! EVE$ADVANCED.TPU Page 8 ! Module initialization code eve$arg1_repeat := "integer"; ! Global process varibles eve$x_dcl_process := 0; ! DCL subprocess used by DCL command endmodule; ! EVE$ADVANCED.TPU Page 9 eve$$require ("eve$core"); ! Build dependency eve$$require ("eve$file"); eve$$require ("eve$windows");