Enable or Disable Code at Run Time
April 5, 2016 Ted Holt
If you program in RPG or C, you should know how to use compiler directives to enable or disable source code at compile time. IBM i programmers should also know how to enable or disable executable code at run time, and why they would want to do such a thing.
Let’s talk about the why first.
One good reason to enable or disable code is for trouble-shooting. You might find it valuable to include commands to:
Such code can help with elusive problems and need only be enabled until a problem is resolved.
Another reason to enable or disable code is to give an end user a way to control execution. For example, he may only want certain programs to run during the first and last months of the year. If you make a program check a setting at run time, and give the user a way to control the setting, you relieve the user of the need to make a run time selection. If the program runs from a job scheduler, then such code is the only way for the user to control run-time behavior.
Now, the how.
One easy way to enable or disable code is by checking for the existence of an object. Any type of object can serve this purpose. I prefer data structures because they’re easy to deal with in both CL and RPG.
In the following example, logical variable &DbgIsOn (debug is on) is controlled by the presence or absence of a data structure named DBG.
dcl &DbgDta *char 96 dcl &DbgDtaSiz *uint 2 dcl &DbgIsOn *lgl value('1') chgvar &DbgDtaSiz value(%size(&DbgDta)) rtvdtaara dtaara(DBG (1 &DbgDtaSiz)) rtnvar(&DbgDta) monmsg cpf1015 exec(do) /* not found */ chgvar &DbgIsOn '0' enddo . . . more stuff . . . if (&DbgIsOn) do dmpclpgm dspjoblog output(*print) enddo
If the data structure exists in any library that is in the library list, the program sets &DbgIsOn to true, causing the program to produce a dump and a job log.
The only problem with this method is that other programs may also have tests for the same data structure. This may or may not cause problems. At best, it could slow down processing and produce a bunch of unwanted spooled files. For this reason, I like to add another test, which looks at the value within the data structure.
Consider a program, which I’ll call AR100.
dcl &DbgDta *char 96 dcl &DbgDtaSiz *uint 2 dcl &DbgIsOn *lgl value('1') chgvar &DbgDtaSiz value(%size(&DbgDta)) rtvdtaara dtaara(DBG (1 &DbgDtaSiz)) rtnvar(&DbgDta) monmsg cpf1015 exec(do) /* not found */ chgvar &DbgIsOn '0' enddo if (&DbgIsOn) do chgvar &DbgIsOn value(%scan(AR100 &DbgDta) *gt 0) enddo . . . more stuff . . . if (&DbgIsOn) do dmpclpgm dspjoblog output(*print) enddo
This program tests for the existence of a data structure named DBG, just as the previous one did. If the data structure exists, the program also looks for the value “AR100” in the data structure.
I have seen programmers add code to aid with debugging and/or problem determination, then delete that code once a problem is found. That isn’t wrong, but many times I have found it valuable to retain such code and activate it as needed.