diff options
-rw-r--r-- | src/mesa/main/nvvertparse.c | 360 |
1 files changed, 151 insertions, 209 deletions
diff --git a/src/mesa/main/nvvertparse.c b/src/mesa/main/nvvertparse.c index 107f238eb16..83215cb621a 100644 --- a/src/mesa/main/nvvertparse.c +++ b/src/mesa/main/nvvertparse.c @@ -1,4 +1,4 @@ -/* $Id: nvvertparse.c,v 1.2 2003/02/23 05:24:39 brianp Exp $ */ +/* $Id: nvvertparse.c,v 1.3 2003/02/25 19:27:54 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -41,7 +41,11 @@ #include "nvvertparse.h" #include "nvvertprog.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 { const GLubyte *pos; GLboolean isStateProgram; @@ -161,25 +165,46 @@ Peek_Token(struct parse_state *parseState, GLubyte *token) parseState->pos += (-i); return GL_FALSE; } - len = _mesa_strlen((char *) token); + len = _mesa_strlen((const char *) token); parseState->pos += (i - len); return GL_TRUE; } /** - * String equality test + * 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 GLboolean -StrEq(const GLubyte *a, const GLubyte *b) +Parse_String(struct parse_state *parseState, const char *pattern) { + const GLubyte *m; GLint i; - for (i = 0; a[i] && b[i] && a[i] == b[i]; i++) - ; - if (a[i] == 0 && b[i] == 0) - return GL_TRUE; - else - return GL_FALSE; + + /* 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; + } + } + else { + /* skip whitespace */ + 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 */ } @@ -206,19 +231,19 @@ static const char *Opcodes[] = { #define RETURN_ERROR \ do { \ - _mesa_printf("vpparse.c error at %d: parse error\n", __LINE__); \ + _mesa_printf("vert prog error at %d\n", __LINE__); \ return GL_FALSE; \ } while(0) #define RETURN_ERROR1(msg) \ do { \ - _mesa_printf("vpparse.c error at %d: %s\n", __LINE__, msg); \ + _mesa_printf("vert prog error at %d: %s\n", __LINE__, msg); \ return GL_FALSE; \ } while(0) #define RETURN_ERROR2(msg1, msg2) \ do { \ - _mesa_printf("vpparse.c error at %d: %s %s\n", __LINE__, msg1, msg2); \ + _mesa_printf("vert prog error at %d: %s %s\n", __LINE__, msg1, msg2);\ return GL_FALSE; \ } while(0) @@ -250,39 +275,6 @@ IsOutputRegister(GLuint r) } - -/** - * Try to match 'pattern' as the next token after any whitespace/comments. - */ -static GLboolean -Parse_String(struct parse_state *parseState, const char *pattern) -{ - 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; - } - } - else { - /* skip whitespace */ - parseState->pos += 1; - } - } - - /* Try to match the pattern */ - for (i = 0; pattern[i]; i++) { - if (*parseState->pos != pattern[i]) - RETURN_ERROR2("failed to match", pattern); /* failure */ - parseState->pos += 1; - } - - return GL_TRUE; /* success */ -} - - /** * Parse a temporary register: Rnn */ @@ -391,7 +383,7 @@ Parse_ParamReg(struct parse_state *parseState, struct vp_src_register *srcReg) RETURN_ERROR1("Bad constant program number"); srcReg->Register = VP_PROG_REG_START + reg; } - else if (StrEq(token, (GLubyte *) "A0")) { + else if (_mesa_strcmp((const char *) token, "A0") == 0) { /* address register "A0.x" */ if (!Parse_AddrReg(parseState)) RETURN_ERROR; @@ -476,7 +468,7 @@ Parse_AttribReg(struct parse_state *parseState, GLint *tempRegNum) } else { for (j = 0; InputRegisters[j]; j++) { - if (StrEq(token, (const GLubyte *) InputRegisters[j])) { + if (_mesa_strcmp((const char *) token, InputRegisters[j]) == 0) { *tempRegNum = VP_INPUT_REG_START + j; break; } @@ -520,7 +512,7 @@ Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum) /* try to match an output register name */ for (j = start; OutputRegisters[j]; j++) { - if (StrEq(token, (const GLubyte *) OutputRegisters[j])) { + if (_mesa_strcmp((const char *) token, OutputRegisters[j]) == 0) { *outputRegNum = VP_OUTPUT_REG_START + j; break; } @@ -769,26 +761,13 @@ Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_src_register *srcRe static GLint -Parse_UnaryOpInstruction(struct parse_state *parseState, struct vp_instruction *inst) +Parse_UnaryOpInstruction(struct parse_state *parseState, + struct vp_instruction *inst, enum vp_opcode opcode) { - GLubyte token[100]; - - /* opcode */ - if (!Parse_Token(parseState, token)) - RETURN_ERROR; + if (opcode == VP_OPCODE_ABS && !parseState->isVersion1_1) + RETURN_ERROR1("ABS illegal for vertex program 1.0"); - if (StrEq(token, (GLubyte *) "MOV")) { - inst->Opcode = VP_OPCODE_MOV; - } - else if (StrEq(token, (GLubyte *) "LIT")) { - inst->Opcode = VP_OPCODE_LIT; - } - else if (StrEq(token, (GLubyte *) "ABS") && parseState->isVersion1_1) { - inst->Opcode = VP_OPCODE_ABS; - } - else { - RETURN_ERROR; - } + inst->Opcode = opcode; /* dest reg */ if (!Parse_MaskedDstReg(parseState, &inst->DstReg)) @@ -811,50 +790,15 @@ Parse_UnaryOpInstruction(struct parse_state *parseState, struct vp_instruction * static GLboolean -Parse_BiOpInstruction(struct parse_state *parseState, struct vp_instruction *inst) +Parse_BiOpInstruction(struct parse_state *parseState, + struct vp_instruction *inst, enum vp_opcode opcode) { - GLubyte token[100]; + if (opcode == VP_OPCODE_DPH && !parseState->isVersion1_1) + RETURN_ERROR1("DPH illegal for vertex program 1.0"); + if (opcode == VP_OPCODE_SUB && !parseState->isVersion1_1) + RETURN_ERROR1("SUB illegal for vertex program 1.0"); - /* opcode */ - if (!Parse_Token(parseState, token)) - RETURN_ERROR; - - if (StrEq(token, (GLubyte *) "MUL")) { - inst->Opcode = VP_OPCODE_MUL; - } - else if (StrEq(token, (GLubyte *) "ADD")) { - inst->Opcode = VP_OPCODE_ADD; - } - else if (StrEq(token, (GLubyte *) "DP3")) { - inst->Opcode = VP_OPCODE_DP3; - } - else if (StrEq(token, (GLubyte *) "DP4")) { - inst->Opcode = VP_OPCODE_DP4; - } - else if (StrEq(token, (GLubyte *) "DST")) { - inst->Opcode = VP_OPCODE_DST; - } - else if (StrEq(token, (GLubyte *) "MIN")) { - inst->Opcode = VP_OPCODE_ADD; - } - else if (StrEq(token, (GLubyte *) "MAX")) { - inst->Opcode = VP_OPCODE_ADD; - } - else if (StrEq(token, (GLubyte *) "SLT")) { - inst->Opcode = VP_OPCODE_SLT; - } - else if (StrEq(token, (GLubyte *) "SGE")) { - inst->Opcode = VP_OPCODE_SGE; - } - else if (StrEq(token, (GLubyte *) "DPH") && parseState->isVersion1_1) { - inst->Opcode = VP_OPCODE_DPH; - } - else if (StrEq(token, (GLubyte *) "SUB") && parseState->isVersion1_1) { - inst->Opcode = VP_OPCODE_SUB; - } - else { - RETURN_ERROR; - } + inst->Opcode = opcode; /* dest reg */ if (!Parse_MaskedDstReg(parseState, &inst->DstReg)) @@ -897,20 +841,10 @@ Parse_BiOpInstruction(struct parse_state *parseState, struct vp_instruction *ins static GLboolean -Parse_TriOpInstruction(struct parse_state *parseState, struct vp_instruction *inst) +Parse_TriOpInstruction(struct parse_state *parseState, + struct vp_instruction *inst, enum vp_opcode opcode) { - GLubyte token[100]; - - /* opcode */ - if (!Parse_Token(parseState, token)) - RETURN_ERROR; - - if (StrEq(token, (GLubyte *) "MAD")) { - inst->Opcode = VP_OPCODE_MAD; - } - else { - RETURN_ERROR; - } + inst->Opcode = opcode; /* dest reg */ if (!Parse_MaskedDstReg(parseState, &inst->DstReg)) @@ -973,32 +907,13 @@ Parse_TriOpInstruction(struct parse_state *parseState, struct vp_instruction *in static GLboolean -Parse_ScalarInstruction(struct parse_state *parseState, struct vp_instruction *inst) +Parse_ScalarInstruction(struct parse_state *parseState, + struct vp_instruction *inst, enum vp_opcode opcode) { - GLubyte token[100]; + if (opcode == VP_OPCODE_RCC && !parseState->isVersion1_1) + RETURN_ERROR1("RCC illegal for vertex program 1.0"); - /* opcode */ - if (!Parse_Token(parseState, token)) - RETURN_ERROR; - - if (StrEq(token, (GLubyte *) "RCP")) { - inst->Opcode = VP_OPCODE_RCP; - } - else if (StrEq(token, (GLubyte *) "RSQ")) { - inst->Opcode = VP_OPCODE_RSQ; - } - else if (StrEq(token, (GLubyte *) "EXP")) { - inst->Opcode = VP_OPCODE_EXP; - } - else if (StrEq(token, (GLubyte *) "LOG")) { - inst->Opcode = VP_OPCODE_LOG; - } - else if (StrEq(token, (GLubyte *) "RCC") && parseState->isVersion1_1) { - inst->Opcode = VP_OPCODE_RCC; - } - else { - RETURN_ERROR; - } + inst->Opcode = opcode; /* dest reg */ if (!Parse_MaskedDstReg(parseState, &inst->DstReg)) @@ -1025,10 +940,6 @@ Parse_AddressInstruction(struct parse_state *parseState, struct vp_instruction * { inst->Opcode = VP_OPCODE_ARL; - /* opcode */ - if (!Parse_String(parseState, "ARL")) - RETURN_ERROR; - /* dest A0 reg */ if (!Parse_AddrReg(parseState)) RETURN_ERROR; @@ -1054,10 +965,6 @@ Parse_EndInstruction(struct parse_state *parseState, struct vp_instruction *inst { GLubyte token[100]; - /* opcode */ - if (!Parse_String(parseState, "END")) - RETURN_ERROR; - inst->Opcode = VP_OPCODE_END; /* this should fail! */ @@ -1073,22 +980,16 @@ Parse_OptionSequence(struct parse_state *parseState, struct vp_instruction program[]) { while (1) { - GLubyte token[100]; - if (!Peek_Token(parseState, token)) { - RETURN_ERROR1("Unexpected end of input"); - return GL_FALSE; /* end of input */ + 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 (!StrEq(token, (GLubyte *) "OPTION")) - return GL_TRUE; /* probably an instruction */ - - Parse_Token(parseState, token); - - if (!Parse_String(parseState, "NV_position_invariant")) - return GL_FALSE; if (!Parse_String(parseState, ";")) return GL_FALSE; - parseState->isPositionInvariant = GL_TRUE; } } @@ -1097,8 +998,6 @@ static GLboolean Parse_InstructionSequence(struct parse_state *parseState, struct vp_instruction program[]) { - GLubyte token[100]; - while (1) { struct vp_instruction *inst = program + parseState->numInst; @@ -1108,46 +1007,91 @@ Parse_InstructionSequence(struct parse_state *parseState, inst->SrcReg[2].Register = -1; inst->DstReg.Register = -1; - if (!Peek_Token(parseState, token)) - RETURN_ERROR; - - if (StrEq(token, (GLubyte *) "MOV") || - StrEq(token, (GLubyte *) "LIT") || - StrEq(token, (GLubyte *) "ABS")) { - if (!Parse_UnaryOpInstruction(parseState, inst)) + if (Parse_String(parseState, "MOV")) { + if (!Parse_UnaryOpInstruction(parseState, inst, VP_OPCODE_MOV)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "LIT")) { + if (!Parse_UnaryOpInstruction(parseState, inst, VP_OPCODE_LIT)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "ABS")) { + if (!Parse_UnaryOpInstruction(parseState, inst, VP_OPCODE_ABS)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "MUL")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_MUL)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "ADD")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_ADD)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "DP3")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_DP3)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "DP4")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_DP4)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "DST")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_DST)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "MIN")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_MIN)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "MAX")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_MAX)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "SLT")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_SLT)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "SGE")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_SGE)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "DPH")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_DPH)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "SUB")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_SUB)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "MAD")) { + if (!Parse_TriOpInstruction(parseState, inst, VP_OPCODE_MAD)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "RCP")) { + if (!Parse_ScalarInstruction(parseState, inst, VP_OPCODE_RCP)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "RSQ")) { + if (!Parse_ScalarInstruction(parseState, inst, VP_OPCODE_RSQ)) RETURN_ERROR; } - else if (StrEq(token, (GLubyte *) "MUL") || - StrEq(token, (GLubyte *) "ADD") || - StrEq(token, (GLubyte *) "DP3") || - StrEq(token, (GLubyte *) "DP4") || - StrEq(token, (GLubyte *) "DST") || - StrEq(token, (GLubyte *) "MIN") || - StrEq(token, (GLubyte *) "MAX") || - StrEq(token, (GLubyte *) "SLT") || - StrEq(token, (GLubyte *) "SGE") || - StrEq(token, (GLubyte *) "DPH") || - StrEq(token, (GLubyte *) "SUB")) { - if (!Parse_BiOpInstruction(parseState, inst)) + else if (Parse_String(parseState, "EXP")) { + if (!Parse_ScalarInstruction(parseState, inst, VP_OPCODE_EXP)) RETURN_ERROR; } - else if (StrEq(token, (GLubyte *) "MAD")) { - if (!Parse_TriOpInstruction(parseState, inst)) + else if (Parse_String(parseState, "LOG")) { + if (!Parse_ScalarInstruction(parseState, inst, VP_OPCODE_LOG)) RETURN_ERROR; } - else if (StrEq(token, (GLubyte *) "RCP") || - StrEq(token, (GLubyte *) "RSQ") || - StrEq(token, (GLubyte *) "EXP") || - StrEq(token, (GLubyte *) "LOG") || - StrEq(token, (GLubyte *) "RCC")) { - if (!Parse_ScalarInstruction(parseState, inst)) + else if (Parse_String(parseState, "RCC")) { + if (!Parse_ScalarInstruction(parseState, inst, VP_OPCODE_RCC)) RETURN_ERROR; } - else if (StrEq(token, (GLubyte *) "ARL")) { + else if (Parse_String(parseState, "ARL")) { if (!Parse_AddressInstruction(parseState, inst)) RETURN_ERROR; } - else if (StrEq(token, (GLubyte *) "END")) { + else if (Parse_String(parseState, "END")) { if (!Parse_EndInstruction(parseState, inst)) RETURN_ERROR; else { @@ -1157,7 +1101,7 @@ Parse_InstructionSequence(struct parse_state *parseState, } else { /* bad instruction name */ - RETURN_ERROR2("Unexpected token: ", token); + RETURN_ERROR1("Unexpected token"); } /* examine input/output registers */ @@ -1290,11 +1234,6 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget, } } - /* save bitmasks of registers read/written */ - program->InputsRead = parseState.inputsRead; - program->OutputsWritten = parseState.outputsWritten; - program->IsPositionInvariant = parseState.isPositionInvariant; - /* copy the compiled instructions */ assert(parseState.numInst <= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS); newInst = (struct vp_instruction *) @@ -1317,6 +1256,9 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget, FREE(program->Instructions); } program->Instructions = newInst; + program->InputsRead = parseState.inputsRead; + program->OutputsWritten = parseState.outputsWritten; + program->IsPositionInvariant = parseState.isPositionInvariant; #ifdef DEBUG_foo _mesa_printf("--- glLoadProgramNV result ---\n"); @@ -1331,11 +1273,11 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget, #ifdef DEBUG { GLint line, column; - const char *lineStr; - lineStr = _mesa_find_line_column((const char *) programString, - (const char *) parseState.pos, &line, &column); + const GLubyte *lineStr; + lineStr = _mesa_find_line_column(programString, + parseState.pos, &line, &column); _mesa_debug(ctx, "Parse error on line %d, column %d:%s\n", - line, column, lineStr); + line, column, (char *) lineStr); _mesa_free((void *) lineStr); } #endif |