With all due respect, this has nothing to do with service programs. If you did the same thing with dynamic program calls in RPG III, you'd have the same problem.

Now say you have the same scenario you described, except you're using *PGMs instead of *SRVPGMs. So you have a PGM1 (to replace mod1, proc1 from your example) , PGM2 (to replace mod2, proc1), PGM22 (replaces mod2, proc2) and PGM3.

To make sure you use the parameters consistently, you create the following copy book:

C PLIST2 PLIST
C PARM PARM1 90
C PARM PARM2 14
C PLIST22 PLIST
C PARM PARM3 50
C PARM PARM4 10
C PLIST3 PLIST
C PARM PARM5 12
C PARM PARM6 25

Just as in your example, PGM1 calls PGM2. PGM2 calls PGM22. PGM22 calls PGM3. You decide to modify PGM3 to accept a data structure. So you change the PLIST3 in the above copy book to look like this:


C PLIST3 PLIST
C PARM PARM5 12
C PARM PARM6 25
C PARM MYDS


Then, in PGM22 you code it like this:

IMYDS DS
I 1 4 FLD1
I 5 14 FLD2
/COPY copybook
C CALL 'PGM3' PARM3

It causes the exact same problem. PGM1 will no longer compile because it uses the same copybook, and doesn't have the definition for MYDS. The problem has nothing whatsoever to do with whether you use a service program or RPG IV or anything.

The problem is that you've defined a parameter list (prototype) that DEPENDS ON the definition of a data structure. In other for programs to use those definitions, the definition for that data structure MUST be available in all programs that use the copy book.

Indeed, the fact that it's a data structure really doesn't matter -- you could've had the same problem with any the PARM1, PARM2, etc definitions as if you hadn't coded the definition right there on the PARM statement (above).

The solution, in all cases, is to have the definition of the variables be a PART OF THE COPY BOOK. That's the whole point behind using the copy book in the first place is to guarantee that all callers use the same definitions! If you require the callers to define some of the parameters internally, then you're defeating the purpose of using a copy book to begin with. In my RPG III example, if every program that calls PGM3 defines MYDS differently, then I really haven't accomplished my goal of forcing all callers to use the same parameters, have I? The same is true in RPG IV -- when your callers call a prototype with parameters based on a LIKE or LIKEDS keyword, then DON'T LET THOSE CALLERS SUPPLY THE DEFINITION FOR THE OBJECT THAT LIKE REFERENCES... otherwise, each caller is (once again) defining it's own parameters. Just like the RPG III example..

The difference between RPG III and RPG IV here is that RPG III doesn't really have a mechanism to allow MYDS to be included in the copy book. Since MYDS belongs in the I-specs, and the PLISTS belong in the C-specs, you can't really use a copy book to define them both -- You'd have to use two separate copy books, one for I-specs and one for C-specs, which is cumbersome.

Worse, the definitions in the RPG III copy book are actual variable definitions -- they take up memory and can easily cause name conflicts. RPG IV's prototypes don't have this problem.

Anyway, the solution is simple. Create a template data structure and put it in your copy book so that the parameter that uses LIKEDS() can refer to another definition in the copy book instead of referring to something outside of the copy book.

Change the code for all callers to define their local copies of the DS with LIKEDS against the one in the prototype so that the DS definition is only specified once.

in copy book, do something like this:

D Order_Address_t...
D ds qualified
D based(Template)
D Name 30a
D Addr1 30a
D Addr2 30a
D addr3 30a

D Order_GetShipAddr...
D pr 1n
D OrderNo 10a const
D ShipTo likeds(Order_Address_t)


Now anyone who uses that copybook will have the definition for both Order_address_t as well as the prototype! Then, they can call it like this:

/copy ORDER_H
D ShipTo ds likeds(Order_address_t)
.
.
if (Order_GetShipAddr('12345': ShipTo) = *OFF);
// handle error
endif;

It's really easy, and it solves problems.


David FOXWELL wrote:

-----Message d'origine-----
De : David FOXWELL
Envoyé : mercredi 27 février 2008 14:54
À : 'Websphere Development Studio Client for iSeries'
Objet : Service programs suck

Hi everyone,

We have this problem with 1 procedure that calls another that calls another :


Module 1 Procedure 1 calls Module 2 Procedure 1.
Module 2 Procedure 2 calls Module 3 Procedure 1.

Module 3 Procedure 1 gets the following modification : a parameter M3P1Parm that is a DS declared LIKE another DS in the same module. Module 2 Procedure 2 is modified accordingly.

Module 3 is recompiled, no problem.
Module 2 is recompiled, the compiler imports the protoypes of all the exported procedures of Module 3 with the definition of M3P1Parm, again no problem.
Module 1 is recompiled, the compiler imports the protoypes of all the exported procedures of Module 2 : Procedure 1 that is uses, and Procedure 2 that it doesn't - PROBLEM, it doesn't know what is M3P1Parm.


Bigger problem : the policy is to systematically compile ALL the modules that use the module modified. I realise that probably raises a few eyebrows but that's the way things are!

Now, I am asked what I think of this way round the problem :

If an exported procedure contains a DS as a parameter then that procedure must have its own module.

I suggest that Module 2 should be a service program and that Module 1 would not have to be recompiled.
I am reminded that we do not use service programs as they use dynamic calls and that would mean the same as going back to RPGIII.

Any enlightenment would be greatly appreciated.


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.