REXX Lost and Found

A little REXX widget I wrote about 10 years ago, that I found back on an old disk:

#!/usr/bin/rexx
--
-- A Generalized Rexx Filter that can be used in a pipe
--
-- Usage: rexx filter.rex builtin-or-external-function-name(arg1, arg2, ...)
--    or: rexx filter.rex < inputfile
--    or: rexx filter.rex (boolean expression) 
--
-- Note 1:
--
--    rexx (to invoke filter.rex) may or may not be required to get 
--    the redirection and piping working, dependent on the operating
--    system and the REXX implementation and/or installation setup.  
--  
-- External functions can have a simple structure, for instance: 
--          
--    rexx filter.rex "cut.rex(!line,10:5)" or filter.rex "cut(!line,10:5)"
--
--    parse arg line,poslen
--    parse var poslen pos ':' length .
--    /* possibly more logic, but return value should be a (modified)
--       line or a boolean if the function is called as an expression */
--    return delstr(line,pos,length)  
--  
-- Argument(s)/Option(s) or even all of the filter have to be quoted generally.
-- On Windows: It's best to use '"' for all of the filtere and "'" for arguments.
-- On *n?x: It's best to use "'" for all of the filter and '"' for arguments.
-- On *n?x: Redirection (< and > or >> ) doesn't seem to work all of the time.
--
-- Pipe variables:
--
-- The input line from the pipe is represented by '!line'. 
-- The running line count is represented by '!count' 
-- The total nr of lines is respresented by '!lines'
-- Using '!lines' in the filter implies buffering the input stream before 
-- any output is passed on to the next pipe stage.
--
-- Example 1: rexx filter.rex changestr(needle,!line,newneedle)
--
-- Example 2: rexx filter.rex strip(!line,'L','>')
--
-- Example 3: rexx filter.rex < somefile.txt  - just echoes the input
--
-- Example 4: rexx filter.rex (pos('>',!line)>0) - a boolean expression 
--
-- Example 5: rexx filter.rex "(!count>10)" - skips first 10 lines of input
--
-- Example 6: rexx filter.rex "(!count>!lines-10)" - shows last 10 lines of input   
--
--    rexx filter.rex <filter.rex | ,
--    rexx filter.rex (pos('-',!line)=1) | , 
--    rexx filter.rex strip(!line,'L','-')
-- 
-- will first read and echo filter.rex, 
-- then output only input lines that start with '-',
-- then strip leading comment identifier '--'. 
--
-- No copyright, no license, no guarantees, use at your own risk.
--
-- And you just read the result of the pipe above.
--
parse source . . me  
parse arg !filter
do (!filter='?' | !filter='-?' | !filter='/?' | !filter='h' | !filter='-h' | !filter='/h' | !filter='--help')
  pipe = 'rexx "'me'"<"'me'" | rexx "'me'" (pos(''-'',!line)=1) | rexx "'me'" strip(!line,''L'',''-'')'
  pipe
  exit
end
!filter = strip(strip(strip(!filter,'B',' '),'B',"'"),'B','"')  -- strip spaces and quotes
do until (lines()>0)  -- a buffered stage can delay the input stream 
  nop
end 
!buffered = (pos('!lines',!filter)>0)
if (!buffered) then do  -- buffer input stream on standard queue
  do !lines=1 by 1 while (lines()>0)
    queue linein()
  end
  !lines = queued()
  !queued = !lines
  if (!queued>0) then do  -- prefetch the 1st line queue
    parse pull !line
  end  
end
else do
  !queued = lines()
  if (!queued>0) then do  -- prefetch the 1st line from stdin
    !line = linein()
  end) 
end
do !count=1 by 1 while (!queued>0)
  if (!filter = '') then do  -- no filter just echoes the input
    !out = !line
  end
  else do 
    if (substr(!filter,1,1)='(') then do
      drop !out    -- to verify !out is a var later on            
      interpret '!test =' !filter  -- apply the test
      if (!test) then do   -- if test yields .true it goes out
        !out = !line
      end
    end
    else do    -- apply the filter
      interpret '!out =' !filter  
    end
  end
   if (var("!out")) then do  -- only write if we have something 
     call lineout ,!out     
  end
  if (!buffered) then do  -- if buffered, next line from queue
  !queued = queued()
  if (!queued>0) then do
    parse pull !line
  end
  end
  else do  -- not buffered, next line from stdin
    !queued = lines()
  if (!queued>0) then do
    !line = linein()
  end
  end
end
exit

The single line comment ( “–” ) style, may limit the use of the above to ooREXX and Regina REXX.

Category(s): (oo)REXX
Tags: , , , , ,

Comments are closed.