/* Rexx - An ISPF editor FIND command for regular expressions. */ /* An example of using Unix System Services in an edit macro. */ /* Regular expressions are documented in the z/OS USS books. */ /*-------------------------------------------------------------------*/ /* Author: Doug Nadel */ /*-------------------------------------------------------------------*/ /* Instructions and Caveats */ /* Only parameter is an unquoted regular expression. */ /* Examples: FINDRX [Oo]nly */ /* FINDRX un.*s */ /* FINDRX "[^"]*" (finds quoted strings) */ /* Supports RFIND (see below) */ /* */ /* Requires a working OMVS segment and write access to /tmp. */ /* The regular expression is used as the source operand in */ /* a sed command: 's/parm/fr xxx/' file */ /* so you may need to use escape sequences. */ /* For example: FINDRX fr x\{3\} or FINDRX .\/parm */ /* */ /* Files containing the string 'fr xxx' (without the space) */ /* will have problems because that string is used in sed cmd. */ /* */ /* Does not respect bounds, labels, excludes, all, first, etc.*/ /* */ /* Highlights found string but also similar ones in same col. */ /* */ /* HILITE is limited to 40 characters by ISPF. */ /* */ /* RFIND wraps unless there is only 1 occurrance in file. */ /* RFIND starts at the next character instead of after the */ /* found string (as the ISPF FIND command does). */ /* */ /* Redefines F/C/RFIND but undoes all redefines on any error. */ /* Subsequent RFINDs may produce a missing label message */ /* because of the way ISPF remembers find operands. */ /* */ /* Redefines FIND, CHANGE and RFIND but resets them when real */ /* FIND or CHANGE commands are issued. */ /* But this does cause 1st native FIND/CHANGE to not show msg.*/ /* */ /* CHANGE commands do not support regular expressions! */ /* */ /* A manual reset is available via the FINDRX RESET or */ /* FINDRX RES commands. */ /* */ /* Temp files created with permission 600. */ /*-------------------------------------------------------------------*/ /* ** This is a work in progress... This should be treated as beta */ /* level code and should not be used in any mission */ /* critical situation. This code has not been formally tested. */ /*-------------------------------------------------------------------*/ /* V1.00 20060912 - first crack at this. */ /*-------------------------------------------------------------------*/ Address isredit 'MACRO (MFRPARM)' Parse Source . . me . Address ispexec 'VGET ZEDITCMD' cmdname=word(translate(zeditcmd),1) If abbrev('FIND',cmdname,1) | abbrev('CHANGE' ,cmdname,1) Then Do Call reset_redefines Address ispexec 'CONTROL ERRORS RETURN' 'BUILTIN 'zeditcmd If rc >=8 Then /* can only show failure messages */ Address ispexec 'SETMSG MSG(*)' Exit End '(R,C) = CURSOR' r=r+0 c=c+0 If 0 <> syscalls('ON') Then Call exitproc ':Unix system services are unavailable' If translate(mfrparm)='RES' | translate(mfrparm)='RESET' Then Do Address ispexec 'VERASE MFRPARM' Call exitproc ':Commands reset, regular expressions discontinued.' End If mfrparm='*' Then Do Address ispexec 'VGET MFRPARM0' mfrparm=mfrparm0 Say 'Restoring regular expression : 'mfrparm End If mfrparm='' Then Address ispexec 'VGET MFRPARM' If mfrparm = '' Then Call exitproc 'No regular expression:'me' requires an operand' Address ispexec 'VPUT MFRPARM' mfrparm0=mfrparm Address ispexec 'VPUT MFRPARM0' Call msg 'OFF' filecopy='/tmp/'me'-source-'userid() file_sed='/tmp/'me'-target-'userid() '(LAST) = LINENUM .ZL' '(CSR) = LINENUM .ZCSR' Address syscall "unlink "file_sed Address syscall "unlink "filecopy stem.0=last Do linenum = 1 to last '(LINE) = LINE' linenum stem.linenum = line End If r>0 & c>0 & csr > 0 Then stem.r=overlay(' ',stem.r,1,c,' ') Address syscall "writefile (filecopy) 600 stem." cmd="umask 177;sed 's/"mfrparm"/fr"||"xxx/' "filecopy">"file_sed Call bpxwunix cmd /* Address tso 'obrowse ' filecopy */ Address syscall "readfile (file_sed) stem." Address syscall "unlink "file_sed Address syscall "unlink "filecopy If stem.0=0 Then Call exitproc 'Result unavailable:Probable expression error.' Address isredit If r=0 Then r=1 c=c+1 scol=c Do a=r to stem.0 Call search End Do a=1 to r /* if not found try from top */ Call search End Call exitproc 'Expression not found:Expression: 'mfrparm Call reset_redefines Exit search: p=pos('fr'||'xxx',stem.a,scol) If p > 0 Then Do 'CURSOR = 'a','1 '(LINE) = LINE' a 'LABEL 'a' = .FR 1' post=delstr(stem.a,1,p+4) len=pos(post,line,p)-p If post='' Then len=length(strip(line,'T'))-p+1 If len<1 Then len=1 str=substr(line,p,len) If len >40 Then Do Parse Value "NO * W " With zerralrm zerrhm zerrtp zerrwn='LNORESP' zerrsm='' /* "HILITE limit 40 chars" */ zerrlm="Only the first 40 characters are highlighted" zerrlm=zerrlm "due to an ISPF editor restriction." Address ispexec 'vget zscreenw' zerrlm=left(zerrlm,zscreenw)||'The actual length is 'len':' zerrlm=left(zerrlm,zscreenw*2 )||str Address ispexec 'SETMSG MSG(ISRZ003)' str=substr(str,1,40) End "BUILTIN F '"c2x(str)"'x .FR .FR FIRST "||p 'DEFINE RFIND ALIAS 'me 'DEFINE FIND ALIAS 'me 'DEFINE CHANGE ALIAS 'me Exit End scol = 1 Return exitproc: Address ispexec 'CONTROL ERRORS RETURN' If Arg(1) <> '' Then Do Call reset_redefines Parse Value "NO *" With zerralrm zerrhm Parse Value Arg(1) With zerrsm':'zerrlm Address ispexec 'SETMSG MSG(ISRZ002)' End Exit reset_redefines: Do Until rc>0 'DEFINE RFIND RESET' End Do Until rc>0 'DEFINE FIND RESET' End Do Until rc>0 'DEFINE CHANGE RESET' End Return