// File: /workspace/github_c_makefile_star2_O0/tditlu[P]shadetabler/src/cwalk/cwalk.c
// Function: cwk_path_get_root_windows
static void cwk_path_get_root_windows(const char *path, size_t *length)
{
  const char *c;
  bool is_device_path;

  // A device path is a path which starts with "\\." or "\\?". A device path can
  // be a UNC path as well, in which case it will take up one more segment.
  is_device_path = false;

  // We can not determine the root if this is an empty string. So we set the
  // root to NULL and the length to zero and cancel the whole thing.
  c = path;
  *length = 0;
  if (!*c) {
    return;
  }

  // Now we have to verify whether this is a windows network path (UNC), which
  // we will consider our root.
  if (cwk_path_is_separator(c)) {
    ++c;

    // Check whether the path starts with a single back slash, which means this
    // is not a network path - just a normal path starting with a backslash.
    if (!cwk_path_is_separator(c)) {
      // Okay, this is not a network path but we still use the backslash as a
      // root.
      ++(*length);
      return;
    }

    // Yes, this is a network or device path. Skip the previous separator. Now
    // we need to determine whether this is a device path. We might advance one
    // character here if the server name starts with a '?' or a '.', but that's
    // fine since we will search for a separator afterwards anyway.
    ++c;
    is_device_path = (*c == '?' || *c == '.') && cwk_path_is_separator(++c);
    if (is_device_path) {
      // That's a device path, and the root must be either "\\.\" or "\\?\"
      // which is 4 characters long. (at least that's how Windows
      // GetFullPathName behaves.)
      *length = 4;
      return;
    }

    // We will grab anything up to the next stop. The next stop might be a '\0'
    // or another separator. That will be the server name.
    c = cwk_path_find_next_stop(c);

    // If this is a separator and not the end of a string we wil have to include
    // it. However, if this is a '\0' we must not skip it.
    while (cwk_path_is_separator(c)) {
      ++c;
    }

    // We are now skipping the shared folder name, which will end after the
    // next stop.
    c = cwk_path_find_next_stop(c);

    // Then there might be a separator at the end. We will include that as well,
    // it will mark the path as absolute.
    if (cwk_path_is_separator(c)) {
      ++c;
    }

    // Finally, calculate the size of the root.
    *length = (size_t)(c - path);
    return;
  }

  // Move to the next and check whether this is a colon.
  if (*++c == ':') {
    *length = 2;

    // Now check whether this is a backslash (or slash). If it is not, we could
    // assume that the next character is a '\0' if it is a valid path. However,
    // we will not assume that - since ':' is not valid in a path it must be a
    // mistake by the caller than. We will try to understand it anyway.
    if (cwk_path_is_separator(++c)) {
      *length = 3;
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movb $0x0, -0x19(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq $0x0, (%rax)
movq -0x18(%rbp), %rax
cmpb $0x0, (%rax)
jne 0x17cb5
jmp 0x17dfb
movq -0x18(%rbp), %rdi
callq 0x18110
testb $0x1, %al
jne 0x17cc7
jmp 0x17db4
movq -0x18(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rdi
callq 0x18110
testb $0x1, %al
jne 0x17cf3
movq -0x10(%rbp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
jmp 0x17dfb
movq -0x18(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x3f, %eax
je 0x17d1c
movq -0x18(%rbp), %rax
movsbl (%rax), %ecx
xorl %eax, %eax
cmpl $0x2e, %ecx
movb %al, -0x1a(%rbp)
jne 0x17d30
movq -0x18(%rbp), %rdi
addq $0x1, %rdi
movq %rdi, -0x18(%rbp)
callq 0x18110
movb %al, -0x1a(%rbp)
movb -0x1a(%rbp), %al
andb $0x1, %al
movb %al, -0x19(%rbp)
testb $0x1, -0x19(%rbp)
je 0x17d4e
movq -0x10(%rbp), %rax
movq $0x4, (%rax)
jmp 0x17dfb
movq -0x18(%rbp), %rdi
callq 0x189e0
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rdi
callq 0x18110
testb $0x1, %al
jne 0x17d6a
jmp 0x17d78
movq -0x18(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x18(%rbp)
jmp 0x17d5b
movq -0x18(%rbp), %rdi
callq 0x189e0
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rdi
callq 0x18110
testb $0x1, %al
jne 0x17d94
jmp 0x17da0
movq -0x18(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rcx
movq -0x8(%rbp), %rax
subq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, (%rax)
jmp 0x17dfb
movq -0x18(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x18(%rbp)
movsbl 0x1(%rax), %eax
cmpl $0x3a, %eax
jne 0x17dfb
movq -0x10(%rbp), %rax
movq $0x2, (%rax)
movq -0x18(%rbp), %rdi
addq $0x1, %rdi
movq %rdi, -0x18(%rbp)
callq 0x18110
testb $0x1, %al
jne 0x17dee
jmp 0x17df9
movq -0x10(%rbp), %rax
movq $0x3, (%rax)
jmp 0x17dfb
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)