External Call Procedure

Since function keys and program options have been externalized, the next logical step is externalizing subprogram calls.

     D callPrograms    PR                   ExtPgm('SC0321RP')                                      
     D  pgmNam                       10a                                                            
     D  lstNam                       10a                                                            
     D  modeIn                        1a                                                            
     D  dataIn                         *                                                            
     D  sizeIn                       10i 0                                                          
     D  rtnID                         7a   
.
.
.
        Dcl-Proc callProgram;                                                                       
         Dcl-PI callProgram              end-PI;                                                    
                                                                                                    
           setParameters();                                                                         
                                                                                                    
           MONITOR;                                                                                 
              CallPrograms( subPgm :                                                                
                            callPM :                                                                
                            subAct :                                                                
                            dtaPtr :                                                                
                            dtaSize:                                                                
                            p$err   ) ;                                                             
           ON-ERROR;                                                                                
              P$ERR = 'MIS0012';                                                                    
              GetMessage('MIS0012');                                                                
           ENDMON;                                                                                  
                                                                                                    
           getParameters();                                                                         
                                                                                                    
          Return ;                                                                                  
                                                                                                    
        END-Proc callProgram ;                                              

This PROGRAM performs the same function as the @CALLS subroutine. Ideally, it would be made a service program. The exported procedure would function as a generic call operation for a group of related programs or a group of tables sharing a common key structure. For a look at the code of SC0321RP, return to the previous page.

Program Options

Retrieving program options and reacting to them happens much the same way as managing the function keys. The procedure GETOPTION performs the lookup of the option seclected on the options database (SCOPTNPF). Typically, options are associated with a data list. The subfile proocess in the program SC0320RP reads the subfile in the @ENTER subroutine. The option is retrieved and the same routine that processes calls for function key macro instructions serves the program options as well.

BEGSR @ENTER;                                                                               
   // Read and Update subfile records ...                                                   
   IF Z$RRN1 > 0;                                                                           
      DOU %eof(SC0320DF);                                                                   
         READC SC0320S1;                                                                    
         listAction = *off;                                                                 
         IF NOT %eof(SC0320DF);                                                             
            IF Z$OPT <> *BLANK;                                                             
               listAction = *ON;                                                            
               thisOption = %triml(z$opt);                                                  
               ThisFormat = fmtnam;                                                         
               ThisPgm = prgnam;                                                            
               GetOption(Thispgm
                        :ThisFormat
                         :thisOption
                         :macro
                         :authl);                        
               SELECT;                                                                      
                WHEN SUBOP = 'CALL';                                                         
                  EXSR @CALLS;                                                              
                WHEN function = 'PROCESS';                                                   
                   objectFound = retrieveObject( exobnm:exobtp );                           
                   IF objectFound;                                                          
                      objectFound = ObjectProcess();                                        
                   ENDIF;                                                                   
                WHEN function = 'RESET';                                                     
                   objectFound = retrieveObject( exobnm:exobtp );                           
                   IF objectFound;                                                          
                      objectFound = ResetProcess();                                         
                   ENDIF;                                                                   
               WHEN function = 'EXCEPTION';                                                 
                   objectFound = retrieveObject( exobnm:exobtp );                           
                   IF objectFound;                                                          
                      objectFound = ProcException();                                        
                   ENDIF;                                                                   
               WHEN function = 'OBSOLETE';                                                  
                   objectFound = retrieveObject( exobnm:exobtp );                           
                   IF objectFound;                                                          
                      objectFound = ObjectObsolete();                                       
                   ENDIF;                                                                   
               WHEN function = 'EXTEND';                                                    
                   objectFound = retrieveObject( exobnm:exobtp );                           
                   IF objectFound;                                                          
                      objectFound = ObjectExpanded();                                       
                   ENDIF;                                                                   
               ENDSL;                                                                       
               z$opt = *BLANK;                                                              
               IF before <> after;                                                          
                  SELECT;                                                                   
                     WHEN p$mode = 'C';                                                     
                        OBJECT = after;                                                     
                        exdesc= '*changed';                                                 
                     WHEN p$mode = 'D';                                                     
                         exdesc = '*deleted';                                                
                         *IN30 = *ON;                                                        
                  ENDSL;                                                                    
               ENDIF;                                                                       
               z$rrn2 =  z$rrn1;                                                            
               UPDATE SC0320S1;                                                             
               *IN30 = *OFF;                                                                
               CLEAR MACRO;                                                                 
            ENDIF;                                                                          
         ENDIF;                                                                             
      ENDDO;                                                                                
   ENDIF;                                                                                   
   EXSR @READ;                                                                              
ENDSR;                                                        


SoftCode Applications Continued

Managing the Function table

A display of the soft coded command keys (SCF) for a program shows entries for internal macro instructions, including one formatted for the @CALLS subroutine

SCROYA1    SC0020RP      iSoftwerks Incorporated           SYSNAME   4/02/10   
SCROY      634042        SOFT FUNCTION EDITOR              SC0020S1 08:12:45   
                                                                               
  APPLICATION: SC0320RP    PANEL:             AUTHORITY LEVEL: 000             
                                                                               
 Key ID     Macro Function, program call or command       Function text        
 F21        &CALL QUSCMDLN                                Command line         
 F23        MOREOPTS                                      More options         
 F24        MOREKEYS                                      More keys            
 F3         EXIT                                          Exit                 
 F4         PROMPT                                        Prompt               
 F5         RESET                                         Refresh              
 F9         CALL SC0335RP  PLIST1                       A Add item             
                                                                               
                                                                               
                                                                               
                                                                               
                                                                               
                                                                               
                                                                               
                                                                               
                                                                             + 
                          F3=Exit                                              

FIG. 1

An Add item request has been entered for the application SC0335RP. The macro has been coded to instruct the requesting program to call the program using the parameter list; PLIST1. The program options (SCOPTNPF) file contains multiple complex macro instructions calling various subprograms using the parameter list called WORKSOURCE.

SCROYA1    SC0020RP      iSoftwerks Incorporated           SYSNAME   4/02/10   
SCROY      634042        SOFT OPTION EDITOR                SC0020S1 08:12:45   
                                                                               
  APPLICATION: SC0320RP    PANEL:             AUTHORITY LEVEL: 000             
                                                                               
  Option    Panel            Macro            Act        Text         Lvl        
 DB                  CALL SC0338CL  WORKSOURCE C DBU                  000
 ES                  CALL SC0345CL  WORKSOURCE C Edit source          000
 RM                  CALL SC0335CL  WORKSOURCE D Remove soure         000
 SD                  CALL SC0370CL  WORKSOURCE S SDA                  000
 VS                  CALL SC0340CL  WORKSOURCE V View source          000
 WK                  CALL SC0300CL  WORKSOURCE W Work keys            000
 WO                  CALL SC0310CL  WORKSOURCE W Work options         000
 2                   CALL SC0335RP  PLIST1     C Edit entry           000
 4                   CALL SC0335RP  PLIST1     D Delete entry         000
 5                   CALL SC0335RP  PLIST1     V View entry           000       
                                                                                                                                                                                                                                     
                                                                               
                                                                               
                                                                               
                                                                               
                                                                               
                                                                             + 
                          F3=Exit                                              

Fig. 1A

The following D specs contain several externally defined data structures commonly associated with the SOFTCODE development process. This subroutine is an example of using the format of the complex macro instruction to format dynamic calls based on the information provided in the macro instruction. The call becomes dynamic--the parameter list to use is populated with program variables. The prototype (see example) references a variable name instead of a literal. This means programs named on the function table or option table can be replaced with newer versions without changing the calling program. (As long as the signature hasn't changed.)


     D WithParms1      PR                  extpgm(SUBPGM)                                           
     D  parm01                       10                                                             
     D  parm02                       10                                                             
     D  mode                          1                                                             
     D  return                        7                                                             
                                                                                                    
     D CommandLine     PR                  extpgm('QUSCMDLN')                                       
                                                                                                    
     D WorkSource      PR                  extpgm(SUBPGM)                                           
     D  parm01                       10                                                             
     D  parm02                       10                                                             
                                                                                                    
     D WorkObject      PR                  extpgm(SUBPGM)                                           
     D  parm01                       10                                                             
     D  parm02                       10                                                             
                                                                                                    
     D NoParms         PR                  extpgm(SUBPGM) 
.
.
.
           ThisFormat = fmtnam;                                                                     
           ThisPgm = prgnam;                                                                        
           GetFunction(thisPgm
			:thisFormat
			:keypressed
			:fkeyid
			:macro
			:authl);                           
                                                                                                    
              SELECT;                                                                               
              WHEN KeyPressed = functionKey.ENTER;                                                  
                 EXSR @ENTER;                                                                       
              WHEN KeyPressed = functionKey.ROLLUP;                                                 
                 EXSR @LOAD;                                                                        
              WHEN KeyPressed = functionKey.ROLLDN;                                                 
                 EXSR @DOWN;                                                                        
              WHEN KeyPressed = functionKey.F23;                                                    
                   DisplayOptions(option: z$opt1: z$opt2: O);                                       
              WHEN KeyPressed = functionKey.F24;                                                    
                   DisplayKeys(cmdkey: z$key1: z$key2: M);                                          
              WHEN Function = 'EXIT';                                                               
                 QUIT();                                                                            
              WHEN Function = 'CANCEL';                                                             
                 EXSR @return;                                                                      
              WHEN Function = 'RESET';                                                              
                 EXSR @RESET;                                                                       
              WHEN Function = 'PROMPT';                                                             
                 EXSR @PROMPT;                                                                      
                 IF promptDta <> *blanks;                                                           
                    PromptDta = *blanks;                                                            
                    EXSR @RESET;                                                                    
                 ENDIF;                                                                             
              WHEN Function = 'HELP';                                                               
                 HelpText(ThisPgm:fmt);                                                             
              WHEN SUBOP = 'CALL';                                                                  
                 EXSR @CALLS;                                                                       
              WHEN Function = 'CMDLINE';                                                            
                 CommandLine();                                                                     
           ENDSL;                             
.
.
.
        BEGSR @CALLS;                                                                               
           EXSR @SETPM;                                                                             
           MONITOR;                                                                                 
           SELECT;                                                                                  
              WHEN CALLPM = 'WORKSOURCE';                                                           
                 CALLP WorkSource(exombr: exobsr);                                                  
              WHEN CALLPM = 'WORKOBJECT';                                                           
                 CALLP WorkObject(parm01: parm02);                                                  
              WHEN CALLPM = 'PLIST1';                                                               
                 CALLP WithParms1(parm01: parm02: p$mode: p$err);                                   
              WHEN CALLPM = 'DBUFILE';                                                              
                 CALLP DBUfile(exobnm: exoblb);                                                     
              OTHER;                                                                                
                 CALLP NoParms();                                                                   
           ENDSL;                                                                                   
           ON-ERROR;                                                                                
              P$ERR = 'MIS0012';                                                                    
              EXSR @GetMsg;                                                                         
           ENDMON;                                                                                  
           EXSR @RETPM;                                                                             
        ENDSR;                                
   

As noted on the previous page, the name of the program is a variable. Any program that shares a common argument with one of the defined protorypes can may be inserted, deleted, or updated by maintaining the the function or option table. The subprogram calls in the program options (Fig. 1A) may invoke RPG programs (SC0335RP) or CL programs such as SC0338CL.

In this example the variable, KEYPRESSED is compared against specific function keys, ENTER (qualified notation, FUNCTIONKEY.ENTER), but the other program actions are defined by the function returned by SOFTCODE process.

The next page outlines the functional authorization level (FAL) built into the SoftCode processes.

Get Function

A single module is required for the SCF is FUNCTIONKEYS a procedure designed to load mnemonic variables with the hex code pattern for function keys. This provides a straight forward method of command function coding without the use of indicators. It also has the added advantage of easily interpreted code.

  • 1) Define the key structure with the externally defined file SCKEYSPF
  • 2) Define the AID byte for the last key pressed using the data structure DSPDS

********************************************************************
FSC0190DF CF   E             WORKSTN
F                                     SFILE(SC0190S1:RRNSI)
F                                     INFDS(DSPDS)
 *===================================================================

D SC0190RP       PI                                             
D  p$usrp                       10a   Const Options(*nopass)     
                                                                 
D FunctionKey   E DS                  EXTNAME(SCKEYSPF) qualified 
D PGMDS         ESDS                  EXTNAME(SCPSTSPF)           
D DSPDS         E DS                  EXTNAME(SCDSPFPF)           
D MACDS         E DS                  EXTNAME(SCFUNCPF) INZ       
D OPTDS         E DS                  EXTNAME(SCOPTNPF) INZ       
D FUNCT         E DS                  EXTNAME(SCMACRPF) INZ


  • 3) Retrieve the hex definition of the keys using the SOFTCODE module FUNCTIONKEYS
  • 4) Invoke the SOFTCODE procedure GETFUNCTION to return the macro instruction
  • 5) Execute the function returned

.
.
.
FunctionKey = FunctionKeys();
.
.
.
   fkeyds = KeyPressed;
   funct = *BLANKS;
   fpgmid = PRGNAM;
   fpnlid = FMTNAM;
   fmacro = *BLANKS;

   MONITOR; 
      GetFunction(fpgmid
		:fpnlid
		:fkeyds
		:fkeyid
		:fmacro
		:authl); 
   ON-ERROR;
      msgid = 'MIS0003';
      EXSR @GetMsg;
   ENDMON;
.
.
.

The program name from the program status data structure along with the key pressessed and record format name (panel ID) are used as the key to find the function. The macro will be returned to the program, assuming the authorization level (AUTHL) allows the operation.

At its simplest, the GETFUNCTION is performing a look-up to determine what function is associated with the key pressed, then having determined that, returns the function macro data to the requesting program. An in-line case structure usually follows the GETFUNCTION. The case structure may be looking for a specific function, or a number of different functions.