Topic
  • 4 replies
  • Latest Post - ‏2012-08-28T15:09:41Z by JonParis
scjt2001
scjt2001
18 Posts

Pinned topic WRKMBRPDM UIM panels

‏2012-08-14T14:54:34Z |
How does WRKMBRPDM allows calling WRKMBRPDM from command line with out any recursively call problem, i am writing a utility using UIM panels which allows command line, but i am not able to call itself from the command line.
Updated on 2012-08-28T15:09:41Z at 2012-08-28T15:09:41Z by JonParis
  • barbara_morris
    barbara_morris
    420 Posts

    Re: WRKMBRPDM UIM panels

    ‏2012-08-14T15:34:58Z  
    It is only RPG that disallows recursion, at least by default. The system supports recursion in general.

    Even ILE RPG supports recursion. For ILE RPG, only the cycle main procedure doesn't support recursion. Subprocedures and linear main procedures can be called recursively. To define a linear main procedure, code the MAIN keyword on the H spec to identify the main procedure, and then code the main procedure using P specs like any subprocedure. Move your program logic into the linear main procedure.

    Another way to allow your programs to be called recursively is to change your RPG so that the logic is in ordinary subprocedures in a NOMAIN module. Then add a CLLE module that calls your RPG subprocedures.

    Say this is your RPG program, TESTPGM:
    
    D testpgm         pi                  extpgm(
    'TESTPGM') D   what                         1a   
    
    const D qcmd            pr                  extpgm(
    'QCMD') /free 
    
    if %parms() > 0 and what = 
    'C'; dsply (
    'calling QCMD, parm ' + what); qcmd (); dsply (
    'returned from QCMD'); endif; 
    
    return;
    

    Here is the linear main version, TESTPGMLM:
    
    H main(testpgmlm) P testpgmlm       b D testpgmlm       pi                  extpgm(
    'TESTPGMLM') D   what                         1a   
    
    const D qcmd            pr                  extpgm(
    'QCMD') /free 
    
    if %parms() > 0 and what = 
    'C'; dsply (
    'calling QCMD, parm ' + what); qcmd (); dsply (
    'returned from QCMD'); endif; 
    
    return; /end-free P testpgmlm       e
    

    Here is the NOMAIN version TESTPGMNM:
    
    H nomain P testpgmnm       b                   export D testpgmnm       pi D   what                         1a   
    
    const D qcmd            pr                  extpgm(
    'QCMD') /free 
    
    if %parms() > 0 and what = 
    'C'; dsply (
    'calling QCMD, parm ' + what); qcmd (); dsply (
    'returned from QCMD'); endif; 
    
    return; /end-free P testpgmnm       e
    

    And the CLLE wrapper TESTPGMNMC:
    
    pgm parm(&what) dcl &what type(*
    
    char) len(1) callprc TESTPGMNM parm(&what)
    


    My session:
    
    3 > 
    /* ------------------- */ 3 > 
    /* ----- TESTPGM ----- */ 3 > 
    /* ------------------- */ 3 > call testpgm 
    'C' DSPLY  calling QCMD, parm C 4 > call testpgm 
    'R' TESTPGM was called recursively. Application error.  RNX8888 unmonitored by TESTPGM at statement *N, instruction X
    '0000'. End of requests. DSPLY  returned from QCMD 3 > 
    /* ------------------------------- */ 3 > 
    /* ----- testpgm linear main ----- */ 3 > 
    /* ------------------------------- */ 3 > call testpgmlm 
    'C' DSPLY  calling QCMD, parm C 4 > call testpgmlm 
    'N' End of requests. DSPLY  returned from QCMD 3 > 
    /* ------------------------ */ 3 > 
    /* ----- clle wrapper ----- */ 3 > 
    /* ------------------------ */ 3 > call testpgmnmc 
    'C' DSPLY  calling QCMD, parm C 4 > call testpgmnmc 
    'N' End of requests. DSPLY  returned from QCMD
    
  • scjt2001
    scjt2001
    18 Posts

    Re: WRKMBRPDM UIM panels

    ‏2012-08-14T17:39:42Z  
    It is only RPG that disallows recursion, at least by default. The system supports recursion in general.

    Even ILE RPG supports recursion. For ILE RPG, only the cycle main procedure doesn't support recursion. Subprocedures and linear main procedures can be called recursively. To define a linear main procedure, code the MAIN keyword on the H spec to identify the main procedure, and then code the main procedure using P specs like any subprocedure. Move your program logic into the linear main procedure.

    Another way to allow your programs to be called recursively is to change your RPG so that the logic is in ordinary subprocedures in a NOMAIN module. Then add a CLLE module that calls your RPG subprocedures.

    Say this is your RPG program, TESTPGM:
    <pre class="jive-pre"> D testpgm pi extpgm( 'TESTPGM') D what 1a const D qcmd pr extpgm( 'QCMD') /free if %parms() > 0 and what = 'C'; dsply ( 'calling QCMD, parm ' + what); qcmd (); dsply ( 'returned from QCMD'); endif; return; </pre>
    Here is the linear main version, TESTPGMLM:
    <pre class="jive-pre"> H main(testpgmlm) P testpgmlm b D testpgmlm pi extpgm( 'TESTPGMLM') D what 1a const D qcmd pr extpgm( 'QCMD') /free if %parms() > 0 and what = 'C'; dsply ( 'calling QCMD, parm ' + what); qcmd (); dsply ( 'returned from QCMD'); endif; return; /end-free P testpgmlm e </pre>
    Here is the NOMAIN version TESTPGMNM:
    <pre class="jive-pre"> H nomain P testpgmnm b export D testpgmnm pi D what 1a const D qcmd pr extpgm( 'QCMD') /free if %parms() > 0 and what = 'C'; dsply ( 'calling QCMD, parm ' + what); qcmd (); dsply ( 'returned from QCMD'); endif; return; /end-free P testpgmnm e </pre>
    And the CLLE wrapper TESTPGMNMC:
    <pre class="jive-pre"> pgm parm(&what) dcl &what type(* char) len(1) callprc TESTPGMNM parm(&what) </pre>

    My session:
    <pre class="jive-pre"> 3 > /* ------------------- */ 3 > /* ----- TESTPGM ----- */ 3 > /* ------------------- */ 3 > call testpgm 'C' DSPLY calling QCMD, parm C 4 > call testpgm 'R' TESTPGM was called recursively. Application error. RNX8888 unmonitored by TESTPGM at statement *N, instruction X '0000'. End of requests. DSPLY returned from QCMD 3 > /* ------------------------------- */ 3 > /* ----- testpgm linear main ----- */ 3 > /* ------------------------------- */ 3 > call testpgmlm 'C' DSPLY calling QCMD, parm C 4 > call testpgmlm 'N' End of requests. DSPLY returned from QCMD 3 > /* ------------------------ */ 3 > /* ----- clle wrapper ----- */ 3 > /* ------------------------ */ 3 > call testpgmnmc 'C' DSPLY calling QCMD, parm C 4 > call testpgmnmc 'N' End of requests. DSPLY returned from QCMD </pre>
    Thankyou so much.
  • SystemAdmin
    SystemAdmin
    535 Posts

    Re: WRKMBRPDM UIM panels

    ‏2012-08-28T05:25:55Z  
    • scjt2001
    • ‏2012-08-14T17:39:42Z
    Thankyou so much.
    H *DFTACTGRP(*NO) ACTGRP(*NEW)*

    This will allow Your RPG Program to be called recursively.
  • JonParis
    JonParis
    154 Posts

    Re: WRKMBRPDM UIM panels

    ‏2012-08-28T15:09:41Z  
    H *DFTACTGRP(*NO) ACTGRP(*NEW)*

    This will allow Your RPG Program to be called recursively.
    <quote>H *DFTACTGRP(*NO) ACTGRP(*NEW)*

    This will allow Your RPG Program to be called recursively.</quote>

    Not really - it will allow it to be called again in the same invocation stack. Not quite the same thing as it cannot have visibility to the original's variables etc. It is as if the second instance is in a completely different job.

    There are also other factors that come into play with *New. Overrides for one, plus the fact that the program will terminate on return no matter what the state of LR. etc. etc.

    *NEW really only gives you the same abilities as a CRTDUPOBJ of the program with a new name and then calling the new version. Barbara's solution is the only real answer.