barbara_morris's Profile

  • Name: Barbara Morris
  • Email: (Private)
  • Member Since: Nov 13, 2008
  • Last Logged In: Nov 19, 2009 11:19 AM
  • Status Level:  

barbara_morris's Latest Content

One of the cool features of RPG is the "move fields" logic where data is moved from input buffers to program fields and from program fields to output buffers. Most RPG programmers don't think of this as cool - it is so fundamental to RPG that RPG programmers take it for granted.

When the RPG programmer defines a file in the RPG source, the compiler implicitly generates an internal program field for each field in the file, and the compiler also implicity moves data from the I/O buffers to the program fields for read and write operations to the file. If a particular field name appears in more than one file used by the RPG program, the field can be read from one file and then written out to the other file without any effort on the part of the RPG programmer.

Example: Say files FILE1 and FILE2 files have fields NAME and ADDR. A READ operation reads both those fields from file1 and a WRITE operation writes both those fields out to file2. It's not necessary to mention the field names in the source unless the fields are needed for some calculation.

    read FILE1;
    write FILE2;

If a new field CITY is added to both files, and the program is recompiled, the CITY field will automatically be handled by the READ and WRITE. No change is required to the program source.

If you look in your compiler listing, you can see the I and O specs that the compiler generates. These specs are not just descriptions of the I/O buffers. They are executable operations. The I specs are move operations from the Input buffer to the program fields, and the O specs are move operations from the program fields to the output buffer. It is because the I and O specs are executable operations to and from program fields that it's possible to have a field defined as packed in a database file and zoned in a screen file. RPG just does any necessary conversions when it move the data between the I/O buffers and the program fields.

You can see the I and O specs in action by stepping through the I and O specs in the debugger. You have to compile with OPTION(*DEBUGIO) and use the listing debug view.

The "move-fields" logic has always been part of RPG, or I should say it has been at least since RPG II. (I don't know much about the original RPG prior to RPG II.)

The EVAL-CORR opcode (added in v5r4) works in a similar way. If the READ and WRITE operations use data structures instead of using the I and O specs, you can assign all the same-name subfields from one data structure to another without actually mentioning the subfields by name. Just like the example above, the following code will automatically handle the new CITY subfields when the program is recompiled after the CITY fields are added to the files.
    read FILE1 ds1;
    eval-corr ds2 = ds1;
    write FILE2 ds2;


Even though I do think it is very cool the way RPG automatically handles the fields from files, I sometimes wonder if it would be better in the long run for program maintenance to have the movement of field data from file to file be more explicit. But that's a topic for another blog post.

1 Comments Permalink

Today is the 20th anniversary of my arrival at IBM and also my arrival in the AS/400 RPG Compiler Development department. The day I arrived, almost everyone was on vacation - there were only 3 other people working. It was near the end of development for V1R3.

My first couple of days were spent on an off-site RPG II self-study course, with no actual computer but only coding sheets to work with. Much of my time was spent scratching my head wondering why anyone would actually choose to code in this bizarre language.

When I got back, one of my co-workers showed me the online education system and told me to go through all the lessons, to learn about jobs, output queues, message queues, joblogs etc. (Too bad they took that education system away - it was very good.) He also told me to write an RPG program, using RPG/400 - nobody in the department was using RPG II except to investigate PMRs. I vaguely recall that it was a program to read all records of a file and output them to a printer file. And then a program to just do some calculations and write to a printer file. That's when I learned about the mysteries of "LR". ("What do you mean, the last record of the file? This program doesn't have a file." (Thanks, Y K, if you're reading this. You were a good teacher.)

The next week, with most people still on vacation, I started working on PMRs and APARs. On my first day, I got a call from support asking me to talk to a customer and explain why the SETLL opcode was behaving the way it was. Talk to a customer? About SETLL?!? What on earth is SETLL?" "Can you call me back in an hour?", I asked. "Sure." I found the SETLL opcode in the manual and read what I thought was a very clear explanation of how it worked. There was a paragraph that answered the customer's question exactly. When I finally was talking to the customer, I just read out that paragraph. The customer was very pleased with the clear explanation.

Around my sixth month, I got my first development project! It was to update the END opcode to allow ENDIF and ENDDO etc. During my design review, I was a bit taken aback by the amount of discussion about whether it should be just ENDDO to end DO/DOU/DOW, or ENDDO/ENDDU/ENDDW. Strangely, I can't remember whether just-ENDDO was my original design, or whether the design was changed to just-ENDDO during the meeting. I do remember that the key reason for just-ENDDO was to make it easier to change from one do-loop to another.

Along the way, some of the more memorable enhancements I've developed were: SORTA for overlay arrays, subprocedures, %EDITC/%EDITW, call-interaction with Java, LIKEDS, and XML-INTO, and local-files and file-parameters.

It's 20 years since that first RPG II course, and I'm still in the team that develops the RPG compilers for IBM i.

And now I can't imagine why anyone wouldn't want to code in RPG.

4 Comments Permalink

The problem

Strange but true: By default, RPG assumes that the CCSID of alphanumeric data is the mixed double-byte + single-byte CCSID that is related to the job CCSID.

This matters when all of the following conditions are met

  1. (very common) the actual job CCSID is a single-byte CCSID such as 37
  2. (quite common) conversions are done between alphanumeric data and UCS-2 data
  3. (rare) the alphanumeric data contains shift characters (x'0E' or x'0F')When the alphanumeric data is being converted to UCS-2, and the CCSID is assumed to be a mixed-byte CCSID, the "shift out" character x'0E' signals that the following data is double byte data; when the "shift in" character x'0F' is encountered, this signals a return to single byte data.

If this data is being converted to Unicode, and the data is not really supposed to be interpreted as mixed-byte data, then the Unicode version of the data will not be correct.

The solution

Code CCSID(*CHAR:*JOBRUN) in the H spec of all your modules.

If you are actually using a mixed JOB CCSID, nothing will change. If you are actually using a single byte CCSID, any conversions involving alphanumeric data containing x'0E' will be correct.

But I never have x'0E' in my single byte alphanumeric data

What never?

Well, hardly ever ...

0 Comments Permalink

barbara_morris's Blogs