Добавление нового параметра ввода в программу RPGLE - PullRequest
0 голосов
/ 05 ноября 2018

Я изменяю эту крайне критичную программу 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 голосов
/ 05 ноября 2018

Вы ожидаете ошибки повреждения памяти ...

Если вы пытались вызвать программу без последнего параметра, и она, кажется, сработала, вам просто повезло, что область памяти не использовалась ... таким образом, были нули, и ваш %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;
0 голосов
/ 06 ноября 2018

Если параметр не будет изменен в программе, то более безопасный способ его использования - инициализация переменной по умолчанию, а при передаче параметра скопируйте параметр в эту переменную. Таким образом, если будет добавлено больше кода, использующего значение параметра, им не нужно будет забывать добавить проверку.

... 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;
0 голосов
/ 05 ноября 2018

Насколько я знаю, RPG рассматривает параметры вызывающей стороны как "Делай, что хочешь". Это означает, что если PGM01 вызывается PGM02, где PGM1 принимает 3 параметра, а вызов PGM2 с 3 параметрами, то все в порядке. Когда PGM01 хочет 3 параметра, а PGM02 дает 2 параметра, вы можете сделать это. Но вы должны позаботиться о том, что произойдет, если третий параметр * NULL (как вы делаете). Если вы вызываете PGM01 с 4 параметрами, тогда как PGM01 только «хочет» 3, проблема не возникает, поскольку PGM01 не заботится об этом.

Но я бы оставил стиль * ENTRY позади и вместо этого использовал бы прототипы. Там вы можете определить, что если параметр является опускаемым, он может использоваться, но не обязательно. Пожалуйста, прочтите руководство по D-Spec и ключевому слову PR.

...