// File: /workspace/github_c_makefile_star2_O0/ShinyaKato[P]skcc/preprocess.c
// Function: scan_macro
struct pp_list *scan_macro(struct preprocessor *pp, struct pp_list *list) {
  struct pp_list *result = allocate_pp_list();

  for(struct pp_node *node = list->head; node != NULL; node = node->next) {
    struct macro_entry *macro = search_macro_table(node->token->text->head);

    // object-like macro invocation
    if(check_object_macro_invocation(pp, node)) {
      struct macro_entry *macro = search_macro_table(node->token->text->head);
      struct pp_list *list = object_macro_invocation(pp, macro);
      concat_pp_list(result, list);
    }

    // function-like macro invocation
    else if(check_function_macro_invocation(pp, node)) {
      struct macro_entry *macro = search_macro_table(node->token->text->head);
      struct pp_list *args[MACRO_PARAMS_LIMIT];
      int args_count = 0;
      int level = 0;
      int valid = 0;

      node = node->next;
      if(node->token->type == PP_NEW_LINE || node->token->type == PP_SPACE) {
        node = node->next;
      }
      node = node->next;

      if(node != NULL && (node->token->type == PP_NEW_LINE || node->token->type == PP_SPACE)) {
        node = node->next;
      }

      // parse arguments
      if(node != NULL && node->token->type == PP_RPAREN) {
        valid = 1;
      } else if(node != NULL) {
        args[args_count] = allocate_pp_list();
        if(macro->parameter_size > 0) {
          for(; node != NULL; node = node->next) {
            struct pp_token *token = node->token;
            if(token->type == PP_LPAREN) {
              append_pp_list(args[args_count], token);
              level++;
            } else if(token->type == PP_RPAREN) {
              if(level == 0) {
                args_count++;
                valid = 1;
                break;
              }
              append_pp_list(args[args_count], token);
              level--;
            } else if(level == 0 && token->type == PP_COMMA) {
              args_count++;
              args[args_count] = allocate_pp_list();
              if(args_count == macro->parameter_size) {
                if(macro->parameter_ellipsis && !valid) {
                  node = node->next;
                  break;
                } else {
                  error("too many arguments.\n");
                }
                break;
              }
            } else {
              append_pp_list(args[args_count], node->token);
            }
          }
        }
        if(macro->parameter_ellipsis && !valid) {
          for(; node != NULL; node = node->next) {
            if(node->token->type == PP_RPAREN) {
              break;
            }
            append_pp_list(args[args_count], node->token);
          }
          args_count++;
          valid = 1;
        }
      }

      if(!valid) {
        error("macro arguments list is not terminated.\n");
      }

      for(int i = 0; i < args_count; i++) {
        if(args[i]->head == NULL) {
          continue;
        }
        if(args[i]->head->token->type == PP_NEW_LINE || args[i]->head->token->type == PP_SPACE) {
          args[i]->head = args[i]->head->next;
        }
        if(args[i]->head != NULL) {
          struct pp_node **arg_node = &(args[i]->head);
          for(; (*arg_node)->next != NULL; arg_node = &((*arg_node)->next));
          if((*arg_node)->token->type == PP_NEW_LINE || (*arg_node)->token->type == PP_SPACE) {
            *arg_node = NULL;
          }
        }
      }

      struct pp_list *list = function_macro_invocation(pp, macro, args, args_count);
      concat_pp_list(result, list);
    }

    // not replaced
    else {
      append_pp_list(result, node->token);
    }
  }

  return result;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x470, %rsp            # imm = 0x470
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
callq 0x53b0
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x612e
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq 0x10(%rax), %rax
movq (%rax), %rdi
callq 0x59c0
movq %rax, -0x28(%rbp)
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x5a70
cmpl $0x0, %eax
je 0x5c95
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq 0x10(%rax), %rax
movq (%rax), %rdi
callq 0x59c0
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x6140
movq %rax, -0x38(%rbp)
movq -0x18(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x54d0
jmp 0x611b
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x5b00
cmpl $0x0, %eax
je 0x6109
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq 0x10(%rax), %rax
movq (%rax), %rdi
callq 0x59c0
movq %rax, -0x40(%rbp)
movl $0x0, -0x444(%rbp)
movl $0x0, -0x448(%rbp)
movl $0x0, -0x44c(%rbp)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rax
cmpl $0x3b, (%rax)
je 0x5d04
movq -0x20(%rbp), %rax
movq (%rax), %rax
cmpl $0x3c, (%rax)
jne 0x5d10
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x5d47
movq -0x20(%rbp), %rax
movq (%rax), %rax
cmpl $0x3b, (%rax)
je 0x5d3b
movq -0x20(%rbp), %rax
movq (%rax), %rax
cmpl $0x3c, (%rax)
jne 0x5d47
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x5d69
movq -0x20(%rbp), %rax
movq (%rax), %rax
cmpl $0x8, (%rax)
jne 0x5d69
movl $0x1, -0x44c(%rbp)
jmp 0x5f82
cmpq $0x0, -0x20(%rbp)
je 0x5f80
callq 0x53b0
movq %rax, %rcx
movslq -0x444(%rbp), %rax
movq %rcx, -0x440(%rbp,%rax,8)
movq -0x40(%rbp), %rax
cmpl $0x0, 0x10(%rax)
jle 0x5f12
jmp 0x5d9b
cmpq $0x0, -0x20(%rbp)
je 0x5f10
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x458(%rbp)
movq -0x458(%rbp), %rax
cmpl $0x7, (%rax)
jne 0x5def
movslq -0x444(%rbp), %rax
movq -0x440(%rbp,%rax,8), %rdi
movq -0x458(%rbp), %rsi
callq 0x5460
movl -0x448(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x448(%rbp)
jmp 0x5efd
movq -0x458(%rbp), %rax
cmpl $0x8, (%rax)
jne 0x5e51
cmpl $0x0, -0x448(%rbp)
jne 0x5e22
movl -0x444(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x444(%rbp)
movl $0x1, -0x44c(%rbp)
jmp 0x5f10
movslq -0x444(%rbp), %rax
movq -0x440(%rbp,%rax,8), %rdi
movq -0x458(%rbp), %rsi
callq 0x5460
movl -0x448(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x448(%rbp)
jmp 0x5efb
cmpl $0x0, -0x448(%rbp)
jne 0x5ede
movq -0x458(%rbp), %rax
cmpl $0xd, (%rax)
jne 0x5ede
movl -0x444(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x444(%rbp)
callq 0x53b0
movq %rax, %rcx
movslq -0x444(%rbp), %rax
movq %rcx, -0x440(%rbp,%rax,8)
movl -0x444(%rbp), %eax
movq -0x40(%rbp), %rcx
cmpl 0x10(%rcx), %eax
jne 0x5edc
movq -0x40(%rbp), %rax
cmpl $0x0, 0x14(%rax)
je 0x5ec0
cmpl $0x0, -0x44c(%rbp)
jne 0x5ec0
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
jmp 0x5f10
leaq 0x4af8(%rip), %rdi      # 0xa9bf
movl $0xf2, %esi
leaq 0x4b1a(%rip), %rdx      # 0xa9ed
movb $0x0, %al
callq 0x1280
jmp 0x5f10
jmp 0x5ef9
movslq -0x444(%rbp), %rax
movq -0x440(%rbp,%rax,8), %rdi
movq -0x20(%rbp), %rax
movq (%rax), %rsi
callq 0x5460
jmp 0x5efb
jmp 0x5efd
jmp 0x5eff
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
jmp 0x5d9b
jmp 0x5f12
movq -0x40(%rbp), %rax
cmpl $0x0, 0x14(%rax)
je 0x5f7e
cmpl $0x0, -0x44c(%rbp)
jne 0x5f7e
jmp 0x5f27
cmpq $0x0, -0x20(%rbp)
je 0x5f65
movq -0x20(%rbp), %rax
movq (%rax), %rax
cmpl $0x8, (%rax)
jne 0x5f3c
jmp 0x5f65
movslq -0x444(%rbp), %rax
movq -0x440(%rbp,%rax,8), %rdi
movq -0x20(%rbp), %rax
movq (%rax), %rsi
callq 0x5460
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
jmp 0x5f27
movl -0x444(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x444(%rbp)
movl $0x1, -0x44c(%rbp)
jmp 0x5f80
jmp 0x5f82
cmpl $0x0, -0x44c(%rbp)
jne 0x5fa5
leaq 0x4a2d(%rip), %rdi      # 0xa9bf
movl $0x108, %esi            # imm = 0x108
leaq 0x4a64(%rip), %rdx      # 0xaa02
movb $0x0, %al
callq 0x1280
movl $0x0, -0x45c(%rbp)
movl -0x45c(%rbp), %eax
cmpl -0x444(%rbp), %eax
jge 0x60d6
movslq -0x45c(%rbp), %rax
movq -0x440(%rbp,%rax,8), %rax
cmpq $0x0, (%rax)
jne 0x5fdb
jmp 0x60c2
movslq -0x45c(%rbp), %rax
movq -0x440(%rbp,%rax,8), %rax
movq (%rax), %rax
movq (%rax), %rax
cmpl $0x3b, (%rax)
je 0x600f
movslq -0x45c(%rbp), %rax
movq -0x440(%rbp,%rax,8), %rax
movq (%rax), %rax
movq (%rax), %rax
cmpl $0x3c, (%rax)
jne 0x6037
movslq -0x45c(%rbp), %rax
movq -0x440(%rbp,%rax,8), %rax
movq (%rax), %rax
movq 0x8(%rax), %rcx
movslq -0x45c(%rbp), %rax
movq -0x440(%rbp,%rax,8), %rax
movq %rcx, (%rax)
movslq -0x45c(%rbp), %rax
movq -0x440(%rbp,%rax,8), %rax
cmpq $0x0, (%rax)
je 0x60c0
movslq -0x45c(%rbp), %rax
movq -0x440(%rbp,%rax,8), %rax
movq %rax, -0x468(%rbp)
movq -0x468(%rbp), %rax
movq (%rax), %rax
cmpq $0x0, 0x8(%rax)
je 0x608c
jmp 0x6075
movq -0x468(%rbp), %rax
movq (%rax), %rax
addq $0x8, %rax
movq %rax, -0x468(%rbp)
jmp 0x6062
movq -0x468(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
cmpl $0x3b, (%rax)
je 0x60b0
movq -0x468(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
cmpl $0x3c, (%rax)
jne 0x60be
movq -0x468(%rbp), %rax
movq $0x0, (%rax)
jmp 0x60c0
jmp 0x60c2
movl -0x45c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x45c(%rbp)
jmp 0x5faf
movq -0x8(%rbp), %rdi
movq -0x40(%rbp), %rsi
leaq -0x440(%rbp), %rdx
movl -0x444(%rbp), %ecx
callq 0x61e0
movq %rax, -0x470(%rbp)
movq -0x18(%rbp), %rdi
movq -0x470(%rbp), %rsi
callq 0x54d0
jmp 0x6119
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rax
movq (%rax), %rsi
callq 0x5460
jmp 0x611b
jmp 0x611d
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
jmp 0x5c27
movq -0x18(%rbp), %rax
addq $0x470, %rsp            # imm = 0x470
popq %rbp
retq
nopl (%rax,%rax)