dmuck0.15-beta/docs/muf/
dmuck0.15-beta/game/
dmuck0.15-beta/game/logs/
dmuck0.15-beta/game/muf/
dmuck0.15-beta/game/muf/text/
/***********************************
 *                                 *
 * smatch string compare utility   *
 * Written by Explorer_Bob.        *
 * modified by Foxen               *
 *                                 *
 ***********************************/

#include <stdio.h>
#include "config.h"
#include "smatch.h"
/* #include <pwd.h> */

static int cmatch(char *s1, int c1);
static int wmatch(char *wlist, char **s2);
static int smatch(char *s1, char *s2);

char   *cstrchr(char *s, int c);
char   *estrchr(char *s, int c, int e);
int     cstrcmp(char *s, char *t);
int     cstrncmp(char *s, char *t, int n);

#ifdef STRSTR
char   *strstr(char *s1, char *s2);

#endif
int     equalstr(char *s, char *t);

extern const char *uppercase, *lowercase;

#define DOWNCASE(x) (lowercase[x])

/* String handlers
 * Some of these are already present in most C libraries, but go by
 * different names or are not always there.  Since they're small, TF
 * simply uses its own routines with non-standard but consistant naming.
 */

char   *cstrchr(char *s, int c)
{
    c = DOWNCASE(c);
    while (*s && DOWNCASE(*s) != c)
	s++;
    if (*s || !c)
	return s;
    else
	return NULL;
}

char   *estrchr(char *s, int c, int e)
{
    while (*s) {
	if (*s == c)
	    break;
	if (*s == e)
	    s++;
	if (*s)
	    s++;
    }
    if (*s)
	return s;
    else
	return NULL;
}

#ifdef STRSTR
char   *strstr(s1, s2)
register char *s1, *s2;
{
    register char *temp = s1;
    int     len = strlen(s2);

    while (temp = strchr(temp, *s2)) {
	if (!strncmp(temp, s2, len))
	    return temp;
	else
	    temp++;
    }
    return NULL;
}

#endif

int cstrcmp(s, t)
register char *s, *t;
{
    while (*s && *t && DOWNCASE(*s) == DOWNCASE(*t)) {
	s++;
	t++;
    }
    return (DOWNCASE(*s) - DOWNCASE(*t));
}

int cstrncmp(s, t, n)
register char *s, *t;
int     n;
{
    for (; n && *s && *t && DOWNCASE(*s) == DOWNCASE(*t); s++, t++, n--);
    if (n <= 0)
	return 0;
    else
	return (DOWNCASE(*s) - DOWNCASE(*t));
}

#define test(x) if (DOWNCASE(x) == c1) return truthval
/* Watch if-else constructions */

static int cmatch(char *s1, int c1)
{
    int     truthval = FALSE;

    c1 = DOWNCASE(c1);
    if (*s1 == '^') {
	s1++;
	truthval = TRUE;
    }
    if (*s1 == '-')
	test(*s1++);
    while (*s1) {
	if (*s1 == '\\' && *(s1 + 1))
	    s1++;
	if (*s1 == '-') {
	    char    c, start = *(s1 - 1), end = *(s1 + 1);

	    if (start > end) {
		test(*s1++);
	    } else {
		for (c = start; c <= end; c++)
		    test(c);
		s1 += 2;
	    }
	} else
	    test(*s1++);
    }
    return !truthval;
}

static int wmatch(wlist, s2)
char   *wlist;		/* word list                      */
char  **s2;			/* buffer to match from           */
{
    char   *matchstr,		/* which word to find             */
           *strend,		/* end of current word from wlist */
           *matchbuf,		/* where to find from             */
           *bufend;		/* end of match buffer            */
    int     result = 1;		/* intermediate result            */

    if (!wlist || !*s2)
	return 1;
    matchbuf = *s2;
    matchstr = wlist;
    bufend = strchr(matchbuf, ' ');
    if (bufend == NULL)
	*s2 += strlen(*s2);
    else {
	*s2 = bufend;
	*bufend = 0;
    }
    do {
	if ((strend = estrchr(matchstr, '|', '\\')) != NULL)
	    *strend = '\0';
	result = smatch(matchstr, matchbuf);
	if (strend != NULL)
	    *strend++ = '|';
	if (!result)
	    break;
    } while ((matchstr = strend) != NULL);
    if (bufend != NULL)
	*bufend = ' ';
    return result;
}

static int smatch(s1, s2)
char   *s1, *s2;
{
    char    ch, *start = s2;

    while (*s1) {
	switch (*s1) {
	    case '\\':
		s1++;
		if (DOWNCASE(*s1++) != DOWNCASE(*s2++))
		    return 1;
		break;
	    case '?':
		if (!*s2++)
		    return 1;
		s1++;
		break;
	    case '*':
		while (*s1 == '*' || (*s1 == '?' && *s2++))
		    s1++;
		if (*s1 == '?')
		    return 1;
		if (*s1 == '{') {
		    if (s2 == start)
			if (!smatch(s1, s2))
			    return 0;
		    while ((s2 = strchr(s2, ' ')) != NULL)
			if (!smatch(s1, ++s2))
			    return 0;
		    return 1;
		} else if (*s1 == '[') {
		    while (*s2)
			if (!smatch(s1, s2++))
			    return 0;
		    return 1;
		}
		if (*s1 == '\\')
		    ch = *(s1 + 1);
		else
		    ch = *s1;
		while ((s2 = cstrchr(s2, ch)) != NULL) {
		    if (!smatch(s1, s2))
			return 0;
		    s2++;
		}
		return 1;
	    case '[':
		{
		    char   *end;
		    int     tmpflg;

		    if (!(end = estrchr(s1, ']', '\\'))) {
			return 1;
		    }
		    *end = '\0';
		    tmpflg = cmatch(&s1[1], *s2++);
		    *end = ']';

		    if (tmpflg) {
			return 1;
		    }
		    s1 = end + 1;
		}
		break;
	    case '{':
		if (s2 != start && *(s2 - 1) != ' ')
		    return 1;
		{
		    char   *end;
		    int     tmpflg = 0;

		    if (s1[1] == '^')
			tmpflg = 1;

		    if (!(end = estrchr(s1, '}', '\\'))) {
			return 1;
		    }
		    *end = '\0';
		    tmpflg -= (wmatch(&s1[tmpflg + 1], &s2)) ? 1 : 0;
		    *end = '}';

		    if (tmpflg) {
			return 1;
		    }
		    s1 = end + 1;
		}
		break;
	    default:
		if (DOWNCASE(*s1++) != DOWNCASE(*s2++))
		    return 1;
		break;
	}
    }
    return DOWNCASE(*s1) - DOWNCASE(*s2);
}

int equalstr(char *s, char *t)
{
    return !smatch(s, t);
}