1 /*
2  * Copyright (c) 2005, 2007, 2010 Genome Research Ltd.
3  * Author(s): James Bonfield
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *    1. Redistributions of source code must retain the above copyright notice,
9  *       this list of conditions and the following disclaimer.
10  *
11  *    2. Redistributions in binary form must reproduce the above
12  *       copyright notice, this list of conditions and the following
13  *       disclaimer in the documentation and/or other materials provided
14  *       with the distribution.
15  *
16  *    3. Neither the names Genome Research Ltd and Wellcome Trust Sanger
17  *    Institute nor the names of its contributors may be used to endorse
18  *    or promote products derived from this software without specific
19  *    prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY GENOME RESEARCH LTD AND CONTRIBUTORS "AS
22  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENOME RESEARCH
25  * LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /*
35  * Author(s): James Bonfield
36  *
37  * Copyright (c) 2001 MEDICAL RESEARCH COUNCIL
38  * All rights reserved
39  *
40  * Redistribution and use in source and binary forms, with or without
41  * modification, are permitted provided that the following conditions are met:
42  *
43  *    1 Redistributions of source code must retain the above copyright notice,
44  *      this list of conditions and the following disclaimer.
45  *
46  *    2 Redistributions in binary form must reproduce the above copyright
47  *      notice, this list of conditions and the following disclaimer in
48  *      the documentation and/or other materials provided with the
49  *      distribution.
50  *
51  *    3 Neither the name of the MEDICAL RESEARCH COUNCIL, THE LABORATORY OF
52  *      MOLECULAR BIOLOGY nor the names of its contributors may be used
53  *      to endorse or promote products derived from this software without
54  *      specific prior written permission.
55  *
56  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
57  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
60  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
61  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
62  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
63  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
64  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
65  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
66  * POSSIBILITY OF SUCH DAMAGE.
67  */
68 
69 /*
70  * Fetches all or several specific comment(s) from a trace file TEXT section.
71  *
72  * Usage:
73  *	get_comment [options] [field ...] < infile
74  *
75  * Options:
76  *	-c	Suppresses display of field-ID
77  *	-h	Help
78  *
79  * Return codes:
80  *	0	Success
81  *	1	At least one field was not found
82  *	2	Failed to read file, or usage message displayed
83  */
84 
85 #ifdef HAVE_CONFIG_H
86 #include "io_lib_config.h"
87 #endif
88 
89 #include <stdio.h>
90 #include <stdlib.h>
91 #include <string.h>
92 #include <unistd.h>
93 
94 #include <io_lib/Read.h>
95 
96 /* Nasty Microsoft bits */
97 #ifdef _MSC_VER
98 #  define DLL_IMPORT __declspec(dllimport)
99 #else
100 #  define DLL_IMPORT
101 #endif
102 
103 /*
104  * From unistd.h
105 extern DLL_IMPORT char *optarg;
106 extern DLL_IMPORT int optind;
107 */
108 
usage(void)109 void usage(void) {
110     puts("Usage:");
111     puts("    get_comment [options] [field ...] < infile");
112     puts("\nOptions:");
113     puts("    -c	Suppresses display of field-ID");
114     puts("    -h	Help");
115     puts("\nReturn codes:");
116     puts("    0	Success");
117     puts("    1	At least one field was not found");
118     puts("    2	Failed to read file, or usage message displayed");
119     exit(2);
120 }
121 
main(int argc,char ** argv)122 int main(int argc, char **argv) {
123     Read *r;
124     char *ident, *value;
125     int ident_len, value_len;
126     enum state_t {
127 	NAME, EQUALS, VALUE, NL
128     } state;
129     size_t len;
130     int i, j, found;
131     int suppress = 0;
132     int *found_args = NULL;
133 
134     /* Parse arguments */
135     for (argc--, argv++; argc > 0; argc--, argv++) {
136 	if (**argv != '-')
137 	    break;
138 
139 	if (strcmp(*argv, "-c") == 0) {
140 	    suppress = 1;
141 
142 	} else {
143 	    usage();
144 	}
145     }
146 
147     /* Read the file */
148     read_sections(READ_COMMENTS);
149     if (NULL == (r = fread_reading(stdin, "(stdin)", TT_ANY))) {
150 	fprintf(stderr, "failed to read trace from stdin\n");
151 	return 2;
152     }
153 
154     if (!r->info)
155 	return 1;
156 
157     if (argc == 0) {
158 	/* Display all of them */
159 	puts(r->info);
160 
161     } else {
162 	/* Display only the ones listed on the command line */
163 
164 	found_args = (int *)calloc(argc, sizeof(int));
165 
166 	len = strlen(r->info);
167 	state = NAME;
168 	ident = r->info;
169 	found = 0;
170 	/* Not needed, but avoids "might be used uninitialized" message */
171 	value = NULL;
172 	ident_len = value_len = 0;
173 	for (i = 0; i <= len; i++) {
174 	    switch (state) {
175 	    case NAME:
176 		if (r->info[i] == '=') {
177 		    state = EQUALS;
178 		    ident_len = &r->info[i] - ident;
179 		    value_len = 0;
180 		}
181 		break;
182 
183 	    case EQUALS:
184 		for (j = 0; j < argc; j++) {
185 		    if (strncmp(ident, argv[j], ident_len) == 0) {
186 			found = 1;
187 			found_args[j] = 1;
188 		    }
189 		}
190 		state = VALUE;
191 		value = &r->info[i];
192 
193 		/* DELIBERATE FLOW THROUGH */
194 
195 	    case VALUE:
196 		if (r->info[i] == '\n' || r->info[i] == 0) {
197 		    value_len = &r->info[i] - value;
198 		    state = NL;
199 		}
200 		break;
201 
202 	    case NL:
203 		if (found) {
204 		    if (suppress) {
205 			printf("%.*s\n",
206 			       value_len, value);
207 		    } else {
208 			printf("%.*s=%.*s\n",
209 			       ident_len, ident, value_len, value);
210 		    }
211 		}
212 		state = NAME;
213 		ident = &r->info[i];
214 		found = 0;
215 		break;
216 	    }
217 	}
218     }
219 
220     read_deallocate(r);
221 
222     if (found_args) {
223 	for (j = 0; j < argc; j++) {
224 	    if (found_args[j] == 0)
225 		return 1;
226 	}
227     }
228 
229     return 0;
230 }
231