/**
 * Construct the GL_EXTENSIONS string.  Called the first time that
 * glGetString(GL_EXTENSIONS) is called.
 */
GLubyte *
_mesa_make_extension_string( GLcontext *ctx )
{
   const GLboolean *base = (const GLboolean *) &ctx->Extensions;
   GLuint extStrLen = 0;
   GLubyte *s;
   GLuint i;

   /* first, compute length of the extension string */
   for (i = 0 ; i < Elements(default_extensions) ; i++) {
      if (!default_extensions[i].flag_offset ||
          *(base + default_extensions[i].flag_offset)) {
         extStrLen += (GLuint)_mesa_strlen(default_extensions[i].name) + 1;
      }
   }
   s = (GLubyte *) _mesa_malloc(extStrLen);

   /* second, build the extension string */
   extStrLen = 0;
   for (i = 0 ; i < Elements(default_extensions) ; i++) {
      if (!default_extensions[i].flag_offset ||
          *(base + default_extensions[i].flag_offset)) {
         GLuint len = (GLuint)_mesa_strlen(default_extensions[i].name);
         _mesa_memcpy(s + extStrLen, default_extensions[i].name, len);
         extStrLen += len;
         s[extStrLen] = (GLubyte) ' ';
         extStrLen++;
      }
   }
   ASSERT(extStrLen > 0);

   s[extStrLen - 1] = 0;

   return s;
}
Exemplo n.º 2
0
/**
 * Get a program attribute.
 * \note Not compiled into display lists.
 * \note Called from the GL API dispatcher.
 */
void GLAPIENTRY
_mesa_GetProgramivNV(GLuint id, GLenum pname, GLint *params)
{
   struct gl_program *prog;
   GET_CURRENT_CONTEXT(ctx);

   if (!ctx->_CurrentProgram)
      ASSERT_OUTSIDE_BEGIN_END(ctx);

   prog = _mesa_lookup_program(ctx, id);
   if (!prog) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramivNV");
      return;
   }

   switch (pname) {
      case GL_PROGRAM_TARGET_NV:
         *params = prog->Target;
         return;
      case GL_PROGRAM_LENGTH_NV:
         *params = prog->String ?(GLint)_mesa_strlen((char *) prog->String) : 0;
         return;
      case GL_PROGRAM_RESIDENT_NV:
         *params = prog->Resident;
         return;
      default:
         _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivNV(pname)");
         return;
   }
}
Exemplo n.º 3
0
void GLAPIENTRY
_mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string)
{
   const struct gl_program *prog;
   char *dst = (char *) string;
   GET_CURRENT_CONTEXT(ctx);

   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (target == GL_VERTEX_PROGRAM_ARB) {
      prog = &(ctx->VertexProgram.Current->Base);
   }
   else if (target == GL_FRAGMENT_PROGRAM_ARB) {
      prog = &(ctx->FragmentProgram.Current->Base);
   }
   else {
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)");
      return;
   }

   ASSERT(prog);

   if (pname != GL_PROGRAM_STRING_ARB) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)");
      return;
   }

   if (prog->String)
      _mesa_memcpy(dst, prog->String, _mesa_strlen((char *) prog->String));
   else
      *dst = '\0';
}
Exemplo n.º 4
0
/**
 * Get the program source code.
 * \note Not compiled into display lists.
 * \note Called from the GL API dispatcher.
 */
void GLAPIENTRY
_mesa_GetProgramStringNV(GLuint id, GLenum pname, GLubyte *program)
{
   struct gl_program *prog;
   GET_CURRENT_CONTEXT(ctx);

   if (!ctx->_CurrentProgram)
      ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (pname != GL_PROGRAM_STRING_NV) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringNV(pname)");
      return;
   }

   prog = _mesa_lookup_program(ctx, id);
   if (!prog) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramStringNV");
      return;
   }

   if (prog->String) {
      MEMCPY(program, prog->String, _mesa_strlen((char *) prog->String));
   }
   else {
      program[0] = 0;
   }
}
Exemplo n.º 5
0
/**
 * Lookup a parameter value by name in the given parameter list.
 * \return pointer to the float[4] values.
 */
GLfloat *
_mesa_lookup_parameter_value(struct program_parameter_list *paramList,
                             GLsizei nameLen, const char *name)
{
   GLuint i;

   if (!paramList)
      return NULL;

   if (nameLen == -1) {
      /* name is null-terminated */
      for (i = 0; i < paramList->NumParameters; i++) {
         if (_mesa_strcmp(paramList->Parameters[i].Name, name) == 0)
            return paramList->Parameters[i].Values;
      }
   }
   else {
      /* name is not null-terminated, use nameLen */
      for (i = 0; i < paramList->NumParameters; i++) {
         if (_mesa_strncmp(paramList->Parameters[i].Name, name, nameLen) == 0
             && _mesa_strlen(paramList->Parameters[i].Name) == (size_t)nameLen)
            return paramList->Parameters[i].Values;
      }
   }
   return NULL;
}
Exemplo n.º 6
0
Arquivo: vpstate.c Projeto: aosm/X11
/**
 * Get the program source code.
 * \note Not compiled into display lists.
 * \note Called from the GL API dispatcher.
 */
void _mesa_GetProgramStringNV(GLuint id, GLenum pname, GLubyte *program)
{
   struct vp_program *vprog;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (pname != GL_PROGRAM_STRING_NV) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivNV(pname)");
      return;
   }

   vprog = (struct vp_program *)
      _mesa_HashLookup(ctx->Shared->VertexPrograms, id);

   if (!vprog) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramivNV");
      return;
   }

   if (vprog->String) {
      MEMCPY(program, vprog->String, _mesa_strlen((char *) vprog->String));
   }
   else {
      program[0] = 0;
   }
}
Exemplo n.º 7
0
Arquivo: vpstate.c Projeto: aosm/X11
/**
 * Get a program attribute.
 * \note Not compiled into display lists.
 * \note Called from the GL API dispatcher.
 */
void _mesa_GetProgramivNV(GLuint id, GLenum pname, GLint *params)
{
   struct vp_program *vprog;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   vprog = (struct vp_program *)
      _mesa_HashLookup(ctx->Shared->VertexPrograms, id);

   if (!vprog) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramivNV");
      return;
   }

   switch (pname) {
      case GL_PROGRAM_TARGET_NV:
         *params = vprog->Target;
         return;
      case GL_PROGRAM_LENGTH_NV:
         *params = vprog->String ? _mesa_strlen((char *) vprog->String) : 0;
         return;
      case GL_PROGRAM_RESIDENT_NV:
         *params = vprog->Resident;
         return;
      default:
         _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivNV(pname)");
         return;
   }
}
Exemplo n.º 8
0
/**
 * Lookup a parameter index by name in the given parameter list.
 * \return index of parameter in the list.
 */
GLint
_mesa_lookup_parameter_index(struct program_parameter_list *paramList,
                             GLsizei nameLen, const char *name)
{
   GLint i;

   if (!paramList)
      return -1;

   if (nameLen == -1) {
      /* name is null-terminated */
      for (i = 0; i < (GLint) paramList->NumParameters; i++) {
         if (_mesa_strcmp(paramList->Parameters[i].Name, name) == 0)
            return i;
      }
   }
   else {
      /* name is not null-terminated, use nameLen */
      for (i = 0; i < (GLint) paramList->NumParameters; i++) {
         if (_mesa_strncmp(paramList->Parameters[i].Name, name, nameLen) == 0
             && _mesa_strlen(paramList->Parameters[i].Name) == (size_t)nameLen)
            return i;
      }
   }
   return -1;
}
Exemplo n.º 9
0
/**
 * Get next token from input stream but don't increment stream pointer.
 */
static GLboolean
Peek_Token(struct parse_state *parseState, GLubyte *token)
{
   GLint i, len;
   i = GetToken(parseState, token);
   if (i <= 0) {
      parseState->pos += (-i);
      return GL_FALSE;
   }
   len = _mesa_strlen((const char *) token);
   parseState->pos += (i - len);
   return GL_TRUE;
}
Exemplo n.º 10
0
/**
 * Clone string, storing in current mempool.
 */
char *
_slang_strdup(const char *s)
{
   if (s) {
      size_t l = _mesa_strlen(s);
      char *s2 = (char *) _slang_alloc(l + 1);
      if (s2)
         _mesa_strcpy(s2, s);
      return s2;
   }
   else {
      return NULL;
   }
}
Exemplo n.º 11
0
/**
 * Find longest name of all uniform parameters in list.
 */
GLuint
_mesa_longest_parameter_name(const struct gl_program_parameter_list *list,
                             enum register_file type)
{
   GLuint i, maxLen = 0;
   if (!list)
      return 0;
   for (i = 0; i < list->NumParameters; i++) {
      if (list->Parameters[i].Type == type) {
         GLuint len = _mesa_strlen(list->Parameters[i].Name);
         if (len > maxLen)
            maxLen = len;
      }
   }
   return maxLen;
}
Exemplo n.º 12
0
static GLvoid
pp_annotate (slang_string *output, const char *fmt, ...)
{
#if PP_ANNOTATE
   va_list va;
   char buffer[1024];

   va_start (va, fmt);
   _mesa_vsprintf (buffer, fmt, va);
   va_end (va);
   slang_string_pushs (output, buffer, _mesa_strlen (buffer));
#else
   (GLvoid) (output);
   (GLvoid) (fmt);
#endif
}
Exemplo n.º 13
0
static GLboolean
parse_if (slang_string *output, const byte *prod, GLuint *pi, GLint *result, pp_state *state,
          grammar eid)
{
   const char *text;
   GLuint len;

   text = (const char *) (&prod[*pi]);
   len = _mesa_strlen (text);

   if (state->cond.top->effective) {
      slang_string expr;
      GLuint count;
      GLint results[2];
      expand_state es;

      /* Expand the expression. */
      slang_string_init (&expr);
      es.output = &expr;
      es.input = text;
      es.state = state;
      if (!expand (&es, &state->symbols))
         return GL_FALSE;

      /* Execute the expression. */
      count = execute_expressions (output, eid, (const byte *) (slang_string_cstr (&expr)),
                                   results, state->elog);
      slang_string_free (&expr);
      if (count != 1)
         return GL_FALSE;
      *result = results[0];
   }
   else {
      /* The directive is dead. */
      *result = 0;
   }

   *pi += len + 1;
   return GL_TRUE;
}
Exemplo n.º 14
0
void GLAPIENTRY
_mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
{
   struct program *prog;
   GET_CURRENT_CONTEXT(ctx);

   if (!ctx->_CurrentProgram)
      ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (target == GL_VERTEX_PROGRAM_ARB
       && ctx->Extensions.ARB_vertex_program) {
      prog = &(ctx->VertexProgram.Current->Base);
   }
   else if (target == GL_FRAGMENT_PROGRAM_ARB
            && ctx->Extensions.ARB_fragment_program) {
      prog = &(ctx->FragmentProgram.Current->Base);
   }
   else {
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
      return;
   }

   ASSERT(prog);

   switch (pname) {
      case GL_PROGRAM_LENGTH_ARB:
         *params = prog->String ? (GLint)_mesa_strlen((char *) prog->String) : 0;
         break;
      case GL_PROGRAM_FORMAT_ARB:
         *params = prog->Format;
         break;
      case GL_PROGRAM_BINDING_ARB:
         *params = prog->Id;
         break;
      case GL_PROGRAM_INSTRUCTIONS_ARB:
         *params = prog->NumInstructions;
         break;
      case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
         if (target == GL_VERTEX_PROGRAM_ARB)
            *params = ctx->Const.MaxVertexProgramInstructions;
         else
            *params = ctx->Const.MaxFragmentProgramInstructions;
         break;
      case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
         *params = prog->NumInstructions;
         break;
      case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
         if (target == GL_VERTEX_PROGRAM_ARB)
            *params = ctx->Const.MaxVertexProgramInstructions;
         else
            *params = ctx->Const.MaxFragmentProgramInstructions;
         break;
      case GL_PROGRAM_TEMPORARIES_ARB:
         *params = prog->NumTemporaries;
         break;
      case GL_MAX_PROGRAM_TEMPORARIES_ARB:
         if (target == GL_VERTEX_PROGRAM_ARB)
            *params = ctx->Const.MaxVertexProgramTemps;
         else
            *params = ctx->Const.MaxFragmentProgramTemps;
         break;
      case GL_PROGRAM_NATIVE_TEMPORARIES_ARB:
         /* XXX same as GL_PROGRAM_TEMPORARIES_ARB? */
         *params = prog->NumTemporaries;
         break;
      case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
         /* XXX same as GL_MAX_PROGRAM_TEMPORARIES_ARB? */
         if (target == GL_VERTEX_PROGRAM_ARB)
            *params = ctx->Const.MaxVertexProgramTemps;
         else
            *params = ctx->Const.MaxFragmentProgramTemps;
         break;
      case GL_PROGRAM_PARAMETERS_ARB:
         *params = prog->NumParameters;
         break;
      case GL_MAX_PROGRAM_PARAMETERS_ARB:
         if (target == GL_VERTEX_PROGRAM_ARB)
            *params = ctx->Const.MaxVertexProgramLocalParams;
         else
            *params = ctx->Const.MaxFragmentProgramLocalParams;
         break;
      case GL_PROGRAM_NATIVE_PARAMETERS_ARB:
         /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
         *params = prog->NumParameters;
         break;
      case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
         /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
         if (target == GL_VERTEX_PROGRAM_ARB)
            *params = ctx->Const.MaxVertexProgramLocalParams;
         else
            *params = ctx->Const.MaxFragmentProgramLocalParams;
         break;
      case GL_PROGRAM_ATTRIBS_ARB:
         *params = prog->NumAttributes;
         break;
      case GL_MAX_PROGRAM_ATTRIBS_ARB:
         if (target == GL_VERTEX_PROGRAM_ARB)
            *params = ctx->Const.MaxVertexProgramAttribs;
         else
            *params = ctx->Const.MaxFragmentProgramAttribs;
         break;
      case GL_PROGRAM_NATIVE_ATTRIBS_ARB:
         /* XXX same as GL_PROGRAM_ATTRIBS_ARB? */
         *params = prog->NumAttributes;
         break;
      case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
         /* XXX same as GL_MAX_PROGRAM_ATTRIBS_ARB? */
         if (target == GL_VERTEX_PROGRAM_ARB)
            *params = ctx->Const.MaxVertexProgramAttribs;
         else
            *params = ctx->Const.MaxFragmentProgramAttribs;
         break;
      case GL_PROGRAM_ADDRESS_REGISTERS_ARB:
         *params = prog->NumAddressRegs;
         break;
      case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
         if (target == GL_VERTEX_PROGRAM_ARB)
            *params = ctx->Const.MaxVertexProgramAddressRegs;
         else
            *params = ctx->Const.MaxFragmentProgramAddressRegs;
         break;
      case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
         /* XXX same as GL_PROGRAM_ADDRESS_REGISTERS_ARB? */
         *params = prog->NumAddressRegs;
         break;
      case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
         /* XXX same as GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB? */
         if (target == GL_VERTEX_PROGRAM_ARB)
            *params = ctx->Const.MaxVertexProgramAddressRegs;
         else
            *params = ctx->Const.MaxFragmentProgramAddressRegs;
         break;
      case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
         if (target == GL_VERTEX_PROGRAM_ARB)
            *params = ctx->Const.MaxVertexProgramLocalParams;
         else
            *params = ctx->Const.MaxFragmentProgramLocalParams;
         break;
      case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
         if (target == GL_VERTEX_PROGRAM_ARB)
            *params = ctx->Const.MaxVertexProgramEnvParams;
         else
            *params = ctx->Const.MaxFragmentProgramEnvParams;
         break;
      case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB:
	 if (ctx->Driver.IsProgramNative) 
	    *params = ctx->Driver.IsProgramNative( ctx, target, prog );
	 else
	    *params = GL_TRUE;
         break;

      /*
       * The following apply to fragment programs only.
       */
      case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
      case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
         if (target != GL_FRAGMENT_PROGRAM_ARB) {
            _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
            return;
         }
         *params = ctx->FragmentProgram.Current->NumAluInstructions;
         break;
      case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
      case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
         if (target != GL_FRAGMENT_PROGRAM_ARB) {
            _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
            return;
         }
         *params = ctx->FragmentProgram.Current->NumTexInstructions;
         break;
      case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
      case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
         if (target != GL_FRAGMENT_PROGRAM_ARB) {
            _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
            return;
         }
         *params = ctx->FragmentProgram.Current->NumTexIndirections;
         break;
      case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
      case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
         if (target != GL_FRAGMENT_PROGRAM_ARB) {
            _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
            return;
         }
         *params = ctx->Const.MaxFragmentProgramAluInstructions;
         break;
      case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
      case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
         if (target != GL_FRAGMENT_PROGRAM_ARB) {
            _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
            return;
         }
         *params = ctx->Const.MaxFragmentProgramTexInstructions;
         break;
      case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB:
      case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
         if (target != GL_FRAGMENT_PROGRAM_ARB) {
            _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
            return;
         }
         *params = ctx->Const.MaxFragmentProgramTexIndirections;
         break;
      default:
         _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
         return;
   }
}
Exemplo n.º 15
0
unsigned int slang_string_length (const char *str)
{
	return _mesa_strlen (str);
}
Exemplo n.º 16
0
void
_mesa_GetProgramRegisterfvMESA(GLenum target,
                               GLsizei len, const GLubyte *registerName,
                               GLfloat *v)
{
   char reg[1000];
   GET_CURRENT_CONTEXT(ctx);

   /* We _should_ be inside glBegin/glEnd */
#if 0
   if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramRegisterfvMESA");
      return;
   }
#endif

   /* make null-terminated copy of registerName */
   len = MIN2((unsigned int) len, sizeof(reg) - 1);
   _mesa_memcpy(reg, registerName, len);
   reg[len] = 0;

   switch (target) {
      case GL_VERTEX_PROGRAM_NV:
         if (!ctx->Extensions.ARB_vertex_program &&
             !ctx->Extensions.NV_vertex_program) {
            _mesa_error(ctx, GL_INVALID_ENUM,
                        "glGetProgramRegisterfvMESA(target)");
            return;
         }
         if (!ctx->VertexProgram.Enabled) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "glGetProgramRegisterfvMESA");
            return;
         }
         /* GL_NV_vertex_program */
         if (reg[0] == 'R') {
            /* Temp register */
            GLint i = _mesa_atoi(reg + 1);
            if (i >= (GLint)ctx->Const.MaxVertexProgramTemps) {
               _mesa_error(ctx, GL_INVALID_VALUE,
                           "glGetProgramRegisterfvMESA(registerName)");
               return;
            }
            COPY_4V(v, ctx->VertexProgram.Temporaries[i]);
         }
         else if (reg[0] == 'v' && reg[1] == '[') {
            /* Vertex Input attribute */
            GLuint i;
            for (i = 0; i < ctx->Const.MaxVertexProgramAttribs; i++) {
               const char *name = _mesa_nv_vertex_input_register_name(i);
               char number[10];
               sprintf(number, "%d", i);
               if (_mesa_strncmp(reg + 2, name, 4) == 0 ||
                   _mesa_strncmp(reg + 2, number, _mesa_strlen(number)) == 0) {
                  COPY_4V(v, ctx->VertexProgram.Inputs[i]);
                  return;
               }
            }
            _mesa_error(ctx, GL_INVALID_VALUE,
                        "glGetProgramRegisterfvMESA(registerName)");
            return;
         }
         else if (reg[0] == 'o' && reg[1] == '[') {
            /* Vertex output attribute */
         }
         /* GL_ARB_vertex_program */
         else if (_mesa_strncmp(reg, "vertex.", 7) == 0) {

         }
         else {
            _mesa_error(ctx, GL_INVALID_VALUE,
                        "glGetProgramRegisterfvMESA(registerName)");
            return;
         }
         break;
      case GL_FRAGMENT_PROGRAM_ARB:
         if (!ctx->Extensions.ARB_fragment_program) {
            _mesa_error(ctx, GL_INVALID_ENUM,
                        "glGetProgramRegisterfvMESA(target)");
            return;
         }
         if (!ctx->FragmentProgram.Enabled) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "glGetProgramRegisterfvMESA");
            return;
         }
         /* XXX to do */
         break;
      case GL_FRAGMENT_PROGRAM_NV:
         if (!ctx->Extensions.NV_fragment_program) {
            _mesa_error(ctx, GL_INVALID_ENUM,
                        "glGetProgramRegisterfvMESA(target)");
            return;
         }
         if (!ctx->FragmentProgram.Enabled) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "glGetProgramRegisterfvMESA");
            return;
         }
         if (reg[0] == 'R') {
            /* Temp register */
            GLint i = _mesa_atoi(reg + 1);
            if (i >= (GLint)ctx->Const.MaxFragmentProgramTemps) {
               _mesa_error(ctx, GL_INVALID_VALUE,
                           "glGetProgramRegisterfvMESA(registerName)");
               return;
            }
            COPY_4V(v, ctx->FragmentProgram.Machine.Temporaries[i]);
         }
         else if (reg[0] == 'f' && reg[1] == '[') {
            /* Fragment input attribute */
            GLuint i;
            for (i = 0; i < ctx->Const.MaxFragmentProgramAttribs; i++) {
               const char *name = _mesa_nv_fragment_input_register_name(i);
               if (_mesa_strncmp(reg + 2, name, 4) == 0) {
                  COPY_4V(v, ctx->FragmentProgram.Machine.Inputs[i]);
                  return;
               }
            }
            _mesa_error(ctx, GL_INVALID_VALUE,
                        "glGetProgramRegisterfvMESA(registerName)");
            return;
         }
         else if (_mesa_strcmp(reg, "o[COLR]") == 0) {
            /* Fragment output color */
            COPY_4V(v, ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_COLR]);
         }
         else if (_mesa_strcmp(reg, "o[COLH]") == 0) {
            /* Fragment output color */
            COPY_4V(v, ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_COLH]);
         }
         else if (_mesa_strcmp(reg, "o[DEPR]") == 0) {
            /* Fragment output depth */
            COPY_4V(v, ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_DEPR]);
         }
         else {
            /* try user-defined identifiers */
            const GLfloat *value = _mesa_lookup_parameter_value(
                       ctx->FragmentProgram.Current->Parameters, -1, reg);
            if (value) {
               COPY_4V(v, value);
            }
            else {
               _mesa_error(ctx, GL_INVALID_VALUE,
                           "glGetProgramRegisterfvMESA(registerName)");
               return;
            }
         }
         break;
      default:
         _mesa_error(ctx, GL_INVALID_ENUM,
                     "glGetProgramRegisterfvMESA(target)");
         return;
   }

}
Exemplo n.º 17
0
char *slang_string_concat (char *dst, const char *src)
{
    return _mesa_strcpy (dst + _mesa_strlen (dst), src);
}
Exemplo n.º 18
0
void GLAPIENTRY
_mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
{
   const struct gl_program_constants *limits;
   struct gl_program *prog;
   GET_CURRENT_CONTEXT(ctx);

   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (target == GL_VERTEX_PROGRAM_ARB
       && ctx->Extensions.ARB_vertex_program) {
      prog = &(ctx->VertexProgram.Current->Base);
      limits = &ctx->Const.VertexProgram;
   }
   else if (target == GL_FRAGMENT_PROGRAM_ARB
            && ctx->Extensions.ARB_fragment_program) {
      prog = &(ctx->FragmentProgram.Current->Base);
      limits = &ctx->Const.FragmentProgram;
   }
   else {
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
      return;
   }

   ASSERT(prog);
   ASSERT(limits);

   /* Queries supported for both vertex and fragment programs */
   switch (pname) {
      case GL_PROGRAM_LENGTH_ARB:
         *params
            = prog->String ? (GLint) _mesa_strlen((char *) prog->String) : 0;
         return;
      case GL_PROGRAM_FORMAT_ARB:
         *params = prog->Format;
         return;
      case GL_PROGRAM_BINDING_ARB:
         *params = prog->Id;
         return;
      case GL_PROGRAM_INSTRUCTIONS_ARB:
         *params = prog->NumInstructions;
         return;
      case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
         *params = limits->MaxInstructions;
         return;
      case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
         *params = prog->NumNativeInstructions;
         return;
      case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
         *params = limits->MaxNativeInstructions;
         return;
      case GL_PROGRAM_TEMPORARIES_ARB:
         *params = prog->NumTemporaries;
         return;
      case GL_MAX_PROGRAM_TEMPORARIES_ARB:
         *params = limits->MaxTemps;
         return;
      case GL_PROGRAM_NATIVE_TEMPORARIES_ARB:
         *params = prog->NumNativeTemporaries;
         return;
      case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
         *params = limits->MaxNativeTemps;
         return;
      case GL_PROGRAM_PARAMETERS_ARB:
         *params = prog->NumParameters;
         return;
      case GL_MAX_PROGRAM_PARAMETERS_ARB:
         *params = limits->MaxParameters;
         return;
      case GL_PROGRAM_NATIVE_PARAMETERS_ARB:
         *params = prog->NumNativeParameters;
         return;
      case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
         *params = limits->MaxNativeParameters;
         return;
      case GL_PROGRAM_ATTRIBS_ARB:
         *params = prog->NumAttributes;
         return;
      case GL_MAX_PROGRAM_ATTRIBS_ARB:
         *params = limits->MaxAttribs;
         return;
      case GL_PROGRAM_NATIVE_ATTRIBS_ARB:
         *params = prog->NumNativeAttributes;
         return;
      case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
         *params = limits->MaxNativeAttribs;
         return;
      case GL_PROGRAM_ADDRESS_REGISTERS_ARB:
         *params = prog->NumAddressRegs;
         return;
      case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
         *params = limits->MaxAddressRegs;
         return;
      case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
         *params = prog->NumNativeAddressRegs;
         return;
      case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
         *params = limits->MaxNativeAddressRegs;
         return;
      case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
         *params = limits->MaxLocalParams;
         return;
      case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
         *params = limits->MaxEnvParams;
         return;
      case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB:
         /*
          * XXX we may not really need a driver callback here.
          * If the number of native instructions, registers, etc. used
          * are all below the maximums, we could return true.
          * The spec says that even if this query returns true, there's
          * no guarantee that the program will run in hardware.
          */
         if (prog->Id == 0) {
            /* default/null program */
            *params = GL_FALSE;
         }
	 else if (ctx->Driver.IsProgramNative) {
            /* ask the driver */
	    *params = ctx->Driver.IsProgramNative( ctx, target, prog );
         }
	 else {
            /* probably running in software */
	    *params = GL_TRUE;
         }
         return;
      default:
         /* continue with fragment-program only queries below */
         break;
   }

   /*
    * The following apply to fragment programs only (at this time)
    */
   if (target == GL_FRAGMENT_PROGRAM_ARB) {
      const struct gl_fragment_program *fp = ctx->FragmentProgram.Current;
      switch (pname) {
         case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
            *params = fp->Base.NumNativeAluInstructions;
            return;
         case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
            *params = fp->Base.NumAluInstructions;
            return;
         case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
            *params = fp->Base.NumTexInstructions;
            return;
         case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
            *params = fp->Base.NumNativeTexInstructions;
            return;
         case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
            *params = fp->Base.NumTexIndirections;
            return;
         case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
            *params = fp->Base.NumNativeTexIndirections;
            return;
         case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
            *params = limits->MaxAluInstructions;
            return;
         case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
            *params = limits->MaxNativeAluInstructions;
            return;
         case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
            *params = limits->MaxTexInstructions;
            return;
         case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
            *params = limits->MaxNativeTexInstructions;
            return;
         case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB:
            *params = limits->MaxTexIndirections;
            return;
         case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
            *params = limits->MaxNativeTexIndirections;
            return;
         default:
            _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
            return;
      }
   } else {
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
      return;
   }
}
Exemplo n.º 19
0
/**
 * Return a string describing the CPU architexture and extensions that
 * Mesa is using (such as SSE or Altivec).
 * \return information string, free it with _mesa_free()
 */
char *
_mesa_get_cpu_string(void)
{
#define MAX_STRING 50
   char *buffer;

   buffer = (char *) _mesa_malloc(MAX_STRING);
   if (!buffer)
      return NULL;

   buffer[0] = 0;

#ifdef USE_X86_ASM

   if (_mesa_x86_cpu_features) {
      strcat(buffer, "x86");
   }

# ifdef USE_MMX_ASM
   if (cpu_has_mmx) {
      strcat(buffer, (cpu_has_mmxext) ? "/MMX+" : "/MMX");
   }
# endif
# ifdef USE_3DNOW_ASM
   if (cpu_has_3dnow) {
      strcat(buffer, (cpu_has_3dnowext) ? "/3DNow!+" : "/3DNow!");
   }
# endif
# ifdef USE_SSE_ASM
   if (cpu_has_xmm) {
      strcat(buffer, (cpu_has_xmm2) ? "/SSE2" : "/SSE");
   }
# endif

#elif defined(USE_SPARC_ASM)

   strcat(buffer, "SPARC");

#elif defined(USE_PPC_ASM)

   if (_mesa_ppc_cpu_features) {
      strcat(buffer, (cpu_has_64) ? "PowerPC 64" : "PowerPC");
   }

# ifdef USE_VMX_ASM

   if (cpu_has_vmx) {
      strcat(buffer, "/Altivec");
   }

# endif

   if (! cpu_has_fpu) {
      strcat(buffer, "/No FPU");
   }

#endif

   assert(_mesa_strlen(buffer) < MAX_STRING);

   return buffer;
}
Exemplo n.º 20
0
static GLboolean
execute_expression (slang_string *output, const byte *code, GLuint *pi, GLint *result,
                    slang_info_log *elog)
{
   GLuint i = *pi;
   GLint stack[EXECUTION_STACK_SIZE];
   GLuint sp = EXECUTION_STACK_SIZE;

   while (code[i] != OP_END) {
      switch (code[i++]) {
         case OP_PUSHINT:
            i++;
            PUSH(_mesa_atoi ((const char *) (&code[i])));
            i += _mesa_strlen ((const char *) (&code[i])) + 1;
            break;
         case OP_LOGICALOR:
            BINARY(||);
            break;
         case OP_LOGICALAND:
            BINARY(&&);
            break;
         case OP_OR:
            BINARY(|);
            break;
         case OP_XOR:
            BINARY(^);
            break;
         case OP_AND:
            BINARY(&);
            break;
         case OP_EQUAL:
            BINARY(==);
            break;
         case OP_NOTEQUAL:
            BINARY(!=);
            break;
         case OP_LESSEQUAL:
            BINARY(<=);
            break;
         case OP_GREATEREQUAL:
            BINARY(>=);
            break;
         case OP_LESS:
            BINARY(<);
            break;
         case OP_GREATER:
            BINARY(>);
            break;
         case OP_LEFTSHIFT:
            BINARY(<<);
            break;
         case OP_RIGHTSHIFT:
            BINARY(>>);
            break;
         case OP_ADD:
            BINARY(+);
            break;
         case OP_SUBTRACT:
            BINARY(-);
            break;
         case OP_MULTIPLY:
            BINARY(*);
            break;
         case OP_DIVIDE:
            BINARYDIV(/);
            break;
         case OP_MODULUS:
            BINARYDIV(%);
            break;
         case OP_PLUS:
            UNARY(+);
            break;
         case OP_MINUS:
            UNARY(-);
            break;
         case OP_NEGATE:
            UNARY(!);
            break;
         case OP_COMPLEMENT:
            UNARY(~);
            break;
         default:
            assert (0);
      }
   }

   /* Write-back the index skipping the OP_END. */
   *pi = i + 1;

   /* There should be exactly one value left on the stack. This is our result. */
   POP(*result);
   pp_annotate (output, "%d ", *result);
   assert (sp == EXECUTION_STACK_SIZE);
   return GL_TRUE;
}
Exemplo n.º 21
0
static GLboolean
preprocess_source (slang_string *output, const char *source,
                   grammar pid, grammar eid,
                   slang_info_log *elog,
                   const struct gl_extensions *extensions,
                   struct gl_sl_pragmas *pragmas)
{
   static const char *predefined[] = {
      "__FILE__",
      "__LINE__",
      "__VERSION__",
#if FEATURE_es2_glsl
      "GL_ES",
      "GL_FRAGMENT_PRECISION_HIGH",
#endif
      NULL
   };
   byte *prod;
   GLuint size, i;
   pp_state state;

   if (!grammar_fast_check (pid, (const byte *) (source), &prod, &size, 65536)) {
      grammar_error_to_log (elog);
      return GL_FALSE;
   }

   pp_state_init (&state, elog, extensions);
   pp_pragmas_init (pragmas);

   /* add the predefined symbols to the symbol table */
   for (i = 0; predefined[i]; i++) {
      pp_symbol *symbol = NULL;
      symbol = pp_symbols_push(&state.symbols);
      assert(symbol);
      slang_string_pushs(&symbol->name,
                         predefined[i], _mesa_strlen(predefined[i]));
   }

   i = 0;
   while (i < size) {
      if (prod[i] != ESCAPE_TOKEN) {
         if (state.cond.top->effective) {
            slang_string input;
            expand_state es;

            /* Eat only one line of source code to expand it.
             * FIXME: This approach has one drawback. If a macro with parameters spans across
             *        multiple lines, the preprocessor will raise an error. */
            slang_string_init (&input);
            while (prod[i] != '\0' && prod[i] != '\n')
               slang_string_pushc (&input, prod[i++]);
            if (prod[i] != '\0')
               slang_string_pushc (&input, prod[i++]);

            /* Increment line number. */
            state.line++;

            es.output = output;
            es.input = slang_string_cstr (&input);
            es.state = &state;
            if (!expand (&es, &state.symbols))
               goto error;

            slang_string_free (&input);
         }
         else {
            /* Condition stack is disabled - keep track on line numbers and output only newlines. */
            if (prod[i] == '\n') {
               state.line++;
               /*pp_annotate (output, "%c", prod[i]);*/
            }
            else {
               /*pp_annotate (output, "%c", prod[i]);*/
            }
            i++;
         }
      }
      else {
         const char *id;
         GLuint idlen;
         GLubyte token;

         i++;
         token = prod[i++];
         switch (token) {

         case TOKEN_END:
            /* End of source string.
               * Check if all #ifs have been terminated by matching #endifs.
               * On condition stack there should be only the global condition context. */
            if (state.cond.top->endif_required) {
               slang_info_log_error (elog, "end of source without matching #endif.");
               return GL_FALSE;
            }
            break;

         case TOKEN_DEFINE:
            {
               pp_symbol *symbol = NULL;

               /* Parse macro name. */
               id = (const char *) (&prod[i]);
               idlen = _mesa_strlen (id);
               if (state.cond.top->effective) {
                  pp_annotate (output, "// #define %s(", id);

                  /* If the symbol is already defined, override it. */
                  symbol = pp_symbols_find (&state.symbols, id);
                  if (symbol == NULL) {
                     symbol = pp_symbols_push (&state.symbols);
                     if (symbol == NULL)
                        goto error;
                     slang_string_pushs (&symbol->name, id, idlen);
                  }
                  else {
                     pp_symbol_reset (symbol);
                  }
               }
               i += idlen + 1;

               /* Parse optional macro parameters. */
               while (prod[i++] != PARAM_END) {
                  pp_symbol *param;

                  id = (const char *) (&prod[i]);
                  idlen = _mesa_strlen (id);
                  if (state.cond.top->effective) {
                     pp_annotate (output, "%s, ", id);
                     param = pp_symbols_push (&symbol->parameters);
                     if (param == NULL)
                        goto error;
                     slang_string_pushs (&param->name, id, idlen);
                  }
                  i += idlen + 1;
               }

               /* Parse macro replacement. */
               id = (const char *) (&prod[i]);
               idlen = _mesa_strlen (id);
               if (state.cond.top->effective) {
                  slang_string replacement;
                  expand_state es;

                  pp_annotate (output, ") %s", id);

                  slang_string_init(&replacement);
                  slang_string_pushs(&replacement, id, idlen);

                  /* Expand macro replacement. */
                  es.output = &symbol->replacement;
                  es.input = slang_string_cstr(&replacement);
                  es.state = &state;
                  if (!expand(&es, &state.symbols)) {
                     slang_string_free(&replacement);
                     goto error;
                  }
                  slang_string_free(&replacement);
               }
               i += idlen + 1;
            }
            break;

         case TOKEN_UNDEF:
            id = (const char *) (&prod[i]);
            i += _mesa_strlen (id) + 1;
            if (state.cond.top->effective) {
               pp_symbol *symbol;

               pp_annotate (output, "// #undef %s", id);
               /* Try to find symbol with given name and remove it. */
               symbol = pp_symbols_find (&state.symbols, id);
               if (symbol != NULL)
                  if (!pp_symbols_erase (&state.symbols, symbol))
                     goto error;
            }
            break;

         case TOKEN_IF:
            {
               GLint result;

               /* Parse #if expression end execute it. */
               pp_annotate (output, "// #if ");
               if (!parse_if (output, prod, &i, &result, &state, eid))
                  goto error;

               /* Push new condition on the stack. */
               if (!pp_cond_stack_push (&state.cond, state.elog))
                  goto error;
               state.cond.top->current = result ? GL_TRUE : GL_FALSE;
               state.cond.top->else_allowed = GL_TRUE;
               state.cond.top->endif_required = GL_TRUE;
               pp_cond_stack_reevaluate (&state.cond);
            }
            break;

         case TOKEN_ELSE:
            /* Check if #else is alloved here. */
            if (!state.cond.top->else_allowed) {
               slang_info_log_error (elog, "#else without matching #if.");
               goto error;
            }

            /* Negate current condition and reevaluate it. */
            state.cond.top->current = !state.cond.top->current;
            state.cond.top->else_allowed = GL_FALSE;
            pp_cond_stack_reevaluate (&state.cond);
            if (state.cond.top->effective)
               pp_annotate (output, "// #else");
            break;

         case TOKEN_ELIF:
            /* Check if #elif is alloved here. */
            if (!state.cond.top->else_allowed) {
               slang_info_log_error (elog, "#elif without matching #if.");
               goto error;
            }

            /* Negate current condition and reevaluate it. */
            state.cond.top->current = !state.cond.top->current;
            pp_cond_stack_reevaluate (&state.cond);

            if (state.cond.top->effective)
               pp_annotate (output, "// #elif ");

            {
               GLint result;

               /* Parse #elif expression end execute it. */
               if (!parse_if (output, prod, &i, &result, &state, eid))
                  goto error;

               /* Update current condition and reevaluate it. */
               state.cond.top->current = result ? GL_TRUE : GL_FALSE;
               pp_cond_stack_reevaluate (&state.cond);
            }
            break;

         case TOKEN_ENDIF:
            /* Check if #endif is alloved here. */
            if (!state.cond.top->endif_required) {
               slang_info_log_error (elog, "#endif without matching #if.");
               goto error;
            }

            /* Pop the condition off the stack. */
            state.cond.top++;
            if (state.cond.top->effective)
               pp_annotate (output, "// #endif");
            break;

         case TOKEN_EXTENSION:
            /* Parse the extension name. */
            id = (const char *) (&prod[i]);
            i += _mesa_strlen (id) + 1;
            if (state.cond.top->effective)
               pp_annotate (output, "// #extension %s: ", id);

            /* Parse and apply extension behavior. */
            if (state.cond.top->effective) {
               switch (prod[i++]) {

               case BEHAVIOR_REQUIRE:
                  pp_annotate (output, "require");
                  if (!pp_ext_set (&state.ext, id, GL_TRUE)) {
                     if (_mesa_strcmp (id, "all") == 0) {
                        slang_info_log_error (elog, "require: bad behavior for #extension all.");
                        goto error;
                     }
                     else {
                        slang_info_log_error (elog, "%s: required extension is not supported.", id);
                        goto error;
                     }
                  }
                  break;

               case BEHAVIOR_ENABLE:
                  pp_annotate (output, "enable");
                  if (!pp_ext_set (&state.ext, id, GL_TRUE)) {
                     if (_mesa_strcmp (id, "all") == 0) {
                        slang_info_log_error (elog, "enable: bad behavior for #extension all.");
                        goto error;
                     }
                     else {
                        slang_info_log_warning (elog, "%s: enabled extension is not supported.", id);
                     }
                  }
                  break;

               case BEHAVIOR_WARN:
                  pp_annotate (output, "warn");
                  if (!pp_ext_set (&state.ext, id, GL_TRUE)) {
                     if (_mesa_strcmp (id, "all") != 0) {
                        slang_info_log_warning (elog, "%s: enabled extension is not supported.", id);
                     }
                  }
                  break;

               case BEHAVIOR_DISABLE:
                  pp_annotate (output, "disable");
                  if (!pp_ext_set (&state.ext, id, GL_FALSE)) {
                     if (_mesa_strcmp (id, "all") == 0) {
                        pp_ext_disable_all (&state.ext);
                     }
                     else {
                        slang_info_log_warning (elog, "%s: disabled extension is not supported.", id);
                     }
                  }
                  break;

               default:
                  assert (0);
               }
            }
            break;

         case TOKEN_PRAGMA:
            {
               GLint have_param;
               const char *pragma, *param;

               pragma = (const char *) (&prod[i]);
               i += _mesa_strlen(pragma) + 1;
               have_param = (prod[i++] == PRAGMA_PARAM);
               if (have_param) {
                  param = (const char *) (&prod[i]);
                  i += _mesa_strlen(param) + 1;
               }
               else {
                  param = NULL;
               }
               pp_pragma(pragmas, pragma, param);
            }
            break;

         case TOKEN_LINE:
            id = (const char *) (&prod[i]);
            i += _mesa_strlen (id) + 1;

            if (state.cond.top->effective) {
               slang_string buffer;
               GLuint count;
               GLint results[2];
               expand_state es;

               slang_string_init (&buffer);
               state.line++;
               es.output = &buffer;
               es.input = id;
               es.state = &state;
               if (!expand (&es, &state.symbols))
                  goto error;

               pp_annotate (output, "// #line ");
               count = execute_expressions (output, eid,
                                             (const byte *) (slang_string_cstr (&buffer)),
                                             results, state.elog);
               slang_string_free (&buffer);
               if (count == 0)
                  goto error;

               state.line = results[0] - 1;
               if (count == 2)
                  state.file = results[1];
            }
            break;
         }
      }
   }

   /* Check for missing #endifs. */
   if (state.cond.top->endif_required) {
      slang_info_log_error (elog, "#endif expected but end of source found.");
      goto error;
   }

   grammar_alloc_free(prod);
   pp_state_free (&state);
   return GL_TRUE;

error:
   grammar_alloc_free(prod);
   pp_state_free (&state);
   return GL_FALSE;
}