// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rsi, %r13
testq %rdi, %rdi
je 0xc570
testq %r13, %r13
je 0xc570
leaq -0x1(%rdi), %r12
incq %rdi
xorl %edx, %edx
movl %edx, %ebx
movq %rdi, %rax
movb 0x1(%r12), %cl
incq %r12
incq %rdi
movb $0x1, %dl
cmpb $0x2a, %cl
je 0xc448
xorl %r15d, %r15d
xorl %ebp, %ebp
xorl %r14d, %r14d
movabsq $0x100000000, %rdx      # imm = 0x100000000
testb %cl, %cl
je 0xc48d
movzbl %cl, %ecx
cmpl $0x2a, %ecx
je 0xc48d
movb (%rax), %cl
decq %r14
incq %rax
addq %rdx, %rbp
incl %r15d
jmp 0xc471
testq %r14, %r14
sete %al
testb %al, %bl
jne 0xc581
movq %r13, %rdi
callq 0x30c0
testq %r14, %r14
jne 0xc4b0
testl %eax, %eax
jne 0xc570
movq %r14, %rcx
negq %rcx
movq %rcx, 0x28(%rsp)
movslq %eax, %rcx
sarq $0x20, %rbp
testl %eax, %eax
movl $0x0, %edx
movq %rax, 0x8(%rsp)
cmovgl %eax, %edx
subq %rbp, %rcx
movq %rcx, 0x30(%rsp)
movq %r13, %rax
movl %r15d, %r13d
movq %rax, 0x20(%rsp)
movq %rax, 0x10(%rsp)
xorl %eax, %eax
movq %rdx, 0x18(%rsp)
cmpq %rdx, %rax
je 0xc574
cmpq 0x30(%rsp), %rax
jg 0xc570
movq %rax, (%rsp)
xorl %r15d, %r15d
cmpq %r15, %r13
je 0xc549
movzbl (%r12,%r15), %edi
cmpl $0x3f, %edi
je 0xc52c
callq 0x32b0
movl %eax, %ebp
movq 0x10(%rsp), %rax
movzbl (%rax,%r15), %edi
callq 0x32b0
cmpl %eax, %ebp
jne 0xc531
incq %r15
jmp 0xc503
testb $0x1, %bl
je 0xc570
movq (%rsp), %rax
incq %rax
incq 0x10(%rsp)
movq 0x18(%rsp), %rdx
jmp 0xc4f0
movl 0x28(%rsp), %eax
cmpb $0x0, (%r12,%rax)
je 0xc586
addq %rax, %r12
movq (%rsp), %rax
subq %r14, %rax
movl %eax, %eax
movq 0x20(%rsp), %r13
addq %rax, %r13
movq %r12, %rdi
jmp 0xc42d
xorl %eax, %eax
jmp 0xc59d
testq %r14, %r14
sete %al
movq 0x8(%rsp), %rcx
jmp 0xc593
pushq $0x1
popq %rax
jmp 0xc59d
movq 0x8(%rsp), %rcx
addl %r14d, %ecx
subl (%rsp), %ecx
movb $0x1, %al
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