× 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.




Arthur J. Marino wrote:

I'm testing the proc in a service pgm that defines 3 parms, all of which
are 10 bytes, alpha and "const". The last 2 have "options(*nopass)". I'm
testing for the presence/absence of the last 2 parms using %addr(parm)
equal/not equal to *null.
I have the main pgm call the proc twice, once with all 3 parms present (x
= proc(p1:p2:p3)), the second time with only the 1st parm present (x =
proc(p1)). In debug, the 2nd invocation of the service pgm proc shows the
2nd and 3rd parms containing the data from the 1st invocation. Since I
didn't pass those parms in the 2nd invocation, shouldn't they be
undefined??? If not, how does one have the proc function differently based
on the number of parms passed? Do I have to check the %parms BIF? If
that's the case, what exactly is %addr(parm) good for?

Arthur J. Marino
Southern Container Corporation
(631) 297 - 2276

Hi Arthur,

Here's a very short story that leads to the answer that we devised:

Once upon a time, someone at our firm (*cough*) had the brilliant idea of mapping some of our service program procedures to SQL User Defined functions. Any procedure that returned a single value seemed eligible.

Extending the procedures to SQL seemed straight-forward:

- Add the SQL provided parameters to the RPG prototype with OPTIONS( *OMIT : *NOPASS ) on the new parameters.

- Add some branching logic to use the SQL parameters WHEN they were provided (return nulls when exceptions occurred, etc.).

However, it was soon discovered that SQL calling RPGLE did NOT provide the minimum operational descriptor information that allows the %PARMS BIF to work (as is true for several processes that can invoke RPGLE). The quick workaround was to check for parameters with a valid address - if the parameter had a valid address, it must have been passed - OR SO ONE WOULD THINK. In testing, this SEEMED to work.

Alas, in the middle of a production day our oversight was brought home to us (*cough* me). Sometimes, an unpassed parameter had a valid address just because it had been passed on a previous call and the memory was still allocated. Sometimes, the valid address existed just because there was allocated memory adjacent to the memory used by the parameters that WERE passed.

If only IBM had anticipated this!

Wait, they did.

There is an IBM API (CEETSTA - Test for Omitted Argument) that does the trick. Wrap a prototype around the API (I dunno... call it $IsThisParmPresent) and use it to test for the presence of any omissible parameter. This will determine if the parameter was truly passed on THIS invocation of your code.

Here is an excerpt from our prototype for the API:

***********************************************************************
* Prototype for $IsThisParmPresent subprocedure *
***********************************************************************

D $IsThisParmPresent...
D PR EXTPROC( 'CEETSTA' )
D p#PresenceFlag...
D LIKE( DtaTypInt )
D p#ParameterNumber...
D LIKE( DtaTypInt ) CONST
D p#FeedbackCode...
D LIKE( DtaTypFC )
D OPTIONS( *OMIT )

Cheers!

As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:

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.