/* match.c  93.12.20
 * Copyright 1983-1992   Albert Davis
 * string compare
 * compares characters until end of first string
 * any non-alpha character is a terminator
 * returns offset into string to legal start of next token
 * (skips trailing spaces and comma, if any)
 *     if they match so far, and enough matched,   else NO (0)
 * Characters in reference string in UPPER case must match.
 * Always requires at least one character to match.
 */
#include "ecah.h"
#include "declare.h"
/*--------------------------------------------------------------------------*/
	int	pmatch(const char*,int*,const char*);
	int	match(const char*,const char*);
static	int	is_alpha(int);
	void	setmatch(const char*,int*);
	int	rematch(const char*);
/*--------------------------------------------------------------------------*/
/* pmatch: partial match -- match a keyword from command string
 * tries to match a partial string &cmd[*cnt] against reference str2
 * calls match, therefore depends on its definition of a match
 * if no match, returns 0 and leaves cnt alone
 * if match, updates cnt, (to eat string that was matched)
 *	and returns the number of characters eaten.  (non zero)
 * return value is usually interpreted as a truth value:
 *	true if match exists.
 */
int pmatch(const char*cmd, int *cnt, const char *str2)
{
 int ind;
 *cnt += ind = match(&cmd[*cnt],str2);
 return ind;
}
/*--------------------------------------------------------------------------*/
/* match: match str1 (under test) against str2 (reference)
 * if no match, returns 0
 * if match, returns the number of characters that match,
 *	---including whitespace---
 * return value is usually interpreted as a truth value:
 *	true if match exists.
 * str1 (being tested) is considered to be case-insensitive
 *	is terminated by a non-alpha character
 * str2 (reference) has special considerations:
 *	upper case characters must match, and must be present
 *	lower case characters must match if present, but may be omitted
 * strings are alpha only.
 */
int match (const char *str1, const char *str2)
{
 int skp = 0;

 skipbl (str1,&skp);
 while (to_lower(str1[skp]) == to_lower(*str2)){
    str2++;
    if (!is_alpha(str1[skp++]) || (!is_alpha(str1[skp]) && !isupper(*str2))){
       skipcom(str1,&skp);
       return skp;
    }
 }
 return 0;
}
/*--------------------------------------------------------------------------*/
/* is_alpha: a real function for isalpha
 * because side-effects of c screw up the isalpha macro
 */
static int is_alpha(int c)
{
 return isalpha(toascii(c));
}
/*--------------------------------------------------------------------------*/
/* setmatch, rematch: switch statement for strings
 * call setmatch once, for the string being tested.
 * repeated calls to rematch, one for each case
 * pmatch always refers to the most recent setmatch: no nesting allowed
 */
static const char *cmdp;
static int  *cntp;

/* setmatch: call with string being tested
 */
void setmatch(const char *cmd, int *cnt)
{
 cmdp = cmd;
 cntp = cnt;
}

/* rematch: test for match.
 * returns true (actually, see pmatch) if string in most recent call to
 * setmatch matches its argument (see match), and updates i, so another
 * call will match the next token
 * returns false if match fails
 */
int rematch(const char *ref)
{
 return pmatch(cmdp,cntp,ref);
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
