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(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) |
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 |
111 return (strerror_r(err, buf, buflen)); |
112#endif 113} 114 115uintmax_t |
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 |
123 p = nptr; |
124 if (base < 0 || base == 1 || base > 36) { |
125 ns = p; |
126 set_errno(EINVAL); |
127 ret = UINTMAX_MAX; 128 goto label_return; |
129 } 130 b = base; 131 132 /* Swallow leading whitespace and get sign, if any. */ 133 neg = false; |
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; |
167 case 'X': case 'x': |
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: |
185 p++; 186 ret = 0; 187 goto label_return; |
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); |
204 ret = UINTMAX_MAX; 205 goto label_return; |
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: |
220 if (endptr != NULL) { 221 if (p == ns) { 222 /* No characters were converted. */ 223 *endptr = (char *)nptr; 224 } else 225 *endptr = (char *)p; 226 } |
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) |
362#define GET_ARG_NUMERIC(val, len) do { \ |
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; \ |
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++; |
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 } |
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; |
461 break; |
462 } default: 463 break; |
464 } |
465 /* Width/precision separator. */ 466 if (*f == '.') 467 f++; 468 else 469 goto label_length; |
470 /* Precision. */ |
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; |
499 case 'q': case 'j': case 't': case 'z': 500 len = *f; |
501 f++; 502 break; |
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; |
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 *); |
567 slen = (prec < 0) ? strlen(s) : prec; |
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(); |
581 } |
582 break; 583 } default: { 584 APPEND_C(*f); 585 f++; 586 break; 587 }} 588 } 589 label_out: --- 75 unchanged lines hidden --- |