예제 #1
0
/*       stop_at_name = TRUE is used when we check all names anyways. */
static gboolean
do_expr_name_loop_check (char const *name, GnmNamedExpr *nexpr,  /* One of these */
			 GnmExpr const *expr,
			 gboolean stop_at_name)
{
	switch (GNM_EXPR_GET_OPER (expr)) {
	case GNM_EXPR_OP_RANGE_CTOR:
	case GNM_EXPR_OP_INTERSECT:
	case GNM_EXPR_OP_ANY_BINARY:
		return (do_expr_name_loop_check (name, nexpr,
						 expr->binary.value_a,
						 stop_at_name) ||
			do_expr_name_loop_check (name, nexpr,
						 expr->binary.value_b,
						 stop_at_name));
	case GNM_EXPR_OP_ANY_UNARY:
		return do_expr_name_loop_check (name, nexpr,
						expr->unary.value,
						stop_at_name);
	case GNM_EXPR_OP_NAME: {
		GnmNamedExpr const *nexpr2 = expr->name.name;
		if (name && !strcmp (nexpr2->name->str, name))
			return TRUE;
		if (nexpr == nexpr2)
			return TRUE;
		if (!stop_at_name && nexpr2->texpr != NULL) /* look inside this name tree too */
			return expr_name_check_for_loop (name, nexpr2->texpr);
		return FALSE;
	}
	case GNM_EXPR_OP_FUNCALL: {
		int i;
		for (i = 0; i < expr->func.argc; i++)
			if (do_expr_name_loop_check (name, nexpr,
						     expr->func.argv[i],
						     stop_at_name))
				return TRUE;
		break;
	}
	case GNM_EXPR_OP_CONSTANT:
	case GNM_EXPR_OP_CELLREF:
	case GNM_EXPR_OP_ARRAY_CORNER:
	case GNM_EXPR_OP_ARRAY_ELEM:
		break;
	case GNM_EXPR_OP_SET: {
		int i;
		for (i = 0; i < expr->set.argc; i++)
			if (do_expr_name_loop_check (name, nexpr,
						     expr->set.argv[i],
						     stop_at_name))
				return TRUE;
		break;
	}
	}
	return FALSE;
}
예제 #2
0
/**
 * global_range_list_parse:
 * @sheet: Sheet where the range specification is relatively parsed to
 * @str  : a range or list of ranges to parse (ex: "A1", "A1:B1,C2,Sheet2!D2:D4")
 *
 * Parses a list of ranges, relative to the @sheet and returns a list with the
 * results.
 *
 * Returns a GSList containing Values of type VALUE_CELLRANGE, or NULL on failure
 **/
GSList *
global_range_list_parse (Sheet *sheet, char const *str)
{
	GnmParsePos  pp;
	GnmExprTop const *texpr;
	GSList   *ranges = NULL;
	GnmValue	 *v;

	g_return_val_if_fail (IS_SHEET (sheet), NULL);
	g_return_val_if_fail (str != NULL, NULL);

	texpr = gnm_expr_parse_str (str,
		 parse_pos_init_sheet (&pp, sheet),
		 GNM_EXPR_PARSE_FORCE_EXPLICIT_SHEET_REFERENCES |
		 GNM_EXPR_PARSE_PERMIT_MULTIPLE_EXPRESSIONS |
		 GNM_EXPR_PARSE_UNKNOWN_NAMES_ARE_STRINGS,
		 NULL, NULL);

	if (texpr != NULL)  {
		if (GNM_EXPR_GET_OPER (texpr->expr) == GNM_EXPR_OP_SET) {
			GnmExpr const *expr = texpr->expr;
			int i;
			for (i = 0; i < expr->set.argc; i++) {
				v = gnm_expr_get_range (expr->set.argv[i]);
				if (v == NULL) {
					range_list_destroy (ranges);
					ranges = NULL;
					break;
				} else
					ranges = g_slist_prepend (ranges, v);
			}
		} else {
			v = gnm_expr_top_get_range (texpr);
			if (v != NULL)
				ranges = g_slist_prepend (ranges, v);
		}
		gnm_expr_top_unref (texpr);
	}

	return g_slist_reverse (ranges);
}