Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Recursive calls in rpgle

1,001 views
Skip to first unread message

tmnelson

unread,
Dec 13, 2001, 4:24:28 PM12/13/01
to
I'm currently working on a project where it would be nice to be abe to
recursively call a program in sqlrpgle. Upon attempting this I receive an
error 'pgm was called recursively'. Is there anyway to do recursive calls in
rpg or doesn't the language allow this?


John Smith

unread,
Dec 13, 2001, 6:35:24 PM12/13/01
to
I've done this in COBOL by calling a CL Program that creates a duplicate
object (CRTDUPOBJ) of the program (in QTEMP) and then calls the program. If
you have to call the program multiple time to can name the object with the
time by appending the time to your object name.

eg
RTVSYSVAL QTIME &TIME
CHGVAL &OBJ ('PGM' || &TIME)
CRTDUPOBJ OBJ(MYLIB/MYPGM) OBJTYPE(*PGM) TOLIB(QTEMP) TOOBJ(&OBJ)
CALL QTEMP/&OBJ


"tmnelson" <tmne...@gfgfs.com> wrote in message
news:i29S7.447$km1.1...@news.uswest.net...

SJ Lennon

unread,
Dec 13, 2001, 7:45:26 PM12/13/01
to
H DFTACTGRP(*NO) ACTGRP(*NEW)

This should start the program in a new activation group each time.
Note, however, that you need to think about the scope of overrides if
you have any.

Sam

"tmnelson" <tmne...@gfgfs.com> wrote in message
news:i29S7.447$km1.1...@news.uswest.net...

SASchollen

unread,
Dec 13, 2001, 11:43:30 PM12/13/01
to
ACTGRP(*NEW) will work but creating a new activiation group with each recursive
call could result in unacceptable performance.

Subprocedures can be called recursively.

Could you implement the recursion within a subprocedure rather than
the whole program?

Barbara Morris

unread,
Dec 14, 2001, 1:54:26 PM12/14/01
to
Doing the recursion within the subprocedure would be ideal, but if a
program is needed for some reason, you could have a program with a ILE
CL module and an ILE RPG module, where the CL just does a CALLPRC to the
RPG subprocedure, passing through any parameters (you can declare all
the parameters simply as *char 1 in the CL).

Normally with recursion, static variables are the same for each
recursive invocation. This is the way subprocedure recursion works:
global variables (including files that are open in the module) and local
variables declared with STATIC are shared by the invocations; each
invocation gets its own copy of local automatic variables. When you use
actgrp(*new) to get recursion, there are no shared variables.

kaushal...@gmail.com

unread,
Feb 24, 2017, 8:20:19 AM2/24/17
to
Hey Barbara,
I always follow your replies and get help in my RPGLE tasks.

Now I am stuck in a weird situation. These are RPGILE programs.

=> Pgm1 calls Pgm2

=> Pgm2 calls Pgm3.

Now, I need to call Pgm2 (already in stack) inside Pgm3. But failing due to recursive call. I cant change the Activation group to *New .

Can I somehow remove the Pgm2 from Call stack (I am sure there will be no impact if we remove pgm2 from stack. Pgm2 is no longer required as soon as
Pgm3 is Called).

Due to existing code (10,000+ lines) complexities I cant re-structure all in to Procedures due to various reasons.

Please help me / Guide me. Thanks in advance.

Kaushal

Stéphane

unread,
Feb 24, 2017, 1:43:56 PM2/24/17
to
Le 24/02/2017 à 14:20, kaushal...@gmail.com a écrit :
> Hey Barbara,
> I always follow your replies and get help in my RPGLE tasks.
>
> Now I am stuck in a weird situation. These are RPGILE programs.
>
> => Pgm1 calls Pgm2
>
> => Pgm2 calls Pgm3.
>
> Now, I need to call Pgm2 (already in stack) inside Pgm3.
> But failing due to recursive call.
> I cant change the Activation group to *New .
>
> Can I somehow remove the Pgm2 from Call stack (I am sure there will be no impact
> if we remove pgm2 from stack. Pgm2 is no longer required as soon as
> Pgm3 is Called).
>
> Due to existing code (10,000+ lines) complexities I cant re-structure all
> in to Procedures due to various reasons.
>
> Please help me / Guide me. Thanks in advance.
>
> Kaushal

You have to copy pgm2 in qtemp before pgm3 call's and remove it after
call. Use a clp to perfom copy, call and dltpgm

CRPence

unread,
Apr 30, 2017, 11:10:24 AM4/30/17
to
On 24-Feb-2017 11:43 -0700, Stéphane wrote:
> Le 24/02/2017 à 14:20, kaushal...@gmail.com a écrit :
>> […] I am stuck in a weird situation. These are RPGILE programs.
>>
>> => Pgm1 calls Pgm2
>> => Pgm2 calls Pgm3
>>
>> Now, I need to call Pgm2 (already in stack) inside Pgm3.
>> But failing due to recursive call.
>> I can't change the Activation group to *New.
>>
>> Can I somehow remove the Pgm2 from Call stack (I am sure there will
>> be no impact if we remove pgm2 from stack. Pgm2 is no longer
>> required as soon as Pgm3 is Called).
>>
>> Due to existing code (10,000+ lines) complexities I cant
>> re-structure all into Procedures due to various reasons.
>>
>> Please help me / Guide me. Thanks in advance.
>>
>
> You have to copy Pgm2 in QTEMP before Pgm3 calls and remove it
> after call. Use a CLP to perform copy, call and DLTPGM

Not a good idea; a very bad idea, IMO. The process will terminate
when the Pgm3 effects actual or effective RETURN to Pgm2; i.e. the
"return" would be [in]to a destroyed object, and the effect is known to
be process termination.

--
Regards, Chuck

CRPence

unread,
Apr 30, 2017, 11:28:10 AM4/30/17
to
On 24-Feb-2017 06:20 -0700, kaushal...@gmail.com wrote:
> […] I am stuck in a weird situation. These are RPGILE programs:
>
> => Pgm1 calls Pgm2
> => Pgm2 calls Pgm3
>
> Now, I need to call Pgm2 (already in stack) inside Pgm3. But failing
> due to recursive call. I can't change the Activation group to *New.
>
> Can I somehow remove the Pgm2 from Call stack (I am sure there will
> be no impact if we remove pgm2 from stack. Pgm2 is no longer
> required as soon as Pgm3 is Called).
>
> Due to existing code (10,000+ lines) complexities I can't
> re-structure all in to Procedures due to various reasons.
>

One possibility [as a kludge; an untested SWAG], within the
restrictions for the use of Scope Message handling:

Declare a condition handler in the Pgm2, in which a RETURN is the
response to the monitored condition, but only after sending a scope
message within Pgm2 for *PGM [or *CSE] to request the invocation of the
Pgm3 after Pgm2 is no longer on the stack. Change Pgm3 to signal the
condition from Pgm3 to Pgm2 when the error condition "recursion
disallowed" occurs in Pgm3.

--
Regards, Chuck

binaw...@gmail.com

unread,
May 1, 2017, 8:06:01 PM5/1/17
to
If you only ever require Pgm1 calls Pgm2, Pgm2 calls Pgm3 and then Pgm3 calls Pgm2 then you could simply compile Pgm2 to both Pgm2 and Pgm2B and then modify Pgm3 to call Pgm2B. Yes, untidy,... if you need to modify since you have to remember to do two compiles,... however you can add a highlighted comment in the source,...

Otherwise the duplicate to QTEMP is the simplest and easiest method. If this needs to be more dynamic you could use API QWVRCSTK to check the program stack and then create the next Pgm2 required and create Pgm201, Pgm202, Pgm203... Return the program to be called to the calling program, (so Pgm1 calls Pgm2Chk, returns Pgm201 and Pgm1 calls Pgm201 which then calls Pgm3. Pgm3 calls Pgm2Chk, returns Pgm202 and Pgm3 calls Pgm202,... until you hit 99!). There is no need to delete the QTEMP objects as they will be cleaned up when the job ends. Use CHKOBJ prior to CRTDUPOBJ and only duplicate if does not exist.

Regards, Mal
0 new messages