gnumeric r16435 - trunk/plugins/paradox
- From: jody svn gnome org
- To: svn-commits-list gnome org
- Subject: gnumeric r16435 - trunk/plugins/paradox
- Date: Sun, 2 Mar 2008 14:51:55 +0000 (GMT)
Author: jody
Date: Sun Mar 2 14:51:55 2008
New Revision: 16435
URL: http://svn.gnome.org/viewvc/gnumeric?rev=16435&view=rev
Log:
Merge in ancient patch to support export.
Modified:
trunk/plugins/paradox/paradox.c
trunk/plugins/paradox/plugin.xml.in
trunk/plugins/paradox/px.h
Modified: trunk/plugins/paradox/paradox.c
==============================================================================
--- trunk/plugins/paradox/paradox.c (original)
+++ trunk/plugins/paradox/paradox.c Sun Mar 2 14:51:55 2008
@@ -8,50 +8,40 @@
#include <gnumeric-config.h>
#include <glib/gi18n-lib.h>
#include <gnumeric.h>
-#include <string.h>
#include "px.h"
#include <workbook-view.h>
#include <workbook.h>
#include <cell.h>
#include <value.h>
-#include <goffice/app/go-plugin.h>
#include <gnm-plugin.h>
#include <sheet.h>
#include <ranges.h>
#include <mstyle.h>
#include <sheet-style.h>
+
+#include <goffice/app/go-plugin.h>
#include <goffice/app/io-context.h>
#include <goffice/utils/datetime.h>
+#include <goffice/utils/go-format.h>
#include <goffice/app/error-info.h>
+#include <string.h>
+#include <unistd.h>
+
GNM_PLUGIN_MODULE_HEADER;
+#ifdef PX_MEMORY_DEBUGGING
+static void gn_errorhandler(pxdoc_t *p, int error, const char *str, void *data) { g_warning(str); }
+#else
+static void *gn_malloc (pxdoc_t *p, size_t len, const char *caller) { return((void *) g_malloc(len)); }
+static void *gn_realloc (pxdoc_t *p, void *mem, size_t len, const char *caller) { return((void *) g_realloc((gpointer) mem, len)); }
+static void gn_free (pxdoc_t *p, void *ptr) { g_free((gpointer) ptr); ptr = NULL; }
+#endif
+
void paradox_file_open (GOFileOpener const *fo, IOContext *io_context,
WorkbookView *wb_view, GsfInput *input);
-
-gboolean
-paradox_file_probe (GOFileOpener const *fo, GsfInput *input,
- FileProbeLevel pl);
-
-static void *gn_malloc(pxdoc_t *p, size_t len, const char *caller) {
- return((void *) g_malloc(len));
-}
-
-static void *gn_realloc(pxdoc_t *p, void *mem, size_t len, const char *caller) {
- return((void *) g_realloc((gpointer) mem, len));
-}
-
-static void gn_free(pxdoc_t *p, void *ptr) {
- g_free((gpointer) ptr);
- ptr = NULL;
-}
-
-static void gn_errorhandler(pxdoc_t *p, int error, const char *str, void *data) {
- g_warning(str);
-}
-
-void
+G_MODULE_EXPORT void
paradox_file_open (GOFileOpener const *fo, IOContext *io_context,
WorkbookView *wb_view, GsfInput *input)
{
@@ -67,17 +57,23 @@
ErrorInfo *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) {
gnumeric_io_error_info_set (io_context, error_info_new_str_with_details (
- _("Error while opening Paradox file."),
- open_error));
+ _("Error while opening Paradox file."),
+ open_error));
return;
}
pxh = pxdoc->px_head;
- fprintf(stderr, "Paradox %2.1f file, %d records, %d columns\n", pxh->px_fileversion/10.0, pxh->px_numrecords, pxh->px_numfields);
-
PX_set_targetencoding(pxdoc, "UTF-8");
wb = wb_view_get_workbook (wb_view);
@@ -90,20 +86,23 @@
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',
- };
+ 'A', 'D', 'S', 'I', '$', 'N', '?', '?',
+ 'L', '?', '?', 'M', 'B', 'F', 'O', 'G',
+ '?', '?', '?', 'T', '@', '+', '#', 'Y',
+ };
cell = sheet_cell_fetch (sheet, i, 0);
- snprintf (str, 30, "%s,%c,%d", pxf->px_fname, ctypes[(int)pxf->px_ftype], pxf->px_flen);
+ 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);
- fprintf(stderr, "%s\n", str2);
gnm_cell_set_text (cell, str2);
+ pxdoc->free(pxdoc, str2);
#else
gnm_cell_set_text (cell, str);
#endif
@@ -119,8 +118,8 @@
if((data = (char *) pxdoc->malloc(pxdoc, pxh->px_recordsize, _("Could not allocate memory for record."))) == NULL) {
gnumeric_io_error_info_set (io_context, error_info_new_str_with_details (
- _("Error while opening Paradox file."),
- open_error));
+ _("Error while opening Paradox file."),
+ open_error));
return;
}
row = 1;
@@ -162,6 +161,8 @@
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;
}
@@ -169,9 +170,10 @@
double value;
if(0 < PX_get_data_double(pxdoc, &data[offset], pxf->px_flen, &value)) {
value = value / 86400000.0;
- /* 693595 = number of days up to 31.12.1899 */
- value -= 693595;
+ /* 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;
}
@@ -190,6 +192,7 @@
PX_SdnToGregorian(value+1721425, &year, &month, &day);
date = g_date_new_dmy (day, month, year);
val = value_new_int (datetime_g_to_serial (date, NULL));
+ value_set_fmt (val, go_format_default_date());
g_date_free (date);
}
break;
@@ -198,6 +201,7 @@
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;
}
@@ -260,11 +264,17 @@
sheet_flag_recompute_spans (sheet);
}
+/*****************************************************************************/
+
gboolean
paradox_file_probe (GOFileOpener const *fo, GsfInput *input,
+ FileProbeLevel pl);
+
+G_MODULE_EXPORT gboolean
+paradox_file_probe (GOFileOpener const *fo, GsfInput *input,
FileProbeLevel pl)
{
- pxdoc_t *pxdoc;
+ pxdoc_t *pxdoc;
pxhead_t *pxh;
pxdoc = PX_new();
@@ -277,5 +287,332 @@
PX_close (pxdoc);
PX_delete (pxdoc);
+#ifdef PX_MEMORY_DEBUGGING
+ PX_mp_list_unfreed();
+#endif
+
return TRUE;
}
+
+/*****************************************************************************/
+
+void paradox_file_save (GOFileSaver const *fs, IOContext *io_context,
+ WorkbookView const *wb_view, GsfOutput *output);
+G_MODULE_EXPORT void
+paradox_file_save (GOFileSaver const *fs, IOContext *io_context,
+ WorkbookView const *wb_view, GsfOutput *output)
+{
+ Sheet *sheet;
+ GnmRange r;
+ gint row, col, i;
+
+ pxdoc_t *pxdoc = NULL;
+ pxfield_t *pxf;
+ char *data;
+ char *tmpfilename;
+
+ sheet = wb_view_cur_sheet (wb_view);
+ if (sheet == NULL) {
+ gnumeric_io_error_string (io_context, _("Cannot get default sheet."));
+ return;
+ }
+
+ r = sheet_get_extent (sheet, FALSE);
+
+#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
+
+ /* Read the field specification and build the field array for
+ * PX_create_fp(). The memory is freed by PX_delete() including
+ * the memory for the field name. */
+ if((pxf = (pxfield_t *) pxdoc->malloc(pxdoc, (r.end.col+1)*sizeof(pxfield_t), _("Allocate memory for field definitions."))) == NULL){
+ gnumeric_io_error_string (io_context, _("Cannot allocate memory for field definitions."));
+ PX_delete(pxdoc);
+ return;
+ }
+
+ for (col = r.start.col; col <= r.end.col; col++) {
+ GnmCell *cell = sheet_cell_get (sheet, col, 0);
+ if (gnm_cell_is_empty (cell)) {
+ gnumeric_io_error_string (io_context, _("First line of sheet must contain database specification."));
+ PX_delete(pxdoc);
+ return;
+ } else {
+ gchar *fieldstr, *tmp;
+ int len, needsize, needprecision;
+
+ i = col;
+ fieldstr = gnm_cell_get_rendered_text (cell);
+ needsize = 0;
+ needprecision = 0;
+
+ /* Search for the first comma which is the end of the field name. */
+ tmp = strchr(fieldstr, ',');
+ if(NULL == tmp) {
+ g_warning(_("Field specification must be a comma separated value (Name,Type,Size,Prec)."));
+ PX_delete(pxdoc);
+ return;
+ }
+ len = tmp-fieldstr;
+ if(NULL == (pxf[i].px_fname = pxdoc->malloc(pxdoc, len+1, _("Allocate memory for column name.")))) {
+ g_warning(_("Could not allocate memory for %d. field name."), i);
+ PX_delete(pxdoc);
+ return;
+ }
+ strncpy(pxf[i].px_fname, fieldstr, len);
+ pxf[i].px_fname[len] = '\0';
+
+ /* Get the field Type */
+ fieldstr = tmp+1;
+ if(*fieldstr == '\0') {
+ g_warning(_("%d. field specification ended unexpectetly."), i);
+ PX_delete(pxdoc);
+ return;
+ }
+ if(*fieldstr == ',') {
+ g_warning(_("%d. field specification misses type."), i);
+ PX_delete(pxdoc);
+ return;
+ }
+ switch((int) *fieldstr) {
+ case 'S':
+ pxf[i].px_ftype = pxfShort;
+ pxf[i].px_flen = 2;
+ break;
+ case 'I':
+ pxf[i].px_ftype = pxfLong;
+ pxf[i].px_flen = 4;
+ break;
+ case 'A':
+ case 'C':
+ pxf[i].px_ftype = pxfAlpha;
+ needsize = 1;
+ break;
+ case 'N':
+ pxf[i].px_ftype = pxfNumber;
+ pxf[i].px_flen = 8;
+ break;
+ case '$':
+ pxf[i].px_ftype = pxfCurrency;
+ pxf[i].px_flen = 8;
+ break;
+ case 'L':
+ pxf[i].px_ftype = pxfLogical;
+ pxf[i].px_flen = 1;
+ break;
+ case 'D':
+ pxf[i].px_ftype = pxfDate;
+ pxf[i].px_flen = 4;
+ break;
+ case '+':
+ pxf[i].px_ftype = pxfAutoInc;
+ pxf[i].px_flen = 4;
+ break;
+ case '@':
+ pxf[i].px_ftype = pxfTimestamp;
+ pxf[i].px_flen = 8;
+ break;
+ case 'T':
+ pxf[i].px_ftype = pxfTime;
+ pxf[i].px_flen = 4;
+ break;
+ case '#':
+ pxf[i].px_ftype = pxfBCD;
+ pxf[i].px_flen = 17;
+ needprecision = 1;
+ break;
+ case 'M':
+ pxf[i].px_ftype = pxfMemoBLOb;
+ needsize = 1;
+ break;
+ case 'B':
+ pxf[i].px_ftype = pxfBLOb;
+ needsize = 1;
+ break;
+ case 'F':
+ pxf[i].px_ftype = pxfFmtMemoBLOb;
+ needsize = 1;
+ break;
+ case 'Y':
+ pxf[i].px_ftype = pxfBytes;
+ needsize = 1;
+ break;
+ default:
+ g_warning(_("%d. field type '%c' is unknown."), i, *fieldstr);
+ pxdoc->free(pxdoc, pxf);
+ PX_delete(pxdoc);
+ return;
+ }
+
+ if(needsize || needprecision) {
+ char *endptr;
+ /* find end of type definition */
+ tmp = strchr(fieldstr, ',');
+ if(NULL == tmp || *(tmp+1) == '\0') {
+ g_warning(_("Field specification misses the column size."));
+ PX_delete(pxdoc);
+ return;
+ }
+ fieldstr = tmp+1;
+ if(needsize)
+ pxf[i].px_flen = strtol(fieldstr, &endptr, 10);
+ else
+ pxf[i].px_fdc = strtol(fieldstr, &endptr, 10);
+ if((endptr == NULL) || (fieldstr == endptr)) {
+ g_warning(_("Field specification misses the column size."));
+ PX_delete(pxdoc);
+ return;
+ }
+ if(*endptr != '\0') {
+ /* There is also precision which we do not care about. */
+ fieldstr = endptr+1;
+ g_warning(_("The remainder '%s' of the specification for field %d is being disregarded."), fieldstr, i+1);
+ }
+ }
+ }
+ }
+
+ /* Create the paradox file */
+ tmpfilename = tempnam("/tmp", NULL);
+ if(0 > PX_create_file(pxdoc, pxf, r.end.col+1, tmpfilename, pxfFileTypNonIndexDB)) {
+ g_warning(_("Could not create output file."));
+ PX_delete(pxdoc);
+ return;
+ }
+
+ PX_set_inputencoding(pxdoc, "UTF-8");
+ PX_set_parameter(pxdoc, "targetencoding", "CP1252");
+ PX_set_tablename(pxdoc, sheet->name_unquoted);
+
+ if((data = (char *) pxdoc->malloc(pxdoc, pxdoc->px_head->px_recordsize, _("Allocate memory for record data."))) == NULL) {
+ g_warning(_("Could not allocate memory for record data."));
+ PX_close(pxdoc);
+ PX_delete(pxdoc);
+ return;
+ }
+ /* Process all cells */
+ for (row = r.start.row+1; row <= r.end.row; row++) {
+ int i;
+ int offset;
+ offset = 0;
+ memset(data, 0, pxdoc->px_head->px_recordsize);
+ for (col = r.start.col, i = 0; col <= r.end.col; col++) {
+ GnmCell *cell = sheet_cell_get (sheet, col, row);
+ if (!gnm_cell_is_empty (cell)) {
+ char *fieldstr = gnm_cell_get_rendered_text (cell);
+ switch(pxf[i].px_ftype) {
+ case pxfShort: {
+ int value = value_get_as_int(cell->value);
+ PX_put_data_short(pxdoc, &data[offset], 2, (short int) value);
+ break;
+ }
+ case pxfLong:
+ case pxfAutoInc: {
+ int value = value_get_as_int (cell->value);
+ PX_put_data_long(pxdoc, &data[offset], 4, value);
+ break;
+ }
+ case pxfTimestamp: {
+ double value = value_get_as_float (cell->value);
+ /* 60 would be 29.2.1900 which didn't exist. */
+ if (value < 60)
+ value += 1.0;
+ value += 693594;
+ value *= 86400000.0;
+ PX_put_data_double(pxdoc, &data[offset], 8, value);
+ break;
+ }
+ case pxfCurrency:
+ case pxfNumber: {
+ double value = value_get_as_float (cell->value);
+ PX_put_data_double(pxdoc, &data[offset], 8, value);
+ break;
+ }
+ case pxfAlpha: {
+ char *value = fieldstr;
+ if ((int)strlen (value) > pxf[i].px_flen) {
+ g_warning(_("Field %d in line %d has possibly been cut off. Data has %d chars."), i+1, row+1, strlen(value));
+ }
+ PX_put_data_alpha(pxdoc, &data[offset], pxf[i].px_flen, value);
+ break;
+ }
+ case pxfMemoBLOb:
+ case pxfFmtMemoBLOb: {
+ char *value = fieldstr;
+ if(0 > PX_put_data_blob(pxdoc, &data[offset], pxf[i].px_flen, value, strlen(value))) {
+ g_warning(_("Field %d in row %d could not be written."), i+1, row+1);
+ }
+ break;
+ }
+ case pxfDate: {
+ long value = value_get_as_int (cell->value);
+ /* 60 would be 29.2.1900 which didn't exist. */
+ if(value < 60)
+ value++;
+ value += 693594;
+ PX_put_data_long(pxdoc, &data[offset], 4, value);
+ break;
+ }
+ case pxfTime: {
+ double dtmp;
+ int value;
+ dtmp = value_get_as_float(cell->value);
+ dtmp -= ((int) dtmp);
+ value = (int) (dtmp * 86400000.0);
+ PX_put_data_long(pxdoc, &data[offset], 4, value);
+ break;
+ }
+ case pxfLogical: {
+ gboolean err; /* Ignored */
+ gboolean value = value_get_as_bool (cell->value, &err);
+ if(!value) {
+ PX_put_data_byte(pxdoc, &data[offset], 1, 0);
+ } else {
+ PX_put_data_byte(pxdoc, &data[offset], 1, 1);
+ }
+ break;
+ }
+ case pxfBCD:
+ PX_put_data_bcd(pxdoc, &data[offset], pxf[i].px_fdc, fieldstr);
+ break;
+ }
+ }
+ offset += pxf[i].px_flen;
+ i++;
+ }
+ if((i > 0) && (0 > PX_put_record(pxdoc, data))) {
+ g_warning(_("Could not write record number %d."), i+1);
+ pxdoc->free(pxdoc, data);
+ PX_close(pxdoc);
+ PX_delete(pxdoc);
+ return;
+ }
+ }
+ pxdoc->free(pxdoc, data);
+ PX_close(pxdoc);
+ PX_delete(pxdoc);
+
+#ifdef PX_MEMORY_DEBUGGING
+ PX_mp_list_unfreed();
+#endif
+
+ {
+ FILE *fp;
+ size_t size;
+ fp = fopen (tmpfilename, "r");
+ if(fp) {
+ data = g_malloc (8192);
+ while(0 != (size = fread(data, 1, 8192, fp)))
+ gsf_output_write(output, size, data);
+ fclose(fp);
+ g_free(data);
+ } else
+ g_warning("Cannot open %s\n", tmpfilename);
+
+ unlink(tmpfilename);
+ }
+}
+
Modified: trunk/plugins/paradox/plugin.xml.in
==============================================================================
--- trunk/plugins/paradox/plugin.xml.in (original)
+++ trunk/plugins/paradox/plugin.xml.in Sun Mar 2 14:51:55 2008
@@ -10,12 +10,17 @@
<services>
<service type="file_opener" id="paradox" priority="100" probe="FALSE">
<information>
- <_description>Paradox database or primary index file</_description>
+ <_description>Paradox database or primary index file (*.db, *.px)</_description>
</information>
<suffixes>
<suffix>db</suffix>
<suffix>px</suffix>
</suffixes>
</service>
+ <service type="file_saver" id="paradox" format_level="write_only" file_extension="db">
+ <information>
+ <_description>Paradox database (*.db)</_description>
+ </information>
+ </service>
</services>
</plugin>
Modified: trunk/plugins/paradox/px.h
==============================================================================
--- trunk/plugins/paradox/px.h (original)
+++ trunk/plugins/paradox/px.h Sun Mar 2 14:51:55 2008
@@ -3,9 +3,12 @@
#include <gnumeric.h>
#include <gsf/gsf.h>
-#if PXLIB_MAJOR_VERSION == 0 && (PXLIB_MINOR_VERION < 3 || (PXLIB_MAJOR_VERSION == 3 && PXLIB_MICRO_VERSION == 0))
#include <pxversion.h>
-#endif
#include <paradox-gsf.h>
+#define PX_MEMORY_DEBUGGING
+#ifdef PX_MEMORY_DEBUGGING
+#include <paradox-mp.h>
+#endif
+
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]