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




Hello David,

You wrote:
>Maybe I'm missing something obvious ... is there a way to make RPG programs
>ignore signature violations in service programs?

Yes.  You can use binding source to force LVLCHK(*NO) which creates a
signature of zero.  However, like LVLCHK(*NO) on database files, doing so is
a truly stupid idea.  And since you must create binding source to set a zero
signature you might as well learn to use it properly.

There was a good discussion on binding source earlier this year.  Search the
archives.  However, read on ...

>I'm working on a bunch of service programs, and every time I add a
>procedure to my service program, I have to recompile all the callers.

I'll bet you are creating the service program with EXPORT(*ALL).  The
signature is calculated from the exported items -- procedures and data.  If
you cheat and use EXPORT(*ALL) when building the service program you will
get a new signature whenever you:
        o Add a new procedure
        o Add a new data item with EXPORT
        o Change the name of a procedure
        o Change the name of a data item with EXPORT
        o Change the order of exported procedures or data

A new signature will require that you recompile the calling programs and
service programs unless you manage the signature creation.

If you define and use binding source you are controlling the EXPORTed items
and therefore controlling the signature -- you can also specify the desired
signature explicitly.

You must create a member in source file to hold the binding source.  The
default source file is QSRVSRC and the default member has the same name as
the service program being created.

The binding source contains a STRPGMEXP command, one or more EXPORT
commands, and an ENDPGMEXP command.  Note that these commands are not
runnable -- they merely provide a convenient mechanism for defining things
(like a tag language).

The binding source may contain multiple groups of STRPGMEXP, EXPORT, and
ENDPGMEXP.  Each group is called an export block and defines a different
public interface and corresponding signature.

Here is a working example.  I design a service program called STRINGS which
will contain string handling functions.  I initially write three procedures
which will be publicly accessible (i.e., callable).  They are toUppercase(),
toLowercase(), and centre().  I may also have some support procedures which
I do not want exposed.  They are only for the use of the service program and
not to be invoked by any caller. Let us presume I have a getStringLength()
private procedure.

I define my public interface using binding source.

        STRPGMEXP  PGMLVL(*CURRENT)
        EXPORT     SYMBOL(toUppercase)
        EXPORT     SYMBOL(toLowercase)
        EXPORT     SYMBOL(centre)
        ENDPGMEXP

Note that the symbol can be a procedure name or a data item name.  Note also
that the procedure names used here are not enclosed in apostrophes which
means the will be interpreted as uppercase names.  That is OK because my
service program is written in RPG IV which is not case sensitive.  If I were
writing the service program in C then I must ensure the symbol name is
exactly the same as the name in the module and use apostrophes as
appropriate.  Also note that the getStringLength() function is not mentioned
in the binding source.

There is a tool in QUSRTOOL called GENBNDSRC which is useful for creating
the first set of binding source but since it insists on sorting the EXPORT
statements is completely bloody useless for subsequent changes.

If I store the binding source in member STRINGS in file QSRVSRC then when I
create my service program the binding source will be processed
automatically.

I compile the programs that use these string functions and life in the IT
department grinds slowly on.

Some time later I discover the need for an additional string function for a
new program I am creating.  I need a SOUNDEX function so I write one and add
it to my STRINGS service program.  I need to make the getSoundex() function
part of the public iterface.  If I simply add it to the existing export
block then I will create a new current signature thus breaking any existing
programs that use STRINGS.  I must follow certain steps to ensure I don't
break things.

I edit the binding source and I duplicate the export block and change one of
the blocks to PGMLVL(*PRV).  I then add my new procedure the end of the
*CURRENT block.

        STRPGMEXP  PGMLVL(*CURRENT)
        EXPORT     SYMBOL(toUppercase)
        EXPORT     SYMBOL(toLowercase)
        EXPORT     SYMBOL(centre)
        EXPORT     SYMBOL(getSoundex)
        ENDPGMEXP

        STRPGMEXP  PGMLVL(*PRV)
        EXPORT     SYMBOL(toUppercase)
        EXPORT     SYMBOL(toLowercase)
        EXPORT     SYMBOL(centre)
        ENDPGMEXP

Any new procedures MUST, repeat MUST go at the end of the current block.
(The real code can go anywhere in the service program itself.)

Now when I create the STRINGS service program it gets two signatures
created.  A current one used by any new programs I compile, and a previous
one which mathces the one used by the existing programs.  Magic happens!
Any existing programs that use STRINGS see the previous signature and thus
the previous view of the service program exports.

The ILE Concepts manual has a very good discussion on this stuff. You should
read it thoroughly before creating binding source.

It is also possible to define your own signature.

        STRPGMEXP  PGMLVL(*CURRENT) SIGNATURE('MY_SIG')
        EXPORT     SYMBOL(toUppercase)
        EXPORT     SYMBOL(toLowercase)
        EXPORT     SYMBOL(centre)
        ENDPGMEXP

This is a little dangerous because the system will assume I know what I am
doing but it does allow me to be a little more flexible in building a
service program in increments.  Let us presume I am building the STRINGS
service program in stages.  My first build use the binding source in the
previous paragraph.  Other developers start using it.  I then add the
SOUNDEX function.  I don't want another signature because, conceptually, the
SOUNDEX function is part of the current version of the service program.  I
change the binding source as follows:

        STRPGMEXP  PGMLVL(*CURRENT) SIGNATURE('MY_SIG')
        EXPORT     SYMBOL(toUppercase)
        EXPORT     SYMBOL(toLowercase)
        EXPORT     SYMBOL(centre)
        EXPORT     SYMBOL(getSoundex)
        ENDPGMEXP

This has the same effect as the first example but only one signature was
created.  I am accepting the responsibility for ensuring that the exports
are in the correct order rather than the system (this is similar to having a
zero signature but much more flexible).

If I am careless and I define the binding source as

        STRPGMEXP  PGMLVL(*CURRENT) SIGNATURE('MY_SIG')
        EXPORT     SYMBOL(getSoundex)
        EXPORT     SYMBOL(toUppercase)
        EXPORT     SYMBOL(toLowercase)
        EXPORT     SYMBOL(centre)
        ENDPGMEXP

then I have just broken all existing programs that use STRINGS.  When an
existing program calls toUppercase() it will actually invoke getSoundex().
When it invokes toLowercase() it wil actually invoke toUppercase().  Oops!

Sometimes this behaviour is useful.  The ILE Concepts manual has an example
showing how to change a rate calculation function for new programs but not
upset existing programs.  I wouldn't do this sort of thing the way that
manual describes but it is interesting in an illustrative way.

One last example.  The literate among you will have noticed that I spell
centre the correct way.  However my cousins (thrice removed) in the American
branch office would spell it center thus my service program will drive them
insane by generating binding errors telling them the center procedure cannot
be found.  One solution would be to use an RPG IV prototype to map center()
to centre().  A similar thing could be done for C.  However, that doesn't
help COBOL programmers.  So I add a new procedure to STRINGS called center()
which simply invokes centre() to do the real work.  I update the binding
source accordingly.

        STRPGMEXP  PGMLVL(*CURRENT)
        EXPORT     SYMBOL(toUppercase)
        EXPORT     SYMBOL(toLowercase)
        EXPORT    SYMBOL(centre)
        EXPORT     SYMBOL(getSoundex)
        EXPORT     SYMBOL(center)
        ENDPGMEXP

        STRPGMEXP  PGMLVL(*PRV)
        EXPORT     SYMBOL(toUppercase)
        EXPORT     SYMBOL(toLowercase)
        EXPORT     SYMBOL(centre)
        EXPORT     SYMBOL(getSoundex)
        ENDPGMEXP

        STRPGMEXP  PGMLVL(*PRV)
        EXPORT     SYMBOL(toUppercase)
        EXPORT     SYMBOL(toLowercase)
        EXPORT     SYMBOL(centre)
        ENDPGMEXP

Do you see the process?  It is quite straightforward if you follow the
rules.  Now, everyone is happy.  Although given the atrocious spelling of
most programmers they are just as likely to spell centre both ways in any
given program.

Binding source does not help with parameter interface changes.  One can only
hope that will be a future extension.  It would be really good to have
overloaded procedures and use binding source to define the parameter types
and number.  Until then we must content ourselves with OPTIONS(*NOPASS) or
*OMIT for extending parameter lists and resign ourselves to the fact that we
can't pass different data types in the same parameter via prototyped calls.

Regards,
Simon Coulter.

«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»
«» FlyByNight Software         AS/400 Technical Specialists       «»
«» Eclipse the competition - run your business on an IBM AS/400.  «»
«»                                                                «»
«» Phone: +61 3 9419 0175   Mobile: +61 0411 091 400        /"\   «»
«» Fax:   +61 3 9419 0175   mailto: shc@flybynight.com.au   \ /   «»
«»                                                           X    «»
«»               ASCII Ribbon campaign against HTML E-Mail  / \   «»
«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»


As an Amazon Associate we earn from qualifying purchases.

This thread ...


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.