// File: /workspace/github_c_makefile_star2_O1/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 $0x48, %rsp
movq %rsi, -0x48(%rbp)
callq 0xc2e4
leaq -0x30(%rbp), %rcx
movq %rdx, (%rcx)
movq %rax, -0x60(%rbp)
movslq %eax, %rdi
movl $0x20, %esi
callq 0x10d0
movq %rax, -0x50(%rbp)
movq $0x0, -0x40(%rbp)
xorl %ebx, %ebx
xorl %eax, %eax
movslq %ebx, %rbx
leal 0x1(%rbx), %r14d
movq %rbx, %r13
shlq $0x5, %r13
movq -0x50(%rbp), %rcx
leaq (%rcx,%r13), %r15
xorl %r12d, %r12d
testl %r12d, %r12d
setne %cl
orb %al, %cl
testb $0x1, %cl
jne 0xd38d
movq -0x30(%rbp), %rax
cmpl $0x4b, (%rax)
je 0xd406
movq -0x30(%rbp), %rax
movl (%rax), %eax
cmpl $0x3, %eax
je 0xd3a2
cmpl $0x4d, %eax
je 0xd3ad
cmpl $0x4c, %eax
jne 0xd3a7
xorl %r12d, %r12d
jmp 0xd3ad
movl $0x2, %r12d
callq 0xa39e
movq -0x30(%rbp), %rdx
movq -0x48(%rbp), %rdi
movq %rax, %rsi
movq %r15, %rcx
callq 0xd93a
movl (%r15), %eax
cmpl $0x2, %eax
jne 0xd3e3
movl %r14d, -0x54(%rbp)
movq -0x50(%rbp), %rcx
movq %rcx, -0x68(%rbp)
cmpl $0x0, -0x40(%rbp)
jne 0xd8da
cmpl $0x2, %eax
je 0xd402
incq %rbx
addq $0x20, -0x30(%rbp)
incl %r14d
addq $0x20, %r15
addq $0x20, %r13
xorl %eax, %eax
jmp 0xd377
xorl %eax, %eax
jmp 0xd408
movb $0x1, %al
testb %al, %al
je 0xd8bb
movq -0x30(%rbp), %rcx
leaq 0x20(%rcx), %rax
movq %rax, -0x30(%rbp)
cmpl $0x4d, 0x20(%rcx)
jne 0xd430
cmpl $0x4d, 0x20(%rax)
leaq 0x20(%rax), %rax
je 0xd422
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpl $0x4c, (%rax)
je 0xd61d
leaq -0x30(%rbp), %rdi
movl $0x18, %esi
leaq 0x518b(%rip), %rdx      # 0x125d8
callq 0x94af
movq -0x30(%rbp), %rax
movq -0x18(%rax), %r15
cmpl $0x4d, (%rax)
leaq -0x38(%rbp), %r14
jne 0xd471
cmpl $0x4d, 0x20(%rax)
leaq 0x20(%rax), %rax
je 0xd463
movq %rax, -0x30(%rbp)
movq %r15, %rdi
leaq 0x518d(%rip), %rsi      # 0x12608
callq 0x10e0
testl %eax, %eax
je 0xd55e
movq %r15, %rdi
leaq 0x517d(%rip), %rsi      # 0x1260f
callq 0x10e0
testl %eax, %eax
je 0xd79b
movq %r15, %rdi
leaq 0x516e(%rip), %rsi      # 0x12617
callq 0x10e0
movl %eax, %r13d
leaq 0x52b4(%rip), %rdx      # 0x1276c
testl %eax, %eax
je 0xd4da
movq %r15, %rdi
leaq 0x5157(%rip), %rsi      # 0x1261d
callq 0x10e0
leaq 0x52b4(%rip), %rdx      # 0x12786
testl %eax, %eax
jne 0xd878
xorl %r14d, %r14d
testl %r13d, %r13d
sete %r12b
leaq -0x30(%rbp), %rdi
movl $0x18, %esi
callq 0x94af
movq -0x30(%rbp), %rax
movq -0x18(%rax), %r15
cmpl $0x4d, (%rax)
jne 0xd50d
cmpl $0x4d, 0x20(%rax)
leaq 0x20(%rax), %rax
je 0xd4ff
movq %rax, -0x30(%rbp)
movb %r12b, %r14b
testl %r13d, %r13d
leaq 0x52ab(%rip), %rdx      # 0x127c5
leaq 0x5280(%rip), %rax      # 0x127a1
cmoveq %rax, %rdx
leaq -0x30(%rbp), %rdi
movl $0x4c, %esi
callq 0x94af
addq $-0x20, -0x30(%rbp)
movq -0x48(%rbp), %rdi
movq %r15, %rsi
callq 0xa389
cmpl %r14d, %eax
jne 0xd62a
movq -0x40(%rbp), %rax
incl %eax
movq %rax, -0x40(%rbp)
movb $0x1, %al
jmp 0xd35e
leaq -0x30(%rbp), %rdi
movl $0x18, %esi
leaq 0x5113(%rip), %rdx      # 0x12681
callq 0x94af
movq -0x30(%rbp), %rax
movq -0x18(%rax), %r14
movl (%rax), %ecx
cmpl $0x4d, %ecx
je 0xd58c
cmpl $0x6, %ecx
jne 0xd59a
jmp 0xd8f0
cmpl $0x4d, 0x20(%rax)
leaq 0x20(%rax), %rax
je 0xd58c
movq %rax, -0x30(%rbp)
movl $0x1, %edi
movl $0x20, %esi
callq 0x10d0
movq %rax, %r15
movq -0x30(%rbp), %rax
leaq 0x20(%rax), %rcx
cmpl $0x4c, (%rax)
je 0xd769
cmpl $0x4c, (%rcx)
jne 0xd8fc
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movups %xmm1, 0x10(%r15)
movups %xmm0, (%r15)
callq 0x5b39
movq %rax, %r12
movq %rax, %rdi
movq %r15, %rsi
callq 0x5ba7
movq -0x48(%rbp), %rdi
movq %r14, %rsi
movq %r12, %rdx
callq 0xa2d8
movq -0x30(%rbp), %rcx
leaq 0x20(%rcx), %rax
movq %rax, -0x30(%rbp)
movb $0x1, %al
cmpl $0x4c, 0x20(%rcx)
jne 0xd35e
addq $0x40, %rcx
movq %rcx, -0x30(%rbp)
jmp 0xd35c
addq $0x20, %rax
movq %rax, -0x30(%rbp)
jmp 0xd35c
movl $0x1, %r13d
movq -0x30(%rbp), %rdi
leaq -0x38(%rbp), %r12
xorl %eax, %eax
testl %eax, %eax
jne 0xd66b
cmpl $0x4b, (%rdi)
jne 0xd66b
leaq 0x20(%rdi), %rcx
movq %rcx, -0x38(%rbp)
cmpl $0x4d, 0x20(%rdi)
jne 0xd65f
cmpl $0x4d, 0x20(%rcx)
leaq 0x20(%rcx), %rcx
je 0xd651
movq %rcx, -0x38(%rbp)
xorl %eax, %eax
cmpl $0x4c, (%rcx)
movq %rcx, %rdi
je 0xd68e
jmp 0xd694
movl (%rdi), %ecx
cmpl $0x3, %ecx
je 0xd67c
cmpl $0x4d, %ecx
je 0xd685
cmpl $0x4c, %ecx
jne 0xd680
xorl %eax, %eax
jmp 0xd685
movl $0x2, %eax
cmpl $0x2, %ecx
je 0xd8d1
addq $0x20, %rdi
jmp 0xd63a
movq %r12, %rdi
movl $0x18, %esi
leaq 0x4f35(%rip), %rdx      # 0x125d8
callq 0x94af
movq -0x38(%rbp), %r14
movq -0x18(%r14), %r15
movq %r15, %rdi
leaq 0x4f5d(%rip), %rsi      # 0x12617
callq 0x10e0
testl %eax, %eax
je 0xd6fe
movq %r15, %rdi
leaq 0x4f50(%rip), %rsi      # 0x1261d
callq 0x10e0
testl %eax, %eax
je 0xd6fe
movq %r15, %rdi
leaq 0x4f44(%rip), %rsi      # 0x12624
callq 0x10e0
movl (%r14), %ecx
testl %eax, %eax
je 0xd718
cmpl $0x4c, %ecx
je 0xd740
cmpl $0x4c, 0x20(%r14)
leaq 0x20(%r14), %r14
jne 0xd6f1
jmp 0xd712
incl %r13d
cmpl $0x4c, (%r14)
je 0xd740
cmpl $0x4c, 0x20(%r14)
leaq 0x20(%r14), %r14
jne 0xd707
movq %r14, -0x38(%rbp)
jmp 0xd740
cmpl $0x4d, %ecx
jne 0xd72c
cmpl $0x4d, 0x20(%r14)
leaq 0x20(%r14), %r14
je 0xd71d
movq %r14, -0x38(%rbp)
movq -0x38(%rbp), %rdi
movl (%rdi), %eax
cmpl $0x4c, %eax
jne 0xd74d
cmpl $0x1, %r13d
je 0xd760
decl %r13d
movq -0x38(%rbp), %rdi
addq $0x20, %rdi
jmp 0xd638
cmpl $0x2, %eax
jne 0xd8df
cmpl $0x1, %r13d
jne 0xd8eb
movq %rdi, -0x30(%rbp)
jmp 0xd35c
movq %rcx, -0x30(%rbp)
movl $0x4d, (%r15)
callq 0x5b39
movq %rax, %r12
movq %rax, %rdi
movq %r15, %rsi
callq 0x5ba7
movq -0x48(%rbp), %rdi
movq %r14, %rsi
movq %r12, %rdx
callq 0xa2d8
jmp 0xd35c
movq -0x30(%rbp), %rax
movq %rax, -0x38(%rbp)
cmpl $0xd, (%rax)
je 0xd908
movq %r14, %rdi
movl $0x39, %esi
leaq 0x4f3b(%rip), %rdx      # 0x126f6
callq 0x94af
movq -0x38(%rbp), %rax
movq -0x10(%rax), %rdi
leaq 0x2b2f(%rip), %rsi      # 0x102fe
callq 0x1130
testq %rax, %rax
je 0xd914
movq %rax, %rdi
callq 0xd26c
movq %rax, %rdi
movq -0x48(%rbp), %rsi
callq 0xd31c
movq %rdx, %r15
movq -0x60(%rbp), %rcx
addl %eax, %ecx
addl $-0x2, %ecx
movq %rcx, -0x60(%rbp)
movslq %ecx, %rsi
shlq $0x5, %rsi
movq -0x50(%rbp), %rdi
callq 0x1120
cmpl $0x2, 0x20(%r15)
movq %rax, -0x50(%rbp)
je 0xd84b
addq %rax, %r13
addq $0x40, %r15
xorl %eax, %eax
movups -0x20(%r15,%rax), %xmm0
movups -0x10(%r15,%rax), %xmm1
movups %xmm1, 0x10(%r13,%rax)
movups %xmm0, (%r13,%rax)
incq %rbx
cmpl $0x2, (%r15,%rax)
leaq 0x20(%rax), %rax
jne 0xd825
movq -0x38(%rbp), %rax
cmpl $0x4d, (%rax)
jne 0xd862
cmpl $0x4d, 0x20(%rax)
leaq 0x20(%rax), %rax
je 0xd854
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
cmpl $0x4c, (%rdi)
jne 0xd91d
addq $0x20, %rdi
jmp 0xd760
movq %r15, %rdi
leaq 0x4da2(%rip), %rsi      # 0x12624
callq 0x10e0
testl %eax, %eax
jne 0xd929
movq -0x40(%rbp), %rax
testl %eax, %eax
jle 0xd935
decl %eax
movq %rax, -0x40(%rbp)
leaq -0x30(%rbp), %rdi
movl $0x4c, %esi
leaq 0x4da7(%rip), %rdx      # 0x12658
callq 0x94af
jmp 0xd35c
movl -0x54(%rbp), %eax
movq -0x68(%rbp), %rdx
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq -0x38(%rbp), %rsi
callq 0x22c5
callq 0x2275
leaq 0x4d72(%rip), %rsi      # 0x12658
callq 0x93c4
callq 0x22f0
leaq 0x4da5(%rip), %rdi      # 0x1269c
callq 0x94cd
leaq 0x4dae(%rip), %rdi      # 0x126b1
callq 0x94cd
leaq 0x4dd6(%rip), %rdi      # 0x126e5
callq 0x94cd
leaq -0x38(%rbp), %rdi
callq 0x2318
leaq 0x4e15(%rip), %rsi      # 0x12739
callq 0x93c4
leaq 0x4d3f(%rip), %rdi      # 0x1266f
callq 0x94cd
callq 0x229d