// Set the initial state static state_t* init(parsed_opts_t* opts) { state_t* retval = calloc(sizeof(state_t), 1); if (!retval) { fprintf(pysamerr, "Out of memory"); return NULL; } retval->merged_input_file = sam_open(opts->merged_input_name, "rb"); if (!retval->merged_input_file) { fprintf(pysamerr, "Could not open input file (%s)\n", opts->merged_input_name); free(retval); return NULL; } retval->merged_input_header = sam_hdr_read(retval->merged_input_file); if (opts->unaccounted_name) { if (opts->unaccounted_header_name) { samFile* hdr_load = sam_open(opts->unaccounted_header_name, "r"); if (!hdr_load) { fprintf(pysamerr, "Could not open unaccounted header file (%s)\n", opts->unaccounted_header_name); cleanup_state(retval); return NULL; } retval->unaccounted_header = sam_hdr_read(hdr_load); sam_close(hdr_load); } else { retval->unaccounted_header = bam_hdr_dup(retval->merged_input_header); } retval->unaccounted_file = sam_open(opts->unaccounted_name, "wb"); if (retval->unaccounted_file == NULL) { fprintf(pysamerr, "Could not open unaccounted output file: %s\n", opts->unaccounted_name); cleanup_state(retval); return NULL; } } // Open output files for RGs if (!count_RG(retval->merged_input_header, &retval->output_count, &retval->rg_id)) return NULL; if (opts->verbose) fprintf(pysamerr, "@RG's found %zu\n",retval->output_count); retval->rg_output_file = (samFile**)calloc(retval->output_count, sizeof(samFile*)); retval->rg_output_header = (bam_hdr_t**)calloc(retval->output_count, sizeof(bam_hdr_t*)); retval->rg_hash = kh_init_c2i(); if (!retval->rg_output_file || !retval->rg_output_header) { fprintf(pysamerr, "Could not allocate memory for output file array. Out of memory?"); cleanup_state(retval); return NULL; } char* dirsep = strrchr(opts->merged_input_name, '/'); char* input_base_name = strdup(dirsep? dirsep+1 : opts->merged_input_name); if (!input_base_name) { fprintf(pysamerr, "Out of memory\n"); cleanup_state(retval); return NULL; } char* extension = strrchr(input_base_name, '.'); if (extension) *extension = '\0'; size_t i; for (i = 0; i < retval->output_count; i++) { char* output_filename = NULL; if ( ( output_filename = expand_format_string(opts->output_format_string, input_base_name, retval->rg_id[i], i) ) == NULL) { fprintf(pysamerr, "Error expanding output filename format string.\r\n"); cleanup_state(retval); free(input_base_name); return NULL; } retval->rg_output_file[i] = sam_open(output_filename, "wb"); if (retval->rg_output_file[i] == NULL) { fprintf(pysamerr, "Could not open output file: %s\r\n", output_filename); cleanup_state(retval); free(input_base_name); return NULL; } // Record index in hash int ret; khiter_t iter = kh_put_c2i(retval->rg_hash, retval->rg_id[i], &ret); kh_val(retval->rg_hash,iter) = i; // Set and edit header retval->rg_output_header[i] = bam_hdr_dup(retval->merged_input_header); if ( !filter_header_rg(retval->rg_output_header[i], retval->rg_id[i]) ) { fprintf(pysamerr, "Could not rewrite header for file: %s\r\n", output_filename); cleanup_state(retval); free(output_filename); free(input_base_name); return NULL; } free(output_filename); } free(input_base_name); return retval; }
int main(int argc, char**argv) { // test state const int NUM_TESTS = 2; int verbose = 0; int success = 0; int failure = 0; int getopt_char; while ((getopt_char = getopt(argc, argv, "v")) != -1) { switch (getopt_char) { case 'v': ++verbose; break; default: printf( "usage: test_filter_header_rg [-v]\n\n" " -v verbose output\n" ); break; } } // Setup pysamerr redirect kstring_t res = { 0, 0, NULL }; FILE* orig_pysamerr = fdopen(dup(STDERR_FILENO), "a"); // Save pysamerr char* tempfname = (optind < argc)? argv[optind] : "test_count_rg.tmp"; FILE* check = NULL; // setup if (verbose) printf("BEGIN test 1\n"); // test eliminating a tag that isn't there bam_hdr_t* hdr1; const char* id_to_keep_1 = "1#2.3"; setup_test_1(&hdr1); if (verbose > 1) { printf("hdr1\n"); dump_hdr(hdr1); } if (verbose) printf("RUN test 1\n"); // test xfreopen(tempfname, "w", pysamerr); // Redirect pysamerr to pipe bool result_1 = filter_header_rg(hdr1, id_to_keep_1); fclose(pysamerr); if (verbose) printf("END RUN test 1\n"); if (verbose > 1) { printf("hdr1\n"); dump_hdr(hdr1); } // check result res.l = 0; check = fopen(tempfname, "r"); if ( result_1 && check_test_1(hdr1) && kgetline(&res, (kgets_func *)fgets, check) < 0 && (feof(check) || res.l == 0)) { ++success; } else { ++failure; if (verbose) printf("FAIL test 1\n"); } fclose(check); // teardown bam_hdr_destroy(hdr1); if (verbose) printf("END test 1\n"); if (verbose) printf("BEGIN test 2\n"); // test eliminating a tag that is there bam_hdr_t* hdr2; const char* id_to_keep_2 = "fish"; setup_test_2(&hdr2); if (verbose > 1) { printf("hdr2\n"); dump_hdr(hdr2); } if (verbose) printf("RUN test 2\n"); // test xfreopen(tempfname, "w", pysamerr); // Redirect pysamerr to pipe bool result_2 = filter_header_rg(hdr2, id_to_keep_2); fclose(pysamerr); if (verbose) printf("END RUN test 2\n"); if (verbose > 1) { printf("hdr2\n"); dump_hdr(hdr2); } // check result res.l = 0; check = fopen(tempfname, "r"); if ( result_2 && check_test_2(hdr2) && kgetline(&res, (kgets_func *)fgets, check) < 0 && (feof(check) || res.l == 0)) { ++success; } else { ++failure; if (verbose) printf("FAIL test 2\n"); } fclose(check); // teardown bam_hdr_destroy(hdr2); if (verbose) printf("END test 2\n"); // Cleanup free(res.s); remove(tempfname); if (failure > 0) fprintf(orig_pysamerr, "%d failures %d successes\n", failure, success); fclose(orig_pysamerr); return (success == NUM_TESTS)? EXIT_SUCCESS : EXIT_FAILURE; }