home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / rxtraptr.zip / you.cmd
OS/2 REXX Batch file  |  2002-04-09  |  7KB  |  144 lines

  1. /*  YOU 0 | pipe | YOU 1           first | YOU 2 | pipe | YOU 1   */
  2. /* /                    \                 /                    \  */
  3. /* \_ pull <==== queue _/                 \_ pull <==== queue _/  */
  4.  
  5.    call trace 'O'                   /* disable any SET RXTRACE=ON */
  6.    signal on novalue  name TRAP     ;  signal on syntax name TRAP
  7.    signal on failure  name TRAP     ;  signal on halt   name TRAP
  8.    call UTIL 'SysSleep'             ;  arg IO QU QD
  9.  
  10.    if wordpos( IO, '0 1 2' ) = 0 | QD <> '' then do
  11.       parse source . . IO  ;  QU = 'examples (looping "forever"):'
  12.       say 'usage:' IO '0|1|2 [queue]'
  13.       say '0    : copy queue to standard output (top)'
  14.       say '1    : copy standard input to queue (tail)'
  15.       say '2    : copy STDIN and then queue to STDOUT'
  16.       say '  XYZ: create / delete queue XYZ'
  17.       say ' else: use default SESSION queue,' QU
  18.       say 'echo loop |' IO '2 | tee \dev\con |' IO '1'
  19.       say 'echo dito |' IO '2 | tee \dev\con | rxqueue'
  20.       say 'echo fail |' IO '2 XYZ | tee \dev\con | rxqueue XYZ'
  21.       say 'echo okay |' IO '2 XYZ | tee \dev\con |' IO '1 XYZ'
  22.       say IO '0 XYZ | chess white | chess black |' IO '1 XYZ'
  23.       exit 1
  24.    end
  25.  
  26.    QD = ( QU <> '' & IO <> 1 )      /* QD = 0: no QUeue Deletion  */
  27.  
  28.    if QD then do
  29.       call rxqueue 'DELETE', QU     /* delete old & create new QU */
  30.       if rxqueue(  'CREATE', QU ) <> QU
  31.          then exit TRAP( 'cannot create queue' QU )
  32.    end
  33.    signal on novalue  name DONE     ;  signal on syntax name DONE
  34.    signal on failure  name DONE     ;  signal on halt   name DONE
  35.  
  36.    if QU <> '' then do              /* wait for new QU creation   */
  37.       call SysSleep 1   ;  call rxqueue 'SET', QU
  38.    end
  39.  
  40.    if IO = 2 then do                /* first copy STDIN to STDOUT */
  41.       IO = 0   ;  signal on notready name LOOP
  42.       do while lines() > 0 ;  say linein()   ;  end
  43.    end                              /* NOTREADY continues at LOOP */
  44. LOOP:                               /* no procedure: using IO, QD */
  45.    signal on notready name DONE     /* signal on any I/O problems */
  46.    do forever
  47.       if IO = 0
  48.          then do while queued() > 0 ;  say PULL()     ;  end
  49.          else do while lines( ) > 0 ;  queue linein() ;  end
  50.       call SysSleep 0               /* wait for other end of pipe */
  51.    end
  52.  
  53. PULL: procedure                     /* artificial pull wrapper to */
  54.    parse pull X   ;  return X       /* get "beautified" LOOP code */
  55.  
  56. UTIL: procedure                  /* load necessary RexxUtil entry */
  57.    if RxFuncQuery(  arg( 1 )) then
  58.       if RxFuncAdd( arg( 1 ), 'RexxUtil', arg( 1 )) then
  59.          exit TRAP( "can't add RexxUtil"  arg( 1 ))
  60.    return 0
  61.  
  62. DONE:                               /* either STDIN or STDOUT is  */
  63.    if IO = 0                        /* NOTREADY, drain other side */
  64.       then do while queued() > 0   ;  pull        ;  end
  65.       else do while lines( ) > 0   ;  call linein ;  end
  66.    call SysSleep 1                  /* wait for other end of pipe */
  67.    if IO = 0                        /* (it will see NOTREADY now) */
  68.       then do while queued() > 0   ;  pull        ;  end
  69.       else do while lines( ) > 0   ;  call linein ;  end
  70.    if condition( 'c' ) = 'HALT'
  71.       then call charout 'STDERR', 'terminated '
  72.    if QD then do                    /* erase the named REXX queue */
  73.       call rxqueue 'DELETE', QU     /* and show result (expect 0) */
  74.       call lineout 'STDERR', 'deleting' QU '(' || result || ')'
  75.    end
  76.  
  77.    if condition( 'c' ) = 'HALT'     then exit 0 /* interrupted or */
  78.    if condition( 'c' ) = 'NOTREADY' then exit 0 /* terminated ok. */
  79.  
  80.    /* otherwise after FAILURE, SYNTAX, or NOVALUE drop into TRAP: */
  81.    signal on novalue  name TRAP     ;  signal on syntax name TRAP
  82.    signal on failure  name TRAP     ;  signal on halt   name TRAP
  83.  
  84. TRAP:                            /* select REXX exception handler */
  85.    call trace 'O' ;  trace N           /* don't trace interactive */
  86.    parse source TRAP                   /* source on separate line */
  87.    TRAP = x2c( 0D ) || right( '+++', 10 ) TRAP || x2c( 0D0A )
  88.    TRAP = TRAP || right( '+++', 10 )   /* = standard trace prefix */
  89.    TRAP = TRAP condition( 'c' ) 'trap:' condition( 'd' )
  90.    select
  91.       when wordpos( condition( 'c' ), 'ERROR FAILURE' ) > 0 then do
  92.          if condition( 'd' ) > ''      /* need an additional line */
  93.             then TRAP = TRAP || x2c( 0D0A ) || right( '+++', 10 )
  94.          TRAP = TRAP '(RC' rc || ')'   /* any system error codes  */
  95.          if condition( 'c' ) = 'FAILURE' then rc = -3
  96.       end
  97.       when wordpos( condition( 'c' ), 'HALT SYNTAX'   ) > 0 then do
  98.          if condition( 'c' ) = 'HALT' then rc = 4
  99.          if condition( 'd' ) > '' & condition( 'd' ) <> rc then do
  100.             if condition( 'd' ) <> errortext( rc ) then do
  101.                TRAP = TRAP || x2c( 0D0A ) || right( '+++', 10 )
  102.                TRAP = TRAP errortext( rc )
  103.             end                        /* future condition( 'd' ) */
  104.          end                           /* may use errortext( rc ) */
  105.          else  TRAP = TRAP errortext( rc )
  106.          rc = -rc                      /* rc < 0: REXX error code */
  107.       end
  108.       when condition( 'c' ) = 'NOVALUE'  then rc = -2 /* dubious  */
  109.       when condition( 'c' ) = 'NOTREADY' then rc = -1 /* dubious  */
  110.       otherwise                        /* force non-zero whole rc */
  111.          if datatype( value( 'RC' ), 'W' ) = 0 then rc = 1
  112.          if condition() = '' then TRAP = TRAP arg( 1 )
  113.    end                                 /* direct: TRAP( message ) */
  114.  
  115.    TRAP = TRAP || x2c( 0D0A ) || format( sigl, 6 )
  116.    signal on syntax name TRAP.SIGL     /* throw syntax error 3... */
  117.    if 0 < sigl & sigl <= sourceline()  /* if no handle for source */
  118.       then TRAP = TRAP '*-*' strip( sourceline( sigl ))
  119.       else TRAP = TRAP '+++ (source line unavailable)'
  120. TRAP.SIGL:                             /* ...catch syntax error 3 */
  121.    if abbrev( right( TRAP, 2 + 6 ), x2c( 0D0A )) then do
  122.       TRAP = TRAP '+++ (source line unreadable)'   ;  rc = -rc
  123.    end
  124.    select
  125.       when 1 then do                   /* in pipes STDERR: output */
  126.          parse version TRAP.REXX . .   /* REXX/Personal: \dev\con */
  127.          signal on syntax name TRAP.FAIL
  128.          if TRAP.REXX = 'REXXSAA'      /* fails if no more handle */
  129.             then call lineout 'STDERR'  , TRAP
  130.             else call lineout '\dev\con', TRAP
  131.       end
  132.       when 0 then do                   /* OS/2 PM: RxMessageBox() */
  133.          signal on syntax name TRAP.FAIL
  134.          call RxMessageBox ,           /* fails if not in PMREXX  */
  135.             translate( TRAP, ' ', x2c( 0D )), , 'CANCEL', 'WARNING'
  136.       end                              /* replace any CR by blank */
  137.       otherwise   say TRAP ; trace ?L  /* interactive Label trace */
  138.    end
  139.  
  140.    if condition() = 'SIGNAL' then signal TRAP.EXIT
  141. TRAP.CALL:  return rc                  /* continue after CALL ON  */
  142. TRAP.FAIL:  say TRAP ;  rc = 0 - rc    /* force TRAP error output */
  143. TRAP.EXIT:  exit   rc                  /* exit for any SIGNAL ON  */
  144.