/*
 * csh a shell by PJAC
 * glob.c - glob pattern matching
 */

#include "csh.h"
#ifdef	MSDOS
#include "ndir.h"
#else
#include <sys/types.h>
#include <dir.h>
#endif

/*
 * explode match into buf
 */

explode(match, buf)
char	*match, *buf;
{
	static	DIR	*dirp;
	static	char	stem[128];
	static	char	tail[MAX_CWD];
	static	int	stemp;
	struct	direct	*d;
	int	state;
	char	*p, *q;

	if(match != 0){	/* if match is non zero then start a new match */
		if(dirp != 0){
			closedir(dirp);
			dirp = 0;
		}
		q = rindex(match, '/');
		p = rindex(match, '\\');
		if(p || q){
			if(!p)
				p = q;
			if(p > q)
				q = p;
			for(p = stem ; match < q ; *p++ = *match++);
			*p = '\0';
			dirp = opendir(stem);
			*p++ = *match++;
			*p = '\0';
		}
		else {
			*stem = '\0';
			dirp = opendir(".");
			if(dirp == 0)
				dirp = opendir("");
		}
		if(dirp == 0)	/* cannot glob it */
			return(0);
		strcpy(tail, match);
		stemp = strlen(stem);
	}
	if(dirp == 0)	/* this should never occur */
		return(0);
	while((d = readdir(dirp)) ){
		if(d->d_name[0] == '.' && *tail != '.')
			continue;
		state = g_match(d->d_name, tail);
		if(state < 0)
			syn_err();
		if(state > 0){
			strcpy(buf, stem);
			strcpy(buf + stemp, d->d_name);
			return(1);
		}
	}
	closedir(dirp);
	dirp = 0;
	return(0);
}

/*
 * match string, given pat
 */

g_match(str, pat)
char	*str, *pat;
{
	int	found;

	for(;*pat;)
		switch(*pat){
		case '*':
			pat++;
			do {
				if(g_match(str, pat))
					return(1);
			} while(*str++);
			return(0);
		case '?':
			if(!*str++)
				return(0);
			pat++;
			continue;
		default:
			if(*str++ != *pat++)
				return(0);
			continue;
		case '[':
			for(found = 0, pat++ ; *pat && *pat != ']'; pat++){
				if(found)
					continue;
				if(*(pat+1) == '-'){
					if(pat[2] && pat[2] != ']'){
						if(*str>= *pat && *str<= pat[2])
							found = 1;
						pat += 2;
						continue;
					}
				}
				if(*pat == *str)
					found = 1;
			}
			if(*pat++ != ']')
				return(-1);
			if(!found)
				return(0);
			str++;
			continue;
		case ']':	/* syntax error */
			return(-1);
		}
	return(*str == '\0');
}
