#include <ctype.h>
#include "base_includes.h"
#include "mycompare.h"
#include "tolower.h"

/* -----------------------------------------------------------------------
 * warning - only define CLIENT_COMPILE if you are compiling for the client
 * If you are not compiling the client, #undef CLIENT_COMPILE
 * ----------------------------------------------------------------------- */

#define CLIENT_COMPILE

/* -----------------------------------------------------------------------
 * I would not suggest using calls in the server. It adds a few seconds
 * per 10000 calls. This may not seem like much, but considering the
 * number of times this routine is called, it can add up
 *
 * Though a reason for having it in is as a fallout..
 * ---------------------------------------------------------------------- */

#undef USE_CALLS

/* ----------------------------------------------------------------------- */

#ifdef USE_CALLS
#  ifdef USE_CALLS_LOCAL
static int calls = 0;
#  else
extern int calls;
#endif

#endif

#ifdef CLIENT_COMPILE
#  define RETURN_FALSE -1
#  define RETURN_TRUE count
#else
#  define RETURN_FALSE 1
#  define RETURN_TRUE 0
#endif

/*
   So I don't make the same mistake twice: We don't need to check for '\\'
   in the input (string to check) because it doesn't have a special meaning
   in that context.
   
   We don't need to check for '\\' when we come accross a * or % .. The rest
   of the routine will do that for us.
 */

int wild_match(char *mask, char *string)
{
  register u_char *m = (u_char *)mask, *n = (u_char *)string;
  register u_char *ma = NULL, *na = NULL;
  int just = 0;
#ifdef CLIENT_COMPILE
  register u_char *mp = NULL, *np = NULL;
  int pcount, acount, count = 0;
#endif

#ifdef USE_CALLS
  calls = 0;
#endif

  while(1)
    {

#ifdef USE_CALLS
      calls++;
#endif
      if (*m == '*')
	{
	  ma = ++m;
	  na = n;
	  just = 1;
#ifdef CLIENT_COMPILE
	  mp = NULL;
	  acount = count;
#endif
	}
#ifdef CLIENT_COMPILE
      else if (*m == '%')
	{
	  mp = ++m;
	  np = n;
	  pcount = count;
	}
#endif
      else if (*m == '?')
	{
	  m++;
	  if (!*n++)
	    return RETURN_FALSE;
	}
      else
	{
	  if (*m == '\\')
	    {
	      m++;
	      /* Quoting "nothing" is a bad thing */
	      if (!*m) return RETURN_FALSE;
	    }
	  if (!*m)
	    {
	      /* 
		 If we are out of both strings or we just saw a wildcard,
		 then we can say we have a match
	      */
	      if (!*n) return RETURN_TRUE;
	      if (just) return RETURN_TRUE;
	      just = 0;
	      goto NOT_MATCH;
	    }
/* We could check for *n == NULL at this point, but since it's more common
   to have a character there, check to see if they match first (m and n) and
   then if they don't match, THEN we can check for the NULL of n
*/
	  just = 0;
	  if (tolower(*m) == tolower(*n))
	    {
	      m++;
#ifdef CLIENT_COMPILE
	      if (*n == ' ') mp = NULL;
	      count++;
#endif
	      n++;
	    }
	  else
	    {

	    NOT_MATCH:
	      
	      /* If there are no more characters in the string, but we still
		 need to find another character (*m != NULL), then it will
		 be impossible to match it
	       */
	      if (!*n) 
		return RETURN_FALSE;
#ifdef CLIENT_COMPILE
	      if (mp)
		{
		  m = mp;
		  if (*np == ' ')
		    {
		      mp = NULL;
		      goto CHECK_PERCENT;
		    }
		  n = ++np;
		  count = pcount;
		}
	      else
#endif
	      CHECK_PERCENT:
		
		if (ma)
		  {
		    m = ma;
		    n = ++na;
#ifdef CLIENT_COMPILE
		    count = acount;
#endif
		  }
		else 
		  return RETURN_FALSE;
	    }
	}
    }
  return RETURN_FALSE; /* satisfy anal compilers */
}



