user: 请将这段汇编代码片段转换成等效的C代码：

```asm
<sr_parse_os_release>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x50,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %rsi,-0x40(%rbp)
  mov    %rdx,-0x48(%rbp)
  mov    -0x38(%rbp),%rax
  mov    %rax,-0x28(%rbp)
  movl   $0x0,-0x2c(%rbp)
  jmp    L45
L60:
  addl   $0x1,-0x2c(%rbp)
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x23,%al
  je     L43
  mov    -0x28(%rbp),%rax
  mov    $0x3d,%esi
  mov    %rax,%rdi
  call   <strchrnul@plt>
  mov    %rax,-0x20(%rbp)
  mov    -0x20(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L61
  mov    -0x2c(%rbp),%eax
  mov    %eax,%esi
  lea    D41(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <warn@plt>
  jmp    L119
L61:
  mov    -0x20(%rbp),%rax
  cmp    -0x28(%rbp),%rax
  jne    L27
  mov    -0x2c(%rbp),%eax
  mov    %eax,%esi
  lea    D5(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <warn@plt>
  jmp    L87
L27:
  mov    -0x28(%rbp),%rax
  mov    $0xa,%esi
  mov    %rax,%rdi
  call   <strchrnul@plt>
  mov    %rax,-0x18(%rbp)
  mov    -0x20(%rbp),%rax
  cmp    -0x18(%rbp),%rax
  jbe    L105
  mov    -0x2c(%rbp),%eax
  mov    %eax,%esi
  lea    D48(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <warn@plt>
  jmp    L87
L105:
  mov    -0x20(%rbp),%rax
  sub    -0x28(%rbp),%rax
  mov    %eax,%edx
  mov    -0x28(%rbp),%rax
  mov    %edx,%esi
  mov    %rax,%rdi
  call   <sr_strndup@plt>
  mov    %rax,-0x10(%rbp)
  mov    -0x18(%rbp),%rax
  sub    -0x20(%rbp),%rax
  sub    $0x1,%eax
  mov    %eax,%edx
  mov    -0x20(%rbp),%rax
  add    $0x1,%rax
  mov    %edx,%esi
  mov    %rax,%rdi
  call   <sr_strndup@plt>
  mov    %rax,-0x8(%rbp)
  mov    -0x8(%rbp),%rdx
  mov    -0x8(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <unescape_osinfo_value@plt>
  mov    -0x8(%rbp),%rcx
  mov    -0x10(%rbp),%rdx
  mov    -0x2c(%rbp),%eax
  mov    %eax,%esi
  lea    D10(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <warn@plt>
  mov    -0x48(%rbp),%rdx
  mov    -0x8(%rbp),%rcx
  mov    -0x10(%rbp),%rax
  mov    -0x40(%rbp),%r8
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   *%r8
  mov    -0x18(%rbp),%rax
  mov    %rax,-0x28(%rbp)
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L54
  mov    -0x2c(%rbp),%eax
  mov    %eax,%esi
  lea    D47(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <warn@plt>
  jmp    L45
L54:
  addq   $0x1,-0x28(%rbp)
  jmp    L45
L43:
  nop
L87:
  mov    -0x28(%rbp),%rax
  mov    $0xa,%esi
  mov    %rax,%rdi
  call   <strchrnul@plt>
  mov    %rax,-0x28(%rbp)
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  setne  %al
  movzbl %al,%eax
  add    %rax,-0x28(%rbp)
L45:
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L60
  nop
L119:
  nop
  leave
  ret
```

tool_calls: name: read_data
arguments: data_tag: D41
type_guessed: string
name: read_data
arguments: data_tag: D5
type_guessed: string
name: read_data
arguments: data_tag: D48
type_guessed: string
name: read_data
arguments: data_tag: D10
type_guessed: string
name: read_data
arguments: data_tag: D47
type_guessed: string

tool: D41: os-release:%u: non empty last line

tool: D5: os-release:%u: 0 length key

tool: D48: os-release:%u: missing '='

tool: D10: os-release:%u: parsed line: '%s'='%s'

tool: D47: os-release:%u: the last value is not terminated by newline

assistant: ```c
void sr_parse_os_release(const char *input, void (*callback)(char *, char *, void *), void *data) {
  const char *cursor = input;
  unsigned line = 0;
  while (cursor[0] != '\0') {
    ++line;
    if (cursor[0] == '#')
      goto skip_line;
    const char *key_end = strchrnul(cursor, '=');
    if (key_end[0] == '\0') {
      warn("os-release:%u: non empty last line", line);
      break;
    }
    if (key_end - cursor == 0) {
      warn("os-release:%u: 0 length key", line);
      goto skip_line;
    }
    const char *value_end = strchrnul(cursor, '\n');
    if (key_end > value_end) {
      warn("os-release:%u: missing '='", line);
      goto skip_line;
    }
    char *key = sr_strndup(cursor, key_end - cursor);
    char *value = sr_strndup(key_end + 1, value_end - key_end - 1);
    unescape_osinfo_value(value, value);
    warn("os-release:%u: parsed line: '%s'='%s'", line, key, value);
    callback(key, value, data);
    cursor = value_end;
    if (value_end[0] == '\0') {
      warn("os-release:%u: the last value is not terminated by newline", line);
    } else
      ++cursor;
    continue;
  skip_line:
    cursor = strchrnul(cursor, '\n');
    cursor += (cursor[0] != '\0');
  }
}
```