[Toc][Index]

General input line enhancer



Some command line programs do not have a comfortable command line editor 
(for example the Oracle CLI programs svgrmgr or sqlplus are programs of 
this kind [at least the Solaris versions are]) 
For these programs you can use the REXX program below to add a command 
line editor. Just call them via 

 
  myshell.cmd program_name {/lf|/cr} {parameter_for_the_program}

Using myshell.cmd you can also add some macro features or something like 
this to such programs. 
To create myshell.cmd do the following: 
   1. Copy this section into a file (e.g., TEXT.TMP) 
   2. Append CMDLINE.CMD to the end of the just created file 
   3. remove all lines until the first comment line from the file TEXT.TMP 
      
   4. rename the file TEXT.TMP to myshell.cmd 
 
 see also REXX Wrapper for textmode programs, Navigate another program, 
 Output & Input control, Using the handles 3 to 9 in REXX programs, Using 
 "Named Pipes" 
 

  
 /* ------------------------------------------------------------------ */
 /* MYSHELL.CMD                                                        */
 /*                                                                    */
 /* function:   add command line editing to other programs             */
 /*                                                                    */
 /* usage:      myshell.cmd {/lf|/cr} prog_to_execute {parameter}      */
 /*                                                                    */
 /* parameters: /lf                                                    */
 /*                use linefeed (0x0A) only (optional)                 */
 /*             /cr                                                    */
 /*                use carriage return (0x0D) only (optional)          */
 /*                                                                    */
 /*             Default without /lf and /cr is CR/LF (0x0D0A)          */
 /*                                                                    */
 /*             prog_to_execute                                        */
 /*                fully qualified path and name of the program to     */
 /*                execute                                             */
 /*                                                                    */
 /*             parameter                                              */
 /*                parameter for the program                           */
 /*                                                                    */
 /* history:    14.07.2003 first release                               */
 /*                                                                    */
 /*                                                                    */
 /* notes:      This program only works if the called program reads    */
 /*             the input from STDIN (standard input)!                 */
 /*                                                                    */
 /*             To test, if a program reads from STDIN create a plain  */
 /*             textfile with commands for that program (e.g. in.txt)  */
 /*             and then issue                                         */
 /*                                                                    */
 /*                 your_program <in.txt                               */
 /*                                                                    */
 /*             If this works, the program reads from STDIN and should */
 /*             work with MYSHELL.CMD                                  */
 /*                                                                    */
 /*             MYSHELL.CMD ends if it finds one of the commands       */
 /*                                                                    */
 /*                 quit                                               */
 /*             or                                                     */
 /*                 exit.                                              */
 /*                                                                    */
 /*             You may add further necessary commands to end          */
 /*             MYSHELL.CMD (depending on the called program) to the   */
 /*             variable                                               */
 /*                                                                    */
 /*                  exit_commands                                     */
 /*                                                                    */
 /*             While MYSHELL.CMD is running you can enter REXX code   */
 /*             using the prefix !, e.g.                               */
 /*                                                                    */
 /*                 !say (4*55)/8                                      */
 /*                                                                    */
 /*             Commands starting with ! are interpreted by            */
 /*             MYSHELL.CMD and NOT by the program to execute.         */
 /*             To pipe a command starting with ! to the program to    */
 /*             execute use " !" or "!!".                              */
 /*                                                                    */
 /*             Use !> to use the output of a REXX statement as        */
 /*             input of your program, e.g.                            */
 /*                                                                    */
 /*                 !>(4+55)/8                                         */
 /*                                                                    */
 /*             would write 7.375 to the STDIN of the program.         */
 /*                                                                    */
 /*             One of the parameter /LF or /CR is neccessary if the   */
 /*             program called does not handle the default line        */
 /*             separator (CR/LF) correct.                             */
 /*                                                                    */
 /*             usage examples:                                        */
 /*                                                                    */
 /*                 myshell c:\os2\cmd.exe                             */
 /*                                                                    */
 /*             You can't use telnet with myshell.cmd - use tnpipe     */
 /*             instead:                                               */
 /*                                                                    */
 /*                 myshell /LF c:\mtpn\bin\tnpipe.exe 127.0.0.1       */
 /*                                                                    */
 /*             Please note that MYSHELL.CMD does NOT work with        */
 /*             every program, for example ftp.exe.                    */
 /*             But at least the cmd.exe works :-)                     */
 /*                                                                    */
 /* (c) 2003 Bernd Schemmer, Germany, EMail: Bernd.Schemmer@gmx.de     */
 /* ------------------------------------------------------------------ */
 
                     /* commands to end MYSHELL.CMD                    */
                     /* add further exit commands here (depending      */
                     /* of the programs you want to use MYSHELL with)  */
   exit_commands = "QUIT EXIT"
 
   parse arg thisOption thisArgs
 
                     /* check for the options for MYSHELL.CMD          */
   select
 
     when translate( thisOption ) = '/H' then
     do
       call lineOut, "Usage:  myshell.cmd {/lf|/cr} prog_to_execute {parameter}"
       exit 1
     end /* when */
 
     when translate( thisOption ) = '/LF' then
       LINE_SEPARATOR = '0A'x
 
     when translate( thisOption ) = '/CR' then
       LINE_SEPARATOR = '0D'x
 
     otherwise
       LINE_SEPARATOR = '0A0D'x
       thisOption = ''
       parse arg thisArgs
 
   end /* select */
 
                     /* get the name and path of this program          */
   parse source . . thisprog
   thisProgname = filespec( "N", thisProg )
 
                     /* check if we're called as filter                */
   FILTER_MARKER = "$$FILTER$$"
   if thisArgs = FILTER_MARKER then
   do
                     /* run in filter mode                             */
     do forever
       if lines() = 0 then
         exit
 
       thisLine = lineIn()
 
       call CharOut , thisLine || LINE_SEPARATOR
 
       if Exitcommand( thisLine ) <> 0 then
         exit
     end /* do forever */
     exit
   end /* if */
 
   if thisArgs <> "" then
   do
                     /* check the supplied program name                */
                     /* you may use SearchFilefile here to search a    */
                     /* program in the PATH                            */
     extProg = word( thisArgs, 1  )
     if stream( extProg, 'c', 'QUERY EXISTS' ) = '' then
     do
       call lineOut "STDERR", thisProg || " - Error: can not find " || extProg || "!"
       exit 255
     end /* if */
     else
     do
                     /*                                                */
                     /* The additional call of MYSHELL.CMD as filter   */
                     /* between MYSHELL.CMD and the program to execute */
                     /* is necessary because it's not possible to use  */
                     /* REXX commands to write to the handle 3.        */
                     /* Therefor we need to use ECHO for this purpose. */
                     /* But ECHO always appends a CR/LF to the string  */
                     /*  - and some programs don't handle CR/LF in     */
                     /* STDIN correct.                                 */
                     /*                                                */
                     /* It is possible to use the handle 2 (STDERR)    */
                     /* instead of 3 to pipe the output of MYSHELL     */
                     /* into the STDIN of the program to execute - but */
                     /* in this case all error messages of MYSHELL.CMD */
                     /* would also go to STDIN of the program to       */
                     /* execute.                                       */
 
       "cmd /c " thisprog "3>>&1 1>>SCREEN$ | " thisProg thisOption FILTER_MARKER " | " thisArgs
     end /* else */
   end /* if */
   else
   do
                     /* second call, now the handle 3 (&3) is STDIN of */
                     /* the MYSHELL.CMD running in filter mode and     */
                     /* STDOUT of MYSHELL.CMD running in filter mode   */
                     /* is STDIN of the called program                 */
                     /*                                                */
                     /* It's simple - isn't it? :-)                    */
                     /*                                                */
     call LineOut , ""
     call LineOut , "---------------------------------------------------"
     call LineOut , thisProgname || " is active "
     call LineOut , "Use !rexx_command to execute a REXX command."
     call LineOut , "Use !exit to leave after the other program ended."
     call LineOut , "Just hit enter if you lost the prompt of the program. "
     call LineOut , "---------------------------------------------------"
     call LineOut , ""
     do forever
 
       inputLine = cmdLine()
 
       if left( inputLine, 1 ) = '!' then
       do
         select
           when left( inputLine, 2 ) = '!!' then
           do
             inputLine = substr( inputLine, 2 )
           end /* if */
 
           when left( inputline, 2 ) = '!>' then
           do
             call lineOut, " +++ REXX code found, now executing it +++"
             if InterpretCommand( "inputLine=" substr( inputLine, 3 ) ) <> 0 then
               iterate
           end /* if */
 
           otherwise
           do
             call lineOut, " +++ REXX code found, now executing it +++"
             call InterpretCommand substr( inputLine, 2 )
             call lineOut, " +++ executing of REXX code done. Press return to get your prompt back+++"
             iterate
           end /* else */
 
         end /* select */
       end /* if */
 
                     /* pipe the line to MYSHELL.CMD which then pipes  */
                     /* it to STDIN of the program to execute          */
       "@echo." || inputline || ">&3"
 
       if Exitcommand( inputLine ) <> 0 then
       do
         call LineOut , "---------------------------------------------------"
         call LineOut , thisProgname || " ended."
         call LineOut , "---------------------------------------------------"
 
         leave
       end /* if */
 
     end /* do forever */
   end /* else */
 
 exit
 
 /* ------------------------------------------------------------------ */
 /* function: check for a command to exit                              */
 /*                                                                    */
 /* call:     exitCommand( inputLine )                                 */
 /*                                                                    */
 /* where:    inputLine - line to check                                */
 /*                                                                    */
 /* returns:  1 - exit command not found                               */
 /*           else - exit command found                                */
 /*                                                                    */
 /*                                                                    */
 /* note:     This check is necessary if MYSHELL.CMD runs as filter    */
 /*           and if MYSHELL.CMD runs in interactive mode to read the  */
 /*           commands. Therefor this is a function.                   */
 /*                                                                    */
 Exitcommand: PROCEDURE expose exit_commands
   return wordpos( translate( arg( 1 ) ), exit_commands )
 
 /* ------------------------------------------------------------------ */
 /* function: interpret a command simulating "CALL ON SYNTAX"          */
 /*                                                                    */
 /* call:     interpretCommand cmd                                     */
 /*                                                                    */
 /* where:    cmd - command to interpret                               */
 /*                                                                    */
 /* returns:  0 - execution okay                                       */
 /*           else error executing the command                         */
 /*                                                                    */
 /*                                                                    */
 /* note:     do not use the keyword PROCEDURE!                        */
 /*                                                                    */
 InterpretCommand:
   parse arg IC.__CurLine
 
                         /* init return code with failure code         */
   IC.__ThisRC = 1
 
                         /* install a local error handler              */
   SIGNAL ON SYNTAX    NAME InterpretCommand1
   SIGNAL OFF NOVALUE
   SIGNAL OFF FAILURE
   SIGNAL OFF ERROR
   SIGNAL OFF NOTREADY
 
                         /* execute the line                           */
   interpret IC.__CurLine
 
                         /* set return code to OK                      */
                         /* this statement is not executed if an error */
                         /* occurs while executing the previous        */
                         /* interpret command                          */
   IC.__ThisRC = 0
 
 InterpretCommand1:
   if IC.__ThisRC = 1 then
   do
     IC.__ThisRC = rc
 
     call LineOut , "---------------------------------------------------"
     call LineOut , thisProgName || ": Error executing the REXX statement "
     call LineOut , IC.__CurLine
     call LineOut , "Condition(C) is " || condition('C')
     call LineOut , "Condition(D) is " || condition('D')
     call LineOut , "---------------------------------------------------"
   end /* if */
                         /* drop unnecessary local variables         */
   drop IC.__CurLine
 
 RETURN IC.__ThisRC
 
 /* !!! insert CMDLINE.CMD here !!! */
 
 
   

Created using Inf-PHP v.2 (c) 2003 Yuri Prokushev
Created using Inf-HTML v.0.9b (c) 1995 Peter Childs