// File: /workspace/github_cpp_makefile_star2_O3/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:
testq %rdi, %rdi
sete %al
testq %rsi, %rsi
sete %cl
orb %al, %cl
jne 0xe6d3
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rsi, %r12
leaq -0x1(%rdi), %r13
incq %rdi
xorl %edx, %edx
movl %edx, %r14d
movq %rdi, %rax
movb 0x1(%r13), %cl
incq %r13
incq %rdi
movb $0x1, %dl
cmpb $0x2a, %cl
je 0xe596
xorl %ebx, %ebx
xorl %r15d, %r15d
xorl %ebp, %ebp
movabsq $0x100000000, %rdx      # imm = 0x100000000
testb %cl, %cl
je 0xe5d9
movzbl %cl, %ecx
cmpl $0x2a, %ecx
je 0xe5d9
incq %rbp
movb (%rax), %cl
incq %rax
addq %rdx, %r15
incl %ebx
jmp 0xe5be
testq %rbp, %rbp
sete %al
testb %al, %r14b
jne 0xe6da
movq %r12, %rdi
callq 0x40f0
testq %rbp, %rbp
jne 0xe5fd
testl %eax, %eax
jne 0xe6d6
testl %eax, %eax
jle 0xe6e1
movq %rax, 0x18(%rsp)
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
sarq $0x20, %r15
movq %rax, 0x28(%rsp)
movq %rax, %rcx
subq %r15, %rcx
movq %r12, %rax
movl %ebx, %r12d
movq %rax, 0x30(%rsp)
movq %rax, 0x10(%rsp)
xorl %eax, %eax
movq %rcx, 0x20(%rsp)
cmpq %rcx, %rax
jg 0xe6d6
testq %rbp, %rbp
je 0xe6cf
movq %rax, 0x8(%rsp)
xorl %ebx, %ebx
movzbl (%r13,%rbx), %edi
cmpl $0x3f, %edi
je 0xe674
callq 0x42b0
movl %eax, %r15d
movq 0x10(%rsp), %rax
movzbl (%rax,%rbx), %edi
callq 0x42b0
cmpl %eax, %r15d
jne 0xe67e
incq %rbx
cmpq %rbx, %r12
jne 0xe64e
jmp 0xe69f
testb $0x1, %r14b
je 0xe6d6
movq 0x8(%rsp), %rax
incq %rax
incq 0x10(%rsp)
cmpq 0x28(%rsp), %rax
movq 0x20(%rsp), %rcx
jne 0xe635
jmp 0xe6f9
movq 0x8(%rsp), %rdx
movl %ebp, %eax
cmpb $0x0, (%r13,%rax)
movq 0x30(%rsp), %rcx
je 0xe6ec
addq %rax, %r13
movl %edx, %eax
addq %rbp, %rax
movl %eax, %r12d
addq %rcx, %r12
movq %r13, %rdi
testq %rcx, %rcx
jne 0xe58d
jmp 0xe6d6
xorl %edx, %edx
jmp 0xe6a4
xorl %eax, %eax
retq
xorl %eax, %eax
jmp 0xe70a
movl $0x1, %eax
jmp 0xe70a
testq %rbp, %rbp
movq %rax, %rcx
sete %al
jmp 0xe700
movq 0x18(%rsp), %rcx
subl %edx, %ecx
subl %ebp, %ecx
movb $0x1, %al
jmp 0xe700
movl $0x1, %ecx
xorl %eax, %eax
testl %ecx, %ecx
sete %cl
andb %al, %cl
movzbl %cl, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nopl (%rax)