02
Sat, Nov
2 New Articles

Command Prompting 101

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

Have you ever called an RPG or CL program from a command entry program, passed parameters to it, and had a problem receiving the parameter's data? This problem started with the System/38 and still exists today.

The problem is that IBM had to decide how big a numeric value was going to default to when it was passed between the command entry display and a program. IBM chose Packed(15,5) as the default size for numeric parameter values and Char(30) for character parameter values.

This means that if you call a program from command entry or submit a call to the program via SBMJOB, the data specified for the parameters on that call are converted into temporary variables whose definition is, for numeric, Packed(15,5) and, for character, Char(30).

If the called program is expecting a numeric field in another size, you're going to see a data mapping error, or perhaps the data will pass through harmlessly if your program doesn't touch the parameter. But either way, you've got data defined differently than you intended.

This is why IBM used Packed(15,5) for the numeric parameters of such legacy APIs as QCMDEXC and QCMDCHK, which were frequently called from within CL programs.

With the huge influx of iSeries programmers over the last couple of years (outside North America and Europe), fundamental components of OS/400, such as creating a user-written CL command, are often overlooked as an easy solution.

A user-written CL command can solve this decades-old data mapping issue by providing a way to specify the type and length of each parameter being passed to a program. User-written CL commands are easy to create, but surprisingly are seldom implemented.

To create a user-written CL command, you first need a program that you want to call. This can be any program on your iSeries system, either written in-house or provided by a third party. A good example to illustrate this capability would be one of the OS/400 APIs, such as QSNDDTAQ (Send Data Queue).

The documentation for this API indicates that the first four parameters are required in order for the API to function properly. Those parameters are defined as follows:

QSNDDTAQ (Send Data Queue) Required Parameters
Parameter
Definition
Data queue name (DTAQ)
Char(10)
Data queue library (DTAQLIB)
Char(10)
Length of data (DATALEN)
Packed(5,0)
Data to queue (DATA)
Char(*)

The third and fourth parameters are the two we need to focus on.

Length of data (DATALEN) is defined as a Packed(5,0) value. If we call this API from command entry, the value will be converted into Packed(15,5), regardless of what we specify as the numeric parameter. Clearly, this is not what the API needs.

Data to queue (DATA) is defined as Char(*). This type of parameter often confuses RPG programmers. It simply means that the parameter is character in nature, but the length of the parameter is not fixed; it is based on other settings. Often, this indicates that a format code is passed to the API along with other values. However, this API gets the length of the data to queue from the value specified on the third parameter.

To create a nice little user-written CL command that can call this API, you need to launch the source code editor of your choice and specify CMD for the SEU attribute.

To start a user-defined command, the first line must be the CMD statement. It specifies the prompt text that appears at the top of the display when the command is prompted. For example, the CPYF command, when prompted, contains the following on the first line:

Copy File (CPYF)

To create something similar for the SNDDTAQ command, specify the following line of command definition source:

SNDDTAQ:    CMD  PROMPT('Send Data Queue Data')

The next line is something I established back in the early 1980s as a standard, and it has been widely used ever since. All user-written commands call a program, but there is no place to specify what that program is except when you compile the command. So I like to insert the name of the program that is going to be called as a comment on the second line. Add the following to the command definition source:

/*  Command processing program is QSNDDTAQ  */ 

The program that is called when our command is run is, in this example, the QSNDDTAQ API. Again, this is for documentation purposes.

The only thing left to do is create a definition for each of the corresponding parameters. The QSNDDTAQ API has multiple parameters, many of which are not required. So we can build a simple command definition with only the four parameters shown in the table above.

The first two parameters are fairly easy. They are Char(10) values, so to define them, you specify the following command definition statements:

    PARM  KWD(DTAQ) TYPE(*NAME) LEN(10) PROMPT('Data queue name')
    PARM  KWD(DTAQLIB) TYPE(*NAME) LEN(10) PROMPT(' Library') 

Note that I used TYPE(*NAME). I could have used TYPE(*CHAR), but the special type of *NAME allows the command prompter to check the specified value at runtime to make sure it conforms to a valid OS/400 object name. It does not verify that the actual object exists, only that the name specified is syntactically correct. Other than that, TYPE(*CHAR) and TYPE(*NAME) are very similar.

But let's not just give the user a basic prompt. Why not do slightly more? Let's modify these two statements so that a little more checking is performed when data is specified on them. Change the above two statements to the following:

   PARM  KWD(DTAQ) TYPE(*NAME) LEN(10) MIN(1) + 
         EXPR(*YES) PROMPT('Data queue name')
   PARM  KWD(DTAQLIB) TYPE(*NAME) LEN(10) DFT(*LIBL) +  
         SPCVAL((*LIBL) (*CURLIB)) EXPR(*YES) + 
         PROMPT(' Library') 

I've added the EXPR(*YES) keyword along with MIN(1) on the DTAQ parameter. EXPR allows you to specify a value for the parameter in a CL program that includes *TCAT and similar expressions. Without this, only a CL variable or a literal would be supported. The MIN(1) keyword indicates that the parameter is required—that is, a value must be specified or the command will not run and the prompter will reject it.

On the DTAQLIB parameter, I've added the DFT(*LIBL) keyword, which allows you to specify a default value for the parameter. This means the parameter need not be specified, and if it isn't, this value is passed to your program automatically. In addition, since the TYPE(*NAME) keyword is used, things like *LIBL and *CURLIB would not conform to a valid name syntax-checking scheme, so I have to tell the command that it is OK to allow the two special values specified on the SPCVAL((*LIBL) (*CURLIB)) keyword. I've also included the EXPR(*YES) keyword as I did on the DTAQ parameter.

Let's look at the final two parameters, DATALEN and DATA.

   PARM  KWD(DATALEN) TYPE(*DEC) LEN(5 0) + 
             PROMPT('Data length') 
   PARM  KWD(DATA) TYPE(*X) LEN(1) +
             PROMPT('Data')  

The DATALEN parameter is a Packed(5,0) value. To define it as such, specify TYPE(*DEC) and LEN(5 0). TYPE(*DEC) is used to define packed parameters (there is no direct support for zoned decimal parameter). Some of the other data types supported include the following:

Supported Data Types
Command Parameter Type
RPG IV Definition
*DEC
P (Packed)
*LGL
N (Named indicator)
*CHAR
A (Character)
*INT2
5I0 (Integer)
*INT4
10I0 (Integer)
*NAME
A (Character)
*GENERIC
A (Character)

This is not a complete list, but it does include the data types most often used in command definitions.

The DATA parameter is a little different from the other parameters. Its data type is TYPE(*X), and its length is set to (1). TYPE(*X) is not normally used with user-written commands, but I've used it for decades without any issues.

This data type is polymorphic. It can be used when the data type is not known until runtime. Normally, other PARM command keywords, such as PASSATR, are specified to help the program being called understand what type of data is being passed. But in our simple user-written command, we're using it because the length of the DATA parameter is really not known until runtime. In addition, the length must be specified on the DATALEN parameter.

To give you a more complete example of the source code for our user-written command, I've summarized the entire source member below:

 SNDDTAQ:    CMD        PROMPT('Send Data Queue Data') 
             /*         Command processing program is QSNDDTAQ  */ 
             PARM       KWD(DTAQ) TYPE(*NAME) LEN(10) MIN(1) + 
                          EXPR(*YES) PROMPT('Data queue name')
             PARM       KWD(DTAQLIB) TYPE(*NAME) LEN(10) DFT(*LIBL) + 
                          SPCVAL((*LIBL) (*CURLIB)) EXPR(*YES) + 
                          PROMPT(' Library') 
             PARM       KWD(DATALEN) TYPE(*DEC) LEN(5 0) + 
                          PROMPT('Data length') 
             PARM       KWD(DATA) TYPE(*X) LEN(1) PROMPT('Data')  

To compile this source code, use PDM option 14 or the CRTCMD command. (Yes, there's a Create Command command.) Be sure to specify the name of the command processing program (CPP) on the PGM parameter of the CRTCMD command, as follows:

CRTCMD CMD(SNDDTAQ)  PGM(QSNDDTAQ)

User-written commands are tokenized and stored in a user space with the same name as the command. Well, it isn't strictly a user space, but it is a space object that is 99% the same as a user space.

Once your user-written command is compiled, go to command entry, type in SNDDTAQ, and press F4. You'll see a prompt similar to Figure 1:

http://www.mcpressonline.com/articles/images/2002/Command%20Prompting%20101--07050600.jpg

Figure 1: SNDDTAQ gives you this prompt. (Click image to enlarge.)

To test this, I created a data queue in my library using CRTDTAQ and then ran the following command:

SNDDTAQ DTAQ(TESTQ1) DTAQLIB(COZZI) DATALEN(19) +
    DATA('Watch iSeriesTV.com')

To verify that this works, I used the DMPOBJ command and dumped the data queue. Then I used WRKSPLF to display the spool file and saw the string "Watch iSeriesTV.com" buried in the output in the right-hand column.

It would be relatively easy to modify this command to include the keyed data queue parameters. In fact, it would only require the following two additional PARM statements:

             PARM       KWD(KEYLEN) TYPE(*DEC) LEN(3 0) + 
                          DFT(*ZERO) SPCVAL((*ZERO 0)) +
                          PROMPT('Key length') 
             PARM       KWD(KEYDATA) TYPE(*X) LEN(1) +
                         SPCVAL((*BLANKS ' ')) PROMPT('Key Data')  

To add support for DDM data queues and their asynchronous option, the following parameter definition would be needed:

             PARM       KWD(ASYNC) TYPE(*CHAR) LEN(10) RSTD(*YES) + 
                          DFT(*NO) VALUES(*YES *NO) +
                          PROMPT('Async DDM data queue') 

User-written commands are still cool and can be used to solve a lot of simple problems, such as passing bad data to your programs. Learn them.

Bob Cozzi is a programmer/consultant, writer/author, and software developer of the RPG xTools, a popular add-on subprocedure library for RPG IV. His book The Modern RPG Language has been the most widely used RPG programming book for nearly two decades. He, along with others, speaks at and runs the highly-popular RPG World conference for RPG programmers.

BOB COZZI

Bob Cozzi is a programmer/consultant, writer/author, and software developer. His popular RPG xTools add-on subprocedure library for RPG IV is fast becoming a standard with RPG developers. His book The Modern RPG Language has been the most widely used RPG programming book for more than a decade. He, along with others, speaks at and produces the highly popular RPG World conference for RPG programmers.


MC Press books written by Robert Cozzi available now on the MC Press Bookstore.

RPG TnT RPG TnT
Get this jam-packed resource of quick, easy-to-implement RPG tips!
List Price $65.00

Now On Sale

The Modern RPG IV Language The Modern RPG IV Language
Cozzi on everything RPG! What more could you want?
List Price $99.95

Now On Sale

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

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

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • 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

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • 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: