// File: /workspace/github_c_makefile_star2_O0/tditlu[P]shadetabler/src/cwalk/cwalk.c
// Function: cwk_path_get_relative
size_t cwk_path_get_relative(const char *base_directory, const char *path,
  char *buffer, size_t buffer_size)
{
  size_t pos, base_root_length, path_root_length;
  bool absolute, base_available, other_available, has_output;
  const char *base_paths[2], *other_paths[2];
  struct cwk_segment_joined bsj, osj;

  pos = 0;

  // First we compare the roots of those two paths. If the roots are not equal
  // we can't continue, since there is no way to get a relative path from
  // different roots.
  cwk_path_get_root(base_directory, &base_root_length);
  cwk_path_get_root(path, &path_root_length);
  if (!cwk_path_is_string_equal(base_directory, path, base_root_length)) {
    return pos;
  }

  // Verify whether this is an absolute path. We need to know that since we can
  // remove all back-segments if it is.
  absolute = cwk_path_is_root_absolute(base_directory, base_root_length);

  // Initialize our joined segments. This will allow us to use the internal
  // functions to skip until diverge and invisible. We only have one path in
  // them though.
  base_paths[0] = base_directory;
  base_paths[1] = NULL;
  other_paths[0] = path;
  other_paths[1] = NULL;
  cwk_path_get_first_segment_joined(base_paths, &bsj);
  cwk_path_get_first_segment_joined(other_paths, &osj);

  // Okay, now we skip until the segments diverge. We don't have anything to do
  // with the segments which are equal.
  cwk_path_skip_segments_until_diverge(&bsj, &osj, absolute, &base_available,
    &other_available);

  // Assume there is no output until we have got some. We will need this
  // information later on to remove trailing slashes or alternatively output a
  // current-segment.
  has_output = false;

  // So if we still have some segments left in the base path we will now output
  // a back segment for all of them.
  if (base_available) {
    do {
      // Skip any invisible segment. We don't care about those and we don't need
      // to navigate back because of them.
      if (!cwk_path_segment_joined_skip_invisible(&bsj, absolute)) {
        break;
      }

      // Toggle the flag if we have output. We need to remember that, since we
      // want to remove the trailing slash.
      has_output = true;

      // Output the back segment and a separator. No need to worry about the
      // superfluous segment since it will be removed later on.
      pos += cwk_path_output_back(buffer, buffer_size, pos);
      pos += cwk_path_output_separator(buffer, buffer_size, pos);
    } while (cwk_path_get_next_segment_joined(&bsj));
  }

  // And if we have some segments available of the target path we will output
  // all of those.
  if (other_available) {
    do {
      // Again, skip any invisible segments since we don't need to navigate into
      // them.
      if (!cwk_path_segment_joined_skip_invisible(&osj, absolute)) {
        break;
      }

      // Toggle the flag if we have output. We need to remember that, since we
      // want to remove the trailing slash.
      has_output = true;

      // Output the current segment and a separator. No need to worry about the
      // superfluous segment since it will be removed later on.
      pos += cwk_path_output_sized(buffer, buffer_size, pos, osj.segment.begin,
        osj.segment.size);
      pos += cwk_path_output_separator(buffer, buffer_size, pos);
    } while (cwk_path_get_next_segment_joined(&osj));
  }

  // If we have some output by now we will have to remove the trailing slash. We
  // simply do that by moving back one character. The terminate output function
  // will then place the '\0' on this position. Otherwise, if there is no
  // output, we will have to output a "current directory", since the target path
  // points to the base path.
  if (has_output) {
    --pos;
  } else {
    pos += cwk_path_output_current(buffer, buffer_size, pos);
  }

  // Finally, we can terminate the output - which means we place a '\0' at the
  // current position or at the end of the buffer.
  cwk_path_terminate_output(buffer, buffer_size, pos);

  return pos;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x17620
movq -0x18(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x17620
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x38(%rbp), %rdx
callq 0x17660
testb $0x1, %al
jne 0x1746f
movq -0x30(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x17610
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x17770
andb $0x1, %al
movb %al, -0x41(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x60(%rbp)
movq $0x0, -0x58(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x70(%rbp)
movq $0x0, -0x68(%rbp)
leaq -0x60(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x177c0
leaq -0x70(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x177c0
movb -0x41(%rbp), %al
leaq -0xa8(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
leaq -0x42(%rbp), %rcx
leaq -0x43(%rbp), %r8
andb $0x1, %al
movzbl %al, %edx
callq 0x17860
movb $0x0, -0x44(%rbp)
testb $0x1, -0x42(%rbp)
je 0x17552
jmp 0x174f0
movb -0x41(%rbp), %al
leaq -0xa8(%rbp), %rdi
andb $0x1, %al
movzbl %al, %esi
callq 0x17940
testb $0x1, %al
jne 0x1750a
jmp 0x17550
movb $0x1, -0x44(%rbp)
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x17990
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x179d0
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x17a20
testb $0x1, %al
jne 0x174f0
jmp 0x17552
testb $0x1, -0x43(%rbp)
je 0x175ca
jmp 0x1755a
movb -0x41(%rbp), %al
leaq -0xe0(%rbp), %rdi
andb $0x1, %al
movzbl %al, %esi
callq 0x17940
testb $0x1, %al
jne 0x17574
jmp 0x175c8
movb $0x1, -0x44(%rbp)
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x30(%rbp), %rdx
movq -0xd0(%rbp), %rcx
movq -0xc0(%rbp), %r8
callq 0x17af0
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x179d0
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
leaq -0xe0(%rbp), %rdi
callq 0x17a20
testb $0x1, %al
jne 0x1755a
jmp 0x175ca
testb $0x1, -0x44(%rbp)
je 0x175de
movq -0x30(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x175f7
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x17b70
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x17bb0
movq -0x30(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xe0, %rsp
popq %rbp
retq
nopl (%rax)