// File: /workspace/github_cpp_makefile_star2_O2/OpenFodder[P]SOS_Unpacker/capsimg/Core/DiskFile.cpp
// Function: CDiskFile::FindFile(char*, char const*, char const*)
int CDiskFile::FindFile(char *result, const char *filename, const char *filter)
{
	// result is not valid by default
	int resvalid = 0;

	// copy source as result by default
	int rescopy = 1;

	// stop if no buffer specified for the result
	if (!result)
		return resvalid;

	// the default result is an empty string
	result[0] = 0;

	// stop if the filename is not specified
	if (!filename)
		return resvalid;

	// length of path and file name components separated
	int pathlen = 0, namelen = 0;

	// wildcard usage counter, wildcards enabled
	int wcused = 0;
	int wcenabled = 1;

	// process the entire source filename or pattern
	for (int rpos = 0; wcenabled && filename[rpos]; rpos++) {
		namelen++;

		switch (filename[rpos]) {
			// if path delimiter found
		case '/':
		case '\\':
			// stop if a wilcard has already been used; only allow wildcards in filename part, not in the path
			if (wcused) {
				// disable write card processing; the result will be the path upto the illegal wildcard segment
				wcenabled = 0;
				break;
			}

			// set new path length as the entire name until now including the delimiter
			pathlen = rpos + 1;

			// clear the filename part
			namelen = 0;
			break;

			// count the wildcards
		case '?':
		case '*':
			wcused++;
			break;
		}
	}

	// if wildcards used
	if (wcused) {
		// and wilcardcards are enabled, ie no error in the path
		if (wcenabled) {
			char *pathbuf = NULL;
			const char *dirpath;

			// make a copy of the path if it's defined or use the current directory as the path
			if (pathlen) {
				pathbuf = new char[pathlen + 1];
				memcpy(pathbuf, filename, pathlen);
				pathbuf[pathlen] = 0;
				dirpath = pathbuf;
			} else
				dirpath = ".";

			// open the selected path
			DIR *pdir = opendir(dirpath);
			if (pdir) {
				dirent *pent;
				const char *pattern = filename + pathlen;

				// iterate all directory entries
				while (pent = readdir(pdir)) {
					// skip any entry that is not a regular file
#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
					if (pent->d_type != DT_REG)
						continue;
#endif

					// check entry to match the filename pattern
					char *fn = pent->d_name;
					if (FileNameMatch(pattern, fn)) {
						// if matches, check entry to match the filter pattern if filter is specified
						if (!filter || FileNameMatch(filter, fn)) {
							// success; copy the original path and add the entry found
							memcpy(result, filename, pathlen);
							strcpy(result + pathlen, fn);

							// keep this result, don't copy the source
							rescopy = 0;

							// result is valid
							resvalid = 1;
							break;
						}
					}
				}

				closedir(pdir);
			}

			// free path buffer
			delete[] pathbuf;
		}
	} else {
		// wilcards unused, result is valid
		resvalid = 1;
	}

	// copy the source if that's the result
	if (rescopy) {
		int reslen = pathlen + namelen;
		memcpy(result, filename, reslen);
		result[reslen] = 0;
	}

	return resvalid;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
xorl %ebp, %ebp
testq %rdi, %rdi
je 0xc3fe
movq %rsi, %r14
movq %rdi, %r13
movb $0x0, (%rdi)
testq %rsi, %rsi
je 0xc3fe
movq %rdx, %r12
pushq $0x1
popq %rax
xorl %ecx, %ecx
xorl %ebx, %ebx
xorl %edx, %edx
movl %eax, %esi
xorl %r15d, %r15d
testl %esi, %esi
je 0xc2a4
movzbl (%r14,%rcx), %esi
testl %esi, %esi
je 0xc2b1
incl %ebx
cmpl $0x2a, %esi
je 0xc29b
cmpl $0x5c, %esi
je 0xc28b
cmpl $0x3f, %esi
je 0xc29b
cmpl $0x2f, %esi
jne 0xc29d
xorl %esi, %esi
testl %edx, %edx
jne 0xc29f
leal 0x1(%rcx), %r15d
xorl %ebx, %ebx
xorl %edx, %edx
jmp 0xc29d
incl %edx
movl %eax, %esi
incq %rcx
jmp 0xc268
xorl %ebp, %ebp
testl %edx, %edx
sete %bpl
jmp 0xc3e4
testl %edx, %edx
je 0xc2ee
movslq %r15d, %rbp
testl %r15d, %r15d
movq %r13, 0x8(%rsp)
je 0xc2f6
leal 0x1(%rbp), %eax
movslq %eax, %rdi
callq 0x3040
movq %rax, %r13
movq %rax, %rdi
movq %r14, %rsi
movq %rbp, %rdx
callq 0x3160
movb $0x0, (%r13,%rbp)
movq %r13, 0x10(%rsp)
movq %r13, %rdi
jmp 0xc306
pushq $0x1
popq %rbp
jmp 0xc3e4
leaq 0x3039(%rip), %rdi      # 0xf336
movq $0x0, 0x10(%rsp)
callq 0x32f0
movq %rax, 0x20(%rsp)
testq %rax, %rax
je 0xc3c3
movq %rbp, %rax
movq %r12, %rbp
movl %r15d, 0x1c(%rsp)
movq %rax, 0x28(%rsp)
addq %r14, %rax
movq %rax, 0x30(%rsp)
movq 0x20(%rsp), %rdi
callq 0x3300
movq %rax, %r13
testq %rax, %rax
setne %r12b
je 0xc3a1
cmpb $0x8, 0x12(%r13)
jne 0xc331
leaq 0x13(%r13), %r15
movq 0x30(%rsp), %rdi
movq %r15, %rsi
callq 0xc41c
testl %eax, %eax
je 0xc331
testq %rbp, %rbp
je 0xc377
movq %rbp, %rdi
movq %r15, %rsi
callq 0xc41c
testl %eax, %eax
je 0xc331
movq 0x8(%rsp), %rdi
movq %r14, %rsi
movq 0x28(%rsp), %rbp
movq %rbp, %rdx
callq 0x3160
addq 0x8(%rsp), %rbp
movq %rbp, %rdi
movq %r15, %rsi
callq 0x31b0
pushq $0x1
popq %rbp
jmp 0xc3a3
xorl %ebp, %ebp
movq 0x20(%rsp), %rdi
callq 0x3320
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
movl 0x1c(%rsp), %r15d
je 0xc40f
movq 0x8(%rsp), %r13
jmp 0xc3da
xorl %ebp, %ebp
movl $0x0, %r12d
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
movq 0x8(%rsp), %r13
je 0xc3e4
callq 0x3250
testb %r12b, %r12b
jne 0xc3fe
addl %ebx, %r15d
movslq %r15d, %r15
movq %r13, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x3160
movb $0x0, (%r13,%r15)
movl %ebp, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
testq %r13, %r13
movq 0x8(%rsp), %r13
jne 0xc3fe
jmp 0xc3e4
nop