comparison ezBAMQC/src/htslib/cram/vlen.c @ 0:dfa3745e5fd8

Uploaded
author youngkim
date Thu, 24 Mar 2016 17:12:52 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:dfa3745e5fd8
1 /*
2 Author: James Bonfield (jkb@sanger.ac.uk)
3
4 Copyright (c) 1995-1996 MEDICAL RESEARCH COUNCIL
5 All rights reserved
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9
10 1 Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12
13 2 Redistributions in binary form must reproduce the above copyright notice,
14 this list of conditions and the following disclaimer in the documentation
15 and/or other materials provided with the distribution.
16
17 3 Neither the name of the MEDICAL RESEARCH COUNCIL, THE LABORATORY OF
18 MOLECULAR BIOLOGY nor the names of its contributors may be used to endorse or
19 promote products derived from this software without specific prior written
20 permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
26 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 /*
35 Copyright (c) 2004, 2009, 2011-2012 Genome Research Ltd.
36
37 Author: James Bonfield <jkb@sanger.ac.uk>
38
39 Redistribution and use in source and binary forms, with or without
40 modification, are permitted provided that the following conditions are met:
41
42 1. Redistributions of source code must retain the above copyright notice,
43 this list of conditions and the following disclaimer.
44
45 2. Redistributions in binary form must reproduce the above copyright notice,
46 this list of conditions and the following disclaimer in the documentation
47 and/or other materials provided with the distribution.
48
49 3. Neither the names Genome Research Ltd and Wellcome Trust Sanger
50 Institute nor the names of its contributors may be used to endorse or promote
51 products derived from this software without specific prior written permission.
52
53 THIS SOFTWARE IS PROVIDED BY GENOME RESEARCH LTD AND CONTRIBUTORS "AS IS" AND
54 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
55 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
56 DISCLAIMED. IN NO EVENT SHALL GENOME RESEARCH LTD OR CONTRIBUTORS BE LIABLE
57 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
59 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
60 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
61 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
62 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63 */
64
65 #ifdef HAVE_CONFIG_H
66 #include "io_lib_config.h"
67 #endif
68
69 #include <stdio.h>
70 #include <stdlib.h>
71 #include <stdarg.h>
72 #include <sys/types.h>
73 #include <string.h>
74
75 #include "cram/vlen.h"
76 #include "cram/os.h"
77
78 #ifndef MAX
79 #define MAX(a,b) ((a)>(b)?(a):(b))
80 #endif
81
82 #ifndef ABS
83 #define ABS(a) ((a)>0?(a):-(a))
84 #endif
85
86 /* #define DEBUG_printf(a,n) printf(a,n) */
87 #define DEBUG_printf(a,n)
88
89 /*
90 * vlen: 27/10/95 written by James Bonfield, jkb@mrc-lmb.cam.ac.uk
91 *
92 * Given sprintf style of arguments this routine returns the maximum
93 * size of buffer needed to allocate to use with sprintf. It errs on
94 * the side of caution by being simplistic in its approach: we assume
95 * all numbers are of maximum length.
96 *
97 * Handles the usual type conversions (%[%diuaxXcfeEgGpns]), but not
98 * the 'wide' character conversions (%C and %S).
99 * Precision is handled in the correct formats, including %*.*
100 * notations.
101 * Additionally, some of the more dubious (but probably illegal) cases
102 * are supported (eg "%10%" will expand to " %" on many
103 * systems).
104 *
105 * We also assume that the largest integer and larger pointer are 64
106 * bits, which at least covers the machines we'll need it for.
107 */
108 int flen(char *fmt, ...)
109 {
110 va_list args;
111
112 va_start(args, fmt);
113 return vflen(fmt, args);
114 }
115
116 int vflen(char *fmt, va_list ap)
117 {
118 int len = 0;
119 char *cp, c;
120 long long l;
121 int i;
122 double d;
123
124 /*
125 * This code modifies 'ap', but we do not know if va_list is a structure
126 * or a pointer to an array so we do not know if it is a local variable
127 * or not.
128 * C99 gets around this by defining va_copy() to make copies of ap, but
129 * this does not exist on all systems.
130 * For now, I just assume that when va_list is a pointer the system also
131 * provides a va_copy macro to work around this problem. The only system
132 * I have seen needing this so far was Linux on AMD64.
133 */
134 #if defined(HAVE_VA_COPY)
135 va_list ap_local;
136 va_copy(ap_local, ap);
137 # define ap ap_local
138 #endif
139
140 for(cp = fmt; *cp; cp++) {
141 switch(*cp) {
142
143 /* A format specifier */
144 case '%': {
145 char *endp;
146 long conv_len1=0, conv_len2=0, conv_len=0;
147 signed int arg_size;
148
149 /* Firstly, strip the modifier flags (+-#0 and [space]) */
150 for(; (c=*++cp);) {
151 if ('#' == c)
152 len+=2; /* Worst case of "0x" */
153 else if ('-' == c || '+' == c || ' ' == c)
154 len++;
155 else
156 break;
157 }
158
159 /* Width specifier */
160 l = strtol(cp, &endp, 10);
161 if (endp != cp) {
162 cp = endp;
163 conv_len = conv_len1 = l;
164 } else if (*cp == '*') {
165 conv_len = conv_len1 = (int)va_arg(ap, int);
166 cp++;
167 }
168
169 /* Precision specifier */
170 if ('.' == *cp) {
171 cp++;
172 conv_len2 = strtol(cp, &endp, 10);
173 if (endp != cp) {
174 cp = endp;
175 } else if (*cp == '*') {
176 conv_len2 = (int)va_arg(ap, int);
177 cp++;
178 }
179 conv_len = MAX(conv_len1, conv_len2);
180 }
181
182 /* Short/long identifier */
183 if ('h' == *cp) {
184 arg_size = -1; /* short */
185 cp++;
186 } else if ('l' == *cp) {
187 arg_size = 1; /* long */
188 cp++;
189 if ('l' == *cp) {
190 arg_size = 2; /* long long */
191 cp++;
192 }
193 } else {
194 arg_size = 0; /* int */
195 }
196
197 /* The actual type */
198 switch (*cp) {
199 case '%':
200 /*
201 * Not real ANSI I suspect, but we'll allow for the
202 * completely daft "%10%" example.
203 */
204 len += MAX(conv_len1, 1);
205 break;
206
207 case 'd':
208 case 'i':
209 case 'u':
210 case 'a':
211 case 'x':
212 case 'X':
213 /* Remember: char and short are sent as int on the stack */
214 if (arg_size == -1)
215 l = (long)va_arg(ap, int);
216 else if (arg_size == 1)
217 l = va_arg(ap, long);
218 else if (arg_size == 2)
219 l = va_arg(ap, long long);
220 else
221 l = (long)va_arg(ap, int);
222
223 DEBUG_printf("%d", l);
224
225 /*
226 * No number can be more than 24 characters so we'll take
227 * the max of conv_len and 24 (23 is len(2^64) in octal).
228 * All that work above and we then go and estimate ;-),
229 * but it's needed incase someone does %500d.
230 */
231 len += MAX(conv_len, 23);
232 break;
233
234 case 'c':
235 i = va_arg(ap, int);
236 DEBUG_printf("%c", i);
237 /*
238 * Note that %10c and %.10c act differently.
239 * Besides, I think precision is not really allowed for %c.
240 */
241 len += MAX(conv_len1, i>=0x80 ?MB_CUR_MAX :1);
242 break;
243
244 case 'f':
245 d = va_arg(ap, double);
246 DEBUG_printf("%f", d);
247 /*
248 * Maybe "Inf" or "NaN", but we'll not worry about that.
249 * Again, err on side of caution and take max of conv_len
250 * and max length of a double. The worst case I can
251 * think of is 317 characters (-1[308 zeros].000000)
252 * without using precision codes. That's horrid. I
253 * cheat and either use 317 or 15 depending on how
254 * large the number is as I reckon 99% of floats
255 * aren't that long.
256 */
257 l = (ABS(d) > 1000000) ? 317 : 15;
258 l = MAX(l, conv_len1 + 2);
259 if (conv_len2) l += conv_len2 - 6;
260 len += l;
261 break;
262
263 case 'e':
264 case 'E':
265 case 'g':
266 case 'G':
267 d = va_arg(ap, double);
268 DEBUG_printf("%g", d);
269 /*
270 * Maybe "Inf" or "NaN", but we'll not worry about that
271 * Again, err on side of caution and take max of conv_len
272 * and max length of a double (which defaults to only
273 * '-' + 6 + '.' + 'E[+-]xxx' == 13.
274 */
275 len += MAX(conv_len, 13);
276 break;
277
278 case 'p':
279 l = (long)va_arg(ap, void *);
280 /*
281 * Max pointer is 64bits == 16 chars (on alpha),
282 * == 20 with + "0x".
283 */
284 DEBUG_printf("%p", (void *)l);
285 len += MAX(conv_len, 20);
286 break;
287
288 case 'n':
289 /* produces no output */
290 break;
291
292 case 's': {
293 char *s = (char *)va_arg(ap, char *);
294 DEBUG_printf("%s", s);
295
296 if (!conv_len2) {
297 len += MAX(conv_len, (int)strlen(s));
298 } else {
299 len += conv_len;
300 }
301 break;
302 }
303
304 default:
305 /* wchar_t types of 'C' and 'S' aren't supported */
306 DEBUG_printf("Arg is %c\n", *cp);
307 }
308
309 }
310
311 case '\0':
312 break;
313
314 default:
315 DEBUG_printf("%c", *cp);
316 len++;
317 }
318 }
319
320 va_end(ap);
321
322 return len+1; /* one for the null character */
323 }
324
325 #if 0
326 int main() {
327 int l;
328 char buf[10000];
329
330 sprintf(buf, "d: %d\n", 500);
331 l = flen("d: %d\n", 500);
332 printf("%d %d\n\n", strlen(buf), l);
333
334 sprintf(buf, "");
335 l = flen("");
336 printf("%d %d\n\n", strlen(buf), l);
337
338 sprintf(buf, "%s\n","test");
339 l = flen("%s\n", "test");
340 printf("%d %d\n\n", strlen(buf), l);
341
342 sprintf(buf, "%c\n", 'a');
343 l = flen("%c\n", 'a');
344 printf("%d %d\n\n", strlen(buf), l);
345
346 sprintf(buf, "%31.30f\n", -9999.99);
347 l = flen("%31.30f\n", -9999.99);
348 printf("%d %d\n\n", strlen(buf), l);
349
350 sprintf(buf, "%f\n", -1e308);
351 l = flen("%f\n", -1e308);
352 printf("%d %d\n\n", strlen(buf), l);
353
354 sprintf(buf, "%.9f\n", -1e308);
355 l = flen("%.9f\n", -1e308);
356 printf("%d %d\n\n", strlen(buf), l);
357
358 sprintf(buf, "%10.20f\n", -1.999222333);
359 l = flen("%10.20f\n", -1.999222333);
360 printf("%d %d\n\n", strlen(buf), l);
361
362 sprintf(buf, "%#g\n", -3.14159265358e-222);
363 l = flen("%#g\n", -3.1415927e-222);
364 printf("%d %d\n\n", strlen(buf), l);
365
366 sprintf(buf, "%e\n", -123456789123456789.1);
367 l = flen("%e\n", -123456789123456789.1);
368 printf("%d %d\n\n", strlen(buf), l);
369
370 sprintf(buf, "%c %f %d %s %c %g %ld %s\n", 'a', 3.1, 9, "one", 'b', 4.2, 9, "two");
371 l = flen("%c %f %d %s %c %g %ld %s\n", 'a', 3.1, 9, "one", 'b', 4.2, 9, "two");
372 printf("%d %d\n\n", strlen(buf), l);
373
374 sprintf(buf, "%*.*e %*c\n", 10, 5, 9.0, 20, 'x');
375 l = flen("%*.*e %*c\n", 10, 5, 9.0, 20, 'x');
376 printf("%d %d\n\n", strlen(buf), l);
377
378 sprintf(buf, "%10c\n", 'z');
379 l = flen("%10c\n", 'z');
380 printf("%d %d\n\n", strlen(buf), l);
381
382 sprintf(buf, "%.10c\n", 'z');
383 l = flen("%.10c\n", 'z');
384 printf("%d %d\n\n", strlen(buf), l);
385
386 sprintf(buf, "%10d\n", 'z');
387 l = flen("%10d\n", 'z');
388 printf("%d %d\n\n", strlen(buf), l);
389
390 sprintf(buf, "%.10d\n", 'z');
391 l = flen("%.10d\n", 'z');
392 printf("%d %d\n\n", strlen(buf), l);
393
394 sprintf(buf, "%10%\n");
395 l = flen("%10%\n");
396 printf("%d %d\n\n", strlen(buf), l);
397
398 sprintf(buf, "%.10%\n");
399 l = flen("%.10%\n");
400 printf("%d %d\n\n", strlen(buf), l);
401
402 sprintf(buf, "%s\n", "0123456789");
403 l = flen("%s\n", "0123456789");
404 printf("%d %d\n\n", strlen(buf), l);
405
406 sprintf(buf, "%5s\n", "0123456789");
407 l = flen("%5s\n", "0123456789");
408 printf("%d %d\n\n", strlen(buf), l);
409
410 sprintf(buf, "%50s\n", "0123456789");
411 l = flen("%50s\n", "0123456789");
412 printf("%d %d\n\n", strlen(buf), l);
413
414 sprintf(buf, "%.5s\n", "0123456789");
415 l = flen("%.5s\n", "0123456789");
416 printf("%d %d\n\n", strlen(buf), l);
417
418 sprintf(buf, "%.50s\n", "0123456789");
419 l = flen("%.50s\n", "0123456789");
420 printf("%d %d\n\n", strlen(buf), l);
421
422 sprintf(buf, "%5.50s\n", "0123456789");
423 l = flen("%5.50s\n", "0123456789");
424 printf("%d %d\n\n", strlen(buf), l);
425
426 sprintf(buf, "%50.5s\n", "0123456789");
427 l = flen("%50.5s\n", "0123456789");
428 printf("%d %d\n\n", strlen(buf), l);
429
430 return 0;
431 }
432 #endif