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



The "Sorcerers Guide" Redbook covers procedures, converting from
subroutines to sub-procedures, and a whole boatload of other stuff
related to moving to RPGIV.

http://www.redbooks.ibm.com/abstracts/sg245402.html

In this case .. put prototypes into a separate member, and /COPY that
member into the source with the procedure AND into the source where
the procedure is being used.  So the prototype does only exist once.

Take care.

On Wed, 8 Dec 2004 11:22:18 -0600, Bob Cozzi <cozzi@xxxxxxxxx> wrote:
> Duane,
> 
> Conventionally you need to have two solutions:
> 
> 1) If a procedure is local to the module and is not EXPORTed then the
> prototype is still required and can be "hard coded" in the global D spec
> area of the source member. No "copybook" is required.
> 
> 2) If a procedure is going to be used anywhere outside of the module in
> which it is implemented, then the prototype should be placed into a /COPY
> member and /COPY'd into both the original implementation module and any
> other program/module that has a call to that procedure.
> 
> I've seen another situation where someone illustrated how to use the same
> source code to contain the implementation of the procedure and the
> prototype, then depending on the result of /IF DEFINE statements, the
> prototype XOR the entire source member was included.
> -Hated that one too.
> 
> My opinion is that you should standardize on the above two styles. Don't try
> to get too creative with other techniques because it will only confuse
> people more. Having written hundreds of thousands of lines of C and C++
> code, I can tell you, these two methodologies are the only ones I've seen
> being used to any extent.
> 
> -Bob Cozzi
> 
> 
> 
> 
> -----Original Message-----
> From: rpg400-l-bounces@xxxxxxxxxxxx [mailto:rpg400-l-bounces@xxxxxxxxxxxx]
> On Behalf Of Christen, Duane J.
> Sent: Wednesday, December 08, 2004 11:04 AM
> To: 'RPG programming on the AS400 / iSeries'
> Subject: Procedure interfaces and prototypes
> 
> I got this question from an associate today, I thought I would pass it and
> my answer along for everyone:
> 
> Okay. I need advice...
> 
> "The procedure interface should be defined directly in the procedure, not
> through a copybook. The compiler uses the prototype to verify that the
> procedure interface is correct and is also used by the compiler to verify
> that the calling program is calling the procedure correctly. If the
> procedure and the calling programs use the same prototype from the copybook
> they will always be right."
> 
> I get this, and I get that it is the way MOST RPGers handle it.  But I don't
> 
> understand it entirely, because it means interface vars have to be
> maintained in TWO places, once in the copybook and again for the procedure
> interface.  If, on the other hand, your copybook contains JUST the parm
> definitions, that code can be included in all THREE locations, in calling
> and called code (including PI defs).  This eliminates dual maintenance.  I
> know everyone says the PI should never be changed, but get real--what do you
> think?????
> 
> My response Below:
> The statement "The procedure interface should be defined directly in the
> procedure, not
> through a copybook." is wrong, and right.
> 
> It is wrong if the procedure is to be a global procedure, available to be
> imported into any program/sp/module.
> 
> It is correct if the procedure is to be local to the program/sp/module.
> 
> Lets say we have a math service program, SPMATH. In this math SP we have
> some functions that other people need to access, these functions are:
> add1ToVar, add2ToVar, multiplyVarBy10.
> add1ToVar is in module MODA, it is exported from MODA and calls a procedure
> getVarValue.
> add2ToVar is in module MODB, it is exported from MODB and calls a procedure
> getVarValue.
> multiplyVarBy10 is in module MODC, it is exported from MODC and calls a
> procedure getVarValue, it also calls a procedure multiplyVar.
> multiplyVar is also in MODC, it is NOT exported from MODC. (It is not called
> by any other procedure except multiplyVarBy10)
> getVarValue is in MODX, it is exported from MODX. (It is called by many of
> the math procedures, but it should only be called from math procedures in
> SPMATH)
> 
> This is how I would put it together:
> SPMATH exports add1ToVar, add2ToVar, and multiplyVarBy10. In other words the
> binding source for SPMATH contains something like this:
> STRPGMEXP  PGMLVL(*CURRENT)
> EXPORT     SYMBOL(ADD1TOVAR)
> EXPORT     SYMBOL(ADD2TOVAR)
> EXPORT     SYMBOL(MULTIPLYVARBY10)
> ENDPGMEXP
> 
> This makes the procedures add1ToVar, add2ToVar, and multiplyVarBy10 global,
> available to be imported into any program/sp/module.
> 
> The copybook for SPMATH would contain prototypes for the procedures
> add1ToVar, add2ToVar, and multiplyVarBy10 and would be /COPYed or /INCLUDEd
> in any program/sp/module that needed to import them. (Including the modules
> that export them)
> 
> Even though getVarValue is local to the service program it must be exported
> from the module MODX, but it is not exported from the sp SPMATH because it
> is not listed in the binding source so the modules MODA, MODB, MODC and MODX
> would contain a copy of prototype for getVarValue, I would not have this
> prototype in a copybook because it is local to the sp SPMATH.
> 
> The module MODC would contain the only prototype for the multiplyVar, and it
> would not be exported from the module because it is local to the module,
> only used by the procedures in MODC.
> 
> The procedure interface is a seperate entity from the prototype and CAN NOT
> be in a copybook. If a procedure is designed correctly the interface, and
> the related prototype should not change.
> 
> If it is necessary to change a procedure interface the change can be
> implemented so that it does not impact any existing code. Lets say this
> procedure, PROCA, is defined like this:
> 
> Prototype in a copybook:
> procA           PI
>                         10A   Value
>                         10P 0   Value
> 
> Procedure interface:
> procA           PI
> field1          10A   Value
> field2          10P 0   Value
> 
> Then lets say that we need to have another parameter field3, the interface
> then would look like this:
> 
> Prototype in a copybook:
> procA           PI
>                         10A   Value
>                         10P 0   Value
>                          5I 0   Value Options(*NOPASS)
> 
> Procedure interface:
> procA           PI
> field1          10A   Value
> field2          10P 0   Value
> field3           5I 0 Value Options(*NOPASS)
> 
> In the code for the procedure PROCA you would have something like this:
> 
> If      %Parms = 3
>         field3Value = field3
> Else
>         field3Value = 0
> EndIf
> 
> What this does is: if 3 parameters were passed into the procedure then the
> variable field3Value, which is used throughout the procedure, is set to the
> value passed into the procedure. Otherwise the variable field3Value is set
> to a default value which will be used throughout the procedure.
> 
> Ok so now lets do one a little more complicated, lets say we now need to
> extend the parameter field1 from 10A to 20A, there are a couple of ways to
> do this but they are all ugly, this is the way I would do it:
> 
> Prototype in a copybook:
> procA           PI
>                         10A   Value
>                         10P 0   Value
>                          5I 0   Value Options(*NOPASS)
>                         20A   Value Options(*NOPASS)
> 
> Procedure interface:
> procA           PI
> field1          10A   Value
> field2          10P 0   Value
> field3           5I 0 Value Options(*NOPASS)
> field4          20A     Value Options(*NOPASS)
> 
> In the code for the procedure PROCA you would have something like this:
> 
> If      %Parms >= 3
>         field3Value = field3
> 
> If      %Parms = 4
>         field1Extended = field4
> EndIf
> Else
>         field3Value = 0
>         field1Extended = field1
> EndIf
> 
> What this does is: if 3 or more parameters were passed into the procedure
> then the variable field3Value, which is used throughout the procedure, is
> set to the value passed into the procedure. If 4 parameters were passed then
> the variable field1Extended, which is used throughout the procedure, is set
> to the value passed in for the longer field1 value. Otherwise the variable
> field3Value is set to a default value which will be used throughout the
> procedure and field1Extended is set to the field1 value.
> 
> This may seem rather ridiculus, and it is, but this is an example of poor
> interface planning and I have done things like this in the past, some even
> more rediculus.
> 
> If you are sure, and I mean SURE that the interface will not change then
> passing individual parameters like this will work just fine for the
> procedure, but if you are not sure or you know that in the future there will
> be the need to "add" capabilities to the procedure then you need to designe
> a flexable interface like this:
> 
> getCustomerInfo...
>                 PI
> infoBase                  *     Value
> infoFormat              10A     Value
> infoLength              10I 0   Value
> keyBase           *     Value
> keyFormat               10A     Value
> keyLength               10I 0   Value
> 
> We can talk about this later, I need to get back to work now.
> 
> Duane Christen
> 
> NOTICE: This electronic mail transmission may contain confidential
> information and is intended only for the person(s) named.  Any use, copying
> or disclosure by any other person is strictly prohibited. If you have
> received this transmission in error, please notify the sender via e-mail.
> 
> --
> This is the RPG programming on the AS400 / iSeries (RPG400-L) mailing list
> To post a message email: RPG400-L@xxxxxxxxxxxx
> To subscribe, unsubscribe, or change list options,
> visit: http://lists.midrange.com/mailman/listinfo/rpg400-l
> or email: RPG400-L-request@xxxxxxxxxxxx
> Before posting, please take a moment to review the archives
> at http://archive.midrange.com/rpg400-l.
> 
> --
> This is the RPG programming on the AS400 / iSeries (RPG400-L) mailing list
> To post a message email: RPG400-L@xxxxxxxxxxxx
> To subscribe, unsubscribe, or change list options,
> visit: http://lists.midrange.com/mailman/listinfo/rpg400-l
> or email: RPG400-L-request@xxxxxxxxxxxx
> Before posting, please take a moment to review the archives
> at http://archive.midrange.com/rpg400-l.
> 
> 


-- 
Tom Jedrzejewicz
tomjedrz@xxxxxxxxx

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.