int cil_gen_typetransition(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
{
	int rc = SEPOL_ERR;
	enum cil_syntax syntax[] = {
		CIL_SYN_STRING,
		CIL_SYN_STRING,
		CIL_SYN_STRING,
		CIL_SYN_STRING,
		CIL_SYN_STRING,
		CIL_SYN_STRING | CIL_SYN_END,
		CIL_SYN_END
	};
	int syntax_len = sizeof(syntax)/sizeof(*syntax);
	char *s1, *s2, *s3, *s4, *s5;

	if (db == NULL || parse_current == NULL || ast_node == NULL ) {
		goto exit;
	}

	rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
	if (rc != SEPOL_OK) {
		goto exit;
	}

	s1 = parse_current->next->data;
	s2 = parse_current->next->next->data;
	s3 = parse_current->next->next->next->data;
	s4 = parse_current->next->next->next->next->data;
	s5 = NULL;

	if (parse_current->next->next->next->next->next) {
		if (s4 == CIL_KEY_STAR) {
			s4 = parse_current->next->next->next->next->next->data;
		} else {
			s5 = parse_current->next->next->next->next->next->data;
		}
	}

	if (s5) {
		struct cil_nametypetransition *nametypetrans = NULL;

		cil_nametypetransition_init(&nametypetrans);

		nametypetrans->src_str = s1;
		nametypetrans->tgt_str = s2;
		nametypetrans->obj_str = s3;
		nametypetrans->result_str = s5;
		nametypetrans->name_str = s4;

		ast_node->data = nametypetrans;
		ast_node->flavor = CIL_NAMETYPETRANSITION;
	} else {
		struct cil_type_rule *rule = NULL;

		cil_type_rule_init(&rule);

		rule->rule_kind = CIL_TYPE_TRANSITION;
		rule->src_str = s1;
		rule->tgt_str = s2;
		rule->obj_str = s3;
		rule->result_str = s4;

		ast_node->data = rule;
		ast_node->flavor = CIL_TYPE_RULE;
	}

	return SEPOL_OK;

exit:
	cil_tree_log(parse_current, CIL_ERR, "Bad typetransition declaration");
	return rc;
}
int cil_gen_typetransition(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
{
	int rc = SEPOL_ERR;
	enum cil_syntax syntax[] = {
		CIL_SYN_STRING,
		CIL_SYN_STRING,
		CIL_SYN_STRING,
		CIL_SYN_STRING,
		CIL_SYN_STRING,
		CIL_SYN_STRING | CIL_SYN_END,
		CIL_SYN_END
	};
	int syntax_len = sizeof(syntax)/sizeof(*syntax);
	char *s1, *s2, *s3, *s4, *s5;

	if (db == NULL || parse_current == NULL || ast_node == NULL ) {
		goto exit;
	}

	rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
	if (rc != SEPOL_OK) {
		goto exit;
	}

	s1 = parse_current->next->data;
	s2 = parse_current->next->next->data;
	s3 = parse_current->next->next->next->data;
	s4 = parse_current->next->next->next->next->data;
	s5 = NULL;

	if (parse_current->next->next->next->next->next) {
		if (s4 == CIL_KEY_STAR) {
			s4 = parse_current->next->next->next->next->next->data;
		} else {
			s5 = parse_current->next->next->next->next->next->data;
		}
	}

	if (s5) {
		struct cil_nametypetransition *nametypetrans = NULL;

		cil_nametypetransition_init(&nametypetrans);

		nametypetrans->src_str = s1;
		nametypetrans->tgt_str = s2;
		nametypetrans->obj_str = s3;
		nametypetrans->result_str = s5;
		nametypetrans->name_str = s4;

		ast_node->data = nametypetrans;
		ast_node->flavor = CIL_NAMETYPETRANSITION;
	} else {
		struct cil_type_rule *rule = NULL;

		cil_type_rule_init(&rule);

		rule->rule_kind = CIL_TYPE_TRANSITION;
		rule->src_str = s1;
		rule->tgt_str = s2;
		rule->obj_str = s3;
		rule->result_str = s4;

		ast_node->data = rule;
		ast_node->flavor = CIL_TYPE_RULE;
	}

	return SEPOL_OK;

exit:
	cil_tree_log(parse_current, CIL_ERR, "Bad typetransition declaration");
	return rc;
}