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



So...

This might be a stupid question, but does proc2 care how many parms were
passed, or does it just care about not using any unpassed ones? For
instance, could you simply pass another parameter (before the optional ones)
stating how many contain actual data? That way, you can just call proc2 with
all parms from proc1:

In proc1:

D optparms S 10 Dim(16)

clear optparms;
if %parms > 1;
optparms(1) = parm2;
if %parms >= 2;
optparms(2) = parm3;
...
...
...
endif;
endif;

callp(e) proc2( parm1 : %parms : optparms(1) : optparms(2) ...to
optparms(16)... );

I didn't include any checking for omitted parms in this example. Perhaps you
could treat a blank parameter as the equivalent of an omitted parameter...
Then in proc2, you check the value of the second parameter passed in rather
than %parms.

Sure, there's the initial long IF statement (which would obviously be much
longer if there were 16 optional parameters - 48 lines, by my calculation),
but I think it's simpler to read than a SELECT which has the call in it. In
fact, if you use the _NPMPARMLISTADDR MI builtin (see below), then you could
replace the entire 48-line IF string with a 6-line loop:

/copy qrpglesrc,mi_parm_p
D optparms S 10 Dim(16)
D curparm S 10 Based(curparm@)

clear optparms;
plist@ = Npm_ParmList_Addr();
dlist@ = plist.desclist@;
for parmnbr = 1 to dlist.argc;
if plist.parm@(parmnbr) <> *null;
curparm@ = plist.parm@(parmnbr)
optparms(parmnbr) = curparm;
endif;
endfor;

callp(e) proc2( parm1 : %parms : optparms(1) : optparms(2) ...to
optparms(16)... );

That might be a little nicer, but it's a bit 'techie'.... Plus it assumes
that the parameters are all the same size/type (and so can be easily moved
to an array such as optparms) and also that they are all passed as CONST.
The same caveat as the top example (having proc2 treat a blank parameter as
being an omitted parameter) also applies to this example.

Having said all of that, there might be a 'better' solution...

If you use a second 'dummy' definition of proc2 as:

D proc2x pr 10I 0 Extproc('PROC2')
D parm1 10
D parm2 * options(*nopass :*omit) value
D parm3 * options(*nopass :*omit) value

then you could pass null pointers to simulate omitted parameters (I think)
as follows:

/copy qrpglesrc,mi_parm_p
D optparms S * Dim(16)

clear optparms;
plist@ = Npm_ParmList_Addr();
dlist@ = plist.desclist@;
for parmnbr = 1 to dlist.argc;
optparms(parmnbr) = plist.parm@(parmnbr);
endfor;

callp(e) proc2x( parm1 : optparms(1) : optparms(2) ...to optparms(16)... );

In this case, I didn't use the (new) second parameter - in proc2, it will
look as though the final unpassed parameters were simply omitted, since they
are passed as null pointers. IOW, %parms in proc2 will show that all
parameters have been passed, but the ones which weren't passed to proc1 will
look as if they were simply omitted instead. So if proc1 is called with only
2 parameters, proc2 will see all 3 parameters, but the last one will be
treated as if *OMIT was specified for it in the call to proc1.

Maybe a bit much, but still, it's a nice technique...

Rory

p.s. Here's my definition of the _NPMPARMLISTADDR API:

/IF NOT DEFINED(MI_PARM_P)
/DEFINE MI_PARM_P

D Npm_ParmList_Addr...
D PR * Extproc('_NPMPARMLISTADDR')

D Npm_ParmList_t DS Qualified Based(TEMPLATE)
D desclist@ *
D 16A
D parm@ * Dim(400)

D Npm_DescList_t DS Qualified Based(TEMPLATE)
D argc 10I 0
D 8A
D opdesc 10I 0
D 16A
D desc@ * Dim(400)

D Npm_Desc_t DS Qualified Based(TEMPLATE)
D desctype 3I 0
D datatype 3I 0
D descinf1 3I 0
D descinf2 3I 0
D datalen 10I 0

D Npm_ParmNbr_t S 10I 0 Based(TEMPLATE)
D Npm_Parm@_t S * Based(TEMPLATE)
D Npm_Data@_t S * Based(TEMPLATE)

/ELSE

D plist DS Likeds(Npm_ParmList_t)
D Based(plist@)
D dlist DS Likeds(Npm_DescList_t)
D Based(dlist@)
D opdesc DS Likeds(Npm_Desc_t)
D Based(opdesc@)
D parmnbr S Like(Npm_ParmNbr_t)
D parm@ S Like(Npm_Parm@_t)
D parmdata@ S Like(Npm_Data@_t)
D Based(parm@)

/ENDIF

As you can see, I have the /COPY statement twice in my program - once at the
top, in the global D-specs, (where it defines the API definition and the
global template variables), and then again inside any procedure which wants
to use it (where it defines the local variables based on the global template
variables). In the examples above, I didn't include the global definition
use of the /COPY.


On 3/8/2011 11:44 AM, hockchai Lim wrote:
Assuming that proc1 is an overloaded procedure of proc2. Proc1 contains
no
business logic. All it does is converting the parm1 into alpha and
calls
proc2. As you can see, both parameter 2& 3 in proc1& proc2 are
*nopass
and *omit type parameters. Can someone give me a pointer on best
approach
on calling proc2 from proc1?



D proc1 pr
D parm1 10p 0
D parm2 10 options(*nopass :*omit) const
D parm3 10 options(*nopass :*omit) const

D proc2 pr
D parm1 10
D parm2 10 options(*nopass :*omit) const
D parm3 10 options(*nopass :*omit) const


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:
Replies:

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.