util.c (242844) | util.c (261071) |
---|---|
1#define assert(e) do { \ 2 if (config_debug && !(e)) { \ 3 malloc_write("<jemalloc>: Failed assertion\n"); \ 4 abort(); \ 5 } \ 6} while (0) 7 8#define not_reached() do { \ --- 79 unchanged lines hidden (view full) --- 88 wrtmessage(NULL, s); 89} 90 91/* 92 * glibc provides a non-standard strerror_r() when _GNU_SOURCE is defined, so 93 * provide a wrapper. 94 */ 95int | 1#define assert(e) do { \ 2 if (config_debug && !(e)) { \ 3 malloc_write("<jemalloc>: Failed assertion\n"); \ 4 abort(); \ 5 } \ 6} while (0) 7 8#define not_reached() do { \ --- 79 unchanged lines hidden (view full) --- 88 wrtmessage(NULL, s); 89} 90 91/* 92 * glibc provides a non-standard strerror_r() when _GNU_SOURCE is defined, so 93 * provide a wrapper. 94 */ 95int |
96buferror(char *buf, size_t buflen) | 96buferror(int err, char *buf, size_t buflen) |
97{ 98 99#ifdef _WIN32 100 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, 101 (LPSTR)buf, buflen, NULL); 102 return (0); 103#elif defined(_GNU_SOURCE) | 97{ 98 99#ifdef _WIN32 100 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, 101 (LPSTR)buf, buflen, NULL); 102 return (0); 103#elif defined(_GNU_SOURCE) |
104 char *b = strerror_r(errno, buf, buflen); | 104 char *b = strerror_r(err, buf, buflen); |
105 if (b != buf) { 106 strncpy(buf, b, buflen); 107 buf[buflen-1] = '\0'; 108 } 109 return (0); 110#else | 105 if (b != buf) { 106 strncpy(buf, b, buflen); 107 buf[buflen-1] = '\0'; 108 } 109 return (0); 110#else |
111 return (strerror_r(errno, buf, buflen)); | 111 return (strerror_r(err, buf, buflen)); |
112#endif 113} 114 115uintmax_t | 112#endif 113} 114 115uintmax_t |
116malloc_strtoumax(const char *nptr, char **endptr, int base) | 116malloc_strtoumax(const char *restrict nptr, char **restrict endptr, int base) |
117{ 118 uintmax_t ret, digit; 119 int b; 120 bool neg; 121 const char *p, *ns; 122 | 117{ 118 uintmax_t ret, digit; 119 int b; 120 bool neg; 121 const char *p, *ns; 122 |
123 p = nptr; |
|
123 if (base < 0 || base == 1 || base > 36) { | 124 if (base < 0 || base == 1 || base > 36) { |
125 ns = p; |
|
124 set_errno(EINVAL); | 126 set_errno(EINVAL); |
125 return (UINTMAX_MAX); | 127 ret = UINTMAX_MAX; 128 goto label_return; |
126 } 127 b = base; 128 129 /* Swallow leading whitespace and get sign, if any. */ 130 neg = false; | 129 } 130 b = base; 131 132 /* Swallow leading whitespace and get sign, if any. */ 133 neg = false; |
131 p = nptr; | |
132 while (true) { 133 switch (*p) { 134 case '\t': case '\n': case '\v': case '\f': case '\r': case ' ': 135 p++; 136 break; 137 case '-': 138 neg = true; 139 /* Fall through. */ --- 17 unchanged lines hidden (view full) --- 157 switch (p[1]) { 158 case '0': case '1': case '2': case '3': case '4': case '5': 159 case '6': case '7': 160 if (b == 0) 161 b = 8; 162 if (b == 8) 163 p++; 164 break; | 134 while (true) { 135 switch (*p) { 136 case '\t': case '\n': case '\v': case '\f': case '\r': case ' ': 137 p++; 138 break; 139 case '-': 140 neg = true; 141 /* Fall through. */ --- 17 unchanged lines hidden (view full) --- 159 switch (p[1]) { 160 case '0': case '1': case '2': case '3': case '4': case '5': 161 case '6': case '7': 162 if (b == 0) 163 b = 8; 164 if (b == 8) 165 p++; 166 break; |
165 case 'x': | 167 case 'X': case 'x': |
166 switch (p[2]) { 167 case '0': case '1': case '2': case '3': case '4': 168 case '5': case '6': case '7': case '8': case '9': 169 case 'A': case 'B': case 'C': case 'D': case 'E': 170 case 'F': 171 case 'a': case 'b': case 'c': case 'd': case 'e': 172 case 'f': 173 if (b == 0) 174 b = 16; 175 if (b == 16) 176 p += 2; 177 break; 178 default: 179 break; 180 } 181 break; 182 default: | 168 switch (p[2]) { 169 case '0': case '1': case '2': case '3': case '4': 170 case '5': case '6': case '7': case '8': case '9': 171 case 'A': case 'B': case 'C': case 'D': case 'E': 172 case 'F': 173 case 'a': case 'b': case 'c': case 'd': case 'e': 174 case 'f': 175 if (b == 0) 176 b = 16; 177 if (b == 16) 178 p += 2; 179 break; 180 default: 181 break; 182 } 183 break; 184 default: |
183 break; | 185 p++; 186 ret = 0; 187 goto label_return; |
184 } 185 } 186 if (b == 0) 187 b = 10; 188 189 /* Convert. */ 190 ret = 0; 191 while ((*p >= '0' && *p <= '9' && (digit = *p - '0') < b) 192 || (*p >= 'A' && *p <= 'Z' && (digit = 10 + *p - 'A') < b) 193 || (*p >= 'a' && *p <= 'z' && (digit = 10 + *p - 'a') < b)) { 194 uintmax_t pret = ret; 195 ret *= b; 196 ret += digit; 197 if (ret < pret) { 198 /* Overflow. */ 199 set_errno(ERANGE); | 188 } 189 } 190 if (b == 0) 191 b = 10; 192 193 /* Convert. */ 194 ret = 0; 195 while ((*p >= '0' && *p <= '9' && (digit = *p - '0') < b) 196 || (*p >= 'A' && *p <= 'Z' && (digit = 10 + *p - 'A') < b) 197 || (*p >= 'a' && *p <= 'z' && (digit = 10 + *p - 'a') < b)) { 198 uintmax_t pret = ret; 199 ret *= b; 200 ret += digit; 201 if (ret < pret) { 202 /* Overflow. */ 203 set_errno(ERANGE); |
200 return (UINTMAX_MAX); | 204 ret = UINTMAX_MAX; 205 goto label_return; |
201 } 202 p++; 203 } 204 if (neg) 205 ret = -ret; 206 | 206 } 207 p++; 208 } 209 if (neg) 210 ret = -ret; 211 |
212 if (p == ns) { 213 /* No conversion performed. */ 214 set_errno(EINVAL); 215 ret = UINTMAX_MAX; 216 goto label_return; 217 } 218 219label_return: |
|
207 if (endptr != NULL) { 208 if (p == ns) { 209 /* No characters were converted. */ 210 *endptr = (char *)nptr; 211 } else 212 *endptr = (char *)p; 213 } | 220 if (endptr != NULL) { 221 if (p == ns) { 222 /* No characters were converted. */ 223 *endptr = (char *)nptr; 224 } else 225 *endptr = (char *)p; 226 } |
214 | |
215 return (ret); 216} 217 218static char * 219u2s(uintmax_t x, unsigned base, bool uppercase, char *s, size_t *slen_p) 220{ 221 unsigned i; 222 --- 119 unchanged lines hidden (view full) --- 342 APPEND_S(s, slen); \ 343 /* Right padding. */ \ 344 if (left_justify && pad_len != 0) { \ 345 size_t j; \ 346 for (j = 0; j < pad_len; j++) \ 347 APPEND_C(' '); \ 348 } \ 349} while (0) | 227 return (ret); 228} 229 230static char * 231u2s(uintmax_t x, unsigned base, bool uppercase, char *s, size_t *slen_p) 232{ 233 unsigned i; 234 --- 119 unchanged lines hidden (view full) --- 354 APPEND_S(s, slen); \ 355 /* Right padding. */ \ 356 if (left_justify && pad_len != 0) { \ 357 size_t j; \ 358 for (j = 0; j < pad_len; j++) \ 359 APPEND_C(' '); \ 360 } \ 361} while (0) |
350#define GET_ARG_NUMERIC(val, len) do { \ | 362#define GET_ARG_NUMERIC(val, len) do { \ |
351 switch (len) { \ 352 case '?': \ 353 val = va_arg(ap, int); \ 354 break; \ 355 case '?' | 0x80: \ 356 val = va_arg(ap, unsigned int); \ 357 break; \ 358 case 'l': \ --- 6 unchanged lines hidden (view full) --- 365 val = va_arg(ap, long long); \ 366 break; \ 367 case 'q' | 0x80: \ 368 val = va_arg(ap, unsigned long long); \ 369 break; \ 370 case 'j': \ 371 val = va_arg(ap, intmax_t); \ 372 break; \ | 363 switch (len) { \ 364 case '?': \ 365 val = va_arg(ap, int); \ 366 break; \ 367 case '?' | 0x80: \ 368 val = va_arg(ap, unsigned int); \ 369 break; \ 370 case 'l': \ --- 6 unchanged lines hidden (view full) --- 377 val = va_arg(ap, long long); \ 378 break; \ 379 case 'q' | 0x80: \ 380 val = va_arg(ap, unsigned long long); \ 381 break; \ 382 case 'j': \ 383 val = va_arg(ap, intmax_t); \ 384 break; \ |
385 case 'j' | 0x80: \ 386 val = va_arg(ap, uintmax_t); \ 387 break; \ |
|
373 case 't': \ 374 val = va_arg(ap, ptrdiff_t); \ 375 break; \ 376 case 'z': \ 377 val = va_arg(ap, ssize_t); \ 378 break; \ 379 case 'z' | 0x80: \ 380 val = va_arg(ap, size_t); \ --- 15 unchanged lines hidden (view full) --- 396 bool left_justify = false; 397 bool plus_space = false; 398 bool plus_plus = false; 399 int prec = -1; 400 int width = -1; 401 unsigned char len = '?'; 402 403 f++; | 388 case 't': \ 389 val = va_arg(ap, ptrdiff_t); \ 390 break; \ 391 case 'z': \ 392 val = va_arg(ap, ssize_t); \ 393 break; \ 394 case 'z' | 0x80: \ 395 val = va_arg(ap, size_t); \ --- 15 unchanged lines hidden (view full) --- 411 bool left_justify = false; 412 bool plus_space = false; 413 bool plus_plus = false; 414 int prec = -1; 415 int width = -1; 416 unsigned char len = '?'; 417 418 f++; |
404 if (*f == '%') { 405 /* %% */ 406 APPEND_C(*f); 407 break; 408 } | |
409 /* Flags. */ 410 while (true) { 411 switch (*f) { 412 case '#': 413 assert(alt_form == false); 414 alt_form = true; 415 break; 416 case '-': --- 13 unchanged lines hidden (view full) --- 430 f++; 431 } 432 /* Width. */ 433 label_width: 434 switch (*f) { 435 case '*': 436 width = va_arg(ap, int); 437 f++; | 419 /* Flags. */ 420 while (true) { 421 switch (*f) { 422 case '#': 423 assert(alt_form == false); 424 alt_form = true; 425 break; 426 case '-': --- 13 unchanged lines hidden (view full) --- 440 f++; 441 } 442 /* Width. */ 443 label_width: 444 switch (*f) { 445 case '*': 446 width = va_arg(ap, int); 447 f++; |
448 if (width < 0) { 449 left_justify = true; 450 width = -width; 451 } |
|
438 break; 439 case '0': case '1': case '2': case '3': case '4': 440 case '5': case '6': case '7': case '8': case '9': { 441 uintmax_t uwidth; 442 set_errno(0); 443 uwidth = malloc_strtoumax(f, (char **)&f, 10); 444 assert(uwidth != UINTMAX_MAX || get_errno() != 445 ERANGE); 446 width = (int)uwidth; | 452 break; 453 case '0': case '1': case '2': case '3': case '4': 454 case '5': case '6': case '7': case '8': case '9': { 455 uintmax_t uwidth; 456 set_errno(0); 457 uwidth = malloc_strtoumax(f, (char **)&f, 10); 458 assert(uwidth != UINTMAX_MAX || get_errno() != 459 ERANGE); 460 width = (int)uwidth; |
447 if (*f == '.') { 448 f++; 449 goto label_precision; 450 } else 451 goto label_length; | |
452 break; | 461 break; |
453 } case '.': 454 f++; 455 goto label_precision; 456 default: goto label_length; | 462 } default: 463 break; |
457 } | 464 } |
465 /* Width/precision separator. */ 466 if (*f == '.') 467 f++; 468 else 469 goto label_length; |
|
458 /* Precision. */ | 470 /* Precision. */ |
459 label_precision: | |
460 switch (*f) { 461 case '*': 462 prec = va_arg(ap, int); 463 f++; 464 break; 465 case '0': case '1': case '2': case '3': case '4': 466 case '5': case '6': case '7': case '8': case '9': { 467 uintmax_t uprec; --- 12 unchanged lines hidden (view full) --- 480 case 'l': 481 f++; 482 if (*f == 'l') { 483 len = 'q'; 484 f++; 485 } else 486 len = 'l'; 487 break; | 471 switch (*f) { 472 case '*': 473 prec = va_arg(ap, int); 474 f++; 475 break; 476 case '0': case '1': case '2': case '3': case '4': 477 case '5': case '6': case '7': case '8': case '9': { 478 uintmax_t uprec; --- 12 unchanged lines hidden (view full) --- 491 case 'l': 492 f++; 493 if (*f == 'l') { 494 len = 'q'; 495 f++; 496 } else 497 len = 'l'; 498 break; |
488 case 'j': 489 len = 'j'; | 499 case 'q': case 'j': case 't': case 'z': 500 len = *f; |
490 f++; 491 break; | 501 f++; 502 break; |
492 case 't': 493 len = 't'; 494 f++; 495 break; 496 case 'z': 497 len = 'z'; 498 f++; 499 break; | |
500 default: break; 501 } 502 /* Conversion specifier. */ 503 switch (*f) { 504 char *s; 505 size_t slen; | 503 default: break; 504 } 505 /* Conversion specifier. */ 506 switch (*f) { 507 char *s; 508 size_t slen; |
509 case '%': 510 /* %% */ 511 APPEND_C(*f); 512 f++; 513 break; |
|
506 case 'd': case 'i': { 507 intmax_t val JEMALLOC_CC_SILENCE_INIT(0); 508 char buf[D2S_BUFSIZE]; 509 510 GET_ARG_NUMERIC(val, len); 511 s = d2s(val, (plus_plus ? '+' : (plus_space ? 512 ' ' : '-')), buf, &slen); 513 APPEND_PADDED_S(s, slen, width, left_justify); --- 37 unchanged lines hidden (view full) --- 551 buf[1] = '\0'; 552 APPEND_PADDED_S(buf, 1, width, left_justify); 553 f++; 554 break; 555 } case 's': 556 assert(len == '?' || len == 'l'); 557 assert_not_implemented(len != 'l'); 558 s = va_arg(ap, char *); | 514 case 'd': case 'i': { 515 intmax_t val JEMALLOC_CC_SILENCE_INIT(0); 516 char buf[D2S_BUFSIZE]; 517 518 GET_ARG_NUMERIC(val, len); 519 s = d2s(val, (plus_plus ? '+' : (plus_space ? 520 ' ' : '-')), buf, &slen); 521 APPEND_PADDED_S(s, slen, width, left_justify); --- 37 unchanged lines hidden (view full) --- 559 buf[1] = '\0'; 560 APPEND_PADDED_S(buf, 1, width, left_justify); 561 f++; 562 break; 563 } case 's': 564 assert(len == '?' || len == 'l'); 565 assert_not_implemented(len != 'l'); 566 s = va_arg(ap, char *); |
559 slen = (prec == -1) ? strlen(s) : prec; | 567 slen = (prec < 0) ? strlen(s) : prec; |
560 APPEND_PADDED_S(s, slen, width, left_justify); 561 f++; 562 break; 563 case 'p': { 564 uintmax_t val; 565 char buf[X2S_BUFSIZE]; 566 567 GET_ARG_NUMERIC(val, 'p'); 568 s = x2s(val, true, false, buf, &slen); 569 APPEND_PADDED_S(s, slen, width, left_justify); 570 f++; 571 break; | 568 APPEND_PADDED_S(s, slen, width, left_justify); 569 f++; 570 break; 571 case 'p': { 572 uintmax_t val; 573 char buf[X2S_BUFSIZE]; 574 575 GET_ARG_NUMERIC(val, 'p'); 576 s = x2s(val, true, false, buf, &slen); 577 APPEND_PADDED_S(s, slen, width, left_justify); 578 f++; 579 break; |
580 } default: not_reached(); |
|
572 } | 581 } |
573 default: not_implemented(); 574 } | |
575 break; 576 } default: { 577 APPEND_C(*f); 578 f++; 579 break; 580 }} 581 } 582 label_out: --- 75 unchanged lines hidden --- | 582 break; 583 } default: { 584 APPEND_C(*f); 585 f++; 586 break; 587 }} 588 } 589 label_out: --- 75 unchanged lines hidden --- |