/* 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