Добавление нового параметра ввода в программу 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 ответа

Решение

У вас есть ошибка повреждения памяти, ожидающая...

Если вы пытались вызвать программу без последнего параметра, и она, кажется, сработала, вам просто повезло, что область памяти не использовалась... таким образом, были нули и ваша %Addr(E_Grp) <> *NULL работал как положено.

Для сравнения %Addr(E_Grp) <> *NULL Ваши вызывающие программы должны пройти *OMIT специальное значение для этого параметра. Очевидно, что это потребует изменения всех вызывающих программ.

Вам не нужно менять вызывающие программы, поэтому в вызываемой программе вам нужно, чтобы параметр был *NOPASS,

Вы должны преобразовать в вызываемую программу, чтобы использовать PR/PI вместо *ENTRY PLIST. Тогда вы можете пометить последний параметр как options(*NOPASS *OMIT)

Затем в вызываемой программе вы можете проверить

  1. если параметр был передан
  2. если переданный параметр был НЕДЕЙСТВИТЕЛЕН (* ПУСК)

Код

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

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

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

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

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

Другие вопросы по тегам