Jump to content

REXX Tips & Tricks:Sample source code

From EDM2
Revision as of 22:19, 21 December 2012 by Martini (talk | contribs) (Created page with "This section contains some sample source code. (see also Using the samples) ==Using ANSI sequences== This section contains some routines for the display and for redefining of ...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

This section contains some sample source code. (see also Using the samples)

Using ANSI sequences

This section contains some routines for the display and for redefining of keys using ANSI sequences. (see also ANSI ESC Sequences)

Check if ANSI is active - 1 -

 
/* sample routine to check if ANSI is activated                       */
/*                                                                    */
/* see also Check if ANSI is active - 2 -                             */
/*                                                                    */

  i = CheckAnsi()
  if i = 1 then
    say "ANSI is activated"
  else
    if i = 0 then
      say "ANSI is not activated."
    else
      say "Error detecting ANSI."

exit 0

/* ------------------------------------------------------------------ */
/* function: Check if ANSI is activated                               */
/*                                                                    */
/* call:     CheckAnsi                                                */
/*                                                                    */
/* where:    -                                                        */
/*                                                                    */
/* returns:  1 - ANSI support detected                                */
/*           0 - no ANSI support available                            */
/*          -1 - error detecting ansi                                 */
/*                                                                    */
/* note:     Tested with the German and the US version of OS/2 3.0    */
/*                                                                    */
/*                                                                    */
CheckAnsi: PROCEDURE
  thisRC = -1

  trace off
                        /* install a local error handler              */
  SIGNAL ON ERROR Name InitAnsiEnd

  "@ANSI 2>NUL | rxqueue 2>NUL"

  thisRC = 0

  do while queued() <> 0
    queueLine = lineIN( "QUEUE:" )
    if pos( " on.", queueLine ) <> 0 | ,                       /* USA */
       pos( " (ON).", queueLine ) <> 0 then                    /* GER */
      thisRC = 1
  end /* do while queued() <> 0 */

InitAnsiEnd:
RETURN thisRC
Check if ANSI is active - 2 -
/* sample routine to check if ANSI is activated (using REXXUTIL)      */
/* based on a idea and code of Erik Schneller                         */
/* (see EMail Addresses)                                              */
/*                                                                    */
/* see also Check if ANSI is active - 1 -                             */
/*                                                                    */
  i = CheckAnsi()
  if i = 1 then
    say "ANSI is activated"
  else
    if i = 0 then
      say "ANSI is not activated."
    else
      say "Error detecting ANSI."

exit 0

/* ------------------------------------------------------------------ */
/* function: Check if ANSI is activated                               */
/*                                                                    */
/* call:     CheckAnsi                                                */
/*                                                                    */
/* where:    -                                                        */
/*                                                                    */
/* returns:  1 - ANSI support detected                                */
/*           0 - no ANSI support available                            */
/*          -1 - error detecting ansi                                 */
/*                                                                    */
/* note:     Tested with the German and the US version of OS/2 3.0    */
/*           based on a idea and code of Erik Schneller               */
/*           (see EMail Addresses)                                    */
/*                                                                    */
/*                                                                    */
CheckAnsi: PROCEDURE
  thisRC = -1

                        /* install a local error handler              */
  SIGNAL ON ERROR Name InitAnsiEnd

                    /* register the function SysCurPos from REXXUTIL  */
  call rxFuncAdd "SysCurPos", "REXXUTIL", "SysCurPos"

                    /* get and save the current cursor position       */
  curPos = SysCurPos()

                    /* write a CR/LF and the ANSI code for CursorUp   */
  call charOut , D2C(13) || "1B"x || "[1A"

                    /* now get the current cursor position            */
  NewPos=SysCurPos()

                    /* compare the new position to the old position   */
  if LEFT( NewPos,2 ) == LEFT( curPos,2 ) THEN
  do
                    /* ANSI support is OFF                            */
     thisRC = 0

                /* goto the begin of the line and delete the garbage  */
     call CharOut, D2C(13) || copies( " ",4 ) || D2C(13)
  end /* if left( ... */
  else
  do
                    /* ANSI support is ON                             */

                    /* restore the old cursor position                */
    call CharOut , "1B"x || "[B"
    thisRC = 1
  end /* else */

InitAnsiEnd:
RETURN thisRC


Get the current cursor position

 
/* sample routine to get the current cursor position with plain REXX  */
/* and ANSI commands                                                  */
/* Original code is from the ANSICD package from Jamie Hoglund        */

  parse value GetCursorPos() with col row
  say "At program start the cursor was at " || ,
      "Column " || col || ", Row " || row || "."
exit 0

/* ------------------------------------------------------------------ */
/* function: Get the current cursor position                          */
/*                                                                    */
/* call:     GetCursorPos                                             */
/*                                                                    */
/* returns:  col row                                                  */
/*                                                                    */
/* note:     This function works only for display sizes up to 200 for */
/*           columns or rows. The upper left corner is 1,1.           */
/*           The REXXUTIL function SysCurPos uses zero based values   */
/*           (the upper left corner is 0,0).                          */
/*           Caution:                                            v2.90*/
/*           The REXX Queue must be empty for this code to work!      */
/*           If the REXX Queue is not empty, you can use code         */
/*           like                                                     */
/*             - create a new                                         */
/*             - make the new queue the default queue                 */
/*             - call GetCursorPos                                    */
/*             - make the old queue the default queue again           */
/*             - delete the new queue                                 */
/*                                                                    */
GetCursorPos: PROCEDURE
  usedChars = ":;<=>?@ABCD"

  Rc = Charout(,D2C(27) || "[6n")
  Pull Q

                                                             /* v2.30 */
  parse var q 3 y1 +1 y2 +1 3 row +2 6 x1 +1 x2 +1 6 col +2 .

  if pos( y1, usedChars ) <> 0 then
    row = 10 || y2

  if pos( x1, usedChars ) <> 0 then
    col = 10 || x2

return col row


Get the current screen size
/* sample routine to get the current screensize for textmode windows  */
/* without using REXXUTIL functions.                                  */

  parse value GetDisplaySize() with columns rows
  say "The current OS/2 window size is " || ,
      rows || " rows and " || columns || " columns."
exit 0

/* ------------------------------------------------------------------ */
/* function: Get the current display size                             */
/*                                                                    */
/* call:     GetDisplaySize                                           */
/*                                                                    */
/* returns:  columns rows                                             */
/*                                                                    */
/* note:     This function works only for display sizes up to 200 for */
/*           columns or rows. The upper left corner is 1,1.           */
/*           The REXXUTIL function SysCurPos uses zero based values   */
/*           (the upper left corner is 0,0).                          */
/*                                                                    */
GetDisplaySize: PROCEDURE expose thisPos

  usedChars = ":;<=>?@ABCD"

                    /* save current cursor position                   */
  rc = CharOut(, D2C(27) || '[' || "6n")
  pull curPos

                    /* try to set the cursor to the position 200,200  */
  rc = CharOut(, D2C(27) || '[' || "200;200H" )

                    /* get cursor position                            */
  rc = CharOut(, D2C(27) || '[' || "6n")
  pull tPos

                    /* restore current cursor position                */
  rc = CharOut(, substr( curPos,1, length( curPos)-1) || "H" )

                                                             /* v2.30 */
  parse var tPos 3 y1 +1 y2 +1 3 rows +2 6 x1 +1 x2 +1 6 cols +2 .

  if pos( y1, usedChars ) <> 0 then
    rows = 10 || y2

  if pos( x1, usedChars ) <> 0 then
    cols = 10 || x2

RETURN cols rows


Redefine some keys
/* sample code to do some key remapping with ANSI sequences           */
/* see also ANSI ESC Sequences ,                                      */
/* Key codes for key redefinitions and                                */
/* Using function keys                                                */
/*                                                                    */
/* Note: Turning extended keys off is NOT necessary for key     v1.60 */
/*       remapping. This information in RXT&T v1.50 was wrong.  v1.60 */


                        /* set F1 key to HELP<RETURN>                 */
  call CharOut , '1B'x || '[0;59;"HELP";13p'

                        /* set ALT-F10 to EXIT (without RETURN)       */
  call CharOut , '1B'x || '[0;113;"EXIT";p'

                        /* set "A" to ABER (without RETURN)           */
                        /* corrected in RXT&T v1.60                   */
  call CharOut , '1B'x || '[65;"ABER";p'

                        /* reset F1 key to F1                         */
  call CharOut , '1B'x || '[0;59;0;59;p'
Using function keys

To use function keys without the REXXUTIL functions, redefine them with a trailing CR (see also ANSI ESC Sequences, Key codes for key redefinitions, and download RxLBox for a working example):

 
/* sample key redefinitons                                            */

                    /* new definitons for the function keys           */
  keys.0 = 0
  i = keys.0

  i=i+1; keys.i.__org = '59'; keys.i.__new = 'F1'
  i=i+1; keys.i.__org = '60'; keys.i.__new = 'F2'
  i=i+1; keys.i.__org = '61'; keys.i.__new = 'F3'
  i=i+1; keys.i.__org = '62'; keys.i.__new = 'F4'
  i=i+1; keys.i.__org = '63'; keys.i.__new = 'F5'
  i=i+1; keys.i.__org = '64'; keys.i.__new = 'F6'
  i=i+1; keys.i.__org = '65'; keys.i.__new = 'F7'
  i=i+1; keys.i.__org = '66'; keys.i.__new = 'F8'
  i=i+1; keys.i.__org = '67'; keys.i.__new = 'F9'
  i=i+1; keys.i.__org = '68'; keys.i.__new = 'F10'

  keys.0 = i

                    /* ANSI esc sequence                              */
  ansi.__ESC = '1B'x

                    /* special character to detect function keys      */
  specialChar = 'FE'x

                    /* install error handler for CTRL-BREAK           */
  signal on halt

                    /* redefine the function keys                     */
  do i = 1 to keys.0
    call CharOut , ansi.__ESC || '[0;' || keys.i.__org || ';' || ,
        '"' || specialChar || keys.i.__New || specialChar || '"' || ,
        ';13p'
  end /* do i = 1 to keys.0 */

                    /* test the new key definitons                    */
  do forever
    call LineOut, 'Test the function key redefinitions'
    call CharOut, 'Enter a string (F10 to end): '
    userInput = lineIn()

                    /* test for function keys                         */
    parse var UserInput part1 (specialChar) fKey (specialChar) part2

    UserInput = part1 || part2

    say 'Userinput was: "' || UserInput || '"'

    if fkey = '' then
      say 'No function key pressed.'
    else
      say 'Function key "' || fkey || '" pressed.'

    if fkey = 'F10' then
      leave

  end /* do forever */

ProgramEnd:
                    /* undo the key redefinitons                      */
  do i = 1 to keys.0
    call CharOut , ansi.__ESC || '[0;' || keys.i.__org || ';' || ,
         '0;' || keys.i.__org || ';p'
  end /* do i = 1 to keys.0 */

exit

/* error handler for CTRL-BREAK                                       */

Halt:
  say
  say 'Program aborted by the user!'
  signal ProgramEnd

Use ANSI for a password input routine
/* sample input routine for passwords using ANSI sequences to hide    */
/* the input (stolen from a message on a public CompuServe forum)     */
/*                                                                    */

  myPassWord = GetPassword( "Please enter the password: " )

  say "You entered the password: " || myPassword

exit

/* ------------------------------------------------------------------ */
/* function: get a password from the user (without showing it on the  */
/*           screen)                                                  */
/*                                                                    */
/* call:     GetPassword( {prompt} )                                  */
/*                                                                    */
/* where:    prompt - prompt string                                   */
/*                    def.: none                                      */
/*                                                                    */
/* returns:  the entered password                                     */
/*                                                                    */
/* note:     This code only works with ANSI enabled                   */
/*                                                                    */
/*                                                                    */
GetPassword: PROCEDURE
  parse arg prompt

                    /* show the prompt (if any) and set the screen    */
                    /* attributes to notvisible                       */
  call CharOut , prompt || "1B"x || "[8m"

                    /* get the user input                             */
  parse pull password
                    /* reset the screen attributes                    */
  call CharOut , "1B"x || "[0m"

RETURN password
Using the lower right corner of the display

To print a character to the lower right corner of the screen without scrolling you must turn off the word wrap function of the ANSI driver (see also ANSI ESC Sequences):

/* code to show how to use the lower right corner of the display      */

                    /* ESC code for ANSI sequences                    */
  ansi.__ESC = "1B"x

                    /* ANSI sequences to position the cursor in the   */
                    /* upper right corner                             */
  ansi.__Pos0 = ansi.__ESC || "[1;1H"

                    /* ANSI code to turn word wrap off                */
  ansi.__WordWrapOff = ansi.__ESC || "[7l"

                    /* ANSI code to turn word wrap on                 */
  ansi.__WordWrapOn  = ansi.__ESC || "[7h"

                    /* empty line for the menu frame                  */
  Menu.__emptyLine   = "º" || copies( " ", 78 ) || "º"

                    /* separator lines for the menu frame             */
  Menu.__FrameLine1  = copies( "Í", 78 )
  Menu.__FrameLine2  = copies( "Ä", 76 )

                    /* menu frame                                     */
  Menu.__MenuMask = ,
     ansi.__Pos0                          || ,  /* position cursor    */
     ansi.__WordWrapOn                    || ,  /* turn word wrap on! */
     "É"  || Menu.__FrameLine1 || "»"     || ,  /* menu frame         */
     Menu.__emptyLine                     || ,
     Menu.__emptyLine                     || ,
     "º " || Menu.__FrameLine2 || " º"    || ,
     Menu.__emptyLine                     || ,
     "Ì"  || Menu.__FrameLine1 || "¹"     || ,
     copies( Menu.__emptyLine, 14 )       || ,
     "Ì"  || Menu.__FrameLine1 || "¹"     || ,
     Menu.__emptyLine                     || ,
     "º " || Menu.__FrameLine2 || " º"    || ,
     Menu.__emptyLine                     || ,
     ansi.__WordWrapOff                   || ,  /* turn word wrap off */
     "È"  || Menu.__FrameLine1 || "¼"     || ,  /* last menu line     */
     ansi.__Pos0                          || ,  /* position cursor    */
     ansi.__WordWrapOn                          /* turn word wrap on  */

                    /* clear the screen                               */
  'cls'
                    /* show the menu frame                            */
  call CharOut , Menu.__MenuMask

                    /* position the cursor in the middle of the       */
                    /* screen                                         */
  call CharOut , ansi.__ESC || "[12;30H"

                    /* wait for a key from the user                   */
  "@pause"

Date converting