[goffice] Formats: fix engineering format problem.



commit c0401f8b8a862f143ba54e804bc8df929ad29275
Author: Morten Welinder <terra gnome org>
Date:   Wed Jan 26 13:52:41 2011 -0500

    Formats: fix engineering format problem.

 ChangeLog                 |    6 +++
 NEWS                      |    5 ++-
 goffice/utils/go-format.c |  111 ++++++++++++++++++++++++++-------------------
 3 files changed, 75 insertions(+), 47 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 9e9aa8f..0ed63c0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2011-01-26  Morten Welinder  <terra gnome org>
+
+	* goffice/utils/go-format.c (printf_engineering): New function.
+	Fix overflow problem.  Fixes #640571.
+	(go_format_execute): Use printf_engineering.
+
 2011-01-25  Jean Brefort  <jean brefort normalesup org>
 	* goffice/data/go-data-simple.c (render_val),
 	(go_data_scalar_val_serialize), (go_data_scalar_val_unserialize),
diff --git a/NEWS b/NEWS
index 782bb7a..eb89bfa 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,6 @@
 goffice 0.8.13:
 
-Andreas
+Andreas:
 	* Write text formats to ODF. [#636158]
 
 Jean:
@@ -9,6 +9,9 @@ Jean:
 	* Invalidate canvas items after reordering to force a redraw? [#639840]
 	* Fix axis limits serialization. [#640438]
 
+Morten:
+	* Fix problem with engineering formats.  [#640571]
+
 --------------------------------------------------------------------------
 goffice 0.8.12:
 
diff --git a/goffice/utils/go-format.c b/goffice/utils/go-format.c
index d1cf57b..cf45676 100644
--- a/goffice/utils/go-format.c
+++ b/goffice/utils/go-format.c
@@ -2402,6 +2402,63 @@ fill_with_char (GString *str, PangoLayout *layout, gsize fill_pos,
 
 #endif
 
+static void
+SUFFIX(printf_engineering) (GString *dst, DOUBLE val, int n, int wd)
+{
+	int exponent_guess = 0;
+	int exponent;
+	int nde = 0;
+	char *epos;
+	char *dot;
+	const GString *decimal = go_locale_get_decimal ();
+
+	if (wd <= 1 || val == 0 || !SUFFIX(go_finite) (val)) {
+		g_string_printf (dst, "%.*" FORMAT_E, n, val);
+		return;
+	}
+
+	exponent_guess = (int)floor (SUFFIX(log10) (SUFFIX(fabs) (val)));
+	/* Extra digits we need assuming guess correct */
+	nde = (exponent_guess >= 0)
+		? exponent_guess % wd
+		: (wd - ((-exponent_guess) % wd)) % wd;
+
+	g_string_printf (dst, "%.*" FORMAT_E, n + nde, val);
+	epos = (char *)strchr (dst->str, 'E');
+	if (!epos)
+		return;
+
+	exponent = atoi (epos + 1);
+	g_string_truncate (dst, epos - dst->str);
+	if (exponent != exponent_guess) {
+		/*
+		 * We rounded from 9.99Exx to
+		 *                 1.00Eyy
+		 * with yy=xx+1.
+		 */
+		nde = (nde + 1) % wd;
+		if (nde == 0)
+			g_string_truncate (dst, dst->len - (wd - 1));
+		else
+			g_string_append_c (dst, '0');
+	}
+
+	dot = (char *)strstr (dst->str, decimal->str);
+	if (dot) {
+		memmove (dot, dot + decimal->len, nde);
+		memcpy (dot + nde, decimal->str, decimal->len);
+	} else {
+		while (nde > 0) {
+			g_string_append_c (dst, '0');
+			nde--;
+		}
+	}
+	exponent -= nde;
+
+	g_string_append_printf (dst, "E%+d", exponent);
+}
+
+
 
 #define INSERT_MINUS(pos) do {							\
 	if (unicode_minus)							\
@@ -2783,53 +2840,19 @@ SUFFIX(go_format_execute) (PangoLayout *layout, GString *dst,
 		case OP_NUM_PRINTF_E: {
 			int n = *prg++;
 			int wd = *prg++;
-			const char *dot;
-			int exponent_guess = 0;
-			int nde = 0;
-			gboolean retry;
-			gboolean retried = FALSE;
-
-			if (wd > 1 && val != 0) {
-				exponent_guess = (int)floor (SUFFIX(log10) (SUFFIX(fabs) (val)));
-				nde = (exponent_guess >= 0)
-					? exponent_guess % wd
-					: (wd - ((-exponent_guess) % wd)) % wd;
-			}
+			char *dot;
+			const char *epos;
 
 			if (!numtxt)
 				numtxt = g_string_sized_new (100);
 
-			do {
-				const char *epos;
-				g_string_printf (numtxt, "%.*" FORMAT_E, n + nde, val);
-				epos = strchr (numtxt->str, 'E');
-				retry = FALSE;
-				if (epos) {
-					exponent = atoi (epos + 1);
-					g_string_truncate (numtxt, epos - numtxt->str);
-				}
+			SUFFIX(printf_engineering) (numtxt, val, n, wd);
 
-				if (wd > 1) {
-					char *dot;
-					if (exponent != exponent_guess && !retried) {
-						nde = (nde == wd - 1) ? 0 : nde + 1;
-						retry = !retried;
-						retried = TRUE;
-						continue;
-					}
-					dot = strstr (numtxt->str, decimal->str);
-					if (dot) {
-						memmove (dot, dot + decimal->len, nde);
-						memcpy (dot + nde, decimal->str, decimal->len);
-					} else {
-						while (nde > 0) {
-							g_string_append_c (numtxt, '0');
-							nde--;
-						}
-					}
-					exponent -= nde;
-				}
-			} while (retry);
+			epos = strchr (numtxt->str, 'E');
+			if (epos) {
+				exponent = atoi (epos + 1);
+				g_string_truncate (numtxt, epos - numtxt->str);
+			}
 
 			dot = strstr (numtxt->str, decimal->str);
 			if (dot) {
@@ -2840,10 +2863,6 @@ SUFFIX(go_format_execute) (PangoLayout *layout, GString *dst,
 				/* Kill zeroes in "xxx.xxx000"  */
 				g_string_truncate (numtxt, i);
 			} else {
-				const char *epos = strchr (numtxt->str, 'E');
-				if (epos)
-					g_string_truncate (numtxt,
-							   epos - numtxt->str);
 				dotpos = numtxt->len;
 			}
 



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