imports.c revision 99c9bc386f54964eea0ed93f6b036477076dae57
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 lest 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/** Implemented using _mesa_malloc() and _mesa_strcpy */
853char *
854_mesa_strdup( const char *s )
855{
856   size_t l = _mesa_strlen(s);
857   char *s2 = (char *) _mesa_malloc(l + 1);
858   if (s2)
859      _mesa_strcpy(s2, s);
860   return s2;
861}
862
863/** Wrapper around atoi() */
864int
865_mesa_atoi(const char *s)
866{
867   return atoi(s);
868}
869
870/** Wrapper around strtod() */
871double
872_mesa_strtod( const char *s, char **end )
873{
874   return strtod(s, end);
875}
876
877/*@}*/
878
879
880/**********************************************************************/
881/** \name I/O */
882/*@{*/
883
884/** Wrapper around vsprintf() */
885int
886_mesa_sprintf( char *str, const char *fmt, ... )
887{
888   int r;
889   va_list args;
890   va_start( args, fmt );
891   r = vsprintf( str, fmt, args );
892   va_end( args );
893   return r;
894}
895
896/** Wrapper around printf(), using vsprintf() for the formatting. */
897void
898_mesa_printf( const char *fmtString, ... )
899{
900   char s[MAXSTRING];
901   va_list args;
902   va_start( args, fmtString );
903   vsnprintf(s, MAXSTRING, fmtString, args);
904   va_end( args );
905   fprintf(stderr,"%s", s);
906}
907
908/** Wrapper around vsprintf() */
909int
910_mesa_vsprintf( char *str, const char *fmt, va_list args )
911{
912   return vsprintf( str, fmt, args );
913}
914
915/*@}*/
916
917
918/**********************************************************************/
919/** \name Diagnostics */
920/*@{*/
921
922/**
923 * Display a warning.
924 *
925 * \param ctx GL context.
926 * \param fmtString printf() alike format string.
927 *
928 * If debugging is enabled (either at compile-time via the DEBUG macro, or
929 * run-time via the MESA_DEBUG environment variable), prints the warning to
930 * stderr via fprintf().
931 */
932void
933_mesa_warning( GLcontext *ctx, const char *fmtString, ... )
934{
935   GLboolean debug;
936   char str[MAXSTRING];
937   va_list args;
938   (void) ctx;
939   va_start( args, fmtString );
940   (void) vsnprintf( str, MAXSTRING, fmtString, args );
941   va_end( args );
942#ifdef DEBUG
943   debug = GL_TRUE; /* always print warning */
944#else
945   debug = _mesa_getenv("MESA_DEBUG") ? GL_TRUE : GL_FALSE;
946#endif
947   if (debug) {
948      fprintf(stderr, "Mesa warning: %s\n", str);
949   }
950}
951
952/**
953 * This function is called when the Mesa user has stumbled into a code
954 * path which may not be implemented fully or correctly.
955 *
956 * \param ctx GL context.
957 * \param s problem description string.
958 *
959 * Prints the message to stderr via fprintf().
960 */
961void
962_mesa_problem( const GLcontext *ctx, const char *fmtString, ... )
963{
964   va_list args;
965   char str[MAXSTRING];
966   (void) ctx;
967
968   va_start( args, fmtString );
969   vsnprintf( str, MAXSTRING, fmtString, args );
970   va_end( args );
971
972   fprintf(stderr, "Mesa %s implementation error: %s\n", MESA_VERSION_STRING, str);
973   fprintf(stderr, "Please report at bugzilla.freedesktop.org\n");
974}
975
976/**
977 * Display an error message.
978 *
979 * If in debug mode, print error message.
980 * Also, record the error code by calling _mesa_record_error().
981 *
982 * \param ctx the GL context.
983 * \param error the error value.
984 * \param fmtString printf() style format string, followed by optional args
985 *
986 * If debugging is enabled (either at compile-time via the DEBUG macro, or
987 * run-time via the MESA_DEBUG environment variable), interperts the error code and
988 * prints the error message via _mesa_debug().
989 */
990void
991_mesa_error( GLcontext *ctx, GLenum error, const char *fmtString, ... )
992{
993   const char *debugEnv;
994   GLboolean debug;
995
996   debugEnv = _mesa_getenv("MESA_DEBUG");
997
998#ifdef DEBUG
999   if (debugEnv && _mesa_strstr(debugEnv, "silent"))
1000      debug = GL_FALSE;
1001   else
1002      debug = GL_TRUE;
1003#else
1004   if (debugEnv)
1005      debug = GL_TRUE;
1006   else
1007      debug = GL_FALSE;
1008#endif
1009
1010   if (debug) {
1011      va_list args;
1012      char where[MAXSTRING];
1013      const char *errstr;
1014
1015      va_start( args, fmtString );
1016      vsnprintf( where, MAXSTRING, fmtString, args );
1017      va_end( args );
1018
1019      switch (error) {
1020	 case GL_NO_ERROR:
1021	    errstr = "GL_NO_ERROR";
1022	    break;
1023	 case GL_INVALID_VALUE:
1024	    errstr = "GL_INVALID_VALUE";
1025	    break;
1026	 case GL_INVALID_ENUM:
1027	    errstr = "GL_INVALID_ENUM";
1028	    break;
1029	 case GL_INVALID_OPERATION:
1030	    errstr = "GL_INVALID_OPERATION";
1031	    break;
1032	 case GL_STACK_OVERFLOW:
1033	    errstr = "GL_STACK_OVERFLOW";
1034	    break;
1035	 case GL_STACK_UNDERFLOW:
1036	    errstr = "GL_STACK_UNDERFLOW";
1037	    break;
1038	 case GL_OUT_OF_MEMORY:
1039	    errstr = "GL_OUT_OF_MEMORY";
1040	    break;
1041         case GL_TABLE_TOO_LARGE:
1042            errstr = "GL_TABLE_TOO_LARGE";
1043            break;
1044         case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
1045            errstr = "GL_INVALID_FRAMEBUFFER_OPERATION";
1046            break;
1047	 default:
1048	    errstr = "unknown";
1049	    break;
1050      }
1051      _mesa_debug(ctx, "User error: %s in %s\n", errstr, where);
1052   }
1053
1054   _mesa_record_error(ctx, error);
1055}
1056
1057/**
1058 * Report debug information.
1059 *
1060 * \param ctx GL context.
1061 * \param fmtString printf() alike format string.
1062 *
1063 * Prints the message to stderr via fprintf().
1064 */
1065void
1066_mesa_debug( const GLcontext *ctx, const char *fmtString, ... )
1067{
1068#ifdef DEBUG
1069   char s[MAXSTRING];
1070   va_list args;
1071   va_start(args, fmtString);
1072   vsnprintf(s, MAXSTRING, fmtString, args);
1073   va_end(args);
1074   fprintf(stderr, "Mesa: %s", s);
1075#endif /* DEBUG */
1076   (void) ctx;
1077   (void) fmtString;
1078}
1079
1080/*@}*/
1081
1082
1083/**********************************************************************/
1084/** \name Exit */
1085/*@{*/
1086
1087/**
1088 * Wrapper for exit().
1089 */
1090void
1091_mesa_exit( int status )
1092{
1093   exit(status);
1094}
1095
1096/*@}*/
1097
1098
1099/**********************************************************************/
1100/** \name Default Imports Wrapper */
1101/*@{*/
1102
1103/** Wrapper around _mesa_malloc() */
1104static void *
1105default_malloc(__GLcontext *gc, size_t size)
1106{
1107   (void) gc;
1108   return _mesa_malloc(size);
1109}
1110
1111/** Wrapper around _mesa_malloc() */
1112static void *
1113default_calloc(__GLcontext *gc, size_t numElem, size_t elemSize)
1114{
1115   (void) gc;
1116   return _mesa_calloc(numElem * elemSize);
1117}
1118
1119/** Wrapper around realloc() */
1120static void *
1121default_realloc(__GLcontext *gc, void *oldAddr, size_t newSize)
1122{
1123   (void) gc;
1124   return realloc(oldAddr, newSize);
1125}
1126
1127/** Wrapper around _mesa_free() */
1128static void
1129default_free(__GLcontext *gc, void *addr)
1130{
1131   (void) gc;
1132   _mesa_free(addr);
1133}
1134
1135/** Wrapper around _mesa_getenv() */
1136static char * CAPI
1137default_getenv( __GLcontext *gc, const char *var )
1138{
1139   (void) gc;
1140   return _mesa_getenv(var);
1141}
1142
1143/** Wrapper around _mesa_warning() */
1144static void
1145default_warning(__GLcontext *gc, char *str)
1146{
1147   _mesa_warning(gc, str);
1148}
1149
1150/** Wrapper around _mesa_problem() */
1151static void
1152default_fatal(__GLcontext *gc, char *str)
1153{
1154   _mesa_problem(gc, str);
1155   abort();
1156}
1157
1158/** Wrapper around atoi() */
1159static int CAPI
1160default_atoi(__GLcontext *gc, const char *str)
1161{
1162   (void) gc;
1163   return atoi(str);
1164}
1165
1166/** Wrapper around vsprintf() */
1167static int CAPI
1168default_sprintf(__GLcontext *gc, char *str, const char *fmt, ...)
1169{
1170   int r;
1171   va_list args;
1172   (void) gc;
1173   va_start( args, fmt );
1174   r = vsprintf( str, fmt, args );
1175   va_end( args );
1176   return r;
1177}
1178
1179/** Wrapper around fopen() */
1180static void * CAPI
1181default_fopen(__GLcontext *gc, const char *path, const char *mode)
1182{
1183   (void) gc;
1184   return fopen(path, mode);
1185}
1186
1187/** Wrapper around fclose() */
1188static int CAPI
1189default_fclose(__GLcontext *gc, void *stream)
1190{
1191   (void) gc;
1192   return fclose((FILE *) stream);
1193}
1194
1195/** Wrapper around vfprintf() */
1196static int CAPI
1197default_fprintf(__GLcontext *gc, void *stream, const char *fmt, ...)
1198{
1199   int r;
1200   va_list args;
1201   (void) gc;
1202   va_start( args, fmt );
1203   r = vfprintf( (FILE *) stream, fmt, args );
1204   va_end( args );
1205   return r;
1206}
1207
1208/*@}*/
1209
1210
1211/**
1212 * Initialize a __GLimports object to point to the functions in this
1213 * file.
1214 *
1215 * This is to be called from device drivers.
1216 *
1217 * Also, do some one-time initializations.
1218 *
1219 * \param imports the object to initialize.
1220 * \param driverCtx pointer to device driver-specific data.
1221 */
1222void
1223_mesa_init_default_imports(__GLimports *imports, void *driverCtx)
1224{
1225   /* XXX maybe move this one-time init stuff into context.c */
1226   static GLboolean initialized = GL_FALSE;
1227   if (!initialized) {
1228      init_sqrt_table();
1229      initialized = GL_TRUE;
1230   }
1231
1232   imports->malloc = default_malloc;
1233   imports->calloc = default_calloc;
1234   imports->realloc = default_realloc;
1235   imports->free = default_free;
1236   imports->warning = default_warning;
1237   imports->fatal = default_fatal;
1238   imports->getenv = default_getenv; /* not used for now */
1239   imports->atoi = default_atoi;
1240   imports->sprintf = default_sprintf;
1241   imports->fopen = default_fopen;
1242   imports->fclose = default_fclose;
1243   imports->fprintf = default_fprintf;
1244   imports->getDrawablePrivate = NULL; /* driver-specific */
1245   imports->getReadablePrivate = NULL; /* driver-specific */
1246   imports->other = driverCtx;
1247}
1248