× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



On 27-Jun-2014 15:47 -0500, rick baird wrote:
I have a very simple program I can call from a CLP that just
retrieves and returns a value based on the value passed - use
example:

CALL PGM(SU22A1) PARM('FROMVERS3 ' &OLDVERS )
CALL PGM(SU22A1) PARM('OBJLIB ' &NJOBDL )
CALL PGM(SU22A1) PARM('JOBD ' &NJOBD )

From the utilization shown, the program SU22A1 could possibly be better coded as a /retrieve-command/ invocation, with a parameter for each of the various passed-values. As a side effect of that implementation, the problem would likely be avoided, because the design of the called program as a CPP for a retrieve command would necessarily have a separate parameter for each return-value.

I use the different variables in commands thereafter. As I step
through each step in debug, after the first call, the variable
&OLDVERS has the value I expect. After the second call, variable
&NJOBDL has the value I expect, but &OLDVERS is now blank, and after
the third call, &NJOBD has the value I expect, but &NJOBDL is blank
too.

What gives? I'm guessing it's an issue with the called program
reusing the same pointer space in memory,

The memory\storage utilized is a distinct address for each CLP variable passed on the separate invocations; the 2nd argument of the /called program/ refers to distinct by-address location that was passed [i.e. passed by reference] from the CLP on each invocation. The three CL variables are likely to be in the same /contiguous/ memory however, yet obviously, they can not be at the /same/ location. Likely the CL variables are in the /same/ vicinity within the /automatic storage/, each at an offset that is incrementally a number of bytes beyond the previous variable; a number that is equivalent to the declared length the previous variable.

but how can I keep this from happening short of saving off the value
before calling the next one?

The method that Booth showed <http://archive.midrange.com/rpg400-l/201406/msg00154.html> is probably the simplest and safest solution, if the changes should be confined to the CLP. In that case, the one CL variable used repeatedly for the 2nd argument would be declared to match the declaration for the 2nd parameter in the program SU22A1. However the Change Variable (CHGVAR) after each invocation may not qualify as avoiding "saving off the value before calling the" program SU22A1 the next time.

Probably the program SU22A1 has declared the 2nd parameter as a character variable with a /long/ length that can accommodate generically, any "value returned" for each of the possible "value passed" literals. That program also probably does a simple assignment to that character [string] variable, for which the effect is blank-padded result. The blank padding for the /long/ length presumably is overwriting the contiguous storage that is utilized for the other CL variables. That is, I suspect the called program SU22A1 does something like the following pseudo-code:

dcl &value_passed *char 10
dcl &value_returned *char 200 /* largest possible rtn value */

case &value_passed
when 'FROMVERS3 '
then &value_returned=&fromver
when 'OBJLIB '
then &value_returned=&objlib
...

The problem described would occur in the calling program because although the calling program passes only a 10-byte variable for the "object library" variable named &objlib, the 190 bytes beyond those first ten bytes would be /cleared/ [set to blanks] as the side effect of the padding for the simple assignment of the variable named &value_returned.

Given the program SU22A1 already must be coded with the /assumption/ that the caller will provide the proper storage for the respective literal value [passed as the 1st argument], then a simple resolution can be confined to the called program; keeping that same /assumption/ however. That called program would be modified to ensure that each assignment is made to a substring of the passed storage, rather than an assignment of the declared character [string] variable itself. In pseudo-code:

case &value_passed
when 'FROMVERS3 '
then %sst(&value_returned:&fromverLen)=&fromver
when 'OBJLIB '
then %sst(&value_returned:&objlibLen)=&objlib
...

That resolution is not very desirable because the assumptions are not removed from the called program.


As an Amazon Associate we earn from qualifying purchases.

This thread ...


Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.