// File: /workspace/github_c_makefile_star2_O2/tditlu[P]shadetabler/src/cwalk/cwalk.c
// Function: cwk_path_get_intersection
size_t cwk_path_get_intersection(const char *path_base, const char *path_other)
{
  bool absolute;
  size_t base_root_length, other_root_length;
  const char *end;
  const char *paths_base[2], *paths_other[2];
  struct cwk_segment_joined base, other;

  // We first compare the two roots. We just return zero if they are not equal.
  // This will also happen to return zero if the paths are mixed relative and
  // absolute.
  cwk_path_get_root(path_base, &base_root_length);
  cwk_path_get_root(path_other, &other_root_length);
  if (!cwk_path_is_string_equal(path_base, path_other, base_root_length)) {
    return 0;
  }

  // Configure our paths. We just have a single path in here for now.
  paths_base[0] = path_base;
  paths_base[1] = NULL;
  paths_other[0] = path_other;
  paths_other[1] = NULL;

  // So we get the first segment of both paths. If one of those paths don't have
  // any segment, we will return 0.
  if (!cwk_path_get_first_segment_joined(paths_base, &base) ||
      !cwk_path_get_first_segment_joined(paths_other, &other)) {
    return base_root_length;
  }

  // We now determine whether the path is absolute or not. This is required
  // because if will ignore removed segments, and this behaves differently if
  // the path is absolute. However, we only need to check the base path because
  // we are guaranteed that both paths are either relative or absolute.
  absolute = cwk_path_is_root_absolute(path_base, base_root_length);

  // We must keep track of the end of the previous segment. Initially, this is
  // set to the beginning of the path. This means that 0 is returned if the
  // first segment is not equal.
  end = path_base + base_root_length;

  // Now we loop over both segments until one of them reaches the end or their
  // contents are not equal.
  do {
    // We skip all segments which will be removed in each path, since we want to
    // know about the true path.
    if (!cwk_path_segment_joined_skip_invisible(&base, absolute) ||
        !cwk_path_segment_joined_skip_invisible(&other, absolute)) {
      break;
    }

    if (!cwk_path_is_string_equal(base.segment.begin, other.segment.begin,
          base.segment.size)) {
      // So the content of those two segments are not equal. We will return the
      // size up to the beginning.
      return (size_t)(end - path_base);
    }

    // Remember the end of the previous segment before we go to the next one.
    end = base.segment.end;
  } while (cwk_path_get_next_segment_joined(&base) &&
           cwk_path_get_next_segment_joined(&other));

  // Now we calculate the length up to the last point where our paths pointed to
  // the same place.
  return (size_t)(end - path_base);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0xb0, %rsp
movq %rsi, %r15
movq %rdi, %r14
leaq 0x20(%rsp), %rbx
movq %rbx, %rsi
callq 0xce34
leaq 0x18(%rsp), %rsi
movq %r15, %rdi
callq 0xce34
movq (%rbx), %rbx
movq %r14, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0xce57
testb %al, %al
je 0xd810
leaq 0x60(%rsp), %rdi
movq %r14, (%rdi)
andq $0x0, 0x8(%rdi)
movq %r15, (%rsp)
andq $0x0, 0x8(%rsp)
leaq 0x28(%rsp), %rsi
callq 0xcef2
testb %al, %al
je 0xd812
movq %rsp, %rdi
leaq 0x78(%rsp), %rsi
callq 0xcef2
testb %al, %al
je 0xd812
movq %r14, %rdi
movq %rbx, %rsi
callq 0xcedf
addq %r14, %rbx
movzbl %al, %ebp
leaq 0x28(%rsp), %r15
leaq 0x78(%rsp), %r12
movq %r15, %rdi
movl %ebp, %esi
callq 0xcf39
testb %al, %al
je 0xd80b
movq %r12, %rdi
movl %ebp, %esi
callq 0xcf39
testb %al, %al
je 0xd80b
movq 0x88(%rsp), %rsi
movq 0x38(%rsp), %rdi
movq 0x48(%rsp), %rdx
callq 0xce57
testb %al, %al
je 0xd80b
movq 0x40(%rsp), %rbx
movq %r15, %rdi
callq 0xcfb1
testb %al, %al
je 0xd80b
movq %r12, %rdi
callq 0xcfb1
testb %al, %al
jne 0xd7b7
subq %r14, %rbx
jmp 0xd812
xorl %ebx, %ebx
movq %rbx, %rax
addq $0xb0, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq