/Free-ness has been expanded to H-specs, F-specs, D-specs, and P-specs, replacing them with control statements.
Editor's Note: This article is excerpted from chapter 13 of 21st Century RPG: /Free, ILE, and MVC, by David Shirey.
That’s right, P-specs. Since these are intimately connected with ILE, it is kind of surprising that they would not have been covered by /Free earlier, and those folks who did a lot of ILE prior to 7.1 were required to switch back and forth between positional and /Free to accommodate the P-specs. But that’s just tough, ain’t it, and now it’s only a forgotten piece of our history. Unless you’re not on 7.1.
So what does that look like? The position-less specs, that is. How different is an F-spec in /Free? Well, the first difference for F-specs, and H-specs, and the others is that in /Free the F-spec does not just look a little different, it doesn’t exist!
Remember? /Free does not have specs. It has control statements. We have not stressed this with the logic control statements (C-specs), but we will with the replacements for the other specs. Even so, unless the editors for this book are very good, you may find me referring to a “file control statement” as an F-spec. Old habits die hard.
/Free Delimiters
We said previously that /Free is processed by the same compiler as regular RPG, and so there needs to be something that tells the compiler what is /Free and what is positional. The rules on this vary depending on what release of i/OS you are on.
Up to TR7 of Release 7.1
That is, if you are on 5.4 or 6.1 or don’t have TR7, then that something was a set of delimiter tags, specifically, /Free, which indicates the start of a section of /Free code, and /end-Free, which indicates the end of that section. Both of these tags will start in column 7.
Above TR7 of 7.1 or on 7.2
If you are above that level, like on 7.2, for example, the compiler is smart enough to differentiate /Free logic statements from C-specs without any special delimiters. You would think they could have done that from the beginning, but they didn’t. And it’s possible the original delimiters were used more to highlight what was /Free and what wasn’t. What’s important is that at TR7 or above, you don’t need the /Free and /end-Free delimiters.
At 7.3 or TR3 of 7.2 or TR9 of 7.1
If you are at this level, then you get two new options.
First, you have more options in terms of the degree of “Free-ness” of your program.
You can continue to do things the way we have been describing them, using the delimiters (if you just like them) or not using the delimiters, intermingling /Free and positional code as the spirit moves you.
Or, you can lock down your program and force it to be /Free, preventing you from using any positional code at all. This is what is new at this level.
To do this (lock out positional), put **Free starting in position 1 at the top of your program (that is, line 1, not the first line of the logic statements). Then just code using /Free code, no positional, and it will be fine. If you do need to include positional code, you can do it with a /Copy. Of course, this would ability to use F- and D-specs; you would have to use the new control statements, but that’s what you should be doing anyway.
Second, this level of /Free eliminates the old 8–80 column limit. That is, you can put your code anywhere on the line, and you are not limited on either end. All in all, it’s just one more restriction removed, restrictions that other languages do not have, and so that is a good thing.
H-specs
OK. On to the control statements. Might as well start at the top, and the first thing we will run into are the H-specs.
The /Free replacement is called an option control statement, and it starts with ctl-opt and ends with a semicolon. That is something we should probably point out right at the start. These control statements are /Free statements, and, just as the logic control statements do, they also need to end with a semicolon.
Between the ctl-opt identifier and the semicolon, you may have one or more keywords.
As with the logic control statements in /Free, you have a lot of flexibility in how you write up these statements. For example, some people like to put related keywords (like maybe the keywords related to debugging) on the same ctl-opt. Or others might have multiple ctl-opt statements with just a single keyword on each line.
Similarly, if you do have multiple keywords on a control statement, you can either list them horizontally or vertically, as we did with IF statements. I will try to show various examples of this, but you will want to decide what seems best (most readable or clear) to you and standardize on that. Consistency is probably more important than picking one format over another.
Multiple parameters on a keyword are separated by colons (:), and the whole set of parameters for the keyword is surrounded by parentheses.
In its simplest form, the /Free form of the H-spec is:
ctl-opt;
If you specify just the statement keyword with no parameters, then all it accomplishes is to keep the compiler from looking for a control specification data area.
Most of the time, however, you will probably want to include some parameters with the keyword. Some of the more common keywords and parameters you might use include this for some of your debug options:
ctl-opt option (*srcstmt : *noiodebug);
Or, you might want to set up your activation group information depending on what the default in your compile command is. Note that like many /Free things, you can either list them horizontally or vertically. Remember, the end of the statement is not the end of the line but where the semicolon is. You gotta love the flexibility.
ctl-opt dftactgrp(*NO):
actgrp(*NEW);
One interesting thing to note is that you don’t need the DFTACTGRP(*NO) if there is at least one option for ACTGRP, BNDDIR, or STGMDL, all of which require the DFTACTGRP to be *NO. See how much time you are saving with /Free?
Some of the other parameter keywords that you might use include the following:
Any questions? Great. If there are, reread this section.
File Control Statements: Basic Format
And now, on to the F-specs. Oops, I mean file control statements.
Like the option control statements, the file control statements (FCS) starts with a statement keyword (dcl-f), then the name of the file, and finally whatever other descriptive keywords might be required. For example:
dcl-f MSPMP100 DISK;
Of course, being free form, you can write it in sentence format like this or put a few spaces in there, so it’s easier to read, such as:
dcl-f MSPMP100 DISK;
DCL-F pspsp100 DISK;
or however you want it to look.
Now let’s look at it in a little more detail. But before we do, we need to notice that while the H-spec replacement starts with ctl-opt, the F-spec replacement starts with dcl-f. All of the /Free specs start with a “dcl-something” except for the H-spec. I have no idea why. That’s just the way it is.
FCS: Details
Unfortunately, unlike option control statements, there are a lot more options to work out here. Let’s run through a few things.
What types of files can you define here?
Full procedural and output files only.
You cannot define table, record address, or cycle files with this statement. So what do you do if you just can’t live without one of those files? Simple: fall back on the F-spec. Remember, you can use either the F-spec or the file control statements and even mix them together with no problem (unless you have locked the program using **FREE). The same is true of other specs and control statements. And remember, you must be on TR7 7.1 or higher, otherwise you can’t do any of this.
If you do use specs with your control statements, you do not need to put a /Free and /end-Free delimiter around the /Free stuff. The compiler will know what is what.
How long can the name be?
You can use names longer than 10 digits as long as you use the EXTFILE and EXTDESC keywords. The EXTFILE must have a value of *EXTDESC, and the EXTDESC keyword will contain the 10-digit name of the file.
And if you were a fan of using ellipses here, you can’t do that anymore.
It should also be noted that you can’t use any of George Carlin’s “Seven words you can’t say on television” in the filename, although most people under 35 use them constantly in casual conversation. Actually, I use most of them pretty routinely as well. But hardly ever in filenames.
dcl-f Product_Master_File Disk EXTFILE(*EXTDESC)
EXTDESC('MSPMP100');
Is there some sort of order you need to list all of this stuff in?
Of course, what kind of world do you think we live in? Naturally, you start with the dcl-f keyword.
Then comes the filename.
Then the first keyword you need to specify is either the device keyword (DISK, PRINTER, SEQ, SPECIAL, or WRKSTN) or the LIKEFILE keyword.
After that, it’s a free for all. And speaking of the device keyword, here’s some more stuff.
FCS: DEVICE Keyword
In case you have forgotten over the last 28 words, the third thing you need to specify is the DEVICE keyword value (or else the LIKEFILE keyword). This is required.
And the values this DEVICE keyword can have are DISK, PRINTER, SEQ, SPECIAL, or WRKSTN. To be clear, what you enter in the file control option statement is DISK or PRINTER or whatever, not DEVICE(DISK), etc. As we will see in a moment, the DISK or PRINTER or whatever value can have a parenthesis-enclosed modifier of its own.
DISK is the default, and if you don’t put anything in, it will default to that (that is, if you don’t specify the DEVICE keyword at all). I know: if it’s required, but doesn’t really require you to enter a value, is it really required?
If the file is externally described, you can put the EXT value in parenthesis with the device keyword: DISK(*EXT) or PRINTER(*EXT). But that value is the default so, again, you can ignore it.
If we are dealing with a program-defined file, then you need to specify the length of the record along with the file type: PRINTER(132) or DISK(256). Is there a better reason for not using program-defined files?
So, for example, something like this might happen:
Again, note that I have listed the three keywords in a vertical format, but that is not required, and there is no particular column that these have to start in. But I like to list the keywords in a vertical format, and so do most cool people. It’s up to you, though.
One thing that should be re-mentioned here is that because this is free format, you need to end each statement with a semicolon. The question is, does this mean a semicolon on every line? And the answer is, no, just on the final line of a given control statement. Good grief, what do you think this is? A police state?
FCS: KEYED Keyword
Remember the K flag to indicate a file was keyed? That has been replaced by the KEYED keyword. And if you have a keyed file, you need to use this.
For an externally described file, there is no value attached to this keyword; it will pick it up from the file definition.
dcl-f MSPMP100 DISK Keyed;
For a program-described file, you can indicate a value of *CHAR:len where len is the length of the key (duh). Unfortunately, I guess, only *CHAR keys are supported right now. But then again, I don’t dig program-described files. Why not define it externally? Are you ashamed of it? Whatever. In the example below, we have a program-defined file with a length of 120 and an eight-character key.
dcl-f Prog_File Disk(120) Keyed(*CHAR:8);
What if you have a packed key? Well, then you make it an externally described file. Or, if you insist, either through willfulness or the same type of behavior that has been strongly linked to juvenile delinquency and drug abuse, you can define the key as *CHAR in your file control statement (almost said “spec”) and then lay that out in a data structure, like so:
And the nice thing about this is that it shows how you can mix dcl-f statements and dcl-ds statements so they are next to each other. That is, the end-ds statement could be followed by another dcl-f. Free-form.
FCS: USAGE Keyword
The USAGE keyword replaces the file type (I, O, U) and the file addition (A) flags in the F-spec—à la USAGE(*INPUT).
You can specify more than one usage, like *UPDATE and *OUTPUT or *INPUT and
*OUTPUT. If you’re listing more than one usage value, use a colon to separate them: USAGE(*UPDATE:*DELETE).
In F-specs, a U can be update and/or delete, but in /Free *DELETE is its own man and must be specified if you want to do a delete.
The default for DISK is INPUT, for PRINTER is OUTPUT, for WRKSTN is (*INPUT:*OUTPUT), and for SEQ and SPECIAL is *INPUT.
Of course, the old hierarchy still holds. So *UPDATE implies *INPUT, and *DELETE implies *UPDATE and *INPUT. We aren’t changing everything. All we are doing is making things more visible, more obvious.
Fortunately, most keywords currently used in F-specs can still be used for file control statements. This includes things like the RENAME or the PREFIX. But for a full view of what is still supported you should check out the ILE RPG Reference (http://www-01.ibm.com/support/knowledgecenter/#!/ssw_ibm_i_71/books/ sc092508a.pdf). What you need to look at here are the lines with a “|” next to them. This shows things that are new in the 7.1 PTF and cover the new free-form control statement details.
What Ya Shoulda Learned
First, you need to know that if you are on a release of the IBM i OS that is below 7.1, TR7, then you do not have the ability to use any of the control statements we have discussed. Refer to the WRKPTFGRP instructions in chapter 2 to see how to check your TR level. If you are not on 7.1 TR7 or above, then none of this will work for you, and everything (except for C-specs) must be set up as specs.
Second, if you are above the 7.1 TR7 line, then you can use either specs or control statements for H-, F-, D-, and P-specs.
Third, H-specs are being replaced by ctl-opt control statements.
Fourth, F-specs are being replaced by dcl-f control statements, with a variety of keywords replacing the old positional codes.
Fifth, for all control statements the format is more or less the same:
There will be no F or H or D or whatever in column 6.
The control statement will begin anywhere in column 8 to 80.
The format is /Free, so that amount of space you leave between different keywords is up to you.
It starts with a dcl-?? (for F-, D-, and P-specs) and opt=?? for H-specs.
Then at the end there is a semicolon.
Sixth, the following rules also apply:
The compiler is smart enough to know what is /Free and what is positional, and no tags are required.
You can mix /Free with positional like some sort of pagan warrior, and there are no consequences. Sure, go ahead, be lawless.
Seventh, if you are on 7.3 or higher, then both of the above rules apply. Plus, you get two more things. I know, confusing, isn’t it?
First, you can force your source to be just /Free by using the **FREE tag in position 1 on the very first line of the source. Now you can’t use any positional code (include F-, D-, or other specs, which have a /Free version). And definitely no I- or O-specs since they do not have a /Free format.
Second, if you are at this level, then you can put your /Free code anywhere starting with column 1 and go past the normal 80-column limit depending on just how large your source record is.
Want to learn more? You can pick up Dave Shirey's book, 21st Century RPG: /Free, ILE, and MVC, at the MC Press Bookstore Today!
LATEST COMMENTS
MC Press Online