[gnumeric] Add ODF compatibility function NUMBERVALUE.



commit f0593e1d18d679411f0024aa9c745c745607d9f1
Author: Andreas J. Guelzow <aguelzow pyrshep ca>
Date:   Sat Oct 24 12:40:42 2009 -0600

    Add ODF compatibility function NUMBERVALUE.
    
    2009-10-24  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* openoffice-read.c (oo_func_map_in): we now have NUMBERVALUE
    	* openoffice-write.c (odf_expr_func_handler): ditto
    
    2009-10-24 Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* functions.c (help_numbervalue): new
    	(gnumeric_numbervalue): new
    	(string_functions): add NUMBERVALUE
    	* plugin.xml.in: add NUMBERVALUE
    
    2009-10-24  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* src/number-match.c (format_match_decimal_number): split into
    	  format_match_decimal_number and format_match_decimal_number_with_locale
    	* src/number-match.h (format_match_decimal_number_with_locale): new

 ChangeLog                             |    6 +++
 NEWS                                  |    2 +-
 plugins/fn-string/ChangeLog           |    7 ++++
 plugins/fn-string/functions.c         |   62 +++++++++++++++++++++++++++++++++
 plugins/fn-string/plugin.xml.in       |    1 +
 plugins/openoffice/ChangeLog          |    5 +++
 plugins/openoffice/openoffice-read.c  |    1 -
 plugins/openoffice/openoffice-write.c |    2 +-
 src/number-match.c                    |   27 ++++++++++----
 src/number-match.h                    |    4 ++
 10 files changed, 107 insertions(+), 10 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 631c13c..2a6ce07 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2009-10-24  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* src/number-match.c (format_match_decimal_number): split into
+	  format_match_decimal_number and format_match_decimal_number_with_locale
+	* src/number-match.h (format_match_decimal_number_with_locale): new
+
 2009-10-23  Morten Welinder  <terra gnome org>
 
 	* src/number-match.c (handle_year): Handle pre-1900 dates.
diff --git a/NEWS b/NEWS
index dd6d2cc..efcdd87 100644
--- a/NEWS
+++ b/NEWS
@@ -5,7 +5,7 @@ Andreas:
 	* Add R.PSNORM, R.DSNORM and R.DST.
 	* Fix small sort dialog problem. [#599091]
 	* A few functions from the christian liturgical calendar.
-	* Add ODF compatibility functions DAYS and ISFORMULA.
+	* Add ODF compatibility functions DAYS, ISFORMULA and NUMBERVALUE.
 	* Work around OpenOffice.org saving function names in lowercase.
 
 Jody:
diff --git a/plugins/fn-string/ChangeLog b/plugins/fn-string/ChangeLog
index 483fb03..36a6aba 100644
--- a/plugins/fn-string/ChangeLog
+++ b/plugins/fn-string/ChangeLog
@@ -1,3 +1,10 @@
+2009-10-24 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* functions.c (help_numbervalue): new
+	(gnumeric_numbervalue): new
+	(string_functions): add NUMBERVALUE
+	* plugin.xml.in: add NUMBERVALUE
+
 2009-10-11  Morten Welinder <terra gnome org>
 
 	* Release 1.9.14
diff --git a/plugins/fn-string/functions.c b/plugins/fn-string/functions.c
index 6f0f902..c667cee 100644
--- a/plugins/fn-string/functions.c
+++ b/plugins/fn-string/functions.c
@@ -1044,6 +1044,65 @@ gnumeric_value (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 
 /***************************************************************************/
 
+static GnmFuncHelp const help_numbervalue[] = {
+        { GNM_FUNC_HELP_NAME, F_("VALUE:numeric value of @{text}")},
+        { GNM_FUNC_HELP_ARG, F_("text:string")},
+        { GNM_FUNC_HELP_ARG, F_("separator:decimal separator")},
+	{ GNM_FUNC_HELP_NOTE, F_("If @{text} does not look like a decimal number, "
+				 "NUMBERVALUE returns the value VALUE would "
+				 "return (ignoring the given @{separator}).")},
+ 	{ GNM_FUNC_HELP_ODF, F_("This function is OpenFormula compatible.") },
+        { GNM_FUNC_HELP_EXAMPLES, "=NUMBERVALUE(\"$1,000\",\",\")" },
+        { GNM_FUNC_HELP_SEEALSO, "VALUE"},
+        { GNM_FUNC_HELP_END}
+};
+
+static GnmValue *
+gnumeric_numbervalue (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
+{
+	char const *sep = value_peek_string (argv[1]);
+	if (strlen(sep) != 1 || (*sep != '.' && *sep != ',')) {
+		return value_new_error_VALUE (ei->pos);
+	}
+	
+	if (VALUE_IS_EMPTY (argv[0]) || VALUE_IS_NUMBER (argv[0]))
+		return value_dup (argv[0]);
+	else {
+		GnmValue *v;
+		char const *p = value_peek_string (argv[0]);
+		GString *curr;
+		GString *thousand;
+		GString *decimal;
+		GOFormatFamily family = GO_FORMAT_GENERAL;
+
+		decimal = g_string_new (sep);
+		thousand = g_string_new ((*sep == '.') ? ",":".");
+		curr = g_string_new ("$");
+
+		/* Skip leading spaces */
+		while (*p && g_unichar_isspace (g_utf8_get_char (p)))
+		       p = g_utf8_next_char (p);
+
+		v = format_match_decimal_number_with_locale 
+			(p, &family, curr, thousand, decimal);
+
+		g_string_free (decimal, TRUE);
+		g_string_free (thousand, TRUE);
+		g_string_free (curr, TRUE);
+
+		if (v == NULL)
+			v = format_match_number 
+				(p, NULL,
+				 workbook_date_conv (ei->pos->sheet->workbook));
+
+		if (v != NULL)
+			return v;
+		return value_new_error_VALUE (ei->pos);
+	}
+}
+
+/***************************************************************************/
+
 static GnmFuncHelp const help_substitute[] = {
         { GNM_FUNC_HELP_NAME, F_("SUBSTITUTE:@{text} with all occurrences of @{old} replaced by @{new}")},
         { GNM_FUNC_HELP_ARG, F_("text:original text")},
@@ -1628,6 +1687,9 @@ GnmFuncDescriptor const string_functions[] = {
         { "midb",        "Sff",               help_midb,
 	  gnumeric_midb, NULL, NULL, NULL, NULL,
 	  GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_NO_TESTSUITE },
+        { "numbervalue",      "SS",          help_numbervalue,
+	  gnumeric_numbervalue, NULL, NULL, NULL, NULL,
+	  GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC, GNM_FUNC_TEST_STATUS_BASIC },
         { "proper",     "S",                         help_proper,
 	  gnumeric_proper, NULL, NULL, NULL, NULL,
 	  GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
diff --git a/plugins/fn-string/plugin.xml.in b/plugins/fn-string/plugin.xml.in
index 8582fec..b59b47a 100644
--- a/plugins/fn-string/plugin.xml.in
+++ b/plugins/fn-string/plugin.xml.in
@@ -29,6 +29,7 @@
 				<function name="lower"/>
 				<function name="mid"/>
 				<function name="midb"/>
+				<function name="numbervalue"/>
 				<function name="proper"/>
 				<function name="replace"/>
 				<function name="replaceb"/>
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index 0f928d3..47579ae 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,5 +1,10 @@
 2009-10-24  Andreas J. Guelzow <aguelzow pyrshep ca>
 
+	* openoffice-read.c (oo_func_map_in): we now have NUMBERVALUE
+	* openoffice-write.c (odf_expr_func_handler): ditto
+
+2009-10-24  Andreas J. Guelzow <aguelzow pyrshep ca>
+
 	* openoffice-read.c (oo_func_map_in): we had COMBINA and ARABIC 
 	  for a while
 	* openoffice-write.c (odf_expr_func_handler): ditto
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index 2a7953e..f067f13 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -4661,7 +4661,6 @@ oo_func_map_in (GnmConventions const *convs, Workbook *scope,
 		{ "DDE","ODF.DDE" },
 		{ "IFNA","ODF.IFNA" },
 		{ "MULTIPLE.OPERATIONS","ODF.MULTIPLE.OPERATIONS" },
-		{ "NUMBERVALUE","ODF.NUMBERVALUE" },
 		{ "SHEET","ODF.SHEET" },
 		{ "SHEETS","ODF.SHEETS" },
 		{ "SUMIFS","ODF.SUMIFS" },
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index ee28d46..40566b7 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -1839,7 +1839,7 @@ odf_expr_func_handler (GnmConventionsOut *out, GnmExprFunction const *func)
 		{ "NOW","NOW" },
 		{ "NPER","NPER" },
 		{ "NPV","NPV" },
-		/* { "NUMBERVALUE","NUMBERVALUE" },  not implemented */
+		{ "NUMBERVALUE","NUMBERVALUE" },
 		{ "OCT2BIN","OCT2BIN" },
 		{ "OCT2DEC","OCT2DEC" },
 		{ "OCT2HEX","OCT2HEX" },
diff --git a/src/number-match.c b/src/number-match.c
index 9bfbdbf..ce5d4b1 100644
--- a/src/number-match.c
+++ b/src/number-match.c
@@ -855,8 +855,10 @@ format_match_fraction (char const *text, int *denlen)
 }
 
 
-static GnmValue *
-format_match_decimal_number (char const *text, GOFormatFamily *family)
+GnmValue *
+format_match_decimal_number_with_locale (char const *text, GOFormatFamily *family, 
+					 GString const *curr, GString const *thousand,
+					 GString const *decimal)
 {
 	gboolean par_open = FALSE;
 	gboolean par_close = FALSE;
@@ -864,11 +866,11 @@ format_match_decimal_number (char const *text, GOFormatFamily *family)
 	gboolean has_percent = FALSE;
 	char sign = 0;
 	GString *numstr = g_string_sized_new (20);
-	GString const *curr = go_locale_get_currency (NULL, NULL);
-	GString const *thousand = go_locale_get_thousand ();
-	GString const *decimal = go_locale_get_decimal ();
 	gboolean last_was_digit = FALSE;
-	gboolean allow1000 = (thousand->len != 0);
+	gboolean allow1000 = (thousand != NULL) && (thousand->len != 0);
+
+	g_return_val_if_fail (curr != NULL, NULL);
+	g_return_val_if_fail (decimal != NULL, NULL);
 
 	while (*text) {
 		gunichar uc = g_utf8_get_char (text);
@@ -917,7 +919,8 @@ format_match_decimal_number (char const *text, GOFormatFamily *family)
 		}
 
 		if (strncmp (decimal->str, text, decimal->len) == 0) {
-			g_string_append_len (numstr, text, decimal->len);
+			GString const *local_decimal = go_locale_get_decimal ();
+			g_string_append_len (numstr, local_decimal->str, local_decimal->len);
 			text += decimal->len;
 			allow1000 = FALSE;
 			continue;
@@ -1029,6 +1032,16 @@ format_match_decimal_number (char const *text, GOFormatFamily *family)
 	}
 }
 
+static GnmValue *
+format_match_decimal_number (char const *text, GOFormatFamily *family)
+{
+	GString const *curr = go_locale_get_currency (NULL, NULL);
+	GString const *thousand = go_locale_get_thousand ();
+	GString const *decimal = go_locale_get_decimal ();
+
+	return format_match_decimal_number_with_locale (text, family, curr, thousand, decimal);
+}
+
 #undef DO_SIGN
 #undef SKIP_SPACES
 #undef SKIP_DIGITS
diff --git a/src/number-match.h b/src/number-match.h
index 1ce5968..7aec1c0 100644
--- a/src/number-match.h
+++ b/src/number-match.h
@@ -11,6 +11,10 @@ GnmValue   *format_match        (char const *s, GOFormat const *cur_fmt,
 				 GODateConventions const *date_conv);
 GnmValue   *format_match_number (char const *s, GOFormat const *cur_fmt,
 				 GODateConventions const *date_conv);
+GnmValue   *format_match_decimal_number_with_locale 
+                                (char const *text, GOFormatFamily *family, 
+				 GString const *curr, GString const *thousand,
+				 GString const *decimal);
 
 G_END_DECLS
 



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