1
2
3 #define INCL_RXSHV /* Shared variable support */
4 #define INCL_RXFUNC /* External functions support */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <ctype.h>
10 #include "rexxsaa.h"
11
12 #ifdef _MSC_VER
13 /* This picky compiler claims about unused formal parameters.
14 * This is correct but hides (for human eyes) other errors since they
15 * are many and we can't reduce them all.
16 * Error 4100 is "unused formal parameter".
17 */
18 # pragma warning(disable:4100)
19 #endif
20
21 #define DLLNAME "rxtest1"
22
23
24 #define FUNCTION1 Test1Function1
25 #define FUNCTION2 Test1Function2
26 #define LOADFUNCS Test1LoadFuncs
27 #define DROPFUNCS Test1DropFuncs
28
29 #define NAME_FUNCTION1 "Test1Function1"
30 #define NAME_FUNCTION2 "Test1Function2"
31 #define NAME_LOADFUNCS "Test1LoadFuncs"
32 #define NAME_DROPFUNCS "Test1DropFuncs"
33
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 RexxFunctionHandler Test1Function1;
38 RexxFunctionHandler Test1Function2;
39 RexxFunctionHandler Test1LoadFuncs;
40 RexxFunctionHandler Test1DropFuncs;
41 #ifdef __cplusplus
42 }
43 #endif
44
45 /*-----------------------------------------------------------------------------
46 * Table entry for a REXX function.
47 *----------------------------------------------------------------------------*/
48 typedef struct {
49 PSZ function_name;
50 PFN EntryPoint;
51 } RexxTestFunction;
52
53 /*-----------------------------------------------------------------------------
54 * Table of REXX Functions. Used to install/de-install functions.
55 *----------------------------------------------------------------------------*/
56 static const RexxTestFunction RexxTestFunctions[] = {
57 {(PSZ)NAME_FUNCTION1, (PFN)Test1Function1 },
58 {(PSZ)NAME_FUNCTION2, (PFN)Test1Function2 },
59 {(PSZ)NAME_DROPFUNCS, (PFN)Test1DropFuncs },
60 {(PSZ)NAME_LOADFUNCS, (PFN)Test1LoadFuncs },
61 {NULL,NULL}
62 };
63
make_upper(char * in)64 static char *make_upper( char *in )
65 {
66 int len = strlen( in );
67 int i;
68
69 for ( i = 0; i < len; i++ )
70 {
71 if ( islower( in[i] ) )
72 in[i] = (char)toupper( in[i] );
73 }
74 return in;
75 }
76
set_rexx_variable(char * name,int suffix,char * value,int value_length)77 static int set_rexx_variable( char *name, int suffix, char *value, int value_length )
78 {
79 SHVBLOCK shv;
80 char variable_name[250];
81 int rc=0;
82
83 shv.shvnext=NULL; /* only one block */
84 shv.shvcode=RXSHV_SET; /* use direct set */
85 sprintf( variable_name, "%s.%-d", name, suffix );
86 (void)make_upper( variable_name );/* make variable name uppercase */
87 /*
88 * Now (attempt to) set the REXX variable
89 * Add name/value to SHVBLOCK
90 */
91 MAKERXSTRING( shv.shvname, variable_name, strlen( variable_name) );
92 MAKERXSTRING( shv.shvvalue, value, value_length );
93 /*
94 * One or both of these is needed, too <sigh>
95 */
96 shv.shvnamelen = strlen( variable_name );
97 shv.shvvaluelen = value_length;
98
99 rc = RexxVariablePool( &shv ); /* Set the REXX variable */
100 if ( rc != RXSHV_OK
101 && rc != RXSHV_NEWV)
102 {
103 rc = 1;
104 }
105 else
106 rc = 0;
107 return rc;
108 }
109
static_show_parameter(ULONG argc,RXSTRING argv[],PSZ func_name)110 static void static_show_parameter(ULONG argc, RXSTRING argv[], PSZ func_name)
111 {
112 char buf[100];
113 if (argc == 0)
114 {
115 printf("%s(static): *** No parameters passed ***\n",DLLNAME);
116 return;
117 }
118 memcpy(buf,argv[0].strptr,argv[0].strlength);
119 buf[argv[0].strlength] = '\0';
120 if (strcmp(func_name,buf) != 0)
121 printf("%s(static): *** Mismatch of parameters: %s is NOT expected: %s ***\n",
122 DLLNAME,buf,func_name);
123 return;
124 }
125
126 #if defined(DYNAMIC_STATIC)
global_show_parameter(ULONG argc,RXSTRING argv[],PSZ func_name)127 static void global_show_parameter(ULONG argc, RXSTRING argv[], PSZ func_name)
128 #else
129 void global_show_parameter(ULONG argc, RXSTRING argv[], PSZ func_name)
130 #endif
131 {
132 char buf[100];
133 if (argc == 0)
134 {
135 printf("%s(global): *** No parameters passed ***\n",DLLNAME);
136 return;
137 }
138 memcpy(buf,argv[0].strptr,argv[0].strlength);
139 buf[argv[0].strlength] = '\0';
140 if (strcmp(func_name,buf) != 0)
141 printf("%s(global): *** Mismatch of parameters: %s is NOT expected: %s ***\n",
142 DLLNAME,buf,func_name);
143 return;
144 }
145
FUNCTION1(PCSZ name,ULONG argc,PRXSTRING argv,PCSZ stck,PRXSTRING retstr)146 APIRET APIENTRY FUNCTION1(PCSZ name,ULONG argc,PRXSTRING argv,PCSZ stck,PRXSTRING retstr)
147 {
148 int i=0;
149 char tmp[50];
150
151 for ( i = 0; i < (int)argc; i++ )
152 {
153 printf( "%s(Test1Function1): Arg: %d <%s>\n", DLLNAME, i, argv[i].strptr );
154 /*
155 * Set Rexx variables for each argument...
156 */
157 if ( set_rexx_variable( (char *)name, i+1, argv[i].strptr, argv[i].strlength ) == 1 )
158 printf( "%s(Test1Function1): Error setting variable for Arg: %d <%s.%d>\n", DLLNAME, i+1, argv[i].strptr, i+1 );
159 }
160 sprintf( tmp, "%ld", argc );
161 if ( set_rexx_variable( (char *)name, 0, tmp, strlen( tmp ) ) == 1 )
162 printf( "%s(Test1Function1): Error setting stem index.\n", DLLNAME );
163 static_show_parameter(argc,argv,NAME_FUNCTION1);
164 global_show_parameter(argc,argv,NAME_FUNCTION1);
165 /*
166 * Set return code...
167 */
168 strcpy(retstr->strptr,"0");
169 retstr->strlength = 1;
170 return 0L;
171 }
172
FUNCTION2(PCSZ name,ULONG argc,PRXSTRING argv,PCSZ stck,PRXSTRING retstr)173 APIRET APIENTRY FUNCTION2(PCSZ name,ULONG argc,PRXSTRING argv,PCSZ stck,PRXSTRING retstr)
174 {
175 int i=0;
176 char tmp[50];
177
178 for ( i = 0; i < (int)argc; i++ )
179 {
180 printf( "%s(Test1Function2): Arg: %d <%s>\n", DLLNAME, i, argv[i].strptr );
181 /*
182 * Set Rexx variables for each argument...
183 */
184 if ( set_rexx_variable( (char *)name, i+1, argv[i].strptr, argv[i].strlength ) == 1 )
185 printf( "%s(Test1Function2): Error setting variable for Arg: %d <%s.%d>\n", DLLNAME, i+1, argv[i].strptr, i+1 );
186 }
187 sprintf( tmp, "%ld", argc );
188 if ( set_rexx_variable( (char *)name, 0, tmp, strlen( tmp ) ) == 1 )
189 printf( "%s(Test1Function2): Error setting stem index.\n", DLLNAME );
190 static_show_parameter(argc,argv,NAME_FUNCTION2);
191 global_show_parameter(argc,argv,NAME_FUNCTION2);
192 /*
193 * Set return code...
194 */
195 strcpy(retstr->strptr,"0");
196 retstr->strlength = 1;
197 return 0L;
198 }
199
200
DROPFUNCS(PCSZ name,ULONG argc,PRXSTRING argv,PCSZ stck,PRXSTRING retstr)201 APIRET APIENTRY DROPFUNCS(PCSZ name,ULONG argc,PRXSTRING argv,PCSZ stck,PRXSTRING retstr)
202 {
203 int rc=0;
204 const RexxTestFunction *func=NULL;
205
206 /* DeRegister all REXX functions */
207 for (func = RexxTestFunctions; func->function_name; func++)
208 rc = RexxDeregisterFunction(func->function_name);
209 sprintf(retstr->strptr,"%d",rc);
210 retstr->strlength = strlen(retstr->strptr);
211 return 0L;
212 }
213
214
215 /*-----------------------------------------------------------------------------
216 * This function is called to initiate REXX interface.
217 *----------------------------------------------------------------------------*/
InitTestRexx(PSZ progname)218 static int InitTestRexx(PSZ progname)
219 {
220 const RexxTestFunction *func=NULL;
221 ULONG rc=0L;
222
223 /* Register all REXX functions */
224 for (func = RexxTestFunctions; func->function_name; func++)
225 rc = RexxRegisterFunctionDll(func->function_name,DLLNAME,func->function_name);
226
227 return rc;
228 }
229
LOADFUNCS(PCSZ name,ULONG argc,PRXSTRING argv,PCSZ stck,PRXSTRING retstr)230 APIRET APIENTRY LOADFUNCS(PCSZ name,ULONG argc,PRXSTRING argv,PCSZ stck,PRXSTRING retstr)
231 {
232 int rc=0;
233
234 rc = InitTestRexx(DLLNAME);
235 printf("%s built %s %s\n",DLLNAME,__DATE__,__TIME__);
236 sprintf(retstr->strptr,"%d",rc);
237 retstr->strlength = strlen(retstr->strptr);
238 return 0L;
239 }
240
241 #if defined( DYNAMIC_STATIC )
getTest1FunctionAddress(char * name)242 void *getTest1FunctionAddress( char *name )
243 {
244 const RexxTestFunction *func=NULL;
245 for (func = RexxTestFunctions; func->function_name; func++)
246 {
247 if ( strcmp( func->function_name, name) == 0 )
248 return func->EntryPoint;
249 }
250 return NULL;
251 }
252 #endif
253
254 #if !defined( DYNAMIC_STATIC )
255 # ifdef SKYOS
256 /*
257 * Required as entry point for DLL under SkyOS
258 */
DllMain(void)259 int DllMain( void )
260 {
261 return 0;
262 }
263 # endif
264 #endif
265