/*---------------------------------------------------------------*/
/*   Copyright (c) 1988 Regents of the University of California  */
/*                 All Rights Reserved                           */
/*---------------------------------------------------------------*/
/*
      @(#)match.c	1.1   (UCLA/IGPP)   11 Dec 1992
 */
/*-- MATCH --------------------------------------------------------*/
/*  Checks to see if the 'compare' string matches the 'mask'       */
/* string. The mask string can contain regular expressions of the  */
/* form:                                                           */
/*    *: match any string up to the end of line or next character  */
/*    ?: match any single character                                */
/*  [?]: match any character in the given set. If the first        */
/*       character of the set is '!' then the match is for all     */
/*       characters not in the set. A set of characters can be     */
/*       specified as 'abc' or 'a-b', which are equivalent.        */
/*                                                                 */
/*  Returns:                                                       */
/*   -2: strings do not match                                      */
/*   -1: bad mask syntax                                           */
/*    0: strings match                                             */
/*                                                                 */
/*  Entry Requirements:                                            */
/*    mask: string to use as the comparison specifier              */
/*    compare: string to comapre to mask.                          */
/*                                                                 */
/*  Developement History:                                          */
/*    Begun: 02/24/87 - Todd King                                  */
/*                   Under GG44 support                            */
/*-----------------------------------------------------------------*/
#include "specialc.h"

match(mask,string)
char *mask, *string;
{

  int m, s, tc;
  int lc, nc;
  unsigned ok, cont, inverse;
  int match 		=  0;
  int bad_syntax	= -1;
  int no_match		= -2;

  for(;;)			/* Scan until some sort of return */
  {
    m = *mask++;
    s = *string++;
    switch(m)		/* Check if mask character matches string character*/
    {
      case '[':			/* Beginning of character class */
	ok = FALSE;
	cont = TRUE;
	inverse = FALSE;
	if(*(mask+1) == '!') {mask++; inverse = TRUE;} /* Inverse spec */
	while(cont)
	{
	  tc = *mask++;
	  switch(tc)
	  {
	    case '\0':		/* End of mask string before ']' */
	      return(bad_syntax);
	    case ']':		/* End of character class */
	      if(!ok) return(bad_syntax);
	      else cont = FALSE;	/* Else continue with processing */
	      break;
	    case '-':		/* Short hand class specs */
	      lc = *(mask-1);
	      nc = *mask++;
	      if(nc == '\0' || lc == '[') return(bad_syntax);
	      if(inverse) {if(!(s >= lc && s <= nc)) ok = TRUE;}
	      else {if(s >= lc && s <= nc) ok = TRUE;}
	      break;
	    default:		/* See if one character in class matches */
	      if(inverse) {if (!(tc == s)) ok = TRUE; }
	      else {if(tc == s) ok = TRUE;}
	      break;
	  }
	}
	break;
      case '\0':		/* End of mask string */
	if(s != '\0') return(no_match); /* Not at end of string - no match */
	return(0);		  /* Otherwise its a match */
      case '?':			/* Automatically match on of s */
	break;
      case '*':			/* Match some set of s */
	while((m = *mask++) == '*' && m != '\0'); /* multiple *'s => '*' */
	for(; (s != '\0' && s != m); s = *string++); /* Compare to s */
	if(s == '\0' && m == '\0') return(match); /* End of both strings */
        if(s == '\0' && m != '\0') return(no_match); /* Must check */
	break;
      default:			/* Check if one-to-one character match */
	if(m != s) return(no_match);
    }
  }
}
