// File: /workspace/github_c_makefile_star2_O2/samtools[P]htslib/hts.c
// Function: hts_hopen
htsFile *hts_hopen(hFILE *hfile, const char *fn, const char *mode)
{
    hFILE *hfile_orig = hfile;
    hFILE *hfile_cleanup = hfile;
    htsFile *fp = (htsFile*)calloc(1, sizeof(htsFile));
    char simple_mode[101], *cp, *opts;
    simple_mode[100] = '\0';

    if (fp == NULL) goto error;

    fp->fn = strdup(fn);
    fp->is_be = ed_is_big();

    // Split mode into simple_mode,opts strings
    if ((cp = strchr(mode, ','))) {
        strncpy(simple_mode, mode, cp-mode <= 100 ? cp-mode : 100);
        simple_mode[cp-mode] = '\0';
        opts = cp+1;
    } else {
        strncpy(simple_mode, mode, 100);
        opts = NULL;
    }

    if (strchr(simple_mode, 'r')) {
        const int max_loops = 5; // Should be plenty
        int loops = 0;
        if (hts_detect_format2(hfile, fn, &fp->format) < 0) goto error;

        // Deal with formats that re-direct an underlying file via a plug-in.
        // Loops as we may have crypt4gh served via htsget, or
        // crypt4gh-in-crypt4gh.

        while (fp->format.format == htsget ||
               fp->format.format == hts_crypt4gh_format) {
            // Ensure we don't get stuck in an endless redirect loop
            if (++loops > max_loops) {
                errno = ELOOP;
                goto error;
            }

            if (fp->format.format == htsget) {
                hFILE *hfile2 = hopen_htsget_redirect(hfile, simple_mode);
                if (hfile2 == NULL) goto error;

                if (hfile != hfile_cleanup) {
                    // Close the result of an earlier redirection
                    hclose_abruptly(hfile);
                }

                hfile = hfile2;
            }
            else if (fp->format.format == hts_crypt4gh_format) {
                int should_preserve = (hfile == hfile_orig);
                int update_cleanup = (hfile == hfile_cleanup);
                if (hts_crypt4gh_redirect(fn, simple_mode, &hfile, fp) < 0)
                    goto error;
                if (should_preserve) {
                    // The original hFILE is now contained in a crypt4gh
                    // wrapper.  Should we need to close the wrapper due
                    // to a later error, we need to prevent the wrapped
                    // handle from being closed as the caller will see
                    // this function return NULL and try to clean up itself.
                    hfile_orig->preserve = 1;
                }
                if (update_cleanup) {
                    // Update handle to close at the end if redirected by htsget
                    hfile_cleanup = hfile;
                }
            }

            // Re-detect format against the result of the redirection
            if (hts_detect_format2(hfile, fn, &fp->format) < 0) goto error;
        }
    }
    else if (strchr(simple_mode, 'w') || strchr(simple_mode, 'a')) {
        htsFormat *fmt = &fp->format;
        fp->is_write = 1;

        if (strchr(simple_mode, 'b')) fmt->format = binary_format;
        else if (strchr(simple_mode, 'c')) fmt->format = cram;
        else if (strchr(simple_mode, 'f')) fmt->format = fastq_format;
        else if (strchr(simple_mode, 'F')) fmt->format = fasta_format;
        else fmt->format = text_format;

        if (strchr(simple_mode, 'z')) fmt->compression = bgzf;
        else if (strchr(simple_mode, 'g')) fmt->compression = gzip;
        else if (strchr(simple_mode, 'u')) fmt->compression = no_compression;
        else {
            // No compression mode specified, set to the default for the format
            switch (fmt->format) {
            case binary_format: fmt->compression = bgzf; break;
            case cram: fmt->compression = custom; break;
            case fastq_format: fmt->compression = no_compression; break;
            case fasta_format: fmt->compression = no_compression; break;
            case text_format: fmt->compression = no_compression; break;
            default: abort();
            }
        }

        // Fill in category (if determinable; e.g. 'b' could be BAM or BCF)
        fmt->category = format_category(fmt->format);

        fmt->version.major = fmt->version.minor = -1;
        fmt->compression_level = -1;
        fmt->specific = NULL;
    }
    else { errno = EINVAL; goto error; }

    switch (fp->format.format) {
    case binary_format:
    case bam:
    case bcf:
        fp->fp.bgzf = bgzf_hopen(hfile, simple_mode);
        if (fp->fp.bgzf == NULL) goto error;
        fp->is_bin = fp->is_bgzf = 1;
        break;

    case cram:
        fp->fp.cram = cram_dopen(hfile, fn, simple_mode);
        if (fp->fp.cram == NULL) goto error;
        if (!fp->is_write)
            cram_set_option(fp->fp.cram, CRAM_OPT_DECODE_MD, -1); // auto
        fp->is_cram = 1;
        break;

    case empty_format:
    case text_format:
    case bed:
    case fasta_format:
    case fastq_format:
    case sam:
    case vcf:
        if (fp->format.compression != no_compression) {
            fp->fp.bgzf = bgzf_hopen(hfile, simple_mode);
            if (fp->fp.bgzf == NULL) goto error;
            fp->is_bgzf = 1;
        }
        else
            fp->fp.hfile = hfile;
        break;

    default:
        errno = EFTYPE;
        goto error;
    }

    if (opts)
        hts_process_opts(fp, opts);

    // Allow original file to close if it was preserved earlier by crypt4gh
    hfile_orig->preserve = 0;

    // If redirecting via htsget, close the original hFILE now (pedantically
    // we would instead close it in hts_close(), but this a simplifying
    // optimisation)
    if (hfile != hfile_cleanup) hclose_abruptly(hfile_cleanup);

    return fp;

error:
    hts_log_error("Failed to open file %s", fn);

    // If redirecting, close the failed redirection hFILE that we have opened
    if (hfile != hfile_orig) hclose_abruptly(hfile);
    hfile_orig->preserve = 0; // Allow caller to close the original hfile

    if (fp) {
        free(fp->fn);
        free(fp->fn_aux);
        free(fp);
    }
    return NULL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x318, %rsp            # imm = 0x318
movq %rdx, %r15
movq %rsi, 0x8(%rsp)
movq %rdi, %r14
pushq $0x1
popq %rdi
movl $0x88, %esi
callq 0x4300
movq %rax, %rbx
movb $0x0, 0x94(%rsp)
movq %r14, (%rsp)
testq %rax, %rax
je 0x10fae
movq 0x8(%rsp), %r13
movq %r13, %rdi
callq 0x4930
movq %rax, 0x28(%rbx)
pushq $0x2c
popq %rsi
movq %r15, %rdi
callq 0x4190
testq %rax, %rax
je 0x10af3
movq %rax, %r12
movq %rax, %r14
subq %r15, %r14
cmpq $0x64, %r14
pushq $0x64
popq %rdx
cmovlq %r14, %rdx
leaq 0x30(%rsp), %rdi
movq %r15, %rsi
callq 0x4250
movb $0x0, 0x30(%rsp,%r14)
incq %r12
jmp 0x10b06
leaq 0x30(%rsp), %rdi
pushq $0x64
popq %rdx
movq %r15, %rsi
callq 0x4250
xorl %r12d, %r12d
leaq 0x30(%rsp), %rdi
pushq $0x72
popq %rsi
callq 0x4190
testq %rax, %rax
je 0x10ce6
movq %r12, 0x20(%rsp)
leaq 0x48(%rbx), %r12
movq (%rsp), %r14
movq %r14, %rdi
movq %r13, %rsi
movq %r12, %rdx
callq 0xf79d
testl %eax, %eax
js 0x10fae
pushq $0x6
popq %r13
movq (%rsp), %rax
movq %rax, %rbp
movq %rax, 0x10(%rsp)
movq %rbx, 0x18(%rsp)
movq %r12, 0x28(%rsp)
movl 0x4c(%rbx), %r15d
cmpl $0x14, %r15d
je 0x10b6d
cmpl $0xe, %r15d
jne 0x10d65
decl %r13d
je 0x10d52
cmpl $0x14, %r15d
je 0x10bb7
cmpl $0xe, %r15d
jne 0x10cc3
movq %rbp, %rdi
leaq 0x30(%rsp), %rsi
callq 0x1ab7c
testq %rax, %rax
je 0x10d5d
movq %rax, %r14
cmpq 0x10(%rsp), %rbp
je 0x10cc6
movq %rbp, %rdi
callq 0xd94c
jmp 0x10cc6
movq 0x8(%rsp), %rdi
callq 0x41d0
movq %rax, %r14
addq $0xa, %r14
leaq 0x110(%rsp), %r15
cmpq $0x201, %r14            # imm = 0x201
jb 0x10bfa
cmpq $0x7ffffffe, %r14       # imm = 0x7FFFFFFE
ja 0x10d5d
movq %r14, %rdi
callq 0x4680
movq %rax, %r15
testq %rax, %rax
je 0x10d5d
movq %r15, %rdi
movq %r14, %rsi
leaq 0x672fa(%rip), %r14     # 0x77f01
movq %r14, %rdx
leaq 0x668f3(%rip), %rcx     # 0x77504
movq 0x8(%rsp), %r8
xorl %eax, %eax
callq 0x4800
leaq 0x30(%rsp), %r12
movq %r12, %rdi
pushq $0x3a
popq %rsi
callq 0x4190
testq %rax, %rax
leaq 0x6711f(%rip), %r8      # 0x77d56
leaq 0x67145(%rip), %rax     # 0x77d83
cmoveq %rax, %r8
leaq 0xa0(%rsp), %rbx
movq %rbx, %rdi
pushq $0x66
popq %rsi
movq %r14, %rdx
movq %r12, %rcx
xorl %eax, %eax
callq 0x4800
movq %r15, %rdi
movq %rbx, %rsi
leaq 0x67db8(%rip), %rdx     # 0x78a22
movq %rbp, %rcx
xorl %r8d, %r8d
xorl %eax, %eax
callq 0xe19b
movq %rax, %r14
leaq 0x110(%rsp), %rax
cmpq %rax, %r15
je 0x10c8f
movq %r15, %rdi
callq 0x45c0
testq %r14, %r14
movq 0x28(%rsp), %r12
je 0x10dad
cmpq (%rsp), %rbp
movq 0x18(%rsp), %rbx
jne 0x10cb0
movq (%rsp), %rax
orb $0x8, 0x30(%rax)
movq 0x10(%rsp), %rax
cmpq %rax, %rbp
cmoveq %r14, %rax
movq %rax, 0x10(%rsp)
jmp 0x10cc6
movq %rbp, %r14
movq %r14, %rdi
movq 0x8(%rsp), %rsi
movq %r12, %rdx
callq 0xf79d
movq %r14, %rbp
testl %eax, %eax
jns 0x10b59
jmp 0x10fae
leaq 0x30(%rsp), %rdi
pushq $0x77
popq %rsi
callq 0x4190
testq %rax, %rax
jne 0x10d0a
leaq 0x30(%rsp), %rdi
pushq $0x61
popq %rsi
callq 0x4190
testq %rax, %rax
je 0x10d7c
movl $0x2, (%rbx)
leaq 0x30(%rsp), %rdi
pushq $0x62
popq %rsi
callq 0x4190
testq %rax, %rax
je 0x10d32
pushq $0x1
popq %r15
movl $0x1, 0x4c(%rbx)
jmp 0x10de2
leaq 0x30(%rsp), %rdi
pushq $0x63
popq %rsi
callq 0x4190
testq %rax, %rax
je 0x10d90
movl $0x6, 0x4c(%rbx)
pushq $0x6
jmp 0x10de0
callq 0x4050
movl $0x28, (%rax)
movq %rbp, %r14
jmp 0x10fae
movq %rbp, %r14
movq 0x8(%rsp), %r13
movq 0x20(%rsp), %r12
movq 0x10(%rsp), %rbp
jmp 0x10e43
callq 0x4050
movl $0x16, (%rax)
movq (%rsp), %r14
jmp 0x10fae
leaq 0x30(%rsp), %rdi
pushq $0x66
popq %rsi
callq 0x4190
testq %rax, %rax
je 0x10dba
movl $0x11, 0x4c(%rbx)
pushq $0x11
jmp 0x10de0
movq %rbp, %r14
movq 0x18(%rsp), %rbx
jmp 0x10fae
leaq 0x30(%rsp), %rdi
pushq $0x46
popq %rsi
callq 0x4190
testq %rax, %rax
je 0x10dd7
movl $0x10, 0x4c(%rbx)
pushq $0x10
jmp 0x10de0
movl $0x2, 0x4c(%rbx)
pushq $0x2
popq %r15
leaq 0x30(%rsp), %rdi
pushq $0x7a
popq %rsi
callq 0x4190
testq %rax, %rax
je 0x10df8
pushq $0x2
jmp 0x10e10
leaq 0x30(%rsp), %rdi
pushq $0x67
popq %rsi
callq 0x4190
testq %rax, %rax
je 0x10f50
pushq $0x1
popq %rcx
movl %ecx, 0x54(%rbx)
leal -0x3(%r15), %ecx
xorl %eax, %eax
cmpl $0xf, %ecx
jae 0x10e2b
movl %ecx, %eax
leaq 0x66dbc(%rip), %rcx     # 0x77be4
movl (%rcx,%rax,4), %eax
movl %eax, 0x48(%rbx)
orl $-0x1, 0x50(%rbx)
orw $-0x1, 0x58(%rbx)
andq $0x0, 0x60(%rbx)
movq (%rsp), %rbp
movq %rbp, %r14
cmpl $0x11, %r15d
ja 0x10fa3
movl $0x3a10c, %eax          # imm = 0x3A10C
btl %r15d, %eax
jae 0x10e7d
cmpl $0x0, 0x54(%rbx)
je 0x10ea7
leaq 0x30(%rsp), %rsi
movq %r14, %rdi
callq 0x9ac3
movq %rax, 0x38(%rbx)
testq %rax, %rax
je 0x10fae
orb $0x10, (%rbx)
jmp 0x10eab
movl $0x212, %eax            # imm = 0x212
btl %r15d, %eax
jae 0x10f02
leaq 0x30(%rsp), %rsi
movq %r14, %rdi
callq 0x9ac3
movq %rax, 0x38(%rbx)
testq %rax, %rax
je 0x10fae
orb $0x11, (%rbx)
jmp 0x10eab
movq %r14, 0x38(%rbx)
testq %r12, %r12
je 0x10ee4
leaq 0x110(%rsp), %rdi
andq $0x0, 0x18(%rdi)
movq %r12, %rsi
callq 0x120ae
testl %eax, %eax
jne 0x10ee4
movq 0x128(%rsp), %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0x11039
movq %r15, %rdi
callq 0x12081
movq (%rsp), %rax
andb $-0x9, 0x30(%rax)
cmpq %rbp, %r14
je 0x11002
movq %rbp, %rdi
callq 0xd94c
jmp 0x11002
cmpl $0x6, %r15d
jne 0x10fa3
leaq 0x30(%rsp), %rdx
movq %r14, %rdi
movq %r13, %rsi
callq 0x4465d
movq %rax, 0x38(%rbx)
testq %rax, %rax
je 0x10fae
movq %rbp, %r15
movl (%rbx), %ebp
testb $0x2, %bpl
jne 0x10f43
pushq $-0x1
popq %rdx
movq %rax, %rdi
xorl %esi, %esi
xorl %eax, %eax
callq 0x451f7
orl $0x8, %ebp
movl %ebp, (%rbx)
movq %r15, %rbp
jmp 0x10eab
leaq 0x30(%rsp), %rdi
pushq $0x75
popq %rsi
callq 0x4190
xorl %ecx, %ecx
testq %rax, %rax
jne 0x10e11
cmpl $0x1, %r15d
je 0x11027
cmpl $0x2, %r15d
je 0x11023
cmpl $0x11, %r15d
je 0x11017
cmpl $0x10, %r15d
je 0x11017
cmpl $0x6, %r15d
jne 0x11034
movl $0x3, 0x54(%rbx)
jmp 0x1101b
callq 0x4050
movl $0x8, (%rax)
leaq 0x672b5(%rip), %rsi     # 0x7826a
leaq 0x672b8(%rip), %rdx     # 0x78274
pushq $0x1
popq %rdi
movq 0x8(%rsp), %rcx
xorl %eax, %eax
callq 0x110c6
cmpq (%rsp), %r14
je 0x10fd9
movq %r14, %rdi
callq 0xd94c
movq (%rsp), %rax
andb $-0x9, 0x30(%rax)
testq %rbx, %rbx
je 0x11000
movq 0x28(%rbx), %rdi
callq 0x45c0
movq 0x30(%rbx), %rdi
callq 0x45c0
movq %rbx, %rdi
callq 0x45c0
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x318, %rsp            # imm = 0x318
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
andl $0x0, 0x54(%rbx)
pushq $0x1
popq %rax
jmp 0x10e2b
xorl %eax, %eax
jmp 0x1102a
pushq $0x2
popq %rax
movl %eax, 0x54(%rbx)
xorl %eax, %eax
jmp 0x10e2b
callq 0x4270