[gnumeric] Handle CEILING import/export from and to ODF



commit 69a0a5ed1839698e52dc378f8dfdb0205b211658
Author: Andreas J. Guelzow <aguelzow pyrshep ca>
Date:   Fri Jun 19 01:38:11 2009 -0600

    Handle CEILING import/export from and to ODF
    
    2009-06-19 Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* openoffice-read.c (odf_func_ceiling_handler): new
    	(oo_func_map_in): hook up the above handler
    	* openoffice-write.c (odf_func_ceiling_handler): new
    	(odf_expr_func_handler): hook up the above handler

 plugins/openoffice/ChangeLog          |    7 +++
 plugins/openoffice/openoffice-read.c  |   78 ++++++++++++++++++++++++++++++++-
 plugins/openoffice/openoffice-write.c |   32 ++++++++++++--
 3 files changed, 112 insertions(+), 5 deletions(-)
---
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index 5be655e..6fd0581 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,3 +1,10 @@
+2009-06-19 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* openoffice-read.c (odf_func_ceiling_handler): new
+	(oo_func_map_in): hook up the above handler
+	* openoffice-write.c (odf_func_ceiling_handler): new
+	(odf_expr_func_handler): hook up the above handler
+	
 2009-06-18 Andreas J. Guelzow <aguelzow pyrshep ca>
 
 	* openoffice-read.c (odf_func_chisqdist_handler): new
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index 3144500..37f49c5 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -3599,6 +3599,81 @@ static GsfXMLInNode const *get_dtd () { return opendoc_content_dtd; }
 /****************************************************************************/
 
 static GnmExpr const *
+odf_func_ceiling_handler (GnmConventions const *convs, Workbook *scope, GnmExprList *args)
+{
+	guint argc = gnm_expr_list_length (args);
+	switch (argc) {
+	case 1: {
+		GnmFunc  *f = gnm_func_lookup_or_add_placeholder ("CEIL", scope, FALSE);
+		return gnm_expr_new_funcall (f, args);
+	}
+	case 2: case 3: {
+		GnmExpr const *expr_mode_zero;
+		GnmExpr const *expr_mode_one;
+		GnmExpr const *expr_if;
+		GnmExpr const *expr_mode;
+		GnmExpr const *expr_sign;
+		GnmFunc  *fd_ceiling = gnm_func_lookup_or_add_placeholder ("CEILING", scope, FALSE);
+		GnmFunc  *fd_abs = gnm_func_lookup_or_add_placeholder ("ABS", scope, FALSE);
+		GnmFunc  *fd_sign = gnm_func_lookup_or_add_placeholder ("SIGN", scope, FALSE);
+		GnmFunc  *fd_if = gnm_func_lookup_or_add_placeholder ("IF", scope, FALSE);
+		
+		expr_sign = gnm_expr_new_funcall1 
+			(fd_sign, gnm_expr_copy (g_slist_nth_data ((GSList *) args, 0)));
+		expr_mode_zero = gnm_expr_new_binary 
+			(expr_sign,
+			 GNM_EXPR_OP_MULT,
+			 gnm_expr_new_funcall2 (fd_ceiling,
+						gnm_expr_new_funcall1 
+						(fd_abs, 
+						 gnm_expr_copy (g_slist_nth_data ((GSList *) args, 0))),
+						gnm_expr_new_binary 
+						(gnm_expr_copy (expr_sign),
+						 GNM_EXPR_OP_MULT, 
+						 gnm_expr_copy (g_slist_nth_data ((GSList *) args, 1)))));
+		if (argc == 2) {
+			gnm_expr_list_unref (args);
+			return expr_mode_zero;
+		}
+
+		expr_mode_one = 
+			gnm_expr_new_funcall2 (fd_ceiling,
+					       gnm_expr_copy (g_slist_nth_data ((GSList *) args, 0)),
+					       gnm_expr_copy (g_slist_nth_data ((GSList *) args, 1)));
+
+		expr_mode = g_slist_nth_data ((GSList *) args, 2);
+		if (GNM_EXPR_GET_OPER (expr_mode) == GNM_EXPR_OP_CONSTANT) {
+			GnmValue const * val = expr_mode->constant.value;
+			if (VALUE_IS_NUMBER (val)) {
+				gnm_float value = value_get_as_float (val);
+				if (value == 0.) {
+					gnm_expr_free (expr_mode_one);
+					gnm_expr_list_unref (args);
+					return expr_mode_zero;
+				} else {
+					gnm_expr_free (expr_mode_zero);
+					gnm_expr_list_unref (args);
+					return expr_mode_one;
+				}
+			}
+		}
+		expr_if = gnm_expr_new_funcall3 (fd_if,
+						 gnm_expr_new_binary 
+						 (gnm_expr_new_constant (value_new_int (0)),
+						  GNM_EXPR_OP_EQUAL,
+						  gnm_expr_copy (expr_mode)),
+						 expr_mode_zero,
+						 expr_mode_one);
+		gnm_expr_list_unref (args);
+		return expr_if;
+	}
+	default:
+		break;
+	}
+	return NULL;
+}
+
+static GnmExpr const *
 odf_func_chisqdist_handler (GnmConventions const *convs, Workbook *scope, GnmExprList *args)
 {
 	switch (gnm_expr_list_length (args)) {
@@ -3655,6 +3730,7 @@ oo_func_map_in (GnmConventions const *convs, Workbook *scope,
 		gpointer handler;
 	} const sc_func_handlers[] = {
 		{"CHISQDIST", odf_func_chisqdist_handler},
+		{"CEILING", odf_func_ceiling_handler},
 		{NULL, NULL}
 	};
 	
@@ -4112,7 +4188,7 @@ oo_func_map_in (GnmConventions const *convs, Workbook *scope,
 	int i;
 	GnmExpr const * (*handler) (GnmConventions const *convs, Workbook *scope, GnmExprList *args);
 
-#warning "TODO : OO adds a 'mode' parm to floor/ceiling"
+#warning "TODO : OO adds a 'mode' parm to floor"
 #warning "TODO : OO missing 'A1' parm for address"
 	if (NULL == namemap) {
 		namemap = g_hash_table_new (go_ascii_strcase_hash,
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index ec37ad4..c4312a3 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -1323,6 +1323,29 @@ odf_func_r_qchisq_handler (GnmConventionsOut *out, GnmExprFunction const *func)
 	return FALSE;
 }
 
+static gboolean
+odf_func_ceiling_handler (GnmConventionsOut *out, GnmExprFunction const *func)
+{
+	GString *target = out->accum;
+	GnmExprConstPtr const *ptr = func->argv;
+	g_string_append (target, "CEILING(");
+	if (func->argc > 0) {
+		gnm_expr_as_gstring (ptr[0], out);
+		g_string_append_c (target, ';');
+		if (func->argc > 1)
+			gnm_expr_as_gstring (ptr[1], out);
+		else {
+			g_string_append (target, "SIGN(");
+			gnm_expr_as_gstring (ptr[0], out);
+			g_string_append_c (target, ')');
+		}
+		g_string_append (target, ";1)");
+		return TRUE;
+	}
+	return FALSE;
+}
+
+
 static void
 odf_expr_func_handler (GnmConventionsOut *out, GnmExprFunction const *func)
 {
@@ -1333,6 +1356,7 @@ odf_expr_func_handler (GnmConventionsOut *out, GnmExprFunction const *func)
 			{"R.QCHISQ", odf_func_r_qchisq_handler},
 			{"R.DCHISQ", odf_func_r_dchisq_handler},
 			{"R.PCHISQ", odf_func_r_pchisq_handler},
+			{"CEILING",  odf_func_ceiling_handler},
 			{NULL, NULL}
 	};
 	
@@ -1480,7 +1504,7 @@ odf_expr_func_handler (GnmConventionsOut *out, GnmExprFunction const *func)
 		{ "R.DBETA","ORG.GNUMERIC.R.DBETA" },
 		{ "R.DBINOM","ORG.GNUMERIC.R.DBINOM" },
 		{ "R.DCAUCHY","ORG.GNUMERIC.R.DCAUCHY" },
-		{ "R.DCHISQ","ORG.GNUMERIC.R.DCHISQ" },
+		{ "R.DCHISQ","ORG.GNUMERIC.R.DCHISQ" },   /* also see the handler code */
 		{ "R.DEXP","ORG.GNUMERIC.R.DEXP" },
 		{ "R.DF","ORG.GNUMERIC.R.DF" },
 		{ "R.DGAMMA","ORG.GNUMERIC.R.DGAMMA" },
@@ -1495,7 +1519,7 @@ odf_expr_func_handler (GnmConventionsOut *out, GnmExprFunction const *func)
 		{ "R.PBETA","ORG.GNUMERIC.R.PBETA" },
 		{ "R.PBINOM","ORG.GNUMERIC.R.PBINOM" },
 		{ "R.PCAUCHY","ORG.GNUMERIC.R.PCAUCHY" },
-		{ "R.PCHISQ","ORG.GNUMERIC.R.PCHISQ" },
+		{ "R.PCHISQ","ORG.GNUMERIC.R.PCHISQ" },  /* also see the handler code */
 		{ "R.PEXP","ORG.GNUMERIC.R.PEXP" },
 		{ "R.PF","ORG.GNUMERIC.R.PF" },
 		{ "R.PGAMMA","ORG.GNUMERIC.R.PGAMMA" },
@@ -1510,7 +1534,7 @@ odf_expr_func_handler (GnmConventionsOut *out, GnmExprFunction const *func)
 		{ "R.QBETA","ORG.GNUMERIC.R.QBETA" },
 		{ "R.QBINOM","ORG.GNUMERIC.R.QBINOM" },
 		{ "R.QCAUCHY","ORG.GNUMERIC.R.QCAUCHY" },
-		{ "R.QCHISQ","ORG.GNUMERIC.R.QCHISQ" },
+		{ "R.QCHISQ","ORG.GNUMERIC.R.QCHISQ" }, /* also  see the handler code */
 		{ "R.QEXP","ORG.GNUMERIC.R.QEXP" },
 		{ "R.QF","ORG.GNUMERIC.R.QF" },
 		{ "R.QGAMMA","ORG.GNUMERIC.R.QGAMMA" },
@@ -1567,7 +1591,7 @@ odf_expr_func_handler (GnmConventionsOut *out, GnmExprFunction const *func)
 /* { "BITOR","BITOR" }, */
 /* { "BITRSHIFT","BITRSHIFT" }, */
 /* { "BITXOR","BITXOR" }, */
-/* { "CEILING","CEILING" }, */
+/* { "CEILING","CEILING" },    see the handler code */
 /* { "CELL","CELL" }, */
 /* { "CHAR","CHAR" }, */
 /* /\* { "CHISQDIST","CHISQDIST" }, *\/ */



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