// File: /workspace/github_c_makefile_star2_O0/koendv[P]stm32duino-raspberrypi/Arduino_Tools/src/stm32flash/parsers/hex.c
// Function: hex_open
parser_err_t hex_open(void *storage, const char *filename, const char write) {
	hex_t *st = storage;
	if (write) {
		return PARSER_ERR_RDONLY;
	} else {
		char mark;
		int fd;
		uint8_t checksum;
		unsigned int c, i;
		uint32_t base = 0;
		unsigned int last_address = 0x0;

		fd = open(filename, O_RDONLY);
		if (fd < 0)
			return PARSER_ERR_SYSTEM;

		/* read in the file */

		while(read(fd, &mark, 1) != 0) {
			if (mark == '\n' || mark == '\r') continue;
			if (mark != ':')
				return PARSER_ERR_INVALID_FILE;

			char buffer[9];
			unsigned int reclen, address, type;
			uint8_t *record = NULL;

			/* get the reclen, address, and type */
			buffer[8] = 0;
			if (read(fd, &buffer, 8) != 8) return PARSER_ERR_INVALID_FILE;
			if (sscanf(buffer, "%2x%4x%2x", &reclen, &address, &type) != 3) {
				close(fd);
				return PARSER_ERR_INVALID_FILE;
			}

			/* setup the checksum */
			checksum =
				reclen +
				((address & 0xFF00) >> 8) +
				((address & 0x00FF) >> 0) +
				type;

			switch(type) {
				/* data record */
				case 0:
					c = address - last_address;
					st->data = realloc(st->data, st->data_len + c + reclen);

					/* if there is a gap, set it to 0xff and increment the length */
					if (c > 0) {
						memset(&st->data[st->data_len], 0xff, c);
						st->data_len += c;
					}

					last_address = address + reclen;
					record = &st->data[st->data_len];
					st->data_len += reclen;
					break;

				/* extended segment address record */
				case 2:
					base = 0;
					break;

				/* extended linear address record */
				case 4:
					base = 0;
					break;
			}

			buffer[2] = 0;
			for(i = 0; i < reclen; ++i) {
				if (read(fd, &buffer, 2) != 2 || sscanf(buffer, "%2x", &c) != 1) {
					close(fd);
					return PARSER_ERR_INVALID_FILE;
				}

				/* add the byte to the checksum */
				checksum += c;

				switch(type) {
					case 0:
						if (record != NULL) {
							record[i] = c;
						} else {
							return PARSER_ERR_INVALID_FILE;
						}
						break;

					case 2:
					case 4:
						base = (base << 8) | c;
						break;
				}
			}

			/* read, scan, and verify the checksum */
			if (
				read(fd, &buffer, 2 ) != 2 ||
				sscanf(buffer, "%2x", &c) != 1 ||
				(uint8_t)(checksum + c) != 0x00
			) {
				close(fd);
				return PARSER_ERR_INVALID_FILE;
			}

			switch(type) {
				/* EOF */
				case 1:
					close(fd);
					return PARSER_ERR_OK;

				/* address record */
				case 4:	base = base << 12;
					/* fall-through */
				case 2: base = base << 4;
					/* Reset last_address since our base changed */
					last_address = 0;

					/* Only assign the program's base address once, and only
					 * do so if we haven't seen any data records yet.
					 * If there are any data records before address records,
					 * the program's base address must be zero.
					 */
					if (st->base == 0 && st->data_len == 0) {
						st->base = base;
						break;
					}

					/* we cant cope with files out of order */
					if (base < st->base) {
						close(fd);
						return PARSER_ERR_INVALID_FILE;
					}

					/* if there is a gap, enlarge and fill with 0xff */
					unsigned int len = base - st->base;
					if (len > st->data_len) {
						st->data = realloc(st->data, len);
						memset(&st->data[st->data_len], 0xff, len - st->data_len);
						st->data_len = len;
					}
					break;
			}
		}

		close(fd);
		return PARSER_ERR_OK;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movb %dl, %al
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movb %al, -0x19(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x28(%rbp)
cmpb $0x0, -0x19(%rbp)
je 0x93d2
movl $0x4, -0x4(%rbp)
jmp 0x97c2
movl $0x0, -0x40(%rbp)
movl $0x0, -0x44(%rbp)
movq -0x18(%rbp), %rdi
xorl %esi, %esi
movb $0x0, %al
callq 0x2220
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
jge 0x9402
movl $0x1, -0x4(%rbp)
jmp 0x97c2
jmp 0x9404
movl -0x30(%rbp), %edi
leaq -0x29(%rbp), %rsi
movl $0x1, %edx
callq 0x2130
cmpq $0x0, %rax
je 0x97b3
movsbl -0x29(%rbp), %eax
cmpl $0xa, %eax
je 0x9431
movsbl -0x29(%rbp), %eax
cmpl $0xd, %eax
jne 0x9433
jmp 0x9404
movsbl -0x29(%rbp), %eax
cmpl $0x3a, %eax
je 0x9448
movl $0x2, -0x4(%rbp)
jmp 0x97c2
movq $0x0, -0x68(%rbp)
movb $0x0, -0x45(%rbp)
movl -0x30(%rbp), %edi
leaq -0x4d(%rbp), %rsi
movl $0x8, %edx
callq 0x2130
cmpq $0x8, %rax
je 0x9477
movl $0x2, -0x4(%rbp)
jmp 0x97c2
leaq -0x4d(%rbp), %rdi
leaq 0x30ca(%rip), %rsi      # 0xc54c
leaq -0x54(%rbp), %rdx
leaq -0x58(%rbp), %rcx
leaq -0x5c(%rbp), %r8
movb $0x0, %al
callq 0x21d0
cmpl $0x3, %eax
je 0x94ae
movl -0x30(%rbp), %edi
callq 0x2120
movl $0x2, -0x4(%rbp)
jmp 0x97c2
movl -0x54(%rbp), %eax
movl -0x58(%rbp), %ecx
movl %ecx, %edx
shrl $0x8, %edx
addl %edx, %eax
addl %ecx, %eax
movl -0x5c(%rbp), %ecx
addl %ecx, %eax
movb %al, -0x31(%rbp)
movl -0x5c(%rbp), %eax
movl %eax, -0x70(%rbp)
testl %eax, %eax
je 0x94f0
jmp 0x94d1
movl -0x70(%rbp), %eax
subl $0x2, %eax
je 0x9584
jmp 0x94df
movl -0x70(%rbp), %eax
subl $0x4, %eax
je 0x958d
jmp 0x9594
movl -0x58(%rbp), %eax
subl -0x44(%rbp), %eax
movl %eax, -0x38(%rbp)
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x28(%rbp), %rax
movq (%rax), %rsi
movl -0x38(%rbp), %eax
addq %rax, %rsi
movl -0x54(%rbp), %eax
addq %rax, %rsi
callq 0x21e0
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x10(%rax)
cmpl $0x0, -0x38(%rbp)
jbe 0x9557
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x28(%rbp), %rax
addq (%rax), %rdi
movl -0x38(%rbp), %eax
movl %eax, %edx
movl $0xff, %esi
callq 0x2100
movl -0x38(%rbp), %eax
movl %eax, %ecx
movq -0x28(%rbp), %rax
addq (%rax), %rcx
movq %rcx, (%rax)
movl -0x58(%rbp), %eax
addl -0x54(%rbp), %eax
movl %eax, -0x44(%rbp)
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x28(%rbp), %rcx
addq (%rcx), %rax
movq %rax, -0x68(%rbp)
movl -0x54(%rbp), %eax
movl %eax, %ecx
movq -0x28(%rbp), %rax
addq (%rax), %rcx
movq %rcx, (%rax)
jmp 0x9594
movl $0x0, -0x40(%rbp)
jmp 0x9594
movl $0x0, -0x40(%rbp)
movb $0x0, -0x4b(%rbp)
movl $0x0, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x54(%rbp), %eax
jae 0x965f
movl -0x30(%rbp), %edi
leaq -0x4d(%rbp), %rsi
movl $0x2, %edx
callq 0x2130
cmpq $0x2, %rax
jne 0x95dd
leaq -0x4d(%rbp), %rdi
leaq 0x27eb(%rip), %rsi      # 0xbdb8
leaq -0x38(%rbp), %rdx
movb $0x0, %al
callq 0x21d0
cmpl $0x1, %eax
je 0x95f1
movl -0x30(%rbp), %edi
callq 0x2120
movl $0x2, -0x4(%rbp)
jmp 0x97c2
movl -0x38(%rbp), %ecx
movzbl -0x31(%rbp), %eax
addl %ecx, %eax
movb %al, -0x31(%rbp)
movl -0x5c(%rbp), %eax
movl %eax, -0x74(%rbp)
testl %eax, %eax
je 0x961d
jmp 0x9609
movl -0x74(%rbp), %eax
subl $0x2, %eax
je 0x9643
jmp 0x9613
movl -0x74(%rbp), %eax
subl $0x4, %eax
je 0x9643
jmp 0x964f
cmpq $0x0, -0x68(%rbp)
je 0x9635
movl -0x38(%rbp), %eax
movb %al, %dl
movq -0x68(%rbp), %rax
movl -0x3c(%rbp), %ecx
movb %dl, (%rax,%rcx)
jmp 0x9641
movl $0x2, -0x4(%rbp)
jmp 0x97c2
jmp 0x964f
movl -0x40(%rbp), %eax
shll $0x8, %eax
orl -0x38(%rbp), %eax
movl %eax, -0x40(%rbp)
jmp 0x9651
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x959f
movl -0x30(%rbp), %edi
leaq -0x4d(%rbp), %rsi
movl $0x2, %edx
callq 0x2130
cmpq $0x2, %rax
jne 0x96a0
leaq -0x4d(%rbp), %rdi
leaq 0x2737(%rip), %rsi      # 0xbdb8
leaq -0x38(%rbp), %rdx
movb $0x0, %al
callq 0x21d0
cmpl $0x1, %eax
jne 0x96a0
movzbl -0x31(%rbp), %eax
addl -0x38(%rbp), %eax
movzbl %al, %eax
cmpl $0x0, %eax
je 0x96b4
movl -0x30(%rbp), %edi
callq 0x2120
movl $0x2, -0x4(%rbp)
jmp 0x97c2
movl -0x5c(%rbp), %eax
movl %eax, -0x78(%rbp)
subl $0x1, %eax
je 0x96d8
jmp 0x96c1
movl -0x78(%rbp), %eax
subl $0x2, %eax
je 0x96f5
jmp 0x96cb
movl -0x78(%rbp), %eax
subl $0x4, %eax
je 0x96ec
jmp 0x97ae
movl -0x30(%rbp), %edi
callq 0x2120
movl $0x0, -0x4(%rbp)
jmp 0x97c2
movl -0x40(%rbp), %eax
shll $0xc, %eax
movl %eax, -0x40(%rbp)
movl -0x40(%rbp), %eax
shll $0x4, %eax
movl %eax, -0x40(%rbp)
movl $0x0, -0x44(%rbp)
movq -0x28(%rbp), %rax
cmpl $0x0, 0x18(%rax)
jne 0x9728
movq -0x28(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x9728
movl -0x40(%rbp), %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0x18(%rax)
jmp 0x97ae
movl -0x40(%rbp), %eax
movq -0x28(%rbp), %rcx
cmpl 0x18(%rcx), %eax
jae 0x9745
movl -0x30(%rbp), %edi
callq 0x2120
movl $0x2, -0x4(%rbp)
jmp 0x97c2
movl -0x40(%rbp), %eax
movq -0x28(%rbp), %rcx
subl 0x18(%rcx), %eax
movl %eax, -0x6c(%rbp)
movl -0x6c(%rbp), %eax
movq -0x28(%rbp), %rcx
cmpq (%rcx), %rax
jbe 0x97ac
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rdi
movl -0x6c(%rbp), %eax
movl %eax, %esi
callq 0x21e0
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x28(%rbp), %rax
addq (%rax), %rdi
movl -0x6c(%rbp), %eax
movl %eax, %edx
movq -0x28(%rbp), %rax
subq (%rax), %rdx
movl $0xff, %esi
callq 0x2100
movl -0x6c(%rbp), %eax
movl %eax, %ecx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
jmp 0x97ae
jmp 0x9404
movl -0x30(%rbp), %edi
callq 0x2120
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x80, %rsp
popq %rbp
retq
nop