#include <config.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <stdint.h>
#include <inttypes.h>
#include "../htslib/hts.h"
#include "../htslib/sam.h"
void reg_expected(sam_hdr_t *hdr, const char *reg, int flags,
char *reg_exp, int tid_exp, hts_pos_t beg_exp, hts_pos_t end_exp) {
const char *reg_out;
int tid_out = -1;
hts_pos_t beg_out = -1, end_out = -1;
reg_out = sam_parse_region(hdr, reg, &tid_out, &beg_out, &end_out, flags);
if ((reg_out != NULL) != (reg_exp != NULL) ||
(reg_out && reg_exp && strcmp(reg_out, reg_exp) != 0) ||
(reg_exp && tid_out != tid_exp) ||
(reg_exp && beg_out != beg_exp) ||
(reg_exp && end_out != end_exp)) {
fprintf(stderr, "Parsing \"%s\" expected return \"%s\", %d:%"PRIhts_pos"-%"PRIhts_pos", "
"but got \"%s\", %d:%"PRIhts_pos"-%"PRIhts_pos"\n",
reg,
reg_exp?reg_exp:"(null)", tid_exp, beg_exp, end_exp,
reg_out?reg_out:"(null)", tid_out, beg_out, end_out);
exit(1);
}
}
int reg_test(char *fn) {
samFile *fp;
sam_hdr_t *hdr;
if (!(fp = sam_open(fn, "r")))
return 1;
if (!(hdr = sam_hdr_read(fp)))
return 1;
reg_expected(hdr, "chr1", 0, "", 0, 0, HTS_POS_MAX);
reg_expected(hdr, "chr1:50", 0, "", 0, 49, HTS_POS_MAX);
reg_expected(hdr, "chr1:50", HTS_PARSE_ONE_COORD, "", 0, 49, 50);
reg_expected(hdr, "chr1:50-100", 0, "", 0, 49, 100);
reg_expected(hdr, "chr1:50-", 0, "", 0, 49, HTS_POS_MAX);
reg_expected(hdr, "chr1:-50", 0, "", 0, 0, 50);
fprintf(stderr, "Expected error: ");
reg_expected(hdr, "chr1:100-200", 0, NULL, 0, 0, 0); reg_expected(hdr, "{chr1}:100-200", 0, "", 0, 99, 200);
reg_expected(hdr, "{chr1:100-200}", 0, "", 2, 0, HTS_POS_MAX);
reg_expected(hdr, "{chr1:100-200}:100-200", 0, "", 2, 99, 200);
reg_expected(hdr, "{chr2:100-200}:100-200", 0, "", 3, 99, 200);
reg_expected(hdr, "chr2:100-200:100-200", 0, "", 3, 99, 200);
reg_expected(hdr, "chr2:100-200", 0, "", 3, 0, HTS_POS_MAX);
reg_expected(hdr, "chr3", 0, "", 4, 0, HTS_POS_MAX);
reg_expected(hdr, "chr3:", 0, "", 4, 0, HTS_POS_MAX);
reg_expected(hdr, "chr3:1000-1500", 0, "", 4, 999, 1500);
reg_expected(hdr, "chr3:1,000-1,500", 0, "", 4, 999, 1500);
reg_expected(hdr, "chr3:1k-1.5K", 0, "", 4, 999, 1500);
reg_expected(hdr, "chr3:1e3-1.5e3", 0, "", 4, 999, 1500);
reg_expected(hdr, "chr3:1e3-15e2", 0, "", 4, 999, 1500);
reg_expected(hdr, "chr1,chr3", HTS_PARSE_LIST, "chr3", 0, 0, HTS_POS_MAX);
fprintf(stderr, "Expected error: ");
reg_expected(hdr, "chr1:100-200,chr3", HTS_PARSE_LIST, NULL, 0, 0, 0); reg_expected(hdr, "{chr1,chr3}", HTS_PARSE_LIST, "", 5, 0, HTS_POS_MAX);
reg_expected(hdr, "{chr1,chr3},chr1", HTS_PARSE_LIST, "chr1", 5, 0, HTS_POS_MAX);
reg_expected(hdr, "chr3:1,000-1,500", HTS_PARSE_LIST | HTS_PARSE_ONE_COORD, "000-1,500", 4, 0, 1);
reg_expected(hdr, "chr2", 0, NULL, 0, 0, 0);
reg_expected(hdr, "chr1,", 0, NULL, 0, 0, 0);
fprintf(stderr, "Expected error: ");
reg_expected(hdr, "{chr1", 0, NULL, 0, 0, 0);
reg_expected(hdr, "chr1:10-10", 0, "", 0, 9, 10); reg_expected(hdr, "chr1:10-9", 0, NULL, 0, 0, 0); fprintf(stderr, "Expected error: ");
reg_expected(hdr, "chr1:x", 0, NULL, 0, 0, 0);
fprintf(stderr, "Expected error: ");
reg_expected(hdr, "chr1:1-y", 0, NULL, 0, 0, 0);
fprintf(stderr, "Expected error: ");
reg_expected(hdr, "chr1:1,chr3", 0, NULL, 0, 0, 0);
sam_hdr_destroy(hdr);
sam_close(fp);
exit(0);
}
int main(int argc, char **argv) {
sam_hdr_t *hdr;
samFile *fp;
int flags = 0;
while (argc > 1) {
if (strcmp(argv[1], "-m") == 0) {
flags |= HTS_PARSE_LIST;
argc--; argv++;
continue;
}
if (strcmp(argv[1], "-c") == 0) {
flags |= HTS_PARSE_ONE_COORD;
argc--; argv++;
continue;
}
if (strcmp(argv[1], "-t") == 0)
reg_test(argv[2]);
break;
}
if (argc != 3) {
fprintf(stderr, "Usage: test-parse-reg [-m] [-c] region[,region]...\n");
exit(1);
}
if (!(fp = sam_open(argv[1], "r"))) {
perror(argv[1]);
exit(1);
}
if (!(hdr = sam_hdr_read(fp))) {
fprintf(stderr, "Couldn't read header\n");
exit(1);
}
const char *reg = argv[2];
while (*reg) {
int tid;
hts_pos_t beg, end;
reg = sam_parse_region(hdr, reg, &tid, &beg, &end, flags);
if (!reg) {
fprintf(stderr, "Failed to parse region\n");
exit(1);
}
printf("%-20s %12"PRIhts_pos" %12"PRIhts_pos"\n",
tid == -1 ? "*" : hdr->target_name[tid],
beg, end);
}
sam_hdr_destroy(hdr);
sam_close(fp);
return 0;
}