• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Advantageous Options

    July 9, 2014 Ted Holt

    It happens to all of us. Someone tells us he needs a program just like an existing one, but with one small change. We clone the program, modify the clone, and now instead of one program to maintain when business requirements change, we have two. Before we know it, we have eight or 10 or more. Fortunately, there is a simple but seldom-used technique we can often use to avoid cloning programs.

    The technique to which I refer is to use an option parameter. An option parameter controls the behavior of a program. Contrast option parameters to data parameters, which contain data values, such as account numbers and dates.

    To find examples of option parameters, we need look no further than the IBM i operating system. Many CL commands have option parameters. For example:

    CRTBNDRPG . . . OPTION(*XREF *SHOWCPY *NOEXPDDS)
    

    The OPTION parameter gives us an easy way to control the behavior of the RPG compiler.

    Here’s another one:

    CPYF . . . FMTOPT(*MAP *DROP)
    

    The Format Option (FMTOPT) parameter provides a way for Copy File (CPYF) to copy different types of database files.

    If you choose to look further, you’ll see option parameters in many places within computing. Unix and Unix-like shells, such as Qshell, heavily use option parameters, which people sometimes call switches. Here’s an example:

    ls -lS
    

    The ls utility lists the contents of a directory. The l (lowercase ell) option tells the program to use the long format (one file per line). The uppercase S option tells the program to include the CCSID in the output.

    You can format options any way you like. I generally follow the convention of the system with which I’m working. In the case of IBM i applications, this means lists of values separated by spaces, except that I don’t feel compelled to include leading asterisks on the option values.

    I’ll illustrate with a CL command. You don’t have to create commands to use options; you can call programs directly. But the command interface does make it easier to pass lists of options to programs.

    Here’s the source code for CL command AR100, an accounts receivable application. Notice the third parameter, especially the VALUES keyword.

    CMD        PROMPT('Post Open AR Transactions')
    PARM       KWD(FROMDATE) TYPE(*DATE) DFT(*FIRST) +
                 SPCVAL((*FIRST 000000)) PROMPT('Beginning +
                 date')
    PARM       KWD(THRUDATE) TYPE(*DATE) DFT(*LAST) +
                 SPCVAL((*LAST  999999)) PROMPT('Ending +
                 date')
    PARM       KWD(OPTIONS) TYPE(*CHAR) LEN(8) RSTD(*YES) +
                 VALUES(REPORT NOREPORT UPDATE NOUPDATE) +
                 MAX(2) CHOICE('(NO)REPORT, (NO)UPDATE') +
                 PROMPT('Options')
    

    This program does two things: it produces a report showing how the database is to be updated, and it updates the database. The options allow us to run the report in many ways. Ignoring the date parameters, here are some of those ways:

    AR100
    AR100 OPTIONS(REPORT)
    AR100 OPTIONS(UPDATE)
    AR100 OPTIONS(REPORT UPDATE)
    AR100 OPTIONS(REPORT NOUPDATE)
    AR100 OPTIONS(NOREPORT UPDATE)
    AR100 OPTIONS(NOREPORT NOUPDATE)
    

    The last version is permissible, even though it makes no sense.

    The system passes the list of options to the command-processing program through a single parameter made up of a two-byte binary value and the options themselves. The binary value tells the number of options in the list.

    The command-processing program assigns default values to the options, then reads the list to change the option values. Here’s how it’s done in CL.

    pgm  parm(&inFromDate &inThruDate &inOptions)
    
          dcl  &inFromDate    *char    7
          dcl  &inThruDate    *char    7
          dcl  &inOptions     *char   18
    
          dcl  &Ndx            *uint    2
          dcl  &Option         *char    8
          dcl  &OptOffset     *uint    2
          dcl  &ToReport      *lgl
          dcl  &ToUpdate      *lgl
    
          callsubr SetOptions
    
          if &ToReport do
             . . .
          enddo
          . . .
          if &ToUpdate do
             . . .
          enddo
          return
    
    subr SetOptions
    
    /* Set defaults for options */
          chgvar       &ToReport         '1'
          chgvar       &ToUpdate         '0'
    
    /* Process the options */
          chgvar       &OptOffset         3
          dofor        var(&Ndx) from(1) to(%bin(&inOptions 1 2))
             chgvar    &Option            %sst(&inOptions &OptOffset 8)
             select
                when (&Option *eq REPORT)   then(chgvar &ToReport '1')
                when (&Option *eq NOREPORT) then(chgvar &ToReport '0')
                when (&Option *eq UPDATE)   then(chgvar &ToUpdate '1')
                when (&Option *eq NOUPDATE) then(chgvar &ToUpdate '0')
             endselect
             chgvar    &OptOffset         (&OptOffset + 8)
          enddo
    
    endsubr
    
    endpgm
    

    Here’s the same thing in RPG:

    H dftactgrp(*no) actgrp(*caller) option(*srcstmt: *nodebugio)
    
    D OptionList_t    ds                  qualified template
    D  Count                         5i 0
    D  Value                         8a   dim(2)
    
    D AR100R          pr                  extpgm('AR100R')
    D  inFromDate                    7a   const
    D  inThruDate                    7a   const
    D  inOptions                          const likeds(OptionList_t)
    
    D AR100R          pi
    D  inFromDate                    7a   const
    D  inThruDate                    7a   const
    D  inOptions                          const likeds(OptionList_t)
    
    D BuildReport     s               n   inz(*on)
    D UpdateDatabase  s               n   inz(*off)
    
    D Ndx             s              3u 0
    
     /free
         *inlr = *on;
         for Ndx = 1 to inOptions.Count;
            select;
               when inOptions.Value (Ndx) = 'REPORT';
                  BuildReport = *on;
               when inOptions.Value (Ndx) = 'NOREPORT';
                  BuildReport = *off;
               when inOptions.Value (Ndx) = 'UPDATE';
                  UpdateDatabase = *on;
               when inOptions.Value (Ndx) = 'NOUPDATE';
                  UpdateDatabase = *off;
            endsl;
         endfor;
         return;
    

    Of course, you don’t have to use this convention. Options can be anything you like.

    Later someone might ask for a summary report. You could add options SUM and NOSUM. Then someone might ask to see only the lines with errors. You might add an ERRONLY option. (Options don’t have to come in pairs.) Later you might decide to add report lines to aid in debugging, as I wrote about last year.

    Here’s the command source as it stands now:

    CMD        PROMPT('Do an important AR task')
    PARM       KWD(FROMDATE) TYPE(*DATE) DFT(*FIRST) +
                 SPCVAL((*FIRST 000000)) PROMPT('Beginning date')
    PARM       KWD(THRUDATE) TYPE(*DATE) DFT(*LAST) +
                 SPCVAL((*LAST  999999)) PROMPT('Ending date')
    PARM       KWD(OPTIONS) TYPE(*CHAR) LEN(8) RSTD(*YES) +
                 VALUES(REPORT NOREPORT UPDATE NOUPDATE +
                        SUM NOSUM ERRONLY DEBUG) +
                 MAX(5) CHOICE('REPORT, UPDATE, ERRONLY ...') +
                 PROMPT('Options')
    

    Here are the pertinent portions of the modified CL command-processing program:

    pgm  parm(&inFromDate &inThruDate &inOptions)
    
          dcl  &inFromDate    *char    7
          dcl  &inThruDate    *char    7
          dcl  &inOptions     *char   42
    
          dcl  &Ndx           *uint    2
          dcl  &Option        *char    8
          dcl  &OptOffset     *uint    2
          dcl  &ToReport      *lgl
          dcl  &ToUpdate      *lgl
          dcl  &Summary       *lgl
          dcl  &ErrorOnly     *lgl
          dcl  &Debugging     *lgl
    
          callsubr SetOptions
    
    
    subr SetOptions
    
    /* Set defaults for options */
          chgvar       &ToReport         '1'
          chgvar       &ToUpdate         '0'
          chgvar       &Summary          '0'
          chgvar       &ErrorOnly        '0'
          chgvar       &Debugging        '0'
    
    /* Process the options */
          chgvar       &OptOffset         3
          dofor        var(&Ndx) from(1) to(%bin(&inOptions 1 2))
             chgvar    &Option            %sst(&inOptions &OptOffset 8)
             select
                when (&Option *eq REPORT)   then(chgvar &ToReport '1')
                when (&Option *eq NOREPORT) then(chgvar &ToReport '0')
                when (&Option *eq UPDATE)   then(chgvar &ToUpdate '1')
                when (&Option *eq NOUPDATE) then(chgvar &ToUpdate  '0')
                when (&Option *eq SUM     ) then(chgvar &Summary   '1')
                when (&Option *eq NOSUM   ) then(chgvar &Summary   '0')
                when (&Option *eq ERRONLY ) then(chgvar &ErrorOnly '1')
                when (&Option *eq DEBUG   ) then(chgvar &Debugging '1')
             endselect
             chgvar    &OptOffset         (&OptOffset + 8)
          enddo
    
    endsubr
    
    endpgm
    

    I encourage you, the next time you’re tempted to clone a program, to ask yourself whether adding an option parameter might not be a better choice. After all, you probably have better things to do than modify cloned programs.

    RELATED STORY

    Tracing Routines Explain Why The Computer Did What It Did



                         Post this story to del.icio.us
                   Post this story to Digg
        Post this story to Slashdot

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags:

    Sponsored by
    Rocket Software

    Software built on TRUST. Delivered with LOVE.

    For over 35 years, Rocket Software’s solutions have empowered businesses to modernize their infrastructure, unlock data value, and drive transformation – all while ensuring modernization without disruption.

    Learn More

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Sponsored Links

    PowerTech:  IBM i security found 94% of systems fail to protect all 27 exit points. Download our study.
    System i Developer:  Upgrade your skills at the RPG & DB2 Summit in Minneapolis, Sept 30 - Oct 2.
    COMMON:  Join us at the COMMON 2014 Fall Conference & Expo in Indianapolis, Oct 27-29

    More IT Jungle Resources:

    System i PTF Guide: Weekly PTF Updates
    IBM i Events Calendar: National Conferences, Local Events, and Webinars
    Breaking News: News Hot Off The Press
    TPM @ EnterpriseTech: High Performance Computing Industry News From ITJ EIC Timothy Prickett Morgan

    EXTOL Finds New Partners for EDI Counting The Cost Of Power8 Systems

    Leave a Reply Cancel reply

Volume 14, Number 15 -- July 9, 2014
THIS ISSUE SPONSORED BY:

PowerTech
WorksRight Software
Valence Framework for IBM i

Table of Contents

  • The Geezer’s Guide To Free-Form RPG, Part 4: Prototypes and Procedure Interfaces
  • Advantageous Options
  • Admin Alerts: Old IBM i Backups, New Tricks

Content archive

  • The Four Hundred
  • Four Hundred Stuff
  • Four Hundred Guru

Recent Posts

  • FAX/400 And CICS For i Are Dead. What Will IBM Kill Next?
  • Fresche Overhauls X-Analysis With Web UI, AI Smarts
  • Is It Time To Add The Rust Programming Language To IBM i?
  • Is IBM Going To Raise Prices On Power10 Expert Care?
  • IBM i PTF Guide, Volume 27, Number 20
  • POWERUp 2025 –Your Source For IBM i 7.6 Information
  • Maxava Consulting Services Does More Than HA/DR Project Management – A Lot More
  • Guru: Creating An SQL Stored Procedure That Returns A Result Set
  • As I See It: At Any Cost
  • IBM i PTF Guide, Volume 27, Number 19

Subscribe

To get news from IT Jungle sent to your inbox every week, subscribe to our newsletter.

Pages

  • About Us
  • Contact
  • Contributors
  • Four Hundred Monitor
  • IBM i PTF Guide
  • Media Kit
  • Subscribe

Search

Copyright © 2025 IT Jungle