FAQ for TSO/REXX Up to the computing page. SendFeedback. Last-modified: 01 Aug 2004Version: 1.4q TSO-REXX Frequently Asked Questions Contents Introduction Changes made to the FAQ at this release To Do Using Rexx. How do I Run My Rexx Exec. How do I allocate Execlibraries and other datasets to my TSO or ISPFsession. Where can I find Rexx manuals anddocumentation. How do I find or access the current levelof a GDG. How do I access data in control blockssuch as jobname. How can I access a calling execsvariables. How do I implement job control with (andfor) Rexx Where are the Standard Rexx I/Ofunctions. How do I replicate CLIST's WRITENRfunctionality. Why does Outtrap() not trap all output. EXECIO, why does it require 'Enter' morethan once. How do I List Datasets and PDS members. How do I access data held on the JESspool. What do unusual return codes suchas -3 and 0196 mean. How do I pass parms to myISPF Edit macro. Why are myprocedure arguments inupper case. Rexx and Different environments. OS/390 Unix Systems Services ISPF Services ISPF Services in Batch Load Modules (I.e. Assembled programs) SQL Console Command Environment Rexx aware editors Rexx Compilers Using Rexx as CGI programs with the WebServer. Style. What are the most effective ways to usecomments? EXECIO. What case should I program in, upper orlower? Functions and procedures Logical (Boolean) variables andfunctions. Symbolic names. Internal and external calls How can I improve performance of my exec? How can my systems programmer improveperformance? What obscure coding tricks arethere? Using Non-Alphanumeric characters. Are there any other style hints? Appendices. Code Examples Other Sources of Information Subscribing to the TSO-REXX List Glossary Introduction This FAQ is for REXX/MVS, that is, REXX for IBM mainframes (MVS,OS/390and VM). It is unofficial and based on questions asked in the TSO-REXXlistservgroup based at LISTSERV@VM.MARIST.EDU.As is the case with all FAQs, this document is a work in progress.Additions,corrections, and comments are very welcome. Please send anycorrespondenceto webspace@neilhancock.co.uk If this FAQ or the List Archivedoesnot answer your Rexx questions, do not email me, but instead subscribe to the TSO-REXX List where yourquestionswill be usually be answered promptly by many knowlegable people.Thanks for contributions from: Jon Alexander, Stephen Bacher, Tim Larsen, John McDonald, and all thosewhoposed and answered questions on the mail list. In coding examples, screen output is indicated by ==> within acomment.Latest edits are marked in bold in the contents section.Changes made to the FAQ at thisrelease. 1.4q - Update links and whatnot, add EXECIO tip, add PARSE ARG. 1.4p - New coding trick. Assorted submissions and updates(Thanks!). 1.4o - Assorted minor things from the list, edit macro parms. 1.4n - R.I.P. Deja. ReMarQ too. Code examples moved externalto FAQ. 1.4m - Performance updated. Coding tricks added. 1.4l - LIBDEF/ALLOC/ALTLIB question and sample. 1.4k - Subscription Info added. 1.4j - Rexx in Batch added. More info added to. RXSQL noted.Docs question added. 1.4i - More reformatting, Some answers reviewed and amended. 1.4h - Minor formatting. 1.4g - Corrections submitted by Peter Tillier. Reinstated rexxinformation sourcesTo Do Is Posix (USS) info still up to date and correct? Inline JCL technique with IEBGENER to temp PDS. XMLify. Scare up some useful google keywords. Using Rexx. How do I Run My Rexx Exec. Most of this is described in the User Guide, or in the guide for theappropriateenvironment. For the TSO environment: Make sure the Exec starts with the /* REXX */comment. TSO EXEC 'hlq.your.dsn(member)' runsRexx in exactly the same way as it would a CLIST. TSO EX yourlib(member) E uses a suffix ofEXEC and the TSO profile prefix to form afull DSN of 'your_prefix.yourlib.EXEC(member)' The SYSEXEC concatenation can be used to run execs using TSOexecname. The SYSPROC concatenation will do just aswell, but is really intended for CLISTS. TSO %execname parameter_string allows you to pass aparameter string to the exec, note that this string is onlya single argument, not multiple arguments as can be used when callingfrom within an exec. The '%' instructs TSO to not use loadlibconcatenationswhen constructing the search path. For running Rexx in batch: Create a batch environment for the Exec to run in withPGM=IRXJCL,PGM=IKJEFT01 or PGM=IKJEFT1B IRXJCL is a straight batch environment IKJEFT01 and IKJEFT1B are the TSO in batch programs. Put the Rexx exec libraries in the SYSEXEC DD concatenation. Call your exec via the PARM='yourprog' or as input in the SYSTSINDD See the Code Examples appendix for examples.For more information, RTFM. How do I allocate Exec libraries and otherdatasetsto my TSO or ISPF session. ALTLIB ACTIVATE can be used to dynamically add an Exec or Clistlibrary to the search path. I don't know whether these ATLIBsare stacked in the way LIBDEFs can be. LIBDEF can be used to dynamically allocate other libraries,such as ISPF panel libraries. Use the STACK option to avoid corruptingthe environment for nested calls to applications. An exampleLIBDEF/ALTLIBis in an appendix. Your allocations at logon are controlled by the JCL procedureused to initiate your TSO environment. This is called your TSO LOGONPROCEDURE, and it will be under the control of your systems programmer. To override the LOGON proc and allocate your own SYSEXEC,ISPPLIB, etc concatenations, the TSO ISRDDN command can create a handyCLIST to use as your base. To generate the TSO ALLOC commands neededto replicate your current allocations, type the CLIST command onthe command line. Edit and save the Clist created, and run it atlogon (outside of ISPF) to allocate your own environment. Where can I find Rexx manuals and documentation.IBMOnline Library inHTMLand PDF form, clisk on the 'elements and features' links.The Rexx Reference and Guide are in the TSO section.ISPF interfaces ( E.g. ISPF Edit Macro commands) are documented in theISPFsection. There is a manual for Rexx in the Unix System Services environment.Interfaces for other applications will be documented with thatapplication. How do I find or access the current level of aGDG.Use Outtrap() on the output of TSO LISTCAT. See RXGDGV() in the appendices. How do I access data in control blocks such asjobname?Use the Storage() function to extract the data from control blocks. /* REXX Get taskname from TCB */ cvt = storage(10,4) /* FLCCVT-PSA data area */ tcbp = storage(d2x(c2d(cvt)),4) /* CVTTCBP */ tcb = storage(d2x(c2d(tcbp)+4),4) tiot = storage(d2x(c2d(tcb)+12),4) /* TCBTIO */ say strip(storage(d2x(c2d(tiot)),8)) /* TIOCNJOB */ /* I have lost the original author of this code.Thanks whoever you are - NWH */ How can I access a calling execs variables.Rexx doesn't allow an exec to access the symbols used by anotherexec.A classic example of this is creating an exec to sort the contents of astemmedsymbol. Some suggested methods are: Use ISPF variable pools to pass values across execs Pass all symbols as arguments and returned values (I.e. Use PARSEARG args and RETURN value). Create your own function in assembler to pass stems across.Refer to the IRXEXCOM macro interface in the IBM Rexx manuals. Generate executable code as the returned string and use INTERPRETon it to make the variables available in the external program. Use the stack, see NEWSTACK, DELSTACK, PUSH, PULL, QUEUE, etc, inthe manual. How do I implement job control with (and for)RexxThe obvious answer is to use JCL condition code processing, possiblyrunninga Rexx exec at the end of each job to perform error recovery, messageissuing,etc. See the ISPF in batch discussion for moreinformation.Another solution if the JCL is part of a single application is topasscheckpoint information between an application server and executingtasks ina dataset. E.g. A server may create and prime a checkpoint dataset, andthensubmit a job that updates the dataset with diagnostic information thattheserver will interrogate when the job has finished.Jon Alexander <johnalex@AOL.COM> writes:SDSF offers a batch interface. I don't have the documentation hereat home,but it can be found as a whole chapter in the SDSF Users Guide (Chapter15seems to stick out in my head). I can't swear that you can"interrogate" sysoutdata or condition codes from this interface, so you will need tovalidatethis also. If you can, then you can build a set of REXX to call thisinterfacefrom within a TSO environment.HOWEVER, you must still consider how you will implement thisfacility.Let's say that you want to monitor the majority of your batch work. Youmust"schedule" this routine to run after every single batch task, inputtingthejobname and JES number for the SDd. This is not an easy task fromwithin CA-7...CA's (formerly Legent's) JOBTRAC scheduling product provides afacilityto run a REXX routine at the termination of each batch event, and alsoprovidesan interface to their "SDSF counterpart" called SYSVIEW/E which willdefinitelyallow you to display sysout text and conditions codes. They distributea sampleREXX with their maintenance tape that provides most of the code forwhatyou would want to do, but I'm not sure you really want to change yourproductionscheduler just to solve this one problem.So, to make a long answer even longer, I would recommend that youget awayfrom looking at the SDSF data, and possibly try to exploit one of thefollowing:- Implement the SHARE sample of an IEFACTRT exit that generates WTOswithstep condition code results, and use your local automation package tointerceptthe WTO and perform an automation process.- See if you can exploit CA-11 or CA-7 as far as a user exit pointor extractingtheir database info, and take actions based on that - Implement your own IEFACTRT exit (there are a lot of samples outthere)to perform the actions you need (yeah, I know, I'd rather do it in REXXalso)- Get with your CA rep and see if CA-7 will be incorporating any oftheREXX technology that CA-JOBTRAC currently uses and possibly a timeframe onthe availability Where are the Standard Rexx I/O functionsLinein(), Lineout(), Stream() etc. have not been implemented inMVS/Rexx*as far as I am aware*. I/O can be done using the functionality ofEXECIO.A function package giving I/O functions for the OE environment only isavailablefrom IBM's Downloadwebsite. How do I replicate CLIST's WRITENRfunctionality?The Rexx say command places a carriage return and line feed at theendof each say command execution.Some suggestions for creating a say command that behaves in the sameway asCLIST's WRITENR are:Use a CLIST call.Use CHAROUT(). However this I/O function is not implemented inMVS/Rexx.The free utility XWRITENR (and also XPROC) are available from ftp.mackinney.com andthe CBT tape Why does Outtrap() not trap all output The Outtrap() function does not trap output written directly to thescreenby the TPUT macro, but only traps output from the PUTLINE macro. UsePUTLINEwhen writing assembler programs, and your program will be of more usein aRexx environment. TSO Session Manager can be used to trap and manage all output thatis normallywritten to the screen. Session Manager may require some setting up byyourSystems Programer, who will have to look things up in the TSO manuals. EXECIO, why does it require 'Enter' more thanonceWhen using "EXECIO * DISKW DDNAME", Rexx will continue pulling inputfromthe stack and from terminal input (depending on the users TSO PROMPT()value)until it gets a null line. So a users will have to hit enter once togeneratea null line. Solutions are: Queue a null line before writing data from the stack. Use the Queued() built in function instead of '*'. Only EXECIO the required number of lines from terminal input.E.g. "EXECIO 1 DISKR DDNAME (FINIS)" will only reada single line from the stack or terminal input. "EXECIO "queued()" DISKW DDNAME (FINIS)" willwrite the entire stack without requiring a null line to terminateoutput. See also EXECIO under Style. How do I List Datasets and PDS members. There are various methods for listing datasets and PDS members. LISTDS - TSO dataset list command. Use the MEMBERS subcommandto get the members of a PDS. LM utilities - ISPF library management utilities. Use LMMLISTwith LMINIT to list the members. See ISPF services manual for details. EXECIO of the PDS directory. A PDS directory can be allocated(LRECL=256) and read with EXECIO. This method does not work with PDSEsand cannot be guaranteed to work in the future. Create your own access routines in assembler using the BPAMaccess method. CSI - Catalog Search Interface. A high performance catalogsearch routine shipped by IBM. Use the LINKMVS environment to useit. FDR - Dataset management tools. Innovations FDR package suppliesa tool for reporting upon datasets (FDREPORT) that can be customisedfor use with Rexx under TSO. How do I access data held on the JES spool.JES3 sites can extract data off of the JES3 spool using E-JES.The TSO STATUS command gives limited information about jobs on thespool.The TSO OUTPUT command can reteive some data from the spool. The TSOCANCEL command can be used to stop jobs, and TSO SUBMIT to them. Brave souls can try the JES interface macros. Try looking at the CBTTape for examples.JES2 users can brave the perils of SDSF in batch or other thirdparty products What do unusual return codes such as -3 and 0196 mean?Basically they are either decimalised abend codes or indicate aproblemwith the environment.E.g. 0196 is decimal for hex 0C4, -3 indicates external environmentnotfound. This is explained further in the Rexx manuals. How do I pass parms to my ISPF Edit macro.From command line calls use ISPEXEC "MACRO (parms)"From ISPEXEC EDIT call use VPUT and VGET Whyare my procedure arguments in upper case.It may be because you are using ARG instead of PARSE ARGPARSE ARG arg01 ,arg02 /* Arguments parsed with no uppercasing */ARG arg01, arg02 /* arguments are uppercased */ Also note that the command line on most panels has CAPS(ON) set.Notable execptions (where case is preserved) are ISPF edit and ISPF 6.Rexx and Different environments. OS/390 Unix System Services address SYSCALL and address SH give you the ability to run execsthat useOpenEdition MVS services. From outside of the shell use the Syscall()functionto activate the environment.See Manual 'Using REXX to Access Unix System Services.' (or whateveritscalled this week).There are some pitfalls in this environment: External names are uppercased. So RXGDGV() will work whilstrxgdgv() will fail not found. Newly created executables may need to be made executable witha 'chmod' command. The syscall environment initialises some variables which maybe the same as those you use. See MTM_RDWR in the mount example below. The method of passing variables into the environment callsis different from 'classic' MVS calls. E.g. mount example. /* REXX mount example */path = /tmp/testpath/mountpointdsn = 'HFS.TEST.MOUNT'address SYSCALL "mount (path) (dsn) HFS "MTM_RDWRsay 'Rc='rc 'Retval='retval 'Errno='errno Command return codes are not exactly passed via the usual rcsymbol, but through new symbols retval and errno. The syscall environment initialises __argv. and __environment.stems. ISPF Servicesaddress ISPEXEC is detailed in the REXX and ISPFmanuals.Examples can be found using the MODELcommand in the ISPFeditor.Some specific areas covered by ISPF services are: PDS interrogation and manipulation using the LM utilities E.g.LMCOPY to copy datasets and PDS members. ISPF table access with the TB utilities. E.g. TBSCAN to finda table record. Edit and Browse with ISPF EDIT and ISPF EDIT macros. Panel services with DISPLAY, ADDPOP, and others.There is a known problem in ISPF table services, where a freed tablemay notbe truly free (its ISPF trying to be eficient), causing the TSO FREE tofail.To avoid the problem, open a fake table, e.g. ADDRESS ISPEXEC "TBOPENFAKETABLIBRARY(FAKELIB) NOWRITE" ISPF Services in Batch ISPF services can be used by a batch job, although panel display anduserinteraction may be a little limited. Use ISPSTART running underIKJEFT01 toinitiate the ISPF environment, see the manuals for this. There can be some difficulties when ISPF return codes >=8 causeISPFto terminate. Firstly, the termination will pass a zero RC back to thebatchjob, most terminations can be controlled using ISPEXEC CONTROL, seebelowfor an example. Secondly, the ISPF RC has to be passed back via profilevariableZISPFRC, as the Rexx RC is ignored by ISPF.Lastly, BDISPMAX and BREDIMAX errors, often caused by ISPF trying todisplaya panel (which it can't in batch, of course) don't appear to becontrolledby CONTROL, and cause abending programs to return zero RCs to the batchjob.I suggest setting RC=4 as normal completion, and treating RC=0 as anabendin the job control. /* REXX - Controlling ISPF errors example */address ISPEXEC /* If an ISPF error occurs, then return control to the Rexx */ say 'Setting CONTROL ERRORS RETURN' "CONTROL ERRORS RETURN" /* Call LMFREE for a nonexistent dataid. Returns rc = 10 , which is not usually terminated by ISPF anyway */ say 'Calling LMFREE' "LMFREE DATAID(EEYORE)" say 'LMFREE rc='rc /* Call LMOPEN with a bad parameter. Returns rc = 20 , which causes ISPF to cancel and is thus influenced by the CONTROL ERRORS RETURN */ say 'Calling LMINIT' "LMINIT DATAID(PIGLET) DATAFISH('HADDOCK')" say 'LMINIT rc='rc /* Call EDIT with a non existent edit macro. I cannot get this to return control to the Rexx, and it terminates here with the 'ISPP330 BDISPMAX exceeded' message. The JCL completion code is an not very useful '00' */ say 'Calling EDIT' "EDIT DATASET('NWH.GENERAL.EXEC(ISPFTEST)') MACRO(MCGYVER)" say 'EDIT rc='rc /* Pass the current value of rc back to job control */ zispfrc = rc address ISPEXEC "VPUT (ZISPFRC)" /* This EXIT return code will not make it back past ISPF, but it would have if just TSO was involved. As ISPF is active, it is overridden with the value of ZISPFRC, and a message appears in the SYSTSPRT output */ exit 12 See the Appendices for an example JCLprocedure. Load Modules (I.e. Assembled programs) address MVS, LINKMVS, ATTCHMVS, etc. are detailed in REXX manuals.Theseallow the user to pass parameter lists into the load module.Creating and accessing Rexx external functions using compilers andassembleris also documented in the Rexx manuals. Examples of using the IRXEXCOMinterfaceare on the CBTTape.It is well worth understanding APF authorisation for load modules.Readthe manuals for full details, but briefly, APF authority abends areusuallya result of the loss of an authorised environment caused by 'dirty'programsin the user address space or non APF authorised libraries in theSTEPLIBconcatenation.Some items to look out for are: The SETPROG console command. TSOCMDxx PARMLIB member for TSO command authorisation. Assembling programs with AC=1 'Problem' programs. A problem program is any non APF authorisedprogram. SQLDB2 for zOS has a Rexx interface, introduced with DB2 version 5, anddescribedin the latest IBM DB2 manuals. The interface supplies the DSNREXX environment(as in ADDRESS DSNREXX "EXECSQL SELECT FROM yadda.yadda"). Console Command Environment Kevin McGrath writes:MVS TSO/REXX will issue MVS commands using TSO's MCS console support.Lookin Appendix "D" and "E" of the TSO/E REXX Reference. You must run underTSO,either interactive or batch. REXX provides a host command environment.I'veattached a simple example. /* REXX under TSO */Parse arg commandAddress TSO "CONSOLE ACTIVATE" /* start a console session. */Address CONSOLE "CART(REXXMVS)" /* Establish a CART token. */Address CONSOLE command /* Issue command. */getcode = GETMSG('prtmsg.','sol','REXXMVS',,60) /* get response */If getcode = 0 then /* got response? */ Do i = 1 to prtmsg.0 Say prtmsg.i /* do something with response */ EndElse Say "GETMSG ERROR RETRIEVING MESSAGE. RETURN CODE IS" GETCODEAddress TSO "CONSOLE DEACTIVATE" /* stop the console session. */ExitNeil Hancock adds: Your security setup may restrict use of the console environment. TherelevantRACF profile is listable using RLIST TSOAUTH CONSOLE ALL. There arealso userprofile OPERPARM segments involved. Note that solicited messages are not necessarily available fromsubsystemssuch as JES, RACF, etc. You may have to issue the command, and processunsolicitedmessages to retrieve information from subsystem commands. Rexx aware editors ISPF edit supplies a color hilite facility that is a must if it isavailable.ISPF edit also supplies models for ISPEXEC services, although you mayhaveto adjust the style to your own. Many *nix editors understand Rexx, andKate(part of KDE) uses a simple XML markup that allows highlighting of anylanguage. Rexx CompilersThere are Rexx compilers available, including one from IBM. Ask onthenewsgroup for Information on what is currently available. A freeware utility that converts Rexx source into a tokenised form(asis used by LLA / VLF) is rumoured to exist. Using Rexx as CGI programs with the Web Server. Rexx can be used to create CGI programs that access MVS based resourcesforWeb browser based users. All the Rexx program is doing is to write a dynamic html page to thePOSIXsysout stream. This can be done using the Rexx say command. The BonusPak supplies two shell commands; cgiutils for writinghttpheaders (for passing html versions and cookies to the browser, etc), andcgiparsefor reading environment variables, including forms data.For the GET CGI method, the CGI parameters are available in environmentvariableQUERY_STRING. Environment variables are available in the Rexx stemmed variable __environment.and the parms can be extracted with the parse command. Note that use ofinterpretto extract parms is insecure. A user may manage to pass raw rexxcommandsinto the CGI exec. For pre OS/390 V1 R3 systems, the Rexx say command wraps at 80characters.Use SYSCALL "write .." instead. Some browsers convert special characters to an escaped notation. Access to Classic MVS resources can be done by using Rexx function shcmdto trap the output from commands run under TSO. Commands can be run under TSO using the tsocmd shellcommand.Both shcmd and tsocmd are available from the IBM Kingston ftp site. Style. These style hints are mostly aimed at programmers from other MVS andTSOlanguages, especially CLIST. Your site may have its own conventions andtheseshould take precedence over anything said here. You may also prefer toworkin your own style, and that too is perfectly acceptable. What are the most effective ways to usecomments? You must have REXX as part of the first line of Rexx, whichmust also be a comment. It seems sensible to take the opportunityto say something about what the program is about in this openingcomment. Only open and close a comment that goes across many lines once.There are no real performance benefits in this, only your codewill contain fewer extraneous characters, and this will help yousee the wood for the trees. It makes little sense to comment every line no matter howtrivial. Rexx isn't assembler and most commands are self evident. Consider commenting what is being terminated at an END statement,particularly select statements and do loops that cover more than onescreenfull of program. Don't squeeze comments down the right hand side of the code. This restricts the insertion of maintenance code, and moreimportantly, the restricted space causes the comments to becomeabbreviatedpast the point of becoming cryptic. EXECIO.Close any brackets. It makes the code look neater.Use address MVS "EXECIO" in preference to addressTSO "EXECIO". You then avoid unexpected occurances of rc(-3)when you run the exec under IRXJCL instead of IKJEFT01.Tim Larsen <DKDDBNGX@IBMMAIL.COM> writes:With DISKW - use the queued() built-in, instead of a null-record and"*".If you forget the null-record ("QUEUE'') you will get a prompt,dependingon the TSO PROFILE!E.g. "EXECIO" queued() "DISKW DDNAME(FINIS)" What case should I program in, upper or lower?Readability can be improved by writing Rexx as if it were ahumanlanguage and not as if it were JCL or assembly code. Avoid having theentireprogram in upper case, this is known as shouting and does nothing tohelpreadability. It is common to write commands addressed to externalenvironmentsin upper case, and to use mixed case for Rexx commands and symbols. Functions and proceduresIf a call returns a value that is not a return code, it may bebetter tocall it as a function rather than a procedure.E.g. Consider: ifLinein(needle,haystack)then say 'Hello' versus: call Linein needle,haystackif result = 1 then say 'Hello'Make the names of functions and procedures meaningful Logical (Boolean) variables and functions.Symbols with a value of 1 are logically true, 0 logicallyfalse.All other values give an error when tested for logical truth.Functions may return logical values, but don't confuse functionsreturninglogical values with those that return numeric values.E.g. if Datatype(var,'NUM') thensay'Hello' /* Is OK */if Pos(needle,haystack) then say 'Hello' /* May abend */ Symbolic names. Symbolic (or variable) names are not limited to eightcharactersas in some other languages, this allows more scope for meaningfulnames. Thenames used will depend largely on the programmers preferences and styleofcode writing, but here are some suggestions to consider.Use long variable names and separate words with an underscore.E.g. Table_name = 'MAILTAB' Underscores are a useful way of hiding variables from ISPF. Use i,j,k,etc as loop control symbols. Execs that do not hidesymbols usingthe procedure command may suffer from reuse of loop control symbols.E.g. do i = 1 to 10 Prefix variable names with specific characters to show the type ofdatathe variable contains, such as logical, numeric, flags, etc. I often prefix variable names with '?' to stop variable substitutionoccurringif stemmed variables. E.g. count = 2 ; year = '1945' ;stem.count.?year= year /* STEM.2.?YEAR = '1945' */ Bboolean = 1; if Bboolean then say 'hello' Fflag = 'A'; if Fflag = 'A' then say 'hello' @address = STORAGE(something) #numeric = 10 + 12 See also the section on usingnon-alphanumeric characters Internal and external calls Rexx allows calls to be made to execs that reside outside ofthecurrently executing exec. This allows programmers to use prewrittenmodules,and to split large amounts of code up into manageable chunks. Howeverthereis a performance overhead in doing this. Here are some other points toconsider:Some aspects of an exec may be relevant to other execs, and you maywishto supply a routine that is usable by other execs performing similartasks.Consider creating external routines that supply a robust and genericservice(e.g. catalogue listing, mail sending, interfaces to data, etc.) sothat otherdevelopers may benefit from reduced development time. Exit external routines with RETURN rather than EXIT. Thisfacilitates thecopying of the routine into an exec for performance benefits. Don't use an external call to a routine that is called recursively,theresulting I/O will drop the exec performance. The inability to share variables across external procedures may leadyouto choose to use internal procedures over external ones . How can I improve performance of my exec?In general, using an appropriate and well tunedalgorythm/solutionis better than using specific 'hacks'. Address external environments directly using ADDRESS. For multiplecallsto the same environment set the environment before entering into themultiplecalls. E.g. address TSO "ALLOC FI(...) DA(....) SHR"Internalise external routines that are called repeatedly. Then theywon'thave to be loaded and tokenised by the interpreter every time they arecalled.Use single letter vars for loop control. TSO/Rexx has some fast-pathoptimisationfor code such as DO I = 1 to 1000.Using the string functions ( POS(), LEFT(), etc ) on a single verylargestring, rather than searching through many stemmed vars.Use terse coding, avoid unnecessary commands.E.g. Consider:if symbol = 'FRED' then say 'Hello'Versus:if symbol = 'FRED' then ,dosay 'Hello'endEmbed function calls within each other rather than build up avariableover several lines of code.E.g. junk = Left(Overlay('A',Userid()||Random(999),1,1),8)Use a compiler. Expect 100% improvement for number maniplulation(addingand whatnot), 30% for string manipulation (using the string functions),andno real improvement when interfacing to external environments.Performance test your code using the SYSVAR('SYSCPU') function and notthe TIME() function. How can my systems programmer improveperformance.Use VLF. See IKJEXEC in Init and Tuning manual. Note that VLF is notusedfor external procedure and function calls, only the EXEC interface,like whatis used when you TSO EXEC MYLIB(MYEXEC).Use the environment tables in SAMPLIB if you have environments thatarenot part of the distribution tables. Supply well written external routines for non trivial tasksperformed byuser code. This may deter users from writing inefficient code toperform thetask themselves. What obscure coding tricks are there.These tricks are not necessarily recommended, as they can reduce thereadabilityof the code. They can also speed things up, particularly those tricksusingPARSE.Use a boolean check.sign = TRANSLATE( (var<0) , '+-' ,'01')boolvar = (test=true)Use the TRANSLATE() function to reorder or insert chars in a string.(Thanksto Doug Nadel)sayTRANSLATE('ab,cde,fgh,ijk,lmn,opq,rst,uvw,xyz', myNumber , 'abcdefghijklmnopqrstuvwxyz')say TRANSLATE('abcdefghijklmnopqrstuvwx yz123456' , hexChars , 'abcdefghijklmnopqrstuvwxyz123456')Use functions such as DATE() to check if some data conforms to atype.Use ON SYNTAX to trap the error.junk = DATE(,testDate,'S') /*Willgive a syntax error is testDate is not a standard date */The many variations of DO. Read the Rexx Reference and Rexx Guidefor inspiration.Use PARSE to initialise variables.parse value '1 2 3 6 4' withvar1var2 var3 var4 var5 .Use PARSE instead of SUBSTR().parse var string =(colA) var1 +(lenA) ., =(colB) var2 +(lenB) ., =(colC) var3 +(lenC) . is functionally equivalent to: var1 =SUBSTR(string,colA,lenA) var2 = SUBSTR(string,colB,lenB)var3 = SUBSTR(string,colC,lenC) Use PARSE to split out bits from a string:parse value X2B(C2X('AA'x)), with x80 2 x40 3 x20 4 x10 5 x08 6x047 x02 8 x01 Use PARSE to increment a stem counter and assign a value to the newlaststem (Attributed to Les Koehler @ IBM Tampa).stem.0 = 1 ;stem.1 = 'cheese'parse value stem.0+1 'mice' , with 1 x stem.x , 1 stem.0 . ;say stem.0 /* ==> '2' */ say stem.1 /* ==> 'cheese' */ say stem.2 /* ==> 'mice' */ say x /* ==> '2' */ Using Non-Alphanumeric characters. Stephen Bacher writes on the subject of using non-alphanumericcharacters:"I disagree strongly with (... the use of ...) non-alphamericcharacters (like! # % ) in REXX variable names. Extensions to REXX, includingobject-orientedextensions, may use these characters. Including them in variable namesisasking for eventual breakage IMHO." Another reason to avoid using the EBCDIC special characters (theseincludecurrency symbols, hash, at, double quotes, etc.) is because thesecharactersmay have different display meanings in foreign EBCDIC chacacter sets. Are there any other style hints? Leave space at the end of line for continuations and short'date changed' comments. Avoid ambiguous or confusing abbreviations in symbol namesand comments. E.g. 'lst' and '1st' appear similar, and will a casual readerknow whether a symbol 'lstPointer' is referring to a 'list pointer'or a 'last pointer' See the Style Guide for a moredetailed style discussionAppendices. Code ExamplesThis is a sample JCL procedure to run ISPFinbatch.//ISPFPROC PROC PREFU='user.lib',PREFS='SYS1',CMD=//ISPF EXEC PGM=IKJEFT01,DYNAMNBR=30, // PARM='ISPSTART CMD(&CMD)' //*//ISPPROF DD DISP=NEW,UNIT=SYSSQ,SPACE=(TRK,(1,1,1)),// DCB=(LRECL=80,BLKSIZE=8000,RECFM=FBA)//*//SYSEXEC DD DISP=SHR,DSN=&PREFU..EXEC// DD DISP=SHR,DSN=&PREFS..SISPEXEC//SYSPROC DD DISP=SHR,DSN=&PREFS..SISPCLIB//ISPPLIB DD DISP=SHR,DSN=&PREFU..PANELS// DD DISP=SHR,DSN=&PREFS..SISPPENU//ISPMLIB DD DISP=SHR,DSN=&PREFU..MSGS// DD DISP=SHR,DSN=&PREFS..SISPMENU//ISPSLIB DD DISP=SHR,DSN=&PREFU..SKELS // DD DISP=SHR,DSN=&PREFS..SISPSENU//ISPTLIB DD DISP=SHR,DSN=&PREFU..TABLES// DD DISP=SHR,DSN=&PREFS..SISPTENU//ISPTABL DD DISP=SHR,DSN=&PREFU..TABLES//ISPLOG DD DUMMY,DCB=(RECFM=VA,LRECL=125,BLKSIZE=129)//ISPLIST DD DUMMY,DCB=(RECFM=VA,LRECL=125,BLKSIZE=129)//ISPLST1 DD DISP=NEW,UNIT=SYSSQ,SPACE=(CYL,(1,1)),// DCB=(LRECL=121,BLKSIZE=1210,RECFM=FBA)//ISPLST2 DD DISP=NEW,UNIT=SYSSQ,SPACE=(CYL,(1,1)),// DCB=(LRECL=121,BLKSIZE=1210,RECFM=FBA)//ISPCTL1 DD DISP=NEW,UNIT=SYSSQ,SPACE=(CYL,(1,1)),// DCB=(LRECL=80,BLKSIZE=800,RECFM=FB)//ISPCTL2 DD DISP=NEW,UNIT=SYSSQ,SPACE=(CYL,(1,1)),// DCB=(LRECL=80,BLKSIZE=800,RECFM=FB)//ISPWRK1 DD DISP=NEW,UNIT=SYSSQ,SPACE=(CYL,(1,1)),// DCB=(LRECL=256,BLKSIZE=2560,RECFM=FB)//ISPWRK2 DD DISP=NEW,UNIT=SYSSQ,SPACE=(CYL,(1,1)),// DCB=(LRECL=256,BLKSIZE=2560,RECFM=FB)//*//SYSUDUMP DD DUMMY//SYSTSPRT DD SYSOUT=Q//SYSPRINT DD DUMMY//SYSTSIN DD DUMMY// PENDAnd run it thus://TESTISPF EXEC ISPFPROC,// PARM.ISPF='ISPSTART CMD(%REXXPROG TESTPARM)', // PREFU='ISP'//* or alternativly, //TESTISPF EXEC ISPFPROC,// CMD='%TESTPROG TESTPARM'// PREFU='ISP' If ISPF is not needed, try using IRXJCL://IRXJCL1 EXEC PGM=IRXJCL,PARM='%execname'//SYSEXEC DD DISP=SHR,DSN=your.exec.library//SYSPRINT DD SYSOUT=*//SYSTSPRT DD SYSOUT=*or TSO in batch://IRXTSO EXEC PGM=IKJEFT01//* You could use PARM='%execname testparms' on exec statement//SYSEXEC DD DISP=SHR,DSN=your.exec.library//SYSTSPRT DD SYSOUT = *//SYSTSIN DD *%execname testparms/*//* You could run more than one exec sequentially from SYSTSIN//* You can also run straight TSO commands like TSO PROF PREF(FRED)This Exec shows how to temporarily LIBDEFISPF datasets to your session, ALTLIB an Exec librarytoyour session, call an ISPF application (under a newapplicationId to avoid name collisions with other ISPF profile var. names), andthenunstack the LIBDEFs, and deactivate the alternative Exec library.address ISPEXEC "LIBDEF ISPPLIB DATASET ID('user.PANELS') STACK"address ISPEXEC "LIBDEF ISPMLIB DATASET ID('user.MSGS') STACK"address ISPEXEC "LIBDEF ISPTLIB DATASET ID('user.TABLES') STACK"address TSO "ALTLIB ACTIVATE APPLICATION(EXEC) DATASET('user.EXEC')"address ISPEXEC "SELECT CMD(%yourexec "your exec options") NEWAPPL(yourappl) PASSLIB"address ISPEXEC "LIBDEF ISPTLIB"address ISPEXEC "LIBDEF ISPMLIB"address ISPEXEC "LIBDEF ISPPLIB"address TSO "ALTLIB DEACTIVATE APPLICATION(EXEC)"Other Sources of Information.Marist College hosts the ListServ Archives at http://www.marist.edu/htbin/wlvindex?tso-rexxYahoo! has a Rexx category thatlists severalRexx information sites.Rexx Book list. Try searching Amazon.Rexx manuals, search the IBMS390 Websiteto find them online in PDF and HTML formats.CbtTape.org has many usefulutilities,including a list of Listservlists.Rexx newsgroup comp.lang.rexx canbe foundvia GoogleISPF has its own active listserv at ISPF-L@listserv.nd.edu, Sendmessagetext 'SUBSCRIBE ISPF-L Your Name'to LISTSERV@listserv.nd.eduand await further instructions.Subscribing to the TSO-REXX ListGo to the TSO-Rexxlist archive, scroll to the bottom of the page, and follow theinstructionsthere. Glossary Generation Data Group. A set of datasets referred to by their GDG base, and a generationnumber referring to the generation required. See MVS/Using datasets. Built-in Function. A standard Rexx function, e.g. SUBSTR(). External Function. An external Rexx function, either supplied with TSO/E, e.g.SYSVAR(), or supplied in a PDS in Rexx source or Load Module form,e.g. RXGDGV() in appendix C. Internal Label. A label within an exec, either hidden (with PROCEDURE withoutEXPOSE), or exposed. Profile prefix. A TSO environment variable. The users default HLQ, prefixedto unqualified datasets to make a qulified DSN HLQ. High Level Qualifier. The first qualifier in a fully qualifieddataset name. DTL Dialog Tag Language. An SGML markup language used to defineISPF panels. DTL documents are converted into panels using the ISPDTLCcompile utility. |
|