2 * GNU Oleo input filter for Gnumeric
5 * Robert Brady <rwb197@ecs.soton.ac.uk>
7 * partially based on the Lotus-123 code,
8 * partially based on actual Oleo code.
10 #include <gnumeric-config.h>
11 #include <glib/gi18n-lib.h>
19 #include <parse-util.h>
21 #include <sheet-style.h>
24 #include <number-match.h>
27 #include <gsf/gsf-input-textline.h>
36 GnmConventions
*convs
;
39 GsfInputTextline
*textline
;
44 append_zeros (GString
*s
, int n
)
47 size_t oldlen
= s
->len
;
48 g_string_set_size (s
, oldlen
+ n
);
49 memset (s
->str
+oldlen
, '0', n
);
53 /* adapted from Oleo */
60 res
= strtol (*ptr
, &end
, 10);
68 oleo_set_style (OleoReader
*state
, GnmStyle
*style
)
70 /* sheet_style_set_range absorbs our reference */
71 gnm_style_ref (style
);
72 sheet_style_set_pos (state
->pp
.sheet
,
73 state
->pp
.eval
.col
, state
->pp
.eval
.row
, style
);
76 static GnmExprTop
const *
77 oleo_parse_formula (OleoReader
*state
, char const *expr_str
)
80 GnmExprTop
const *texpr
= gnm_expr_parse_str (expr_str
,
81 &state
->pp
, GNM_EXPR_PARSE_DEFAULT
,
82 state
->convs
, parse_error_init (&error
));
84 if (error
.err
!= NULL
) {
85 g_warning ("%s \"%s\" at %s!%s.", error
.err
->message
, expr_str
,
86 state
->pp
.sheet
->name_unquoted
,
87 cell_coord_name (state
->pp
.eval
.col
, state
->pp
.eval
.row
));
89 parse_error_free (&error
);
95 oleo_parse_cell (OleoReader
*state
, guint8
*str
, GnmStyle
*style
)
98 GnmExprTop
const *texpr
= NULL
;
99 char *ptr
= str
+ 1, *cval
= NULL
, *formula
= NULL
;
105 g_warning ("ptr: %s.", ptr
);
111 case 'c' : state
->pp
.eval
.col
= astol (&ptr
) - 1; break;
112 case 'r' : state
->pp
.eval
.row
= astol (&ptr
) - 1; break;
116 while (*ptr
&& (*ptr
!= ';' || quotes
> 0))
123 while (*ptr
&& *ptr
!= ';')
129 g_warning ("oleo: Don't know how to deal with C; '%c'.",
132 ptr
= (char *)""; /* I wish C had multilevel break */
140 cell
= sheet_cell_fetch (state
->pp
.sheet
,
141 state
->pp
.eval
.col
, state
->pp
.eval
.row
);
144 texpr
= oleo_parse_formula (state
, formula
);
147 GnmValue
*val
= format_match_simple (cval
);
150 char *last
= cval
+ strlen (cval
) - 1;
151 if (*cval
== '"' && *last
== '"') {
153 val
= value_new_string (cval
+ 1);
155 val
= value_new_string (cval
);
159 gnm_cell_set_expr_and_value (cell
, texpr
, val
, TRUE
);
161 gnm_cell_set_value (cell
, val
);
164 oleo_set_style (state
, style
);
168 g_warning ("oleo: cval is NULL.");
170 /* We can still store the expression, even if the value is missing */
172 gnm_cell_set_expr (cell
, texpr
);
175 gnm_expr_top_unref (texpr
);
178 /* NOTE : We don't care too much about formatting as such, but we need to
179 * parse the command as it may update current row/column */
181 oleo_parse_style (OleoReader
*state
, guint8
*str
, GnmStyle
**res
)
184 GnmStyle
*style
= gnm_style_new_default ();
185 GString
*fmt_string
= g_string_new (NULL
);
191 case 'c' : state
->pp
.eval
.col
= astol (&ptr
) - 1; break;
192 case 'r' : state
->pp
.eval
.row
= astol (&ptr
) - 1; break;
196 g_string_truncate (fmt_string
, 0);
197 g_string_append_c (fmt_string
, '0');
198 if (g_ascii_isdigit (*ptr
))
199 append_zeros (fmt_string
, astol (&ptr
));
204 g_string_append_c (fmt_string
, '%');
206 default: /* Unknown format type... */
207 g_string_truncate (fmt_string
, 0);
211 gnm_style_set_align_h (style
, GNM_HALIGN_LEFT
);
214 gnm_style_set_align_h (style
, GNM_HALIGN_RIGHT
);
218 gnm_style_set_format_text (style
, fmt_string
->str
);
219 g_string_free (fmt_string
, TRUE
);
222 gnm_style_unref (*res
);
227 oleo_new_sheet (Workbook
*wb
, int idx
)
229 char *sheet_name
= g_strdup_printf (_("Sheet%d"), idx
);
230 Sheet
*sheet
= sheet_new (wb
, sheet_name
, 256, 65536);
232 workbook_sheet_attach (wb
, sheet
);
234 /* Ensure that things get rendered and spanned */
235 sheet_flag_recompute_spans (sheet
);
239 static GnmConventions
*
240 oleo_conventions_new (void)
242 GnmConventions
*convs
= gnm_conventions_new ();
244 convs
->decimal_sep_dot
= TRUE
;
245 convs
->intersection_char
= 0;
246 convs
->r1c1_addresses
= TRUE
;
252 oleo_read (GOIOContext
*io_context
, Workbook
*wb
, GsfInput
*input
)
255 GnmStyle
*style
= NULL
;
259 state
.convs
= oleo_conventions_new ();
260 parse_pos_init (&state
.pp
,
261 wb
, oleo_new_sheet (wb
, ++sheetidx
), 0, 0);
263 /* Does this need to come from the import dialog ? */
264 state
.converter
= g_iconv_open ("UTF-8", "ISO-8859-1");
265 state
.textline
= (GsfInputTextline
*) gsf_input_textline_new (input
);
267 while (NULL
!= (line
= gsf_input_textline_ascii_gets (state
.textline
))) {
269 g_convert_with_iconv (line
, -1, state
.converter
, NULL
, NULL
, NULL
);
271 switch (utf8line
[0]) {
272 case '#': /* Comment */
275 case 'C': oleo_parse_cell (&state
, utf8line
, style
);
278 case 'F': oleo_parse_style (&state
, utf8line
, &style
);
281 default: /* unknown */
283 g_warning ("oleo: Don't know how to deal with %c.",
293 gnm_style_unref (style
);
295 g_iconv_close (state
.converter
);
296 gnm_conventions_unref (state
.convs
);
297 g_object_unref (state
.textline
);