// File: OpenFodder[P]SOS_Unpacker/capsimg/Core/DiskFile.cpp
// Function: CDiskFile::FileNameMatch(char const*, char const*)
int CDiskFile::FileNameMatch(const char *pattern, const char *filename)
{
	// an undefined pattern or filename never matches
	if (!pattern || !filename)
		return 0;

	// starmode is true if the pattern starts with a *
	int starmode = 0;

	// fold multiple consecutive stars into a single one - the meaning is identical
	while (pattern[0] == '*') {
		// pattern has at least a *
		starmode = 1;

		// the leading * gets removed, ie the pattern never includes any *
		pattern++;
	}

	// length of the current pattern
	int patternlength = 0;

	// find the length of the current pattern; either the remaining string or the string until the next * 
	while (pattern[patternlength]) {
		if (pattern[patternlength] == '*')
			break;

		patternlength++;
	}

	// always match if the pattern segment is empty and starts with *
	if (!patternlength && starmode)
		return 1;

	// length of the filename
	int namelength = (int)strlen(filename);

	// no match if pattern segment is empty, but the remaining filename is not
	if (!patternlength && namelength)
		return 0;

	// Now the actual pattern segment only contains valid characters or ?
	// Try to match the pattern segment with the actual remaining filename from the beginning.
	// If this fails, try the next position until the filename ends.
	for (int namepos = 0; namepos < namelength; namepos++) {
		// no match if the pattern segment is longer than the remaining filename
		if (patternlength > namelength - namepos)
			return 0;

		int patpos;

		// compare each character of the pattern segment with the remaining filename
		for (patpos = 0; patpos < patternlength; patpos++) {
			// ? matches any character
			if (pattern[patpos] == '?')
				continue;

			// case insensitive comparison; stop if the characters are different
			if (tolower((unsigned char)pattern[patpos]) != tolower((unsigned char)filename[patpos+namepos]))
				break;
		}

		if (patpos >= patternlength) {
			// If the pattern segment fully matches:
			// remove the pattern segment from the pattern
			pattern += patternlength;

			// remove the matched segment from the filename
			filename += patternlength + namepos;

			// calculate the remaining filename length 
			namelength -= patternlength + namepos;

			// empty pattern segment
			patternlength = 0;

			// If the pattern has more characters, recursively match the remaining pattern with the remaining filename
			if (pattern[0])
				return FileNameMatch(pattern, filename);
			else
				break;
		} else {
			// The pattern does not match the filename at the current position.
			// Fail, if the pattern segment did not start with a * allowing the segment to match from any position
			// Otherwise, try the comparison from the next character in the filename
			if (!starmode)
				return 0;
		}
	}

	// All processing done; match if the pattern and the name have no characters left, fail otherwise.
	return !patternlength && !namelength;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x178fe
cmpq $0x0, -0x18(%rbp)
jne 0x1790a
movl $0x0, -0x4(%rbp)
jmp 0x17ad3
movl $0x0, -0x1c(%rbp)
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2a, %eax
jne 0x17932
movl $0x1, -0x1c(%rbp)
movq -0x10(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x10(%rbp)
jmp 0x17911
movl $0x0, -0x20(%rbp)
movq -0x10(%rbp), %rax
movslq -0x20(%rbp), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x17965
movq -0x10(%rbp), %rax
movslq -0x20(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x2a, %eax
jne 0x1795a
jmp 0x17965
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x17939
cmpl $0x0, -0x20(%rbp)
jne 0x1797d
cmpl $0x0, -0x1c(%rbp)
je 0x1797d
movl $0x1, -0x4(%rbp)
jmp 0x17ad3
movq -0x18(%rbp), %rdi
callq 0x4100
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x20(%rbp)
jne 0x179a1
cmpl $0x0, -0x24(%rbp)
je 0x179a1
movl $0x0, -0x4(%rbp)
jmp 0x17ad3
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
cmpl -0x24(%rbp), %eax
jge 0x17ab1
movl -0x20(%rbp), %eax
movl -0x24(%rbp), %ecx
subl -0x28(%rbp), %ecx
cmpl %ecx, %eax
jle 0x179cd
movl $0x0, -0x4(%rbp)
jmp 0x17ad3
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x20(%rbp), %eax
jge 0x17a31
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x3f, %eax
jne 0x179ef
jmp 0x17a26
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movzbl (%rax,%rcx), %edi
callq 0x4490
movl %eax, -0x30(%rbp)
movq -0x18(%rbp), %rax
movl -0x2c(%rbp), %ecx
addl -0x28(%rbp), %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %edi
callq 0x4490
movl %eax, %ecx
movl -0x30(%rbp), %eax
cmpl %ecx, %eax
je 0x17a24
jmp 0x17a31
jmp 0x17a26
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x179d4
movl -0x2c(%rbp), %eax
cmpl -0x20(%rbp), %eax
jl 0x17a90
movl -0x20(%rbp), %ecx
movq -0x10(%rbp), %rax
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x10(%rbp)
movl -0x20(%rbp), %ecx
addl -0x28(%rbp), %ecx
movq -0x18(%rbp), %rax
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x18(%rbp)
movl -0x20(%rbp), %ecx
addl -0x28(%rbp), %ecx
movl -0x24(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x24(%rbp)
movl $0x0, -0x20(%rbp)
movq -0x10(%rbp), %rax
cmpb $0x0, (%rax)
je 0x17a8e
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x178e0
movl %eax, -0x4(%rbp)
jmp 0x17ad3
jmp 0x17ab1
cmpl $0x0, -0x1c(%rbp)
jne 0x17a9f
movl $0x0, -0x4(%rbp)
jmp 0x17ad3
jmp 0x17aa1
jmp 0x17aa3
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x179a8
xorl %eax, %eax
cmpl $0x0, -0x20(%rbp)
movb %al, -0x31(%rbp)
jne 0x17ac8
cmpl $0x0, -0x24(%rbp)
setne %al
xorb $-0x1, %al
movb %al, -0x31(%rbp)
movb -0x31(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax)