⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nvvertparse.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Mesa 3-D graphics library * Version:  6.5.2 * * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *//** * \file nvvertparse.c * NVIDIA vertex program parser. * \author Brian Paul *//* * Regarding GL_NV_vertex_program, GL_NV_vertex_program1_1: * * Portions of this software may use or implement intellectual * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims * any and all warranties with respect to such intellectual property, * including any use thereof or modifications thereto. */#include "glheader.h"#include "context.h"#include "imports.h"#include "macros.h"#include "nvprogram.h"#include "nvvertparse.h"#include "prog_instruction.h"#include "program.h"/** * Current parsing state.  This structure is passed among the parsing * functions and keeps track of the current parser position and various * program attributes. */struct parse_state {   GLcontext *ctx;   const GLubyte *start;   const GLubyte *pos;   const GLubyte *curLine;   GLboolean isStateProgram;   GLboolean isPositionInvariant;   GLboolean isVersion1_1;   GLbitfield inputsRead;   GLbitfield outputsWritten;   GLboolean anyProgRegsWritten;   GLuint numInst;                 /* number of instructions parsed */};/* * Called whenever we find an error during parsing. */static voidrecord_error(struct parse_state *parseState, const char *msg, int lineNo){#ifdef DEBUG   GLint line, column;   const GLubyte *lineStr;   lineStr = _mesa_find_line_column(parseState->start,                                    parseState->pos, &line, &column);   _mesa_debug(parseState->ctx,               "nvfragparse.c(%d): line %d, column %d:%s (%s)\n",               lineNo, line, column, (char *) lineStr, msg);   _mesa_free((void *) lineStr);#else   (void) lineNo;#endif   /* Check that no error was already recorded.  Only record the first one. */   if (parseState->ctx->Program.ErrorString[0] == 0) {      _mesa_set_program_error(parseState->ctx,                              parseState->pos - parseState->start,                              msg);   }}#define RETURN_ERROR							\do {									\   record_error(parseState, "Unexpected end of input.", __LINE__);	\   return GL_FALSE;							\} while(0)#define RETURN_ERROR1(msg)						\do {									\   record_error(parseState, msg, __LINE__);				\   return GL_FALSE;							\} while(0)#define RETURN_ERROR2(msg1, msg2)					\do {									\   char err[1000];							\   _mesa_sprintf(err, "%s %s", msg1, msg2);				\   record_error(parseState, err, __LINE__);				\   return GL_FALSE;							\} while(0)static GLboolean IsLetter(GLubyte b){   return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z');}static GLboolean IsDigit(GLubyte b){   return b >= '0' && b <= '9';}static GLboolean IsWhitespace(GLubyte b){   return b == ' ' || b == '\t' || b == '\n' || b == '\r';}/** * Starting at 'str' find the next token.  A token can be an integer, * an identifier or punctuation symbol. * \return <= 0 we found an error, else, return number of characters parsed. */static GLintGetToken(struct parse_state *parseState, GLubyte *token){   const GLubyte *str = parseState->pos;   GLint i = 0, j = 0;   token[0] = 0;   /* skip whitespace and comments */   while (str[i] && (IsWhitespace(str[i]) || str[i] == '#')) {      if (str[i] == '#') {         /* skip comment */         while (str[i] && (str[i] != '\n' && str[i] != '\r')) {            i++;         }         if (str[i] == '\n' || str[i] == '\r')            parseState->curLine = str + i + 1;      }      else {         /* skip whitespace */         if (str[i] == '\n' || str[i] == '\r')            parseState->curLine = str + i + 1;         i++;      }   }   if (str[i] == 0)      return -i;   /* try matching an integer */   while (str[i] && IsDigit(str[i])) {      token[j++] = str[i++];   }   if (j > 0 || !str[i]) {      token[j] = 0;      return i;   }   /* try matching an identifier */   if (IsLetter(str[i])) {      while (str[i] && (IsLetter(str[i]) || IsDigit(str[i]))) {         token[j++] = str[i++];      }      token[j] = 0;      return i;   }   /* punctuation character */   if (str[i]) {      token[0] = str[i++];      token[1] = 0;      return i;   }   /* end of input */   token[0] = 0;   return i;}/** * Get next token from input stream and increment stream pointer past token. */static GLbooleanParse_Token(struct parse_state *parseState, GLubyte *token){   GLint i;   i = GetToken(parseState, token);   if (i <= 0) {      parseState->pos += (-i);      return GL_FALSE;   }   parseState->pos += i;   return GL_TRUE;}/** * Get next token from input stream but don't increment stream pointer. */static GLbooleanPeek_Token(struct parse_state *parseState, GLubyte *token){   GLint i, len;   i = GetToken(parseState, token);   if (i <= 0) {      parseState->pos += (-i);      return GL_FALSE;   }   len = (GLint)_mesa_strlen((const char *) token);   parseState->pos += (i - len);   return GL_TRUE;}/** * Try to match 'pattern' as the next token after any whitespace/comments. * Advance the current parsing position only if we match the pattern. * \return GL_TRUE if pattern is matched, GL_FALSE otherwise. */static GLbooleanParse_String(struct parse_state *parseState, const char *pattern){   const GLubyte *m;   GLint i;   /* skip whitespace and comments */   while (IsWhitespace(*parseState->pos) || *parseState->pos == '#') {      if (*parseState->pos == '#') {         while (*parseState->pos && (*parseState->pos != '\n' && *parseState->pos != '\r')) {            parseState->pos += 1;         }         if (*parseState->pos == '\n' || *parseState->pos == '\r')            parseState->curLine = parseState->pos + 1;      }      else {         /* skip whitespace */         if (*parseState->pos == '\n' || *parseState->pos == '\r')            parseState->curLine = parseState->pos + 1;         parseState->pos += 1;      }   }   /* Try to match the pattern */   m = parseState->pos;   for (i = 0; pattern[i]; i++) {      if (*m != (GLubyte) pattern[i])         return GL_FALSE;      m += 1;   }   parseState->pos = m;   return GL_TRUE; /* success */}/**********************************************************************/static const char *InputRegisters[MAX_NV_VERTEX_PROGRAM_INPUTS + 1] = {   "OPOS", "WGHT", "NRML", "COL0", "COL1", "FOGC", "6", "7",   "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL};static const char *OutputRegisters[MAX_NV_VERTEX_PROGRAM_OUTPUTS + 1] = {   "HPOS", "COL0", "COL1", "FOGC",    "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7",    "PSIZ", "BFC0", "BFC1", NULL};/** * Parse a temporary register: Rnn */static GLbooleanParse_TempReg(struct parse_state *parseState, GLint *tempRegNum){   GLubyte token[100];   /* Should be 'R##' */   if (!Parse_Token(parseState, token))      RETURN_ERROR;   if (token[0] != 'R')      RETURN_ERROR1("Expected R##");   if (IsDigit(token[1])) {      GLint reg = _mesa_atoi((char *) (token + 1));      if (reg >= MAX_NV_VERTEX_PROGRAM_TEMPS)         RETURN_ERROR1("Bad temporary register name");      *tempRegNum = reg;   }   else {      RETURN_ERROR1("Bad temporary register name");   }   return GL_TRUE;}/** * Parse address register "A0.x" */static GLbooleanParse_AddrReg(struct parse_state *parseState){   /* match 'A0' */   if (!Parse_String(parseState, "A0"))      RETURN_ERROR;   /* match '.' */   if (!Parse_String(parseState, "."))      RETURN_ERROR;   /* match 'x' */   if (!Parse_String(parseState, "x"))      RETURN_ERROR;   return GL_TRUE;}/** * Parse absolute program parameter register "c[##]" */static GLbooleanParse_AbsParamReg(struct parse_state *parseState, GLint *regNum){   GLubyte token[100];   if (!Parse_String(parseState, "c"))      RETURN_ERROR;   if (!Parse_String(parseState, "["))      RETURN_ERROR;   if (!Parse_Token(parseState, token))      RETURN_ERROR;   if (IsDigit(token[0])) {      /* a numbered program parameter register */      GLint reg = _mesa_atoi((char *) token);      if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS)         RETURN_ERROR1("Bad program parameter number");      *regNum = reg;   }   else {      RETURN_ERROR;   }   if (!Parse_String(parseState, "]"))      RETURN_ERROR;   return GL_TRUE;}static GLbooleanParse_ParamReg(struct parse_state *parseState, struct prog_src_register *srcReg){   GLubyte token[100];   if (!Parse_String(parseState, "c"))      RETURN_ERROR;   if (!Parse_String(parseState, "["))      RETURN_ERROR;   if (!Peek_Token(parseState, token))      RETURN_ERROR;   if (IsDigit(token[0])) {      /* a numbered program parameter register */      GLint reg;      (void) Parse_Token(parseState, token);      reg = _mesa_atoi((char *) token);      if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS)         RETURN_ERROR1("Bad program parameter number");      srcReg->File = PROGRAM_ENV_PARAM;      srcReg->Index = reg;   }   else if (_mesa_strcmp((const char *) token, "A0") == 0) {      /* address register "A0.x" */      if (!Parse_AddrReg(parseState))         RETURN_ERROR;      srcReg->RelAddr = GL_TRUE;      srcReg->File = PROGRAM_ENV_PARAM;      /* Look for +/-N offset */      if (!Peek_Token(parseState, token))         RETURN_ERROR;      if (token[0] == '-' || token[0] == '+') {         const GLubyte sign = token[0];         (void) Parse_Token(parseState, token); /* consume +/- */         /* an integer should be next */         if (!Parse_Token(parseState, token))            RETURN_ERROR;         if (IsDigit(token[0])) {            const GLint k = _mesa_atoi((char *) token);            if (sign == '-') {               if (k > 64)                  RETURN_ERROR1("Bad address offset");               srcReg->Index = -k;            }            else {               if (k > 63)                  RETURN_ERROR1("Bad address offset");               srcReg->Index = k;            }         }         else {            RETURN_ERROR;         }      }      else {         /* probably got a ']', catch it below */      }   }   else {      RETURN_ERROR;   }   /* Match closing ']' */   if (!Parse_String(parseState, "]"))      RETURN_ERROR;   return GL_TRUE;}/** * Parse v[#] or v[<name>] */static GLbooleanParse_AttribReg(struct parse_state *parseState, GLint *tempRegNum){   GLubyte token[100];   GLint j;   /* Match 'v' */   if (!Parse_String(parseState, "v"))      RETURN_ERROR;   /* Match '[' */   if (!Parse_String(parseState, "["))      RETURN_ERROR;   /* match number or named register */   if (!Parse_Token(parseState, token))      RETURN_ERROR;   if (parseState->isStateProgram && token[0] != '0')      RETURN_ERROR1("Only v[0] accessible in vertex state programs");   if (IsDigit(token[0])) {      GLint reg = _mesa_atoi((char *) token);      if (reg >= MAX_NV_VERTEX_PROGRAM_INPUTS)         RETURN_ERROR1("Bad vertex attribute register name");      *tempRegNum = reg;   }   else {      for (j = 0; InputRegisters[j]; j++) {         if (_mesa_strcmp((const char *) token, InputRegisters[j]) == 0) {            *tempRegNum = j;            break;         }      }      if (!InputRegisters[j]) {         /* unknown input register label */         RETURN_ERROR2("Bad register name", token);      }   }   /* Match '[' */   if (!Parse_String(parseState, "]"))      RETURN_ERROR;   return GL_TRUE;}static GLbooleanParse_OutputReg(struct parse_state *parseState, GLint *outputRegNum){   GLubyte token[100];   GLint start, j;   /* Match 'o' */   if (!Parse_String(parseState, "o"))      RETURN_ERROR;   /* Match '[' */   if (!Parse_String(parseState, "["))      RETURN_ERROR;   /* Get output reg name */   if (!Parse_Token(parseState, token))      RETURN_ERROR;   if (parseState->isPositionInvariant)      start = 1; /* skip HPOS register name */   else      start = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -