rexxapi3.c
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
4 /* Copyright (c) 2005-2014 Rexx Language Association. All rights reserved. */
5 /* */
6 /* This program and the accompanying materials are made available under */
7 /* the terms of the Common Public License v1.0 which accompanies this */
8 /* distribution. A copy is also available at the following address: */
9 /* http://www.oorexx.org/license.html */
10 /* */
11 /* Redistribution and use in source and binary forms, with or */
12 /* without modification, are permitted provided that the following */
13 /* conditions are met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright */
16 /* notice, this list of conditions and the following disclaimer. */
17 /* Redistributions in binary form must reproduce the above copyright */
18 /* notice, this list of conditions and the following disclaimer in */
19 /* the documentation and/or other materials provided with the distribution. */
20 /* */
21 /* Neither the name of Rexx Language Association nor the names */
22 /* of its contributors may be used to endorse or promote products */
23 /* derived from this software without specific prior written permission. */
24 /* */
25 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
26 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
27 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
28 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
29 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
30 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
31 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
32 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
33 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
34 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
35 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36 /* */
37 /*----------------------------------------------------------------------------*/
38 
39 #include <string.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 
43 #include <Windows.h>
44 #include <rexx.h>
45 
46 /*********************************************************************/
47 /* Numeric Return calls */
48 /*********************************************************************/
49 
50 #define INVALID_ROUTINE 40 /* Raise Rexx error */
51 #define VALID_ROUTINE 0 /* Successful completion */
52 
53 
54 /*********************************************************************/
55 /* ApiFncTable */
56 /* Array of names of the REXXApi functions. */
57 /* This list is used for registration and deregistration. */
58 /*********************************************************************/
59 static PSZ ApiFncTable[] =
60  {
61  "Api_Exchange_Data",
62  "ApiDeregFunc",
63  "Api_Read_All_Variables_From_REXX_VP",
64  "Api_Read_All_Elements_Of_A_Specific_Stem_From_REXX_VP"
65  };
66 
67 
68 /*************************************************************************
69 * Function: ApiLoadFuncs *
70 * *
71 * Syntax: call ApiLoadFuncs *
72 * *
73 * Params: none *
74 * *
75 * Return: null string *
76 *************************************************************************/
77 
79  PSZ name, /* Function name */
80  LONG numargs, /* Number of arguments */
81  RXSTRING args[], /* Argument array */
82  PSZ queuename, /* Current queue */
83  PRXSTRING retstr ) /* Return RXSTRING */
84 {
85  INT entries; /* Num of entries */
86  INT j; /* Counter */
87 
88 
89  entries = sizeof(ApiFncTable)/sizeof(PSZ);
90 
91  for (j = 0; j < entries; j++)
92  {
94  "REXXAPI3", ApiFncTable[j]);
95  }
96  return VALID_ROUTINE;
97 }
98 
99 
100 /*************************************************************************
101 * Function: ApiDeregFunc *
102 * *
103 * Syntax: call ApiDeregFuncs *
104 * *
105 * Params: none *
106 * *
107 * Return: null string *
108 *************************************************************************/
109 
111  PSZ name, /* Function name */
112  LONG numargs, /* Number of arguments */
113  RXSTRING args[], /* Argument array */
114  PSZ queuename, /* Current queue */
115  PRXSTRING retstr ) /* Return RXSTRING */
116 {
117  INT entries; /* Num of entries */
118  INT j; /* Counter */
119 
120  retstr->strlength = 0; /* set return value */
121 
122  if (numargs > 0)
123  return INVALID_ROUTINE;
124 
125 
126  entries = sizeof(ApiFncTable)/sizeof(PSZ);
127 
128  for (j = 0; j < entries; j++)
129  {
131  }
132  RexxDeregisterFunction("ApiLoadFuncs");
133  return VALID_ROUTINE;
134 }
135 
136 /*************************************************************************
137 * Function: Api_Read_All_Variables_From_REXX_VP *
138 * *
139 * Syntax: call Api_Read_All_Variables_From_REXX_VP *
140 * *
141 * Params: No parameter required. The function is called by Apitest3. *
142 * It uses a while loop to read all the variables in the active*
143 * REXX-variable pool. The shared variable block request code *
144 * is RXSHV_NEXTV. Be aware that with this request code REXX *
145 * treads every Stem variable as a variable itself (not the *
146 * whole stem). This gives the calling C-routine a chance *
147 * to clear up memory which was previously allocated by REXX *
148 * for every returned variable. If you don't free memory, the *
149 * system will run out of storage. *
150 * Be aware that the returned variables are NOT in any spe- *
151 * cified order. *
152 *************************************************************************/
153 
155  PSZ name, /* Function name */
156  LONG numargs, /* Number of arguments */
157  RXSTRING args[], /* Argument array */
158  PSZ queuename, /* Current queue */
159  PRXSTRING retstr ) /* Return RXSTRING */
160 {
161  SHVBLOCK rxshv;
162  SHVBLOCK *prxshv = &rxshv;
163  RexxReturnCode rc;
164  int i = 1;
165 
166  strcpy(retstr->strptr, "0");
167  retstr->strlength = strlen(retstr->strptr);
168 
169  prxshv->shvnext = NULL;
170  prxshv->shvname.strlength = 0;
171  prxshv->shvname.strptr = NULL; /* let rexx allocate it for me */
172  prxshv->shvvalue.strptr = NULL; /* let rexx allocate it for me */
173  /* Another way would be to assign an existing buffer and specify its max. length */
174  prxshv->shvcode = RXSHV_NEXTV;
175 
176 /* Now reading all variables from the REXX-variable pool ***********/
177 
178  rc = RexxVariablePool(prxshv);
179  if (rc)
180  {
181  if (rc != RXSHV_LVAR)
182  {
183  printf("ERROR: shvret is %x hex after var nr. %d \n",rc,i);
184  return INVALID_ROUTINE;
185  }
186  }
187 
188  if (prxshv->shvvalue.strlength)
189  printf("Name of the variable from the Variable Pool: %s, Value: %s \n", prxshv->shvname.strptr, prxshv->shvvalue.strptr);
190  else
191  printf("Name of the variable from the Variable Pool: %s, Empty\n", prxshv->shvname.strptr);
192  i++;
193  RexxFreeMemory((void *)prxshv->shvname.strptr); /* free pointers allocated by REXX */
194  RexxFreeMemory(prxshv->shvvalue.strptr); /* free pointers allocated by REXX */
195 
196  while (!prxshv->shvret)
197  {
198  prxshv->shvret = 0;
199  prxshv->shvnext = NULL;
200  prxshv->shvname.strlength = 0;
201  prxshv->shvname.strptr = NULL; /* let rexx allocate it for me */
202  prxshv->shvvalue.strptr = NULL; /* let rexx allocate it for me */
203  prxshv->shvcode = RXSHV_NEXTV;
204  rc = RexxVariablePool(prxshv);
205  if (rc)
206  {
207  if (rc== RXSHV_MEMFL)
208  {
209  strcpy(retstr->strptr, "Allocation error occured");
210  retstr->strlength = strlen(retstr->strptr);
211  return VALID_ROUTINE;
212  }
213  else if (rc != RXSHV_LVAR)
214  {
215  printf("ERROR: shvret is %x hex after var nr. %d\n",rc,i);
216  return INVALID_ROUTINE;
217  }
218  }
219  i++;
220  if (!prxshv->shvret)
221  {
222  if (prxshv->shvvalue.strlength)
223  printf("Name of the variable from the Variable Pool: %s, Value: %s \n", prxshv->shvname.strptr, prxshv->shvvalue.strptr);
224  else
225  printf("Name of the variable from the Variable Pool: %s, Empty\n", prxshv->shvname.strptr);
226  RexxFreeMemory((void *)prxshv->shvname.strptr); /* free pointers allocated by REXX */
227  RexxFreeMemory(prxshv->shvvalue.strptr); /* free pointers allocated by REXX */
228  }
229  }
230  return VALID_ROUTINE;
231 }
232 
233 /*************************************************************************
234 * Function: Api_Read_All_Elements_Of_A_Specific_Stem_From_REXX_VP *
235 * *
236 * Syntax: call Api_Read_All_Elements_Of_A_Specific_Stem_From_REXX_VP *
237 * with the stem variable the values should be returned *
238 * *
239 * Params: A stem where all values of the stem variables should be *
240 * returned. *
241 * The shared variable block request code is RXSHV_SYFET. *
242 * Only ONE call is necessary *
243 * *
244 *************************************************************************/
245 
247  PSZ name, /* Function name */
248  LONG numargs, /* Number of arguments */
249  RXSTRING args[], /* Argument array */
250  PSZ queuename, /* Current queue */
251  PRXSTRING retstr ) /* Return RXSTRING */
252 {
253  SHVBLOCK rxshv;
254  SHVBLOCK *prxshv = &rxshv, *temp, *interim;
255  RexxReturnCode rc;
256  char array[20], value[10];
257  char pch[64], *result;
258  char *varName;
259 
260  int chars;
261  int j, k = 0;
262 
263  if (numargs != 1 ) /* validate arg count */
264  return INVALID_ROUTINE;
265  strcpy(retstr->strptr, "0");
266  retstr->strlength = strlen(retstr->strptr);
267 
268  strncpy(pch, args[0].strptr, 64);
269 
270  prxshv->shvnext = NULL;
271  prxshv->shvname.strptr = pch; /* here we use our own buffer that is limited to 64 characters */
272  prxshv->shvname.strlength = strlen(pch);
273  prxshv->shvvalue.strptr = NULL; /* let rexx allocate for me */
274  prxshv->shvcode = RXSHV_SYFET;
275 
276  rc = RexxVariablePool(prxshv);
277  if (rc)
278  {
279  strcpy(retstr->strptr, "ApiFETCH failed \n");
280  retstr->strlength = strlen(retstr->strptr);
281  return VALID_ROUTINE;
282  }
283 
284  j = atoi(prxshv->shvvalue.strptr);
285 
286  chars = '.';
287  result = strrchr(pch, chars);
288  result++;
289  *result = 0x00;
290 
291  temp = prxshv;
292 
293  memset(array, 0x00, sizeof(array));
294  memset(value, 0x00, sizeof(value));
295  for (k = 1;k <= j; k++)
296  {
297  temp->shvnext = (PSHVBLOCK)malloc(sizeof(SHVBLOCK)); /* allocate a new node */
298  temp = temp->shvnext;
299  if (!temp)
300  {
301  strcpy(retstr->strptr, "Allocation error occured");
302  retstr->strlength = strlen(retstr->strptr);
303  return VALID_ROUTINE;
304  }
305  strcpy(array, pch);
306  sprintf(value, "%d", k);
307  strcat(array, value);
308  temp->shvnext = NULL;
309  temp->shvname.strlength = strlen(array);
310  varName = malloc(strlen(array)+1);
311  strcpy(varName, array);
312  temp->shvname.strptr = varName;
313  temp->shvvalue.strptr = NULL; /* let rexx allocate it for me */
314  temp->shvcode = RXSHV_SYFET;
315  }
316 
317  temp = prxshv->shvnext; /* first allocated one */
318  rc = RexxVariablePool(temp);
319  if (rc)
320  {
321  if (rc== RXSHV_MEMFL)
322  {
323  strcpy(retstr->strptr, "Allocation error occured");
324  retstr->strlength = strlen(retstr->strptr);
325  return VALID_ROUTINE;
326  }
327  else if (rc != RXSHV_LVAR)
328  {
329  printf("ERROR: shvret is %x hex after var nr. %d\n",rc,k);
330  return INVALID_ROUTINE;
331  }
332  }
333 
334  for (k = 1;k <= j; k++)
335  {
336  printf("Name of the Stem-variable from the Variable Pool: %s, Value: %s \n", temp->shvname.strptr,temp->shvvalue.strptr);
337  free((void *)temp->shvname.strptr); /* allocated by us and therefore freed with free */
338  RexxFreeMemory(temp->shvvalue.strptr); /* allocated by REXX and therefore freed by RexxFreeMemory */
339  interim = temp;
340  temp = temp->shvnext; /* process next in list */
341  free(interim); /* free current node */
342  }
343  RexxFreeMemory(prxshv->shvvalue.strptr); /* allocated by REXX and freed by RexxFreeMemory */
344 
345  return VALID_ROUTINE;
346 }
347 
RexxReturnCode RexxEntry RexxVariablePool(PSHVBLOCK pshvblock)
RexxReturnCode REXXENTRY RexxDeregisterFunction(CONSTANT_STRING)
SHVBLOCK * PSHVBLOCK
Definition: rexx.h:213
RexxReturnCode REXXENTRY RexxFreeMemory(void *)
RexxReturnCode REXXENTRY RexxRegisterFunctionDll(CONSTANT_STRING, CONSTANT_STRING, CONSTANT_STRING)
int RexxReturnCode
Definition: rexx.h:73
LONG REXXENTRY ApiLoadFuncs(PSZ name, LONG numargs, RXSTRING args[], PSZ queuename, PRXSTRING retstr)
Definition: rexxapi3.c:78
LONG REXXENTRY Api_Read_All_Variables_From_REXX_VP(PSZ name, LONG numargs, RXSTRING args[], PSZ queuename, PRXSTRING retstr)
Definition: rexxapi3.c:154
#define VALID_ROUTINE
Definition: rexxapi3.c:51
LONG REXXENTRY ApiDeregFunc(PSZ name, LONG numargs, RXSTRING args[], PSZ queuename, PRXSTRING retstr)
Definition: rexxapi3.c:110
LONG REXXENTRY Api_Read_All_Elements_Of_A_Specific_Stem_From_REXX_VP(PSZ name, LONG numargs, RXSTRING args[], PSZ queuename, PRXSTRING retstr)
Definition: rexxapi3.c:246
#define INVALID_ROUTINE
Definition: rexxapi3.c:50
static PSZ ApiFncTable[]
Definition: rexxapi3.c:59
#define RXSHV_NEXTV
Definition: rexxapidefs.h:103
#define RXSHV_SYFET
Definition: rexxapidefs.h:101
#define RXSHV_LVAR
Definition: rexxapidefs.h:114
#define RXSHV_MEMFL
Definition: rexxapidefs.h:117
size_t strlength
Definition: rexx.h:157
char * strptr
Definition: rexx.h:158
CONSTANT_RXSTRING shvname
Definition: rexx.h:206
unsigned char shvret
Definition: rexx.h:211
unsigned char shvcode
Definition: rexx.h:210
RXSTRING shvvalue
Definition: rexx.h:207
struct _SHVBLOCK * shvnext
Definition: rexx.h:205
#define REXXENTRY