/*----------------------------------------------------------------------------*/ /* */ /* 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 #include #include #include #include #include #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; }