imports.c revision 89b31c9619449d5c9b8ebe4e245c2a926e3583e6
1/** 2 * \file imports.c 3 * Standard C library function wrappers. 4 * 5 * Imports are services which the device driver or window system or 6 * operating system provides to the core renderer. The core renderer (Mesa) 7 * will call these functions in order to do memory allocation, simple I/O, 8 * etc. 9 * 10 * Some drivers will want to override/replace this file with something 11 * specialized, but that'll be rare. 12 * 13 * Eventually, I want to move roll the glheader.h file into this. 14 * 15 * \todo Functions still needed: 16 * - scanf 17 * - qsort 18 * - rand and RAND_MAX 19 */ 20 21/* 22 * Mesa 3-D graphics library 23 * Version: 7.1 24 * 25 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 26 * 27 * Permission is hereby granted, free of charge, to any person obtaining a 28 * copy of this software and associated documentation files (the "Software"), 29 * to deal in the Software without restriction, including without limitation 30 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 31 * and/or sell copies of the Software, and to permit persons to whom the 32 * Software is furnished to do so, subject to the following conditions: 33 * 34 * The above copyright notice and this permission notice shall be included 35 * in all copies or substantial portions of the Software. 36 * 37 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 38 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 39 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 40 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 41 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 42 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 43 */ 44 45 46 47#include "imports.h" 48#include "context.h" 49#include "version.h" 50 51#ifdef _GNU_SOURCE 52#include <locale.h> 53#endif 54 55 56#define MAXSTRING 4000 /* for vsnprintf() */ 57 58#ifdef WIN32 59#define vsnprintf _vsnprintf 60#elif defined(__IBMC__) || defined(__IBMCPP__) || ( defined(__VMS) && __CRTL_VER < 70312000 ) 61extern int vsnprintf(char *str, size_t count, const char *fmt, va_list arg); 62#ifdef __VMS 63#include "vsnprintf.c" 64#endif 65#endif 66 67/**********************************************************************/ 68/** \name Memory */ 69/*@{*/ 70 71/** Wrapper around malloc() */ 72void * 73_mesa_malloc(size_t bytes) 74{ 75 return malloc(bytes); 76} 77 78/** Wrapper around calloc() */ 79void * 80_mesa_calloc(size_t bytes) 81{ 82 return calloc(1, bytes); 83} 84 85/** Wrapper around free() */ 86void 87_mesa_free(void *ptr) 88{ 89 free(ptr); 90} 91 92/** 93 * Allocate aligned memory. 94 * 95 * \param bytes number of bytes to allocate. 96 * \param alignment alignment (must be greater than zero). 97 * 98 * Allocates extra memory to accommodate rounding up the address for 99 * alignment and to record the real malloc address. 100 * 101 * \sa _mesa_align_free(). 102 */ 103void * 104_mesa_align_malloc(size_t bytes, unsigned long alignment) 105{ 106#if defined(HAVE_POSIX_MEMALIGN) 107 void *mem; 108 109 (void) posix_memalign(& mem, alignment, bytes); 110 return mem; 111#elif defined(_WIN32) && defined(_MSC_VER) 112 return _aligned_malloc(bytes, alignment); 113#else 114 uintptr_t ptr, buf; 115 116 ASSERT( alignment > 0 ); 117 118 ptr = (uintptr_t) _mesa_malloc(bytes + alignment + sizeof(void *)); 119 if (!ptr) 120 return NULL; 121 122 buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1); 123 *(uintptr_t *)(buf - sizeof(void *)) = ptr; 124 125#ifdef DEBUG 126 /* mark the non-aligned area */ 127 while ( ptr < buf - sizeof(void *) ) { 128 *(unsigned long *)ptr = 0xcdcdcdcd; 129 ptr += sizeof(unsigned long); 130 } 131#endif 132 133 return (void *) buf; 134#endif /* defined(HAVE_POSIX_MEMALIGN) */ 135} 136 137/** 138 * Same as _mesa_align_malloc(), but using _mesa_calloc() instead of 139 * _mesa_malloc() 140 */ 141void * 142_mesa_align_calloc(size_t bytes, unsigned long alignment) 143{ 144#if defined(HAVE_POSIX_MEMALIGN) 145 void *mem; 146 147 mem = _mesa_align_malloc(bytes, alignment); 148 if (mem != NULL) { 149 (void) memset(mem, 0, bytes); 150 } 151 152 return mem; 153#elif defined(_WIN32) && defined(_MSC_VER) 154 void *mem; 155 156 mem = _aligned_malloc(bytes, alignment); 157 if (mem != NULL) { 158 (void) memset(mem, 0, bytes); 159 } 160 161 return mem; 162#else 163 uintptr_t ptr, buf; 164 165 ASSERT( alignment > 0 ); 166 167 ptr = (uintptr_t) _mesa_calloc(bytes + alignment + sizeof(void *)); 168 if (!ptr) 169 return NULL; 170 171 buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1); 172 *(uintptr_t *)(buf - sizeof(void *)) = ptr; 173 174#ifdef DEBUG 175 /* mark the non-aligned area */ 176 while ( ptr < buf - sizeof(void *) ) { 177 *(unsigned long *)ptr = 0xcdcdcdcd; 178 ptr += sizeof(unsigned long); 179 } 180#endif 181 182 return (void *)buf; 183#endif /* defined(HAVE_POSIX_MEMALIGN) */ 184} 185 186/** 187 * Free memory which was allocated with either _mesa_align_malloc() 188 * or _mesa_align_calloc(). 189 * \param ptr pointer to the memory to be freed. 190 * The actual address to free is stored in the word immediately before the 191 * address the client sees. 192 */ 193void 194_mesa_align_free(void *ptr) 195{ 196#if defined(HAVE_POSIX_MEMALIGN) 197 free(ptr); 198#elif defined(_WIN32) && defined(_MSC_VER) 199 _aligned_free(ptr); 200#else 201 void **cubbyHole = (void **) ((char *) ptr - sizeof(void *)); 202 void *realAddr = *cubbyHole; 203 _mesa_free(realAddr); 204#endif /* defined(HAVE_POSIX_MEMALIGN) */ 205} 206 207/** 208 * Reallocate memory, with alignment. 209 */ 210void * 211_mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize, 212 unsigned long alignment) 213{ 214#if defined(_WIN32) && defined(_MSC_VER) 215 (void) oldSize; 216 return _aligned_realloc(oldBuffer, newSize, alignment); 217#else 218 const size_t copySize = (oldSize < newSize) ? oldSize : newSize; 219 void *newBuf = _mesa_align_malloc(newSize, alignment); 220 if (newBuf && oldBuffer && copySize > 0) { 221 _mesa_memcpy(newBuf, oldBuffer, copySize); 222 } 223 if (oldBuffer) 224 _mesa_align_free(oldBuffer); 225 return newBuf; 226#endif 227} 228 229 230 231/** Reallocate memory */ 232void * 233_mesa_realloc(void *oldBuffer, size_t oldSize, size_t newSize) 234{ 235 const size_t copySize = (oldSize < newSize) ? oldSize : newSize; 236 void *newBuffer = _mesa_malloc(newSize); 237 if (newBuffer && oldBuffer && copySize > 0) 238 _mesa_memcpy(newBuffer, oldBuffer, copySize); 239 if (oldBuffer) 240 _mesa_free(oldBuffer); 241 return newBuffer; 242} 243 244/** memcpy wrapper */ 245void * 246_mesa_memcpy(void *dest, const void *src, size_t n) 247{ 248#if defined(SUNOS4) 249 return memcpy((char *) dest, (char *) src, (int) n); 250#else 251 return memcpy(dest, src, n); 252#endif 253} 254 255/** Wrapper around memset() */ 256void 257_mesa_memset( void *dst, int val, size_t n ) 258{ 259#if defined(SUNOS4) 260 memset( (char *) dst, (int) val, (int) n ); 261#else 262 memset(dst, val, n); 263#endif 264} 265 266/** 267 * Fill memory with a constant 16bit word. 268 * \param dst destination pointer. 269 * \param val value. 270 * \param n number of words. 271 */ 272void 273_mesa_memset16( unsigned short *dst, unsigned short val, size_t n ) 274{ 275 while (n-- > 0) 276 *dst++ = val; 277} 278 279/** Wrapper around either memset() or bzero() */ 280void 281_mesa_bzero( void *dst, size_t n ) 282{ 283#if defined(__FreeBSD__) 284 bzero( dst, n ); 285#else 286 memset( dst, 0, n ); 287#endif 288} 289 290/** Wrapper around memcmp() */ 291int 292_mesa_memcmp( const void *s1, const void *s2, size_t n ) 293{ 294#if defined(SUNOS4) 295 return memcmp( (char *) s1, (char *) s2, (int) n ); 296#else 297 return memcmp(s1, s2, n); 298#endif 299} 300 301/*@}*/ 302 303 304/**********************************************************************/ 305/** \name Math */ 306/*@{*/ 307 308/** Wrapper around sin() */ 309double 310_mesa_sin(double a) 311{ 312 return sin(a); 313} 314 315/** Single precision wrapper around sin() */ 316float 317_mesa_sinf(float a) 318{ 319 return (float) sin((double) a); 320} 321 322/** Wrapper around cos() */ 323double 324_mesa_cos(double a) 325{ 326 return cos(a); 327} 328 329/** Single precision wrapper around asin() */ 330float 331_mesa_asinf(float x) 332{ 333 return (float) asin((double) x); 334} 335 336/** Single precision wrapper around atan() */ 337float 338_mesa_atanf(float x) 339{ 340 return (float) atan((double) x); 341} 342 343/** Wrapper around sqrt() */ 344double 345_mesa_sqrtd(double x) 346{ 347 return sqrt(x); 348} 349 350 351/* 352 * A High Speed, Low Precision Square Root 353 * by Paul Lalonde and Robert Dawson 354 * from "Graphics Gems", Academic Press, 1990 355 * 356 * SPARC implementation of a fast square root by table 357 * lookup. 358 * SPARC floating point format is as follows: 359 * 360 * BIT 31 30 23 22 0 361 * sign exponent mantissa 362 */ 363static short sqrttab[0x100]; /* declare table of square roots */ 364 365void 366_mesa_init_sqrt_table(void) 367{ 368#if defined(USE_IEEE) && !defined(DEBUG) 369 unsigned short i; 370 fi_type fi; /* to access the bits of a float in C quickly */ 371 /* we use a union defined in glheader.h */ 372 373 for(i=0; i<= 0x7f; i++) { 374 fi.i = 0; 375 376 /* 377 * Build a float with the bit pattern i as mantissa 378 * and an exponent of 0, stored as 127 379 */ 380 381 fi.i = (i << 16) | (127 << 23); 382 fi.f = _mesa_sqrtd(fi.f); 383 384 /* 385 * Take the square root then strip the first 7 bits of 386 * the mantissa into the table 387 */ 388 389 sqrttab[i] = (fi.i & 0x7fffff) >> 16; 390 391 /* 392 * Repeat the process, this time with an exponent of 393 * 1, stored as 128 394 */ 395 396 fi.i = 0; 397 fi.i = (i << 16) | (128 << 23); 398 fi.f = sqrt(fi.f); 399 sqrttab[i+0x80] = (fi.i & 0x7fffff) >> 16; 400 } 401#else 402 (void) sqrttab; /* silence compiler warnings */ 403#endif /*HAVE_FAST_MATH*/ 404} 405 406 407/** 408 * Single precision square root. 409 */ 410float 411_mesa_sqrtf( float x ) 412{ 413#if defined(USE_IEEE) && !defined(DEBUG) 414 fi_type num; 415 /* to access the bits of a float in C 416 * we use a union from glheader.h */ 417 418 short e; /* the exponent */ 419 if (x == 0.0F) return 0.0F; /* check for square root of 0 */ 420 num.f = x; 421 e = (num.i >> 23) - 127; /* get the exponent - on a SPARC the */ 422 /* exponent is stored with 127 added */ 423 num.i &= 0x7fffff; /* leave only the mantissa */ 424 if (e & 0x01) num.i |= 0x800000; 425 /* the exponent is odd so we have to */ 426 /* look it up in the second half of */ 427 /* the lookup table, so we set the */ 428 /* high bit */ 429 e >>= 1; /* divide the exponent by two */ 430 /* note that in C the shift */ 431 /* operators are sign preserving */ 432 /* for signed operands */ 433 /* Do the table lookup, based on the quaternary mantissa, 434 * then reconstruct the result back into a float 435 */ 436 num.i = ((sqrttab[num.i >> 16]) << 16) | ((e + 127) << 23); 437 438 return num.f; 439#else 440 return (float) _mesa_sqrtd((double) x); 441#endif 442} 443 444 445/** 446 inv_sqrt - A single precision 1/sqrt routine for IEEE format floats. 447 written by Josh Vanderhoof, based on newsgroup posts by James Van Buskirk 448 and Vesa Karvonen. 449*/ 450float 451_mesa_inv_sqrtf(float n) 452{ 453#if defined(USE_IEEE) && !defined(DEBUG) 454 float r0, x0, y0; 455 float r1, x1, y1; 456 float r2, x2, y2; 457#if 0 /* not used, see below -BP */ 458 float r3, x3, y3; 459#endif 460 union { float f; unsigned int i; } u; 461 unsigned int magic; 462 463 /* 464 Exponent part of the magic number - 465 466 We want to: 467 1. subtract the bias from the exponent, 468 2. negate it 469 3. divide by two (rounding towards -inf) 470 4. add the bias back 471 472 Which is the same as subtracting the exponent from 381 and dividing 473 by 2. 474 475 floor(-(x - 127) / 2) + 127 = floor((381 - x) / 2) 476 */ 477 478 magic = 381 << 23; 479 480 /* 481 Significand part of magic number - 482 483 With the current magic number, "(magic - u.i) >> 1" will give you: 484 485 for 1 <= u.f <= 2: 1.25 - u.f / 4 486 for 2 <= u.f <= 4: 1.00 - u.f / 8 487 488 This isn't a bad approximation of 1/sqrt. The maximum difference from 489 1/sqrt will be around .06. After three Newton-Raphson iterations, the 490 maximum difference is less than 4.5e-8. (Which is actually close 491 enough to make the following bias academic...) 492 493 To get a better approximation you can add a bias to the magic 494 number. For example, if you subtract 1/2 of the maximum difference in 495 the first approximation (.03), you will get the following function: 496 497 for 1 <= u.f <= 2: 1.22 - u.f / 4 498 for 2 <= u.f <= 3.76: 0.97 - u.f / 8 499 for 3.76 <= u.f <= 4: 0.72 - u.f / 16 500 (The 3.76 to 4 range is where the result is < .5.) 501 502 This is the closest possible initial approximation, but with a maximum 503 error of 8e-11 after three NR iterations, it is still not perfect. If 504 you subtract 0.0332281 instead of .03, the maximum error will be 505 2.5e-11 after three NR iterations, which should be about as close as 506 is possible. 507 508 for 1 <= u.f <= 2: 1.2167719 - u.f / 4 509 for 2 <= u.f <= 3.73: 0.9667719 - u.f / 8 510 for 3.73 <= u.f <= 4: 0.7167719 - u.f / 16 511 512 */ 513 514 magic -= (int)(0.0332281 * (1 << 25)); 515 516 u.f = n; 517 u.i = (magic - u.i) >> 1; 518 519 /* 520 Instead of Newton-Raphson, we use Goldschmidt's algorithm, which 521 allows more parallelism. From what I understand, the parallelism 522 comes at the cost of less precision, because it lets error 523 accumulate across iterations. 524 */ 525 x0 = 1.0f; 526 y0 = 0.5f * n; 527 r0 = u.f; 528 529 x1 = x0 * r0; 530 y1 = y0 * r0 * r0; 531 r1 = 1.5f - y1; 532 533 x2 = x1 * r1; 534 y2 = y1 * r1 * r1; 535 r2 = 1.5f - y2; 536 537#if 1 538 return x2 * r2; /* we can stop here, and be conformant -BP */ 539#else 540 x3 = x2 * r2; 541 y3 = y2 * r2 * r2; 542 r3 = 1.5f - y3; 543 544 return x3 * r3; 545#endif 546#else 547 return (float) (1.0 / sqrt(n)); 548#endif 549} 550 551 552/** Wrapper around pow() */ 553double 554_mesa_pow(double x, double y) 555{ 556 return pow(x, y); 557} 558 559 560/** 561 * Find the first bit set in a word. 562 */ 563int 564_mesa_ffs(int32_t i) 565{ 566#if (defined(_WIN32) ) || defined(__IBMC__) || defined(__IBMCPP__) 567 register int bit = 0; 568 if (i != 0) { 569 if ((i & 0xffff) == 0) { 570 bit += 16; 571 i >>= 16; 572 } 573 if ((i & 0xff) == 0) { 574 bit += 8; 575 i >>= 8; 576 } 577 if ((i & 0xf) == 0) { 578 bit += 4; 579 i >>= 4; 580 } 581 while ((i & 1) == 0) { 582 bit++; 583 i >>= 1; 584 } 585 bit++; 586 } 587 return bit; 588#else 589 return ffs(i); 590#endif 591} 592 593 594/** 595 * Find position of first bit set in given value. 596 * XXX Warning: this function can only be used on 64-bit systems! 597 * \return position of least-significant bit set, starting at 1, return zero 598 * if no bits set. 599 */ 600int 601_mesa_ffsll(int64_t val) 602{ 603#ifdef ffsll 604 return ffsll(val); 605#else 606 int bit; 607 608 assert(sizeof(val) == 8); 609 610 bit = _mesa_ffs((int32_t)val); 611 if (bit != 0) 612 return bit; 613 614 bit = _mesa_ffs((int32_t)(val >> 32)); 615 if (bit != 0) 616 return 32 + bit; 617 618 return 0; 619#endif 620} 621 622 623/** 624 * Return number of bits set in given GLuint. 625 */ 626unsigned int 627_mesa_bitcount(unsigned int n) 628{ 629 unsigned int bits; 630 for (bits = 0; n > 0; n = n >> 1) { 631 bits += (n & 1); 632 } 633 return bits; 634} 635 636 637/** 638 * Convert a 4-byte float to a 2-byte half float. 639 * Based on code from: 640 * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html 641 */ 642GLhalfARB 643_mesa_float_to_half(float val) 644{ 645 const int flt = *((int *) (void *) &val); 646 const int flt_m = flt & 0x7fffff; 647 const int flt_e = (flt >> 23) & 0xff; 648 const int flt_s = (flt >> 31) & 0x1; 649 int s, e, m = 0; 650 GLhalfARB result; 651 652 /* sign bit */ 653 s = flt_s; 654 655 /* handle special cases */ 656 if ((flt_e == 0) && (flt_m == 0)) { 657 /* zero */ 658 /* m = 0; - already set */ 659 e = 0; 660 } 661 else if ((flt_e == 0) && (flt_m != 0)) { 662 /* denorm -- denorm float maps to 0 half */ 663 /* m = 0; - already set */ 664 e = 0; 665 } 666 else if ((flt_e == 0xff) && (flt_m == 0)) { 667 /* infinity */ 668 /* m = 0; - already set */ 669 e = 31; 670 } 671 else if ((flt_e == 0xff) && (flt_m != 0)) { 672 /* NaN */ 673 m = 1; 674 e = 31; 675 } 676 else { 677 /* regular number */ 678 const int new_exp = flt_e - 127; 679 if (new_exp < -24) { 680 /* this maps to 0 */ 681 /* m = 0; - already set */ 682 e = 0; 683 } 684 else if (new_exp < -14) { 685 /* this maps to a denorm */ 686 unsigned int exp_val = (unsigned int) (-14 - new_exp); /* 2^-exp_val*/ 687 e = 0; 688 switch (exp_val) { 689 case 0: 690 _mesa_warning(NULL, 691 "float_to_half: logical error in denorm creation!\n"); 692 /* m = 0; - already set */ 693 break; 694 case 1: m = 512 + (flt_m >> 14); break; 695 case 2: m = 256 + (flt_m >> 15); break; 696 case 3: m = 128 + (flt_m >> 16); break; 697 case 4: m = 64 + (flt_m >> 17); break; 698 case 5: m = 32 + (flt_m >> 18); break; 699 case 6: m = 16 + (flt_m >> 19); break; 700 case 7: m = 8 + (flt_m >> 20); break; 701 case 8: m = 4 + (flt_m >> 21); break; 702 case 9: m = 2 + (flt_m >> 22); break; 703 case 10: m = 1; break; 704 } 705 } 706 else if (new_exp > 15) { 707 /* map this value to infinity */ 708 /* m = 0; - already set */ 709 e = 31; 710 } 711 else { 712 /* regular */ 713 e = new_exp + 15; 714 m = flt_m >> 13; 715 } 716 } 717 718 result = (s << 15) | (e << 10) | m; 719 return result; 720} 721 722 723/** 724 * Convert a 2-byte half float to a 4-byte float. 725 * Based on code from: 726 * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html 727 */ 728float 729_mesa_half_to_float(GLhalfARB val) 730{ 731 /* XXX could also use a 64K-entry lookup table */ 732 const int m = val & 0x3ff; 733 const int e = (val >> 10) & 0x1f; 734 const int s = (val >> 15) & 0x1; 735 int flt_m, flt_e, flt_s, flt; 736 float result; 737 738 /* sign bit */ 739 flt_s = s; 740 741 /* handle special cases */ 742 if ((e == 0) && (m == 0)) { 743 /* zero */ 744 flt_m = 0; 745 flt_e = 0; 746 } 747 else if ((e == 0) && (m != 0)) { 748 /* denorm -- denorm half will fit in non-denorm single */ 749 const float half_denorm = 1.0f / 16384.0f; /* 2^-14 */ 750 float mantissa = ((float) (m)) / 1024.0f; 751 float sign = s ? -1.0f : 1.0f; 752 return sign * mantissa * half_denorm; 753 } 754 else if ((e == 31) && (m == 0)) { 755 /* infinity */ 756 flt_e = 0xff; 757 flt_m = 0; 758 } 759 else if ((e == 31) && (m != 0)) { 760 /* NaN */ 761 flt_e = 0xff; 762 flt_m = 1; 763 } 764 else { 765 /* regular */ 766 flt_e = e + 112; 767 flt_m = m << 13; 768 } 769 770 flt = (flt_s << 31) | (flt_e << 23) | flt_m; 771 result = *((float *) (void *) &flt); 772 return result; 773} 774 775/*@}*/ 776 777 778/**********************************************************************/ 779/** \name Sort & Search */ 780/*@{*/ 781 782/** 783 * Wrapper for bsearch(). 784 */ 785void * 786_mesa_bsearch( const void *key, const void *base, size_t nmemb, size_t size, 787 int (*compar)(const void *, const void *) ) 788{ 789#if defined(_WIN32_WCE) 790 void *mid; 791 int cmp; 792 while (nmemb) { 793 nmemb >>= 1; 794 mid = (char *)base + nmemb * size; 795 cmp = (*compar)(key, mid); 796 if (cmp == 0) 797 return mid; 798 if (cmp > 0) { 799 base = (char *)mid + size; 800 --nmemb; 801 } 802 } 803 return NULL; 804#else 805 return bsearch(key, base, nmemb, size, compar); 806#endif 807} 808 809/*@}*/ 810 811 812/**********************************************************************/ 813/** \name Environment vars */ 814/*@{*/ 815 816/** 817 * Wrapper for getenv(). 818 */ 819char * 820_mesa_getenv( const char *var ) 821{ 822#if defined(_XBOX) || defined(_WIN32_WCE) 823 return NULL; 824#else 825 return getenv(var); 826#endif 827} 828 829/*@}*/ 830 831 832/**********************************************************************/ 833/** \name String */ 834/*@{*/ 835 836/** Wrapper around strstr() */ 837char * 838_mesa_strstr( const char *haystack, const char *needle ) 839{ 840 return strstr(haystack, needle); 841} 842 843/** Wrapper around strncat() */ 844char * 845_mesa_strncat( char *dest, const char *src, size_t n ) 846{ 847 return strncat(dest, src, n); 848} 849 850/** Wrapper around strcpy() */ 851char * 852_mesa_strcpy( char *dest, const char *src ) 853{ 854 return strcpy(dest, src); 855} 856 857/** Wrapper around strncpy() */ 858char * 859_mesa_strncpy( char *dest, const char *src, size_t n ) 860{ 861 return strncpy(dest, src, n); 862} 863 864/** Wrapper around strlen() */ 865size_t 866_mesa_strlen( const char *s ) 867{ 868 return strlen(s); 869} 870 871/** Wrapper around strcmp() */ 872int 873_mesa_strcmp( const char *s1, const char *s2 ) 874{ 875 return strcmp(s1, s2); 876} 877 878/** Wrapper around strncmp() */ 879int 880_mesa_strncmp( const char *s1, const char *s2, size_t n ) 881{ 882 return strncmp(s1, s2, n); 883} 884 885/** 886 * Implemented using _mesa_malloc() and _mesa_strcpy. 887 * Note that NULL is handled accordingly. 888 */ 889char * 890_mesa_strdup( const char *s ) 891{ 892 if (s) { 893 size_t l = _mesa_strlen(s); 894 char *s2 = (char *) _mesa_malloc(l + 1); 895 if (s2) 896 _mesa_strcpy(s2, s); 897 return s2; 898 } 899 else { 900 return NULL; 901 } 902} 903 904/** Wrapper around atoi() */ 905int 906_mesa_atoi(const char *s) 907{ 908 return atoi(s); 909} 910 911/** Wrapper around strtod() */ 912double 913_mesa_strtod( const char *s, char **end ) 914{ 915#ifdef _GNU_SOURCE 916 static locale_t loc = NULL; 917 if (!loc) { 918 loc = newlocale(LC_CTYPE_MASK, "C", NULL); 919 } 920 return strtod_l(s, end, loc); 921#else 922 return strtod(s, end); 923#endif 924} 925 926/** Compute simple checksum/hash for a string */ 927unsigned int 928_mesa_str_checksum(const char *str) 929{ 930 /* This could probably be much better */ 931 unsigned int sum, i; 932 const char *c; 933 sum = i = 1; 934 for (c = str; *c; c++) 935 sum += *c * (i % 100); 936 return sum; 937} 938 939 940/*@}*/ 941 942 943/**********************************************************************/ 944/** \name I/O */ 945/*@{*/ 946 947/** Wrapper around vsprintf() */ 948int 949_mesa_sprintf( char *str, const char *fmt, ... ) 950{ 951 int r; 952 va_list args; 953 va_start( args, fmt ); 954 r = vsprintf( str, fmt, args ); 955 va_end( args ); 956 return r; 957} 958 959/** Wrapper around vsnprintf() */ 960int 961_mesa_snprintf( char *str, size_t size, const char *fmt, ... ) 962{ 963 int r; 964 va_list args; 965 va_start( args, fmt ); 966 r = vsnprintf( str, size, fmt, args ); 967 va_end( args ); 968 return r; 969} 970 971/** Wrapper around printf(), using vsprintf() for the formatting. */ 972void 973_mesa_printf( const char *fmtString, ... ) 974{ 975 va_list args; 976 va_start( args, fmtString ); 977 vfprintf(stderr, fmtString, args); 978 va_end( args ); 979} 980 981/** Wrapper around fprintf(), using vsprintf() for the formatting. */ 982void 983_mesa_fprintf( FILE *f, const char *fmtString, ... ) 984{ 985 char s[MAXSTRING]; 986 va_list args; 987 va_start( args, fmtString ); 988 vsnprintf(s, MAXSTRING, fmtString, args); 989 va_end( args ); 990 fprintf(f, "%s", s); 991} 992 993 994/** Wrapper around vsprintf() */ 995int 996_mesa_vsprintf( char *str, const char *fmt, va_list args ) 997{ 998 return vsprintf( str, fmt, args ); 999} 1000 1001/*@}*/ 1002 1003 1004/**********************************************************************/ 1005/** \name Diagnostics */ 1006/*@{*/ 1007 1008static void 1009output_if_debug(const char *prefixString, const char *outputString, 1010 GLboolean newline) 1011{ 1012 static int debug = -1; 1013 1014 /* Check the MESA_DEBUG environment variable if it hasn't 1015 * been checked yet. We only have to check it once... 1016 */ 1017 if (debug == -1) { 1018 char *env = _mesa_getenv("MESA_DEBUG"); 1019 1020 /* In a debug build, we print warning messages *unless* 1021 * MESA_DEBUG is 0. In a non-debug build, we don't 1022 * print warning messages *unless* MESA_DEBUG is 1023 * set *to any value*. 1024 */ 1025#ifdef DEBUG 1026 debug = (env != NULL && _mesa_atoi(env) == 0) ? 0 : 1; 1027#else 1028 debug = (env != NULL) ? 1 : 0; 1029#endif 1030 } 1031 1032 /* Now only print the string if we're required to do so. */ 1033 if (debug) { 1034 fprintf(stderr, "%s: %s", prefixString, outputString); 1035 if (newline) 1036 fprintf(stderr, "\n"); 1037 1038#if defined(_WIN32) && !defined(_WIN32_WCE) 1039 /* stderr from windows applications without console is not usually 1040 * visible, so communicate with the debugger instead */ 1041 { 1042 char buf[4096]; 1043 _mesa_snprintf(buf, sizeof(buf), "%s: %s%s", prefixString, outputString, newline ? "\n" : ""); 1044 OutputDebugStringA(buf); 1045 } 1046#endif 1047 } 1048} 1049 1050 1051/** 1052 * Return string version of GL error code. 1053 */ 1054static const char * 1055error_string( GLenum error ) 1056{ 1057 switch (error) { 1058 case GL_NO_ERROR: 1059 return "GL_NO_ERROR"; 1060 case GL_INVALID_VALUE: 1061 return "GL_INVALID_VALUE"; 1062 case GL_INVALID_ENUM: 1063 return "GL_INVALID_ENUM"; 1064 case GL_INVALID_OPERATION: 1065 return "GL_INVALID_OPERATION"; 1066 case GL_STACK_OVERFLOW: 1067 return "GL_STACK_OVERFLOW"; 1068 case GL_STACK_UNDERFLOW: 1069 return "GL_STACK_UNDERFLOW"; 1070 case GL_OUT_OF_MEMORY: 1071 return "GL_OUT_OF_MEMORY"; 1072 case GL_TABLE_TOO_LARGE: 1073 return "GL_TABLE_TOO_LARGE"; 1074 case GL_INVALID_FRAMEBUFFER_OPERATION_EXT: 1075 return "GL_INVALID_FRAMEBUFFER_OPERATION"; 1076 default: 1077 return "unknown"; 1078 } 1079} 1080 1081 1082/** 1083 * When a new type of error is recorded, print a message describing 1084 * previous errors which were accumulated. 1085 */ 1086static void 1087flush_delayed_errors( GLcontext *ctx ) 1088{ 1089 char s[MAXSTRING]; 1090 1091 if (ctx->ErrorDebugCount) { 1092 _mesa_snprintf(s, MAXSTRING, "%d similar %s errors", 1093 ctx->ErrorDebugCount, 1094 error_string(ctx->ErrorValue)); 1095 1096 output_if_debug("Mesa", s, GL_TRUE); 1097 1098 ctx->ErrorDebugCount = 0; 1099 } 1100} 1101 1102 1103/** 1104 * Report a warning (a recoverable error condition) to stderr if 1105 * either DEBUG is defined or the MESA_DEBUG env var is set. 1106 * 1107 * \param ctx GL context. 1108 * \param fmtString printf()-like format string. 1109 */ 1110void 1111_mesa_warning( GLcontext *ctx, const char *fmtString, ... ) 1112{ 1113 char str[MAXSTRING]; 1114 va_list args; 1115 va_start( args, fmtString ); 1116 (void) vsnprintf( str, MAXSTRING, fmtString, args ); 1117 va_end( args ); 1118 1119 if (ctx) 1120 flush_delayed_errors( ctx ); 1121 1122 output_if_debug("Mesa warning", str, GL_TRUE); 1123} 1124 1125 1126/** 1127 * Report an internal implementation problem. 1128 * Prints the message to stderr via fprintf(). 1129 * 1130 * \param ctx GL context. 1131 * \param fmtString problem description string. 1132 */ 1133void 1134_mesa_problem( const GLcontext *ctx, const char *fmtString, ... ) 1135{ 1136 va_list args; 1137 char str[MAXSTRING]; 1138 (void) ctx; 1139 1140 va_start( args, fmtString ); 1141 vsnprintf( str, MAXSTRING, fmtString, args ); 1142 va_end( args ); 1143 1144 fprintf(stderr, "Mesa %s implementation error: %s\n", MESA_VERSION_STRING, str); 1145 fprintf(stderr, "Please report at bugzilla.freedesktop.org\n"); 1146} 1147 1148 1149/** 1150 * Record an OpenGL state error. These usually occur when the user 1151 * passes invalid parameters to a GL function. 1152 * 1153 * If debugging is enabled (either at compile-time via the DEBUG macro, or 1154 * run-time via the MESA_DEBUG environment variable), report the error with 1155 * _mesa_debug(). 1156 * 1157 * \param ctx the GL context. 1158 * \param error the error value. 1159 * \param fmtString printf() style format string, followed by optional args 1160 */ 1161void 1162_mesa_error( GLcontext *ctx, GLenum error, const char *fmtString, ... ) 1163{ 1164 static GLint debug = -1; 1165 1166 /* Check debug environment variable only once: 1167 */ 1168 if (debug == -1) { 1169 const char *debugEnv = _mesa_getenv("MESA_DEBUG"); 1170 1171#ifdef DEBUG 1172 if (debugEnv && _mesa_strstr(debugEnv, "silent")) 1173 debug = GL_FALSE; 1174 else 1175 debug = GL_TRUE; 1176#else 1177 if (debugEnv) 1178 debug = GL_TRUE; 1179 else 1180 debug = GL_FALSE; 1181#endif 1182 } 1183 1184 if (debug) { 1185 if (ctx->ErrorValue == error && 1186 ctx->ErrorDebugFmtString == fmtString) { 1187 ctx->ErrorDebugCount++; 1188 } 1189 else { 1190 char s[MAXSTRING], s2[MAXSTRING]; 1191 va_list args; 1192 1193 flush_delayed_errors( ctx ); 1194 1195 va_start(args, fmtString); 1196 vsnprintf(s, MAXSTRING, fmtString, args); 1197 va_end(args); 1198 1199 _mesa_snprintf(s2, MAXSTRING, "%s in %s", error_string(error), s); 1200 output_if_debug("Mesa: User error", s2, GL_TRUE); 1201 1202 ctx->ErrorDebugFmtString = fmtString; 1203 ctx->ErrorDebugCount = 0; 1204 } 1205 } 1206 1207 _mesa_record_error(ctx, error); 1208} 1209 1210 1211/** 1212 * Report debug information. Print error message to stderr via fprintf(). 1213 * No-op if DEBUG mode not enabled. 1214 * 1215 * \param ctx GL context. 1216 * \param fmtString printf()-style format string, followed by optional args. 1217 */ 1218void 1219_mesa_debug( const GLcontext *ctx, const char *fmtString, ... ) 1220{ 1221#ifdef DEBUG 1222 char s[MAXSTRING]; 1223 va_list args; 1224 va_start(args, fmtString); 1225 vsnprintf(s, MAXSTRING, fmtString, args); 1226 va_end(args); 1227 output_if_debug("Mesa", s, GL_FALSE); 1228#endif /* DEBUG */ 1229 (void) ctx; 1230 (void) fmtString; 1231} 1232 1233/*@}*/ 1234 1235 1236/** 1237 * Wrapper for exit(). 1238 */ 1239void 1240_mesa_exit( int status ) 1241{ 1242 exit(status); 1243} 1244