// File: /workspace/github_cpp_makefile_star2_O1/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 0xe53a
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rsi, %r13
movq %rdi, %r15
decq %r15
xorl %eax, %eax
movl %eax, %edx
cmpb $0x2a, 0x1(%r15)
leaq 0x1(%r15), %r15
movb $0x1, %al
je 0xe515
xorl %r14d, %r14d
movzbl (%r15,%r14), %eax
testl %eax, %eax
je 0xe53d
cmpl $0x2a, %eax
je 0xe53d
incq %r14
jmp 0xe527
xorl %eax, %eax
retq
testq %r14, %r14
sete %cl
movl $0x1, %eax
testb %cl, %dl
jne 0xe6ef
movb %dl, 0x3(%rsp)
testq %r14, %r14
sete %bl
movq %r13, %rdi
callq 0x40f0
testl %eax, %eax
setne %cl
testb %cl, %bl
je 0xe572
xorl %eax, %eax
jmp 0xe6ef
testl %eax, %eax
movq %rax, %rbx
jle 0xe6d2
movb 0x3(%rsp), %al
notb %al
movzbl %al, %eax
andl $0x1, %eax
movl %eax, 0x24(%rsp)
xorl %esi, %esi
movl %ebx, %ecx
subl %esi, %ecx
cmpl %ecx, %r14d
jg 0xe6d6
movq %rsi, 0x8(%rsp)
movl %eax, 0x4(%rsp)
movq %rbx, 0x28(%rsp)
movq %r13, 0x10(%rsp)
movq %r14, 0x18(%rsp)
testl %r14d, %r14d
setg %bl
jle 0xe65b
movl 0x18(%rsp), %r14d
movq 0x10(%rsp), %rax
movq 0x8(%rsp), %rcx
addq %rcx, %rax
movq %rax, 0x30(%rsp)
movq %r14, %rbp
negq %rbp
movl $0x1, %r13d
movzbl -0x1(%r15,%r13), %edi
cmpl $0x3f, %edi
je 0xe60b
callq 0x42b0
movl %eax, %r12d
movq 0x30(%rsp), %rax
movzbl -0x1(%rax,%r13), %edi
callq 0x42b0
cmpl %eax, %r12d
jne 0xe627
cmpq %r14, %r13
setb %bl
leaq 0x1(,%r13), %rax
addq %rbp, %rax
incq %r13
cmpq $0x1, %rax
jne 0xe5e3
jmp 0xe65b
testb $0x1, %bl
je 0xe65b
movb 0x3(%rsp), %dl
testb $0x1, %dl
movl 0x4(%rsp), %eax
movl $0x0, %ecx
cmovel %ecx, %eax
movl %edx, %ecx
movl 0x24(%rsp), %edx
movq 0x18(%rsp), %r14
movq 0x10(%rsp), %r13
movq 0x28(%rsp), %rbx
movq 0x8(%rsp), %rsi
jmp 0xe6b7
movq 0x18(%rsp), %rcx
movslq %ecx, %rax
leaq (%r15,%rax), %r12
movq 0x8(%rsp), %rsi
addl %esi, %ecx
movslq %ecx, %rcx
movq 0x10(%rsp), %r13
addq %rcx, %r13
movq 0x28(%rsp), %rbx
subl %ecx, %ebx
cmpb $0x0, (%r15,%rax)
je 0xe6a6
movq %r12, %rdi
movq %r13, %rsi
callq 0xe4ec
movq 0x8(%rsp), %rsi
movl $0x1, %edx
xorl %r14d, %r14d
movq %r12, %r15
xorl %ecx, %ecx
jmp 0xe6b7
movl $0x6, %edx
xorl %r14d, %r14d
movq %r12, %r15
xorl %ecx, %ecx
movl 0x4(%rsp), %eax
testb $0x1, %cl
je 0xe6dd
incq %rsi
movslq %ebx, %rcx
cmpq %rcx, %rsi
jl 0xe58f
movl $0x6, %edx
jmp 0xe6dd
movb $0x1, %cl
jmp 0xe6e3
movl $0x1, %edx
xorl %eax, %eax
cmpl $0x6, %edx
sete %cl
testb %cl, %cl
je 0xe6ef
xorl %eax, %eax
orl %ebx, %r14d
sete %al
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop