
/*
 *  REXX.C
 *
 *      (c) Copyright 1987, 1988 by Kim DeVaughn, All Rights Reserved
 *
 *      This program is freely redistributable for non-commercial purposes.
 *
 *      For commercial use, you may contact the author via USENET at:
 *          kim@amdahl.amdahl.com
 *
 *
 *  ARexx interface code, etc. to interface with Matt Dillon's "dme" editor
 *  (v1.29).
 *
 */


#include "defs.h"
#include "rexx.h"

#if AREXX

APTR OpenLibrary();
APTR FindPort();
APTR GetMsg();
APTR CreateRexxMsg();
APTR CreateArgstring();

extern int foundcmd;

struct RxsLib *RexxSysBase;



/*
 * initialization for ARexx ... just open rexsyslib.library
 */

void
openrexx()
{
    RexxSysBase = (struct RxsLib *)OpenLibrary("rexxsyslib.library", (ULONG)RXSVERS);
    return();
}



/*
 * cleanup any open ARexx stuff ...  just close rexsyslib.library for now
 */

void
closerexx()
{
    if (RexxSysBase) {
        CloseLibrary(RexxSysBase);
    }
    return();
}



/*
 *  explicit invocation interface between do_command() and do_rexx
 *  for ARexx macros having NO arguments (i.e., for the "rx" command)
 */

do_rx()
{
    do_rexx(av[1]);
    return();
}



/*
 *  explicit invocation interface between do_command() and do_rexx
 *  for ARexx macros having ONE argument (i.e., for the "rx1" command)
 */

do_rx1()
{
    char macbuf[256];

    strcpy(macbuf, av[1]);
    strcat(macbuf, " ");
    strcat(macbuf, av[2]);
    do_rexx(macbuf);
    return();
}



/*
 *  explicit invocation interface between do_command() and do_rexx
 *  for ARexx macros having TWO arguments (i.e., for the "rx2" command)
 */

do_rx2()
{
    char macbuf[256];

    strcpy(macbuf, av[1]);
    strcat(macbuf, " ");
    strcat(macbuf, av[2]);
    strcat(macbuf, " ");
    strcat(macbuf, av[3]);
    do_rexx(macbuf);
    return();
}



/*
 *  issue a command to ARexx ...
 */

do_rexx(macstr)
char *macstr;
{
    struct RexxArg *macarg;

    struct MsgPort  RexxPort;
    struct MsgPort *ARexxPort;

    struct RexxMsg *macptr;
    struct RexxMsg *cmdptr;

    char host[16];
    char hexbuf[12];        /* should only need 9 bytes */
    char errmsg[80];        /* don't build a larger error message */

    int  ret;


    if (RexxSysBase == 0) {
        title("Unknown Command   -   No Macros:  ARexx Not Installed ");   /* no rexxsyslib */
        return(0);
    }


    ClearMem(&RexxPort, sizeof(struct MsgPort));
    strcpy(host, "DME");
    sprintf(hexbuf, "%08x", &RexxPort);
    strcat(host, hexbuf);
    InitPort(&RexxPort, host);      /* need to error check this */
    AddPort(&RexxPort);
    /* return here if InitPort failed */


    if (macarg = (struct RexxArg *)CreateArgstring(macstr, strlen(macstr))) {
        if (macptr = (struct RexxMsg *)CreateRexxMsg(&RexxPort, "dme", host)) {
            ACTION(macptr) = RXCOMM;
            ARG0(macptr)   = (STRPTR)macarg;

            Forbid();
            if (ARexxPort = (struct MsgPort *)FindPort("REXX")) {
                PutMsg(ARexxPort, macptr);
                Permit();
                title("Calling ARexx Macro ... ");

                for (;;) {
                    WaitPort(&RexxPort);
                    cmdptr = (struct RexxMsg *)GetMsg(&RexxPort);

                    if (IsRexxMsg(cmdptr)) {

                        foundcmd = 0;
                        ret = do_command(ARG0(cmdptr));
                        if (foundcmd) {
                            ret = (ret == 1) ? 0 : 5;   /* cmd error:  RC = 5  */
                        } else {
                            ret = do_rexx(ARG0(cmdptr));    /* another macro? */
                        }

                        RESULT1(cmdptr) = ret;
                        RESULT2(cmdptr) = 0;
                        ReplyMsg(cmdptr);
                    }
                    do_command("null");     /* a kludge to set "foundcmd" */
                    if (macptr == cmdptr) break;
                }


                if (ret = RESULT1(cmdptr)) {
                    if (RESULT2(cmdptr)) {
                        if (RESULT2(cmdptr) == 1) {
                            title("Unknown Command ");
                        } else {
                            sprintf(errmsg, "ARexx Macro Error:  Code = %d  Severity = %d ", RESULT2(cmdptr), ret);
                            title(errmsg);
                        }
                    } else {
                        sprintf(errmsg, "User Specified Macro Error:  RC = %d ", ret);
                        title(errmsg);
                    }
                } else {
                    title("OK ");
                }
            } else {
                title("Unknown Command   -   No Macros:  ARexx Not Active ");   /* no REXX port */
                ret = -1;
            }
            DeleteRexxMsg(macptr);
        } else {
            title("CreateRexxMsg() Failed ");   /* may be overkill, and not need to ckeck this */
            ret = -1;
        }
        DeleteArgstring(macarg);
    } else {
        title("CreateArgstring() Failed ");     /* may be overkill, and not need to check this */
        ret = -1;
    }


    RemPort(&RexxPort);
    FreePort(&RexxPort);
    return(ret);
}



/*
 *  a kludge to flush the do_command pipe ... until I can fix a recursive macro bug ...
 */

void
do_null()
{
    return();
}

#endif

