Joined: 02 Dec 2002 Posts: 624 Topics: 175 Location: Stockholm, Sweden
Posted: Wed Jan 10, 2024 10:51 am Post subject: Compiling Rexx scripts
I searched the forum, but couldn't find anything that seemed relevant.
I am playing with compiling some Rexx code and have a few questions.
- when compiling, the compiled code ends up in a PDS. I'm assuming that every script has to/should be compiled into the same PDS? From what I've read, I understood it to be that if I have, say, 3 scripts, A, B and C and A & B are compiled into PDS1 (first in the chain of libraries) and C is uncompiled in PDS2, then Rexx will automatically "switch over" to PDS2 to run C from A or B?
- is it possible to/should one "link" all the scripts into one MASSIVE script. If it's possible, are there any particular advantages?
- I read somewhere a discussion about compiling panels as well (I assume they meant ISPF ones). Is this necessary, and is there any real point to it?
I'm assuming that every script has to/should be compiled into the same PDS? From what I've read, I understood it to be that if I have, say, 3 scripts, A, B and C and A & B are compiled into PDS1 (first in the chain of libraries) and C is uncompiled in PDS2, then Rexx will automatically "switch over" to PDS2 to run C from A or B?
When you compile you create an object deck and when you link edit it it will become executable load module. So a compiled rexx is NO longer an interpreted code at run time.
misi01 wrote:
- I read somewhere a discussion about compiling panels as well (I assume they meant ISPF ones). Is this necessary, and is there any real point to it?
well the panels will do the same thing as executing the catalogued procedures under the covers. Check this link
Joined: 02 Dec 2002 Posts: 624 Topics: 175 Location: Stockholm, Sweden
Posted: Thu Feb 08, 2024 7:06 am Post subject: Cannot preview append
I was going to append a long description of how my attempts went compiling Rexx scripts, but the preview button is still failing. _________________ Michael
Joined: 26 Nov 2002 Posts: 12369 Topics: 75 Location: San Jose
Posted: Thu Feb 08, 2024 3:21 pm Post subject: Re: Cannot preview append
misi01 wrote:
I was going to append a long description of how my attempts went compiling Rexx scripts, but the preview button is still failing.
The preview is working fine for me using Firefox. What browser are you using? can you clear cookies and cache and see if it works? _________________ Kolusu
www.linkedin.com/in/kolusu
Now the interesting part started.
First of all, which member do you use, CEXEC or OBJ?
I'm sure it's in the docs SOMEWHERE, but I couldn't see it.
I tested using OBJ and received the following message
Quote:
STMT 1 OTHER THAN DBCS CHARACTER FOUND IN A DBCS STRING
Turns out that it's the CEXEC library.
Next part is that at OUR installation, you can define a special PDS and
member called userid.TEST.EXEC(xLDDNAME) which contains lines along these
Quote:
ISPMLIB S6843F.TEST.MSGS
ISPPLIB S6843F.TEST.PANELS
ISPSLIB S6843F.TEST.SKELS
SYSPROC S6843F.TEST.CEXEC <--- the compiled scripts
SYSPROC S6843F.TEST.CLIST <--- my Rexx scripts
Now, originally, my TEST.CLIST had DCB's of VB, 255, 3600.
I compiled a script (called MSGESQL) that uses panels and other scripts and compiled it (so it ended up in the CEXEC library).
I then renamed it to MSGESQLB in TEST.CLIST.
That way, I knew that if TSO MSGESQL worked correctly, it was because it was coming from the CEXEC library and not the TEST.CLIST one.
That's where I hit my first "problem". Starting TSO MSGESQL immediately gave the message
Quote:
An invalid record was found during exec load. This is an internal error.
42 +++ rc = dl1db232()
15 +++ rc = init()
Error 43 running compiled MSGESQL, line 42: Routine not found
DL1DB32 was NOT compiled into CEXEC, so I did that, and tried again.
This time I got the same message for a script called ISPFADD.
This is where I started to guess/realize that I either had to compile all the called scripts into the CEXEC library
..... OR .....
try copying TEST.CLIST to a library with the same DCB's as the CEXEC one. This time my xLDDNAME looked like this
Quote:
ISPMLIB S6843F.TEST.MSGS
ISPPLIB S6843F.TEST.PANELS
ISPSLIB S6843F.TEST.SKELS
SYSPROC S6843F.TEST.CEXEC <--- the compiled scripts
SYSPROC S6843F.TEST.CLIST.FB80 <--- same DCB's as TEST.CEXEC
I then deleted DL1DB232 from TEST.CEXEC, logged off and on and tried again. SUCCESS !!!!
Now it seems to turn out that Rexx scripts are run from CEXEC first and if not found there, then from TEST.CLIST.
Why was my original TEST.CLIST VB 255 ? Because all the other standard company EXEC/CLIST PDS's are.
My only "problem" now is that every time I log on to ISPF, I get the error message
Quote:
INVALID COMMAND NAME SYNTAX
every time before entering ISPF (I'm guessing it's something to do with our logon procedures, but
and I have no idea where it's coming from).
I've reported it, but it's a slight irritant rather than a serious error
All the standard libraries allocated to SYSPROC are defined as VB 255, so I thought I could copy TEST.CEXEC to
TEST.CEXEC.VB27998 (same DCB's as the other SYSPROC libraries).
For my troubles (TSO MSGESQL) I receive the following error
Quote:
System abend code 0C4, reason code 00000016.
IDI0001I Fault Analyzer V15R1M03 (UI94574 2023/11/22) invoked by IDIXDCAP using
SYS1.PARMLIB.IDI(IDICNF34)
ISPV028
IKJCT441 interface error
The caller is not in a CLIST or REXX environment. Return code = 40. This
could be a result of not having the function pool flag set in the ISPTCM
table for the command being executed.
so I'm guessing that the CEXEC library has to be FB 80 and the idea died.
(I'm assuming that the requisite DCB's are defined somewhere in the link you sent me, but again, it's not obvious) _________________ Michael
Joined: 02 Dec 2002 Posts: 624 Topics: 175 Location: Stockholm, Sweden
Posted: Thu Feb 15, 2024 5:02 am Post subject:
Thought I'd update this thread a bit more.
One of the "quirks" of the Rexx compiler (CREXX) is the fact that it is less "forgiving" than the interpretative variation (IREXX) (which is both good and bad, depending on ...)
For example, IREXX allows duplicate procedure names, whereas CREXX gives a compiler error. IREXX doesn't care if you have code such as
Code:
fred = left(bert)
(as long as you don't try to actually use it). CREXX gives a compiler error.
So, basically, unless there's some option I haven't noticed/don't know about, you have to review the JCL results of any Rexx compilation to check if your code is "invalid".
Not only that, but the results of the compilation (valid or not) ALWAYS result in a member in your CEXEC PDS.
This is obviously a hassle. The result of this, is I changed my proclib and skeleton JCL to the following.
(I set SYSPUNCH to DUMMY since I never envisage linking my compiled Rexx scripts into a load library)
Code:
//REXX EXEC PGM=REXXCOMP,PARM='&OPTIONS'
//STEPLIB DD DSN=&COMPDSN,DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSTERM DD SYSOUT=*
//SYSCEXEC DD DSN=&&CEXEC(GO),DISP=(MOD,PASS),UNIT=SYSDA,
// SPACE=(800,(800,100,1))
//SYSPUNCH DD DUMMY
//*
// IF (REXX.RC NE 0) THEN
//* Compilation threw errors for whatever reason
//*
//S010 EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//SYSIN DD *
SET MAXCC = 12
/*
// ELSE
(more code here to do this and that)
ENDIF
and my SKEL JCL to
Code:
//&ZUSER.A JOB (CCC0,),'&ZUSER.',CLASS=IMSB,
// MSGCLASS=X,MSGLEVEL=(1,1),
// REGION=20M,NOTIFY=&SYSUID
//*
//JCLLIB JCLLIB ORDER=(&ZUSER..TEST.PROCLIB)
//*
//*
//* Compile a Rexx script
//*
// EXPORT SYMLIST=(MEMBER)
// SET MEMBER=&MEMBER
//*
//REXXDEL EXEC PGM=IDCAMS
//*
//* Ensure the output CEXEC member is always deleted first
//*
//SYSPRINT DD SYSOUT=*
//*
//SYSIN DD *,SYMBOLS=JCLONLY
DELETE &SYSUID..TEST.CEXEC(&MEMBER)
SET MAXCC = 0
//*
//*
//REXXC EXEC REXXC
//REXX.SYSCEXEC DD DSN=&ZUSER..TEST.CEXEC(&MEMBER),DISP=SHR
//REXX.SYSIN DD DSN=&ZUSER..TEST.CLIST(&MEMBER),DISP=SHR
//*
// IF (REXXC.REXX.RC GT 1) THEN
//* Problems with compilation. Delete the CEXEC member
//*
//S010REXX EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//SYSIN DD *
DELETE &SYSUID..TEST.CEXEC(&MEMBER)
/*
// ENDIF
What this does is to ensure any existing member in TEST.CEXEC is deleted before the compiler is calledand
if the compiler returns a non-zero return code, then delete the TEST.CEXEC member afterwards as well. _________________ Michael
Joined: 02 Dec 2002 Posts: 624 Topics: 175 Location: Stockholm, Sweden
Posted: Thu Feb 15, 2024 5:20 am Post subject: Keeping your Rexx source/CEXEC libraries in synch
The idea (?) behind compiled Rexx is to be able to distribute your code as object code only while "protecting" your source code from prying eyes.
One of the problems you're going to run into inevitably is knowing whether you need to recompile your source code, i.e., is the CEXEC member back-leveled?
To this end, I've written a Rexx panel script that allows you to compare the source script changed date/time against that for the CEXEC member.
Code:
MS Check source Rexx against compiled code
COMMAND ===>
As can be seen from the screen scrape above, you specify your source code library and your CEXEC one. You can specify a pattern for the source code.
From above, the DL1DB01 line will be shown in green, since the last changed date for the member is
less than that for the CEXEC member, so that member is in synch.
In this example, the remaining source members have not been compiled yet.
You can select any rows via the select column, press PF12 and each entry will be submitted as a job to be compiled.
.... and this is where the changed PROCLIB/SKEL entries shown in the previous append come into play.
For any "invalid" source script, the JCL will now return a return code of 12. _________________ Michael
Joined: 26 Nov 2002 Posts: 12369 Topics: 75 Location: San Jose
Posted: Thu Feb 15, 2024 11:36 am Post subject: Re: Keeping your Rexx source/CEXEC libraries in synch
misi01 wrote:
The idea (?) behind compiled Rexx is to be able to distribute your code as object code only while "protecting" your source code from prying eyes.
Misi01,
My sample JCL uses the option NOCOMPILE(W) on the compile step which suppresses the generation of compiled code if a warning, error, severe error, or terminating error is detected.
The next steps (PLKED and LKED) check the return code the compile Step REXX and skip running them.
I hope you also realize that SYSPRINT in REXX step actually is the Compiler LISTING of the rexx code.
The output of SYSCEXEC is kinda of Object code which cannot be deciphered that easily.
misi01 wrote:
For example, IREXX allows duplicate procedure names, whereas CREXX gives a compiler error. [b]IREXX doesn't care if you have code such as
Code:
fred = left(bert)
(as long as you don't try to actually use it). CREXX gives a compiler error. [/
For duplicate procedure names, the compiled exec gives you a warning
Code:
+++FANPAR0071W Duplicate label: Only first occurrence on line 39 used
Joined: 02 Dec 2002 Posts: 624 Topics: 175 Location: Stockholm, Sweden
Posted: Sat Mar 02, 2024 3:02 am Post subject:
I think you missed the bit where I wrote
Quote:
as long as you don't try to actually use it
Not sure if want to compile the code using the NOCOMPILE option you mentioned.
I'm quite happy to see duplicate procedure names pointed out as well as other similar errors.
Duplicate names can be a bummer inasmuch as Rexx always uses thelast entry.
You then try and understand why things aren't working as expected. Edit the script and do a find on the name and find the first one rather than the failing one and are left wondering what the hell is going on. My bad coding, but if the computer catches that, I'm good.
Are there any specific advantages in creating object (?) Rexx rather than the simple compiled Rexx?
Is object rexx more "encrypted" (the compiled code seemed pretty unreadable, though, theoretically, one might want to "hide" simple strings a bit better)
It seems to me that any change in the Rexx source code only needs to be compiled and distributed on its own, whereas, using object code everything has to be "linked".
BTW
I think I forgot to mention how my scripts are used. Basically they are all such that
a) the user starts a panel to drive the script
b) they are edit macros.
I read/saw the bit about object scripts (from your link), but then lost it when it started talking about stubs. My (very) simple text indicated the following.
I have 2 scripts, A and B (A calls B)
My login procedure allocates the compiled Rexx library first, then the uncompiled one.
If I compile A and run it, uncompiled B is called happily and run.
If I then compile B, compiled A will call and run compiled B automatically.
In what sort of situation would the object code be needed? _________________ Michael
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum