/*static char *SCCSID = "@(#)mmatch.c	6.3 92/01/31";*/
#define INCL_DOSERRORS
#include <os2def.h>
#include <bse.h>
#include <fsh.h>	/* for dbcs.h */
#include <cdib.h>

#include "api.h"
#include "const.h"
#include "chain.h"
#include "misc.h"
#include "buf.h"
#include "dir.h"
#include "find.h"
#include "storage.h"
#include "volume.h"
#include "tables.h"
#include "frame.h"
#include "pb_ifs.h"
#include "ea.h"
#include "dbcs.h"
#include "codepage.h"
#include "pr_FIND.h"
#include "heap.h"
#include "pr_heap.h"
#include "pr_debug.h"
#include "pr_misc.h"

PCHAR pcMatchBuf;

/***	MetaMatch - check if name matches pattern
 *
 *	BUGBUG: this routine was replaced by a call to FSH_WILDMATCH
 *		to help with the problem with DBCS and in the future
 *		to facilitate moving to case preserving/case insensitive
 *		file names.  This needs to be revisited when we do this.
 *		One thing that we could do to improve speed is to null
 *		terminate the find pattern in the find record.  We at
 *		least would save the copy of ONE of the file names.
 *
 *	WARNING: This routine is case sensitive.
 *
 *	This routine is identical in function to FSH_WILDMATCH
 *	except for the return codes.  The FSH version returns 2
 *	codes which indicate match or no match.  This version returns
 *	3 codes indicating match, no match, and done.  The last code
 *	is used for optimizing the FindMatch algorithm - if we know
 *	that no more matches will occur then we can terminate the search.
 *
 *	When matching characters, the order of tests is essential:
 *	(1) The test for '*' must be before the test for '\0'
 *	    in order to match the strings: "foo*" and "foo".
 *	(2) The test for '\0' must be before the test for
 *	    (*pattern == *candidate) because '\0's matching would cause
 *	    the comparison to continue beyond the end of the strings.
 *	(3) The test for '?' before (*pattern == *candidate) is just for
 *	    efficiency in manipulating the string and expression pointers.
 *
 *
 *	ENTRY	pspPattern = pattern string pointer (non-zero len+1,string)
 *		pspCandidate = candidate string pointer	 (non-zero len,string)
 *		iCodePage = index into paCodePageEnt for candidate string
 *
 *		*** Note that the use of the 'length' word is inconsistent
 *		    across the two parameters.
 *
 *	EXIT	METAMATCH_EQUAL		= pattern and candidate match
 *		METAMATCH_NOT_EQUAL	= pattern and candidate do not match
 *		METAMATCH_DONE		= pattern and candidate do not match
 *					  and there will be no more matches
 *					  (candidate > pattern)
 *
 *	HISTORY
 *	    12-Mar-1990 by JR (John Rogers, JohnRo@Microsoft)
 *		- Speedup directory searches.
 *	    19-Sep-89 by JR (John Rogers, JohnRo@Microsoft)
 *		- Avoid warnings from Microsoft C 5.2 (on slash-slash comments).
 */

USHORT
MetaMatch (pspPattern, pspCandidate, iCodePage)
PPASCALSTRING	pspPattern;	/* pattern string (count = len + 1) */
PPASCALSTRING	pspCandidate;	/* candidate string (count = len) */
UINT		iCodePage;	/* index into paCodePageEnt for Candidate */
{

	PBYTE pszCandidate;
	PBYTE pszTemp;
	USHORT cbTemp;

#ifdef DEBUG_FIND
	dprintf( __FILE__": pspPattern='" );
	PrintPascalString( pspPattern );
	dprintf( "', pspCandidate='" );
	PrintPascalString( pspCandidate );
	dprintf( "'\n" );
#endif /* DEBUG_FIND */

	if (pspPattern->c == sizeof (pspPattern->c)) {
	    /* this matches all - so no need to do more */
	    return (METAMATCH_EQUAL);
	}

	/*
	 * BUGBUG - if we use two global arrays then we don't have
	 * to do this assignment every time.
	 */
	pszCandidate = pcMatchBuf + CCHMAXPATHCOMP + 1;

	pszTemp = pspPattern->b;
	cbTemp = pspPattern->c - sizeof (pspPattern->c);

	BYTE_COPY (pszTemp, pcMatchBuf, cbTemp);

	pcMatchBuf [cbTemp] = '\0';

	pszTemp = pspCandidate->b;
	cbTemp = pspCandidate->c;

	NameUpCase (pszTemp, cbTemp, &paCodePageEnt [iCodePage], pszCandidate);

	pszCandidate [cbTemp] = '\0';

	{
	    SHORT sRetCode;
	    sRetCode = FSH_WILDMATCH (pcMatchBuf, pszCandidate);
	    if (sRetCode == 0) {
		/* exact match */
		return (METAMATCH_EQUAL);
	    } else if ( (sRetCode > 0) || (sRetCode == (SHORT) 0x8000) ) {
		/* > 0, no match, pattern > string, so continue searching. */
		/* 0x8000, no match, but continue. */
		return (METAMATCH_NOT_EQUAL);
	    } else { /* sRetCode < 0 */
		/* < 0 no match, str > pat. */
		return (METAMATCH_DONE);
	    }
	}
	/* NOTREACHED */
}
