// File: /workspace/github_c_makefile_star2_O2/wkoszek[P]mini_gzip/mini_gzip_testprog.c
// Function: main
int
main(int argc, char **argv)
{
	struct mini_gzip gz;
	struct stat st;
	char	in_fn[MAX_PATH_LEN], out_fn[MAX_PATH_LEN];
	char	*sptr, *mem_in, *mem_out;
	int	level, flag_c, o, in_fd, out_fd, ret, is_gzipped, out_len;

	level = 6;
	flag_c = 0;
	while ((o = getopt(argc, argv, "cd123456789")) != -1) {
		switch (o) {
		case 'd':
			level = 0;
			break;
		case 'c':
			flag_c = 1;
			break;
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			assert(o != '0');
			level = o - '0';
			break;
		default:
			abort();
			break;
		}
	}
	
	argc -= optind;
	argv += optind;

	GZAS(argc == 2, "2 file names must be passed: input and output file");

	is_gzipped = 0;
	sptr = strstr(argv[0], ".gz");
	if (sptr != NULL) {
		is_gzipped = 1;
	}
	printf("flag_c: %d is_gzipped: %d\n", flag_c, is_gzipped);

	if (is_gzipped) {
		GZAS(flag_c == 0, "Requesting to compress .gz file? Looks wrong");
	} else {
		GZAS(flag_c == 1, "Requesting to decompress normal file?");
	}

	snprintf(in_fn, sizeof(in_fn) - 1, "%s", argv[0]);
	snprintf(out_fn, sizeof(out_fn) - 1, "%s", argv[1]);

	printf("in_fn: %s out_fn: %s level %d\n", in_fn, out_fn, level);

	mem_in = calloc(1024*1024, 1);
	mem_out = calloc(1024*1024, 1);
	GZAS(mem_in != NULL, "Couldn't allocate memory for input file");
	GZAS(mem_out != NULL, "Couldn't allocate memory for output file");

	in_fd = open(in_fn, O_RDONLY);
	GZAS(in_fd != -1, "Couldn't open file %s for reading", in_fn);
	ret = fstat(in_fd, &st);
	GZAS(ret == 0, "Couldn't call fstat(), %d returned", ret);
	ret = read(in_fd, mem_in, st.st_size);
	GZAS(ret == st.st_size, "Read only %d bytes, %jd expected", ret,
							(uintmax_t)st.st_size);
	out_fd = open(out_fn, O_WRONLY|O_CREAT, st.st_mode);
	GZAS(out_fd != -1, "Couldn't create output file '%s' for writing",
								out_fn);

	if (flag_c) {
		abort();
#if 0
		mini_gz_init(&gz);
		printf("COMP\n");
		out_len = mini_gz_pack(&gz, level, mem_in, st.st_size, mem_out,
								1024*1024);
		printf("out_len = %d\n", out_len);
		ret = write(out_fd, mem_out, out_len);
		printf("ret = %d\n", ret);
		GZAS(ret == out_len, "Wrote only %d bytes, expected %d", ret, out_len);
#endif
	} else {
		printf("--- testing decompression --\n");
		ret = mini_gz_start(&gz, mem_in, st.st_size);
		GZAS(ret == 0, "mini_gz_start() failed, ret=%d", ret);
		out_len = mini_gz_unpack(&gz, mem_out, 1024*1024);
		printf("out_len = %d\n", out_len);
		ret = write(out_fd, mem_out, out_len);
		printf("ret = %d\n", ret);
		GZAS(ret == out_len, "Wrote only %d bytes, expected %d", ret, out_len);
	}
	close(in_fd);
	close(out_fd);

	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x8f8, %rsp            # imm = 0x8F8
movq %rsi, %r14
movl %edi, %r15d
pushq $0x6
popq %rbx
xorl %ebp, %ebp
movb $0x1, %al
movl %eax, 0xc(%rsp)
leaq 0x5bf1(%rip), %r12      # 0x7116
pushq $0x1
popq %r13
movl %ebx, %ecx
movl %ecx, %ebx
movl %r15d, %edi
movq %r14, %rsi
movq %r12, %rdx
callq 0x1120
leal -0x31(%rax), %ecx
cmpl $0x9, %ecx
jae 0x154a
addl $-0x30, %eax
movl %eax, %ecx
jmp 0x152b
xorl %ecx, %ecx
cmpl $0x64, %eax
je 0x152b
cmpl $-0x1, %eax
je 0x156c
cmpl $0x63, %eax
jne 0x16e7
movl $0x0, 0xc(%rsp)
movl %r13d, %ebp
jmp 0x1529
movq 0x9a6d(%rip), %rax      # 0xafe0
movslq (%rax), %r15
movq (%r14,%r15,8), %rdi
leaq 0x5bd6(%rip), %rsi      # 0x7157
callq 0x1140
xorl %edx, %edx
testq %rax, %rax
setne %dl
leaq 0x5bc6(%rip), %rdi      # 0x715b
movl %ebp, %esi
xorl %eax, %eax
callq 0x1070
movq (%r14,%r15,8), %rcx
leaq 0x5bcd(%rip), %r12      # 0x7176
leaq 0x4f0(%rsp), %r13
movl $0x3ff, %esi            # imm = 0x3FF
movq %r13, %rdi
movq %r12, %rdx
xorl %eax, %eax
callq 0x1080
movq 0x8(%r14,%r15,8), %rcx
leaq 0xf0(%rsp), %r15
movl $0x3ff, %esi            # imm = 0x3FF
movq %r15, %rdi
movq %r12, %rdx
xorl %eax, %eax
callq 0x1080
leaq 0x5b90(%rip), %rdi      # 0x7179
movq %r13, %rsi
movq %r15, %rdx
movl %ebx, %ecx
xorl %eax, %eax
callq 0x1070
pushq $0x1
popq %rbx
movl $0x100000, %edi         # imm = 0x100000
movq %rbx, %rsi
callq 0x10d0
movq %rax, %r12
movl $0x100000, %edi         # imm = 0x100000
movq %rbx, %rsi
callq 0x10d0
movq %rax, %r14
movq %r13, %rdi
xorl %esi, %esi
xorl %eax, %eax
callq 0x1110
movl %eax, %ebx
leaq 0x60(%rsp), %rbp
movl %eax, %edi
movq %rbp, %rsi
callq 0x1130
movq 0x30(%rbp), %r13
movl %ebx, %edi
movq %r12, %rsi
movq %r13, %rdx
callq 0x10c0
movl 0x18(%rbp), %edx
pushq $0x41
popq %rsi
movq %r15, %rdi
xorl %eax, %eax
callq 0x1110
testb $0x1, 0xc(%rsp)
je 0x1709
movl %eax, %ebp
leaq 0x5b43(%rip), %rdi      # 0x71b0
callq 0x1050
leaq 0x10(%rsp), %r15
movq %r15, %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0x124c
movl $0x100000, %edx         # imm = 0x100000
movq %r15, %rdi
movq %r14, %rsi
callq 0x1398
movl %eax, %r15d
leaq 0x5af9(%rip), %rdi      # 0x7198
movl %eax, %esi
xorl %eax, %eax
callq 0x1070
movslq %r15d, %rdx
movl %ebp, %edi
movq %r14, %rsi
callq 0x1060
leaq 0x5aea(%rip), %rdi      # 0x71a6
movl %eax, %esi
xorl %eax, %eax
callq 0x1070
movl %ebx, %edi
callq 0x10b0
movl %ebp, %edi
callq 0x10b0
xorl %eax, %eax
addq $0x8f8, %rsp            # imm = 0x8F8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x30, %eax
jne 0x1709
leaq 0x5a2f(%rip), %rdi      # 0x7122
leaq 0x5a31(%rip), %rsi      # 0x712b
leaq 0x5a3f(%rip), %rcx      # 0x7140
pushq $0x2e
popq %rdx
callq 0x1090
callq 0x1040
nop