RPG Academy: Parameters: Do You Know Your Options?, Part 3

RPG
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

Morphing parameters, C language-like strings, and (sort of) self-formatting parametershidden or at least little know features provided by the OPTIONS keyword. Curious? Continue reading to find out!

 

This is the final article of the options series. If you missed parts 1 and 2, look here and here. And now let's move on!

 

The Morphing Parameter (Wait, What?!)

The idea of a "morphing parameter" that can change size at each call can be hard to wrap your head around, but the OPTIONS(*VARSIZE) option is extremely useful, as you'll soon see.

 

If you ever used one of the many APIs IBM provides, you've probably come across the *VARSIZE option. One classic example is the QCMDEXC API, which allows you to run CL commands from within an RPG program:

 

     D QCMDEXC         PR                 ExtPgm('QCMDEXC')

     D P_CmdString               32702A   Const OPTIONS(*VARSIZE)

     D P_CmdLen                     15P 5 Const

     D P_DbcsFlag                   3A   Const OPTIONS(*NOPASS)

 

And if you've read the previous articles of this series, most of what you see here should be familiar: you'll see that I'm defining a prototype in order to use the QCMDEXC API as if it were a procedure or function; then, you'll find that all the parameters use the CONST keyword and the last parameter P_DbcsFlag is optional, via the OPTIONS(*NOPASS) keyword. The only part that is truly new is the use of the OPTIONS(*VARSIZE) in the P_CmdString parameter. Speaking of which, have you noticed the unusually large size of the parameter? A parameter that long can cause some performance issues, even with the CONST keyword, because it requires a sizable chunk of memory to be allocated every time the API is called. That's why the *VARSIZE option is being used here. This option removes the matching parameter size restriction and allows you to pass a variable of any length, up to the size of the parameter, without causing compilation errors (I'll address run-time errors in a second). In practice, this means that you can call QCMDEXC using this:

 

D QCMDEXC       PR                 ExtPgm('QCMDEXC')

D P_Cmd                       350A                  

D P_Cmdlen                     15P 5  

 

P_Cmd doesn't have the 32.702 characters that QCMDEXC requires, but since it makes use of the *VARSIZE option, a variable of any length up to 32.702 works. However (and this is really, really important), you need to "clean" the parameter value before using it. Since you're not using the full length of the parameter, the part that is not being used may (OK, probably will) contain "garbage"memory that was used for something else, which has nothing to do with your variable. How do you do it? If you answered "with a BIF," then you're (almost) correct.

 

Just let me do a quick recap here: to make sure that it was safe to use a parameter defined with OPTIONS(*NOPASS), you'd resort to %PARMS; and to check if a parameter was not omitted when defined with OPTIONS(*OMIT), you'd use %ADDR. So it's only logical that the "cleaning" process I mentioned earlier uses BIFs. In this case, it uses two: %TRIM (which I'll explain in detail in the next article) and %LEN. This last BIF returns the number of digits or characters of a variable expression. However, in this particular case, if you use %LEN by itself, you'll get the field length (32.702), which is not what you want. What you want is the length of the content of the variable, not the length of variable itself. That's where %TRIM comes in: this BIF removes the leading and trailing blanks of a string. By using a combination of these two BIFs, you're able to determine the length you need to "clean" the *VARSIZE-defined parameter of any garbage. You do that by using a work variable and the %LEN-%TRIM combination and the %SUBST (substring) BIFs to retrieve the valid content of the parameter:

 

* Retrieving the valid content of P_Cmd                          

C                   Eval     W_Cmd = %SUBST(P_Cmd : 1 :

C                                           %LEN(%TRIM(P_Cmd)))

 

C-Like Strings

In the C language (and in a few other languages too), the strings are null-terminated. This means that a special character (x'00') is inserted after the last character of the string. So the next option on my list, *STRING, is basically used to invoke C APIs, even though you can use it in "standard" RPG programs as well, because RPG supports both types of strings: the ones we're used to (the fixed-length strings) and the null-terminated ones. Since null-terminated strings are usually related to pointers and that's a fairly advanced topic, I won't explain it in detail here. If you want to see an example of the OPTIONS(*STRING) keyword in action, read this post about a QCMDEXC alternative. The System() function has the same functionality as QCMDEXC, but it doesn't need to know the length of the command, because the OPTIONS(*STRING) keyword will cause the command string to be concatenated with the x'00' special character, create a temporary variable with it, and pass a pointer to that variable to the procedure.

 

(Sort of) Self-Formatting Parameters

Finally, a few words about the *RIGHTADJ and *TRIM options. I could never really find a practical use for them, but let me explain what they do. Their names tell the whole story.

 

Let's start with *RIGHTADJ. The value passed to a *RIGHTADJ-defined parameter will get (you guessed it) right-adjusted once the procedure/function begins to execute, assuming that the content is shorter than the parameter.

 

As for the *TRIM option, it also does what the name suggests: the passed parameter is copied without leading and trailing blanks to a temporary variable. If the parameter is not a varying-length parameter, the trimmed value is padded with blanks (on the left if OPTIONS(*RIGHTADJ) is specified; otherwise on the right). Then the temporary variable is passed (instead of the original parameter) to the called procedure/function. Specifying OPTIONS(*TRIM) causes the parameter to be treated exactly as though %TRIM were coded on every call to the procedure.

 

There's one more option, named *NULLIND, which I won't discuss here, because its use requires some additional keywords and is somewhat an advanced feature that might not be easy to grasp for those taking the first steps in ILE. If you really want to know, just Google "OPTIONS(*NULLIND)" to find links that might help.

 

Now You Know Your Options

Well, that ends this "Do You Know Your Options?" series. The next articles will be about built-in functions (BIFs) and their many uses. Until then, feel free to comment about, correct, and improve on this article in the comments section below or in one of the LinkedIn group discussions where my articles usually pop up!

Rafael Victoria-Pereira

Rafael Victória-Pereira has more than 20 years of IBM i experience as a programmer, analyst, and manager. Over that period, he has been an active voice in the IBM i community, encouraging and helping programmers transition to ILE and free-format RPG. Rafael has written more than 100 technical articles about topics ranging from interfaces (the topic for his first book, Flexible Input, Dazzling Output with IBM i) to modern RPG and SQL in his popular RPG Academy and SQL 101 series on mcpressonline.com and in his books Evolve Your RPG Coding and SQL for IBM i: A Database Modernization Guide. Rafael writes in an easy-to-read, practical style that is highly popular with his audience of IBM technology professionals.

Rafael is the Deputy IT Director - Infrastructures and Services at the Luis Simões Group in Portugal. His areas of expertise include programming in the IBM i native languages (RPG, CL, and DB2 SQL) and in "modern" programming languages, such as Java, C#, and Python, as well as project management and consultancy.


MC Press books written by Rafael Victória-Pereira available now on the MC Press Bookstore.

Evolve Your RPG Coding: Move from OPM to ILE...and Beyond Evolve Your RPG Coding: Move from OPM to ILE...and Beyond
Transition to modern RPG programming with this step-by-step guide through ILE and free-format RPG, SQL, and modernization techniques.
List Price $79.95

Now On Sale

Flexible Input, Dazzling Output with IBM i Flexible Input, Dazzling Output with IBM i
Uncover easier, more flexible ways to get data into your system, plus some methods for exporting and presenting the vital business data it contains.
List Price $79.95

Now On Sale

SQL for IBM i: A Database Modernization Guide SQL for IBM i: A Database Modernization Guide
Learn how to use SQL’s capabilities to modernize and enhance your IBM i database.
List Price $79.95

Now On Sale

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

Book Reviews

Resource Center

  •  

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: