static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr)
{
	int rc = SEPOL_ERR;
	enum cil_flavor op;
	struct cil_list *lexpr;
	struct cil_list *rexpr;

	if (current->data == NULL || current->cl_head != NULL) {
		cil_log(CIL_ERR, "Expected a string at the start of the constraint expression\n");
		goto exit;
	}

	op = __cil_get_constraint_operator_flavor(current->data);

	rc = cil_verify_constraint_expr_syntax(current, op);
	if (rc != SEPOL_OK) {
		goto exit;
	}

	switch (op) {
	case CIL_EQ:
	case CIL_NEQ:
	case CIL_CONS_DOM:
	case CIL_CONS_DOMBY:
	case CIL_CONS_INCOMP:
		rc = __cil_fill_constraint_leaf_expr(current, flavor, op, expr);
		if (rc != SEPOL_OK) {
			goto exit;
		}
		break;
	case CIL_NOT:
		rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr);
		if (rc != SEPOL_OK) {
			goto exit;
		}
		cil_list_init(expr, flavor);
		cil_list_append(*expr, CIL_OP, (void *)op);
		cil_list_append(*expr, CIL_LIST, lexpr);
		break;
	default:
		rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr);
		if (rc != SEPOL_OK) {
			goto exit;
		}
		rc = __cil_fill_constraint_expr(current->next->next->cl_head, flavor, &rexpr);
		if (rc != SEPOL_OK) {
			cil_list_destroy(&lexpr, CIL_TRUE);
			goto exit;
		}
		cil_list_init(expr, flavor);
		cil_list_append(*expr, CIL_OP, (void *)op);
		cil_list_append(*expr, CIL_LIST, lexpr);
		cil_list_append(*expr, CIL_LIST, rexpr);
		break;
	}

	return SEPOL_OK;
exit:

	return rc;
}
static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr)
{
	int rc = SEPOL_ERR;
	enum cil_flavor op;
	struct cil_list *lexpr;
	struct cil_list *rexpr;

	if (current->data == NULL || current->cl_head != NULL) {
		cil_log(CIL_ERR, "Expected a string at the start of the constraint expression\n");
		goto exit;
	}

	op = __cil_get_constraint_operator_flavor(current->data);

	rc = cil_verify_constraint_expr_syntax(current, op);
	if (rc != SEPOL_OK) {
		goto exit;
	}

	switch (op) {
	case CIL_EQ:
	case CIL_NEQ:
	case CIL_CONS_DOM:
	case CIL_CONS_DOMBY:
	case CIL_CONS_INCOMP:
		rc = __cil_fill_constraint_leaf_expr(current, flavor, op, expr);
		if (rc != SEPOL_OK) {
			goto exit;
		}
		break;
	case CIL_NOT:
		rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr);
		if (rc != SEPOL_OK) {
			goto exit;
		}
		cil_list_init(expr, flavor);
		cil_list_append(*expr, CIL_OP, (void *)op);
		cil_list_append(*expr, CIL_LIST, lexpr);
		break;
	default:
		rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr);
		if (rc != SEPOL_OK) {
			goto exit;
		}
		rc = __cil_fill_constraint_expr(current->next->next->cl_head, flavor, &rexpr);
		if (rc != SEPOL_OK) {
			cil_list_destroy(&lexpr, CIL_TRUE);
			goto exit;
		}
		cil_list_init(expr, flavor);
		cil_list_append(*expr, CIL_OP, (void *)op);
		cil_list_append(*expr, CIL_LIST, lexpr);
		cil_list_append(*expr, CIL_LIST, rexpr);
		break;
	}

	return SEPOL_OK;
exit:

	return rc;
}