// File: gpertea[P]gclib/GStr.cpp
// Function: GStr::tr(char const*, char const*)
GStr&  GStr::tr(const char *rfrom, const char* rto) {
 if (length() == 0 || rfrom==NULL || strlen(rfrom)==0)
        return *this;
 unsigned int l=strlen(rfrom);
 if (rto!=NULL && rto[0]==0) rto=NULL;
 if (rto!=NULL && strlen(rto)!=l)
      invalid_args_error("tr()");
 make_unique(); //edit operation ahead

 if (rto==NULL) { //delete all characters
   Data *data = new_data(length());
   char* s = my_data->chars;
   char* p=NULL;
   char* dest = data->chars;
   do {
      if ((p=strpbrk(s,rfrom))!=NULL) {
        memcpy(dest,s,p-s);
        dest+=p-s;
        s=p+1;
        }
       else {
        strcpy(dest, s);
        dest+=strlen(s);
        }
      } while (p!=NULL);
   (*dest)='\0';
   data->length=strlen(data->chars);
   replace_data(data);
   }
  else { //char substitution case - easier!
   const char* p=NULL;
   for (int i=0; i<length(); i++) {
    if ((p=strchr(rfrom, my_data->chars[i]))!=NULL)
         my_data->chars[i]=rto[p-rfrom];
    }
   }
 return *this;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x60(%rbp)
callq 0xb660
cmpl $0x0, %eax
je 0x92cc
cmpq $0x0, -0x18(%rbp)
je 0x92cc
movq -0x18(%rbp), %rdi
callq 0x2140
cmpq $0x0, %rax
jne 0x92d9
movq -0x60(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x949c
movq -0x18(%rbp), %rdi
callq 0x2140
movl %eax, -0x24(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x9300
movq -0x20(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
jne 0x9300
movq $0x0, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x9324
movq -0x20(%rbp), %rdi
callq 0x2140
movl -0x24(%rbp), %ecx
cmpq %rcx, %rax
je 0x9324
leaq 0xae91(%rip), %rdi      # 0x141b0
callq 0x91c0
movq -0x60(%rbp), %rdi
callq 0x63e0
cmpq $0x0, -0x20(%rbp)
jne 0x9418
movq -0x60(%rbp), %rdi
callq 0xb660
movl %eax, %edi
xorl %esi, %esi
callq 0x6100
movq %rax, %rcx
movq -0x60(%rbp), %rax
movq %rcx, -0x30(%rbp)
movq 0x20(%rax), %rax
addq $0xc, %rax
movq %rax, -0x38(%rbp)
movq $0x0, -0x40(%rbp)
movq -0x30(%rbp), %rax
addq $0xc, %rax
movq %rax, -0x48(%rbp)
movq -0x38(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x23f0
movq %rax, -0x40(%rbp)
cmpq $0x0, %rax
je 0x93c5
movq -0x48(%rbp), %rdi
movq -0x38(%rbp), %rsi
movq -0x40(%rbp), %rdx
movq -0x38(%rbp), %rax
subq %rax, %rdx
callq 0x21f0
movq -0x40(%rbp), %rax
movq -0x38(%rbp), %rcx
subq %rcx, %rax
addq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x93e3
movq -0x48(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x2240
movq -0x38(%rbp), %rdi
callq 0x2140
addq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
jmp 0x93e5
cmpq $0x0, -0x40(%rbp)
jne 0x9375
movq -0x48(%rbp), %rax
movb $0x0, (%rax)
movq -0x30(%rbp), %rdi
addq $0xc, %rdi
callq 0x2140
movq -0x60(%rbp), %rdi
movl %eax, %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x30(%rbp), %rsi
callq 0x6460
jmp 0x9494
movq $0x0, -0x50(%rbp)
movl $0x0, -0x54(%rbp)
movq -0x60(%rbp), %rdi
movl -0x54(%rbp), %eax
movl %eax, -0x64(%rbp)
callq 0xb660
movl %eax, %ecx
movl -0x64(%rbp), %eax
cmpl %ecx, %eax
jge 0x9492
movq -0x60(%rbp), %rax
movq -0x18(%rbp), %rdi
movq 0x20(%rax), %rax
movslq -0x54(%rbp), %rcx
movsbl 0xc(%rax,%rcx), %esi
callq 0x2100
movq %rax, -0x50(%rbp)
cmpq $0x0, %rax
je 0x9485
movq -0x60(%rbp), %rax
movq -0x20(%rbp), %rcx
movq -0x50(%rbp), %rdx
movq -0x18(%rbp), %rsi
subq %rsi, %rdx
movb (%rcx,%rdx), %dl
movq 0x20(%rax), %rax
movslq -0x54(%rbp), %rcx
movb %dl, 0xc(%rax,%rcx)
jmp 0x9487
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0x9427
jmp 0x9494
movq -0x60(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x70, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)