/***********************************************************
	match.c -- match filenames
***********************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <string.h>
#include <farstr.h>
#include <ctype.h>
#include "lh.h"
#include "errmes.h"

struct pat far *pbuf;
static struct pat far *pnxt, far *plst;

/***************************************
	initialize pattern pointers
***************************************/
void initpat(void)
{
	pbuf = plst = e_farmalloc(sizeof(struct pat far *));
	pbuf -> nxt = NULL;
}

/***************************************
	regist file matching pattern
***************************************/
void regpat(char *pattern, char far *bdir)
{
	char *p;

	p = getfilename(pattern);
	pnxt = e_farmalloc(strlen(pattern) + sizeof(struct pat));
	pnxt -> nxt = NULL;
	pnxt -> bdir = bdir;
	pnxt -> cnt = 0;
	far_strcpy(pnxt -> pname, pattern);
	pnxt -> fname = pnxt -> pname + (p - pattern);
	plst = plst -> nxt = pnxt;
}

/***************************************
	regist base directory
****************************************
	bdir   : base directory
	return : saved address
***************************************/
char far *regbdir(char *bdir)
{
	char far *p;

	p = e_farmalloc(strlen(bdir) + 1);
	far_strcpy(p, bdir);
	return p;
}

/***************************************
	match filename to pattern
	including wild cards

	pname : filename in the pattern
	fname : filename given
***************************************/
char *matchfname(char far *pname, char *fname)
{
	static char dummy[] = " ";

	for (; *pname; pname++) {
		switch (*pname) {
		case '+':
			while ((uchar)*fname != DELIM && *fname) fname++;
			break;
		case '*':
			while (*fname != '.' && 
			       (uchar)*fname != DELIM && *fname) fname++;
			break;
		case '?':
			if (*fname != '.' && 
			    (uchar)*fname != DELIM && *fname) fname++;
			break;
		case '.':
			if ((uchar)*fname == DELIM || *fname == '\0')
				break;
		default:
			if ((*pname != *fname) && 
				(flg_i || toupper(*pname) != toupper(*fname))) {
				return dummy;		/* not NUL */
			}
			fname++;
		}
	}
	return fname;
}

/***************************************
	match pathname to pattern
****************************************
	path   : pathname
	return : it's base directory
***************************************/
char far *matchpat(char *path)
{
	struct pat far *pt;
	char far *p, far *r;
	char *file, *q;
	char c;

	file = getfilename(path);
	for (pt = pbuf -> nxt; pt != NULL; pt = pt -> nxt) {
		p = pt -> pname;
		switch (flg_r) {
		case 0:
			if (pt -> fname == p && flg_p == 0) {
				q = matchfname(p, file);
			} else {
				q = matchfname(p, path);
			}
			if (*q) q = NULL;
			break;
		case 1:
			c = *(r = pt -> fname);
			*r = '\0';
			q = matchfname(p, path);
			*r = c;
			if (q) {
				q = matchfname(pt -> fname, file);
				if (*q) q = NULL;
			}
			break;
		case 2:
			q = matchfname(p, path);
			if (*q && (uchar)*q != DELIM) q = NULL;
			break;
		}
		if (q) {
			(pt -> cnt)++;
			return (pt -> bdir);
		}
	}
	return NULL;
}

/***************************************
	whether pattern was used or not
****************************************
	return 0 : all pattern was used
	       1 : some pattern not used
***************************************/
int tstpat(void)
{
	int cnt;
	struct pat far *pt;

	cnt = 0;
	for (pt = pbuf -> nxt; pt != NULL; pt = pt -> nxt)
		cnt += pt -> cnt;
	if (cnt == 0)						/* no file matched */
		error(NOFILEERR, NULL);
	cnt = 0;
	for (pt = pbuf -> nxt; pt != NULL; pt = pt -> nxt) {
		if (pt -> cnt == 0) {			/* if any work name was not used */
			far_strcpy(work, pt -> pname);
			if (cnt == 0) eprintf("\n");
			cnt++;
			eprintf("%s : '%s'\n", NOMATCHERR, work);
			errorlevel = 1;				/* display warning */
		}
	}
	return errorlevel;
}
