// File: /workspace/github_c_makefile_star2_O0/System-Glitch[P]ESGILinter-C/src/parsing_functions.c
// Function: get_function_from_declaration
function_t *get_function_from_declaration(int line_index, char *line) {
	unsigned int star_count_type;
	unsigned int star_count_name;
	unsigned int type_sub_index;
	unsigned int length;
	unsigned int type_length;
	unsigned int type_start_index   = 0;
	unsigned int params_start_index = 0;
	unsigned int index              = 0;
	function_t *function = NULL;
	arraylist_t *params  = NULL;
	match_t *match_type  = NULL;
	char *tmp_name;
	char *tmp_params;
	char *name = NULL;
	char *type = NULL;
	char is_prototype;

	line = str_remove_comments(line);

	is_prototype = function_is_prototype(line);
	if(is_prototype == -1) {
		free(line);
		free(match_type);
		return NULL;
	}

	match_type = parse_type(line);
	if(match_type == NULL) {
		free(line);
		return NULL;
	}

	type = substr_match(line, *match_type);
	type_start_index = match_type->index_start;
	free(match_type);

	if(type != NULL) {

		type_length = strlen(type);
		tmp_name    = strsubstr(line, type_start_index + type_length, strlen(line) - type_length);
		length      = strlen(tmp_name);

		if(length > 0) {
			star_count_type = strcount(type, '*');
			type_sub_index  = strcountuntil(type, '*', 1, 1);

			//Remove stars
			type[type_length - type_sub_index] = '\0';

			//No array modifier in type

			if(strcount(type, '*')) { //Contains stars inside the type name -> invalid type
				free(tmp_name);
				free(type);
				free(line);
				return NULL;
			}

			name = parse_function_name(tmp_name, &star_count_name, &params_start_index);

			if(name != NULL) {

				index = params_start_index;
				//Find closing parenthesis
				while(tmp_name[index] != ')' && index < length) {
					index++;
				}

				if(tmp_name[index] != ')') { //Syntax error, no closing parenthesis found
					free(tmp_name);
					free(name);
					free(type);
					free(line);
					return NULL;
				}

				tmp_params = strsubstr(tmp_name, params_start_index, index - params_start_index);

				params = parse_function_parameters(tmp_params, is_prototype, line_index);
				free(tmp_params);
				free(tmp_name);

				if(params != NULL) {
					function = function_init(name, is_prototype, strduplicate(type), star_count_type + star_count_name, params, line_index);
				} else {
					free(line);
					return NULL;
				}
			} else {
				free(tmp_name);
				free(type);
				free(line);
				return NULL;
			}

		}

		free(type);
	}

	free(line);

	return function;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movl %edi, -0xc(%rbp)
movq %rsi, -0x18(%rbp)
movl $0x0, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
movl $0x0, -0x38(%rbp)
movq $0x0, -0x40(%rbp)
movq $0x0, -0x48(%rbp)
movq $0x0, -0x50(%rbp)
movq $0x0, -0x68(%rbp)
movq $0x0, -0x70(%rbp)
movq -0x18(%rbp), %rdi
callq 0xa2b0
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rdi
callq 0xf1e0
movb %al, -0x71(%rbp)
movsbl -0x71(%rbp), %eax
cmpl $-0x1, %eax
jne 0xef20
movq -0x18(%rbp), %rdi
callq 0x2030
movq -0x50(%rbp), %rdi
callq 0x2030
movq $0x0, -0x8(%rbp)
jmp 0xf1cf
movq -0x18(%rbp), %rdi
callq 0x8a90
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x50(%rbp)
jne 0xef4a
movq -0x18(%rbp), %rdi
callq 0x2030
movq $0x0, -0x8(%rbp)
jmp 0xf1cf
movq -0x18(%rbp), %rdi
movq -0x50(%rbp), %rax
movq (%rax), %rsi
callq 0xac10
movq %rax, -0x70(%rbp)
movq -0x50(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x30(%rbp)
movq -0x50(%rbp), %rdi
callq 0x2030
cmpq $0x0, -0x70(%rbp)
je 0xf1be
movq -0x70(%rbp), %rdi
callq 0x2090
movl %eax, -0x2c(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x80(%rbp)
movl -0x30(%rbp), %eax
addl -0x2c(%rbp), %eax
movl %eax, -0x78(%rbp)
movq -0x18(%rbp), %rdi
callq 0x2090
movq -0x80(%rbp), %rdi
movl -0x78(%rbp), %esi
movl -0x2c(%rbp), %ecx
subq %rcx, %rax
movl %eax, %edx
callq 0xa5e0
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rdi
callq 0x2090
movl %eax, -0x28(%rbp)
cmpl $0x0, -0x28(%rbp)
jbe 0xf1b5
movq -0x70(%rbp), %rdi
movl $0x2a, %esi
callq 0xa660
movl %eax, -0x1c(%rbp)
movq -0x70(%rbp), %rdi
movl $0x2a, %esi
movl $0x1, %ecx
movl %ecx, %edx
callq 0xa6d0
movl %eax, -0x24(%rbp)
movq -0x70(%rbp), %rax
movl -0x2c(%rbp), %ecx
subl -0x24(%rbp), %ecx
movl %ecx, %ecx
movb $0x0, (%rax,%rcx)
movq -0x70(%rbp), %rdi
movl $0x2a, %esi
callq 0xa660
cmpl $0x0, %eax
je 0xf043
movq -0x58(%rbp), %rdi
callq 0x2030
movq -0x70(%rbp), %rdi
callq 0x2030
movq -0x18(%rbp), %rdi
callq 0x2030
movq $0x0, -0x8(%rbp)
jmp 0xf1cf
movq -0x58(%rbp), %rdi
leaq -0x20(%rbp), %rsi
leaq -0x34(%rbp), %rdx
callq 0xf280
movq %rax, -0x68(%rbp)
cmpq $0x0, -0x68(%rbp)
je 0xf18e
movl -0x34(%rbp), %eax
movl %eax, -0x38(%rbp)
movq -0x58(%rbp), %rax
movl -0x38(%rbp), %ecx
movsbl (%rax,%rcx), %ecx
xorl %eax, %eax
cmpl $0x29, %ecx
movb %al, -0x81(%rbp)
je 0xf090
movl -0x38(%rbp), %eax
cmpl -0x28(%rbp), %eax
setb %al
movb %al, -0x81(%rbp)
movb -0x81(%rbp), %al
testb $0x1, %al
jne 0xf09c
jmp 0xf0a7
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0xf069
movq -0x58(%rbp), %rax
movl -0x38(%rbp), %ecx
movsbl (%rax,%rcx), %eax
cmpl $0x29, %eax
je 0xf0e8
movq -0x58(%rbp), %rdi
callq 0x2030
movq -0x68(%rbp), %rdi
callq 0x2030
movq -0x70(%rbp), %rdi
callq 0x2030
movq -0x18(%rbp), %rdi
callq 0x2030
movq $0x0, -0x8(%rbp)
jmp 0xf1cf
movq -0x58(%rbp), %rdi
movl -0x34(%rbp), %esi
movl -0x38(%rbp), %edx
subl -0x34(%rbp), %edx
callq 0xa5e0
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rdi
movb -0x71(%rbp), %al
movl -0xc(%rbp), %edx
movzbl %al, %esi
callq 0xf4e0
movq %rax, -0x48(%rbp)
movq -0x60(%rbp), %rdi
callq 0x2030
movq -0x58(%rbp), %rdi
callq 0x2030
cmpq $0x0, -0x48(%rbp)
je 0xf179
movq -0x68(%rbp), %rax
movq %rax, -0x90(%rbp)
movb -0x71(%rbp), %al
movb %al, -0x82(%rbp)
movq -0x70(%rbp), %rdi
callq 0xa550
movq -0x90(%rbp), %rdi
movb -0x82(%rbp), %cl
movq %rax, %rdx
movl -0x1c(%rbp), %eax
addl -0x20(%rbp), %eax
movq -0x48(%rbp), %r8
movl -0xc(%rbp), %r9d
movzbl %cl, %esi
movzbl %al, %ecx
callq 0xee00
movq %rax, -0x40(%rbp)
jmp 0xf18c
movq -0x18(%rbp), %rdi
callq 0x2030
movq $0x0, -0x8(%rbp)
jmp 0xf1cf
jmp 0xf1b3
movq -0x58(%rbp), %rdi
callq 0x2030
movq -0x70(%rbp), %rdi
callq 0x2030
movq -0x18(%rbp), %rdi
callq 0x2030
movq $0x0, -0x8(%rbp)
jmp 0xf1cf
jmp 0xf1b5
movq -0x70(%rbp), %rdi
callq 0x2030
movq -0x18(%rbp), %rdi
callq 0x2030
movq -0x40(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x90, %rsp
popq %rbp
retq
nopl (%rax)