Группа :: Офис
Пакет: catdoc
Главная Изменения Спек Патчи Загрузить Bugs and FR
Патч: catdoc-fix-broken-formatting.patch
diff -uNr catdoc/src/xls.h catdoc-devel/src/xls.h
--- catdoc/src/xls.h 2004-10-18 21:12:36 +0300
+++ catdoc/src/xls.h 2004-10-19 18:14:48 +0300
@@ -42,6 +42,11 @@
void do_table(FILE *input,char *filename);
char *mark_string(char *instr);
+/* ---- added by Igor ---- */
+void SetFormatIdxUsed(int format_code);
+/* -- end added by Igor -- */
+
+
#ifdef __TURBOC__
#define rint(x) floor((x+0.5))
#endif
diff -uNr catdoc/src/xlsparse.c catdoc-devel/src/xlsparse.c
--- catdoc/src/xlsparse.c 2004-10-18 21:12:36 +0300
+++ catdoc/src/xlsparse.c 2004-10-19 18:47:21 +0300
@@ -151,19 +151,25 @@
break;
}
case FORMAT: {- /* int i;
- char *ptr;
- printf( "Format %x \"",getshort(rec,0));
- if (rec[2] == reclen - 3 && rec[3] != 0) {- for (i=0,ptr=rec+3;i<rec[2];i++,ptr++) {- fputc(*ptr,stdout);
- }
- } else {- for (i=0,ptr=rec+5;i<rec[2];i++,ptr+=2) {- fputc(*ptr,stdout);
- }
- }
- printf ("\"\n"); */+ int format_code;
+ format_code=getshort(rec,0);
+ SetFormatIdxUsed(format_code);
+ /* this debug code prints format string */
+/*
+ int i;
+ char *ptr;
+ printf( "Format %x \"",format_code);
+ if (rec[2] == reclen - 3 && rec[3] != 0) {+ for (i=0,ptr=rec+3;i<rec[2];i++,ptr++) {+ fputc(*ptr,stdout);
+ }
+ } else {+ for (i=0,ptr=rec+5;i<rec[2];i++,ptr+=2) {+ fputc(*ptr,stdout);
+ }
+ }
+ printf ("\"\n");+*/
break;
}
case SST: {@@ -506,6 +512,102 @@
*src=s+to_skip;
return dest;
}
+
+
+/*
+ * Format code is index into format table (which is list of XF records
+ * in the file
+ * Second word of XF record is format type idnex
+ * format index between 0x0E and 0x16 also between 0x2D and ox2F denotes
+ * date if it is not used for explicitly stored formats.
+ * BuiltInDateFormatIdx converts format index into index of explicit
+ * built-in date formats sutable for strftime.
+ */
+int BuiltInDateFormatIdx (int index) {+ int offset;
+ offset=1; /* offset of date formats */
+ /* 0 is used as false -- format not found */
+ if ((index>= 0x0E) && (index<=0x16)) {+ return offset+index-0x0E;
+ } else
+ if ((index>=0x2d) && (index<=0x2F)) {+ return offset+index-0x2d+9;
+ } else if (index==0xa4) { + return 12+offset;
+ } else
+ return 0;
+}
+
+/*
+ * GetBuiltInDateFormat stores and returns
+ * built in xls2csv strftime formats.
+ */
+#define NUMOFDATEFORMATS 13
+char *GetBuiltInDateFormat(int dateindex) {+ static char *formats[]={+ /* reserved */ NULL, /* BuiltInDateFormatIdx use dateindex=0 as flag format not found */
+ /* 0x0E */ "%m-%d-%y", /* 01 */
+ /* 0x0F */ "%d-%b-%y", /* 02 */
+ /* 0x10 */ "%d-%b", /* 03 */
+ /* 0x11 */ "%b-%d", /* 04 */
+ /* 0x12 */ "%l:%M %p", /* 05 */
+ /* 0x13 */ "%l:%M:%S %p", /* 06 */
+ /* 0x14 */ "%H:%M", /* 07 */
+ /* 0x15 */ "%H:%M:%S", /* 08 */
+ /* 0x16 */ "%m-%d-%y %H:%M", /* 09 */
+ /* 0x2d */ "%M:%S", /* 10 */
+ /* 0x2e */ "%H:%M:%S", /* 11 */
+ /* 0x2f */ "%M:%S", /* 12 */
+ /* 0xa4 */ "%m.%d.%Y %l:%M:%S %p" /* 13 */
+ };
+ if (dateindex>0 && dateindex <= NUMOFDATEFORMATS) {+ return formats[dateindex];
+ } else
+ return NULL;
+}
+
+static char FormatIdxUsed[NUMOFDATEFORMATS];
+
+/*
+ * format index between 0x0E and 0x16 also between 0x2D and ox2F denotes
+ * date in case when they are built-in Excel97 formats.
+ * Nevertheless, those indexes can be used for explicitly stored formats,
+ * which are not dates in general.
+ * SetFormatIdxUsed marks this formats as already used
+ * and excludes them from list of built-in formats
+ * preventing misformatting of corresponding data.
+ */
+void SetFormatIdxUsed(int format_code) {+ int dateindex;
+/* fprintf(stderr,"Format idx %x to be set to dirty\n",format_code); */
+ dateindex=BuiltInDateFormatIdx(format_code);
+ if (dateindex) {+ FormatIdxUsed[dateindex]=1;
+/* fprintf(stderr,"Date idx %d is set to be dirty\n",dateindex); */
+ }
+}
+
+/*
+ * format index between 0x0E and 0x16 also between 0x2D and ox2F denotes
+ * date in case when they are built-in Excel97 formats.
+ * Nevertheless, those indexes can be used for explicitly stored formats,
+ * which are not dates in general.
+ * SetFormatIdxUsed marks this formats as already used
+ * and excludes them from list of built-in formats
+ * preventing misformatting of corresponding data.
+ * IsFormatIdxUsed tests this case.
+ */
+char IsFormatIdxUsed(int format_code) {+ int dateindex;
+ dateindex=BuiltInDateFormatIdx(format_code);
+ if (dateindex) {+/* fprintf(stderr,"Date idx %d is dirty\n",dateindex); */
+ return FormatIdxUsed[dateindex]=1;
+ }
+ else return 0;
+}
+
+
/* Checks if format denoted by given code is date
* Format code is index into format table (which is list of XF records
* in the file
@@ -517,39 +619,28 @@
*/
char *isDateFormat(int format_code) {int index;
-static char *formats[]={- /* 0x0E */ "%m-%d-%y",
- /* 0x0F */ "%d-%b-%y",
- /* 0x10 */ "%d-%b",
- /* 0x11 */ "%b-%d",
- /* 0x12 */ "%l:%M %p",
- /* 0x13 */ "%l:%M:%S %p",
- /* 0x14 */ "%H:%M",
- /* 0x15 */ "%H:%M:%S",
- /* 0x16 */ "%m-%d-%y %H:%M",
- /* 0x2d */ "%M:%S",
- /* 0x2e */ "%H:%M:%S",
- /* 0x2f */ "%M:%S",
- /* 0xa4 */ "%m.%d.%Y %l:%M:%S %p"
-};
+ int dateindex;
+ // int format_code;
if (format_code>=formatTableIndex) {fprintf(stderr,"Format code %d is used before definition\n",format_code);
return NULL;
}
+
index = formatTable[format_code];
- if ((index>= 0x0E) && (index<=0x16)) {- if (forced_date_format) return forced_date_format;
- return formats[index-0x0E];
- } else
- if ((index>=0x2d) && (index<=0x2F)) {- if (forced_date_format) return forced_date_format;
- return formats[index-0x2d+9];
- } else if (index==0xa4) { - if (forced_date_format) return forced_date_format;
- return formats[12];
+ if (IsFormatIdxUsed(index)) {+ /* this format is something user-defined --- not a standard built-in date*/
+ return NULL;
+ }
+ dateindex=BuiltInDateFormatIdx(index);
+ if (dateindex) {+ if (forced_date_format) return forced_date_format;
+ return GetBuiltInDateFormat(dateindex);
} else
return NULL;
}
+
+
+
time_t float2date(double d);
/*
* Extracts floating point value and formats it
