17 extern ULONG _emx_exception ( EXCEPTIONREPORTRECORD *,
18 EXCEPTIONREGISTRATIONRECORD *,
22 static RXSTRING * strs;
24 static SHVBLOCK * vars;
29 static RXSTRING rxcommand = { 9, "RXCOMMAND" };
30 static RXSTRING rxsubroutine = { 12, "RXSUBROUTINE" };
31 static RXSTRING rxfunction = { 11, "RXFUNCTION" };
34 static ULONG PERLCALL(PCSZ name, ULONG argc, PRXSTRING argv, PCSZ queue, PRXSTRING ret);
35 static ULONG PERLCALLcv(PCSZ name, SV *cv, ULONG argc, PRXSTRING argv, PCSZ queue, PRXSTRING ret);
36 static ULONG PERLSTART(PCSZ name, ULONG argc, PRXSTRING argv, PCSZ queue, PRXSTRING ret);
37 static RexxSubcomHandler SubCommandPerlEval;
41 #define Fetch RXSHV_FETCH
42 #define Drop RXSHV_DROPV
44 #define Set RXSHV_SYSET
45 #define Fetch RXSHV_SYFET
46 #define Drop RXSHV_SYDRO
49 static long incompartment; /* May be used to unload the REXX */
51 static LONG APIENTRY (*pRexxStart) (LONG, PRXSTRING, PSZ, PRXSTRING,
52 PSZ, LONG, PRXSYSEXIT, PSHORT, PRXSTRING);
53 static APIRET APIENTRY (*pRexxRegisterFunctionExe) (PSZ,
54 RexxFunctionHandler *);
55 static APIRET APIENTRY (*pRexxDeregisterFunction) (PSZ);
57 static ULONG (*pRexxVariablePool) (PSHVBLOCK pRequest);
61 /* Create a REXX compartment,
62 register `n' callbacks `handlers' with the REXX names `handlerNames',
63 evaluate the REXX expression `cmd'.
66 exec_in_REXX_with(pTHX_ char *cmd, int c, char **handlerNames, RexxFunctionHandler **handlers)
75 int n = c, have_nl = 0;
76 char *ocmd = cmd, *s, *t;
81 Newz(728, subs, c, char);
83 rc = pRexxRegisterFunctionExe(handlerNames[n], handlers[n]);
84 if (rc == RXFUNC_DEFINED)
90 if (*s == '\n') { /* Is not preceeded by \r! */
91 New(728, cmd, 2*strlen(cmd)+1, char);
101 } else if (*s == '\r')
105 MAKERXSTRING(args[0], NULL, 0);
106 MAKERXSTRING(inst[0], cmd, strlen(cmd));
107 MAKERXSTRING(inst[1], NULL, 0);
108 MAKERXSTRING(result, NULL, 0);
109 rc = pRexxStart(0, args, /* No arguments */
110 "REXX_in_Perl", /* Returned on REXX' PARSE SOURCE,
111 and the "macrospace function name" */
112 inst, /* inst[0] - the code to execute,
113 inst[1] will contain tokens. */
114 "Perl", /* Pass string-cmds to this callback */
115 RXSUBROUTINE, /* Many arguments, maybe result */
116 NULL, /* No callbacks/exits to register */
123 pRexxDeregisterFunction(handlerNames[n]);
128 #if 0 /* Do we want to restore these? */
129 DosFreeModule(hRexxAPI);
130 DosFreeModule(hRexx);
133 if (RXSTRPTR(inst[1])) /* Free the tokenized version */
134 DosFreeMem(RXSTRPTR(inst[1]));
135 if (!RXNULLSTRING(result)) {
136 res = newSVpv(RXSTRPTR(result), RXSTRLEN(result));
137 DosFreeMem(RXSTRPTR(result));
141 if (rc || SvTRUE(GvSV(PL_errgv))) {
142 if (SvTRUE(GvSV(PL_errgv))) {
144 Perl_croak(aTHX_ "Error inside perl function called from REXX compartment:\n%s", SvPV(GvSV(PL_errgv), n_a)) ;
146 Perl_croak(aTHX_ "REXX compartment returned non-zero status %li", rc);
152 /* Call the Perl function given by name, or if name=0, by cv,
153 with the given arguments. Return the stringified result to REXX. */
155 PERLCALLcv(PCSZ name, SV *cv, ULONG argc, PRXSTRING argv, PCSZ queue, PRXSTRING ret)
158 EXCEPTIONREGISTRATIONRECORD xreg = { NULL, _emx_exception };
165 DosSetExceptionHandler(&xreg);
173 DosUnsetExceptionHandler(&xreg);
178 for (i = 0; i < argc; ++i)
179 XPUSHs(sv_2mortal(newSVpvn(argv[i].strptr, argv[i].strlength)));
182 rc = perl_call_pv(name, G_SCALAR | G_EVAL);
184 rc = perl_call_sv(cv, G_SCALAR | G_EVAL);
190 if (rc == 1) /* must be! */
192 if (rc == 1 && SvOK(res)) {
193 str = SvPVx(res, len);
194 if (len <= 256 /* Default buffer is 256-char long */
195 || !CheckOSError(DosAllocMem((PPVOID)&ret->strptr, len,
196 PAG_READ|PAG_WRITE|PAG_COMMIT))) {
197 memcpy(ret->strptr, str, len);
198 ret->strlength = len;
208 DosUnsetExceptionHandler(&xreg);
209 return rc == 1 ? 0 : 1; /* 0 means SUCCESS */
213 PERLSTART(PCSZ name, ULONG argc, PRXSTRING argv, PCSZ queue, PRXSTRING ret)
218 return PERLCALLcv(NULL, cv, argc, argv, queue, ret);
222 PERLCALL(PCSZ name, ULONG argc, PRXSTRING argv, PCSZ queue, PRXSTRING ret)
224 return PERLCALLcv(name, Nullsv, argc, argv, queue, ret);
227 RexxFunctionHandler* PF = &PERLSTART;
228 char* PF_name = "StartPerl";
230 #define REXX_eval_with(cmd,name,cv) \
231 ( exec_cv = cv, exec_in_REXX_with(aTHX_ (cmd),1, &(name), &PF))
232 #define REXX_call(cv) REXX_eval_with("return StartPerl()\r\n", PF_name, (cv))
233 #define REXX_eval(cmd) ( exec_in_REXX_with(aTHX_ (cmd), 0, NULL, NULL))
237 PRXSTRING command, /* command to issue */
238 PUSHORT flags, /* error/failure flags */
239 PRXSTRING retstr ) /* return code */
251 in = sv_2mortal(newSVpvn(command->strptr, command->strlength));
252 eval_sv(in, G_SCALAR);
259 *flags = RXSUBCOM_ERROR; /* raise error condition */
260 str = SvPV(ERRSV, len);
261 } else if (!SvOK(res)) {
262 *flags = RXSUBCOM_ERROR; /* raise error condition */
263 str = "undefined value returned by Perl-in-REXX";
266 str = SvPV(res, len);
267 if (len <= 256 /* Default buffer is 256-char long */
268 || !DosAllocMem((PPVOID)&retstr->strptr, len,
269 PAG_READ|PAG_WRITE|PAG_COMMIT)) {
270 memcpy(retstr->strptr, str, len);
271 retstr->strlength = len;
273 *flags = RXSUBCOM_ERROR; /* raise error condition */
274 strcpy(retstr->strptr, "Not enough memory for the return string of Perl-in-REXX");
275 retstr->strlength = strlen(retstr->strptr);
281 return 0; /* finished */
291 strs = malloc(nstrs * sizeof(RXSTRING));
302 vars = malloc(nvars * sizeof(SHVBLOCK));
310 *(PFN *)&pRexxStart = loadByOrdinal(ORD_RexxStart, 1);
311 *(PFN *)&pRexxRegisterFunctionExe
312 = loadByOrdinal(ORD_RexxRegisterFunctionExe, 1);
313 *(PFN *)&pRexxDeregisterFunction
314 = loadByOrdinal(ORD_RexxDeregisterFunction, 1);
315 *(PFN *)&pRexxVariablePool = loadByOrdinal(ORD_RexxVariablePool, 1);
318 trace = getenv("PERL_REXX_DEBUG");
320 rc = RexxRegisterSubcomExe("PERLEVAL", (PFN)&SubCommandPerlEval, NULL);
324 constant(char *name, int arg)
331 MODULE = OS2::REXX PACKAGE = OS2::REXX
348 int n = (items + 1) / 2;
352 fprintf(stderr, "REXXCALL::_set");
353 for (i = 0; i < n; ++i) {
354 SHVBLOCK * var = &vars[i];
357 name = SvPV(ST(2*i+0),namelen);
359 value = SvPV(ST(2*i+1),valuelen);
365 var->shvcode = RXSHV_SET;
366 var->shvnext = &vars[i+1];
367 var->shvnamelen = namelen;
368 var->shvvaluelen = valuelen;
369 MAKERXSTRING(var->shvname, name, namelen);
370 MAKERXSTRING(var->shvvalue, value, valuelen);
372 fprintf(stderr, " %.*s='%.*s'",
373 (int)var->shvname.strlength, var->shvname.strptr,
374 (int)var->shvvalue.strlength, var->shvvalue.strptr);
377 fprintf(stderr, "\n");
378 vars[n-1].shvnext = NULL;
379 rc = pRexxVariablePool(vars);
381 fprintf(stderr, " rc=%#lX\n", rc);
382 RETVAL = (rc & ~RXSHV_NEWV) ? FALSE : TRUE;
397 fprintf(stderr, "REXXCALL::_fetch");
398 for (i = 0; i < items; ++i) {
399 SHVBLOCK * var = &vars[i];
401 name = SvPV(ST(i),namelen);
402 var->shvcode = RXSHV_FETCH;
403 var->shvnext = &vars[i+1];
404 var->shvnamelen = namelen;
405 var->shvvaluelen = 0;
406 MAKERXSTRING(var->shvname, name, namelen);
407 MAKERXSTRING(var->shvvalue, NULL, 0);
409 fprintf(stderr, " '%s'", name);
412 fprintf(stderr, "\n");
413 vars[items-1].shvnext = NULL;
414 rc = pRexxVariablePool(vars);
415 if (!(rc & ~RXSHV_NEWV)) {
416 for (i = 0; i < items; ++i) {
418 SHVBLOCK * var = &vars[i];
419 /* returned lengths appear to be swapped */
420 /* but beware of "future bug fixes" */
421 namelen = var->shvvalue.strlength; /* should be */
422 if (var->shvvaluelen < var->shvvalue.strlength)
423 namelen = var->shvvaluelen; /* is */
425 fprintf(stderr, " %.*s='%.*s'\n",
426 (int)var->shvname.strlength, var->shvname.strptr,
427 namelen, var->shvvalue.strptr);
428 if (var->shvret & RXSHV_NEWV || !var->shvvalue.strptr)
431 PUSHs(sv_2mortal(newSVpv(var->shvvalue.strptr,
436 fprintf(stderr, " rc=%#lX\n", rc);
448 int len = strlen(stem), namelen, valuelen;
450 fprintf(stderr, "REXXCALL::_next stem='%s'\n", stem);
451 sv.shvcode = RXSHV_NEXTV;
453 MAKERXSTRING(sv.shvvalue, NULL, 0);
455 sv.shvnamelen = sizeof name;
457 MAKERXSTRING(sv.shvname, name, sizeof name);
458 if (sv.shvvalue.strptr) {
459 DosFreeMem(sv.shvvalue.strptr);
460 MAKERXSTRING(sv.shvvalue, NULL, 0);
462 rc = pRexxVariablePool(&sv);
463 } while (!rc && memcmp(stem, sv.shvname.strptr, len) != 0);
466 /* returned lengths appear to be swapped */
467 /* but beware of "future bug fixes" */
468 namelen = sv.shvname.strlength; /* should be */
469 if (sv.shvnamelen < sv.shvname.strlength)
470 namelen = sv.shvnamelen; /* is */
471 valuelen = sv.shvvalue.strlength; /* should be */
472 if (sv.shvvaluelen < sv.shvvalue.strlength)
473 valuelen = sv.shvvaluelen; /* is */
475 fprintf(stderr, " %.*s='%.*s'\n",
476 namelen, sv.shvname.strptr,
477 valuelen, sv.shvvalue.strptr);
478 PUSHs(sv_2mortal(newSVpv(sv.shvname.strptr+len, namelen-len)));
479 if (sv.shvvalue.strptr) {
480 PUSHs(sv_2mortal(newSVpv(sv.shvvalue.strptr, valuelen)));
481 DosFreeMem(sv.shvvalue.strptr);
484 } else if (rc != RXSHV_LVAR) {
485 die("Error %i when in _next", rc);
488 fprintf(stderr, " rc=%#lX\n", rc);
499 for (i = 0; i < items; ++i) {
500 SHVBLOCK * var = &vars[i];
502 name = SvPV(ST(i),namelen);
503 var->shvcode = RXSHV_DROPV;
504 var->shvnext = &vars[i+1];
505 var->shvnamelen = namelen;
506 var->shvvaluelen = 0;
507 MAKERXSTRING(var->shvname, name, var->shvnamelen);
508 MAKERXSTRING(var->shvvalue, NULL, 0);
510 vars[items-1].shvnext = NULL;
511 RETVAL = (pRexxVariablePool(vars) & ~RXSHV_NEWV) ? FALSE : TRUE;
520 RETVAL = pRexxRegisterFunctionExe(name, PERLCALL);
534 REXX_eval_with(cmd,name,cv)
539 #ifdef THIS_IS_NOT_FINISHED
542 _REXX_eval_with(cmd,...)
546 int n = (items - 1)/2;
550 if ((items % 2) == 0)
551 Perl_croak(aTHX_ "Name/values should come in pairs in REXX_eval_with()");
552 New(730, names, n, char*);
553 New(730, cvs, n, SV*);
554 /* XXX Unfinished... */