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
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
LATEST COMMENTS
MC Press Online