Embed inside COBOL code
Inline REXX code as string in COBOL code can be passed to REXX SAA API via C Code
rexxsaa.h is a c Library offers API to invoke REXX from C.
REXX is almost like COBOL it is very useful code to be used as macro in MVS system.
Below code explains how to do it.
#include <stdio.h>
#include <string.h>
#include <rexxsaa.h>
int ocrexxcmd(char *cmds, char *args, char *resfield, int reslen, short *result) {
APIRET rexxapiret;
RXSTRING retstr;
RXSTRING arglist[1];
RXSTRING instore[2];
short rexxret = 0;
int ignore = 0;
/* For syntax check, no evaluate, taken from 8.4 of the Regina3.4 pdf */
arglist[0].strptr = "//T";
arglist[0].strlength = 3;
arglist[0].strptr = args;
arglist[0].strlength = strlen(args);
/* Move the command(s) to the instore array */
instore[0].strptr = cmds;
instore[0].strlength = strlen(cmds);
instore[1].strptr = NULL;
instore[1].strlength = 0;
/* Call Rexx. Use argcount 1 and &arglist to call syntax check */
retstr.strptr = NULL;
retstr.strlength = 0;
rexxapiret = RexxStart(1, (PRXSTRING)&arglist, "FILLER",
(PRXSTRING)&instore, "COMMAND" /* NULL */,
RXCOMMAND, NULL, &rexxret, &retstr);
/* set result back to GnuCOBOL */
memset(resfield, ' ', reslen);
if (rexxapiret == 0) {
memcpy(resfield, retstr.strptr,
(retstr.strlength > reslen) ? reslen : retstr.strlength);
*result = rexxret;
}
/* Let Rexx do all the memory alllocation */
if (instore[1].strptr != NULL) { ignore = RexxFreeMemory(instore[1].strptr); }
if (retstr.strptr != NULL) { ignore = RexxFreeMemory(retstr.strptr); }
return (int)rexxapiret;
}
/**/
COBOL Code
identification division.
program-id. testrexx.
data division.
working-storage section.
01 newline constant as x"0a".
01 trimmer usage binary-long.
01 apicode usage binary-long.
01 resultcode usage binary-short.
01 argument pic x(256) value 'OC1.1 args' & x"00".
01 cmds pic x(1024).
01 rexxstring pic x(1048576).
procedure division.
move "rc=10" & x"0a" &
"col=0" & x"0a" &
"ol=''" & x"0a" &
"Do i=1 To rc-1" & x"0a" &
"col=0" & x"0a" &
"Do j=i*(i-1)/2+1 to i*(i+1)/2" & x"0a" &
"col=col+1" & x"0a" &
"ol=ol '*'" & x"0a" &
"end" & x"0a" &
"ol=ol '0a'x" & x"0a" &
"end" & x"0a" &
"return ol" & x"00" to cmds.
compute
trimmer = function length(function trim(cmds))
end-compute
call "ocrexxcmd"
using
by reference cmds
by reference argument
by reference rexxstring
by value function length(rexxstring)
by reference resultcode
returning apicode
end-call
display function trim(rexxstring trailing) end-display
goback.
end program testrexx.
Compile C Code using cobc
$ cobc -c -lregina ocrexx.c
Compile COBOL Code including the .o file from the above compile
$ cobc -x -lregina testrexx.cob ocrexx.o
Run the COBOL EXE
$ ./testrexx
*
* *
* * *
* * * *
* * * * *
* * * * * *
* * * * * * *
* * * * * * * *
* * * * * * * * *
End Of Article