[gnumeric] xls: fix export of XIRR, FVSCHEDULE, and XNPV.



commit 7eb047cbb8a851ab0cedaf998535cf8385fceee1
Author: Morten Welinder <terra gnome org>
Date:   Mon Mar 29 11:43:51 2010 -0400

    xls: fix export of XIRR, FVSCHEDULE, and XNPV.

 NEWS                             |    1 +
 plugins/excel/ChangeLog          |   10 ++++++++++
 plugins/excel/ms-excel-write.c   |   18 +++++++++++++-----
 plugins/excel/ms-formula-read.c  |    3 +++
 plugins/excel/ms-formula-write.c |   34 ++++++++++++++++++++++++++++++++++
 5 files changed, 61 insertions(+), 5 deletions(-)
---
diff --git a/NEWS b/NEWS
index 0986951..5139fc7 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ Morten:
 	* Make more menu entries available when an object is selected.
 	* Improve partitioning of status area.
 	* Fix goal seek problem affecting XIRR.  [#614147]
+	* Fix export xls of XIRR, FVSCHEDULE, and XNPV.  [#614257]
 
 --------------------------------------------------------------------------
 Gnumeric 1.10.1
diff --git a/plugins/excel/ChangeLog b/plugins/excel/ChangeLog
index 25fab6d..de3f292 100644
--- a/plugins/excel/ChangeLog
+++ b/plugins/excel/ChangeLog
@@ -1,3 +1,13 @@
+2010-03-29  Morten Welinder  <terra gnome org>
+
+	* ms-formula-write.c (write_funcall): Guess argument types for
+	functions that the excel format doesn't know about.
+	(guess_arg_types): New function.
+
+	* ms-excel-write.c (excel_write_externsheets_v7,
+	excel_write_externsheets_v8): Fix letter case for extername
+	records.
+
 2010-03-08  Morten Welinder <terra gnome org>
 
 	* Release 1.10.1
diff --git a/plugins/excel/ms-excel-write.c b/plugins/excel/ms-excel-write.c
index abd73ff..5497c69 100644
--- a/plugins/excel/ms-excel-write.c
+++ b/plugins/excel/ms-excel-write.c
@@ -540,7 +540,6 @@ excel_write_externsheets_v7 (ExcelWriteState *ewb)
 	static guint8 const magic_addin[] = { 0x01, 0x3a };
 	static guint8 const magic_self[]  = { 0x01, 0x04 };
 	unsigned i, num_sheets = ewb->esheets->len;
-	GnmFunc *func;
 
 	ms_biff_put_2byte (ewb->bp, BIFF_EXTERNCOUNT, num_sheets + 2);
 
@@ -567,12 +566,17 @@ excel_write_externsheets_v7 (ExcelWriteState *ewb)
 	ms_biff_put_commit (ewb->bp);
 
 	for (i = 0; i < ewb->externnames->len ; i++) {
+		GnmFunc *func;
+		char *func_name;
+
 		ms_biff_put_var_next (ewb->bp, BIFF_EXTERNNAME_v0); /* yes v0 */
 		ms_biff_put_var_write (ewb->bp, zeros, 6);
 
 		/* write the name and the 1 byte length */
 		func = g_ptr_array_index (ewb->externnames, i);
-		excel_write_string (ewb->bp, STR_ONE_BYTE_LENGTH, func->name);
+		func_name = g_utf8_strup (func->name, -1);
+		excel_write_string (ewb->bp, STR_ONE_BYTE_LENGTH, func_name);
+		g_free (func_name);
 
 		ms_biff_put_var_write (ewb->bp, expr_ref, sizeof (expr_ref));
 		ms_biff_put_commit (ewb->bp);
@@ -603,8 +607,7 @@ excel_write_externsheets_v8 (ExcelWriteState *ewb)
 	static guint8 const magic_addin[] = { 0x01, 0x00, 0x01, 0x3a };
 	static guint8 const magic_self[]  = { 0x01, 0x04 };
 	unsigned i;
-	guint8 data [8];
-	GnmFunc *func;
+	guint8 data[8];
 
 	/* XL appears to get irrate if we export an addin SUPBOOK with
 	 * no names.  So be extra tidy and only export it if necessary */
@@ -614,12 +617,17 @@ excel_write_externsheets_v8 (ExcelWriteState *ewb)
 		ms_biff_put_commit (ewb->bp);
 
 		for (i = 0; i < ewb->externnames->len ; i++) {
+			GnmFunc *func;
+			char *func_name;
+
 			ms_biff_put_var_next (ewb->bp, BIFF_EXTERNNAME_v0); /* yes v0 */
 			ms_biff_put_var_write (ewb->bp, zeros, 6);
 
 			/* write the name and the 1 byte length */
 			func = g_ptr_array_index (ewb->externnames, i);
-			excel_write_string (ewb->bp, STR_ONE_BYTE_LENGTH, func->name);
+			func_name = g_utf8_strup (func->name, -1);
+			excel_write_string (ewb->bp, STR_ONE_BYTE_LENGTH, func_name);
+			g_free (func_name);
 			ms_biff_put_var_write (ewb->bp, expr_ref, sizeof (expr_ref));
 			ms_biff_put_commit (ewb->bp);
 		}
diff --git a/plugins/excel/ms-formula-read.c b/plugins/excel/ms-formula-read.c
index 68929c6..2e7d87a 100644
--- a/plugins/excel/ms-formula-read.c
+++ b/plugins/excel/ms-formula-read.c
@@ -658,6 +658,9 @@ make_function (GnmExprList **stack, int fn_idx, int numargs, Workbook *wb)
 		}
 
 		name = gnm_func_lookup (f_name, wb);
+		d (2, fprintf (stderr, "Function '%s' of %d args\n",
+			       f_name, numargs););
+
 		if (name == NULL)
 			name = gnm_func_add_placeholder (wb, f_name, "UNKNOWN", TRUE);
 
diff --git a/plugins/excel/ms-formula-write.c b/plugins/excel/ms-formula-write.c
index b0552e5..1e0c835 100644
--- a/plugins/excel/ms-formula-write.c
+++ b/plugins/excel/ms-formula-write.c
@@ -482,6 +482,35 @@ excel_formula_write_AREA (PolishData *pd, GnmCellRef const *a, GnmCellRef const
 		excel_formula_write_CELLREF (pd, a, b->sheet, target_type);
 }
 
+static char *
+guess_arg_types (const GnmFunc *func)
+{
+	char *res, *p;
+
+	if (func->fn_type != GNM_FUNC_TYPE_ARGS)
+		return NULL;
+
+	res = g_strdup (func->fn.args.arg_types);
+
+	for (p = res; *p; p++) {
+		switch (*p) {
+		case 'r':
+		case 'A':
+			*p = 'A';
+			break;
+		default:
+			*p = 'V';
+		}
+	}
+
+#if FORMULA_DEBUG > 1
+	g_printerr ("Coming up with arg types for %s: %s\n",
+		    func->name, res);
+#endif
+
+	return res;
+}
+
 static void
 write_funcall (PolishData *pd, GnmExpr const *expr,
 	       XLOpType target_type)
@@ -492,6 +521,7 @@ write_funcall (PolishData *pd, GnmExpr const *expr,
 	gboolean prompt   = FALSE;
 	gboolean cmdequiv = FALSE;
 	char const *arg_types = NULL;
+	char *arg_types_holder = NULL;
 	GnmFunc *func = expr->func.func;
 	ExcelFunc *ef = g_hash_table_lookup (pd->ewb->function_map, func);
 	XLOpType arg_type = XL_VAL; /* default */
@@ -520,6 +550,9 @@ write_funcall (PolishData *pd, GnmExpr const *expr,
 				push_guint16 (pd, ef->idx);
 				push_guint16 (pd, 0); /* reserved */
 			}
+
+			arg_types_holder = guess_arg_types (func);
+			arg_types = arg_types_holder;
 		}
 	} else
 		arg_types = ef->efunc->known_args;
@@ -538,6 +571,7 @@ write_funcall (PolishData *pd, GnmExpr const *expr,
 			}
 			write_node (pd, expr->func.argv[arg], 0, arg_type);
 		}
+	g_free (arg_types_holder);
 
 	if (ef->efunc != NULL) {
 		guint8 op_class = xl_get_op_class (pd,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]