/*----------------------------------------------------------------------------*/ /* */ /* 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. */ /* */ /*----------------------------------------------------------------------------*/ /***************************************************************************/ /* */ /* rexxapi3.c Open Object Rexx samples */ /* */ /* ----------------------------------------------------------------------- */ /* */ /* Description: functions used by Open Object Rexx script */ /* */ /***************************************************************************/ #include #include #include #include /*********************************************************************/ /* Numeric Return calls */ /*********************************************************************/ #define INVALID_ROUTINE 40 /* Raise Rexx error */ #define VALID_ROUTINE 0 /* Successful completion */ #ifdef __cplusplus extern "C" { #endif /*********************************************************************/ /* ApiFncTable */ /* Array of names of the REXXAPI functions. */ /* This list is used for registration and deregistration. */ /*********************************************************************/ static const char *ApiFncTable[] = { "Api_Exchange_Data", "ApiDeregFunc3", "Api_Read_All_Variables_From_REXX_VP", "Api_Read_All_Elements_Of_A_Specific_Stem_From_REXX_VP" }; /************************************************************************* * Function: ApiLoadFuncs * * * * Syntax: call ApiLoadFuncs * * * * Params: none * * * * Return: null string * *************************************************************************/ RexxReturnCode REXXENTRY ApiLoadFuncs3( const char *name, /* Function name */ size_t numargs, /* Number of arguments */ CONSTRXSTRING args[], /* Argument array */ const char * queuename, /* Current queue */ PRXSTRING retstr ) /* Return RXSTRING */ { int entries; /* Num of entries */ int j; /* Counter */ entries = sizeof(ApiFncTable)/sizeof(const char *); for (j = 0; j < entries; j++) { RexxRegisterFunctionDll(ApiFncTable[j], "rexxapi3", ApiFncTable[j]); } return VALID_ROUTINE; } /************************************************************************* * Function: ApiDeregFunc * * * * Syntax: call ApiDeregFuncs * * * * Params: none * * * * Return: null string * *************************************************************************/ RexxReturnCode REXXENTRY ApiDeregFunc3( const char *name, /* Function name */ size_t numargs, /* Number of arguments */ CONSTRXSTRING args[], /* Argument array */ const char * queuename, /* Current queue */ PRXSTRING retstr ) /* Return RXSTRING */ { int entries; /* Num of entries */ int j; /* Counter */ retstr->strlength = 0; /* set return value */ if (numargs > 0) return INVALID_ROUTINE; entries = sizeof(ApiFncTable)/sizeof(const char *); for (j = 0; j < entries; j++) { RexxDeregisterFunction(ApiFncTable[j]); } return VALID_ROUTINE; } /************************************************************************* * Function: Api_Read_All_Variables_From_REXX_VP * * * * Syntax: call Api_Read_All_Variables_From_REXX_VP * * * * Params: No parameter required. The function is called by APITEST. * * It uses a while loop to read all the variables in the active* * REXX-variable pool. The shared variable block request code * * is RXSHV_NEXTV. Be aware that with this request code REXX * * treads every Stem variable as a variable itself (not the * * whole stem). This gives the calling C-routine a chance * * to clear up memory which was previously allocated by REXX * * for every returned variable. If you don't free memory the * * system will get out of storage. * * Be aware that the returned variables are NOT in any spe- * * cified order. * * Return: 0 - success, 1 - failure * *************************************************************************/ RexxReturnCode REXXENTRY Api_Read_All_Variables_From_REXX_VP( const char *name, /* Function name */ size_t numargs, /* Number of arguments */ CONSTRXSTRING args[], /* Argument array */ const char * queuename, /* Current queue */ PRXSTRING retstr ) /* Return RXSTRING */ { SHVBLOCK *prxshv; RexxReturnCode rc; int i = 1; strcpy(retstr->strptr, "0"); retstr->strlength = strlen(retstr->strptr); prxshv = (PSHVBLOCK)malloc(sizeof(SHVBLOCK)); if (!prxshv) { strcpy(retstr->strptr, "Allocation error occured"); retstr->strlength = strlen(retstr->strptr); return VALID_ROUTINE; } prxshv->shvnext = NULL; prxshv->shvname.strlength = 0; prxshv->shvname.strptr = NULL; prxshv->shvvalue.strptr = NULL; /*** let Rexx allocate for me ***/ prxshv->shvcode = RXSHV_NEXTV; /* Now reading all variables from the Rexx-variable pool ***********/ rc = RexxVariablePool(prxshv); if (rc) { if (rc != RXSHV_LVAR) { printf("ERROR: shvret is %x hex after var nr. %d \n",rc,i); } } printf("Name of the variable from the Variable Pool: %s, Value: %s \n", prxshv->shvname.strptr, prxshv->shvvalue.strptr); i++; while (!prxshv->shvret) { prxshv->shvnext = (PSHVBLOCK)malloc(sizeof(SHVBLOCK)); prxshv = prxshv->shvnext; if (!prxshv) { strcpy(retstr->strptr, "Allocation error occured"); retstr->strlength = strlen(retstr->strptr); return VALID_ROUTINE; } prxshv->shvnext = NULL; prxshv->shvname.strlength = 0; prxshv->shvname.strptr = NULL; prxshv->shvvalue.strptr = NULL; /*** let Rexx allocate for me ***/ prxshv->shvcode = RXSHV_NEXTV; rc = RexxVariablePool(prxshv); if (rc) { if (rc== RXSHV_MEMFL) { strcpy(retstr->strptr, "Allocation error occured"); retstr->strlength = strlen(retstr->strptr); return VALID_ROUTINE; } else if (rc != RXSHV_LVAR) { printf("ERROR: shvret is %x hex after var nr. %d\n",rc,i); return INVALID_ROUTINE; } } i++; printf("Name of the variable from the Variable Pool: %s, Value: %s \n", prxshv->shvname.strptr, prxshv->shvvalue.strptr); RexxFreeMemory((void *)prxshv->shvname.strptr); RexxFreeMemory((void *)prxshv->shvvalue.strptr); } return VALID_ROUTINE; } /************************************************************************* * Function: Api_Read_All_Elements_Of_A_Specific_Stem_From_REXX_VP * * * * Syntax: call Api_Read_All_Elements_Of_A_Specific_Stem_From_REXX_VP * * with the stem variable the values should be returned * * * * Params: A stem where all values of the stem variables should be * returned. * * The shared variable block request code is RXSHV_SYFET. * * Only ONE call is necessary. If the stem contains to many * * variables the memory resources are exhausted and Rexx * * should return RXSHV_MEMFL. There is no change for the * * calling routine to handle the problem with DosFreeMem * * because it doesn't get any control before Rexx terminates. * * The problem is during allocating memory for the values of * * the stem-variables by DosAllocMem which allocates on 64k * * boundary. * * Return: 0 - success, 1 - failure * *************************************************************************/ RexxReturnCode REXXENTRY Api_Read_All_Elements_Of_A_Specific_Stem_From_REXX_VP( const char *name, /* Function name */ size_t numargs, /* Number of arguments */ CONSTRXSTRING args[], /* Argument array */ const char * queuename, /* Current queue */ PRXSTRING retstr ) /* Return RXSTRING */ { SHVBLOCK *prxshv, *temp, *interim, rxshv; RexxReturnCode rc; char array[20], value[11]; char *pch, *result; int chars; int j, k = 0; prxshv = &rxshv; if (numargs != 1 ) /* validate arg count */ return INVALID_ROUTINE; strcpy(retstr->strptr, "0"); retstr->strlength = strlen(retstr->strptr); pch = (char *) malloc(strlen(args[0].strptr) +1); strcpy(pch, args[0].strptr); prxshv->shvnext = NULL; prxshv->shvname.strlength = strlen(pch); prxshv->shvname.strptr = pch; prxshv->shvvalue.strptr = NULL; /*** let Rexx allocate for me ***/ prxshv->shvcode = RXSHV_SYFET; rc = RexxVariablePool(prxshv); if (rc) { strcpy(retstr->strptr, "APIFETCH failed \n"); retstr->strlength = strlen(retstr->strptr); return VALID_ROUTINE; } j = atoi(prxshv->shvvalue.strptr); chars = '.'; result = strrchr(pch, chars); result++; *result = 0x00; temp = prxshv; memset(array, 0x00, sizeof(array)); memset(value, 0x00, sizeof(value)); for (k = 1;k <= j; k++) { temp->shvnext = (PSHVBLOCK)malloc(sizeof(SHVBLOCK)); temp = temp->shvnext; if (!temp) { strcpy(retstr->strptr, "Allocation error occured"); retstr->strlength = strlen(retstr->strptr); return VALID_ROUTINE; } strcpy(array, pch); sprintf(value, "%d", k); strcat(array, value); temp->shvnext = NULL; temp->shvname.strlength = strlen(array); temp->shvname.strptr = (char *) malloc(strlen(array)+1); strcpy((char *)temp->shvname.strptr, array); temp->shvvalue.strptr = NULL; /*** let Rexx allocate for me ***/ temp->shvcode = RXSHV_SYFET; } rc = RexxVariablePool(prxshv->shvnext); if (rc) { if (rc== RXSHV_MEMFL) { strcpy(retstr->strptr, "Allocation error occured"); retstr->strlength = strlen(retstr->strptr); return VALID_ROUTINE; } else if (rc != RXSHV_LVAR) { printf("ERROR: shvret is %x hex \n",rc); return INVALID_ROUTINE; } } temp = prxshv->shvnext; for (k = 1;k <= j; k++) { printf("Name of the Stem-variable from the Rexx Variable Pool: %s, Value: %s \n", temp->shvname.strptr, temp->shvvalue.strptr); interim = temp; RexxFreeMemory((void *)temp->shvname.strptr); RexxFreeMemory((void *)temp->shvvalue.strptr); temp = temp->shvnext; free(interim); } RexxFreeMemory((void *)prxshv->shvvalue.strptr); free(pch); return VALID_ROUTINE; } #ifdef __cplusplus } #endif