From:	CSBVAX::CSBVAX::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 28-JAN-1989 02:37
To:	MRGATE::"ARISIA::EVERHART"
Subj:	real vs. foreign commands, better example..


Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Fri, 27 JAN 89 13:08:40 PDT
Received: from uwavm.acs.washington.edu (oly.acs.washington.edu) by KL.SRI.COM with TCP; Fri, 27 Jan 89 12:47:15 PST
Received: from UWAVM.ACS.WASHINGTON.EDU by uwavm.acs.washington.edu ; Fri, 27 Jan 89 12:40:46 PST
Received: from FHCRCVAX.BITNET (JOE) by UWAVM.ACS.WASHINGTON.EDU (Mailer R2.02)
 with BSMTP id 4921; Fri, 27 Jan 89 12:40:45 PST
Date: Fri, 27 Jan 89 12:40 PST
From: Joe Meadows <JOE%FHCRCVAX.BITNET@uwavm.acs.washington.edu>
Subject: real vs. foreign commands, better example..
To: info-vax@kl.sri.COM
X-VMS-To: IN%"info-vax@kl.sri.com"

In the example code I posted earlier, I used LIB$GET_FOREIGN to
get the rest of the command line. This is fairly restrictive, it
only allows for a much smaller string, and does slightly different
parsing. The following tidbit fixes that by using the $LINE argument
to CLI$GET_VALUE, and pulling of the foreign image specification.

In case you missed the other posting, I suppose I should say more.
The following code allows you to write programs that use the CLI$
routines to be either defined as a real command, or as a "foreign"
command. To use this, you would create a .CLD (without an IMAGE clause),
use SET COMMAND/OBJECT to create an object file out of the .CLD,
and reference the tables in your program, (in C via "globalvalue TableName")
Then call the following tidbit as:
        status = init_cli(TableName,"VerbName");
From then you parse like you would normally do for real commands.

Cheers,
Joe Meadows     joe@fhcrcvax.bitnet

$ create/log INIT_CLI.C
$DECK
#include descrip
/* "table" is a pointer to the internal CLD
 * "name" is a text string containing the name of the verb
 * note that the case of the verb name is important, should be uppercase
 */
init_cli(char *table, char *name)
{
  static struct dsc$descriptor cmd = {0,DSC$K_DTYPE_T,DSC$K_CLASS_D,0};
  static $DESCRIPTOR(verb,"$VERB");
  static $DESCRIPTOR(line,"$LINE");
  int i,j,sts;

  sts = CLI$GET_VALUE(&verb,&cmd);
  if (!(sts & 1)) return(sts);

  if (strncmp(cmd.dsc$a_pointer,name,cmd.dsc$w_length) == 0)
  {
    return(1);    /* the command must have been properly defined! */
  }
  else
  {
    /* this code assumes that the verb is shorter than than the foreign
     * image specification, which should be reasonable since it includes
     * device:[directory]filename
     */
    sts = CLI$GET_VALUE(&line,&cmd);
    if (!(sts & 1)) return(sts);

    j = strlen(name);
    for (i = 0; (i < cmd.dsc$w_length) &&
                (cmd.dsc$a_pointer[i] != ' ') &&
                (cmd.dsc$a_pointer[i] != '/'); ++i)
      cmd.dsc$a_pointer[i] = (i < j)?name[i]:' ';

    return(CLI$DCL_PARSE(&cmd,table)); /* initialize the parse tables */
  }
}
$EOD

