/*********************************************************************/
/*                                                                   */
/*  File Name:          CALLREXX1.C                                   */
/*                                                                   */
/*  Description:        Samples of how to invoke the Object REXX     */
/*                      interpreter.                                 */
/*                                                                   */
/*  Entry Points:       main - main entry point                      */
/*                                                                   */
/*  Input:              None                                         */
/*                                                                   */
/*  Output:             returns from the Object REXX programs        */
/*                                                                   */
/*********************************************************************/

#define INCL_RXSHV
#define INCL_RXSYSEXIT

#define INCL_REXXSAA
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <curses.h>
#include "rexx.h"                                             /* @MIC002A */


//#include <sys/ldr.h>
//#include <filehdr.h>

#include <dlfcn.h>
#include <sys/stat.h>

#include <errno.h>

PCHAR   pcharTemp;

int main()
{
    RXSTRING arg[4];                      /* argument string for REXX  */
    RXSTRING rexxretval;                  /* return value from REXX    */
    RXSTRING instore[2];                  /* in storage parms          */
    CHAR     *pszTemp;
    PRXSTART FuncAddress;
    APIRET   rc = 0;                      /* return code from REXX      */
    LONG     rexxrc = 0;                  /* return code from function  */

    CHAR    val;
    CHAR    *str1 = "Arg number one";            /* text to swap   */
    CHAR    *str2 = "Arg number two";            /* text to swap   */
    CHAR    *str3 = "Arg number three";          /* text to swap   */
    CHAR    *str4 = "Arg number four";           /* text to swap   */
    CHAR    *prg1 = "say Arg(1)";       /* text to swap   */
    CHAR    *sync_tst = "call time 'Reset';" \
                        "object1 = .example~new;" \
                        "object2 = .example~new;" \
                        "object3 = .example~new;" \
                        "a.1 = object1~start('REPEAT', 4 , 'Object 1 running');" \
                        "say a.1~result;" \
                        "say 'The result method waits until the START message has completed:';" \
                        "a.2 = object2~start('REPEAT', 2, 'Object 2 running');" \
                        "a.3 = object3~start('REPEAT', 2, 'Object 3 running');" \
                        "say a.2~result;" \
                        "say a.3~result;" \
                        "say 'main ended';" \
                        "say 'Elapsed time: ' time('E');" \
                        "exit;" \
                        "::REQUIRES 'example.cmd'";

    /* By setting the strlength of the REXX output to zero, the        */
    /* interpreter allocates memory.                                   */
    /* We can provide a buffer for the interpreter to use instead.     */
    /* If the returned value does not fit into the buffer, Object REXX */
    /* creates a new one.                                              */

    system("clear");

    rexxretval.strptr = NULL;         /*initialize return-pointer to empty*/
    rexxretval.strlength = 0;         /*initialize return-length to zero  */

    printf("This is an easy sample of how to invoke the REXX interpreter. \n");
    printf("The REXX commandfile which is started is named: startrx1.cmd\n");

    printf("Press Enter to continue\n");
    scanf("%c", &val);


    /* This is the interpreter invocation.                        */

    rc=REXXSTART(
            (LONG)       0,              /* number of arguments   */
            (PRXSTRING)  NULL,           /* array of arguments    */
            (PSZ)        "startrx1.cmd", /* name of REXX file     */
            (PRXSTRING)  NULL,           /* No INSTORE used       */
            (PSZ)        "ksh",          /* Command env. name     */
            (LONG)       RXCOMMAND,      /* Code for how invoked  */
            (PRXSYSEXIT) NULL,           /* No EXITs on this call */
            (PSHORT)     &rexxrc,        /* Rexx program output   */
            (PRXSTRING)  &rexxretval );  /* Rexx program output   */

    printf("CALLREXX1 - Back from REXXSTART:  Return Code: %d\n", rc);
    printf("CALLREXX1 - RESULT-LENGTH:           %d\n", rexxretval.strlength);
    printf("CALLREXX1 - RESULT-Value:            %s\n", rexxretval.strptr);

    RexxWaitForTermination();
    free(rexxretval.strptr);

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    system("clear");

    printf("In this case a previously defined Resultstring is \n");
    printf("delivered to Object REXX, which is large enough to \n");
    printf("hold the Return Value of the REXX commandfile\n");

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    rexxretval.strptr = (char *) malloc(100 * sizeof(char));
    rexxretval.strlength = 100;

    rc=REXXSTART(
            (LONG)       0,              /* number of arguments   */
            (PRXSTRING)  NULL,           /* array of arguments    */
            (PSZ)        "startrx1.cmd", /* name of REXX file     */
            (PRXSTRING)  NULL,           /* No INSTORE used       */
            (PSZ)        "ksh",          /* Command env. name     */
            (LONG)       RXCOMMAND,      /* Code for how invoked  */
            (PRXSYSEXIT) NULL,           /* No EXITs on this call */
            (PSHORT)     &rexxrc,        /* Rexx program output   */
            (PRXSTRING)  &rexxretval );  /* Rexx program output   */

    printf("CALLREXX1 - Back from REXXSTART:  Return Code: %d\n", rc);
    printf("CALLREXX1 - RESULT-LENGTH:           %d\n", rexxretval.strlength);
    printf("CALLREXX1 - RESULT-Value:            %s\n", rexxretval.strptr);

    RexxWaitForTermination();
    free(rexxretval.strptr);

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    system("clear");

    printf("In this case a previously defined Resultstring is \n");
    printf("delivered to Object REXX, which is too small to\n");
    printf("hold the Return Value of the REXX commandfile.\n");
    printf("REXX reallocates the buffer which needs to be freed\n");
    printf("in the calling program\n");

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    rexxretval.strptr = (char *) malloc(2 * sizeof(char));
    pszTemp = rexxretval.strptr;
    rexxretval.strlength = 2;

    printf("The Length of the Resultstring is %d\n", rexxretval.strlength);

    rc=REXXSTART(
            (LONG)       0,              /* number of arguments   */
            (PRXSTRING)  NULL,           /* array of arguments    */
            (PSZ)        "startrx1.cmd", /* name of REXX file     */
            (PRXSTRING)  NULL,           /* No INSTORE used       */
            (PSZ)        "ksh",          /* Command env. name     */
            (LONG)       RXCOMMAND,      /* Code for how invoked  */
            (PRXSYSEXIT) NULL,           /* No EXITs on this call */
            (PSHORT)     &rexxrc,        /* Rexx program output   */
            (PRXSTRING)  &rexxretval );  /* Rexx program output   */

    printf("CALLREXX1 - Back from REXXSTART:  Return Code: %d\n", rc);
    printf("CALLREXX1 - RESULT-LENGTH:           %d\n", rexxretval.strlength);
    printf("CALLREXX1 - RESULT-Value:            %s\n", rexxretval.strptr);

    RexxWaitForTermination();
    free(rexxretval.strptr);

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    system("clear");

    rexxretval.strptr = NULL;         /*initialize return-pointer to empty*/
    rexxretval.strlength = 0;         /*initialize return-length to zero  */

    printf("This is a sample with 4 arguments delivered to  \n");
    printf("REXXSTART\n");
    printf("The REXX commandfile which is started is named: startrx2.cmd\n");

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    MAKERXSTRING(arg[0], str1, strlen(str1)); /* create input argument 1     */
    MAKERXSTRING(arg[1], str2, strlen(str2));/* create input argument 2    */
    MAKERXSTRING(arg[2], str3, strlen(str3));/* create input argument 2    */
    MAKERXSTRING(arg[3], str4, strlen(str4));/* create input argument 2    */

    rc=REXXSTART(
            (LONG)       4,              /* number of arguments   */
            (PRXSTRING)  arg,            /* array of arguments    */
            (PSZ)        "startrx2.cmd", /* name of REXX file     */
            (PRXSTRING)  NULL,           /* No INSTORE used       */
            (PSZ)        "ksh",          /* Command env. name     */
            (LONG)       RXCOMMAND,      /* Code for how invoked  */
            (PRXSYSEXIT) NULL,           /* No EXITs on this call */
            (PSHORT)     &rexxrc,        /* Rexx program output   */
            (PRXSTRING)  &rexxretval );  /* Rexx program output   */

    printf("CALLREXX1 - Back from REXXSTART:  Return Code: %d\n", rc);
    printf("CALLREXX1 - RESULT-LENGTH:           %d\n", rexxretval.strlength);
    printf("CALLREXX1 - RESULT-Value:            %s\n", rexxretval.strptr);

    RexxWaitForTermination();
    free(rexxretval.strptr);

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    system("clear");

    printf("This is a sample with 2 arguments delivered to  \n");
    printf("REXXSTART\n");
    printf("The REXX commandfile which is started is named: startrx2.cmd\n");

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    rexxretval.strptr = NULL;         /*initialize return-pointer to empty*/
    rexxretval.strlength = 0;         /*initialize return-length to zero  */

    rc=REXXSTART(
            (LONG)       2,              /* number of arguments   */
            (PRXSTRING)  arg,            /* array of arguments    */
            (PSZ)        "startrx2.cmd", /* name of REXX file     */
            (PRXSTRING)  NULL,           /* No INSTORE used       */
            (PSZ)        "ksh",          /* Command env. name     */
            (LONG)       RXCOMMAND,      /* Code for how invoked  */
            (PRXSYSEXIT) NULL,           /* No EXITs on this call */
            (PSHORT)     &rexxrc,        /* Rexx program output   */
            (PRXSTRING)  &rexxretval );  /* Rexx program output   */

    printf("CALLREXX1 - Back from REXXSTART:  Return Code: %d\n", rc);
    printf("CALLREXX1 - RESULT-LENGTH:           %d\n", rexxretval.strlength);
    printf("CALLREXX1 - RESULT-Value:            %s\n", rexxretval.strptr);

    RexxWaitForTermination();
    free(rexxretval.strptr);

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    system("clear");

    printf("This is a sample where the directory listing of the   \n");
    printf("actual directory is returned by the REXX program. The \n");
    printf("returned ResultString is displayed\n");
    printf("The REXX commandfile which is started is named: startrx3.cmd\n");

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    rexxretval.strptr = NULL;         /*initialize return-pointer to empty*/
    rexxretval.strlength = 0;         /*initialize return-length to zero  */

    rc=REXXSTART(
            (LONG)       0,              /* number of arguments   */
            (PRXSTRING)  NULL,           /* array of arguments    */
            (PSZ)        "startrx3.cmd", /* name of REXX file     */
            (PRXSTRING)  NULL,           /* No INSTORE used       */
            (PSZ)        "ksh",          /* Command env. name     */
            (LONG)       RXCOMMAND,      /* Code for how invoked  */
            (PRXSYSEXIT) NULL,           /* No EXITs on this call */
            (PSHORT)     &rexxrc,        /* Rexx program output   */
            (PRXSTRING)  &rexxretval );  /* Rexx program output   */

    printf("CALLREXX1 - Back from REXXSTART:  Return Code: %d\n", rc);
    printf("CALLREXX1 - RESULT-LENGTH:           %d\n", rexxretval.strlength);
    printf("CALLREXX1 - RESULT-Value:            %s\n", rexxretval.strptr);

    RexxWaitForTermination();
    free(rexxretval.strptr);

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    system("clear");

    printf("This is a sample where the instore parameter [0] is \n");
    printf("tested. Instore parameter [0] is loaded with \n");
    printf("a small Object REXX script showing the concurrency feature.\n");

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    instore[0].strptr = sync_tst;
    instore[0].strlength = strlen(instore[0].strptr);
    instore[1].strptr = NULL;
    instore[1].strlength = 0;

    rc=REXXSTART(
            (LONG)       0,              /* number of arguments   */
            (PRXSTRING)  NULL,           /* array of arguments    */
            (PSZ)        NULL,           /* name of REXX file     */
            (PRXSTRING)  instore,        /* No INSTORE used       */
            (PSZ)        "ksh",          /* Command env. name     */
            (LONG)       RXCOMMAND,      /* Code for how invoked  */
            (PRXSYSEXIT) NULL,           /* No EXITs on this call */
            (PSHORT)     &rexxrc,        /* Rexx program output   */
            (PRXSTRING)  &rexxretval );  /* Rexx program output   */

    printf("CALLREXX1 - Back from REXXSTART:  Return Code: %d\n", rc);
    printf("CALLREXX1 - RESULT-LENGTH:           %d\n", rexxretval.strlength);
    printf("CALLREXX1 - RESULT-Value:            %s\n", rexxretval.strptr);

    RexxWaitForTermination();
    free(rexxretval.strptr);

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    system("clear");

    printf("Now instore[1] is loaded with the content of instore[0]. \n");
    printf("It can be used on subsequent calls. instore[0] is set to NULL \n");

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    instore[0].strptr = NULL;
    instore[0].strlength = 0;

    rc=REXXSTART(
            (LONG)       0,              /* number of arguments   */
            (PRXSTRING)  NULL,           /* array of arguments    */
            (PSZ)        NULL,           /* name of REXX file     */
            (PRXSTRING)  instore,        /* No INSTORE used       */
            (PSZ)        "ksh",          /* Command env. name     */
            (LONG)       RXCOMMAND,      /* Code for how invoked  */
            (PRXSYSEXIT) NULL,           /* No EXITs on this call */
            (PSHORT)     &rexxrc,        /* Rexx program output   */
            (PRXSTRING)  &rexxretval );  /* Rexx program output   */

    printf("CALLREXX1 - Back from REXXSTART:  Return Code: %d\n", rc);
    printf("CALLREXX1 - RESULT-LENGTH:           %d\n", rexxretval.strlength);
    printf("CALLREXX1 - RESULT-Value:            %s\n", rexxretval.strptr);

    RexxWaitForTermination();
    free(rexxretval.strptr);
    free(instore[1].strptr);

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    system("clear");

    printf("This is a sample to show how to use the REXX MacroSpace facility. \n");
    printf("First of all load_macro.cmd is called to load \n");
    printf("the REXX script macros.cmd into Macrospace. The Macrospace- \n");
    printf("name is upload.cmd. \n");

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    rexxretval.strptr = NULL;         /*initialize return-pointer to empty*/
    rexxretval.strlength = 0;         /*initialize return-length to zero  */

    rc=REXXSTART(
            (LONG)       0,              /* number of arguments   */
            (PRXSTRING)  NULL,           /* array of arguments    */
            (PSZ)        "load_macro.cmd", /* name of REXX file     */
            (PRXSTRING)  NULL,           /* No INSTORE used       */
            (PSZ)        "ksh",          /* Command env. name     */
            (LONG)       RXCOMMAND,      /* Code for how invoked  */
            (PRXSYSEXIT) NULL,           /* No EXITs on this call */
            (PSHORT)     &rexxrc,        /* Rexx program output   */
            (PRXSTRING)  &rexxretval );  /* Rexx program output   */

    printf("CALLREXX1 - Back from REXXSTART:  Return Code: %d\n", rc);
    printf("CALLREXX1 - RESULT-LENGTH:           %d\n", rexxretval.strlength);
    printf("CALLREXX1 - RESULT-Value:            %s\n", rexxretval.strptr);

    RexxWaitForTermination();
    free(rexxretval.strptr);

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    system("clear");

    printf("Now the Object REXX script macros.cmd (named upload.cmd) has been loaded\n");
    printf("into Macrospace. It is now used in the name option of\n");
    printf("the REXXSTART command. \n");
    printf("It is very important that instore paramenter [0] and [1] are\n");
    printf("initialized to NULL rsp. 0 and used as REXXSTART parameters\n");

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    rexxretval.strptr = NULL;         /*initialize return-pointer to empty*/
    rexxretval.strlength = 0;         /*initialize return-length to zero  */

    instore[1].strptr = NULL;
    instore[1].strlength = 0;
    instore[0].strptr = NULL;
    instore[0].strlength = 0;

    rc=REXXSTART(
            (LONG)       0,              /* number of arguments   */
            (PRXSTRING)  NULL,           /* array of arguments    */
            (PSZ)        "upload.cmd",   /* name of REXX file     */
            (PRXSTRING)  instore,        /* No INSTORE used       */
            (PSZ)        "ksh",          /* Command env. name     */
            (LONG)       RXCOMMAND,      /* Code for how invoked  */
            (PRXSYSEXIT) NULL,           /* No EXITs on this call */
            (PSHORT)     &rexxrc,        /* Rexx program output   */
            (PRXSTRING)  &rexxretval );  /* Rexx program output   */

    printf("CALLREXX1 - Back from REXXSTART:  Return Code: %d\n", rc);
    printf("CALLREXX1 - RESULT-LENGTH:           %d\n", rexxretval.strlength);
    printf("CALLREXX1 - RESULT-Value:            %s\n", rexxretval.strptr);

    RexxWaitForTermination();
    free(rexxretval.strptr);

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    system("clear");

    printf("Finally del_macro.cmd is called to delete macros.cmd (named upload.cmd)\n");
    printf("out of the Object REXX Macrospace.\n");

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    rc=REXXSTART(
            (LONG)       0,              /* number of arguments   */
            (PRXSTRING)  NULL,           /* array of arguments    */
            (PSZ)        "del_macro.cmd",   /* name of REXX file     */
            (PRXSTRING)  NULL,           /* No INSTORE used       */
            (PSZ)        "ksh",          /* Command env. name     */
            (LONG)       RXCOMMAND,      /* Code for how invoked  */
            (PRXSYSEXIT) NULL,           /* No EXITs on this call */
            (PSHORT)     &rexxrc,        /* Rexx program output   */
            (PRXSTRING)  &rexxretval );  /* Rexx program output   */

    printf("CALLREXX1 - Back from REXXSTART:  Return Code: %d\n", rc);
    printf("CALLREXX1 - RESULT-LENGTH:           %d\n", rexxretval.strlength);
    printf("CALLREXX1 - RESULT-Value:            %s\n", rexxretval.strptr);

    RexxWaitForTermination();
    free(rexxretval.strptr);

    printf("Press Enter to continue\n");
    scanf("%c", &val);

    system("clear");
}

