Mercurial > repos > youngkim > ezbamqc
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 |
