/* REXX FIXTOOL Report a tool-error. Use '(routine name) ?' for HELP-text. |**-***-***-***-***-***-***-***-***-***-***-***-***-***-***-***-**| | | | WARNING: EMBEDDED COMPONENTS. | | See text following TOOLKIT_INIT | | | |**-***-***-***-***-***-***-***-***-***-***-***-***-***-***-***-**| Written by Frank Clarke rexxhead@yahoo.com 20091203 Impact Analysis . SYSEXEC ICEUSER . SYSEXEC LA . SYSEXEC TBLGEN . SYSEXEC TRAPOUT . ISPPLIB EMAINT (embedded) . ISPPLIB EMAINTH (embedded) . ISPPLIB GETEMA (embedded) . ISPPLIB GETEMAH (embedded) . ISPPLIB ITDETL (embedded) . ISPPLIB ITDETLH (embedded) . ISPPLIB ITMAIN (embedded) . ISPPLIB ITMAINH (embedded) . ISPPLIB NEWPROB (embedded) . ISPPLIB NEWPROBH (embedded) . ISPPLIB NEWSUGG (embedded) . ISPPLIB NEWSUGGH (embedded) . ISPPLIB PROBLST (embedded) . ISPPLIB PROBLSTH (embedded) . ISPPLIB TOOLFIX (embedded) . ISPPLIB TOOLFIXH (embedded) Modification History 20211105 fxc Collect each user name via GETNAME and save on the 3F row as 20230203 fxc make callable from READY 20230327 fxc CAPS(OFF) for 'itrdesc' in panel TOOLFIX; 20230415 fxc adjust HELP; 20230608 fxc use &zup/&zcont 20230613 fxc add DEL to DEIMBED ALLOC What would a good tool-trouble-reporting tool do? + There's a problem: - which tool? - who found it? - doing what? when? how? - logs or traps? - what did the problem look like? - notify the toolies + I have a suggestion: - which tool? - who suggests? - how should it work? - notify the toolies + It's fixed: - which tool? - what was the end-result? - notify the reporter(s) - close the report + I'm interested in this problem: - which tool? - who's interested - add to the list-of-reporters + What problems are on the list? - open (unfixed) - all (fixed and unfixed) */ arg argline address TSO /* REXXSKEL ver.20040227 */ arg parms "((" opts signal on syntax signal on novalue call TOOLKIT_INIT /* conventional start-up -*/ rc = Trace("O"); rc = Trace(tv) info = parms /* to enable parsing */ if sw.inispf = "0" then do arg line line = line "(( RESTARTED" /* tell the next invocation */ address TSO "ISPSTART CMD("exec_name line")" /* Invoke ISPF if nec. */ exit 2 /* bail out */ end call A_INIT /* -*/ call B_ISPF_OPTS /* -*/ if \sw.nested then call DUMP_QUEUE /* -*/ if sw.0restarted then do /* at end of mainline */ rc = OutTrap("ll.") exit 4 end exit /*@ FIXTOOL */ /* Establish root information . ----------------------------------------------------------------- */ A_INIT: /*@ */ if branch then call BRANCH address TSO report_error = "R" fix_problem = "F" make_suggest = "S" add_me_as_ip = "I" show_problem = "L" openmode.0 = "WRITE" /* based on NOUPDT */ openmode.1 = "NOWRITE" thisuser = Userid() parse value "" with, uname. email. parse value "0 0 0 0 0 0 0 0" with, msg. . call AK_KEYWDS /* -*/ if sw.0LoadQueue then do /* invoke TBLMSTR */ call Z_QUEUE /* adds IT row to AAMSTR -*/ end return /*@ A_INIT */ /* . ----------------------------------------------------------------- */ AK_KEYWDS: /*@ */ if branch then call BRANCH address TSO sw.0FixEmail = SWITCH( "EMAIL" ) /* Edit email address */ sw.0LoadQueue = SWITCH( "LOADQ" ) /* Set up IT table */ return /*@ AK_KEYWDS */ /* Post a new issue? Review an existing issue? Announce a fix? . ----------------------------------------------------------------- */ B_ISPF_OPTS: /*@ */ if branch then call BRANCH address ISPEXEC call BA_PROLOG /* -*/ if sw.0FixEmail then, call BB_FIX_EMAIL /* maintain my email address -*/ else, if sw.0Admin then, call BC_ADMIN /* maintain email addresses -*/ else, call BD_DISPLAY /* -*/ call BZ_EPILOG /* -*/ return /*@ B_ISPF_OPTS */ /* Invokes TBLGEN to build an IT-form table: AATBLID(IT) AATBLNM(TOOLERR) AAKEYS(ITTOOL ITRDATE ITRTIME ITRUSER) AANAMES(ITRDESC ITFDATE ITFDESC ITFUSER ITIPARTY ITSTATE) AADESC(Tool Problem Reports and Fixes) AASORT( ITRDATE,N,D ITRTIME,N,D ) . ----------------------------------------------------------------- */ BA_PROLOG: /*@ */ if branch then call BRANCH address ISPEXEC "LIBDEF ISPTLIB DATASET ID("isptlib") STACK" "TBSTATS" $tn$ "STATUS1(s1) STATUS2(s2)" if s1 > 1 then do if monitor then say, "Calling TBLGEN to build new IT table" address TSO "TBLGEN IT" call BAL_LOAD_SPECIAL /* -*/ end; else, if s2 = 1 then do /* table is not open */ "TBOPEN " $tn$ openmode.NOUPDT if rc > 4 then do sw.0error_found = 1 zerrsm = "Table did not OPEN" zerrlm = "Table" $tn$ "cannot be opened due to prior", "enqueues." "SETMSG MSG(ISRZ002)" end end "TBSORT" $tn$ "FIELDS( ITRDATE,N,D ITRTIME,N,D )" "LIBDEF ISPTLIB" call DEIMBED /* unload ISPF assets */ dd = "" do Words(ddnlist) /* each LIBDEF DD */ parse value ddnlist dd with dd ddnlist $ddn = $ddn.dd /* PLIB322 <- PLIB */ "LIBDEF ISP"dd "LIBRARY ID("$ddn") STACK" end ddnlist = ddnlist dd /* The special row, keyed as "3F"x holds only extension variables. Each of those is a userid, and the value stored under each userid is the email address for that user. That is: we now know all the email addresses for all users who have ever accessed FIXTOOL to report a problem, fix a problem, or who have been 'interested parties'. */ "TBVCLEAR" $tn$ /* zap all vars */ ittool = "3F"x /* special row */ "TBGET" $tn$ "SAVENAME( ULIST )" if rc > 0 then ulist = "( )" parse var ulist "(" ulist ")" /* yes, we want no bananas */ /* "ulist" is a list of all known userids. */ if ulist = "" then do /* brand-new table */ tools = "FCLARKE" fclarke = "rexxhead@yahoo.com" ulist = "TOOLS FCLARKE" /* admin rows */ "TBMOD" $tn$ "SAVE(" ulist ")" if monitor then say, "Admin row set to default" end /* empty ULIST */ else do /* ulist is populated */ u1 = "" do Words( ulist ) /* each user */ parse value ulist u1 with u1 ulist /* snip! */ udata = Value( u1 ) /* emailaddr;username */ parse var udata email.u1 ";" uname.u1 end /* Words */ ulist = ulist u1 end /* parse user IDs */ if uname.thisuser = "" then do uname.thisuser = GETNAME() /* get it from storage -*/ uname.thisuser = SHIFT( uname.thisuser ) /* re-case -*/ end return /*@ BA_PROLOG */ /* The special row is missing; build it. . ----------------------------------------------------------------- */ BAL_LOAD_SPECIAL: /*@ */ if branch then call BRANCH address ISPEXEC if monitor then say, "Building new Admin row" "TBVCLEAR" $tn$ /* zap all vars */ ittool = "3F"x /* lower than blank */ ulist = "" /* empty */ "TBADD" $tn$ "SAVE(" ulist ")" return /*@ BAL_LOAD_SPECIAL */ /* Allow this user to adjust their own email address. . ----------------------------------------------------------------- */ BB_FIX_EMAIL: /*@ */ if branch then call BRANCH address ISPEXEC mvsema = Value( Userid() ) call BX_LOAD_EMAIL /* collect email address -*/ if sw.0User_added = 1 then do /* update special row */ "TBVCLEAR" $tn$ ittool = "3F"x /* special row */ "TBMOD" $tn$ "SAVE(" ulist ")" if monitor then say, "Updated Admin row for user" itruser", E-mail" mvsema end /* User added */ return /*@ BB_FIX_EMAIL */ /* Special access to the special row for maintaining email addresses. . ----------------------------------------------------------------- */ BC_ADMIN: /*@ */ if branch then call BRANCH address ISPEXEC "TBCREATE ROW3F KEYS( UID ) NAMES( EADDR ) NOWRITE REPLACE" uid = "" do Words( ulist ) parse value ulist uid with uid ulist eaddr = Value( uid ) "TBADD ROW3F" end /* ulist */ ulist = Space( ulist uid,1 ) "TBSORT ROW3F FIELDS( UID )" /* TBTOPs the table */ do forever sel = "" "TBDISPL ROW3F PANEL( EMAINT )" if rc > 4 then leave /* ===> add dtaxyz john.smith@gmail.com */ if zcmd <> "" then do parse var zcmd verb uid eaddr upper verb uid if verb = "ADD" then, "TBMOD ROW3F" end else, do ztdsels upper sel select when sel = "D" then do "TBDELETE ROW3F" end otherwise "TBMOD ROW3F" end /* select */ if ztdsels > 1 then "TBDISPL ROW3F" end /* ztdsels */ sel = "" end /* forever */ "TBSORT ROW3F FIELDS( UID )" /* TBTOPs the table */ ulist = "" /* init */ do forever "TBSKIP ROW3F" /* next row */ if rc > 0 then leave /* end of table */ ulist = ulist uid /* add to ulist */ $rc = Value( uid,eaddr ) /* load eaddr to uid */ end /* forever */ ulist = Space( ulist,1 ) "TBVCLEAR" $tn$ /* zap all vars */ ittool = "3F"x /* lower than blank */ "TBMOD" $tn$ "SAVE(" ulist ")" sw.0changed = 1 return /*@ BC_ADMIN */ /* Main routing panel. . ----------------------------------------------------------------- */ BD_DISPLAY: /*@ */ if branch then call BRANCH address ISPEXEC itruser = Userid() /* this user */ do forever sel = "" "DISPLAY PANEL( ITMAIN )" /* collect task information */ if rc > 0 then leave "CONTROL DISPLAY SAVE" task = Left( sel,1 ) if task = show_problem then do call BDL_LIST_PROBS /* for FIX and ADD_IP -*/ end /* show_problem */ else, if task = report_error then do call BDR_REPORT /* panel NEWPROB -*/ end /* report_error */ else, if task = make_suggest then do call BDS_SUGGEST /* -*/ end /* make_suggest */ "CONTROL DISPLAY RESTORE" end /* forever */ /* During processing, we may have added material to the special row. If so, now is the time to write that data back to the table. */ if sw.0User_added = 1 then do /* update special row */ "TBVCLEAR" $tn$ ittool = "3F"x /* special row */ "TBMOD" $tn$ "SAVE(" ulist ")" end /* User added */ return /*@ BD_DISPLAY */ /* Parse ZCMD and adjust the table. SORT if necessary. Reduce the display, or reset it. . ----------------------------------------------------------------- */ BDC_PROCESS_CMD: /*@ */ if branch then call BRANCH address ISPEXEC parse var zcmd verb text select when ABBREV( "RESET",verb,3 ) then do "TBVCLEAR" $tn$ itruser = " " "TBSARG" $tn$ "NAMECOND( itruser,NE )" end /* RESET */ when verb = "SORT" then do /* TOOL or DEFAULT */ parse var text field if field = "TOOL" then, sortstr = "ITTOOL,C,A" else, if field = "FIX" then, sortstr = "ITFDATE,N,D ITFTIME,N,D" else, if ABBREV( "DEFAULT",field,3 ) then, sortstr = "ITRDATE,N,D ITRTIME,N,D" "TBSORT" $tn$ "FIELDS(" sortstr ")" end /* SORT */ when verb = "ONLY" then do /* ONLY toolname */ parse var text tooln . "TBVCLEAR" $tn$ ittool = tooln "TBSARG" $tn$ "NAMECOND( ittool,EQ )" end /* ONLY */ otherwise end /* select */ return /*@ BDC_PROCESS_CMD */ /* Enter a solution and mark the problem "fixed". Should also send a note to the users on the "interested parties" list. . ----------------------------------------------------------------- */ BDF_FIX: /*@ */ if branch then call BRANCH address ISPEXEC itfuser = Userid() if WordPos( itfuser,ulist ) = 0 then do /* unknown */ call BX_LOAD_EMAIL /* collect email address -*/ end parse value Date("S") Time() with , itfdate itftime . itftime = Translate( "HhMmSs",itftime,"Hh:Mm:Ss" ) "DISPLAY PANEL( TOOLFIX )" itfdesc = Space( itfdesc1 itfdesc2 itfdesc3 itfdesc4 itfdesc5,1 ) if itfdesc <> "" then do itstate = "F" /* Fixed */ "TBMOD" $tn$ "SAVE(" evars ")" sw.0changed = 1 /* Send a note to ITRUSER and to all users on the IPLIST */ call BDZ_NOTIFY( "FIX" ) /* -*/ end return /*@ BDF_FIX */ /* Add this user (and email) to the "interested parties" list. . ----------------------------------------------------------------- */ BDI_ADD_IP: /*@ */ if branch then call BRANCH address ISPEXEC if WordPos( itruser,ulist ) = 0 then do /* unknown */ call BX_LOAD_EMAIL /* collect email address -*/ end if WordPos( itruser,itiparty ) = 0 then, itiparty = Space( itiparty itruser,1 ) "TBMOD" $tn$ "SAVE(" evars ")" if monitor then say, itruser "added to IP list for" ittool return /*@ BDI_ADD_IP */ /* Show a selectable list of all problems or all OPEN problems. Entry to "fix problem" logic and "add interested party" logic. . ----------------------------------------------------------------- */ BDL_LIST_PROBS: /*@ */ if branch then call BRANCH address ISPEXEC /* Set up the )MODEL lines */ modl1 = '{z!itrdate !itrtime!ittool !z !z !itrdesc' modl2 = '{z!itfdate !itftime!ittool !z !z !itrdesc' /* Set up the literal header lines */ desc1 = 'V --DateR- -TimeR --Tool-- St By User Description' desc2 = 'V --DateF- -TimeF --Tool-- St By User Description' parse value "2 2 1 0 0 0" with, stylect styles style csrrow . $scanv = "SCAN" "TBVCLEAR" $tn$ if sel = "LO" then do /* only OPEN problems */ itstate = "F" itruser = " " "TBSARG" $tn$ "NAMECOND( itruser,NE itstate,NE )" end /* LO */ else do /* all problems */ itruser = " " "TBSARG" $tn$ "NAMECOND( itruser,NE )" end /* L */ "TBTOP" $tn$ "VGET (ZPF10 ZPF11) PROFILE" parse value zpf10 zpf11 with, save_f10 save_f11 . sel = "" do forever modl = Value('modl'style) desc = Value('desc'style) zvar = Value('zvar'style) if csrrow <> 0 then do /* skip to 1st displayed line */ "TBTOP" $tn$ "TBSKIP" $tn$ "NUMBER("csrrow")" end parse value "END END" with zpf10 zpf11 . /* set keys to 'end' */ "VPUT (ZPF10 ZPF11) PROFILE" "TBDISPL" $tn$ "PANEL( PROBLST )" disp_rc = rc parse value save_f10 save_f11 with, zpf10 zpf11 . "VPUT (ZPF10 ZPF11) PROFILE" /* immediate restore */ if pfkey = "PF03" | disp_rc > 4 then leave if WordPos(pfkey,"PF10 PF11") > 0 then do if pfkey = "PF11" then, style = style//stylect + 1 /* next style */ else , if pfkey = "PF10" then, style = (style+stylect-2)//stylect + 1 /* prev style */ csrrow = ztdtop /* set TBSKIP position */ iterate end else csrrow = 0 if zcmd <> "" then do call BDC_PROCESS_CMD zcmd = "" iterate end /* zcmd */ do ztdsels "CONTROL DISPLAY SAVE" "TBGET" $tn$ "SAVENAME( EVARS )" parse var evars "(" evars ")" /* yes, we want no bananas */ select when sel = fix_problem then do call BDF_FIX /* panel FIXPROB -*/ end /* Fix problem */ when sel = add_me_as_ip then do call BDI_ADD_IP /* panel ADDME -*/ end /* add_me_as_ip */ otherwise do "DISPLAY PANEL( ITDETL )" end end "CONTROL DISPLAY RESTORE" if ztdsels > 1 then "TBDISPL" $tn$ end /* ztdsels */ sel = "" end /* forever */ return /*@ BDL_LIST_PROBS */ /* TBCREATE a record with ITTOOL, ITRDATE, ITRTIME, and ITRUSER. Allow the loading of a text description as ITRDESC. . KEYS(ITTOOL ITRDATE ITRTIME ITRUSER) NAMES(ITRDESC ITSTATE ITFUSER ITFDESC ITFTIME ITFDATE ITIPARTY) "ITIPARTY" lists the interested parties to this problem suggestion and each Userid should have an entry in row "3F"x with an email address. . ----------------------------------------------------------------- */ BDR_REPORT: /*@ */ if branch then call BRANCH address ISPEXEC if WordPos( itruser,ulist ) = 0 then do /* unknown */ call BX_LOAD_EMAIL /* collect email address -*/ end parse value Date("S") Time() with , itrdate itrtime . itrtime = Translate( "HhMmSs",itrtime,"Hh:Mm:Ss" ) "DISPLAY PANEL( NEWPROB )" itrdesc = Space( itrdesc1 itrdesc2 itrdesc3 itrdesc4 itrdesc5,1 ) itstate = "O" /* Open */ if itrdesc <> "" then do "TBADD" $tn$ sw.0changed = 1 call BDZ_NOTIFY( "RPT" ) /* -*/ end return /*@ BDR_REPORT */ /* Allow user to key in a suggestion for improvement. . ----------------------------------------------------------------- */ BDS_SUGGEST: /*@ */ if branch then call BRANCH address ISPEXEC if WordPos( itruser,ulist ) = 0 then do /* unknown */ call BX_LOAD_EMAIL /* collect email address -*/ end parse value Date("S") Time() with , itrdate itrtime . itrtime = Translate( "HhMmSs",itrtime,"Hh:Mm:Ss" ) "DISPLAY PANEL( NEWSUGG )" itrdesc = Space( itrdesc1 itrdesc2 itrdesc3 itrdesc4 itrdesc5,1 ) itstate = "S" /* Open */ if itrdesc <> "" then do "TBADD" $tn$ sw.0changed = 1 call BDZ_NOTIFY( "SUG" ) /* -*/ end return /*@ BDS_SUGGEST */ /* Notify the reporter that a fix has been placed, or notify TOOLS of a new report or suggestion. . ----------------------------------------------------------------- */ BDZ_NOTIFY: /*@ */ if branch then call BRANCH address TSO return /* on the CBT system, it is not possible to send email to someone outside that system. SMTPNOTE is not available. This routine is stubbed to prevent abends. */ msg. = 0 /* init */ msgdsn = "msglist" alloc.0 = "NEW DELETE UNIT(VIO) SPACE(1 5) TRACKS", "RECFM(V B) LRECL(255) BLKSIZE(0)" alloc.1 = "SHR" /* if it already exists... */ tempstat = Sysdsn(msgdsn) = "OK" /* 1=exists, 0=missing */ "ALLOC FI($MSG) DA("msgdsn") REU" alloc.tempstat arg action rest "NEWSTACK" select when WordPos( action,"RPT SUG") > 0 then do idlist = tools /* send to dev center */ if action = "RPT" then aword = "problem report" else aword = "suggestion" queue "A new" aword "has been filed by" itruser queue "("Value(itruser)") for tool" ittool", dated" queue itrdate itrtime"." queue " " queue "Description:" itrdesc end when WordPos( action,"FIX") > 0 then do idlist = itiparty /* interested parties */ queue "The problem you reported for tool" ittool", dated" queue itrdate itrtime", described as:" itrdesc"," queue "has been marked 'fixed':" itfdesc end otherwise say "Action >"action"< not recognized." "DELSTACK" return end /* select */ /* Build the address list: If FIX, primary is ITRUSER, CC to ITIPARTY If not, primary is TOOLS Each of these contains a list of userids: u1 u2 u3 etc Each userid is an extension variable whose value is an email address. */ if action = "FIX" then do tostring = Value( itruser ) /* reporter */ ccstring = "" /* init */ subj = "Tool Action -" ittool "- Fix" do Words( idlist ) /* interested parties */ parse var idlist w1 idlist ccstring = ccstring"," Value( w1 ) end /* idlist */ ccstring = Strip( ccstring,,"," ) end /* FIX */ else, if WordPos( action,"SUG RPT" ) > 0 then do tostring = "" ccstring = "" /* init */ subj = "Tool Action -" ittool "- Open" action do Words( idlist ) /* Toolsmiths */ parse var idlist w1 idlist tostring = tostring"," Value( w1 ) end /* idlist */ tostring = Strip( tostring,,"," ) end /* SUG or RPT */ "EXECIO" queued() "DISKW $MSG (FINIS" tostring = Strip( tostring ) ccstring = Strip( ccstring ) if mail_pgm <> "?" then do cmd = mail_pgm /* which way to send? */ cmd = cmd "TO("tostring") SUBJECT("subj")" if ccstring <> "" then, cmd = cmd "CC("ccstring")" cmd = cmd "DATASET("msgdsn") BATCH" (cmd) /* execute SMTPNOTE */ end /* mail_pgm */ "DELSTACK" return /*@ BDZ_NOTIFY */ /* If this user is unknown to the special row in the table, collect the user's email address, verify it, and load it back to the special row. . ----------------------------------------------------------------- */ BX_LOAD_EMAIL: /*@ */ if branch then call BRANCH address ISPEXEC do forever "ADDPOP ROW(12) COLUMN(3)" "DISPLAY PANEL( GETEMA )" bad = rc > 0 "REMPOP ALL" if bad then leave if mvsema <> mvsemb then iterate if WordPos( itruser,ulist ) = 0 then, ulist = Space( ulist itruser,1 ) @rc = Value( itruser,mvsema ) /* load MVSEMA to ITRUSER */ sw.0changed = 1 sw.0User_added = 1 leave end /* forever */ return /*@ BX_LOAD_EMAIL */ /* Close and write the table, tear down the ISPF panels, etc. . ----------------------------------------------------------------- */ BZ_EPILOG: /*@ */ if branch then call BRANCH address ISPEXEC "LIBDEF ISPTABL DATASET ID("isptabl") STACK" if noupdt then sw.0changed = 0 if sw.0changed = 0 then, "TBEND " $tn$ /* don't save */ else, "TBCLOSE" $tn$ "LIBDEF ISPTABL" dd = "" do Words(ddnlist) /* each LIBDEF DD */ parse value ddnlist dd with dd ddnlist $ddn = $ddn.dd /* PLIB322 <- PLIB */ "LIBDEF ISP"dd address TSO "FREE FI("$ddn")" end ddnlist = ddnlist dd return /*@ BZ_EPILOG */ /* . ----------------------------------------------------------------- */ Z_QUEUE: /*@ */ if branch then call BRANCH address TSO "NEWSTACK" queue "AATBLID IT " queue "AATBLNM TOOLERR " queue "AAKEYS ITTOOL ITRDATE ITRTIME ITRUSER " queue "AANAMES ITRDESC ITFDATE ITFDESC ITFUSER ITIPARTY ITSTATE " queue "AADESC Tool Problem Reports and Fixes " queue "AASORT ITRDATE,N,D ITRTIME,N,D " queue "AALIBR CBT.SISPTENU" "TBLMSTR (( NEWROW" opts "DELSTACK" return /*@ Z_QUEUE */ /* Routine-specific customization. . ----------------------------------------------------------------- */ LOCAL_PREINIT: /*@ customize opts */ address TSO sw.0restarted = SWITCH( "RESTARTED" ) "NEWSTACK" "ICEUSER" /* get special IDs */ pull icemen "DELSTACK" sw.0Iceman = Wordpos(Userid(),icemen) > 0 if sw.0Iceman then, sw.0Admin = SWITCH( "ADMIN" ) parse value KEYWD("VIA") "? SMTPNOTE" with, mail_pgm . "NEWSTACK" "LA ISPTABL ((STACK" pull isptlib . isptlib = "'"isptlib"'" "DELSTACK" parse value KEYWD("ISPTLIB") isptlib with, isptlib . parse value KEYWD("ISPTABL") isptlib with, isptabl . parse value KEYWD("USETBL") "TOOLERR" with, $tn$ . return /*@ LOCAL_PREINIT */ /* subroutines below LOCAL_PREINIT are not selected by SHOWFLOW */ /* . ----------------------------------------------------------------- */ SHIFT: Procedure /*@ */ address TSO shifted = "" arg wordlist do Words( wordlist ) parse var wordlist word wordlist low = Translate(word,, "abcdefghijklmnopqrstuvwxyz",, "ABCDEFGHIJKLMNOPQRSTUVWXYZ") word = Left(word,1)Substr(low,2) shifted = shifted word end /* wordlist */ return( shifted ) /*@ SHIFT */ /* . ----------------------------------------------------------------- */ GETNAME: Procedure expose, /*@ */ (tk_globalvars) address TSO ASCBASXB = d2x(c2d(Storage(224,4))+108) ASXBSENV = d2x(c2d(Storage(ASCBASXB,4))+200) ACEEUNAM = d2x(c2d(Storage(ASXBSENV,4))+100) Adr = c2x(Storage(ACEEUNAM,4)) Name = Storage(d2x(c2d(Storage(ACEEUNAM,4))+1),c2d(Storage(Adr,1))-1) uname = Strip(Name,"B"," ") return( name ) /*@ GETNAME */ /* Parse out the embedded components at the back of the source code. . ----------------------------------------------------------------- */ DEIMBED: Procedure expose, /*@ */ (tk_globalvars) ddnlist $ddn. daid. address TSO address ISPEXEC "VGET ZSCREENW" fb80po.0 = "NEW DEL UNIT(VIO) SPACE(5 5) TRACKS DIR(40)", "RECFM(F B) LRECL("zscreenw") BLKSIZE(0)" parse value "" with ddnlist $ddn. daid. lastln = sourceline() currln = lastln if Left(sourceline(currln),2) <> "*/" then return currln = currln - 1 /* previous line */ "NEWSTACK" address ISPEXEC do while Left( sourceline(currln),2 ) <> "/*" text = sourceline(currln) /* save with a short name ! */ if Left(text,3) = ")))" then do /* package the queue */ parse var text ")))" ddn mbr . /* PLIB PANL001 maybe */ if Pos(ddn,ddnlist) = 0 then do /* doesn't exist */ ddnlist = ddnlist ddn /* keep track */ $ddn = ddn || Random(999) $ddn.ddn = $ddn address TSO "ALLOC FI("$ddn")" fb80po.0 "LMINIT DATAID(DAID) DDNAME("$ddn")" daid.ddn = daid end daid = daid.ddn "LMOPEN DATAID("daid") OPTION(OUTPUT)" do queued() parse pull line "LMPUT DATAID("daid") MODE(INVAR) DATALOC(LINE)" , "DATALEN("zscreenw")" end "LMMADD DATAID("daid") MEMBER("mbr")" "LMCLOSE DATAID("daid")" end /* package the queue */ else push text /* onto the top of the stack */ currln = currln - 1 /* previous line */ end /* while */ address TSO "DELSTACK" return /*@ DEIMBED */ /* . ----------------------------------------------------------------- */ HELP: /*@ */ address TSO;"CLEAR" ; say "" if helpmsg <> "" then say helpmsg; say "" ex_nam = Left(exec_name,8) /* predictable size */ say " "ex_nam" provides a facility for reporting errors found in tools, " say " for notifying problem-reporters when a reported error is " say " fixed, and for allowing other interested parties to also " say " be notified when certain problems are addressed. " say " " say " "ex_nam" is entirely panel-driven. An initial panel offers the " say " choice of reporting a new problem or suggestion, or " say " listing the known problems. From the list of known " say " problems, any may be tagged as 'fixed', or a user may add " say " their userid to the list of interested observers. " say " " say " Syntax: "ex_nam" EMAIL " say " '((' ISPTLIB tblin (Defaults)" say " ISPTABL tblout (Defaults)" say " USETBL tblnm (Defaults)" if sw.0Iceman then, say " ADMIN " say " " say " more... " "NEWSTACK"; pull ; "CLEAR" ; "DELSTACK" say " " say " EMAIL if specified, the user's stored email address is " say " offered for update. The normal initial panel is not" say " shown. " say " " say " tblin is the name of the input table library that is the " say " source of tblnm. If not specified, the current " say " ISPTABL will be used. " say " " say " tblout is the name of the output table library to receive " say " the updated tblnm. It defaults to tblin. " say " " say " tblnm is the name of the table. It defaults to 'TOOLERR'." if sw.0Iceman then do say " " say " ADMIN (switch in opts) allows maintenance of the " say " collected email addresses. " end /* Iceman */ say " " say " more... " "NEWSTACK"; pull ; "CLEAR" ; "DELSTACK" say " Debugging tools provided include: " say " " say " NOUPDT: by-pass all update logic. " say " " say " BRANCH: show all paragraph entries. " say " " say " TRACE tv: will use value following TRACE to place the " say " execution in REXX TRACE Mode. " say " " say " " say " Debugging tools can be accessed in the following manner: " say " " say " TSO "ex_nam" parameters (( debug-options " say " " say " For example: " say " " say " TSO "ex_nam" (( MONITOR TRACE ?R " say " " if sysvar("SYSISPF") = "ACTIVE" then, address ISPEXEC "CONTROL DISPLAY REFRESH" exit /*@ HELP */ /* . ----------------------------------------------------------------- */ BRANCH: Procedure expose, /*@ */ sigl exec_name rc = trace("O") /* we do not want to see this */ arg brparm . origin = sigl /* where was I called from ? */ do currln = origin to 1 by -1 /* inch backward to label */ if Right(Word(Sourceline(currln),1),1) = ":" then do parse value sourceline(currln) with pgfname ":" . /* Label */ leave ; end /* name */ end /* currln */ select when brparm = "NAME" then return(pgfname) /* Return full name */ when brparm = "ID" then do /* wants the prefix */ parse var pgfname pgfpref "_" . /* get the prefix */ return(pgfpref) end /* brparm = "ID" */ otherwise say left(sigl,6) left(pgfname,40) exec_name "Time:" time("L") end /* select */ return /*@ BRANCH */ /* . ----------------------------------------------------------------- */ DUMP_QUEUE: /*@ Take whatever is in stack */ rc = trace("O") /* and write to the screen */ address TSO arg mode . "QSTACK" /* how many stacks? */ stk2dump = rc - tk_init_stacks /* remaining stacks */ if stk2dump = 0 & queued() = 0 then return if mode <> "QUIET" then, say "Total Stacks" rc , /* rc = #of stacks */ " Begin Stacks" tk_init_stacks , /* Stacks present at start */ " Excess Stacks to dump" stk2dump do dd = rc to tk_init_stacks by -1 /* empty each one. */ if mode <> "QUIET" then, say "Processing Stack #" dd " Total Lines:" queued() do queued();parse pull line;say line;end /* pump to the screen */ "DELSTACK" /* remove stack */ end /* dd = 1 to rc */ return /*@ DUMP_QUEUE */ /* Handle CLIST-form keywords added 20020513 . ----------------------------------------------------------------- */ CLKWD: Procedure expose info /*@ hide all except info */ arg kw kw = kw"(" /* form is 'KEY(DATA)' */ kw_pos = Pos(kw,info) /* find where it is, maybe */ if kw_pos = 0 then return "" /* send back a null, not found*/ rtpt = Pos(") ",info" ",kw_pos) /* locate end-paren */ slug = Substr(info,kw_pos,rtpt-kw_pos+1) /* isolate */ info = Delstr(info,kw_pos,rtpt-kw_pos+1) /* excise */ parse var slug (kw) slug /* drop kw */ slug = Reverse(Substr(Reverse(Strip(slug)),2)) return slug /*@CLKWD */ /* Handle multi-word keys 20020513 . ----------------------------------------------------------------- */ KEYWD: Procedure expose info /*@ hide all vars, except info*/ arg kw /* form is 'KEY DATA' */ kw_pos = wordpos(kw,info) /* find where it is, maybe */ if kw_pos = 0 then return "" /* send back a null, not found*/ kw_val = word(info,kw_pos+Words(kw))/* get the next word */ info = Delword(info,kw_pos,2) /* remove both */ return kw_val /*@ KEYWD */ /* . ----------------------------------------------------------------- */ KEYPHRS: Procedure expose, /*@ */ info helpmsg exec_name /* except these three */ arg kp /* form is 'KEY ;: DATA ;:' */ wp = wordpos(kp,info) /* where is it? */ if wp = 0 then return "" /* not found */ front = subword(info,1,wp-1) /* everything before kp */ back = subword(info,wp+1) /* everything after kp */ parse var back dlm back /* 1st token must be 2 bytes */ if length(dlm) <> 2 then /* Must be two bytes */ helpmsg = helpmsg, "Invalid length for delimiter("dlm") with KEYPHRS("kp")" if wordpos(dlm,back) = 0 then /* search for ending delimiter*/ helpmsg = helpmsg, "No matching second delimiter("dlm") with KEYPHRS("kp")" if helpmsg <> "" then call HELP /* Something is wrong */ parse var back kpval (dlm) back /* get everything b/w delim */ info = front back /* restore remainder */ return Strip(kpval) /*@ KEYPHRS */ /* . ----------------------------------------------------------------- */ NOVALUE: /*@ */ say exec_name "raised NOVALUE at line" sigl say " " say "The referenced variable is" condition("D") say " " zsigl = sigl signal SHOW_SOURCE /*@ NOVALUE */ /* . ----------------------------------------------------------------- */ SHOW_SOURCE: /*@ */ call DUMP_QUEUE /* Spill contents of stacks -*/ if sourceline() <> "0" then /* to screen */ say sourceline(zsigl) rc = trace("?R") nop exit /*@ SHOW_SOURCE */ /* . ----------------------------------------------------------------- */ SS: Procedure /*@ Show Source */ arg ssbeg ssct . /* 'call ss 122 6' maybe */ if ssct = "" then ssct = 10 if \datatype(ssbeg,"W") | \datatype(ssct,"W") then return ssend = ssbeg + ssct do ssii = ssbeg to ssend ; say Strip(sourceline(ssii),'T') ; end return /*@ SS */ /* . ----------------------------------------------------------------- */ SWITCH: Procedure expose info /*@ */ arg kw /* form is 'KEY' */ sw_val = Wordpos(kw,info) > 0 /* exists = 1; not found = 0 */ if sw_val then /* exists */ info = Delword(info,Wordpos(kw,info),1) /* remove it */ return sw_val /*@ SWITCH */ /* . ----------------------------------------------------------------- */ SYNTAX: /*@ */ errormsg = exec_name "encountered REXX error" rc "in line" sigl":", errortext(rc) say errormsg zsigl = sigl signal SHOW_SOURCE /*@ SYNTAX */ /* Can call TRAPOUT. . ----------------------------------------------------------------- */ TOOLKIT_INIT: /*@ */ address TSO info = Strip(opts,"T",")") /* clip trailing paren */ parse source sys_id how_invokt exec_name DD_nm DS_nm, as_invokt cmd_env addr_spc usr_tokn parse value "" with tv helpmsg . parse value 0 "ISR00000 YES" "Error-Press PF1" with, sw. zerrhm zerralrm zerrsm if SWITCH("TRAPOUT") then do "TRAPOUT" exec_name parms "(( TRACE R" info exit end /* trapout */ sw.nested = sysvar("SYSNEST") = "YES" sw.batch = sysvar("SYSENV") = "BACK" sw.inispf = sysvar("SYSISPF") = "ACTIVE" if Word(parms,1) = "?" then call HELP /* I won't be back */ "QSTACK" ; tk_init_stacks = rc /* How many stacks? */ parse value SWITCH("BRANCH") SWITCH("MONITOR") SWITCH("NOUPDT") with, branch monitor noupdt . parse value mvsvar("SYSNAME") sysvar("SYSNODE") with, #tk_cpu node . parse value KEYWD("TRACE") "N" with tv . tk_globalvars = "exec_name tv helpmsg sw. zerrhm zerralrm ", "zerrsm zerrlm tk_init_stacks branch monitor ", "noupdt" call LOCAL_PREINIT /* for more opts -*/ return /*@ TOOLKIT_INIT */ /* ISPF assets for DEIMBED start here ))) PLIB EMAINT MAINTAIN EMAIL ADDRESSES )ATTR % TYPE(TEXT) INTENS(HIGH) SKIP(ON) + TYPE(TEXT) INTENS(LOW) SKIP(ON) _ TYPE(INPUT) INTENS(HIGH) CAPS(OFF) ! TYPE(OUTPUT) INTENS(HIGH) SKIP(ON) @ TYPE(OUTPUT) INTENS(LOW) SKIP(ON) )BODY EXPAND(||) WIDTH(&ZSCREENW) %|-| Row 3F +|-| %Command ===>_ZCMD %Scroll ===>_ZAMT+ +V Userid Email address )MODEL _z!uid _eaddr )INIT .ZVARS = '(SEL)' .HELP = EMAINTH )REINIT )PROC )END ))) PLIB EMAINTH MAINTAIN EMAIL ADDRESSES )ATTR % TYPE(TEXT) INTENS(HIGH) SKIP(ON) + TYPE(TEXT) INTENS(LOW) SKIP(ON) _ TYPE(INPUT) INTENS(HIGH) ! TYPE(OUTPUT) INTENS(HIGH) SKIP(ON) { TYPE(OUTPUT) INTENS(LOW) SKIP(ON) )BODY EXPAND(||) WIDTH(&ZSCREENW) %TUTORIAL |-| Row 3F |-| TUTORIAL %Next Selection ===>_ZCMD + If an email address needs to be updated, this panel can be used for that purpose. Changes made to the email address will be retained. It is also possible to add new rows via the command field: %add admin dtafxc ntdxyz + or %add ntdxyz xerxes.zabrodski@gmail.com + + Note that%non-userid rows+should have one or more%userids+as their value. % Userid rows+should have a%single email address+as the value. + Delete rows with a 'D' line command. )PROC &ZUP = EMAINTH &ZCONT = EMAINTH )END ))) PLIB ITMAIN Main Selection Panel )ATTR % TYPE(TEXT) INTENS(HIGH) SKIP(ON) + TYPE(TEXT) INTENS(LOW) SKIP(ON) _ TYPE(INPUT) INTENS(LOW) CAPS(ON) @ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW) ! TYPE(INPUT) INTENS(NON) )BODY EXPAND(||) WIDTH(&ZSCREENW) @|-|% Main Selection Panel @|-| %COMMAND ===>_ZCMD + Select one option below or PF3 to exit. + % R +- %Report+a tool error % S +- %Suggest+an improvement to a tool % L +- %List+all outstanding problems % LO+- %List all OPEN+problems + + Option ===>_z + (R, S, L, LO) )INIT .ZVARS = '( SEL )' .HELP = ITMAINH )PROC VER( &SEL,LIST,R,S,L,LO ) )END ))) PLIB ITMAINH Main Selection Panel )ATTR % TYPE(TEXT) INTENS(HIGH) SKIP(ON) + TYPE(TEXT) INTENS(LOW) SKIP(ON) _ TYPE(INPUT) INTENS(HIGH) ! TYPE(OUTPUT) INTENS(HIGH) SKIP(ON) @ TYPE(OUTPUT) INTENS(LOW) SKIP(ON) )BODY EXPAND(||) WIDTH(&ZSCREENW) %TUTORIAL |-| Main Selection Panel |-| TUTORIAL %Next Selection ===>_ZCMD + To report a tool-error, select%R+ + To suggest an improvement or feature for a tool, select%S+ + To display a list of known problems, select%L+(for%ALL+problems) or%LO+(for only%OPEN+problems). )PROC &ZUP = ITMAINH &ZCONT = ITMAINH )END ))) PLIB NEWPROB Enter problem details )ATTR % TYPE( TEXT ) INTENS( HIGH ) SKIP( ON ) + TYPE( TEXT ) INTENS( LOW ) SKIP( ON ) _ TYPE( INPUT ) INTENS( LOW ) CAPS( ON ) @ TYPE( TEXT ) INTENS( HIGH ) COLOR( YELLOW ) ! TYPE( INPUT ) PAD( - ) CAPS( OFF ) { TYPE( OUTPUT ) SKIP( ON ) )BODY EXPAND(||) WIDTH(&ZSCREENW) @|-|% Enter Problem Details @|-| %COMMAND ===>_ZCMD + You are ===>{itruser + Which Tool ===>_ittool + Date ===>{itrdate + Time ===>{itrtime + + Describe the problem in detail below: !itrdesc1 !itrdesc2 !itrdesc3 !itrdesc4 !itrdesc5 + )INIT .HELP = NEWPROBH .CURSOR = ITTOOL &ITRDESC1 = &Z &ITRDESC2 = &Z &ITRDESC3 = &Z &ITRDESC4 = &Z &ITRDESC5 = &Z )PROC )END ))) PLIB NEWPROBH Enter problem details )ATTR % TYPE(TEXT) INTENS(HIGH) SKIP(ON) + TYPE(TEXT) INTENS(LOW) SKIP(ON) _ TYPE(INPUT) INTENS(HIGH) ! TYPE(OUTPUT) INTENS(HIGH) SKIP(ON) @ TYPE(OUTPUT) INTENS(LOW) SKIP(ON) )BODY EXPAND(||) WIDTH(&ZSCREENW) %TUTORIAL |-| Enter Problem Details |-| TUTORIAL %Next Selection ===>_ZCMD + Insert the name of the tool which is having problems in the designated spot, then describe as well as you can what the problem appears to be. Include as much diagnostic material as you can. )PROC &ZUP = NEWPROBH &ZCONT = NEWPROBH )END ))) PLIB TOOLFIX Enter solution details )ATTR % TYPE( TEXT ) INTENS( HIGH ) SKIP( ON ) + TYPE( TEXT ) INTENS( LOW ) SKIP( ON ) _ TYPE( INPUT ) INTENS( LOW ) CAPS( ON ) @ TYPE( TEXT ) INTENS( HIGH ) COLOR( YELLOW ) ! TYPE( INPUT ) PAD( - ) CAPS( OFF ) { TYPE( OUTPUT ) SKIP( ON ) CAPS(OFF) )BODY EXPAND(||) WIDTH(&ZSCREENW) @|-|% Enter Solution Details @|-| %COMMAND ===>_ZCMD + Problem Description by {itruser {itrdate {itrtime {itrdesc + Tool ===>{ittool + You are ===>{itfuser + Date ===>{itfdate + Time ===>{itftime + + + Describe the correction in detail below: !itfdesc1 !itfdesc2 !itfdesc3 !itfdesc4 !itfdesc5 + )INIT .HELP = TOOLFIXH &ITFDESC1 = &Z &ITFDESC2 = &Z &ITFDESC3 = &Z &ITFDESC4 = &Z &ITFDESC5 = &Z )PROC )END ))) PLIB TOOLFIXH Enter solution details )ATTR % TYPE(TEXT) INTENS(HIGH) SKIP(ON) + TYPE(TEXT) INTENS(LOW) SKIP(ON) _ TYPE(INPUT) INTENS(HIGH) ! TYPE(OUTPUT) INTENS(HIGH) SKIP(ON) @ TYPE(OUTPUT) INTENS(LOW) SKIP(ON) )BODY EXPAND(||) WIDTH(&ZSCREENW) %TUTORIAL |-| Enter Solution Details |-| TUTORIAL %Next Selection ===>_ZCMD + The problem is fixed! Congratulations! Now tell the reporter about the fix. )PROC &ZUP = TOOLFIXH &ZCONT = TOOLFIXH )END ))) PLIB NEWSUGG Enter a suggestion for improvement )ATTR % TYPE( TEXT ) INTENS( HIGH ) SKIP( ON ) + TYPE( TEXT ) INTENS( LOW ) SKIP( ON ) _ TYPE( INPUT ) INTENS( LOW ) CAPS( ON ) @ TYPE( TEXT ) INTENS( HIGH ) COLOR( YELLOW ) ! TYPE( INPUT ) PAD( - ) CAPS( OFF ) { TYPE( OUTPUT ) SKIP( ON ) )BODY EXPAND(||) WIDTH(&ZSCREENW) @|-|% Enter Suggested Improvement @|-| %COMMAND ===>_ZCMD + You are ===>{itruser + Which Tool ===>_ittool + Date ===>{itrdate + Time ===>{itrtime + + Thanks in advance for helping to make the tools better. Enter your suggestion below: !itrdesc1 !itrdesc2 !itrdesc3 !itrdesc4 !itrdesc5 + )INIT .HELP = NEWSUGGH .CURSOR = ITTOOL &ITRDESC1 = &Z &ITRDESC2 = &Z &ITRDESC3 = &Z &ITRDESC4 = &Z &ITRDESC5 = &Z )PROC )END ))) PLIB NEWSUGGH Enter a suggestion for improvement )ATTR % TYPE(TEXT) INTENS(HIGH) SKIP(ON) + TYPE(TEXT) INTENS(LOW) SKIP(ON) _ TYPE(INPUT) INTENS(HIGH) ! TYPE(OUTPUT) INTENS(HIGH) SKIP(ON) @ TYPE(OUTPUT) INTENS(LOW) SKIP(ON) )BODY EXPAND(||) WIDTH(&ZSCREENW) %TUTORIAL |-| Enter Suggested Improvement |-| TUTORIAL %Next Selection ===>_ZCMD + Thanks for helping make the tools better! Please tell us the name of the tool in the appropriate spot, then describe your suggestion in as much detail as you can in the space below. )PROC &ZUP = NEWSUGGH &ZCONT = NEWSUGGH )END ))) PLIB PROBLST List of all known problems )ATTR % TYPE(TEXT) INTENS(HIGH) SKIP(ON) + TYPE(TEXT) INTENS(LOW) SKIP(ON) _ TYPE(INPUT) INTENS(HIGH) { TYPE(INPUT) INTENS(HIGH) CAPS(ON) ! TYPE(OUTPUT) INTENS(HIGH) SKIP(ON) @ TYPE(OUTPUT) INTENS(LOW) SKIP(ON) CAPS(OFF) )BODY EXPAND(||) WIDTH(&ZSCREENW) %|-| Problem List +|-| %Command ===>_ZCMD %Scroll ===>_ZAMT+ + /-- I=add Interested Party F=enter solution *=Display detail + / Primary commands:%SORT ONLY RESET+(see HELP) + / PF10 or PF11 to shift display @desc )MODEL ROWS( &$SCANV ) &modl )INIT .ZVARS = '( SEL ITSTATE ITRUSER )' .HELP = PROBLSTH )REINIT )PROC IF (.PFKEY = 'PF05') &PFKEY = 'F5' .RESP = END IF (.PFKEY = 'PF10') .RESP = 'ENTER' IF (.PFKEY = 'PF11') .RESP = 'ENTER' &PFKEY = .PFKEY )END ))) PLIB PROBLSTH List of all known problems )ATTR % TYPE(TEXT) INTENS(HIGH) SKIP(ON) + TYPE(TEXT) INTENS(LOW) SKIP(ON) _ TYPE(INPUT) INTENS(HIGH) ! TYPE(OUTPUT) INTENS(HIGH) SKIP(ON) @ TYPE(OUTPUT) INTENS(LOW) SKIP(ON) )BODY EXPAND(||) WIDTH(&ZSCREENW) %TUTORIAL |-| Problem List |-| TUTORIAL %Next Selection ===>_ZCMD + Select any row or rows with a command letter: + %I+- to designate yourself as an 'interested party'. You will be notified by email when the problem closes. + %F+- to enter a 'fix' for this problem. + Any other character to display the details including text descriptions of the problem and, if available, the solution. + + Primary commands: %SORT + may be 'TOOL', 'FIX', or 'DEFault' %ONLY + names a tool for exclusive display %RESet+ displays all lines + )PROC &ZUP = PROBLSTH &ZCONT = PROBLSTH )END ))) PLIB ITDETL Single problem details )ATTR % TYPE( TEXT ) INTENS( HIGH ) SKIP( ON ) + TYPE( TEXT ) INTENS( LOW ) SKIP( ON ) _ TYPE( INPUT ) INTENS( LOW ) CAPS( ON ) @ TYPE( TEXT ) INTENS( HIGH ) COLOR( YELLOW ) ! TYPE( INPUT ) PAD( - ) CAPS( OFF ) { TYPE( OUTPUT ) SKIP( ON ) CAPS( OFF ) )BODY EXPAND(||) WIDTH(&ZSCREENW) @|-|% Display Problem Details @|-| %COMMAND ===>_ZCMD + Tool ===>{ittool + + + Problem Description by {itruser {itrdate {itrtime {itrdesc + + Solution Description by {itfuser {itfdate {itftime {itfdesc + )INIT .HELP = ITDETLH )PROC )END ))) PLIB ITDETLH Single problem details )ATTR % TYPE(TEXT) INTENS(HIGH) SKIP(ON) + TYPE(TEXT) INTENS(LOW) SKIP(ON) _ TYPE(INPUT) INTENS(HIGH) ! TYPE(OUTPUT) INTENS(HIGH) SKIP(ON) @ TYPE(OUTPUT) INTENS(LOW) SKIP(ON) )BODY EXPAND(||) WIDTH(&ZSCREENW) %TUTORIAL |-| Display Problem Details |-| TUTORIAL %Next Selection ===>_ZCMD + This panel shows all the available detail for the selected problem. )PROC &ZUP = ITDETLH &ZCONT = ITDETLH )END ))) PLIB GETEMA Get new email address )ATTR { TYPE( INPUT ) PAD( - ) CAPS( OFF ) )BODY WINDOW(55,5) + + Email addr ===>{mvsema + Again, pls ===>{mvsemb )INIT .HELP = GETEMAH .CURSOR = MVSEMA &MVSEMB = &Z )PROC )END ))) PLIB GETEMAH Get new email address )ATTR % TYPE(TEXT) INTENS(HIGH) SKIP(ON) + TYPE(TEXT) INTENS(LOW) SKIP(ON) _ TYPE(INPUT) INTENS(HIGH) ! TYPE(OUTPUT) INTENS(HIGH) SKIP(ON) @ TYPE(OUTPUT) INTENS(LOW) SKIP(ON) )BODY EXPAND(||) WIDTH(&ZSCREENW) %TUTORIAL |-| Enter Your Email Address |-| TUTORIAL %Next Selection ===>_ZCMD + In order to keep you notified of activity on this problem we need your email address, and there's no way to look it up. The email address you enter here will be used for all problem-related communication, so make sure it's a good one. )PROC &ZUP = GETEMAH &ZCONT = GETEMAH )END */