Coverage Report

Created: 2024-06-17 06:08

/src/libxls/src/xlstool.c
Line
Count
Source (jump to first uncovered line)
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
 *
3
 * Copyright 2004 Komarov Valery
4
 * Copyright 2006 Christophe Leitienne
5
 * Copyright 2008-2017 David Hoerl
6
 * Copyright 2013 Bob Colbert
7
 * Copyright 2013-2018 Evan Miller
8
 *
9
 * This file is part of libxls -- A multiplatform, C/C++ library for parsing
10
 * Excel(TM) files.
11
 *
12
 * Redistribution and use in source and binary forms, with or without
13
 * modification, are permitted provided that the following conditions are met:
14
 *
15
 *    1. Redistributions of source code must retain the above copyright notice,
16
 *    this list of conditions and the following disclaimer.
17
 *
18
 *    2. Redistributions in binary form must reproduce the above copyright
19
 *    notice, this list of conditions and the following disclaimer in the
20
 *    documentation and/or other materials provided with the distribution.
21
 *
22
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS
23
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
26
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
29
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
 *
34
 */
35
36
#include "config.h"
37
38
#include <sys/types.h>
39
#include <wchar.h>
40
#include <stdio.h>
41
42
#ifdef HAVE_ICONV
43
#include <iconv.h>
44
#endif
45
46
#include <limits.h>
47
#include <stdlib.h>
48
#include <errno.h>
49
#include <memory.h>
50
#include <string.h>
51
52
//#include "xls.h"
53
#include "../include/libxls/xlstypes.h"
54
#include "../include/libxls/xlsstruct.h"
55
#include "../include/libxls/xlstool.h"
56
#include "../include/libxls/brdb.h"
57
#include "../include/libxls/endian.h"
58
#include "../include/libxls/locale.h"
59
60
extern int xls_debug;
61
62
/* Not a complete list */
63
enum xls_format_e {
64
    XLS_FORMAT_GENERAL, // ""
65
    XLS_FORMAT_NUMBER1, // "0"
66
    XLS_FORMAT_NUMBER2,  //     "0.00",
67
    XLS_FORMAT_NUMBER3,  //     "#,##0",
68
    XLS_FORMAT_NUMBER4,  //     "#,##0.00",
69
    XLS_FORMAT_CURRENCY1,  //   "\"$\"#,##0_);(\"$\"#,##0)",
70
    XLS_FORMAT_CURRENCY2,  //   "\"$\"#,##0_);[Red](\"$\"#,##0)",
71
    XLS_FORMAT_CURRENCY3,  //   "\"$\"#,##0.00_);(\"$\"#,##0.00)",
72
    XLS_FORMAT_CURRENCY4,  //   "\"$\"#,##0.00_);[Red](\"$\"#,##0.00)",
73
    XLS_FORMAT_PERCENT1,  //    "0%",
74
    XLS_FORMAT_PERCENT2,  //    "0.00%",
75
    XLS_FORMAT_SCIENTIFIC1,  // "0.00E+00",
76
    XLS_FORMAT_SCIENTIFIC2 = 34 // "##0.0E+0"
77
};
78
79
static const DWORD colors[] =
80
    {
81
        0x000000,
82
        0xFFFFFF,
83
        0xFF0000,
84
        0x00FF00,
85
        0x0000FF,
86
        0xFFFF00,
87
        0xFF00FF,
88
        0x00FFFF,
89
        0x800000,
90
        0x008000,
91
        0x000080,
92
        0x808000,
93
        0x800080,
94
        0x008080,
95
        0xC0C0C0,
96
        0x808080,
97
        0x9999FF,
98
        0x993366,
99
        0xFFFFCC,
100
        0xCCFFFF,
101
        0x660066,
102
        0xFF8080,
103
        0x0066CC,
104
        0xCCCCFF,
105
        0x000080,
106
        0xFF00FF,
107
        0xFFFF00,
108
        0x00FFFF,
109
        0x800080,
110
        0x800000,
111
        0x008080,
112
        0x0000FF,
113
        0x00CCFF,
114
        0xCCFFFF,
115
        0xCCFFCC,
116
        0xFFFF99,
117
        0x99CCFF,
118
        0xFF99CC,
119
        0xCC99FF,
120
        0xFFCC99,
121
        0x3366FF,
122
        0x33CCCC,
123
        0x99CC00,
124
        0xFFCC00,
125
        0xFF9900,
126
        0xFF6600,
127
        0x666699,
128
        0x969696,
129
        0x003366,
130
        0x339966,
131
        0x003300,
132
        0x333300,
133
        0x993300,
134
        0x993366,
135
        0x333399,
136
        0x333333
137
    };
138
139
140
// Display string if in debug mode
141
void verbose(char* str)
142
103k
{
143
103k
    if (xls_debug)
144
0
        printf("libxls : %s\n",str);
145
103k
}
146
147
#ifdef HAVE_ICONV
148
149
struct codepage_entry_t {
150
    int code;
151
    const char *name;
152
};
153
154
static struct codepage_entry_t _codepage_entries[] = {
155
    { .code = 874, .name = "WINDOWS-874" },
156
    { .code = 932, .name = "SHIFT-JIS" },
157
    { .code = 936, .name = "WINDOWS-936" },
158
    { .code = 950, .name = "BIG-5" },
159
    { .code = 951, .name = "BIG5-HKSCS" },
160
    { .code = 1250, .name = "WINDOWS-1250" },
161
    { .code = 1251, .name = "WINDOWS-1251" },
162
    { .code = 1252, .name = "WINDOWS-1252" },
163
    { .code = 1253, .name = "WINDOWS-1253" },
164
    { .code = 1254, .name = "WINDOWS-1254" },
165
    { .code = 1255, .name = "WINDOWS-1255" },
166
    { .code = 1256, .name = "WINDOWS-1256" },
167
    { .code = 1257, .name = "WINDOWS-1257" },
168
    { .code = 1258, .name = "WINDOWS-1258" },
169
    { .code = 10000, .name = "MACROMAN" },
170
    { .code = 10004, .name = "MACARABIC" },
171
    { .code = 10005, .name = "MACHEBREW" },
172
    { .code = 10006, .name = "MACGREEK" },
173
    { .code = 10007, .name = "MACCYRILLIC" },
174
    { .code = 10010, .name = "MACROMANIA" },
175
    { .code = 10017, .name = "MACUKRAINE" },
176
    { .code = 10021, .name = "MACTHAI" },
177
    { .code = 10029, .name = "MACCENTRALEUROPE" },
178
    { .code = 10079, .name = "MACICELAND" },
179
    { .code = 10081, .name = "MACTURKISH" },
180
    { .code = 10082, .name = "MACCROATIAN" },
181
};
182
183
640
static int codepage_compare(const void *key, const void *value) {
184
640
    const struct codepage_entry_t *cp1 = key;
185
640
    const struct codepage_entry_t *cp2 = value;
186
640
    return cp1->code - cp2->code;
187
640
}
188
189
149
static const char *encoding_for_codepage(WORD codepage) {
190
149
    struct codepage_entry_t key = { .code = codepage };
191
149
    struct codepage_entry_t *result = bsearch(&key, _codepage_entries,
192
149
            sizeof(_codepage_entries)/sizeof(_codepage_entries[0]),
193
149
            sizeof(_codepage_entries[0]), &codepage_compare);
194
149
    if (result) {
195
53
        return result->name;
196
53
    }
197
96
    return "WINDOWS-1252";
198
149
}
199
200
4.17k
static char* unicode_decode_iconv(const char *s, size_t len, iconv_t ic) {
201
4.17k
    char* outbuf = 0;
202
203
4.17k
    if(s && len && ic)
204
2.62k
    {
205
2.62k
        size_t outlenleft = len;
206
2.62k
        int outlen = len;
207
2.62k
        size_t inlenleft = len;
208
2.62k
        const char* src_ptr = s;
209
2.62k
        char* out_ptr = 0;
210
211
2.62k
        size_t st; 
212
2.62k
        outbuf = malloc(outlen + 1);
213
214
2.62k
    if(outbuf)
215
2.62k
        {
216
2.62k
            out_ptr = outbuf;
217
6.14k
            while(inlenleft)
218
3.67k
            {
219
3.67k
                st = iconv(ic, (ICONV_CONST char **)&src_ptr, &inlenleft, (char **)&out_ptr,(size_t *) &outlenleft);
220
3.67k
                if(st == (size_t)(-1))
221
1.21k
                {
222
1.21k
                    if(errno == E2BIG)
223
1.05k
                    {
224
1.05k
                        size_t diff = out_ptr - outbuf;
225
1.05k
                        outlen += inlenleft;
226
1.05k
                        outlenleft += inlenleft;
227
1.05k
                        outbuf = realloc(outbuf, outlen + 1);
228
1.05k
                        if(!outbuf)
229
0
                        {
230
0
                            break;
231
0
                        }
232
1.05k
                        out_ptr = outbuf + diff;
233
1.05k
                    }
234
162
                    else
235
162
                    {
236
162
                        free(outbuf), outbuf = NULL;
237
162
                        break;
238
162
                    }
239
1.21k
                }
240
3.67k
            }
241
2.62k
        }
242
2.62k
        outlen -= outlenleft;
243
244
2.62k
        if(outbuf)
245
2.46k
        {
246
2.46k
            outbuf[outlen] = 0;
247
2.46k
        }
248
2.62k
    }
249
4.17k
    return outbuf;
250
4.17k
}
251
252
#endif
253
254
// Convert UTF-16 to UTF-8 without iconv
255
11.0k
static char *unicode_decode_wcstombs(const char *s, size_t len, xls_locale_t locale) {
256
  // Do wcstombs conversion
257
11.0k
    char *converted = NULL;
258
11.0k
    int count, count2;
259
11.0k
    size_t i;
260
11.0k
    wchar_t *w = NULL;
261
262
11.0k
    w = malloc((len/2+1)*sizeof(wchar_t));
263
264
61.6k
    for(i=0; i<len/2; i++)
265
50.5k
    {
266
50.5k
        w[i] = (BYTE)s[2*i] + ((BYTE)s[2*i+1] << 8);
267
50.5k
    }
268
11.0k
    w[len/2] = '\0';
269
270
11.0k
    count = xls_wcstombs_l(NULL, w, INT_MAX, locale);
271
272
11.0k
    if (count <= 0) {
273
7.13k
        goto cleanup;
274
7.13k
    }
275
276
3.96k
    converted = calloc(count+1, sizeof(char));
277
3.96k
    count2 = xls_wcstombs_l(converted, w, count, locale);
278
3.96k
    if (count2 <= 0) {
279
0
        printf("wcstombs failed (%lu)\n", (unsigned long)len/2);
280
0
        goto cleanup;
281
0
    }
282
283
11.0k
cleanup:
284
11.0k
    free(w);
285
11.0k
    return converted;
286
3.96k
}
287
288
// Converts Latin-1 to UTF-8 the old-fashioned way
289
static char *transcode_latin1_to_utf8(const char *str, DWORD len)
290
4.02k
{
291
4.02k
  int utf8_chars = 0;
292
4.02k
  char *ret = NULL;
293
4.02k
    DWORD i;
294
  
295
302k
    for(i=0; i<len; ++i) {
296
298k
        if(str[i] & (BYTE)0x80) {
297
44.8k
            ++utf8_chars;
298
44.8k
        }
299
298k
    }
300
  
301
4.02k
    char *out = ret = malloc(len+utf8_chars+1);
302
    // UTF-8 encoding inline
303
302k
    for(i=0; i<len; ++i) {
304
298k
        BYTE c = str[i];
305
298k
        if(c & (BYTE)0x80) {
306
44.8k
            *out++ = (BYTE)0xC0 | (c >> 6);
307
44.8k
            *out++ = (BYTE)0x80 | (c & 0x3F);
308
253k
        } else {
309
253k
            *out++ = c;
310
253k
        }
311
298k
    }
312
4.02k
    *out = 0;
313
314
4.02k
  return ret;
315
4.02k
}
316
317
// Convert BIFF5 string or compressed BIFF8 string to the encoding desired
318
// by the workbook. Returns a NUL-terminated string
319
5.40k
char* codepage_decode(const char *s, size_t len, xlsWorkBook *pWB) {
320
5.40k
    if (!pWB->is5ver && strcmp(pWB->charset, "UTF-8") == 0)
321
4.02k
        return transcode_latin1_to_utf8(s, len);
322
323
1.38k
#ifdef HAVE_ICONV
324
1.38k
    if (!pWB->converter) {
325
149
        const char *from_encoding = pWB->is5ver ? encoding_for_codepage(pWB->codepage) : "ISO-8859-1";
326
149
        iconv_t converter = iconv_open(pWB->charset, from_encoding);
327
149
        if (converter == (iconv_t)-1) {
328
52
            printf("conversion from '%s' to '%s' not available", from_encoding, pWB->charset);
329
52
            return NULL;
330
52
        }
331
97
        pWB->converter = (void *)converter;
332
97
    }
333
1.32k
    return unicode_decode_iconv(s, len, pWB->converter);
334
#else
335
    char *ret = malloc(len+1);
336
    memcpy(ret, s, len);
337
    ret[len] = 0;
338
    return ret;
339
#endif
340
1.38k
}
341
342
// Convert unicode string to UTF-8
343
11.0k
char* transcode_utf16_to_utf8(const char *s, size_t len) {
344
11.0k
    xls_locale_t locale = xls_createlocale();
345
11.0k
    char *result = unicode_decode_wcstombs(s, len, locale);
346
11.0k
    xls_freelocale(locale);
347
11.0k
    return result;
348
11.0k
}
349
350
// Convert unicode string to the encoding desired by the workbook
351
char* unicode_decode(const char *s, size_t len, xlsWorkBook *pWB)
352
2.84k
{
353
2.84k
#ifdef HAVE_ICONV
354
#if defined(_AIX) || defined(__sun)
355
    const char *from_enc = "UTF-16le";
356
#else
357
2.84k
    const char *from_enc = "UTF-16LE";
358
2.84k
#endif
359
2.84k
    if (!pWB->utf16_converter) {
360
404
        iconv_t converter = iconv_open(pWB->charset, from_enc);
361
404
        if (converter == (iconv_t)-1) {
362
0
            printf("conversion from '%s' to '%s' not available\n", from_enc, pWB->charset);
363
0
            return NULL;
364
0
        }
365
404
        pWB->utf16_converter = (void *)converter;
366
404
    }
367
2.84k
    return unicode_decode_iconv(s, len, pWB->utf16_converter);
368
#else
369
    if (!pWB->utf8_locale) {
370
        xls_locale_t locale = xls_createlocale();
371
        if (locale == NULL) {
372
            printf("creation of UTF-8 locale failed\n");
373
            return NULL;
374
        }
375
        pWB->utf8_locale = (void *)locale;
376
    }
377
    return unicode_decode_wcstombs(s, len, pWB->utf8_locale);
378
#endif
379
2.84k
}
380
381
// Read and decode string
382
char *get_string(const char *s, size_t len, BYTE is2, xlsWorkBook* pWB)
383
27.8k
{
384
27.8k
    WORD ln;
385
27.8k
    DWORD ofs = 0;
386
27.8k
    BYTE flag = 0;
387
27.8k
    const char *str = s;
388
27.8k
    char *ret = NULL;
389
  
390
27.8k
    if (is2) {
391
    // length is two bytes
392
3.20k
        if (ofs + 2 > len) {
393
843
            return NULL;
394
843
        }
395
2.36k
        ln= ((BYTE*)str)[0] + (((BYTE*)str)[1] << 8);
396
2.36k
        ofs+=2;
397
24.6k
    } else {
398
    // single byte length
399
24.6k
        if (ofs + 1 > len) {
400
604
            return NULL;
401
604
        }
402
24.0k
        ln=*(BYTE*)str;
403
24.0k
        ofs++;
404
24.0k
    }
405
406
26.3k
  if(!pWB->is5ver) {
407
    // unicode strings have a format byte before the string
408
25.3k
        if (ofs + 1 > len) {
409
20.5k
            return NULL;
410
20.5k
        }
411
4.79k
    flag=*(BYTE*)(str+ofs);
412
4.79k
    ofs++;
413
4.79k
  }
414
5.86k
    if (flag&0x8) {
415
    // WORD rt;
416
        // rt=*(WORD*)(str+ofs); // unused
417
1.41k
        ofs+=2;
418
1.41k
    }
419
5.86k
    if (flag&0x4) {
420
    // DWORD sz;
421
        // sz=*(DWORD*)(str+ofs); // unused
422
1.36k
        ofs+=4;
423
1.36k
    }
424
5.86k
    if(flag & 0x1) {
425
2.19k
        if (ofs + 2*ln > len) {
426
1.38k
            return NULL;
427
1.38k
        }
428
812
        ret = unicode_decode(str+ofs, ln*2, pWB);
429
3.67k
    } else {
430
3.67k
        if (ofs + ln > len) {
431
1.80k
            return NULL;
432
1.80k
        }
433
1.86k
        ret = codepage_decode(str+ofs, ln, pWB);
434
1.86k
    }
435
436
#if 0 // debugging
437
  if(xls_debug == 100) {
438
    ofs += (flag & 0x1) ? ln*2 : ln;
439
440
    printf("ofs=%d ret[0]=%d\n", ofs, *ret);
441
    {
442
      unsigned char *ptr;
443
      
444
      ptr = ret;
445
      
446
      printf("%x %x %x %x %x %x %x %x\n", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7] );
447
      printf("%s\n", ret);
448
    }
449
  }
450
#endif
451
452
2.68k
    return ret;
453
5.86k
}
454
455
DWORD xls_getColor(const WORD color,WORD def)
456
0
{
457
0
    int cor=8;
458
0
    int size = 64 - cor;
459
0
    int max = size;
460
0
    WORD idx=color;
461
0
    if( idx >= cor)
462
0
        idx -= cor;
463
0
    if( idx < max )
464
0
    {
465
0
        return colors[idx];
466
0
    }
467
0
    else
468
0
        return colors[def];
469
0
}
470
471
472
void xls_showBookInfo(xlsWorkBook* pWB)
473
0
{
474
0
    verbose("BookInfo");
475
0
    printf("  is5ver: %i\n",pWB->is5ver);
476
0
    printf("codepage: %i\n",pWB->codepage);
477
0
    printf("    type: %.4X ",pWB->type);
478
0
    switch (pWB->type)
479
0
    {
480
0
    case 0x5:
481
0
        printf("Workbook globals\n");
482
0
        break;
483
0
    case 0x6:
484
0
        printf("Visual Basic module\n");
485
0
        break;
486
0
    case 0x10:
487
0
        printf("Worksheet\n");
488
0
        break;
489
0
    case 0x20:
490
0
        printf("Chart\n");
491
0
        break;
492
0
    case 0x40:
493
0
        printf("BIFF4 Macro sheet\n");
494
0
        break;
495
0
    case 0x100:
496
0
        printf("BIFF4W Workbook globals\n");
497
0
        break;
498
0
    }
499
0
    printf("------------------- END BOOK INFO---------------------------\n");
500
0
}
501
502
503
void xls_showBOF(BOF* bof)
504
0
{
505
0
    printf("----------------------------------------------\n");
506
0
    verbose("BOF");
507
0
    printf("   ID: %.4Xh %s (%s)\n",bof->id,brdb[get_brbdnum(bof->id)].name,brdb[get_brbdnum(bof->id)].desc);
508
0
    printf("   Size: %i\n",bof->size);
509
0
}
510
511
#if 0
512
static void xls_showBOUNDSHEET(BOUNDSHEET* bsheet)
513
{
514
    switch (bsheet->type & 0x000f)
515
    {
516
    case 0x0000:
517
        /* worksheet or dialog sheet */
518
        verbose ("85: Worksheet or dialog sheet");
519
        break;
520
    case 0x0001:
521
        /* Microsoft Excel 4.0 macro sheet */
522
        verbose ("85: Microsoft Excel 4.0 macro sheet");
523
        break;
524
    case 0x0002:
525
        /* Chart */
526
        verbose ("85: Chart sheet");
527
        break;
528
    case 0x0006:
529
        /* Visual Basic module */
530
        verbose ("85: Visual Basic sheet");
531
        break;
532
    default:
533
        break;
534
    }
535
    printf("    Pos: %Xh\n",bsheet->filepos);
536
    printf("  flags: %.4Xh\n",bsheet->type);
537
    //  printf("   Name: [%i] %s\n",bsheet->len,bsheet->name);
538
}
539
#endif
540
541
void xls_showROW(struct st_row_data* row)
542
0
{
543
0
    verbose("ROW");
544
0
    printf("    Index: %i \n",row->index);
545
0
    printf("First col: %i \n",row->fcell);
546
0
    printf(" Last col: %i \n",row->lcell);
547
0
    printf("   Height: %i (1/20 px)\n",row->height);
548
0
    printf("    Flags: %.4X \n",row->flags);
549
0
    printf("       xf: %i \n",row->xf);
550
0
    printf("----------------------------------------------\n");
551
0
}
552
553
void xls_showColinfo(struct st_colinfo_data* col)
554
0
{
555
0
    verbose("COLINFO");
556
0
    printf("First col: %i \n",col->first);
557
0
    printf(" Last col: %i \n",col->last);
558
0
    printf("    Width: %i (1/256 px)\n",col->width);
559
0
    printf("       XF: %i \n",col->xf);
560
0
    printf("    Flags: %i (",col->flags);
561
0
    if (col->flags & 0x1)
562
0
        printf("hidden ");
563
0
    if (col->flags & 0x700)
564
0
        printf("outline ");
565
0
    if (col->flags & 0x1000)
566
0
        printf("collapsed ");
567
0
    printf(")\n");
568
0
    printf("----------------------------------------------\n");
569
0
}
570
571
void xls_showCell(struct st_cell_data* cell)
572
0
{
573
0
    printf("  -----------\n");
574
0
    printf("     ID: %.4Xh %s (%s)\n",cell->id, brdb[get_brbdnum(cell->id)].name, brdb[get_brbdnum(cell->id)].desc);
575
0
    printf("   Cell: %c:%u  [%u:%u]\n",cell->col+'A',cell->row+1,cell->col,cell->row);
576
//    printf("   Cell: %u:%u\n",cell->col+1,cell->row+1);
577
0
    printf("     xf: %i\n",cell->xf);
578
0
  if(cell->id == XLS_RECORD_BLANK) {
579
    //printf("BLANK_CELL!\n");
580
0
    return;
581
0
  }
582
0
    printf(" double: %f\n",cell->d);
583
0
    printf("    int: %d\n",cell->l);
584
0
    if (cell->str!=NULL)
585
0
        printf("    str: %s\n",cell->str);
586
0
}
587
588
589
void xls_showFont(struct st_font_data* font)
590
0
{
591
592
0
    printf("      name: %s\n",font->name);
593
0
    printf("    height: %i\n",font->height);
594
0
    printf("      flag: %.4X\n",font->flag);
595
0
    printf("     color: %.6X\n",font->color);
596
0
    printf("      bold: %i\n",font->bold);
597
0
    printf("escapement: %i\n",font->escapement);
598
0
    printf(" underline: %i\n",font->underline);
599
0
    printf("    family: %i\n",font->family);
600
0
    printf("   charset: %i\n",font->charset);
601
602
0
}
603
#if 0
604
typedef struct st_format
605
  {
606
    long count;   //Count of FORMAT's
607
    struct st_format_data
608
    {
609
      WORD index;
610
      char *value;
611
    }
612
    * format;
613
  }
614
  st_format;
615
#endif
616
617
void xls_showFormat(struct st_format_data* frmt)
618
0
{
619
0
  printf("    index : %u\n", frmt->index);
620
0
    printf("     value: %s\n", frmt->value);
621
0
}
622
623
void xls_showXF(XF8* xf)
624
0
{
625
0
  static int idx;
626
  
627
0
    printf("      Index: %u\n",idx++);
628
0
    printf("       Font: %u\n",xf->font);
629
0
    printf("     Format: %u\n",xf->format);
630
0
    printf("       Type: 0x%x\n",xf->type);
631
0
    printf("      Align: 0x%x\n",xf->align);
632
0
    printf("   Rotation: 0x%x\n",xf->rotation);
633
0
    printf("      Ident: 0x%x\n",xf->ident);
634
0
    printf("   UsedAttr: 0x%x\n",xf->usedattr);
635
0
    printf("  LineStyle: 0x%x\n",xf->linestyle);
636
0
    printf("  Linecolor: 0x%x\n",xf->linecolor);
637
0
    printf("GroundColor: 0x%x\n",xf->groundcolor);
638
0
}
639
640
char *xls_getfcell(xlsWorkBook* pWB, struct st_cell_data* cell, BYTE *label)
641
24.9k
{
642
24.9k
    struct st_xf_data *xf = NULL;
643
24.9k
  WORD  len = 0;
644
24.9k
    DWORD   offset = 0;
645
24.9k
    char  *ret = NULL;
646
24.9k
    size_t  retlen = 100;
647
648
24.9k
    if (cell->xf < pWB->xfs.count)
649
345
        xf=&pWB->xfs.xf[cell->xf];
650
651
24.9k
    switch (cell->id)
652
24.9k
    {
653
2.18k
    case XLS_RECORD_LABELSST:
654
2.18k
        offset = label[0] + (label[1] << 8);
655
2.18k
        if(!pWB->is5ver) {
656
1.96k
            offset += ((DWORD)label[2] << 16);
657
1.96k
            offset += ((DWORD)label[3] << 24);
658
1.96k
        }
659
2.18k
        if(offset < pWB->sst.count && pWB->sst.string[offset].str) {
660
203
            ret = strdup(pWB->sst.string[offset].str);
661
203
        }
662
2.18k
        break;
663
10.1k
    case XLS_RECORD_BLANK:
664
10.1k
    case XLS_RECORD_MULBLANK:
665
10.1k
        ret = strdup("");
666
10.1k
        break;
667
790
    case XLS_RECORD_LABEL:
668
1.36k
    case XLS_RECORD_RSTRING:
669
1.36k
        len = label[0] + (label[1] << 8);
670
1.36k
        label += 2;
671
1.36k
        if (pWB->is5ver || (*(label++) & 0x01) == 0) {
672
836
            ret = codepage_decode((char *)label, len, pWB);
673
836
        } else {
674
532
            ret = unicode_decode((char *)label, len*2, pWB);
675
532
        }
676
1.36k
        break;
677
8.71k
    case XLS_RECORD_RK:
678
11.2k
    case XLS_RECORD_NUMBER:
679
11.2k
        ret = malloc(retlen);
680
11.2k
        snprintf(ret, retlen, "%lf", cell->d);
681
11.2k
    break;
682
    //    if( RK || MULRK || NUMBER || FORMULA)
683
    //    if (cell->id==0x27e || cell->id==0x0BD || cell->id==0x203 || 6 (formula))
684
0
    default:
685
0
        if (xf) {
686
0
            ret = malloc(retlen);
687
0
            switch (xf->format)
688
0
            {
689
0
                case XLS_FORMAT_GENERAL:
690
0
                case XLS_FORMAT_NUMBER1:
691
0
                case XLS_FORMAT_NUMBER3:
692
0
                    snprintf(ret, retlen, "%.0lf", cell->d);
693
0
                    break;
694
0
                case XLS_FORMAT_NUMBER2:
695
0
                case XLS_FORMAT_NUMBER4:
696
0
                    snprintf(ret, retlen, "%.2f", cell->d);
697
0
                    break;
698
0
                case XLS_FORMAT_PERCENT1:
699
0
                    snprintf(ret, retlen, "%.0lf%%", 100 * cell->d);
700
0
                    break;
701
0
                case XLS_FORMAT_PERCENT2:
702
0
                    snprintf(ret, retlen, "%.2lf%%", 100 * cell->d);
703
0
                    break;
704
0
                case XLS_FORMAT_SCIENTIFIC1:
705
0
                    snprintf(ret, retlen, "%.2e", cell->d);
706
0
                    break;
707
0
                case XLS_FORMAT_SCIENTIFIC2:
708
0
                    snprintf(ret, retlen, "%.1e", cell->d);
709
0
                    break;
710
0
                default:
711
0
                    snprintf(ret, retlen, "%.2f", cell->d);
712
0
                    break;
713
0
            }
714
0
            break;
715
0
        }
716
24.9k
    }
717
718
24.9k
    return ret;
719
24.9k
}
720
721
char* xls_getCSS(xlsWorkBook* pWB)
722
0
{
723
0
    char color[255];
724
0
    char* align;
725
0
    char* valign;
726
0
    char borderleft[255];
727
0
    char borderright[255];
728
0
    char bordertop[255];
729
0
    char borderbottom[255];
730
0
    char italic[255];
731
0
    char underline[255];
732
0
    char bold[255];
733
0
    WORD size;
734
0
    char fontname[255];
735
0
    struct st_xf_data* xf;
736
0
    DWORD background;
737
0
    DWORD i;
738
739
0
    char *ret = malloc(65535);
740
0
    size_t buf_len = 4096;
741
0
    char *buf = malloc(buf_len);
742
0
  ret[0] = '\0';
743
744
0
    for (i=0;i<pWB->xfs.count;i++)
745
0
    {
746
0
        xf=&pWB->xfs.xf[i];
747
0
        switch ((xf->align & 0x70)>>4)
748
0
        {
749
0
        case 0:
750
0
            valign=(char*)"top";
751
0
            break;
752
0
        case 1:
753
0
            valign=(char*)"middle";
754
0
            break;
755
0
        case 2:
756
0
            valign=(char*)"bottom";
757
0
            break;
758
            //      case 3: valign=(char*)"right"; break;
759
            //      case 4: valign=(char*)"right"; break;
760
0
        default:
761
0
            valign=(char*)"middle";
762
0
            break;
763
0
        }
764
765
0
        switch (xf->align & 0x07)
766
0
        {
767
0
        case 1:
768
0
            align=(char*)"left";
769
0
            break;
770
0
        case 2:
771
0
            align=(char*)"center";
772
0
            break;
773
0
        case 3:
774
0
            align=(char*)"right";
775
0
            break;
776
0
        default:
777
0
            align=(char*)"left";
778
0
            break;
779
0
        }
780
781
0
        switch (xf->linestyle & 0x0f)
782
0
        {
783
0
        case 0:
784
0
            snprintf(borderleft, sizeof(borderleft), "%s", "");
785
0
            break;
786
0
        default:
787
0
            snprintf(borderleft, sizeof(borderleft), "border-left: 1px solid black;");
788
0
            break;
789
0
        }
790
791
0
        switch (xf->linestyle & 0x0f0)
792
0
        {
793
0
        case 0:
794
0
            snprintf(borderright, sizeof(borderright), "%s", "");
795
0
            break;
796
0
        default:
797
0
            snprintf(borderright, sizeof(borderright), "border-right: 1px solid black;");
798
0
            break;
799
0
        }
800
801
0
        switch (xf->linestyle & 0x0f00)
802
0
        {
803
0
        case 0:
804
0
            snprintf(bordertop, sizeof(bordertop), "%s", "");
805
0
            break;
806
0
        default:
807
0
            snprintf(bordertop, sizeof(bordertop), "border-top: 1px solid black;");
808
0
            break;
809
0
        }
810
811
0
        switch (xf->linestyle & 0x0f000)
812
0
        {
813
0
        case 0:
814
0
            snprintf(borderbottom, sizeof(borderbottom), "%s", "");
815
0
            break;
816
0
        default:
817
0
            snprintf(borderbottom, sizeof(borderbottom), "border-bottom: 1px solid Black;");
818
0
            break;
819
0
        }
820
821
0
        if (xf->font)
822
0
            snprintf(color, sizeof(color), "color:#%.6X;",xls_getColor(pWB->fonts.font[xf->font-1].color,0));
823
0
        else
824
0
            snprintf(color, sizeof(color), "%s", "");
825
826
0
        if (xf->font && (pWB->fonts.font[xf->font-1].flag & 2))
827
0
            snprintf(italic, sizeof(italic), "font-style: italic;");
828
0
        else
829
0
            snprintf(italic, sizeof(italic), "%s", "");
830
831
0
        if (xf->font && (pWB->fonts.font[xf->font-1].bold>400))
832
0
            snprintf(bold, sizeof(bold), "font-weight: bold;");
833
0
        else
834
0
            snprintf(bold, sizeof(bold), "%s", "");
835
836
0
        if (xf->font && (pWB->fonts.font[xf->font-1].underline))
837
0
            snprintf(underline, sizeof(underline), "text-decoration: underline;");
838
0
        else
839
0
            snprintf(underline, sizeof(underline), "%s", "");
840
841
0
        if (xf->font)
842
0
            size=pWB->fonts.font[xf->font-1].height/20;
843
0
        else
844
0
            size=10;
845
846
0
        if (xf->font)
847
0
            snprintf(fontname, sizeof(fontname),"%s",pWB->fonts.font[xf->font-1].name);
848
0
        else
849
0
            snprintf(fontname, sizeof(fontname),"Arial");
850
851
0
        background=xls_getColor((WORD)(xf->groundcolor & 0x7f),1);
852
0
        snprintf(buf, buf_len, ".xf%i{ font-size:%ipt;font-family: \"%s\";background:#%.6X;text-align:%s;vertical-align:%s;%s%s%s%s%s%s%s%s}\n",
853
0
                i,size,fontname,background,align,valign,borderleft,borderright,bordertop,borderbottom,color,italic,bold,underline);
854
855
0
    strcat(ret,buf);
856
0
    }
857
0
  ret = realloc(ret, strlen(ret)+1);
858
0
  free(buf);
859
860
0
    return ret;
861
0
}