Bob Marl Bob Marl - 2 months ago 7
C Question

as400: what is the C equivalent of SNDRCVF

I have a display file for a menu. I successfully made a working CL program which displays the menu and waits for input. Simply enough, all it does is display the file and waits for the user to press F1 to quit.

Display file (approximation):

A R DISPLAY
A CA01(01 'Exit')
A 2 2'some text....'


Creation command:
crtdspf file(display) srcfile(test) srcmbr(display)


CL program:

PGM
DCLF FILE(DISPLAY) RCDFMT(DISPLAY)
LOOP: SNDRCVF
IF COND(&IN01 *EQ '1') THEN(DO)
GOTO END
ENDDO
GOTO LOOP
END:
ENDPGM


Compile command:
crtclpgm pgm(test) srcfile(test) srcmbr(clsrc) output(*print)


What is the equivalent of SNDRCVF in C?

Here is what I've come with so far. It compiles fine, but when I call it, it does nothing.

#include <stdio.h>
#include <recio.h>

// Include my display file.
#pragma mapinc("display","lib/display(display)", "both", "")
#include "display"

// Shortcuts to the generated structs.
typedef LIB_DISPLAY_DISPLAY_i_t input_t;
typedef LIB_DISPLAY_DISPLAY_o_t output_t;

int main(int argc, char* argv[]){
input_t input;
output_t output;
_RFILE* dspf;

// The file opens fine.
dspf = _Ropen("lib/display", "wr");
if(dspf == NULL){
printf("ERROR: Display file open failed.\n");
return 0;
}

// I tell which record format to use.
_Rformat(dspf, "display");

// Write my file to display?
_Rwrite(dspf, "", 0);

// Wait for input.
_Rreadn(dspf, &input, sizeof(input), __DFT);

// Close it and quit.
_Rclose(dspf);
return 0;
}


Compile command:
crtbndc pgm(test) srcfile(test) srcmbr(main) output(*print)


Then call:
call test


What am I doing wrong?

Answer

I made a few minor changes. First, for your TYPEDEFs, I used this:

// Shortcuts to the generated structs.
typedef MYLIB_CDSPMNU_DISPLAY_both_t input_t;
typedef MYLIB_CDSPMNU_DISPLAY_both_t output_t;

Because you specified "both", the referenced identifier name should have 'both' rather than 'i' or 'o'. It's not clear how you could've successfully compiled as you had it. Perhaps you had an earlier successful compilation so that your CALL command worked, but the compiled program wasn't a current version.

Then I opened the file with this mode:

   // The file opens fine.
   dspf = _Ropen("mylib/cdspmnu", "rr+");

You had "wr", so it it was opened only for output ("wr"iting). You need it for input and output. Your joblog should show a C2M3005 "File is not opened for read operations." after you CALL your program (depending on what compiled version you actually CALL).

And I changed your _Rformat() function:

   // I tell which record format to use.
   _Rformat(dspf, "DISPLAY");

From the ILE C/C++ Runtime Library Functions manual, the definition of _Rformat() says:

The fmt parameter is a null-ended C string. The fmt parameter must be in uppercase.

The format name isn't folded to uppercase like file and library names are in other places. No idea why not; it's just the way it is. Personally, I'd use uppercase wherever it actually means an uppercase name without relying on the compiler; so I'd also change a couple other places in the code.

Technically, I also changed the DSPF source to reference the F3 key rather than the F1 key that you show in your DDS. The F1 key would normally be for 'help' functions while F3 is a standard for 'Exit'. That doesn't really matter, but it's one habit to get started. And a name or two was changed just to fit within my environment.

No spooled files were necessary. Easiest way to view your job's "joblog" after a CALL command is to run a DSPJOBLOG command. Perhaps better, though, is to use the basic command entry display provided by CALL QCMD. Basic joblog messages can be toggled on/off on that display by use of the F10 key to either "Include detailed messages" or "Exclude detailed messages".

All in all, you were pretty close. Not bad at all if this was your first attempt to work with a DSPF.

Comments