plugin.c 13.6 KB
Newer Older
Mark Probst's avatar
Mark Probst committed
1
/* -*- mode: c; c-basic-offset: 8 -*- */
Ariel Rios's avatar
typos  
Ariel Rios committed
2 3 4 5 6 7 8 9

/*
  Authors: Mark Probst
           Ariel Rios <ariel@arcavia.com>
	   
	   Copyright Mark Probst, Ariel Rios 2000
*/

10
#include <config.h>
11
#include <glib.h>
Mark Probst's avatar
Mark Probst committed
12 13 14 15
#include <assert.h>
#include <stdio.h>
#include <libguile.h>
#include <gnome.h>
16
#include <guile/gh.h>
Mark Probst's avatar
Mark Probst committed
17

18 19 20 21
#include "gnumeric.h"
#include "symbol.h"
#include "plugin.h"
#include "expr.h"
22
#include "gutils.h"
23
#include "func.h"
24
#include "cell.h"
25
#include "value.h"
Jody Goldberg's avatar
Jody Goldberg committed
26 27
#include "main.h"
#include "command-context.h"
Mark Probst's avatar
Mark Probst committed
28

29 30 31 32 33
/* This is damn ugly.
 * However, it will get things working again (I hope)
 * until someone who actually uses this thing takes
 * over maintaing it.
 */
34
static EvalPos const *eval_pos = NULL;
35

Mark Probst's avatar
Mark Probst committed
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
static SCM
scm_symbolfrom0str (char *name)
{
	return SCM_CAR(scm_intern0(name));
}

static SCM
list_to_scm (GList *list, CellRef eval_cell)
{
				/* FIXME: implement this */
	return SCM_EOL;
}

static SCM
cell_ref_to_scm (CellRef cell, CellRef eval_cell)
{
	int col = cell.col_relative ? cell.col + eval_cell.col : cell.col,
		row = cell.row_relative ? cell.row + eval_cell.row : cell.row;

Ariel Rios's avatar
Ariel Rios committed
55 56
	return scm_cons (scm_symbolfrom0str ("cell-ref"),
			scm_cons(scm_long2num (col), scm_long2num (row)));
57 58
				/* FIXME: we need the relative-flags,
				 * and the sheet, and workbook */
Mark Probst's avatar
Mark Probst committed
59 60 61 62 63
}

static CellRef
scm_to_cell_ref (SCM scm)
{
64 65
	/* Sheet local, absolute references */
	CellRef cell = { NULL, 0, 0, FALSE, FALSE };
Mark Probst's avatar
Mark Probst committed
66

Ariel Rios's avatar
Ariel Rios committed
67 68 69 70
	if (SCM_NIMP (scm) && SCM_CONSP (scm)
	    && SCM_NFALSEP (scm_eq_p (SCM_CAR (scm), scm_symbolfrom0str ("cell-ref")))
	    && SCM_NIMP (SCM_CDR (scm)) && SCM_CONSP (SCM_CDR (scm))
	    && SCM_NFALSEP (scm_number_p (SCM_CADR (scm))) && SCM_NFALSEP (scm_number_p (SCM_CDDR(scm))))
Mark Probst's avatar
Mark Probst committed
71
	{
Ariel Rios's avatar
Ariel Rios committed
72 73
		cell.col = gh_scm2int (SCM_CADR (scm));
		cell.row = gh_scm2int (SCM_CDDR (scm));
Mark Probst's avatar
Mark Probst committed
74 75 76
	}
	else
		;		/* FIXME: should report error */
Ariel Rios's avatar
Ariel Rios committed
77
	
Mark Probst's avatar
Mark Probst committed
78 79 80 81
	return cell;
}

static SCM
82
value_to_scm (Value const *val, CellRef cell_ref)
Mark Probst's avatar
Mark Probst committed
83 84 85 86 87 88
{
	if (val == NULL)
		return SCM_EOL;

	switch (val->type)
	{
89
		case VALUE_EMPTY :
Ariel Rios's avatar
Ariel Rios committed
90
			return gh_eval_str ("'()");
91
 
92
		case VALUE_BOOLEAN :
Ariel Rios's avatar
Ariel Rios committed
93
			return gh_bool2scm (val->v_bool.val);	
94
			
95 96
		case VALUE_ERROR :
			/* FIXME ?? what belongs here */
Ariel Rios's avatar
Ariel Rios committed
97
			return scm_makfrom0str (val->v_err.mesg->str);
98

Mark Probst's avatar
Mark Probst committed
99
		case VALUE_STRING :
Ariel Rios's avatar
Ariel Rios committed
100
			return scm_makfrom0str (val->v_str.val->str);
Mark Probst's avatar
Mark Probst committed
101 102

		case VALUE_INTEGER :
Ariel Rios's avatar
Ariel Rios committed
103
			return scm_long2num (val->v_int.val);
Mark Probst's avatar
Mark Probst committed
104

105
		case VALUE_FLOAT :
Ariel Rios's avatar
Ariel Rios committed
106
			return gh_double2scm (val->v_float.val);
107

Mark Probst's avatar
Mark Probst committed
108
		case VALUE_CELLRANGE :
109
			/* FIXME : Support inverted ranges */
Ariel Rios's avatar
Ariel Rios committed
110 111 112
			return scm_cons (scm_symbolfrom0str ("cell-range"),
					 scm_cons (cell_ref_to_scm(val->v_range.cell.a, cell_ref),
						   cell_ref_to_scm (val->v_range.cell.b, cell_ref)));
Mark Probst's avatar
Mark Probst committed
113 114

		case VALUE_ARRAY :
115 116 117 118
			{
				int x, y, i, ii;
				SCM ls;

119 120
				x = val->v_array.x;
				y = val->v_array.y;
121

Ariel Rios's avatar
Ariel Rios committed
122
				ls = gh_eval_str ("'()");
123

124
				/* FIXME : I added the value_to_scm wrapper. This seems more correct */
Ariel Rios's avatar
Ariel Rios committed
125
				for (i = 0; i < y; i++)
126
					for (ii = 0; i < x; i++)
Ariel Rios's avatar
Ariel Rios committed
127 128
						ls = scm_cons (value_to_scm (val->v_array.vals[ii][i], cell_ref), ls);
				return scm_reverse (ls);
129
			}
Mark Probst's avatar
Mark Probst committed
130 131 132 133 134 135 136 137
	}

	return SCM_UNSPECIFIED;
}

static Value*
scm_to_value (SCM scm)
{
138 139 140
	if (SCM_NIMP(scm) && SCM_STRINGP(scm)) {
		/* assuming (wrongly?) that scm strings are zero-terminated */
		return value_new_string (SCM_CHARS(scm));
Mark Probst's avatar
Mark Probst committed
141

142
	} else if (SCM_NFALSEP(scm_number_p(scm))) {
143
		/* We do not need to do any distinction between an integer or
144
		 *  a float here. If we do so, we can crash gnumeric if the
145
                 *  size of scm is bigger than the size of int
146
		 */
147
		return value_new_float ((float_t)scm_num2dbl(scm, 0));
148 149

	} else if (SCM_NIMP(scm) && SCM_CONSP(scm))
Mark Probst's avatar
Mark Probst committed
150 151 152 153
	{
		if (scm_eq_p(SCM_CAR(scm), scm_symbolfrom0str("cell-range"))
		    && SCM_NIMP(SCM_CDR(scm)) && SCM_CONSP(SCM_CDR(scm)))
		{
154 155
			CellRef a = scm_to_cell_ref(SCM_CADR(scm));
			CellRef b = scm_to_cell_ref(SCM_CDDR(scm));
Mark Probst's avatar
Mark Probst committed
156

157 158
			/* The refs are always absolute so the 0,0 is irrelevant */
			return value_new_cellrange (&a, &b, 0, 0);
Mark Probst's avatar
Mark Probst committed
159 160 161
		}
	}

162 163 164 165
	else if (gh_boolean_p (scm))
		      
		return value_new_bool ((gboolean) gh_scm2bool (scm));		       

Mark Probst's avatar
Mark Probst committed
166 167 168 169 170 171
	return NULL;		/* maybe we should return something more meaningful!? */
}

static SCM
expr_to_scm (ExprTree *expr, CellRef cell_ref)
{
Jody Goldberg's avatar
Jody Goldberg committed
172
	switch (expr->any.oper)
Mark Probst's avatar
Mark Probst committed
173 174 175
	{
		case OPER_EQUAL :
			return SCM_LIST3(scm_symbolfrom0str("="),
Jody Goldberg's avatar
Jody Goldberg committed
176 177
					 expr_to_scm(expr->binary.value_a, cell_ref),
					 expr_to_scm(expr->binary.value_b, cell_ref));
Mark Probst's avatar
Mark Probst committed
178 179 180

		case OPER_GT :
			return SCM_LIST3(scm_symbolfrom0str(">"),
Jody Goldberg's avatar
Jody Goldberg committed
181 182
					 expr_to_scm(expr->binary.value_a, cell_ref),
					 expr_to_scm(expr->binary.value_b, cell_ref));
Mark Probst's avatar
Mark Probst committed
183 184 185

		case OPER_LT :
			return SCM_LIST3(scm_symbolfrom0str("<"),
Jody Goldberg's avatar
Jody Goldberg committed
186 187
					 expr_to_scm(expr->binary.value_a, cell_ref),
					 expr_to_scm(expr->binary.value_b, cell_ref));
Mark Probst's avatar
Mark Probst committed
188 189 190

		case OPER_GTE :
			return SCM_LIST3(scm_symbolfrom0str(">="),
Jody Goldberg's avatar
Jody Goldberg committed
191 192
					 expr_to_scm(expr->binary.value_a, cell_ref),
					 expr_to_scm(expr->binary.value_b, cell_ref));
Mark Probst's avatar
Mark Probst committed
193 194 195

		case OPER_LTE :
			return SCM_LIST3(scm_symbolfrom0str("<="),
Jody Goldberg's avatar
Jody Goldberg committed
196 197
					 expr_to_scm(expr->binary.value_a, cell_ref),
					 expr_to_scm(expr->binary.value_b, cell_ref));
Mark Probst's avatar
Mark Probst committed
198 199 200

		case OPER_NOT_EQUAL :
			return SCM_LIST3(scm_symbolfrom0str("<>"),
Jody Goldberg's avatar
Jody Goldberg committed
201 202
					 expr_to_scm(expr->binary.value_a, cell_ref),
					 expr_to_scm(expr->binary.value_b, cell_ref));
Mark Probst's avatar
Mark Probst committed
203 204 205

		case OPER_ADD :
			return SCM_LIST3(scm_symbolfrom0str("+"),
Jody Goldberg's avatar
Jody Goldberg committed
206 207
					 expr_to_scm(expr->binary.value_a, cell_ref),
					 expr_to_scm(expr->binary.value_b, cell_ref));
Mark Probst's avatar
Mark Probst committed
208 209 210

		case OPER_SUB :
			return SCM_LIST3(scm_symbolfrom0str("-"),
Jody Goldberg's avatar
Jody Goldberg committed
211 212
					 expr_to_scm(expr->binary.value_a, cell_ref),
					 expr_to_scm(expr->binary.value_b, cell_ref));
Mark Probst's avatar
Mark Probst committed
213

Jody Goldberg's avatar
Jody Goldberg committed
214 215
		case OPER_UNARY_PLUS :
			return SCM_LIST2(scm_symbolfrom0str("+"),
Jody Goldberg's avatar
Jody Goldberg committed
216
					 expr_to_scm(expr->unary.value, cell_ref));
Jody Goldberg's avatar
Jody Goldberg committed
217 218

		case OPER_UNARY_NEG :
Mark Probst's avatar
Mark Probst committed
219
			return SCM_LIST2(scm_symbolfrom0str("neg"),
Jody Goldberg's avatar
Jody Goldberg committed
220
					 expr_to_scm(expr->unary.value, cell_ref));
Mark Probst's avatar
Mark Probst committed
221 222 223

		case OPER_MULT :
			return SCM_LIST3(scm_symbolfrom0str("*"),
Jody Goldberg's avatar
Jody Goldberg committed
224 225
					 expr_to_scm(expr->binary.value_a, cell_ref),
					 expr_to_scm(expr->binary.value_b, cell_ref));
Mark Probst's avatar
Mark Probst committed
226 227 228

		case OPER_DIV :
			return SCM_LIST3(scm_symbolfrom0str("/"),
Jody Goldberg's avatar
Jody Goldberg committed
229 230
					 expr_to_scm(expr->binary.value_a, cell_ref),
					 expr_to_scm(expr->binary.value_b, cell_ref));
Mark Probst's avatar
Mark Probst committed
231

232
		case OPER_PERCENT :
Jody Goldberg's avatar
Jody Goldberg committed
233 234 235
			return SCM_LIST3(scm_symbolfrom0str("/"),
					 expr_to_scm(expr->unary.value, cell_ref),
					 gh_double2scm(100.));
236

Mark Probst's avatar
Mark Probst committed
237 238
		case OPER_EXP :
			return SCM_LIST3(scm_symbolfrom0str("expt"),
Jody Goldberg's avatar
Jody Goldberg committed
239 240
					 expr_to_scm(expr->binary.value_a, cell_ref),
					 expr_to_scm(expr->binary.value_b, cell_ref));
Mark Probst's avatar
Mark Probst committed
241 242 243

		case OPER_CONCAT :
			return SCM_LIST3(scm_symbolfrom0str("string-append"),
Jody Goldberg's avatar
Jody Goldberg committed
244 245
					 expr_to_scm(expr->binary.value_a, cell_ref),
					 expr_to_scm(expr->binary.value_b, cell_ref));
Mark Probst's avatar
Mark Probst committed
246 247 248

		case OPER_FUNCALL :
			return SCM_LIST3(scm_symbolfrom0str("funcall"),
Jody Goldberg's avatar
Jody Goldberg committed
249 250
					 scm_makfrom0str(expr->func.symbol->str),
					 list_to_scm(expr->func.arg_list, cell_ref));
Mark Probst's avatar
Mark Probst committed
251 252

		case OPER_CONSTANT :
Jody Goldberg's avatar
Jody Goldberg committed
253
			return value_to_scm(expr->constant.value, cell_ref);
Mark Probst's avatar
Mark Probst committed
254 255 256

		case OPER_VAR :
			return scm_cons(scm_symbolfrom0str("var"),
Jody Goldberg's avatar
Jody Goldberg committed
257
					cell_ref_to_scm(expr->var.ref, cell_ref));
258

259 260 261 262 263
	        case OPER_NAME :

	        case OPER_ARRAY :
		

264
		/* FIXME : default : */
Mark Probst's avatar
Mark Probst committed
265 266 267 268 269 270
	}

	return SCM_UNSPECIFIED;
}

static Value*
Michael Meeks's avatar
Michael Meeks committed
271
func_scm_apply (FunctionEvalInfo *ei, GList *expr_node_list)
Mark Probst's avatar
Mark Probst committed
272 273 274 275 276 277 278 279 280
{
	int i;
	Value *value;
	char *symbol;
	SCM args = SCM_EOL,
		function,
		result;

	if (g_list_length(expr_node_list) < 1)
281
		return value_new_error (ei->pos, _("Invalid number of arguments"));
Mark Probst's avatar
Mark Probst committed
282

283
	/* Retrieve the function name,  This can be empty, but not a non scalar */
284
	value = eval_expr (ei->pos, (ExprTree*)expr_node_list->data, EVAL_PERMIT_EMPTY);
Mark Probst's avatar
Mark Probst committed
285
	if (value == NULL)
286
		return value_new_error (ei->pos, _("First argument to SCM must be a Guile expression"));
Michael Meeks's avatar
Michael Meeks committed
287

Michael Meeks's avatar
Michael Meeks committed
288
	symbol = value_get_as_string (value);
Mark Probst's avatar
Mark Probst committed
289
	if (symbol == NULL)
290
		/* FIXME : This looks like a leak (JEG 4/4/00) */
291
		return value_new_error (ei->pos, _("First argument to SCM must be a Guile expression"));
Michael Meeks's avatar
Michael Meeks committed
292

Mark Probst's avatar
Mark Probst committed
293 294
	function = scm_eval_0str(symbol);
	if (SCM_UNBNDP(function))
295
		return value_new_error (ei->pos, _("Undefined scheme function"));
Michael Meeks's avatar
Michael Meeks committed
296

Mark Probst's avatar
Mark Probst committed
297 298 299 300
	value_release(value);

	for (i = g_list_length(expr_node_list) - 1; i >= 1; --i)
	{
301 302
		CellRef eval_cell;

Jon K Hellan's avatar
Jon K Hellan committed
303
		eval_cell.col = ei->pos->eval.col;
304
		eval_cell.row = ei->pos->eval.row;
305 306 307
		eval_cell.col_relative = 0;
		eval_cell.row_relative = 0;
		eval_cell.sheet = NULL;
308

309 310 311
		/* Evaluate each argument, non scalar is ok, but empty is not */
		value = eval_expr (ei->pos, (ExprTree*)g_list_nth(expr_node_list, i)->data,
				   EVAL_PERMIT_NON_SCALAR);
Mark Probst's avatar
Mark Probst committed
312
		if (value == NULL)
313
			return value_new_error (ei->pos, _("Could not evaluate argument"));
Michael Meeks's avatar
Michael Meeks committed
314

Mark Probst's avatar
Mark Probst committed
315 316 317 318 319 320 321 322 323 324 325 326 327
		args = scm_cons(value_to_scm(value, eval_cell), args);
		value_release(value);
	}

	result = scm_apply(function, args, SCM_EOL);

	return scm_to_value(result);
}

static SCM
scm_cell_value (SCM scm)
{
	CellRef cell_ref = scm_to_cell_ref(scm);
328
	Cell *cell;
329

330 331 332
	g_return_val_if_fail (eval_pos != NULL, SCM_EOL);

	cell = sheet_cell_get(eval_pos->sheet, cell_ref.col, cell_ref.row);
Mark Probst's avatar
Mark Probst committed
333 334 335 336

	if (cell == NULL)
		return SCM_EOL;

337
	assert (cell->value != NULL);
Mark Probst's avatar
Mark Probst committed
338 339 340 341 342 343 344 345

	return value_to_scm(cell->value, cell_ref);
}

static SCM
scm_cell_expr (SCM scm)
{
	CellRef cell_ref = scm_to_cell_ref(scm);
346 347 348 349 350
	Cell *cell;

	g_return_val_if_fail (eval_pos != NULL, SCM_EOL);

	cell = sheet_cell_get(eval_pos->sheet, cell_ref.col, cell_ref.row);
Mark Probst's avatar
Mark Probst committed
351

352
	if (cell == NULL || cell_has_expr (cell))
Mark Probst's avatar
Mark Probst committed
353 354
		return SCM_EOL;

355
	return expr_to_scm (cell->u.expression, cell_ref);
Mark Probst's avatar
Mark Probst committed
356 357 358 359 360 361
}

static SCM
scm_set_cell_string (SCM scm_cell_ref, SCM scm_string)
{
	CellRef cell_ref = scm_to_cell_ref(scm_cell_ref);
362 363 364 365 366
	Cell *cell;

	g_return_val_if_fail (eval_pos != NULL, SCM_EOL);

	cell = sheet_cell_get(eval_pos->sheet, cell_ref.col, cell_ref.row);
Mark Probst's avatar
Mark Probst committed
367 368 369 370 371 372

	SCM_ASSERT(SCM_NIMP(scm_string) && SCM_STRINGP(scm_string), scm_string, SCM_ARG2, "set-cell-string!");

	if (cell == NULL)
		return SCM_UNSPECIFIED;

373
	cell_set_text (cell, SCM_CHARS(scm_string));
Mark Probst's avatar
Mark Probst committed
374 375 376 377 378

	return SCM_UNSPECIFIED;
}

static SCM
Michael Meeks's avatar
Michael Meeks committed
379
scm_gnumeric_funcall (SCM funcname, SCM arglist)
Mark Probst's avatar
Mark Probst committed
380 381 382 383 384
{
	int i, num_args;
	Value **values;
	CellRef cell_ref = { 0, 0, 0, 0 };

Michael Meeks's avatar
Michael Meeks committed
385 386
	SCM_ASSERT (SCM_NIMP (funcname) && SCM_STRINGP (funcname), funcname, SCM_ARG1, "gnumeric-funcall");
	SCM_ASSERT (SCM_NFALSEP (scm_list_p (arglist)), arglist, SCM_ARG2, "gnumeric-funcall");
Mark Probst's avatar
Mark Probst committed
387

Michael Meeks's avatar
Michael Meeks committed
388 389 390 391 392
	num_args = scm_ilength (arglist);
	values = g_new (Value *, num_args);
	for (i = 0; i < num_args; ++i) {
		values[i] = scm_to_value (SCM_CAR (arglist));
		arglist = SCM_CDR (arglist);
Mark Probst's avatar
Mark Probst committed
393 394
	}

Michael Meeks's avatar
Michael Meeks committed
395 396 397 398 399
	return value_to_scm (function_call_with_values (eval_pos,
							SCM_CHARS (funcname),
							num_args,
							values),
			     cell_ref);
Mark Probst's avatar
Mark Probst committed
400 401 402
}

static Value*
Michael Meeks's avatar
Michael Meeks committed
403
func_marshal_func (FunctionEvalInfo *ei, Value *argv[])
Mark Probst's avatar
Mark Probst committed
404
{
405
	FunctionDefinition const *fndef = ei->func_def;
406
	SCM args = SCM_EOL, result, function;
Mark Probst's avatar
Mark Probst committed
407
	CellRef dummy = { 0, 0, 0, 0 };
408
	EvalPos const *old_eval_pos;
409
	int i, min, max;
410

Michael Meeks's avatar
Michael Meeks committed
411
	function_def_count_args (fndef, &min, &max);
Mark Probst's avatar
Mark Probst committed
412

Michael Meeks's avatar
Michael Meeks committed
413
	function = GPOINTER_TO_INT (function_def_get_user_data (fndef));
Mark Probst's avatar
Mark Probst committed
414

415
	for (i = min - 1; i >= 0; --i)
416
		args = scm_cons (value_to_scm (argv [i], dummy), args);
Mark Probst's avatar
Mark Probst committed
417

418
	old_eval_pos = eval_pos;
419 420 421
	eval_pos     = ei->pos;
	result       = scm_apply (function, args, SCM_EOL);
	eval_pos     = old_eval_pos;
Mark Probst's avatar
Mark Probst committed
422

423
	return scm_to_value (result);
Mark Probst's avatar
Mark Probst committed
424 425 426
}

static SCM
427
scm_register_function (SCM scm_name, SCM scm_args, SCM scm_help, SCM scm_category, SCM scm_function)
Mark Probst's avatar
Mark Probst committed
428 429
{
	FunctionDefinition *fndef;
Michael Meeks's avatar
Michael Meeks committed
430
	FunctionCategory   *cat;
Michael Meeks's avatar
Michael Meeks committed
431
	char              **help;
Mark Probst's avatar
Mark Probst committed
432

Ariel Rios's avatar
typos  
Ariel Rios committed
433

Michael Meeks's avatar
Michael Meeks committed
434 435 436
	SCM_ASSERT (SCM_NIMP (scm_name) && SCM_STRINGP (scm_name), scm_name, SCM_ARG1, "scm_register_function");
	SCM_ASSERT (SCM_NIMP (scm_args) && SCM_STRINGP (scm_args), scm_args, SCM_ARG2, "scm_register_function");
	SCM_ASSERT (SCM_NIMP (scm_help) && SCM_STRINGP (scm_help), scm_help, SCM_ARG3, "scm_register_function");
437 438 439
	SCM_ASSERT (SCM_NIMP (scm_category) && SCM_STRINGP (scm_category), 
		    scm_category, SCM_ARG4, "scm_register_function");
	SCM_ASSERT (scm_procedure_p (scm_function), scm_function, SCM_ARG5, "scm_register_function");
Mark Probst's avatar
Mark Probst committed
440

Ariel Rios's avatar
typos  
Ariel Rios committed
441
	scm_permanent_object (scm_function); 
Mark Probst's avatar
Mark Probst committed
442

Michael Meeks's avatar
Michael Meeks committed
443
	help  = g_new (char *, 1);
Michael Meeks's avatar
Michael Meeks committed
444
	*help = g_strdup (SCM_CHARS (scm_help));
445
	cat   = function_get_category (g_strdup (SCM_CHARS (scm_category)));
Michael Meeks's avatar
Michael Meeks committed
446 447
	fndef = function_add_args (cat, g_strdup (SCM_CHARS (scm_name)),
				   g_strdup (SCM_CHARS (scm_args)), NULL,
Michael Meeks's avatar
Michael Meeks committed
448
				   help, func_marshal_func);
Mark Probst's avatar
Mark Probst committed
449

Michael Meeks's avatar
Michael Meeks committed
450
	function_def_set_user_data (fndef, GINT_TO_POINTER (scm_function));
Mark Probst's avatar
Mark Probst committed
451 452 453 454 455 456 457 458 459 460

	return SCM_UNSPECIFIED;
}

static int
no_unloading_for_me (PluginData *pd)
{
	return 0;
}

461 462 463 464 465 466 467 468 469
static void
no_cleanup_for_me (PluginData *pd)
{
	return;
}

#define GUILE_TITLE _("Guile Plugin")
#define GUILE_DESCR _("This plugin enables Guile(scheme) support in Gnumeric")

470
PluginInitResult
471
init_plugin (CommandContext *context, PluginData *pd)
Mark Probst's avatar
Mark Probst committed
472
{
Michael Meeks's avatar
Michael Meeks committed
473
	FunctionCategory *cat;
474
	char *name, *dir;
475 476

	if (plugin_version_mismatch  (context, pd, GNUMERIC_VERSION))
477
		return PLUGIN_QUIET_ERROR;
Mark Probst's avatar
Mark Probst committed
478

Jody Goldberg's avatar
Jody Goldberg committed
479 480 481 482 483 484
	if (!has_gnumeric_been_compiled_with_guile_support ()) {
		gnumeric_error_plugin_problem (context,
			_("Gnumeric has not been compiled with support for guile."));
		return PLUGIN_QUIET_ERROR;
	}

485 486 487
	/* Initialize just in case. */
	eval_pos = NULL;

Michael Meeks's avatar
Michael Meeks committed
488
	cat = function_get_category ("Guile");
489

Michael Meeks's avatar
Michael Meeks committed
490 491
	function_add_nodes (cat, "scm_apply", 0, "symbol", NULL, func_scm_apply);

Michael Meeks's avatar
Michael Meeks committed
492 493 494 495
	scm_make_gsubr ("cell-value", 1, 0, 0, scm_cell_value);
	scm_make_gsubr ("cell-expr", 1, 0, 0, scm_cell_expr);
	scm_make_gsubr ("set-cell-string!", 2, 0, 0, scm_set_cell_string);
	scm_make_gsubr ("gnumeric-funcall", 2, 0, 0, scm_gnumeric_funcall);
Ariel Rios's avatar
work  
Ariel Rios committed
496
	scm_make_gsubr ("register-function", 5, 0, 0, scm_register_function);
Michael Meeks's avatar
Michael Meeks committed
497

498 499
	dir = gnumeric_sys_data_dir ("guile");
	name = g_strconcat (dir, "gnumeric_startup.scm", NULL);
Michael Meeks's avatar
Michael Meeks committed
500 501 502 503
	scm_apply (scm_eval_0str ("(lambda (filename)"
				  "  (if (access? filename R_OK)"
				  "    (load filename)"
				  "    (display (string-append \"could not read Guile plug-in init file\" filename \"\n\"))))"),
504
		  scm_cons (scm_makfrom0str (name), SCM_EOL),
Mark Probst's avatar
Mark Probst committed
505
		  SCM_EOL);
506 507
	g_free (name);
	g_free (dir);
Mark Probst's avatar
Mark Probst committed
508

509 510 511 512
	if (!plugin_data_init (pd, no_unloading_for_me, no_cleanup_for_me,
			      GUILE_TITLE, GUILE_DESCR))
		return PLUGIN_ERROR;

513
	return PLUGIN_OK;
Mark Probst's avatar
Mark Probst committed
514
}
Ariel Rios's avatar
Ariel Rios committed
515 516