#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 */
struct servent {
  unsigned short s_port;
};

/* Variables and functions */
struct servent *getservbyname(char const *, char const *);
unsigned short htons(unsigned short);
long strtol(char *, char **, int /*<<< orphan*/);
unsigned short inet_service(const char *service, const char *proto) {
  unsigned short port = 0;
  char *endp;
  long temp;
  if (!service)
    return 0;
  temp = strtol((char *)service, &endp, 0);
  if (*endp == '\0' && temp > 0 && temp < 65536) {
    port = htons((unsigned short)temp);
  } else {
    struct servent *serv = getservbyname(service, proto);
    if (serv)
      port = serv->s_port;
  }
  return port;
}


x86 assembly (clang, -O0):
<inet_service>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
movw   $0x0,-0x1a(%rbp)
cmpq   $0x0,-0x10(%rbp)
jne    115c <inet_service+0x2c>
movw   $0x0,-0x2(%rbp)
jmp    11e1 <inet_service+0xb1>
mov    -0x10(%rbp),%rdi
lea    -0x28(%rbp),%rsi
xor    %edx,%edx
call   1050 <strtol@plt>
mov    %rax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
jne    11ad <inet_service+0x7d>
cmpq   $0x0,-0x30(%rbp)
jle    11ad <inet_service+0x7d>
cmpq   $0x10000,-0x30(%rbp)
jge    11ad <inet_service+0x7d>
mov    -0x30(%rbp),%rax
movzwl %ax,%edi
call   1030 <htons@plt>
mov    %ax,-0x1a(%rbp)
jmp    11d9 <inet_service+0xa9>
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1040 <getservbyname@plt>
mov    %rax,-0x38(%rbp)
cmpq   $0x0,-0x38(%rbp)
je     11d4 <inet_service+0xa4>
mov    -0x38(%rbp),%rax
mov    (%rax),%ax
mov    %ax,-0x1a(%rbp)
jmp    11d9 <inet_service+0xa9>
mov    -0x1a(%rbp),%ax
mov    %ax,-0x2(%rbp)
movzwl -0x2(%rbp),%eax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<inet_service>:
push   %r14
push   %rbx
push   %rax
test   %rdi,%rdi
je     1183 <inet_service+0x53>
mov    %rsi,%r14
mov    %rdi,%rbx
mov    %rsp,%rsi
xor    %edx,%edx
call   1050 <strtol@plt>
mov    (%rsp),%rcx
cmpb   $0x0,(%rcx)
jne    116e <inet_service+0x3e>
test   %rax,%rax
jle    116e <inet_service+0x3e>
cmp    $0xffff,%rax
jg     116e <inet_service+0x3e>
movzwl %ax,%edi
add    $0x8,%rsp
pop    %rbx
pop    %r14
jmp    1030 <htons@plt>
mov    %rbx,%rdi
mov    %r14,%rsi
call   1040 <getservbyname@plt>
test   %rax,%rax
je     1183 <inet_service+0x53>
movzwl (%rax),%eax
jmp    1185 <inet_service+0x55>
xor    %eax,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
%struct.servent = type { i16 }
define zeroext i16 @inet_service(i8* %0, i8* %1) {
%3 = alloca i16
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i16
%7 = alloca i8*
%8 = alloca i64
%9 = alloca %struct.servent*
store i8* %0, i8** %4
store i8* %1, i8** %5
store i16 0, i16* %6
%10 = load i8*, i8** %4
%11 = icmp ne i8* %10, null
br i1 %11, label %13, label %12
12: ; preds = %2
store i16 0, i16* %3
br label %43
13: ; preds = %2
%14 = load i8*, i8** %4
%15 = call i64 @strtol(i8* %14, i8** %7, i32 0)
store i64 %15, i64* %8
%16 = load i8*, i8** %7
%17 = load i8, i8* %16
%18 = sext i8 %17 to i32
%19 = icmp eq i32 %18, 0
br i1 %19, label %20, label %30
20: ; preds = %13
%21 = load i64, i64* %8
%22 = icmp sgt i64 %21, 0
br i1 %22, label %23, label %30
23: ; preds = %20
%24 = load i64, i64* %8
%25 = icmp slt i64 %24, 65536
br i1 %25, label %26, label %30
26: ; preds = %23
%27 = load i64, i64* %8
%28 = trunc i64 %27 to i16
%29 = call zeroext i16 @htons(i16 zeroext %28)
store i16 %29, i16* %6
br label %41
30: ; preds = %23, %20, %13
%31 = load i8*, i8** %4
%32 = load i8*, i8** %5
%33 = call %struct.servent* @getservbyname(i8* %31, i8* %32)
store %struct.servent* %33, %struct.servent** %9
%34 = load %struct.servent*, %struct.servent** %9
%35 = icmp ne %struct.servent* %34, null
br i1 %35, label %36, label %40
36: ; preds = %30
%37 = load %struct.servent*, %struct.servent** %9
%38 = getelementptr inbounds %struct.servent, %struct.servent* %37, i32 0, i32 0
%39 = load i16, i16* %38
store i16 %39, i16* %6
br label %40
40: ; preds = %36, %30
br label %41
41: ; preds = %40, %26
%42 = load i16, i16* %6
store i16 %42, i16* %3
br label %43
43: ; preds = %41, %12
%44 = load i16, i16* %3
ret i16 %44
}

LLVM IR (-O2):
%struct.servent = type { i16 }
define zeroext i16 @inet_service(i8* %0, i8* %1) {
%3 = alloca i8*
%4 = bitcast i8** %3 to i8*
%5 = icmp eq i8* %0, null
br i1 %5, label %24, label %6
6: ; preds = %2
%7 = call i64 @strtol(i8* %0, i8** %3, i32 0)
%8 = load i8*, i8** %3
%9 = load i8, i8* %8
%10 = icmp eq i8 %9, 0
%11 = icmp sgt i64 %7, 0
%12 = select i1 %10, i1 %11, i1 false
%13 = icmp slt i64 %7, 65536
%14 = select i1 %12, i1 %13, i1 false
br i1 %14, label %15, label %18
15: ; preds = %6
%16 = trunc i64 %7 to i16
%17 = tail call zeroext i16 @htons(i16 zeroext %16)
br label %24
18: ; preds = %6
%19 = tail call %struct.servent* @getservbyname(i8* %0, i8* %1)
%20 = icmp eq %struct.servent* %19, null
br i1 %20, label %24, label %21
21: ; preds = %18
%22 = getelementptr inbounds %struct.servent, %struct.servent* %19, i64 0, i32 0
%23 = load i16, i16* %22
br label %24
24: ; preds = %15, %21, %18, %2
%25 = phi i16 [ 0, %2 ], [ %17, %15 ], [ %23, %21 ], [ 0, %18 ]
ret i16 %25
}