523 lines
24 KiB
C
523 lines
24 KiB
C
/*----------------------------------------------------------------------------*/
|
|
/* */
|
|
/* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
|
|
/* Copyright (c) 2005-2021 Rexx Language Association. All rights reserved. */
|
|
/* */
|
|
/* This program and the accompanying materials are made available under */
|
|
/* the terms of the Common Public License v1.0 which accompanies this */
|
|
/* distribution. A copy is also available at the following address: */
|
|
/* https://www.oorexx.org/license.html */
|
|
/* */
|
|
/* Redistribution and use in source and binary forms, with or */
|
|
/* without modification, are permitted provided that the following */
|
|
/* conditions are met: */
|
|
/* */
|
|
/* Redistributions of source code must retain the above copyright */
|
|
/* notice, this list of conditions and the following disclaimer. */
|
|
/* Redistributions in binary form must reproduce the above copyright */
|
|
/* notice, this list of conditions and the following disclaimer in */
|
|
/* the documentation and/or other materials provided with the distribution. */
|
|
/* */
|
|
/* Neither the name of Rexx Language Association nor the names */
|
|
/* of its contributors may be used to endorse or promote products */
|
|
/* derived from this software without specific prior written permission. */
|
|
/* */
|
|
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
|
|
/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
|
|
/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
|
|
/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
|
|
/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
|
|
/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
|
|
/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
|
|
/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
|
|
/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
|
|
/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
|
|
/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
|
/* */
|
|
/*----------------------------------------------------------------------------*/
|
|
/*********************************************************************/
|
|
/* */
|
|
/* File Name: CALLREXX2.C */
|
|
/* */
|
|
/* ----------------------------------------------------------------- */
|
|
/* */
|
|
/* Description: Samples of how to invoke the Open Object Rexx*/
|
|
/* interpreter. It loads the Rexx library at */
|
|
/* runtime. */
|
|
/* */
|
|
/* Entry Points: main - main entry point */
|
|
/* */
|
|
/* Input: None */
|
|
/* */
|
|
/* Output: returns from the Open Object Rexx programs */
|
|
/* */
|
|
/*********************************************************************/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <dlfcn.h>
|
|
#include <sys/stat.h>
|
|
#include <errno.h>
|
|
|
|
#include "rexx.h"
|
|
|
|
char *pcharTemp;
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
CONSTRXSTRING arg[4]; /* argument string for Rexx */
|
|
RXSTRING rexxretval; /* return value from Rexx */
|
|
RXSTRING instore[2]; /* in storage parms */
|
|
PFNREXXSTART FuncAddress;
|
|
void *pLibHandle = NULL; /* Library handle */
|
|
RexxReturnCode rc = 0; /* return code from Rexx */
|
|
short rexxrc = 0; /* return code from function */
|
|
#ifdef __APPLE__
|
|
const char *pszLibraryName = "librexx.dylib"; /* define the library name */
|
|
#else
|
|
const char *pszLibraryName = "librexx.so"; /* define the library name */
|
|
#endif
|
|
char returnBuffer[100];
|
|
int ignore; // avoid warning: ignoring return value of 'system'
|
|
// avoid warning: ignoring return value of 'scanf'
|
|
|
|
char val;
|
|
const char *str1 = "Arg number one"; /* text to swap */
|
|
const char *str2 = "Arg number two"; /* text to swap */
|
|
const char *str3 = "Arg number three"; /* text to swap */
|
|
const char *str4 = "Arg number four"; /* text to swap */
|
|
|
|
const 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.rex'";
|
|
|
|
if (!(pLibHandle = dlopen(pszLibraryName, RTLD_LAZY )))
|
|
{ /* Load and resolve symbols immediately */
|
|
fprintf(stderr, " *** Unable to load library %s !\nError message: %s\n",
|
|
pszLibraryName, dlerror());
|
|
return 99;
|
|
}
|
|
|
|
if(!(FuncAddress = (PFNREXXSTART) dlsym(pLibHandle, "RexxStart")))
|
|
{
|
|
rc = 1; /* could not resolve */
|
|
fprintf(stderr, " *** Unable to load function %s !\nError message: %s\n",
|
|
"RexxStart", dlerror());
|
|
return 99;
|
|
}
|
|
|
|
|
|
/* 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, */
|
|
/* Open Object Rexx creates a new one. */
|
|
|
|
ignore = 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.rex\n");
|
|
|
|
printf("Press Enter to continue\n");
|
|
ignore = scanf("%c", &val);
|
|
|
|
|
|
/* This is the interpreter invocation. ------------------------------ */
|
|
|
|
rc = (*FuncAddress)(
|
|
0, /* number of arguments */
|
|
NULL, /* array of arguments */
|
|
"startrx1.rex", /* name of Rexx file */
|
|
NULL, /* No INSTORE used */
|
|
"ksh", /* Command env. name */
|
|
RXCOMMAND, /* Code for how invoked */
|
|
NULL, /* No EXITs on this call */
|
|
&rexxrc, /* Rexx program output */
|
|
&rexxretval ); /* Rexx program output */
|
|
|
|
printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
|
|
printf("CALLREXX2 - RESULT-LENGTH: %zd\n", rexxretval.strlength);
|
|
printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr);
|
|
|
|
if (rexxretval.strptr != NULL)
|
|
{
|
|
RexxFreeMemory(rexxretval.strptr);
|
|
}
|
|
|
|
printf("Press Enter to continue\n");
|
|
ignore = scanf("%c", &val);
|
|
|
|
ignore = system("clear");
|
|
|
|
printf("In this case a previously defined Resultstring is \n");
|
|
printf("delivered to Open Object Rexx, which is large enough to \n");
|
|
printf("hold the Return Value of the Rexx commandfile.\n");
|
|
|
|
printf("Press Enter to continue\n");
|
|
ignore = scanf("%c", &val);
|
|
|
|
rexxretval.strptr = returnBuffer;
|
|
rexxretval.strlength = sizeof(returnBuffer);
|
|
|
|
rc = (*FuncAddress)(
|
|
0, /* number of arguments */
|
|
NULL, /* array of arguments */
|
|
"startrx1.rex", /* name of Rexx file */
|
|
NULL, /* No INSTORE used */
|
|
"ksh", /* Command env. name */
|
|
RXCOMMAND, /* Code for how invoked */
|
|
NULL, /* No EXITs on this call */
|
|
&rexxrc, /* Rexx program output */
|
|
&rexxretval ); /* Rexx program output */
|
|
|
|
printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
|
|
printf("rexxretval.strptr contains %s\n", rexxretval.strptr);
|
|
printf("CALLREXX2 - RESULT-LENGTH: %zd\n", rexxretval.strlength);
|
|
printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr);
|
|
/* if Rexx needed to allocate a new buffer, release that one */
|
|
if (rexxretval.strptr != returnBuffer)
|
|
{
|
|
RexxFreeMemory(rexxretval.strptr);
|
|
}
|
|
|
|
printf("Press Enter to continue\n");
|
|
ignore = scanf("%c", &val);
|
|
|
|
ignore = system("clear");
|
|
|
|
printf("In this case a previously defined Resultstring is \n");
|
|
printf("delivered to Open 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");
|
|
ignore = scanf("%c", &val);
|
|
|
|
rexxretval.strptr = (char *)returnBuffer;
|
|
rexxretval.strlength = 2;
|
|
|
|
printf("The length of the Resultstring is %zd\n", rexxretval.strlength);
|
|
|
|
rc = (*FuncAddress)(
|
|
0, /* number of arguments */
|
|
NULL, /* array of arguments */
|
|
"startrx1.rex", /* name of Rexx file */
|
|
NULL, /* No INSTORE used */
|
|
"ksh", /* Command env. name */
|
|
RXCOMMAND, /* Code for how invoked */
|
|
NULL, /* No EXITs on this call */
|
|
&rexxrc, /* Rexx program output */
|
|
&rexxretval ); /* Rexx program output */
|
|
|
|
printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
|
|
printf("The ResultString contains %s after call\n", rexxretval.strptr);
|
|
printf("The length is now %zd\n", rexxretval.strlength);
|
|
|
|
/* if Rexx needed to allocate a new buffer, release that one */
|
|
if (rexxretval.strptr != returnBuffer)
|
|
{
|
|
RexxFreeMemory(rexxretval.strptr);
|
|
}
|
|
|
|
printf("Press Enter to continue\n");
|
|
ignore = scanf("%c", &val);
|
|
|
|
ignore = 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.rex\n");
|
|
|
|
printf("Press Enter to continue\n");
|
|
ignore = 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 3 */
|
|
MAKERXSTRING(arg[3], str4, strlen(str4)); /* create input argument 4 */
|
|
|
|
rc = (*FuncAddress)(
|
|
4, /* number of arguments */
|
|
arg, /* array of arguments */
|
|
"startrx2.rex", /* name of Rexx file */
|
|
NULL, /* No INSTORE used */
|
|
"ksh", /* Command env. name */
|
|
RXCOMMAND, /* Code for how invoked */
|
|
NULL, /* No EXITs on this call */
|
|
&rexxrc, /* Rexx program output */
|
|
&rexxretval ); /* Rexx program output */
|
|
|
|
printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
|
|
printf("CALLREXX2 - RESULT-LENGTH: %zd\n", rexxretval.strlength);
|
|
printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr);
|
|
|
|
RexxFreeMemory(rexxretval.strptr);
|
|
|
|
printf("Press Enter to continue\n");
|
|
ignore = scanf("%c", &val);
|
|
|
|
ignore = 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.rex\n");
|
|
|
|
printf("Press Enter to continue\n");
|
|
ignore = scanf("%c", &val);
|
|
|
|
rexxretval.strptr = NULL; /* initialize return-pointer to empty */
|
|
rexxretval.strlength = 0; /* initialize return-length to zero */
|
|
|
|
rc = (*FuncAddress)(
|
|
2, /* number of arguments */
|
|
arg, /* array of arguments */
|
|
"startrx2.rex", /* name of Rexx file */
|
|
NULL, /* No INSTORE used */
|
|
"ksh", /* Command env. name */
|
|
RXCOMMAND, /* Code for how invoked */
|
|
NULL, /* No EXITs on this call */
|
|
&rexxrc, /* Rexx program output */
|
|
&rexxretval ); /* Rexx program output */
|
|
|
|
printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
|
|
printf("CALLREXX2 - RESULT-LENGTH: %zd\n", rexxretval.strlength);
|
|
printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr);
|
|
|
|
RexxFreeMemory(rexxretval.strptr);
|
|
|
|
printf("Press Enter to continue\n");
|
|
ignore = scanf("%c", &val);
|
|
|
|
ignore = 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.rex\n");
|
|
|
|
printf("Press Enter to continue\n");
|
|
ignore = scanf("%c", &val);
|
|
|
|
rexxretval.strptr = NULL; /* initialize return-pointer to empty */
|
|
rexxretval.strlength = 0; /* initialize return-length to zero */
|
|
|
|
rc = (*FuncAddress)(
|
|
0, /* number of arguments */
|
|
NULL, /* array of arguments */
|
|
"startrx3.rex", /* name of Rexx file */
|
|
NULL, /* No INSTORE used */
|
|
"ksh", /* Command env. name */
|
|
RXCOMMAND, /* Code for how invoked */
|
|
NULL, /* No EXITs on this call */
|
|
&rexxrc, /* Rexx program output */
|
|
&rexxretval ); /* Rexx program output */
|
|
|
|
printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
|
|
printf("CALLREXX2 - RESULT-LENGTH: %zd\n", rexxretval.strlength);
|
|
printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr);
|
|
|
|
RexxFreeMemory(rexxretval.strptr);
|
|
|
|
printf("Press Enter to continue\n");
|
|
ignore = scanf("%c", &val);
|
|
|
|
ignore = 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 Open Object Rexx script showing the concurrency feature.\n");
|
|
|
|
printf("Press Enter to continue\n");
|
|
ignore = scanf("%c", &val);
|
|
|
|
instore[0].strptr = (char *)sync_tst;
|
|
instore[0].strlength = strlen(instore[0].strptr);
|
|
instore[1].strptr = NULL;
|
|
instore[1].strlength = 0;
|
|
|
|
rexxretval.strptr = NULL; /* initialize return-pointer to empty */
|
|
rexxretval.strlength = 0; /* initialize return-length to zero */
|
|
|
|
rc = (*FuncAddress)(
|
|
0, /* number of arguments */
|
|
NULL, /* array of arguments */
|
|
NULL, /* no name for Rexx file */
|
|
instore, /* INSTORE used */
|
|
"ksh", /* Command env. name */
|
|
RXCOMMAND, /* Code for how invoked */
|
|
NULL, /* No EXITs on this call */
|
|
&rexxrc, /* Rexx program output */
|
|
&rexxretval ); /* Rexx program output */
|
|
|
|
printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
|
|
printf("CALLREXX2 - RESULT-LENGTH: %zd\n", rexxretval.strlength);
|
|
printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr);
|
|
|
|
RexxFreeMemory(rexxretval.strptr);
|
|
|
|
printf("Press Enter to continue\n");
|
|
ignore = scanf("%c", &val);
|
|
|
|
ignore = 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");
|
|
ignore = scanf("%c", &val);
|
|
|
|
instore[0].strptr = NULL;
|
|
instore[0].strlength = 0;
|
|
|
|
rexxretval.strptr = NULL; /* initialize return-pointer to empty */
|
|
rexxretval.strlength = 0; /* initialize return-length to zero */
|
|
|
|
rc = (*FuncAddress)(
|
|
0, /* number of arguments */
|
|
NULL, /* array of arguments */
|
|
NULL, /* no name for Rexx file */
|
|
instore, /* INSTORE used */
|
|
"ksh", /* Command env. name */
|
|
RXCOMMAND, /* Code for how invoked */
|
|
NULL, /* No EXITs on this call */
|
|
&rexxrc, /* Rexx program output */
|
|
&rexxretval ); /* Rexx program output */
|
|
|
|
printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
|
|
printf("CALLREXX2 - RESULT-LENGTH: %zd\n", rexxretval.strlength);
|
|
printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr);
|
|
|
|
RexxFreeMemory(rexxretval.strptr);
|
|
|
|
free(instore[1].strptr);
|
|
|
|
printf("Press Enter to continue\n");
|
|
ignore = scanf("%c", &val);
|
|
|
|
ignore = system("clear");
|
|
|
|
printf("This is a sample to show how to use the Rexx MacroSpace facility. \n");
|
|
printf("First of all load_macro.rex is called to load \n");
|
|
printf("the Rexx script macros.rex into Macrospace. The Macrospace- \n");
|
|
printf("name is upload.rex. \n");
|
|
|
|
printf("Press Enter to continue\n");
|
|
ignore = scanf("%c", &val);
|
|
|
|
rexxretval.strptr = NULL; /* initialize return-pointer to empty */
|
|
rexxretval.strlength = 0; /* initialize return-length to zero */
|
|
|
|
rc = (*FuncAddress)(
|
|
0, /* number of arguments */
|
|
NULL, /* array of arguments */
|
|
"load_macro.rex", /* name for Rexx macrospacefile*/
|
|
NULL, /* INSTORE not used */
|
|
"ksh", /* Command env. name */
|
|
RXCOMMAND, /* Code for how invoked */
|
|
NULL, /* No EXITs on this call */
|
|
&rexxrc, /* Rexx program output */
|
|
&rexxretval ); /* Rexx program output */
|
|
|
|
printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
|
|
printf("CALLREXX2 - RESULT-LENGTH: %zd\n", rexxretval.strlength);
|
|
printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr);
|
|
|
|
RexxFreeMemory(rexxretval.strptr);
|
|
|
|
printf("Press Enter to continue\n");
|
|
ignore = scanf("%c", &val);
|
|
|
|
ignore = system("clear");
|
|
|
|
printf("Now the Open Object Rexx script macros.rex (named upload.rex) 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");
|
|
ignore = 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 = (*FuncAddress)(
|
|
0, /* number of arguments */
|
|
NULL, /* array of arguments */
|
|
"upload.rex", /* name for Rexx macrospacefile */
|
|
instore, /* INSTORE used */
|
|
"ksh", /* Command env. name */
|
|
RXCOMMAND, /* Code for how invoked */
|
|
NULL, /* No EXITs on this call */
|
|
&rexxrc, /* Rexx program output */
|
|
&rexxretval ); /* Rexx program output */
|
|
|
|
printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
|
|
printf("CALLREXX2 - RESULT-LENGTH: %zd\n", rexxretval.strlength);
|
|
printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr);
|
|
|
|
RexxFreeMemory(rexxretval.strptr);
|
|
|
|
free(rexxretval.strptr);
|
|
|
|
printf("Press Enter to continue\n");
|
|
ignore = scanf("%c", &val);
|
|
|
|
ignore = system("clear");
|
|
|
|
printf("Finally del_macro.rex is called to delete macros.rex (named upload.rex)\n");
|
|
printf("out of the Open Object Rexx Macrospace.\n");
|
|
|
|
printf("Press Enter to continue\n");
|
|
ignore = scanf("%c", &val);
|
|
|
|
rc = (*FuncAddress)(
|
|
0, /* number of arguments */
|
|
NULL, /* array of arguments */
|
|
"del_macro.rex", /* name for Rexx macrospacefile */
|
|
NULL, /* INSTORE not used */
|
|
"ksh", /* Command env. name */
|
|
RXCOMMAND, /* Code for how invoked */
|
|
NULL, /* No EXITs on this call */
|
|
&rexxrc, /* Rexx program output */
|
|
&rexxretval ); /* Rexx program output */
|
|
|
|
printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
|
|
printf("CALLREXX2 - RESULT-LENGTH: %zd\n", rexxretval.strlength);
|
|
printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr);
|
|
|
|
RexxFreeMemory(rexxretval.strptr);
|
|
|
|
printf("Press Enter to continue\n");
|
|
ignore = scanf("%c", &val);
|
|
|
|
ignore = system("clear");
|
|
return 0;
|
|
}
|
|
|