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 ep_parse_other(struct effect_parser *ep) { bool is_property = false, is_const = false, is_uniform = false; char *type = NULL, *name = NULL; if (!ep_get_var_specifiers(ep, &is_property, &is_const, &is_uniform)) goto error; if (cf_get_name(&ep->cfp, &type, "type", ";") != PARSE_SUCCESS) goto error; if (cf_next_name(&ep->cfp, &name, "name", ";") != PARSE_SUCCESS) goto error; if (!cf_next_valid_token(&ep->cfp)) goto error; if (cf_token_is(&ep->cfp, "(")) { report_invalid_func_keyword(ep, "property", is_property); report_invalid_func_keyword(ep, "const", is_const); report_invalid_func_keyword(ep, "uniform", is_uniform); ep_parse_function(ep, type, name); return; } else { ep_parse_param(ep, type, name, is_property, is_const, is_uniform); return; } error: bfree(type); bfree(name); }
static void sp_parse_other(struct shader_parser *sp) { bool is_const = false, is_uniform = false; char *type = NULL, *name = NULL; if (!sp_get_var_specifiers(sp, &is_const, &is_uniform)) goto error; if (cf_get_name(&sp->cfp, &type, "type", ";") != PARSE_SUCCESS) goto error; if (cf_next_name(&sp->cfp, &name, "name", ";") != PARSE_SUCCESS) goto error; if (!cf_next_valid_token(&sp->cfp)) goto error; if (cf_token_is(&sp->cfp, "(")) { report_invalid_func_keyword(sp, "const", is_const); report_invalid_func_keyword(sp, "uniform", is_uniform); sp_parse_function(sp, type, name); return; } else { sp_parse_param(sp, type, name, is_const, is_uniform); return; } error: bfree(type); bfree(name); }
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_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_valid_token(&ep->cfp)) return; if (!cf_token_is(&ep->cfp, "{")) { if (!cf_go_to_token(&ep->cfp, ";", NULL)) { cf_adderror_expecting(&ep->cfp, ";"); return; } cf_adderror_expecting(&ep->cfp, "{"); 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); }
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 inline int ep_parse_func_param(struct effect_parser *ep, struct ep_func *func, struct ep_var *var) { int code; if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; code = ep_check_for_keyword(ep, "uniform", &var->uniform); if (code == PARSE_EOF) return PARSE_EOF; code = cf_get_name(&ep->cfp, &var->type, "type", ")"); if (code != PARSE_SUCCESS) return code; code = cf_next_name(&ep->cfp, &var->name, "name", ")"); if (code != PARSE_SUCCESS) return code; if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; if (cf_token_is(&ep->cfp, ":")) { code = cf_next_name(&ep->cfp, &var->mapping, "mapping specifier", ")"); if (code != PARSE_SUCCESS) return code; if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; } if (ep_getstruct(ep, var->type) != NULL) da_push_back(func->struct_deps, &var->type); else if (ep_getsampler(ep, var->type) != NULL) da_push_back(func->sampler_deps, &var->type); return PARSE_SUCCESS; }
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 inline int sp_parse_func_param(struct shader_parser *sp, struct shader_var *var) { int code; bool is_uniform = false; if (!cf_next_valid_token(&sp->cfp)) return PARSE_EOF; code = sp_check_for_keyword(sp, "uniform", &is_uniform); if (code == PARSE_EOF) return PARSE_EOF; var->var_type = is_uniform ? SHADER_VAR_UNIFORM : SHADER_VAR_NONE; code = cf_get_name(&sp->cfp, &var->type, "type", ")"); if (code != PARSE_SUCCESS) return code; code = cf_next_name(&sp->cfp, &var->name, "name", ")"); if (code != PARSE_SUCCESS) return code; if (!cf_next_valid_token(&sp->cfp)) return PARSE_EOF; if (cf_token_is(&sp->cfp, ":")) { code = cf_next_name(&sp->cfp, &var->mapping, "mapping specifier", ")"); if (code != PARSE_SUCCESS) return code; if (!cf_next_valid_token(&sp->cfp)) return PARSE_EOF; } return PARSE_SUCCESS; }
static void ep_parse_function(struct effect_parser *ep, char *type, char *name) { struct ep_func func; int code; ep_func_init(&func, type, name); if (ep_getstruct(ep, type)) da_push_back(func.struct_deps, &func.ret_type); if (!ep_parse_func_params(ep, &func)) goto error; if (!cf_next_valid_token(&ep->cfp)) goto error; /* if function is mapped to something, for example COLOR */ if (cf_token_is(&ep->cfp, ":")) { code = cf_next_name(&ep->cfp, &func.mapping, "mapping specifier", "{"); if (code == PARSE_EOF) goto error; else if (code != PARSE_CONTINUE) { if (!cf_next_valid_token(&ep->cfp)) goto error; } } if (!cf_token_is(&ep->cfp, "{")) { cf_adderror_expecting(&ep->cfp, "{"); goto error; } if (!ep_parse_func_contents(ep, &func)) goto error; /* it is established that the current token is '}' if we reach this */ cf_next_token(&ep->cfp); da_push_back(ep->funcs, &func); return; error: ep_func_free(&func); }
static void sp_parse_function(struct shader_parser *sp, char *type, char *name) { struct shader_func func; shader_func_init(&func, type, name); if (!sp_parse_func_params(sp, &func)) goto error; if (!cf_next_valid_token(&sp->cfp)) goto error; /* if function is mapped to something, for example COLOR */ if (cf_token_is(&sp->cfp, ":")) { char *mapping = NULL; int errorcode = cf_next_name(&sp->cfp, &mapping, "mapping", "{"); if (errorcode != PARSE_SUCCESS) goto error; func.mapping = mapping; if (!cf_next_valid_token(&sp->cfp)) goto error; } if (!cf_token_is(&sp->cfp, "{")) { cf_adderror_expecting(&sp->cfp, "{"); goto error; } func.start = sp->cfp.cur_token; if (!cf_pass_pair(&sp->cfp, '{', '}')) goto error; /* it is established that the current token is '}' if we reach this */ cf_next_token(&sp->cfp); func.end = sp->cfp.cur_token; da_push_back(sp->funcs, &func); return; error: shader_func_free(&func); }
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; }