Search code examples
ibm-midrangerpgle

Adding new entry parameter in an RPGLE program


I am modifying this highly critical RPGLE program where the changes involve adding a new entry parameter to it.

*entry        plist                                                              
              parm                    ecorp                          corp        
              parm                    edivi                          divi        
              parm                    eplvl                          parent lv   
              parm                    ewrsc                          wc rscd     
              parm                    eplnt                          plnt        
              parm                    eclvl                          child lv    
              parm                    emord                          ord         
              parm                    easst                          asst        
              parm                    emrwk                          mrwk#       
              parm                    eseqn                          seq #       
              parm                    easeq                          alt seq #   
              parm                    epprd                          alt seq #   
              parm                    eotst                          alt seq #   
              parm                    ewpqt                          alt seq #   
              parm                    ecmpc                          alt seq #   
              parm                    ewurs                          alt seq #   
              parm                    emurs                          alt seq #   
              parm                    epcdt                          alt seq #   
              parm                    E_Optn                         option          
              parm                    eeoj                           end of job      
              parm                    E_Pgm                          program         
              parm                    E_GRP                          MO GROUP        

The program entry parameter list is as above with the exception of the last parameter which I have added now. The program works fine. But what I am a bit concerned is if this would somehow impact other areas from where this program is called. i.e Caller Programs where the last entry parameter is not passed.

This new entry parameter is going to be passed from only one another program that is part of the change. There are quite a few other programs which are going to call the program passing the same parameter list as earlier.

If (%Addr(E_Grp) <> *NULL);            
  Chain (E_Grp:EWURS:ssmurs) MFMPP00;  
  If %Found();                         
    MchAllotted = *On;                 
    Leave;                             
  EndIf;                               
EndIf;                                 

The only other area in the code where this parameter is used is shown above. Here, I have ensured that before the parameter is referred, it is checked that the parameter has been passed.

I have tested and this works fine. However, considering the criticality of the application, still thought to seek expert help.

Any guidance/suggestions regarding this are welcome.


Solution

  • You have memory corruption bug waiting to happen...

    If you've tried calling the program without the last parameter and it seems to have worked, you've just gotten lucky that the memory area had not been used...thus was zeros and your %Addr(E_Grp) <> *NULL worked as expected.

    For a comparison %Addr(E_Grp) <> *NULL your calling programs have to pass the *OMIT special value for that parameter. Obviously that would require changing all the calling programs.

    What you want is to not have to change the calling programs, thus what you need in the called program is for the parameter to be *NOPASS.

    You should convert to called program to use a PR/PI instead of an *ENTRY PLIST. Then you can mark the last parameter as options(*NOPASS *OMIT)

    Then in the called program, you can check

    1. if the parameter was passed
    2. if the passed parm was NULL (*OMIT)

    Code

    // check if the parm was passed
    if %parms() > = %parmnum(E_GRP);
      // check if passed parm is not NULL
      if  %Addr(E_Grp) <> *NULL;
         //ok to use E_Grp
         Chain (E_Grp:EWURS:ssmurs) MFMPP00;  
         If %Found();                         
           MchAllotted = *On;                 
           Leave;                             
         endif;
      endif;
    endif;