示例#1
0
/* collects parameter tokens of a used macro and stores them for the unwrap */
static void cf_preprocess_save_macro_params(struct cf_preprocessor *pp,
		struct cf_token **p_cur_token, const struct cf_def *def,
		const struct cf_token *base,
		const struct macro_params *cur_params,
		struct macro_params *dst)
{
	struct cf_token *cur_token = *p_cur_token;
	size_t count = 0;

	next_token(&cur_token, false);
	if (cur_token->type != CFTOKEN_OTHER || *cur_token->str.array != '(') {
		cf_adderror_expecting(pp, cur_token, "'('");
		goto exit;
	}

	do {
		struct macro_param param;
		macro_param_init(&param);
		cur_token++;
		count++;

		cf_preprocess_save_macro_param(pp, &cur_token, &param, base,
				cur_params);
		if (cur_token->type != CFTOKEN_OTHER
		    || (*cur_token->str.array != ','
		        && *cur_token->str.array != ')')) {

			macro_param_free(&param);
			cf_adderror_expecting(pp, cur_token, "',' or ')'");
			goto exit;
		}

		if (param_is_whitespace(&param)) {
			/* if 0-param macro, ignore first entry */
			if (count == 1 && !def->params.num &&
			    *cur_token->str.array == ')') {
				macro_param_free(&param);
				break;
			}
		}

		if (count <= def->params.num) {
			cf_token_copy(&param.name,
					cf_def_getparam(def, count-1));
			da_push_back(dst->params, &param);
		} else {
			macro_param_free(&param);
		}
	} while (*cur_token->str.array != ')');

	if (count != def->params.num)
		cf_adderror(pp, cur_token,
				"Mismatching number of macro parameters",
				NULL, NULL, NULL);

exit:
	*p_cur_token = cur_token;
}
示例#2
0
static int ep_parse_annotations(struct effect_parser *ep,
		struct darray *annotations)
{
	if (!cf_token_is(&ep->cfp, "<")) {
		cf_adderror_expecting(&ep->cfp, "<");
		goto error;
	}

	/* get annotation variables */
	while (true) {
		bool do_break = false;
		struct ep_param var;

		ep_param_init(&var, bstrdup(""), bstrdup(""), false, false,
				false);

		switch (ep_parse_param_annotation_var(ep, &var)) {
		case PARSE_UNEXPECTED_CONTINUE:
			cf_adderror_syntax_error(&ep->cfp);
			/* Falls through. */
		case PARSE_CONTINUE:
			ep_param_free(&var);
			continue;

		case PARSE_UNEXPECTED_BREAK:
			cf_adderror_syntax_error(&ep->cfp);
			/* Falls through. */
		case PARSE_BREAK:
			ep_param_free(&var);
			do_break = true;
			break;

		case PARSE_EOF:
			ep_param_free(&var);
			goto error;
		}

		if (do_break)
			break;

		darray_push_back(sizeof(struct ep_param), annotations, &var);
	}

	if (!cf_token_is(&ep->cfp, ">")) {
		cf_adderror_expecting(&ep->cfp, ">");
		goto error;
	}
	if (!cf_next_valid_token(&ep->cfp))
		goto error;

	return true;

error:
	return false;
}
示例#3
0
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);
}
示例#4
0
static void cf_preprocess_ifdef(struct cf_preprocessor *pp,
		bool ifnot, struct cf_token **p_cur_token)
{
	struct cf_token *cur_token = *p_cur_token;
	struct cf_def *def;
	bool is_true;

	next_token(&cur_token, true);
	if (cur_token->type != CFTOKEN_NAME) {
		cf_adderror_expecting(pp, cur_token, "identifier");
		go_to_newline(&cur_token);
		goto exit;
	}

	def = cf_preprocess_get_def(pp, &cur_token->str);
	is_true = (def == NULL) == ifnot;

	if (!cf_preprocess_subblock(pp, !is_true, &cur_token))
		goto exit;

	if (strref_cmp(&cur_token->str, "else") == 0) {
		if (!cf_preprocess_subblock(pp, is_true, &cur_token))
			goto exit;
	/*} else if (strref_cmp(&cur_token->str, "elif") == 0) {*/
	}

	cur_token++;

exit:
	*p_cur_token = cur_token;
}
示例#5
0
static void cf_preprocess_include(struct cf_preprocessor *pp,
		struct cf_token **p_cur_token)
{
	struct cf_token *cur_token = *p_cur_token;

	if (pp->ignore_state) {
		go_to_newline(p_cur_token);
		return;
	}

	next_token(&cur_token, true);

	if (cur_token->type != CFTOKEN_STRING) {
		cf_adderror_expecting(pp, cur_token, "string");
		go_to_newline(&cur_token);
		goto exit;
	}

	if (is_sys_include(&cur_token->str)) {
		/* TODO */
	} else if (is_loc_include(&cur_token->str)) {
		if (!pp->ignore_state)
			cf_include_file(pp, cur_token);
	} else {
		cf_adderror(pp, cur_token, "Invalid or incomplete string",
				NULL, NULL, NULL);
		go_to_newline(&cur_token);
		goto exit;
	}

	cur_token++;

exit:
	*p_cur_token = cur_token;
}
示例#6
0
static bool cf_preprocess_macro_params(struct cf_preprocessor *pp,
		struct cf_def *def, struct cf_token **p_cur_token)
{
	struct cf_token *cur_token = *p_cur_token;
	bool success = false;
	def->macro = true;

	do {
		next_token(&cur_token, true);
		if (cur_token->type != CFTOKEN_NAME) {
			cf_adderror_expecting(pp, cur_token, "identifier");
			go_to_newline(&cur_token);
			goto exit;
		}

		cf_def_addparam(def, cur_token);

		next_token(&cur_token, true);
		if (cur_token->type != CFTOKEN_OTHER
		    || (*cur_token->str.array != ','
		        && *cur_token->str.array != ')')) {

			cf_adderror_expecting(pp, cur_token, "',' or ')'");
			go_to_newline(&cur_token);
			goto exit;
		}
	} while (*cur_token->str.array != ')');

	/* ended properly, now go to first define token (or newline) */
	next_token(&cur_token, true);
	success = true;

exit:
	*p_cur_token = cur_token;
	return success;
}
示例#7
0
static void cf_preprocess_define(struct cf_preprocessor *pp,
		struct cf_token **p_cur_token)
{
	struct cf_token *cur_token = *p_cur_token;
	struct cf_def def;

	if (pp->ignore_state) {
		go_to_newline(p_cur_token);
		return;
	}

	cf_def_init(&def);

	next_token(&cur_token, true);
	if (cur_token->type != CFTOKEN_NAME) {
		cf_adderror_expecting(pp, cur_token, "identifier");
		go_to_newline(&cur_token);
		goto exit;
	}

	append_space(pp, &def.tokens.da, NULL);
	cf_token_copy(&def.name, cur_token);

	if (!next_token(&cur_token, true))
		goto complete;

	/* process macro */
	if (*cur_token->str.array == '(') {
		if (!cf_preprocess_macro_params(pp, &def, &cur_token))
			goto error;
	}

	while (cur_token->type != CFTOKEN_NEWLINE &&
	       cur_token->type != CFTOKEN_NONE)
		cf_def_addtoken(&def, cur_token++);

complete:
	append_end_token(&def.tokens.da);
	append_space(pp, &def.tokens.da, NULL);
	da_push_back(pp->defines, &def);
	goto exit;

error:
	cf_def_free(&def);

exit:
	*p_cur_token = cur_token;
}
示例#8
0
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);
}
示例#9
0
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);
}
示例#10
0
static inline int ep_parse_param_assign_bool(struct effect_parser *ep,
		struct ep_param *param)
{
	if (!cf_next_valid_token(&ep->cfp))
		return PARSE_EOF;

	if (cf_token_is(&ep->cfp, "true")) {
		long l = 1;
		da_push_back_array(param->default_val, &l, sizeof(long));
		return PARSE_SUCCESS;
	} else if (cf_token_is(&ep->cfp, "false")) {
		long l = 0;
		da_push_back_array(param->default_val, &l, sizeof(long));
		return PARSE_SUCCESS;
	}

	cf_adderror_expecting(&ep->cfp, "true or false");

	return PARSE_EOF;
}
示例#11
0
static inline int ep_parse_pass_command_call(struct effect_parser *ep,
		struct darray *call)
{
	struct cf_token end_token;
	cf_token_clear(&end_token);

	while (!cf_token_is(&ep->cfp, ";")) {
		if (cf_token_is(&ep->cfp, "}")) {
			cf_adderror_expecting(&ep->cfp, ";");
			return PARSE_CONTINUE;
		}

		darray_push_back(sizeof(struct cf_token), call,
				ep->cfp.cur_token);
		if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF;
	}

	darray_push_back(sizeof(struct cf_token), call, ep->cfp.cur_token);
	darray_push_back(sizeof(struct cf_token), call, &end_token);
	return PARSE_SUCCESS;
}
示例#12
0
static void cf_preprocess_undef(struct cf_preprocessor *pp,
		struct cf_token **p_cur_token)
{
	struct cf_token *cur_token = *p_cur_token;

	if (pp->ignore_state) {
		go_to_newline(p_cur_token);
		return;
	}

	next_token(&cur_token, true);
	if (cur_token->type != CFTOKEN_NAME) {
		cf_adderror_expecting(pp, cur_token, "identifier");
		go_to_newline(&cur_token);
		goto exit;
	}

	cf_preprocess_remove_def_strref(pp, &cur_token->str);
	cur_token++;

exit:
	*p_cur_token = cur_token;
}
示例#13
0
static inline int ep_parse_param_annotation_var(struct effect_parser *ep,
		struct ep_param *var)
{
	int code;

	/* -------------------------------------- */
	/* variable type */

	if (!cf_next_valid_token(&ep->cfp))
		return PARSE_EOF;

	if (cf_token_is(&ep->cfp, ";"))
		return PARSE_CONTINUE;
	if (cf_token_is(&ep->cfp, ">"))
		return PARSE_BREAK;

	code = cf_token_is_type(&ep->cfp, CFTOKEN_NAME, "type name", ";");
	if (code != PARSE_SUCCESS)
		return code;

	bfree(var->type);
	cf_copy_token(&ep->cfp, &var->type);

	/* -------------------------------------- */
	/* variable name */

	if (!cf_next_valid_token(&ep->cfp))
		return PARSE_EOF;

	if (cf_token_is(&ep->cfp, ";")) {
		cf_adderror_expecting(&ep->cfp, "variable name");
		return PARSE_UNEXPECTED_CONTINUE;
	}
	if (cf_token_is(&ep->cfp, ">")) {
		cf_adderror_expecting(&ep->cfp, "variable name");
		return PARSE_UNEXPECTED_BREAK;
	}

	code = cf_token_is_type(&ep->cfp, CFTOKEN_NAME, "variable name", ";");
	if (code != PARSE_SUCCESS)
		return code;

	bfree(var->name);
	cf_copy_token(&ep->cfp, &var->name);

	/* -------------------------------------- */
	/* variable mapping if any (POSITION, TEXCOORD, etc) */

	if (!cf_next_valid_token(&ep->cfp))
		return PARSE_EOF;

	if (cf_token_is(&ep->cfp, ":")) {
		cf_adderror_expecting(&ep->cfp, "= or ;");
		return PARSE_UNEXPECTED_BREAK;
	} else if (cf_token_is(&ep->cfp, ">")) {
		cf_adderror_expecting(&ep->cfp, "= or ;");
		return PARSE_UNEXPECTED_BREAK;
	} else if (cf_token_is(&ep->cfp, "=")) {
		if (!ep_parse_param_assign(ep, var)) {
			cf_adderror_expecting(&ep->cfp, "assignment value");
			return PARSE_UNEXPECTED_BREAK;
		}
	}

	/* -------------------------------------- */

	if (!cf_token_is(&ep->cfp, ";")) {
		if (!cf_go_to_valid_token(&ep->cfp, ";", ">")) {
			cf_adderror_expecting(&ep->cfp, "; or >");
			return PARSE_EOF;
		}
		return PARSE_CONTINUE;
	}

	return PARSE_SUCCESS;
}