/*static char *SCCSID = "@(#)macro.c    6.1 91/09/20";*/
/*********************************************************************/
/*								     */
/*  File Name:		MACRO.C					     */
/*								     */
/*  Description:	Provides access to the macrospace interface  */
/*			functions for REXXSAA from REXX programs     */
/*			via the Available Function Table, which is   */
/*			composed of external functions for the REXX  */
/*			interpreter written in languages other than  */
/*			REXX.					     */
/*								     */
/*  Entry Points:	MacroLoad  - load a file or library	     */
/*			MacroSave  - save macrospace to a library    */
/*			MacroErase - clear the macrospace	     */
/*			MacroQuery - check for a function	     */
/*								     */
/*  Notes:		Each of the entry points to this library     */
/*			conforms to the external function interface  */
/*			format for REXXSAA, i.e., each function has  */
/*			five (5) parameters: the name the function   */
/*			was called as, the argument count, the list  */
/*			of argument strings, the current active	     */
/*			external data queue, and the address of the  */
/*			RXSTRING structure to contain any return     */
/*			information.				     */
/*								     */
/*			For each function, the returned value is set */
/*			to the return code from the macrospace API   */
/*			function call which it performs; therefore,  */
/*			to properly use these functions a program    */
/*			should compare the returned value with '0'   */
/*			to check for successful completion.	     */
/*								     */
/*  Return Codes:	 0 == Function completed without error	     */
/*			-1 == Illegal call to function		     */
/*								     */
/*  Usage Notes:	Since each function has its own entry point  */
/*			in the library, they can be registered in    */
/*			the Available Function Table by any name     */
/*			which is convenient for a program.  The	     */
/*			function name parameter passed to each	     */
/*			routine by the interpreter is ignored.	     */
/*								     */
/*********************************************************************/

#define INCL_RXMACRO		  /* include macrospace info	     */
#define INCL_RXFUNC		  /* include external function	info */
#include <rexxsaa.h>		  /* REXXSAA header information	     */
#include <string.h>




/*********************************************************************/
/* MacroLoad							     */
/* This function will do one of two functions:			     */
/*   When called with one argument:				     */
/*     The argument must be the name of a file created by	     */
/*     RexxSaveMacroSpace on the current release of OS/2.	     */
/*     All macros saved in the file will be loaded.		     */
/*								     */
/*   When called with three arguments:				     */
/*     The first argument must be the name of a REXX program file.   */
/*     The second must be "BEFORE" or "AFTER" (upper/lower case does */
/*	 not matter)						     */
/*     The third is the name that the REXX program will be called by.*/
/*								     */
/* If called with a different number of arguments, it will raise an  */
/*   error.							     */
/*								     */
/* The return value of the function is the return code from	     */
/*   calling the RexxLoadMacroSpace or RexxAddMacro API.	     */
/*								     */
/*********************************************************************/

RexxFunctionHandler MacroLoad;
RexxFunctionHandler MacroSave;
RexxFunctionHandler MacroErase;
RexxFunctionHandler MacroQuery;

/*$PE*/
/*$FD.MacroLoad*/

ULONG /*APIENTRY*/ MacroLoad(
   PUCHAR    func,
   ULONG     ac,
   PRXSTRING av,
   PSZ	     que,
   PRXSTRING ret)
  {
  APIRET rc = -1;		       /* return code from function  */
  ULONG	 srch_ord = -1;		       /* search order position flag */
				       /*			     */
  if (ac == 1) {		       /* 1 arg == library load	     */
    rc = RexxLoadMacroSpace(0L,	       /* set return code from call  */
		     (PSZ *)0,	       /*   to RexxLoadMacroSpace    */
		     av[0].strptr);    /*			     */
    sprintf(ret->strptr, "%d", (int)rc);
    ret->strlength=strlen(ret->strptr);/*			     */
    rc = 0;			       /* no errors in call	     */
    }				       /*			     */

  else if (ac == 3) {		       /* 3 args == function load    */
    if (!stricmp(av[1].strptr,"BEFORE"))   /* set 'before' search    */
      srch_ord = RXMACRO_SEARCH_BEFORE;/*			     */
    else if(!stricmp(av[1].strptr,"AFTER"))/* set 'after' search     */
      srch_ord = RXMACRO_SEARCH_AFTER; /*			     */

    rc = RexxAddMacro(av[2].strptr,    /* set return code from call  */
		       av[0].strptr,   /*   to RexxAddMacro	     */
		       srch_ord),      /*			     */
    sprintf(ret->strptr, "%d", (int)rc);
    ret->strlength=strlen(ret->strptr);/*			     */
    rc = 0;			       /* no errors in call	     */
    }				       /*			     */

  /* We usually return 0 to indicate our processing was successful   */
  /* and we have returned a valid result.  If we return non-zero,    */
  /* then REXX will raise error 40, "invalid call to routine".	     */
  /* For all the functions in this program, we only raise an	     */
  /* error if we are called with an incorrect number of arguments.   */
  return rc;			       /*			     */
  }				       /*			     */


/*********************************************************************/
/* MacroSave							     */
/* This function must be called with one argument.		     */
/*   The argument must be a valid OS/2 file name.		     */
/*   This function will call RexxSaveMacroSpace to create a file     */
/*   containing all the REXX programs currently loaded in the	     */
/*   macrospace.  NOTE:	 This file may have to be re-created after   */
/*   applying service or upgrading to a new release of OS/2.	     */
/*								     */
/* If called with a different number of arguments, it will raise an  */
/*   error.							     */
/*								     */
/* The return value of the function is the return code from	     */
/*   calling the RexxSaveMacroSpace API.			     */
/*								     */
/*********************************************************************/
/*$PE*/
/*$FD.MacroSave*/
ULONG /*APIENTRY*/ MacroSave(
   PUCHAR    func,
   ULONG     ac,
   PRXSTRING av,
   PSZ	     que,
   PRXSTRING ret)
  {
  APIRET rc = -1;		       /* return code from function  */
				       /*			     */
  if (ac == 1) {		       /* need only one arg	     */
    rc = RexxSaveMacroSpace(0,	       /* set return code from call  */
		     (PSZ *)0,	       /*   to RexxSaveMacroSpace    */
		     av[0].strptr);    /*			     */
    sprintf(ret->strptr, "%d",(int)rc);/*			     */
    ret->strlength=strlen(ret->strptr);/*			     */
    rc = 0;			       /* no errors in call	     */
    }				       /*			     */
  return rc;			       /*			     */
  }				       /*			     */


/*********************************************************************/
/* MacroErase							     */
/* This function must be called with no arguments.		     */
/*   This function will call RexxClearMacroSpace to remove all REXX  */
/*   macros from the macrospace.				     */
/*								     */
/* If called with any arguments, it will raise an error		     */
/*								     */
/* The return value of the function is the return code from	     */
/*   calling the RexxSaveMacroSpace API.			     */
/*								     */
/*********************************************************************/
/*$PE*/
/*$FD.MacroErase*/
ULONG /*APIENTRY*/ MacroErase(
   PUCHAR    func,
   ULONG     ac,
   PRXSTRING av,
   PSZ	     que,
   PRXSTRING ret)
  {
  APIRET rc = -1;		       /* return code from function  */
				       /*			     */
  if (ac == 0) {		       /* no args allowed in call    */
    rc = RexxClearMacroSpace();	       /* set return code from call  */
    sprintf(ret->strptr, "%d", (int)rc);
    rc = 0;			       /* no errors in call	     */
    }				       /*			     */
  return rc;			       /*			     */
  }				       /*			     */


/*********************************************************************/
/* MacroQuery							     */
/* This function must be called with one argument.		     */
/*   The argument gives the name of a macro that may be in the	     */
/*   macrospace.  This function will call RexxQueryMacro	     */
/*   to find out if the macro is present.  This function returns the */
/*   return code of the RexxQueryMacro API.  This function does not  */
/*   return the search order flag.				     */
/*								     */
/* If called with a different number of arguments, it will raise an  */
/*   error.							     */
/*								     */
/* The return value of the function is the return code from	     */
/*   calling the RexxQueryMacro API.				     */
/*								     */
/*********************************************************************/
/*$PE*/
/*$FD.MacroQuery*/
ULONG /*APIENTRY*/ MacroQuery(
   PUCHAR    func,
   ULONG     ac,
   PRXSTRING av,
   PSZ	     que,
   PRXSTRING ret)
  {
  APIRET rc = -1;		       /* return code from function  */
  USHORT pos = 0;		       /* return of search position  */
				       /*			     */
  if (ac == 1) {		       /* need only one arg	     */
    rc = RexxQueryMacro(av[0].strptr,&pos);/* set return code from   */
				       /*   call to RexxQueryMacro   */
    sprintf(ret->strptr, "%d", (int) rc);
    ret->strlength=strlen(ret->strptr);/*			     */
    rc = 0;			       /* no errors in call	     */
    }				       /*			     */
  return rc;			       /*			     */
  }				       /*			     */
