
/* Copyright (c) Mark J. Kilgard, 1994, 1997, 2001. */

/* This program is freely distributable without licensing fees
   and is provided without guarantee or warrantee expressed or
   implied. This program is -not- in the public domain. */

#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "glutint.h"

static const GLubyte *extensions = NULL;
static GLXContext cachedContext = NULL;

void
__glutInvalidateExtensionStringCacheIfNeeded(GLXContext context)
{
  if (cachedContext != context) {
    /* No invalidation required. */
    return;
  }
  cachedContext = NULL;
  extensions = NULL;
}

/* CENTRY */
int GLUTAPIENTRY 
glutExtensionSupported(const char *extension)
{
  const GLubyte *start;
  const GLubyte *where, *terminator;

  /* Extension names should not have spaces. */
  where = (GLubyte *) strchr(extension, ' ');
  if (where || *extension == '\0') {
    return 0;
  }

  if (!extensions || (GET_CURRENT_CONTEXT() != cachedContext)) {
    extensions = glGetString(GL_EXTENSIONS);
    assert(extensions);  /* If this assets, likely no current GL context. */
    cachedContext = GET_CURRENT_CONTEXT();
  }
  if (extensions) {
    /* It takes a bit of care to be fool-proof about parsing the
       OpenGL extensions string.  Don't be fooled by sub-strings,
       etc. */
    start = extensions;
    for (;;) {
      /* If your application crashes in the strstr routine below,
         you are probably calling glutExtensionSupported without
         having a current window.  Calling glGetString without
         a current OpenGL context has unpredictable results.
         Please fix your program. */
      where = (const GLubyte *)strstr((const char *)start, extension);
      if (!where) {
        break;
      }
      terminator = where + strlen(extension);
      if (where == start || *(where - 1) == ' ') {
        if (*terminator == ' ' || *terminator == '\0') {
          return 1;
        }
      }
      start = terminator;
    }
  }
  return 0;
}

/* ENDCENTRY */
