/*
 *				f m a t c h . c
 */

/*)LIBRARY
*/

#ifdef	DOCUMENTATION

title	fmatch	Pattern Match Using DEC Filename Conventions
index		Pattern match using DEC filename conventions

synopsis

	 int
	 fmatch(name, pattern)
	 char	*name;		/* What to look for	*/
	 char	*pattern;	/* Pattern to match	*/

description

	fmatch returns TRUE if the name argument is matched by the
	pattern argument.

	The pattern follows DEC filename wildcard conventions:
	'*' matches any string (even null) and '?' or '%' matches any
	single (non-null) byte.  Also, upper/lower case differences
	are ignored.

	When matching against file name strings, the calling program
	must already have parsed the name string to remove terminators,
	such as '.' or ';'.

bugs

author

	Martin Minow, borrowed from RT11 PIP.

#endif

/*
 *)EDITLEVEL=03
 * Edit History
 * 0.1 09-Dec-81 MM	Initial edit
 */

#define	EOS	0
#define	FALSE	0
#define	TRUE	1

int
fmatch(name, pattern)
register char	*name;		/* What to look for			*/
register char	*pattern;	/* May have wildcard			*/
/*
 * Recursive routine to match "name" against "pattern".
 * Returns TRUE if successful, FALSE if failure.
 *
 * pattern follows Dec filename wildcard conventions:  '*' matches any
 * string (even null), '?' or '%' matches any single (non-null) byte
 * and upper/lower case differences are ignored.
 *
 * Note that the calling program has already parsed the name string
 * to remove terminators (such as '.' or ';').
 */
{
	register char	pattbyte;
	char		namebyte;

	for (;;) {
		/*
		 * First check for one-byte pattern "*" -- this must succeed
		 */
		if ((pattbyte = *pattern++) == '*' && *pattern == EOS)
			return (TRUE);
		/*
	 	 * If not, then if both strings finish equally, it succeeds.
	 	 */
		if ((namebyte = *name) == EOS && pattbyte == EOS)
			return (TRUE);
		/*
		 * Not at end of the name string.
		 */
		switch (pattbyte) {
		case EOS:		/* End of pattern -> failure	*/
			return (FALSE);
	
		case '*':		/* Wild card means "advance"	*/
			do {
				if (fmatch(name, pattern))
					return (TRUE);
			} while (*name++ != EOS);
			return (FALSE);	/* Did our best			*/

		default:
			if (tolower(namebyte) != tolower(pattbyte))
				return (FALSE);
		case '?':		/* One byte joker		*/
		case '%':		/* RT11 one byte joker		*/
			name++;		/* Matched this one		*/
		}
	}
}
