× 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 28/02/2008, at 9:47 PM, David FOXWELL wrote:

Thanks Scott and everyone else but I think I have been misunderstood.
I apologise for not being clear enough.

I read your original append in the same way as the others therefore did not respond when I saw it had been answered adequately.


The DS IS declared with a copy book as you advise, Scott in Module 3.

Module 2 pulls in this declaration like this :
/DEFINE COPY_PROTOTYPE
D/COPY QRPGLESRC,MODULE3
/UNDEFINE COPY_PROTOTYPE

Why do you do this rubbish? If a module needs prototypes just /copy them. What is the point of the /DEFINE and /UNDEFINE rubbish? The consumer should simply include what it needs. The copy member itself should have
/IF NOT DEFINED(this-include)
/DEFINE this-include
definitions
prototypes
etc.
/ENDIF

That will stop multiple definitions appearing in the same module.


This copies all the prototype definitions of exported procedures in module 3 like this :

* Exported procedures.
D Module3_procedure1 PR
D A_DS LIKE ( MyDS )

/COPY MYDS

D Module3_procedure2 PR
/IF DEFINED (COPY_PROTOTYPE)
/EOF
/ENDIF

* Non exported procedures.
D Module3_procedure3 PR


So when we need to call an exported procedure, unfortunately we end up with the protoypes of ALL the exported procedures, not just those that are used.

So? Why are you concerned about prototypes being included? They don't affect performance of the application (but they do affect the performance of the COMPILER due to additional source to process but unless huge copy members you are unlikely to notice).

Now, you can see module 2 will also have the DS declared in module 3.

So? It needs the definition so it can successfully compile the prototypes that reference it.


Module 1 will pull in all the prototypes for Module 2 like this :
/DEFINE COPY_PROTOTYPE
D/COPY QRPGLESRC,MODULE2
/UNDEFINE COPY_PROTOTYPE

Again with this rubbish.


In the code imported, we get the procedures exported from module 2
+D Module2_procedure1 PR

+D Module2_procedure2 PR
+D A_DS LIKE ( MyDS )DS

Procedure 2 is not used but imported all the same.

Not imported. Simply defined. You will need to make MyDS available to successfully compile. If you are concerned about storage allocation then make it BASED in the copy member (at least until RPG gets TYPEDEF support)

Module 1 will not compile because MyDS is not declared.

This is entirely due to the way you do things. If the prototype for Module 3 procedures requires the definition of the MyDS structure then it should be defined or copied into the Module 3 copy member. You should not require the consumer to include the prototypes and also include the data definitions. The caller should just do

/COPY MOD3PROTO

or whatever you call it--hopefully something better than that

MOD3PROTO should have the prototypes defined and /COPY MYDS or MYDS should be defined directly in MOD3PROTO.


I realize there is a problem perhaps with the way we import our prototype definitions.

Yes, exactly!


I'd be interested to know how others include these definitions.

-----Message d'origine-----
De : midrange-l-bounces@xxxxxxxxxxxx [mailto:midrange-l- bounces@xxxxxxxxxxxx] De la part de Scott Klement
Envoyé : mercredi 27 février 2008 20:17
À : Midrange Systems Technical Discussion
Objet : Re: Service programs suck

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.

--
This is the Midrange Systems Technical Discussion (MIDRANGE-L) mailing list To post a message email: MIDRANGE-L@xxxxxxxxxxxx To subscribe, unsubscribe, or change list options,
visit: http://lists.midrange.com/mailman/listinfo/midrange-l
or email: MIDRANGE-L-request@xxxxxxxxxxxx Before posting, please take a moment to review the archives at http://archive.midrange.com/ midrange-l.

--
This is the Midrange Systems Technical Discussion (MIDRANGE-L) mailing list
To post a message email: MIDRANGE-L@xxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit: http://lists.midrange.com/mailman/listinfo/midrange-l
or email: MIDRANGE-L-request@xxxxxxxxxxxx
Before posting, please take a moment to review the archives
at http://archive.midrange.com/midrange-l.



Regards,
Simon Coulter.
--------------------------------------------------------------------
FlyByNight Software OS/400, i5/OS Technical Specialists

http://www.flybynight.com.au/
Phone: +61 2 6657 8251 Mobile: +61 0411 091 400 /"\
Fax: +61 2 6657 8251 \ /
X
ASCII Ribbon campaign against HTML E-Mail / \
--------------------------------------------------------------------




As an Amazon Associate we earn from qualifying purchases.

This thread ...

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.