/*
 *	clipfnma.c
 *
 *	POSIX準拠のファイル名比較ルーチン
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2011 Naoyuki Sawa
 *
 *	* Thu Feb 03 00:28:15 JST 2011 Naoyuki Sawa
 *	- 1st リリース。
 *	- P/ECE開発環境、および、EPSONのS1C33開発環境には、POSIX準拠のfnmatch.hヘッダファイルが含まれていません。
 *	  Webや書籍のサンプルプログラム等をコンパイルする時に必要になる場合に備えて、用意しておくことにしました。
 *	- 2011/02/03現在の実装では、fnmatch()のflags引数は無視し、指定しても動作に違いは有りません。
 *	  P/ECE上でファイル名を比較する用途ならば、これらのフラグは不要であるはずです。
 */
#include "clip.h"

int
fnmatch(const char* pattern, const char* string, int flags)
{
	int p;
	int s;

	for(;;) {
		/* パターンを一文字取得し、次へ進めます。 */
		p = *pattern++;
		/* パターン文字が'*'ならば… */
		if(p == '*') {
			/* 後続のパターンが無ければ、この'*'が後続のファイル名を全て消費すると見なせます。 */
			if(*pattern == '\0') {
				return 0;
			}
			/* 後続のパターンが有れば… */
			for(;;) {
				/* 後続のパターンが、後続のファイル名にマッチすれば… */
				if(fnmatch(pattern, string, flags) == 0) {
					return 0;
				}
				/* ↑この処理順序は必須です。 */
				/* ↓逆にすると、パターン"**"が、ファイル名""にマッチできません。 */
				/* 後続のパターンが有るのに、後続のファイル名が無ければ… */
				if(*string == '\0') {
					return FNM_NOMATCH;
				}
				/* この'*'が、後続のファイル名を一文字消費したと見なします。 */
				string++;
			}
		}
		/* ファイル名を一文字取得し、次へ進めます。 */
		s = *string++;
		/* パターン文字が'?'ならば… */
		if(p == '?') {
			/* 終端以外の任意のファイル名文字に一致します。 */
			if(s == '\0') {
				return FNM_NOMATCH;
			}
			continue; /* 継続 */
		}
		/* パターン文字とファイル名文字が一致ならば… */
		if(p == s) {
			/* どちらも終端ならば… */
			if(s == '\0') {
				return 0;
			}
			continue; /* 継続 */
		}
		/* パターン文字とファイル名文字が不一致ならば… */
		return FNM_NOMATCH;
	}
}

