// File: /workspace/github_c_makefile_star2_O0/inflex[P]ripMIME/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 0x10c05
movq $0x0, -0x8(%rbp)
jmp 0x11292
movq -0x10(%rbp), %rax
movq (%rax), %rdi
callq 0x2100
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 0x2100
movl %eax, -0x64(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x2100
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 0x10c89
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x2100
cmpq $0x1, %rax
jae 0x10c89
movq -0x10(%rbp), %rax
movq $0x0, 0x18(%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x20(%rax)
je 0x10cb3
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x2100
cmpq $0x1, %rax
jae 0x10cb3
movq -0x10(%rbp), %rax
movq $0x0, 0x20(%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x18(%rax)
je 0x10cf6
movq -0x10(%rbp), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %edx
callq 0x10540
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x10cf4
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x8(%rbp)
jmp 0x11292
jmp 0x10cf6
movq -0x10(%rbp), %rax
cmpq $0x0, 0x20(%rax)
je 0x10d8e
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 0x10540
movq %rax, -0x78(%rbp)
cmpq $0x0, -0x78(%rbp)
je 0x10d6c
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 0x2100
movq %rax, %rcx
movq -0xb0(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x78(%rbp)
jmp 0x10d6e
cmpq $0x0, -0x78(%rbp)
jne 0x10d18
cmpq $0x0, -0x50(%rbp)
jne 0x10d8c
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x8(%rbp)
jmp 0x11292
jmp 0x10d8e
cmpl $0x0, -0x5c(%rbp)
jle 0x10e24
cmpl $0x0, -0x54(%rbp)
jne 0x10e10
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 0x10540
movq %rax, -0x88(%rbp)
cmpq $0x0, -0x88(%rbp)
je 0x10e0e
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 0x10540
movq %rax, -0x88(%rbp)
jmp 0x10dc8
jmp 0x10e10
movl -0x60(%rbp), %eax
movl -0x5c(%rbp), %ecx
imull -0x54(%rbp), %ecx
addl %ecx, %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0x10e2d
movl -0x60(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
movslq -0x58(%rbp), %rdi
shlq $0x0, %rdi
callq 0x2290
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0x10e72
movl -0x58(%rbp), %ecx
leaq 0xdb66(%rip), %rdi      # 0x1e9b5
leaq 0xdbbf(%rip), %rsi      # 0x1ea15
movl $0x1b8, %edx            # imm = 0x1B8
movb $0x0, %al
callq 0x117c0
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x8(%rbp)
jmp 0x11292
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 0x10540
movq %rax, -0x30(%rbp)
xorl %eax, %eax
cmpq $0x0, -0x30(%rbp)
movb %al, -0xb1(%rbp)
je 0x10ef1
xorl %eax, %eax
cmpl $0x0, -0x6c(%rbp)
movb %al, -0xb1(%rbp)
jne 0x10ef1
movq -0x10(%rbp), %rcx
movb $0x1, %al
cmpq $0x0, 0x18(%rcx)
movb %al, -0xb2(%rbp)
jne 0x10ee5
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 0x10f00
jmp 0x10fa9
movl $0x0, -0x8c(%rbp)
movl $0x0, -0x90(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x10f27
movl $0x1, -0x8c(%rbp)
jmp 0x10f3d
movq -0x48(%rbp), %rax
cmpq -0x30(%rbp), %rax
jae 0x10f3b
movl $0x1, -0x8c(%rbp)
jmp 0x10f3d
cmpq $0x0, -0x50(%rbp)
jne 0x10f50
movl $0x1, -0x90(%rbp)
jmp 0x10f66
movq -0x50(%rbp), %rax
cmpq -0x30(%rbp), %rax
jbe 0x10f64
movl $0x1, -0x90(%rbp)
jmp 0x10f66
cmpl $0x0, -0x8c(%rbp)
je 0x10f78
cmpl $0x0, -0x90(%rbp)
jne 0x10f9d
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 0x10540
movq %rax, -0x30(%rbp)
jmp 0x10fa4
movl $0x1, -0x6c(%rbp)
jmp 0x10ea3
movq -0x28(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0x11283
cmpq $0x0, -0x30(%rbp)
jne 0x10fd3
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 0x11003
cmpl $0x0, -0x58(%rbp)
setg %al
movb %al, -0xb3(%rbp)
movb -0xb3(%rbp), %al
testb $0x1, %al
jne 0x1100f
jmp 0x1103e
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 0x10fe4
movq -0x30(%rbp), %rax
cmpq -0x20(%rbp), %rax
jae 0x110d5
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 0x1108f
cmpl $0x0, -0x58(%rbp)
setg %al
movb %al, -0xb4(%rbp)
movb -0xb4(%rbp), %al
testb $0x1, %al
jne 0x1109b
jmp 0x110d3
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 0x11064
jmp 0x110d5
cmpl $0x1, -0x58(%rbp)
jge 0x11111
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rcx
movq -0x10(%rbp), %rax
movq 0x10(%rax), %r8
leaq 0xd92c(%rip), %rdi      # 0x1ea1e
leaq 0xd91c(%rip), %rsi      # 0x1ea15
movl $0x209, %edx            # imm = 0x209
movb $0x0, %al
callq 0x117c0
movq -0x40(%rbp), %rax
movb $0x0, (%rax)
jmp 0x11283
movq -0x30(%rbp), %rax
movslq -0x64(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x28(%rbp)
cmpl $0x0, -0x54(%rbp)
jne 0x11133
movq $0x0, -0x30(%rbp)
jmp 0x1127e
movq -0x28(%rbp), %rax
cmpq -0x20(%rbp), %rax
jbe 0x1114a
movq $0x0, -0x28(%rbp)
jmp 0x1127c
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 0x10540
movq %rax, -0x30(%rbp)
xorl %eax, %eax
cmpq $0x0, -0x30(%rbp)
movb %al, -0xb5(%rbp)
je 0x111c2
xorl %eax, %eax
cmpl $0x0, -0x6c(%rbp)
movb %al, -0xb5(%rbp)
jne 0x111c2
movq -0x10(%rbp), %rcx
movb $0x1, %al
cmpq $0x0, 0x18(%rcx)
movb %al, -0xb6(%rbp)
jne 0x111b6
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 0x111d1
jmp 0x1127a
movl $0x0, -0xa4(%rbp)
movl $0x0, -0xa8(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x111f8
movl $0x1, -0xa4(%rbp)
jmp 0x1120e
movq -0x48(%rbp), %rax
cmpq -0x30(%rbp), %rax
jae 0x1120c
movl $0x1, -0xa4(%rbp)
jmp 0x1120e
cmpq $0x0, -0x50(%rbp)
jne 0x11221
movl $0x1, -0xa8(%rbp)
jmp 0x11237
movq -0x50(%rbp), %rax
cmpq -0x30(%rbp), %rax
jbe 0x11235
movl $0x1, -0xa8(%rbp)
jmp 0x11237
cmpl $0x0, -0xa4(%rbp)
je 0x11249
cmpl $0x0, -0xa8(%rbp)
jne 0x1126e
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 0x10540
movq %rax, -0x30(%rbp)
jmp 0x11275
movl $0x1, -0x6c(%rbp)
jmp 0x11174
jmp 0x1127c
jmp 0x1127e
jmp 0x10fb9
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