imports.c revision 29c471aafc6a3fef23d553e31a555d1782854a77
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 )
65extern 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() */
76void *
77_mesa_malloc(size_t bytes)
78{
79   return malloc(bytes);
80}
81
82/** Wrapper around calloc() */
83void *
84_mesa_calloc(size_t bytes)
85{
86   return calloc(1, bytes);
87}
88
89/** Wrapper around free() */
90void
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 */
107void *
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 */
143void *
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 */
186void
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 */
201void *
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 */
218void *
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 */
231void *
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() */
242void
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 */
258void
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() */
266void
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() */
277int
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() */
295double
296_mesa_sin(double a)
297{
298   return sin(a);
299}
300
301/** Single precision wrapper around sin() */
302float
303_mesa_sinf(float a)
304{
305   return (float) sin((double) a);
306}
307
308/** Wrapper around cos() */
309double
310_mesa_cos(double a)
311{
312   return cos(a);
313}
314
315/** Single precision wrapper around asin() */
316float
317_mesa_asinf(float x)
318{
319   return (float) asin((double) x);
320}
321
322/** Single precision wrapper around atan() */
323float
324_mesa_atanf(float x)
325{
326   return (float) atan((double) x);
327}
328
329/** Wrapper around sqrt() */
330double
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 */
349static short sqrttab[0x100];    /* declare table of square roots */
350
351static void init_sqrt_table(void)
352{
353#if defined(USE_IEEE) && !defined(DEBUG)
354   unsigned short i;
355   fi_type fi;     /* to access the bits of a float in  C quickly  */
356                   /* we use a union defined in glheader.h         */
357
358   for(i=0; i<= 0x7f; i++) {
359      fi.i = 0;
360
361      /*
362       * Build a float with the bit pattern i as mantissa
363       * and an exponent of 0, stored as 127
364       */
365
366      fi.i = (i << 16) | (127 << 23);
367      fi.f = _mesa_sqrtd(fi.f);
368
369      /*
370       * Take the square root then strip the first 7 bits of
371       * the mantissa into the table
372       */
373
374      sqrttab[i] = (fi.i & 0x7fffff) >> 16;
375
376      /*
377       * Repeat the process, this time with an exponent of
378       * 1, stored as 128
379       */
380
381      fi.i = 0;
382      fi.i = (i << 16) | (128 << 23);
383      fi.f = sqrt(fi.f);
384      sqrttab[i+0x80] = (fi.i & 0x7fffff) >> 16;
385   }
386#else
387   (void) sqrttab;  /* silence compiler warnings */
388#endif /*HAVE_FAST_MATH*/
389}
390
391
392/**
393 * Single precision square root.
394 */
395float
396_mesa_sqrtf( float x )
397{
398#if defined(USE_IEEE) && !defined(DEBUG)
399   fi_type num;
400                                /* to access the bits of a float in C
401                                 * we use a union from glheader.h     */
402
403   short e;                     /* the exponent */
404   if (x == 0.0F) return 0.0F;  /* check for square root of 0 */
405   num.f = x;
406   e = (num.i >> 23) - 127;     /* get the exponent - on a SPARC the */
407                                /* exponent is stored with 127 added */
408   num.i &= 0x7fffff;           /* leave only the mantissa */
409   if (e & 0x01) num.i |= 0x800000;
410                                /* the exponent is odd so we have to */
411                                /* look it up in the second half of  */
412                                /* the lookup table, so we set the   */
413                                /* high bit                                */
414   e >>= 1;                     /* divide the exponent by two */
415                                /* note that in C the shift */
416                                /* operators are sign preserving */
417                                /* for signed operands */
418   /* Do the table lookup, based on the quaternary mantissa,
419    * then reconstruct the result back into a float
420    */
421   num.i = ((sqrttab[num.i >> 16]) << 16) | ((e + 127) << 23);
422
423   return num.f;
424#else
425   return (float) _mesa_sqrtd((double) x);
426#endif
427}
428
429
430/**
431 inv_sqrt - A single precision 1/sqrt routine for IEEE format floats.
432 written by Josh Vanderhoof, based on newsgroup posts by James Van Buskirk
433 and Vesa Karvonen.
434*/
435float
436_mesa_inv_sqrtf(float n)
437{
438#if defined(USE_IEEE) && !defined(DEBUG)
439        float r0, x0, y0;
440        float r1, x1, y1;
441        float r2, x2, y2;
442#if 0 /* not used, see below -BP */
443        float r3, x3, y3;
444#endif
445        union { float f; unsigned int i; } u;
446        unsigned int magic;
447
448        /*
449         Exponent part of the magic number -
450
451         We want to:
452         1. subtract the bias from the exponent,
453         2. negate it
454         3. divide by two (rounding towards -inf)
455         4. add the bias back
456
457         Which is the same as subtracting the exponent from 381 and dividing
458         by 2.
459
460         floor(-(x - 127) / 2) + 127 = floor((381 - x) / 2)
461        */
462
463        magic = 381 << 23;
464
465        /*
466         Significand part of magic number -
467
468         With the current magic number, "(magic - u.i) >> 1" will give you:
469
470         for 1 <= u.f <= 2: 1.25 - u.f / 4
471         for 2 <= u.f <= 4: 1.00 - u.f / 8
472
473         This isn't a bad approximation of 1/sqrt.  The maximum difference from
474         1/sqrt will be around .06.  After three Newton-Raphson iterations, the
475         maximum difference is less than 4.5e-8.  (Which is actually close
476         enough to make the following bias academic...)
477
478         To get a better approximation you can add a bias to the magic
479         number.  For example, if you subtract 1/2 of the maximum difference in
480         the first approximation (.03), you will get the following function:
481
482         for 1 <= u.f <= 2:    1.22 - u.f / 4
483         for 2 <= u.f <= 3.76: 0.97 - u.f / 8
484         for 3.76 <= u.f <= 4: 0.72 - u.f / 16
485         (The 3.76 to 4 range is where the result is < .5.)
486
487         This is the closest possible initial approximation, but with a maximum
488         error of 8e-11 after three NR iterations, it is still not perfect.  If
489         you subtract 0.0332281 instead of .03, the maximum error will be
490         2.5e-11 after three NR iterations, which should be about as close as
491         is possible.
492
493         for 1 <= u.f <= 2:    1.2167719 - u.f / 4
494         for 2 <= u.f <= 3.73: 0.9667719 - u.f / 8
495         for 3.73 <= u.f <= 4: 0.7167719 - u.f / 16
496
497        */
498
499        magic -= (int)(0.0332281 * (1 << 25));
500
501        u.f = n;
502        u.i = (magic - u.i) >> 1;
503
504        /*
505         Instead of Newton-Raphson, we use Goldschmidt's algorithm, which
506         allows more parallelism.  From what I understand, the parallelism
507         comes at the cost of less precision, because it lets error
508         accumulate across iterations.
509        */
510        x0 = 1.0f;
511        y0 = 0.5f * n;
512        r0 = u.f;
513
514        x1 = x0 * r0;
515        y1 = y0 * r0 * r0;
516        r1 = 1.5f - y1;
517
518        x2 = x1 * r1;
519        y2 = y1 * r1 * r1;
520        r2 = 1.5f - y2;
521
522#if 1
523        return x2 * r2;  /* we can stop here, and be conformant -BP */
524#else
525        x3 = x2 * r2;
526        y3 = y2 * r2 * r2;
527        r3 = 1.5f - y3;
528
529        return x3 * r3;
530#endif
531#else
532        return (float) (1.0 / sqrt(n));
533#endif
534}
535
536
537/** Wrapper around pow() */
538double
539_mesa_pow(double x, double y)
540{
541   return pow(x, y);
542}
543
544
545/**
546 * Find the first bit set in a word.
547 */
548int
549_mesa_ffs(int i)
550{
551#if (defined(_WIN32) && !defined(__MINGW32__) ) || defined(__IBMC__) || defined(__IBMCPP__)
552   register int bit = 0;
553   if (i != 0) {
554      if ((i & 0xffff) == 0) {
555         bit += 16;
556         i >>= 16;
557      }
558      if ((i & 0xff) == 0) {
559         bit += 8;
560         i >>= 8;
561      }
562      if ((i & 0xf) == 0) {
563         bit += 4;
564         i >>= 4;
565      }
566      while ((i & 1) == 0) {
567         bit++;
568         i >>= 1;
569      }
570   }
571   return bit;
572#else
573   return ffs(i);
574#endif
575}
576
577
578/**
579 * Find position of first bit set in given value.
580 * XXX Warning: this function can only be used on 64-bit systems!
581 * \return  position of least-significant bit set, starting at 1, return zero
582 *          if no bits set.
583 */
584int
585_mesa_ffsll(long long val)
586{
587#ifdef ffsll
588   return ffsll(val);
589#else
590   int bit;
591
592   assert(sizeof(val) == 8);
593
594   bit = ffs(val);
595   if (bit != 0)
596      return bit;
597
598   bit = ffs(val >> 32);
599   if (bit != 0)
600      return 32 + bit;
601
602   return 0;
603#endif
604}
605
606
607/**
608 * Return number of bits set in given GLuint.
609 */
610unsigned int
611_mesa_bitcount(unsigned int n)
612{
613   unsigned int bits;
614   for (bits = 0; n > 0; n = n >> 1) {
615      bits += (n & 1);
616   }
617   return bits;
618}
619
620
621/**
622 * Convert a 4-byte float to a 2-byte half float.
623 * Based on code from:
624 * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html
625 */
626GLhalfARB
627_mesa_float_to_half(float val)
628{
629   const int flt = *((int *) (void *) &val);
630   const int flt_m = flt & 0x7fffff;
631   const int flt_e = (flt >> 23) & 0xff;
632   const int flt_s = (flt >> 31) & 0x1;
633   int s, e, m = 0;
634   GLhalfARB result;
635
636   /* sign bit */
637   s = flt_s;
638
639   /* handle special cases */
640   if ((flt_e == 0) && (flt_m == 0)) {
641      /* zero */
642      /* m = 0; - already set */
643      e = 0;
644   }
645   else if ((flt_e == 0) && (flt_m != 0)) {
646      /* denorm -- denorm float maps to 0 half */
647      /* m = 0; - already set */
648      e = 0;
649   }
650   else if ((flt_e == 0xff) && (flt_m == 0)) {
651      /* infinity */
652      /* m = 0; - already set */
653      e = 31;
654   }
655   else if ((flt_e == 0xff) && (flt_m != 0)) {
656      /* NaN */
657      m = 1;
658      e = 31;
659   }
660   else {
661      /* regular number */
662      const int new_exp = flt_e - 127;
663      if (new_exp < -24) {
664         /* this maps to 0 */
665         /* m = 0; - already set */
666         e = 0;
667      }
668      else if (new_exp < -14) {
669         /* this maps to a denorm */
670         unsigned int exp_val = (unsigned int) (-14 - new_exp); /* 2^-exp_val*/
671         e = 0;
672         switch (exp_val) {
673            case 0:
674               _mesa_warning(NULL,
675                   "float_to_half: logical error in denorm creation!\n");
676               /* m = 0; - already set */
677               break;
678            case 1: m = 512 + (flt_m >> 14); break;
679            case 2: m = 256 + (flt_m >> 15); break;
680            case 3: m = 128 + (flt_m >> 16); break;
681            case 4: m = 64 + (flt_m >> 17); break;
682            case 5: m = 32 + (flt_m >> 18); break;
683            case 6: m = 16 + (flt_m >> 19); break;
684            case 7: m = 8 + (flt_m >> 20); break;
685            case 8: m = 4 + (flt_m >> 21); break;
686            case 9: m = 2 + (flt_m >> 22); break;
687            case 10: m = 1; break;
688         }
689      }
690      else if (new_exp > 15) {
691         /* map this value to infinity */
692         /* m = 0; - already set */
693         e = 31;
694      }
695      else {
696         /* regular */
697         e = new_exp + 15;
698         m = flt_m >> 13;
699      }
700   }
701
702   result = (s << 15) | (e << 10) | m;
703   return result;
704}
705
706
707/**
708 * Convert a 2-byte half float to a 4-byte float.
709 * Based on code from:
710 * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html
711 */
712float
713_mesa_half_to_float(GLhalfARB val)
714{
715   /* XXX could also use a 64K-entry lookup table */
716   const int m = val & 0x3ff;
717   const int e = (val >> 10) & 0x1f;
718   const int s = (val >> 15) & 0x1;
719   int flt_m, flt_e, flt_s, flt;
720   float result;
721
722   /* sign bit */
723   flt_s = s;
724
725   /* handle special cases */
726   if ((e == 0) && (m == 0)) {
727      /* zero */
728      flt_m = 0;
729      flt_e = 0;
730   }
731   else if ((e == 0) && (m != 0)) {
732      /* denorm -- denorm half will fit in non-denorm single */
733      const float half_denorm = 1.0f / 16384.0f; /* 2^-14 */
734      float mantissa = ((float) (m)) / 1024.0f;
735      float sign = s ? -1.0f : 1.0f;
736      return sign * mantissa * half_denorm;
737   }
738   else if ((e == 31) && (m == 0)) {
739      /* infinity */
740      flt_e = 0xff;
741      flt_m = 0;
742   }
743   else if ((e == 31) && (m != 0)) {
744      /* NaN */
745      flt_e = 0xff;
746      flt_m = 1;
747   }
748   else {
749      /* regular */
750      flt_e = e + 112;
751      flt_m = m << 13;
752   }
753
754   flt = (flt_s << 31) | (flt_e << 23) | flt_m;
755   result = *((float *) (void *) &flt);
756   return result;
757}
758
759/*@}*/
760
761
762/**********************************************************************/
763/** \name Sort & Search */
764/*@{*/
765
766/**
767 * Wrapper for bsearch().
768 */
769void *
770_mesa_bsearch( const void *key, const void *base, size_t nmemb, size_t size,
771               int (*compar)(const void *, const void *) )
772{
773   return bsearch(key, base, nmemb, size, compar);
774}
775
776/*@}*/
777
778
779/**********************************************************************/
780/** \name Environment vars */
781/*@{*/
782
783/**
784 * Wrapper for getenv().
785 */
786char *
787_mesa_getenv( const char *var )
788{
789#if defined(_XBOX)
790   return NULL;
791#else
792   return getenv(var);
793#endif
794}
795
796/*@}*/
797
798
799/**********************************************************************/
800/** \name String */
801/*@{*/
802
803/** Wrapper around strstr() */
804char *
805_mesa_strstr( const char *haystack, const char *needle )
806{
807   return strstr(haystack, needle);
808}
809
810/** Wrapper around strncat() */
811char *
812_mesa_strncat( char *dest, const char *src, size_t n )
813{
814   return strncat(dest, src, n);
815}
816
817/** Wrapper around strcpy() */
818char *
819_mesa_strcpy( char *dest, const char *src )
820{
821   return strcpy(dest, src);
822}
823
824/** Wrapper around strncpy() */
825char *
826_mesa_strncpy( char *dest, const char *src, size_t n )
827{
828   return strncpy(dest, src, n);
829}
830
831/** Wrapper around strlen() */
832size_t
833_mesa_strlen( const char *s )
834{
835   return strlen(s);
836}
837
838/** Wrapper around strcmp() */
839int
840_mesa_strcmp( const char *s1, const char *s2 )
841{
842   return strcmp(s1, s2);
843}
844
845/** Wrapper around strncmp() */
846int
847_mesa_strncmp( const char *s1, const char *s2, size_t n )
848{
849   return strncmp(s1, s2, n);
850}
851
852/**
853 * Implemented using _mesa_malloc() and _mesa_strcpy.
854 * Note that NULL is handled accordingly.
855 */
856char *
857_mesa_strdup( const char *s )
858{
859   if (s) {
860      size_t l = _mesa_strlen(s);
861      char *s2 = (char *) _mesa_malloc(l + 1);
862      if (s2)
863         _mesa_strcpy(s2, s);
864      return s2;
865   }
866   else {
867      return NULL;
868   }
869}
870
871/** Wrapper around atoi() */
872int
873_mesa_atoi(const char *s)
874{
875   return atoi(s);
876}
877
878/** Wrapper around strtod() */
879double
880_mesa_strtod( const char *s, char **end )
881{
882   return strtod(s, end);
883}
884
885/*@}*/
886
887
888/**********************************************************************/
889/** \name I/O */
890/*@{*/
891
892/** Wrapper around vsprintf() */
893int
894_mesa_sprintf( char *str, const char *fmt, ... )
895{
896   int r;
897   va_list args;
898   va_start( args, fmt );
899   r = vsprintf( str, fmt, args );
900   va_end( args );
901   return r;
902}
903
904/** Wrapper around printf(), using vsprintf() for the formatting. */
905void
906_mesa_printf( const char *fmtString, ... )
907{
908   char s[MAXSTRING];
909   va_list args;
910   va_start( args, fmtString );
911   vsnprintf(s, MAXSTRING, fmtString, args);
912   va_end( args );
913   fprintf(stderr,"%s", s);
914}
915
916/** Wrapper around vsprintf() */
917int
918_mesa_vsprintf( char *str, const char *fmt, va_list args )
919{
920   return vsprintf( str, fmt, args );
921}
922
923/*@}*/
924
925
926/**********************************************************************/
927/** \name Diagnostics */
928/*@{*/
929
930/**
931 * Display a warning.
932 *
933 * \param ctx GL context.
934 * \param fmtString printf() alike format string.
935 *
936 * If debugging is enabled (either at compile-time via the DEBUG macro, or
937 * run-time via the MESA_DEBUG environment variable), prints the warning to
938 * stderr via fprintf().
939 */
940void
941_mesa_warning( GLcontext *ctx, const char *fmtString, ... )
942{
943   GLboolean debug;
944   char str[MAXSTRING];
945   va_list args;
946   (void) ctx;
947   va_start( args, fmtString );
948   (void) vsnprintf( str, MAXSTRING, fmtString, args );
949   va_end( args );
950#ifdef DEBUG
951   debug = GL_TRUE; /* always print warning */
952#else
953   debug = _mesa_getenv("MESA_DEBUG") ? GL_TRUE : GL_FALSE;
954#endif
955   if (debug) {
956      fprintf(stderr, "Mesa warning: %s\n", str);
957   }
958}
959
960/**
961 * This function is called when the Mesa user has stumbled into a code
962 * path which may not be implemented fully or correctly.
963 *
964 * \param ctx GL context.
965 * \param s problem description string.
966 *
967 * Prints the message to stderr via fprintf().
968 */
969void
970_mesa_problem( const GLcontext *ctx, const char *fmtString, ... )
971{
972   va_list args;
973   char str[MAXSTRING];
974   (void) ctx;
975
976   va_start( args, fmtString );
977   vsnprintf( str, MAXSTRING, fmtString, args );
978   va_end( args );
979
980   fprintf(stderr, "Mesa %s implementation error: %s\n", MESA_VERSION_STRING, str);
981   fprintf(stderr, "Please report at bugzilla.freedesktop.org\n");
982}
983
984/**
985 * Display an error message.
986 *
987 * If in debug mode, print error message.
988 * Also, record the error code by calling _mesa_record_error().
989 *
990 * \param ctx the GL context.
991 * \param error the error value.
992 * \param fmtString printf() style format string, followed by optional args
993 *
994 * If debugging is enabled (either at compile-time via the DEBUG macro, or
995 * run-time via the MESA_DEBUG environment variable), interperts the error code and
996 * prints the error message via _mesa_debug().
997 */
998void
999_mesa_error( GLcontext *ctx, GLenum error, const char *fmtString, ... )
1000{
1001   const char *debugEnv;
1002   GLboolean debug;
1003
1004   debugEnv = _mesa_getenv("MESA_DEBUG");
1005
1006#ifdef DEBUG
1007   if (debugEnv && _mesa_strstr(debugEnv, "silent"))
1008      debug = GL_FALSE;
1009   else
1010      debug = GL_TRUE;
1011#else
1012   if (debugEnv)
1013      debug = GL_TRUE;
1014   else
1015      debug = GL_FALSE;
1016#endif
1017
1018   if (debug) {
1019      va_list args;
1020      char where[MAXSTRING];
1021      const char *errstr;
1022
1023      va_start( args, fmtString );
1024      vsnprintf( where, MAXSTRING, fmtString, args );
1025      va_end( args );
1026
1027      switch (error) {
1028	 case GL_NO_ERROR:
1029	    errstr = "GL_NO_ERROR";
1030	    break;
1031	 case GL_INVALID_VALUE:
1032	    errstr = "GL_INVALID_VALUE";
1033	    break;
1034	 case GL_INVALID_ENUM:
1035	    errstr = "GL_INVALID_ENUM";
1036	    break;
1037	 case GL_INVALID_OPERATION:
1038	    errstr = "GL_INVALID_OPERATION";
1039	    break;
1040	 case GL_STACK_OVERFLOW:
1041	    errstr = "GL_STACK_OVERFLOW";
1042	    break;
1043	 case GL_STACK_UNDERFLOW:
1044	    errstr = "GL_STACK_UNDERFLOW";
1045	    break;
1046	 case GL_OUT_OF_MEMORY:
1047	    errstr = "GL_OUT_OF_MEMORY";
1048	    break;
1049         case GL_TABLE_TOO_LARGE:
1050            errstr = "GL_TABLE_TOO_LARGE";
1051            break;
1052         case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
1053            errstr = "GL_INVALID_FRAMEBUFFER_OPERATION";
1054            break;
1055	 default:
1056	    errstr = "unknown";
1057	    break;
1058      }
1059      _mesa_debug(ctx, "User error: %s in %s\n", errstr, where);
1060   }
1061
1062   _mesa_record_error(ctx, error);
1063}
1064
1065/**
1066 * Report debug information.
1067 *
1068 * \param ctx GL context.
1069 * \param fmtString printf() alike format string.
1070 *
1071 * Prints the message to stderr via fprintf().
1072 */
1073void
1074_mesa_debug( const GLcontext *ctx, const char *fmtString, ... )
1075{
1076#ifdef DEBUG
1077   char s[MAXSTRING];
1078   va_list args;
1079   va_start(args, fmtString);
1080   vsnprintf(s, MAXSTRING, fmtString, args);
1081   va_end(args);
1082   fprintf(stderr, "Mesa: %s", s);
1083#endif /* DEBUG */
1084   (void) ctx;
1085   (void) fmtString;
1086}
1087
1088/*@}*/
1089
1090
1091/**********************************************************************/
1092/** \name Exit */
1093/*@{*/
1094
1095/**
1096 * Wrapper for exit().
1097 */
1098void
1099_mesa_exit( int status )
1100{
1101   exit(status);
1102}
1103
1104/*@}*/
1105
1106
1107/**********************************************************************/
1108/** \name Default Imports Wrapper */
1109/*@{*/
1110
1111/** Wrapper around _mesa_malloc() */
1112static void *
1113default_malloc(__GLcontext *gc, size_t size)
1114{
1115   (void) gc;
1116   return _mesa_malloc(size);
1117}
1118
1119/** Wrapper around _mesa_malloc() */
1120static void *
1121default_calloc(__GLcontext *gc, size_t numElem, size_t elemSize)
1122{
1123   (void) gc;
1124   return _mesa_calloc(numElem * elemSize);
1125}
1126
1127/** Wrapper around realloc() */
1128static void *
1129default_realloc(__GLcontext *gc, void *oldAddr, size_t newSize)
1130{
1131   (void) gc;
1132   return realloc(oldAddr, newSize);
1133}
1134
1135/** Wrapper around _mesa_free() */
1136static void
1137default_free(__GLcontext *gc, void *addr)
1138{
1139   (void) gc;
1140   _mesa_free(addr);
1141}
1142
1143/** Wrapper around _mesa_getenv() */
1144static char * CAPI
1145default_getenv( __GLcontext *gc, const char *var )
1146{
1147   (void) gc;
1148   return _mesa_getenv(var);
1149}
1150
1151/** Wrapper around _mesa_warning() */
1152static void
1153default_warning(__GLcontext *gc, char *str)
1154{
1155   _mesa_warning(gc, str);
1156}
1157
1158/** Wrapper around _mesa_problem() */
1159static void
1160default_fatal(__GLcontext *gc, char *str)
1161{
1162   _mesa_problem(gc, str);
1163   abort();
1164}
1165
1166/** Wrapper around atoi() */
1167static int CAPI
1168default_atoi(__GLcontext *gc, const char *str)
1169{
1170   (void) gc;
1171   return atoi(str);
1172}
1173
1174/** Wrapper around vsprintf() */
1175static int CAPI
1176default_sprintf(__GLcontext *gc, char *str, const char *fmt, ...)
1177{
1178   int r;
1179   va_list args;
1180   (void) gc;
1181   va_start( args, fmt );
1182   r = vsprintf( str, fmt, args );
1183   va_end( args );
1184   return r;
1185}
1186
1187/** Wrapper around fopen() */
1188static void * CAPI
1189default_fopen(__GLcontext *gc, const char *path, const char *mode)
1190{
1191   (void) gc;
1192   return fopen(path, mode);
1193}
1194
1195/** Wrapper around fclose() */
1196static int CAPI
1197default_fclose(__GLcontext *gc, void *stream)
1198{
1199   (void) gc;
1200   return fclose((FILE *) stream);
1201}
1202
1203/** Wrapper around vfprintf() */
1204static int CAPI
1205default_fprintf(__GLcontext *gc, void *stream, const char *fmt, ...)
1206{
1207   int r;
1208   va_list args;
1209   (void) gc;
1210   va_start( args, fmt );
1211   r = vfprintf( (FILE *) stream, fmt, args );
1212   va_end( args );
1213   return r;
1214}
1215
1216/*@}*/
1217
1218
1219/**
1220 * Initialize a __GLimports object to point to the functions in this
1221 * file.
1222 *
1223 * This is to be called from device drivers.
1224 *
1225 * Also, do some one-time initializations.
1226 *
1227 * \param imports the object to initialize.
1228 * \param driverCtx pointer to device driver-specific data.
1229 */
1230void
1231_mesa_init_default_imports(__GLimports *imports, void *driverCtx)
1232{
1233   /* XXX maybe move this one-time init stuff into context.c */
1234   static GLboolean initialized = GL_FALSE;
1235   if (!initialized) {
1236      init_sqrt_table();
1237      initialized = GL_TRUE;
1238   }
1239
1240   imports->malloc = default_malloc;
1241   imports->calloc = default_calloc;
1242   imports->realloc = default_realloc;
1243   imports->free = default_free;
1244   imports->warning = default_warning;
1245   imports->fatal = default_fatal;
1246   imports->getenv = default_getenv; /* not used for now */
1247   imports->atoi = default_atoi;
1248   imports->sprintf = default_sprintf;
1249   imports->fopen = default_fopen;
1250   imports->fclose = default_fclose;
1251   imports->fprintf = default_fprintf;
1252   imports->getDrawablePrivate = NULL; /* driver-specific */
1253   imports->getReadablePrivate = NULL; /* driver-specific */
1254   imports->other = driverCtx;
1255}
1256