static int ep_parse_sampler_state_item(struct effect_parser *ep, struct ep_sampler *eps) { int ret; char *state = NULL, *value = NULL; ret = cf_next_name(&ep->cfp, &state, "state name", ";"); if (ret != PARSE_SUCCESS) goto fail; ret = cf_next_token_should_be(&ep->cfp, "=", ";", NULL); if (ret != PARSE_SUCCESS) goto fail; ret = cf_next_name(&ep->cfp, &value, "value name", ";"); if (ret != PARSE_SUCCESS) goto fail; ret = cf_next_token_should_be(&ep->cfp, ";", ";", NULL); if (ret != PARSE_SUCCESS) goto fail; da_push_back(eps->states, &state); da_push_back(eps->values, &value); return ret; fail: bfree(state); bfree(value); return ret; }
static void ep_parse_sampler_state(struct effect_parser *ep) { struct ep_sampler eps; struct cf_token peek; ep_sampler_init(&eps); if (cf_next_name(&ep->cfp, &eps.name, "name", ";") != PARSE_SUCCESS) goto error; if (cf_next_token_should_be(&ep->cfp, "{", ";", NULL) != PARSE_SUCCESS) goto error; if (!cf_peek_valid_token(&ep->cfp, &peek)) goto error; while (strref_cmp(&peek.str, "}") != 0) { int ret = ep_parse_sampler_state_item(ep, &eps); if (ret == PARSE_EOF) goto error; if (!cf_peek_valid_token(&ep->cfp, &peek)) goto error; } if (cf_next_token_should_be(&ep->cfp, "}", ";", NULL) != PARSE_SUCCESS) goto error; if (cf_next_token_should_be(&ep->cfp, ";", NULL, NULL) != PARSE_SUCCESS) goto error; da_push_back(ep->samplers, &eps); return; error: ep_sampler_free(&eps); }
static void sp_parse_sampler_state(struct shader_parser *sp) { struct shader_sampler ss; struct cf_token peek; shader_sampler_init(&ss); if (cf_next_name(&sp->cfp, &ss.name, "name", ";") != PARSE_SUCCESS) goto error; if (cf_next_token_should_be(&sp->cfp, "{", ";", NULL) != PARSE_SUCCESS) goto error; if (!cf_peek_valid_token(&sp->cfp, &peek)) goto error; while (strref_cmp(&peek.str, "}") != 0) { int ret = sp_parse_sampler_state_item(sp, &ss); if (ret == PARSE_EOF) goto error; if (!cf_peek_valid_token(&sp->cfp, &peek)) goto error; } if (cf_next_token_should_be(&sp->cfp, "}", ";", NULL) != PARSE_SUCCESS) goto error; if (cf_next_token_should_be(&sp->cfp, ";", NULL, NULL) != PARSE_SUCCESS) goto error; da_push_back(sp->samplers, &ss); return; error: shader_sampler_free(&ss); }
static void ep_parse_struct(struct effect_parser *ep) { struct ep_struct eps; ep_struct_init(&eps); if (cf_next_name(&ep->cfp, &eps.name, "name", ";") != PARSE_SUCCESS) goto error; if (cf_next_token_should_be(&ep->cfp, "{", ";", NULL) != PARSE_SUCCESS) goto error; /* get structure variables */ while (true) { bool do_break = false; struct ep_var var; ep_var_init(&var); switch (ep_parse_struct_var(ep, &var)) { case PARSE_UNEXPECTED_CONTINUE: cf_adderror_syntax_error(&ep->cfp); /* Falls through. */ case PARSE_CONTINUE: ep_var_free(&var); continue; case PARSE_UNEXPECTED_BREAK: cf_adderror_syntax_error(&ep->cfp); /* Falls through. */ case PARSE_BREAK: ep_var_free(&var); do_break = true; break; case PARSE_EOF: ep_var_free(&var); goto error; } if (do_break) break; da_push_back(eps.vars, &var); } if (cf_next_token_should_be(&ep->cfp, ";", NULL, NULL) != PARSE_SUCCESS) goto error; da_push_back(ep->structs, &eps); return; error: ep_struct_free(&eps); }
static void sp_parse_struct(struct shader_parser *sp) { struct shader_struct ss; shader_struct_init(&ss); if (cf_next_name(&sp->cfp, &ss.name, "name", ";") != PARSE_SUCCESS) goto error; if (cf_next_token_should_be(&sp->cfp, "{", ";", NULL) != PARSE_SUCCESS) goto error; /* get structure variables */ while (true) { bool do_break = false; struct shader_var var; shader_var_init(&var); switch (sp_parse_struct_var(sp, &var)) { case PARSE_UNEXPECTED_CONTINUE: cf_adderror_syntax_error(&sp->cfp); case PARSE_CONTINUE: shader_var_free(&var); continue; case PARSE_UNEXPECTED_BREAK: cf_adderror_syntax_error(&sp->cfp); case PARSE_BREAK: shader_var_free(&var); do_break = true; break; case PARSE_EOF: shader_var_free(&var); goto error; } if (do_break) break; da_push_back(ss.vars, &var); } if (cf_next_token_should_be(&sp->cfp, ";", NULL, NULL) != PARSE_SUCCESS) goto error; da_push_back(sp->structs, &ss); return; error: shader_struct_free(&ss); }
static int ep_parse_pass_command(struct effect_parser *ep, struct ep_pass *pass) { struct darray *call; /* struct cf_token */ if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; if (cf_token_is(&ep->cfp, "vertex_shader") || cf_token_is(&ep->cfp, "vertex_program")) { call = &pass->vertex_program.da; } else if (cf_token_is(&ep->cfp, "pixel_shader") || cf_token_is(&ep->cfp, "pixel_program")) { call = &pass->fragment_program.da; } else { cf_adderror_syntax_error(&ep->cfp); if (!cf_go_to_valid_token(&ep->cfp, ";", "}")) return PARSE_EOF; return PARSE_CONTINUE; } if (cf_next_token_should_be(&ep->cfp, "=", ";", "}") != PARSE_SUCCESS) return PARSE_CONTINUE; if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; if (cf_token_is(&ep->cfp, "compile")) { cf_adderror(&ep->cfp, "compile keyword not necessary", LEX_WARNING, NULL, NULL, NULL); if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; } return ep_parse_pass_command_call(ep, call); }
/* * parses assignment for float1, float2, float3, float4, int1, int2, int3, int4, * and any combination for float3x3, float4x4, int3x3, int4x4, etc */ static inline int ep_parse_param_assign_intfloat_array(struct effect_parser *ep, struct ep_param *param, bool is_float) { const char *intfloat_type = param->type + (is_float ? 5 : 3); int intfloat_count = 0, code, i; /* -------------------------------------------- */ if (intfloat_type[0] < '1' || intfloat_type[0] > '4') cf_adderror(&ep->cfp, "Invalid row count", LEX_ERROR, NULL, NULL, NULL); intfloat_count = intfloat_type[0]-'0'; if (intfloat_type[1] == 'x') { if (intfloat_type[2] < '1' || intfloat_type[2] > '4') cf_adderror(&ep->cfp, "Invalid column count", LEX_ERROR, NULL, NULL, NULL); intfloat_count *= intfloat_type[2]-'0'; } /* -------------------------------------------- */ code = cf_next_token_should_be(&ep->cfp, "{", ";", NULL); if (code != PARSE_SUCCESS) return code; for (i = 0; i < intfloat_count; i++) { char *next = ((i+1) < intfloat_count) ? "," : "}"; code = ep_parse_param_assign_intfloat(ep, param, is_float); if (code != PARSE_SUCCESS) return code; code = cf_next_token_should_be(&ep->cfp, next, ";", NULL); if (code != PARSE_SUCCESS) return code; } return PARSE_SUCCESS; }
/* * parses assignment for float1, float2, float3, float4, and any combination * for float3x3, float4x4, etc */ static inline int sp_parse_param_assign_float_array(struct shader_parser *sp, struct shader_var *param) { const char *float_type = param->type+5; int float_count = 0, code, i; /* -------------------------------------------- */ if (float_type[0] < '1' || float_type[0] > '4') cf_adderror(&sp->cfp, "Invalid row count", LEX_ERROR, NULL, NULL, NULL); float_count = float_type[0]-'0'; if (float_type[1] == 'x') { if (float_type[2] < '1' || float_type[2] > '4') cf_adderror(&sp->cfp, "Invalid column count", LEX_ERROR, NULL, NULL, NULL); float_count *= float_type[2]-'0'; } /* -------------------------------------------- */ code = cf_next_token_should_be(&sp->cfp, "{", ";", NULL); if (code != PARSE_SUCCESS) return code; for (i = 0; i < float_count; i++) { char *next = ((i+1) < float_count) ? "," : "}"; code = sp_parse_param_assign_intfloat(sp, param, true); if (code != PARSE_SUCCESS) return code; code = cf_next_token_should_be(&sp->cfp, next, ";", NULL); if (code != PARSE_SUCCESS) return code; } return PARSE_SUCCESS; }
static void ep_parse_technique(struct effect_parser *ep) { struct ep_technique ept; ep_technique_init(&ept); if (cf_next_name(&ep->cfp, &ept.name, "name", ";") != PARSE_SUCCESS) goto error; if (cf_next_token_should_be(&ep->cfp, "{", ";", NULL) != PARSE_SUCCESS) goto error; if (!cf_next_valid_token(&ep->cfp)) goto error; while (!cf_token_is(&ep->cfp, "}")) { struct ep_pass pass; ep_pass_init(&pass); switch (ep_parse_pass(ep, &pass)) { case PARSE_UNEXPECTED_CONTINUE: ep_pass_free(&pass); if (!cf_go_to_token(&ep->cfp, "}", NULL)) goto error; continue; case PARSE_EOF: ep_pass_free(&pass); goto error; } da_push_back(ept.passes, &pass); if (!cf_next_valid_token(&ep->cfp)) goto error; } /* pass the current token (which is '}') if we reached here */ cf_next_token(&ep->cfp); da_push_back(ep->techniques, &ept); return; error: cf_next_token(&ep->cfp); ep_technique_free(&ept); }
/* parses "array[count]" */ static bool ep_parse_param_array(struct effect_parser *ep, struct ep_param *param) { if (!cf_next_valid_token(&ep->cfp)) return false; if (ep->cfp.cur_token->type != CFTOKEN_NUM || !valid_int_str(ep->cfp.cur_token->str.array, ep->cfp.cur_token->str.len)) return false; param->array_count =(int)strtol(ep->cfp.cur_token->str.array, NULL, 10); if (cf_next_token_should_be(&ep->cfp, "]", ";", NULL) == PARSE_EOF) return false; if (!cf_next_valid_token(&ep->cfp)) return false; return true; }
/* parses "array[count]" */ static bool sp_parse_param_array(struct shader_parser *sp, struct shader_var *param) { if (!cf_next_valid_token(&sp->cfp)) return false; if (sp->cfp.cur_token->type != CFTOKEN_NUM || !valid_int_str(sp->cfp.cur_token->str.array, sp->cfp.cur_token->str.len)) return false; param->array_count =(int)strtol(sp->cfp.cur_token->str.array, NULL, 10); if (cf_next_token_should_be(&sp->cfp, "]", ";", NULL) == PARSE_EOF) return false; if (!cf_next_valid_token(&sp->cfp)) return false; return true; }
static int ep_parse_sampler_state_item(struct effect_parser *ep, struct ep_sampler *eps) { int ret; char *state = NULL; struct dstr value = {0}; ret = cf_next_name(&ep->cfp, &state, "state name", ";"); if (ret != PARSE_SUCCESS) goto fail; ret = cf_next_token_should_be(&ep->cfp, "=", ";", NULL); if (ret != PARSE_SUCCESS) goto fail; for (;;) { const char *cur_str; if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; cur_str = ep->cfp.cur_token->str.array; if (*cur_str == ';') break; dstr_ncat(&value, cur_str, ep->cfp.cur_token->str.len); } if (value.len) { da_push_back(eps->states, &state); da_push_back(eps->values, &value.array); } return ret; fail: bfree(state); dstr_free(&value); return ret; }