/*----------------------------------------------------------------------------*/ /* */ /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */ /* Copyright (c) 2005-2014 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. */ /* */ /*----------------------------------------------------------------------------*/ #include #include #include #include #include /*********************************************************************/ /* Numeric Return calls */ /*********************************************************************/ #define INVALID_ROUTINE 40 /* Raise Rexx error */ #define VALID_ROUTINE 0 /* Successful completion */ /*********************************************************************/ /* ApiFncTable */ /* Array of names of the REXXApi functions. */ /* This list is used for registration and deregistration. */ /*********************************************************************/ static PSZ ApiFncTable[] = { "Api_Exchange_Data", "ApiDeregFunc", "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 * *************************************************************************/ LONG REXXENTRY ApiLoadFuncs( PSZ name, /* Function name */ LONG numargs, /* Number of arguments */ RXSTRING args[], /* Argument array */ PSZ queuename, /* Current queue */ PRXSTRING retstr ) /* Return RXSTRING */ { INT entries; /* Num of entries */ INT j; /* Counter */ entries = sizeof(ApiFncTable)/sizeof(PSZ); 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 * *************************************************************************/ LONG REXXENTRY ApiDeregFunc( PSZ name, /* Function name */ LONG numargs, /* Number of arguments */ RXSTRING args[], /* Argument array */ PSZ 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(PSZ); for (j = 0; j < entries; j++) { RexxDeregisterFunction(ApiFncTable[j]); } RexxDeregisterFunction("ApiLoadFuncs"); 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 Apitest3. * * 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 run out of storage. * * Be aware that the returned variables are NOT in any spe- * * cified order. * *************************************************************************/ LONG REXXENTRY Api_Read_All_Variables_From_REXX_VP( PSZ name, /* Function name */ LONG numargs, /* Number of arguments */ RXSTRING args[], /* Argument array */ PSZ queuename, /* Current queue */ PRXSTRING retstr ) /* Return RXSTRING */ { SHVBLOCK rxshv; SHVBLOCK *prxshv = &rxshv; RexxReturnCode rc; int i = 1; strcpy(retstr->strptr, "0"); retstr->strlength = strlen(retstr->strptr); prxshv->shvnext = NULL; prxshv->shvname.strlength = 0; prxshv->shvname.strptr = NULL; /* let rexx allocate it for me */ prxshv->shvvalue.strptr = NULL; /* let rexx allocate it for me */ /* Another way would be to assign an existing buffer and specify its max. length */ 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); return INVALID_ROUTINE; } } if (prxshv->shvvalue.strlength) printf("Name of the variable from the Variable Pool: %s, Value: %s \n", prxshv->shvname.strptr, prxshv->shvvalue.strptr); else printf("Name of the variable from the Variable Pool: %s, Empty\n", prxshv->shvname.strptr); i++; RexxFreeMemory((void *)prxshv->shvname.strptr); /* free pointers allocated by REXX */ RexxFreeMemory(prxshv->shvvalue.strptr); /* free pointers allocated by REXX */ while (!prxshv->shvret) { prxshv->shvret = 0; prxshv->shvnext = NULL; prxshv->shvname.strlength = 0; prxshv->shvname.strptr = NULL; /* let rexx allocate it for me */ prxshv->shvvalue.strptr = NULL; /* let rexx allocate it 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++; if (!prxshv->shvret) { if (prxshv->shvvalue.strlength) printf("Name of the variable from the Variable Pool: %s, Value: %s \n", prxshv->shvname.strptr, prxshv->shvvalue.strptr); else printf("Name of the variable from the Variable Pool: %s, Empty\n", prxshv->shvname.strptr); RexxFreeMemory((void *)prxshv->shvname.strptr); /* free pointers allocated by REXX */ RexxFreeMemory(prxshv->shvvalue.strptr); /* free pointers allocated by REXX */ } } 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 * * * *************************************************************************/ LONG REXXENTRY Api_Read_All_Elements_Of_A_Specific_Stem_From_REXX_VP( PSZ name, /* Function name */ LONG numargs, /* Number of arguments */ RXSTRING args[], /* Argument array */ PSZ queuename, /* Current queue */ PRXSTRING retstr ) /* Return RXSTRING */ { SHVBLOCK rxshv; SHVBLOCK *prxshv = &rxshv, *temp, *interim; RexxReturnCode rc; char array[20], value[10]; char pch[64], *result; char *varName; int chars; int j, k = 0; if (numargs != 1 ) /* validate arg count */ return INVALID_ROUTINE; strcpy(retstr->strptr, "0"); retstr->strlength = strlen(retstr->strptr); strncpy(pch, args[0].strptr, 64); prxshv->shvnext = NULL; prxshv->shvname.strptr = pch; /* here we use our own buffer that is limited to 64 characters */ prxshv->shvname.strlength = strlen(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)); /* allocate a new node */ 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); varName = malloc(strlen(array)+1); strcpy(varName, array); temp->shvname.strptr = varName; temp->shvvalue.strptr = NULL; /* let rexx allocate it for me */ temp->shvcode = RXSHV_SYFET; } temp = prxshv->shvnext; /* first allocated one */ rc = RexxVariablePool(temp); 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,k); return INVALID_ROUTINE; } } for (k = 1;k <= j; k++) { printf("Name of the Stem-variable from the Variable Pool: %s, Value: %s \n", temp->shvname.strptr,temp->shvvalue.strptr); free((void *)temp->shvname.strptr); /* allocated by us and therefore freed with free */ RexxFreeMemory(temp->shvvalue.strptr); /* allocated by REXX and therefore freed by RexxFreeMemory */ interim = temp; temp = temp->shvnext; /* process next in list */ free(interim); /* free current node */ } RexxFreeMemory(prxshv->shvvalue.strptr); /* allocated by REXX and freed by RexxFreeMemory */ return VALID_ROUTINE; }