× 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 2/19/2013 3:44 PM, sjl wrote:
Binding Source, with STRPGMEXP PGMLVL(*PRV) for previous versions ?

- sjl

I used to use *PRV signature blocks, but the practicality of one, never
changing, *CURRENT block has won me over.

"RPGLIST" wrote in message
news:mailman.16066.1361306316.10847.rpg400-l@xxxxxxxxxxxx...

Is there an easy way to avoid problems with signatures since we are
supposed to have the ability to add new modules to a service program that
will not require us to recompile all the objects that depend on that
service program.

I add new exports to my service programs all the time. Here's how I do it.

My service programs are made up of a single module. In that module are
all the sub-procedures I want that service program to have. Some of
those sub-procedures are intended for public consumption and are
exported from the service program. Some are meant to be internal 'work'
functions and remain private. The source for that module comes from a a
pair of source members; the PIs in QRPGLESRC and the PRs in QPROTOSRC.
The QPROTOSRC gets /COPY'd into every source member that needs one of
the public functions. The binder language is stored in another source
file called QSRVSRC. Every one of these source members has the same
name as the module which in turn has the same name as the service
program. There is a binding directory which points to the service
program. It all looks like this:

BUCK *SRVPGM
BUCK *MODULE
BUCK *BNDDIR

To create the module, I use PDM option 14 on QRPGLESRC, member BUCK.

QRPGLESRC mbr(BUCK)
QPROTOSRC mbr(BUCK)
QSRVSRC mbr(BUCK)

I saw a post by Rory Hewitt for a function that returns the procedure
name that fired a trigger. Here's what I do to add it to my service
program:

1) Edit BUCK/QRPGLESRC mbr(BUCK). Add the QWVRCSTK prototype. Internal
to this service program only.

// This /copy goes everywhere I need the PR blocks,
// including this service program
/copy qprotosrc,buck
...
* retrieve job stack
d qwvrcstk PR Extpgm('QWVRCSTK')
d RcvVar 65535a Options(*Varsize)
d RcvVarLen 10i 0 Const
d Format 8a Const
d JobIDInfo 65535a Const Options(*Varsize)
d JobIDFormat 8a Const
d ApiError Like(QUSEC)

...the wrapper for QWVRCSTK. Also private.

// simple QWVRCSTK algorithm, RPG only
d QWVRCSTK0100 pr
d library 10a
d program 10a
d module 10a
d proc 132a

...the implementation of the private wrapper.

p QWVRCSTK0100 b
d QWVRCSTK0100 pi
d library 10a
d program 10a
d module 10a
d proc 132a

...the public interface. It has a decent name and more error handling
than shown here.

p GetProcName b export
d GetProcName pi
d library 10a
d program 10a
d module 10a
d proc 132a

c/free
QWVRCSTK0100(library: program: module: proc);
/end-free
P E

2) Edit BUCK/QPROTOSRC mbr(BUCK). Add the prototype for the public
function.

*=====================================================================
* GetProcName(): Returns the full qualified name of the procedure.
*=====================================================================
d GetProcName PR
d library 10a
d program 10a
d module 10a
d proc 132a

3) Edit BUCK/QSRVSRC mbr(BUCK). Add the new function to the bottom of
the list of exports.

strpgmexp pgmlvl(*current) signature('Buck utilities')
export symbol("CLEANMBRNAME")
export symbol("LSTOBJLCK")
export symbol("SETDBGMODE")
export symbol("SCANCHARBAD")
export symbol(listSplf)
export symbol(lstDBFields)
export symbol(lstDBRecs)
export symbol(getProcName)
endpgmexp

4) CRTSRVPGM SRVPGM(BUCK)
MODULE(*SRVPGM)
EXPORT(*SRCFILE)
SRCFILE(BUCK/QSRVSRC)
SRCMBR(*SRVPGM)
ACTGRP(*CALLER)

The service program has the exact same signature it did before I made
the change. All of the existing callers run just fine because the order
of the exports was unchanged. A new one was added to the end, but since
none of the existing programs knows about it, they won't be trying to
call it and so cannot fall over.

To use the new function in a program:

1) Edit BUCK/QRPGLESRC mbr(TRIGGER). Add the prototype and the function
call.

h bnddir('BUCK')
...
/copy qprotosrc,buck
...
if trgStatus = 'Y';
callp(e) getProcName(callLib: callPgm: callMod: callPrc);
...

2) Compile with PDM option 14.

--buck

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.