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