home *** CD-ROM | disk | FTP | other *** search
- /*
- * This file sends out and recieves REXX commands (well recieving them means
- * we hand the off to excline, but...)
- */
- #include "rexx.h"
-
- #ifdef REXX
-
- #include <exec/types.h>
- #include <exec/ports.h>
- #include <rexx/storage.h>
- #include <rexx/rxslib.h>
- #ifdef LATTICE
- #include <proto/exec.h>
- #include <proto/intuition.h>
- #else
- #include <functions.h>
- #endif
-
- #undef TRUE
- #undef FALSE
- #include "def.h"
- #include "line.h"
- #include "buffer.h"
- #include "window.h"
- #include "macro.h"
- #include "region.h"
-
- #ifdef ANSI
- #undef EOF /* Strange..., but stdio complains about it */
- #include <stdio.h> /* Only if we've got sprintf in here */
- #include <stdlib.h>
- #include <fcntl.h>
- #undef HUGE /* Collides with math.h */
- #include <math.h>
- #include <string.h>
- #endif
-
- /*
- * The pointer to the Rexx library, which we really want when dealing with
- * Rexx, and some return value for messages.
- */
- struct Library *RexxSysBase;
- #define FAIL_LOCKED 3
- #define FAIL_NOREXX 4
-
- /*
- * My static functions.
- */
- static int rexxdocommand PROTO((char *, long));
- static int getrexxargs PROTO((struct RexxMsg *, int));
- static int rexxread PROTO((int));
- static int rexxstemint PROTO((char *, int, int));
- static int rexxstemstring PROTO((char *, int, char *, int));
- static int findline PROTO((struct line *));
- static struct MsgPort *lockport PROTO((char *));
- static int spinport PROTO((struct MsgPort *));
-
- #ifdef LATTICE
- long __stdargs SetRexxVar PROTO((struct RexxMsg *, char *, char *, long)) ;
- #else
- long SetRexxVar PROTO((struct RexxMsg *, char *, char *, long)) ;
- static char *strupr PROTO((char *));
- #endif
-
- struct RexxArg *CreateArgstring PROTO((char *, long)) ;
- long LengthArgstring PROTO((struct RexxArg *)) ;
- void DeleteArgstring PROTO((struct RexxArg *)) ;
- struct RexxMsg *CreateRexxMsg PROTO((struct MsgPort *, char *, char *)) ;
- void ClearRexxMsg PROTO((struct RexxMsg *, long)) ;
- void DeleteRexxMsg PROTO((struct RexxMsg *)) ;
-
- /*
- * Pointer to rexx macro to run on exit.
- */
- static char *RexxExitCmd;
-
- /*
- * Commands that return results can only do so if the RexxMsg that caused
- * them to be executed is willing to take results. To make this test easy,
- * the RexxMsg is stored in CurrentMsg between it's being recieved and
- * sending out the reply. Any other time, it will be NULL, and the Rexx
- * command check for that if they shouldn't be executed unless there is a
- * RexxMsg active. In addition, rexxlock needs to reply to this message
- * indicating that the lock succeeded before going into locked mode, so it
- * needs access to CurrentMsg. Result strings get passed from rexx commands
- * back to the script - and the other way, in the case of rexxdoregion - via
- * RexxResult. It's normally NULL, unless the executed command set a result,
- * or a macro that we were still locked to on exit returned a result. In
- * which case, it points to the RexxArgstring for the result. The consumer is
- * responsible for deleting it, and the producer is responsible for creating
- * it.
- *
- */
- static struct RexxMsg *CurrentMsg = NULL;
- static struct RexxArg *RexxResult = NULL;
-
- /*
- * Things for dealing with asynch REXX messages. rexxport is the port that
- * those messages come in on, and it's name is mgname. Since rexxport must be
- * checked for messages in the event loop, it's not static. RepliesNeeded is
- * the number of reply messages we need to see on rexxport. Lockadd is the
- * address of the port name that a given macro is locked to, or NULL if we're
- * not locked. ADDSIZE is the size of the port name we use for dynamically
- * allocated ports
- */
- struct MsgPort *rexxport = NULL;
- static char mgname[5] = "mg\0\0";
- static unsigned RepliesNeeded = 0;
- static char *lockadd = NULL;
- #define ADDSIZE 8
-
- /*
- * This routine dispatches any REXX messages coming in. However, to allow for
- * REXX commands that start other REXX commands, we must save and restore the
- * environment (CurrentMsg).
- */
- int
- disprexx(inport)
- struct MsgPort *inport;
- {
- register int s, t;
- register struct RexxMsg *savemsg;
-
- savemsg = CurrentMsg;
-
- for (;;) {
- RexxResult = NULL;
- /* Check for commands */
- if (inport && (CurrentMsg = (struct RexxMsg *) GetMsg(inport))) {
- if (CurrentMsg->rm_Node.mn_Node.ln_Type != NT_REPLYMSG)
- s = excline(ARG0(CurrentMsg),
- LengthArgstring((struct RexxArg *) ARG0(CurrentMsg)));
- }
- /* And then for replies or asynch commands */
- else if (CurrentMsg = (struct RexxMsg *) GetMsg(rexxport)) {
- if (CurrentMsg->rm_Node.mn_Node.ln_Type != NT_REPLYMSG)
- if (!inport)
- s = FAIL_NOREXX;
- else if (lockadd)
- s = FAIL_LOCKED;
- else
- s = excline(ARG0(CurrentMsg),
- LengthArgstring((struct RexxArg *) ARG0(CurrentMsg)));
- }
- if (CurrentMsg == NULL)
- break;
- if (CurrentMsg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG) {
- RepliesNeeded -= 1;
- s = CurrentMsg->rm_Result1 < 2
- ? 1 - CurrentMsg->rm_Result1
- : ABORT;
- t = ((char *)CurrentMsg->rm_CommAddr == lockadd);
- if (s == TRUE && (CurrentMsg->rm_Action & RXFF_RESULT)
- && CurrentMsg->rm_Result2 != NULL)
- /* Aha - a result. Deal with it. */
- if (t)
- RexxResult = (struct RexxArg *) CurrentMsg->rm_Result2;
- else
- DeleteArgstring((struct RexxArg *)
- CurrentMsg->rm_Result2);
- /* Free the memory for this message */
- FreeMem(CurrentMsg->rm_CommAddr, ADDSIZE);
- ClearRexxMsg(CurrentMsg, 16);
- DeleteRexxMsg(CurrentMsg);
- if (!t)
- continue;
- CurrentMsg = savemsg;
- lockadd = NULL;
- return s;
- }
- if (s < 2)
- s = 1 - s;
- CurrentMsg->rm_Result1 = s;
- CurrentMsg->rm_Result2 = (RexxResult != NULL)
- ? (LONG) RexxResult
- : 0L;
- ReplyMsg((struct Message *) CurrentMsg);
- }
- CurrentMsg = savemsg;
- return -1;
- }
-
- void
- openrexx()
- {
- register short i, j;
-
- if ((RexxSysBase = OpenLibrary(RXSNAME, 0)) == NULL)
- return;
- srand((unsigned) &lockadd); /* Just to make things change */
- for (i = 33; i < 127; i++) {
- for (j = 33; j < 127; j++) {
- Forbid();
- if (FindPort(mgname) == NULL)
- rexxport = CreatePort(mgname, 0L);
- Permit();
- if (rexxport != NULL)
- return;
- mgname[2] = j;
- }
- mgname[3] = i;
- }
-
- /* No port opened, so we don't do Rexx, so we close RexxSysBase */
- CloseLibrary(RexxSysBase);
- RexxSysBase = NULL;
- }
-
- void
- closerexx()
- {
-
- if (!RexxSysBase)
- return; /* No Rexx to close */
- if (RexxExitCmd != NULL)
- rexxdocommand(RexxExitCmd, RXCOMM);
- if (rexxport) {
- while (RepliesNeeded) {
- WaitPort(rexxport);
- disprexx(NULL);
- }
- DeletePort(rexxport);
- }
- CloseLibrary(RexxSysBase);
- }
- /*
- * Commands that make Rexx macros execute.
- */
-
- rexxexitcommand(f, n)
- {
- int s;
- static char exitcom[NLINE];
-
- if (!RexxSysBase)
- return FALSE;
- if ((s = ereply("REXX command to run on exit: ", exitcom, NLINE)) != TRUE)
- return s;
- RexxExitCmd = exitcom;
- return TRUE;
- }
-
- rexxcommand(f, n)
- {
- int s;
- char cmd[NLINE];
-
- if (!RexxSysBase)
- return FALSE;
- if ((s = ereply("REXX command: ", cmd, NLINE)) != TRUE)
- return s;
-
- return rexxdocommand(cmd, f & FFUNIV ? RXCOMM | RXFF_TOKEN : RXCOMM);
- }
-
- rexxcomregion(f, n)
- int f, n;
- {
- char *out;
- register RSIZE length, size;
- register struct line *lp;
- int status, insertres;
- char *string;
- struct region reg;
-
- if (!RexxSysBase)
- return FALSE;
- if ((length = getregion(®)) != TRUE)
- return length;
- size = reg.r_size;
-
- if ((out = malloc(size + 1)) == NULL) {
- ewprintf("Can't get %d bytes", size + 1);
- return FALSE;
- }
- string = out; /* Save the start of the thing... */
-
- /* Copy the region to out */
- lp = reg.r_linep;
- length = llength(lp) - reg.r_offset;
- bcopy(<ext(lp)[reg.r_offset], out, length);
- size -= length;
- out += length;
-
- while (size > 0) {
- /* Add a newline to the output string */
- *out++ = '\n';
- size -= 1;
-
- /* Add part/all of the current line to the output string */
- lp = lforw(lp);
- length = llength(lp);
- if (length > size)
- length = size;
- bcopy(ltext(lp), out, length);
- out += length;
- size -= length;
- }
- *out = '\0';
-
- /* Figure out how many arguments we really have */
- insertres = (n <= 0);
- if ((f & FFARG) == 0)
- n = 0;
- else if (insertres)
- n = -n;
- if (n > MAXRMARG) {
- ewprintf("Can only have %d args for rexx commands", MAXRMARG);
- n = MAXRMARG;
- }
- status = rexxdocommand(string, RXFUNC | RXFF_RESULT | RXFF_STRING | n);
-
- /* Deal with result string if we've got one */
- if (status == TRUE && RexxResult != NULL) {
- if (insertres)
- sinsert((char *) RexxResult);
- else
- ewprintf("Result was: %s", (char *) RexxResult);
- DeleteArgstring(RexxResult);
- }
- RexxResult = NULL;
- return status;
- }
- /*
- * rexxgetargs - get N args from the user, returning ABORT if they abort,
- * etc.
- */
- int
- getrexxargs(msg, n)
- struct RexxMsg *msg;
- int n;
- {
- register int count, status = TRUE;
- char arg[NLINE];
-
- for (count = 1; count <= n; count += 1) {
- if ((status = ereply("Arg #%d? ", arg, NLINE, count)) != TRUE
- || (msg->rm_Args[count] =
- (STRPTR) CreateArgstring(arg, strlen(arg))) == NULL)
- break;
- }
- return status;
- }
-
- /*
- * Finish filling in the msg, send the message to Rexx, and then call
- * spinport to get the work done. We get here from commands that can be
- * issued by macros, so we can be run when locked. So we have to save lockadd
- * upon entry, and restore it before we exit.
- */
- static
- rexxdocommand(command, action)
- char *command;
- long action;
- {
- register struct RexxMsg *out = NULL;
- struct MsgPort *macport = NULL, *rexx;
- int s;
- char *savelock;
-
- if (rexxport == NULL)
- return FALSE;
- savelock = lockadd;
- if ((lockadd = AllocMem(ADDSIZE, 0L)) == NULL) {
- ewprintf("Can't get %d bytes", ADDSIZE);
- goto error;
- }
- if ((macport = lockport(lockadd)) == NULL)
- goto error;
- if ((out = CreateRexxMsg(rexxport, "mg", lockadd)) == NULL
- || (out->rm_Args[0] = (STRPTR) CreateArgstring(command, strlen(command))) == NULL
- || ((action & RXFUNC) && (s = getrexxargs(out, action & 0xF)) != TRUE))
- goto error;
- out->rm_Action = action;
-
- Forbid();
- rexx = FindPort("REXX");
- if (rexx)
- PutMsg(rexx, (struct Message *) out);
- Permit();
- if (!rexx) {
- s = FALSE;
- goto error;
- }
- RepliesNeeded += 1;
-
- /* Spin until macro finishes, or unlocked */
- s = spinport(macport);
- lockadd = savelock;
- return s;
-
- /* Something died, so clean up and tell the use about it */
- error:
- if (lockadd)
- FreeMem(lockadd, ADDSIZE);
- if (macport)
- DeletePort(macport);
- if (out) {
- ClearRexxMsg(out, 16);
- DeleteRexxMsg(out);
- }
- lockadd = savelock;
- return s;
- }
-
- /*
- * Set lockadd to the name of a public port, and return the address of the
- * port.
- */
- static struct MsgPort *
- lockport(portname)
- char *portname;
- {
- struct MsgPort *port = NULL;
-
- while (port == NULL) {
- sprintf(portname, "mg_%04d", rand() % 10000);
- Forbid();
- if (FindPort(portname) == NULL)
- port = CreatePort(portname, 0L);
- Permit();
- }
- return port;
- }
-
- /*
- * Spin on the port we got passed until either rexxunlock is called, or until
- * we get a reply message for the macro we started. In the fomer case, return
- * true; in the latter, return the value the macro returned.
- */
- static int
- spinport(port)
- struct MsgPort *port;
- {
- register int s;
- register int sigbits;
-
- sigbits = (1l << rexxport->mp_SigBit) | (1L << port->mp_SigBit);
- do {
- Wait(sigbits);
- } while ((s = disprexx(port)) < 0 && lockadd);
-
- DeletePort(port);
- if (lockadd)
- rexxunlock(FFRAND, 1);
- else
- s = TRUE;
- return s;
- }
-
- /*
- * rexx locking & unlocking functions. Rexxlock creates a new port for the
- * macro we're locking, and calls spinport on that port. Rexxunlock just
- * toggles the global lockadd to indicate we're not locked. Both return the
- * public port name that will now accept messages to the invoking rexx
- * program.
- */
- rexxlock(f, n)
- int f, n;
- {
- struct MsgPort *port;
- char lockname[ADDSIZE];
-
- /* Make sure we got called properly */
- if (!CurrentMsg || lockadd || !(CurrentMsg->rm_Action & RXFF_RESULT))
- return FALSE;
-
- if ((port = lockport(lockname)) == NULL)
- return FALSE;
-
- CurrentMsg->rm_Result1 = 0;
- lockadd = (char *) CreateArgstring(lockname, strlen(lockname));
- CurrentMsg->rm_Result2 = (long) lockadd;
- ReplyMsg((struct Message *) CurrentMsg);
-
- /* Tun off the reply to this message in disprexx */
- CurrentMsg = NULL;
- return spinport(port);
- }
-
- rexxunlock(f, n)
- int f, n;
- {
-
- lockadd = NULL;
- if (!(f & FFRAND) && CurrentMsg && CurrentMsg->rm_Action & RXFF_RESULT)
- RexxResult = CreateArgstring(mgname, strlen(mgname));
- return TRUE;
- }
- /*
- * rexx echo line functions.
- */
- rexxdisplay(f, n)
- int f, n;
- {
- struct macro *save;
- char buf[NLINE];
-
- if (!CurrentMsg)
- return FALSE;
- eread("", buf, NLINE, 0);
- save = inmacro;
- inmacro = NULL;
- ewprintf("%s", buf);
- inmacro = save;
- return TRUE;
- }
-
- rexxrequest(f, n)
- int f, n;
- {
-
- return rexxread(EFNEW);
- }
-
- rexxreqbuf(f, n)
- int f, n;
- {
-
- return rexxread(EFNEW | EFBUF);
- }
-
- rexxreqfunc(f, n)
- int f, n;
- {
-
- return rexxread(EFNEW | EFFUNC);
- }
-
- rexxreqmacro(f, n)
- int f, n;
- {
-
- return rexxread(EFNEW | EFMACRO);
- }
-
- static
- rexxread(flag)
- {
- char buf[NLINE], inbuf[NLINE];
- struct macro *save;
- int status;
-
- if (!CurrentMsg)
- return FALSE;
- eread("", buf, NLINE, 0);
- save = inmacro;
- inmacro = NULL;
- if ((status = eread("%s", inbuf, NLINE, flag, buf)) == TRUE
- && (CurrentMsg->rm_Action & RXFF_RESULT))
- RexxResult = CreateArgstring(inbuf, strlen(inbuf));
- inmacro = save;
- return status;
- }
- /*
- * Misc. rexx functions.
- */
- rexxinsert(f, n)
- int f, n;
- {
- KCHAR c;
-
- if (!CurrentMsg)
- return FALSE;
- c = getkey(SEESCR);
- while (c != SOFTCR) {
- if (((c == '\n') ? lnewline() : linsert(1, c)) != TRUE)
- return FALSE;
- c = getkey(SEESCR);
- }
- return TRUE;
- }
-
- rexxline(f, n)
- int f, n;
- {
- register struct line *clp;
-
- if ((CurrentMsg->rm_Action & RXFF_RESULT) == 0)
- return TRUE;
- if ((f & FFARG) == 0)
- clp = curwp->w_dotp;
- else if (n > 0) {
- clp = lforw(curbp->b_linep); /* "clp" is first line */
- while (--n > 0) {
- if (lforw(clp) == curbp->b_linep)
- return FALSE;
- clp = lforw(clp);
- }
- } else {
- clp = lback(curbp->b_linep); /* clp is last line */
- while (n < 0) {
- if (lback(clp) == curbp->b_linep)
- return FALSE;
- clp = lback(clp);
- n++;
- }
- }
- RexxResult = CreateArgstring(ltext(clp), llength(clp));
- return TRUE;
- }
-
- /*
- * A pair of tools for manipulating the window we use.
- */
- rexxwait(f, n)
- int f, n;
- {
-
- if (!RexxSysBase)
- return FALSE;
- tthide(FALSE);
- WaitPort(rexxport);
- ttshow(FALSE);
- /* Go run the command and update the screen */
- disprexx(rexxport);
- update();
- return TRUE;
- }
-
- rexxtopwindow(f, n)
- int f, n;
- {
- extern struct Window *EmW;
-
- WindowToFront(EmW);
- return TRUE;
- }
-
- /*
- * rexx stem-variable functions.
- */
- rexxwindow(f, n)
- int f, n;
- {
- char stem[NLINE];
- register int count;
-
- if (!CurrentMsg)
- return FALSE;
- eread("", stem, NLINE, 0);
-
- /* Upcase the variable name: required by the interface */
- strupr(stem);
-
- /* Window Dimensions */
- if (rexxstemint(stem, 1, curwp->w_ntrows) == FALSE)
- count = 0;
- else if (rexxstemint(stem, 2, ncol) == FALSE)
- count = 1;
- else if (rexxstemint(stem, 3, findline(curwp->w_linep)) == FALSE)
- count = 2;
- else if (curwp->w_bufp == NULL || curwp->w_bufp->b_bname == NULL
- || rexxstemstring(stem, 4, curwp->w_bufp->b_bname, -1) == FALSE)
- count = 3;
- else if (rexxstemstring(stem, 5, curwp->w_bufp->b_fname, -1) == FALSE)
- count = 4;
- else
- count = 5; /* Did them ALL! */
-
- rexxstemint(stem, 0, count);
- return count == 5;
- }
-
- rexxpoint(f, n)
- int f, n;
- {
- char stem[NLINE];
- register int count;
-
- if (!CurrentMsg)
- return FALSE;
- eread("", stem, NLINE, 0);
-
- /* Upcase the variable name: required by the interface */
- strupr(stem);
-
- if (rexxstemint(stem, 1, findline(curwp->w_dotp)) == FALSE)
- count = 0;
- else if (rexxstemint(stem, 2, curwp->w_doto + 1) == FALSE)
- count = 1;
- else if (rexxstemstring(stem, 3, ltext(curwp->w_dotp), llength(curwp->w_dotp)) == FALSE)
- count = 2;
- else
- count = 3;
-
- rexxstemint(stem, 0, count);
- return count == 3;
- }
-
- rexxmark(f, n)
- int f, n;
- {
- char stem[NLINE];
- register int count;
-
- if (!CurrentMsg)
- return FALSE;
- eread("", stem, NLINE, 0);
-
- if (curwp->w_markp == NULL) { /* No mark */
- rexxstemint(stem, 0, 0);
- return FALSE;
- }
- /* Upcase the variable name: required by the interface */
- strupr(stem);
-
- if (rexxstemint(stem, 1, findline(curwp->w_markp)) == FALSE)
- count = 0;
- else if (rexxstemint(stem, 2, curwp->w_marko + 1) == FALSE)
- count = 1;
- else if (rexxstemstring(stem, 3, ltext(curwp->w_markp), llength(curwp->w_markp)) == FALSE)
- count = 2;
- else
- count = 3;
-
- rexxstemint(stem, 0, count);
- return count == 3;
- }
-
- rexxbuffer(f, n)
- int f, n;
- {
- char stem[NLINE];
- register int count;
- register RSIZE chars, lines;
- RSIZE mark, point;
- register struct line *clp;
-
- if (!CurrentMsg)
- return FALSE;
- eread("", stem, NLINE, 0);
-
- /* Upcase the variable name: required by the interface */
- strupr(stem);
-
- /* Find the line & dot numbers */
- clp = lforw(curbp->b_linep);
- mark = point = chars = 0;
- for (lines = 1;; lines += 1) {
- chars += llength(clp);
- if (clp == curwp->w_dotp)
- point = lines;
- if (clp == curwp->w_markp)
- mark = lines;
- if ((clp = lforw(clp)) == curbp->b_linep)
- break;
- chars += 1; /* Newline, if present */
- }
-
- if (curbp->b_bname == NULL
- || rexxstemstring(stem, 1, curbp->b_bname, -1) == FALSE)
- count = 0;
- else if (rexxstemstring(stem, 2, curbp->b_fname, -1) == FALSE)
- count = 1;
- else if (rexxstemint(stem, 3, lines) == FALSE)
- count = 2;
- else if (rexxstemint(stem, 4, chars) == FALSE)
- count = 3;
- else if (rexxstemint(stem, 5, point) == FALSE)
- count = 4;
- else if (mark == 0 || rexxstemint(stem, 6, mark) == FALSE)
- count = 5;
- else
- count = 6;
-
- rexxstemint(stem, 0, count);
- return count == 6;
- }
-
- rexxbuflist(f, n)
- int f, n;
- {
- char stem[NLINE], var[NLINE + 10], value[NLINE];
- register int count;
- register struct buffer *bp;
-
- if (!CurrentMsg)
- return FALSE;
- eread("", stem, NLINE, 0);
-
- /* Upcase the variable name: required by the interface */
- strupr(stem);
-
- for (count = 1, bp = bheadp; bp; bp = bp->b_bufp, count += 1) {
- if (bp->b_bname == NULL)
- break;
- sprintf(var, "%s.%d.NAME", stem, count);
- strcpy(value, bp->b_bname);
- if (SetRexxVar(CurrentMsg, var, value, strlen(value)))
- break;
- sprintf(var, "%s.%d.FILE", stem, count);
- strcpy(value, bp->b_fname);
- if (SetRexxVar(CurrentMsg, var, value, strlen(value)))
- break;
- sprintf(var, "%s.%d.STATUS", stem, count);
- value[0] = '\0';
- if (bp->b_flag & BFCHG)
- strcat(value, "CHANGED ");
- if (bp == curbp)
- strcat(value, "CURRENT");
- if (SetRexxVar(CurrentMsg, var, value, strlen(value)))
- break;
- }
-
- rexxstemint(stem, 0, count - 1);
- return bp == NULL;
- }
-
- rexxregion(f, n)
- int f, n;
- {
- register struct line *lp;
- register RSIZE count, length;
- char stem[NLINE], out[NLINE + 2];
- struct region reg;
-
- if (!CurrentMsg)
- return FALSE;
- eread("", stem, NLINE, 0);
- strupr(stem);
-
- if ((count = getregion(®)) != TRUE) {
- rexxstemint(stem, 0, 0);
- return count;
- }
- lp = reg.r_linep;
-
- /* Set up end of first line */
- length = llength(lp) - reg.r_offset;
- bcopy(<ext(lp)[reg.r_offset], out, length);
- count = 1;
-
- while (reg.r_size > length) {
- out[length] = '\n';
- if (rexxstemstring(stem, count, out, length + 1) == FALSE)
- reg.r_size = -1;
- else {
- reg.r_size -= length + 1;
- count += 1;
- lp = lforw(lp);
- length = llength(lp);
- bcopy(ltext(lp), out, length);
- }
- }
-
- /* Now, if needed, do head of last line */
- if (reg.r_size <= 0)
- count -= 1;
- else if (rexxstemstring(stem, count, out, reg.r_size) == FALSE) {
- reg.r_size = -1;
- count -= 1;
- }
- rexxstemint(stem, 0, count);
- return reg.r_size != -1;
- }
-
- static int
- rexxstemint(stem, count, in)
- char *stem;
- int count, in;
- {
- char var[NLINE + 2], value[NLINE];
-
- sprintf(var, "%s.%d", stem, count);
- sprintf(value, "%d", in);
- return SetRexxVar(CurrentMsg, var, value, strlen(value)) == 0;
- }
-
- static int
- rexxstemstring(stem, count, value, length)
- char *stem;
- int count;
- char *value;
- int length;
- {
- char var[NLINE + 2];
-
- sprintf(var, "%s.%d", stem, count);
- if (length < 0)
- length = strlen(value);
- return SetRexxVar(CurrentMsg, var, value, length) == 0;
- }
-
- static int
- findline(lp)
- struct line *lp;
- {
- register struct line *slp;
- register int count;
-
- for (slp = curbp->b_linep, count = 0;
- slp != lp;
- slp = lforw(slp), count += 1);
- return count;
- }
-
- #ifndef LATTICE
- static char *
- strupr(s)
- char *s;
- {
- char *c;
- extern char toupper();
-
- c=s;
- while(*s) {
- *s = toupper(*s);
- s++;
- }
- return(c);
- }
- #endif
- #else
- #include "nullfile.h"
- #endif
-