// File: /workspace/github_c_makefile_star2_O2/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 0xb0dc
movq %rdx, %r15
leaq -0x30(%rbp), %rdi
movq %rdx, (%rdi)
movq %rax, -0x60(%rbp)
movslq %eax, %rdi
pushq $0x20
popq %rsi
callq 0x10d0
movq %rax, -0x58(%rbp)
pushq $0x1
popq %rax
movq $0x0, -0x48(%rbp)
xorl %ebx, %ebx
testl %eax, %eax
setne %al
movslq %ebx, %rbx
leal 0x1(%rbx), %r14d
movq %rbx, -0x40(%rbp)
movq %rbx, %r12
shlq $0x5, %r12
movq -0x58(%rbp), %rcx
leaq (%rcx,%r12), %r13
xorl %ebx, %ebx
movl (%r15), %ecx
testb $0x1, %al
je 0xc04d
testl %ebx, %ebx
jne 0xc04d
cmpl $0x4b, %ecx
je 0xc0a5
cmpl $0x3, %ecx
je 0xc061
cmpl $0x4c, %ecx
je 0xc061
cmpl $0x4d, %ecx
je 0xc063
pushq $0x2
popq %rbx
jmp 0xc063
xorl %ebx, %ebx
callq 0x9319
movq -0x30(%rbp), %rdx
movq -0x50(%rbp), %rdi
movq %rax, %rsi
movq %r13, %rcx
callq 0xc5a9
cmpl $0x2, (%r13)
je 0xc4ce
incq -0x40(%rbp)
movq -0x30(%rbp), %r15
addq $0x20, %r15
movq %r15, -0x30(%rbp)
incl %r14d
addq $0x20, %r13
addq $0x20, %r12
movb $0x1, %al
jmp 0xc03d
addq $0x20, %r15
movq %r15, -0x30(%rbp)
leaq -0x30(%rbp), %rbx
movq %rbx, %rdi
callq 0xc640
movq -0x30(%rbp), %r15
cmpl $0x4c, (%r15)
jne 0xc0d6
addq $0x20, %r15
movq %r15, -0x30(%rbp)
movb $0x1, %al
movq -0x40(%rbp), %rbx
jmp 0xc021
movq %rbx, %rdi
pushq $0x18
popq %r15
movl %r15d, %esi
leaq 0x53c6(%rip), %rdx      # 0x114ad
callq 0x8168
movq -0x30(%rbp), %rax
movq -0x18(%rax), %r14
movq %rbx, %rdi
callq 0xc640
movq %r14, %rdi
leaq 0x53d7(%rip), %rsi      # 0x114dd
callq 0x10e0
testl %eax, %eax
je 0xc1b7
movq %r14, %rdi
leaq 0x53c7(%rip), %rsi      # 0x114e4
callq 0x10e0
testl %eax, %eax
je 0xc295
movq %r14, %rdi
leaq 0x53b8(%rip), %rsi      # 0x114ec
callq 0x10e0
movl %eax, %r13d
leaq 0x5533(%rip), %r15      # 0x11676
leaq 0x54f7(%rip), %rdx      # 0x11641
testl %eax, %eax
je 0xc233
movq %r14, %rdi
leaq 0x5396(%rip), %rsi      # 0x114f2
callq 0x10e0
leaq 0x5532(%rip), %r15      # 0x1169a
leaq 0x54ec(%rip), %rdx      # 0x1165b
testl %eax, %eax
je 0xc233
movq %r14, %rdi
leaq 0x5378(%rip), %rsi      # 0x114f9
callq 0x10e0
testl %eax, %eax
jne 0xc585
movq -0x48(%rbp), %rax
testl %eax, %eax
jle 0xc591
decl %eax
movq %rax, -0x48(%rbp)
movq %rbx, %rdi
pushq $0x4c
popq %rsi
leaq 0x5380(%rip), %rdx      # 0x1152d
callq 0x8168
jmp 0xc4be
movq %rbx, %rdi
movl %r15d, %esi
leaq 0x5392(%rip), %rdx      # 0x11556
callq 0x8168
movq -0x30(%rbp), %rax
cmpl $0x6, (%rax)
je 0xc533
movq -0x18(%rax), %r14
movq %rbx, %rdi
callq 0xc640
pushq $0x1
popq %rdi
pushq $0x20
popq %rsi
callq 0x10d0
movq %rax, %r15
movq -0x30(%rbp), %rax
leaq 0x20(%rax), %rcx
cmpl $0x4c, (%rax)
jne 0xc361
movq %rcx, -0x30(%rbp)
movl $0x4d, (%r15)
callq 0x49f5
movq %rax, %r13
movq %rax, %rdi
movq %r15, %rsi
callq 0x4a57
movq -0x50(%rbp), %rdi
movq %r14, %rsi
movq %r13, %rdx
callq 0x9250
jmp 0xc4be
movq %rbx, %r12
xorl %ebx, %ebx
testl %r13d, %r13d
sete %bl
movq %r12, %rdi
pushq $0x18
popq %r13
movl %r13d, %esi
callq 0x8168
movq -0x30(%rbp), %rax
movq -0x18(%rax), %r14
movq %r12, %rdi
callq 0xc640
movq %r12, %rdi
pushq $0x4c
popq %rsi
movq %r15, %rdx
callq 0x8168
addq $-0x20, -0x30(%rbp)
movq -0x50(%rbp), %rdi
movq %r14, %rsi
callq 0x9304
cmpl %ebx, %eax
jne 0xc3c8
movq -0x48(%rbp), %rax
incl %eax
movq %rax, -0x48(%rbp)
xorl %eax, %eax
jmp 0xc4c1
movq -0x30(%rbp), %rax
movq %rax, -0x38(%rbp)
cmpl $0xd, (%rax)
je 0xc53f
leaq -0x38(%rbp), %rdi
pushq $0x39
popq %rsi
leaq 0x5317(%rip), %rdx      # 0x115cb
callq 0x8168
movq -0x38(%rbp), %rax
movq -0x10(%rax), %rdi
leaq 0x3026(%rip), %rsi      # 0xf2ee
callq 0x1130
testq %rax, %rax
movq -0x40(%rbp), %rbx
je 0xc54b
movq %rax, %rdi
callq 0xbf44
movq %rax, %rdi
movq -0x50(%rbp), %rsi
callq 0xbfd8
movq %rdx, %r14
movq -0x60(%rbp), %rcx
addl %eax, %ecx
addl $-0x2, %ecx
movq %rcx, -0x60(%rbp)
movslq %ecx, %rsi
shlq $0x5, %rsi
movq -0x58(%rbp), %rdi
callq 0x1120
addq $0x20, %r14
movq %rax, -0x58(%rbp)
addq %rax, %r12
xorl %eax, %eax
cmpl $0x2, (%r14,%rax)
je 0xc341
leaq (%r14,%rax), %rcx
movups (%rcx), %xmm0
movups 0x10(%rcx), %xmm1
movups %xmm1, 0x10(%r12,%rax)
movups %xmm0, (%r12,%rax)
incq %rbx
addq $0x20, %rax
jmp 0xc31b
leaq -0x38(%rbp), %rdi
callq 0xc640
movq -0x38(%rbp), %rdi
cmpl $0x4c, (%rdi)
jne 0xc56d
addq $0x20, %rdi
movq %rdi, -0x30(%rbp)
jmp 0xc3c0
cmpl $0x4c, (%rcx)
movq -0x40(%rbp), %rbx
jne 0xc579
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movups %xmm1, 0x10(%r15)
movups %xmm0, (%r15)
callq 0x49f5
movq %rax, %r13
movq %rax, %rdi
movq %r15, %rsi
callq 0x4a57
movq -0x50(%rbp), %rdi
movq %r14, %rsi
movq %r13, %rdx
callq 0x9250
movq -0x30(%rbp), %rcx
leaq 0x20(%rcx), %rax
movq %rax, -0x30(%rbp)
xorl %eax, %eax
cmpl $0x4c, 0x20(%rcx)
jne 0xc4c5
addq $0x40, %rcx
movq %rcx, -0x30(%rbp)
pushq $0x1
popq %rax
jmp 0xc4c5
movq -0x30(%rbp), %rax
pushq $0x1
popq %r15
leaq 0x50d6(%rip), %rbx      # 0x114ad
leaq -0x38(%rbp), %r12
xorl %ecx, %ecx
movl (%rax), %edx
testl %ecx, %ecx
jne 0xc405
cmpl $0x4b, %edx
jne 0xc405
addq $0x20, %rax
movq %rax, -0x38(%rbp)
movq %r12, %rdi
callq 0xc640
movq -0x38(%rbp), %rax
xorl %ecx, %ecx
cmpl $0x4c, (%rax)
je 0xc424
jmp 0xc42a
cmpl $0x3, %edx
je 0xc422
cmpl $0x4c, %edx
je 0xc422
cmpl $0x4d, %edx
je 0xc424
cmpl $0x2, %edx
je 0xc4ea
pushq $0x2
popq %rcx
jmp 0xc424
xorl %ecx, %ecx
addq $0x20, %rax
jmp 0xc3dd
movq %r12, %rdi
movl %r13d, %esi
movq %rbx, %rdx
callq 0x8168
movq -0x38(%rbp), %rax
movq -0x18(%rax), %r14
movq %r14, %rdi
leaq 0x50a2(%rip), %rsi      # 0x114ec
callq 0x10e0
testl %eax, %eax
je 0xc497
movq %r14, %rdi
leaq 0x5095(%rip), %rsi      # 0x114f2
callq 0x10e0
testl %eax, %eax
je 0xc497
movq %r14, %rdi
leaq 0x5089(%rip), %rsi      # 0x114f9
callq 0x10e0
testl %eax, %eax
jne 0xc49a
movq %r12, %rdi
callq 0xc640
movq -0x38(%rbp), %rdi
movl (%rdi), %eax
cmpl $0x4c, %eax
jne 0xc4af
cmpl $0x1, %r15d
je 0xc4ba
decl %r15d
jmp 0xc4a2
incl %r15d
movq %r12, %rdi
callq 0xc658
movq -0x38(%rbp), %rax
addq $0x20, %rax
jmp 0xc3db
cmpl $0x2, %eax
jne 0xc527
cmpl $0x1, %r15d
jne 0xc4ee
movq %rdi, -0x30(%rbp)
pushq $0x1
popq %rax
movq -0x40(%rbp), %rbx
movq -0x30(%rbp), %r15
jmp 0xc01c
cmpl $0x0, -0x48(%rbp)
jne 0xc503
movl %r14d, %eax
movq -0x58(%rbp), %rdx
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, -0x38(%rbp)
movq 0x9b03(%rip), %rax      # 0x15ff8
movq (%rax), %rcx
leaq 0x51c0(%rip), %rdi      # 0x116bf
pushq $0x21
jmp 0xc516
movq 0x9aee(%rip), %rax      # 0x15ff8
movq (%rax), %rcx
leaq 0x4f76(%rip), %rdi      # 0x1148a
pushq $0x22
popq %rsi
pushq $0x1
popq %rdx
callq 0x1180
pushq $0x1
popq %rdi
callq 0x1170
leaq 0x4fff(%rip), %rsi      # 0x1152d
callq 0x8084
leaq 0x5037(%rip), %rdi      # 0x11571
callq 0x8186
leaq 0x5074(%rip), %rdi      # 0x115ba
callq 0x8186
movq 0x9aa6(%rip), %rax      # 0x15ff8
movq (%rax), %rdi
movq -0x38(%rbp), %rax
movq -0x10(%rax), %rdx
leaq 0x507d(%rip), %rsi      # 0x115e1
xorl %eax, %eax
callq 0x10f0
jmp 0xc51f
leaq 0x509a(%rip), %rsi      # 0x1160e
callq 0x8084
leaq 0x5006(%rip), %rdi      # 0x11586
callq 0x8186
leaq 0x4fb8(%rip), %rdi      # 0x11544
callq 0x8186
movq 0x9a60(%rip), %rax      # 0x15ff8
movq (%rax), %rcx
leaq 0x4f5d(%rip), %rdi      # 0x114ff
pushq $0x2d
jmp 0xc516