#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int /*<<< orphan*/ EINVAL;
scalar_t__ _gpgme_is_valid_mailbox(char const *);
char *ascii_strlwr(char *);
int /*<<< orphan*/ errno;
int /*<<< orphan*/ free(char *);
scalar_t__ has_dotdot_after_at(char *);
char *malloc(size_t);
char *strchr(char const *, char);
char *strdup(char const *);
int string_count_chr(char *, char);
scalar_t__ string_has_ctrl_or_space(char *);
int /*<<< orphan*/ strncpy(char *, char const *, size_t);
char *_gpgme_mailbox_from_userid(const char *userid) {
  const char *s, *s_end;
  size_t len;
  char *result = NULL;
  s = strchr(userid, '<');
  if (s) {
    s++;
    s_end = strchr(s, '>');
    if (s_end && s_end > s) {
      len = s_end - s;
      result = malloc(len + 1);
      if (!result)
        return NULL;
      strncpy(result, s, len);
      result[len] = 0;
      if (string_count_chr(result, '@') != 1 || *result == '@' ||
          result[len - 1] == '@' || result[len - 1] == '.' ||
          string_has_ctrl_or_space(result) || has_dotdot_after_at(result)) {
        free(result);
        result = NULL;
        errno = EINVAL;
      }
    } else
      errno = EINVAL;
  } else if (_gpgme_is_valid_mailbox(userid)) {
    result = strdup(userid);
  } else
    errno = EINVAL;
  return result ? ascii_strlwr(result) : NULL;
}


x86 assembly (clang, -O0):
<_gpgme_mailbox_from_userid>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
movq   $0x0,-0x30(%rbp)
mov    -0x10(%rbp),%rdi
mov    $0x3c,%esi
call   1060 <strchr@plt>
mov    %rax,-0x18(%rbp)
cmpq   $0x0,-0x18(%rbp)
je     131b <_gpgme_mailbox_from_userid+0x17b>
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rdi
mov    $0x3e,%esi
call   1060 <strchr@plt>
mov    %rax,-0x20(%rbp)
cmpq   $0x0,-0x20(%rbp)
je     1304 <_gpgme_mailbox_from_userid+0x164>
mov    -0x20(%rbp),%rax
cmp    -0x18(%rbp),%rax
jbe    1304 <_gpgme_mailbox_from_userid+0x164>
mov    -0x20(%rbp),%rax
mov    -0x18(%rbp),%rcx
sub    %rcx,%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rdi
add    $0x1,%rdi
call   1080 <malloc@plt>
mov    %rax,-0x30(%rbp)
cmpq   $0x0,-0x30(%rbp)
jne    1240 <_gpgme_mailbox_from_userid+0xa0>
movq   $0x0,-0x8(%rbp)
jmp    1387 <_gpgme_mailbox_from_userid+0x1e7>
mov    -0x30(%rbp),%rdi
mov    -0x18(%rbp),%rsi
mov    -0x28(%rbp),%rdx
call   1040 <strncpy@plt>
mov    -0x30(%rbp),%rax
mov    -0x28(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x30(%rbp),%rdi
mov    $0x40,%esi
call   1070 <string_count_chr@plt>
cmp    $0x1,%eax
jne    12dc <_gpgme_mailbox_from_userid+0x13c>
mov    -0x30(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x40,%eax
je     12dc <_gpgme_mailbox_from_userid+0x13c>
mov    -0x30(%rbp),%rax
mov    -0x28(%rbp),%rcx
sub    $0x1,%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x40,%eax
je     12dc <_gpgme_mailbox_from_userid+0x13c>
mov    -0x30(%rbp),%rax
mov    -0x28(%rbp),%rcx
sub    $0x1,%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x2e,%eax
je     12dc <_gpgme_mailbox_from_userid+0x13c>
mov    -0x30(%rbp),%rdi
call   10b0 <string_has_ctrl_or_space@plt>
cmp    $0x0,%rax
jne    12dc <_gpgme_mailbox_from_userid+0x13c>
mov    -0x30(%rbp),%rdi
call   1090 <has_dotdot_after_at@plt>
cmp    $0x0,%rax
je     12ff <_gpgme_mailbox_from_userid+0x15f>
mov    -0x30(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x30(%rbp)
mov    0x2ce4(%rip),%rax
mov    (%rax),%ecx
mov    0x2ce3(%rip),%rax
mov    %ecx,(%rax)
jmp    1316 <_gpgme_mailbox_from_userid+0x176>
mov    0x2ccd(%rip),%rax
mov    (%rax),%ecx
mov    0x2ccc(%rip),%rax
mov    %ecx,(%rax)
jmp    1357 <_gpgme_mailbox_from_userid+0x1b7>
mov    -0x10(%rbp),%rdi
call   1050 <_gpgme_is_valid_mailbox@plt>
cmp    $0x0,%rax
je     1340 <_gpgme_mailbox_from_userid+0x1a0>
mov    -0x10(%rbp),%rdi
call   10c0 <strdup@plt>
mov    %rax,-0x30(%rbp)
jmp    1352 <_gpgme_mailbox_from_userid+0x1b2>
mov    0x2c91(%rip),%rax
mov    (%rax),%ecx
mov    0x2c90(%rip),%rax
mov    %ecx,(%rax)
jmp    1357 <_gpgme_mailbox_from_userid+0x1b7>
cmpq   $0x0,-0x30(%rbp)
je     1374 <_gpgme_mailbox_from_userid+0x1d4>
mov    -0x30(%rbp),%rdi
call   10a0 <ascii_strlwr@plt>
mov    %rax,-0x38(%rbp)
jmp    137f <_gpgme_mailbox_from_userid+0x1df>
xor    %eax,%eax
mov    %rax,-0x38(%rbp)
jmp    137f <_gpgme_mailbox_from_userid+0x1df>
mov    -0x38(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<_gpgme_mailbox_from_userid>:
push   %r15
push   %r14
push   %rbx
mov    %rdi,%r14
mov    $0x3c,%esi
call   1060 <strchr@plt>
test   %rax,%rax
je     124c <_gpgme_mailbox_from_userid+0xac>
mov    %rax,%rbx
add    $0x1,%rbx
mov    %rbx,%rdi
mov    $0x3e,%esi
call   1060 <strchr@plt>
mov    %rax,%r15
sub    %rbx,%r15
jbe    1276 <_gpgme_mailbox_from_userid+0xd6>
lea    0x1(%r15),%rdi
call   1080 <malloc@plt>
test   %rax,%rax
je     1288 <_gpgme_mailbox_from_userid+0xe8>
mov    %rax,%r14
mov    %rax,%rdi
mov    %rbx,%rsi
mov    %r15,%rdx
call   1040 <strncpy@plt>
movb   $0x0,(%r14,%r15,1)
mov    %r14,%rdi
mov    $0x40,%esi
call   1070 <string_count_chr@plt>
cmp    $0x1,%eax
jne    1242 <_gpgme_mailbox_from_userid+0xa2>
cmpb   $0x40,(%r14)
je     1242 <_gpgme_mailbox_from_userid+0xa2>
mov    -0x1(%r15,%r14,1),%al
cmp    $0x2e,%al
je     1242 <_gpgme_mailbox_from_userid+0xa2>
cmp    $0x40,%al
je     1242 <_gpgme_mailbox_from_userid+0xa2>
mov    %r14,%rdi
call   10b0 <string_has_ctrl_or_space@plt>
test   %rax,%rax
jne    1242 <_gpgme_mailbox_from_userid+0xa2>
mov    %r14,%rdi
call   1090 <has_dotdot_after_at@plt>
test   %rax,%rax
je     1269 <_gpgme_mailbox_from_userid+0xc9>
mov    %r14,%rdi
call   1030 <free@plt>
jmp    1276 <_gpgme_mailbox_from_userid+0xd6>
mov    %r14,%rdi
call   1050 <_gpgme_is_valid_mailbox@plt>
test   %rax,%rax
je     1276 <_gpgme_mailbox_from_userid+0xd6>
mov    %r14,%rdi
call   10c0 <strdup@plt>
mov    %rax,%r14
test   %rax,%rax
je     1288 <_gpgme_mailbox_from_userid+0xe8>
mov    %r14,%rdi
pop    %rbx
pop    %r14
pop    %r15
jmp    10a0 <ascii_strlwr@plt>
mov    0x2d5b(%rip),%rax
mov    (%rax),%eax
mov    0x2d5a(%rip),%rcx
mov    %eax,(%rcx)
xor    %eax,%eax
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@EINVAL = global i32 0
@errno = global i32 0
define i8* @_gpgme_mailbox_from_userid(i8* %0) {
%2 = alloca i8*
%3 = alloca i8*
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i64
%7 = alloca i8*
store i8* %0, i8** %3
store i8* null, i8** %7
%8 = load i8*, i8** %3
%9 = call i8* @strchr(i8* %8, i8 signext 60)
store i8* %9, i8** %4
%10 = load i8*, i8** %4
%11 = icmp ne i8* %10, null
br i1 %11, label %12, label %83
12: ; preds = %1
%13 = load i8*, i8** %4
%14 = getelementptr inbounds i8, i8* %13, i32 1
store i8* %14, i8** %4
%15 = load i8*, i8** %4
%16 = call i8* @strchr(i8* %15, i8 signext 62)
store i8* %16, i8** %5
%17 = load i8*, i8** %5
%18 = icmp ne i8* %17, null
br i1 %18, label %19, label %80
19: ; preds = %12
%20 = load i8*, i8** %5
%21 = load i8*, i8** %4
%22 = icmp ugt i8* %20, %21
br i1 %22, label %23, label %80
23: ; preds = %19
%24 = load i8*, i8** %5
%25 = load i8*, i8** %4
%26 = ptrtoint i8* %24 to i64
%27 = ptrtoint i8* %25 to i64
%28 = sub i64 %26, %27
store i64 %28, i64* %6
%29 = load i64, i64* %6
%30 = add i64 %29, 1
%31 = call i8* @malloc(i64 %30)
store i8* %31, i8** %7
%32 = load i8*, i8** %7
%33 = icmp ne i8* %32, null
br i1 %33, label %35, label %34
34: ; preds = %23
store i8* null, i8** %2
br label %102
35: ; preds = %23
%36 = load i8*, i8** %7
%37 = load i8*, i8** %4
%38 = load i64, i64* %6
%39 = call i32 @strncpy(i8* %36, i8* %37, i64 %38)
%40 = load i8*, i8** %7
%41 = load i64, i64* %6
%42 = getelementptr inbounds i8, i8* %40, i64 %41
store i8 0, i8* %42
%43 = load i8*, i8** %7
%44 = call i32 @string_count_chr(i8* %43, i8 signext 64)
%45 = icmp ne i32 %44, 1
br i1 %45, label %75, label %46
46: ; preds = %35
%47 = load i8*, i8** %7
%48 = load i8, i8* %47
%49 = sext i8 %48 to i32
%50 = icmp eq i32 %49, 64
br i1 %50, label %75, label %51
51: ; preds = %46
%52 = load i8*, i8** %7
%53 = load i64, i64* %6
%54 = sub i64 %53, 1
%55 = getelementptr inbounds i8, i8* %52, i64 %54
%56 = load i8, i8* %55
%57 = sext i8 %56 to i32
%58 = icmp eq i32 %57, 64
br i1 %58, label %75, label %59
59: ; preds = %51
%60 = load i8*, i8** %7
%61 = load i64, i64* %6
%62 = sub i64 %61, 1
%63 = getelementptr inbounds i8, i8* %60, i64 %62
%64 = load i8, i8* %63
%65 = sext i8 %64 to i32
%66 = icmp eq i32 %65, 46
br i1 %66, label %75, label %67
67: ; preds = %59
%68 = load i8*, i8** %7
%69 = call i64 @string_has_ctrl_or_space(i8* %68)
%70 = icmp ne i64 %69, 0
br i1 %70, label %75, label %71
71: ; preds = %67
%72 = load i8*, i8** %7
%73 = call i64 @has_dotdot_after_at(i8* %72)
%74 = icmp ne i64 %73, 0
br i1 %74, label %75, label %79
75: ; preds = %71, %67, %59, %51, %46, %35
%76 = load i8*, i8** %7
%77 = call i32 @free(i8* %76)
store i8* null, i8** %7
%78 = load i32, i32* @EINVAL
store i32 %78, i32* @errno
br label %79
79: ; preds = %75, %71
br label %82
80: ; preds = %19, %12
%81 = load i32, i32* @EINVAL
store i32 %81, i32* @errno
br label %82
82: ; preds = %80, %79
br label %93
83: ; preds = %1
%84 = load i8*, i8** %3
%85 = call i64 @_gpgme_is_valid_mailbox(i8* %84)
%86 = icmp ne i64 %85, 0
br i1 %86, label %87, label %90
87: ; preds = %83
%88 = load i8*, i8** %3
%89 = call i8* @strdup(i8* %88)
store i8* %89, i8** %7
br label %92
90: ; preds = %83
%91 = load i32, i32* @EINVAL
store i32 %91, i32* @errno
br label %92
92: ; preds = %90, %87
br label %93
93: ; preds = %92, %82
%94 = load i8*, i8** %7
%95 = icmp ne i8* %94, null
br i1 %95, label %96, label %99
96: ; preds = %93
%97 = load i8*, i8** %7
%98 = call i8* @ascii_strlwr(i8* %97)
br label %100
99: ; preds = %93
br label %100
100: ; preds = %99, %96
%101 = phi i8* [ %98, %96 ], [ null, %99 ]
store i8* %101, i8** %2
br label %102
102: ; preds = %100, %34
%103 = load i8*, i8** %2
ret i8* %103
}

LLVM IR (-O2):
@EINVAL = global i32 0
@errno = global i32 0
define i8* @_gpgme_mailbox_from_userid(i8* %0) {
%2 = tail call i8* @strchr(i8* dereferenceable(1) %0, i8 signext 60)
%3 = icmp eq i8* %2, null
br i1 %3, label %38, label %4
4: ; preds = %1
%5 = getelementptr inbounds i8, i8* %2, i64 1
%6 = tail call i8* @strchr(i8* %5, i8 signext 62)
%7 = icmp ugt i8* %6, %5
br i1 %7, label %8, label %36
8: ; preds = %4
%9 = ptrtoint i8* %6 to i64
%10 = ptrtoint i8* %5 to i64
%11 = sub i64 %9, %10
%12 = add i64 %11, 1
%13 = tail call i8* @malloc(i64 %12)
%14 = icmp eq i8* %13, null
br i1 %14, label %49, label %15
15: ; preds = %8
%16 = tail call i32 @strncpy(i8* %13, i8* %5, i64 %11)
%17 = getelementptr inbounds i8, i8* %13, i64 %11
store i8 0, i8* %17
%18 = tail call i32 @string_count_chr(i8* %13, i8 signext 64)
%19 = icmp eq i32 %18, 1
br i1 %19, label %20, label %33
20: ; preds = %15
%21 = load i8, i8* %13
%22 = icmp eq i8 %21, 64
br i1 %22, label %33, label %23
23: ; preds = %20
%24 = add i64 %11, -1
%25 = getelementptr inbounds i8, i8* %13, i64 %24
%26 = load i8, i8* %25
switch i8 %26, label %27 [
i8 64, label %33
i8 46, label %33
]
27: ; preds = %23
%28 = tail call i64 @string_has_ctrl_or_space(i8* %13)
%29 = icmp eq i64 %28, 0
br i1 %29, label %30, label %33
30: ; preds = %27
%31 = tail call i64 @has_dotdot_after_at(i8* %13)
%32 = icmp eq i64 %31, 0
br i1 %32, label %46, label %33
33: ; preds = %23, %23, %30, %27, %20, %15
%34 = tail call i32 @free(i8* %13)
%35 = load i32, i32* @EINVAL
store i32 %35, i32* @errno
br label %49
36: ; preds = %4
%37 = load i32, i32* @EINVAL
store i32 %37, i32* @errno
br label %49
38: ; preds = %1
%39 = tail call i64 @_gpgme_is_valid_mailbox(i8* %0)
%40 = icmp eq i64 %39, 0
br i1 %40, label %41, label %43
41: ; preds = %38
%42 = load i32, i32* @EINVAL
store i32 %42, i32* @errno
br label %49
43: ; preds = %38
%44 = tail call i8* @strdup(i8* %0)
%45 = icmp eq i8* %44, null
br i1 %45, label %49, label %46
46: ; preds = %30, %43
%47 = phi i8* [ %44, %43 ], [ %13, %30 ]
%48 = tail call i8* @ascii_strlwr(i8* %47)
br label %49
49: ; preds = %41, %36, %33, %46, %43, %8
%50 = phi i8* [ null, %8 ], [ %48, %46 ], [ null, %43 ], [ null, %33 ], [ null, %36 ], [ null, %41 ]
ret i8* %50
}