modified: src1/input.c
[GalaxyCodeBases.git] / c_cpp / lib / htslib / htsfile.c
blob25e7769fcb578d689f949b754015f8bf23f2746f
1 /* htsfile.c -- file identifier and minimal viewer.
3 Copyright (C) 2014-2017 Genome Research Ltd.
5 Author: John Marshall <jm18@sanger.ac.uk>
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 DEALINGS IN THE SOFTWARE. */
25 #include <config.h>
27 #include <ctype.h>
28 #include <errno.h>
29 #include <stdarg.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <getopt.h>
34 #include <unistd.h>
36 #include "htslib/hfile.h"
37 #include "htslib/hts.h"
38 #include "htslib/sam.h"
39 #include "htslib/vcf.h"
41 enum { identify, view_headers, view_all } mode = identify;
42 int show_headers = 1;
43 int verbose = 0;
44 int status = EXIT_SUCCESS; /* Exit status from main */
46 void error(const char *format, ...)
48 int err = errno;
49 va_list args;
50 va_start(args, format);
51 fflush(stdout);
52 fprintf(stderr, "htsfile: ");
53 vfprintf(stderr, format, args);
54 if (err) fprintf(stderr, ": %s\n", strerror(err));
55 else fprintf(stderr, "\n");
56 fflush(stderr);
57 va_end(args);
58 status = EXIT_FAILURE;
61 static htsFile *dup_stdout(const char *mode)
63 int fd = dup(STDOUT_FILENO);
64 hFILE *hfp = (fd >= 0)? hdopen(fd, mode) : NULL;
65 return hfp? hts_hopen(hfp, "-", mode) : NULL;
68 static void view_sam(samFile *in, const char *filename)
70 bam1_t *b = NULL;
71 bam_hdr_t *hdr = NULL;
72 samFile *out = NULL;
74 hdr = sam_hdr_read(in);
75 if (hdr == NULL) {
76 errno = 0; error("reading headers from \"%s\" failed", filename);
77 goto clean;
80 out = dup_stdout("w");
81 if (out == NULL) { error("reopening standard output failed"); goto clean; }
83 if (show_headers) {
84 if (sam_hdr_write(out, hdr) != 0) {
85 error("writing headers to standard output failed");
86 goto clean;
90 if (mode == view_all) {
91 int ret;
93 b = bam_init1();
94 if (b == NULL) { error("can't create record"); goto clean; }
96 while ((ret = sam_read1(in, hdr, b)) >= 0) {
97 if (sam_write1(out, hdr, b) < 0) {
98 error("writing to standard output failed");
99 goto clean;
103 if (ret < -1) { error("reading \"%s\" failed", filename); goto clean; }
106 clean:
107 bam_hdr_destroy(hdr);
108 bam_destroy1(b);
109 if (out) hts_close(out);
112 static void view_vcf(vcfFile *in, const char *filename)
114 bcf1_t *rec = NULL;
115 bcf_hdr_t *hdr = NULL;
116 vcfFile *out = NULL;
118 hdr = bcf_hdr_read(in);
119 if (hdr == NULL) {
120 errno = 0; error("reading headers from \"%s\" failed", filename);
121 goto clean;
124 out = dup_stdout("w");
125 if (out == NULL) { error("reopening standard output failed"); goto clean; }
127 if (show_headers) {
128 if (bcf_hdr_write(out, hdr) != 0) {
129 error("writing headers to standard output failed");
130 goto clean;
134 if (mode == view_all) {
135 int ret;
137 rec = bcf_init();
138 if (rec == NULL) { error("can't create record"); goto clean; }
140 while ((ret = bcf_read(in, hdr, rec)) >= 0) {
141 if (bcf_write(out, hdr, rec) < 0) {
142 error("writing to standard output failed");
143 goto clean;
147 if (ret < -1) { error("reading \"%s\" failed", filename); goto clean; }
150 clean:
151 if (hdr) bcf_hdr_destroy(hdr);
152 if (rec) bcf_destroy(rec);
153 if (out) hts_close(out);
156 static void view_raw(hFILE *fp, const char *filename)
158 int c, prev;
159 for (prev = '\n'; (c = hgetc(fp)) != EOF; prev = c)
160 if (isprint(c) || c == '\n' || c == '\t') putchar(c);
161 else if (c == '\r') fputs("\\r", stdout);
162 else if (c == '\0') fputs("\\0", stdout);
163 else printf("\\x%02x", c);
165 if (prev != '\n') putchar('\n');
167 if (herrno(fp)) {
168 errno = herrno(fp);
169 error("reading \"%s\" failed", filename);
173 static void usage(FILE *fp, int status)
175 fprintf(fp,
176 "Usage: htsfile [-chHv] FILE...\n"
177 "Options:\n"
178 " -c, --view Write textual form of FILEs to standard output\n"
179 " -h, --header-only Display only headers in view mode, not records\n"
180 " -H, --no-header Suppress header display in view mode\n"
181 " -v, --verbose Increase verbosity of warnings and diagnostics\n");
182 exit(status);
185 int main(int argc, char **argv)
187 static const struct option options[] = {
188 { "header-only", no_argument, NULL, 'h' },
189 { "no-header", no_argument, NULL, 'H' },
190 { "view", no_argument, NULL, 'c' },
191 { "verbose", no_argument, NULL, 'v' },
192 { "help", no_argument, NULL, '?' },
193 { "version", no_argument, NULL, 1 },
194 { NULL, 0, NULL, 0 }
197 int c, i;
199 status = EXIT_SUCCESS;
200 while ((c = getopt_long(argc, argv, "chHv?", options, NULL)) >= 0)
201 switch (c) {
202 case 'c': mode = view_all; break;
203 case 'h': mode = view_headers; show_headers = 1; break;
204 case 'H': show_headers = 0; break;
205 case 'v': hts_verbose++; verbose++; break;
206 case 1:
207 printf(
208 "htsfile (htslib) %s\n"
209 "Copyright (C) 2017 Genome Research Ltd.\n",
210 hts_version());
211 exit(EXIT_SUCCESS);
212 break;
213 case '?': usage(stdout, EXIT_SUCCESS); break;
214 default: usage(stderr, EXIT_FAILURE); break;
217 if (optind == argc) usage(stderr, EXIT_FAILURE);
219 for (i = optind; i < argc; i++) {
220 hFILE *fp = hopen(argv[i], "r");
221 if (fp == NULL) {
222 error("can't open \"%s\"", argv[i]);
223 continue;
226 if (mode == identify) {
227 htsFormat fmt;
228 if (hts_detect_format(fp, &fmt) < 0) {
229 error("detecting \"%s\" format failed", argv[i]);
230 hclose_abruptly(fp);
231 continue;
234 char *description = hts_format_description(&fmt);
235 printf("%s:\t%s\n", argv[i], description);
236 free(description);
238 else {
239 htsFile *hts = hts_hopen(fp, argv[i], "r");
240 if (hts) {
241 switch (hts_get_format(hts)->category) {
242 case sequence_data:
243 view_sam(hts, argv[i]);
244 break;
245 case variant_data:
246 view_vcf(hts, argv[i]);
247 break;
248 default:
249 if (verbose)
250 view_raw(fp, argv[i]);
251 else {
252 errno = 0;
253 error("can't view \"%s\": unknown format", argv[i]);
255 break;
258 if (hts_close(hts) < 0) error("closing \"%s\" failed", argv[i]);
259 fp = NULL;
261 else if (errno == ENOEXEC && verbose)
262 view_raw(fp, argv[i]);
263 else
264 error("can't view \"%s\"", argv[i]);
267 if (fp && hclose(fp) < 0) error("closing \"%s\" failed", argv[i]);
270 return status;