@database "Programming Guide"
@Index indexnode
@author "Ketil Hunn"
@(c) "Copyright © 1994,1995 Ketil Hunn"
@$VER: Programming Guide V3 (07.12.95)
@font AmigaGuide.font 11
@wordwrap

************************************************************************
@node Main "Documentation for EasyRexx"

This documentation describes the easyrexx.library and how to make your application ARexx compatible using this library.

@{" Description " link description}
@{" License " link license}
@{" Copyrights & Credits " link credits}

@{" Programming " link programming}
@{" Argument switches " link switches}
@{" Register your ARexx compatible application " link register}

@{" Known bugs " link bugs}
@{" Author " link author}
@endnode

************************************************************************
@node description "Description"

@{fg shine}Description@{fg text}
easyrexx.library is a very fast shared run-time library that lets application developers add an ARexx port to their application with no fuss at all.  Interpreting EasyRexx ARexx messages will now be as easy as reading arguments from a DOS prompt!	A whole new world will open up, just by calling a few functions in this library!  

Starting with version 2.0 the EasyRexx package also features an ARexx Interface Designer, a GUI-based program which allows you to define the entire ARexx interface and generate source codes which are ready to be compiled.

Starting with version 3.0 easyrexx.library also features a set of functions which makes it easy to add recordable macros to applications using the easyrexx.library.

Most functions are tagbased which makes them very easy to use and fully extendable.  The example source is pretty much self-explanatory so you should take a look it and see how easy it is to use the library.

All functions in the library are thoroughly described in the EasyRexx autodoc.
@endnode

************************************************************************
@node license "License"

@{fg shine}Disclaimer@{fg text}
The files are provided "AS-IS" and with no warranties.  Use at your own risk.

@{fg shine}Distribution@{fg text}
The files may be distributed as needed. That means that for products that use the easyrexx.library, only the library itself needs to be distributed. For development purposes, the library and its documentation should be all  distributed together, all of course in an unaltered form.

@{fg shine}License@{fg text}
The license is the same for all software, regardless of what type of software the library is used  in, be it commercial, shareware, freeware or whatever. It is @{b}FREE@{ub} as long as you:

@{fg shine}1)@{fg text} Note in the program and documentation that easyrexx.library is copyrighted 1994, 1995 to Ketil Hunn.

@{fg shine}2)@{fg text} You give me a copy of each version of the software which uses the library.  There should be no cost to me.
@endnode

************************************************************************
@node credits "Credits"

The EasyRexx V3.0 package (binaries, libraries, fonts, docs, scripts, icons, include-files and source codes included) is copyrighted 1994,1995 to @{"Ketil Hunn" link author}, (Fredrikstad / Molde - Høgskolen i Molde, Norway).  Please read the @{"license" link license} for restrictions of distribution for this product.

@{fg shine}Requirements@{fg text}
Any Amiga with WB2.0+ with rexxsyslib.library.
OS2.1 or higher for a localized ARexx Interface Designer.

@{fg shine}Development@{fg text}
This package was developed on  an  A3000 25MHz with 6Mb RAM, ForeFront monitor, 105Mb harddrive,  3 disk-drives and a Nec P20-printer.  All software were running under WB3.1 on 714x566, 8 colors screen.

Development tools:
SAS/C V6.56 by SAS Institute Inc.
fd2pragma by Jochen Wiedmann.
RevCo by Litrik De Roy.
MemMinister by Marcus Ohlström.

@{fg shine}Betatesters@{fg text}
Doug Dyer
Stefan Gerberding
Erich Kuester

@{fg shine}Includes and examples@{fg text}
C by Ketil Hunn.
E by Leon Woestenberg.
Modula-2 by Tom Breeden.
Oberon by Volker Stolz.

@{fg shine}Catalog translators@{fg text}
Deutsch by Erich Kuester.
Nederlands by Leon Woestenberg.
Norsk by Ketil Hunn.

@{fg shine}Other credits@{fg text}
ScreenNotify.library is copyrighted to Stefan Becker.
SnoopDos is copyrighted to Eddy Carrol.
@endnode

************************************************************************
@node programming "Programming techniques"

This part of the documentation discusses the programming techniques used to make your application ARexx compatible.

@{" Making your application ARexx compatible " link techniques}
@{" Useful guidelines " link guidelines}
@{" How to record ARexx macros " link recording}
@endnode

************************************************************************
@node techniques "Programming using easyrexx.library"

An ARexx interface using easyrexx.library can be built in two ways: Using the @{"ARexx Interface Designer" link designer} utility or by doing it by hand, which is described below.  

@{fg shine}1)@{fg text} @{" include header files " link include}
@{fg shine}2)@{fg text} @{" Define unique IDs " link define}
@{fg shine}3)@{fg text} @{" Create table of commands " link createtable}
@{fg shine}4)@{fg text} @{" Create a handler-function " link handler}
@{fg shine}5)@{fg text} @{" Extend your signal handler " link signal}
@{fg shine}6)@{fg text} @{" Allocate and Free context " link context}

After doing the 6 steps described above, your application should now be able to understand three ARexx commands: OPEN, SAVE, QUIT.

See the easyrexx.autodoc for further details about defined tags and macros.

When easyrexx.library receives an ARexx command that matches a command in the command table, it will parse the arguments according to the template.  If the arguments do not match or are too few it will reply the message with an error and your application will never hear the message.

If the command and its arguments was successfully parsed, your application will receive the command with all arguments stuffed in an array with the first argument in 0, second in 1 etc.

QUIT takes one argument FORCE so both 'QUIT' and 'QUIT FORCE' will be accepted.  You can find out if the FORCE argument was given using the macro ARG(context, 0) which is defined in the EasyRexx header file.

OPEN takes two arguments: FILENAME and FORCE.  The FILENAME argument needs the keyword FILENAME to be present.

Accepted:
OPEN FILENAME "ram:foo" FORCE
OPEN FILENAME "ram:foo"

Rejected:
OPEN "ram:foo" FORCE
OPEN "ram:foo"

SAVE takes no arguments.

See also
@{" Setting argument switches " link switches}
@{" Useful macros " link macros}
@endnode

************************************************************************
@node designer "Using ARexx Interface Designer to build the interface"

The ARexx Interface Designer utility will simplify the design phase of your ARexx interface significantly since it is capable of generating the code shown in the 6 steps.

The generated code will have spots in the code with the remark: @{b}Insert own code here@{ub}.  Here you need to insert @{b}what@{ub} to do when specific ARexx commands arrives at the port.

That's it and that's that.  No more programming than that is needed before your application will have an operational ARexx port.
@endnode

************************************************************************
@node include "Include header-file"

In order to use the easyrexx.library in your application you must include it's header file.

Examples:
@{" C " link c_include}
@{" E " link e_include}
@{" Modula-2 " link modula2_include}
@{" Oberon " link oberon_include}
@endnode

@node c_include "C includes" 

#include <libraries/easyrexx.h>

If you do not want to use the macros defined in easyrexx.h you should define EASYREXX_NOMACROS before including the easyrexx header file.
@endnode

@node e_include "E modules"

MODULE 'libraries/easyrexx'

or

OPT PREPROCESS

MODULE 'libraries/easyrexx'
MODULE 'libraries/easyrexx_macros'

if you want to make use of the special EasyRexx macros.
@endnode

@node modula2_include "Modula-2 modules"

IMPORT EasyRexx, RexxErrors, Utility;
@endnode

@node oberon_include "Oberon modules"

IMPORT
  ER  : EasyRexx,
  R   : Rexx,
  U   : Utility;
@endnode

************************************************************************
@node define "Defining IDs"

Define unique IDs for each ARexx command your application will handle, starting at 1.  It is very important to start the IDs at 1 since the negative values are reserved for internal use and 0 indicates end of table:

Examples:
@{" C " link c_ids}
@{" E " link e_ids}
@{" Modula-2 " link modula2_ids}
@{" Oberon " link oberon_ids}
@endnode

@node c_ids "Defining IDs in C"

#define ARexx_QUIT 1
#define ARexx_OPEN 2
#define ARexx_SAVE 3
@endnode

@node e_ids "Defining IDs in E"

ENUM
  ARexx_QUIT=1,
  ARexx_OPEN,
  ARexx_SAVE
@endnode

@node modula2_ids "Defining IDs in Modula-2"

CONST
  ARexxQUIT=1;
  ARexxOPEN=2;
  ARexxSAVE=3;
@endnode

@node oberon_ids "Defining IDs in Oberon"

CONST
  ARexxQUIT=1;
  ARexxOPEN=2;
  ARexxSAVE=3;
@endnode

************************************************************************
@node createtable "Creating a table of commands"

Create a table of commands that your application will handle.  The table contains:

@{fg shine}Id@{fg text}
Id that will be returned (i.e. ARexx_QUIT).

@{fg shine}Name of ARexx command@{fg text}
Name of the command.  Will be parsed quicker if the name is given in upper-case (i.e. "QUIT").

@{fg shine}Argument template@{fg text}
Standard way of defining how the arguments should be parsed.  (i.e. "FORCE/S".

@{fg shine}Userdata@{fg text}
You can put anything you want here.  This field will not be used by any functions in the library.  Normally you could put the address of a function to be associated with a certain ARexx command. The Source drawer contains example source codes which show how to use this method.

Examples:
@{" C " link c_context}
@{" E " link e_context}
@{" Modula-2 " link modula2_context}
@{" Oberon " link oberon_context}


See also @{" Setting argument switches " link switches}
@endnode

@node c_context "Creating a table of commands in C"

struct ARexxCommandTable table[]=
{
  ARexx_QUIT, "QUIT",	"FORCE/S", NULL,
  ARexx_OPEN, "OPEN",	"FILENAME/K,FORCE/S", NULL,
  ARexx_SAVE, "SAVE",	NULL, NULL,
  TABLE_END,
};
@endnode

@node e_context "Creating a table of commands in E"

commandtable:=
 [
  ARexx_QUIT, 'QUIT', 'FORCE/S', NULL,
  ARexx_OPEN, 'OPEN', 'FILENAME/K,FORCE/S', NULL,
  ARexx_SAVE, 'SAVE', NULL, NULL,
  TABLE_END
 ]
@endnode

@node modula2_context "Creating a table of commands in Modula-2"

VAR commandTable:ARRAY[1..4] OF EasyRexx.ARexxCommandTable;

PROCEDURE InitCmdTable;
BEGIN
  WITH commandTable[ARexxQUIT] DO
    id          := ARexxQUIT;
    command     := ADR("QUIT");
    cmdtemplate := ADR("FORCE/S");
    userdata    := NIL;
  END;
  WITH commandTable[ARexxOPEN] DO
    id          := ARexxOPEN;
    command     := ADR("OPEN");
    cmdtemplate := ADR("");
    userdata    := NIL;
  END;
  WITH commandTable[ARexxSAVE] DO
    id          := ARexxSAVE;
    command     := ADR("SAVE");
    cmdtemplate := ADR("FORCE/S,FILENAME/K,");
    userdata    := NIL;
  END;
  EasyRexx.TableEnd(commandTable[ARexxENDTABLE]);
END InitCmdTable;

@endnode

@node oberon_context "Creating a table of commands Oberon"

TYPE
  table = ARRAY 4 OF ER.ARexxCommandTable;

PROCEDURE initCommandTable();
BEGIN
  table[0].id         :=ARexxQUIT;
  table[0].command    :=sys.ADR("QUIT");
  table[0].cmdTemplate:=sys.ADR("FORCE/S");
  table[0].userData   :=NIL;

  table[1].id         :=ARexxOPEN;
  table[1].command    :=sys.ADR("OPEN");
  table[1].cmdTemplate:=sys.ADR("FILENAME/K,FORCE/S");
  table[1].userData   :=NIL;

  table[2].id         :=ARexxSAVE;
  table[2].command    :=sys.ADR("SAVE");
  table[2].cmdTemplate:=sys.ADR("");
  table[2].userData   :=NIL;

  table[3].id         :=NIL;
  table[3].command    :=NIL;
  table[3].cmdTemplate:=NIL;
  table[3].userData   :=NIL;
END initCommandTable;
@endnode

************************************************************************
@node handler "Creating a handler-function"

Create your function to handle incoming ARexx events.

Examples:
@{" C " link c_handle}
@{" E " link e_handle}
@{" Modula-2 " link modula2_handle}
@{" Oberon " link oberon_handle}


See also @{" Useful macros " link macros}
@endnode

@node c_handle "ARexx handler function in C"

void myHandleARexx(void)
{
  if(GetARexxMsg(context))
  {
    switch(context->id)
    {
      case ARexx_QUIT:
        quit=TRUE;
        break;
      case ARexx_OPEN:
        OpenProject(ARGSTRING(context, 0), ARGBOOL(context, 1));
        break;
      case ARexx_SAVE:
        SaveProject();
        break;
    }
    ReplyARexxMsg(context, TAG_DONE);
  }
}
@endnode

@node e_handle "ARexx handler function in E"

PROC myHandleARexx()
  DEF id

  IF GetARexxMsg(context)
    id:=c.id
    SELECT id
      CASE ARexx_QUIT
        quit:=TRUE
      CASE ARexx_OPEN
        openProject(ARGSTRING(context, 0), ARGBOOL(context, 1))
      CASE ARexx_SAVE
        saveProject()
    ENDSELECT
    ReplyARexxMsg(context, TAG_DONE)
  ENDIF
ENDPROC
@endnode

@node modula2_handle "ARexx handler function in Modula-2"

PROCEDURE myHandleARexx(c:EasyRexx.ARexxContext):INTEGER;
BEGIN
  WHILE CHAR(EasyRexx.GetARexxMsg(c)) # 0C DO
    CASE VAL(INTEGER, EasyRexx.Id(c)) OF
      ARexxQUIT:
        done:=1;
        |
      ARexxOPEN:
        openProject();
        |
      ARexxSAVE:
        saveProject();
        |
    END;
    EasyRexx.ReplyARexxMsgA(c, NIL);
  END;
  RETURN done;
END myHandleARexx;
@endnode

@node oberon_handle "ARexx handler function in Oberon"

PROCEDURE myHandleARexx(c : ER.ARexxContextPtr) : INTEGER;
VAR
  done          : INTEGER;
BEGIN
  done            :=0;
  IF ER.GetARexxMsg(c) THEN
    CASE c.id OF
       ARexxQUIT : done:=1;
      |ARexxOPEN : openProject();
      |ARexxSAVE : saveProject();
    END;
    ER.ReplyARexxMsg(c, U.done);
  END;
  RETURN done;
END myHandleARexx;

@endnode
************************************************************************
@node signal "Extend your signal-handler"

Make your event-handler handle incoming ARexx signals.

Examples:
@{" C " link c_signals}
@{" E " link e_signals}
@{" Modula-2 " link modula2_signals}
@{" Oberon " link oberon_signals}
@endnode

@node c_signals "Signal handler in C"

@{fg shine}BEFORE:@{fg text}
  signals=Wait(1L<<myport->mp_SigBit);
 
  if(signals & 1L<<myport->mp_SigBit)
    handlestuff();

@{fg shine}AFTER:@{fg text}
  signals=Wait(1L<<myport->mp_SigBit | ER_SIGNAL(context));
  ER_SETSIGNALS(context, signals);

  if(signals & ER_SIGNAL(context))
    myHandleARexx(context);
  else if(signals & 1L<<myport->mp_SigBit)
    handlestuff();
@endnode

@node e_signals "Signal handler in E"

@{fg shine}BEFORE:@{fg text}
  signals:=Wait(Shl(1,myport.sigbit))
  IF (signals AND Shl(1,myport.sigbit)) THEN
    handlestuff()

@{fg shine}AFTER:@{fg text}
  signals:=Wait(Shl(1,myport.sigbit) OR ER_SIGNAL(context))
  ER_SETSIGNALS(context, signals)

  IF(signals AND ER_SIGNAL(context))
    myHandleARexx(context)
  ELSEIF(signals AND Shl(1,myport.sigbit))
    handlestuff()
  ENDIF
@endnode

@node modula2_signals "Signal handler in Modula-2"

@{fg shine}BEFORE:@{fg text}
  signals := Tasks.Wait(mysignal);
  IF (signals * mysignal # Tasks.SignalSet{}) THEN
    handleStuff();
  END;


@{fg shine}AFTER:@{fg text}
  signals := Tasks.Wait(mysignal * EasyRexx.ERSignals(context));
  EasyRexx.ERSetSignals(context, signals);
  IF (signals * EasyRexx.ERSignal(context) # Tasks.SignalSet{}) THEN
    done := myHandleARexx(context);
  END;
  IF (signals * mysignal # Tasks.SignalSet{}) THEN
   handleStuff();
  END;
@endnode

@node oberon_signals "Signal handler in Oberon"

@{fg shine}BEFORE:@{fg text}
  signals:=E.Wait(mysignal);
  IF (signals AND mysignal) THEN
    handleStuff();

@{fg shine}AFTER:@{fg text}
  signals:=E.Wait(mysignal OR ER.Signal(context));
  ER.SetSignals(context,signals);
  IF (signals AND ER.Signal(context)) THEN
    done:=myHandleARexx(context);
  END;
  IF (signals AND mysignal) THEN
    handleStuff();
  END;
@endnode

************************************************************************
@node context "Allocate and free context"

Allocate and free the context in your main function.  The context structure is needed by most functions in the easyrexx.library.

Remember not to terminate your program when easyrexx.library is not found, but rather continue without ARexx support.

Examples:
@{" C " link c_allocate}
@{" E " link e_allocate}
@{" Modula-2 " link modula2_allocate}
@{" Oberon " link oberon_allocate}


See also @{" Useful guidelines " link guidelines}
@endnode

@node c_allocate "Allocate and free context in C"

struct ARexxContext *context;
context=AllocARexxContext(
  ER_Portname,     "MYAPP",
  ER_CommandTable, table,
  ER_Author,       "Ketil Hunn",
  ER_Copyright,    "(C) 1995 ArtWorks",
  ER_Version,      "V2.0",
  TAG_DONE);

/* input handler */
your_input_handler();

if(EasyRexxBase)
  FreeARexxContext(context);
@endnode

@node e_allocate "Allocate and free context in E"

DEF context:PTR TO arexxcontext
context:=AllocARexxContext(
  ER_Portname,     'MYAPP',
  ER_CommandTable, table,
  ER_Author,       'Ketil Hunn',
  ER_Copyright,    '(C) 1995 ArtWorks',
  ER_Version,      'V2.0',
  TAG_DONE)

-> input handler
your_input_handler()

IF easyrexxbase
  FreeARexxContext(context)
@endnode

@node modula2_allocate "Allocate and free context in Modula-2"

initCmdTable();
context:=EasyRexx.NULLARexxContext;
TagsUtils.AsgTags5(taglist, EasyRexx.ERCommandTable, ADR(commandTable),
                            EasyRexx.ERAuthor,       ADR("Ketil Hunn"),
                            EasyRexx.ERCopyright,    ADR("(C) Ketil Hunn"),
                            EasyRexx.ERVersion,      ADR("Myapp V1.0"),
                            EasyRexx.ERPortname,     ADR("MYARexx_PORT"));
context:=EasyRexx.AllocARexxContextA(ADR(taglist));

(* input handler *)
handleinput();

IF context # NIL THEN
  EasyRexx.FreeARexxContext(context);
END;
@endnode

@node oberon_allocate "Allocate and free context in Oberon"

 initCommandTable();
 context:=ER.AllocARexxContext(ER.CommandTable, sys.ADR(ARexxCommandTable),
                               ER.Author,       sys.ADR("Ketil Hunn"),
                               ER.Copyright,    sys.ADR("© 1995"),
                               ER.Version,      sys.ADR("Myapp V1.0"),
                               ER.PortName,     sys.ADR("MYARexx_PORT"),
                               U.done);
 (* input handler *)
 inputhandler();

 IF context # NIL THEN
   ER.FreeARexxContext(context);
 END;
@endnode

************************************************************************
@node guidelines "Useful guidelines"

@{fg shine}o@{fg text} Do @{b}not@{ub} terminate your application if easyrexx.library was not found.  Just continue without ARexx support.  This can be done by checking the EasyRexxBase pointer before calling any easyrexx.library functions.  Remember also not to wait on any ARexxContext signals.  You should also disable any ARexx related menu items.  Do NOT remove the ARexx menu completely as this may confuse the user.  Disabling is sufficient enough as it shows that ARexx support is not available.

@{fg shine}o@{fg text} Always show your application's ARexx portname in your About requester or window.

@{fg shine}o@{fg text} Use simple names for your ARexx commands.  OPEN is preferred over XX_OPEN (where XX is some kind of acronym for your application's name).  Following this rule your will make your application appear more 'standardized' and the users do not have to learn all your special-named commands.

@{fg shine}o@{fg text} Use command names near the english language.  OPEN PROJECT is preferred over OPENPROJECT or PROJECTOPEN.  This may be done by making the PROJECT part of the command into an argument switch.  Doing so will also allow the command OPEN as well.

@{fg shine}o@{fg text} Combine equal commands into one command, for example all OPEN commands where the actual type that will be opened is determined by the switch.  E.g. is OPEN PROJECT/S,TEXT/S,SETTINGS/S preferred over OPENPROJECT, OPENTEXT and OPENSETTINGS.  Be sure to make the most frequent used command (preferably OPEN PROJECT) to be the default (both OPEN PROJECT and just OPEN will be accepted).  This will reduce the amount of commands and simplify the usage.

@{fg shine}o@{fg text} Always include the ARexx commands below in your ARexx interface.  Even though they have nothing to do with your application's functionality, they are extremely useful for the macro programmer.
@{b}<MYAPP>TOFRONT:@{ub} Bring application's screen and window to front.
@{b}<MYAPP>TOBACK:@{ub} Bring application's screen and window to back.
@{b}REQUEST:@{ub} Show a standard system query requester.  The command should return the gadget selected.
@{b}REQUESTFILE:@{ub} Show a standard Asl file/drawer requester.  The command should return the selected file/drawer.

@{fg shine}o@{fg text} Include a macro menu called ARexx in your menu structure.  Calling the menu "ARexx" is preferred over "Macro" since it explicitly tells the user that the macro script being used is ARexx and not some own designed macro language.  The menu structure should be close to the menu structure used in the ARexx Interface Designer (or better if you can come up with one ;).  The structure is pretty much self-explanatory.


See also @{" How to create ARexx macros " link recording}
@endnode

************************************************************************
@node recording "How to record ARexx macros"

Starting with version 3.0, easyrexx.library features a set of functions which makes it easy to create, execute and write ARexx macros.  Your application should make use of these functions to simplify the ARexx usage of your application.

Adding ARexx macro recording to your application is very simple:

@{fg shine}1)@{fg text}  Add a global flag to your application called 'recording'.

@{fg shine}2)@{fg text} Allocate a global ARexxMacro structure, macro, using

@{fg shine}3)@{fg text} Add a few lines to each of your functions that may be recorded. For example:

void myfunc(void)
{
  /* do normal function stuff */
  if(recording)
    AddARexxMacroCommand(macro,
      ER_Command,        "MYCOMMAND '%s'",
      ER_ArgumentString, "MYPARAM1 MYPARAM2",
      TAG_DONE);
}	

In this case the macro will be recorded while the user performs his/hers actions.

If the user enters some data you should always ask the user if he/she wants to store the data entered in the macro.  This allows the user to enter new data each time the macro is executed:

  if(recording)
    AddARexxMacroCommand(macro,
      ER_Command, "MYCOMMAND '%s'",
      (KeepContents() ?
        ER_ArgumentString:TAG_IGNORE),
        "MYPARAM1 MYPARAM2",
      TAG_DONE);

@{fg shine}4)@{fg text} Set recording to TRUE when the user selects 'Start recording' and to FALSE when the user selects 'Stop recording'.  'Start recording' should also provide the user with visual feedback that the program has entered a record ARexx macro state.  This can for example be done by changing the mouse pointer.  The EasyRexx header file has a predefined ARexx macro recording mouse pointer you can use if you want to.  'Stop recording' should clear the mouse pointer, write the ARexx macro to disk and then clear the macro to free memory.

@{fg shine}5)@{fg text} You should also provide the user with an ARexx menu to allow the user to run ARexx macros by selecting the macro in the menu.


See also @{" Useful guidelines " link guidelines}
@endnode


************************************************************************
@node switches "Setting argument switches"

Options in the template are separated by commas.  To get the results of EasyRexx message, you examine the array of longwords you passed to it (one entry per option in the template).  Exactly what is put in a given entry depends on the type of option.  The default is a string (a sequence of non-whitespace characters, or delimited by quotes, which will be stripped, in which case the entry will be a pointer.

Options can be followed by modifiers, which specify things such as the type of the option.  Modifiers are specified by following the option with a / and a single character modifier.  Multiple modifiers can be specified by using multiple /'s.  Valid modifiers are:

 /A -	@{" Always   " link always}
 /K -	@{" Keyword  " link keyword}
 /N -	@{" Number   " link number}
 /S -	@{" Switch   " link switch}
 /T -	@{" Toggle   " link toggle}
 /M -	@{" Multiple " link multiple}
 /F -	@{" Final    " link final}
@endnode

************************************************************************
@node always "Always"

Setting this switch means that this argument must be given a value during command-line processing, or an error will be returned.

There is an interaction between @{"Multiple" link multiple} parameters and Always parameters. If there are unfilled Always parameters after parsing, it will grab strings from the end of a previous @{"Multiple" link multiple} parameter list to fill the /As.  This is used for things like Copy ("From/A/M,To/A").


See also @{" General about switches " link switches}
@endnode

************************************************************************
@node keyword "Keyword"

Set this switch if a keyword is required in front of the argument.  For example if the template is "Name/K", then unless "Name=<string>" or "Name <string>" appears in the command line, Name will not be filled.


See also @{" General about switches " link switches}
@endnode

************************************************************************
@node number "Number"

Setting this switch is considered a decimal number.  If an invalid number is specified, an error will be returned.  The entry will be a pointer to the longword number (this is how you know if a number was specified).


See also @{" General about switches " link switches}
@endnode

************************************************************************
@node switch "Switch"

Set this switch and the argument will be considered a boolean variable, and will be set if the option name appears in the command-line.  The entry is the boolean (0 for not set, non-zero for set).


See also @{" General about switches " link switches}
@endnode

************************************************************************
@node toggle "Toggle"

This is similar to @{"Switch" link switch}, but when specified causes the boolean value to "toggle".  Similar to /S.


See also @{" General about switches " link switches}
@endnode

************************************************************************
@node multiple "Multiple"

Setting this switch means the argument will take any number of strings, returning them as an array of strings.  Any arguments not considered to be part of another option will be added to this option.  Only one /M should be specified in a template.  Example for a template "Dir/M,All/S" the command-line "foo bar all qwe" will set the boolean "all", and return an array consisting of "foo", "bar", and "qwe".  The entry in the array will be a pointer to an array of string pointers, the last of which will be NULL.

There is an interaction between Multiple parameters and @{"Always" link always} parameters. If there are unfilled @{"Always" link always} parameters after parsing, it will grab strings from the end of a previous Multiple parameter list to fill the /As.  This is used for things like Copy ("From/A/M,To/A").


See also @{" General about switches " link switches}
@endnode

************************************************************************
@node final "Final"

If this is specified for an argument, the entire rest of the line is taken as the parameter for the option, even if other option  keywords appear in it.


See also @{" General about switches " link switches}
@endnode

************************************************************************
@node macros "Useful macros"

These macros will only be operative if you have NOT defined EASYREXX_NOMACROS.

@{b}ARGSTRING(context, i)@{ub}
returns the string in argument i.

@{b}ARGNUMBER(context, i)@{ub}
returns the number in argument i.

@{b}ARG(context, i)@{ub}
returns 0 if the argument is NULL and non-zero if it present.

@{b}ARGBOOL(context,i)@{ub}
returns TRUE if the argument is not empty and FALSE if it is.

@{b}TABLE_END@{ub}
end of context table.

@{b}SAFETOQUIT(context)@{ub}
returns TRUE when its safe to quit.  Quitting when this macro returns FALSE may lead to crash or memory loss.  It is very important to use this macro whenever you send commands asynchronously with SendARexxCommandA() (V2)

@{b}ISSHELLOPEN(context)@{ub}
returns TRUE if the shell is open, FALSE if not. (V2)

@{b}SETSIGNALS(context,s)@{ub}
copies the signals 's' received from the Wait() command.  Must be used whenever a ARexxCommandShell() will be used.  (V2)

@{b}GETRC(context)@{ub}
returns the primary result from a SendARexxCommand() call.  (V2)

@{b}GETRESULT1(context)@{ub}
alias for GETRC().  (V2)

@{b}GETRESULT2(context)@{ub}
returns the secondary result (if any) from a SendARexxCommand call.  (V2)
@endnode

************************************************************************
@node register "Register your ARexx compatible application"

@{fg shine}NOTE@{fg text}
The actual form, 'AppList.form', to fill in can be found in the Docs drawer.  That file contains the right indenting that Dan wants.  (Red.Rem. Ketil)


@{u}@{fg shine}Message from Dan Barrett:@{fg text}@{uu}

Would you please send me ARexx information about your product for The ARexx Application List?  This is a freely-distributable list of all known ARexx-compatible products.  The list is announced or posted on the first day of every month in the USENET newsgroup comp.sys.amiga.applications.


Please remove the angled brackets ">" and "<" when you fill it in.  And please do not change the indenting (tabbing).

I hope the form is self-explanatory, but here is an explanation just in case.  The first 5 fields should be obvious:  the program name, its version number, what kind of program it is, the author/company name, and whether the product is commercial, shareware, freeware, or public domain.  If the program is on a Fish Disk, put "(Fish Disk nnn)" after the version number, where nnn is the disk number.  If it's not on a Fish Disk, but is on an ftp site, put "(ftp NAME_OF_SITE)" after the version number, where NAME_OF_SITE is the name of the ftp site.

"Port name" is the name of the ARexx port (or ports) that the product provides.  This might have several forms:

o A fixed name.  Just fill it in.  Make sure you pay attention to upper/lower case, since this is significant to most ARexx programs.

o A name followed by a number, indicating how many copies of the software are currently running.  For example, if you run 3 copies of "FooBlaster", the ARexx ports might be called FooBlaster_1, FooBlaster_2, and FooBlaster_3.  In this case write:

 FooBlaster_1, FooBlaster_2, ...

o A combination of the above 2 methods.  I think that TurboText does this, for example:  a "main" ARexx port, plus one for each window.

o A name that may be set by the user.  In this case, write "May be set by user."

"Number of Commands" means the number of ARexx commands that the program provides.

"Executes scripts by" means how the program lets the user invoke commands FROM INSIDE THE PROGRAM ONLY.  For example, New Horizon's FLOW lets each function key execute an ARexx script, and lets the user invoke scripts from a menu, so the entry would read "function keys, menu".  On the other hand, Virus_Checker does not let the user invoke scripts from inside the program at all -- it can be controlled only by an external script.

"Notes" is a section for any important or special features that you think *must* be mentioned.  Be BRIEF -- try to keep it on one line, but don't omit important information just to keep it short.

Here are some examples:

Product name: Video Destruction
Product version: 1.0 (Fish Disk 9834)
Product type: MULTIMEDIA
Author: Harry Hosehead
Contact: hosehead@foo.bar.blat
Status: freeware
Port name: May be set by user.
Number of commands: 5
Executes scripts by: External control only
Notes: Next version (1.1) will bind scripts to function keys

Product name: Spamwriter
Product version: 2.2
Product type: WORD PROCESSOR
Author: Zyzzyva Software
Contact: 1234 Snog Avenue, New York, NY 10001, (212)555-1234
Status: shareware
Port name: Spam_1, Spam_2, ...
Number of commands: 250
Executes scripts by: Any keystroke, mouse buttons
Notes: Uses ARexx as its internal scripting language.

Please E-MAIL your information to barrett@cs.umass.edu.  If you cannot reach me by e-mail, then send me the information by ordinary mail:

	Daniel Barrett
	Department of Computer Science
	Lederle Graduate Research Center
	University of Massachusetts
	Amherst, MA  01003
	(413) 545-2146

If you participate, your name will go in the "SPECIAL THANKS" section in the list (unless you don't want it there).  Thank you very much!


Dan
@endnode

************************************************************************
@node bugs "Known bugs"

ARexxCommandShell:

o Inserting characters in the middle of a string when the string exceeds one line will not wrap the string onto the next line.
@endnode

************************************************************************
@node author "Author"

Send your contribution, suggestions and bug-reports to this address:

@{fg shine}Ketil Hunn
Nabbetorpveien 35B
N-1632 Gamle Fredrikstad
NORWAY@{fg text}

e-mail:
@{fg shine}Ketil.Hunn@hiMolde.no@{fg text}

www:
@{fg shine}http://www.himolde.no/~ketil/@{fg text}
This site will always contain the latest versions of all my public projects.

NOTE
The e-mail address may not be valid for long.  If your mail bounces back or you get no response, you should try searching for me on Internet - preferably at the University of Pittsburgh, USA (ketil@lis.pitt.edu or something).


Have fun :)

Ketil Hunn
December, 1995
@endnode

************************************************************************
@node indexnode "Index"

@{fg shine}A@{fg text}
@{"Allocate and Free context" link "context"}
@{"Always" link "always"}
@{"Author" link "author"}

@{fg shine}C@{fg text}
@{"Creating a handler-function" link "handler"}
@{"Creating a table of commands" link "createtable"}
@{"Credits" link "credits"}

@{fg shine}D@{fg text}
@{"Defining IDs" link "define"}
@{"Designer" link "designer"}
@{"Description" link "description"}
@{"Documentation for EasyRexx" link "Main"}

@{fg shine}E@{fg text}
@{"Extend your signal-handler" link "signal"}

@{fg shine}F@{fg text}
@{"Final" link "final"}

@{fg shine}H@{fg text}
@{"How to record ARexx macros" link "recording"}

@{fg shine}I@{fg text}
@{"Include header-file" link "include"}

@{fg shine}K@{fg text}
@{"Keyword" link "keyword"}
@{"Known bugs" link "bugs"}

@{fg shine}L@{fg text}
@{"License" link "license"}

@{fg shine}M@{fg text}
@{"Multiple" link "multiple"}
@{"Number" link "number"}

@{fg shine}P@{fg text}
@{"Programming techniques" link "programming"}
@{"Programming using easyrexx.library" link "techniques"}

@{fg shine}R@{fg text}
@{"Register your ARexx compatible application" link "register"}

@{fg shine}S@{fg text}
@{"Setting argument switches" link "switches"}
@{"Switch" link "switch"}

@{fg shine}T@{fg text}
@{"Toggle" link "toggle"}

@{fg shine}U@{fg text}
@{"Useful guidelines" link "guidelines"}
@{"Useful macros" link "macros"}
@endnode

