// File: /workspace/github_c_makefile_star2_O0/inflex[P]ripMIME/ripOLE/pldstr.c
// Function: PLD_strreplace_general
char *PLD_strreplace_general( struct PLD_strreplace *replace_details )
{
	char *new_buffer=NULL;
	char *source_end;
	char *segment_start, *segment_end, *segment_p;
	char *new_p;
	char *preexist_location=NULL;
	char *postexist_location=NULL;
	int replace_count=0;
	int size_required;
	int size_difference;
	int source_length;
	int searchfor_length;
	int replacewith_length;
	int segment_ok;

	if (replace_details->source == NULL) return NULL;

	source_length = strlen( replace_details->source );
	source_end = replace_details->source +source_length;
	searchfor_length = strlen(replace_details->searchfor);
	replacewith_length = strlen(replace_details->replacewith);
	size_difference = replacewith_length -searchfor_length;
	size_required = source_length;
	replace_count = replace_details->replacenumber;

	if ((replace_details->preexist != NULL)&&(strlen(replace_details->preexist) < 1)) replace_details->preexist = NULL;
	if ((replace_details->postexist != NULL)&&(strlen(replace_details->postexist) < 1)) replace_details->postexist = NULL;

	// If we have a 'pre-exist' request, then we need to check this out first
	//		because if the pre-exist string cannot be found, then there's very
	//		little point us continuing on in our search ( because without the
	//		preexist string existing, we are thus not qualified to replace anything )
	if (replace_details->preexist != NULL)
	{
		preexist_location = PLD_strstr(replace_details->source, replace_details->preexist, replace_details->insensitive);
		if (preexist_location == NULL)
		{
			return replace_details->source;
		}
	} 

	// Determine if initial POSTexist tests will pass, if we don't pick up
	//		anything here, then there's no point in continuing either
	if (replace_details->postexist != NULL)
	{
		char *p = replace_details->source;
		postexist_location = NULL;
		do {
			p = PLD_strstr(p, replace_details->postexist, replace_details->insensitive);
			if (p != NULL)
			{
				postexist_location = p;
				p = p +strlen(replace_details->postexist);
			} 
		} while (p != NULL);

		if (postexist_location == NULL)
		{
			return replace_details->source;
		}
	} 


	// Step 1 - determine the MAXIMUM number of times we might have to replace this string ( or the limit
	//		set by replacenumber
	//
	//	Note - we only need this number if the string we're going to be inserting into the 
	//	source is larger than the one we're replacing - this is so that we can ensure that
	//	we have sufficient memory available in the buffer.
	if (size_difference > 0)
	{
		if (replace_count == 0)
		{
			char *p, *q;

			p = replace_details->source;
			q = PLD_strstr(p, replace_details->searchfor, replace_details->insensitive);
			while (q != NULL)
			{
				replace_count++;
				//size_required += size_difference;
				p = q +searchfor_length;
				q = PLD_strstr(p, replace_details->searchfor, replace_details->insensitive);
			}

		}
		size_required = source_length +(size_difference *replace_count) +1;
	} else size_required = source_length +1;

	
	// Allocate the memory required to hold the new string [at least], check to see that
	//		all went well, if not, then return an error
	new_buffer = malloc( sizeof(char) *size_required);
	if (new_buffer == NULL)
	{
		LOGGER_log("%s:%d:PLD_strreplace:ERROR: Cannot allocate %d bytes of memory to perform replacement operation", FL, size_required);
		return replace_details->source;
	} 

	// Our segment must always start at the beginning of the source, 
	//		on the other hand, the segment_end can be anything from the
	//		next byte to NULL ( which is specially treated to mean to 
	//		the end of the source )
	segment_start = replace_details->source;


	// Locate the first segment 
	segment_ok = 0;
	segment_end = PLD_strstr(replace_details->source, replace_details->searchfor, replace_details->insensitive);

	// Determine if the first segment is valid in the presence of the 
	//	pre-exist and post-exist requirements
	while ((segment_end != NULL)&&(segment_ok == 0)\
			&&((replace_details->preexist != NULL)||(replace_details->postexist != NULL)))
	{
		int pre_ok = 0;
		int post_ok = 0;

		// The PREexist test assumes a couple of factors - please ensure these are
		//		relevant if you change any code prior to this point.
		//	
		//	1. preexist_location has already been computed and is not NULL
		//
		//	2. By relative position, the first preexist_location will be a valid location
		//			on which to validate for ALL replacements beyond that point, thus, we
		//			never actually have to recompute preexist_location again.
		//
		// 3. Conversely, the last computed postexist_location is valid for all 
		//			matches before it
		//
		if (preexist_location == NULL) pre_ok = 1;
		else if (preexist_location < segment_end){ pre_ok = 1;}

		if (postexist_location == NULL) post_ok = 1;
		else if (postexist_location > segment_end){ post_ok = 1;}

		if ((pre_ok == 0)||(post_ok == 0)) { segment_end = PLD_strstr(segment_end +searchfor_length, replace_details->searchfor, replace_details->insensitive); }
		else segment_ok = 1;
	} 

	segment_p = segment_start;
	new_p = new_buffer;
	while (segment_start != NULL)
	{	
		int replacewith_count;
		char *replacewith_p;

		if (segment_end == NULL) segment_end = source_end;

		replace_count--;

		// Perform the segment copy
		segment_p = segment_start;
		while ((segment_p < segment_end)&&(size_required > 0))
		{
			*new_p = *segment_p;
			new_p++;
			segment_p++;
			size_required--;
		}

		// Perform the string replacement
		if (segment_end < source_end)
		{
			replacewith_count = replacewith_length;
			replacewith_p = replace_details->replacewith;
			while ((replacewith_count--)&&(size_required > 0))
			{
				*new_p = *replacewith_p;
				new_p++;
				replacewith_p++;
				size_required--;
			}
		}

		if (size_required < 1 )
		{
			LOGGER_log("%s:%d:PLD_strreplace_general: Allocated memory ran out while replacing '%s' with '%s'",FL, replace_details->searchfor, replace_details->replacewith);
			*new_p='\0';
			break;
		}

		// Find the next segment
		segment_start = segment_end +searchfor_length;

		// If we've reached the end of the number of replacements we're supposed
		//		to do, then we prepare the termination of the while loop by setting
		//		our segment end to the end of the source.
		//
		// NOTE: Remember that the replace_count is pre-decremented at the start
		//		of the while loop, so, if the caller requested '0' replacements
		//		this will now be -1, thus, it won't get terminated from this == 0
		//		match.  Just thought you'd like to be reminded of that incase you
		//		were wondering "Huh? this would terminate an unlimited replacement"
		if (replace_count == 0)
		{
			segment_end = NULL;
		} else {
			// If our new segment to copy starts after the
			//		end of the source, then we actually have 
			//		nothing else to copy, thus, we prepare the
			//		segment_start varible to cause the while loop 
			//		to terminate.
			//
			// Otherwise, we try and locate the next segment
			//		ending point, and set the starting point to
			//		be on the 'other side' of the 'searchfor' string
			//		which we found in the last search.
			//
			if (segment_start > source_end) 
			{
				segment_start = NULL;
			} else {

				// Try find the next segment
				segment_ok = 0;
				segment_end = PLD_strstr(segment_end +searchfor_length, replace_details->searchfor, replace_details->insensitive);

				// If we have a pre/post-exist requirement, then enter into this
				//		series of tests.  NOTE - at least one of the pre or post tests
				//		must fire to give an meaningful result - else we'll end up with 
				//		a loop which simply goes to the end of the searchspace buffer
				while ((segment_end != NULL)&&(segment_ok == 0)\
						&&((replace_details->preexist != NULL)||(replace_details->postexist != NULL)))
				{
					int pre_ok = 0;
					int post_ok = 0;

					// The PREexist test assumes a couple of factors - please ensure these are
					//		relevant if you change any code prior to this point.
					//	
					//	1. preexist_location has already been computed and is not NULL
					//
					//	2. By relative position, the first preexist_location will be a valid location
					//			on which to validate for ALL replacements beyond that point, thus, we
					//			never actually have to recompute preexist_location again.
					//
					// 3. Conversely, the last computed postexist_location is valid for all 
					//			matches before it
					//
					if (preexist_location == NULL) pre_ok = 1;
					else if (preexist_location < segment_end){ pre_ok = 1;}

					if (postexist_location == NULL) post_ok = 1;
					else if (postexist_location > segment_end){ post_ok = 1;}

					if ((pre_ok == 0)||(post_ok == 0)) { segment_end = PLD_strstr(segment_end +searchfor_length, replace_details->searchfor, replace_details->insensitive); }
					else segment_ok = 1;
				} 

			} // If-else segment_start > source_end

		}

	}

	*new_p = '\0';

//	if (replace_details->source != NULL) free (replace_details->source);
//	replace_details->source = new_buffer;
	return new_buffer;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x10(%rbp)
movq $0x0, -0x18(%rbp)
movq $0x0, -0x48(%rbp)
movq $0x0, -0x50(%rbp)
movl $0x0, -0x54(%rbp)
movq -0x10(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x59b5
movq $0x0, -0x8(%rbp)
jmp 0x6042
movq -0x10(%rbp), %rax
movq (%rax), %rdi
callq 0x10a0
movl %eax, -0x60(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movslq -0x60(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x10a0
movl %eax, -0x64(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x10a0
movl %eax, -0x68(%rbp)
movl -0x68(%rbp), %eax
subl -0x64(%rbp), %eax
movl %eax, -0x5c(%rbp)
movl -0x60(%rbp), %eax
movl %eax, -0x58(%rbp)
movq -0x10(%rbp), %rax
movl 0x28(%rax), %eax
movl %eax, -0x54(%rbp)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x18(%rax)
je 0x5a39
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x10a0
cmpq $0x1, %rax
jae 0x5a39
movq -0x10(%rbp), %rax
movq $0x0, 0x18(%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x20(%rax)
je 0x5a63
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x10a0
cmpq $0x1, %rax
jae 0x5a63
movq -0x10(%rbp), %rax
movq $0x0, 0x20(%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x18(%rax)
je 0x5aa6
movq -0x10(%rbp), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %edx
callq 0x52f0
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x5aa4
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x8(%rbp)
jmp 0x6042
jmp 0x5aa6
movq -0x10(%rbp), %rax
cmpq $0x0, 0x20(%rax)
je 0x5b3e
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x78(%rbp)
movq $0x0, -0x50(%rbp)
movq -0x78(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rsi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %edx
callq 0x52f0
movq %rax, -0x78(%rbp)
cmpq $0x0, -0x78(%rbp)
je 0x5b1c
movq -0x78(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x78(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x10a0
movq %rax, %rcx
movq -0xb0(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x78(%rbp)
jmp 0x5b1e
cmpq $0x0, -0x78(%rbp)
jne 0x5ac8
cmpq $0x0, -0x50(%rbp)
jne 0x5b3c
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x8(%rbp)
jmp 0x6042
jmp 0x5b3e
cmpl $0x0, -0x5c(%rbp)
jle 0x5bd4
cmpl $0x0, -0x54(%rbp)
jne 0x5bc0
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %edx
callq 0x52f0
movq %rax, -0x88(%rbp)
cmpq $0x0, -0x88(%rbp)
je 0x5bbe
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
movq -0x88(%rbp), %rax
movslq -0x64(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %edx
callq 0x52f0
movq %rax, -0x88(%rbp)
jmp 0x5b78
jmp 0x5bc0
movl -0x60(%rbp), %eax
movl -0x5c(%rbp), %ecx
imull -0x54(%rbp), %ecx
addl %ecx, %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0x5bdd
movl -0x60(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
movslq -0x58(%rbp), %rdi
shlq $0x0, %rdi
callq 0x1120
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0x5c22
movl -0x58(%rbp), %ecx
leaq 0x32ea(%rip), %rdi      # 0x8ee9
leaq 0x3343(%rip), %rsi      # 0x8f49
movl $0x1f2, %edx            # imm = 0x1F2
movb $0x0, %al
callq 0x5040
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x8(%rbp)
jmp 0x6042
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x28(%rbp)
movl $0x0, -0x6c(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %edx
callq 0x52f0
movq %rax, -0x30(%rbp)
xorl %eax, %eax
cmpq $0x0, -0x30(%rbp)
movb %al, -0xb1(%rbp)
je 0x5ca1
xorl %eax, %eax
cmpl $0x0, -0x6c(%rbp)
movb %al, -0xb1(%rbp)
jne 0x5ca1
movq -0x10(%rbp), %rcx
movb $0x1, %al
cmpq $0x0, 0x18(%rcx)
movb %al, -0xb2(%rbp)
jne 0x5c95
movq -0x10(%rbp), %rax
cmpq $0x0, 0x20(%rax)
setne %al
movb %al, -0xb2(%rbp)
movb -0xb2(%rbp), %al
movb %al, -0xb1(%rbp)
movb -0xb1(%rbp), %al
testb $0x1, %al
jne 0x5cb0
jmp 0x5d59
movl $0x0, -0x8c(%rbp)
movl $0x0, -0x90(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x5cd7
movl $0x1, -0x8c(%rbp)
jmp 0x5ced
movq -0x48(%rbp), %rax
cmpq -0x30(%rbp), %rax
jae 0x5ceb
movl $0x1, -0x8c(%rbp)
jmp 0x5ced
cmpq $0x0, -0x50(%rbp)
jne 0x5d00
movl $0x1, -0x90(%rbp)
jmp 0x5d16
movq -0x50(%rbp), %rax
cmpq -0x30(%rbp), %rax
jbe 0x5d14
movl $0x1, -0x90(%rbp)
jmp 0x5d16
cmpl $0x0, -0x8c(%rbp)
je 0x5d28
cmpl $0x0, -0x90(%rbp)
jne 0x5d4d
movq -0x30(%rbp), %rdi
movslq -0x64(%rbp), %rax
addq %rax, %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %edx
callq 0x52f0
movq %rax, -0x30(%rbp)
jmp 0x5d54
movl $0x1, -0x6c(%rbp)
jmp 0x5c53
movq -0x28(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0x6033
cmpq $0x0, -0x30(%rbp)
jne 0x5d83
movq -0x20(%rbp), %rax
movq %rax, -0x30(%rbp)
movl -0x54(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x54(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rcx
xorl %eax, %eax
cmpq -0x30(%rbp), %rcx
movb %al, -0xb3(%rbp)
jae 0x5db3
cmpl $0x0, -0x58(%rbp)
setg %al
movb %al, -0xb3(%rbp)
movb -0xb3(%rbp), %al
testb $0x1, %al
jne 0x5dbf
jmp 0x5dee
movq -0x38(%rbp), %rax
movb (%rax), %cl
movq -0x40(%rbp), %rax
movb %cl, (%rax)
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
movl -0x58(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0x5d94
movq -0x30(%rbp), %rax
cmpq -0x20(%rbp), %rax
jae 0x5e85
movl -0x68(%rbp), %eax
movl %eax, -0x94(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0xa0(%rbp)
movl -0x94(%rbp), %ecx
movl %ecx, %eax
addl $-0x1, %eax
movl %eax, -0x94(%rbp)
xorl %eax, %eax
cmpl $0x0, %ecx
movb %al, -0xb4(%rbp)
je 0x5e3f
cmpl $0x0, -0x58(%rbp)
setg %al
movb %al, -0xb4(%rbp)
movb -0xb4(%rbp), %al
testb $0x1, %al
jne 0x5e4b
jmp 0x5e83
movq -0xa0(%rbp), %rax
movb (%rax), %cl
movq -0x40(%rbp), %rax
movb %cl, (%rax)
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
movq -0xa0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa0(%rbp)
movl -0x58(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0x5e14
jmp 0x5e85
cmpl $0x1, -0x58(%rbp)
jge 0x5ec1
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rcx
movq -0x10(%rbp), %rax
movq 0x10(%rax), %r8
leaq 0x30b0(%rip), %rdi      # 0x8f52
leaq 0x30a0(%rip), %rsi      # 0x8f49
movl $0x244, %edx            # imm = 0x244
movb $0x0, %al
callq 0x5040
movq -0x40(%rbp), %rax
movb $0x0, (%rax)
jmp 0x6033
movq -0x30(%rbp), %rax
movslq -0x64(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x28(%rbp)
cmpl $0x0, -0x54(%rbp)
jne 0x5ee3
movq $0x0, -0x30(%rbp)
jmp 0x602e
movq -0x28(%rbp), %rax
cmpq -0x20(%rbp), %rax
jbe 0x5efa
movq $0x0, -0x28(%rbp)
jmp 0x602c
movl $0x0, -0x6c(%rbp)
movq -0x30(%rbp), %rdi
movslq -0x64(%rbp), %rax
addq %rax, %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %edx
callq 0x52f0
movq %rax, -0x30(%rbp)
xorl %eax, %eax
cmpq $0x0, -0x30(%rbp)
movb %al, -0xb5(%rbp)
je 0x5f72
xorl %eax, %eax
cmpl $0x0, -0x6c(%rbp)
movb %al, -0xb5(%rbp)
jne 0x5f72
movq -0x10(%rbp), %rcx
movb $0x1, %al
cmpq $0x0, 0x18(%rcx)
movb %al, -0xb6(%rbp)
jne 0x5f66
movq -0x10(%rbp), %rax
cmpq $0x0, 0x20(%rax)
setne %al
movb %al, -0xb6(%rbp)
movb -0xb6(%rbp), %al
movb %al, -0xb5(%rbp)
movb -0xb5(%rbp), %al
testb $0x1, %al
jne 0x5f81
jmp 0x602a
movl $0x0, -0xa4(%rbp)
movl $0x0, -0xa8(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x5fa8
movl $0x1, -0xa4(%rbp)
jmp 0x5fbe
movq -0x48(%rbp), %rax
cmpq -0x30(%rbp), %rax
jae 0x5fbc
movl $0x1, -0xa4(%rbp)
jmp 0x5fbe
cmpq $0x0, -0x50(%rbp)
jne 0x5fd1
movl $0x1, -0xa8(%rbp)
jmp 0x5fe7
movq -0x50(%rbp), %rax
cmpq -0x30(%rbp), %rax
jbe 0x5fe5
movl $0x1, -0xa8(%rbp)
jmp 0x5fe7
cmpl $0x0, -0xa4(%rbp)
je 0x5ff9
cmpl $0x0, -0xa8(%rbp)
jne 0x601e
movq -0x30(%rbp), %rdi
movslq -0x64(%rbp), %rax
addq %rax, %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %edx
callq 0x52f0
movq %rax, -0x30(%rbp)
jmp 0x6025
movl $0x1, -0x6c(%rbp)
jmp 0x5f24
jmp 0x602c
jmp 0x602e
jmp 0x5d69
movq -0x40(%rbp), %rax
movb $0x0, (%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xc0, %rsp
popq %rbp
retq
nop