Esempio n. 1
0
/**
 * expr_name_set_pos:
 * @nexpr : the named expression
 * @pp: the new position
 *
 * Returns a translated error string which the caller must free if something
 * goes wrong.
 **/
char *
expr_name_set_pos (GnmNamedExpr *nexpr, GnmParsePos const *pp)
{
	GnmNamedExprCollection *old_scope, *new_scope;
	const char *name;

	g_return_val_if_fail (nexpr != NULL, NULL);
	g_return_val_if_fail (nexpr->scope != NULL, NULL);
	g_return_val_if_fail (pp != NULL, NULL);

	old_scope = nexpr->scope;
	new_scope = pp->sheet ? pp->sheet->names : pp->wb->names;

	name = nexpr->name->str;
	if (old_scope != new_scope &&
	    (g_hash_table_lookup (new_scope->placeholders, name) ||
	     g_hash_table_lookup (new_scope->names, name))) {
		const char *fmt = pp->sheet
			? _("'%s' is already defined in sheet")
			: _("'%s' is already defined in workbook");
		return g_strdup_printf (fmt, name);
	}

	g_hash_table_steal (
		nexpr->is_placeholder ? old_scope->placeholders : old_scope->names,
		name);

	nexpr->pos = *pp;
	gnm_named_expr_collection_insert (new_scope, nexpr);
	return NULL;
}
Esempio n. 2
0
void
expr_name_set_is_placeholder (GnmNamedExpr *nexpr, gboolean is_placeholder)
{
	g_return_if_fail (nexpr != NULL);

	is_placeholder = !!is_placeholder;
	if (nexpr->is_placeholder == is_placeholder)
		return;
	nexpr->is_placeholder = is_placeholder;

	if (nexpr->scope) {
		const char *name = expr_name_name (nexpr);

		g_hash_table_steal (is_placeholder
				    ? nexpr->scope->names
				    : nexpr->scope->placeholders,
				    name);
		gnm_named_expr_collection_insert (nexpr->scope, nexpr);
	}
}
Esempio n. 3
0
/**
 * expr_name_add:
 * @pp:
 * @name:
 * @texpr: if texpr == NULL then create a placeholder with value #NAME?
 * @error_msg:
 * @link_to_container:
 *
 * Absorbs the reference to @texpr.
 * If @error_msg is non NULL it may hold a pointer to a translated descriptive
 * string.  NOTE : caller is responsible for freeing the error message.
 *
 * The reference semantics of the new expression are
 * 1) new names with @link_to_container TRUE are referenced by the container.
 *    The caller DOES NOT OWN a reference to the result, and needs to add their
 *    own.
 * 2) if @link_to_container is FALSE the caller DOES OWN a reference, and
 *    can free the result by unrefing the name.
 **/
GnmNamedExpr *
expr_name_add (GnmParsePos const *pp, char const *name,
	       GnmExprTop const *texpr, char **error_msg,
	       gboolean link_to_container,
	       GnmNamedExpr *stub)
{
	GnmNamedExpr *nexpr = NULL;
	GnmNamedExprCollection *scope = NULL;

	g_return_val_if_fail (pp != NULL, NULL);
	g_return_val_if_fail (pp->sheet != NULL || pp->wb != NULL, NULL);
	g_return_val_if_fail (name != NULL, NULL);
	g_return_val_if_fail (stub == NULL || stub->is_placeholder, NULL);

	if (texpr != NULL && expr_name_check_for_loop (name, texpr)) {
		gnm_expr_top_unref (texpr);
		if (error_msg)
			*error_msg = g_strdup_printf (_("'%s' has a circular reference"), name);
		return NULL;
	}

	scope = (pp->sheet != NULL) ? pp->sheet->names : pp->wb->names;
	/* see if there was a place holder */
	nexpr = g_hash_table_lookup (scope->placeholders, name);
	if (nexpr != NULL) {
		if (texpr == NULL) {
			/* there was already a placeholder for this */
			expr_name_ref (nexpr);
			return nexpr;
		}

		/* convert the placeholder into a real name */
		g_hash_table_steal (scope->placeholders, name);
		nexpr->is_placeholder = FALSE;
	} else {
		nexpr = g_hash_table_lookup (scope->names, name);
		/* If this is a permanent name, we may be adding it */
		/* on opening of a file, although */
		/* the name is already in place. */
		if (nexpr != NULL) {
			if (nexpr->is_permanent)
				link_to_container = FALSE;
			else {
				if (error_msg != NULL)
					*error_msg = (pp->sheet != NULL)
						? g_strdup_printf (_("'%s' is already defined in sheet"), name)
						: g_strdup_printf (_("'%s' is already defined in workbook"), name);

				gnm_expr_top_unref (texpr);
				return NULL;
			}
		}
	}

	if (error_msg)
		*error_msg = NULL;

	if (nexpr == NULL) {
		if (stub != NULL) {
			nexpr = stub;
			stub->is_placeholder = FALSE;
			go_string_unref (stub->name);
			stub->name = go_string_new (name);
		} else {
			nexpr = expr_name_new (name);
			nexpr->is_placeholder = (texpr == NULL);
		}
	}
	parse_pos_init (&nexpr->pos,
		pp->wb, pp->sheet, pp->eval.col, pp->eval.row);
	if (texpr == NULL)
		texpr = gnm_expr_top_new_constant
			(value_new_error_NAME (NULL));
	expr_name_set_expr (nexpr, texpr);
	if (link_to_container)
		gnm_named_expr_collection_insert (scope, nexpr);

	return nexpr;
}