Exemplo n.º 1
0
Arquivo: dif.c Projeto: GNOME/gnumeric
/*
 * Raturns FALSE on EOF.
 */
static gboolean
dif_parse_data (DifInputContext *ctxt)
{
	gboolean too_many_rows = FALSE, too_many_columns = FALSE;
	gint row = -1, col = 0;
	gint val_type;
	GnmCell *cell;
	gchar *msg;

	while (1) {
		if (!dif_get_line (ctxt))
			return FALSE;

		val_type = atoi (ctxt->line);
		if (val_type == 0) {
			gchar const *comma = strchr (ctxt->line, ',');
			if (comma == NULL)
				go_io_warning (ctxt->io_context,
						_("Syntax error at line %d. Ignoring."),
						ctxt->line_no);
			else if (col > gnm_sheet_get_max_cols (ctxt->sheet)) {
				too_many_columns = TRUE;
				break;
			} else {
				gnm_float num = gnm_strto (comma+1, NULL);
				GnmValue *v = NULL;

				if (!dif_get_line (ctxt))
					return FALSE;

				if (0 == strcmp (ctxt->line, "V")) {		/* V       value */
					v = value_new_float (num);
				} else if (0 == strcmp (ctxt->line, "NA")) {	/* NA      not available res must be O */
					v = value_new_error_NA (NULL);
				} else if (0 == strcmp (ctxt->line, "TRUE")) {	/* TRUE    bool T	 res must be 1 */
					v = value_new_bool (TRUE);
				} else if (0 == strcmp (ctxt->line, "FALSE")) {	/* FALSE   bool F	 res must be O */
					v = value_new_bool (TRUE);
				} else if (0 == strcmp (ctxt->line, "ERROR")) {	/* ERROR   err		 res must be O */
					go_io_warning (ctxt->io_context,
							_("Unknown value type '%s' at line %d. Ignoring."),
							ctxt->line, ctxt->line_no);
				}

				if (NULL != v) {
					cell = sheet_cell_fetch (ctxt->sheet, col, row);
					gnm_cell_set_value (cell, v);
				}
				col++;
			}
		} else if (val_type == 1) {
			if (!dif_get_line (ctxt))
				return FALSE;
			if (col > gnm_sheet_get_max_cols (ctxt->sheet)) {
				too_many_columns = TRUE;
				continue;
			}
			cell = sheet_cell_fetch (ctxt->sheet, col, row);
			if (ctxt->line_len >= 2 &&
			    ctxt->line[0] == '"' && ctxt->line[ctxt->line_len - 1] == '"') {
				ctxt->line[ctxt->line_len - 1] = '\0';
				gnm_cell_set_text (cell, ctxt->line + 1);
			} else
				gnm_cell_set_text (cell, ctxt->line);
			col++;
		} else if (val_type == -1) {
			if (!dif_get_line (ctxt))
				return FALSE;
			if (strcmp (ctxt->line, "BOT") == 0) {
				col = 0;
				row++;
				if (row > gnm_sheet_get_max_rows (ctxt->sheet)) {
					too_many_rows = TRUE;
					break;
				}
			} else if (strcmp (ctxt->line, "EOD") == 0) {
				break;
			} else {
				msg = g_strdup_printf (
				      _("Unknown data value \"%s\" at line %d. Ignoring."),
				      ctxt->line, ctxt->line_no);
				g_warning ("%s", msg);
				g_free (msg);
			}
		} else {
			msg = g_strdup_printf (
			      _("Unknown value type %d at line %d. Ignoring."),
			      val_type, ctxt->line_no);
			g_warning ("%s", msg);
			g_free (msg);
			(void) dif_get_line (ctxt);
		}
	}

	if (too_many_rows) {
		g_warning (_("DIF file has more than the maximum number of rows %d. "
		             "Ignoring remaining rows."), gnm_sheet_get_max_rows (ctxt->sheet));
	}
	if (too_many_columns) {
		g_warning (_("DIF file has more than the maximum number of columns %d. "
		             "Ignoring remaining columns."), gnm_sheet_get_max_cols (ctxt->sheet));
	}

	return TRUE;
}
Exemplo n.º 2
0
G_MODULE_EXPORT void
paradox_file_open (GOFileOpener const *fo, GOIOContext *io_context,
                   WorkbookView *wb_view, GsfInput *input)
{
	Workbook  *wb;
	pxdoc_t	  *pxdoc;
	pxhead_t	*pxh;
	pxfield_t	*pxf;
	char	*data;
	char	  *name;
	Sheet	  *sheet;
	GnmCell	  *cell;
	GnmValue	  *val = NULL;
	GOErrorInfo *open_error = NULL;
	guint row, i, j, offset;

#ifdef PX_MEMORY_DEBUGGING
	PX_mp_init ();
#endif

#ifdef PX_MEMORY_DEBUGGING
	pxdoc = PX_new2 (gn_errorhandler, PX_mp_malloc, PX_mp_realloc, PX_mp_free);
#else
	pxdoc = PX_new2 (gn_errorhandler, gn_malloc, gn_realloc, gn_free);
#endif
	if (PX_open_gsf (pxdoc, input) < 0) {
		go_io_error_info_set (io_context, go_error_info_new_str_with_details (
					    _("Error while opening Paradox file."),
					    open_error));
		return;
	}
	pxh = pxdoc->px_head;

	PX_set_targetencoding (pxdoc, "UTF-8");

	wb = wb_view_get_workbook (wb_view);
	name = workbook_sheet_get_free_name (wb, pxh->px_tablename, FALSE, TRUE);
	sheet = sheet_new (wb, name, 256, 65536);
	g_free (name);
	workbook_sheet_attach (wb, sheet);

	pxf = pxh->px_fields;
	for (i = 0 ; i < (guint) pxh->px_numfields; i++) {
		char str[30], *str2;
		char ctypes[26] = {'?',
				   'A', 'D', 'S', 'I', '$', 'N', '?', '?',
				   'L', '?', '?', 'M', 'B', 'F', 'O', 'G',
				   '?', '?', '?', 'T', '@', '+', '#', 'Y',
				   };
		cell = sheet_cell_fetch (sheet, i, 0);
		if (pxf->px_ftype == pxfBCD)
			snprintf (str, 30, "%s,%c,%d", pxf->px_fname, ctypes[(int)pxf->px_ftype], pxf->px_fdc);
		else
			snprintf (str, 30, "%s,%c,%d", pxf->px_fname, ctypes[(int)pxf->px_ftype], pxf->px_flen);
#if PXLIB_MAJOR_VERSION == 0 && (PXLIB_MINOR_VERION < 3 || (PXLIB_MAJOR_VERSION == 3 && PXLIB_MICRO_VERSION == 0))
		/* Convert the field names to utf-8. This is actually in pxlib
		 * responsibility, but hasn't been implemented yet. For the mean time
		 * we *misuse* PX_get_data_alpha()
		 */
		PX_get_data_alpha (pxdoc, str, strlen (str), &str2);
		gnm_cell_set_text (cell, str2);
		pxdoc->free (pxdoc, str2);
#else
		gnm_cell_set_text (cell, str);
#endif
		pxf++;
	}
	{
		GnmRange r;
		GnmStyle *bold = gnm_style_new ();
		gnm_style_set_font_bold (bold, TRUE);
		sheet_style_apply_range	(sheet,
			range_init (&r, 0, 0, pxh->px_numfields-1, 0), bold);
	}

	if ((data = (char *) pxdoc->malloc (pxdoc, pxh->px_recordsize, _("Could not allocate memory for record."))) == NULL) {
		go_io_error_info_set (io_context, go_error_info_new_str_with_details (
					    _("Error while opening Paradox file."),
					    open_error));
		return;
	}
	row = 1;
	for (j = 0; j < (guint)pxh->px_numrecords; j++) {
		pxdatablockinfo_t pxdbinfo;
		int isdeleted = 0;
		if (NULL != PX_get_record2 (pxdoc, j, data, &isdeleted, &pxdbinfo)) {
			offset = 0;
			pxf = pxh->px_fields;
			for (i = 0; i < (guint) pxh->px_numfields ; i++) {
				cell = sheet_cell_fetch (sheet, i, row);
				val = NULL;
				switch (pxf->px_ftype) {
				case pxfAlpha: {
					char *value;
					if (0 < PX_get_data_alpha (pxdoc, &data[offset], pxf->px_flen, &value)) {
						val = value_new_string_nocopy (value);
/*							value_set_fmt (val, field->fmt); */
					}
					break;
				}
				case pxfShort: {
					short int value;
					if (0 < PX_get_data_short (pxdoc, &data[offset], pxf->px_flen, &value)) {
						val = value_new_int (value);
					}
					break;
				}
				case pxfAutoInc:
				case pxfLong: {
					long value;
					if (0 < PX_get_data_long (pxdoc, &data[offset], pxf->px_flen, &value)) {
						val = value_new_int (value);
					}
					break;
				}
				case pxfCurrency:
				case pxfNumber: {
					double value;
					if (0 < PX_get_data_double (pxdoc, &data[offset], pxf->px_flen, &value)) {
						val = value_new_float (value);
						if (pxf->px_ftype == pxfCurrency)
							value_set_fmt (val, go_format_default_money ());
					}
					break;
				}
				case pxfTimestamp: {
					double value;
					if (0 < PX_get_data_double (pxdoc, &data[offset], pxf->px_flen, &value)) {
						value = value / 86400000.0;
						/* 693594 = number of days up to 31.12.1899 */
						value -= 693594;
						val = value_new_float (value);
						value_set_fmt (val, go_format_default_date_time ());
					}
					break;
				}
				case  pxfLogical: {
					char value;
					if (0 < PX_get_data_byte (pxdoc, &data[offset], pxf->px_flen, &value)) {
						val = value_new_bool (value ? TRUE : FALSE);
					}
					break;
				}
				case pxfDate: {
					long value;
					int year, month, day;
					GDate *date;
					if (0 < PX_get_data_long (pxdoc, &data[offset], pxf->px_flen, &value)) {
						PX_SdnToGregorian (value+1721425, &year, &month, &day);
						date = g_date_new_dmy (day, month, year);
						val = value_new_int (go_date_g_to_serial (date, NULL));
						value_set_fmt (val, go_format_default_date ());
						g_date_free (date);
					}
					break;
				}
				case pxfTime: {
					long value;
					if (0 < PX_get_data_long (pxdoc, &data[offset], pxf->px_flen, &value)) {
						val = value_new_float (value/86400000.0);
						value_set_fmt (val, go_format_default_time ());
					}
					break;
				}
				case pxfBCD: {
					char *value;
					if (0 < PX_get_data_bcd (pxdoc, &data[offset], pxf->px_fdc, &value)) {
						val = value_new_string_nocopy (value);
					}
					break;
				}
				case pxfMemoBLOb: {
					char *value;
					int size, mod_nr;
					if (0 < PX_get_data_blob (pxdoc, &data[offset], pxf->px_flen, &mod_nr, &size, &value)) {
						val = value_new_string_nocopy (value);
					}
					break;
				}
				default:
					val = value_new_string_nocopy (
						g_strdup_printf (_("Field type %d is not supported."), pxf->px_ftype));
				}
				if (val)
					gnm_cell_set_value (cell, val);
				offset += pxf->px_flen;
				pxf++;
			}
			if (pxh->px_filetype == pxfFileTypPrimIndex) {
				short int value;
				cell = sheet_cell_fetch (sheet, i++, row);
				if (0 < PX_get_data_short (pxdoc, &data[offset], 2, &value)) {
					val = value_new_int (value);
					gnm_cell_set_value (cell, val);
				}
				offset += 2;
				cell = sheet_cell_fetch (sheet, i++, row);
				if (0 < PX_get_data_short (pxdoc, &data[offset], 2, &value)) {
					val = value_new_int (value);
					gnm_cell_set_value (cell, val);
				}
				offset += 2;
				cell = sheet_cell_fetch (sheet, i++, row);
				if (0 < PX_get_data_short (pxdoc, &data[offset], 2, &value)) {
					val = value_new_int (value);
					gnm_cell_set_value (cell, val);
				}
				cell = sheet_cell_fetch (sheet, i++, row);
				val = value_new_int (pxdbinfo.number);
				gnm_cell_set_value (cell, val);
			}
		}
		row++;
	}
	pxdoc->free (pxdoc, data);

	PX_close (pxdoc);
	PX_delete (pxdoc);

	sheet_flag_recompute_spans (sheet);
}
Exemplo n.º 3
0
static void
html_read_row (htmlNodePtr cur, htmlDocPtr doc, GnmHtmlTableCtxt *tc)
{
	htmlNodePtr ptr;
	int col = -1;

	for (ptr = cur->children; ptr != NULL ; ptr = ptr->next) {
		if (xmlStrEqual (ptr->name, CC2XML ("td")) ||
		    xmlStrEqual (ptr->name, CC2XML ("th"))) {
			GString *buf;
			xmlBufferPtr a_buf;
			xmlAttrPtr   props;
			int colspan = 1;
			int rowspan = 1;
			GnmCellPos pos;
			GnmStyle *mstyle;
			GSList *hrefs = NULL;
			GnmHLink *lnk = NULL;

			/* Check whether we need to skip merges from above */
			pos.row = tc->row;
			pos.col = col + 1;
			while (gnm_sheet_merge_contains_pos (tc->sheet, &pos)) {
				col++;
				pos.col++;
			}

			/* Do we span across multiple rows or cols? */
			props = ptr->properties;
			while (props) {
				if (xmlStrEqual (props->name, CC2XML ("colspan")) && props->children)
				    colspan = atoi (CXML2C (props->children->content));
				if (xmlStrEqual (props->name, CC2XML ("rowspan")) && props->children)
				    rowspan = atoi (CXML2C (props->children->content));
				props = props->next;
			}
			if (colspan < 1)
				colspan = 1;
			if (rowspan < 1)
				rowspan = 1;

			/* Let's figure out the content of the cell */
			buf = g_string_new (NULL);
			a_buf = xmlBufferCreate ();

			mstyle = gnm_style_new_default ();
			if (xmlStrEqual (ptr->name, CC2XML ("th")))
				gnm_style_set_font_bold (mstyle, TRUE);

			html_read_content (ptr, buf, mstyle, a_buf,
					   &hrefs, TRUE, doc, tc);


			if (g_slist_length (hrefs) >= 1 &&
			    buf->len > 0) {
				/* One hyperlink, and text to make it
				 * visible */
				char *url;
				xmlBufferPtr h_buf = xmlBufferCreate ();

				hrefs = g_slist_reverse (hrefs);
				htmlNodeDump (
					h_buf, doc, (htmlNodePtr)hrefs->data);
				url = g_strndup (
					CXML2C (h_buf->content), h_buf->use);
				if (strncmp (url, "mailto:",
					     strlen ("mailto:")) == 0)
					lnk = gnm_hlink_new (
						gnm_hlink_email_get_type (),
						tc->sheet);
				else
					lnk = gnm_hlink_new (
						gnm_hlink_url_get_type (),
						tc->sheet);
				gnm_hlink_set_target (lnk, url);
				gnm_style_set_hlink (mstyle, lnk);
				gnm_style_set_font_uline (mstyle,
							  UNDERLINE_SINGLE);
				gnm_style_set_font_color (mstyle,
							  gnm_color_new_go (GO_COLOR_BLUE));
				g_free (url);
				xmlBufferFree (h_buf);
			}
			if (g_slist_length (hrefs) > 1 || buf->len <= 0) {
				/* Multiple links,
				 * or no text to give hyperlink style,
				 * so put them in a comment */
				GSList *l;

				for (l = hrefs; l != NULL; l = l->next) {
					htmlNodeDump (a_buf, doc,
						      (htmlNodePtr)l->data);
					xmlBufferAdd (a_buf, CC2XML ("\n"),
						      -1);
				}
			}
			g_slist_free (hrefs);
			if (buf->len > 0) {
				GnmCell *cell = sheet_cell_fetch (tc->sheet, col + 1, tc->row);
				sheet_style_set_pos (tc->sheet, col + 1, tc->row, mstyle);
				gnm_cell_set_text (cell, buf->str);
			} else
				gnm_style_unref (mstyle);

			if (a_buf->use > 0) {
				char *name;

				name = g_strndup (CXML2C (a_buf->content), a_buf->use);
				cell_set_comment (tc->sheet, &pos, NULL, name, NULL);
				g_free (name);
			}
			g_string_free (buf, TRUE);
			xmlBufferFree (a_buf);

			/* If necessary create the merge */
			if (colspan > 1 || rowspan > 1) {
				GnmRange range;
				GnmRange *r = &range;

				range_init (r, col + 1, tc->row, col + colspan, tc->row + rowspan - 1);
				gnm_sheet_merge_add (tc->sheet, r, FALSE, NULL);
			}

			col += colspan;
		}
	}
}