Beispiel #1
0
/**
 * Parse a program local parameter register "p[##]"
 */
static GLboolean
Parse_ProgramParamReg(struct parse_state *parseState, GLint *regNum)
{
   GLubyte token[100];

   if (!Parse_String(parseState, "p["))
      RETURN_ERROR1("Expected p[");

   if (!Parse_Token(parseState, token))
      RETURN_ERROR;

   if (IsDigit(token[0])) {
      /* a numbered program parameter register */
      GLint reg = _mesa_atoi((const char *) token);
      if (reg >= MAX_NV_FRAGMENT_PROGRAM_PARAMS)
         RETURN_ERROR1("Invalid constant program number");
      *regNum = reg;
   }
   else {
      RETURN_ERROR;
   }

   if (!Parse_String(parseState, "]"))
      RETURN_ERROR1("Expected ]");

   return GL_TRUE;
}
Beispiel #2
0
/**
 * Parse f[name]  - fragment input register
 */
static GLboolean
Parse_FragReg(struct parse_state *parseState, GLint *tempRegNum)
{
   GLubyte token[100];
   GLint j;

   /* Match 'f[' */
   if (!Parse_String(parseState, "f["))
      RETURN_ERROR1("Expected f[");

   /* get <name> and look for match */
   if (!Parse_Token(parseState, token)) {
      RETURN_ERROR;
   }
   for (j = 0; InputRegisters[j]; j++) {
      if (_mesa_strcmp((const char *) token, InputRegisters[j]) == 0) {
         *tempRegNum = j;
         parseState->inputsRead |= (1 << j);
         break;
      }
   }
   if (!InputRegisters[j]) {
      /* unknown input register label */
      RETURN_ERROR2("Invalid register name", token);
   }

   /* Match '[' */
   if (!Parse_String(parseState, "]"))
      RETURN_ERROR1("Expected ]");

   return GL_TRUE;
}
Beispiel #3
0
static GLboolean
Parse_ScalarInstruction(struct parse_state *parseState,
                        struct prog_instruction *inst,
                        enum prog_opcode opcode)
{
   if (opcode == OPCODE_RCC && !parseState->isVersion1_1)
      RETURN_ERROR1("RCC illegal for vertex program 1.0");

   inst->Opcode = opcode;
   inst->StringPos = parseState->curLine - parseState->start;

   /* dest reg */
   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
      RETURN_ERROR;

   /* comma */
   if (!Parse_String(parseState, ","))
      RETURN_ERROR;

   /* first src arg */
   if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
      RETURN_ERROR;

   /* semicolon */
   if (!Parse_String(parseState, ";"))
      RETURN_ERROR;

   return GL_TRUE;
}
Beispiel #4
0
static GLboolean
Parse_AddressInstruction(struct parse_state *parseState, struct prog_instruction *inst)
{
   inst->Opcode = OPCODE_ARL;
   inst->StringPos = parseState->curLine - parseState->start;

   /* Make ARB_vp backends happy */
   inst->DstReg.File = PROGRAM_ADDRESS;
   inst->DstReg.WriteMask = WRITEMASK_X;
   inst->DstReg.Index = 0;

   /* dest A0 reg */
   if (!Parse_AddrReg(parseState))
      RETURN_ERROR;

   /* comma */
   if (!Parse_String(parseState, ","))
      RETURN_ERROR;

   /* parse src reg */
   if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
      RETURN_ERROR;

   /* semicolon */
   if (!Parse_String(parseState, ";"))
      RETURN_ERROR;

   return GL_TRUE;
}
Beispiel #5
0
UCS2 *Parser::Parse_Concat(bool pathname)
{
    UCS2 *str;
    UCS2 *New;

    Parse_Paren_Begin();

    New = Parse_String();

    EXPECT
        CASE(RIGHT_PAREN_TOKEN)
            UNGET
            EXIT
        END_CASE

        OTHERWISE
            UNGET
            Parse_Comma();
            str = Parse_String(pathname);
            New = UCS2_strcat(New, str);
            POV_FREE(str);
        END_CASE
    END_EXPECT

    Parse_Paren_End();

    return New;
}
Beispiel #6
0
/**
 * Parse absolute program parameter register "c[##]"
 */
static GLboolean
Parse_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;
}
Beispiel #7
0
static GLint
Parse_UnaryOpInstruction(struct parse_state *parseState,
                         struct vp_instruction *inst, enum vp_opcode opcode)
{
   if (opcode == VP_OPCODE_ABS && !parseState->isVersion1_1)
      RETURN_ERROR1("ABS illegal for vertex program 1.0");

   inst->Opcode = opcode;
   inst->StringPos = parseState->curLine - parseState->start;

   /* dest reg */
   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
      RETURN_ERROR;

   /* comma */
   if (!Parse_String(parseState, ","))
      RETURN_ERROR;

   /* src arg */
   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
      RETURN_ERROR;

   /* semicolon */
   if (!Parse_String(parseState, ";"))
      RETURN_ERROR;

   return GL_TRUE;
}
Beispiel #8
0
static GLboolean
Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum)
{
   GLubyte token[100];

   /* Match "o[" */
   if (!Parse_String(parseState, "o["))
      RETURN_ERROR1("Expected o[");

   /* Get output reg name */
   if (!Parse_Token(parseState, token))
      RETURN_ERROR;

   /* try to match an output register name */
   if (_mesa_strcmp((char *) token, "COLR") == 0 ||
       _mesa_strcmp((char *) token, "COLH") == 0) {
      /* note that we don't distinguish between COLR and COLH */
      *outputRegNum = FRAG_RESULT_COLOR;
      parseState->outputsWritten |= (1 << FRAG_RESULT_COLOR);
   }
   else if (_mesa_strcmp((char *) token, "DEPR") == 0) {
      *outputRegNum = FRAG_RESULT_DEPTH;
      parseState->outputsWritten |= (1 << FRAG_RESULT_DEPTH);
   }
   else {
      RETURN_ERROR1("Invalid output register name");
   }

   /* Match ']' */
   if (!Parse_String(parseState, "]"))
      RETURN_ERROR1("Expected ]");

   return GL_TRUE;
}
static GLboolean
Parse_BiOpInstruction(struct parse_state *parseState,
                      struct prog_instruction *inst,
                      enum prog_opcode opcode)
{
   if (opcode == OPCODE_DPH && !parseState->isVersion1_1)
      RETURN_ERROR1("DPH illegal for vertex program 1.0");
   if (opcode == OPCODE_SUB && !parseState->isVersion1_1)
      RETURN_ERROR1("SUB illegal for vertex program 1.0");

   inst->Opcode = opcode;
   inst->StringPos = parseState->curLine - parseState->start;

   /* dest reg */
   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
      RETURN_ERROR;

   /* comma */
   if (!Parse_String(parseState, ","))
      RETURN_ERROR;

   /* first src arg */
   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
      RETURN_ERROR;

   /* comma */
   if (!Parse_String(parseState, ","))
      RETURN_ERROR;

   /* second src arg */
   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1]))
      RETURN_ERROR;

   /* semicolon */
   if (!Parse_String(parseState, ";"))
      RETURN_ERROR;

   /* make sure we don't reference more than one program parameter register */
   if (inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
       inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
       inst->SrcReg[0].Index != inst->SrcReg[1].Index)
      RETURN_ERROR1("Can't reference two program parameter registers");

   /* make sure we don't reference more than one vertex attribute register */
   if (inst->SrcReg[0].File == PROGRAM_INPUT &&
       inst->SrcReg[1].File == PROGRAM_INPUT &&
       inst->SrcReg[0].Index != inst->SrcReg[1].Index)
      RETURN_ERROR1("Can't reference two vertex attribute registers");

   return GL_TRUE;
}
static GLboolean
Parse_PrintInstruction(struct parse_state *parseState,
                       struct prog_instruction *inst)
{
   const GLubyte *str;
   GLubyte *msg;
   GLuint len;
   GLint idx;

   /* The first argument is a literal string 'just like this' */
   if (!Parse_String(parseState, "'"))
      RETURN_ERROR1("Expected '");

   str = parseState->pos;
   for (len = 0; str[len] != '\''; len++) /* find closing quote */
      ;
   parseState->pos += len + 1;
   msg = (GLubyte*) malloc(len + 1);

   memcpy(msg, str, len);
   msg[len] = 0;
   inst->Data = msg;

   if (Parse_String(parseState, ",")) {
      /* got an optional register to print */
      GLubyte token[100];
      GetToken(parseState, token);
      if (token[0] == 'o') {
         /* dst reg */
         if (!Parse_OutputReg(parseState, &idx))
            RETURN_ERROR;
	 inst->SrcReg[0].Index = idx;
         inst->SrcReg[0].File = PROGRAM_OUTPUT;
      }
      else {
         /* src reg */
         if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
            RETURN_ERROR;
      }
   }
   else {
      inst->SrcReg[0].File = PROGRAM_UNDEFINED;
   }

   inst->SrcReg[0].Swizzle = SWIZZLE_NOOP;
   inst->SrcReg[0].Abs = GL_FALSE;
   inst->SrcReg[0].Negate = NEGATE_NONE;

   return GL_TRUE;
}
/**
 * Parse a write-only dummy register: RC or HC.
 */
static GLboolean
Parse_DummyReg(struct parse_state *parseState, GLint *regNum)
{
   if (Parse_String(parseState, "RC")) {
       *regNum = 0;
   }
   else if (Parse_String(parseState, "HC")) {
       *regNum = 1;
   }
   else {
      RETURN_ERROR1("Invalid write-only register name");
   }

   return GL_TRUE;
}
Beispiel #12
0
UCS2 *Parser::Parse_Substr(bool pathname)
{
	UCS2 *str;
	UCS2 *New;
	int l, d;

	GET(LEFT_PAREN_TOKEN);

	str = Parse_String(pathname);
	Parse_Comma();
	l = (int)Parse_Float();
	Parse_Comma();
	d = (int)Parse_Float();

	GET(RIGHT_PAREN_TOKEN);

	if(((l + d - 1) > UCS2_strlen(str)) || (l < 0) || (d < 0))
		Error("Illegal parameters in substr.");

	New = reinterpret_cast<UCS2 *>(POV_MALLOC(sizeof(UCS2) * (d + 1), "temporary string"));
	UCS2_strncpy(New, &(str[l - 1]), d);
	New[d] = 0;

	POV_FREE(str);

	return New;
}
Beispiel #13
0
std::string Parser::Parse_SysString(bool pathname, bool require)
{
    UCS2 *cstr = Parse_String(pathname, require);
    std::string ret(UCS2toSysString(cstr));
    POV_FREE(cstr);
    return ret;
}
/**
 * Parse address register "A0.x"
 */
static GLboolean
Parse_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;
}
Beispiel #15
0
static GLboolean
Parse_OptionSequence(struct parse_state *parseState,
                     struct vp_instruction program[])
{
   while (1) {
      if (!Parse_String(parseState, "OPTION"))
         return GL_TRUE;  /* ok, not an OPTION statement */
      if (Parse_String(parseState, "NV_position_invariant")) {
         parseState->isPositionInvariant = GL_TRUE;
      }
      else {
         RETURN_ERROR1("unexpected OPTION statement");
      }
      if (!Parse_String(parseState, ";"))
         return GL_FALSE;
   }
}
/**
 * Parse v[#] or v[<name>]
 */
static GLboolean
Parse_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;
}
Beispiel #17
0
void Parser::ParseString(UTF8String& s, bool pathname)
{
    /// @todo Add support for non-ASCII strings.

    UCS2 *str = Parse_String(pathname);
    char *New = UCS2_To_String(str);

    s = New;

    POV_FREE(str);
}
Beispiel #18
0
UCS2 *Parser::Parse_Strlwr(bool pathname)
{
	UCS2 *New;

	GET(LEFT_PAREN_TOKEN);

	New = Parse_String(pathname);
	UCS2_strlwr(New);

	GET(RIGHT_PAREN_TOKEN);

	return New;
}
Beispiel #19
0
UCS2 *Parser::Parse_Strlwr(bool pathname)
{
    UCS2 *New;

    Parse_Paren_Begin();

    New = Parse_String(pathname);
    UCS2_strlwr(New);

    Parse_Paren_End();

    return New;
}
Beispiel #20
0
char * Db_Record::Get_Field_Number (int number, char field [], int field_size)
{
	char *ptr = Record ();

	if (ptr == NULL) {
		Status (RECORD_SIZE);
		return (NULL);
	}
	for (int i=0; i < number && ptr != NULL; i++) {
		ptr = Parse_String (ptr, field, field_size);
	}
	return (field);
}
static GLboolean
Parse_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;

   /* try to match an output register name */
   for (j = start; OutputRegisters[j]; j++) {
      if (_mesa_strcmp((const char *) token, OutputRegisters[j]) == 0) {
         *outputRegNum = j;
         break;
      }
   }
   if (!OutputRegisters[j])
      RETURN_ERROR1("Unrecognized output register name");

   /* Match ']' */
   if (!Parse_String(parseState, "]"))
      RETURN_ERROR1("Expected ]");

   return GL_TRUE;
}
/**
 * Parse <number>, <varname> or {a, b, c, d}.
 * Return number of values in the vector or scalar, or zero if parse error.
 */
static GLuint
Parse_VectorOrScalarConstant(struct parse_state *parseState, GLfloat *vec)
{
   if (Parse_String(parseState, "{")) {
      return Parse_VectorConstant(parseState, vec);
   }
   else {
      GLboolean b = Parse_ScalarConstant(parseState, vec);
      if (b) {
         vec[1] = vec[2] = vec[3] = vec[0];
      }
      return b;
   }
}
static GLboolean
Parse_AddressInstruction(struct parse_state *parseState, struct vp_instruction *inst)
{
   inst->Opcode = VP_OPCODE_ARL;
   inst->StringPos = parseState->curLine - parseState->start;

   /* dest A0 reg */
   if (!Parse_AddrReg(parseState))
      RETURN_ERROR;

   /* comma */
   if (!Parse_String(parseState, ","))
      RETURN_ERROR;

   /* parse src reg */
   if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
      RETURN_ERROR;

   /* semicolon */
   if (!Parse_String(parseState, ";"))
      RETURN_ERROR;

   return GL_TRUE;
}
static GLboolean
Parse_CondCodeMask(struct parse_state *parseState,
                   struct prog_dst_register *dstReg)
{
   if (Parse_String(parseState, "EQ"))
      dstReg->CondMask = COND_EQ;
   else if (Parse_String(parseState, "GE"))
      dstReg->CondMask = COND_GE;
   else if (Parse_String(parseState, "GT"))
      dstReg->CondMask = COND_GT;
   else if (Parse_String(parseState, "LE"))
      dstReg->CondMask = COND_LE;
   else if (Parse_String(parseState, "LT"))
      dstReg->CondMask = COND_LT;
   else if (Parse_String(parseState, "NE"))
      dstReg->CondMask = COND_NE;
   else if (Parse_String(parseState, "TR"))
      dstReg->CondMask = COND_TR;
   else if (Parse_String(parseState, "FL"))
      dstReg->CondMask = COND_FL;
   else
      RETURN_ERROR1("Invalid condition code mask");

   /* look for optional .xyzw swizzle */
   if (Parse_String(parseState, ".")) {
      GLubyte token[100];
      GLuint swz[4];

      if (!Parse_Token(parseState, token))  /* get xyzw suffix */
         RETURN_ERROR;

      if (!Parse_SwizzleSuffix(token, swz))
         RETURN_ERROR1("Invalid swizzle suffix");

      dstReg->CondSwizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
   }

   return GL_TRUE;
}
/**
 * Parse a texture image source:
 *    [TEX0 | TEX1 | .. | TEX15] , [1D | 2D | 3D | CUBE | RECT]
 */
static GLboolean
Parse_TextureImageId(struct parse_state *parseState,
                     GLubyte *texUnit, GLubyte *texTargetBit)
{
   GLubyte imageSrc[100];
   GLint unit;

   if (!Parse_Token(parseState, imageSrc))
      RETURN_ERROR;
   
   if (imageSrc[0] != 'T' ||
       imageSrc[1] != 'E' ||
       imageSrc[2] != 'X') {
      RETURN_ERROR1("Expected TEX# source");
   }
   unit = atoi((const char *) imageSrc + 3);
   if ((unit < 0 || unit > MAX_TEXTURE_IMAGE_UNITS) ||
       (unit == 0 && (imageSrc[3] != '0' || imageSrc[4] != 0))) {
      RETURN_ERROR1("Invalied TEX# source index");
   }
   *texUnit = unit;

   if (!Parse_String(parseState, ","))
      RETURN_ERROR1("Expected ,");

   if (Parse_String(parseState, "1D")) {
      *texTargetBit = TEXTURE_1D_BIT;
   }
   else if (Parse_String(parseState, "2D")) {
      *texTargetBit = TEXTURE_2D_BIT;
   }
   else if (Parse_String(parseState, "3D")) {
      *texTargetBit = TEXTURE_3D_BIT;
   }
   else if (Parse_String(parseState, "CUBE")) {
      *texTargetBit = TEXTURE_CUBE_BIT;
   }
   else if (Parse_String(parseState, "RECT")) {
      *texTargetBit = TEXTURE_RECT_BIT;
   }
   else {
      RETURN_ERROR1("Invalid texture target token");
   }

   /* update record of referenced texture units */
   parseState->texturesUsed[*texUnit] |= *texTargetBit;
   if (_mesa_bitcount(parseState->texturesUsed[*texUnit]) > 1) {
      RETURN_ERROR1("Only one texture target can be used per texture unit.");
   }

   return GL_TRUE;
}
/**
 * Parse a vector constant, one of:
 *   { float }
 *   { float, float }
 *   { float, float, float }
 *   { float, float, float, float }
 */
static GLboolean
Parse_VectorConstant(struct parse_state *parseState, GLfloat *vec)
{
   /* "{" was already consumed */

   ASSIGN_4V(vec, 0.0, 0.0, 0.0, 1.0);

   if (!Parse_ScalarConstant(parseState, vec+0))  /* X */
      return GL_FALSE;

   if (Parse_String(parseState, "}")) {
      return GL_TRUE;
   }

   if (!Parse_String(parseState, ","))
      RETURN_ERROR1("Expected comma in vector constant");

   if (!Parse_ScalarConstant(parseState, vec+1))  /* Y */
      return GL_FALSE;

   if (Parse_String(parseState, "}")) {
      return GL_TRUE;
   }

   if (!Parse_String(parseState, ","))
      RETURN_ERROR1("Expected comma in vector constant");

   if (!Parse_ScalarConstant(parseState, vec+2))  /* Z */
      return GL_FALSE;

   if (Parse_String(parseState, "}")) {
      return GL_TRUE;
   }

   if (!Parse_String(parseState, ","))
      RETURN_ERROR1("Expected comma in vector constant");

   if (!Parse_ScalarConstant(parseState, vec+3))  /* W */
      return GL_FALSE;

   if (!Parse_String(parseState, "}"))
      RETURN_ERROR1("Expected closing brace in vector constant");

   return GL_TRUE;
}
static GLboolean
Parse_TriOpInstruction(struct parse_state *parseState,
                       struct vp_instruction *inst, enum vp_opcode opcode)
{
   inst->Opcode = opcode;
   inst->StringPos = parseState->curLine - parseState->start;

   /* dest reg */
   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
      RETURN_ERROR;

   /* comma */
   if (!Parse_String(parseState, ","))
      RETURN_ERROR;

   /* first src arg */
   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
      RETURN_ERROR;

   /* comma */
   if (!Parse_String(parseState, ","))
      RETURN_ERROR;

   /* second src arg */
   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1]))
      RETURN_ERROR;

   /* comma */
   if (!Parse_String(parseState, ","))
      RETURN_ERROR;

   /* third src arg */
   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[2]))
      RETURN_ERROR;

   /* semicolon */
   if (!Parse_String(parseState, ";"))
      RETURN_ERROR;

   /* make sure we don't reference more than one program parameter register */
   if ((inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
        inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
        inst->SrcReg[0].Index != inst->SrcReg[1].Index) ||
       (inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
        inst->SrcReg[2].File == PROGRAM_ENV_PARAM &&
        inst->SrcReg[0].Index != inst->SrcReg[2].Index) ||
       (inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
        inst->SrcReg[2].File == PROGRAM_ENV_PARAM &&
        inst->SrcReg[1].Index != inst->SrcReg[2].Index))
      RETURN_ERROR1("Can only reference one program register");

   /* make sure we don't reference more than one vertex attribute register */
   if ((inst->SrcReg[0].File == PROGRAM_INPUT &&
        inst->SrcReg[1].File == PROGRAM_INPUT &&
        inst->SrcReg[0].Index != inst->SrcReg[1].Index) ||
       (inst->SrcReg[0].File == PROGRAM_INPUT &&
        inst->SrcReg[2].File == PROGRAM_INPUT &&
        inst->SrcReg[0].Index != inst->SrcReg[2].Index) ||
       (inst->SrcReg[1].File == PROGRAM_INPUT &&
        inst->SrcReg[2].File == PROGRAM_INPUT &&
        inst->SrcReg[1].Index != inst->SrcReg[2].Index))
      RETURN_ERROR1("Can only reference one input register");

   return GL_TRUE;
}
static GLboolean
Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_src_register *srcReg)
{
   GLubyte token[100];

   srcReg->RelAddr = GL_FALSE;

   /* check for '-' */
   if (!Peek_Token(parseState, token))
      RETURN_ERROR;
   if (token[0] == '-') {
      srcReg->Negate = GL_TRUE;
      (void) Parse_String(parseState, "-"); /* consume '-' */
      if (!Peek_Token(parseState, token))
         RETURN_ERROR;
   }
   else {
      srcReg->Negate = GL_FALSE;
   }

   /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
   if (token[0] == 'R') {
      srcReg->File = PROGRAM_TEMPORARY;
      if (!Parse_TempReg(parseState, &srcReg->Index))
         RETURN_ERROR;
   }
   else if (token[0] == 'c') {
      if (!Parse_ParamReg(parseState, srcReg))
         RETURN_ERROR;
   }
   else if (token[0] == 'v') {
      srcReg->File = PROGRAM_INPUT;
      if (!Parse_AttribReg(parseState, &srcReg->Index))
         RETURN_ERROR;
   }
   else {
      RETURN_ERROR2("Bad source register name", token);
   }

   /* Look for .[xyzw] suffix */
   if (!Parse_String(parseState, "."))
      RETURN_ERROR;

   if (!Parse_Token(parseState, token))
      RETURN_ERROR;

   if (token[0] == 'x' && token[1] == 0) {
      srcReg->Swizzle[0] = 0;
   }
   else if (token[0] == 'y' && token[1] == 0) {
      srcReg->Swizzle[0] = 1;
   }
   else if (token[0] == 'z' && token[1] == 0) {
      srcReg->Swizzle[0] = 2;
   }
   else if (token[0] == 'w' && token[1] == 0) {
      srcReg->Swizzle[0] = 3;
   }
   else {
      RETURN_ERROR1("Bad scalar source suffix");
   }
   srcReg->Swizzle[1] = srcReg->Swizzle[2] = srcReg->Swizzle[3] = 0;

   return GL_TRUE;
}
static GLboolean
Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcReg)
{
   GLubyte token[100];

   srcReg->RelAddr = GL_FALSE;

   /* check for '-' */
   if (!Peek_Token(parseState, token))
      RETURN_ERROR;
   if (token[0] == '-') {
      (void) Parse_String(parseState, "-");
      srcReg->Negate = GL_TRUE;
      if (!Peek_Token(parseState, token))
         RETURN_ERROR;
   }
   else {
      srcReg->Negate = GL_FALSE;
   }

   /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
   if (token[0] == 'R') {
      srcReg->File = PROGRAM_TEMPORARY;
      if (!Parse_TempReg(parseState, &srcReg->Index))
         RETURN_ERROR;
   }
   else if (token[0] == 'c') {
      if (!Parse_ParamReg(parseState, srcReg))
         RETURN_ERROR;
   }
   else if (token[0] == 'v') {
      srcReg->File = PROGRAM_INPUT;
      if (!Parse_AttribReg(parseState, &srcReg->Index))
         RETURN_ERROR;
   }
   else {
      RETURN_ERROR2("Bad source register name", token);
   }

   /* init swizzle fields */
   srcReg->Swizzle[0] = 0;
   srcReg->Swizzle[1] = 1;
   srcReg->Swizzle[2] = 2;
   srcReg->Swizzle[3] = 3;

   /* Look for optional swizzle suffix */
   if (!Peek_Token(parseState, token))
      RETURN_ERROR;
   if (token[0] == '.') {
      (void) Parse_String(parseState, ".");  /* consume . */

      if (!Parse_Token(parseState, token))
         RETURN_ERROR;

      if (token[1] == 0) {
         /* single letter swizzle */
         if (token[0] == 'x')
            ASSIGN_4V(srcReg->Swizzle, 0, 0, 0, 0);
         else if (token[0] == 'y')
            ASSIGN_4V(srcReg->Swizzle, 1, 1, 1, 1);
         else if (token[0] == 'z')
            ASSIGN_4V(srcReg->Swizzle, 2, 2, 2, 2);
         else if (token[0] == 'w')
            ASSIGN_4V(srcReg->Swizzle, 3, 3, 3, 3);
         else
            RETURN_ERROR1("Expected x, y, z, or w");
      }
      else {
         /* 2, 3 or 4-component swizzle */
         GLint k;
         for (k = 0; token[k] && k < 5; k++) {
            if (token[k] == 'x')
               srcReg->Swizzle[k] = 0;
            else if (token[k] == 'y')
               srcReg->Swizzle[k] = 1;
            else if (token[k] == 'z')
               srcReg->Swizzle[k] = 2;
            else if (token[k] == 'w')
               srcReg->Swizzle[k] = 3;
            else
               RETURN_ERROR;
         }
         if (k >= 5)
            RETURN_ERROR;
      }
   }

   return GL_TRUE;
}
static GLboolean
Parse_MaskedDstReg(struct parse_state *parseState, struct vp_dst_register *dstReg)
{
   GLubyte token[100];

   /* Dst reg can be R<n> or o[n] */
   if (!Peek_Token(parseState, token))
      RETURN_ERROR;

   if (token[0] == 'R') {
      /* a temporary register */
      dstReg->File = PROGRAM_TEMPORARY;
      if (!Parse_TempReg(parseState, &dstReg->Index))
         RETURN_ERROR;
   }
   else if (!parseState->isStateProgram && token[0] == 'o') {
      /* an output register */
      dstReg->File = PROGRAM_OUTPUT;
      if (!Parse_OutputReg(parseState, &dstReg->Index))
         RETURN_ERROR;
   }
   else if (parseState->isStateProgram && token[0] == 'c' &&
            parseState->isStateProgram) {
      /* absolute program parameter register */
      /* Only valid for vertex state programs */
      dstReg->File = PROGRAM_ENV_PARAM;
      if (!Parse_AbsParamReg(parseState, &dstReg->Index))
         RETURN_ERROR;
   }
   else {
      RETURN_ERROR1("Bad destination register name");
   }

   /* Parse optional write mask */
   if (!Peek_Token(parseState, token))
      RETURN_ERROR;

   if (token[0] == '.') {
      /* got a mask */
      GLint k = 0;

      if (!Parse_String(parseState, "."))
         RETURN_ERROR;

      if (!Parse_Token(parseState, token))
         RETURN_ERROR;

      dstReg->WriteMask[0] = GL_FALSE;
      dstReg->WriteMask[1] = GL_FALSE;
      dstReg->WriteMask[2] = GL_FALSE;
      dstReg->WriteMask[3] = GL_FALSE;

      if (token[k] == 'x') {
         dstReg->WriteMask[0] = GL_TRUE;
         k++;
      }
      if (token[k] == 'y') {
         dstReg->WriteMask[1] = GL_TRUE;
         k++;
      }
      if (token[k] == 'z') {
         dstReg->WriteMask[2] = GL_TRUE;
         k++;
      }
      if (token[k] == 'w') {
         dstReg->WriteMask[3] = GL_TRUE;
         k++;
      }
      if (k == 0) {
         RETURN_ERROR1("Bad writemask character");
      }
      return GL_TRUE;
   }
   else {
      dstReg->WriteMask[0] = GL_TRUE;
      dstReg->WriteMask[1] = GL_TRUE;
      dstReg->WriteMask[2] = GL_TRUE;
      dstReg->WriteMask[3] = GL_TRUE;
      return GL_TRUE;
   }
}