Commit 22ad1db5 authored by Jody Goldberg's avatar Jody Goldberg Committed by Jody Goldberg

burn ancient kruft and use the newly exposed format engine.

2001-12-10  Jody Goldberg <jody@gnome.org>

	* fn-string.c (gnumeric_fixed) : burn ancient kruft and use the newly
	  exposed format engine.

2001-12-10  Jody Goldberg <jody@gnome.org>

	* src/value.c (value_new_string_str) : absorb the ref.
	(value_duplicate) : manually add a ref here.

	* src/format.c (render_number) : make public.
	(do_render_number) : remove pointless args.
	(format_number) : localize more of the scientific handling.
parent b81df762
2001-12-10 Jody Goldberg <jody@gnome.org>
* src/value.c (value_new_string_str) : absorb the ref.
(value_duplicate) : manually add a ref here.
* src/format.c (render_number) : make public.
(do_render_number) : remove pointless args.
(format_number) : localize more of the scientific handling.
2001-12-09 Jody Goldberg <jody@gnome.org>
http://bugzilla.gnome.org/show_bug.cgi?id=66442
......
......@@ -44,6 +44,7 @@ Jody:
* Minor etable warning tweak.
* Improve cursor handling for frozen panes.
* Fix sorting with hidden cols/rows before region.
* have FIXED use the format engine.
Morten:
* Fix EXPRESSION crash.
......
2001-12-10 Jody Goldberg <jody@gnome.org>
* src/value.c (value_new_string_str) : absorb the ref.
(value_duplicate) : manually add a ref here.
* src/format.c (render_number) : make public.
(do_render_number) : remove pointless args.
(format_number) : localize more of the scientific handling.
2001-12-09 Jody Goldberg <jody@gnome.org>
http://bugzilla.gnome.org/show_bug.cgi?id=66442
......
2001-12-10 Jody Goldberg <jody@gnome.org>
* src/value.c (value_new_string_str) : absorb the ref.
(value_duplicate) : manually add a ref here.
* src/format.c (render_number) : make public.
(do_render_number) : remove pointless args.
(format_number) : localize more of the scientific handling.
2001-12-09 Jody Goldberg <jody@gnome.org>
http://bugzilla.gnome.org/show_bug.cgi?id=66442
......
2001-12-10 Jody Goldberg <jody@gnome.org>
* src/value.c (value_new_string_str) : absorb the ref.
(value_duplicate) : manually add a ref here.
* src/format.c (render_number) : make public.
(do_render_number) : remove pointless args.
(format_number) : localize more of the scientific handling.
2001-12-09 Jody Goldberg <jody@gnome.org>
http://bugzilla.gnome.org/show_bug.cgi?id=66442
......
......@@ -15,6 +15,7 @@
#include "str.h"
#include "sheet.h"
#include "number-match.h"
#include "mathfunc.h"
#include <ctype.h>
#include <math.h>
......@@ -487,89 +488,52 @@ static char *help_fixed = {
static Value *
gnumeric_fixed (FunctionEvalInfo *ei, Value **argv)
{
Value *v;
gchar *s, *p, *f;
gint dec, commas, tmp;
gnum_float num;
int decimals;
gdouble num;
gboolean commas = TRUE;
format_info_t fmt;
GString *str;
Value *res;
num = value_get_as_float (argv[0]);
dec = argv[1] ? value_get_as_int (argv[1]) : 2;
if (argv[2]) {
decimals = argv[1] ? value_get_as_int (argv[1]) : 2;
if (argv[2] != NULL) {
gboolean err;
commas = !value_get_as_bool (argv[2], &err);
if (err)
return value_new_error (ei->pos, _("Type Mismatch"));
} else
commas = TRUE;
}
if (dec >= 1000) { /* else buffer under-run */
if (decimals >= 127) /* else buffer overflow */
return value_new_error (ei->pos, gnumeric_err_VALUE);
/*
} else if (lc->thousands_sep[1] != '\0') {
fprintf (stderr, "thousands_sep:\"%s\"\n", lc->thousands_sep);
return value_new_error (ei->pos,
_("Invalid thousands separator"));
*/
} else if (dec <= 0) { /* no decimal point : just round and pad 0's */
dec *= -1;
num /= pow (10, dec);
if (num < 1 && num > -1) {
s = g_strdup ("0");
commas = 0;
} else {
f = g_strdup ("%00?s%.0f%.00?u"); /* commas, no point, 0's */
tmp = dec;
dec += log10 (fabs (num));
if (commas)
commas = dec / 3;
p = &f[13]; /* last 0 in trailing 0's count */
do
*p-- = '0' + (tmp % 10);
while (tmp /= 10);
tmp = commas;
p = &f[3]; /* last 0 in leading blank spaces for commas */
do
*p-- = '0' + (tmp % 10);
while (tmp /= 10);
s = g_strdup_printf (f, "", num, 0);
g_free (f);
}
} else { /* decimal point format */
f = g_strdup ("%00?s%.00?f");
tmp = dec;
dec = log10 (fabs (num));
if (commas)
commas = dec / 3;
p = &f[9];
do
*p-- = '0' + (tmp % 10);
while (tmp /= 10);
tmp = commas;
p = &f[3];
do
*p-- = '0' + (tmp % 10);
while (tmp /= 10);
s = g_strdup_printf (f, "", num);
g_free (f);
}
if (commas) {
p = s;
f = &s[commas];
if (*f == '-')
*p++ = *f++;
dec -= 2;
while (dec-- > 0) {
*p++ = *f++;
if (dec%3 == 0)
/* FIXME: should use lc->thousands_sep[0] */
*p++ = ',';
}
}
v = value_new_string (s);
g_free (s);
return v;
if (decimals <= 0) {
/* no decimal point : just round and pad 0's */
double mult = gpow10 (decimals);
num = (gnumeric_fake_round (num * mult) / mult);
fmt.right_req = fmt.right_allowed = 0;
} else /* decimal point format */
fmt.right_req = fmt.right_allowed = decimals;
fmt.right_optional = 0;
fmt.right_spaces = 0;
fmt.left_spaces = 0;
fmt.left_req = 0;
fmt.decimal_separator_seen = (decimals > 0);
fmt.supress_minus = FALSE;
fmt.group_thousands = commas;
fmt.has_fraction = FALSE;
fmt.negative = num < 0.;
if (fmt.negative)
num = -num;
str = g_string_new ("");
render_number (str, num, &fmt);
if (str->len == 0)
g_string_append_c (str, '0');
res = value_new_string_str (string_get_nocopy (str->str));
g_string_free (str, FALSE);
return res;
}
/***************************************************************************/
......
......@@ -662,39 +662,22 @@ lookup_color (const char *str, const char *end)
return NULL;
}
typedef struct {
int right_optional, right_spaces, right_req, right_allowed;
int left_spaces, left_req;
int scientific;
int scientific_exp;
gboolean scientific_shows_plus;
gboolean rendered;
gboolean negative;
gboolean decimal_separator_seen;
gboolean supress_minus;
gboolean comma_separator_seen;
gboolean has_fraction;
} format_info_t;
static double beyond_precision;
static void
void
render_number (GString *result,
gdouble number,
int left_req,
int right_req,
int left_spaces,
int right_spaces,
int right_allowed,
char const *show_decimal,
format_info_t const *info)
{
char thousands_sep;
char thousands_sep = format_get_thousand ();
unsigned char num_buf[(DBL_MANT_DIG + DBL_MAX_EXP) * 2 + 1];
unsigned char *num = num_buf + sizeof (num_buf) - 1;
double frac_part, int_part;
int group, zero_count, digit_count = 0;
thousands_sep = format_get_thousand ();
int left_req = info->left_req;
int right_req = info->right_req;
int left_spaces = info->left_spaces;
int right_spaces = info->right_spaces;
int right_allowed = info->right_allowed + info->right_optional;
if (right_allowed >= 0 && !info->has_fraction) {
/* Change "rounding" into "truncating". */
......@@ -705,7 +688,7 @@ render_number (GString *result,
frac_part = modf (gnumeric_add_epsilon (number), &int_part);
*num = '\0';
group = (info->comma_separator_seen) ? 3 : -1;
group = (info->group_thousands) ? 3 : -1;
for (; int_part > beyond_precision ; int_part /= 10., digit_count++) {
if (group-- == 0) {
group = 2;
......@@ -737,10 +720,16 @@ render_number (GString *result,
g_string_append (result, num);
if (info->decimal_separator_seen)
/* If the format contains only "#"s to the left of the decimal
* point, number in the [0.0,1.0] range are prefixed with a
* decimal point
*/
if (info->decimal_separator_seen ||
(number > 0.0 &&
number < 1.0 &&
info->right_allowed == 0 &&
info->right_optional > 0))
g_string_append_c (result, format_get_decimal ());
else
g_string_append (result, show_decimal);
/* TODO : clip this a DBL_DIG */
/* TODO : What if is a fraction ? */
......@@ -780,21 +769,8 @@ render_number (GString *result,
static void
do_render_number (gdouble number, format_info_t *info, GString *result)
{
char decimal_point[2];
info->rendered = TRUE;
/*
* If the format contains only "#"s to the left of the decimal
* point, number in the [0.0,1.0] range are prefixed with a
* decimal point
*/
if (number > 0.0 && number < 1.0 && info->right_allowed == 0 && info->right_optional > 0){
decimal_point[0] = format_get_decimal ();
decimal_point[1] = 0;
} else
decimal_point[0] = 0;
#if 0
printf ("Rendering: %g with:\n", number);
printf ("left_req: %d\n"
......@@ -817,15 +793,7 @@ do_render_number (gdouble number, format_info_t *info, GString *result)
decimal_point);
#endif
render_number (result,
number,
info->left_req,
info->right_req,
info->left_spaces,
info->right_spaces,
info->right_allowed + info->right_optional,
decimal_point,
info);
render_number (result, number, info);
}
/*
......@@ -1114,42 +1082,36 @@ format_number (gdouble number, int col_width, StyleFormatEntry const *entry)
char const sep = format_get_thousand ();
g_string_append_c (result, sep);
} else
info.comma_separator_seen = TRUE;
info.group_thousands = TRUE;
break;
}
case 'E': case 'e':
/* FIXME: this is a gross hack */
case 'E': case 'e': {
gboolean const is_lower = (*format == 'e');
gboolean shows_plus = FALSE;
int prec = info.right_optional + info.right_req;
char *buffer = g_alloca (40 + prec + 2);
can_render_number = TRUE;
info.scientific = *format;
for (format++; *format;){
if (*format == '+'){
info.scientific_shows_plus = TRUE;
format++;
} else if (*format == '-')
format++;
else if (*format == '0'){
info.scientific_exp++;
format++;
} else
while (*(++format))
if (*format == '+')
shows_plus = TRUE;
else if (*format == '-' || *format == '0')
;
else
break;
}
/* FIXME: this is a gross hack */
{
int prec = info.right_optional + info.right_req;
char *buffer = g_alloca (40 + prec + 2);
sprintf (buffer, (info.scientific == 'e')
? "%s%.*e"
: "%s%.*E",
info.negative
? "-" :
info.scientific_shows_plus
? "+" : "",
prec, number);
g_string_append (result, buffer);
goto finish;
}
sprintf (buffer, is_lower ? "%s%.*e" : "%s%.*E",
info.negative
? "-" :
shows_plus
? "+" : "",
prec, number);
g_string_append (result, buffer);
goto finish;
}
case '\\':
if (format[1] != '\0') {
......@@ -1418,8 +1380,8 @@ format_number (gdouble number, int col_width, StyleFormatEntry const *entry)
}
finish:
res = g_strdup (result->str);
g_string_free (result, TRUE);
res = result->str;
g_string_free (result, FALSE);
return res;
}
......
......@@ -37,6 +37,18 @@ void format_color_shutdown (void);
char *format_add_decimal (StyleFormat const *fmt);
char *format_remove_decimal (StyleFormat const *fmt);
typedef struct {
int right_optional, right_spaces, right_req, right_allowed;
int left_spaces, left_req;
gboolean rendered;
gboolean negative;
gboolean decimal_separator_seen;
gboolean supress_minus;
gboolean group_thousands;
gboolean has_fraction;
} format_info_t;
void render_number (GString *result, gdouble number, format_info_t const *info);
/* Locale support routines */
char const *gnumeric_setlocale (int category, char const *val);
char const *format_get_currency (gboolean *precedes, gboolean *space_sep);
......
2001-12-10 Jody Goldberg <jody@gnome.org>
* fn-string.c (gnumeric_fixed) : burn ancient kruft and use the newly
exposed format engine.
2001-12-06 Jody Goldberg <jody@gnome.org>
* fn-information.c (gnumeric_cell) : const.
......
......@@ -15,6 +15,7 @@
#include "str.h"
#include "sheet.h"
#include "number-match.h"
#include "mathfunc.h"
#include <ctype.h>
#include <math.h>
......@@ -487,89 +488,52 @@ static char *help_fixed = {
static Value *
gnumeric_fixed (FunctionEvalInfo *ei, Value **argv)
{
Value *v;
gchar *s, *p, *f;
gint dec, commas, tmp;
gnum_float num;
int decimals;
gdouble num;
gboolean commas = TRUE;
format_info_t fmt;
GString *str;
Value *res;
num = value_get_as_float (argv[0]);
dec = argv[1] ? value_get_as_int (argv[1]) : 2;
if (argv[2]) {
decimals = argv[1] ? value_get_as_int (argv[1]) : 2;
if (argv[2] != NULL) {
gboolean err;
commas = !value_get_as_bool (argv[2], &err);
if (err)
return value_new_error (ei->pos, _("Type Mismatch"));
} else
commas = TRUE;
}
if (dec >= 1000) { /* else buffer under-run */
if (decimals >= 127) /* else buffer overflow */
return value_new_error (ei->pos, gnumeric_err_VALUE);
/*
} else if (lc->thousands_sep[1] != '\0') {
fprintf (stderr, "thousands_sep:\"%s\"\n", lc->thousands_sep);
return value_new_error (ei->pos,
_("Invalid thousands separator"));
*/
} else if (dec <= 0) { /* no decimal point : just round and pad 0's */
dec *= -1;
num /= pow (10, dec);
if (num < 1 && num > -1) {
s = g_strdup ("0");
commas = 0;
} else {
f = g_strdup ("%00?s%.0f%.00?u"); /* commas, no point, 0's */
tmp = dec;
dec += log10 (fabs (num));
if (commas)
commas = dec / 3;
p = &f[13]; /* last 0 in trailing 0's count */
do
*p-- = '0' + (tmp % 10);
while (tmp /= 10);
tmp = commas;
p = &f[3]; /* last 0 in leading blank spaces for commas */
do
*p-- = '0' + (tmp % 10);
while (tmp /= 10);
s = g_strdup_printf (f, "", num, 0);
g_free (f);
}
} else { /* decimal point format */
f = g_strdup ("%00?s%.00?f");
tmp = dec;
dec = log10 (fabs (num));
if (commas)
commas = dec / 3;
p = &f[9];
do
*p-- = '0' + (tmp % 10);
while (tmp /= 10);
tmp = commas;
p = &f[3];
do
*p-- = '0' + (tmp % 10);
while (tmp /= 10);
s = g_strdup_printf (f, "", num);
g_free (f);
}
if (commas) {
p = s;
f = &s[commas];
if (*f == '-')
*p++ = *f++;
dec -= 2;
while (dec-- > 0) {
*p++ = *f++;
if (dec%3 == 0)
/* FIXME: should use lc->thousands_sep[0] */
*p++ = ',';
}
}
v = value_new_string (s);
g_free (s);
return v;
if (decimals <= 0) {
/* no decimal point : just round and pad 0's */
double mult = gpow10 (decimals);
num = (gnumeric_fake_round (num * mult) / mult);
fmt.right_req = fmt.right_allowed = 0;
} else /* decimal point format */
fmt.right_req = fmt.right_allowed = decimals;
fmt.right_optional = 0;
fmt.right_spaces = 0;
fmt.left_spaces = 0;
fmt.left_req = 0;
fmt.decimal_separator_seen = (decimals > 0);
fmt.supress_minus = FALSE;
fmt.group_thousands = commas;
fmt.has_fraction = FALSE;
fmt.negative = num < 0.;
if (fmt.negative)
num = -num;
str = g_string_new ("");
render_number (str, num, &fmt);
if (str->len == 0)
g_string_append_c (str, '0');
res = value_new_string_str (string_get_nocopy (str->str));
g_string_free (str, FALSE);
return res;
}
/***************************************************************************/
......
......@@ -101,12 +101,13 @@ value_new_string (char const *str)
return (Value *)v;
}
/* NOTE : absorbs the reference */
Value *
value_new_string_str (String *str)
{
ValueStr *v = g_new (ValueStr, 1);
*((ValueType *)&(v->type)) = VALUE_STRING;
v->val = string_ref (str);
v->val = str;
return (Value *)v;
}
......@@ -383,6 +384,7 @@ value_duplicate (Value const *src)
src->v_err.mesg);
case VALUE_STRING:
string_ref (src->v_str.val);
return value_new_string_str (src->v_str.val);
case VALUE_CELLRANGE:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment