#include "data/data-in.h"
+#include "gl/c-strtod.h"
#include "gl/minmax.h"
#include "gettext.h"
int target_sheet_index;
- int wanted_row_start;
- int wanted_col_start;
-
-#if 0
int start_row;
int start_col;
int stop_row;
int stop_col;
-#endif
int col_span;
const char *
ods_get_sheet_name (struct spreadsheet *s, int n)
{
- int ret;
struct ods_reader *or = (struct ods_reader *) s;
assert (n < s->n_sheets);
while (
- (or->n_allocated_sheets <= n)
- &&
- (1 == (ret = xmlTextReaderRead (or->xtr)))
+ (or->n_allocated_sheets <= n)
+ || or->state != STATE_SPREADSHEET
)
{
+ int ret = xmlTextReaderRead (or->xtr);
+ if ( ret != 1)
+ break;
+
process_node (or);
}
char *
ods_get_sheet_range (struct spreadsheet *s, int n)
{
- int ret = -1;
struct ods_reader *or = (struct ods_reader *) s;
assert (n < s->n_sheets);
while (
- (
(or->n_allocated_sheets <= n)
- || (or->sheets[n].stop_row == -1) )
- &&
- (1 == (ret = xmlTextReaderRead (or->xtr)))
+ || (or->sheets[n].stop_row == -1)
+ || or->state != STATE_SPREADSHEET
)
{
+ int ret = xmlTextReaderRead (or->xtr);
+ if ( ret != 1)
+ break;
+
process_node (or);
}
-
return create_cell_ref (
or->sheets[n].start_col,
or->sheets[n].start_row,
if (r->current_sheet >= r->n_allocated_sheets)
{
+ assert (r->current_sheet == r->n_allocated_sheets);
r->sheets = xrealloc (r->sheets, sizeof (*r->sheets) * ++r->n_allocated_sheets);
r->sheets[r->n_allocated_sheets - 1].start_col = -1;
r->sheets[r->n_allocated_sheets - 1].stop_col = -1;
r->sheets[r->n_allocated_sheets - 1].start_row = -1;
r->sheets[r->n_allocated_sheets - 1].stop_row = -1;
- r->sheets[r->n_allocated_sheets - 1].name = xmlStrdup (r->current_sheet_name);
+ r->sheets[r->n_allocated_sheets - 1].name = CHAR_CAST (char *, xmlStrdup (r->current_sheet_name));
}
r->col = 0;
}
break;
case STATE_ROW:
- // printf ("%s:%d Name is %s\n", __FILE__, __LINE__, name);
if ( (0 == xmlStrcasecmp (name, _xml ("table:table-cell")))
&&
(XML_READER_TYPE_ELEMENT == r->node_type))
r->col_span = value ? _xmlchar_to_int (value) : 1;
r->col += r->col_span;
- // printf ("%s:%d %s\n", __FILE__, __LINE__, value);
-
if (! xmlTextReaderIsEmptyElement (r->xtr))
r->state = STATE_CELL;
+
+ xmlFree (value);
}
else if ( (0 == xmlStrcasecmp (name, _xml ("table:table-row")))
&&
value_copy_str_rpad (v, var_get_width (var), xmv->text, ' ');
else
{
- const char *text ;
const struct fmt_spec *fmt = var_get_write_format (var);
enum fmt_category fc = fmt_get_category (fmt->type);
assert ( fc != FMT_CAT_STRING);
- text =
- xmv->value ? CHAR_CAST (const char *, xmv->value) : CHAR_CAST (const char *, xmv->text);
+ if ( 0 == xmlStrcmp (xmv->type, _xml("float")))
+ {
+ v->f = c_strtod (CHAR_CAST (const char *, xmv->value), NULL);
+ }
+ else
+ {
+ const char *text = xmv->value ?
+ CHAR_CAST (const char *, xmv->value) : CHAR_CAST (const char *, xmv->text);
+
- free (data_in (ss_cstr (text), "UTF-8",
- fmt->type,
- v,
- var_get_width (var),
- "UTF-8"));
+ free (data_in (ss_cstr (text), "UTF-8",
+ fmt->type,
+ v,
+ var_get_width (var),
+ "UTF-8"));
+ }
}
}
if ( 0 == xmlStrcmp (name, _xml("meta:document-statistic")))
{
xmlChar *attr = xmlTextReaderGetAttribute (mxtr, _xml ("meta:table-count"));
-
+
if ( attr != NULL)
{
int s = _xmlchar_to_int (attr);
+ xmlFreeTextReader (mxtr);
+ xmlFree (name);
+ xmlFree (attr);
return s;
}
+ xmlFree (attr);
}
+ xmlFree (name);
}
+
+ xmlFreeTextReader (mxtr);
return -1;
}
r->xtr = xtr;
r->spreadsheet.type = SPREADSHEET_ODS;
+ r->row = 0;
+ r->col = 0;
+ r->current_sheet = 0;
+ r->state = STATE_INIT;
if (report_errors)
xmlTextReaderSetErrorHandler (xtr, ods_error_handler, r);
if ( !init_reader (r, true))
goto error;
-#if 0
if ( opts->cell_range )
{
if ( ! convert_cell_ref (opts->cell_range,
r->stop_col = -1;
r->stop_row = -1;
}
-#endif
r->state = STATE_INIT;
r->target_sheet_name = BAD_CAST opts->sheet_name;
r->target_sheet_index = opts->sheet_index;
r->row = r->col = 0;
+
#if 0
- /* If CELLRANGE was given, then we know how many variables should be read */
- if ( r->stop_col != -1 )
- {
- assert (var_spec == NULL);
- n_var_specs = r->stop_col - r->start_col + 1;
- var_spec = xrealloc (var_spec, sizeof (*var_spec) * n_var_specs);
- memset (var_spec, '\0', sizeof (*var_spec) * n_var_specs);
- }
+ printf ("%s:%d %d,%d %d,%d\n", __FILE__, __LINE__,
+ r->start_col,
+ r->start_row,
+ r->stop_col,
+ r->stop_row);
#endif
+
/* Advance to the start of the cells for the target sheet */
- while ( ! reading_target_sheet (r) || r->state != STATE_ROW )
+ while ( ! reading_target_sheet (r)
+ || r->state != STATE_ROW || r->row <= r->start_row )
{
if (1 != (ret = xmlTextReaderRead (r->xtr)))
break;
process_node (r);
}
-
if (ret < 1)
{
msg (MW, _("Selected sheet or range of spreadsheet `%s' is empty."),
process_node (r);
/* If the row is finished then stop for now */
- if (r->state == STATE_TABLE && r->row > r->wanted_row_start)
+ if (r->state == STATE_TABLE && r->row > r->start_row)
break;
- idx = r->col - r->wanted_col_start - 1;
+ idx = r->col - r->start_col -1 ;
+
+ if ( idx < 0)
+ continue;
+
+ if (r->stop_col != -1 && idx > r->stop_col - r->start_col)
+ continue;
if (r->state == STATE_CELL_CONTENT
&&
/* xrealloc (unlike realloc) doesn't initialise its memory to 0 */
memset (var_spec + n_var_specs,
0,
- (n_var_specs - idx + 1) * sizeof (*var_spec));
+ (idx - n_var_specs + 1) * sizeof (*var_spec));
n_var_specs = idx + 1;
}
var_spec[idx].firstval.text = 0;
var_spec[idx].firstval.type = 0;
var_spec [idx].name = strdup (CHAR_CAST (const char *, value));
+
xmlFree (value);
}
}
int idx;
process_node (r);
+ if ( ! reading_target_sheet (r) )
+ break;
+
/* If the row is finished then stop for now */
- if (r->state == STATE_TABLE && r->row > r->wanted_row_start + (opts->read_names ? 1 : 0))
+ if (r->state == STATE_TABLE &&
+ r->row > r->start_row + (opts->read_names ? 1 : 0))
break;
- idx = r->col - r->wanted_col_start - 1;
+ idx = r->col - r->start_col - 1;
+ if (idx < 0)
+ continue;
+
+ if (r->stop_col != -1 && idx > r->stop_col - r->start_col)
+ continue;
if ( r->state == STATE_CELL &&
XML_READER_TYPE_ELEMENT == r->node_type)
if ( r->state == STATE_CELL_CONTENT &&
XML_READER_TYPE_TEXT == r->node_type)
{
- if ( idx >= n_var_specs)
+#if 0
+ printf ("%s:%d Idx %d n_var_specs %d\n", __FILE__, __LINE__,
+ idx, n_var_specs);
+
+ printf ("%s:%d Idx %d r_col %d\n", __FILE__, __LINE__,
+ idx, r->col);
+#endif
+
+ if (idx >= n_var_specs)
{
var_spec = xrealloc (var_spec, sizeof (*var_spec) * (idx + 1));
+ memset (var_spec + n_var_specs,
+ 0,
+ (idx - n_var_specs + 1) * sizeof (*var_spec));
+
var_spec [idx].name = NULL;
n_var_specs = idx + 1;
}
-
+
var_spec [idx].firstval.type = type;
var_spec [idx].firstval.text = xmlTextReaderValue (r->xtr);
var_spec [idx].firstval.value = val_string;
break;
}
- // zip_reader_destroy (zreader);
+ // zip_reader_destroy (zreader);
-#if 0
for ( i = 0 ; i < n_var_specs ; ++i )
{
free (var_spec[i].firstval.type);
}
free (var_spec);
-#endif
+
return casereader_create_sequential
(NULL,
error:
- // zip_reader_destroy (zreader);
+ //zip_reader_destroy (zreader);
for ( i = 0 ; i < n_var_specs ; ++i )
{
{
struct ccase *c = NULL;
xmlChar *val_string = NULL;
+ xmlChar *type = NULL;
struct ods_reader *r = r_;
- int current_row = r->row;
if (!r->used_first_case)
{
/* Advance to the start of a row. (If there is one) */
- while (r->state != STATE_ROW && 1 == xmlTextReaderRead (r->xtr))
+ while (r->state != STATE_ROW
+ && 1 == xmlTextReaderRead (r->xtr)
+ )
{
process_node (r);
}
- if ( ! reading_target_sheet (r) || r->state < STATE_TABLE)
+ if ( ! reading_target_sheet (r)
+ || r->state < STATE_TABLE
+ || (r->stop_row != -1 && r->row > r->stop_row + 1)
+ )
{
return NULL;
}
while (1 == xmlTextReaderRead (r->xtr))
{
process_node (r);
-#if 0
- if (r->row > current_row && r->state == STATE_ROW)
+
+ if ( r->stop_row != -1 && r->row > r->stop_row + 1)
break;
-#endif
- // printf ("%s:%d\n", __FILE__, __LINE__);
+
if (r->state == STATE_CELL &&
r->node_type == XML_READER_TYPE_ELEMENT)
{
+ type = xmlTextReaderGetAttribute (r->xtr, _xml ("office:value-type"));
val_string = xmlTextReaderGetAttribute (r->xtr, _xml ("office:value"));
}
int col;
struct xml_value *xmv = xzalloc (sizeof *xmv);
xmv->text = xmlTextReaderValue (r->xtr);
- xmv->value = val_string;
+ xmv->value = val_string;
+ xmv->type = type;
val_string = NULL;
for (col = 0; col < r->col_span; ++col)
{
- const int idx = r->col + col - r->wanted_col_start - 1;
- const struct variable *var = dict_get_var (r->dict, idx);
+ const struct variable *var;
+ const int idx = r->col + col - r->start_col - 1;
+ if (idx < 0)
+ continue;
+ if (r->stop_col != -1 && idx > r->stop_col - r->start_col )
+ break;
+
+ var = dict_get_var (r->dict, idx);
convert_xml_to_value (c, var, xmv);
}
- free (xmv->text);
- free (xmv->value);
+ xmlFree (xmv->text);
+ xmlFree (xmv->value);
+ xmlFree (xmv->type);
free (xmv);
}
if ( r->state <= STATE_TABLE)