summaryrefslogtreecommitdiff
path: root/os2/OS2/REXX/DLL/DLL.xs
blob: c8e7c58007b9faeb87044c784947c56764150d5c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#define INCL_BASE
#define INCL_REXXSAA
#include <os2emx.h>

static RXSTRING * strs;
static int	  nstrs;
static char *	  trace;

static void
needstrs(int n)
{
    if (n > nstrs) {
	if (strs)
	    free(strs);
	nstrs = 2 * n;
	strs = malloc(nstrs * sizeof(RXSTRING));
    }
}

MODULE = OS2::DLL		PACKAGE = OS2::DLL

BOOT:
    needstrs(8);
    trace = getenv("PERL_REXX_DEBUG");

SV *
_call(name, address, queue="SESSION", ...)
	char *		name
	void *		address
	char *		queue
 CODE:
   {
       ULONG	rc;
       int	argc, i;
       RXSTRING	result;
       UCHAR	resbuf[256];
       RexxFunctionHandler *fcn = address;
       argc = items-3;
       needstrs(argc);
       if (trace)
	   fprintf(stderr, "REXXCALL::_call name: '%s' args:", name);
       for (i = 0; i < argc; ++i) {
	   STRLEN len;
	   char *ptr = SvPV(ST(3+i), len);
	   MAKERXSTRING(strs[i], ptr, len);
	   if (trace)
	       fprintf(stderr, " '%.*s'", len, ptr);
       }
       if (!*queue)
	   queue = "SESSION";
       if (trace)
	   fprintf(stderr, "\n");
       MAKERXSTRING(result, resbuf, sizeof resbuf);
       rc = fcn(name, argc, strs, queue, &result);
       if (trace)
	   fprintf(stderr, "  rc=%X, result='%.*s'\n", rc,
		   result.strlength, result.strptr);
       ST(0) = sv_newmortal();
       if (rc == 0) {
	   if (result.strptr)
	       sv_setpvn(ST(0), result.strptr, result.strlength);
	   else
	       sv_setpvn(ST(0), "", 0);
       }
       if (result.strptr && result.strptr != resbuf)
	   DosFreeMem(result.strptr);
   }