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