"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "plugins/lotus-123/lotus.c" between
gnumeric-1.12.49.tar.xz and gnumeric-1.12.50.tar.xz

About: Gnumeric - The GNOME office spreadsheet.

lotus.c  (gnumeric-1.12.49.tar.xz):lotus.c  (gnumeric-1.12.50.tar.xz)
/** /**
* lotus.c: Lotus 123 support for Gnumeric * lotus.c: Lotus 123 support for Gnumeric
* *
* Authors: * Authors:
* See: README * See: README
* Michael Meeks (mmeeks@gnu.org) * Michael Meeks (mmeeks@gnu.org)
* Stephen Wood (saw@genhomepage.com) * Stephen Wood (saw@genhomepage.com)
* Morten Welinder (terra@gnome.org) * Morten Welinder (terra@gnome.org)
*
* Docs are scarce.
* https://www.mettalogic.co.uk/tim/l123/l123r4.html
**/ **/
#include <gnumeric-config.h> #include <gnumeric-config.h>
#include <gnumeric.h> #include <gnumeric.h>
#include "lotus.h" #include "lotus.h"
#include "lotus-types.h" #include "lotus-types.h"
#include "lotus-formula.h" #include "lotus-formula.h"
#include <workbook.h> #include <workbook.h>
#include <cell.h> #include <cell.h>
#include <expr.h> #include <expr.h>
#include <value.h> #include <value.h>
#include <gutils.h> #include <gutils.h>
#include <ranges.h> #include <ranges.h>
#include <mstyle.h> #include <mstyle.h>
#include <style-color.h> #include <style-color.h>
#include <style-font.h> #include <style-font.h>
#include <parse-util.h> #include <parse-util.h>
#include <sheet-style.h> #include <sheet-style.h>
#include <sheet-object-cell-comment.h> #include <sheet-object-cell-comment.h>
#include <sheet-view.h>
#include <selection.h>
#include <gsf/gsf-input.h> #include <gsf/gsf-input.h>
#include <gsf/gsf-utils.h> #include <gsf/gsf-utils.h>
#include <gsf/gsf-msole-utils.h> #include <gsf/gsf-msole-utils.h>
#include <string.h> #include <string.h>
#define LOTUS_DEBUG 0 #define LOTUS_DEBUG 0
#undef DEBUG_RLDB #undef DEBUG_RLDB
#undef DEBUG_STYLE #undef DEBUG_STYLE
#undef DEBUG_FORMAT #undef DEBUG_FORMAT
skipping to change at line 932 skipping to change at line 937
: lotus_value ((gnm_float)mant / -f); : lotus_value ((gnm_float)mant / -f);
} else } else
return value_new_int (d >> 1); return value_new_int (d >> 1);
} }
static GnmValue * static GnmValue *
lotus_extfloat (guint64 mant, guint16 signexp) lotus_extfloat (guint64 mant, guint16 signexp)
{ {
int exp = (signexp & 0x7fff) - 16383; int exp = (signexp & 0x7fff) - 16383;
int sign = (signexp & 0x8000) ? -1 : 1; int sign = (signexp & 0x8000) ? -1 : 1;
/* FIXME: Special values may indicate NaN, +/- inf */
/* /*
* NOTE: if gnm_float is "double", then passing the first argument * NOTE: if gnm_float is "double", then passing the first argument
* to gnm_ldexp will perform rounding from 64-bit integer to * to gnm_ldexp will perform rounding from 64-bit integer to
* 53-bit mantissa in a double. * 53-bit mantissa in a double.
* *
* NOTE: the gnm_ldexp may under- or overflow. That ought to do * NOTE: the gnm_ldexp may under- or overflow. That ought to do
* the right thing. * the right thing.
*/ */
return lotus_value (sign * gnm_ldexp (mant, exp - 63)); return lotus_value (sign * gnm_ldexp (mant, exp - 63));
} }
GnmValue * GnmValue *
lotus_load_treal (gconstpointer p) lotus_load_treal (gconstpointer p)
{ {
const guint8 *pc = p;
if (pc[9] == 0xff && pc[8] == 0xff) {
switch (pc[7]) {
case 0x00: return value_new_empty ();
case 0xc0: return value_new_error_VALUE (NULL);
case 0xd0: return value_new_error_NA (NULL);
case 0xe0: return value_new_string (""); // Supplied in FORMULAST
RING
}
}
return lotus_extfloat (GSF_LE_GET_GUINT64 (p), return lotus_extfloat (GSF_LE_GET_GUINT64 (p),
GSF_LE_GET_GUINT16 ((const char *)p + 8)); GSF_LE_GET_GUINT16 (pc + 8));
} }
static GnmValue * static GnmValue *
lotus_treal (const record_t *r, int ofs) lotus_treal (const record_t *r, int ofs)
{ {
g_return_val_if_fail (ofs + 10 <= r->len, NULL); g_return_val_if_fail (ofs + 10 <= r->len, NULL);
return lotus_load_treal (r->data + ofs); return lotus_load_treal (r->data + ofs);
} }
skipping to change at line 1952 skipping to change at line 1967
do { do {
switch (r->type) { switch (r->type) {
case LOTUS_BOF: CHECK_RECORD_SIZE (>= 18) { case LOTUS_BOF: CHECK_RECORD_SIZE (>= 18) {
state->lmbcs_group = GSF_LE_GET_GUINT8 (r->data + 16); state->lmbcs_group = GSF_LE_GET_GUINT8 (r->data + 16);
break; break;
} }
case LOTUS_EOF: case LOTUS_EOF:
goto done; goto done;
case LOTUS_SHEETCELLPTR: CHECK_RECORD_SIZE (== 16) {
Sheet *sheet = lotus_get_sheet (state->wb, r->data[0]);
int row = GSF_LE_GET_GUINT16 (r->data + 4);
int col = r->data[6];
int left = r->data[7];
int top = GSF_LE_GET_GUINT16 (r->data + 8);
SheetView *sv = sheet_get_view (sheet, state->wbv);
GnmCellPos edit;
edit.col = col;
edit.row = row;
sv_selection_set (sv, &edit, col, row, col, row);
gnm_sheet_view_set_initial_top_left (sv, left, top);
break;
}
case LOTUS_SHEETLAYOUT: CHECK_RECORD_SIZE (== 5) {
// Despite the name, this stores default col width
Sheet *sheet = lotus_get_sheet (state->wb, r->data[0]);
guint8 chars = r->data[4];
// Very approximate
double size = lotus_twips_to_points (chars * (20 * 72 / 1
1));
sheet_col_set_default_size_pts (sheet, size);
break;
}
case LOTUS_COLW4: CHECK_RECORD_SIZE (>= 4) {
Sheet *sheet = lotus_get_sheet (state->wb, r->data[0]);
int i, n = (r->len - 4) / 2;
for (i = 0; i < n; i++) {
guint8 col = r->data[4 + 2 * i];
guint8 chars = r->data[5 + 2 * i];
gboolean value_set = TRUE;
// Very approximate
double size = lotus_twips_to_points (chars * (20
* 72 / 11));
sheet_col_set_size_pts (sheet, col, size, value_s
et);
}
break;
}
case LOTUS_FORMAT: CHECK_RECORD_SIZE (>= 2) { case LOTUS_FORMAT: CHECK_RECORD_SIZE (>= 2) {
Sheet *sheet = lotus_get_sheet (state->wb, r->data[0]); Sheet *sheet = lotus_get_sheet (state->wb, r->data[0]);
guint8 subtype = GSF_LE_GET_GUINT8 (r->data + 1); guint8 subtype = GSF_LE_GET_GUINT8 (r->data + 1);
switch (subtype) { switch (subtype) {
case 0: CHECK_RECORD_SIZE (>= 4) { // FORMAT case 0: CHECK_RECORD_SIZE (>= 4) { // FORMAT
int row = GSF_LE_GET_GUINT16 (r->data + 2); int row = GSF_LE_GET_GUINT16 (r->data + 2);
int col = 0, o; int col = 0, o;
for (o = 4; o + 4 <= r->len; o += 4) { for (o = 4; o + 4 <= r->len; o += 4) {
guint32 frmt = GSF_LE_GET_GUINT32 (r->dat a + o); guint32 frmt = GSF_LE_GET_GUINT32 (r->dat a + o);
gboolean rep = (frmt & 0x80000000u) && (o + 4 < r->len); gboolean rep = (frmt & 0x80000000u) && (o + 4 < r->len);
skipping to change at line 2184 skipping to change at line 2238
gnm_style_dump (style); gnm_style_dump (style);
#endif #endif
g_hash_table_insert (state->style_pool, g_hash_table_insert (state->style_pool,
GUINT_TO_POINTER ((guint)sty leid), GUINT_TO_POINTER ((guint)sty leid),
style); style);
g_free (fontname); g_free (fontname);
break; break;
} }
case 0x36b0: CHECK_RECORD_SIZE (> 5) {
// Sheet name
guint8 sheetno = GSF_LE_GET_GUINT8 (r->data + 2);
char *name = g_strndup (r->data + 4, r->len - 5);
Sheet *sheet = lotus_get_sheet (state->wb, sheetn
o);
g_object_set (sheet, "name", name, NULL);
g_free (name);
break;
}
default: default:
g_printerr ("Unknown style record 0x%x/%04x of le ngth %d.\n", g_printerr ("Unknown style record 0x%x/%04x of le ngth %d.\n",
r->type, subtype, r->type, subtype,
r->len); r->len);
case 0xfab: /* Edge style */ case 0x07d7: // Row height
case 0xfb4: /* Interior style */ case 0x0fab: // Edge style
case 0xfc9: /* Frame style */ case 0x0fb4: // Interior style
case 0xfe6: /* Named style */ case 0x0fc9: // Frame style
case 0xffa: /* Style pool */ case 0x0fe6: // Background style
case 0x0ff0: // Text style
case 0x0ffa: // Style pool
case 0x32e7: // Named style
break; break;
} }
break; break;
} }
case LOTUS_PACKED_NUMBER: CHECK_RECORD_SIZE (== 8) { case LOTUS_PACKED_NUMBER: CHECK_RECORD_SIZE (== 8) {
int row = GSF_LE_GET_GUINT16 (r->data); int row = GSF_LE_GET_GUINT16 (r->data);
Sheet *sheet = lotus_get_sheet (state->wb, r->data[2]); Sheet *sheet = lotus_get_sheet (state->wb, r->data[2]);
int col = r->data[3]; int col = r->data[3];
GnmValue *val = lotus_unpack_number (GSF_LE_GET_GUINT32 ( r->data + 4)); GnmValue *val = lotus_unpack_number (GSF_LE_GET_GUINT32 ( r->data + 4));
skipping to change at line 2277 skipping to change at line 2344
cell = lotus_cell_fetch (state, sheet, col, row); cell = lotus_cell_fetch (state, sheet, col, row);
if (cell) if (cell)
gnm_cell_set_expr_and_value (cell, texpr, curval, TRUE); gnm_cell_set_expr_and_value (cell, texpr, curval, TRUE);
else else
value_release (curval); value_release (curval);
gnm_expr_top_unref (texpr); gnm_expr_top_unref (texpr);
break; break;
} }
case LOTUS_FORMULASTRING: CHECK_RECORD_SIZE (>= 5) {
int row = GSF_LE_GET_GUINT16 (r->data);
Sheet *sheet = lotus_get_sheet (state->wb, r->data[2]);
int col = r->data[3];
char *s = g_strndup (r->data + 4, r->len - 5);
GnmCell *cell = lotus_cell_fetch (state, sheet, col, row)
;
gnm_cell_assign_value (cell, value_new_string_nocopy (s))
;
break;
}
case LOTUS_CA_DB: case LOTUS_CA_DB:
case LOTUS_DEFAULTS_DB: case LOTUS_DEFAULTS_DB:
case LOTUS_NAMED_STYLE_DB: case LOTUS_NAMED_STYLE_DB:
break; break;
case LOTUS_RLDB_PACKINFO: CHECK_RECORD_SIZE (>= 4 + rllsize) { case LOTUS_RLDB_PACKINFO: CHECK_RECORD_SIZE (>= 4 + rllsize) {
int ndims = GSF_LE_GET_GUINT16 (r->data + 2); int ndims = GSF_LE_GET_GUINT16 (r->data + 2);
int *dims, i; int *dims, i;
if (rldb) { if (rldb) {
 End of changes. 9 change blocks. 
7 lines changed or deleted 91 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)