// File: /workspace/github_c_makefile_star2_O2/ShinyaKato[P]skcc/preprocess.c
// Function: define_directive
void define_directive(struct preprocessor *pp) {
  struct macro_entry *macro = allocate_macro_entry();

  macro->identifier = expect_pp_token(pp, PP_IDENT)->text->head;

  if(check_pp_token(pp, PP_SPACE) || check_pp_token(pp, PP_NEW_LINE)) {
    macro->type = MACRO_OBJECT;
    remove_white_space(pp);
  } else if(check_pp_token(pp, PP_LPAREN)) {
    macro->type = MACRO_FUNCTION;
    macro->parameter_size = 0;

    skip_pp_token_with_space(pp);

    if(check_pp_token(pp, PP_RPAREN)) {
      macro->parameter_ellipsis = 0;
      skip_pp_token_with_space(pp);
    } else {
      while(1) {
        if(check_pp_token(pp, PP_IDENT)) {
          if(macro->parameter_size == MACRO_PARAMS_LIMIT) {
            error("too many macro parameters.\n");
          }

          struct pp_token *token = read_pp_token_with_space(pp);
          macro->parameters[macro->parameter_size++] = token->text;

          if(check_pp_token(pp, PP_COMMA)) {
            skip_pp_token_with_space(pp);
          } else if(check_pp_token(pp, PP_RPAREN)) {
            macro->parameter_ellipsis = 0;
            skip_pp_token_with_space(pp);
            break;
          } else {
            unexpected_pp_token(pp);
          }
        } else if(check_pp_token(pp, PP_ELLIPSIS)) {
          skip_pp_token_with_space(pp);

          struct string *va_args = allocate_string();
          write_string(va_args, "__VA_ARGS__");
          macro->parameters[macro->parameter_size] = va_args;
          macro->parameter_ellipsis = 1;

          if(check_pp_token(pp, PP_RPAREN)) {
            skip_pp_token_with_space(pp);
            break;
          } else {
            unexpected_pp_token(pp);
          }
        }
        else {
          unexpected_pp_token(pp);
        }
      }
    }
  } else {
    unexpected_pp_token(pp);
  }

  while(!check_pp_token(pp, PP_NEW_LINE)) {
    struct pp_token *token = read_pp_token(pp);
    append_pp_list(macro->replacement_list, token);
  }

  discard_new_line(pp);

  if(macro->type == MACRO_FUNCTION && !check_stringify_operator(macro)) {
    error("invalid # operator.\n");
  }
  if(!check_concat_operator(macro)) {
    error("invalid ## operator.\n");
  }

  insert_macro_table(macro);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %r14
callq 0x3301
movq %rax, %rbx
pushq $0x1
popq %rsi
movq %r14, %rdi
callq 0x4065
movq 0x10(%rax), %rax
movq (%rax), %rax
movq %rax, 0x8(%rbx)
pushq $0x3c
popq %rsi
movq %r14, %rdi
callq 0x3ffb
testl %eax, %eax
jne 0x51b9
pushq $0x3b
popq %rsi
movq %r14, %rdi
callq 0x3ffb
testl %eax, %eax
je 0x525d
andl $0x0, (%rbx)
movq %r14, %rdi
callq 0x404a
pushq $0x3b
popq %rbp
movq %r14, %rdi
movl %ebp, %esi
callq 0x3ffb
testl %eax, %eax
jne 0x51ee
movq %r14, %rdi
callq 0x3fcd
movq 0x418(%rbx), %rdi
movq %rax, %rsi
callq 0x32b4
jmp 0x51c7
movq %r14, %rdi
callq 0x40a7
cmpl $0x1, (%rbx)
jne 0x5221
movq %rbx, %rdi
callq 0x50da
testl %eax, %eax
jne 0x5221
leaq 0x1d02(%rip), %rdi      # 0x6f10
leaq 0x1ed5(%rip), %rdx      # 0x70ea
movl $0x47d, %esi            # imm = 0x47D
xorl %eax, %eax
callq 0x1252
movq %rbx, %rdi
callq 0x5136
testl %eax, %eax
jne 0x5247
leaq 0x1cdc(%rip), %rdi      # 0x6f10
leaq 0x1ec4(%rip), %rdx      # 0x70ff
movl $0x480, %esi            # imm = 0x480
xorl %eax, %eax
callq 0x1252
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3445
pushq $0x7
popq %rsi
movq %r14, %rdi
callq 0x3ffb
testl %eax, %eax
je 0x529e
movl $0x1, (%rbx)
andl $0x0, 0x10(%rbx)
movq %r14, %rdi
callq 0x40db
pushq $0x8
popq %rsi
movq %r14, %rdi
callq 0x3ffb
testl %eax, %eax
je 0x52d2
andl $0x0, 0x14(%rbx)
movq %r14, %rdi
callq 0x40db
jmp 0x51c4
movq %r14, %rdi
callq 0x3fcd
movl (%rax), %ecx
shlq $0x5, %rcx
addq 0x4d2d(%rip), %rcx      # 0x9fe0
leaq 0x1c56(%rip), %rdi      # 0x6f10
leaq 0x1df9(%rip), %rdx      # 0x70ba
movl $0x472, %esi            # imm = 0x472
xorl %eax, %eax
callq 0x1252
jmp 0x51c4
pushq $0x1
popq %rbp
leaq 0x1c34(%rip), %r12      # 0x6f10
leaq 0x1dd7(%rip), %r13      # 0x70ba
xorl %r15d, %r15d
movl %r15d, %eax
movq %rax, (%rsp)
pushq $0xc
popq %r15
movq %r14, %rdi
movl %ebp, %esi
callq 0x3ffb
testl %eax, %eax
jne 0x53ac
movq %r14, %rdi
movl %r15d, %esi
callq 0x3ffb
movq %r14, %rdi
testl %eax, %eax
jne 0x533b
callq 0x3fcd
movl (%rax), %ecx
shlq $0x5, %rcx
addq 0x4cb9(%rip), %rcx      # 0x9fe0
movq %r12, %rdi
movl $0x46d, %esi            # imm = 0x46D
movq %r13, %rdx
xorl %eax, %eax
callq 0x1252
jmp 0x52f1
callq 0x40db
xorl %eax, %eax
callq 0x1904
movq %rax, %r15
movq %rax, %rdi
leaq 0x1d8a(%rip), %rsi      # 0x70de
callq 0x19b2
movq (%rsp), %rax
movq %r15, 0x18(%rbx,%rax,8)
movl $0x1, 0x14(%rbx)
movq %r14, %rdi
pushq $0x8
popq %rsi
callq 0x3ffb
testl %eax, %eax
jne 0x5291
movq %r14, %rdi
callq 0x3fcd
movl (%rax), %ecx
shlq $0x5, %rcx
addq 0x4c4f(%rip), %rcx      # 0x9fe0
movq %r12, %rdi
movl $0x469, %esi            # imm = 0x469
movq %r13, %rdx
xorl %eax, %eax
callq 0x1252
pushq $0xc
popq %r15
jmp 0x52f1
cmpl $0x7f, (%rsp)
jne 0x53c8
movq %r12, %rdi
movl $0x44e, %esi            # imm = 0x44E
leaq 0x1cdd(%rip), %rdx      # 0x709e
xorl %eax, %eax
callq 0x1252
movq %r14, %rdi
callq 0x40b9
movq 0x10(%rax), %rax
movq (%rsp), %rcx
leal 0x1(%rcx), %r15d
movl %r15d, 0x10(%rbx)
movq %rax, 0x18(%rbx,%rcx,8)
movq %r14, %rdi
pushq $0xd
popq %rsi
callq 0x3ffb
movq %r14, %rdi
testl %eax, %eax
je 0x5401
callq 0x40db
jmp 0x52e6
pushq $0x8
popq %rsi
callq 0x3ffb
testl %eax, %eax
jne 0x528d
movq %r14, %rdi
callq 0x3fcd
movl (%rax), %ecx
shlq $0x5, %rcx
addq 0x4bba(%rip), %rcx      # 0x9fe0
movq %r12, %rdi
movl $0x45b, %esi            # imm = 0x45B
movq %r13, %rdx
xorl %eax, %eax
callq 0x1252
jmp 0x52e6