在RPGLE程序中添加新的输入参数

时间:2018-11-05 11:26:12

标签: ibm-midrange rpgle

我正在修改这个非常关键的RPGLE程序,其中的更改涉及向其添加新的输入参数。

*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        

除了我现在添加的最后一个参数外,程序条目参数列表与上面相同。该程序工作正常。但是我有点担心的是,这是否会以某种方式影响调用此程序的其他区域。即没有传递最后一个输入参数的调用程序。

此新的进入参数将仅从作为更改一部分的另一个程序传递。还有许多其他程序将调用该程序,并传递与先前相同的参数列表。

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

上面显示了代码中使用此参数的唯一其他区域。在这里,我确保在引用参数之前,先检查是否已传递参数。

我已经测试过,可以正常工作。但是,考虑到应用程序的重要性,仍然认为寻求专家的帮助。

欢迎对此提供任何指导/建议。

3 个答案:

答案 0 :(得分:5)

您有等待发生的内存损坏错误...

如果您尝试在不使用最后一个参数的情况下调用该程序,并且看起来似乎可行,那么您就很幸运,未使用该存储区...因此为零,而您的%Addr(E_Grp) <> *NULL可以正常工作如预期的那样。

为进行比较%Addr(E_Grp) <> *NULL,您的调用程序必须为该参数传递*OMIT特殊值。显然,这需要更改所有调用程序。

您想要的是不必更改调用程序,因此在被调用程序中需要的是参数为*NOPASS

您应该转换为调用程序以使用PR / PI而不是* ENTRY PLIST。然后,您可以将最后一个参数标记为options(*NOPASS *OMIT)

然后在调用的程序中,可以检查

  1. 如果参数已通过
  2. 如果传递的参数为NULL(* OMIT)

代码

// 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;

答案 1 :(得分:2)

据我所知,RPG正在考虑将来自调用方的参数视为“做您想做的事”。这意味着如果PGM02调用了PGM01,则PGM1接受3个参数,而PGM2调用3个参数,一切都很好。当PGM01需要3个参数而PGM02给2个参数时,您可以这样做。但是,您必须注意如果第三个参数为* NULL(会这样做)会发生什么。如果您使用4个参数调用PGM01,而PGM01仅“希望” 3,则没有问题,因为PGM01对此并不关心。

但是我会留下* ENTRY样式,而使用原型。您可以在此处定义是否可以省略参数,该参数可以使用,但不必使用。请阅读手册D-Spec和关键字PR

答案 2 :(得分:2)

如果不打算在程序中修改参数,则使用它的更安全方法是将变量初始化为默认值,如果传递了参数,则将参数复制到该变量。这样,如果添加了更多使用参数值的代码,他们将不必记住添加检查。

... Change the name of E_GRP parameter to E_GRP_parm

dcl-s E_GRP ... INZ(whatever);

if %parms() >= %parmnum(E_GRP_parm);
   E_GRP = E_GRP_parm;
endif;

您还可以将此技术与已更改 的参数一起使用:

dcl-pi *n;
   something_parm char(10) OPTIONS(*NOPASS);
end-pi; 

dcl-s something char(10) INZ('Whatever');

// Get the value of the "someThing" parameter if it was passed
if %parms() >= %parmnum(something_parm);
   someThing = someThing_parm;
endif;
...
// Update the "someThing" parameter if it was passed
if %parms() >= %parmnum(someThing_parm);
   someThing_parm = someThing;
endif;