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