04
Mon, Nov
1 New Articles

Freedom of Choice in C-Compilers

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

Stacking C/400 against the competition -- Diploma/C

by Don Denoncourt

For a decade, the midrange product line has given us few alternatives for programming languages. RPG and, to a lesser extent, COBOL and PL/I were the only viable languages available for business application programming. IBM was basically saying, "You can buy any compiler you want -- as long as it's blue."

Today, however, we can choose C as an alternative language on the AS/400. C is a Systems Application Architecture (SAA) language that is excellent for creating portable applications. Also, for the first time on the AS/400, we have an alternative source for a 3GL compiler -- Amalgamated Software of North America offers Diploma/C. Immediately, questions arise: is one compiler better than the other? Will the one you select support all the functions you need? Perhaps things were easier when IBM made all the decisions for you. After all, no one ever got fired for buying IBM. But ASNA has done some excellent work creating Diploma/C. The days of managers buying only IBM are over.

How do the two available C compilers stack up against each other? What about compatibility with the standards of SAA and the American National Standards Institute (ANSI)? How good are the AS/400-specific functions like externally defined file support and keyed record access? Do Diploma/C and C/400 handle call/parms? Do they support inline SQL or MI? Finally, what does one compiler provide that the other does not?

I compared the two C environments, C/400 and ASNA's Diploma/C, using IBM's OS/400 Release 3.0. I also took into consideration IBM's add-on to C/400 -- System/C. System/C allows you to code IBM-approved MI instructions.

Standards

Both C/400 and Diploma/C fully support the ANSI standard for the C language. The ANSI standard for C is a set of guidelines for supported functions and their parameters. The end result is that code which conforms to the ANSI standard will be highly portable to other platforms. Functions that are hardware-specific are not always portable -- for example, C code written on a PC to directly access screen memory to achieve a higher execution speed. This type of function would have to be rewritten to be ported successfully. Some standard ANSI C functions include the file open, close, input, and output functions.

IBM's SAA levels I and II are supported by both Diploma/C and C/400. SAA is IBM's response to the DEC/VAX method of writing applications that are portable across all of DEC's platforms.

There is another level, if not yet a standard, of functions available in Diploma/C and C/400. This level of functions, which IBM categorizes as extended, is for AS/400-specific programming. These functions include such things as externally defined file support and keyed record access. Both Diploma/C and C/400 refer to these AS/400 file functions as "record I/O." The standard for ANSI C is a "Character or Stream I/O" method of file operations. This method for record I/O is implemented through system-specific functions. ANSI C really does not do any record I/O except indirectly, through buffering data to a data structure delimited by its size or to a character string delimited by a linefeed character.

The C/400 compile command has an option that allows *SAA, *SAAL2, *ANSI or *EXTENDED to be entered. This option causes the compiler to flag any functions which are beyond the scope of the standard for that compile option. Diploma/C has no such compile option. ASNA did, however, use a simple naming convention for their AS/400-specific functions. ANSI and SAA functions were already named by the ANSI committee and IBM. Diploma/C prefixed all of their AS/400 extended functions with a two-character underscore __. All of their io5250 data-streaming functions are prefixed with a single underscore _. Neither the ANSI nor the SAA standards use non-alpha prefixes. Note that it is an unwritten standard in C environments that underscore prefixes for functions and field names are reserved for compiler-specific use.

I/O in the AS/400 Environment

Experienced C programmers are accustomed to working with files as "streams." In the ANSI environment, a stream is read into a C program one byte at a time. The problem ASNA and IBM had with the AS/400 is that it can read a file only one record at a time. To provide ANSI stream support, both Diploma/C and C/400 had to simulate the byte-at-a-time stream process. This stream simulation was necessary to provide compatibility with the ANSI standard file I/O functions.

Every C program will automatically open three streams -- STDIN, STDOUT, STDERR. These streams are generic files for use as simplified and standard input, output, and error messaging. Most ANSI environments default all of these three files to the terminal display. In the standard ANSI environment, everything is a stream, including the display. The standard files can, on most systems, be piped (overridden) to other streams. STDOUT is often piped to the printer and STDIN is regularly piped to a file.

Diploma/C and C/400 both support the three standard files, but for some reason, Diploma/C's are all prefixed with DC. Both environments allow the standard files to be overridden to other files via OVRDBF. A Diploma/C program submitted to batch will abort when it cannot attach the DCSTDIN DCSTDOUT DCSTDERR files to a display. Therefore, all Diploma/C programs must be overridden before the automatic open is performed. I found this quite aggravating. I inelegantly solved the problem by creating a generic batch CL program to override the standard files and then call the C program. C/400 is smart enough to automatically override the standard files if they are not overridden before a batch open. C/400 will then override STDIN to QINLINE, STDOUT and STDERR to QPRINT.

The standard input environment is worth some mention. Using STDIN can be a quick method of writing simple screen I/O programs. When a Diploma/C or C/400 program opens the interactive STDIN file, a session manager takes over to handle stream I/O from the screen. On many platforms, byte-at-a-time stream I/O allows programs to respond immediately to single keystrokes. On the C/400 and Diploma/C implementations, the session manager must wait until enter is pressed before processing input. This works fine, without the fancy use of ALT-X and other PC-style screen control codes. The session manager will automatically scroll the screen up as I/O occurs. The programmer should take care to handle the lines displayed on a screen, since the page may start rolling out of sight. At this point, the C program could prompt the user to press enter to continue the list.

C/400 allows use of some of the standard SAA function keys when the Session Manager takes over the screen. The F9 key will retrieve the last screen input line and the F21 key will extend the line. C/400 also allows use of the roll keys to review scrolled screen I/O, and the F3 key to abort the executing C program and end the session manager. Diploma/C does not support these function keys on standard screen I/O; however, it more than makes up for this omission with its io5250 stream processing.

If you refer to back issues of Midrange Computing (April and May, 1990) you will find a series of interesting articles on 5250 data-streaming. You can gain almost total control of the display with the methods of screen I/O defined in these articles. I found the articles fascinating, but the RPG methodology awkward and complex. In contrast, Diploma/C's io5250 data-streaming functions are quite simple to understand and use. Because of some of the implementation performance problems of the AS/400, Diploma/C's io5250 screen processing method is slower than DDS. Nevertheless, ASNA's innovative technique of screen I/O does some amazing things.

Diploma/C's io5250 data-streaming functions allow dynamically defined structures called screens, frames, and fields. A screen is a state of a display's image that can be saved and restored. This allows you to display one screen and write to another saved screen while waiting for input from the user. A frame is a group of field definitions that is written and read, to and from the screen. The io5250 field structures define the attributes of displayable characters and their relation to a frame. ASNA has written their UNIX-like C-debugger totally with io5250 data-streaming. The UNIX-style of debugging would not have been possible using standard methods. More on debugging later.

The Code

The big issue for RPG III programmers is not ANSI or SAA compatibility, but availability of standard AS/400 functions. ANSI programming is fully supported with either compiler, so let's just get on with some of the stuff we do every day in RPG III. If you look at Figures 3-5, you will see the AS/400 extended functions provided by ASNA and IBM. As you can see, there is little similarity between Diploma/C and C/400 record I/O functions. Both compilers do, however, provide a full range of AS/400 database access.

The pseudocode in 1 describes the processes of the Diploma/C and C/400 record I/O programs listed in6 and 8.

The pseudocode in Figure 1 describes the processes of the Diploma/C and C/400 record I/O programs listed in Figures 6 and 8.

Note that the lines prefixed with a + in6 and 8 are for the type definitions record structure created by the compiler to provide external file support. Diploma/C goes one step further than C/400 when generating the record structure. For each packed field, a macro is created using the field name as part of the macro name to simplify packed conversion in your programs. In my Diploma/C DCBILL example (6), I used macros provided by Diploma/C's preprocessor to pack and unpack the company number. These macros save you from having to code the field and decimal length into the packed conversion functions.

Note that the lines prefixed with a + in Figures 6 and 8 are for the type definitions record structure created by the compiler to provide external file support. Diploma/C goes one step further than C/400 when generating the record structure. For each packed field, a macro is created using the field name as part of the macro name to simplify packed conversion in your programs. In my Diploma/C DCBILL example (Figure 6), I used macros provided by Diploma/C's preprocessor to pack and unpack the company number. These macros save you from having to code the field and decimal length into the packed conversion functions.

It is possible that the greatest reason for the variance in Diploma/C and C/400's record I/O functions is that ASNA was the first to provide them. IBM could not have copied ASNA, now, could they? Well, at any rate, Diploma/C may provide more compatibility with C/400 in later releases. As of Release 2.04, Diploma/C does have a compile option to provide some compatibility with C/400 OS/400 Release 2.0's functions. For example, Diploma/C will allow use of IBM's C/400 Extended Program Module's QXXITOP and other packed conversion routines if the macro _C400 is defined.

If you look at 3 closely, you will notice a few omissions in Diploma/C's record I/O functions. Diploma/C, as of yet, does not support journaling, commitment control, data-areas, or acquiring control of devices. I did find, however, that Diploma/C's record I/O functions were more straightforward and simpler to use in coding with than C/400's.

If you look at Figure 3 closely, you will notice a few omissions in Diploma/C's record I/O functions. Diploma/C, as of yet, does not support journaling, commitment control, data-areas, or acquiring control of devices. I did find, however, that Diploma/C's record I/O functions were more straightforward and simpler to use in coding with than C/400's.

SQL is another alternative for I/O on the AS/400. C/400 fully supports embedded SQL, as well as dynamic SQL. The only other language that supports dynamic SQL is PL/I, since only these two languages support the use of pointers. Diploma/C does not support the use of embedded SQL at this time.

Compiling, Binding and Linking

Let's venture far away from familiar RPG territory and into C's rocky terrain of compiling, binding, and linking. Most C environments create executable code by first compiling, then linking. The compile command actually does two steps itself -- preprocessing and syntax checking. Preprocessing brings in function definitions requested by the at the beginning of the code, and extends macros into standard C code. The compiler then checks the C code for correct syntax. If the syntax is correct, the compiler will create an object that is not yet an executable program. This object has lists of functions used by the program that are coded elsewhere -- typically, standard ANSI functions and other user functions coded in other source files. To create the executable program, the function references must be "resolved" or pulled into an executable environment. This process is generally known as linking.

This compile and link process is one area in which Diploma/C and C/400 differ greatly. Diploma/C works much like PC-based C compilers, with the two-step compile and link process. After C source code is entered, the programmer does a CRTDCTU which does the preprocessing and syntax checking and, if the code has no errors, creates a translation unit. The translation unit is actually a data area that has an object attribute of TU. I created a user-defined PDM option, TU, to submit a batch CRTDCTU. The Diploma/C translation unit can then be linked with other user-created TUs to create an object program. Again I created a user-defined PDM option, DC, to submit a batch Diploma/C CRTDCPGM. The Diploma/C Create Program command defaults to creating a statically linked program. Static linking resolves external references once, when the program is created. Note that to link statically, all of the TUs must be available at link time. Also, if any of the TUs change after the program is created, then they must be relinked.

Diploma/C also supports dynamic linking, which resolves entering references at run time and typically creates faster-running code. This process is suggested by ASNA for such times as when a program size gets too large to perform efficiently, or when a group of functions are used infrequently. By linking at run time, the code that is executing actually has a smaller program size. This space is saved because the program does not have a copy of the externally referred-to functions like a statically linked program would. Functions that are not used often can be set up so they are linked to the executing code only when they are called. ASNA calls this process "binding."

The Diploma/C programmer selects which programs should be statically linked and then groups them into segments with the Diploma/C command, CRTDCSEG. To then bind segments of code into an executable program object, the Diploma/C command BNDDCPGM is used. The program needs only to be bound once. Rebinding is necessary only when the parameter declarations of one function of a bound segment have been altered.

IBM's EPM dynamically links C/400 programs at run time. It is quite a different animal than Diploma/C and other C implementations when it comes to the compile and link process. IBM threw C in with a group of programming languages that have multiple entry points and shared data - including Pascal and FORTRAN. An entry point is simply a function in C. The default entry point in C is the main() function. IBM has created the EPM environment on the AS/400 to handle the unique nature of these languages, and for some of BASIC's implementations needs. The EPM handles the following areas:

1) the run time environment 2) the session manager 3) an exception handler 4) the debugging tool 5) application library routines

It may seem like I have digressed here from compiling and linking, but the EPM handles dynamic linking at run time. The SETPGMINF command "defines" the run time environment, and EPM uses that definition to create the environment at run time. The environment is implicitly created and deleted by OS/400 when a main() function is called. Explicit creation and deletion of non-main() linked environments are user-controlled by calling the QPXXCALL and QPXXDLTE EPM interface programs, or by using the CL commands STREPMENV and ENDEPMENV. Usually the programs that must use these last strange calls and commands are written in non-EPM languages like RPG, COBOL, and CL. Note that if all of the functions of a C/400 program including a main() function are in one source file, the SETPGMINF command need not be done by the programmer to make the program ready for execution.

Both Diploma/C and C/400 provide a listing of the seconds to compile and link C source into a program object. As brief but complete examples, the Diploma/C program took a total of 118.9 seconds to create, and the C/400 program took 427.0 seconds to create.

EPM does allow C/400 to do something that Diploma/C cannot -- it allows calls to non-main() entry points. This capability is similar to what you would have if RPG allowed calls to specific subroutines from another program. A non-main entry point is a compiled C function other that the main() function. Normally, non-main() functions are linked to a C main() function. Imagine the capability to call functions that may have been developed for a complete C application from within an RPG program. An RPG or COBOL program need only invoke the EPM environment to call the non-main C program. To do this type of thing in Diploma/C, you would have to create a "dummy" main() source program that would contain the desired function and then have the other RPG program call the main() routine.

ANSI C programs handle main() entry parameters with an integer variable and a pointer to an array-of-pointers variable. In standard ANSI calls to a main routine, the program name is followed by the passing variables. The variables are put into the array of pointers from the second array element on. The operating system will place the called program name into the first array element, and the number of passed variables into the integer variable.

Calling the Programs

Okay, so now that we have created all of these Diploma/C and C/400 programs, let's get down to how you call them. There are some differences. For example, to call my Diploma/C DCBILL and C/400 bill programs from the command entry, I used the following:

PGM(DCBILL) PARM('123456 123' 10)

PGM(BILL) PARM('123456' '123')

123456 is the part number for which a bill should be listed, and 123 is the company number. In the DCBILL call, the 10 is simply the length of the first string. The Diploma/C default parameter method is to put all of the passed variables in parameter one, delimited by spaces, and the length of parameter one as parameter two. Actually, parameter two is needed in Diploma/C only when parameter one is longer than eighteen bytes. The Diploma/C method of passing variables could cause a problem when you wish to pass a value that contains embedded blanks. Calling a C/400 program requires a parameter for each variable. Take note, however, that the called example programs DCBILL and BILL use exactly the same syntax to receive the parameters. I could also have called the bill-of-material programs from an RPG program with the following syntax:

Diploma/C:

MOVEL'123456' PRMSTR 10 MOVE '011' PRMSTR Z-ADD10 PRMLEN 20 CALL 'DCBILL' PARM PRMSTR PARM PRMLEN

C/400:

MOVE '123456' PARTNO 15 MOVE '011' CPYNO 3 CALL 'DCBILL' PARM PARTNO PARM CPYNO

I believe the C/400 calling parameter method is the better method. To call a C/400 program from RPG, the parameter variables would be set up just like a call to another RPG program. With Diploma/C, the variables would have to be set up into a single variable with space delimiters. Diploma/C enthusiasts needn't fret though. ASNA thoughtfully added a link option to allow use of the standard AS/400 calling conventions. Therefore, if you like, calls to Diploma/C programs can be done exactly like C/400 calls.

Debugging

C/400 programs can be debugged almost like any RPG programs, with STRDBG and ADDBKP. IBM knew, however, that the standard OS/400 debugging methods were simply not enough for C. Let's face it -- with C you can really screw things up. Pointers, structures, variable references like strct.ptr->field, memory allocation and deallocation . . . it's a lot to manage. You will use the EPM debugger to debug a C/400 program. The EPM debugger is actually for all of the EPM languages, but it does provide some capabilities specific to C/400. If you refer to the EPM options (see 9), you can immediately extrapolate most of the functionality available with these commands during a debug session. I will therefore cover only several of the more complex and C-specific commands used.

C/400 programs can be debugged almost like any RPG programs, with STRDBG and ADDBKP. IBM knew, however, that the standard OS/400 debugging methods were simply not enough for C. Let's face it -- with C you can really screw things up. Pointers, structures, variable references like strct.ptr->field, memory allocation and deallocation . . . it's a lot to manage. You will use the EPM debugger to debug a C/400 program. The EPM debugger is actually for all of the EPM languages, but it does provide some capabilities specific to C/400. If you refer to the EPM options (see Figure 9), you can immediately extrapolate most of the functionality available with these commands during a debug session. I will therefore cover only several of the more complex and C-specific commands used.

The break command requires the program and function names, and the statement number. You can also request the break to occur at the return point of a function. The cryptic view command (,) allows all complex C structures to be listed along with the optional attributes of the variable. Attributes of a variable are the data type, storage class, length, and the function where the variable was declared. Format specifiers like that in the ANSI printf() can also be used. The following would list fifteen bytes of the string variable field pointed to by ptr of the structure strct:

, strct.ptr->field%.15s

Data aggregates, such as a complete structure or array, can be viewed with the (?) command. Lengthy variable declarations can become quite time-consuming in a debug session, but EPM provides for that also. The equate command lets you create a macro during the debug session to avoid rekeying the debugging commands. For instance, to create a macro for the lengthy view command example, enter:

equate Y , strct.ptr->field%.15s

Then, whenever you desire to look at the field value, you would simply enter Y. The EPM manual provides excellent documentation and examples for the debugging commands. As good as the EPM C/400 debugging commands are, the Diploma/C UNIX-like debugger is much easier to use. After you enter the Diploma/C command STRDCDBG, the integrated environment screen is displayed. The screen is split, allowing the top portion for display of the C source and the bottom for the debugging commands. Entering "help" or "h" will display the debugging commands listed in 8. Many of these commands are similar in nature to the IBM EPM commands. The B F function name command will display the requested function source in the top portion of the split screen. Besides browsing source by function, you can also browse a source file's member or browse source by the TU name.

Then, whenever you desire to look at the field value, you would simply enter Y. The EPM manual provides excellent documentation and examples for the debugging commands. As good as the EPM C/400 debugging commands are, the Diploma/C UNIX-like debugger is much easier to use. After you enter the Diploma/C command STRDCDBG, the integrated environment screen is displayed. The screen is split, allowing the top portion for display of the C source and the bottom for the debugging commands. Entering "help" or "h" will display the debugging commands listed in Figure 8. Many of these commands are similar in nature to the IBM EPM commands. The B F function name command will display the requested function source in the top portion of the split screen. Besides browsing source by function, you can also browse a source file's member or browse source by the TU name.

To change Diploma/C's screen split line simply requires positioning the cursor to the desired line and pressing F6. Setting breakpoints can also be done with a single keystroke. You simply position the cursor to the source line on which you wish to break, and press F13. Displaying SEU line numbers can be toggled with F4. F16, like SEU, performs a find. F9 retrieves the last debug command used in the bottom portion of the screen. F7 and F8 start and end a copy function. Diploma/C's debugger was written entirely in C using the io5250 screen functions. ASNA plans to continue to improve its debugger. If they can achieve the complete debugging capabilities of those provided on many PC C platforms, debugging programs may even become a pleasant experience.

System/C

A little now about IBM's System/C. System/C, like Diploma/C, allows static linking, hence the internal name for System/C -- "Freestanding C." System/C provides access to AS/400 system functions and ninety of the MI instructions. System/C supports many ANSI functions, but not all. No file I/O is supported in System/C. IBM had System/C set up to work with C/400; in fact, System/C will not work without C/400 installed. Nevertheless, because of its static linking, many C/400 sites will purchase System/C for the purpose of writing highly used, high-speed functions.

I brought System/C up not so much to critique it, but to compare its system functions with Diploma/C's inline MI. Diploma/C allows use of all of the AS/400 MI instructions, unlike System/C, which supports only ninety. This may be a moot point since OS/400 Release 3.0 restricts creation of MI instructions that access what IBM feels is "secure." This appears to be true even if a AS/400 C development site is using security level 30. ASNA feels confident, however, that they can continue to develop Diploma/C's MI capabilities regardless of IBM's security constraints. Basically, if you wish to do only a little systems programming, Diploma/C's inline MI would be appropriate. System/C would be easier to use for programming system functions -- that is, the ones that IBM allowed in System/C.

If you are considering price and want some MI and system access, Diploma/C would be the more inexpensive product when compared with System/C and C/400.

Documentation

Diploma/C provides two relatively thin manuals. One is a user guide with many good examples and concise explanations of Diploma/C use. As far as C/400 manuals are concerned, I was once told that you must read IBM manuals backwards to understand them. I think I was better off having read the Diploma/C manuals first. This allowed me to better grasp AS/400 C implementation issues. The C/400 user guide contained poor and mostly incomplete examples. There was one complete example for keyed record access but it did not use the #pragma mapinc directive to include the externally defined record format. But as usual, everything is available somewhere in the C/400 manuals if you keep reading the "refer to" text.

Diploma/C also provides some excellent sample source with its distribution tape. C/400 also included a sample source file -- the infamous "Hello World" program -- that ought to clear some things up for you. Both C compiler environments have on-line support available. C/400 has its ECS, and ASNA has what it calls ESS. ESS works much like ECS in that you can dial up their electronic support, review fixes and additions, and selectively download them. I must say that the technical phone support from ASNA was very good. They answered all of my questions within a short period, faxed documentation, and overnighted recent releases. All of this excellent support was provided before they were aware of my intention to write this article.

Which One?

You can get a pretty good idea of the salient differences between C/400 and Diploma/C by looking at 2. If you are using SQL, journaling, or commitment control, C/400 may be your choice. Otherwise, Diploma/C offers many advantages over C/400, and it costs less than the combination of C/400 and System/C. If compile and run times are a real issue, Diploma/C stands out. But then, IBM's non-main entry points allow dynamic system modularity. Aside from matters of compiler capabilities, one advantage of Diploma/C is the level of user support. If you are new to C programming, it is nice to have help just a phone call away. Your choice of a compiler really comes down to a choice between being "blue" or not. ------------------------------------------------------------------------------- PC PLATFORM C SUPPORT

You can get a pretty good idea of the salient differences between C/400 and Diploma/C by looking at Figure 2. If you are using SQL, journaling, or commitment control, C/400 may be your choice. Otherwise, Diploma/C offers many advantages over C/400, and it costs less than the combination of C/400 and System/C. If compile and run times are a real issue, Diploma/C stands out. But then, IBM's non-main entry points allow dynamic system modularity. Aside from matters of compiler capabilities, one advantage of Diploma/C is the level of user support. If you are new to C programming, it is nice to have help just a phone call away. Your choice of a compiler really comes down to a choice between being "blue" or not. ------------------------------------------------------------------------------- PC PLATFORM C SUPPORT

Compilation times can be a real issue with both compilers. Because of the nature of free-format code, any C compiler can find only so many syntax errors before it gets confused. For instance, if the compiler finds missing semi-colons (statement terminators), it thinks that the next line is part of the same statement. After the compiler discovers several errors of this nature, the compile will terminate. On the AS/400, where the batch compiles are all but mandatory, this compilation process becomes a real time-burner. The first time this happened to me, I created a C source file, and compiled it. One error. Fine. I corrected that error, submitted a recompile, and went home for the weekend. On Monday, I had a compilation listing with ten errors. This compile/edit process went on for several hours. With RPG you could find all your syntax errors in one pass...well, maybe you guys could!

In frustration, I set up a PC platform to develop AS/400 C code. Sounds fancy? No, it was easy. I simply downloaded the header files provided by one of the AS/400 C-compilers to a new directory on my 386sx PC. I then directed my PC C-compiler to look at the new directory for the header include files. The only problem was the external file definitions. I had to enter the record format structures manually. Later, I plan to create an AS/400 process to create and download the appropriate C record structures for externally defined files. The compile/edit process with my integrated PC-based C compiler is fantastic. I can do a compile with a keystroke. The actual compile takes seconds for a two to three page source file. On the AS/400 I would have started working on something else while the C compile waited in a batch queue, ran, and then, finally, sent me my abnormal termination message. Ten recompiles could have taken me all day with my attention diverted to other things. On my PC it was taking me ten minutes or so, plus a minute or two to then upload the syntax-free source file. You can gain all this developmental speed with a PC, PC-support, and a $200 integrated environment PC compiler. Of course, you cannot link and run any C source that references any AS/400-specific functions like record I/O.


Freedom of Choice in C-Compilers

Figure 1 Pseudocode for sample C program

 
  Figure 1: Pseudocode for Sample C Program 
 
  1.  Pull the externally defined Bill of Material record format into a C 
      structure. 
 
  2.  Set up a FILE pointer to the Bill of Material. 
 
  3.  Set up a data buffer that will allow access to the Bill's C structure's 
      field names. 
 
  4.  OPEN the Bill of Material. 
 
  5.  Setup a KEY LIST with a packed company number and a character part number. 
 
  6.  DISPLAY the values used in the key list to STDOUT. 
 
  7.  DO WHILE more components for the passed part and company numbers are 
      available. 
 
  8.  READ the component record. 
 
  9.  DISPLAY the parent and component part number to STDOUT. 
 
  10. END DO. 
 
  11. CLOSE the Bill of Material file. 

Freedom of Choice in C-Compilers

Figure 2 Benefits table

 
  Figure 2: Benefits Table 
 
  Diploma/C                                  C/400 
  -----------------------------------        ------------------------------------ 
  Simpler extended functions                 Dark Blue 
  Inline MI                                  Inline SQL 
  Phone support                              Journaling 
  IO5250 data-streaming                      Commitment Control 
  Unix-like debugger                         System/C 
  Dynamic Linking/Run Speed                  non-main()interfacecalls 
  Compiles Faster than C/400 
  Price when compared to 
   C/400 & System/C 

Freedom of Choice in C-Compilers

Figure 3 C/400 record I/O functions

 
  Figure 3: C/400 Record I/O Functions 
 
  _Rclose       Close a file (CLOSE) 
  _Rdelete      Delete the locked record (DELET) 
  _Rfeod        Force an end-of-data condition (FEOD) 
  _Ropen        Open a file (OPEN) 
  _Rreadd       Get a record by RRN (CHAIN) 
  _Rreadf       Get the first record 
  _Rreadk       Get a record by key 
  _Rreadl       Get the last record 
  _Rreadn       Get the next record (READ) 
  _Rreadnc      Get the next changed SFL record (READC) 
  _Rreadp       Get the previous record (READP) 
  _Rreads       Get the same record 
  _Rrlslck      Release a locked record 
  _Rupdate      Update the current record (UPDAT) 
  _Rwrite       Put a record (WRITE) 
  _Rwrited      Put a record directly by RRN 
  _Rwriterd     Put a record then read it back (EXFMT) 

Freedom of Choice in C-Compilers

Figure 4 C/400 record I/O macros

 
  Figure 4: C/400 Record I/O Macros 
 
  _Racquire     Acquire a program device (ACQ) 
  _Rcommit      Commit data changes to file (COMIT) 
  _Rdevatr      Get device attributes 
  _Rformat      Set the record format name 
  _Rindara      Set a separate indicator area 
  _Riofbk       Input/Output feedback information 
  _Ropnfbk      Pointer to feedback information 
  _Rlocate      Position file cursor (SETLL) 
  _Rpgmdev      Set default program device 
  _Rreadindv    Get from invited device 
  _Rrelease     Release a program device (REL) 
  _Rrollbck     Roll back data changes (ROLBCK) 

Freedom of Choice in C-Compilers

Figure 5 Diploma/C record I/O functions

 
  Figure 5: Diploma/C Record I/O Functions 
 
  __chain       Get a record by key or RRN (CHAIN) 
  __crtkeylist  Create a multi-field key (KLIST) 
  __delete      Delete the locked record (DELET) 
  __feod        Force an end-of-data condition (FEOD) 
  __inreclen    Get the record length 
  __key         Get the key of last record read 
  __read        Get the next record (READ) 
  __reade       Get the next record of equal key (READE) 
  __readep      Get previous record of equal key (REDPE) 
  __readp       Get the previous record (READP) 
  __release     Release a locked record 
  __rrn         Get the RRN of the last record read 
  __setformat   Set the record format name 
  __setindara   Set separate indicator area 
  __setgt       Position file > a key or RRN (SETGT) 
  __setge       Position file >= a key or RRN (SETLL) 
  __update      Update the current record 
  __write       Put a record (WRITE) 
  __writeread   Put a record then read it back (EXFMT) 
  __writesubf   Put a SFL record (WRITE) 

Freedom of Choice in C-Compilers

Figure 6 Diploma/C program DCBILL

 
  Figure 6: Diploma/C Program DCBILL 
 
  #include  
  #include  
  #include  
  #include  
  #include  
  #include  
 
  /* pull in external file description */ 
  #pragma edf DONLIB/PST pz N 
  +   typedef  struct { 
  +       char    CPY 2 ;         /* company number packed 3/0 */ 
  +               #define PSTR_CPY_2i     __ptoi(p,3,0) 
  +       char    PARENT 15 ;     /* parent part number character 15 */ 
  +       char    CMPNT 15 ;      /* component part number character 15 */ 
  +       char    QTY 5 ;         /* quantity per packed 9/0 */ 
  +               #define PSTR_QTY_2i     __ptoi(p,9,0) 
  }   PSTR_in; 
 
  int  main (int argc, char *argv   ) 
  { 
     FILE *pf;              /* file pointer */ 
     PSTR_in  *inbuf;      /* input buffer */ 
     void     *bill_key;   /* product structure file key pointer */ 
     char K_CPY sizeof(inbuf->CPY) ; 
     char K_PARENT 15  = "               "; 
 
     /* set up and print key list */ 
     memcpy (K_PARENT, argv 1 , strlen(argv 1 )); 
     PSTR_CPY_i2 ( K_CPY, atoi ( argv 2  ) ); 
     printf("
key list: %d, %.15s
", PSTR_CPY_2i(K_CPY), K_PARENT); 
 
     pf  = fopen ("*libl/PST",     "r  type=record"); 
     if (pf == 0) printf("PST not found
"); 
     inbuf  = (PSTR_in  *) _RIO_recbuf(pf); 
     __setformat (pf, "PSTR"); 
 
     bill_key = __crtkeylist(PSTR_keydef, 2, K_CPY, K_PARENT); 
     __setgte(pf, _KEYL, bill_key); 
 
     while (__reade(pf, _KEYL, bill_key, 0) == _RIO_GOOD) 
         printf("Bill: %.15s %.15s
", inbuf->PARENT,inbuf->CMPNT); 
     fclose (pf); 
     return (0); 
  } 

Freedom of Choice in C-Compilers

Figure 7 C/400 program BILL

 
  Figure 7: C/400 Program BILL 
 
  #include  
  #include  
  #include  
  #include  
  #include  
 
  /* pull in external file description */ 
  #pragma mapinc("wrklib/dbf/pst","donlib/pst(pstr)","input key","p z") 
  #include "wrklib/dbf/pst" 
  +   typedef  struct { 
  +       char    CPY 2 ;         /* company number packed 3/0 */ 
  +       char    PARENT 15 ;     /* parent part number character 15 */ 
  +       char    CMPNT 15 ;      /* component part number character 15 */ 
  +       char    QTY 5 ;         /* quantity per packed 9/0 */ 
  }   DONLIB_PST_PSTR_i_t; 
  +   typedef  struct { 
  +       char    CPY 2 ;         /* company number packed 3/0 */ 
  +       char    PARENT 15 ;     /* parent part number character 15 */ 
  }   DONLIB_PST_PSTR_key_t; 
 
  int  main (int argc, char *argv   ) 
  { 
     _RFILE *pf;                       /* file pointer */ 
     _RIOFB_T *fb;                     /* record I/O Open feedback pointer */ 
     DONLIB_PST_PSTR_i_t inbuf;        /* input buffer */ 
     DONLIB_PST_PSTR_key_t bill_key;   /* product structure file key pointer */ 
     /* set up and print key list */ 
     memcpy (bill_key.PARENT,"               ", 15); 
     memcpy (bill_key.PARENT,argv 1 , strlen(argv 1 ) ); 
     QXXITOP (bill_key.CPY, 3, 0, atoi( argv 2  ) ); 
     printf("
key list: %d, %.15s
", QXXPTOI (bill_key.CPY, 3, 0), 
                                       bill_key.PARENT); 
 
     pf  = _Ropen ("*libl/PST", "rr+"); 
     if (pf == 0) { printf("PST not found
"); exit(1); } 
 
     fb = _Rreadk(pf, &inbuf, sizeof(inbuf), __KEY_EQ, bill_key.CPY,17); 
     if (fb->num_bytes == 0) { printf("record not found
"); exit(2); } 
 
     while (fb->num_bytes != 0) { 
         printf("Bill: %.15s %.15s
", inbuf.PARENT, inbuf.CMPNT); 
         fb = _Rreadk(pf, &inbuf, sizeof(inbuf), __KEY_NEXTEQ, 
      bill_key.CPY,17); 
     } 
     _Rclose (pf); 
     return (0); 
  } 

Freedom of Choice in C-Compilers

Figure 8 Diploma/C debugger commands

 
  Figure 8: Diploma/C Debugger Commands 
 
  Abreak  ( funcname || seu || #mi 
  BFunction name 
  BMember libr/file memb 
  BTunit  (libr/) name 
  CALL    pgm < parameters > 
  Cmd01 Cmd03 Cmd05 Cmd06 Cmd07 Cmd08 Cmd09 Cmd10 Cmd11 
    Cmd12 Cmd13 Cmd16 
  DBreaks 
  DFuncs < -as > 
  DLocation 
  Dmembers 
  DSegments 
  DTunits < -as > 
  DVariable < -fstx > ( name || #hexmi) < , ( name || #hexmi).. 
  Go 
  Help < topic > 
  Quit 
  RBreak  ( funcname || seu || #mi 
  Set ( seg || Tunit ) valu 
  / < command > 

Freedom of Choice in C-Compilers

Figure 9 EPM debugger commands

 
  Figure 9: EPM Debugger Commands 
 
  ?aggregate      Format an aggregate 
  ,variable       Display a variable 
  Break           Set a breakpoint 
  Change          Change a variable 
  Display Debug   Display current resume point 
  Display Breaks  Display currently set breakpoints 
  Display Equates Display currently set equates 
  Display Names   Display all routines in current module 
  Display Trace   Display invocation chain of routines 
  Display Varsg   Display list all variables 
  END or QUIT     Halt program 
  Equate          Set identifier to literal value 
  Go              Continue running program 
  Help key        This command list 
  Qualify         Set default module/routine 
  Remove          Remove a specific breakpoint 
  Remove ALL      Remove all breakpoints 
  Set Attr        Set deault viewing information ON/OFF 
  Set Show        Set default viewing all data ON/OFF 
  Set Qual        Set default viewing qualification ON/OFF/BLK 
  SYstem          Enter Command Entry mode 
Don Denoncourt

Don Denoncourt is a freelance consultant. He can be reached at This email address is being protected from spambots. You need JavaScript enabled to view it..


MC Press books written by Don Denoncourt available now on the MC Press Bookstore.

Java Application Strategies for iSeries and AS/400 Java Application Strategies for iSeries and AS/400
Explore the realities of using Java to develop real-world OS/400 applications.
List Price $89.00

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: