// File: /workspace/github_c_makefile_star2_O3/hsjoihs[P]c-compiler/cpp.c
// Function: preprocess
struct Tokvec preprocess(const char *str,
                         struct Map2 /*<struct Vector<struct Token>*/ *def_map)
{
	const struct Tokvec t = read_all_tokens(str);
	const struct Token *src = t.v;

	int total_token_num = t.tok_num;
	int ifdef_depth = 0;

	struct Token *dst_initial = calloc(total_token_num, sizeof(struct Token));

	int dst_offset = 0;

	int flag = 1;
	while (1) {
		for (enum LineState s = LINE_HAS_JUST_STARTED;
		     flag == 0 || s != LINE_HAS_JUST_STARTED || src[0].kind != HASH;
		     dst_offset++, src++) {
			flag = 1;

			set_line_state(&s, src[0].kind);

			struct Map2 *used_map = init_map();
			replace_recursively(def_map, used_map, src,
			                    &dst_initial[dst_offset]);

			if (dst_initial[dst_offset].kind == END) {
				if (ifdef_depth) {
					fprintf(stderr, "insufficient number of `#endif`s.\n");
					exit(EXIT_FAILURE);
				}

				struct Tokvec u;
				u.tok_num = dst_offset + 1;
				u.v = dst_initial;

				return u;
			}
		}

		src++; /* HASH */

		consume_spaces(&src);

		if (src[0].kind == NEWLINE) { /* empty directive */
			src++;
			continue;
		}
		expect_and_consume(&src, IDENT_OR_RESERVED,
		                   "identifier after `#` for preprocessor directive");

		const char *directive = src[-1].ident_str;
		consume_spaces(&src);

		if (strcmp(directive, "define") == 0) {
			flag = handle_define(&src, def_map);
		} else if (strcmp(directive, "include") == 0) {
			/* dst_initial may be realloc'd; total_token_num could be modified
			 */
			handle_include(&dst_initial, &src, &dst_offset, def_map,
			               &total_token_num);
			flag = 1;
		} else if (strcmp(directive, "ifdef") == 0 ||
		           strcmp(directive, "ifndef") == 0) {
			flag = handle_ifdef(strcmp(directive, "ifdef") == 0, &src, def_map,
			                    &ifdef_depth);
		} else if (strcmp(directive, "endif") ==
		           0) { /* passes only when the #if(n)?def condition was
			               true. If false, it will be handled in
			               #if(n)?def.*/
			if (ifdef_depth < 1) {
				fprintf(stderr,
				        "mismatch of `#endif` directive was detected.\n");
				exit(EXIT_FAILURE);
			}

			ifdef_depth--;
			expect_and_consume(&src, NEWLINE, "newline after `#endif`");
			flag = 1;
		} else {
			unsupported("unknown directive");
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rsi, -0x50(%rbp)
callq 0xc354
movq %rdx, %r15
leaq -0x30(%rbp), %rcx
movq %rdx, (%rcx)
movq %rax, -0x58(%rbp)
movslq %eax, %rdi
movl $0x20, %esi
callq 0x10d0
movq %rax, %rbx
movl $0x1, %eax
movq $0x0, -0x48(%rbp)
xorl %r12d, %r12d
testl %eax, %eax
setne %cl
movq %r12, %r13
movq %rbx, -0x40(%rbp)
movslq %r13d, %r12
movl (%r15), %eax
testb $0x1, %cl
je 0xd350
cmpl $0x4b, %eax
je 0xd3bf
incl %r13d
movq %r12, %r14
shlq $0x5, %r14
addq %rbx, %r14
xorl %ebx, %ebx
cmpl $0x3, %eax
je 0xd375
cmpl $0x4c, %eax
je 0xd375
cmpl $0x4d, %eax
je 0xd377
movl $0x2, %ebx
jmp 0xd377
xorl %ebx, %ebx
callq 0xa40d
movq -0x30(%rbp), %rdx
movq -0x50(%rbp), %rdi
movq %rax, %rsi
movq %r14, %rcx
callq 0xd93c
cmpl $0x2, (%r14)
je 0xd8b1
incq %r12
movq -0x30(%rbp), %rax
leaq 0x20(%rax), %r15
movq %r15, -0x30(%rbp)
movl 0x20(%rax), %eax
movl %eax, %ecx
xorl $0x4b, %ecx
incl %r13d
addq $0x20, %r14
orl %ebx, %ecx
jne 0xd35f
movq -0x40(%rbp), %rbx
leaq 0x20(%r15), %rax
movq %rax, -0x30(%rbp)
movl 0x20(%r15), %ecx
cmpl $0x4d, %ecx
jne 0xd3e7
movl 0x20(%rax), %ecx
addq $0x20, %rax
cmpl $0x4d, %ecx
je 0xd3d0
movq %rax, -0x30(%rbp)
addq $-0x20, %rax
movq %rax, %r15
cmpl $0x4c, %ecx
jne 0xd3fe
addq $0x40, %r15
movq %r15, -0x30(%rbp)
movb $0x1, %cl
movq %r12, %r13
jmp 0xd340
leaq -0x30(%rbp), %rdi
movl $0x18, %esi
leaq 0x507f(%rip), %rdx      # 0x1248d
callq 0x9563
movq -0x30(%rbp), %rbx
movq -0x18(%rbx), %r14
movl (%rbx), %r15d
cmpl $0x4d, %r15d
jne 0xd436
movl 0x20(%rbx), %r15d
addq $0x20, %rbx
cmpl $0x4d, %r15d
je 0xd424
movq %rbx, -0x30(%rbp)
movq %r14, %rdi
leaq 0x507d(%rip), %rsi      # 0x124bd
callq 0x10e0
testl %eax, %eax
je 0xd4ea
movq %r14, %rdi
leaq 0x506d(%rip), %rsi      # 0x124c4
callq 0x10e0
testl %eax, %eax
je 0xd601
movq %r14, %rdi
leaq 0x505e(%rip), %rsi      # 0x124cc
callq 0x10e0
movl %eax, %r15d
leaq 0x51a4(%rip), %rdx      # 0x12621
testl %eax, %eax
je 0xd57f
movq %r14, %rdi
leaq 0x5043(%rip), %rsi      # 0x124d2
callq 0x10e0
leaq 0x51a0(%rip), %rdx      # 0x1263b
testl %eax, %eax
je 0xd57f
movq %r14, %rdi
leaq 0x502c(%rip), %rsi      # 0x124d9
callq 0x10e0
testl %eax, %eax
jne 0xd92b
movq -0x48(%rbp), %rax
testl %eax, %eax
movq -0x40(%rbp), %rbx
jle 0xd926
decl %eax
movq %rax, -0x48(%rbp)
leaq -0x30(%rbp), %rdi
movl $0x4c, %esi
leaq 0x502d(%rip), %rdx      # 0x1250d
callq 0x9563
jmp 0xd8a3
leaq -0x30(%rbp), %rdi
movl $0x18, %esi
leaq 0x503c(%rip), %rdx      # 0x12536
callq 0x9563
movq -0x30(%rbp), %rbx
movq -0x18(%rbx), %r14
movl (%rbx), %r13d
cmpl $0x4d, %r13d
je 0xd51b
cmpl $0x6, %r13d
jne 0xd52d
jmp 0xd90e
movl 0x20(%rbx), %r13d
addq $0x20, %rbx
cmpl $0x4d, %r13d
je 0xd51b
movq %rbx, -0x30(%rbp)
movl $0x1, %edi
movl $0x20, %esi
callq 0x10d0
movq %rax, %r15
leaq 0x20(%rbx), %rax
cmpl $0x4c, %r13d
jne 0xd6e6
movq %rax, -0x30(%rbp)
movl $0x4d, (%r15)
callq 0x5d33
movq %rax, %r13
movq %rax, %rdi
movq %r15, %rsi
callq 0x5d9b
movq -0x50(%rbp), %rdi
movq %r14, %rsi
movq %r13, %rdx
callq 0xa344
jmp 0xd73d
xorl %ebx, %ebx
testl %r15d, %r15d
sete %r13b
leaq -0x30(%rbp), %rdi
movl $0x18, %esi
callq 0x9563
movq -0x30(%rbp), %rax
movq -0x18(%rax), %r14
cmpl $0x4d, (%rax)
jne 0xd5b1
cmpl $0x4d, 0x20(%rax)
leaq 0x20(%rax), %rax
je 0xd5a3
movq %rax, -0x30(%rbp)
movb %r13b, %bl
testl %r15d, %r15d
leaq 0x50bc(%rip), %rdx      # 0x1267a
leaq 0x5091(%rip), %rax      # 0x12656
cmoveq %rax, %rdx
leaq -0x30(%rbp), %rdi
movl $0x4c, %esi
callq 0x9563
addq $-0x20, -0x30(%rbp)
movq -0x50(%rbp), %rdi
movq %r14, %rsi
callq 0xa3f8
cmpl %ebx, %eax
jne 0xd74b
movq -0x48(%rbp), %rax
incl %eax
movq %rax, -0x48(%rbp)
xorl %eax, %eax
jmp 0xd742
movq %rbx, -0x38(%rbp)
cmpl $0xd, %r15d
je 0xd8ed
leaq -0x38(%rbp), %rdi
movl $0x39, %esi
leaq 0x4f8c(%rip), %rdx      # 0x125ab
callq 0x9563
movq -0x38(%rbp), %rax
movq -0x10(%rax), %rdi
leaq 0x2c9b(%rip), %rsi      # 0x102ce
callq 0x1130
testq %rax, %rax
movq -0x40(%rbp), %rbx
je 0xd8f9
movq %rax, %rdi
callq 0xd23c
movq %rax, %rdi
movq -0x50(%rbp), %rsi
callq 0xd2ec
movq %rdx, %r14
movq -0x58(%rbp), %rcx
addl %eax, %ecx
addl $-0x2, %ecx
movq %rcx, -0x58(%rbp)
movslq %ecx, %rsi
shlq $0x5, %rsi
movq %rbx, %rdi
callq 0x1120
movq %rax, %rbx
cmpl $0x2, 0x20(%r14)
je 0xd6b5
movq %r12, %rax
shlq $0x5, %rax
addq %rbx, %rax
addq $0x40, %r14
xorl %ecx, %ecx
movups -0x20(%r14,%rcx), %xmm0
movups -0x10(%r14,%rcx), %xmm1
movups %xmm1, 0x10(%rax,%rcx)
movups %xmm0, (%rax,%rcx)
incq %r12
cmpl $0x2, (%r14,%rcx)
leaq 0x20(%rcx), %rcx
jne 0xd692
movq -0x38(%rbp), %rdi
movl (%rdi), %eax
cmpl $0x4d, %eax
jne 0xd6d0
movl 0x20(%rdi), %eax
addq $0x20, %rdi
cmpl $0x4d, %eax
je 0xd6c0
movq %rdi, -0x38(%rbp)
cmpl $0x4c, %eax
jne 0xd902
addq $0x20, %rdi
movq %rdi, -0x30(%rbp)
jmp 0xd8a3
cmpl $0x4c, (%rax)
jne 0xd91a
movups (%rbx), %xmm0
movups 0x10(%rbx), %xmm1
movups %xmm1, 0x10(%r15)
movups %xmm0, (%r15)
callq 0x5d33
movq %rax, %r13
movq %rax, %rdi
movq %r15, %rsi
callq 0x5d9b
movq -0x50(%rbp), %rdi
movq %r14, %rsi
movq %r13, %rdx
callq 0xa344
movq -0x30(%rbp), %rcx
leaq 0x20(%rcx), %rax
movq %rax, -0x30(%rbp)
xorl %eax, %eax
cmpl $0x4c, 0x20(%rcx)
jne 0xd742
addq $0x40, %rcx
movq %rcx, -0x30(%rbp)
movl $0x1, %eax
movq -0x40(%rbp), %rbx
jmp 0xd8a8
movl $0x1, %r13d
movq -0x30(%rbp), %r15
movq -0x40(%rbp), %rbx
movl (%r15), %eax
cmpl $0x4b, %eax
jne 0xd766
movq %r15, %rdx
jmp 0xd7a7
xorl %ecx, %ecx
cmpl $0x4b, %eax
jle 0xd779
cmpl $0x4d, %eax
je 0xd790
cmpl $0x4c, %eax
je 0xd77e
jmp 0xd78b
cmpl $0x3, %eax
jne 0xd782
xorl %ecx, %ecx
jmp 0xd790
cmpl $0x2, %eax
je 0xd8cd
movl $0x2, %ecx
leaq 0x20(%r15), %rdx
movl 0x20(%r15), %eax
movq %rdx, %r15
testl %ecx, %ecx
jne 0xd768
movq %rdx, %r15
cmpl $0x4b, %eax
jne 0xd768
leaq 0x20(%rdx), %rcx
movq %rcx, -0x38(%rbp)
movl 0x20(%rdx), %eax
cmpl $0x4d, %eax
jne 0xd7ce
movl 0x20(%rcx), %eax
addq $0x20, %rcx
cmpl $0x4d, %eax
je 0xd7b7
movq %rcx, -0x38(%rbp)
addq $-0x20, %rcx
movq %rcx, %rdx
addq $0x40, %rdx
movq %rdx, %r15
cmpl $0x4c, %eax
je 0xd759
leaq -0x38(%rbp), %rdi
movl $0x18, %esi
leaq 0x4c9f(%rip), %rdx      # 0x1248d
callq 0x9563
movq -0x38(%rbp), %r15
movq -0x18(%r15), %r14
movq %r14, %rdi
leaq 0x4cc7(%rip), %rsi      # 0x124cc
callq 0x10e0
testl %eax, %eax
je 0xd849
movq %r14, %rdi
leaq 0x4cba(%rip), %rsi      # 0x124d2
callq 0x10e0
testl %eax, %eax
je 0xd849
movq %r14, %rdi
leaq 0x4cae(%rip), %rsi      # 0x124d9
callq 0x10e0
movl (%r15), %ecx
testl %eax, %eax
je 0xd863
cmpl $0x4c, %ecx
je 0xd887
cmpl $0x4c, 0x20(%r15)
leaq 0x20(%r15), %r15
jne 0xd83c
jmp 0xd85d
incl %r13d
cmpl $0x4c, (%r15)
je 0xd887
cmpl $0x4c, 0x20(%r15)
leaq 0x20(%r15), %r15
jne 0xd852
movq %r15, -0x38(%rbp)
jmp 0xd887
cmpl $0x4d, %ecx
jne 0xd879
movl 0x20(%r15), %ecx
addq $0x20, %r15
cmpl $0x4d, %ecx
je 0xd868
movq %r15, -0x38(%rbp)
cmpl $0x4c, %ecx
jne 0xd890
cmpl $0x1, %r13d
je 0xd89f
decl %r13d
addq $0x20, %r15
jmp 0xd759
cmpl $0x2, %ecx
jne 0xd8de
cmpl $0x1, %r13d
jne 0xd937
movq %r15, -0x30(%rbp)
movl $0x1, %eax
movq -0x30(%rbp), %r15
jmp 0xd334
cmpl $0x0, -0x48(%rbp)
jne 0xd8d9
movl %r13d, %eax
movq -0x40(%rbp), %rdx
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq -0x38(%rbp), %rsi
movq %r15, %rdi
callq 0x22c2
callq 0x2272
leaq 0x4c28(%rip), %rsi      # 0x1250d
movq %r15, %rdi
callq 0x9478
leaq 0x4ca6(%rip), %rdi      # 0x1259a
callq 0x9581
leaq -0x38(%rbp), %rdi
callq 0x2315
leaq 0x4ce5(%rip), %rsi      # 0x125ee
callq 0x9478
leaq 0x4c3c(%rip), %rdi      # 0x12551
callq 0x9581
leaq 0x4c45(%rip), %rdi      # 0x12566
callq 0x9581
callq 0x229a
leaq 0x4bf2(%rip), %rdi      # 0x12524
callq 0x9581
callq 0x22ed